RangeSlider

RangeSlider

두 개의 썸으로 값 범위를 선택하는 슬라이더 컴포넌트예요.

출처: 문서

본문

사용법 (Usage)

RangeSlider로 값 범위를 선택해요. color, size, radius, label 관련 prop을 지원해요.

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

function Demo() {
  return <RangeSlider defaultValue={[20, 80]} />;
}

제어 방식 (Controlled)

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

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

비제어 방식 (Uncontrolled)

RangeSlider은 네이티브 인풋 요소와 같은 방식으로 비제어 폼과 함께 사용할 수 있어요. 폼 제출 시 FormData 객체에 범위 슬라이더 값을 포함하려면 name 속성을 설정해요. 비제어 폼에서 초기 값을 제어하려면 defaultValue prop을 사용해요.

FormData와 함께 비제어 RangeSlider을 사용하는 예시:

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

function Demo() {
  return (
    <form
      onSubmit={(event) => {
        event.preventDefault();
        const formData = new FormData(event.currentTarget);
        console.log('Range slider value:', formData.get('range'));
      }}
    >
      <RangeSlider name="range" />
      <button type="submit">Submit</button>
    </form>
  );
}

비활성 (Disabled)

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

function Demo() {
  return <RangeSlider defaultValue={[20, 80]} disabled />;
}

라벨 제어 (Control label)

라벨 동작과 모양을 바꾸려면 다음 prop을 설정해요.

  • label – 포맷터 함수, 값 인자를 받고, 라벨을 비활성화하려면 null 설정, 기본값은 f => f
  • labelAlwaysOn – true면 라벨이 항상 표시되고, 기본적으로는 사용자가 드래그할 때만 보여요
  • labelTransitionProps – Transition 컴포넌트에 전달되는 prop, 라벨 애니메이션을 커스터마이즈하는 데 사용
import { RangeSlider, Text } from '@mantine/core';

function Demo() {
  return (
    <>
      <Text>No label</Text>
      <RangeSlider min={0} max={100} label={null} defaultValue={[20, 80]} />

      <Text>Formatted label</Text>
      <RangeSlider min={0} max={100} label={(value) => `${value} °C`} defaultValue={[20, 80]} />

      <Text>Label always visible</Text>
      <RangeSlider min={0} max={100} labelAlwaysOn defaultValue={[20, 80]} />

      <Text>Custom label transition</Text>
      <RangeSlider min={0} max={100} labelTransitionProps={{ transition: 'skew-up' }} defaultValue={[20, 80]} />
    </>
  );
}

min, max와 step

import { RangeSlider, Text } from '@mantine/core';

const marks = [{ value: 0 }, { value: 25 }, { value: 50 }, { value: 75 }, { value: 100 }];

function Demo() {
  return (
    <>
      <Text>Decimal step</Text>
      <RangeSlider min={0} max={1} step={0.1} defaultValue={[0.2, 0.8]} />

      <Text>Step matched with marks</Text>
      <RangeSlider min={0} max={100} step={25} marks={marks} defaultValue={[25, 75]} />
    </>
  );
}

도메인 (Domain)

기본적으로 min과 max 값이 가능한 값의 범위를 정의해요. domain prop을 사용하면 min과 max 값과 독립적으로 가능한 값의 범위를 설정할 수 있어요.

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

function Demo() {
  return <RangeSlider min={10} max={90} domain={[0, 100]} defaultValue={[20, 80]} />;
}

소수 값 (Decimal values)

RangeSlider을 소수 값과 함께 사용하려면 min, max, step prop을 설정해요.

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

function Demo() {
  return <RangeSlider min={0} max={1} step={0.1} defaultValue={[0.2, 0.8]} />;
}

minRange

minRange prop으로 RangeSlider에서 from과 to 값 사이의 최소 범위를 제어할 수 있어요. 기본값은 10이에요. 이는 썸이 최소한 지정된 거리만큼 떨어져 있어야 함을 보장해요.

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

function Demo() {
  const [value, setValue] = useState([30, 60]);

  return (
    <>
      <Text size="sm">Minimum range: 20 (thumbs must be at least 20 units apart)</Text>
      <RangeSlider minRange={20} value={value} onChange={setValue} />
      <Text size="sm">Value: [{value[0]}, {value[1]}] - Range: {value[1] - value[0]}</Text>
    </>
  );
}

maxRange

