Slider

An ASCII-styled shadcn slider you can install and customize.

Volume

"use client";
import { Slider } from "@/components/ui/slider";
export function Demo() {
  return (
    <div className="w-full max-w-sm space-y-4">
      <p id="volume-label">Volume</p>
      <Slider
        aria-labelledby="volume-label"
        defaultValue={[40]}
        max={100}
        step={1}
      />
    </div>
  );
}

Installation

pnpm dlx shadcn@latest add https://ascii-cn.kdawg.dev/r/slider.json

Usage

import { Slider } from "@/components/ui/slider"
example.tsx
"use client";
import { Slider } from "@/components/ui/slider";
export function Demo() {
  return (
    <div className="w-full max-w-sm space-y-4">
      <p id="volume-label">Volume</p>
      <Slider
        aria-labelledby="volume-label"
        defaultValue={[40]}
        max={100}
        step={1}
      />
    </div>
  );
}

Customize

Edit the component's Tailwind classes directly. The component keeps the shadcn composition API with square geometry and the ASCII color palette.

components/ui/slider.tsx
"use client";
import { Slider as SliderPrimitive } from "@base-ui/react/slider";
import { cn } from "@/lib/utils";

function Slider({
  className,
  defaultValue,
  value,
  min = 0,
  max = 100,
  ...props
}: SliderPrimitive.Root.Props) {
  const _values = Array.isArray(value)
    ? value
    : Array.isArray(defaultValue)
      ? defaultValue
      : [
          typeof value === "number"
            ? value
            : typeof defaultValue === "number"
              ? defaultValue
              : min,
        ];

  return (
    <SliderPrimitive.Root
      className={cn("data-horizontal:w-full data-vertical:h-full", className)}
      data-slot="slider"
      defaultValue={defaultValue}
      value={value}
      min={min}
      max={max}
      thumbAlignment="edge"
      {...props}
    >
      <SliderPrimitive.Control className="relative flex min-h-11 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">
        <SliderPrimitive.Track
          data-slot="slider-track"
          className="relative grow overflow-hidden rounded-none border border-[#64717c] bg-black select-none data-horizontal:h-2 data-horizontal:w-full data-vertical:h-full data-vertical:w-1"
        >
          <SliderPrimitive.Indicator
            data-slot="slider-range"
            className="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}
            className="relative block size-4 shrink-0 rounded-none border border-ring bg-[#79bdff] ring-ring/50 transition-[color,box-shadow] select-none after:absolute after:-inset-2 hover:ring-3 focus-visible:ring-3 focus-visible:outline-hidden active:ring-3 disabled:pointer-events-none disabled:opacity-50"
          />
        ))}
      </SliderPrimitive.Control>
    </SliderPrimitive.Root>
  );
}

export { Slider };