Slider

The Slider component is used to select a value or range of values ​​from a range of values.

export const Example = () => {
  return <Slider defaultValue={[50]} />;
};

Installation

If you haven't included Piksel UI in your project, include it first. You can check the installation page.

Source code

Copy the following source code and add it to your project.

import React, { ComponentPropsWithRef, forwardRef } from "react";
import { tv, VariantProps } from "tailwind-variants";
import * as SliderPrimitive from "@radix-ui/react-slider";

export const sliderDisplayName = "Slider";
export type SliderProps = ComponentPropsWithRef<typeof SliderPrimitive.Root> &
  VariantProps<typeof sliderStyles>;
/**
 * @name Slider
 * @description The Slider component is used to select a value or range of values ​​from a range of values.
 */
export const Slider = forwardRef<HTMLDivElement, SliderProps>((props, ref) => {
  const { color, size, radius, className, defaultValue, value, ...rest } =
    props;
  const thumbCount = value?.length ?? defaultValue?.length ?? 1;

  const { root, range, thumb, track } = sliderStyles({
    color,
    size,
    radius,
  });

  return (
    <SliderPrimitive.Root
      value={value}
      defaultValue={defaultValue}
      className={root()}
      {...rest}
      ref={ref}
    >
      <SliderPrimitive.Track className={track()}>
        <SliderPrimitive.Range className={range()} />
      </SliderPrimitive.Track>
      {Array.from({ length: thumbCount }).map((_, i) => (
        <SliderPrimitive.Thumb key={i} className={thumb()} />
      ))}
    </SliderPrimitive.Root>
  );
});
Slider.displayName = sliderDisplayName;

export const sliderStyles = tv({
  slots: {
    root: "relative flex items-center select-none touch-none w-full",
    track: "bg-zinc-100 relative grow rounded-full",
    range: "absolute rounded-full h-full",
    thumb:
      "block bg-white shadow rounded-full outline-none ring-1 transition-all",
  },
  variants: {
    color: {
      blue: {
        range: "bg-blue-600",
        thumb: "ring-blue-200 active:ring-blue-400",
      },
      red: {
        range: "bg-red-600",
        thumb: "ring-red-200 active:ring-red-400",
      },
      indigo: {
        range: "bg-indigo-600",
        thumb: "ring-indigo-200 active:ring-indigo-400",
      },
      green: {
        range: "bg-green-600",
        thumb: "ring-green-200 active:ring-green-400",
      },
      yellow: {
        range: "bg-yellow-600",
        thumb: "ring-yellow-200 active:ring-yellow-400",
      },
      zinc: {
        range: "bg-zinc-600",
        thumb: "ring-zinc-200 active:ring-zinc-400",
      },
      white: {
        range: "bg-white",
        thumb: "ring-zinc-200 active:ring-zinc-400",
      },
      black: {
        range: "bg-black",
        thumb: "ring-zinc-200 active:ring-zinc-400",
      },
    },
    size: {
      sm: {
        root: "h-4",
        track: "h-1",
        thumb: "w-3 h-3",
      },
      md: {
        root: "h-5",
        track: "h-1.5",
        thumb: "w-4 h-4",
      },
      lg: {
        root: "h-6",
        track: "h-2",
        thumb: "w-5 h-5",
      },
    },
    radius: {
      none: {
        track: "rounded-none",
        range: "rounded-none",
        thumb: "rounded-none",
      },
      sm: {
        track: "rounded-sm",
        range: "rounded-sm",
        thumb: "rounded-sm",
      },
      md: {
        track: "rounded-md",
        range: "rounded-md",
        thumb: "rounded-md",
      },
      lg: {
        track: "rounded-lg",
        range: "rounded-lg",
        thumb: "rounded-lg",
      },
      xl: {
        track: "rounded-xl",
        range: "rounded-xl",
        thumb: "rounded-xl",
      },
      full: {
        track: "rounded-full",
        range: "rounded-full",
        thumb: "rounded-full",
      },
    },
  },
  defaultVariants: {
    color: "black",
    size: "md",
    radius: "full",
  },
});