Built on Vercel’s UI SDK 0.1.0-beta.2. Its API may change.
Segmented control
A segmented control on Vercel's UI SDK with a sliding indicator, three sizes, icon-only items, full width, vertical layout and radio-group keyboard.
- Form components
- 2 parts
- 10 examples
@ui-sdk/core@ui-sdk/react
pnpm dlx shadcn@latest add https://hextaui.com/r/ui-sdk-segmented-control.jsonAdds the component, the HextaUI theme tokens and any HextaUI components it depends on.
Add the theme tokens to your global CSS, if you haven’t yet.
Install the dependencies.
pnpm add @ui-sdk/react@0.1.0-beta.2 @ui-sdk/core@0.1.0-beta.2 cnCopy and paste the following code into your project.
components/ui/ui-sdk-segmented-control.tsx Update the import paths to match your project setup.
UI SDK adds a little CSS of its own in a cascade layer named ui-sdk. Declare that layer at the top of your global stylesheet, above the Tailwind import, so your classes win over it.
A segmented control switches between a few views or settings. It works like a radio group, with one value and one tab stop, and the indicator behind the checked item slides to the next choice. Name it with aria-label or aria-labelledby. UI SDK marks it experimental in 0.1.0-beta.2.
The control draws its own indicator, so you only add items.
size is sm, default or lg. Items grow on touch screens.
An item holding only an icon turns square. Name it with aria-label.
Give the control w-full and the items share its width.
orientation="vertical" stacks the items. Arrow keys on both axes still move between them.
disabled on the control turns it all off and submits nothing. On one item, the arrow keys skip it.
Pass value and update it in onValueChange. A controller from createSegmentedControlController() checks an item from anywhere.
Each item holds a hidden native radio, so name submits the checked value, required waits for a choice, and a reset returns to the default.
A read-only control keeps its value and still submits. Arrow keys move focus without checking anything.
The items run from the right, and the indicator follows them.
| Key | Action |
|---|---|
| Tab | Moves into the control, onto the checked item or the first enabled one. |
| ←→↑↓ | Move to the next or previous item and check it, skipping disabled ones. They wrap unless loop is false. |
| Space | Checks the focused item. |
| Enter | Submits its form. |
The control is a radio group and each item a radio, so screen readers announce the choice and its position. The indicator is presentational and skipped by screen readers.
The indicator only slides once the page is interactive, so it never animates in on load, and it doesn’t slide at all when reduced motion is on. In forced colors, the checked item keeps a visible border.
Each part wraps the UI SDK part of the same name and accepts all of its props, including render and a className that can be a function of the part’s state.
| Prop | Type | Default |
|---|---|---|
value | T | null | – |
defaultValue | T | null | – |
onValueChange | (value: T | null, details) => void | – |
size | "sm" | "default" | "lg" | "default" |
orientation | "horizontal" | "vertical" | "horizontal" |
loop | boolean | true |
disabled | boolean | false |
readOnly | boolean | false |
required | boolean | false |
name | string | – |
form | string | – |
controllerFrom createSegmentedControlController(). | SegmentedControlController | – |
render | ReactElement | (props, state) => ReactElement | – |
| Attribute | Description |
|---|---|
data-slot="segmented-control" | Target the segmented control in CSS. |
data-size | The size: sm, default or lg. |
data-orientation | horizontal or vertical. |
data-disabled | Present when disabled. |
data-readonly | Present when read-only. |
data-required | Present when required. |
| Prop | Type | Default |
|---|---|---|
value | string | – |
disabled | boolean | false |
render | ReactElement | (props, state) => ReactElement | – |
| Attribute | Description |
|---|---|
data-slot="segmented-control-item" | Target an item in CSS. |
data-checked | Present on the checked item. |
data-unchecked | Present on the other items. |
data-icon-only | Present when the item holds only an icon. |
data-disabled | Present when disabled. |
- CalendarA date grid for single, range and multiple selection, with sliding months, range previews and touch-sized days.
- CheckboxA checkbox whose check draws in, with indeterminate parents, groups and labels that share its hover.
- ComboboxA filterable select with chips, groups and async results, in a popup that resizes as you type.
- Date pickerA button that opens a calendar in a popover, or a bottom sheet on phones, for single dates and ranges.
- FieldLabels, descriptions and errors wired to their control, with validation states and layouts for forms.
- InputA text input with three sizes, invalid and read-only states, native validation styling and a 16px touch font so phones never zoom in.