Skip to content
Nerdfishui
Esc
navigateopen⌘Jpreview
On this page

Slider

An input where the user selects a value from within a given range.

'use client'

import { Slider, SliderThumb } from '@nerdfish/react/slider'

export default function SliderExample() {
	return (
		<div className="w-xs max-w-[calc(100vw-3rem)]">
			<Slider defaultValue={[50]} max={100} step={1}>
				<SliderThumb />
			</Slider>
		</div>
	)
}

Labels

'use client'

import { Label } from '@nerdfish/react/label'
import { Slider, SliderThumb } from '@nerdfish/react/slider'
import { useState } from 'react'

export default function SliderLabelsExample() {
	const min_price = 5
	const max_price = 1240
	const [value, setValue] = useState([min_price, max_price])

	const formatPrice = (price: number) => {
		return price === max_price
			? `€${price.toLocaleString()}+`
			: `€${price.toLocaleString()}`
	}

	return (
		<div className="w-xs max-w-[calc(100vw-3rem)] *:not-first:mt-3.5">
			<Label className="tabular-nums">
				From {formatPrice(value[0] ?? 0)} to {formatPrice(value[1] ?? 0)}
			</Label>
			<div className="flex items-center gap-4">
				<Slider
					value={value}
					onValueChange={(newValue) => setValue(newValue as number[])}
					min={min_price}
					max={max_price}
					aria-label="Price range slider"
				>
					<SliderThumb />
					<SliderThumb />
				</Slider>
			</div>
		</div>
	)
}

Tooltip

'use client'

import { Slider } from '@nerdfish/react/slider'

export default function SliderTooltipExample() {
	return (
		<div className="w-xs max-w-[calc(100vw-3rem)] *:not-first:mt-4">
			<div>
				<span
					className="text-foreground-muted mb-friends gap-bff flex w-full items-center justify-between text-xs font-medium"
					aria-hidden="true"
				>
					<span>Low</span>
					<span>High</span>
				</span>
				<Slider
					defaultValue={[50]}
					step={10}
					showTooltip={true}
					aria-label="Slider with labels and tooltip"
				/>
			</div>
		</div>
	)
}

Vertical

'use client'

import { Slider } from '@nerdfish/react/slider'

export default function SliderVerticalExample() {
	return (
		<div className="w-xs max-w-[calc(100vw-3rem)] *:not-first:mt-4">
			<div className="flex h-40 justify-center">
				<Slider
					defaultValue={[2, 7]}
					max={10}
					orientation="vertical"
					aria-label="Vertical slider"
					showTooltip={true}
					tooltipContent={(value) => `Value: ${value}`}
					tooltipVariant="light"
				/>
			</div>
		</div>
	)
}

Rating

'use client'

import { Label } from '@nerdfish/react/label'
import { Slider, SliderThumb } from '@nerdfish/react/slider'
import { useState } from 'react'

export default function SliderRatingExample() {
	const [value, setValue] = useState([3])

	const labels = ['Awful', 'Poor', 'Okay', 'Good', 'Amazing']

	return (
		<div className="w-xs max-w-[calc(100vw-3rem)] space-y-3">
			<div className="flex items-center justify-between gap-2">
				<Label className="leading-6">Rate your experience</Label>
				<span className="text-sm font-medium">{labels[value[0] ?? 0 - 1]}</span>
			</div>
			<div className="flex items-center gap-2">
				<span className="mr-best-friends text-2xl">😡</span>
				<Slider
					value={value}
					onValueChange={(newValue) => setValue(newValue as number[])}
					min={1}
					max={5}
					aria-label="Rate your experience"
				>
					<SliderThumb />
				</Slider>
				<span className="ml-best-friends text-2xl">😍</span>
			</div>
		</div>
	)
}

Ticks

'use client'

import { Label } from '@nerdfish/react/label'
import { Slider, SliderThumb } from '@nerdfish/react/slider'
import { cn } from '@nerdfish/utils/class'

export default function SliderTicksExample() {
	const max = 12
	const skipInterval = 2 // Set to 1 to allow no text skipping
	const ticks = [...Array(max + 1)].map((_, i) => i)

	return (
		<div className="w-xs max-w-[calc(100vw-3rem)] *:not-first:mt-4">
			<Label>Slider with ticks</Label>
			<div>
				<Slider defaultValue={[5]} max={max} aria-label="Slider with ticks">
					<SliderThumb />
				</Slider>
				<span
					className="text-foreground-muted gap-1.125 mt-3 flex w-full items-center justify-between px-0.5 text-xs font-medium"
					aria-hidden="true"
				>
					{ticks.map((_, i) => (
						<span
							key={i}
							className="flex w-0 flex-col items-center justify-center gap-2"
						>
							<span
								className={cn(
									'bg-foreground-muted h-1 w-px',
									i % skipInterval !== 0 && 'h-0.5',
								)}
							/>
							<span className={cn(i % skipInterval !== 0 && 'opacity-0')}>
								{i}
							</span>
						</span>
					))}
				</span>
			</div>
		</div>
	)
}