SegmentedControl

A linear set of two or more segments

Import

Usage

Orientation
Size
Radius
import { SegmentedControl } from '@mantine/core';

function Demo() {
  return <SegmentedControl data={['React', 'Angular', 'Vue']} />;
}

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 – used when value and label are the same
  2. An array of objects – used when value and label are different
import { SegmentedControl } from '@mantine/core';

function ArrayOfStrings() {
  return <SegmentedControl data={['React', 'Angular', 'Svelte', 'Vue']} />;
}

function ArrayOfObjects() {
  return (
    <SegmentedControl
      data={[
        { value: 'React', label: 'React' },
        { value: 'Angular', label: 'Angular' },
        { value: 'Svelte', label: 'Svelte' },
        { value: 'Vue', label: 'Vue' },
      ]}
    />
  );
}

Disabled

To disable SegmentedControl item, use array of objects data format and set disabled: true on the item that you want to disable. To disable the entire component, use disabled prop.

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

You can use any React node as label:

import { Center, SegmentedControl, Box, rem } from '@mantine/core';
import { IconEye, IconCode, IconExternalLink } from '@tabler/icons-react';

function Demo() {
  return (
    <SegmentedControl
      data={[
        {
          value: 'preview',
          label: (
            <Center>
              <IconEye style={{ width: rem(16), height: rem(16) }} />
              <Box ml={10}>Preview</Box>
            </Center>
          ),
        },
        {
          value: 'code',
          label: (
            <Center>
              <IconCode style={{ width: rem(16), height: rem(16) }} />
              <Box ml={10}>Code</Box>
            </Center>
          ),
        },
        {
          value: 'export',
          label: (
            <Center>
              <IconExternalLink style={{ width: rem(16), height: rem(16) }} />
              <Box ml={10}>Export</Box>
            </Center>
          ),
        },
      ]}
    />
  );
}

Color

By default, SegmentedControl uses theme.white with shadow in light color scheme and var(--mantine-color-dark-6) background color for indicator. Set color prop to change indicator background-color:

Color
import { SegmentedControl } from '@mantine/core';

function Demo() {
  return <SegmentedControl color="blue" data={['React', 'Angular', 'Vue', 'Svelte']} />;
}

Transitions

Change transition properties with:

  • transitionDuration – all transitions duration in ms, 200 by default
  • transitionTimingFunction – all transitions timing function, ease by default

No transitions

500ms linear transition

import { SegmentedControl } from '@mantine/core';

function Demo() {
  return (
    <>
      <Text size="sm" fw={500} mt={3}>
        No transitions
      </Text>
      <SegmentedControl data={['React', 'Angular', 'Vue', 'Svelte']} transitionDuration={0} />

      <Text size="sm" fw={500} mt="md">
        500ms linear transition
      </Text>
      <SegmentedControl
        data={['React', 'Angular', 'Vue', 'Svelte']}
        transitionDuration={500}
        transitionTimingFunction="linear"
      />
    </>
  );
}

readOnly

Set readOnly prop to prevent value from being changed:

import { SegmentedControl } from '@mantine/core';

function Demo() {
  return <SegmentedControl readOnly defaultValue="Angular" data={['React', 'Angular', 'Vue']} />;
}

Styles API

SegmentedControl supports Styles API, you can add styles to any inner element of the component withclassNames prop. Follow Styles API documentation to learn more.

Component Styles API

Hover over selectors to highlight corresponding elements

/*
 * Hover over selectors to apply outline styles
 *
 */

Accessibility and usability

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

In case you do not have text in labels (for example, when you want to use SegmentedControl with icons only), use VisuallyHidden to make component accessible:

import { SegmentedControl, VisuallyHidden, rem } from '@mantine/core';
import { IconEye, IconCode, IconExternalLink } from '@tabler/icons-react';

function Demo() {
  const iconProps = {
    style: { width: rem(20), height: rem(20), display: 'block' },
    stroke: 1.5,
  };

  return (
    <SegmentedControl
      data={[
        {
          value: 'preview',
          label: (
            <>
              <IconEye {...iconProps} />
              <VisuallyHidden>Preview</VisuallyHidden>
            </>
          ),
        },
        {
          value: 'code',
          label: (
            <>
              <IconCode {...iconProps} />
              <VisuallyHidden>Code</VisuallyHidden>
            </>
          ),
        },
        {
          value: 'export',
          label: (
            <>
              <IconExternalLink {...iconProps} />
              <VisuallyHidden>Export</VisuallyHidden>
            </>
          ),
        },
      ]}
    />
  );
}