Skip to content

feat(bulma-ui): make Button and Link as prop polymorphic (React.ElementType) - #238

Merged
allxsmith merged 1 commit into
mainfrom
claude/issue-188-20260707-0205
Jul 7, 2026
Merged

allxsmith merged 1 commit into
mainfrom
claude/issue-188-20260707-0205

Conversation

@bestaxbot

@bestaxbot bestaxbot commented Jul 7, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Widen the Button as prop from a fixed 'a' | 'button' union to React.ElementType, so it can render as a router Link component (React Router, Next.js, TanStack Router, etc.) while keeping Bulma styling and real anchor semantics.
  • Add a new as prop (default 'a') to Link for the same polymorphic rendering.
  • LinkButton inherits the same polymorphism for free, since it already forwards its props to Button — no code change needed there.
  • Add an accessibility admonition to the top of the Button docs page steering readers toward LinkButton for link-styled or navigating click targets.
  • Add Storybook stories and Jest tests for the new polymorphic as usage; update the Button, Link, and LinkButton docs pages.

Fixes #188

Test plan

  • pnpm --filter @allxsmith/bestax-bulma run typecheck
  • pnpm --filter @allxsmith/bestax-bulma run lint (0 errors, pre-existing unrelated warnings only)
  • pnpm --filter @allxsmith/bestax-bulma run test:coverage (3325/3325 passing, Button.tsx/Link.tsx/LinkButton.tsx at 100% coverage)
  • pnpm run format:check
  • pnpm run gen:catalog:check (catalog unchanged — no component added/renamed)

Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Button, Link, and LinkButton now support rendering with a custom as component, making them more flexible for router-style links and other custom elements.
    • Added examples in Storybook showing polymorphic usage for each component.
  • Bug Fixes

    • Improved prop forwarding so component-specific attributes are passed through correctly.
    • Prevented button-only attributes from leaking onto non-button render targets.
  • Documentation

    • Updated API docs and usage examples to cover the new polymorphic rendering behavior and related accessibility guidance.

…ntType)

Widen Button's `as` prop from 'a' | 'button' to React.ElementType and add
an `as` prop (default 'a') to Link, so both can render as a router Link
component (React Router, Next.js, TanStack Router, etc.) while keeping
Bulma styling and real anchor semantics. LinkButton inherits the same
polymorphism for free since it already forwards its props to Button.

Fixes #188

Co-authored-by: Alex Smith <allxsmith@users.noreply.github.com>
@bestaxbot bestaxbot added the ai-loop AI-authored PR in the autonomous review/fix loop label Jul 7, 2026
@coderabbitai

coderabbitai Bot commented Jul 7, 2026 •

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The as prop on Button and Link (and by extension LinkButton) is widened from a restricted string union to React.ElementType, enabling polymorphic rendering via custom components (e.g., router Link). Rendering logic, prop stripping, stories, tests, and docs are updated accordingly.

Changes

Polymorphic as prop implementation

Layer / File(s) Summary
Button core rendering logic
bulma-ui/src/elements/Button.tsx
ButtonProps.as widened to React.ElementType; internal Component variable defaults to 'button'; render path switches on Component !== 'button' and renders <Component> with anchor-only prop stripping.
Button stories and tests
bulma-ui/src/elements/Button.stories.tsx, bulma-ui/src/elements/__tests__/Button.test.tsx
New PolymorphicAs story and tests verify custom-component rendering, forwarded link props, and stripped button-only attributes.
Link core rendering logic
bulma-ui/src/elements/Link.tsx
LinkProps gains as?: React.ElementType (default 'a'); component destructures Component and renders it instead of a hardcoded <a>.
Link stories and tests
bulma-ui/src/elements/Link.stories.tsx, bulma-ui/src/elements/__tests__/Link.test.tsx
New PolymorphicAs story and tests verify default <a> rendering and custom component prop/class forwarding.
LinkButton stories and tests
bulma-ui/src/elements/LinkButton.stories.tsx, bulma-ui/src/elements/__tests__/LinkButton.test.tsx
New PolymorphicAs story and test confirm LinkButton inherits polymorphic rendering via Button.
Documentation updates
docs/docs/api/elements/button.md, docs/docs/api/elements/link.md, docs/docs/api/elements/linkbutton.md
Props tables updated to React.ElementType; new "Polymorphic as (Router Links)" usage sections added; accessibility caution added to Button docs.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant App
  participant Button
  participant Component as "Custom Component (e.g., RouterLink)"

  App->>Button: render with as=RouterLink, to="/visit"
  Button->>Button: destructure as Component (default 'button')
  Button->>Button: check Component !== 'button'
  Button->>Button: strip button-only props (type, disabled, form)
  Button->>Component: render <Component> with remaining props + className
  Component-->>App: rendered anchor/router element
Loading

Possibly related issues

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: polymorphic as support for Button and Link.
Description check ✅ Passed The description covers the summary and test plan, but it omits several template sections like package checklist, change type, and screenshots.
Linked Issues check ✅ Passed The PR implements the linked feature by making Button and Link polymorphic, preserving LinkButton behavior, and updating docs/tests/stories.
Out of Scope Changes check ✅ Passed The changed files all support the polymorphic as feature and related documentation/testing, with no clear unrelated additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/issue-188-20260707-0205

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Preview Deployment

Preview URL: https://9d24ba79.bestax.pages.dev

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

**Deep review complete** — 0 finding(s) posted as inline comments.

Reviewed the polymorphic as (React.ElementType) change across Button, Link, and LinkButton. Verified: old 'a'/'button' behavior preserved (Component !== 'button' branch), as destructured so it never leaks to the DOM, button-only attributes stripped for the link branch (documented), and accessibility handling (aria-disabled, tabIndex, disabled onClick preventDefault) intact. Ran the affected suites (60 tests pass), confirmed 100% coverage on all three changed files, and typecheck is clean. All five artifacts present — component, tests, stories, and docs pages — and the skills component catalog is not stale (description extractor skips the new :::caution admonition). No correctness, a11y, API-consistency, or coverage defects found.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

♻️ Duplicate comments (1)
bulma-ui/src/elements/Link.tsx (1)

30-30: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Same polymorphism gap as Button: as?: React.ElementType doesn't widen the prop surface.

Link is React.FC<LinkProps> and LinkProps extends only React.AnchorHTMLAttributes. <Link as={RouterLikeLink} to="/about"> (story/test) passes to, which isn't in LinkProps, so it won't type-check under strict TS. Consider a generic polymorphic signature so custom-component props are inferred from as.

