chore(web): console onto @unom/ui 0.9.2 #142

Merged
enricobuehler merged 3 commits from worktree-console-unom-092 into main 2026-08-09 15:32:39 +00:00
Owner

The console was pinned to @unom/ui@^0.8.16 while the design system had moved to 0.9.2. This brings it current.

What it picks up

0.9.x adds the Badge, Spinner, Skeleton, Switch, Table, EmptyState and CodeBlock primitives, and 0.9.2 carries two form fixes that were live in this console:

  • Select used border-main and focus-visible:ring-main/50. --main is the foreground here (--main: var(--foreground) in web/src/styles.css), so the trigger wore a near-white border and a 3px near-white focus ring. Its chevron and placeholder were painted --secondary, which is a surface colour on this palette, so they all but vanished — which is what stopped it reading as a select. Now on --input/--ring, the same tokens InputText already used.
  • InputNumber declares a color-scheme, so the browser-drawn spinner arrows stop being near-black on a near-black field.

Both were found while overhauling the rom-manager plugin UI, but the console shares the palette that exposes them.

Verification

  • codegen + vite build clean, tsc --noEmit clean, bun test server/ 9/9
  • Storybook builds, 31/31 screenshots captured
  • A probe across all 61 stories reports zero page errors
  • The two stories containing a Select now render it at h-input-height with border: rgb(42, 33, 72) (the input token) and a muted-foreground chevron

Unchanged on purpose

The web/src/components/ui/ wrapper layer stays as-is. In particular dialog.tsx is still required: @unom/ui's DialogContent remains a surface with no Portal and no placement, and that wrapper is what supplies them. (The rom-manager plugin hit exactly this and had to add the same wrapper.)

Not included

@unom/app-ui — the console does not currently depend on it at all. See the discussion on scope; adopting it is a refactor rather than a version bump.

The console was pinned to `@unom/ui@^0.8.16` while the design system had moved to 0.9.2. This brings it current. ### What it picks up 0.9.x adds the Badge, Spinner, Skeleton, Switch, Table, EmptyState and CodeBlock primitives, and **0.9.2 carries two form fixes that were live in this console**: - **`Select`** used `border-main` and `focus-visible:ring-main/50`. `--main` is the **foreground** here (`--main: var(--foreground)` in `web/src/styles.css`), so the trigger wore a near-white border and a 3px near-white focus ring. Its chevron and placeholder were painted `--secondary`, which is a **surface** colour on this palette, so they all but vanished — which is what stopped it reading as a select. Now on `--input`/`--ring`, the same tokens `InputText` already used. - **`InputNumber`** declares a `color-scheme`, so the browser-drawn spinner arrows stop being near-black on a near-black field. Both were found while overhauling the rom-manager plugin UI, but the console shares the palette that exposes them. ### Verification - `codegen` + `vite build` clean, `tsc --noEmit` clean, `bun test server/` 9/9 - Storybook builds, 31/31 screenshots captured - A probe across **all 61 stories** reports **zero page errors** - The two stories containing a `Select` now render it at `h-input-height` with `border: rgb(42, 33, 72)` (the input token) and a muted-foreground chevron ### Unchanged on purpose The `web/src/components/ui/` wrapper layer stays as-is. In particular `dialog.tsx` is still required: `@unom/ui`'s `DialogContent` remains a **surface** with no Portal and no placement, and that wrapper is what supplies them. (The rom-manager plugin hit exactly this and had to add the same wrapper.) ### Not included `@unom/app-ui` — the console does not currently depend on it at all. See the discussion on scope; adopting it is a refactor rather than a version bump.
enricobuehler added 1 commit 2026-08-09 14:28:26 +00:00
chore(web): @unom/ui 0.8.16 → 0.9.2
ci / rust-arm64 (pull_request) Failing after 31s
ci / docs-site (pull_request) Successful in 3m1s
ci / bun-nix (pull_request) Successful in 3m27s
ci / web (pull_request) Successful in 4m29s
ci / rust (pull_request) Failing after 13m16s
nix / flake (pull_request) Failing after 19m47s
d13d253c2f
Brings the console onto the current design system. 0.9.x adds the Badge, Spinner,
Skeleton, Switch, Table, EmptyState and CodeBlock primitives, and 0.9.2 carries the
form fixes found while overhauling the rom-manager plugin UI:

- Select's border and focus ring resolved to `--main`, which is the FOREGROUND here
  (`--main: var(--foreground)` in web/src/styles.css), so the trigger wore a near-white
  border and a 3px near-white focus ring. Its chevron and placeholder were painted
  `--secondary`, a SURFACE colour, and all but vanished. Now on `--input`/`--ring`, the
  same tokens InputText already used.
- InputNumber declares a color-scheme, so the browser-drawn spinner arrows stop being
  near-black on a near-black field.

Both defects were live in this console too — the console palette is what exposes them.

Verified: codegen + vite build clean, `tsc --noEmit` clean, `bun test server/` 9/9,
Storybook builds, 31/31 screenshots. A probe over all 61 stories reports ZERO page
errors, and the two stories containing a Select now render it at h-input-height with
`border: rgb(42, 33, 72)` (the input token) and a muted-foreground chevron.

