Skip to content

fix(bulma-ui): make Theme colorMode switch the scheme under the prefixed builds - #894

Merged
allxsmith merged 5 commits into
mainfrom
fix/theme-colormode-prefixed
Oct 5, 2026
Merged

allxsmith merged 5 commits into
mainfrom
fix/theme-colormode-prefixed

Conversation

@allxsmith

Copy link
Copy Markdown
Owner

<Theme colorMode="dark"> did nothing under the prefixed builds. Theme writes data-theme, but Bulma's theme mixin emits [data-#{$class-prefix}theme=…], so bestax-prefixed and bestax-no-helpers-prefixed key their schemes off data-bestax-theme and carry no data-theme hook at all. Dark on a light OS stayed light, and light on a dark OS stayed dark.

  • Theme reads the class prefix from ConfigProvider, and under one, colorMode writes data-<prefix>theme alongside data-theme, from scoped and root Themes alike. 'system' removes both, and unmounting or changing colorMode restores each to what it was.
  • With no prefix, nothing changes: only data-theme is written, with the same DOM operations as before, and no CSS moved.
  • A prefix that can't form an attribute name (md/, say) still gets data-theme, as it did before, instead of throwing.

A new styles test compiles every published sheet and resolves the scheme on <html> for dark, light, system and unmount, scoped and root, on a light and a dark OS. On main every Theme case failed on both prefixed sheets and passed on the unprefixed ones. Chromium agrees: the prefixed sheets ignore data-theme alone and switch with both. Unit tests cover the no-prefix case, both attributes, isRoot, system, restoring on unmount and an invalid prefix.

The colorMode TSDoc moved onto the prop and says both attributes are written; the Theme page and the theming skill's dark mode reference say the same, and note that [data-theme='dark'] custom CSS still matches.

pnpm all passes locally.

…xed builds

Bulma names its scheme attribute after the class prefix a stylesheet is built with
(`[data-#{$class-prefix}theme=dark]`), so `bestax-prefixed.css` and
`bestax-no-helpers-prefixed.css` read `data-bestax-theme` and never `data-theme`. `colorMode` only
wrote `data-theme`, so under a prefixed build `colorMode="dark"` left the page light on a light
OS, and `colorMode="light"` left it dark on a dark OS.

Under a `ConfigProvider` `classPrefix`, Theme now writes `data-<prefix>theme` alongside
`data-theme`, from a scoped or a root Theme alike. `'system'` removes both, and unmounting
restores each to what it was. With no prefix only `data-theme` is written, exactly as before. A
prefix that makes no valid attribute name is skipped rather than throwing, so `data-theme` keeps
working for it.

The new styles test compiles every published stylesheet that carries a dark scheme and resolves
`--bulma-scheme-main-l` on the root for dark, light, system and unmount, from a scoped and a root
Theme. It simulates the OS preference by renaming the sheet's own `prefers-color-scheme` block. On
main every prefixed case failed and every unprefixed one passed.

The `colorMode` TSDoc, now inline on the prop instead of in the `@property` block, the Theme page
and the theming skill's dark-mode reference say so.
@coderabbitai

coderabbitai Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 31 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository: allxsmith/bestax/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a0ae2bb6-65a3-4022-a227-8b3198cb4707
📥 Commits

Reviewing files that changed from the base of the PR and between 99426b4 and 81b02df.

📒 Files selected for processing (15)
  • bestax-mcp/data/components/Theme.json
  • bestax-mcp/data/skills.json
  • bulma-ui/src/helpers/CLAUDE.md
  • bulma-ui/src/helpers/Theme.tsx
  • bulma-ui/src/helpers/__tests__/Theme.styles.test.tsx
  • bulma-ui/src/helpers/__tests__/Theme.test.tsx
  • docs/docs/api/helpers/theme.md
  • docs/docs/guides/features/css-variables.md
  • docs/docs/guides/getting-started/optimizing-css.md
  • docs/docs/guides/helpers/color.md
  • docs/docs/skills/theming.mdx
  • skills/README.md
  • skills/bestax-theming/SKILL.md
  • skills/bestax-theming/examples/dark-mode.tsx
  • skills/bestax-theming/references/css-variables.md
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

Preview Deployment

Preview URL: https://1707c222.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 — 0 blocking · 3 advisory

No. Severity Area Finding Location
1 🔵 Advisory Correctness colorMode is documented as "always global", but the prefixed attribute now depends on where Theme sits relative to ConfigProvider — a Theme colorMode mounted above the provider writes only data-theme, and a prefixed sheet still ignores it bulma-ui/src/helpers/Theme.tsx:1084
2 🔵 Advisory Robustness The catch is silent, so a classPrefix that is a legal CSS ident but not a legal attribute name (any non-ASCII — an emoji prefix, say) makes Bulma emit a selector the DOM can never satisfy, and colorMode fails with no diagnostic bulma-ui/src/helpers/Theme.tsx:1096
3 🔵 Advisory API Three other surfaces still describe colorMode as writing data-theme with no prefixed caveat (skills/bestax-theming/SKILL.md:27, docs/docs/guides/features/css-variables.md:236, Theme.stories.tsx:572), and the prop-table parenthetical names data-bestax-theme where a classPrefix="my-" yields data-my-theme. All still true, just incomplete — and SKILL.md is what an agent reads before the reference that was updated skills/bestax-theming/SKILL.md:27

Overall: The change is sound, and the diagnosis is right at the source: bulma-theme at node_modules/bulma/sass/utilities/css-variables.scss:489 is the only attribute hook Bulma has, and it is prefix-named; nothing in bulma-ui/src/scss adds a [data-theme] rule of its own. So a prefixed sheet genuinely carries no data-theme hook, and writing both attributes is both necessary and sufficient. The riskiest part is Theme.styles.test.tsx, the only thing standing between this and a silent regression — it leans on two non-obvious premises (jsdom applies an @media list only when it names screen, and Bulma emits its :root{light} default before the prefers-color-scheme blocks, so the renamed block wins the cascade), both of which I confirmed against bulma/sass/themes/_index.scss:11-34 and a green run. A human should look first at advisory 1: the reach of the fix is a React-context question, while the attribute it writes is a document-global one.

Residual risk:

  • A prefixed sheet carrying a data-theme hook after all — refuted. bulma-theme (css-variables.scss:489-493) is the only attribute hook and it interpolates $class-prefix; a grep over bulma-ui/src/scss finds no [data-theme], theme-dark or prefers-color-scheme rule of our own. The extra data-theme written under a prefix is inert, not conflicting.
  • The other Bulma hook, .<prefix>theme-dark — not a regression: colorMode never wrote a class, before or after, so the class path is equally unreachable on both branches.
  • bestax-no-dark-mode.css — refuted as a gap. It emits :root { light-theme; setup-theme } and no [data-theme=…] block at all, so colorMode="dark" is a no-op there before and after. The filter in themedStylesheets() excludes it correctly (its SCSS matches neither import form the regex looks for), and an accidental inclusion would throw has no dark theme block in beforeAll rather than pass quietly.
  • The invalid-prefix path throwing — refuted. getAttribute and removeAttribute do no name validation, so only setAttribute can throw and it is guarded; the setAttribute branch in the cleanup needs a non-null previous, which an invalid name can never have, because the HTML tokenizer terminates an attribute name at a slash. Exercised live by the md/ test (Theme.test.tsx:1118), unmount restore included.
  • Nested Themes with colorMode — previous is still a per-effect snapshot, so two mounted Themes still restore last-in-wins. Unchanged in kind by this PR (one name became two, with identical per-name semantics), and the restore tests cover the single-Theme contract.
  • Open: the ConfigProvider placement dependency of advisory 1. Mitigated, not closed, by convention — every shipped prefixed example puts ConfigProvider outermost (docs/docs/guides/getting-started/variations.md:67 and :152), so no documented arrangement hits it.
What I ran
Check Result
jest src/helpers/__tests__/Theme*.test.tsx 106 passed
jest src/helpers (whole folder) 33 suites, 1038 passed
jest --coverage --collectCoverageFrom=src/helpers/Theme.tsx 100% stmts / branch / funcs / lines
tsc -p tsconfig.test.json --noEmit clean
eslint on the three changed sources clean
gen-mcp-index.mjs, gen-skills-rosters.mjs, gen-eslint-meta.mjs all regenerate to an empty git status — no stale artefact

Reverting Theme.tsx in this checkout was not permitted, so I did not re-run the "fails on main" claim directly. It follows from the harness: for a bestax- prefix, the pre-fix effect writes only data-theme, for which the compiled prefixed sheet has no rule, so schemeMainL() resolves to the OS value and turns the page dark with colorMode="dark" on a light OS must fail.

🏄 Clean little set-wave, this one — paddled straight at the real reef (Bulma names its scheme attribute after the prefix, so the prefixed sheets were never listening) and rode it in with a styles test that compiles the actual SCSS instead of trusting an attribute merely landing in the DOM. Good to go, dude — just know the prefixed half of the fix only works when ConfigProvider sits upwind of your Theme.

@github-actions github-actions Bot added the review-converged Deep review converged: no blocking findings, all review threads resolved, checks green label Oct 4, 2026
@allxsmith allxsmith added the needs-human-review Loop converged (or contested): awaiting owner review + manual merge label Oct 4, 2026
@github-actions github-actions Bot removed the review-converged Deep review converged: no blocking findings, all review threads resolved, checks green label Oct 4, 2026
@github-actions

github-actions Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

📸 Story screenshots at handoff — 81b02df

6 stories (light + dark) from this PR's changed files under bulma-ui/src/ (workflow run · artifact story-screenshots-pr-894, 30-day retention).

