Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .jules/palette.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
**Learning:** Found instances where `<label>` elements were missing the `htmlFor` attribute and their corresponding `<input>` elements were missing `id` attributes. This breaks the semantic association required by screen readers and removes the click-to-focus functionality.
**Action:** When creating or modifying forms, always ensure that every `<label>` has an `htmlFor` attribute that exactly matches the `id` of its corresponding input field.

## 2024-05-18 - Missing ARIA Labels on Icon-Only Close Buttons
## 2026-05-18 - Missing ARIA Labels on Icon-Only Close Buttons
**Learning:** Found that custom `Close` buttons (like `<X />` icons) in application popovers or overlay widgets (like System Health and System Settings) frequently omit explicit `aria-label` and `title` attributes if they were implemented without using a standard accessible `Dialog` component.
**Action:** When auditing custom overlays and widgets, explicitly check the structural controls (like 'close', 'minimize', or 'refresh' icon buttons) for `aria-label` attributes to ensure they are accessible to screen readers.

Expand All @@ -106,7 +106,11 @@
**Learning:** Found multiple interactive `<button>` elements in user-facing components (`UserManagementPanel`, `UserMenuWidget`) that lacked keyboard focus indicators. This makes navigation via keyboard difficult for users relying on alternative inputs.
**Action:** When creating or maintaining new buttons, always append `focus-visible:ring-1 focus-visible:ring-[color] outline-none` to ensure standard keyboard accessibility across the UI.

## 2024-05-18 - Accordion Header Accessibility
## 2026-05-18 - Missing Focus States and ARIA Expansion Logic on NWS Alerts Dropdown
**Learning:** The NWS Alerts Widget had a custom dropdown button that toggled the display of weather alerts. While it functioned correctly with mouse clicks, it missed two crucial accessibility features: `aria-expanded` was not bound to the `expanded` state, meaning screen readers couldn't announce its toggle state, and it lacked the standard `focus-visible` ring utility classes, rendering it invisible to keyboard navigators when tabbed to.
**Action:** Always ensure custom dropdown or toggle buttons have `aria-expanded` and `aria-controls` explicitly set, and include keyboard focus indicators (`focus-visible:ring-1 focus-visible:ring-[color] outline-none`) that match the surrounding UI components.

## 2026-05-18 - Accordion Header Accessibility
**Learning:** Found an accordion header using a basic `div` with an `onClick` handler but lacking keyboard interaction and state announcement. Converting it to a real `<button>` risked layout breakages from browser defaults.
**Action:** Used `role="button"`, `tabIndex={0}`, `aria-expanded`, an explicit `onKeyDown` handler (Space + Enter), and `focus-visible` ring classes to safely enhance the `div` into an accessible interactive element without disrupting styles.

Expand Down
6 changes: 5 additions & 1 deletion frontend/src/components/widgets/NWSAlertsWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,10 @@ export function NWSAlertsWidget({ nwsAlerts, mission, onEvent, visible = true }:
{/* ── Header ── */}
<button
onClick={() => setExpanded((v) => !v)}
className={`flex items-center justify-between p-2.5 backdrop-blur-md text-left w-full border ${
aria-expanded={expanded}
aria-controls="nws-alerts-content"
aria-label="Toggle NWS Alerts"
className={`flex items-center justify-between p-2.5 backdrop-blur-md text-left w-full border focus-visible:ring-1 focus-visible:ring-amber-400 outline-none ${
expanded ? "rounded-t-sm border-b-0" : "rounded-sm"
}`}
style={{
Expand Down Expand Up @@ -210,6 +213,7 @@ export function NWSAlertsWidget({ nwsAlerts, mission, onEvent, visible = true }:
{/* ── Body ── */}
{expanded && (
<div
id="nws-alerts-content"
className="border border-t-0 bg-black/50 backdrop-blur-md rounded-b-sm"
style={{ borderColor: `${headerColor}25` }}
>
Expand Down