Implements headless Slider with Root, Track, Range, and Thumb parts. Supports controlled/uncontrolled value, keyboard navigation (Arrow, Page, Home, End), clamping, step, orientation, and disabled state. 10 tests added, all 152 suite tests pass.
68 lines
1.8 KiB
TypeScript
68 lines
1.8 KiB
TypeScript
import type { JSX } from "solid-js";
|
|
import { splitProps } from "solid-js";
|
|
import { useSliderContext } from "./slider-context";
|
|
|
|
/** Props for Slider.Thumb. */
|
|
export interface SliderThumbProps extends JSX.HTMLAttributes<HTMLSpanElement> {
|
|
/** Accessible label for the thumb. */
|
|
"aria-label"?: string;
|
|
}
|
|
|
|
/** The draggable thumb element. Handles keyboard navigation. */
|
|
export function SliderThumb(props: SliderThumbProps): JSX.Element {
|
|
const [local, rest] = splitProps(props, ["onKeyDown"]);
|
|
const ctx = useSliderContext();
|
|
|
|
const handleKeyDown: JSX.EventHandler<HTMLSpanElement, KeyboardEvent> = (e) => {
|
|
if (typeof local.onKeyDown === "function") local.onKeyDown(e);
|
|
if (ctx.disabled()) return;
|
|
|
|
const current = ctx.value();
|
|
const s = ctx.step();
|
|
|
|
switch (e.key) {
|
|
case "ArrowRight":
|
|
case "ArrowUp":
|
|
e.preventDefault();
|
|
ctx.setValue(current + s);
|
|
break;
|
|
case "ArrowLeft":
|
|
case "ArrowDown":
|
|
e.preventDefault();
|
|
ctx.setValue(current - s);
|
|
break;
|
|
case "PageUp":
|
|
e.preventDefault();
|
|
ctx.setValue(current + s * 10);
|
|
break;
|
|
case "PageDown":
|
|
e.preventDefault();
|
|
ctx.setValue(current - s * 10);
|
|
break;
|
|
case "Home":
|
|
e.preventDefault();
|
|
ctx.setValue(ctx.min());
|
|
break;
|
|
case "End":
|
|
e.preventDefault();
|
|
ctx.setValue(ctx.max());
|
|
break;
|
|
}
|
|
};
|
|
|
|
return (
|
|
<span
|
|
role="slider"
|
|
aria-valuemin={ctx.min()}
|
|
aria-valuemax={ctx.max()}
|
|
aria-valuenow={ctx.value()}
|
|
aria-orientation={ctx.orientation()}
|
|
aria-disabled={ctx.disabled() || undefined}
|
|
data-disabled={ctx.disabled() || undefined}
|
|
tabIndex={ctx.disabled() ? -1 : 0}
|
|
onKeyDown={handleKeyDown}
|
|
{...rest}
|
|
/>
|
|
);
|
|
}
|