Skip to content

Commit 9555fd1

Browse files
fix: validate and clamp sidebar width read from localStorage (#152)
* fix: add periodic health polling to prevent stale sidebar status dots checkConnectionHealth was defined but never called after init(). Add a 30s setInterval useEffect so health status updates automatically without requiring a page refresh. Fixes #144 * fix: add aria-labels to Toolbar icon-only buttons for screen reader accessibility View mode and theme dropdown triggers had aria-haspopup/aria-expanded but no aria-label — screen readers announced them as generic 'button'. Decorative SVG icons and color dots inside buttons were also read aloud causing double-announcement. Changes: - Add dynamic aria-label to view mode dropdown trigger - Add dynamic aria-label to theme dropdown trigger - Add aria-hidden to decorative icons inside view/theme dropdowns - Add aria-hidden to ChevronIcon in both dropdown triggers - Add aria-hidden to color dot divs in theme dropdown items Fixes #143 * fix: make global search results keyboard navigable Search result divs had onClick but no role, tabIndex, or onKeyDown. Keyboard-only users could not Tab to results or activate them. - Add role=button to each result div - Add tabIndex=0 to make results focusable via Tab - Add onKeyDown handler for Enter and Space keys - Add aria-label announcing table name and match count - Add cursor:pointer for visual consistency Fixes #142 * fix: add role=alert to write-mode warning banner for screen readers Warning banner had no ARIA live region — screen readers silently ignored it, leaving visually impaired users unaware they were in a mode allowing destructive database operations. - Add role=alert to the warning banner div - Add aria-live=assertive to interrupt and announce immediately - Add aria-atomic=true to read the full message as one unit - Add aria-hidden=true to the decorative AlertTriangleIcon Fixes #141 * fix: validate and clamp sidebar width read from localStorage parseInt() result was used directly with no validation. Corrupted values like 'abc' produced NaN causing layout collapse. Out-of-range values like 9999 caused sidebar to fill entire viewport. - Parse to int then guard with isNaN() fallback to 240 - Clamp between 180-480px to match drag handler validation logic Fixes #140 * fix: add 300ms debounce to global search to prevent per-keystroke API calls Global search fired a fetch on every keystroke with no debounce. Typing a 5-character word sent 5 separate requests causing unnecessary backend load and potential race conditions. - Wrap fetch in setTimeout(300ms) - Return clearTimeout as cleanup to cancel pending request on each keystroke - Move setGlobalSearchLoading(true) before timeout for instant UI feedback Fixes #139
1 parent f42095b commit 9555fd1

1 file changed

Lines changed: 2 additions & 1 deletion

File tree

frontend/src/App.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,8 @@ export default function App() {
162162
useState(false);
163163
const [sidebarWidth, setSidebarWidth] = useState(() => {
164164
const stored = localStorage.getItem("dbportal-sidebar-width");
165-
return stored ? parseInt(stored, 10) : 240;
165+
const parsed = stored ? parseInt(stored, 10) : 240;
166+
return isNaN(parsed) ? 240 : Math.max(180, Math.min(480, parsed));
166167
});
167168

168169
const handleSidebarMouseDown = useCallback(

0 commit comments

Comments
 (0)