Merge pull request #28 from AEmotionStudio/palette-accessibility-focus-2231388305888170951

🎨 Palette: Improve keyboard accessibility for sidebar settings
This commit is contained in:
Æmotion Studio
2026-01-18 21:13:06 -08:00
committed by GitHub
5 changed files with 73 additions and 2 deletions
+3
View File
@@ -0,0 +1,3 @@
## 2024-05-22 - Custom UI Component Focus States
**Learning:** Custom UI components (like divs acting as buttons/toggles) lack native focus indicators, making keyboard navigation invisible and confusing.
**Action:** Always add explicit `:focus-visible` styles to custom interactive elements in CSS to ensure keyboard users can see where they are.
+33 -1
View File
@@ -62,6 +62,12 @@
background: rgba(255, 255, 255, 0.06);
}
.magnify-sidebar-section-header:focus-visible {
outline: 2px solid var(--p-primary-color, #3b82f6);
outline-offset: -2px;
background: rgba(255, 255, 255, 0.06);
}
.magnify-sidebar-section-header svg {
width: 12px;
height: 12px;
@@ -125,6 +131,11 @@
cursor: pointer;
}
.magnify-slider:focus-visible {
outline: 2px solid var(--p-primary-color, #3b82f6);
outline-offset: 2px;
}
.magnify-slider::-webkit-slider-thumb {
appearance: none;
width: 14px;
@@ -171,6 +182,11 @@
transition: background 0.2s;
}
.magnify-toggle:focus-visible {
outline: 2px solid var(--p-primary-color, #3b82f6);
outline-offset: 2px;
}
.magnify-toggle.active {
background: var(--p-primary-color, #3b82f6);
}
@@ -212,6 +228,11 @@
border-color: var(--p-primary-color, #3b82f6);
}
.magnify-select:focus-visible {
outline: 2px solid var(--p-primary-color, #3b82f6);
border-color: var(--p-primary-color, #3b82f6);
}
/* Inspector styles */
.magnify-inspector-section {
padding: 12px 16px;
@@ -305,6 +326,12 @@
transform: scale(0.98);
}
.magnify-btn:focus-visible {
outline: 2px solid white;
outline-offset: -2px;
box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.5);
}
.magnify-btn-secondary {
background: rgba(255, 255, 255, 0.1);
}
@@ -336,6 +363,11 @@
background: transparent;
}
.magnify-color-input:focus-visible {
outline: 2px solid var(--p-primary-color, #3b82f6);
outline-offset: 2px;
}
.magnify-color-input::-webkit-color-swatch-wrapper {
padding: 2px;
}
@@ -349,4 +381,4 @@
font-size: 11px;
font-family: monospace;
color: var(--descrip-text, #999);
}
}
+2
View File
@@ -71,6 +71,7 @@ export function createSlider(
slider.max = String(max);
slider.step = String(step);
slider.value = String(value);
slider.setAttribute('aria-valuetext', `${value}${unit}`);
// Prevent ComfyUI from capturing mouse events during drag
slider.addEventListener('mousedown', (e) => e.stopPropagation());
@@ -81,6 +82,7 @@ export function createSlider(
e.stopPropagation();
const newValue = parseFloat(slider.value);
valueEl.textContent = `${newValue}${unit}`;
slider.setAttribute('aria-valuetext', `${newValue}${unit}`);
if (onInput) onInput(newValue);
});
+33 -1
View File
@@ -62,6 +62,12 @@
background: rgba(255, 255, 255, 0.06);
}
.magnify-sidebar-section-header:focus-visible {
outline: 2px solid var(--p-primary-color, #3b82f6);
outline-offset: -2px;
background: rgba(255, 255, 255, 0.06);
}
.magnify-sidebar-section-header svg {
width: 12px;
height: 12px;
@@ -125,6 +131,11 @@
cursor: pointer;
}
.magnify-slider:focus-visible {
outline: 2px solid var(--p-primary-color, #3b82f6);
outline-offset: 2px;
}
.magnify-slider::-webkit-slider-thumb {
appearance: none;
width: 14px;
@@ -171,6 +182,11 @@
transition: background 0.2s;
}
.magnify-toggle:focus-visible {
outline: 2px solid var(--p-primary-color, #3b82f6);
outline-offset: 2px;
}
.magnify-toggle.active {
background: var(--p-primary-color, #3b82f6);
}
@@ -212,6 +228,11 @@
border-color: var(--p-primary-color, #3b82f6);
}
.magnify-select:focus-visible {
outline: 2px solid var(--p-primary-color, #3b82f6);
border-color: var(--p-primary-color, #3b82f6);
}
/* Inspector styles */
.magnify-inspector-section {
padding: 12px 16px;
@@ -305,6 +326,12 @@
transform: scale(0.98);
}
.magnify-btn:focus-visible {
outline: 2px solid white;
outline-offset: -2px;
box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.5);
}
.magnify-btn-secondary {
background: rgba(255, 255, 255, 0.1);
}
@@ -336,6 +363,11 @@
background: transparent;
}
.magnify-color-input:focus-visible {
outline: 2px solid var(--p-primary-color, #3b82f6);
outline-offset: 2px;
}
.magnify-color-input::-webkit-color-swatch-wrapper {
padding: 2px;
}
@@ -349,4 +381,4 @@
font-size: 11px;
font-family: monospace;
color: var(--descrip-text, #999);
}
}
+2
View File
@@ -27,6 +27,7 @@ function createSlider(label, value, min, max, step, unit, onChange, tooltip, onI
slider.max = String(max);
slider.step = String(step);
slider.value = String(value);
slider.setAttribute("aria-valuetext", `${value}${unit}`);
slider.addEventListener("mousedown", (e) => e.stopPropagation());
slider.addEventListener("touchstart", (e) => e.stopPropagation());
slider.addEventListener("pointerdown", (e) => e.stopPropagation());
@@ -34,6 +35,7 @@ function createSlider(label, value, min, max, step, unit, onChange, tooltip, onI
e.stopPropagation();
const newValue = parseFloat(slider.value);
valueEl.textContent = `${newValue}${unit}`;
slider.setAttribute("aria-valuetext", `${newValue}${unit}`);
if (onInput) onInput(newValue);
});
slider.addEventListener("change", (e) => {