SegmentedButton
Use SegmentedButton to arrange related controls in a single pill-shaped row.
React
Group
Use Group for independent action buttons with no shared selection state. Items
default to ghost.
<Box
_dark={{ bgColor: 'background.primary' }}
alignItems="flex-start"
bgColor="background.primaryInvert"
borderRadius="400"
display="flex"
p="500"
>
<SegmentedButton.Group>
<SegmentedButton.Item icon={iconPlus} label="Zoom in" onClick={() => {}} />
<SegmentedButton.Item
icon={iconMinus}
label="Zoom out"
onClick={() => {}}
/>
</SegmentedButton.Group>
</Box>Group variant
Pass variant on the group to set the track background color. Items are
unaffected—they stay ghost unless each item sets its own variant.
<Box
_dark={{ bgColor: 'background.primary' }}
alignItems="flex-start"
bgColor="background.primaryInvert"
borderRadius="400"
display="flex"
p="500"
>
<SegmentedButton.Group variant="primary">
<SegmentedButton.Item icon={iconPlus} label="Add" onClick={() => {}} />
<SegmentedButton.Item icon={iconGrip} label="Grid" onClick={() => {}} />
<SegmentedButton.Item icon={iconMinus} label="Remove" onClick={() => {}} />
</SegmentedButton.Group>
</Box>Group item variant
Pass variant on individual items to style them differently. Items without a
variant stay ghost.
<Box
_dark={{ bgColor: 'background.primary' }}
alignItems="flex-start"
bgColor="background.primaryInvert"
borderRadius="400"
display="flex"
p="500"
>
<SegmentedButton.Group>
<SegmentedButton.Item
icon={iconPlus}
label="Zoom in"
onClick={() => {}}
variant="primary"
/>
<SegmentedButton.Item
icon={iconMinus}
label="Zoom out"
onClick={() => {}}
variant="secondary"
/>
</SegmentedButton.Group>
</Box>Mixed icon and label
<Box
_dark={{ bgColor: 'background.primary' }}
alignItems="flex-start"
bgColor="background.primaryInvert"
borderRadius="400"
display="flex"
p="500"
>
<SegmentedButton.Group>
<SegmentedButton.Item
icon={iconPlus}
label="Add"
onClick={() => {}}
variant="primary"
/>
<SegmentedButton.Item onClick={() => {}} variant="secondary">
Reset
</SegmentedButton.Item>
<SegmentedButton.Item
icon={iconGrip}
label="Grid"
onClick={() => {}}
variant="secondary"
/>
</SegmentedButton.Group>
</Box>Image button
Place a custom element directly inside Group to render a non-standard
control—for example a circular image button. Match the item height with
boxSize="400" and borderRadius="full" so it lines up with the other buttons.
<Box
_dark={{ bgColor: 'background.primary' }}
alignItems="flex-start"
bgColor="background.primaryInvert"
borderRadius="400"
display="flex"
p="500"
>
<SegmentedButton.Group>
<SegmentedButton.Item icon={iconPlus} label="Zoom in" onClick={() => {}} />
<SegmentedButton.Item icon={iconGrip} label="Grid" onClick={() => {}} />
<Image
alt="Select cat"
borderRadius="full"
boxSize="400"
cursor="pointer"
flexShrink={0}
objectFit="cover"
onClick={() => {}}
role="button"
src="https://placecats.com/300/200"
tabIndex={0}
/>
</SegmentedButton.Group>
</Box>Sizes
Group accepts size="medium" (default), "small", or "xs".
<Box
_dark={{ bgColor: 'background.primary' }}
alignItems="flex-start"
bgColor="background.primaryInvert"
borderRadius="400"
display="flex"
p="500"
>
<Stack direction="column" spacing="300">
<SegmentedButton.Group size="medium">
<SegmentedButton.Item icon={iconGrip} label="Grid" onClick={() => {}} />
<SegmentedButton.Item
icon={iconCellPhone}
label="Phone"
onClick={() => {}}
/>
<SegmentedButton.Item
icon={iconMinus}
label="Remove"
onClick={() => {}}
/>
</SegmentedButton.Group>
<SegmentedButton.Group size="small">
<SegmentedButton.Item icon={iconGrip} label="Grid" onClick={() => {}} />
<SegmentedButton.Item
icon={iconCellPhone}
label="Phone"
onClick={() => {}}
/>
<SegmentedButton.Item
icon={iconMinus}
label="Remove"
onClick={() => {}}
/>
</SegmentedButton.Group>
<SegmentedButton.Group size="xs">
<SegmentedButton.Item icon={iconGrip} label="Grid" onClick={() => {}} />
<SegmentedButton.Item
icon={iconCellPhone}
label="Phone"
onClick={() => {}}
/>
<SegmentedButton.Item
icon={iconMinus}
label="Remove"
onClick={() => {}}
/>
</SegmentedButton.Group>
</Stack>
</Box>Color mode
Use colorMode="light" when placing the component on a dark surface.
<Stack alignItems="flex-start" bgColor="neutral.875" borderRadius="400" p="500">
<SegmentedButton.Group colorMode="light">
<SegmentedButton.Item icon={iconGrip} label="Grid" onClick={() => {}} />
<SegmentedButton.Item
icon={iconCellPhone}
label="Phone"
onClick={() => {}}
/>
<SegmentedButton.Item icon={iconMinus} label="Remove" onClick={() => {}} />
</SegmentedButton.Group>
</Stack>Dividers
Use hasDivider to render a vertical separator after the first item, splitting
off the leading control from the rest of the group. This is useful when a
SegmentedButton sits inline with other toolbar elements.
<Box
_dark={{ bgColor: 'background.primary' }}
alignItems="flex-start"
bgColor="background.primaryInvert"
borderRadius="400"
display="flex"
p="500"
>
<SegmentedButton.Group hasDivider>
<SegmentedButton.Item
icon={iconCellPhone}
label="Phone view"
onClick={() => {}}
/>
<SegmentedButton.Item icon={iconPlus} label="Zoom in" onClick={() => {}} />
<SegmentedButton.Item
icon={iconMinus}
label="Zoom out"
onClick={() => {}}
/>
<SegmentedButton.Item
icon={iconGrip}
label="Grid view"
onClick={() => {}}
/>
</SegmentedButton.Group>
</Box>Props
SegmentedButton.Group
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | SegmentedButton.Item elements | |
variant | 'primary' | 'secondary' | 'glass' | 'primary' | Sets the track background color; does not affect item styling |
size | 'medium' | 'small' | 'xs' | 'medium' | Size applied to every item in the group |
colorMode | 'light' | 'dark' | system | Force a color mode; defaults to the surrounding theme |
hasDivider | boolean | false | Render a divider after the first item (leading edge) |
hasShadow | boolean | false | Render the track with a drop shadow |
SegmentedButton.Item
| Prop | Type | Default | Description |
|---|---|---|---|
icon | IconType | Icon to render. When set, the item is icon-only and label is required for accessibility | |
label | string | Accessible label (required when icon is set) | |
children | ReactNode | Text content for a label item (use instead of icon) | |
variant | 'primary' | 'secondary' | 'glass' | 'ghost' | 'ghost' | Per-item button style; takes precedence over the group default |
onClick | () => void | Called when the item is pressed | |
isDisabled | boolean | false | Disables the item |