Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
41f0fb2
test(webui): pin Tooltip behavior before adopting the shared one
inureyes Sep 19, 2026
c1857ec
refactor(webui): adopt the shared Tooltip behind an adapter
inureyes Sep 19, 2026
fd0e7e9
test(webui): pin ErrorBanner semantics before the ErrorState swap
inureyes Sep 19, 2026
e0fb968
refactor(webui): render ErrorBanner through the shared ErrorState
inureyes Sep 19, 2026
2a202e0
test(webui): pin gallery card semantics before the BaseCard swap
inureyes Sep 19, 2026
8defa3a
refactor(webui): build the gallery cards on the shared BaseCard
inureyes Sep 19, 2026
b5c4679
test(webui): pin the off-canvas navigation before the Drawer swap
inureyes Sep 19, 2026
837c9a8
refactor(webui): drive the compact navigation with the shared Drawer
inureyes Sep 19, 2026
8bad674
test(webui): pin the shell content column before adopting PageLayout
inureyes Sep 19, 2026
88f990a
refactor(webui): delegate the shell content column to PageLayout
inureyes Sep 19, 2026
81450d3
test(webui): pin page headings before adopting PageHeader
inureyes Sep 19, 2026
356fba3
refactor(webui): render the Settings, gallery and sign-in headers wit…
inureyes Sep 19, 2026
0dfdd72
test(webui): pin Activity runtime tiles before adopting StatCard
inureyes Sep 19, 2026
fcc32c9
refactor(webui): show Activity runtime measurements as StatCard tiles
inureyes Sep 19, 2026
9406c87
test(webui): pin the Models catalog waiting state before Skeleton
inureyes Sep 19, 2026
ff6b46e
refactor(webui): show Skeleton rows while the Models catalog loads
inureyes Sep 19, 2026
13906ec
test(webui): pin the Activity operations list before SmoothHeight
inureyes Sep 19, 2026
369ed18
refactor(webui): smooth Activity operations list height with SmoothHe…
inureyes Sep 19, 2026
6651e0f
test(webui): pin Models row metadata before rendering it as Badges
inureyes Sep 19, 2026
8f2178b
refactor(webui): show Models row metadata as shared Badges
inureyes Sep 19, 2026
46a7f0a
test(webui): exercise the shared Drawer and Tooltip in the served-CSP…
inureyes Sep 19, 2026
a951bfb
docs(webui): record the ui-common adoption, its bridges and decisions
inureyes Sep 19, 2026
202e9d2
chore(webui): regenerate the embedded bundle for the ui-common adoption
inureyes Sep 19, 2026
c301aed
test(webui): catch the hovered disabled primary button losing its fill
inureyes Sep 19, 2026
e6e38ee
fix(webui): keep disabled buttons' fill when hovered
inureyes Sep 19, 2026
92c64af
docs(webui): count the disabled-hover browser case
inureyes Sep 19, 2026
95fab15
chore(webui): regenerate the embedded bundle after the hover fix
inureyes Sep 19, 2026
827d3a6
test(webui): catch hovered enabled primary buttons losing their fill
inureyes Sep 19, 2026
eb57bd8
fix(webui): keep enabled primary and danger hover fills
inureyes Sep 19, 2026
682c424
test(webui): pin drawer focus containment after a pointer press
inureyes Sep 19, 2026
1bd39db
fix(webui): keep the page behind the open nav drawer inert
inureyes Sep 19, 2026
68a3671
docs(webui): record the drawer's inert page and outside Escape
inureyes Sep 19, 2026
8141562
chore(webui): regenerate the embedded bundle after the review fixes
inureyes Sep 19, 2026
191aec1
test(webui): catch SmoothHeight's early settle-window release
inureyes Sep 19, 2026
6447e7b
fix(webui): restart SmoothHeight's settle window from the latest false
inureyes Sep 19, 2026
036ad2f
test(webui): catch the drawer closing on an already-handled Escape
inureyes Sep 19, 2026
fd5acb1
fix(webui): keep the drawer open under an already-handled Escape
inureyes Sep 19, 2026
7b0183d
fix(webui): scope the safe-layout whitelist to the product adapters
inureyes Sep 19, 2026
8b37b48
docs(webui): record the settle-window and Escape hardening
inureyes Sep 19, 2026
6bdbfb6
chore(webui): regenerate the embedded bundle after the hardening fixes
inureyes Sep 19, 2026
3e9f6e2
chore: merge origin/main into the ui-common adoption branch
inureyes Sep 19, 2026
be87e27
docs(webui): state the test counts after merging main
inureyes Sep 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/webui/design-system.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,21 @@ Tokens live in `webui/src/design-system/tokens.css` and `glass-intensity.css`. P

The user-requested [ui-common migration](ui-common.md) now centralizes available controls on pinned alpha.19 while retaining product tokens and native modal exceptions. That document defines the mandatory feature-page export seam and the new verification gates; historical4185 acceptance below does not certify rewritten component DOM.

`webui/src/design-system/primitives.tsx` exports the canonical Button, IconButton, Field, Select, StatusBadge, ProgressBar, EmptyState, ErrorBanner, Dialog, Sheet, Tooltip, Tabs, Inspector, DataTable, DenseList, AuthGate, LoginView and SchemaMismatchView. Use native `<select>` as the combobox baseline and native `<dialog>` through these wrappers as the single modal/sheet primitive so focus restoration and Escape behavior are consistent. LoginView is controlled by callbacks, keeps submitted tokens in component memory only and clears the field on submit, logout and unmount. The form and password field request `autocomplete="off"` as a browser hint; this does not guarantee that browsers or password-manager extensions will decline to save a credential. SchemaMismatchView exposes an explicit recovery callback. Do not add page-specific focus traps, alternate dialog implementations or second auth caches.
`webui/src/design-system/primitives.tsx` exports the canonical Button, IconButton, Field, Select, StatusBadge, ProgressBar, EmptyState, ErrorBanner, Dialog, Drawer, Tooltip, Tabs, Card, PageLayout, PageHeader, StatCard, LoadingStatus, SmoothHeight, Badge, Inspector, StaticTable, DataTable, DenseList, AuthGate, LoginView and SchemaMismatchView. The [ui-common matrix](ui-common.md) names the shared component behind each adapter and the bridges each one needs. Native `<dialog>` through `Dialog` is the single modal-dialog primitive, and the shared `Drawer` is used only for the compact navigation sheet; both keep a focus trap, Escape close and focus restoration to the opener. LoginView is controlled by callbacks, keeps submitted tokens in component memory only and clears the field on submit, logout and unmount. The form and password field request `autocomplete="off"` as a browser hint; this does not guarantee that browsers or password-manager extensions will decline to save a credential. SchemaMismatchView exposes an explicit recovery callback. Do not add page-specific focus traps, alternate dialog implementations or second auth caches.

All controls expose visible focus, disabled and busy states, minimum 24 px targets with 32 px toolbar targets, and non-color-only state text. Long English/CJK labels must use `.truncate` with a `title` or another accessible full label. Progress uses explicit indeterminate semantics when total bytes are unknown rather than fabricated percentages. Lifecycle badges cover `unloaded`, `loading`, `ready`, `draining`, `unloading` and `failed` without implying a model is ready in placeholder screens.

## Shell and localization

`AppShell` defines the sidebar, top toolbar, content area and optional inspector. Primary navigation contains Models, Chat, Activity and Settings; the component gallery remains available as the direct `#gallery` artifact route and is listed in the command palette only while that route is already active. Cmd/Ctrl+K opens the command palette, `?` opens keyboard help, Escape closes the active dialog through the native dialog mechanism, and `[`/`]` move primary navigation only while the sidebar owns focus. Global shortcuts are suppressed inside edit controls, modal dialogs, IME composition and Alt-key chords. Compact widths below 960 px use an off-canvas sheet opened from the toolbar; no permanent mobile rail is rendered.
`AppShell` defines the sidebar, top toolbar, content column (the shared PageLayout) and optional inspector. Primary navigation contains Models, Chat, Activity and Settings; the component gallery remains available as the direct `#gallery` artifact route and is listed in the command palette only while that route is already active. Cmd/Ctrl+K opens the command palette, `?` opens keyboard help, Escape closes the active dialog through the native dialog mechanism or the navigation drawer through its own handler, with focus back on the opener, and `[`/`]` move primary navigation only while the sidebar owns focus. Global shortcuts are suppressed inside edit controls, modal dialogs, the open navigation drawer, IME composition and Alt-key chords. Compact widths below 960 px use the shared Drawer as a left off-canvas sheet opened from the toolbar, with the page behind it inert while it is open; widening past 960 px while it is open closes it and moves focus to the desktop sidebar. No permanent mobile rail is rendered.

The production shell consumes the shared `WebUiProvider` snapshot and actions directly: LoginView submits through `actions.login`, logout uses `actions.logout`, and connection, catalog/operation freshness, selected model and schema recovery derive from the shared authority. It maintains no second session cache. Initial browsing makes no local API call before explicit login; authenticated route browsing does not load models or call inference endpoints. Models, Chat and Activity currently expose truthful staged guidance until their feature-page issues implement the workflows.

