섹션
컴포넌트
슬라이더
값이나 범위(볼륨, 가격 필터, 설정 등)를 선택할 수 있는 드래그 가능한 입력 요소로, 네오브루탈리즘 스타일의 테두리와 그림자 효과가 적용되어 있습니다.
import { Slider } from "@/components/ui/slider"
export function SliderDemo() {슬라이더는 트랙을 드래그해 값 — 또는 두 썸 사이의 범위 — 을 고르게 합니다. Base UI Slider 프리미티브를 기반으로 하며, 두꺼운 테두리, 선명한 그림자 사각 썸, 단색 채움 범위로 네오브루탈리즘 공식을 입혔습니다.
다음과 같은 경우에 사용합니다.
- 볼륨, 밝기, 재생 위치 — 입력보다 드래그가 나은 미디어 플레이어와 기기형 컨트롤.
- 가격·범위 필터 — 썸 두 개로 검색과 이커머스 목록의 min–max 필터를 만듭니다.
- 범위가 분명한 숫자 설정 — 불투명도, 테두리 반경, 글자 크기. 입력보다 보여 주는 편이 나은 유계 숫자.
설치#
pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/slider.jsonnpx shadcn@latest add https://neobrutalism.com/r/base/slider.jsonyarn dlx shadcn@latest add https://neobrutalism.com/r/base/slider.jsonbunx --bun shadcn@latest add https://neobrutalism.com/r/base/slider.json
다음 의존성을 설치합니다.
pnpm add @base-ui/reactnpm install @base-ui/reactyarn add @base-ui/reactbun add @base-ui/react
다음 코드를 복사하여 프로젝트에 붙여넣습니다.
"use client"
import * as React from "react"
import { Slider as SliderPrimitive } from "radix-ui"
import { cn } from "@/lib/utils"
function Slider({
className,
defaultValue,
value,
min = 0,
max = 100,
// Pulled out of the root spread so they land on the Thumb (the element
// with role="slider" that screen readers announce), not just the Root.
"aria-label": ariaLabel,
"aria-labelledby": ariaLabelledby,
...props
}: React.ComponentProps<typeof SliderPrimitive.Root>) {
const _values = React.useMemo(
() =>
Array.isArray(value)
? value
: Array.isArray(defaultValue)
? defaultValue
: [min, max],
[value, defaultValue, min, max]
)
return (
<SliderPrimitive.Root
data-slot="slider"
defaultValue={defaultValue}
value={value}
min={min}
max={max}
className={cn(
"relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:min-h-40 data-vertical:w-auto data-vertical:flex-col",
className
)}
{...props}
>
<SliderPrimitive.Track
data-slot="slider-track"
className="relative grow overflow-hidden border-2 bg-background data-horizontal:h-3 data-horizontal:w-full data-vertical:h-full data-vertical:w-3"
>
<SliderPrimitive.Range
data-slot="slider-range"
className="absolute bg-primary select-none data-horizontal:h-full data-vertical:w-full"
/>
</SliderPrimitive.Track>
{Array.from({ length: _values.length }, (_, index) => (
<SliderPrimitive.Thumb
data-slot="slider-thumb"
key={index}
aria-label={ariaLabel}
aria-labelledby={ariaLabelledby}
className="relative block size-4.5 shrink-0 border-2 bg-background shadow-sm transition-[color,box-shadow] select-none after:absolute after:-inset-2 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary disabled:pointer-events-none disabled:opacity-50"
/>
))}
</SliderPrimitive.Root>
)
}
export { Slider }
임포트 경로를 프로젝트 구성에 맞게 조정합니다.
사용법#
import { Slider } from "@/components/ui/slider"<Slider defaultValue={[33]} max={100} step={1} />예제#
범위#
범위 슬라이더에는 두 개의 값을 가진 배열을 사용합니다.
import { Slider } from "@/components/ui/slider"
export function SliderRange() {여러 개의 썸#
여러 개의 썸에는 여러 값을 가진 배열을 사용합니다.
import { Slider } from "@/components/ui/slider"
export function SliderMultiple() {세로#
세로 방향 슬라이더에는 orientation="vertical"을 지정합니다.
import { Slider } from "@/components/ui/slider"
export function SliderVertical() {제어 상태#
"use client"
import * as React from "react"비활성화#
disabled prop을 사용하여 슬라이더를 비활성화합니다.
import { Slider } from "@/components/ui/slider"
export function SliderDisabled() {RTL#
Neobrutalism에서 RTL 지원을 활성화하는 방법은 RTL 설정 가이드를 참고하세요.
"use client"
import * as React from "react"접근성#
슬라이더는 WAI-ARIA Slider 패턴을 따릅니다. 각 썸은 aria-valuemin, aria-valuemax, aria-valuenow가 동기화되는 포커스 가능한 role="slider" 요소입니다. 폼 제출용 숨겨진 input이 뒤에 있습니다. 슬라이더 자체에는 보이는 레이블이 없으므로 aria-label 또는 aria-labelledby를 전달하세요. 이 래퍼는 둘 다 스크린 리더가 실제로 읽는 요소인 썸으로 전달합니다.
키보드 상호작용:
| 키 | 동작 |
|---|---|
Tab / Shift + Tab | 썸 사이와 밖으로 포커스 이동 |
ArrowRight / ArrowUp | 값을 한 단계 증가 |
ArrowLeft / ArrowDown | 값을 한 단계 감소 |
PageUp / PageDown | largeStep(기본 10)만큼 증가/감소 |
Shift + Arrow | largeStep만큼 증가/감소 |
Home / End | 최소/최대로 이동 |
RTL에서 가로 화살표 키는 읽기 방향을 따릅니다.
API 참조#
Base UI Slider 문서를 참고하세요.