All components

Slider

Slider is a React and Tailwind CSS form component from UI Layouts, licensed MIT. Copy it and paste it into your project.

UI Layouts MIT forms

What it is

Slider is a React and Tailwind CSS form component from UI Layouts, licensed MIT. Copy it and paste it into your project.

How to use it

Open it in the catalogue, press copy, and paste it into your project. The prompt you copy carries the code and the rules that tell your agent to reproduce it without changing anything.

Open in the catalogue

Five free copies a month. No card.

Needs

npm i @number-flow/react @radix-ui/react-slider

Licence

This component comes from UI Layouts and is redistributed under the MIT licence, which permits commercial use. The copyright notice travels with the code.

Slider

./components/ui/slider.tsx
'use client';

import { cn } from '@/lib/utils';
import NumberFlow from '@number-flow/react';
import * as SliderPrimitive from '@radix-ui/react-slider';
import { GripVertical } from 'lucide-react';
import * as React from 'react';

interface DualRangeSliderProps extends React.ComponentProps<typeof SliderPrimitive.Root> {
  labelPosition?: 'top' | 'bottom' | 'static';
  lableContenPos?: 'left' | 'right';
  label?: React.ReactNode | ((value: number | undefined) => React.ReactNode);
}

const DualRangeSlider = React.forwardRef<
  React.ElementRef<typeof SliderPrimitive.Root>,
  DualRangeSliderProps
>(({ className, label, labelPosition = 'top', lableContenPos = 'right', ...props }, ref) => {
  const initialValue = Array.isArray(props.value) ? props.value : [props.min, props.max];

  return (
    <SliderPrimitive.Root
      ref={ref}
      className={cn('relative flex w-full touch-none select-none items-center', className)}
      {...props}
    >
      <SliderPrimitive.Track className='relative h-6 w-full grow overflow-hidden bg-[linear-gradient(to_right,#e2e2e22c_1px,transparent_1px),linear-gradient(to_bottom,#9c9c9c2c_1px,transparent_1px)] bg-size-[4px_4px] dark:bg-neutral-950 bg-neutral-50 rounded-md dark:bg-[linear-gradient(to_right,#4f4f4f2e_1px,transparent_1px),linear-gradient(to_bottom,#4f4f4f2e_1px,transparent_1px)]'>
        <SliderPrimitive.Range className='absolute h-full dark:bg-neutral-100 bg-neutral-950' />
      </SliderPrimitive.Track>
      <>
        {initialValue.map((value, index) => (
          <React.Fragment key={value}>
            <SliderPrimitive.Thumb className='relative grid h-6 w-3 cursor-grab place-content-center dark:bg-neutral-100 bg-neutral-950 shadow-sm focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-white'>
              {label && labelPosition !== 'static' && (
                <div
                  className={cn(
                    'absolute flex w-full justify-center items-start gap-0.5',
                    labelPosition === 'top' && '-top-7',
                    labelPosition === 'bottom' && 'top-4'
                  )}
                >
                  {lableContenPos === 'left' && (
                    <>
                      {typeof label === 'function' ? (
                        <span className='inline-block  -translate-y-0.5'>{label(value)}</span>
                      ) : (
                        label && <span className='inline-block '>{label}</span>
                      )}
                    </>
                  )}
                  <NumberFlow
                    willChange
                    // @ts-expect-error
                    value={value}
                    isolate
                    opacityTiming={{
                      duration: 250,
                      easing: 'ease-out',
                    }}
                    transformTiming={{
                      easing: `linear(0, 0.0033 0.8%, 0.0263 2.39%, 0.0896 4.77%, 0.4676 15.12%, 0.5688, 0.6553, 0.7274, 0.7862, 0.8336 31.04%, 0.8793, 0.9132 38.99%, 0.9421 43.77%, 0.9642 49.34%, 0.9796 55.71%, 0.9893 62.87%, 0.9952 71.62%, 0.9983 82.76%, 0.9996 99.47%)`,
                      duration: 500,
                    }}
                  />
                  {lableContenPos === 'right' && (
                    <>
                      {typeof label === 'function' ? (
                        <span className='inline-block  -translate-y-1'>{label(value)}</span>
                      ) : (
                        label && <span className='inline-block '>{label}</span>
                      )}
                    </>
                  )}
                </div>
              )}
              <GripVertical size={16} className='px-0.5 text-primary-foreground' />
            </SliderPrimitive.Thumb>
          </React.Fragment>
        ))}
      </>

      {label && labelPosition === 'static' && (
        <>
          {initialValue.map((value, index) => (
            <div
              key={`${value}-${index}`}
              className={cn(
                'absolute -top-7 w-fit right-0 flex  justify-center items-start gap-0.5'
              )}
            >
              {lableContenPos === 'left' && (
                <>
                  {typeof label === 'function' ? (
                    <span className='inline-block  -translate-y-0.5'>{label(value)}</span>
                  ) : (
                    label && <span className='inline-block '>{label}</span>
                  )}
                </>
              )}
              <NumberFlow
                willChange
                // @ts-expect-error
                value={value}
                isolate
                opacityTiming={{
                  duration: 250,
                  easing: 'ease-out',
                }}
                transformTiming={{
                  easing: `linear(0, 0.0033 0.8%, 0.0263 2.39%, 0.0896 4.77%, 0.4676 15.12%, 0.5688, 0.6553, 0.7274, 0.7862, 0.8336 31.04%, 0.8793, 0.9132 38.99%, 0.9421 43.77%, 0.9642 49.34%, 0.9796 55.71%, 0.9893 62.87%, 0.9952 71.62%, 0.9983 82.76%, 0.9996 99.47%)`,
                  duration: 500,
                }}
              />
              {lableContenPos === 'right' && (
                <>
                  {typeof label === 'function' ? (
                    <span className='inline-block  -translate-y-1'>{label(value)}</span>
                  ) : (
                    label && <span className='inline-block '>{label}</span>
                  )}
                </>
              )}
            </div>
          ))}
        </>
      )}
    </SliderPrimitive.Root>
  );
});
DualRangeSlider.displayName = 'DualRangeSlider';

export { DualRangeSlider };

Similar components