Segment
A segmented control component for single-select, supporting controlled, uncontrolled and options-driven modes
Installation
- $npx litefy@latest add segment
- $pnpm dlx litefy@latest add segment
- $yarn dlx litefy@latest add segment
- $bun --bun litefy@latest add segment
Usage
Data-driven segmented control for single-select, supporting controlled and uncontrolled modes.
Selected: list
"use client";import { useState } from "react";import { SegmentGroup } from "@/ui";export default function Demo() { const [value, setValue] = useState("list"); return ( <div className="flex flex-col gap-3"> <SegmentGroup value={value} onValueChange={setValue} options={[ { label: "List", value: "list" }, { label: "Grid", value: "grid" }, { label: "Table", value: "table" }, ]} /> <p className="text-sm text-muted-foreground">Selected: {value}</p> </div> );}Disabled
Disable a single option via its own disabled flag, or the whole group via the group's disabled.
"use client";
import { SegmentGroup } from "@/ui";
export default function SegmentDisabledDemo() {
return (
<SegmentGroup
disabled
defaultValue="table"
options={[
{ label: "List", value: "list" },
{ label: "Grid", value: "grid" },
{ label: "Table", value: "table" },
]}
/>
);
}
Variants
fill is the default and is shown in Basic Usage; the text variant only tints the selected text.
text
"use client";
import { SegmentGroup } from "@/ui";
const options = [
{ label: "List", value: "list" },
{ label: "Grid", value: "grid" },
{ label: "Table", value: "table" },
];
export default function Demo() {
return (
<div className="flex flex-col items-center gap-2">
<SegmentGroup variant="text" defaultValue="grid" options={options} />
<p className="text-xs text-muted-foreground">text</p>
</div>
);
}
Custom
Assemble segments manually with the controlled parts.
"use client";import { useState } from "react";import { Segment } from "@/ui";const options = [ { label: "Day", value: "day" }, { label: "Week", value: "week" }, { label: "Month", value: "month" },];export default function Demo() { const [value, setValue] = useState("week"); const activeIndex = options.findIndex((option) => option.value === value); return ( <div role="radiogroup" className="relative grid w-72 grid-flow-col auto-cols-fr overflow-hidden rounded-md border border-border bg-muted" > <div aria-hidden className="absolute inset-y-0 bg-primary transition-[left] duration-200 ease-out" style={{ left: `${(activeIndex / options.length) * 100}%`, width: `${100 / options.length}%`, }} /> {options.map((option) => ( <Segment key={option.value} checked={value === option.value} onClick={() => setValue(option.value)} className="relative border-0 bg-transparent aria-checked:bg-transparent" > {option.label} </Segment> ))} </div> );}API Reference
High-level Components
Ready-to-use composite component.
SegmentGroup
| Prop | Type | Default | Description |
|---|---|---|---|
options | SegmentOptionConfig[] | - | Options data array |
value | string | - | Controlled selected value |
defaultValue | string | - | Default selected value (uncontrolled) |
onValueChange | (value: string) => void | - | Callback when the selected value changes |
disabled | boolean | false | Disable all options |
variant | "fill" | "text" | "fill" | Visual variant: fill highlights with a primary background, text only tints the selected text |
className | ClassNameValue | - | Custom class names, applied to the container |
itemClassName | ClassNameValue | - | Custom class names, applied to each segment |
Keyboard: roving-tabindex radio group — arrow keys move to and select the next / previous enabled option, Home / End jump to the ends, Enter / Space activate.
SegmentOptionConfig
| Field | Type | Default | Description |
|---|---|---|---|
label | string | - | Option display text |
value | string | - | Unique identifier value |
disabled | boolean | false | Disable the option |
className | ClassNameValue | - | Custom class names, overrides itemClassName |
Composable Components
Segment
A single segment part with radio semantics; it holds no internal state — checked must be provided from outside.
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | - | The segment content |
checked | boolean | false | Checked state, drives aria-checked and the checked styles |
variant | "fill" | "text" | "fill" | Visual variant: fill highlights with a primary background, text only tints the selected text |
className | ClassNameValue | - | Custom class names |
...props | React.ComponentProps<"button"> | - | Supports all native button props (except type), such as onClick, disabled |