helpers-theme--sunset-theme · Helpers/Theme · Sunset Theme
Light Dark
helpers-theme--sunset-theme light helpers-theme--sunset-theme dark
helpers-theme--forest-theme · Helpers/Theme · Forest Theme
Light Dark
helpers-theme--forest-theme light helpers-theme--forest-theme dark
helpers-theme--global-theme · Helpers/Theme · Global Theme
Light Dark
helpers-theme--global-theme light helpers-theme--global-theme dark
helpers-theme--local-theme · Helpers/Theme · Local Theme
Light Dark
helpers-theme--local-theme light helpers-theme--local-theme dark
helpers-theme--theme-with-class-name · Helpers/Theme · Theme With Class Name
Light Dark
helpers-theme--theme-with-class-name light helpers-theme--theme-with-class-name dark
helpers-theme--nested-themes · Helpers/Theme · Nested Themes
Light Dark
helpers-theme--nested-themes light helpers-theme--nested-themes dark
> ✂ 4 more matched stories skipped by the cap: `helpers-theme--bulma-prefixed-theme`, `helpers-theme--shadow-theme`, `helpers-theme--radius-theme`, `helpers-theme--dark-mode` — full set in the artifact.

github-actions Bot added a commit that referenced this pull request Oct 4, 2026
@github-actions github-actions Bot added the review-converged Deep review converged: no blocking findings, all review threads resolved, checks green label Oct 4, 2026
@allxsmith allxsmith removed the needs-human-review Loop converged (or contested): awaiting owner review + manual merge label Oct 4, 2026
…ribute to write

A class prefix that makes no valid attribute name, such as one with a slash, left `colorMode`
writing only `data-theme` with no sign that a stylesheet built with that prefix would keep its
scheme. It now says so once in development.

The theming skill's dark-mode summary and the CSS variables guide said `colorMode` writes
`data-theme` and nothing more, and the Theme page's props table named only `data-bestax-theme`.
The skill and the table now name `data-<prefix>theme`, and the guide links to the Theme page's
dark-mode section for it.
@allxsmith

Copy link
Copy Markdown
Owner Author

Every finding from the review, fixed or answered, in 75d504a:

  1. The prefixed attribute depends on Theme sitting inside ConfigProvider: refuted. That's consistent with every other prefixed output. Theme reads the prefix from ConfigProvider context the way every component reads it for its classes, so a Theme mounted above the provider is outside the prefixed app just as an unprefixed Button there would be. The TSDoc and the Theme page say the prefixed attribute is written under a ConfigProvider classPrefix, and every documented prefixed setup puts the provider outermost.
  2. A prefix that can't form an attribute name failed silently: fixed. It now raises a development warning naming the attribute and saying the prefixed sheet keeps its scheme; the test asserted the warning before the code had it.
  3. The docs named only data-bestax-theme, or restated the mechanism: fixed in part. The theming skill's dark mode summary and the Theme page's props table name data-<prefix>theme, and the CSS variables guide links to the Theme page's dark mode section rather than restating it. The DarkMode story's text is left as is: it renders without a class prefix, so "sets data-theme on <html>" is exactly what it does there.

@allxsmith

Copy link
Copy Markdown
Owner Author

deep-review: fresh

The advisories from the last review are fixed or answered in the comment above; this reviews 75d504a.

@github-actions github-actions Bot removed the review-converged Deep review converged: no blocking findings, all review threads resolved, checks green label Oct 4, 2026
@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

Preview Deployment

Preview URL: https://ee92fd41.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 — 0 blocking · 4 advisory

# Severity Area Finding Location
1 🔵 Advisory API The new invalid-prefix development warning is described nowhere a consumer reads — not in the colorMode TSDoc, not in the Theme page's dark-mode prose or its props-table row — unlike Theme's other two dev warnings (isRoot radius, isRoot columnGap), which the props table calls out explicitly bulma-ui/src/helpers/Theme.tsx:1101
2 🔵 Advisory Correctness Adjacent surfaces in the same failure class still name only the unprefixed attribute, and none is touched here: the PurgeCSS example safelists /data-theme/, which does not match data-bestax-theme (docs/docs/guides/getting-started/optimizing-css.md:78); the per-surface recipe is <Box data-theme="light"> (docs/docs/guides/helpers/color.md:158); plus docs/docs/skills/theming.mdx:192, skills/bestax-theming/examples/dark-mode.tsx:4 and bulma-ui/src/helpers/CLAUDE.md. Each is true of an unprefixed build — incomplete, not wrong docs/docs/guides/getting-started/optimizing-css.md:78
3 🔵 Advisory Robustness The diagnostic is mode-dependent: removeAttribute never validates a name, so colorMode="system" under an attribute-invalid prefix warns nothing. Benign — there is no prefixed attribute to remove — but the misconfiguration only surfaces on 'light'/'dark' bulma-ui/src/helpers/Theme.tsx:1090
4 🔵 Advisory Coverage The harness floor asserts only that '' and 'bestax-' appear among the discovered prefixes, so a sheet silently dropped by the content filter — the other unprefixed one, bestax-no-helpers.scss, say — would still pass it. All four themed sheets do run today (37 tests = 4 × 9 + 1) bulma-ui/src/helpers/__tests__/Theme.styles.test.tsx:60

Overall: Sound, and the diagnosis holds up empirically rather than by argument — I compiled src/scss/versions/bestax-prefixed.scss and its only scheme hooks are [data-bestax-theme=light], [data-bestax-theme=dark], .bestax-theme-light and .bestax-theme-dark, with zero data-theme selectors anywhere in the sheet, so a prefixed build genuinely was deaf to colorMode and writing both names is both necessary and sufficient. The riskiest part remains Theme.styles.test.tsx — it is the only thing standing between this and a silent regression, and it rests on two unasserted premises (jsdom honours an @media list only when it names screen; Bulma emits its prefers-color-scheme blocks before the attribute blocks, so the attribute wins at equal specificity) — both of which I confirmed against the compiled cascade. A human can merge on the code and spend their attention on advisory 2 instead: the executable fix is complete, but the surrounding guidance a reader or an agent follows for a prefixed app still points at data-theme alone, and no check in this repo can see that.

Residual risk:

  • A prefixed sheet carrying a data-theme hook after all — refuted empirically. Compiled bestax-prefixed.scss with the real load path; a grep for the [data-…theme=…] form returns only the two data-bestax-theme selectors, and the class hooks are .bestax-theme-*. So the extra data-theme written under a prefix is inert, never conflicting.
  • The harness quietly skipping a sheet — refuted. The content filter admits bestax.scss (''), bestax-no-helpers.scss (''), bestax-prefixed.scss (bestax-) and bestax-no-helpers-prefixed.scss (bestax-), and correctly rejects extras.scss (no Bulma import) and bestax-no-dark-mode.scss (imports only bulma/sass/utilities and bulma/sass/themes/light, neither of which the regex matches). --verbose confirms 37 tests, i.e. all four sheets × 9 cases plus the floor. An accidental inclusion of the no-dark-mode sheet would throw has no dark theme block in beforeAll, not pass quietly.
  • The cleanup's unguarded root.setAttribute(name, value) — refuted. previous[i] for an attribute-invalid name is always null: setAttribute is the only route that creates one and it is the guarded call, and HTML's attribute-name tokenizer terminates a name at /, so markup cannot produce data-md/theme either. The restore therefore takes the removeAttribute branch, which performs no name validation. Exercised live by the md/ test's post-unmount assertion.
  • A case-differing prefix (classPrefix="Bestax-") — refuted. setAttribute ASCII-lowercases the qualified name on an HTML element, and attribute names in selectors are matched ASCII case-insensitively in HTML documents, so Bulma's [data-Bestax-theme=dark] still matches the data-bestax-theme that lands. No silent half-failure between the two casings.
  • classPrefix changing while a colorMode Theme is mounted — refuted. classPrefix is in the effect's dep list, so the old name set is restored before the new one is written; useClassPrefix returns a plain string from context, so the effect does not re-run spuriously.
  • Test pollution from the restore-on-unmount contract — refuted, and the new explicit cleanup() is load-bearing rather than decorative. RTL registers its auto-cleanup afterEach at root level when the module is imported, and Jest runs afterEach innermost-first, so without the explicit call the data-bestax-theme=light pre-set test would have its value re-added by the effect cleanup after the hook removed it.
  • Nested Themes both setting colorMode — unchanged in kind. previous is still a per-effect snapshot, so two mounted Themes still restore last-in-wins; one name became two with identical per-name semantics.
  • Open, in an executable path: only advisory 3's asymmetry — 'system' never warns. Everything else in the failure class that this diff touches is closed above; the remaining exposure is the unprefixed-only guidance of advisory 2, which is prose and so out of scope here.
What I ran
Check Result
jest Theme.test.tsx Theme.styles.test.tsx 2 suites, 106 passed
jest src/helpers/__tests__/Theme (incl. SSR) 3 suites, 108 passed
jest src/helpers (whole folder) 33 suites, 1038 passed
jest --listTests src/helpers Theme.styles.test.tsx is in the default run, not orphaned
jest Theme.styles.test.tsx --verbose 37 tests — all four themed sheets exercised
jest --coverage --collectCoverageFrom=src/helpers/Theme.tsx 100% stmts / branch / funcs / lines
pnpm typecheck:tests (tsc -p tsconfig.test.json) clean
eslint on the three changed sources clean
prettier --check on all seven hand-edited files clean
pnpm check:conformance all 23 checks pass
gen:mcp:check, gen:catalog:check both regenerate identically — no stale artefact
sass compile of bestax-prefixed.scss, selector grep only [data-bestax-theme=…] / .bestax-theme-*; no data-theme hook
Cascade order in that compiled sheet prefers-color-scheme at 916/1784, [data-bestax-theme=…] at 1834/2735 — the attribute wins at equal specificity, so the harness's rename trick is valid
Build preview site check on this SHA success, and onBrokenAnchors: 'throw' — so the new theme.md#dark-mode link resolves