Note: the console's components/ui/ wrapper layer is unchanged and still required —
@unom/ui's DialogContent remains a surface with no Portal or placement, which is
exactly what web/src/components/ui/dialog.tsx supplies.
enricobuehler added 1 commit 2026-08-09 14:58:55 +00:00
feat(web): tab the Virtual displays page
ci / rust-arm64 (pull_request) Successful in 2m6s
ci / docs-site (pull_request) Successful in 3m59s
ci / bun-nix (pull_request) Successful in 4m39s
ci / web (pull_request) Successful in 5m1s
ci / rust (pull_request) Failing after 13m18s
nix / flake (pull_request) Failing after 23m11s
31aef4b09f
Same pill strip the plugin UIs use, via @unom/ui's Tabs: Configuration | Live displays.

The page was two stacked cards, and the configuration card ALONE is taller than the
viewport — the existing comment on the unsaved badge says as much, because that height
is how pending edits went unnoticed. The live-display list sat below all of it, so in
practice it was off screen.

Two details that are not cosmetic:

- The dirty marker moved from the card header onto the Configuration TRIGGER. Behind a
  tab the old badge would vanish entirely while Live was open — a strictly worse version
  of the problem it was added to solve. On the trigger it survives both tabs, and the
  Custom block keeps its own inline badge for when the tab IS open.
- The strip is extracted as a presentational `DisplayTabs` rather than inlined in
  `DisplaySection`. The container calls `useBlocker`, which needs a router, so it cannot
  render in Storybook — and this page's story exists specifically to pin the MOTION
  NESTING of the preset grid (a card sets no delayChildren, so tiles nested one level
  deeper stop staggering). Inserting tabs changes that ancestor chain, so the story has
  to render the real one or it passes for the wrong reason.

Adds Pages/Displays → "Unsaved on other tab", which switches to Live with a dirty draft:
if the marker ever goes silent there, the warning is gone exactly when it matters.

Verified: tsc clean, biome clean, `bun test server/` 9/9, vite build + i18n check clean,
Storybook builds, 32/32 screenshots.
enricobuehler added 1 commit 2026-08-09 15:23:20 +00:00
fix(web): fix the card inset at the root, not at the call sites
ci / bun-nix (pull_request) Successful in 51s
ci / docs-site (pull_request) Successful in 1m35s
ci / web (pull_request) Successful in 2m30s
ci / rust-arm64 (pull_request) Successful in 3m16s
ci / rust (pull_request) Failing after 9m12s
nix / flake (pull_request) Failing after 19m50s
0b252403cd
The broken inset on the Displays configuration card was the symptom. The cause is
structural, and it had already been diagnosed at least twice in-tree without being fixed.

Two faults, both in components/ui/card.tsx:

1. The padding was a RESPONSIVE COMPOUND: `p-4 pt-0 sm:p-6 sm:pt-0`. tailwind-merge
   resolves conflicts only within a variant, so any call-site override won at the base
   and lost at `sm:` — correct on a phone, wrong on every desktop. Measured on the
   Displays card before this change: padding-top 24px at 500px, 0px at 1440px.

2. `pt-0` encoded an assumption about a SIBLING that nothing enforced — "a CardHeader is
   above me and supplies the top inset". Delete the header, which is exactly what tabbing
   a page does since the tab label replaces the card title, and the top inset silently
   vanishes at ≥640px.

Fix:

- One single-variant utility, `p-padding-card` — the same `--spacing-padding-card` token
  @unom/ui's own Card uses, so nested cards finally agree on their inset. A single
  variant cannot half-lose an override.
- Top inset is now self-correcting: `[&:not(:first-child)]:pt-0`. Ask the DOM instead of
  the author. A headerless CardContent keeps its inset with nothing to remember.

Seven call sites had grown their own compensation in five dialects — `p-6`,
`p-card pt-card sm:pt-card` (×3), `p-4 sm:pt-6` (×3), `pt-4 sm:pt-6`, and my own `pt-6`
from the tabs commit. All removed; they are the symptom-fixes this replaces. LogsCard
even carried a six-line comment correctly describing the trap and working around it
locally — that comment is now three lines saying it no longer needs saying.

`flush` stays: full-bleed content is a real intent, expressed as a prop the component
honours rather than a utility that has to out-argue the one already there.

Guarded by UI/Card → "Inset with and without header", a headered/headerless pair that has
to look identical on every side. It must be checked at BOTH widths — a single width
cannot show this class of bug, which is why it kept surviving.

Verified by measuring computed padding at 500px and 1440px: first child 20px on all four
sides, after-a-header 0px top and 20px elsewhere, identical at both widths. tsc clean,
biome clean on every touched file, 9/9 server tests, build + i18n clean, 32/32 screenshots.
enricobuehler merged commit 235b8e55d4 into main 2026-08-09 15:32:39 +00:00
enricobuehler deleted branch worktree-console-unom-092 2026-08-09 15:32:46 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: unom/punktfunk#142