@mshafiqyajid/react-tabs
Headless tabs hook and styled component for React. Line, solid, and pill variants with a ResizeObserver-driven sliding indicator. Controlled and uncontrolled, full keyboard navigation, ARIA-compliant.
Playground #
Overview content goes here.
Features content goes here.
Pricing content goes here.
Props
TSX
import { TabsStyled } from "@mshafiqyajid/react-tabs/styled";
import "@mshafiqyajid/react-tabs/styles.css";
<TabsStyled
tabs={tabs}
defaultValue="overview"
/>Install #
npm install @mshafiqyajid/react-tabs Quick start #
import { TabsStyled } from "@mshafiqyajid/react-tabs/styled";
import "@mshafiqyajid/react-tabs/styles.css";
const tabs = [
{ value: "overview", label: "Overview", content: <p>Overview</p> },
{ value: "features", label: "Features", content: <p>Features</p> },
];
<TabsStyled tabs={tabs} defaultValue="overview" /> Controlled #
const [tab, setTab] = useState("overview");
<TabsStyled tabs={tabs} value={tab} onChange={setTab} /> Variants #
<TabsStyled tabs={tabs} variant="line" /> {/* default */}
<TabsStyled tabs={tabs} variant="solid" />
<TabsStyled tabs={tabs} variant="pill" /> Disabled tab #
const tabs = [
{ value: "a", label: "Active", content: <p>A</p> },
{ value: "b", label: "Disabled", content: <p>B</p>, disabled: true },
]; Headless #
import { useTabs } from "@mshafiqyajid/react-tabs";
const { activeValue, getTabProps, getPanelProps } = useTabs({
tabs: [{ value: "a" }, { value: "b" }],
defaultValue: "a",
});
<div role="tablist">
<button {...getTabProps("a")}>Tab A</button>
<button {...getTabProps("b")}>Tab B</button>
</div>
<div {...getPanelProps("a")}>Content A</div>
<div {...getPanelProps("b")}>Content B</div> API #
| Prop | Type | Default | Description |
|---|---|---|---|
| tabs | TabItem[] | — | Array of { value, label, content, disabled? } |
| variant | "line" | "solid" | "pill" | "line" | Visual style |
| size | "sm" | "md" | "lg" | "md" | Size variant |
| tone | "neutral" | "primary" | "neutral" | Color tone |
| defaultValue | string | first enabled | Initially active tab (uncontrolled) |
| value | string | — | Controlled active tab |
| onChange | (value: string) => void | — | Called when active tab changes |