a11y(measurements): aria-controls on drill-down chevron

Thread aria-controls from the cumulative-type expand/collapse chevron
to the per-day drill-down container so screen readers can jump from
the disclosure button to the disclosed content. Uses dayKey-derived
stable ids on both desktop (TableRow) and mobile (wrapper div)
layouts; falls back to row id when ungrouped.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Marc-André BombeckandClaude Opus 4.7 committed 2026-05-17 17:11:22 +02:00
1 parent feae5b5215
commit 1fd76f2607
1 file changed
+18 -7
@@ -525,6 +525,11 @@ export function MeasurementList({ onEdit, onAddFirst }: MeasurementListProps) {
const isExpanded = isGrouped
? expandedDayKeys.has(m.dayKey as string)
: false;
// v1.4.38 W-D P1-1 — stable drill-down id so the
// disclosure chevron can thread aria-controls to the
// expanded panel. dayKey is unique per row when
// grouped; fall back to m.id otherwise.
const drilldownId = `drilldown-desktop-${m.dayKey ?? m.id}`;
return (
<Fragment key={m.id}>
<TableRow>
@@ -585,6 +590,7 @@ export function MeasurementList({ onEdit, onAddFirst }: MeasurementListProps) {
toggleExpand(m.dayKey as string)
}
aria-expanded={isExpanded}
aria-controls={drilldownId}
aria-label={
isExpanded
? t("measurements.collapseDay")
@@ -617,7 +623,7 @@ export function MeasurementList({ onEdit, onAddFirst }: MeasurementListProps) {
</TableCell>
</TableRow>
{isGrouped && isExpanded && (
<TableRow>
<TableRow id={drilldownId}>
<TableCell colSpan={6} className="p-0">
<DayDrillDown
type={m.type}
@@ -644,6 +650,8 @@ export function MeasurementList({ onEdit, onAddFirst }: MeasurementListProps) {
const isExpanded = isGrouped
? expandedDayKeys.has(m.dayKey as string)
: false;
// v1.4.38 W-D P1-1 — see desktop counterpart.
const drilldownId = `drilldown-mobile-${m.dayKey ?? m.id}`;
return (
<div
key={m.id}
@@ -712,6 +720,7 @@ export function MeasurementList({ onEdit, onAddFirst }: MeasurementListProps) {
data-testid="measurement-day-expand"
onClick={() => toggleExpand(m.dayKey as string)}
aria-expanded={isExpanded}
aria-controls={drilldownId}
aria-label={
isExpanded
? t("measurements.collapseDay")
@@ -742,12 +751,14 @@ export function MeasurementList({ onEdit, onAddFirst }: MeasurementListProps) {
</div>
</div>
{isGrouped && isExpanded && (
<DayDrillDown
type={m.type}
dayKey={m.dayKey as string}
unit={m.unit}
layout="mobile"
/>
<div id={drilldownId}>
<DayDrillDown
type={m.type}
dayKey={m.dayKey as string}
unit={m.unit}
layout="mobile"
/>
</div>
)}
</div>
);