Skip to content
45 linesCodeBlameRaw
1import { Slider as Primitive } from "radix-ui";
2import type { ComponentProps } from "react";
3
4import { cn } from "../../lib/cn";
5
6// shadcn/ui's slider, styled with g1t's tokens: a value picked along a
7// line, with the keyboard (arrows, Home, End, Page Up and Down) as well as
8// the pointer. Give it an `aria-label`, or point a <Label> at the thumb
9// through `aria-labelledby`. One thumb unless `value` has several.
10
11export function Slider({ className, value, defaultValue, min = 0, max = 100, ...props }: ComponentProps<typeof Primitive.Root>) {
12 const thumbs = Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min];
13 return (
14 <Primitive.Root
15 data-slot="slider"
16 value={value}
17 defaultValue={defaultValue}
18 min={min}
19 max={max}
20 className={cn(
21 "relative flex w-full touch-none items-center select-none data-[disabled]:opacity-50",
22 "data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col",
23 className,
24 )}
25 {...props}
26 >
27 <Primitive.Track
28 data-slot="slider-track"
29 className="relative grow overflow-hidden rounded-full bg-line data-[orientation=horizontal]:h-1.5 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1.5"
30 >
31 <Primitive.Range data-slot="slider-range" className="absolute bg-accent data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full" />
32 </Primitive.Track>
33 {thumbs.map((_, index) => (
34 <Primitive.Thumb
35 key={index}
36 data-slot="slider-thumb"
37 className={cn(
38 "block size-4 shrink-0 rounded-full border border-accent bg-fg shadow-sm transition-[color,box-shadow] outline-none",
39 "hover:ring-4 hover:ring-accent/25 focus-visible:ring-4 focus-visible:ring-accent/40 disabled:pointer-events-none",
40 )}
41 />
42 ))}
43 </Primitive.Root>
44 );
45}