fix(ui): keep the voice highlight on layer rows

Toggle the count-line modifier with a directive that leaves other classes alone, so a re-render no longer clears gev-voice-focus.
This commit is contained in:
Sameh Khamis committed 2026-10-30 23:56:20 -07:00
1 parent 231ac4b67b
commit dc9d200725
4 files changed
+65 -4

No files matched your search

+3
View File
@@ -552,6 +552,7 @@
"src/ui/railCardBlocks.js",
"src/ui/layerRowText.js",
"src/ui/layerPanel/LayerRows.vue",
"src/ui/rail/classToggle.js",
"src/ui/layerPanel/RowText.vue",
"src/ui/railTimeline.js",
"src/ui/clearLayersControl.js",
@@ -857,6 +858,7 @@
"src/ui/railCardBlocks.js",
"src/ui/layerRowText.js",
"src/ui/layerPanel/LayerRows.vue",
"src/ui/rail/classToggle.js",
"src/ui/layerPanel/RowText.vue",
"src/ui/railTimeline.js",
"src/ui/layers.js",
@@ -2553,6 +2555,7 @@
"src/ui/railCardBlocks.js",
"src/ui/layerRowText.js",
"src/ui/layerPanel/LayerRows.vue",
"src/ui/rail/classToggle.js",
"src/ui/layerPanel/RowText.vue",
"src/ui/railTimeline.js",
"src/ui/layers.js",
+5 -4
View File
@@ -2,6 +2,7 @@
import RailChips from '../rail/RailChips.vue';
import RailRowList from '../rail/RailRowList.vue';
import RowText from './RowText.vue';
import { vClassToggle } from '../rail/classToggle.js';
// The data layer rows under their group headings. LayerPanel presents every
// value; clicks reach it with the layer id, and it re-reads the live
@@ -21,10 +22,10 @@ defineProps({
}}</h3
><div
v-else
:class="[
'data-toggle-row',
{ 'data-toggle-row--count-line': item.count?.countLine },
]"
class="data-toggle-row"
v-class-toggle="{
'data-toggle-row--count-line': item.count?.countLine,
}"
:data-layer-id="item.id"
:data-layer-name="item.englishName"
><div class="data-toggle-top"
+46
View File
@@ -0,0 +1,46 @@
// src/ui/layerPanel/layerRows.test.mjs — a layer row's own classes change
// without wiping classes other code adds, such as the voice highlight.
import '../../testSupport/registerDom.mjs';
import test from 'node:test';
import assert from 'node:assert/strict';
import { h, render } from 'vue';
import LayerRows from './LayerRows.vue';
const row = (countLine) => ({
key: 'flights',
id: 'flights',
englishName: 'Flights',
icon: 'flight',
name: 'Flights',
meta: '',
toggle: {
classes: [],
text: 'OFF',
ariaLabel: 'Flights',
title: '',
ariaBusy: 'false',
ariaDisabled: 'false',
feedState: '',
},
count: { countLine, text: '12', empty: false },
controls: null,
});
test('the count-line class toggles without dropping the voice highlight', () => {
document.body.replaceChildren();
const container = document.body.appendChild(document.createElement('div'));
render(h(LayerRows, { items: [row(false)] }), container);
const element = container.querySelector('[data-layer-id="flights"]');
assert.equal(element.className, 'data-toggle-row');
element.classList.add('gev-voice-focus');
render(h(LayerRows, { items: [row(true)] }), container);
assert.equal(element.classList.contains('data-toggle-row--count-line'), true);
assert.equal(element.classList.contains('gev-voice-focus'), true);
render(h(LayerRows, { items: [row(false)] }), container);
assert.equal(element.classList.contains('data-toggle-row--count-line'), false);
assert.equal(element.classList.contains('gev-voice-focus'), true);
assert.equal(element.classList.contains('data-toggle-row'), true);
render(null, container);
});
+11
View File
@@ -0,0 +1,11 @@
/**
* `v-class-toggle`: toggles each named class with `classList`, so classes other
* code adds to the element (a voice highlight) survive a re-render. A `:class`
* binding rewrites the whole `className` instead.
*/
const apply = (el, { value }) => {
for (const [name, on] of Object.entries(value || {}))
if (el.classList.contains(name) !== Boolean(on))
el.classList.toggle(name, Boolean(on));
};
export const vClassToggle = { mounted: apply, updated: apply };