AngleSlider

Pick angle value between 0 and 360

PackageIcon

Usage

Use the AngleSlider component to pick an angle value between 0 and 360:

0
Size
Thumb size
import { AngleSlider } from '@mantine/core';

function Demo() {
  return <AngleSlider aria-label="Angle slider" size={60} thumbSize={8} />;
}

Controlled

The AngleSlider value is a number between 0 and 360.

import { useState } from 'react';
import { AngleSlider } from '@mantine/core';

function Demo() {
  const [value, setValue] = useState(180);
  return <AngleSlider value={value} onChange={setValue} />;
}

AngleSlider with uncontrolled forms

AngleSlider can be used with uncontrolled forms. Set the name attribute to include slider value in FormData object on form submission. To control initial value in uncontrolled forms, use defaultValue prop.

Props for usage with uncontrolled forms:

  • name – name attribute passed to the hidden input
  • hiddenInputProps – additional props passed to the hidden input

Example of uncontrolled AngleSlider with FormData:

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

export function WithFormData() {
  return (
    <form
      onSubmit={(event) => {
        event.preventDefault();
        const formData = new FormData(event.currentTarget);
        console.log('Checkbox group value:', formData.get('angle'));
      }}
    >
      <AngleSlider name="angle" defaultValue={120} />
      <button type="submit">Submit</button>
    </form>
  );
}

formatLabel

Use the formatLabel prop to change the angle label format. It accepts a function that takes the angle value and returns a React node:

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

function Demo() {
  return <AngleSlider aria-label="Angle slider" formatLabel={(value) => `${value}°`} />;
}

Marks

Set the marks prop to display marks on the slider. A mark is an object with a value (required, number between 0 and 360) and label (optional, React node). To restrict selection to marks only, set the restrictToMarks prop:

import { AngleSlider, Group } from '@mantine/core';

function Demo() {
  return (
    <Group p="lg" gap={50}>
      <AngleSlider
        aria-label="Angle slider"
        formatLabel={(value) => `${value}°`}
        size={100}
        restrictToMarks
        marks={[
          { value: 0 },
          { value: 45 },
          { value: 90 },
          { value: 135 },
          { value: 180 },
          { value: 225 },
          { value: 270 },
          { value: 315 },
        ]}
      />

      <AngleSlider
        aria-label="Angle slider"
        formatLabel={(value) => `${value}°`}
        size={100}
        marks={[
          { value: 0, label: '0°' },
          { value: 45, label: '45°' },
          { value: 90, label: '90°' },
          { value: 135, label: '135°' },
          { value: 180, label: '180°' },
          { value: 225, label: '225°' },
          { value: 270, label: '270°' },
          { value: 315, label: '315°' },
        ]}
      />
    </Group>
  );
}

onChangeEnd

The onChangeEnd callback fires when the user stops dragging the slider or changes its value with the keyboard. Use it as a debounced callback to prevent frequent updates.

0

Current value: 0

End value: 0

import { useState } from 'react';
import { AngleSlider, Text } from '@mantine/core';

function Demo() {
  const [value, setValue] = useState(0);
  const [endValue, setEndValue] = useState(0);

  return (
    <>
      <AngleSlider value={value} onChange={setValue} onChangeEnd={setEndValue} />
      <Text mt="md">Current value: {value}</Text>
      <Text>End value: {endValue}</Text>
    </>
  );
}

disabled

The disabled prop disables the component and prevents user interaction:

0
import { AngleSlider } from '@mantine/core';

function Demo() {
  return <AngleSlider aria-label="Angle slider" disabled />;
}

Accessibility

To make the component accessible for screen readers, set the aria-label prop:

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

function Demo() {
  return <AngleSlider aria-label="Gradient angle" />;
}

Keyboard interactions when the component is focused:

KeyDescription
ArrowDownDecreases value by step
ArrowLeftDecreases value by step
ArrowUpIncreases value by step
ArrowRightIncreases value by step
HomeSets value to 0
EndSets value to 359

Based on use-radial-move

AngleSlider is based on the use-radial-move hook. You can build a custom radial slider using this hook if you need more control over the component's behavior.

115°
import { useState } from 'react';
import { Box } from '@mantine/core';
import { useRadialMove } from '@mantine/hooks';
import classes from './Demo.module.css';

function Demo() {
  const [value, setValue] = useState(115);
  const { ref } = useRadialMove(setValue);

  return (
    <Box className={classes.root} ref={ref} style={{ '--angle': `${value}deg` }}>
      <div className={classes.value}>{value}°</div>
      <div className={classes.thumb} />
    </Box>
  );
}