Skip to content

GUI consistency: no density token scope and no part contracts, so views hand-roll spacing and reach into primitive internals #17564

Open

Description

@mrveiss

Part of #12730. Two mechanisms the shared primitives do not expose, both of which push views into hand-rolling the thing the umbrella wants standardised.

Problem 1 — there is no density scope

autobot-frontend has a large token layer (src/assets/css/design-tokens.css, 698 custom properties) but spacing density is not part of it. --card-padding is declared once; there is no --table-row-height, no --table-cell-py, and no density scope class. So every table and card carries literal spacing, and a user-facing compact/comfortable/spacious control is not expressible without touching every component.

The mechanism that avoids per-component size props entirely is a scope class on an ancestor that redefines a handful of spacing tokens — four is enough (--table-row-height, --table-cell-py, --card-padding, --spacing-unit). Components consume var(--…) and never learn density exists.

Problem 2 — composite primitives have no addressable parts

Cards, tables and panels expose no named internal parts. A view that must restyle a card header or a table cell therefore reaches in with its own class — and each reach is a fresh divergence that no linter sees, because the class is locally valid.

A part-contract convention (a stable data-slot="card-header"-style attribute on each internal region, targeted by the stylesheet) makes the internals a declared API instead of an accident of DOM shape.

Both are cheap once the primitives are single-sourced, and both are wasted effort before that — hence the dependency below.

Approach

  1. Add the four density tokens to design-tokens.css with the current values as the comfortable default, so nothing moves on landing.
  2. Add .density-compact / .density-comfortable / .density-spacious scope classes that redefine only those tokens.
  3. Make the kit's card and table primitives consume the tokens instead of literal spacing.
  4. Define the part-name convention in the kit's docs, apply it to the primitives merged by Retire the local Base* component forks in autobot-frontend into the shared kit #14776/Promote BaseInput, BasePanel and BaseTable into the shared kit #14778, and state that a part name is a public API — renaming one is a breaking change.
  5. Do not retrofit part names ad hoc onto unmerged forks; that is how a third namespace starts.

Acceptance criteria

Implementation Order

Wave: 3
Depends on: #14776, #14778, #14785
Unblocks: —

Evidence

src/assets/css/design-tokens.css — 698 --var: declarations, --card-padding declared once, no row-height or cell-padding token · no part-name attribute convention anywhere in libs/autobot-ui or autobot-frontend/src/components.

Found during a comparative GUI-standardisation audit — see docs/research/dashboard-shell-and-component-standardisation.md, gaps G3 and G4.

Activity

  1. mrveiss commented on Sep 26, 2026

    @mrveiss
    OwnerAuthor

    Second GUI: the density half does not apply yet, the part-contract half applies more

    Audited after filing.

    Density. autobot-slm-frontend defines 173 tokens of its own (src/assets/styles/main.css 152 + src/assets/styles/aui-theme.css 43) and references var(--…) in only 12 of 113 component files. A density scope class works by redefining tokens that components consume — so in the SLM GUI it would currently change almost nothing. Density must therefore land after #17566 (the SLM tokenisation sweep), or it ships working in one GUI and inert in the other.

    Part contracts. These apply more strongly there, not less: with no table primitive, no page header and no breadcrumb, every SLM view builds its own internals, so there is nothing whose parts could be addressed. Defining the convention while the kit primitives are being merged (#14776/#14778) and built (#17563) is the cheap moment; retrofitting 113 files later is not.

    One counter-measurement, so the "local override" framing is applied to the right GUI. Components that redefine a design token inside their own <style>:

    files declarations
    autobot-frontend 12 47 (components/workflow/WorkflowCanvas.vue alone: 18)
    autobot-slm-frontend 0 0

    !important in component <style>: 14 files / 58 uses (main) vs 3 files / 4 uses (SLM).

    So the token-level local overrides are entirely a main-GUI problem, while the palette-class local overrides are overwhelmingly an SLM problem (6,213 vs 689 — #17566, #14580). Two different failure modes under one owner rule; a single check will not find both.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions