Skip to content
Closed
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
3 changes: 3 additions & 0 deletions .Jules/palette.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 2025-02-23 - Accessible Collapsible Sections and Screen Reader Noise Reduction
**Learning:** When creating collapsible UI sections (like "What do these numbers mean?"), it's crucial to semantically link the toggle button to the content container using `aria-controls="[id]"` and `aria-expanded={boolean}` so screen readers understand the relationship. Additionally, visual-only decorative elements and instructional text that is evident visually but redundant to the component's functionality (e.g. `β€” click to expand`) should be hidden from screen readers using `aria-hidden="true"` to reduce cognitive load and noise.
**Action:** Always verify that custom disclose/expand widgets have an explicit `id` on the target container, `aria-controls` on the button, and properly synced `aria-expanded`. Audit buttons with complex inner HTML and apply `aria-hidden="true"` to spans that are purely visual or decorative.
11 changes: 8 additions & 3 deletions packages/web/src/components/dashboard/overview-stats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ function StatTile({ label, value, valueTone = 'default', subtext }: StatTileProp
)
}

import { useId } from 'react'

export function OverviewStats({
periodLabel,
sessions,
Expand All @@ -56,6 +58,7 @@ export function OverviewStats({
rangeSelector,
}: OverviewStatsProps) {
const [expanded, setExpanded] = useState(false)
const detailsId = useId()

return (
<div className="rounded-xl bg-card ring-1 ring-foreground/10 p-4 sm:p-5">
Expand Down Expand Up @@ -85,15 +88,17 @@ export function OverviewStats({
<button
type="button"
onClick={() => setExpanded(v => !v)}
aria-expanded={expanded}
aria-controls={detailsId}
className="mt-4 flex items-center gap-2 text-xs text-muted-foreground hover:text-foreground transition-colors"
>
<span className={cn('inline-block transition-transform', expanded && 'rotate-90')}>β–Έ</span>
<span aria-hidden="true" className={cn('inline-block transition-transform', expanded && 'rotate-90')}>β–Έ</span>
<span className="font-medium text-foreground">What do these numbers mean?</span>
<span>β€” {expanded ? 'click to collapse' : 'click to expand'}</span>
<span aria-hidden="true">β€” {expanded ? 'click to collapse' : 'click to expand'}</span>
</button>

{expanded && (
<div className="mt-3 text-xs text-muted-foreground space-y-2 leading-relaxed">
<div id={detailsId} className="mt-3 text-xs text-muted-foreground space-y-2 leading-relaxed">
<p>
<span className="font-medium text-foreground">Sessions</span> β€” νŒ€μ›λ“€μ΄ μ‹œμž‘ν•œ Claude Code μ„Έμ…˜ 수.
</p>
Expand Down
Loading