diff --git a/.jules/palette.md b/.jules/palette.md index 6bdec41c..a6c72a75 100644 --- a/.jules/palette.md +++ b/.jules/palette.md @@ -65,3 +65,7 @@ ## 2025-02-18 - Search Input Escape Key **Learning:** Users who heavily rely on keyboard navigation (and power users) experience friction when forced to backspace manually or switch to the mouse to click a "Clear" button after filtering a list. **Action:** Always provide an `Escape` key listener on search inputs to instantly clear the query and re-render the view, matching native OS text field behavior. + +## 2024-08-12 - Proxy native file inputs for consistent UX +**Learning:** In single-page applications, browsers natively suppress `change` events on `` if the user selects the same file path sequentially. Additionally, native file inputs have inconsistent cross-browser styling. +**Action:** Visually hide the native `` (using `sr-only`, `tabindex="-1"`, and `aria-hidden="true"`) and use a styled proxy ` +

@@ -320,6 +321,7 @@

Dashboard

} const fileInput = document.getElementById('file'); +document.getElementById('header-browse').addEventListener('click', () => fileInput.click()); fileInput.addEventListener('change', () => { const selectedFile = fileInput.files?.[0]; fileInput.value = ''; diff --git a/tests/test_dashboard_core.py b/tests/test_dashboard_core.py index aa4cbe73..e63378d9 100644 --- a/tests/test_dashboard_core.py +++ b/tests/test_dashboard_core.py @@ -66,13 +66,23 @@ def test_dashboard_rows_are_keyboard_accessible(): assert 'tabindex="0" role="button"' in html assert 'title="View details for finding"' in html assert "tbody tr:focus-visible" in html - assert "aria-label=\"Upload findings file\"" in html assert "aria-label=\"Search findings\"" in html assert "aria-label=\"Filter by severity\"" in html assert "tr.addEventListener('keydown'" in html assert "e.key === 'Enter' || e.key === ' '" in html +def test_dashboard_upload_proxy_preserves_accessible_file_selection_contract(): + """The styled upload control must remain a real button wired to the hidden input.""" + html = dashboard_index_path().read_text(encoding="utf-8") + + assert '