feat(buttons): add Button and LinkButton with CVA variants [INTORG-705]#266
feat(buttons): add Button and LinkButton with CVA variants [INTORG-705]#266Infi-Knight wants to merge 3 commits intostagingfrom
Conversation
Ships two new components (Button.astro, LinkButton.astro) and a long-lived
SEO-excluded preview route at /preview/ui-components. Establishes the
pillar-aware primary button colour system via three runtime CSS vars
(--color-button-primary{,-hover,-disabled}) with orchid as the :root default.
No consumers migrated in this PR. Migration is a follow-up series.
✅ Deploy Preview for interledger-org-v5 ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
| ], | ||
| { | ||
| variants: { | ||
| variant: { |
There was a problem hiding this comment.
Bug: for the secondary variant, the disabled button changes on hover
There was a problem hiding this comment.
Good catch, fixed in 0cfbea0. Root cause: :hover still fires on <button disabled> natively (the spec only blocks click events, not pointer states). The compoundVariants for secondary now explicitly reset bg/border/text under both disabled: and aria-disabled:, so the disabled state is fully inert visually.
| <svg | ||
| slot="icon-left" | ||
| class="size-4" | ||
| viewBox="0 0 16 16" | ||
| fill="none" | ||
| aria-hidden="true" | ||
| > | ||
| <path | ||
| d="M10 4 6 8l4 4" | ||
| stroke="currentColor" | ||
| stroke-width="2" | ||
| stroke-linecap="round" | ||
| stroke-linejoin="round"></path> | ||
| </svg> |
There was a problem hiding this comment.
Refactored in 0cfbea0: added src/components/shared/Icon.astro keyed by name (chevron-left, chevron-right for now), default size-4 overridable via class, currentColor so it inherits from the parent button text colour. The preview page now uses <Icon name="chevron-right" /> instead of inlined SVGs.
On the Figma mismatch: the chevrons in the preview page are placeholders: icons are slot content the caller passes in. Adding the exact Figma icon set is a separate piece of work (icon extract / sprite pipeline / naming convention), so I would prefer to keep this PR focused. Happy to open a follow-up issue once we agree on the approach. Does that work?
| class={twMerge( | ||
| buttonVariants({ variant, mode, size, iconOnly, class: className }) | ||
| )} | ||
| data-umami-event={umami} |
There was a problem hiding this comment.
For analytics, there's already a PR that auto-instruments data-umami-event on links (See PR #256) - flagging in case it slipped past you, since we're turning away from manually adding umami props.
I'm not saying you should handle it in this PR, but if you don't, could you open a follow-up issue so it doesn't get lost? 😁
There was a problem hiding this comment.
Removed the umami prop in 0cfbea0. The wrapper was incomplete anyway (only set data-umami-event, not the full data-event-* set that buildUmamiAttrs produces). Consumers can pass data-umami-event (and any data-event-*) directly via the rest spread on <LinkButton>, or use buildUmamiAttrs and spread the result. PR #256 covers MDX inline links via the rehype plugin; component-level instrumentation stays at the call site where it has the right context.
Anca2022
left a comment
There was a problem hiding this comment.
Waiting on the final Figma, but in the meantime I left a few comments and flagged one bug.
Other than that, this truly looks great, Ravi! 😁
- Reset bg/border on disabled secondary buttons; hover was still firing on disabled <button>, leaving the hover bg/border visible. - Remove docs/plans/intorg-705.md reference - Remove redundant umami prop from LinkButton; callers can pass data-umami-event via rest props if needed (auto-instrumentation in #256 covers MDX inline links). - Add Icon.astro component, replace inlined SVGs in the preview page.
|
The 404 page seems to have broken |


Summary
Ships
Button.astroandLinkButton.astroplus a long-lived SEO-excluded preview route at/preview/ui-components. Establishes the pillar-aware primary-button colour system through three runtime CSS vars (--color-button-primary,--color-button-primary-hover,--color-button-primary-disabled) with orchid as the:rootdefault.Related Issue
Fixes INTORG-705. Builds on INTORG-643 (PR #263) which landed the design-system token foundation.
Manual Test
pnpm devand open http://localhost:1103/preview/ui-componentsclass="w-full"to a<Button>produces a full-width button (tailwind-merge lets caller classes win).Checks
pnpm run formatpnpm run lintPR Checklist
Why CVA
Multi-axis variant matrix (variant x mode x size x iconOnly) handled with
compoundVariants. Every Tailwind class is a literal string at definition time so the v4 content scanner sees them. Callerclassflows through tailwind-merge so per-property dedup picks the right winner.Pillar-aware primary, how it works
Primary button colour resolves through three runtime CSS vars defined on
:rootinsrc/styles/base/variables.cssand exposed as Tailwind utilities (bg-button-primary, etc.) via an@theme inlineblock insrc/styles/theme.css. Orchid is the:rootdefault, effectively "the orchid pillar." Per-pillar mappings for tech, mission, vision, and values are out of scope for this PR (blocked on design); each future pillar is a 3-line addition under a[data-pillar='X']selector.Caller overrides, three patterns
Pattern A (preferred when re-tinting to a known pillar):
Pattern B (preferred when forcing a specific palette colour):
Pattern C (preferred for one-off non-colour tweaks):