See the companion comment on Button.tsx (Line 67) for the root-cause detail and verification.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@bulma-ui/src/elements/Link.tsx` at line 30, `Link` currently only accepts
anchor attributes even when `as` points to a custom component, so props like
`to` are not inferred. Update the `Link` typing to use a polymorphic generic
signature (similar to the `Button` fix) so `LinkProps` widens based on the `as`
component, and make sure `Link` itself and its prop definitions reflect that
inferred prop surface.
🧹 Nitpick comments (1)
bulma-ui/src/elements/Button.stories.tsx (1)

415-431: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Extract the shared RouterLikeLink story helper. It’s duplicated in Button.stories.tsx, Link.stories.tsx, and LinkButton.stories.tsx, so a small shared helper would reduce drift in the polymorphic stories.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@bulma-ui/src/elements/Button.stories.tsx` around lines 415 - 431, The
polymorphic Router-like link helper is duplicated across the Button, Link, and
LinkButton stories, so extract the shared RouterLikeLink component into a
reusable story helper and import it where needed. Update the PolymorphicAs story
in Button.stories.tsx to use the shared helper, and keep the same props shape
and anchor passthrough behavior so the polymorphic stories stay consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@bulma-ui/src/elements/Button.tsx`:
- Line 67: The Button component is only partially polymorphic: the current as
prop changes the rendered element, but ButtonProps still do not inherit props
from the chosen element, so router-specific props like to won’t type-check.
Update Button to use a generic polymorphic type based on the selected element
(for example via ComponentProps<T> and a generic Button signature), or restrict
the API to only button/anchor props if full polymorphism is not intended. Focus
on the Button component types and its public props definition so RouterLikeLink
usages are accepted correctly.

In `@docs/docs/api/elements/button.md`:
- Around line 292-306: The router-link example in the Button docs is not
type-safe because ButtonProps currently does not accept router-specific props
like to when using as={RouterLink}. Update the docs example to match the actual
polymorphic API exposed by Button, either by widening the Button/ButtonProps
typing to forward the router component’s props or by replacing to with a prop
shape that is already supported by the component. Also tighten the “real anchor
semantics” copy in the Button polymorphic as section unless Button truly renders
or forwards an anchor element for custom components.

In `@docs/docs/api/elements/link.md`:
- Around line 109-121: The router-link example in Link documentation uses props
like to that are not part of the current Link type surface, so update the
example to avoid implying direct support for router-specific props unless Link
is truly polymorphic. Either rewrite the example to use a small wrapper
component that accepts and forwards router props, or adjust Link’s
typing/implementation so the as prop carries through the target component’s
props; reference the Link component and its polymorphic as usage in the docs
example.

In `@docs/docs/api/elements/linkbutton.md`:
- Around line 129-141: The router-link example in LinkButton docs is not
supported by the current type surface because LinkButton is only a
React.FC<LinkButtonProps> over ButtonProps, so it does not expose a typed to
prop. Update the documentation near the LinkButton “Polymorphic as” section to
either remove the RouterLink example or change LinkButton/Button to a truly
polymorphic API first; use the LinkButtonProps and ButtonProps symbols to verify
the documented usage matches the actual exported types.

---

Duplicate comments:
In `@bulma-ui/src/elements/Link.tsx`:
- Line 30: `Link` currently only accepts anchor attributes even when `as` points
to a custom component, so props like `to` are not inferred. Update the `Link`
typing to use a polymorphic generic signature (similar to the `Button` fix) so
`LinkProps` widens based on the `as` component, and make sure `Link` itself and
its prop definitions reflect that inferred prop surface.

---

Nitpick comments:
In `@bulma-ui/src/elements/Button.stories.tsx`:
- Around line 415-431: The polymorphic Router-like link helper is duplicated
across the Button, Link, and LinkButton stories, so extract the shared
RouterLikeLink component into a reusable story helper and import it where
needed. Update the PolymorphicAs story in Button.stories.tsx to use the shared
helper, and keep the same props shape and anchor passthrough behavior so the
polymorphic stories stay consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 826fe6ad-0f64-4c76-82fa-71c6e8e18bd0

📥 Commits

Reviewing files that changed from the base of the PR and between 46d4e6e and 1f38a5b.

📒 Files selected for processing (11)
  • bulma-ui/src/elements/Button.stories.tsx
  • bulma-ui/src/elements/Button.tsx
  • bulma-ui/src/elements/Link.stories.tsx
  • bulma-ui/src/elements/Link.tsx
  • bulma-ui/src/elements/LinkButton.stories.tsx
  • bulma-ui/src/elements/__tests__/Button.test.tsx
  • bulma-ui/src/elements/__tests__/Link.test.tsx
  • bulma-ui/src/elements/__tests__/LinkButton.test.tsx
  • docs/docs/api/elements/button.md
  • docs/docs/api/elements/link.md
  • docs/docs/api/elements/linkbutton.md

Comment thread bulma-ui/src/elements/Button.tsx
Comment thread docs/docs/api/elements/button.md
Comment thread docs/docs/api/elements/link.md
Comment thread docs/docs/api/elements/linkbutton.md
@github-actions

github-actions Bot commented Jul 7, 2026 •

Copy link
Copy Markdown
Contributor

AI loop status: iteration 1/4 — fix-reviews at 1f38a5b (2026-07-07T02:47:31Z).
Managed by claude-pr-loop.yml. To resume after a pause: set iteration back to 0 on the first line, re-add ai-loop, remove ai-loop-paused, then re-run via workflow_dispatch.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

AI loop paused: the fix run failed without pushing (see the Actions log). Remove ai-loop-paused, re-add ai-loop, and re-run via workflow_dispatch to retry.

@github-actions github-actions Bot added ai-loop-paused Loop hit cap or a guard: owner intervention required and removed ai-loop AI-authored PR in the autonomous review/fix loop labels Jul 7, 2026
allxsmith added a commit that referenced this pull request Jul 7, 2026
#239)

The fix run on PR #238 died with error_max_turns: 80 turns, 42 permission
denials, $3.82, and zero output — no refutations, no fixes, no summary.
The agent thrashed on denied tool calls and never converged; the loop then
paused safely (ai-loop-paused).

Root cause is a task/allowance mismatch on the FIX agent specifically. Its
job is heavy — verify each finding against code, edit, test, reply in
threads, commit, push — but its allowlist carried no read-only inspection
utilities, so every rg/cat/sed/ls/grep a verifying agent reaches for was a
denial. Compounded by a tight 80-turn cap and the weaker sonnet model.

Mirror robobun's approach (scope tools to the task; stronger model; no tight
turn starvation) for this heavy pass:
- Add read-only inspection utils: rg, grep, cat, sed, ls, head, tail, wc,
  find — kills the denial source, all read-only.
- Raise the cap 80 -> 120 (the implement agent already runs at 150).
- Run the fixer on claude-opus-4-8[1m] instead of sonnet-5 — a stronger
  model wastes fewer turns on a multi-finding adversarial pass, and the
  deep reviewer already uses opus.

Implement agent is unchanged (it works — it opened #238).


Claude-Session: https://claude.ai/code/session_01NVR5yWevceZEFbTJmpviiM

Co-authored-by: Claude <noreply@anthropic.com>
@allxsmith allxsmith added ai-loop AI-authored PR in the autonomous review/fix loop and removed ai-loop-paused Loop hit cap or a guard: owner intervention required labels Jul 7, 2026 — with Claude
@bestaxbot

Copy link
Copy Markdown
Collaborator Author

FIX agent (iteration 1/4, mode: fix-reviews) — summary

No code changes this pass. All four open CodeRabbit findings are the same underlying request and I am refuting them.

Finding (thread) Verdict Reason
Button.tsx:67 — make Button truly polymorphic (ComponentProps) Refuted Full generic polymorphic API is explicitly deferred by issue #188 (ideal but not required); a large public-API/type-system refactor, out of scope for a fix pass
button.md:306 — router example not type-safe Refuted Example mirrors the exact usage requested in #188; to is forwarded at runtime; static typing of forwarded props needs the deferred generic API
link.md:121 — router props not in type surface Refuted Link now adds as?: React.ElementType + ...rest per #188; runtime-forwards to; generic typing deferred
linkbutton.md:141 — router example misleading Refuted LinkButton forwards ...props to Button per #188; runtime-forwards to; generic typing deferred

Why refuted (shared reasoning):

  • Issue [Feature] Make Button, Link, and LinkButton as prop polymorphic (React.ElementType) for router Link integration #188 sets the contract. It states a fully generic as with prop inference would be ideal, but that widening to React.ElementType and spreading ...rest onto the element would unblock the common case — and the per-component notes are literally widen as and forward ...rest (Button), add as?: React.ElementType default a (Link), flows for free (LinkButton). The PR implements exactly this.
  • The type point is technically real but is the known, issue-accepted limitation: under a standalone strict tsc, <Button as={RouterLink} to=...> reports TS2322 because to is not on ButtonProps. However to is forwarded at runtime — the tests assert the rendered element receives data-to — so the documented common case works.
  • Repo gates are green: pnpm run typecheck excludes *.stories.tsx/__tests__ (bulma-ui/tsconfig.json), and the jest suite passes (ts-jest does not surface this as a failure here).
  • Making the trio fully generic (ComponentProps<T> inference) is a deliberate public-API decision that should be reviewed on its own, not folded into a review-fix pass. Escalating that call to a human maintainer.

Verification performed this pass:

No commit made (no cosmetic changes). CodeRabbit threads left open and unresolved for the reviewer to reconcile.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

AI loop stopped — contested findings. The fix agent pushed no changes and 1 review thread(s) remain open (refuted or unaddressable). A human ruling is needed; see the fix agent's summary above.

@github-actions github-actions Bot added needs-human-review Loop converged (or contested): awaiting owner review + manual merge and removed ai-loop AI-authored PR in the autonomous review/fix loop labels Jul 7, 2026
@github-actions
github-actions Bot requested a review from allxsmith July 7, 2026 02:56
@allxsmith
allxsmith merged commit ce90304 into main Jul 7, 2026
60 of 61 checks passed
github-actions Bot pushed a commit that referenced this pull request Jul 7, 2026
# [5.2.0](https://github.com/allxsmith/bestax/compare/@allxsmith/bestax-bulma@5.1.3...@allxsmith/bestax-bulma@5.2.0) (2026-07-07)

### Features

* **bulma-ui:** make Button and Link as prop polymorphic (React.ElementType) ([#238](#238)) ([ce90304](ce90304)), closes [#188](#188)
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 5.2.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

allxsmith added a commit that referenced this pull request Jul 7, 2026
…recipe (#248)

On PR #247 the fix agent ran clean (opus, 24 turns, success) but hit 15
permission denials and produced ZERO output — no commits, no thread replies,
no recap — so the loop escalated with the findings unaddressed. Same class
as the original #238 thrash: the agent reached for a tool that is not
allowlisted and gave up. The execution-output artifact that would name the
tool is defeated by the proxy blocking its blob-storage host, and the job
log hides per-turn detail by default.

Two fixes:
- show_full_output: true on the fix AND verify jobs, so every tool call and
  denial lands in the readable job log (no artifact needed).
- Give both agents the explicit gh-api thread-reply recipe
  (addPullRequestReviewThreadReply) and state plainly that there is NO MCP
  'reply' tool here — only mcp__github_inline_comment__create_inline_comment
  for a NEW comment. Reaching for a nonexistent MCP reply tool is the most
  likely denial source; this makes the reply path deterministic.


Claude-Session: https://claude.ai/code/session_01NVR5yWevceZEFbTJmpviiM

Co-authored-by: Claude <noreply@anthropic.com>
allxsmith added a commit that referenced this pull request Jul 7, 2026
* ci: log full fix/verify output + tell agents the gh-api thread-reply recipe

On PR #247 the fix agent ran clean (opus, 24 turns, success) but hit 15
permission denials and produced ZERO output — no commits, no thread replies,
no recap — so the loop escalated with the findings unaddressed. Same class
as the original #238 thrash: the agent reached for a tool that is not
allowlisted and gave up. The execution-output artifact that would name the
tool is defeated by the proxy blocking its blob-storage host, and the job
log hides per-turn detail by default.

Two fixes:
- show_full_output: true on the fix AND verify jobs, so every tool call and
  denial lands in the readable job log (no artifact needed).
- Give both agents the explicit gh-api thread-reply recipe
  (addPullRequestReviewThreadReply) and state plainly that there is NO MCP
  'reply' tool here — only mcp__github_inline_comment__create_inline_comment
  for a NEW comment. Reaching for a nonexistent MCP reply tool is the most
  likely denial source; this makes the reply path deterministic.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NVR5yWevceZEFbTJmpviiM

* ci: bestaxbot signs off the terminal states in surfer dialect

The loop's human-facing terminal comments (converged / contested /
paused / wipeout) were posted by github-actions[bot] in flat prose.
Give them a personality: bestaxbot now authors them (via AI_LOOP_PAT;
the label + reviewer edits stay on the job token), in a
Californian/Hawaiian surfer voice with an AI-superiority streak —
'clean set, total convergence, need a meat sack to hit merge.'

Covers all five terminal comments: converged handoff, contested
findings, halt (cap/protected/review-failed/cr-stalled), fix-run
wipeout, and verify no-progress. Only the comment author + wording
change; labels, reviewers, and the machine-parsed ai-loop-state
comment are untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NVR5yWevceZEFbTJmpviiM

---------

Co-authored-by: Claude <noreply@anthropic.com>
github-actions Bot pushed a commit that referenced this pull request Jul 11, 2026
# [3.2.0](https://github.com/allxsmith/bestax/compare/create-bestax@3.1.4...create-bestax@3.2.0) (2026-07-11)

### Bug Fixes

* **bulma-ui:** strip redundant library prefix from Icon name ([#242](#242)) ([dbe3622](dbe3622)), closes [#189](#189)

### Features

* **bulma-ui:** add Avatar, Avatars, and Badge components ([#257](#257)) ([0817018](0817018)), closes [#256](#256)
* **bulma-ui:** add Reveal component for scroll-triggered animations ([#255](#255)) ([a89c574](a89c574))
* **bulma-ui:** make Button and Link as prop polymorphic (React.ElementType) ([#238](#238)) ([ce90304](ce90304)), closes [#188](#188)
* **create-bestax:** scaffold-aware CLAUDE.md with setup facts and house style ([#271](#271)) ([c1681b0](c1681b0))
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 3.2.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

allxsmith added a commit that referenced this pull request Jul 14, 2026
New Routing Integration feature guide (docs/guides/features/routing):
Menu.Item as={Link} to (compiles via index signature, forwarding noted),
the Navbar.Item typed-alias workaround (first-class typing spec'd in
#306), ButtonLink/useNavigate patterns (Button as polymorphic since
#238), boundary-matched active-route styling via useLocation, and
correct Next.js version guidance (13+ href pattern; 13-15 deprecated
legacyBehavior/passHref removed in 16; pre-13 anchor-child wrapper).
The layout skill's Navbar section gains a routing note replacing the
href="#" copy-paste trap.

Closes #190
github-actions Bot pushed a commit that referenced this pull request Jul 20, 2026
# 1.0.0 (2026-07-20)

* feat(bulma-ui)!: remove bestax-bulma-prefixed CSS variant ([94baa34](94baa34))
* feat(create-bestax)!: require Node.js 18+ and align with bestax-bulma v2 ([#118](#118)) ([b22f183](b22f183))

### Bug Fixes

* add comprehensive rules to prevent bulma-ui versioning on non-bulma-ui commits ([#122](#122)) ([525ccfa](525ccfa)), closes [#119](#119)
* **bulma-ui:** a11y + case-insensitive Taginput matching from PR review ([d576829](d576829))
* **bulma-ui:** accept router props like `to` on Navbar.Item without casts ([#311](#311)) ([b78856b](b78856b)), closes [#306](#306)
* **bulma-ui:** Add build step to publish in ci.yml ([e3707fc](e3707fc))
* **bulma-ui:** add fontawesome-free as explicit devDependency ([a4a5389](a4a5389))
* **bulma-ui:** add missing exports ([0d16633](0d16633))
* **bulma-ui:** Add Skeleton to exports ([e481599](e481599))
* **bulma-ui:** another attempt to fix semantic release builds with ci.yml ([cc3a3e2](cc3a3e2))
* **bulma-ui:** another attempt to fix semantic release builds with ci.yml ([314bc39](314bc39))
* **bulma-ui:** another attempt to fix semantic release builds with ci.yml ([c930693](c930693))
* **bulma-ui:** complete domain migration and fix semantic-release configuration ([#64](#64)) ([f4cd71d](f4cd71d))
* **bulma-ui:** correct blog post examples and add Modal compound components ([#81](#81)) ([559c2e3](559c2e3))
* **bulma-ui:** correct NPM_TOKEN env variable in ci.yml ([94b48b4](94b48b4))
* **bulma-ui:** Fix release.config.js to include package-lock.json ([390da59](390da59))
* **bulma-ui:** fix standalone Badge pointer-events, pulse halo, and falsy content ([#295](#295)) ([a9db031](a9db031)), closes [#264](#264)
* **bulma-ui:** full classPrefix support across layout/grid + prefix utils ([4ce0b53](4ce0b53))
* **bulma-ui:** improve npm package discoverability with optimized keywords and badges ([#72](#72)) ([8c7a696](8c7a696))
* **bulma-ui:** Initial semantic release changes ([b78d785](b78d785))
* **bulma-ui:** migrate domain from bestax.cc to bestax.io ([#64](#64)) ([4870b1e](4870b1e))
* **bulma-ui:** migrate ionicons to v8 to unblock publish and Storybook ([927a55b](927a55b)), closes [#142](#142)
* **bulma-ui:** publish rewritten README to npm ([9810081](9810081))
* **bulma-ui:** publish with npm provenance attestation ([172da62](172da62)), closes [#180](#180)
* **bulma-ui:** reference llms docs from README and package.json ([#198](#198)) ([db8aab3](db8aab3))
* **bulma-ui:** reject predicate-blocked values during manual entry ([a8f6e28](a8f6e28))
* **bulma-ui:** resolve flex item properties and Card compound component issues ([#55](#55)) ([e774da3](e774da3))
* **bulma-ui:** resolve flex item properties and Card compound component issues ([#55](#55)) ([7641a53](7641a53))
* **bulma-ui:** resolve react-hooks v7 and [@eslint-react](https://github.com/eslint-react) findings ([14caaaf](14caaaf))
* **bulma-ui:** resolve security vulnerabilities and update dependencies ([#128](#128)) ([112f6e4](112f6e4)), closes [#127](#127)
* **bulma-ui:** restrict semantic-release to bulma-ui scoped commits only ([2d67bf9](2d67bf9)), closes [#62](#62)
* **bulma-ui:** retry failed Avatar src, flatten Fragment children in Avatars, RTL-safe overlap ([#297](#297)) ([c00b9db](c00b9db))
* **bulma-ui:** route every hardcoded class through the prefix helpers; add classPrefix sweep test ([#301](#301)) ([a50b134](a50b134)), closes [#286](#286)
* **bulma-ui:** setup gpg signing with semantic-release ([3e24722](3e24722))
* **bulma-ui:** strip redundant library prefix from Icon name ([#242](#242)) ([dbe3622](dbe3622)), closes [#189](#189)
* **bulma-ui:** trigger release to publish via OIDC trusted publishing ([e2d09c5](e2d09c5))
* **bulma-ui:** update bundle size claims to accurate 21KB gzipped ([#66](#66)) ([6e381bd](6e381bd))
* **bulma-ui:** update package-lock.json ([853d585](853d585))
* **bulma-ui:** update package.json for better seo, exports, types, engines, funding, etc ([98cbc56](98cbc56))
* **bulma-ui:** use createRequire for ESM compatibility in Storybook 10 ([#130](#130)) ([b27e60e](b27e60e)), closes [#129](#129)
* **ci:** collect screenshots as artifacts and commit in single batch to avoid conflicts ([27b259d](27b259d))
* **ci:** ensure npm install uses fresh downloads with --prefer-online ([1f2e15d](1f2e15d))
* **ci:** properly extract base path for recursive file search ([e0330ff](e0330ff))
* **ci:** use find command instead of glob module in verified-commit action ([0e2d159](0e2d159))
* **ci:** use npm ci for scaffolded app dependencies ([35652c8](35652c8))
* **create-bestax:** correct browser title to prioritize Bestax branding ([#106](#106)) ([23aa535](23aa535)), closes [#105](#105)
* **create-bestax:** correct template path resolution from ../../ to ../ ([65b4493](65b4493)), closes [#78](#78)
* **create-bestax:** dark-mode contrast rules in theming/layout skills and docs ([#303](#303)) ([490bf21](490bf21)), closes [#194](#194) [#195](#195)
* **create-bestax:** exclude templates directory from linting and typecheck ([18fec0b](18fec0b))
* **create-bestax:** fail fast with guidance instead of hanging when stdin is not a TTY ([#293](#293)) ([46a172d](46a172d)), closes [#192](#192)
* **create-bestax:** move templates into package directory and update docs ([195bf01](195bf01)), closes [#78](#78)
* **create-bestax:** point scaffolded CLAUDE.md at llms docs; document skills ([#198](#198)) ([b2e0514](b2e0514))
* **create-bestax:** publish with npm provenance attestation ([21ffe8f](21ffe8f)), closes [#180](#180)
* **create-bestax:** read version from package.json instead of hardcoded value ([#109](#109)) ([8605699](8605699))
* **create-bestax:** refresh README and bump scaffolded bestax-bulma to ^5 ([4e19e86](4e19e86))
* **create-bestax:** reject dot-only project names, pin icon versions, bundle bestax-icons skill ([#310](#310)) ([ddff8e5](ddff8e5))
* **create-bestax:** scaffold @allxsmith/bestax-bulma ^4.0.0 ([1d3b802](1d3b802))
* **create-bestax:** scaffold bundled bestax CSS flavors, not stock Bulma ([43621dc](43621dc))
* **create-bestax:** ship improved bundled skills + component catalog ([#199](#199)) ([a1515c2](a1515c2))
* **create-bestax:** skills-sync conformance gate + theming skill reference backfill ([#326](#326)) ([9584133](9584133)), closes [#285](#285)
* **create-bestax:** synchronize version with bestax-bulma to 2.4.0 ([623ee79](623ee79)), closes [#96](#96)
* **create-bestax:** update template dependency to ^2.4.0 ([200971d](200971d))
* **create-bestax:** use scenario-specific screenshot directories to prevent overwrites ([#108](#108)) ([c675957](c675957)), closes [#107](#107)
* **docs:** correct Content Signals syntax in robots.txt ([#134](#134)) ([85dd9de](85dd9de))
* **docs:** emit per-page markdown so llms.txt links resolve ([#200](#200)) ([7877083](7877083))
* **docs:** escape apostrophe in QuickStart notification text ([25d6d72](25d6d72))
* **docs:** generate llms.txt so the advertised homepage link resolves ([9fae464](9fae464)), closes [#177](#177)
* **docs:** improve homepage hero layout and button spacing ([5f7a5a7](5f7a5a7))
* **docs:** move robots.txt to correct deployment location ([#90](#90)) ([1e2aeee](1e2aeee))
* **docs:** rebrand and reorganize Storybook ([#83](#83)) ([dfb9937](dfb9937))
* **docs:** remove Google Analytics and add robots.txt ([94776f7](94776f7))
* **docs:** update Storybook logo path to /img/logo.svg for deployed site ([bf59758](bf59758))
* **e2e:** correct notification CSS selectors to use contains instead of ends-with ([182acc1](182acc1))
* implement independent package versioning strategy ([#111](#111)) ([7819c73](7819c73)), closes [#110](#110)
* prevent bulma-ui from versioning on create-bestax commits ([#120](#120)) ([4dfaf9c](4dfaf9c)), closes [#119](#119)
* resolve React Hooks violations and ESLint configuration issues ([32d2931](32d2931))
* upgrade Turbo, Storybook, and Docusaurus dependencies ([5b4ebdd](5b4ebdd)), closes [#98](#98)

### Documentation

* fix stale versioning and coverage docs; drop CLAUDE.md stale-docs flags ([71c4583](71c4583))

### Features

* add theme system and config provider with comprehensive test coverage ([f3ca7f0](f3ca7f0))
* **bestax-migrate:** react-bulma-components → bestax-bulma codemod CLI, skill, and docs ([#333](#333)) ([e04a12b](e04a12b)), closes [#1e6b99](https://github.com/allxsmith/bestax/issues/1e6b99)
* **bulma-ui:** add Avatar, Avatars, and Badge components ([#257](#257)) ([0817018](0817018)), closes [#256](#256)
* **bulma-ui:** add colorMode dark-mode prop to Theme ([4acc41e](4acc41e)), closes [#174](#174)
* **bulma-ui:** add consistent gap prop to Columns, aliasing gapSize ([#300](#300)) ([6c36455](6c36455)), closes [#282](#282)
* **bulma-ui:** add cursor helper, closeDelay prop, and polish Tooltip stories ([37945b5](37945b5))
* **bulma-ui:** add extra components, form elements, and SCSS styles ([59daf28](59daf28))
* **bulma-ui:** add HTML element wrapper components ([#135](#135)) ([#136](#136)) ([20fb16d](20fb16d))
* **bulma-ui:** add manual-entry stories for format, bounds, and blocked-value variations ([e93d51c](e93d51c))
* **bulma-ui:** add Reveal component for scroll-triggered animations ([#255](#255)) ([a89c574](a89c574))
* **bulma-ui:** Add skeletons ([6c46e4b](6c46e4b))
* **bulma-ui:** add themed Checkbox/Radio, convenience Field components, and Autocomplete cleanup ([3c57a5a](3c57a5a))
* **bulma-ui:** add typing-first story variants for all picker property variations ([078433f](078433f))
* **bulma-ui:** avatar/badge a11y batch — decorative alt, accessible names, live region, button type, surplus i18n, focus ring ([#298](#298)) ([508477f](508477f)), closes [#266](#266) [#266](#266)
* **bulma-ui:** change the default primary color to [#1](#1 ([8872620](8872620)), closes [#1e6b99](https://github.com/allxsmith/bestax/issues/1e6b99) [#1e6b99](https://github.com/allxsmith/bestax/issues/1e6b99)
* **bulma-ui:** compound (dot-notation) sub-components for all parent/child families via shared withSubComponents helper ([#331](#331)) ([07516c5](07516c5))
* **bulma-ui:** dim and blur the calendar behind the Datetimepicker time wheels ([3d90619](3d90619))
* **bulma-ui:** finalize the 3.0 component set ([87ccc0e](87ccc0e))
* **bulma-ui:** make Button and Link as prop polymorphic (React.ElementType) ([#238](#238)) ([ce90304](ce90304)), closes [#188](#188)
* **bulma-ui:** require React 18 as the minimum supported version ([c7251b0](c7251b0))
* **ci:** add verified-commit action for GPG-signed commits ([d078dfa](d078dfa))
* **create-bestax:** add bestax-optimize skill for shrinking built CSS ([#329](#329)) ([f597b9f](f597b9f))
* **create-bestax:** add CLI tool with Vite templates and automated publishing ([9748c3d](9748c3d))
* **create-bestax:** add cross-platform emoji support with figures ([#103](#103)) ([15567d9](15567d9))
* **create-bestax:** add README with templates location note ([8ddc73d](8ddc73d))
* **create-bestax:** add visual regression testing and synchronized versioning ([17e1e22](17e1e22)), closes [#94](#94)
* **create-bestax:** bestax-icons skill — teach agents the icon system ([#302](#302)) ([61c8ef2](61c8ef2)), closes [#287](#287)
* **create-bestax:** improve favicon visibility and add distinct branding ([621590d](621590d)), closes [#100](#100)
* **create-bestax:** modernize templates (Vite 8, ESLint 10, TS 6) + add working lint config ([4537629](4537629)), closes [#167](#167)
* **create-bestax:** offer to install the bestax AI skills when scaffolding ([625b7bf](625b7bf)), closes [#174](#174)
* **create-bestax:** scaffold-aware CLAUDE.md with setup facts and house style ([#271](#271)) ([c1681b0](c1681b0))
* **docs:** add Google Analytics tracking for usage insights ([#68](#68)) ([90ab951](90ab951))
* **docs:** add pronunciation guide and dark mode support ([#58](#58)) ([48a8916](48a8916))
* **docs:** migrate from GitHub Pages to Cloudflare Pages ([#132](#132)) ([2154672](2154672)), closes [#131](#131)
* **form:** add Datepicker, Timepicker, and Datetimepicker components ([c6684e6](c6684e6))

### BREAKING CHANGES

* footer requirement, and the commitlint scope rule
- CONTRIBUTING.md: replace the type-less commit example with a
  commitlint-valid conventional format (verified against commitlint);
  correct all four coverage mentions to the real jest thresholds
  (bulma-ui 99%, create-bestax 95%/78% branches); fix the npm package
  name (@allxsmith/bestax-bulma, plus create-bestax) and link VERSIONING.md
- CLAUDE.md: remove the stale-docs warning and asides now that the
  underlying docs are correct; point at VERSIONING.md again

Closes #206.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131uD6QKmAij7Byk3SByyLh
* the @allxsmith/bestax-bulma/versions/bestax-bulma-prefixed.css
export is removed. Use versions/bestax-prefixed.css with classPrefix="bestax-".
* **bulma-ui:** React 16 and 17 are no longer supported; the minimum
supported React version is now 18.
* **bulma-ui:** Snackbar has been removed and merged into Toast; use Toast
with its positioning and queue props instead.
* **bulma-ui:** form controls now auto-wrap in Field/Control, and Checkbox
and Radio ship new themed visuals. See the 2.x -> 3.x migration guide.
* This version requires Node.js 18.0.0 or higher. The CLI now enforces this requirement and will exit with an error message if running on older Node.js versions. This aligns create-bestax with the bestax-bulma v2.x ecosystem.

* fix(create-bestax): correct Prettier formatting in index.ts
* None - all changes are additive and backward compatible
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 1.0.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

bestax-release-bot Bot pushed a commit that referenced this pull request Aug 12, 2026
# 1.0.0 (2026-08-12)

* feat(bulma-ui)!: remove bestax-bulma-prefixed CSS variant ([94baa34](94baa34))
* feat(create-bestax)!: require Node.js 18+ and align with bestax-bulma v2 ([#118](#118)) ([b22f183](b22f183))

### Bug Fixes

* add comprehensive rules to prevent bulma-ui versioning on non-bulma-ui commits ([#122](#122)) ([525ccfa](525ccfa)), closes [#119](#119)
* **bestax-mcp:** derive the near-miss guidance from the skill, and only when it helps ([1141cca](1141cca))
* **bestax-mcp:** do not split a helper-prop table cell on an escaped pipe ([bdac820](bdac820))
* **bestax-mcp:** lead get_helper_props with the inline-style prohibition ([ffc627a](ffc627a))
* **bestax-mcp:** make list_components point at the next step ([8ddb2fd](8ddb2fd))
* **bestax-mcp:** make tests and cached builds work from a clean checkout ([6e63820](6e63820)), closes [bestax-mcp#build](https://github.com/bestax-mcp/issues/build)
* **bestax-mcp:** name list_components as the entry point, not search_bestax ([206380b](206380b))
* **bestax-mcp:** name the three near-miss components in the list_components footer ([1c7af67](1c7af67))
* **bestax-mcp:** route helper questions to the tool that answers them ([cd6ce12](cd6ce12))
* **bestax-mcp:** validate the one input that is not ours, and bound the rest ([3e1adc9](3e1adc9))
* **bestax-migrate:** give the kitchen-sink e2e a per-process scratch dir ([2211ea5](2211ea5))
* **bestax-migrate:** reject pnpm's workspace alias form instead of unwrapping it ([de6a900](de6a900))
* **bestax-migrate:** require the pack script to exist, not just be named ([5315efe](5315efe))
* **bestax-migrate:** resolve bare workspace: and guard the catalog: protocol ([7fda9db](7fda9db)), closes [#417](#417) [#412](#412)
* **bestax-migrate:** resolve workspace: specifiers before publishing ([782829a](782829a)), closes [bestax-migrate#test](https://github.com/bestax-migrate/issues/test) [#412](#412)
* **bestax-migrate:** stop the pack hooks excusing a catalog: devDependency ([4127ead](4127ead)), closes [#412-shaped](#412)
* **bulma-ui:** a11y + case-insensitive Taginput matching from PR review ([d576829](d576829))
* **bulma-ui:** accept router props like `to` on Navbar.Item without casts ([#311](#311)) ([b78856b](b78856b)), closes [#306](#306)
* **bulma-ui:** Add build step to publish in ci.yml ([e3707fc](e3707fc))
* **bulma-ui:** add fontawesome-free as explicit devDependency ([a4a5389](a4a5389))
* **bulma-ui:** add missing exports ([0d16633](0d16633))
* **bulma-ui:** Add Skeleton to exports ([e481599](e481599))
* **bulma-ui:** another attempt to fix semantic release builds with ci.yml ([cc3a3e2](cc3a3e2))
* **bulma-ui:** another attempt to fix semantic release builds with ci.yml ([314bc39](314bc39))
* **bulma-ui:** another attempt to fix semantic release builds with ci.yml ([c930693](c930693))
* **bulma-ui:** associate Autocomplete and Taginput labels with their inner inputs ([7ae37d4](7ae37d4))
* **bulma-ui:** associate Autocomplete and Taginput labels with their inner inputs ([384bd38](384bd38))
* **bulma-ui:** associate the form label prop with its control via a generated id ([e6686af](e6686af))
* **bulma-ui:** complete domain migration and fix semantic-release configuration ([#64](#64)) ([f4cd71d](f4cd71d))
* **bulma-ui:** correct blog post examples and add Modal compound components ([#81](#81)) ([559c2e3](559c2e3))
* **bulma-ui:** correct NPM_TOKEN env variable in ci.yml ([94b48b4](94b48b4))
* **bulma-ui:** cover horizontal-layout group label association ([ef3ca9f](ef3ca9f))
* **bulma-ui:** deprecate CSS-less color values, warn in dev, fix has-text fall-through ([fb111eb](fb111eb))
* **bulma-ui:** fail closed on missing process and scope color guidance to real props ([117c0c0](117c0c0))
* **bulma-ui:** Fix release.config.js to include package-lock.json ([390da59](390da59))
* **bulma-ui:** fix standalone Badge pointer-events, pulse halo, and falsy content ([#295](#295)) ([a9db031](a9db031)), closes [#264](#264)
* **bulma-ui:** full classPrefix support across layout/grid + prefix utils ([4ce0b53](4ce0b53))
* **bulma-ui:** honor the htmlFor opt-out in the convenience hook and tighten the association docs ([92aa622](92aa622))
* **bulma-ui:** improve npm package discoverability with optimized keywords and badges ([#72](#72)) ([8c7a696](8c7a696))
* **bulma-ui:** Initial semantic release changes ([b78d785](b78d785))
* **bulma-ui:** keep Taginput's fallback name unless the label targets its input ([73cec33](73cec33))
* **bulma-ui:** keep Taginput's fallback name unless the label targets its input ([ca5996a](ca5996a))
* **bulma-ui:** migrate domain from bestax.cc to bestax.io ([#64](#64)) ([4870b1e](4870b1e))
* **bulma-ui:** migrate ionicons to v8 to unblock publish and Storybook ([927a55b](927a55b)), closes [#142](#142)
* **bulma-ui:** name Rate, Checkboxes, and Radios groups from their labels via aria-labelledby ([dce0ee7](dce0ee7))
* **bulma-ui:** name Rate, Checkboxes, and Radios groups from their labels via aria-labelledby ([#497](#497)) ([5c4222e](5c4222e))
* **bulma-ui:** name the three near-miss components in AGENTS.md ([c63f491](c63f491)), closes [#344](#344)
* **bulma-ui:** never let labelProps.htmlFor wire a group label to a control ([3b3aaaf](3b3aaaf))
* **bulma-ui:** publish rewritten README to npm ([9810081](9810081))
* **bulma-ui:** publish with npm provenance attestation ([172da62](172da62)), closes [#180](#180)
* **bulma-ui:** reference llms docs from README and package.json ([#198](#198)) ([db8aab3](db8aab3))
* **bulma-ui:** reject predicate-blocked values during manual entry ([a8f6e28](a8f6e28))
* **bulma-ui:** resolve flex item properties and Card compound component issues ([#55](#55)) ([e774da3](e774da3))
* **bulma-ui:** resolve flex item properties and Card compound component issues ([#55](#55)) ([7641a53](7641a53))
* **bulma-ui:** resolve react-hooks v7 and [@eslint-react](https://github.com/eslint-react) findings ([14caaaf](14caaaf))
* **bulma-ui:** resolve security vulnerabilities and update dependencies ([#128](#128)) ([112f6e4](112f6e4)), closes [#127](#127)
* **bulma-ui:** restrict semantic-release to bulma-ui scoped commits only ([2d67bf9](2d67bf9)), closes [#62](#62)
* **bulma-ui:** retry failed Avatar src, flatten Fragment children in Avatars, RTL-safe overlap ([#297](#297)) ([c00b9db](c00b9db))
* **bulma-ui:** route every hardcoded class through the prefix helpers; add classPrefix sweep test ([#301](#301)) ([a50b134](a50b134)), closes [#286](#286)
* **bulma-ui:** setup gpg signing with semantic-release ([3e24722](3e24722))
* **bulma-ui:** strip redundant library prefix from Icon name ([#242](#242)) ([dbe3622](dbe3622)), closes [#189](#189)
* **bulma-ui:** trigger release to publish via OIDC trusted publishing ([e2d09c5](e2d09c5))
* **bulma-ui:** update bundle size claims to accurate 21KB gzipped ([#66](#66)) ([6e381bd](6e381bd))
* **bulma-ui:** update package-lock.json ([853d585](853d585))
* **bulma-ui:** update package.json for better seo, exports, types, engines, funding, etc ([98cbc56](98cbc56))
* **bulma-ui:** use createRequire for ESM compatibility in Storybook 10 ([#130](#130)) ([b27e60e](b27e60e)), closes [#129](#129)
* **ci:** collect screenshots as artifacts and commit in single batch to avoid conflicts ([27b259d](27b259d))
* **ci:** ensure npm install uses fresh downloads with --prefer-online ([1f2e15d](1f2e15d))
* **ci:** properly extract base path for recursive file search ([e0330ff](e0330ff))
* **ci:** use find command instead of glob module in verified-commit action ([0e2d159](0e2d159))
* **ci:** use npm ci for scaffolded app dependencies ([35652c8](35652c8))
* **create-bestax:** concrete inline-style → helper-prop mapping for the never-inline rule ([#357](#357)) ([5f72a90](5f72a90)), closes [#350](#350) [#350](#350)
* **create-bestax:** correct browser title to prioritize Bestax branding ([#106](#106)) ([23aa535](23aa535)), closes [#105](#105)
* **create-bestax:** correct template path resolution from ../../ to ../ ([65b4493](65b4493)), closes [#78](#78)
* **create-bestax:** dark-mode contrast rules in theming/layout skills and docs ([#303](#303)) ([490bf21](490bf21)), closes [#194](#194) [#195](#195)
* **create-bestax:** exclude templates directory from linting and typecheck ([18fec0b](18fec0b))
* **create-bestax:** fail fast with guidance instead of hanging when stdin is not a TTY ([#293](#293)) ([46a172d](46a172d)), closes [#192](#192)
* **create-bestax:** move templates into package directory and update docs ([195bf01](195bf01)), closes [#78](#78)
* **create-bestax:** point scaffolded CLAUDE.md at llms docs; document skills ([#198](#198)) ([b2e0514](b2e0514))
* **create-bestax:** publish with npm provenance attestation ([21ffe8f](21ffe8f)), closes [#180](#180)
* **create-bestax:** put the near-miss guidance where every session sees it ([6db49f3](6db49f3))
* **create-bestax:** read version from package.json instead of hardcoded value ([#109](#109)) ([8605699](8605699))
* **create-bestax:** refresh README and bump scaffolded bestax-bulma to ^5 ([4e19e86](4e19e86))
* **create-bestax:** reject dot-only project names, pin icon versions, bundle bestax-icons skill ([#310](#310)) ([ddff8e5](ddff8e5))
* **create-bestax:** scaffold @allxsmith/bestax-bulma ^4.0.0 ([1d3b802](1d3b802))
* **create-bestax:** scaffold bundled bestax CSS flavors, not stock Bulma ([43621dc](43621dc))
* **create-bestax:** ship improved bundled skills + component catalog ([#199](#199)) ([a1515c2](a1515c2))
* **create-bestax:** shrink the near-miss block and pin the copies together ([d582da5](d582da5))
* **create-bestax:** skills-sync conformance gate + theming skill reference backfill ([#326](#326)) ([9584133](9584133)), closes [#285](#285)
* **create-bestax:** stop the skills teaching a Theme call that does not compile ([2935bb2](2935bb2))
* **create-bestax:** synchronize version with bestax-bulma to 2.4.0 ([623ee79](623ee79)), closes [#96](#96)
* **create-bestax:** teach the skills the three components Bulma hides ([22dcff7](22dcff7))
* **create-bestax:** update template dependency to ^2.4.0 ([200971d](200971d))
* **create-bestax:** use scenario-specific screenshot directories to prevent overwrites ([#108](#108)) ([c675957](c675957)), closes [#107](#107)
* **create-bestax:** validate at submit in the bestax-form signup example ([0b9518f](0b9518f))
* **create-bestax:** wire labeled controls in the skill showcase story ([af49a16](af49a16))
* **docs:** announce the hero copy, and stop remounting the icons ([98e2cb0](98e2cb0)), closes [#434](#434)
* **docs:** correct Content Signals syntax in robots.txt ([#134](#134)) ([85dd9de](85dd9de))
* **docs:** correct the frozen-install translation and reject leaked fences ([1883de3](1883de3))
* **docs:** drop dead nomodule ionicons fallback ([82be3e4](82be3e4))
* **docs:** emit per-page markdown so llms.txt links resolve ([#200](#200)) ([7877083](7877083))
* **docs:** escape apostrophe in QuickStart notification text ([25d6d72](25d6d72))
* **docs:** generate llms.txt so the advertised homepage link resolves ([9fae464](9fae464)), closes [#177](#177)
* **docs:** give every batch run its own port — slot reuse was corrupting runs ([6ef1755](6ef1755))
* **docs:** harden PackageManagerTabs and document how to author it ([5b0d3e6](5b0d3e6)), closes [#434](#434)
* **docs:** harden the hero copy button and share the tab storage key ([9e16cd7](9e16cd7))
* **docs:** improve homepage hero layout and button spacing ([5f7a5a7](5f7a5a7))
* **docs:** make the eval batch resumable after a container restart ([d56229e](d56229e))
* **docs:** make the hero package-manager switcher a real radiogroup ([aa14ff2](aa14ff2)), closes [#434](#434)
* **docs:** move robots.txt to correct deployment location ([#90](#90)) ([1e2aeee](1e2aeee))
* **docs:** rebrand and reorganize Storybook ([#83](#83)) ([dfb9937](dfb9937))
* **docs:** remove Google Analytics and add robots.txt ([94776f7](94776f7))
* **docs:** stop cssnano stripping Font Awesome [@font-face](https://github.com/font-face), add [#3](#3) CSS framework blog post ([#401](#401)) ([5d114e1](5d114e1)), closes [#400](#400)
* **docs:** update Storybook logo path to /img/logo.svg for deployed site ([bf59758](bf59758))
* **e2e:** correct notification CSS selectors to use contains instead of ends-with ([182acc1](182acc1))
* implement independent package versioning strategy ([#111](#111)) ([7819c73](7819c73)), closes [#110](#110)
* prevent bulma-ui from versioning on create-bestax commits ([#120](#120)) ([4dfaf9c](4dfaf9c)), closes [#119](#119)
* resolve React Hooks violations and ESLint configuration issues ([32d2931](32d2931))
* upgrade Turbo, Storybook, and Docusaurus dependencies ([5b4ebdd](5b4ebdd)), closes [#98](#98)

### chore

* **deps:** consolidate the dependabot backlog, require Node 22 in both CLIs ([#447](#447)) ([e68148c](e68148c)), closes [#427](#427) [#428](#428) [#431](#431) [#432](#432) [#440](#440) [#393](#393)

### Documentation

* fix stale versioning and coverage docs; drop CLAUDE.md stale-docs flags ([71c4583](71c4583))

### Features

* add theme system and config provider with comprehensive test coverage ([f3ca7f0](f3ca7f0))
* **bestax-mcp:** serve component docs, props, examples and skills over MCP ([c2abcc4](c2abcc4))
* **bestax-migrate:** react-bulma-components → bestax-bulma codemod CLI, skill, and docs ([#333](#333)) ([e04a12b](e04a12b)), closes [#1e6b99](https://github.com/allxsmith/bestax/issues/1e6b99)
* **bestax-migrate:** require Node 22 and take chalk 6 ([#449](#449)) ([4c0e1e2](4c0e1e2)), closes [#447](#447)
* **bulma-ui:** add Avatar, Avatars, and Badge components ([#257](#257)) ([0817018](0817018)), closes [#256](#256)
* **bulma-ui:** add colorMode dark-mode prop to Theme ([4acc41e](4acc41e)), closes [#174](#174)
* **bulma-ui:** add consistent gap prop to Columns, aliasing gapSize ([#300](#300)) ([6c36455](6c36455)), closes [#282](#282)
* **bulma-ui:** add cursor helper, closeDelay prop, and polish Tooltip stories ([37945b5](37945b5))
* **bulma-ui:** add extra components, form elements, and SCSS styles ([59daf28](59daf28))
* **bulma-ui:** add HTML element wrapper components ([#135](#135)) ([#136](#136)) ([20fb16d](20fb16d))
* **bulma-ui:** add manual-entry stories for format, bounds, and blocked-value variations ([e93d51c](e93d51c))
* **bulma-ui:** add Reveal component for scroll-triggered animations ([#255](#255)) ([a89c574](a89c574))
* **bulma-ui:** Add skeletons ([6c46e4b](6c46e4b))
* **bulma-ui:** add themed Checkbox/Radio, convenience Field components, and Autocomplete cleanup ([3c57a5a](3c57a5a))
* **bulma-ui:** add typing-first story variants for all picker property variations ([078433f](078433f))
* **bulma-ui:** associate Field's label with a composed base control ([219f631](219f631))
* **bulma-ui:** avatar/badge a11y batch — decorative alt, accessible names, live region, button type, surplus i18n, focus ring ([#298](#298)) ([508477f](508477f)), closes [#266](#266) [#266](#266)
* **bulma-ui:** change the default primary color to [#1](#1 ([8872620](8872620)), closes [#1e6b99](https://github.com/allxsmith/bestax/issues/1e6b99) [#1e6b99](https://github.com/allxsmith/bestax/issues/1e6b99)
* **bulma-ui:** compound (dot-notation) sub-components for all parent/child families via shared withSubComponents helper ([#331](#331)) ([07516c5](07516c5))
* **bulma-ui:** dim and blur the calendar behind the Datetimepicker time wheels ([3d90619](3d90619))
* **bulma-ui:** finalize the 3.0 component set ([87ccc0e](87ccc0e))
* **bulma-ui:** make Button and Link as prop polymorphic (React.ElementType) ([#238](#238)) ([ce90304](ce90304)), closes [#188](#188)
* **bulma-ui:** require React 18 as the minimum supported version ([c7251b0](c7251b0))
* **bulma-ui:** ship agent-discovery files in the npm tarball ([#345](#345)) ([4b58739](4b58739)), closes [#344](#344) [#344](#344) [#344](#344)
* **ci:** add verified-commit action for GPG-signed commits ([d078dfa](d078dfa))
* **create-bestax:** add bestax-optimize skill for shrinking built CSS ([#329](#329)) ([f597b9f](f597b9f))
* **create-bestax:** add CLI tool with Vite templates and automated publishing ([9748c3d](9748c3d))
* **create-bestax:** add controlled-Burger Navbar to the landing archetype ([#355](#355)) ([36d4d09](36d4d09)), closes [#348](#348)
* **create-bestax:** add cross-platform emoji support with figures ([#103](#103)) ([15567d9](15567d9))
* **create-bestax:** add README with templates location note ([8ddc73d](8ddc73d))
* **create-bestax:** add visual regression testing and synchronized versioning ([17e1e22](17e1e22)), closes [#94](#94)
* **create-bestax:** agent-validated guidance for skills, scaffold CLAUDE.md, and catalog ([#365](#365)) ([6fd06ae](6fd06ae)), closes [#2](#2)
* **create-bestax:** bestax-icons skill — teach agents the icon system ([#302](#302)) ([61c8ef2](61c8ef2)), closes [#287](#287)
* **create-bestax:** improve favicon visibility and add distinct branding ([621590d](621590d)), closes [#100](#100)
* **create-bestax:** modernize templates (Vite 8, ESLint 10, TS 6) + add working lint config ([4537629](4537629)), closes [#167](#167)
* **create-bestax:** offer to install the bestax AI skills when scaffolding ([625b7bf](625b7bf)), closes [#174](#174)
* **create-bestax:** require Node 22 and take chalk 6 ([#448](#448)) ([90fced2](90fced2)), closes [#447](#447)
* **create-bestax:** scaffold .claude/launch.json with the AI skills opt-in ([#343](#343)) ([189135a](189135a))
* **create-bestax:** scaffold-aware CLAUDE.md with setup facts and house style ([#271](#271)) ([c1681b0](c1681b0))
* **create-bestax:** set scaffolded index.html title to the project name ([#356](#356)) ([3bfbea3](3bfbea3)), closes [#349](#349) [#349](#349)
* **docs:** add Google Analytics tracking for usage insights ([#68](#68)) ([90ab951](90ab951))
* **docs:** add package-manager switches to the homepage hero ([374caf8](374caf8))
* **docs:** add PackageManagerTabs and register it globally ([23c9989](23c9989))
* **docs:** add pronunciation guide and dark mode support ([#58](#58)) ([48a8916](48a8916))
* **docs:** aggregate-runs.mjs — distribution stats across a runs directory ([5de9c07](5de9c07))
* **docs:** batch runner for the eval harness, with the concurrency fixes it needed ([f8e268c](f8e268c))
* **docs:** migrate from GitHub Pages to Cloudflare Pages ([#132](#132)) ([2154672](2154672)), closes [#131](#131)
* **docs:** rubric v2 and a brief that demands the components beyond Bulma ([e6047be](e6047be))
* **docs:** show all posts in the blog sidebar ([d29e9c6](d29e9c6))
* **form:** add Datepicker, Timepicker, and Datetimepicker components ([c6684e6](c6684e6))

### Performance Improvements

* **bestax-mcp:** stop get_helper_props costing half the session ([b865651](b865651))
* **docs:** defer live previews until they scroll into view ([d6bf87b](d6bf87b))
* **docs:** share one parsed stylesheet set across every live preview ([feb993a](feb993a))

### BREAKING CHANGES

* **bestax-migrate:** bestax-migrate now requires Node.js 22 or newer. Node 18 and
20 are both past end-of-life. Running it on an older runtime prints an explicit
upgrade message and exits 1. This applies to the runtime the codemod executes
on, not to the app being migrated.

Claude-Session: https://claude.ai/code/session_01TGA6sFTUGsJ6oXhfpjKEnh
* **create-bestax:** create-bestax now requires Node.js 22 or newer. Node 18 and 20
are both past end-of-life. Running it on an older runtime prints an explicit
upgrade message and exits 1.

Claude-Session: https://claude.ai/code/session_01TGA6sFTUGsJ6oXhfpjKEnh
* **deps:** create-bestax now requires Node.js 22 or newer. Node 18 and 20
are both past end-of-life. Running it on an older runtime prints an explicit
upgrade message and exits 1.

Claude-Session: https://claude.ai/code/session_01TGA6sFTUGsJ6oXhfpjKEnh

* feat(bestax-migrate): require Node 22 and take chalk 6

chalk 6 drops support for Node below 22. The API surface this package uses is
unchanged, so no calling code changes.

The version guard in src/index.ts moves ahead of every import and no longer
depends on anything: import declarations are hoisted and evaluated before any
statement in the module, and chalk 6 itself requires Node >= 22, so a static
import would fail to load on exactly the runtimes the guard exists to catch.
./cli.js is now imported dynamically for the same reason.

@babel/parser deliberately stays on 7.x. Babel 8 removes the
`deprecatedImportAssert` plugin with no replacement, and this package parses
the legacy `import x from 'y' assert { type: 'json' }` form on purpose — a
codemod that migrates older codebases must not crash on the syntax those
codebases still contain. There is a regression test for it ("parses the legacy
import-assert syntax"), which Babel 8 fails outright. jscodeshift 17 bundles
its own Babel 7 regardless, so staying on 7 also keeps a single parser in the
tree rather than two.
* **deps:** bestax-migrate now requires Node.js 22 or newer. Node 18 and
20 are both past end-of-life. Running it on an older runtime prints an explicit
upgrade message and exits 1.

Claude-Session: https://claude.ai/code/session_01TGA6sFTUGsJ6oXhfpjKEnh
* footer requirement, and the commitlint scope rule
- CONTRIBUTING.md: replace the type-less commit example with a
  commitlint-valid conventional format (verified against commitlint);
  correct all four coverage mentions to the real jest thresholds
  (bulma-ui 99%, create-bestax 95%/78% branches); fix the npm package
  name (@allxsmith/bestax-bulma, plus create-bestax) and link VERSIONING.md
- CLAUDE.md: remove the stale-docs warning and asides now that the
  underlying docs are correct; point at VERSIONING.md again

Closes #206.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131uD6QKmAij7Byk3SByyLh
* the @allxsmith/bestax-bulma/versions/bestax-bulma-prefixed.css
export is removed. Use versions/bestax-prefixed.css with classPrefix="bestax-".
* **bulma-ui:** React 16 and 17 are no longer supported; the minimum
supported React version is now 18.
* **bulma-ui:** Snackbar has been removed and merged into Toast; use Toast
with its positioning and queue props instead.
* **bulma-ui:** form controls now auto-wrap in Field/Control, and Checkbox
and Radio ship new themed visuals. See the 2.x -> 3.x migration guide.
* This version requires Node.js 18.0.0 or higher. The CLI now enforces this requirement and will exit with an error message if running on older Node.js versions. This aligns create-bestax with the bestax-bulma v2.x ecosystem.

* fix(create-bestax): correct Prettier formatting in index.ts
* None - all changes are additive and backward compatible
@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 1.0.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-human-review Loop converged (or contested): awaiting owner review + manual merge released

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Make Button, Link, and LinkButton as prop polymorphic (React.ElementType) for router Link integration

2 participants