import { Slider as AriaSlider, type SliderProps as AriaSliderProps, SliderOutput, SliderThumb, SliderTrack, } from 'react-aria-components/Slider'; import { tv } from 'tailwind-variants'; import { Label } from './Field'; import { composeTailwindRenderProps, focusRing } from './utils'; const trackStyles = tv({ base: 'rounded-full', variants: { orientation: { horizontal: 'h-1 w-full', vertical: 'ml-[50%] h-full w-1 -translate-x-[50%]', }, isDisabled: { false: 'bg-gray-400 dark:bg-zinc-500 forced-colors:bg-[ButtonBorder]', true: 'bg-gray-100 dark:bg-zinc-800 forced-colors:bg-[GrayText]', }, }, }); const thumbStyles = tv({ extend: focusRing, base: 'border-secondary-800 group-orientation-horizontal/track:mt-6 group-orientation-vertical/track:ml-3 hover:bg-secondary-100 dark:border-secondary-400 size-6 rounded-full border-[3px] bg-white dark:bg-zinc-900 hover:dark:bg-zinc-800', variants: { isDragging: { true: 'dragging:bg-secondary-50 dragging:dark:bg-secondary-950 forced-colors:bg-[ButtonBorder]', }, isDisabled: { true: 'border-gray-200 dark:border-zinc-700 forced-colors:border-[GrayText]', }, }, }); export interface SliderProps extends AriaSliderProps { label?: string; thumbLabels?: string[]; } function getTrackStyle(range: number, orientation?: string) { if (orientation === 'vertical') { return { top: `${(1 - range) * 100}%`, }; } return { width: `${range * 100}%`, }; } export function Slider({ label, thumbLabels, ...props }: SliderProps) { return ( {({ state }) => state.values.map((_, i) => state.getThumbValueLabel(i)).join(' – ') } {({ state, ...renderProps }) => ( <>
{props.defaultValue && (typeof props.defaultValue === 'number' || (Array.isArray(props.defaultValue) && props.defaultValue.length === 1)) && (
)} {state.values.map((_, i) => ( ))} )} ); }