Segment
freeSegment switches between a few related options from one compact control.
Preview
Dark
import Segment from '@/components/ui/Segment';
export default function UsageDemo() {
return (
<Segment defaultValue="board">
<Segment.Item value="list">List</Segment.Item>
<Segment.Item value="board">Board</Segment.Item>
<Segment.Item value="calendar">Calendar</Segment.Item>
</Segment>
);
}Installation
Add this component with the NateUI CLI.
npx nateui@latest add SegmentExamples
Basic
Preview
Dark
import Segment from '@/components/ui/Segment';
export default function BasicDemo() {
return (
<Segment>
<Segment.Item value="left">Left</Segment.Item>
<Segment.Item value="center">Center</Segment.Item>
<Segment.Item value="right">Right</Segment.Item>
</Segment>
);
}Size
Preview
Dark
import Segment from '@/components/ui/Segment';
export default function SizeDemo() {
return (
<div className="flex flex-col items-start gap-8">
<Segment size="sm" defaultValue="center">
<Segment.Item value="left">Left</Segment.Item>
<Segment.Item value="center">Center</Segment.Item>
<Segment.Item value="right">Right</Segment.Item>
</Segment>
<Segment size="md" defaultValue="center">
<Segment.Item value="left">Left</Segment.Item>
<Segment.Item value="center">Center</Segment.Item>
<Segment.Item value="right">Right</Segment.Item>
</Segment>
<Segment size="lg" defaultValue="center">
<Segment.Item value="left">Left</Segment.Item>
<Segment.Item value="center">Center</Segment.Item>
<Segment.Item value="right">Right</Segment.Item>
</Segment>
</div>
);
}Multiple Selection
Preview
Dark
import Segment from '@/components/ui/Segment';
export default function MultipleDemo() {
return (
<Segment<'multiple'>
selectionType="multiple"
defaultValue={['bold', 'underline']}
>
<Segment.Item value="bold">Bold</Segment.Item>
<Segment.Item value="italic">Italic</Segment.Item>
<Segment.Item value="underline">Underline</Segment.Item>
</Segment>
);
}With Icons
Preview
Dark
import Segment from '@/components/ui/Segment';
import {
PiTextAlignCenter,
PiTextAlignLeft,
PiTextAlignRight,
} from 'react-icons/pi'
export default function WithIconsDemo() {
return (
<Segment defaultValue="left">
<Segment.Item value="left" className="gap-2">
<PiTextAlignLeft />
<span>Left</span>
</Segment.Item>
<Segment.Item value="center" className="gap-2">
<PiTextAlignCenter />
<span>Center</span>
</Segment.Item>
<Segment.Item value="right" className="gap-2">
<PiTextAlignRight />
<span>Right</span>
</Segment.Item>
</Segment>
);
}Disabled
Preview
Dark
import Segment from '@/components/ui/Segment';
export default function DisabledDemo() {
return (
<Segment defaultValue="left">
<Segment.Item value="left">Left</Segment.Item>
<Segment.Item value="center" disabled>
Center
</Segment.Item>
<Segment.Item value="right">Right</Segment.Item>
</Segment>
);
}Controlled
Preview
Dark
Active view: board
import { useState } from 'react';
import Segment from '@/components/ui/Segment';
export default function ControlledDemo() {
const [view, setView] = useState('board');
return (
<div className="flex flex-col items-start gap-4">
<Segment value={view} onChange={(value) => setView(value)}>
<Segment.Item value="list">List</Segment.Item>
<Segment.Item value="board">Board</Segment.Item>
<Segment.Item value="calendar">Calendar</Segment.Item>
</Segment>
<div className="text-sm text-muted-foreground">
Active view:{' '}
<span className="font-semibold text-foreground">
{view || 'none'}
</span>
</div>
</div>
);
}API
Segment is a compound control: the Segment root holds selection state and renders the sliding indicator, while each Segment.Item is one selectable option. In single mode selecting the active item again clears the selection; in multiple mode each item toggles independently.
Segment
| Prop | Description | Type | Default |
|---|---|---|---|
selectionType | Whether one item or several items can be active at once. | 'single' | 'multiple' | 'single' |
value | Active value in controlled mode. A string for single selection, an array for multiple. | SegmentValue | - |
defaultValue | Initial value when uncontrolled. A string for single selection, an array for multiple. | SegmentValue | - |
onChange | Fires with the new value whenever the selection changes. | (value: SegmentValue) => void | - |
size | Control size applied to every item, unless an item sets its own. | ControlSize | 'md' |
className | Class names for the root element. | string | - |
ref | Ref forwarded to the root element. | Ref<HTMLDivElement> | - |
...nativeProps | Native props for the root div (except onChange). | Omit<ComponentProps<'div'>, 'onChange'> | - |
Segment.Item
| Prop | Description | Type | Default |
|---|---|---|---|
value | Unique value that identifies this item within the group. | string | - |
children | Item content, or a render function that receives the item state for a custom look. | ReactNode | ((params: SegmentItemRenderProps) => ReactNode) | - |
disabled | Prevent this item from being selected and dim it. | boolean | false |
size | Control size for this item, overriding the group size. | ControlSize | - |
className | Class names for the item button. | string | - |
ref | Ref forwarded to the item button. | Ref<HTMLButtonElement> | - |
...nativeProps | Native button props (except children). | Omit<ComponentPropsWithRef<'button'>, 'children'> | - |
Types
type ControlSize = 'sm' | 'md' | 'lg'
// string for single selection, string[] for multiple selection
type SegmentValue = string | string[]
type SegmentItemRenderProps = {
active: boolean
disabled: boolean
value: string
onSegmentItemClick: () => void
}