I could not write to the checkout's sources, so the "fails on main" claim was not re-run by reverting the effect. The compiled-sheet evidence makes it a certainty for the two prefixed sheets: the pre-fix effect writes only data-theme, for which those sheets contain no rule at all.

Housekeeping, not a PR change: my sass invocation left an untracked bulma-ui/bulma-ui/.tmp-pref.css that the sandbox would not let me delete. It is mine, not this PR's — git clean -fdx bulma-ui/bulma-ui removes it.

🏄 Second lap on this one and it's cleaner than the first — the silent catch now actually hollers when a gnarly prefix eats the attribute, and the docs stopped pretending data-theme is the only name in the water. Good to go, dude; the only kelp left is the guidance around the fix, like that PurgeCSS safelist still only knowing the unprefixed name.

@github-actions github-actions Bot added review-converged Deep review converged: no blocking findings, all review threads resolved, checks green and removed review-converged Deep review converged: no blocking findings, all review threads resolved, checks green labels Oct 4, 2026
@allxsmith

Copy link
Copy Markdown
Owner Author

deep-review: fresh

Main is merged in, so this review posts every finding, advisory included, as its own thread. It reviews 0e084e0.

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Preview Deployment

Preview URL: https://3179c778.bestax.pages.dev

Comment thread bulma-ui/src/helpers/Theme.tsx
Comment thread bulma-ui/src/helpers/Theme.tsx
Comment thread bulma-ui/src/helpers/__tests__/Theme.styles.test.tsx Outdated
Comment thread skills/bestax-theming/SKILL.md

@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 — 0 blocking · 4 advisory

# Severity Area Finding Location
1 🔵 Advisory Correctness Four adjacent colorMode surfaces still name only data-theme; the PurgeCSS safelist is the one this PR makes worse — the prefixed name is now assembled at runtime, so data-bestax-theme is a literal in no scanned file and /data-theme/ cannot match it skills/bestax-theming/SKILL.md:27
2 🔵 Advisory API The new invalid-prefix dev warning is documented nowhere a consumer reads, unlike Theme's other three dev warnings, which the props table calls out — and helpers/theme.md is in GENERATED_EXEMPT, so nothing will reconcile the two surfaces bulma-ui/src/helpers/Theme.tsx:856
3 🔵 Advisory Robustness The diagnostic is mode-dependent: removeAttribute never validates a name, so colorMode="system" — the initial state the shipped skill example uses — warns nothing under an attribute-invalid prefix bulma-ui/src/helpers/Theme.tsx:1123
4 🔵 Advisory Coverage The harness floor asserts prefix membership, so a themed sheet dropped by the content regex still passes while a sibling supplies its prefix bulma-ui/src/helpers/__tests__/Theme.styles.test.tsx:62

