Search for a command to run...
An input where the user selects a value from within a given range.
npx shadcn@latest add @zaidan/sliderpnpx shadcn add @zaidan/slideryarn dlx shadcn@latest add @zaidan/sliderbunx shadcn@latest add @zaidan/sliderCopy and paste the following code into your project.
1import type { PolymorphicProps } from "@kobalte/core/polymorphic";2import {3 type SliderFillProps,4 Slider as SliderPrimitive,5 type SliderRootProps,6 type SliderThumbProps,7 type SliderTrackProps,8 useSliderContext,9} from "@kobalte/core/slider";10import {11 type ComponentProps,12 createMemo,13 For,14 mergeProps,15 splitProps,16 untrack,17 type ValidComponent,18} from "solid-js";19import { cn } from "~/lib/utils";20
21type SliderProps<T extends ValidComponent = "div"> = PolymorphicProps<T, SliderRootProps<T>> &22 Pick<ComponentProps<T>, "class">;23
24const Slider = <T extends ValidComponent = "div">(rawProps: SliderProps<T>) => {25 const props = mergeProps({ minValue: 0, maxValue: 100 } as SliderProps<T>, rawProps);26 const [local, others] = splitProps(props as SliderProps, ["class", "defaultValue", "value"]);27
28 const values = createMemo(() => {29 if (Array.isArray(untrack(() => local.value))) return untrack(() => local.value);30 if (Array.isArray(local.defaultValue)) return local.defaultValue;31 return [others.minValue, others.maxValue];32 });33
34 return (35 <SliderPrimitive36 data-slot="slider"37 defaultValue={local.defaultValue}38 value={local.value}39 class={cn(40 "relative z-slider flex w-full touch-none select-none items-center data-[orientation=vertical]:h-full data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col data-disabled:opacity-50",41 local.class,42 )}43 {...others}44 >45 <SliderTrack>46 <SliderFill />47 </SliderTrack>48 <For each={values()}>{() => <SliderThumb />}</For>49 </SliderPrimitive>50 );51};52
53type SliderTrackComponentProps<T extends ValidComponent = "div"> = PolymorphicProps<54 T,55 SliderTrackProps<T>56> &57 Pick<ComponentProps<T>, "class" | "children">;58
59const SliderTrack = <T extends ValidComponent = "div">(props: SliderTrackComponentProps<T>) => {60 const [local, others] = splitProps(props as SliderTrackComponentProps, ["class", "children"]);61 const context = useSliderContext();62 return (63 <SliderPrimitive.Track64 data-slot="slider-track"65 data-orientation={context.state.orientation()}66 class={cn(67 "relative z-slider-track grow overflow-hidden rounded-full data-[orientation=horizontal]:h-1.5 data-[orientation=vertical]:h-full data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-1.5",68 local.class,69 )}70 {...others}71 >72 {local.children}73 </SliderPrimitive.Track>74 );75};76
77type SliderFillComponentProps<T extends ValidComponent = "div"> = PolymorphicProps<78 T,79 SliderFillProps<T>80> &81 Pick<ComponentProps<T>, "class">;82
83const SliderFill = <T extends ValidComponent = "div">(props: SliderFillComponentProps<T>) => {84 const [local, others] = splitProps(props as SliderFillComponentProps, ["class"]);85 const context = useSliderContext();86 return (87 <SliderPrimitive.Fill88 data-slot="slider-range"89 data-orientation={context.state.orientation()}90 class={cn(91 "absolute z-slider-range data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full",92 local.class,93 )}94 {...others}95 />96 );97};98
99type SliderThumbComponentProps<T extends ValidComponent = "span"> = PolymorphicProps<100 T,101 SliderThumbProps<T>102> &103 Pick<ComponentProps<T>, "class">;104
105const SliderThumb = <T extends ValidComponent = "span">(props: SliderThumbComponentProps<T>) => {106 const [local, others] = splitProps(props as SliderThumbComponentProps, ["class"]);107 return (108 <SliderPrimitive.Thumb109 data-slot="slider-thumb"110 class={cn(111 "z-slider-thumb block shrink-0 select-none disabled:pointer-events-none disabled:opacity-50",112 local.class,113 )}114 {...others}115 >116 <SliderPrimitive.Input />117 </SliderPrimitive.Thumb>118 );119};120
121export { Slider };The Slider component uses Kobalte's Slider primitive under the hood. Here are the main props:
| Prop | Type | Default | Description |
|---|---|---|---|
value | number[] | - | The controlled value of the slider |
defaultValue | number[] | - | The default value of the slider |
onChange | (value: number[]) => void | - | Handler called when value changes |
onChangeEnd | (value: number[]) => void | - | Handler called after dragging ends |
minValue | number | 0 | The minimum value |
maxValue | number | 100 | The maximum value |
step | number | 1 | The stepping interval |
orientation | "horizontal" | "vertical" | "horizontal" | The orientation of the slider |
disabled | boolean | false | Whether the slider is disabled |
Here are the source code of all the examples from the preview page:
import { Slider } from "~/components/ui/slider";function SliderBasic() { return ( <Example title="Basic"> <Slider defaultValue={[50]} maxValue={100} step={1} /> </Example> );}import { Slider } from "~/components/ui/slider";function SliderRange() { return ( <Example title="Range"> <Slider defaultValue={[25, 50]} maxValue={100} step={5} /> </Example> );}import { Slider } from "~/components/ui/slider";function SliderMultiple() { return ( <Example title="Multiple Thumbs"> <Slider defaultValue={[10, 20, 70]} maxValue={100} step={10} /> </Example> );}import { Slider } from "~/components/ui/slider";function SliderVertical() { return ( <Example title="Vertical"> <div class="flex items-center gap-6"> <Slider defaultValue={[50]} maxValue={100} step={1} orientation="vertical" class="h-40" /> <Slider defaultValue={[25]} maxValue={100} step={1} orientation="vertical" class="h-40" /> </div> </Example> );}import { createSignal } from "solid-js";import { Label } from "~/components/ui/label";import { Slider } from "~/components/ui/slider";function SliderControlled() { const [value, setValue] = createSignal([0.3, 0.7]);
return ( <Example title="Controlled"> <div class="grid w-full gap-3"> <div class="flex items-center justify-between gap-2"> <Label for="slider-demo-temperature">Temperature</Label> <span class="text-muted-foreground text-sm">{value().join(", ")}</span> </div> <Slider id="slider-demo-temperature" value={value()} onChange={(v) => setValue(v)} minValue={0} maxValue={1} step={0.1} /> </div> </Example> );}import { Slider } from "~/components/ui/slider";function SliderDisabled() { return ( <Example title="Disabled"> <Slider defaultValue={[50]} maxValue={100} step={1} disabled /> </Example> );}