From b355594958790cb1ff9be5a557fbe58fb692091b Mon Sep 17 00:00:00 2001 From: Doxa Maps Date: Mon, 28 Sep 2026 19:41:26 +0000 Subject: [PATCH] The mobile legend's toggles announce their state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every toggle in this file carried aria-label="aria.toggleLegend" and no aria-expanded, so a screen-reader user was told the control is a toggle and never told whether the legend was open or closed. SemanticTreeLegend has had this right all along; this is the copy that drifted, and it drifted on whether the control is usable without sight rather than on how it looks. gospel found it while measuring four implementations of the same control. I verified it here before changing anything rather than taking the report: zero occurrences of aria-expanded against four toggle labels. One computed drives all four buttons, so they cannot disagree with each other about a state they all describe — which is the same failure, one level down, as four files disagreeing about the control. This is the accessibility half of the C11 collapse-caret promotion and does not wait for it: the promotion is a refactor, this is a defect. --- library/components/legends/LegendMobile.vue | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/library/components/legends/LegendMobile.vue b/library/components/legends/LegendMobile.vue index b274bae81..6c02fda59 100644 --- a/library/components/legends/LegendMobile.vue +++ b/library/components/legends/LegendMobile.vue @@ -539,6 +539,16 @@ const justDragged = () => Date.now() - lastDragEndAt < 400 // Computed properties from stores const legendState = computed(() => uiStore.legendState) +/** + * ★ WHAT THE CARET ANNOUNCES. Every toggle in this file carried aria-label="aria.toggleLegend" and + * NO aria-expanded, so a screen-reader user was told the control is a toggle and never told its + * STATE — they could not hear whether the legend was open or closed. SemanticTreeLegend has had + * this right all along; this is the copy that drifted, and it drifted on whether the control is + * usable without sight rather than on decoration. gospel found it while measuring four + * implementations of the same control; I verified it here before changing anything: 0 occurrences + * of aria-expanded against 4 toggle labels. + */ +const legendExpanded = computed(() => legendState.value !== 'collapsed') const legendHeight = computed(() => uiStore.legendHeight) const caretRotation = computed(() => uiStore.caretRotation) const showPullTab = computed(() => uiStore.showPullTab) @@ -796,6 +806,7 @@ onBeforeUnmount(() => { v-if="legendMode === 'detail' && legendState !== 'collapsed'" class="detail-collapse-btn-mobile" @click.stop="handleCaretClick" + :aria-expanded="String(legendExpanded)" :aria-label="t('aria.toggleLegend')" > @@ -825,7 +836,8 @@ onBeforeUnmount(() => { >