Skip to content

Commit 03f4514

Browse files
committed
fix(toggle): commits immediately with reduced motion
When `prefers-reduced-motion` is active, the tracker's transition duration becomes 0ms. This can prevent the `transitionend` event from firing, leaving the toggler in a pending state and preventing it from committing the new selection or navigating. Committing immediately in this scenario ensures the toggler functions correctly for users with reduced motion preferences.
1 parent 7d60547 commit 03f4514

1 file changed

Lines changed: 25 additions & 9 deletions

File tree

projects/client/src/lib/components/toggles/Toggler.svelte

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,11 @@
2727
let trackerElement: HTMLDivElement;
2828
let pending = $state<{ index: number; href?: string } | null>(null);
2929
30-
const handleChange = (index: number, href?: string) => {
31-
pending = { index, href };
32-
trackerIndex.set(index);
33-
trackerElement?.classList.add("moving");
34-
};
35-
36-
const handleTransitionEnd = (event: TransitionEvent) => {
37-
if (event.propertyName === "opacity" || !pending) return;
30+
const prefersReducedMotion = () =>
31+
globalThis.matchMedia("(prefers-reduced-motion: reduce)").matches;
3832
39-
(event.currentTarget as HTMLDivElement).classList.remove("moving");
33+
const commit = () => {
34+
if (!pending) return;
4035
4136
const { index, href } = pending;
4237
pending = null;
@@ -49,6 +44,27 @@
4944
}
5045
};
5146
47+
const handleChange = (index: number, href?: string) => {
48+
pending = { index, href };
49+
trackerIndex.set(index);
50+
51+
// With reduced motion the tracker transition is 0ms, so transitionend
52+
// never fires - commit immediately instead of waiting for it.
53+
if (prefersReducedMotion()) {
54+
commit();
55+
return;
56+
}
57+
58+
trackerElement?.classList.add("moving");
59+
};
60+
61+
const handleTransitionEnd = (event: TransitionEvent) => {
62+
if (event.propertyName === "opacity" || !pending) return;
63+
64+
(event.currentTarget as HTMLDivElement).classList.remove("moving");
65+
commit();
66+
};
67+
5268
const getTriggerProps = (option: ToggleOption<T>, index: number) => {
5369
if (option.href) {
5470
return {

0 commit comments

Comments
 (0)