Keep the reader's legend choice across a resize

Every width change reset the legend from the breakpoint, so opening the decoder
on a phone lost it on rotation, and closing it on a wide window reopened it by
dragging the edge. The resize was undoing the reader's decision rather than
responding to it.

The width now decides only until the reader does. After that their choice holds
at both widths.

This is the same defect fixed in the other plugin's legend earlier today, written
again here a few hours later, because the two legends are separate
implementations of one control and only one of them had learned. That is the
argument for promoting the control, not for being more careful next time.
This commit is contained in:
Doxa Maps 2026-09-28 19:37:25 +00:00
parent 7617c23f0c
commit a0f5a9d8e4

View file

@ -42,7 +42,19 @@ const activeRing = ref(null)
const narrow = ref(false)
const legendOpen = ref(true)
let mq = null
function applyWidth(m) { narrow.value = m.matches; legendOpen.value = !m.matches }
// ★ A DELIBERATE CHOICE SURVIVES A RESIZE. The first version of this set legendOpen from the
// breakpoint on EVERY width change, so a reader who opened the decoder on a phone lost it on
// rotation, and one who closed it on desktop had it reopened by dragging the window. The resize
// would be undoing their decision rather than responding to it.
// This is the same defect I had already fixed in the other plugin's legend today and then wrote
// again here, because the two legends are separate implementations of one control. That is the
// case for promoting the control rather than a reason to be more careful.
let chosen = null // null = the reader has not decided yet
function applyWidth(m) {
narrow.value = m.matches
legendOpen.value = chosen == null ? !m.matches : chosen
}
function setLegendOpen(v) { chosen = v; legendOpen.value = v }
onMounted(() => {
try {
mq = window.matchMedia('(max-width: 900px)')
@ -151,7 +163,7 @@ useShadowStyles(
</div>
<div class="gcs-aside" :class="{ collapsed: narrow && !legendOpen }">
<button v-if="narrow" type="button" class="gcs-legend-toggle"
:aria-expanded="String(legendOpen)" @click="legendOpen = !legendOpen">
:aria-expanded="String(legendOpen)" @click="setLegendOpen(!legendOpen)">
<!-- Existing keys only. A new "hide" string would have meant a new catalogue entry in
eleven locales, owned by another tab, landing in another batch — a cross-owner
dependency bought for one word. aria.collapseLegend already exists everywhere and