From f34dae6a187833c50491596ca6438d7c00a5e04c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nicole=20miko=C5=82ajczyk?= Date: Sat, 21 Feb 2026 15:28:53 +0100 Subject: [PATCH] nicolium: slider accessibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nicole mikołajczyk --- packages/pl-fe/src/components/ui/slider.tsx | 42 +++++++++++++++++++ .../pl-fe/src/components/ui/step-slider.tsx | 42 +++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/packages/pl-fe/src/components/ui/slider.tsx b/packages/pl-fe/src/components/ui/slider.tsx index 988db115a..80418695d 100644 --- a/packages/pl-fe/src/components/ui/slider.tsx +++ b/packages/pl-fe/src/components/ui/slider.tsx @@ -54,6 +54,42 @@ const Slider: React.FC = ({ value, onChange }) => { [node.current], ); + const handleKeyDown: React.KeyboardEventHandler = (event) => { + let nextValue: number | null = null; + + switch (event.key) { + case 'ArrowLeft': + case 'ArrowDown': + nextValue = value - 0.05; + break; + case 'ArrowRight': + case 'ArrowUp': + nextValue = value + 0.05; + break; + case 'PageDown': + case 'Home': + nextValue = 0; + break; + case 'PageUp': + case 'End': + nextValue = 1; + break; + default: + break; + } + + if (nextValue !== null) { + event.preventDefault(); + if (nextValue < 0) { + nextValue = 0; + } else if (nextValue > 1) { + nextValue = 1; + } + + onChange(nextValue); + } + }; + return (
= ({ value, onChange }) => { className='absolute top-1/2 z-10 -ml-1.5 size-3 -translate-y-1/2 rounded-full bg-accent-500 shadow' tabIndex={0} style={{ left: `${value * 100}%` }} + role='slider' + aria-valuemin={0} + aria-valuemax={1} + aria-valuenow={value} + aria-orientation='horizontal' + onKeyDown={handleKeyDown} />
); diff --git a/packages/pl-fe/src/components/ui/step-slider.tsx b/packages/pl-fe/src/components/ui/step-slider.tsx index 0d791ca6f..8193734d9 100644 --- a/packages/pl-fe/src/components/ui/step-slider.tsx +++ b/packages/pl-fe/src/components/ui/step-slider.tsx @@ -57,6 +57,42 @@ const StepSlider: React.FC = ({ value, steps, onChange }) => { [node.current], ); + const handleKeyDown: React.KeyboardEventHandler = (event) => { + let nextValue: number | null = null; + + switch (event.key) { + case 'ArrowLeft': + case 'ArrowDown': + nextValue = value - 1; + break; + case 'ArrowRight': + case 'ArrowUp': + nextValue = value + 1; + break; + case 'PageDown': + case 'Home': + nextValue = 0; + break; + case 'PageUp': + case 'End': + nextValue = steps - 1; + break; + default: + break; + } + + if (nextValue !== null) { + event.preventDefault(); + if (nextValue < 0) { + nextValue = 0; + } else if (nextValue > steps - 1) { + nextValue = steps - 1; + } + + onChange(nextValue); + } + }; + return (
= ({ value, steps, onChange }) => {