Skip to content

feat(ui): add ButtonGroup primitive#4308

Closed
warcos-fact wants to merge 17 commits into
cocreation-patterns-definitionfrom
feat/f0card-footer-buttongroup
Closed

feat(ui): add ButtonGroup primitive#4308
warcos-fact wants to merge 17 commits into
cocreation-patterns-definitionfrom
feat/f0card-footer-buttongroup

Conversation

@warcos-fact

@warcos-fact warcos-fact commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a ButtonGroup UI primitive for grouping action buttons (alignment, gap, responsive stacking).

Stacked on top of cocreation-patterns-definition (PR #4307).

Note: The footer adoption was rolled back — ButtonGroup still needs to evolve to cover all card/dialog footer cases before it's applied. This PR now ships the standalone primitive only; CardActions and F0DialogFooter keep their original layout. Kept in draft until the component is ready to adopt.

Changes

  • Add ButtonGroup UI primitive + story.

🤖 Generated with Claude Code

Introduce a low-level ButtonGroup layout primitive (alignment, gap,
responsive stacking) and use it for the CardActions footer and the
F0Dialog footer so action rows share one arrangement primitive.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@warcos-fact warcos-fact requested a review from a team as a code owner June 3, 2026 14:28
@github-actions github-actions Bot added feat react Changes affect packages/react labels Jun 3, 2026
@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

🔍 Visual review for your branch is published 🔍

Here are the links to:

@warcos-fact warcos-fact marked this pull request as draft June 4, 2026 08:43
warcos-fact and others added 2 commits June 4, 2026 10:47
…imitive)

The ButtonGroup primitive needs to evolve to cover all footer cases before
it's adopted. Restore CardActions and F0DialogFooter to their pre-adoption
layout (also dropping the hideLabel plumbing that came with the adoption),
while keeping the standalone ButtonGroup component and its story.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@warcos-fact warcos-fact changed the title feat(ui): add ButtonGroup primitive and adopt it in card/dialog footers feat(ui): add ButtonGroup primitive Jun 4, 2026
warcos-fact and others added 14 commits June 4, 2026 16:10
Evolve the ButtonGroup primitive so its variants express the action-button
arrangements of Dialog footer/header, ResourceHeader, and Card footer/oneLiner,
with a behavior-matrix doc and proof-of-replaceability stories. No real
components are migrated yet.

- variants: align (end/between), gap, stack (viewport sm/md + container-md),
  fullWidthOnStack, wrap; plus a ButtonGroupSeparator divider.
- ButtonGroupOverflow: width-driven overflow helper (wraps OverflowList) with an
  ellipsis "more" trigger + menu rows.
- ButtonGroup.mdx: behavior matrix + per-surface recipes; documents what the
  primitive does NOT own (chrome, size, collapse decisions) and viewport vs
  container stacking.
- Stories: per-surface proof examples inside minimal mock surfaces.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ng patterns

Reconcile the five real-world examples into three agnostic, intent-based
patterns (Trailing / Split / Reflowing) plus orthogonal composition pieces
(split button, overflow menu, separator, icon-only).

- Replace the wide behavior matrix with a compact 3-column at-a-glance table
  plus one short section per pattern.
- Minimal mock surfaces (footer/header/card frames) without placeholder
  bars; fix the Reflowing example rendering full-bleed (drop layout
  fullscreen) and show the overflow menu at several widths so the
  width-driven collapse is visible.
- Drop the orphaned reverseOnStack control (its variant had been removed,
  leaving a no-op knob).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reverses the stacked (column) order via flex-col-reverse so the primary
(passed last) sits on top when the group stacks, while the row order at/above
the breakpoint is unchanged. The whole column reverses — secondary buttons flip
too — which is acceptable. Re-adds the control and a StackReversed story.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…tions

Extract the one-liner card into its own F0CardOneLiner component and remove the
`oneLiner` boolean from F0Card (the two layouts were separate render trees behind
a flag).

