diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f276b151..d32717dbd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,7 +65,10 @@ what the answering action returned. The Display, Radio, RTL-SDR, Cockpit, mission replay and style parameter sliders are the kit's `UiSlider`, a native range input that emits numbers, and the pressed toggles are the - kit's `UiButton`, which gains `pressedClass`. `syncScopeControls` + kit's `UiButton`, which gains `pressedClass`; so are the rail card + chips, map source chips and location pills (which now report + `aria-pressed`), and the voice card's chips + are the kit's new `UiChip`. `syncScopeControls` (`./ui/display`) and `shouldHideCollapsedRightPanels` (`./ui/layout`) are deprecated: the Display view and the rail now own what they did. `./ui/input` imports Vue (samehkhamis). diff --git a/docs/VUE-MIGRATION.md b/docs/VUE-MIGRATION.md index 0aeec0ac2..d5fbc63fa 100644 --- a/docs/VUE-MIGRATION.md +++ b/docs/VUE-MIGRATION.md @@ -61,7 +61,10 @@ adapter is gone. `active`); its pressed classes toggle through `classList`, so a class other code adds (a voice highlight) survives a press. Every pressed toggle in the views is a `UiButton` except Bhote Koshi's cinematic button and the -tilt-map button, whose owners still write their state into the DOM. +tilt-map button, whose owners still write their state into the DOM. Core's +pressable chips and pills (rail card chips, map sources, cities and places) +are `UiButton`s too; `UiChip` is ui-vue's non-interactive label chip, used by +the voice card. `UiSlider` keeps the native range input where ui-vue draws a `role="slider"` track, so Core's keyboard, form behaviour and styling stay; it takes ui-vue's `v-model`, `min`, `max`, `step` and `disabled`, emits a diff --git a/scripts/format-scope.json b/scripts/format-scope.json index d8814419c..57f479111 100644 --- a/scripts/format-scope.json +++ b/scripts/format-scope.json @@ -1132,6 +1132,9 @@ "src/ui/kit/UiSlider.test.mjs", "src/ui/kit/UiButton.vue", "src/ui/kit/UiButton.test.mjs", + "src/ui/kit/UiChip.vue", + "src/ui/kit/UiChip.test.mjs", + "src/ui/rail/RailChips.vue", "src/ui/displayPanelActions.test.mjs", "src/testSupport/vueDom.mjs", "build/vueLoader.js", diff --git a/scripts/package-boundaries.json b/scripts/package-boundaries.json index 8d5c468db..fb68740ae 100644 --- a/scripts/package-boundaries.json +++ b/scripts/package-boundaries.json @@ -134,7 +134,8 @@ "src/ui/rail/PanelCollapseButton.vue", "src/ui/rail/panelState.js", "src/sdr/gain.js", - "src/ui/kit/UiSlider.js" + "src/ui/kit/UiSlider.js", + "src/ui/kit/UiChip.vue" ], "external": ["vue", "pinia"] }, @@ -667,7 +668,8 @@ "src/ui/rail/utcClock.js", "src/ui/rail/RailTimeline.vue", "src/ui/rail/rangeValue.js", - "src/ui/weather/WeatherReadout.vue" + "src/ui/weather/WeatherReadout.vue", + "src/ui/kit/UiButton.vue" ], "external": ["vue"] }, @@ -1066,7 +1068,8 @@ "src/ui/stores/panelChrome.js", "src/ui/rail/panelState.js", "src/ui/rail/fieldValue.js", - "src/ui/kit/UiSlider.js" + "src/ui/kit/UiSlider.js", + "src/ui/kit/UiButton.vue" ], "external": ["cesium", "vue", "pinia"] }, @@ -3076,7 +3079,8 @@ "src/ui/stores/panelChrome.js", "src/ui/rail/panelState.js", "src/ui/rail/fieldValue.js", - "src/ui/kit/UiSlider.js" + "src/ui/kit/UiSlider.js", + "src/ui/kit/UiButton.vue" ], "external": [ "hls.js", diff --git a/src/data/managerPanel.test.mjs b/src/data/managerPanel.test.mjs index 51cfd3d23..d8b089255 100644 --- a/src/data/managerPanel.test.mjs +++ b/src/data/managerPanel.test.mjs @@ -898,7 +898,9 @@ test('row info and legends reconcile in place while chips retain focus and order controls.chips.push({ id: 'two', label: 'Two' }); manager._refreshTogglePanel(); assert.deepEqual( - [...block.children].map((node) => node.className), + [...block.children].map((node) => + [...node.classList].filter((name) => !name.startsWith('ui-')).join(' '), + ), [ 'data-toggle-chip chip-idle', 'data-toggle-chip chip-idle', diff --git a/src/ui/kit/UiChip.test.mjs b/src/ui/kit/UiChip.test.mjs new file mode 100644 index 000000000..68253212e --- /dev/null +++ b/src/ui/kit/UiChip.test.mjs @@ -0,0 +1,28 @@ +import { after, before, test } from 'node:test'; +import assert from 'node:assert/strict'; +import { installVueDom } from '../../testSupport/vueDom.mjs'; + +let mount; +let UiChip; +let uninstall; +before(async () => { + uninstall = installVueDom(); + ({ mount } = await import('@vue/test-utils')); + UiChip = (await import('./UiChip.vue')).default; +}); +after(() => uninstall()); + +test('a chip is a span with the kit classes and Core’s', async () => { + const wrapper = mount(UiChip, { + attrs: { class: 'gev-voice-card-chip', 'data-tone': 'ok' }, + slots: { default: 'ok' }, + }); + const chip = wrapper.get('span'); + assert.deepEqual(chip.classes(), ['ui-chip', 'gev-voice-card-chip']); + assert.equal(chip.attributes('data-tone'), 'ok'); + assert.equal(chip.text(), 'ok'); + await wrapper.setProps({ selected: true, mono: true }); + assert.ok(chip.classes().includes('ui-chip--selected')); + assert.ok(chip.classes().includes('ui-mono')); + wrapper.unmount(); +}); diff --git a/src/ui/kit/UiChip.vue b/src/ui/kit/UiChip.vue new file mode 100644 index 000000000..f2d590a7e --- /dev/null +++ b/src/ui/kit/UiChip.vue @@ -0,0 +1,19 @@ + + + diff --git a/src/ui/rail/RailChips.vue b/src/ui/rail/RailChips.vue index d912be6fa..5f04372d9 100644 --- a/src/ui/rail/RailChips.vue +++ b/src/ui/rail/RailChips.vue @@ -1,4 +1,6 @@ diff --git a/src/ui/views/CommandDockView.vue b/src/ui/views/CommandDockView.vue index c34e37286..552d0e739 100644 --- a/src/ui/views/CommandDockView.vue +++ b/src/ui/views/CommandDockView.vue @@ -117,7 +117,7 @@ function selectMapSource(chip) { MAP SOURCE {{ mapSource ? mapSource.status.text : '3D' }} -
+
{{ chip.label }}{{ chip.requirement }}
@@ -145,10 +145,10 @@ function selectMapSource(chip) {
-
+
{{ poi.key }}{{ poi.name }}
-
+
{{ city.label }}