SegmentedControl

Horizontal control with multiple segments
Import

Usage

import { SegmentedControl } from '@mantine/core';
function Demo() {
return (
<SegmentedControl
data={[
{ label: 'React', value: 'react' },
{ label: 'Angular', value: 'ng' },
{ label: 'Vue', value: 'vue' },
{ label: 'Svelte', value: 'svelte' },
]}
/>
);
}

Controlled

import { useState } from 'react';
import { SegmentedControl } from '@mantine/core';
function Demo() {
const [value, setValue] = useState('react');
return (
<SegmentedControl
value={value}
onChange={setValue}
data={[
{ label: 'React', value: 'react' },
{ label: 'Angular', value: 'ng' },
{ label: 'Vue', value: 'vue' },
{ label: 'Svelte', value: 'svelte' },
]}
/>
);
}

Data prop

SegmentedControl support two different data formats:

  1. An array of strings – use when you do not need to customize item component or display label different than value
  2. An array of objects with required value and label properties and any other additional properties
// Data as an array of strings, will be mapped to
// [
// { value: 'React', label: 'React' },
// { value: 'Angular', label: 'Angular' },
// { value: 'Svelte', label: 'Svelte' },
// { value: 'Vue', label: 'Vue' },
// ]
<SegmentedControl data={['React', 'Angular', 'Svelte', 'Vue']} />
// Data as an array of objects:
<SegmentedControl data={[
{ value: 'React', label: 'React' },
{ value: 'Angular', label: 'Angular' },
{ value: 'Svelte', label: 'Svelte' },
{ value: 'Vue', label: 'Vue' },
]} />

Disabled

Disabled control
Disabled option
import { SegmentedControl } from '@mantine/core';
function Demo() {
return (
<>
{/* Disabled control */}
<SegmentedControl disabled={true} />
{/* Disabled option */}
<SegmentedControl
data={[
{ value: 'preview', label: 'Preview', disabled: true },
{ value: 'code', label: 'Code' },
{ value: 'export', label: 'Export' },
]}
/>
</>
);
}

React node as label

import { Center, SegmentedControl, Box } from '@mantine/core';
import { IconEye, IconCode, IconExternalLink } from '@tabler/icons';
function Demo() {
return (
<SegmentedControl
data={[
{
value: 'preview',
label: (
<Center>
<IconEye size={16} />
<Box ml={10}>Preview</Box>
</Center>
),
},
{
value: 'code',
label: (
<Center>
<IconCode size={16} />
<Box ml={10}>Code</Box>
</Center>
),
},
{
value: 'export',
label: (
<Center>
<IconExternalLink size={16} />
<Box ml={10}>Export</Box>
</Center>
),
},
]}
/>
);
}

Full width and orientation

By default, SegmentedControl will take only the amount of space that is required to render elements. Set fullWidth prop to make it block and take 100% width of its container.

Orientation
import { SegmentedControl } from '@mantine/core';
function Demo() {
return <SegmentedControl />;
}

Sizes

Component supports 5 sizes: xs, sm, md, lg, xl. Size controls font-size and padding properties.

<SegmentedControl size="sm" />

SegmentedControl sizes from xs to xl:

Radius

xs, sm, md, lg, xl radius values are defined in theme.radius. Alternatively, you can use a number to set radius in px:

<SegmentedControl radius="lg" /> // -> theme predefined large radius
<SegmentedControl radius={20} /> // -> { borderRadius: '20px' }
<SegmentedControl radius={0} /> // -> { borderRadius: 0 }

Default theme radius values from xs to xl with lg size:

Color

By default, segmented control uses theme.white with shadow in light color scheme and theme.colors.dark[6] background color for active element. You can choose any color defined in theme.colors in case you need colored variant:

Color
import { SegmentedControl } from '@mantine/core';
function Demo() {
return <SegmentedControl color="blue" />;
}

Transitions

Change transition properties with:

  • transitionDuration – all transitions duration in ms (ignored if user prefers to reduce motion)
  • transitionTimingFunction – defaults to theme.transitionTimingFunction
No transitions
500ms linear transition
import { SegmentedControl } from '@mantine/core';
function Demo() {
return (
<>
{/* No transitions */}
<SegmentedControl transitionDuration={0} />
{/* 500ms linear transition */}
<SegmentedControl
transitionDuration={500}
transitionTimingFunction="linear"
/>
</>
);
}

Accessibility and usability

SegmentedControl uses radio inputs under the hood, it is accessible by default with no extra steps required. Component support the same keyboard events as a regular radio group.

SegmentedControl component props

NameTypeDescription
color
MantineColor
Active control color from theme.colors, defaults to white in light color scheme and theme.colors.dark[9] in dark
data *
string[] | SegmentedControlItem[]
Data based on which controls are rendered
defaultValue
string
Default value for uncontrolled component
disabled
boolean
Disabled input state
fullWidth
boolean
True if component should have 100% width
name
string
Name of the radio group, default to random id
onChange
(value: string) => void
Called when value changes
orientation
"horizontal" | "vertical"
Display Vertically
radius
number | "xs" | "sm" | "md" | "lg" | "xl"
Border-radius from theme or number to set border-radius in px
size
"xs" | "sm" | "md" | "lg" | "xl"
Controls font-size, paddings and height
transitionDuration
number
Transition duration in ms, set to 0 to turn off transitions
transitionTimingFunction
string
Transition timing function for all transitions, defaults to theme.transitionTimingFunction
value
string
Current selected value

SegmentedControl component Styles API

NameStatic selectorDescription
root.mantine-SegmentedControl-rootRoot element
label.mantine-SegmentedControl-labelInput label element
labelActive.mantine-SegmentedControl-labelActiveLabel of active element
input.mantine-SegmentedControl-inputRadio input (visually hidden)
control.mantine-SegmentedControl-controlControl wrapper, contains input and label
controlActive.mantine-SegmentedControl-controlActiveActive control wrapper
active.mantine-SegmentedControl-activeElement which indicates current active item, positioned below controls
disabled.mantine-SegmentedControl-disabledDisabled item modifier