Add WCAG 2.1 Level AA accessibility across all components
A break timer designed to prevent RSI should be usable by people who already live with disabilities. This overhaul adds comprehensive accessibility without changing the visual design. Changes across 17 source files: - Global focus-visible outlines, sr-only utility, forced-colors support - prefers-reduced-motion kills all CSS animations AND JS Web Animations - All text upgraded to 4.5:1+ contrast ratio (WCAG AA) - Keyboard navigation for ColorPicker, Stepper, TimeSpinner - Screen reader: aria-live status regions, progressbar roles, labeled controls, sr-only chart data table, focus management on view changes - Focus trap on break screen, aria-hidden on decorative elements - Descriptive labels on all 25+ toggle/stepper instances in Settings - README updated with accessibility section and WCAG badge
This commit is contained in:
@@ -52,10 +52,28 @@
|
||||
};
|
||||
});
|
||||
|
||||
// Transition parameters
|
||||
const DURATION = 700;
|
||||
// Reduced motion preference
|
||||
let reducedMotion = $state(window.matchMedia("(prefers-reduced-motion: reduce)").matches);
|
||||
$effect(() => {
|
||||
const mq = window.matchMedia("(prefers-reduced-motion: reduce)");
|
||||
const handler = (e: MediaQueryListEvent) => { reducedMotion = e.matches; };
|
||||
mq.addEventListener("change", handler);
|
||||
return () => mq.removeEventListener("change", handler);
|
||||
});
|
||||
|
||||
// Transition parameters — zero when reduced motion active
|
||||
const DURATION = $derived(reducedMotion ? 0 : 700);
|
||||
const easing = cubicOut;
|
||||
|
||||
// Focus management: move focus to new view's heading on view change
|
||||
$effect(() => {
|
||||
const _view = effectiveView;
|
||||
requestAnimationFrame(() => {
|
||||
const heading = document.querySelector("h1[tabindex='-1']") as HTMLElement | null;
|
||||
heading?.focus({ preventScroll: true });
|
||||
});
|
||||
});
|
||||
|
||||
// When fullscreen_mode is OFF, the separate break window handles breaks,
|
||||
// so the main window should keep showing whatever view it was on (dashboard).
|
||||
const effectiveView = $derived(
|
||||
@@ -65,7 +83,7 @@
|
||||
);
|
||||
</script>
|
||||
|
||||
<div class="relative h-full bg-black">
|
||||
<main class="relative h-full bg-black">
|
||||
{#if $config.background_blobs_enabled}
|
||||
<BackgroundBlobs accentColor={$config.accent_color} breakColor={$config.break_color} />
|
||||
{/if}
|
||||
@@ -115,4 +133,4 @@
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
Reference in New Issue
Block a user