Every user-facing string has a typed key in `webui/src/i18n/catalog.ts` and a synchronized entry in `tests/fixtures/webui/strings.json` with English, Korean and a primary test ID. Locale-aware formatting helpers live beside the design system for bytes and tokens/s.

## Verification

The component gallery is available at `#gallery`. `pnpm --dir webui run unit` executes the activity-stream node:test spec and 316 Vitest tests across 36 files, covering the shared client/provider and shell behavior. `pnpm --dir webui run browser` executes 28 Playwright tests, 29 with `MLXCEL_WEBUI_FONT_DIAGNOSTICS=1`: 12 layout and accessibility cases (8 gallery and 4 product-shell variants), seven further `browser.spec.ts` cases covering provider/mock-API journeys, keyboard/focus/shortcut behavior, production-selector compact reflow, contrast/reduced-motion/visibility behavior and backdrop-filter fallback, and the Activity, Chat, Models and Settings route specs. The variants in `webui/tests/browser-fixtures.ts` cover 390/1024/1440 widths, light/dark, tinted/opaque, high contrast and CJK labels. Each of the 12 cases runs axe with all violations rejected and asserts measured geometry: document and key-panel overflow, toolbar hiding above 960 px, 44 px compact hit targets, data-table column visibility, heading hierarchy across repeated tab remounts and progress/sample row alignment. No pixel baselines are committed. A baseline is specific to one renderer, font set and platform, so keeping one per platform required a hosted capture and a manual visual review on every font, Chromium or UI change, and it bought no assertion that the geometry checks do not already make. A failing case still writes its actual page image and a trace into `webui/test-results/`, which is git-ignored and uploaded as a CI artifact; run with `--headed` to watch a variant render. The CI job still pins `fonts-dejavu-core`, `fonts-dejavu-extra` and `fonts-wqy-zenhei` on Ubuntu 24.04, because the geometry assertions measure text and the CJK drawer variant needs a Korean face to lay out at all. The opt-in `MLXCEL_WEBUI_FONT_DIAGNOSTICS=1` test reports the fonts Chromium actually resolved, rather than trusting `fc-match` alone.
The component gallery is available at `#gallery`. `pnpm --dir webui run unit` executes the activity-stream node:test spec and 359 Vitest tests across 47 files, covering the shared client/provider, shell behavior and the shared-component adapters. `pnpm --dir webui run browser` executes 56 Playwright tests, 57 with `MLXCEL_WEBUI_FONT_DIAGNOSTICS=1`: 12 layout and accessibility cases (8 gallery and 4 product-shell variants), seven further `browser.spec.ts` cases covering provider/mock-API journeys, keyboard/focus/shortcut behavior, production-selector compact reflow, contrast/reduced-motion/visibility behavior and backdrop-filter fallback, the Activity, Chat, Models and Settings route specs, and the shared-component specs `ui-common-components.spec.ts` (14 cases) and `ui-common-shell.spec.ts` (12 cases). The variants in `webui/tests/browser-fixtures.ts` cover 390/1024/1440 widths, light/dark, tinted/opaque, high contrast and CJK labels. Each of the 12 cases runs axe with all violations rejected and asserts measured geometry: document and key-panel overflow, toolbar hiding above 960 px, 44 px compact hit targets, data-table column visibility, heading hierarchy across repeated tab remounts and progress/sample row alignment. No pixel baselines are committed. A baseline is specific to one renderer, font set and platform, so keeping one per platform required a hosted capture and a manual visual review on every font, Chromium or UI change, and it bought no assertion that the geometry checks do not already make. A failing case still writes its actual page image and a trace into `webui/test-results/`, which is git-ignored and uploaded as a CI artifact; run with `--headed` to watch a variant render. The CI job still pins `fonts-dejavu-core`, `fonts-dejavu-extra` and `fonts-wqy-zenhei` on Ubuntu 24.04, because the geometry assertions measure text and the CJK drawer variant needs a Korean face to lay out at all. The opt-in `MLXCEL_WEBUI_FONT_DIAGNOSTICS=1` test reports the fonts Chromium actually resolved, rather than trusting `fc-match` alone.

The text-scale case uses a test-only root attribute to enlarge text metrics to 200%; compact wrapping itself is implemented in production CSS, and a separate test checks it without text-scale layout selectors. These assertions cover document/key-panel overflow, full labels, visible compact focus and 44 px compact toolbar targets; they are not native browser zoom tests. Product-shell cases use explicit mock API responses, not a real backend session.

Expand Down
Loading