Skip to content

Segmented Control

A row of options with a selected fill that slides between them.

From the Nitip template — see it in context

Showing projects as grid

Installation

$ npx shadcn@latest add https://framebrick.co/r/segmented-control.json

Usage

import { SegmentedControl } from "@/components/ui/segmented-control";

const [view, setView] = useState("grid");

<SegmentedControl
  label="Project view"
  options={[{ value: "grid", label: "Grid" }, { value: "list", label: "List" }]}
  value={view}
  onValueChange={setView}
/>

Props

PropTypeDefaultDescription
options{ value, label, disabled? }[]—The choices, in order.
labelstring—Accessible name of the group.
valuestring—Selected value (controlled).
defaultValuestringfirst optionInitial value (uncontrolled).
onValueChange(value) => void—Called when the selection changes.
size"sm" | "md""md"Compact or regular.
  • Keyboard: arrow keys, Home and End move the selection (radio group).

AI prompt

Paste into v0, Lovable, Bolt or Claude to rebuild this component in your own project.

Create a React + Tailwind CSS + Motion (motion/react) component called SegmentedControl.
- Look like the shadcn/ui TabsList: bg-muted, rounded-lg, 3px padding, h-9; options text-sm font-medium px-3,
  unselected text-muted-foreground (hover text-foreground).
- The selected option has a bg-background rounded-md shadow-sm fill behind its label that slides between options with a
  shared layoutId (spring bounce 0.15, duration 0.45s); its text is text-foreground.
- Props: options {value,label,disabled?}[], value / defaultValue / onValueChange (controlled or not), label (aria-label), size sm|md.
- Accessibility: role radiogroup, each option role radio with aria-checked, roving tabindex,
  arrow keys / Home / End move and select. Visible focus ring.

Be the first to know

Get new templates and components first

One short email when we release a template or a free component. No spam — unsubscribe anytime.

We use your email only for Framebrick updates. Privacy policy