feat(badge): Badge primitive (shadcn v4) + gallery showcase#49
Merged
Conversation
added 10 commits
June 15, 2026 10:16
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Badge — the third flutterbits primitive
Ships
Badgeatapps/gallery/lib/components/ui/badge.dart— a Material-free, themeable, shadcn-v4-faithful variant pill. It's the canonical shape for a variant-based, non-interactive, single-box primitive:Button's variant discipline (typed enum + exhaustiveswitch+ record palette) withoutButton's interaction-state machine, andCard's non-interactive stance withoutCard's composition.shadcn v4 class mapping
Authoritative base (new-york-v4):
inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap [&>svg]:size-3.rounded-full/overflow-hidden.roundedFull/.clip()border border-transparent+ outlineborder-border.border(1, color:)— transparentColor(0x00000000)(filled) /c.border(outline)px-2 py-0.5 text-xs font-medium gap-1.px(2).py(0.5).textSize(FwFontSize.xs.px).weight(FwFontWeight.medium)+FwRow(gap:1)[&>svg]:size-3IconTheme.merge(size:12)(pins icon size independent of text size)BadgeVariant {primary, secondary, destructive, outline}Design decisions
StatelessWidget). shadcn's default badge is a<span>; its hover states are[a&]:(link-only). Clickability is composed by wrapping — documented, consistent withCard.default→primary(Dart reserved word), every other shadcn name verbatim. No size enum (shadcn's Badge has one size).Button): destructive foreground uses thedestructiveForegroundtoken, not a literaltext-white(AGENTS.md §3.1 bans color literals except transparent; ≈ white in the stock theme and it reskins); thedark:bg-destructive/60refinement is dropped in favor of the flatdestructivetoken both brightnesses.w-fit) — documented behavior in a stretch parent (wrap inAlign/FwRow).semanticLabelreplaces child semantics viaSemantics(excludeSemantics: true)— verified empirically (without it a text child double-announces). Icon-only badges must pass it.Tests
destructiveForeground), icon slots (gap-1 horizontalFlex,mainAxisSize.min),semanticLabelreplacement for both icon-only and text children (no double-announce), RTL composition, theme reskin (dark token present, light absent).badge_golden_test.dart) — all 4 variants + icon slots, light / dark / RTL.apps/gallery(Badges section) + smoke-tested.Also
.gitignore: generalized the golden-failure-artifact rule to**/test/**/failures/so it covers every package/app test tree (it previously only matched a root-leveltest/).Executed via superpowers subagent-driven-development (implementer + spec-review + code-quality-review; review findings triaged and applied —
excludeSemantics, foreground/border/Flex test guards).🤖 Generated with Claude Code
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com