Skip to content

Rebuild Button on the design system axes - #89

Draft
librowski wants to merge 2 commits into
ds2-pipeline-switchfrom
ds2-buttons
Draft

Rebuild Button on the design system axes#89
librowski wants to merge 2 commits into
ds2-pipeline-switchfrom
ds2-buttons

Conversation

@librowski

@librowski librowski commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Rebuilds the regular Button on the design system's own axes.

APIvariant, size and shape are explicit props; content is composed from prefixIcon, children and suffixIcon. The three structural subtypes (label / icon / icon+label) and the children-shape inference that picked between them are gone, along with the overload cast.

  • variant: primary, secondary, critical, success, warning and the five ghost treatments (ghost-primary, ghost-secondary, ghost-critical, ghost-success, ghost-warning).
  • size: xl l m s xs.
  • shape: default, square, round — the latter two render the icon-only 1:1 box.

Design fidelity — measured from the component set: heights 48/42/36/32/28, padding 16/16, 14/16, 12/12, 10/10, 8/8, gap 8, radius 8/8/6/4/4, icon box 24/20/18/18/16, label roles 16/14/12/12/12 at weight 600. Icon-only padding 12/11/9/7/6. Every fill, border and label colour binds to its component token; the --ax-public-button-* contract is extended to the new variant set rather than shrunk.

ghost-secondary carries no background in any state — that is what the design paints, and it is why the token export ships no background for it; only its border moves between stroke-subtle and grey-500.

Migration (in this PR for every call site): the outlined treatment is now ghost-secondary, secondary is the solid grey fill that gray used to be, errorcritical, ghost-destructiveghost-critical, word sizes → letters, icon children → prefixIcon/suffixIcon with shape="square" for icon-only buttons.

Verified: ui/sdk lint + typecheck, build:ui, build:lib, stylelint, 61 test files / 475 tests, docs build, demo build.

The component takes variant, size and shape as explicit props and
composes its content from prefixIcon, children and suffixIcon, so the
three structural subtypes and the children-shape inference behind them
are gone. Ten variants cover the solid and ghost treatments, sizes are
letter-scaled, and square and round render the icon-only box.

Metrics and colours come from the design component set: heights
48/42/36/32/28 with matching padding, gap, radius, icon box and label
role per size, and every fill, border and label colour bound to its
component token.

Call sites move with it: the outlined treatment is now ghost-secondary
while secondary is the solid grey fill, error becomes critical, and
word sizes become letters.
@librowski librowski changed the title feat(ui)!: rebuild Button on the design system axes Rebuild Button on the design system axes Aug 21, 2026
…n props

Disabled solid buttons paired the disabled surface with the ghost text
colour, which resolves to the same value in the dark theme - the label
and icons disappeared. They take the disabled text token the design
specifies, and each ghost variant takes its own accent counterpart.

The loading dots inherit the current colour instead of the on-accent
one, so they stay visible on light ghost buttons.

Props are a union: a label button with optional icons, or a square or
round button that requires the icon it renders. Combinations that
rendered an empty box no longer compile, and the element-child
fallback is gone, so nothing inspects children's shape any more. Two
SDK wrappers and one call site that erased the discrimination now name
the label form explicitly.

Loading also reaches assistive technology and blocks activation, not
just pointers. The placeholder draws one dashed outline again, the
retired variant variables are deleted, and the docs table lists every
prop the component takes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant