Merge pull request #28 from AEmotionStudio/palette-accessibility-focus-2231388305888170951
🎨 Palette: Improve keyboard accessibility for sidebar settings
This commit is contained in:
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
Reference in New Issue
Block a user