- F0CardOneLiner: optional md avatar (any avatar type) on the left, stacked
  single-line title + description, actions on the right; supports primary /
  secondary actions, otherActions and the alert banner.
- Actions use a left-positioned "more" (⋯) menu with the primary pinned at the
  trailing edge. Wide: all secondary buttons inline. Narrow: the row drops to its
  own line and secondary buttons shed right→left into the ⋯ (measured via
  OverflowList's engine); otherActions ride along in that menu.
- CardAvatar gains a `size` prop (md now reachable, no vertical margin inline).
- Migrate F0HILActionConfirmation to F0CardOneLiner; move the one-liner stories
  to F0CardOneLiner.stories.tsx.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…OneLiner

- `stackAt` ("sm" | "md" | "lg" | "never", default "md") controls the container
  width at which the actions drop to their own line; "never" keeps them inline at
  every width (the title truncates instead).
- `confirmAction` / `rejectAction` render an icon-only ✗ (reject) + ✓ (confirm)
  pair in place of the standard actions, for inline approve/reject rows.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…prop controls

- `stackAt` now defaults to "sm" (actions drop to their own line below the @sm
  container width instead of @md).
- Add `module` (F0AvatarModule) to the avatar options, rendered at md.
- Declare explicit argTypes on the OneLiner story so every prop (avatar, stackAt,
  confirm/reject, …) shows in autodocs Controls — docgen can't infer them through
  the withDataTestId(withSkeleton(...)) wrapper.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…a11y

- gap is now a constant gap-md (8px) for every group; drop the gap variant
  (the old lg→gap-md mapped to the same 8px as md).
- ButtonGroupOverflow: shed buttons into a real ellipsis Dropdown (Radix menu
  that closes on select), measured via useOverflowCalculation — replaces the
  OverflowList popover whose plain-button items never closed.
- ButtonGroup: add role="group".
- ButtonGroupSeparator: drop the fragile showOn prop (always renders, for row
  layouts) and use bg-f1-background-secondary.
- Stories: @container on the main decorator so the container-md control works;
  rename the Stack helper to Cases.
- Docs: rewrite the Reflowing rationale (the order reflows via reverseOnStack;
  two groups are only for the size flip + Dropdown↔MobileDropdown swap) and
  document reverseOnStack.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Standardize the overflow/"more" affordance on the vertical ellipsis (kebab) for
consistency, since it opens a dropdown menu: ButtonGroupOverflow and the Reflowing
desktop Dropdown were using the horizontal ellipsis.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Promote F0CardOneLiner toward Stable:
- Add a unit test suite covering title/description, every avatar type, link,
  onClick, primary/secondary/other actions, the confirm/reject variant, alert,
  and stackAt.
- Add a component description + use cases to the autodocs page.
- Fix the docs "Importing this component" snippet: resolveImportPath derives the
  name from the story filename first, so it shows F0CardOneLiner (not F0Card).
- Polish OneLinerActions: import the Ref type instead of the global React
  namespace, and skip the hidden measurement subtree when stackAt is "never".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
"OneLiner" overclaimed a single line (the component shows title + description and
can stack actions onto a second row) and read as a colloquialism. F0CardRow names
it after what it is: the horizontal, row-shaped counterpart to the stacked F0Card.

Renames the component, props/types (CardRowStackAt, CardRowConfirmAction), the
internal CardRowActions, files, story title (Card/Row), tests, and the
F0HILActionConfirmation consumer. No behaviour change. Done pre-release, so no
deprecation alias is needed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@warcos-fact

Copy link
Copy Markdown
Contributor Author

Superseded by the split PRs: #4339 (ButtonGroup primitive) and #4340 (F0CardRow). The combined feat/f0card-footer-buttongroup branch is kept for reference.

@warcos-fact warcos-fact closed this Jun 5, 2026
@warcos-fact warcos-fact deleted the feat/f0card-footer-buttongroup branch June 5, 2026 10:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat react Changes affect packages/react

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant