Segmented control
Segmented control whose selection pill is driven by two springs, so it stretches between options and recolours labels exactly where it covers them.
Playground
Change a prop and the component re-renders. Props marked remounts set an initial value, so the component starts over.
<UiSegmented
options={[
"Day",
"Week",
"Month",
"Year"
]}
defaultValue="Week"
label="Options"
/>Installation
pnpm dlx shadcn@latest add @lumesec/ui-segmentedFirst timeRegister the @lumesec registry once, or install by URL+
Adds @lumesec to your components.json:
pnpm dlx shadcn@latest registry add @lumesec=https://elements.lumesec.ai/r/{name}.jsonOr skip the setup and install by URL:
npx shadcn@latest add https://elements.lumesec.ai/r/ui-segmented.jsonUsage
import { UiSegmented } from "@/components/lumesec/ui-segmented";
export function Example() {
return <UiSegmented options={["Day", "Week", "Month", "Year"]} defaultValue="Week" label="Range" />;
}Behaviour
Two springs drive the selection pill: the leading edge snaps ahead, the trailing edge catches up, so it stretches and squashes on the way. Labels change colour exactly where the pill covers them.
API reference
Props
Also accepts every prop of <div> (React.ComponentProps<"div">), spread onto the root element.
valueTypestringControlled selected label. Use with onValueChange. A label that is not in options selects the first option.
defaultValueTypestringDefaultfirst optionInitially selected label when uncontrolled.
optionsTypereadonly string[]Default["Chat", "Code", "Design"]Option labels. Each label is also the option's value.
labelTypestringDefault"Options"Accessible name of the radio group.
onValueChangeType(value: string) => voidCalled when the user picks a different option by click or arrow key. Changing value from outside does not call it.
Ref
ref points at the root HTMLDivElement.
Keyboard
| Keys | Action |
|---|---|
| ArrowRight / ArrowDown | Select and focus the next option, wrapping at the end. |
| ArrowLeft / ArrowUp | Select and focus the previous option, wrapping at the start. |
Accessibility
- The root has
role="radiogroup"and anaria-labelfromlabel; options are native buttons withrole="radio"andaria-checked. - Roving tabindex: only the selected option is in the tab order.
- The pill and a second, recoloured label layer used for the pill effect are
aria-hidden. - Reduced motion: the pill jumps to the selected option without the spring stretch.
Theming
Styled with Tailwind classes on your shadcn theme tokens, so light and dark follow your theme. The accent comes from --lumesec. See Theming.
This component reads --muted, --card, --foreground, --muted-foreground and --lumesec.
Notes
- The control is as wide as its options. Give it a width (
className="w-full") to stretch the track; the options stay at the start. - Options carry
data-state="checked"ordata-state="unchecked". - Changing
optionssnaps the pill to the selected option without animating.
Related
Was this page helpful?