fix(slider): normalize value, reactive trackEl, aria-valuetext
This commit is contained in:
@@ -87,7 +87,7 @@ const percent = $derived.by(() => {
|
|||||||
return Math.min(Math.max(((value - min) / (max - min)) * 100, 0), 100);
|
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);
|
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.
|
* 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-valuemin={min}
|
||||||
aria-valuemax={max}
|
aria-valuemax={max}
|
||||||
aria-valuenow={value}
|
aria-valuenow={value}
|
||||||
|
aria-valuetext={String(format(value))}
|
||||||
aria-disabled={disabled ? 'true' : undefined}
|
aria-disabled={disabled ? 'true' : undefined}
|
||||||
data-active={dragging ? '' : undefined}
|
data-active={dragging ? '' : undefined}
|
||||||
onkeydown={handleKeyDown}
|
onkeydown={handleKeyDown}
|
||||||
@@ -276,6 +291,7 @@ const thumbClasses = `block w-2.5 h-2.5 bg-brand
|
|||||||
aria-valuemin={min}
|
aria-valuemin={min}
|
||||||
aria-valuemax={max}
|
aria-valuemax={max}
|
||||||
aria-valuenow={value}
|
aria-valuenow={value}
|
||||||
|
aria-valuetext={String(format(value))}
|
||||||
aria-disabled={disabled ? 'true' : undefined}
|
aria-disabled={disabled ? 'true' : undefined}
|
||||||
data-active={dragging ? '' : undefined}
|
data-active={dragging ? '' : undefined}
|
||||||
onkeydown={handleKeyDown}
|
onkeydown={handleKeyDown}
|
||||||
|
|||||||
Reference in New Issue
Block a user