Feature/slider #47
@@ -39,8 +39,6 @@ const { Story } = defineMeta({
|
||||
<script lang="ts">
|
||||
import type { ComponentProps } from 'svelte';
|
||||
let value = $state(50);
|
||||
let valueLow = $state(25);
|
||||
let valueHigh = $state(75);
|
||||
</script>
|
||||
|
||||
<Story
|
||||
|
||||
@@ -88,6 +88,7 @@ const percent = $derived.by(() => {
|
||||
});
|
||||
|
||||
let trackEl: HTMLElement | undefined = $state();
|
||||
let thumbEl: HTMLElement | undefined = $state();
|
||||
let dragging = $state(false);
|
||||
|
||||
/**
|
||||
@@ -131,6 +132,7 @@ function handlePointerDown(event: PointerEvent): void {
|
||||
return;
|
||||
}
|
||||
dragging = true;
|
||||
thumbEl?.focus();
|
||||
(event.currentTarget as HTMLElement).setPointerCapture?.(event.pointerId);
|
||||
seek(event);
|
||||
}
|
||||
@@ -237,6 +239,7 @@ const thumbClasses = `block w-2.5 h-2.5 bg-brand
|
||||
|
||||
<span
|
||||
role="slider"
|
||||
bind:this={thumbEl}
|
||||
tabindex={disabled ? -1 : 0}
|
||||
aria-label="Value"
|
||||
aria-orientation="vertical"
|
||||
@@ -285,6 +288,7 @@ const thumbClasses = `block w-2.5 h-2.5 bg-brand
|
||||
|
||||
<span
|
||||
role="slider"
|
||||
bind:this={thumbEl}
|
||||
tabindex={disabled ? -1 : 0}
|
||||
aria-label="Value"
|
||||
aria-orientation="horizontal"
|
||||
|
||||
@@ -149,6 +149,15 @@ describe('Pointer', () => {
|
||||
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 () => {
|
||||
const { container } = render(Slider, { value: 0, min: 0, max: 100, orientation: 'vertical' });
|
||||
const track = container.querySelector('[role="presentation"]') as HTMLElement;
|
||||
|
||||
Reference in New Issue
Block a user