SegmentedControl
Usage
SegmentedControl is usually used as an alternative to:
- Tabs to switch views
- RadioGroup to capture user feedback limited to certain options
<SegmentedControldata={[{ 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 (<SegmentedControlvalue={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:
- An array of strings – use when you do not need to customize item component or display
label
different thanvalue
- An array of objects with required
value
andlabel
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' },]} />
Full width
By default SegmentedControl is inline and will take only the amount of space which is required to render elements.
Set fullWidth
prop to make it block and take 100% width of its container:
// By default component is inline<SegmentedControl />// Set fullWidth to make it block and take 100% of width<SegmentedControl fullWidth />
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:
<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<SegmentedControl transitionDuration={0} />// 500ms linear transition<SegmentedControltransitionDuration={500}transitionTimingFunction="linear"/>
Server side rendering
Component uses use-id hook to generate random id which is used to bind inputs to labels. If you want to avoid id mismatch during hydration provide static name value:
// -> oh-oh, id on elements is mismatched, won't break anything, but shows nasty error<SegmentedControl />// -> ok, inputs ids are static and will match during hydration<SegmentedControl name="my-control" />
Resize observer
SegmentedControl uses ResizeObserver to calculate active control background position. Position changes on container width change with 50ms debounce to avoid performance issue.
ResizeObserver is supported by all modern browsers, if you encounter any errors with browser compatibility use polyfill:
import ResizeObserver from 'resize-observer-polyfill';window.ResizeObserver = ResizeObserver;
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 regular radio group.