maxRange prop으로 from과 to 값 사이의 최대 범위를 제어할 수 있어요. 이는 선택이 얼마나 넓어질 수 있는지를 제한해요. 기본적으로 maxRange는 Infinity로 설정돼요.

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

function Demo() {
  const [value, setValue] = useState([20, 80]);

  return (
    <>
      <Text size="sm">Maximum range: 50 (selection cannot be wider than 50 units)</Text>
      <RangeSlider maxRange={50} value={value} onChange={setValue} />
      <Text size="sm">Value: [{value[0]}, {value[1]}] - Range: {value[1] - value[0]}</Text>
    </>
  );
}

pushOnOverlap

pushOnOverlap prop은 썸이 겹칠 때 서로 밀어야 할지 제어해요. 기본적으로 pushOnOverlap은 true예요. 이 동작을 비활성화하려면 false로 설정해요.

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

function Demo() {
  return <RangeSlider pushOnOverlap={false} defaultValue={[50, 50]} />;
}

마크 (Marks)

marks prop을 객체 배열로 설정하면 슬라이더에 원하는 수의 마크를 추가할 수 있어요.

const marks = [
  { value: 20 }, // -> 슬라이더 트랙에 마크 표시
  { value: 40, label: '40%' }, // -> 슬라이더 트랙 아래에 마크 라벨 추가
];

마크 값은 너비가 아니라 슬라이더 값에 상대적이에요.

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

function Demo() {
  return (
    <RangeSlider
      defaultValue={[20, 80]}
      marks={[
        { value: 20, label: '20%' },
        { value: 50, label: '50%' },
        { value: 80, label: '80%' },
      ]}
    />
  );
}

마크로 선택 제한 (Restrict selection to marks)

restrictToMarks prop으로 슬라이더 값을 마크로만 제한할 수 있어요. 이 경우 step prop은 무시돼요.

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

function Demo() {
  return (
    <RangeSlider
      defaultValue={[20, 80]}
      restrictToMarks
      marks={[{ value: 20 }, { value: 50 }, { value: 80 }]}
    />
  );
}

뒤집기 (Inverted)

inverted prop으로 트랙을 뒤집을 수 있어요.

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

function Demo() {
  return <RangeSlider inverted defaultValue={[20, 80]} />;
}

숨겨진 마크 (Hidden marks)

숨겨진 마크를 사용하면 트랙에 시각적으로 표시하지 않고 특정 값에 스냅할 수 있어요. 사용자에게 보여주고 싶지 않은 특정 값에 "끈적이는" 스냅 동작을 만들고 싶을 때 유용해요. 이 기능은 restrictToMarks prop과 함께 사용해요.

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

function Demo() {
  const [value, setValue] = useState([25, 75]);

  return (
    <>
      <Text size="sm">
        Hidden marks allow you to snap to specific values without displaying them visually.
        Current value: [{value[0]}, {value[1]}]
      </Text>
      <RangeSlider value={value} onChange={setValue} restrictToMarks hiddenMarks={[0, 25, 50, 75, 100]} />
    </>
  );
}

접근성 (Accessibility)

RangeSlider 컴포넌트는 기본적으로 접근 가능해요.

  • 썸은 포커스 가능해요
  • 사용자가 마우스로 슬라이더를 조작하면 포커스가 슬라이더 트랙으로 이동하고, 화살표 키를 누르면 썸으로 포커스가 이동해요
  • 화살표 키로 step만큼 값을 증감할 수 있어요

스크린 리더를 위해 컴포넌트에 라벨을 지정하려면 썸에 라벨을 추가해요.

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

function Demo() {
  return <RangeSlider thumbFromLabel="Minimum value" thumbToLabel="Maximum value" />;
}

scale을 사용하거나 표시 값을 형식화(예: 통화나 백분율)한 경우, 스크린 리더가 읽을 수 있는 값을 제공하려면 thumbValueText를 설정해요. 이는 두 썸 모두에 aria-valuetext로 렌더링돼요. 함수가 제공되면 해당 썸의 스케일된 값을 받아요.

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

function Demo() {
  return (
    <RangeSlider
      scale={(v) => v * 10}
      thumbValueText={(value) => `${value}%`}
    />
  );
}

키보드 상호작용 (Keyboard interactions)

Key Description
ArrowRight/ArrowUp 슬라이더 값을 한 단계 증가
ArrowLeft/ArrowDown 슬라이더 값을 한 단계 감소

더 알아보기 (Learn more)