Co-authored-by: dev_agent <dev_agent@cubecraftlabs.com> Co-committed-by: dev_agent <dev_agent@cubecraftlabs.com>
This commit was merged in pull request #34.
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
import type { CSSProperties, ComponentPropsWithRef } from 'react'
|
||||
import styles from './Slider.module.css'
|
||||
|
||||
export type SliderProps = Omit<ComponentPropsWithRef<'input'>, 'type' | 'value' | 'min' | 'max'> & {
|
||||
value: number
|
||||
min: number
|
||||
max: number
|
||||
}
|
||||
|
||||
// Native range input, styled: 8 px track, grape fill up to the value, 24 px
|
||||
// knob with a 3 px grape ring. Controlled, because the fill follows `value`.
|
||||
// Name it with aria-label or aria-labelledby.
|
||||
export function Slider({ value, min, max, className, style, ...rest }: SliderProps) {
|
||||
if (!(max > min)) throw new Error(`Slider: max (${max}) must be greater than min (${min})`)
|
||||
if (!(value >= min && value <= max)) {
|
||||
throw new Error(`Slider: value (${value}) must be within [${min}, ${max}]`)
|
||||
}
|
||||
const fill = `${((value - min) / (max - min)) * 100}%`
|
||||
return (
|
||||
<input
|
||||
type="range"
|
||||
value={value}
|
||||
min={min}
|
||||
max={max}
|
||||
className={[styles.slider, className].filter(Boolean).join(' ')}
|
||||
style={{ ...style, '--slider-fill': fill } as CSSProperties}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user