Overall: The fix is correct and the diagnosis is right at the source. @mixin bulma-theme (node_modules/bulma/sass/utilities/css-variables.scss:489-493) emits [data-#{$class-prefix}theme="…"], .#{$class-prefix}theme-… and is Bulma's only attribute hook; a grep for data-theme across all of bulma/sass and bulma-ui/src/scss returns two comment lines and nothing else, so the prefixed sheets genuinely carried no data-theme rule and writing both names is both necessary and sufficient. The riskiest artefact is Theme.styles.test.tsx — it is the only thing standing between this and a silent regression, and it leans on two unasserted premises (jsdom honours an @media list only when it names screen; Bulma emits its prefers-color-scheme blocks before the attribute blocks, so the renamed block loses to the attribute at equal specificity), both of which the green run confirms. A human can merge on the code and spend their attention on finding 1 instead: the executable fix is complete, but the guidance around it that a prefixed app follows still points at the unprefixed name, and no check here can see that.

Residual risk:

  • A prefixed sheet carrying a data-theme hook after all — refuted at the source. bulma-theme interpolates $class-prefix and is the only attribute hook; grep -rn data-theme node_modules/bulma/sass bulma-ui/src/scss yields only themes/_index.scss:26 and :32, both comments. The extra data-theme written under a prefix is inert, never conflicting — and it is not new behaviour, so no prefixed app gains a collision it did not already have.
  • The other hook, .<prefix>theme-dark — not a regression. colorMode wrote no class before this PR and writes none after, so the class path is equally unreachable on both branches.
  • bestax-no-dark-mode.css — refuted as a gap. It loads only bulma/sass/themes/light, so it has no [data-…theme=dark] block at all and colorMode="dark" was a no-op there before and after. The filter excludes it correctly, and an accidental inclusion throws has no dark theme block in beforeAll rather than passing quietly.
  • The invalid-prefix path throwing anywhere — refuted. Only setAttribute validates a name, and it is the guarded call; getAttribute returns null and removeAttribute is a no-op for a name no element can hold, so the cleanup always takes the removeAttribute branch (previous[i] cannot be non-null for an attribute-invalid name). Exercised live by the md/ test, post-unmount assertion included.
  • classPrefix changing under a mounted colorMode Theme — refuted. It is in the effect's dep list, so the old name set is restored before the new one is written, and useClassPrefix returns a plain string from context, so the effect does not churn.
  • A case-differing prefix (classPrefix="Bestax-") — refuted. setAttribute ASCII-lowercases the qualified name on an HTML element, and selector attribute names match ASCII case-insensitively in HTML documents, so Bulma's [data-Bestax-theme=dark] still matches the data-bestax-theme that lands.
  • Nested Themes both setting colorMode — unchanged in kind. previous is still a per-effect snapshot, so two mounted Themes restore last-in-wins. One name became two with identical per-name semantics; the restore tests cover the single-Theme contract.
  • A Theme colorMode mounted above its ConfigProvider — settled, not re-raised. Answered in the author's comment on the first review as deliberate and consistent with every other prefixed output, with the TSDoc and Theme page both scoping the prefixed attribute to "under a ConfigProvider classPrefix"; the code it points at has not changed, so the reason still holds.
  • Open: finding 3's 'system' asymmetry is the only executable path in the failure class still unclosed. Everything else above is refuted; finding 1 is prose and so not a residual risk by definition, but it is where the remaining real-world exposure sits.
What I ran
Check Result
jest Theme.test.tsx Theme.styles.test.tsx 2 suites, 111 passed
jest Theme.styles.test.tsx --verbose 37 tests — all four themed sheets x 9 cases, plus the floor
jest --coverage --collectCoverageFrom=src/helpers/Theme.tsx 100% stmts / branch / funcs / lines
pnpm check:conformance all 23 checks pass
pnpm gen:mcp:check regenerates identically — no stale MCP index
pnpm gen:catalog:check regenerates identically — no stale catalog
prettier --check on all seven hand-edited files clean
grep -rn data-theme node_modules/bulma/sass bulma-ui/src/scss two comment lines only — no unprefixed attribute hook anywhere
bulma/sass/utilities/css-variables.scss:489-493 read directly [data-#{$class-prefix}theme] / .#{$class-prefix}theme-… confirmed as the sole hooks
src/scss flavour-by-flavour trace against the test's content regex 4 admitted, 2 correctly rejected (table in finding 4)
scripts/lib/api-sources.mjs helpers/ is in GENERATED_EXEMPT — theme.md's props table is hand-written, so finding 2's two surfaces drift independently
Checks on this SHA Build and Test, Test and Preview Deployment, Build preview site, React 18 + 19, CodeQL all success

Reverting the effect to re-run the "fails on main" claim was not permitted in this checkout (both file writes and git show redirection were blocked), so it rests on the source evidence above rather than a red run: for a bestax- prefix the pre-fix effect wrote only data-theme, for which those two compiled sheets contain no rule at all, so schemeMainL() necessarily resolved to the OS value.

🏄 Third lap and the wave's still holding its shape — the reef was real (Bulma names its scheme attribute after the prefix, so the prefixed sheets were never listening) and the styles test paddles out and compiles the actual SCSS instead of trusting an attribute merely landing in the DOM. Good to go, dude; the only kelp left is the guidance around the fix, like that PurgeCSS safelist still only knowing the unprefixed name.

…s described

The PurgeCSS recipe safelisted /data-theme/, which does not match data-bestax-theme, so a
prefixed build purged its [data-bestax-theme] rules and colorMode could not switch the scheme
in production. The pattern now matches data-<prefix>theme too.

The dark-mode example, the theming skill page and the helpers CLAUDE.md name the prefixed
attribute next to data-theme. The colorMode TSDoc and props row say that a prefix which cannot
form an attribute name writes only data-theme and warns in development.

The stylesheet harness now names the published sheets its filter leaves out, so a themed sheet
the filter drops fails even while a sibling still covers its prefix.
…nd color guide

The theming skill's examples list and checklist, and the skills README tree, now name
data-<prefix>theme next to data-theme. The color guide's per-surface recipe says a prefixed
build reads data-<prefix>theme instead, so with the prefixed flavors the surface takes
data-bestax-theme="light". The compiled prefixed sheet matches [data-bestax-theme=light] on
any element and has no data-theme selector.
@allxsmith

Copy link
Copy Markdown
Owner Author

deep-review: verify

Every open thread has a reply: fixed, with the commit, or refuted with a reason. This settles them on 81b02df.

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Preview Deployment

Preview URL: https://8ad8f651.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 (verify) — 0 resolved · 0 open

No threads left to settle — all four threads from this review were already resolved on this same commit (81b02dfe), each carrying its verification or acceptance reply:

Thread Severity Disposition
bulma-ui/src/helpers/Theme.tsx:859 — new dev warning documented nowhere 🔵 Advisory Verified fixed (ece8511a), resolved
bulma-ui/src/helpers/Theme.tsx:1129 — the system mode never warns 🔵 Advisory Refutation accepted, resolved
bulma-ui/src/helpers/__tests__/Theme.styles.test.tsx — harness floor 🔵 Advisory Verified fixed (ece8511a), resolved
skills/bestax-theming/SKILL.md:30 — adjacent colorMode surfaces 🔵 Advisory Verified fixed (ece8511a, 81b02dfe), resolved

Overall: This pass settled threads and reviewed no commits. Re-reading the current tree confirms every disposition still holds: the colorMode TSDoc (Theme.tsx:860-861) and the props row (docs/docs/api/helpers/theme.md:481) both scope the warning to light/dark, the stylesheet floor asserts the exact complement of the content filter (Theme.styles.test.tsx:64-72), and the PurgeCSS safelist pattern in both deep and greedy now matches the prefixed attribute name as well as the plain one (optimizing-css.md:78-79). Theme.styles.test.tsx + Theme.test.tsx: 111 passed. Nothing of mine is open, so a human can go straight to the merge decision; anyone wanting the current code looked at again should ask for a fresh review rather than another verify.

Residual risk: none identified by this pass — a verify pass raises no findings, and the residual risks for this change were enumerated in the fresh review of 0e084e0b and answered in the four threads above.

🏄 Nothing left in the lineup on this one, dude — every wave already got ridden clean, threads closed, tests green. Just a mellow paddle back to shore.

@github-actions github-actions Bot added the review-converged Deep review converged: no blocking findings, all review threads resolved, checks green label Oct 5, 2026
@allxsmith allxsmith added the needs-human-review Loop converged (or contested): awaiting owner review + manual merge label Oct 5, 2026
@github-actions github-actions Bot removed the review-converged Deep review converged: no blocking findings, all review threads resolved, checks green label Oct 5, 2026
github-actions Bot added a commit that referenced this pull request Oct 5, 2026
@github-actions github-actions Bot added the review-converged Deep review converged: no blocking findings, all review threads resolved, checks green label Oct 5, 2026
@allxsmith
allxsmith merged commit 2bd6ec2 into main Oct 5, 2026
102 of 103 checks passed
@allxsmith
allxsmith deleted the fix/theme-colormode-prefixed branch October 5, 2026 11:43
bestax-release-bot Bot pushed a commit that referenced this pull request Oct 5, 2026
## [5.26.3](https://github.com/allxsmith/bestax/compare/@allxsmith/bestax-bulma@5.26.2...@allxsmith/bestax-bulma@5.26.3) (2026-10-05)

### Bug Fixes

* **bulma-ui:** fire the pickers' onOpen and onClose once under StrictMode ([#896](#896)) ([20b51ed](20b51ed))
* **bulma-ui:** let focus follow the keys in an inline calendar, and skip disabled days for the tab stop ([#885](#885)) ([f55af27](f55af27))
* **bulma-ui:** make Theme colorMode switch the scheme under the prefixed builds ([#894](#894)) ([2bd6ec2](2bd6ec2))
* **bulma-ui:** place a portaled picker panel by its coordinates alone ([#886](#886)) ([040299b](040299b))
* **bulma-ui:** read picker bounds and months in years 0 to 99 as written ([#890](#890)) ([02fb619](02fb619))
* **bulma-ui:** start a date picker's focus on the focused cell ([#897](#897)) ([6a55714](6a55714))
* **bulma-ui:** stop the indeterminate progress bar and skeleton pulse under reduced motion ([bcf5407](bcf5407))
@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 5.26.3 🎉

The release is available on:

Your semantic-release bot 📦🚀

bestax-release-bot Bot pushed a commit that referenced this pull request Oct 7, 2026
# [2.25.0](https://github.com/allxsmith/bestax/compare/bestax-migrate@2.24.0...bestax-migrate@2.25.0) (2026-10-07)

### Bug Fixes

* **bulma-ui:** announce polite notifications through a status region kept from mount ([#835](#835)) ([c93478d](c93478d))
* **bulma-ui:** answer the granularity review on native input and blur ([7a17486](7a17486))
* **bulma-ui:** attach useFocusTrap to a container that mounts after it turns on ([17a944d](17a944d))
* **bulma-ui:** bring File and Taginput under the bare-Control Field rule ([cdaa6c2](cdaa6c2))
* **bulma-ui:** clear a picker's unused seed whenever its popover closes ([cbe86c5](cbe86c5))
* **bulma-ui:** color the calendar from the color prop and read TimeInput's wheel variables ([2251e67](2251e67)), closes [#832](#832)
* **bulma-ui:** commit nothing when a picker popover is dismissed ([0a46209](0a46209))
* **bulma-ui:** commit nothing when Enter confirms untouched picker text ([773e146](773e146))
* **bulma-ui:** commit nothing when focus leaves a picker untouched ([30b4849](30b4849))
* **bulma-ui:** draw the time wheel focus ring where the wheel's mask shows it ([e1d8c9f](e1d8c9f)), closes [#832](#832)
* **bulma-ui:** fall back when useFocusTrap's initialFocusRef can't take focus ([c191931](c191931))
* **bulma-ui:** fire the pickers' onOpen and onClose once under StrictMode ([#896](#896)) ([20b51ed](20b51ed))
* **bulma-ui:** give the selected calendar cell a ring that shows on its fill ([b3eecc6](b3eecc6))
* **bulma-ui:** hide a picker's launcher for a loading Control it sits in ([9a3888e](9a3888e))
* **bulma-ui:** hide a picker's launcher only for the spinner it draws ([7a28a0e](7a28a0e))
* **bulma-ui:** hold Portal to looking a selector up on each render ([8fe02ce](8fe02ce))
* **bulma-ui:** hold the year-1 floor under a max before it ([4f6eb18](4f6eb18))
* **bulma-ui:** judge image map areas by their image in useFocusTrap ([af7bc59](af7bc59))
* **bulma-ui:** keep a tab stop in the year list when the year falls outside it ([fe028c1](fe028c1))
* **bulma-ui:** keep an empty picker's seed while a portaled popover is open ([1e66528](1e66528))
* **bulma-ui:** keep an inline date picker's calendar on its released id ([c26da07](c26da07)), closes [#897](#897) [#897](#897)
* **bulma-ui:** keep button defaults through a spread, and type the buttons that had none ([#853](#853)) ([0810482](0810482))
* **bulma-ui:** keep button types and Avatar's accessible name through a spread ([#826](#826)) ([dc798d4](dc798d4))
* **bulma-ui:** keep the Field for horizontal and fieldClassName in a bare Control ([e4dc513](e4dc513))
* **bulma-ui:** keep the picker focus rings visible in every color ([612aa09](612aa09))
* **bulma-ui:** let focus follow the keys in an inline calendar, and skip disabled days for the tab stop ([#885](#885)) ([f55af27](f55af27))
* **bulma-ui:** let the picker bases give way to a loading Control too ([66e803a](66e803a))
* **bulma-ui:** let useFocusTrap go of a container that leaves while it is on ([8c56d7a](8c56d7a))
* **bulma-ui:** make auto leave room for an in-place picker panel's themed offset ([8c534bd](8c534bd)), closes [#904](#904)
* **bulma-ui:** make Theme colorMode switch the scheme under the prefixed builds ([#894](#894)) ([2bd6ec2](2bd6ec2))
* **bulma-ui:** make useFocusTrap follow radio groups and initialFocusRef past the trap ([d6219d4](d6219d4))
* **bulma-ui:** match a picker's opening focus only inside its calendar ([e3c22ed](e3c22ed))
* **bulma-ui:** place a portaled picker panel by its coordinates alone ([#886](#886)) ([040299b](040299b))
* **bulma-ui:** place toasts and notifications at the position they were shown with ([#834](#834)) ([62feab9](62feab9))
* **bulma-ui:** read clicks and focus inside a shadow root ([474f2cc](474f2cc))
* **bulma-ui:** read picker bounds and months in years 0 to 99 as written ([#890](#890)) ([02fb619](02fb619))
* **bulma-ui:** restore a portaled Modal's focus to an opener in a shadow root ([c564bd3](c564bd3))
* **bulma-ui:** return focus to the input when a date picker closes ([b741264](b741264))
* **bulma-ui:** settle Popover's deep review findings ([feadaf4](feadaf4))
* **bulma-ui:** start a date picker's focus on the focused cell ([#897](#897)) ([6a55714](6a55714))
* **bulma-ui:** stop Bulma's spinners under reduced motion in every stylesheet ([b234712](b234712)), closes [#770](#770)
* **bulma-ui:** stop form wrappers nesting a Field in a bare Control ([2c6d295](2c6d295))
* **bulma-ui:** stop the date pickers at year 1 ([853142a](853142a))
* **bulma-ui:** stop the indeterminate progress bar and skeleton pulse under reduced motion ([bcf5407](bcf5407))
* **bulma-ui:** stop the Rate pop and DateTimeInput scrim under reduced motion ([3a59129](3a59129))
* **bulma-ui:** stop TimeInput reopening on the focus its popover hands back ([1c87c15](1c87c15))
* **bulma-ui:** warn when a root Theme drops its className and helpers ([05c10e0](05c10e0))
* **eslint-plugin:** judge Columns' gap by its own steps, and lengths as lengths ([4786c8d](4786c8d))

### Features

* **bestax-mcp:** publish to the official MCP Registry ([74efc7f](74efc7f))
* **bestax-migrate:** convert the gap, position, overflow, radius and aspect-ratio helpers ([13dcf63](13dcf63))
* **bulma-ui:** add Bulma's gap helper props to every component ([#877](#877)) ([1bd4abc](1bd4abc))
* **bulma-ui:** add Bulma's position, overflow, radius and aspect-ratio helper props ([#845](#845)) ([64fb91c](64fb91c))
* **bulma-ui:** add Collapses, an accordion group for Collapse ([#849](#849)) ([a12c823](a12c823))
* **bulma-ui:** add Loader, Bulma's inline spinner ([c5e9eb0](c5e9eb0)), closes [#770](#770)
* **bulma-ui:** add month and year pickers to DateInput through granularity ([c4cfc2b](c4cfc2b)), closes [#773](#773)
* **bulma-ui:** add Popover ([2e17fac](2e17fac)), closes [#776](#776)
* **bulma-ui:** export ClientOnly and useIsHydrated ([2c0c1e6](2c0c1e6))
* **bulma-ui:** export Portal ([346d8c2](346d8c2))
* **bulma-ui:** export useFocusTrap, counting the stops the browser's Tab visits ([c304fef](c304fef)), closes [#772](#772)
* **bulma-ui:** make columnGap the column gap helper on Theme ([eb2c611](eb2c611)), closes [#694](#694)
* **eslint-plugin:** check the gap helper props ([b53a749](b53a749))
@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 2.25.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

bestax-release-bot Bot pushed a commit that referenced this pull request Oct 8, 2026
## [4.2.13](https://github.com/allxsmith/bestax/compare/create-bestax@4.2.12...create-bestax@4.2.13) (2026-10-08)

### Bug Fixes

* **bestax-mcp:** give .image's ratios their reason in the lookup ([3ea4d0c](3ea4d0c))
* **bestax-mcp:** say an .image converts around elements written out, not an expression ([49bb27b](49bb27b))
* **bestax-migrate:** convert an .image around its children only when they're elements ([ff99907](ff99907))
* **bestax-migrate:** flag react-bulma-components Pagination's delta={0} rather than renaming it ([e339ff1](e339ff1))
* **bestax-migrate:** keep a .menu-list around a bestax Menu.List as markup ([2119c3f](2119c3f))
* **bestax-migrate:** keep a Modal part as markup inside an existing bestax Modal ([cfd5f15](cfd5f15))
* **bestax-migrate:** keep a named anchor as markup instead of saying its name does nothing ([74dc360](74dc360)), closes [#fragment](https://github.com/allxsmith/bestax/issues/fragment)
* **bestax-migrate:** keep a page link as markup when its li is a component's only child ([0e72683](0e72683))
* **bestax-migrate:** know a bestax part imported under its flat export ([7a325ee](7a325ee))
* **bestax-migrate:** leave a wrapper tag alone when none of its classes would become a prop ([2397b9d](2397b9d))
* **bestax-migrate:** leave a wrapper tag with no helper class alone, TODOs and all ([1167a29](1167a29))
* **bestax-migrate:** map react-bulma-components Pagination onto the props it now renders from ([6cd4b51](6cd4b51))
* **bestax-migrate:** rename rbx innerRef to ref on a plain Navbar.Item too ([bb6ace0](bb6ace0)), closes [#734](#734)
* **bestax-migrate:** say why .image's ratios stay classes ([2fbfbd5](2fbfbd5))
* **bestax-migrate:** write a File text with a backslash as a string ([212831e](212831e))
* **bestax-migrate:** write a tabIndex string as a number on every root ([546bf8a](546bf8a)), closes [#814](#814)
* **bestax-migrate:** write isFullwidth from react-bulma-components too ([01da047](01da047))
* **bestax-migrate:** write isFullwidth rather than its deprecated alias from bloomer ([c2a1d22](c2a1d22)), closes [#680](#680)
* **bulma-ui:** announce polite notifications through a status region kept from mount ([#835](#835)) ([c93478d](c93478d))
* **bulma-ui:** answer the granularity review on native input and blur ([7a17486](7a17486))
* **bulma-ui:** apply textColor helper class on Navbar Menu, Start, End, and Burger ([#792](#792)) ([feb83c8](feb83c8))
* **bulma-ui:** attach useFocusTrap to a container that mounts after it turns on ([17a944d](17a944d))
* **bulma-ui:** avoid empty class attribute on several components ([#793](#793)) ([7c5c316](7c5c316))
* **bulma-ui:** bring File and Taginput under the bare-Control Field rule ([cdaa6c2](cdaa6c2))
* **bulma-ui:** clear a picker's unused seed whenever its popover closes ([cbe86c5](cbe86c5))
* **bulma-ui:** close a picker's popover on Alt+ArrowUp from inside it ([b6da4ef](b6da4ef))
* **bulma-ui:** color the calendar from the color prop and read TimeInput's wheel variables ([2251e67](2251e67)), closes [#832](#832)
* **bulma-ui:** color TimeInput's wheels from the color prop ([#832](#832)) ([ad370c9](ad370c9))
* **bulma-ui:** commit nothing when a picker popover is dismissed ([0a46209](0a46209))
* **bulma-ui:** commit nothing when Enter confirms untouched picker text ([773e146](773e146))
* **bulma-ui:** commit nothing when focus leaves a picker untouched ([30b4849](30b4849))
* **bulma-ui:** document the checkbox, radio and switch color and size tuples ([bd39ff3](bd39ff3))
* **bulma-ui:** draw the time wheel focus ring where the wheel's mask shows it ([e1d8c9f](e1d8c9f)), closes [#832](#832)
* **bulma-ui:** drop the openOnFocus TSDoc reason that only holds for segments ([efde0d9](efde0d9))
* **bulma-ui:** Dropdown items withhold attributes by tag and answer Enter and Space ([#827](#827)) ([f6aeb2d](f6aeb2d))
* **bulma-ui:** fall back when useFocusTrap's initialFocusRef can't take focus ([c191931](c191931))
* **bulma-ui:** fire the pickers' onOpen and onClose once under StrictMode ([#896](#896)) ([20b51ed](20b51ed))
* **bulma-ui:** give the calendar's day grid rows of a week ([971a196](971a196)), closes [#774](#774)
* **bulma-ui:** give the selected calendar cell a ring that shows on its fill ([b3eecc6](b3eecc6))
* **bulma-ui:** hide a picker's launcher for a loading Control it sits in ([9a3888e](9a3888e))
* **bulma-ui:** hide a picker's launcher only for the spinner it draws ([7a28a0e](7a28a0e))
* **bulma-ui:** hold Portal to looking a selector up on each render ([8fe02ce](8fe02ce))
* **bulma-ui:** hold the year-1 floor under a max before it ([4f6eb18](4f6eb18))
* **bulma-ui:** judge image map areas by their image in useFocusTrap ([af7bc59](af7bc59))
* **bulma-ui:** keep a range's end while the start's digits are coming ([8d1f862](8d1f862))
* **bulma-ui:** keep a read-only date or time picker closed on ArrowDown ([ba74bf7](ba74bf7))
* **bulma-ui:** keep a tab stop in the year list when the year falls outside it ([fe028c1](fe028c1))
* **bulma-ui:** keep an empty picker's seed while a portaled popover is open ([1e66528](1e66528))
* **bulma-ui:** keep an inline date picker's calendar on its released id ([c26da07](c26da07)), closes [#897](#897) [#897](#897)
* **bulma-ui:** keep button defaults through a spread, and type the buttons that had none ([#853](#853)) ([0810482](0810482))
* **bulma-ui:** keep button types and Avatar's accessible name through a spread ([#826](#826)) ([dc798d4](dc798d4))
* **bulma-ui:** keep menuitemcheckbox and menuitemradio items in Dropdown's arrow-key order ([#786](#786)) ([064155a](064155a))
* **bulma-ui:** keep Numberinput's buttons in a row inside Field > Control ([4dff84c](4dff84c))
* **bulma-ui:** keep Numberinput's Field examples in a row and labelled ([c937c88](c937c88))
* **bulma-ui:** keep radiusless zeroing the radius inside a Theme ([07db6a3](07db6a3)), closes [#829](#829) [#694](#694)
* **bulma-ui:** keep the calendar behind DateTimeInput's time wheels out of reach ([c7f674c](c7f674c))
* **bulma-ui:** keep the clock's seconds out of a picked date and time ([0af2e71](0af2e71))
* **bulma-ui:** keep the Field for horizontal and fieldClassName in a bare Control ([e4dc513](e4dc513))
* **bulma-ui:** keep the picker focus rings visible in every color ([612aa09](612aa09))
* **bulma-ui:** keep the range band under the pointer in the calendar ([c1f2008](c1f2008))
* **bulma-ui:** key the Avatar link warning on the element and attributes ([e628eba](e628eba)), closes [#733](#733) [#733](#733)
* **bulma-ui:** key the Control-level warning by its advice ([24cda3d](24cda3d))
* **bulma-ui:** leave keys on a control inside a tab to that control ([4a9f7b6](4a9f7b6))
* **bulma-ui:** leave rel out of the Avatar link attribute warning ([b059476](b059476)), closes [#733](#733) [#733](#733)
* **bulma-ui:** let Autocomplete's clear button give way to a loading spinner ([5c11fb2](5c11fb2))
* **bulma-ui:** let Escape in a popover's year dropdown go back to the grid ([a8b1dbf](a8b1dbf)), closes [#901](#901)
* **bulma-ui:** let File's picked-files count be reworded, and document its name in the label ([e86545c](e86545c))
* **bulma-ui:** let focus follow the keys in an inline calendar, and skip disabled days for the tab stop ([#885](#885)) ([f55af27](f55af27))
* **bulma-ui:** let several isRoot Themes share the :root style element ([04f399f](04f399f)), closes [#736](#736)
* **bulma-ui:** let the arrow keys move through the calendar's year dropdown ([6abc329](6abc329)), closes [#901](#901)
* **bulma-ui:** let the picker bases give way to a loading Control too ([66e803a](66e803a))
* **bulma-ui:** let useFocusTrap go of a container that leaves while it is on ([8c56d7a](8c56d7a))
* **bulma-ui:** let warnOnce decide when the Avatar link warning fires ([1a5965c](1a5965c)), closes [#733](#733)
* **bulma-ui:** make ArrowUp raise a time wheel's value ([c27c310](c27c310))
* **bulma-ui:** make auto leave room for an in-place picker panel's themed offset ([8c534bd](8c534bd)), closes [#904](#904)
* **bulma-ui:** make Tabs keyboard operable with the WAI-ARIA tabs pattern ([fe0e7ef](fe0e7ef))
* **bulma-ui:** make Theme colorMode switch the scheme under the prefixed builds ([#894](#894)) ([2bd6ec2](2bd6ec2))
* **bulma-ui:** make Theme's radius the helper it is typed as ([36c73d3](36c73d3)), closes [#694](#694)
* **bulma-ui:** make useFocusTrap follow radio groups and initialFocusRef past the trap ([d6219d4](d6219d4))
* **bulma-ui:** match a picker's opening focus only inside its calendar ([e3c22ed](e3c22ed))
* **bulma-ui:** merge className into Navbar.Divider instead of overwriting it ([#791](#791)) ([fcc0d51](fcc0d51))
* **bulma-ui:** move focus into DateTimeInput's time wheels as they open ([adfa9db](adfa9db))
* **bulma-ui:** move the year dropdown's tab stop with the arrow keys ([f56daf5](f56daf5))
* **bulma-ui:** name a picker's default icon when its icon size or column moves ([6f6de39](6f6de39))
* **bulma-ui:** name custom elements among the targets that get Avatar's target and rel ([a962259](a962259)), closes [#733](#733)
* **bulma-ui:** name DateRangeInput's default icon in its Control-level warning ([15cbbb8](15cbbb8)), closes [#952](#952)
* **bulma-ui:** name DateRangeInput's default icon in its Control-level warning ([9cbe7ca](9cbe7ca)), closes [#952](#952)
* **bulma-ui:** name Pagination's page links, and read a count that's no number as its default ([0a1cf06](0a1cf06))
* **bulma-ui:** open DateRangeInput's popover on Alt+ArrowDown, as the other pickers ([c0e22ec](c0e22ec))
* **bulma-ui:** open the date and time popovers on Alt+ArrowDown ([6db22cc](6db22cc))
* **bulma-ui:** order the Tabs fallback stop by index and style disabled tabs ([eefd283](eefd283))
* **bulma-ui:** pick a DateInput day at midnight by key as by click ([92c27ca](92c27ca))
* **bulma-ui:** place a portaled picker panel by its coordinates alone ([#886](#886)) ([040299b](040299b))
* **bulma-ui:** place toasts and notifications at the position they were shown with ([#834](#834)) ([62feab9](62feab9))
* **bulma-ui:** prefix the is-current and is-disabled classes on Pagination's parts ([c9a5fae](c9a5fae))
* **bulma-ui:** reach Taginput's delete buttons and Autocomplete's clear button ([21a064b](21a064b))
* **bulma-ui:** read a Pagination current page that's no number as the first ([68e963b](68e963b))
* **bulma-ui:** read clicks and focus inside a shadow root ([474f2cc](474f2cc))
* **bulma-ui:** read picker bounds and months in years 0 to 99 as written ([#890](#890)) ([02fb619](02fb619))
* **bulma-ui:** render the four burger spans Bulma v1 positions ([#785](#785)) ([8e4e1e6](8e4e1e6))
* **bulma-ui:** restore a portaled Modal's focus to an opener in a shadow root ([c564bd3](c564bd3))
* **bulma-ui:** return focus to the input when a date picker closes ([b741264](b741264))
* **bulma-ui:** say a picked DateTimeInput day keeps milliseconds and meets the bounds ([3536467](3536467))
* **bulma-ui:** say Tab reaches DateRangeInput's end input only when typing ([d2d3d1a](d2d3d1a))
* **bulma-ui:** say where Numberinput goes bare and test bare={false} in a Field ([0461631](0461631))
* **bulma-ui:** send a press on DateRangeInput's field to the nearer input ([f06b2b0](f06b2b0))
* **bulma-ui:** settle Popover's deep review findings ([feadaf4](feadaf4))
* **bulma-ui:** show the picked file with File's hasName and add a keyboard focus ring ([7881db4](7881db4))
* **bulma-ui:** show toasts, notifications and dialogs raised before their container mounts ([#828](#828)) ([2ab4493](2ab4493))
* **bulma-ui:** skip the Avatar target warning on elements with their own target ([27b58f4](27b58f4)), closes [#733](#733)
* **bulma-ui:** start a date picker's focus on the focused cell ([#897](#897)) ([6a55714](6a55714))
* **bulma-ui:** stop Bulma's spinners under reduced motion in every stylesheet ([b234712](b234712)), closes [#770](#770)
* **bulma-ui:** stop form wrappers nesting a Field in a bare Control ([2c6d295](2c6d295))
* **bulma-ui:** stop shipping test-only exports, and document notification() ([#781](#781)) ([5f95398](5f95398))
* **bulma-ui:** stop the date pickers at year 1 ([853142a](853142a))
* **bulma-ui:** stop the indeterminate progress bar and skeleton pulse under reduced motion ([bcf5407](bcf5407))
* **bulma-ui:** stop the Rate pop and DateTimeInput scrim under reduced motion ([3a59129](3a59129))
* **bulma-ui:** stop TimeInput reopening on the focus its popover hands back ([1c87c15](1c87c15))
* **bulma-ui:** strip the Avatar link warning from production builds ([a243fa5](a243fa5)), closes [#733](#733)
* **bulma-ui:** warn about a dropped Avatar href only for an as the caller wrote ([c93b27c](c93b27c)), closes [#733](#733)
* **bulma-ui:** warn in development when Avatar drops an href on a non-link as ([c76e632](c76e632)), closes [#733](#733)
* **bulma-ui:** warn when a root Theme drops its className and helpers ([05c10e0](05c10e0))
* **bulma-ui:** warn when a wrapper inside a Control drops its Control-level props ([cbf434b](cbf434b)), closes [#921](#921)
* **bulma-ui:** warn when an inline picker drops its Control-level props ([f0494bd](f0494bd)), closes [#921](#921)
* **bulma-ui:** warn when Avatar drops a target or rel on a non-link as ([50c385e](50c385e)), closes [#733](#733) [#733](#733)
* **create-bestax:** check the react ranges fit the library's peers, not equal them ([8ae5a0c](8ae5a0c)), closes [#950](#950)
* **create-bestax:** import the icon CSS for every Bulma flavor, not only complete ([a712b91](a712b91)), closes [#946](#946)
* **create-bestax:** install react and react-dom so Yarn 1 reports no unmet peers ([9c9814c](9c9814c)), closes [#644](#644) [#950](#950)
* **create-bestax:** name the files the overwrite prompt removes, and stop on a file path ([39b6232](39b6232)), closes [#945](#945)
* **create-bestax:** never empty a non-empty folder under -y, and validate flags first ([917f195](917f195)), closes [#950](#950) [#945](#945) [#950](#950)
* **create-bestax:** warn when the icon CSS import has nowhere to go ([f7f0b64](f7f0b64)), closes [#946](#946) [#946](#946)
* **eslint-plugin:** judge Columns' gap by its own steps, and lengths as lengths ([4786c8d](4786c8d))
* **eslint-plugin:** report .file as a class the codemod converts ([72a32c9](72a32c9))
* **eslint-plugin:** report .image with the message for a class the codemod converts ([d27c19b](d27c19b))
* **eslint-plugin:** report .menu, .menu-label and .menu-list with the converts message ([8ffaccc](8ffaccc))
* **eslint-plugin:** report .select and .breadcrumb as converted ([a9d8082](a9d8082))
* **eslint-plugin:** report Bulma form markup as classes the codemod converts ([128e832](128e832))
* **eslint-plugin:** report Bulma skeletons as converted ([04ca4ee](04ca4ee))
* **eslint-plugin:** report Modal's parts with the message for a class the codemod converts ([87f3c08](87f3c08))
* **eslint-plugin:** report Pagination's converting parts with the converts message ([6b94f14](6b94f14))
* **eslint-plugin:** report the pagination links and ellipsis as classes the codemod converts ([54ba0b3](54ba0b3))
* **eslint-plugin:** report Theme's deprecated radius route accurately ([5605816](5605816)), closes [#694](#694)
* **eslint-plugin:** suggest radiusless for a near miss on Theme ([21aa9a7](21aa9a7)), closes [#694](#694)

### Features

* **bestax-mcp:** look up .image as Image, with the props it takes from its <img> ([3e63230](3e63230))
* **bestax-mcp:** look up .menu and its label and list as Menu's parts ([f9fe7cd](f9fe7cd))
* **bestax-mcp:** look up Card's title and footer items on the tags their as takes ([ba8193e](ba8193e))
* **bestax-mcp:** look up Modal's parts as components ([b71583a](b71583a))
* **bestax-mcp:** look up Pagination, its list and its previous and next links as components ([f1298df](f1298df))
* **bestax-mcp:** look up the bestax component and props for a Bulma class string ([4a4b246](4a4b246)), closes [#744](#744)
* **bestax-mcp:** publish to the official MCP Registry ([74efc7f](74efc7f))
* **bestax-mcp:** say a Bulma field wraps its children only when horizontal ([929bc82](929bc82))
* **bestax-mcp:** say an .image converts around anything but a bare <img> ([60e9219](60e9219))
* **bestax-mcp:** say Menu.List renders .menu-list only at the top level ([dcce74f](dcce74f))
* **bestax-mcp:** say when a component renders the children from a count ([b60c295](b60c295))
* **bestax-mcp:** say when a component renders the element inside it ([4ced25c](4ced25c))
* **bestax-mcp:** say when a component renders the li around its element, or its own text ([8fd3faf](8fd3faf))
* **bestax-mcp:** say when a component renders the whole .file tree from props ([976d8a3](976d8a3))
* **bestax-migrate:** convert .file inside a Field, building its tree from props ([724dff5](724dff5)), closes [#809](#809)
* **bestax-migrate:** convert .icon-text, building its icons from props ([#823](#823)) ([933868f](933868f))
* **bestax-migrate:** convert .menu, its labels and its top-level lists ([02f4db6](02f4db6))
* **bestax-migrate:** convert .select and .breadcrumb with the element inside them ([d76c569](d76c569))
* **bestax-migrate:** convert .tabs and .icon around their children ([#815](#815)) ([3967a80](3967a80))
* **bestax-migrate:** convert a menu list's items to Menu.Item ([#816](#816)) ([b385687](b385687))
* **bestax-migrate:** convert an .image and its <img> to Image ([d4f3673](d4f3673)), closes [#793](#793)
* **bestax-migrate:** convert an .image around anything but a bare <img> ([0a31c5b](0a31c5b)), closes [#801](#801)
* **bestax-migrate:** convert Bulma cards built from their parts ([#752](#752)) ([1b08e17](1b08e17))
* **bestax-migrate:** convert Bulma form fields, controls, inputs and textareas ([3da788d](3da788d)), closes [#743](#743)
* **bestax-migrate:** convert Bulma grids and cells ([#760](#760)) ([22adc7c](22adc7c)), closes [#743](#743)
* **bestax-migrate:** convert Bulma navbars ([#754](#754)) ([02fdd72](02fdd72))
* **bestax-migrate:** convert Bulma skeletons ([2574ace](2574ace))
* **bestax-migrate:** convert Card's title and footer items on the tags their as takes ([20bc0c6](20bc0c6)), closes [#794](#794)
* **bestax-migrate:** convert conditional classes in clsx and classnames calls ([8948cce](8948cce))
* **bestax-migrate:** convert Modal's parts element by element ([4d41ad2](4d41ad2)), closes [#805](#805)
* **bestax-migrate:** convert navbar dividers with classes, and navbar text colors ([#796](#796)) ([c97c7e9](c97c7e9))
* **bestax-migrate:** convert Pagination, its list and its previous and next links ([d75bc70](d75bc70)), closes [#807](#807)
* **bestax-migrate:** convert Pagination's page links and ellipsis in their li's place ([ae720fa](ae720fa)), closes [#809](#809)
* **bestax-migrate:** convert Panel and its heading, tabs and blocks ([#811](#811)) ([0694e54](0694e54))
* **bestax-migrate:** convert the gap, position, overflow, radius and aspect-ratio helpers ([13dcf63](13dcf63))
* **bestax-migrate:** fold .table-container and .fixed-grid into the component inside ([#761](#761)) ([72504f5](72504f5)), closes [#743](#743)
* **bulma-ui:** add Bulma's gap helper props to every component ([#877](#877)) ([1bd4abc](1bd4abc))
* **bulma-ui:** add Bulma's position, overflow, radius and aspect-ratio helper props ([#845](#845)) ([64fb91c](64fb91c))
* **bulma-ui:** add Collapses, an accordion group for Collapse ([#849](#849)) ([a12c823](a12c823))
* **bulma-ui:** add DateRangeInput ([50fcba7](50fcba7)), closes [#774](#774)
* **bulma-ui:** add Loader, Bulma's inline spinner ([c5e9eb0](c5e9eb0)), closes [#770](#770)
* **bulma-ui:** add month and year pickers to DateInput through granularity ([c4cfc2b](c4cfc2b)), closes [#773](#773)
* **bulma-ui:** add Popover ([2e17fac](2e17fac)), closes [#776](#776)
* **bulma-ui:** export ClientOnly and useIsHydrated ([2c0c1e6](2c0c1e6))
* **bulma-ui:** export Portal ([346d8c2](346d8c2))
* **bulma-ui:** export useFocusTrap, counting the stops the browser's Tab visits ([c304fef](c304fef)), closes [#772](#772)
* **bulma-ui:** let Card.Header.Title and Card.FooterItem render Bulma's own tags ([#794](#794)) ([47ecdb6](47ecdb6))
* **bulma-ui:** make columnGap the column gap helper on Theme ([eb2c611](eb2c611)), closes [#694](#694)
* **bulma-ui:** render Pagination from total, current and onPageChange ([f7ddf04](f7ddf04)), closes [#813](#813)
* **eslint-plugin:** add an opt-in rule for plain elements styled with a Bulma component class ([#750](#750)) ([0bb4d80](0bb4d80))
* **eslint-plugin:** check the gap helper props ([b53a749](b53a749))
@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 4.2.13 🎉

The release is available on:

Your semantic-release bot 📦🚀

bestax-release-bot Bot pushed a commit that referenced this pull request Oct 9, 2026
## [1.14.1](https://github.com/allxsmith/bestax/compare/bestax-mcp@1.14.0...bestax-mcp@1.14.1) (2026-10-09)

### Bug Fixes

* **bestax-mcp:** describe a built icon's attributes as the codemod writes them ([d2f341b](d2f341b)), closes [#942](#942)
* **bestax-mcp:** hold every docs Storybook link to a real story, and floor the index's ([3a6df21](3a6df21))
* **bestax-mcp:** keep a described or named component first in a sentence-shaped search ([2e2a1ef](2e2a1ef))
* **bestax-mcp:** name every component that declares a CSS variable, its owner first ([8bf01e3](8bf01e3))
* **bestax-mcp:** point the index's Storybook links at stories that exist ([0852de4](0852de4))
* **bestax-mcp:** rank the component a search is about above passing mentions ([cc952c2](cc952c2))
* **bestax-mcp:** read self-closing names, explain Theme on every query, advertise dot-paths ([62a4a3a](62a4a3a))
* **bestax-mcp:** release the skill examples that compile in a vite-ts scaffold ([3a7f222](3a7f222))
* **bestax-mcp:** smooth the rough edges a smoke test found ([b6ed21a](b6ed21a))
* **bestax-mcp:** stop the search comment claiming every variable has an owner ([4f1d102](4f1d102))
* **bestax-migrate:** convert a .icon to Icon by the attributes Icon now writes ([a3795fb](a3795fb)), closes [#942](#942)
* **bestax-migrate:** convert an unnamed .icon with a role of its own without aria-hidden ([7c5ff91](7c5ff91)), closes [#942](#942)
* **bestax-migrate:** convert an unnamed .icon with a tabIndex of its own without aria-hidden ([df24c06](df24c06)), closes [#942](#942)
* **bulma-ui:** attach useFocusTrap to a container that mounts after it turns on ([17a944d](17a944d))
* **bulma-ui:** bring File and Taginput under the bare-Control Field rule ([cdaa6c2](cdaa6c2))
* **bulma-ui:** carry Rate's value on its checked star, not the radiogroup ([84f86d8](84f86d8)), closes [#942](#942)
* **bulma-ui:** check initializers for import-time work and stop overstating namespace imports ([20ef350](20ef350))
* **bulma-ui:** clear a picker's unused seed whenever its popover closes ([cbe86c5](cbe86c5))
* **bulma-ui:** close a picker's popover on Alt+ArrowUp from inside it ([b6da4ef](b6da4ef))
* **bulma-ui:** collapse an inline DateTimeInput's wheels on Enter ([ff44aa3](ff44aa3))
* **bulma-ui:** commit nothing when a picker popover is dismissed ([0a46209](0a46209))
* **bulma-ui:** commit nothing when Enter confirms untouched picker text ([773e146](773e146))
* **bulma-ui:** commit nothing when focus leaves a picker untouched ([30b4849](30b4849))
* **bulma-ui:** commit the time on Enter from the seconds wheel too ([d2c0920](d2c0920))
* **bulma-ui:** drop the openOnFocus TSDoc reason that only holds for segments ([efde0d9](efde0d9))
* **bulma-ui:** emit the ESM build one file per module so unused components shake out ([2893197](2893197))
* **bulma-ui:** fire the pickers' onOpen and onClose once under StrictMode ([#896](#896)) ([20b51ed](20b51ed))
* **bulma-ui:** give the calendar's day grid rows of a week ([971a196](971a196)), closes [#774](#774)
* **bulma-ui:** give TimeInput's wheels an id apart from the popover's ([40824cc](40824cc))
* **bulma-ui:** hide a picker's launcher for a loading Control it sits in ([9a3888e](9a3888e))
* **bulma-ui:** hide a picker's launcher only for the spinner it draws ([7a28a0e](7a28a0e))
* **bulma-ui:** hide an unnamed Icon and make a named one an image ([f9de39c](f9de39c)), closes [#942](#942)
* **bulma-ui:** hold the year-1 floor under a max before it ([4f6eb18](4f6eb18))
* **bulma-ui:** keep a press on a time wheel item from focusing the hidden item ([c57836a](c57836a)), closes [#942](#942)
* **bulma-ui:** keep a range's end while the start's digits are coming ([8d1f862](8d1f862))
* **bulma-ui:** keep a read-only date or time picker closed on ArrowDown ([ba74bf7](ba74bf7))
* **bulma-ui:** keep a tab stop in the year list when the year falls outside it ([fe028c1](fe028c1))
* **bulma-ui:** keep an empty picker's seed while a portaled popover is open ([1e66528](1e66528))
* **bulma-ui:** keep an inline date picker's calendar on its released id ([c26da07](c26da07)), closes [#897](#897) [#897](#897)
* **bulma-ui:** keep each Rate star's name its own at a value a hair off a whole number ([eed3d99](eed3d99)), closes [#942](#942)
* **bulma-ui:** keep Numberinput's buttons in a row inside Field > Control ([4dff84c](4dff84c))
* **bulma-ui:** keep Numberinput's Field examples in a row and labelled ([c937c88](c937c88))
* **bulma-ui:** keep the calendar behind DateTimeInput's time wheels out of reach ([c7f674c](c7f674c))
* **bulma-ui:** keep the clock's seconds out of a picked date and time ([0af2e71](0af2e71))
* **bulma-ui:** keep the Field for horizontal and fieldClassName in a bare Control ([e4dc513](e4dc513))
* **bulma-ui:** keep the range band under the pointer in the calendar ([c1f2008](c1f2008))
* **bulma-ui:** keep the time wheels' items out of their spinbutton ([6a02615](6a02615)), closes [#942](#942)
* **bulma-ui:** key the Control-level warning by its advice ([24cda3d](24cda3d))
* **bulma-ui:** leave an unnamed Icon with a role of its own visible ([b1e85f5](b1e85f5)), closes [#942](#942)
* **bulma-ui:** leave an unnamed Icon with a tabIndex of its own visible ([a41d131](a41d131)), closes [#942](#942)
* **bulma-ui:** leave Dropdown's menu nothing focusable but its items ([c1ec016](c1ec016)), closes [#942](#942)
* **bulma-ui:** leave keys on a control inside a tab to that control ([4a9f7b6](4a9f7b6))
* **bulma-ui:** let Autocomplete's clear button give way to a loading spinner ([5c11fb2](5c11fb2))
* **bulma-ui:** let Escape in a popover's year dropdown go back to the grid ([a8b1dbf](a8b1dbf)), closes [#901](#901)
* **bulma-ui:** let File's picked-files count be reworded, and document its name in the label ([e86545c](e86545c))
* **bulma-ui:** let focus follow the keys in an inline calendar, and skip disabled days for the tab stop ([#885](#885)) ([f55af27](f55af27))
* **bulma-ui:** let the arrow keys move through the calendar's year dropdown ([6abc329](6abc329)), closes [#901](#901)
* **bulma-ui:** let the picker bases give way to a loading Control too ([66e803a](66e803a))
* **bulma-ui:** let useFocusTrap go of a container that leaves while it is on ([8c56d7a](8c56d7a))
* **bulma-ui:** make ArrowUp raise a time wheel's value ([c27c310](c27c310))
* **bulma-ui:** make auto leave room for an in-place picker panel's themed offset ([8c534bd](8c534bd)), closes [#904](#904)
* **bulma-ui:** make Tabs keyboard operable with the WAI-ARIA tabs pattern ([fe0e7ef](fe0e7ef))
* **bulma-ui:** make Theme colorMode switch the scheme under the prefixed builds ([#894](#894)) ([2bd6ec2](2bd6ec2))
* **bulma-ui:** match a picker's opening focus only inside its calendar ([e3c22ed](e3c22ed))
* **bulma-ui:** move focus into DateTimeInput's time wheels as they open ([adfa9db](adfa9db))
* **bulma-ui:** move the year dropdown's tab stop with the arrow keys ([f56daf5](f56daf5))
* **bulma-ui:** name a picker's default icon when its icon size or column moves ([6f6de39](6f6de39))
* **bulma-ui:** name DateRangeInput's default icon in its Control-level warning ([51fc017](51fc017)), closes [#952](#952)
* **bulma-ui:** name DateRangeInput's default icon in its Control-level warning ([633f5dc](633f5dc)), closes [#952](#952)
* **bulma-ui:** name DateRangeInput's default icon in its Control-level warning ([15cbbb8](15cbbb8)), closes [#952](#952)
* **bulma-ui:** name DateRangeInput's default icon in its Control-level warning ([9cbe7ca](9cbe7ca)), closes [#952](#952)
* **bulma-ui:** name DateRangeInput's default icon in its Control-level warning ([25b7a0b](25b7a0b)), closes [#952](#952)
* **bulma-ui:** open DateRangeInput's popover on Alt+ArrowDown, as the other pickers ([c0e22ec](c0e22ec))
* **bulma-ui:** open the date and time popovers on Alt+ArrowDown ([6db22cc](6db22cc))
* **bulma-ui:** order the Tabs fallback stop by index and style disabled tabs ([eefd283](eefd283))
* **bulma-ui:** pick a DateInput day at midnight by key as by click ([92c27ca](92c27ca))
* **bulma-ui:** place a portaled picker panel by its coordinates alone ([#886](#886)) ([040299b](040299b))
* **bulma-ui:** point Autocomplete's aria-controls at its list only while the list is on screen ([8a16115](8a16115)), closes [#942](#942)
* **bulma-ui:** reach Taginput's delete buttons and Autocomplete's clear button ([21a064b](21a064b))
* **bulma-ui:** read a day that is both today and a nearby month the same inside a range band ([4164c3b](4164c3b)), closes [#983](#983)
* **bulma-ui:** read DateTimeInput's footer time row at 4.5:1 in both schemes ([585aa3b](585aa3b)), closes [#976](#976)
* **bulma-ui:** read every calendar day at 4.5:1 in both schemes ([876fe60](876fe60)), closes [#983](#983)
* **bulma-ui:** read picker bounds and months in years 0 to 99 as written ([#890](#890)) ([02fb619](02fb619))
* **bulma-ui:** render the time wheels' inert calendar through inertProps ([f023f25](f023f25))
* **bulma-ui:** return focus to the input when a date picker closes ([b741264](b741264))
* **bulma-ui:** say a picked DateTimeInput day keeps milliseconds and meets the bounds ([3536467](3536467))
* **bulma-ui:** say Alt+ArrowUp closes DateTimeInput's popover from the wheels ([f994d7d](f994d7d))
* **bulma-ui:** say Tab reaches DateRangeInput's end input only when typing ([d2d3d1a](d2d3d1a))
* **bulma-ui:** say where Numberinput goes bare and test bare={false} in a Field ([0461631](0461631))
* **bulma-ui:** send a press on DateRangeInput's field to the nearer input ([f06b2b0](f06b2b0))
* **bulma-ui:** show the picked file with File's hasName and add a keyboard focus ring ([7881db4](7881db4))
* **bulma-ui:** start a date picker's focus on the focused cell ([#897](#897)) ([6a55714](6a55714))
* **bulma-ui:** stop form wrappers nesting a Field in a bare Control ([2c6d295](2c6d295))
* **bulma-ui:** stop the date pickers at year 1 ([853142a](853142a))
* **bulma-ui:** stop the indeterminate progress bar and skeleton pulse under reduced motion ([bcf5407](bcf5407))
* **bulma-ui:** stop the picker popover partial warning about global nth() ([0b34d84](0b34d84))
* **bulma-ui:** stop the Rate pop and DateTimeInput scrim under reduced motion ([3a59129](3a59129))
* **bulma-ui:** tie DateTimeInput's Time button to the wheels it opens ([889fc7e](889fc7e))
* **bulma-ui:** warn when a root Theme drops its className and helpers ([05c10e0](05c10e0))
* **bulma-ui:** warn when a wrapper inside a Control drops its Control-level props ([cbf434b](cbf434b)), closes [#921](#921)
* **bulma-ui:** warn when an inline picker drops its Control-level props ([f0494bd](f0494bd)), closes [#921](#921)
* **bulma-ui:** wire Autocomplete's combobox to a named listbox ([213f648](213f648)), closes [#942](#942)
* **create-bestax:** check the react ranges fit the library's peers, not equal them ([8ae5a0c](8ae5a0c)), closes [#950](#950)
* **create-bestax:** have the optimize skill install with the project's package manager ([e0ba314](e0ba314)), closes [#597](#597)
* **create-bestax:** import the icon CSS for every Bulma flavor, not only complete ([a712b91](a712b91)), closes [#946](#946)
* **create-bestax:** install react and react-dom so Yarn 1 reports no unmet peers ([9c9814c](9c9814c)), closes [#644](#644) [#950](#950)
* **create-bestax:** make every skill example compile in a vite-ts scaffold ([6cc5fec](6cc5fec))
* **create-bestax:** name the files the overwrite prompt removes, and stop on a file path ([39b6232](39b6232)), closes [#945](#945)
* **create-bestax:** never empty a non-empty folder under -y, and validate flags first ([917f195](917f195)), closes [#950](#950) [#945](#945) [#950](#950)
* **create-bestax:** read the flags after a `--` that pnpm or bun forwards ([82112a2](82112a2)), closes [#950](#950)
* **create-bestax:** tell the optimize skill's modular build to install bulma ([4289d0a](4289d0a)), closes [#597](#597)
* **create-bestax:** warn when the icon CSS import has nowhere to go ([f7f0b64](f7f0b64)), closes [#946](#946) [#946](#946)
* **eslint-plugin:** judge Columns' gap by its own steps, and lengths as lengths ([4786c8d](4786c8d))

### Features

* **bestax-migrate:** convert the gap, position, overflow, radius and aspect-ratio helpers ([13dcf63](13dcf63))
* **bulma-ui:** add Bulma's gap helper props to every component ([#877](#877)) ([1bd4abc](1bd4abc))
* **bulma-ui:** add DateRangeInput ([50fcba7](50fcba7)), closes [#774](#774)
* **bulma-ui:** make columnGap the column gap helper on Theme ([eb2c611](eb2c611)), closes [#694](#694)
* **eslint-plugin:** check the gap helper props ([b53a749](b53a749))
@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 1.14.1 🎉

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

deep-review needs-human-review Loop converged (or contested): awaiting owner review + manual merge released review-converged Deep review converged: no blocking findings, all review threads resolved, checks green

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant