From 642f7546855891648a1281504384eead1567687d Mon Sep 17 00:00:00 2001 From: Vishal Dipake Date: Sat, 17 Oct 2026 13:38:37 +0530 Subject: [PATCH 1/2] fix(editor): improve control accessibility --- src/components/editor/ColorPicker.tsx | 16 ++++++++++++-- src/components/editor/FontSelector.tsx | 22 ++++++++++++++----- src/components/editor/ImageUploader.tsx | 28 +++++++++++++++++++------ src/components/editor/SliderControl.tsx | 18 ++++++++++++++-- src/components/editor/ToggleSwitch.tsx | 12 +++++++++-- src/styles/editor.css | 19 +++++++++++++++++ 6 files changed, 98 insertions(+), 17 deletions(-) diff --git a/src/components/editor/ColorPicker.tsx b/src/components/editor/ColorPicker.tsx index e88d89d..8864f65 100644 --- a/src/components/editor/ColorPicker.tsx +++ b/src/components/editor/ColorPicker.tsx @@ -1,3 +1,5 @@ +import { useId } from "react"; + interface ColorPickerProps { label: string; value: string; @@ -5,20 +7,30 @@ interface ColorPickerProps { } export function ColorPicker({ label, value, onChange }: ColorPickerProps) { - const displayValue = value.startsWith('#') ? value : `#${value}`; + const id = useId(); + const colorId = `${id}-color`; + const hexId = `${id}-hex`; + const displayValue = value.startsWith("#") ? value : `#${value}`; return (
- + +
onChange(e.target.value)} /> + onChange(e.target.value)} diff --git a/src/components/editor/FontSelector.tsx b/src/components/editor/FontSelector.tsx index 4aa2d2f..8e9e9ec 100644 --- a/src/components/editor/FontSelector.tsx +++ b/src/components/editor/FontSelector.tsx @@ -1,3 +1,5 @@ +import { useId } from "react"; + interface FontSelectorProps { label: string; value: string; @@ -6,18 +8,28 @@ interface FontSelectorProps { } const defaultFontOptions = [ - { label: 'Inter', value: 'Inter' }, - { label: 'Playfair Display', value: 'Playfair Display' }, - { label: 'JetBrains Mono', value: 'JetBrains Mono' }, + { label: "Inter", value: "Inter" }, + { label: "Playfair Display", value: "Playfair Display" }, + { label: "JetBrains Mono", value: "JetBrains Mono" }, ]; -export function FontSelector({ label, value, onChange, options }: FontSelectorProps) { +export function FontSelector({ + label, + value, + onChange, + options, +}: FontSelectorProps) { + const id = useId(); const opts = options || defaultFontOptions; return (
- + + onChange(e.target.value)} placeholder="Image URL or upload..." /> -
); diff --git a/src/components/editor/SliderControl.tsx b/src/components/editor/SliderControl.tsx index 09cb0a2..2a73c09 100644 --- a/src/components/editor/SliderControl.tsx +++ b/src/components/editor/SliderControl.tsx @@ -1,3 +1,5 @@ +import { useId } from "react"; + interface SliderControlProps { label: string; value: number; @@ -6,14 +8,26 @@ interface SliderControlProps { max?: number; } -export function SliderControl({ label, value, onChange, min = 0, max = 100 }: SliderControlProps) { +export function SliderControl({ + label, + value, + onChange, + min = 0, + max = 100, +}: SliderControlProps) { + const id = useId(); + return (
- + {value}
+ - + + {label} + + diff --git a/src/styles/editor.css b/src/styles/editor.css index 83453f2..45d78d3 100644 --- a/src/styles/editor.css +++ b/src/styles/editor.css @@ -551,6 +551,25 @@ } /* Upload Button */ + +.editor-file-input { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip-path: inset(50%); + white-space: nowrap; + border: 0; +} + +.editor-file-input:focus-visible + .editor-upload-btn { + outline: 2px solid var(--border-strong); + outline-offset: 3px; +} + + .editor-upload-btn { display: inline-flex; align-items: center; From d466716ff7993f4f4ca9d37b94b601442b275c7f Mon Sep 17 00:00:00 2001 From: Vishal Dipake Date: Mon, 19 Oct 2026 11:57:20 +0530 Subject: [PATCH 2/2] fix(editor): address accessibility review feedback --- src/components/editor/ColorPicker.tsx | 4 ++-- src/components/editor/FontSelector.tsx | 15 +++++---------- src/components/editor/ImageUploader.tsx | 6 +++--- src/components/editor/SliderControl.tsx | 10 ++-------- src/components/editor/ToggleSwitch.tsx | 6 +++--- src/styles/editor.css | 7 ++----- 6 files changed, 17 insertions(+), 31 deletions(-) diff --git a/src/components/editor/ColorPicker.tsx b/src/components/editor/ColorPicker.tsx index 8864f65..413e82a 100644 --- a/src/components/editor/ColorPicker.tsx +++ b/src/components/editor/ColorPicker.tsx @@ -1,4 +1,4 @@ -import { useId } from "react"; +import { useId } from 'react'; interface ColorPickerProps { label: string; @@ -10,7 +10,7 @@ export function ColorPicker({ label, value, onChange }: ColorPickerProps) { const id = useId(); const colorId = `${id}-color`; const hexId = `${id}-hex`; - const displayValue = value.startsWith("#") ? value : `#${value}`; + const displayValue = value.startsWith('#') ? value : `#${value}`; return (
diff --git a/src/components/editor/FontSelector.tsx b/src/components/editor/FontSelector.tsx index 8e9e9ec..17dd912 100644 --- a/src/components/editor/FontSelector.tsx +++ b/src/components/editor/FontSelector.tsx @@ -1,4 +1,4 @@ -import { useId } from "react"; +import { useId } from 'react'; interface FontSelectorProps { label: string; @@ -8,17 +8,12 @@ interface FontSelectorProps { } const defaultFontOptions = [ - { label: "Inter", value: "Inter" }, - { label: "Playfair Display", value: "Playfair Display" }, - { label: "JetBrains Mono", value: "JetBrains Mono" }, + { label: 'Inter', value: 'Inter' }, + { label: 'Playfair Display', value: 'Playfair Display' }, + { label: 'JetBrains Mono', value: 'JetBrains Mono' }, ]; -export function FontSelector({ - label, - value, - onChange, - options, -}: FontSelectorProps) { +export function FontSelector({ label, value, onChange, options }: FontSelectorProps) { const id = useId(); const opts = options || defaultFontOptions; diff --git a/src/components/editor/ImageUploader.tsx b/src/components/editor/ImageUploader.tsx index 24274e0..ad9e736 100644 --- a/src/components/editor/ImageUploader.tsx +++ b/src/components/editor/ImageUploader.tsx @@ -1,4 +1,4 @@ -import { useCallback, useId } from "react"; +import { useCallback, useId } from 'react'; interface ImageUploaderProps { label: string; @@ -18,13 +18,13 @@ export function ImageUploader({ label, value, onChange }: ImageUploaderProps) { const reader = new FileReader(); reader.onload = () => { - if (typeof reader.result === "string") { + if (typeof reader.result === 'string') { onChange(reader.result); } }; reader.readAsDataURL(file); }, - [onChange], + [onChange] ); return ( diff --git a/src/components/editor/SliderControl.tsx b/src/components/editor/SliderControl.tsx index 2a73c09..44890fc 100644 --- a/src/components/editor/SliderControl.tsx +++ b/src/components/editor/SliderControl.tsx @@ -1,4 +1,4 @@ -import { useId } from "react"; +import { useId } from 'react'; interface SliderControlProps { label: string; @@ -8,13 +8,7 @@ interface SliderControlProps { max?: number; } -export function SliderControl({ - label, - value, - onChange, - min = 0, - max = 100, -}: SliderControlProps) { +export function SliderControl({ label, value, onChange, min = 0, max = 100 }: SliderControlProps) { const id = useId(); return ( diff --git a/src/components/editor/ToggleSwitch.tsx b/src/components/editor/ToggleSwitch.tsx index 15dbef2..1cd7e9e 100644 --- a/src/components/editor/ToggleSwitch.tsx +++ b/src/components/editor/ToggleSwitch.tsx @@ -1,4 +1,4 @@ -import { useId } from "react"; +import { useId } from 'react'; interface ToggleSwitchProps { label: string; @@ -17,11 +17,11 @@ export function ToggleSwitch({ label, value, onChange }: ToggleSwitchProps) { diff --git a/src/styles/editor.css b/src/styles/editor.css index 45d78d3..06f8c7b 100644 --- a/src/styles/editor.css +++ b/src/styles/editor.css @@ -549,9 +549,7 @@ cursor: pointer; box-shadow: var(--shadow-sm); } - /* Upload Button */ - .editor-file-input { position: absolute; width: 1px; @@ -565,11 +563,10 @@ } .editor-file-input:focus-visible + .editor-upload-btn { - outline: 2px solid var(--border-strong); - outline-offset: 3px; + outline: 2px solid var(--accent-primary); + outline-offset: 2px; } - .editor-upload-btn { display: inline-flex; align-items: center;