Skip to content

feat(flutterbits): canonical Button + apps/gallery (first component slice)#45

Merged
SiphoChris merged 10 commits into
mainfrom
feat/flutterbits-button-gallery
Jun 10, 2026
Merged

feat(flutterbits): canonical Button + apps/gallery (first component slice)#45
SiphoChris merged 10 commits into
mainfrom
feat/flutterbits-button-gallery

Conversation

@SiphoChris

Copy link
Copy Markdown
Owner

First flutterbits component slice: the canonical Button + the new apps/gallery component app. Executed task-by-task (TDD) from docs/superpowers/plans/2026-06-10-flutterbits-button-and-gallery.md, with spec + code-quality review after each task and a final whole-implementation review (Opus).

What's here

  • apps/gallery — a new Material-free Flutter app + pub-workspace member; the flutterbits component golden/compile target (distinct from the engine's apps/example). Its root is a temporary WidgetsApp bootstrap, clearly labeled — the structure plan replaces it with Layout.
  • Button (apps/gallery/lib/components/ui/button.dart) — Material-free, copy-paste source. 6 variants (primary/secondary/destructive/outline/ghost/link) × 4 sizes (sm/md/lg/icon), styled entirely through flutterwindcss .tw with semantic tokens only. Sources its own hover/focus/pressed/disabled via FocusableActionDetector + a tap detector; keyboard activation (Enter/Space via ActivateIntentCallbackAction); focus-visible ring (context.fw.colors.ring); Semantics(button:, enabled:, label:); directional layout.
  • Tests — behavior (tap fires / disabled blocks / keyboard activates / semantics flags / one styled box per variant), a golden grid (every variant × size × brightness + a disabled row + RTL), and a gallery smoke test. 10/10 pass, flutter analyze --fatal-infos --fatal-warnings clean, dart format clean.
  • Docs reconciliation (in-branch, no-drift)default is a Dart reserved word, so shadcn's default variant → primary and default size → md; recorded in AGENTS.md §4 + the charter §3.2.

Review status

Final Opus review: Ready to merge. Every AGENTS.md §6 "component done" item and §3 hard rule passes (no material.dart, context.fw only, Color.withValues, only-transparent literal, exhaustive switches). No leftover shims/TODOs. A code-quality finding ("ring fires on mouse focus") was verified against the SDK as a false positiveonShowFocusHighlight is already gated on FocusManager.highlightMode, so it's correctly focus-visible (a clarifying comment was added).

Known follow-ups (explicitly out of this plan's scope)

  1. No CI job for apps/gallery yet.github/workflows/ci.yaml covers flutterwindcss/example/docs but not gallery. A job mirroring the apps/example one is needed to gate the component in CI.
  2. Goldens are Windows-generated — baselines were generated locally and eyeball-verified (every variant renders correctly), but CI Linux is the authoritative golden platform (AGENTS.md §9); they must be regenerated on CI Linux before a gallery CI golden job can pass deterministically.
  3. Registry promotionregistry/button.dart + the manifest JSON + tooling/build_registry.dart are deliberately deferred to the next (registry/CLI) plan, where the manifest's metadata-source is decided alongside the CLI.

🤖 Generated with Claude Code

Sipho Nkebe and others added 10 commits June 10, 2026 22:11
Adds ButtonVariant and ButtonSize enums, the minimal Button StatefulWidget
skeleton (Semantics wrapper, no styling yet), and the first behavior test
asserting label rendering and button/enabled semantics flags.

Adapts plan's test to Flutter 3.41.9 API (flagsCollection on SemanticsData,
Tristate from dart:ui — hasFlag was deprecated after v3.32.0).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add FocusableActionDetector with Enter/Space → ActivateIntent wiring so the
Button activates from the keyboard. Adds focusNode param for external focus
control (used by tests). Stores _hovered/_focused/_pressed state booleans;
_stateProxy reads all three (Task 4 replaces the pass-through with real .tw
styling). Adds two keyboard tests (Enter + Space) following the direct
focus.requestFocus() harness pattern for test reliability.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- I-1 (false positive): onShowFocusHighlight is already focus-visible-aware
  (gates on _canShowHighlight which is false for FocusHighlightMode.touch).
  Added a comment at the ring site explaining this so a future reader does
  not add a redundant highlightMode check.
- I-2: added one-sentence hover comment noting the /90 alpha is translucent
  and requires a background-coloured surface to avoid bleed-through.
- M-1: collapsed the Center ternary to a single Center(widthFactor: ... ? null : 1.0).
- M-2: replaced var isLink = false / isLink = true with final isLink = variant == link.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Covers all 6 ButtonVariant × 4 ButtonSize combinations in light and dark
themes, plus a dedicated disabled row and a light-RTL mirror test that
verifies EdgeInsetsDirectional padding/border layout is correctly flipped.

Surface overflow avoided via UnconstrainedBox around the RepaintBoundary;
find.byType(RepaintBoundary).first used as the stable capture target.

Baselines generated on Windows (Flutter 3.41.9) for local verification.
CI Linux is the authoritative golden platform (AGENTS.md §9) — regenerate
with --update-goldens on CI when the apps/gallery CI job lands.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ants/sizes

Reconciles charter 3.2 + AGENTS 4 with the implemented Button: 'default' is a
Dart reserved word so it can't be an enum constant — shadcn's 'default' variant
maps to 'primary' and 'default' size to 'md'; every other shadcn name verbatim.

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

vercel Bot commented Jun 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
flutterbits Ready Ready Preview, Comment Jun 10, 2026 9:15pm

@SiphoChris SiphoChris merged commit aed9563 into main Jun 10, 2026
7 checks passed
@SiphoChris SiphoChris deleted the feat/flutterbits-button-gallery branch June 10, 2026 21:20
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