SegmentedControl

Horizontal control made of multiple segments, alternative to RadioGroup
Import

Usage

SegmentedControl is usually used as an alternative to:

  • Tabs to switch views
  • RadioGroup to capture user feedback limited to certain options
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 { Eye, Code, ExternalLink } from 'tabler-icons-react';
function Demo() {
return (
<SegmentedControl
data={[
{
value: 'preview',
label: (
<Center>
<Eye size={16} />
<Box ml={10}>Preview</Box>
</Center>
),
},
{
value: 'code',
label: (
<Center>
<Code size={16} />
<Box ml={10}>Code</Box>
</Center>
),
},
{
value: 'export',
label: (
<Center>
<ExternalLink 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.