Feature/slider #47
@@ -87,7 +87,7 @@ const percent = $derived.by(() => {
|
||||
return Math.min(Math.max(((value - min) / (max - min)) * 100, 0), 100);
|
||||
});
|
||||
|
||||
let trackEl: HTMLElement | undefined;
|
||||
let trackEl: HTMLElement | undefined = $state();
|
||||
let dragging = $state(false);
|
||||
|
||||
/**
|
||||
@@ -101,6 +101,20 @@ function commit(raw: number): void {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep an externally-supplied value normalized to the step grid and range.
|
||||
* Mirrors the bits-ui primitive's behavior so out-of-range or off-grid
|
||||
* props don't desync the thumb position from aria-valuenow / the label.
|
||||
* Converges in one pass: once snapped, the value equals its own snap.
|
||||
*/
|
||||
$effect(() => {
|
||||
const normalized = snapToStep(value, { min, max, step });
|
||||
if (normalized !== value) {
|
||||
value = normalized;
|
||||
onValueChange?.(normalized);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Resolve a pointer event to a value using the live track rect.
|
||||
*/
|
||||
@@ -229,6 +243,7 @@ const thumbClasses = `block w-2.5 h-2.5 bg-brand
|
||||
aria-valuemin={min}
|
||||
aria-valuemax={max}
|
||||
aria-valuenow={value}
|
||||
aria-valuetext={String(format(value))}
|
||||
aria-disabled={disabled ? 'true' : undefined}
|
||||
data-active={dragging ? '' : undefined}
|
||||
onkeydown={handleKeyDown}
|
||||
@@ -276,6 +291,7 @@ const thumbClasses = `block w-2.5 h-2.5 bg-brand
|
||||
aria-valuemin={min}
|
||||
aria-valuemax={max}
|
||||
aria-valuenow={value}
|
||||
aria-valuetext={String(format(value))}
|
||||
aria-disabled={disabled ? 'true' : undefined}
|
||||
data-active={dragging ? '' : undefined}
|
||||
onkeydown={handleKeyDown}
|
||||
|
||||
Reference in New Issue
Block a user