Skip to content
Components

Slider

Selects one value or a bounded range along a track.

Monthly budget range$250–$750

Playground

scheme

Applies a semantic color to the range and thumbs.

range

Example-only prop that switches between two thumbs and one.

orientation

Changes the track direction and example layout.

disabled

Prevents pointer and keyboard value changes.

Usage

tsx
import { Slider } from "earthling-ui/slider";

export function Example() {
  return (
    <>
      <Slider
        defaultValue={[25, 75]}
        thumbLabels={["Minimum budget", "Maximum budget"]}
      />
    </>
  );
}
  • Pass one value for a single thumb or multiple values for a range.
  • Provide thumbLabels when multiple thumbs need distinct accessible names.
  • Use min, max, and step to match the scale represented by the control.

Installation

Start with the project setup for React and Tailwind CSS 4. Both paths use the same component and theme.

bash
npm install earthling-ui

Use the component import shown above. Package updates keep the implementation current.

API reference

Declarations from the current library build, including inherited primitive props. Playground controls above show selected options; they are not the complete API.

tsx
// Generated by dts-bundle-generator v9.5.1

import * as SliderPrimitive from '@radix-ui/react-slider';
import { VariantProps } from 'class-variance-authority';
import { ComponentPropsWithoutRef } from 'react';

export declare const sliderVariants: (props?: ({
	scheme?: "default" | "primary" | "secondary" | "tertiary" | "neutral" | "muted" | "good" | "caution" | "bad" | null | undefined;
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
export interface SliderProps extends ComponentPropsWithoutRef<typeof SliderPrimitive.Root>, VariantProps<typeof sliderVariants> {
	thumbLabels?: string[];
}
export declare const Slider: import("react").ForwardRefExoticComponent<SliderProps & import("react").RefAttributes<HTMLSpanElement>>;

export {};

Runtime dependencies: @radix-ui/react-slider, class-variance-authority, cnfast.

Source

Use the eject command to copy this implementation with its required helpers and project-specific imports.

View Slider implementation
tsx
"use client";

import * as SliderPrimitive from "@radix-ui/react-slider";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/utils/cn";
import { schemes } from "@/utils/variants";
import {
  forwardRef,
  type ComponentPropsWithoutRef,
  type ComponentRef,
} from "react";

const sliderVariants = cva(
  "relative flex w-full touch-none select-none items-center data-[orientation=vertical]:h-full data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col",
  {
    variants: {
      scheme: schemes,
    },
    defaultVariants: { scheme: "primary" },
  },
);

export interface SliderProps
  extends
    ComponentPropsWithoutRef<typeof SliderPrimitive.Root>,
    VariantProps<typeof sliderVariants> {
  thumbLabels?: string[];
}

const Slider = forwardRef<
  ComponentRef<typeof SliderPrimitive.Root>,
  SliderProps
>(({ className, scheme, thumbLabels, ...props }, ref) => {
  const thumbCount = props.value?.length ?? props.defaultValue?.length ?? 1;

  return (
    <SliderPrimitive.Root
      ref={ref}
      className={cn(
        sliderVariants({ scheme }),
        "data-disabled:cursor-not-allowed data-disabled:opacity-50",
        className,
      )}
      {...props}
    >
      <SliderPrimitive.Track className="relative h-2 w-full grow overflow-hidden rounded-full bg-(--scheme-tint)/20 data-[orientation=vertical]:h-full data-[orientation=vertical]:w-2">
        <SliderPrimitive.Range className="absolute bg-(--scheme-tint) data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full" />
      </SliderPrimitive.Track>
      {Array.from({ length: thumbCount }, (_, index) => (
        <SliderPrimitive.Thumb
          key={index}
          aria-label={thumbLabels?.[index]}
          className="block size-5 rounded-full border-2 border-(--scheme-tint) bg-background ring-offset-background transition-transform duration-150 ease-out motion-reduce:transition-none active:scale-110 motion-reduce:active:scale-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-outline focus-visible:ring-offset-2 disabled:pointer-events-none"
        />
      ))}
    </SliderPrimitive.Root>
  );
});
Slider.displayName = SliderPrimitive.Root.displayName;

export { Slider, sliderVariants };