Feature/slider #47

Merged
ilia merged 7 commits from feature/slider into main 2026-06-02 12:10:43 +00:00
3 changed files with 13 additions and 2 deletions
Showing only changes of commit ae2d0e3c2f - Show all commits
@@ -39,8 +39,6 @@ const { Story } = defineMeta({
<script lang="ts"> <script lang="ts">
import type { ComponentProps } from 'svelte'; import type { ComponentProps } from 'svelte';
let value = $state(50); let value = $state(50);
let valueLow = $state(25);
let valueHigh = $state(75);
</script> </script>
<Story <Story
+4
View File
@@ -88,6 +88,7 @@ const percent = $derived.by(() => {
}); });
let trackEl: HTMLElement | undefined = $state(); let trackEl: HTMLElement | undefined = $state();
let thumbEl: HTMLElement | undefined = $state();
let dragging = $state(false); let dragging = $state(false);
/** /**
@@ -131,6 +132,7 @@ function handlePointerDown(event: PointerEvent): void {
return; return;
} }
dragging = true; dragging = true;
thumbEl?.focus();
(event.currentTarget as HTMLElement).setPointerCapture?.(event.pointerId); (event.currentTarget as HTMLElement).setPointerCapture?.(event.pointerId);
seek(event); seek(event);
} }
@@ -237,6 +239,7 @@ const thumbClasses = `block w-2.5 h-2.5 bg-brand
<span <span
role="slider" role="slider"
bind:this={thumbEl}
tabindex={disabled ? -1 : 0} tabindex={disabled ? -1 : 0}
aria-label="Value" aria-label="Value"
aria-orientation="vertical" aria-orientation="vertical"
@@ -285,6 +288,7 @@ const thumbClasses = `block w-2.5 h-2.5 bg-brand
<span <span
role="slider" role="slider"
bind:this={thumbEl}
tabindex={disabled ? -1 : 0} tabindex={disabled ? -1 : 0}
aria-label="Value" aria-label="Value"
aria-orientation="horizontal" aria-orientation="horizontal"
@@ -149,6 +149,15 @@ describe('Pointer', () => {
expect(screen.getByRole('slider')).toHaveAttribute('aria-valuenow', '0'); expect(screen.getByRole('slider')).toHaveAttribute('aria-valuenow', '0');
}); });
it('focuses the thumb on pointerdown so arrow keys work immediately', async () => {
const { container } = render(Slider, { value: 0, min: 0, max: 100 });
const track = container.querySelector('[role="presentation"]') as HTMLElement;
track.getBoundingClientRect = () =>
({ left: 0, right: 200, top: 0, bottom: 20, width: 200, height: 20 }) as DOMRect;
await fireEvent.pointerDown(track, { clientX: 100, clientY: 10, pointerId: 1 });
expect(screen.getByRole('slider')).toBe(document.activeElement);
});
it('maps a vertical drag with the inverted axis (bottom→min, top→max)', async () => { it('maps a vertical drag with the inverted axis (bottom→min, top→max)', async () => {
const { container } = render(Slider, { value: 0, min: 0, max: 100, orientation: 'vertical' }); const { container } = render(Slider, { value: 0, min: 0, max: 100, orientation: 'vertical' });
const track = container.querySelector('[role="presentation"]') as HTMLElement; const track = container.querySelector('[role="presentation"]') as HTMLElement;