@mshafiqyajid/react-segmented-control
Headless segmented control hook and styled component for React. Buttery sliding indicator, ResizeObserver measurement, full keyboard nav, generic over option type, object options with custom labels.
Playground #
Time range
Props
TSX
import { SegmentedControlStyled } from "@mshafiqyajid/react-segmented-control/styled";
import "@mshafiqyajid/react-segmented-control/styles.css";
<SegmentedControlStyled
options=["Day","Week","Month","Year"]
value={value}
onChange={setValue}
/>Install #
npm install @mshafiqyajid/react-segmented-control Quick start #
import { SegmentedControlStyled } from "@mshafiqyajid/react-segmented-control/styled";
import "@mshafiqyajid/react-segmented-control/styles.css";
const [view, setView] = useState("week");
<SegmentedControlStyled
options={["day", "week", "month"]}
value={view}
onChange={setView}
tone="primary"
/> Recipes #
Object options with custom labels
<SegmentedControlStyled
options={[
{ value: "asc", label: "↑ Ascending" },
{ value: "desc", label: "↓ Descending" },
]}
value={sort}
onChange={setSort}
/> With disabled options
<SegmentedControlStyled
options={[
"Free",
"Pro",
{ value: "Enterprise", disabled: true },
]}
defaultValue="Free"
/> Generic over object types
type Plan = { id: string; price: number };
<SegmentedControlStyled<Plan>
options={plans.map(p => ({ value: p, label: p.id }))}
value={selected}
onChange={setSelected}
equals={(a, b) => a.id === b.id}
/> API #
SegmentedControlStyled
| Prop | Type | Default | Description |
|---|---|---|---|
| options | Array<T | { value, label?, disabled? }> | — | Required. Options to render. |
| value | T | — | Controlled value. |
| defaultValue | T | first option | Uncontrolled initial value. |
| onChange | (value: T) => void | — | Fires on change. |
| equals | (a: T, b: T) => boolean | Object.is | Custom equality for objects. |
| variant | solid | pill | underline | solid | Visual style. |
| size | sm | md | lg | md | Size. |
| tone | neutral | primary | success | danger | primary | Indicator color. |
| fullWidth | boolean | false | Stretch to container. |
| label | ReactNode | — | Label above. |