docs: describe the component kit on its own terms

The kit's comments and docs describe its props and classes directly instead
of by reference to another kit.
This commit is contained in:
Sameh Khamis committed 2026-11-01 19:40:46 -08:00
1 parent 859ceac8b4
commit 5582ff288d
12 files changed
+33 -46

No files matched your search

+1 -2
View File
@@ -155,8 +155,7 @@ are existing ones when a change converts them:
`UiSlider`, `UiSegmented`, `UiChip` (a label, not a control), `UiBadge`, `UiSlider`, `UiSegmented`, `UiChip` (a label, not a control), `UiBadge`,
`UiEmpty`, `UiIcon`, `UiTooltip`, `UiPanel` and `UiRail`. Use these before `UiEmpty`, `UiIcon`, `UiTooltip`, `UiPanel` and `UiRail`. Use these before
writing a control. When the kit lacks something, extend a kit component or writing a control. When the kit lacks something, extend a kit component or
add one that follows the names, props, events and class names of add one that follows the kit's names, props, events and class names (see
Halfpixel's `ui-vue` kit, as the existing ones do (see
[Component kit](docs/VUE-MIGRATION.md#component-kit)), rather than [Component kit](docs/VUE-MIGRATION.md#component-kit)), rather than
building a one-off. building a one-off.
- **No hand-written DOM binding.** Don't build elements or write text, - **No hand-written DOM binding.** Don't build elements or write text,
+1 -1
View File
@@ -56,7 +56,7 @@
panel's open and pinned state to the `gev-panel-chrome` store, and the panel's open and pinned state to the `gev-panel-chrome` store, and the
buttons, now views, call it there. `bindPanelDisclosure` (`./ui/panels`) binds buttons, now views, call it there. `bindPanelDisclosure` (`./ui/panels`) binds
only a panel's Escape; it no longer takes `buttons` or `onChange`. `UiButton` only a panel's Escape; it no longer takes `buttons` or `onChange`. `UiButton`
joins the component kit with ui-vue's props (samehkhamis, #1499). joins the component kit (samehkhamis, #1499).
- `SceneControls` (`./ui/scenes`) no longer takes `elements` or writes the Scene - `SceneControls` (`./ui/scenes`) no longer takes `elements` or writes the Scene
panel's buttons, status, progress or runtime chip: it presents them to the panel's buttons, status, progress or runtime chip: it presents them to the
+13 -17
View File
@@ -41,17 +41,15 @@ one-panel rule too. Share links continue to record which panels are open.
`UiBadge` and `UiEmpty` so far, with more joining as the controls they serve `UiBadge` and `UiEmpty` so far, with more joining as the controls they serve
are converted. One component are converted. One component
serves every use of a control, with props for the differences (`UiPanel`'s serves every use of a control, with props for the differences (`UiPanel`'s
`sideways`, `glow`, `scroll`), rather than a copy per panel. Names, props, `sideways`, `glow`, `scroll`), rather than a copy per panel. The components
events and class names follow Halfpixel's `ui-vue` kit so the two can merge are styled by the existing stylesheet and custom properties; a kit class such as
later, but the components are written for this repository and styled by its
existing stylesheet and custom properties; a kit class such as
`ui-button--icon` carries no Core style yet, and a converted control keeps `ui-button--icon` carries no Core style yet, and a converted control keeps
its own classes beside it. They contain no application state. its own classes beside it. They contain no application state.
`UiPanel` takes ui-vue's `title`, slots and `v-model:collapsed`, but its `UiPanel` takes a `title`, slots and `v-model:collapsed`, but its
`collapsed` drives only the button and `ui-panel--collapsed`: the root's `collapsed` drives only the button and `ui-panel--collapsed`: the root's
`collapsed` class, which hides the body, is drawn at once by `v-panel-state` `collapsed` class, which hides the body, is drawn at once by `v-panel-state`
from the panel chrome store, and there is no `closable`, since Core's panels collapse rather than close. from the panel chrome store, and there is no `closable`, since Core's panels collapse rather than close.
`UiSegmented` adds `keyboard` (`none`, `arrows` as in ui-vue, or `radio` with `UiSegmented` adds `keyboard` (`none`, `arrows`, or `radio` with
Home and End), since each of Core's groups keeps its own keyboard policy, and Home and End), since each of Core's groups keeps its own keyboard policy, and
`itemClass`/`activeClass` for Core's segment classes. A key moves focus at `itemClass`/`activeClass` for Core's segment classes. A key moves focus at
once and asks for a change only when it lands on another option. Every once and asks for a change only when it lands on another option. Every
@@ -63,26 +61,25 @@ 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 views is a `UiButton` except Bhote Koshi's cinematic button and the
tilt-map button, whose owners still write their state into the DOM. Core's 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) 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 are `UiButton`s too; `UiChip` is a non-interactive label chip, used by
the voice card. the voice card.
`UiSelect` renders the bare native select (Core's labels sit outside it or `UiSelect` renders the bare native select (Core's labels sit outside it or
come as an `aria-label`) with ui-vue's `v-model`, `options` and `disabled`; come as an `aria-label`) with `v-model`, `options` and `disabled`;
options that carry their own attributes come through the slot, a caller's options that carry their own attributes come through the slot, a caller's
`@change` still reaches the select, and `hold` works as in `UiSlider`. `@change` still reaches the select, and `hold` works as in `UiSlider`.
Without `hold`, a select takes its model back after its own change renders, Without `hold`, a select takes its model back after its own change renders,
so a pick its owner refuses goes back; an owner that answers later (the SDR so a pick its owner refuses goes back; an owner that answers later (the SDR
gain) takes `hold`. Every select in the views is a `UiSelect`. gain) takes `hold`. Every select in the views is a `UiSelect`.
`UiBadge` takes ui-vue's `tone` and carries Core's `gev-status-badge`; its `UiBadge` takes a `tone` and carries Core's `gev-status-badge`; its
density variants and colours stay caller classes, and it renders the CCTV density variants and colours stay caller classes, and it renders the CCTV
source and calibration badges and the rail card badges. `UiEmpty` takes source and calibration badges and the rail card badges. `UiEmpty` takes
ui-vue's `title` and `hint`, but Core's empty states are one line, so the title a `title` and `hint`, but Core's empty states are one line, so the title
is the text itself rather than a bold heading; the Scene shot list, mission is the text itself rather than a bold heading; the Scene shot list, mission
roster and imagery strip use it. The locale picker's and the mission tables' roster and imagery strip use it. The locale picker's and the mission tables'
empty rows stay a paragraph and table cells, and no Core block matches empty rows stay a paragraph and table cells.
`UiSection`'s header and well, so none uses it yet. `UiSlider` keeps the native range input rather than drawing a
`UiSlider` keeps the native range input where ui-vue draws a
`role="slider"` track, so Core's keyboard, form behaviour and styling stay; `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 it takes `v-model`, `min`, `max`, `step` and `disabled`, emits a
number, and adds `hold` (never rewrite a focused handle, and take the model number, and adds `hold` (never rewrite a focused handle, and take the model
back on blur) and `unstyled` (the browser's own range, as Bhote Koshi's back on blur) and `unstyled` (the browser's own range, as Bhote Koshi's
are, without Core's slider surface). A caller's own input, change and blur are, without Core's slider surface). A caller's own input, change and blur
@@ -91,11 +88,10 @@ a functional render-function component, so the portable `./ui/input` rows
use it without a component compiler. Every range in the views is a use it without a component compiler. Every range in the views is a
`UiSlider` except the radio tuner's: its owner moves the handle back to the `UiSlider` except the radio tuner's: its owner moves the handle back to the
selected station on a drag's first input without changing the slot, which selected station on a drag's first input without changing the slot, which
a functional component would not render again. Merging the kits means a functional component would not render again.
settling native input against the drawn track.
Controls share one skin, so every panel reads the same. Every scrolling Controls share one skin, so every panel reads the same. Every scrolling
surface carries the kit's `.ui-scroll` (ui-vue's name), which draws the thin surface carries the kit's `.ui-scroll`, which draws the thin
themed scrollbar from `--scroll-thumb` and `--scroll-track`; the Cyber theme themed scrollbar from `--scroll-thumb` and `--scroll-track`; the Cyber theme
sets those two tokens, and Cockpit's HUD windows keep their accent tint. A sets those two tokens, and Cockpit's HUD windows keep their accent tint. A
surface without it would draw the platform's light scrollbar, because the surface without it would draw the platform's light scrollbar, because the
+1 -2
View File
@@ -1,6 +1,5 @@
<script setup> <script setup>
// Core's read-only badge, with @halfpixel/ui-vue UiBadge's `tone` and classes // Core's read-only badge, with a `tone` and the kit's classes. It carries Core's `gev-status-badge` class, and
// so the two kits can merge. It carries Core's `gev-status-badge` class, and
// callers add its density variants (`gev-status-badge--box`, `--plain`) and // callers add its density variants (`gev-status-badge--box`, `--plain`) and
// the feature classes that colour it; the kit classes carry no Core styles // the feature classes that colour it; the kit classes carry no Core styles
// yet. Not mirrored yet: pulse, busy, the tone glyphs and the clipped title. // yet. Not mirrored yet: pulse, busy, the tone glyphs and the clipped title.
+1 -2
View File
@@ -2,8 +2,7 @@
import { computed } from 'vue'; import { computed } from 'vue';
import { vClassToggle } from '../rail/classToggle.js'; import { vClassToggle } from '../rail/classToggle.js';
// Core's button, with @halfpixel/ui-vue UiButton's props, classes and // Core's button and its attribute contract: the button is always the root,
// attribute contract so the two kits can merge: the button is always the root,
// attributes passed in win over its own (a `title` replaces the label's), and // attributes passed in win over its own (a `title` replaces the label's), and
// `pressed` renders aria-pressed only when it is passed. Core styles the // `pressed` renders aria-pressed only when it is passed. Core styles the
// button through the classes its callers pass; the kit classes carry no Core // button through the classes its callers pass; the kit classes carry no Core
+1 -2
View File
@@ -1,6 +1,5 @@
<script setup> <script setup>
// Core's chip, with @halfpixel/ui-vue UiChip's props and classes so the two // Core's chip: a label that says what something is, never a control.
// kits can merge: a label that says what something is, never a control.
// Core styles it through the classes its callers pass; the kit classes carry // Core styles it through the classes its callers pass; the kit classes carry
// no Core styles yet. A chip that presses is a UiButton with pressedClass. // no Core styles yet. A chip that presses is a UiButton with pressedClass.
defineProps({ defineProps({
+3 -3
View File
@@ -1,7 +1,7 @@
<script setup> <script setup>
// Core's empty state, with @halfpixel/ui-vue UiEmpty's `title` and `hint` so // Core's empty state, with a `title` and `hint`. Core's empty states are one
// the two kits can merge. Core's empty states are one line, so the title is // line, so the title is the text itself rather than a bold heading; a hint
// the text itself rather than ui-vue's bold heading; a hint follows it. Core // follows it. Core
// styles it through the classes its callers pass. Not mirrored yet: icon. // styles it through the classes its callers pass. Not mirrored yet: icon.
defineProps({ defineProps({
title: { type: String, required: true }, title: { type: String, required: true },
+2 -3
View File
@@ -2,11 +2,10 @@
import { vClassToggle } from '../rail/classToggle.js'; import { vClassToggle } from '../rail/classToggle.js';
import UiPanelToggle from './UiPanelToggle.vue'; import UiPanelToggle from './UiPanelToggle.vue';
// Core's panel, with @halfpixel/ui-vue UiPanel's name, title, slots and // Core's panel, with a name, title, slots and v-model:collapsed. It draws Core's panel markup
// v-model:collapsed so the two kits can merge. It draws Core's panel markup
// (glow, inner, a header with the title, badges, divider, actions and the // (glow, inner, a header with the title, badges, divider, actions and the
// collapse button, then the body) and keeps Core's classes beside the kit's. // collapse button, then the body) and keeps Core's classes beside the kit's.
// Unlike ui-vue's, `collapsed` does not hide the body: the root's classes // `collapsed` does not hide the body: the root's classes
// stay as rendered, and whatever owns the panel's state writes its // stay as rendered, and whatever owns the panel's state writes its
// `collapsed` class at once (PanelChrome, through vPanelState), because the // `collapsed` class at once (PanelChrome, through vPanelState), because the
// rails measure a panel in the task that opens it. `collapsed` drives the // rails measure a panel in the task that opens it. `collapsed` drives the
+3 -4
View File
@@ -1,11 +1,10 @@
<script setup> <script setup>
import { computed } from 'vue'; import { computed } from 'vue';
// Core's segmented control, with @halfpixel/ui-vue UiSegmented's // Core's segmented control, with v-model, options, label, stacked and
// v-model, options, label, stacked and disabled so the two kits can merge. // disabled. It adds `keyboard`, because its groups keep their own policy: `none`
// Core adds `keyboard`, because its groups keep their own policy: `none`
// (Tab reaches every option and arrows do nothing), `arrows` (a roving tab // (Tab reaches every option and arrows do nothing), `arrows` (a roving tab
// stop that arrows move, as in ui-vue) or `radio` (arrows plus Home and // stop that arrows move) or `radio` (arrows plus Home and
// End). Each option may carry `attrs` (an id, data attributes, a tip), and // End). Each option may carry `attrs` (an id, data attributes, a tip), and
// Core's classes sit beside the kit's: `gev-segmented`, `gev-segment` and the // Core's classes sit beside the kit's: `gev-segmented`, `gev-segment` and the
// selected option's `activeClass`. Not mirrored yet: an option's icon. // selected option's `activeClass`. Not mirrored yet: an option's icon.
+1 -2
View File
@@ -16,8 +16,7 @@ function takeModel(select, props) {
} }
/** /**
* Core's select, with @halfpixel/ui-vue UiSelect's v-model, options and * Core's select, with v-model, options and disabled. Core renders the bare select: its
* disabled so the two kits can merge. Core renders the bare select: its
* labels sit outside it or come as an `aria-label` attribute, so the attribute * labels sit outside it or come as an `aria-label` attribute, so the attribute
* pass translates them. Options come from `options` ({ value, label }) or, * pass translates them. Options come from `options` ({ value, label }) or,
* where they carry their own attributes, the default slot. A change emits the * where they carry their own attributes, the default slot. A change emits the
+3 -4
View File
@@ -18,10 +18,9 @@ function takeModel(input, props) {
} }
/** /**
* Core's slider, with @halfpixel/ui-vue UiSlider's v-model, min, max, step * Core's slider, with v-model, min, max, step and disabled. Core keeps the
* and disabled so the two kits can merge. Core keeps the native range input * native range input (its keyboard, form and styling) rather than drawing a
* (its keyboard, form and styling) where ui-vue draws a `role="slider"` * `role="slider"` track. The input carries Core's `gev-quantitative-slider` class ahead of
* track. The input carries Core's `gev-quantitative-slider` class ahead of
* the caller's (`unstyled` leaves it off, for a range drawn as the browser's * the caller's (`unstyled` leaves it off, for a range drawn as the browser's
* own), the caller's attributes come first, as in the markup this replaced, * own), the caller's attributes come first, as in the markup this replaced,
* and the accessible name comes as an `aria-label` attribute so the attribute * and the accessible name comes as an `aria-label` attribute so the attribute
+3 -4
View File
@@ -1,8 +1,7 @@
/* Generic components in src/ui/kit. Names follow Halfpixel's ui-vue kit; the /* Generic components in src/ui/kit. The surfaces use this application's
surfaces use this application's glass, accent and type tokens. */ glass, accent and type tokens. */
/* The thin themed scrollbar every scrolling surface wears, as ui-vue's /* The thin themed scrollbar every scrolling surface wears (.ui-scroll). Without it a surface draws the platform's light scrollbar,
.ui-scroll. Without it a surface draws the platform's light scrollbar,
because the page declares no dark color-scheme. */ because the page declares no dark color-scheme. */
/* Cesium builds its credit list and the rail card builder its lines, so /* Cesium builds its credit list and the rail card builder its lines, so
those two surfaces are named here instead of carrying the class. */ those two surfaces are named here instead of carrying the class. */