Skip to content

fix(bestax-migrate): keep a title's heading level when its size carries over - #1071

Merged
allxsmith merged 13 commits into
mainfrom
fix/1069-title-levels
Oct 16, 2026
Merged

allxsmith merged 13 commits into
mainfrom
fix/1069-title-levels

Conversation

@allxsmith

@allxsmith allxsmith commented Oct 15, 2026 •

Copy link
Copy Markdown
Owner

Title and SubTitle render the heading their size names unless as="p", so
<Title as="h3" size="4"> is an <h4>. Two places in the repo were written as if as set the
level. This fixes both, and neither touches the components.

The Codemod

Every source library rendered a title at the element its tag prop named, or at its own default,
whatever the size: bloomer's Title an <h1> and its Subtitle an <h2>, rbx's Title and
RBC's Heading an <h1>, subtitle or not. I read each one off the library's source at the SHA
its corpus script pins. The codemod renamed the size straight onto bestax's size, so the
heading outline changed under every sized title, and the bloomer prop map said the level was
kept. The issue named bloomer, but rbx and RBC had the same bug, so all three are fixed here
through one shared helper, keepTitleLevel in _shared/specials-utils.ts.

Before: the size became size, always. bloomer's Subtitle also gained as="h2" whenever
it had no tag.

After: the size stays size only where that renders the element the source did: a <p>, or
the heading the size names. Anywhere else it becomes textSize, which sets the same font size
and leaves the level to as. So does a 7: Bulma styles .title.is-7, but bestax's size stops
at 6, and textSize takes '7'. bloomer's Subtitle still gets as="h2", except where
size={2} already renders one, so the output stays minimal. In rbx, where a spread can carry
as, a readable size beside one moves even where it names the default <h1>. bloomer's tag
and RBC's renderAs never reach as from inside a spread, so there the spread changes nothing.
A size the codemod can't read stays size, and at a heading it gets a TODO that says to carry
it with textSize. The same TODO covers an rbx or RBC title that already sets textSize. A
literal bestax's size doesn't take, a bare isSize included, renders no size class, so its TODO
says to drop it or set a textSize from 1 to 7.

The bloomer imports-basic fixture, before and after:

// bloomer
<Title isSize={2} isSpaced>Heading</Title>
<Subtitle isSize={4} tag="h3">Sub</Subtitle>

// before: an <h2> and an <h4>
<Title size={2} isSpaced>Heading</Title>
<SubTitle size={4} as="h3">Sub</SubTitle>

// after: the <h1> and <h3> bloomer rendered
<Title textSize="2" isSpaced>Heading</Title>
<SubTitle textSize="4" as="h3">Sub</SubTitle>

textSize writes Bulma's is-size-4 where the title had is-4. Both use the same Sass size, so
the look holds, but an app's own CSS that targets .title.is-4 needs the new class too. And
is-size-4 is !important where .title.is-4 is not, so a font size the app's CSS gives the
title, such as .hero .title, can now lose where it used to win. The prop maps say both.

What pins it:

  • A title-levels fixture pair per source covers each branch: the default, a size that names
    the level, a size that doesn't, a tag, p, and a 7.
  • e2e/title-levels.test.ts migrates each case, renders it against the built library and
    compares the opening tag with what the source library rendered, classes included, reading
    is-size-N as is-N. The existing fixtures only compare text, which is how this shipped.
  • Each kitchen sink's leftovers gains a dynamic size, and the e2es check its TODO and that the
    rule is documented.
  • New unit tests cover the dynamic size, the p exemption, a dynamic tag, a spread in bloomer
    and in rbx, an out-of-range literal, a bare isSize and the textSize collision.

The skill references now say how the size is carried: a "Title and Subtitle sizes" section in
bloomer's prop map, matching sections in rbx's and RBC's, a recipe for the TODO in each
unmappables.md, and a note on RBC's Heading row. The three docs migration guides say it
too, and the MCP index is regenerated.

The ProfileCard Example

The custom-component skill's ProfileCard wrote <Title size="4" as="h3">, an <h4>. It is now
<Title as="h3" textSize="4"> in bulma-ui/src/skill-examples/ProfileCard.tsx,
docs/docs/skills/custom-component.mdx and the docs live-preview copy in
docs/src/components/SkillExamples/ProfileCard.jsx. There's no copy under skills/. The role
line's <SubTitle size="6" as="p"> stays, since as="p" wins.

The guidance that produced it goes too. The inline-style table in the custom-component and
layout-scaffold skills, and its copy in the CLAUDE.md create-bestax writes into a new app, told
agents to size a heading with size. That row now says as sets the level and size picks it
too, so an <h3> at size 4 is as="h3" textSize="4".

I swept the repo for every Title/SubTitle that sets both as and size. The rest are fine:
HoverCard and the stories, docs, templates and skill examples all use as="p", which size
never overrides, and the two as="h4" size="2" cases in Title.test.tsx and SubTitle.test.tsx
pin the precedence on purpose.

Release

The squash title should carry fix(bestax-migrate). That releases a bestax-migrate patch, which
is what gets the codemod fix to users. The bulma-ui commit is docs(bulma-ui):
ProfileCard is a Storybook and docs example with no runtime code in the package, and the
.d.ts the build emits for it doesn't change. A fix(bulma-ui) title would publish bestax-bulma
and bestax-mcp patches that change nothing, and bestax-migrate wouldn't release at all. The
create-bestax CLAUDE.md row and the two skill rows ride the next create-bestax release, the way
skill changes usually do.

Listings

This edits the bestax-migrate, custom-component and layout-scaffold skills, so per "What goes
stale" in the distribution guide, the cursor.directory and ClawHub copies of those skills need
the new text pasted in, and the Tessl
Registry and Skills Directory keep the old scan until it's analysed again. Once the
bestax-migrate patch ships, the Codemod Registry wrapper needs its usual bump and republish.

Checks

Run locally: bestax-migrate's full suite (fixtures, the e2es, the ref roster), create-bestax's
tests, typecheck,
typecheck:tests, lint, format:check, check:conformance, test:scripts (the docs fence,
ESLint docs and skill-examples typecheck tests included), bestax-mcp's tests, and pnpm gen with
nothing stale left behind.

Fixes #1069

…es over

bloomer, rbx and react-bulma-components all rendered a title at the element their tag
prop named, or at their own default, whatever the size. bestax's Title and SubTitle
render the heading their size names unless as="p", so renaming the size changed the
heading outline: bloomer's <Subtitle isSize={4}> became <SubTitle size={4} as="h2">,
an h4, while the prop map said the level was kept. rbx's <Title size={4}> and RBC's
<Heading size={4}> turned their h1 into an h4 the same way.

keepTitleLevel in _shared/specials-utils.ts now decides where the size goes for all
three sources. It stays size only where that renders the element the source did: a
<p>, or the heading the size names. Anywhere else it moves to textSize, which sets
the same font size and leaves the level to as. bloomer's Subtitle still writes out
as="h2", except where size={2} already renders one. A size it cannot read stays size
with a TODO that says to pass it as textSize.

New title-levels fixtures cover each branch per source, and e2e/title-levels.test.ts
renders the output and compares the opening tag with what each library rendered.
The kitchen-sink leftovers carry a dynamic size each, the migrate references and
docs guides say how the size is carried, and the MCP index is regenerated.
…tSize

The custom-component skill's ProfileCard wrote <Title size="4" as="h3">, which renders
an h4: Title's size picks the heading level unless as="p". It is now
<Title as="h3" textSize="4">, the same look at the level the example meant, in the
Storybook copy, the skill page's generated code and the docs live-preview copy.
Agents copy this example, so it should model the pattern that works.

The role line's <SubTitle size="6" as="p"> stays as it is, since as="p" wins.
@allxsmith

Copy link
Copy Markdown
Owner Author

deep-review: fresh

This fixes #1069. The bloomer, rbx and react-bulma-components codemods carried a title's size over as size. Because size picks the heading level, a migrated title changed its level. A shared keepTitleLevel helper now keeps size only where it renders the element the source library rendered. Anywhere else the size moves to textSize, and as is written only where it's needed. A dynamic size keeps size with a TODO. The ProfileCard skill example's title moves to as="h3" textSize="4" in its three copies.

Review it in full. Above all:

  • check each library's default title element against its source at the corpus-pinned SHA;
  • check every branch of keepTitleLevel (a <p>, a matching hN, a dynamic tag, a spread, a dynamic size, out-of-range literals);
  • check that the new title-levels e2e renders against the built library and asserts what each source rendered;
  • check the prop-map and guide wording;
  • check the is-size-N versus is-N class note.

Post every finding, advisory included, as its own thread.

@coderabbitai

coderabbitai Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

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 53 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: 712a7f2e-98a5-4b66-acc8-ce5ec80215d4
📥 Commits

Reviewing files that changed from the base of the PR and between 7e95f94 and 5a687a5.

📒 Files selected for processing: 43
  • bestax-mcp/data/skills.json
  • bestax-migrate/e2e/bloomer-kitchen-sink.test.ts
  • bestax-migrate/e2e/kitchen-sink.test.ts
  • bestax-migrate/e2e/rbx-kitchen-sink.test.ts
  • bestax-migrate/e2e/title-levels.test.ts
  • bestax-migrate/fixtures/bloomer-kitchen-sink/src/leftovers.tsx
  • bestax-migrate/fixtures/kitchen-sink/src/leftovers.tsx
  • bestax-migrate/fixtures/rbx-kitchen-sink/src/leftovers.tsx
  • bestax-migrate/src/sources/_shared/specials-utils.ts
  • bestax-migrate/src/sources/bloomer/__testfixtures__/imports-basic.output.tsx
  • bestax-migrate/src/sources/bloomer/__testfixtures__/title-levels.input.tsx
  • bestax-migrate/src/sources/bloomer/__testfixtures__/title-levels.output.tsx
  • bestax-migrate/src/sources/bloomer/__testfixtures__/todos-unmappable.output.tsx
  • bestax-migrate/src/sources/bloomer/__tests__/specials.test.ts
  • bestax-migrate/src/sources/bloomer/mapping.ts
  • bestax-migrate/src/sources/bloomer/specials.ts
  • bestax-migrate/src/sources/rbx/__testfixtures__/imports-basic.output.tsx
  • bestax-migrate/src/sources/rbx/__testfixtures__/title-levels.input.tsx
  • bestax-migrate/src/sources/rbx/__testfixtures__/title-levels.output.tsx
  • bestax-migrate/src/sources/rbx/__tests__/specials.test.ts
  • bestax-migrate/src/sources/rbx/specials.ts
  • bestax-migrate/src/sources/react-bulma-components/__testfixtures__/compounds.output.tsx
  • bestax-migrate/src/sources/react-bulma-components/__testfixtures__/heading-literals.output.tsx
  • bestax-migrate/src/sources/react-bulma-components/__testfixtures__/title-levels.input.tsx
  • bestax-migrate/src/sources/react-bulma-components/__testfixtures__/title-levels.output.tsx
  • bestax-migrate/src/sources/react-bulma-components/__tests__/transform.test.ts
  • bestax-migrate/src/sources/react-bulma-components/specials.ts
  • bulma-ui/src/skill-examples/ProfileCard.tsx
  • create-bestax/src/constants.ts
  • docs/docs/guides/getting-started/migration/bloomer.md
  • docs/docs/guides/getting-started/migration/rbx.md
  • docs/docs/guides/getting-started/migration/react-bulma-components.md
  • docs/docs/skills/custom-component.mdx
  • docs/src/components/SkillExamples/ProfileCard.jsx
  • skills/bestax-custom-component/SKILL.md
  • skills/bestax-layout-scaffold/SKILL.md
  • skills/bestax-migrate/references/bloomer/prop-map.md
  • skills/bestax-migrate/references/bloomer/unmappables.md
  • skills/bestax-migrate/references/rbx/prop-map.md
  • skills/bestax-migrate/references/rbx/unmappables.md
  • skills/bestax-migrate/references/react-bulma-components/component-map.md
  • skills/bestax-migrate/references/react-bulma-components/prop-map.md
  • skills/bestax-migrate/references/react-bulma-components/unmappables.md

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: allxsmith/bestax/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: f284a499-4e79-4d1a-a067-449a47918ed2
📥 Commits

Reviewing files that changed from the base of the PR and between 795e233 and 7e95f94.

📒 Files selected for processing: 3
  • bestax-mcp/data/skills.json
  • skills/bestax-layout-scaffold/SKILL.md
  • skills/bestax-migrate/references/react-bulma-components/unmappables.md
🚧 Files skipped from review as they are similar to previous changes: 1
  • skills/bestax-migrate/references/react-bulma-components/unmappables.md

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

Walkthrough

Title migrations for Bloomer, rbx, and react-bulma-components use shared logic to preserve rendered heading levels while translating size props. Tests, fixtures, examples, and migration references cover the updated mappings and TODO cases.

Changes

Title level migration

Layer / File(s) Summary
Shared title-size transformation
bestax-migrate/src/sources/_shared/specials-utils.ts
A shared helper preserves rendered title levels, translates supported size props to textSize, and reports TODOs for values it cannot safely carry over.
Source transform integrations
bestax-migrate/src/sources/{bloomer,rbx,react-bulma-components}/specials.ts, bestax-migrate/src/sources/bloomer/mapping.ts
The three source handlers call the helper with their source props and default heading levels. Bloomer maps Title to its special transform.
Source-specific fixtures and regression tests
bestax-migrate/src/sources/{bloomer,rbx,react-bulma-components}/__testfixtures__/*, bestax-migrate/src/sources/{bloomer,rbx,react-bulma-components}/__tests__/*
Fixtures and tests cover size conversion, rendered heading levels, dynamic sizes, spreads, and TODO cases.
Rendered-level validation
bestax-migrate/e2e/title-levels.test.ts, bestax-migrate/e2e/{bloomer-kitchen-sink,kitchen-sink,rbx-kitchen-sink}.test.ts, bestax-migrate/fixtures/*/src/leftovers.tsx
End-to-end tests render transformed title examples and compare opening tags. Kitchen-sink cases check TODOs for dynamic sizes.
Migration guidance and examples
skills/bestax-migrate/references/{bloomer,rbx,react-bulma-components}/*, docs/docs/guides/getting-started/migration/*, skills/*, bulma-ui/src/skill-examples/ProfileCard.tsx, docs/src/components/SkillExamples/ProfileCard.jsx, docs/docs/skills/custom-component.mdx, create-bestax/src/constants.ts, bestax-mcp/data/skills.json
Migration references and guides describe size mappings and TODO cases. Title examples use textSize for visual size, and skills data records updated reference sizes.

Priority: ➖ Normal

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

Change: Bug fix · Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant BloomerSpecials
  participant RbxSpecials
  participant ReactBulmaComponentsSpecials
  participant keepTitleLevel
  BloomerSpecials->>keepTitleLevel: Pass title size, tag, and default level
  RbxSpecials->>keepTitleLevel: Pass title size, as, and default level
  ReactBulmaComponentsSpecials->>keepTitleLevel: Pass Heading size, renderAs, and default level
  keepTitleLevel-->>BloomerSpecials: Return transformed props and TODO rules
  keepTitleLevel-->>RbxSpecials: Return transformed props and TODO rules
  keepTitleLevel-->>ReactBulmaComponentsSpecials: Return transformed props and TODO rules
Loading

Suggested reviewers: bestaxbot

Merge Risk: ⚪ Minimal · up to 7e95f

The migration guidance matches the component behavior and calls out the CSS override difference. MCP skill references are refreshed from the updated source files before build, so no actionable merge risk remains.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 29 files. (3 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Linked Issues check Passed Issue #1069 requires heading-level preservation, a rendered-tag fixture, bloomer prop-map guidance, and corrected ProfileCard examples. keepTitleLevel moves incompatible readable sizes to textSize…
Out of Scope Changes check Passed The rbx and react-bulma-components changes address the same heading-level migration defect through the shared keepTitleLevel helper. Their fixtures, tests, references, and guides support that behavi…
Title check Passed The title clearly and concisely describes the main change: preserving a title's heading level when its size is migrated.
Description check Passed The description is detailed and covers the affected codemod packages, implementation, tests, documentation, related issue, release impact, and additional context. It does not use the template headings…
Full details: Linked Issues check

Explanation

Issue #1069 requires heading-level preservation, a rendered-tag fixture, bloomer prop-map guidance, and corrected ProfileCard examples. keepTitleLevel moves incompatible readable sizes to textSize and preserves as or the source default. The bloomer fixture and title-levels.test.ts compare rendered opening tags. The bloomer prop map and unmappables guidance describe the rule. All ProfileCard copies use as="h3" textSize="4". The changes do not modify components.

Full details: Out of Scope Changes check

Explanation

The rbx and react-bulma-components changes address the same heading-level migration defect through the shared keepTitleLevel helper. Their fixtures, tests, references, and guides support that behavior. The skill guidance and ProfileCard updates implement the linked issue. No unrelated runtime component changes are shown.

Full details: Description check

Explanation

The description is detailed and covers the affected codemod packages, implementation, tests, documentation, related issue, release impact, and additional context. It does not use the template headings or explicitly report completed checklist results, but the required information is mostly present.

Full details: Docstring Coverage

Explanation

Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 29 files. (3 skipped: 3 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · 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

Copy link
Copy Markdown
Contributor

Preview Deployment

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

Comment thread bestax-migrate/src/sources/_shared/specials-utils.ts
Comment thread bestax-migrate/src/sources/_shared/specials-utils.ts Outdated
Comment thread bestax-migrate/src/sources/_shared/specials-utils.ts
Comment thread bulma-ui/src/skill-examples/ProfileCard.tsx
Comment thread docs/docs/guides/getting-started/migration/rbx.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 · 5 advisory

# Severity Area Finding Location
1 🔵 Advisory Correctness textSize renders .is-size-N with !important, so the migrated title now beats app CSS that overrides the unqualified .title — a caveat the .title.is-4 note does not cover bestax-migrate/src/sources/_shared/specials-utils.ts:435
2 🔵 Advisory Correctness The spread is treated as possibly carrying the tag when deciding the size, but not when appending as — the two halves of the helper disagree bestax-migrate/src/sources/_shared/specials-utils.ts:455
3 🔵 Advisory Robustness A literal size of 7 matches no branch: it lands on bestax's size, which drops it, so the class is lost silently (pre-existing, now pinned by a test) bestax-migrate/src/sources/_shared/specials-utils.ts:367
4 🔵 Advisory API Two shipped skills still tell agents "for headings use Title/SubTitle size", the step that produced #1069's <h4> bulma-ui/src/skill-examples/ProfileCard.tsx:53
5 🔵 Advisory Correctness The rbx and RBC migration guides scope the rule to the library's default <h1>, but it also fires when as/renderAs named another element docs/docs/guides/getting-started/migration/rbx.md:58

Overall: The change is sound and unusually well pinned. keepTitleLevel gets every branch I could reason through right — a <p> and a size that already names the rendered heading keep size; everything readable moves to textSize; a dynamic size or a textSize collision keeps size and files one TODO each — and the three fixture pairs plus e2e/title-levels.test.ts assert the rendered opening tag against the built library rather than text, which is precisely the check whose absence let the bug ship. All 2389 bestax-migrate tests pass, specials-utils.ts is at 100% lines / 93.5% branches, check:conformance is clean and gen:mcp:check finds nothing stale; the "same Sass size" claim behind is-size-N checks out against Bulma's own stylesheet (both .title.is-N and .is-size-N read dv.$sizes). The riskiest part is not the logic but the oracle: the e2e's expected tags are hand-written claims about libraries this repo deliberately never installs, so nothing mechanical holds them to the pinned SHAs. A human should spot-check those three "what the source rendered" comment blocks, and finding 1, which is the one way a migrated app can still look wrong after this fix.

Residual risk:

  • The e2e's expected tags are unverified assertions. This session had no network access, so I could not read AlgusDark/bloomer@b9af827, dfee/rbx@f2a55cf or couds/react-bulma-components@3fc281a as the brief asked. What I could check: every expectation is internally consistent with claims this repo already made and shipped (bloomer's Subtitle default h2 was the pre-existing special's whole reason for existing; Heading to Title with an h1 default is pinned by the existing heading-literals and compounds fixtures; rbx's subtitle class replacing title rather than joining it matches heading-literals.output.tsx's heading subtitle paragraph). Open — the comparison against the three sources at their pinned SHAs still needs a human or a networked run.
  • The fourth source was already immune. bulma-classes converts raw markup, and its title/subtitle entries carry sizeDrivesTag: true with tagIn restricted to the matching hN and p (src/sources/bulma-classes/class-map.ts:1544,1633), so a title is-4 sitting on an <h2> never becomes size="4". Refuted.
  • No second path reaches Title/SubTitle. Across all three mapping tables, target: 'Title' / 'SubTitle' appears only on bloomer's Title/Subtitle, rbx's Title and RBC's Heading — each of which now routes through keepTitleLevel. Refuted.
  • The repo-wide sweep holds. Every remaining Title/SubTitle that sets both as="hN" and size is deliberate: the two precedence tests in Title.test.tsx/SubTitle.test.tsx, plus codemod fixtures and doc tables where the two agree. The rest of the library's examples use as="p", which size never overrides. Refuted.
  • textSize survives on both components. TitleProps/SubTitleProps extend BulmaClassesProps, validTextSizes is '1' through '7', and the class is emitted through createBulmaClassHelpers, so a configured class prefix reaches it the same way it reaches is-4. Refuted.
  • One branch is unreachable per source, by design. bloomer has no textSize source prop, so its collision branch cannot fire — and bloomer's unmappables.md correctly omits the collision recipe that rbx's and RBC's include (RBC does have a universal textSize, mapping.ts:44). Refuted.
  • Not a residual risk, for the record: the RBC heading-truthy path drops size onto the plain paragraph it builds, but a <p> carries no heading level and Bulma v1 ships no .heading styles, so it falls outside this failure class.

🏄 Paddled out expecting a gnarly close-out and found clean glassy water instead — one shared helper doing the work of three, fixtures that actually render instead of squinting at strings, and docs that mostly tell the truth. Five little advisory ripples, nothing that'll pitch you off the board. Send it.

…ame way for as

A literal size of 7 fell through keepTitleLevel to a plain size={7}. Bulma styles title.is-7,
but bestax's size stops at 6, so that was a type error that rendered no size class at all.
textSize takes '7', so a 7 now moves there, including beside a <p>, where size={7} would
also have lost its class. Any other literal outside 1 to 7 gets the TODO a dynamic size
gets, instead of a quiet rename.

The helper also read a spread two ways. For the size it made the element unknown, but it
still appended Subtitle's as="h2" after the spread, so the two halves disagreed. A spread
can only name the element where the source spells its tag prop as, which is rbx. bloomer's
tag and RBC's renderAs inside a spread never reach bestax's as, so for those two the spread
no longer hides the element, and as is only written where the element is known.

The fixtures and the title-levels e2e gain size-7 cases, and the prop maps and unmappables
say where a 7 and an out-of-range literal go.
…s plus textSize

Bulma's is-size-N helper is !important and title.is-N is not, so a font size an app's own
CSS gives a migrated title, such as .hero .title, can now lose where it used to win. The
three migrate prop maps say so next to the class-name note.

The custom-component and layout-scaffold skills' inline-style table told agents to size a
heading with Title/SubTitle size, the step that produced #1069's h4. The row now says as
sets the level and size picks it too, so an h3 at size 4 is as="h3" textSize="4".

The rbx and RBC migration guides named only the default h1 where the size moves to
textSize. They now say the element the library rendered, which covers an as or renderAs.
…as plus textSize

The CLAUDE.md create-bestax writes into a new app carries the same inline-style table as
the custom-component and layout-scaffold skills, with the row that told agents to size a
heading with Title/SubTitle size. It now says what the skills say: as sets the level and
size picks it too, so an h3 at size 4 is as="h3" textSize="4".
@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 795e233.

@github-actions

Copy link
Copy Markdown
Contributor

Preview Deployment

Preview URL: https://4a2d5943.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) — 5 resolved · 0 open

No Severity Area Finding Location
1 🔵 Advisory Correctness textSize swaps a non-!important size for an !important one — the caveat is now stated in all three prop maps skills/bestax-migrate/references/bloomer/prop-map.md:102
2 🔵 Advisory Correctness Spread respected for the size but not for as — both halves now gate on rendered bestax-migrate/src/sources/_shared/specials-utils.ts:418
3 🔵 Advisory Robustness A literal size of 7 lost its class — it now moves to textSize, and 8 or more gets a TODO bestax-migrate/src/sources/_shared/specials-utils.ts:369
4 🔵 Advisory API The skill fontSize row still steered agents at size — it now names as plus textSize skills/bestax-custom-component/SKILL.md:177
5 🔵 Advisory Correctness The migration guides named only the default element — now "the element rbx/RBC rendered" docs/docs/guides/getting-started/migration/rbx.md:59

Overall: This pass settled threads and reviewed no commits. All five of my open threads — every one 🔵 Advisory — are verified fixed against the current code and resolved; nothing is left open, and no new findings were raised. The two code fixes are the substantive ones: TEXT_SIZES now carries the seventh Bulma size, so a size of 7 moves to textSize="7" instead of being renamed into a class-less size; a literal outside 1 to 7 reaches the TODO branch rather than a silent rename; and a spread hides the element only for rbx, the one source whose tag prop is spelled as, so the size decision and the as write read the same unknown.

Residual risk: this pass raises none — it settles threads rather than re-reviewing. For the record, what I checked while verifying:

  • Size-7 path — refuted as still broken: movable tests TEXT_SIZES while takes tests TITLE_SIZES, so 7 moves even beside as="p"; e2e/title-levels.test.ts:43,44,68,91 asserts the rendered title is-7 survives on an h1 and on a p across all three sources.
  • Out-of-range literal — refuted: bloomer/__tests__/specials.test.ts:920-926 pins a size of 8 to a prop:isSize TODO, replacing the earlier test that asserted silence.
  • Spread vs as disagreement — refuted: specials-utils.ts:418 and :462 both gate on rendered; rbx is unaffected, its level being h1.
  • Generated artefacts — refuted as stale: gen:mcp:check, gen:catalog:check and check:conformance all pass on the head commit.
  • Test evidence — bestax-migrate: 57 suites, 2394 tests, all green, after building bulma-ui/dist, which the e2e typecheck needs.
  • Cascade caveat — .is-size-N being !important is a real behavioural difference no code here removes; it is documented in all three prop maps and accepted deliberately, with the reason recorded on the thread.

🏄 Clean set, dude — every wave I called out got ridden all the way in, two of them with real code and tests behind them, not just hand-waving. Threads are closed out and the suite is glassy. Good to go.

@allxsmith allxsmith added the needs-human-review Loop converged (or contested): awaiting owner review + manual merge label Oct 15, 2026
@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 7e95f94.

@github-actions

Copy link
Copy Markdown
Contributor

Preview Deployment

Preview URL: https://77bddd5e.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 five of my inline threads were already resolved by the preceding verify pass; this pass found nothing open and raised nothing new.

# Severity Area Finding Location
— — — No open threads; nothing resolved this pass. —
Re-check of the five already-settled threads against 7e95f94e

The branch has since merged main twice (795e2338, 2871c2a3) and regenerated (7e95f94e), so I re-confirmed each fix survived the merges rather than taking the earlier verification on trust:

Thread Fix still present at HEAD
textSize swaps a non-!important size for an !important one the caveat is in all three prop maps — bloomer/prop-map.md:101, rbx/prop-map.md:139, react-bulma-components/prop-map.md:67
Spread respected for the size but not for as specials-utils.ts:421 — the else if now also requires that the source not spell its tag prop as
A literal size of 7 falls through every branch specials-utils.ts:370 adds TEXT_SIZES; movable tests it (:434) while takes keeps testing TITLE_SIZES (:438)
Skill still sends agents to size for headings bestax-custom-component/SKILL.md:177, bestax-layout-scaffold/SKILL.md:194, create-bestax/src/constants.ts:143
Guide line names only the default element rbx.md:59 and react-bulma-components.md:49 now say the size moves wherever bestax size would change the element the source rendered

Test run: pnpm --filter bestax-migrate run test — 57 suites, 2394 tests passed. (The first run failed 17 suites on TS2307: Cannot find module @allxsmith/bestax-bulma; that is the documented missing-bulma-ui/dist condition, not a defect — building bulma-ui first made it green.)

Overall: This pass settled threads and reviewed no commits. Nothing was left open for it to settle — every finding from the original review had already been fixed and verified, and I re-confirmed all five fixes are still in the tree at 7e95f94e after the two main merges, with the full bestax-migrate suite green. A reader who wants the commits pushed since the original review read needs a fresh review: a deep-review: steer whose first word is fresh, then the label re-applied.

Residual risk: none identified — a verify pass reads no new code, so it introduces no residual risk of its own; the residual-risk analysis for the change itself stands as written in the original review.

🏄 Nothing but glassy water out here, dude — every wave already ridden, paddled back out, and the board is still waxed after two merges with main. Zero open threads, 2394 tests clean. This one is good to go.

@allxsmith

Copy link
Copy Markdown
Owner Author

deep-review: fresh

Main is merged in, bringing the refreshed create-bestax visual baselines, so the Visual Regression checks this PR touches are green again. The PR's own changes are the ones the last verify pass settled: the codemod's keepTitleLevel, the size-7 and spread rules, and the skill and guide wording. Review 7e95f94 in full and post every finding, advisory included, as its own thread.

Comment thread bestax-migrate/src/sources/_shared/specials-utils.ts Outdated
Comment thread skills/bestax-migrate/references/rbx/prop-map.md Outdated
Comment thread bestax-migrate/src/sources/_shared/specials-utils.ts Outdated

@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 — 1 blocking · 2 advisory

# Severity Area Finding Location
1 🟡 Minor Correctness The prop:size TODO claims bestax renders "the heading its size names" for a literal outside 1 to 7, where bestax instead drops the size class and keeps as / h1 — and names textSize as the destination for a value it cannot take bestax-migrate/src/sources/_shared/specials-utils.ts:455
2 🔵 Advisory Correctness The rbx and RBC prop-map and unmappables say an unreadable size is always flagged; beside as="p" / renderAs="p" it is kept with no TODO (the bloomer unmappables states that exemption, the bloomer prop-map does not) skills/bestax-migrate/references/rbx/prop-map.md:141
3 🔵 Advisory Coverage The boolean-literal guard is the only new branch nothing reaches (93.03% branch, line 447 uncovered); a bare isSize gets neither a move nor a TODO and lands as a boolean size bestax-migrate/src/sources/_shared/specials-utils.ts:447

Overall: The change is sound, and the design is the right one: keepTitleLevel keeps size only where it renders the element the source did (a <p>, or the heading the size names) and moves it to textSize everywhere else, with all three sources sharing one helper rather than three near-copies — exactly what bestax-migrate/CLAUDE.md asks for after #613. The strongest part is e2e/title-levels.test.ts: it renders the migrated output against the built library and compares opening tags including the class list, which is the check the text-only fixtures could never make, and it is what makes the claimed per-branch coverage believable rather than merely asserted. The riskiest surface is not the transform but the prose it generates and ships — the TODO message in finding 1 and the reference wording in finding 2 are both claims about bestax that no test reads, which is how the four false TODOs on #613 got out. Read those two first; everything else here verified green.

Residual risk:

  • The same failure class in bulma-classes, the fourth source, untouched by this diff — refuted: class-map.ts:1544-1559 already gates every is-N to size write behind a tagIn of the matching heading or p, and plan.ts:1100 skips a modifier whose tagIn excludes the tag being converted, so a title is-4 on an h2 never converts into a size that would re-level it.
  • A spread that smuggles in the element prop — refuted for the element the codemod writes: for rbx and RBC, keepTitleLevel leaves the element unknown beside a spread and moves the size conservatively (specials-utils.ts:421), and for bloomer a tag or renderAs inside a spread never becomes the bestax as, so the element is the one the written props decide. Unit tests cover both halves.
  • A textSize already on the element — refuted: the move is guarded by movable && !textSize, so no element can emit the prop twice; a collision takes the TODO path instead (rbx/__tests__/specials.test.ts, "flags a size it cannot move").
  • The as that enforcePolymorphicProps later drops — open, and unchanged in kind by this PR: an as="span" beside a size now renders h1 where it used to render the heading the size named. rbx rendered a <span>, so neither is right, and the existing prop:as TODO names the tag to restore.
  • Helper-class specificity — on the record already (resolved thread): textSize writes the Bulma helper, which is !important, where the title size class is not, so an app rule such as .hero .title can now lose where it used to win. The e2e reads the helper class as the title class, so by construction it cannot see this; the three prop maps say it in prose.
  • Release scoping — refuted: ProfileCard has no runtime code in the published tarball (absent from dist/index.cjs and dist/index.esm.js; only dist/types/skill-examples/ProfileCard.d.ts, which a JSX body cannot change), so the docs(bulma-ui) plus fix(bestax-migrate) split the PR body describes is right.

What I ran: turbo test --filter=bestax-migrate (57 suites / 2394 tests, including the new e2e/title-levels.test.ts), the same for @allxsmith/bestax-bulma and create-bestax (191 / 7934) and for bestax-mcp, plus check:conformance, test:scripts (green once eslint-plugin/dist was built; every measured file at or above its floor) and test:coverage --filter=bestax-migrate. The six reference byte counts in bestax-mcp/data/skills.json match the files on disk.

🏄 Clean little set wave, dude — the codemod finally quit turning the top-of-page heading into a deeper one behind your back, and that new render-the-real-tag e2e is the honest paddle-out that proves it. Just two bits of beach graffiti to touch up in the TODO text and the rbx/RBC reference sheets, and this one is good to go.

…lag a bare one

keepTitleLevel gave a literal outside 1 to 7 the TODO a dynamic size gets, which says the
heading follows the size. bestax's Title ignores a size outside 1 to 6: it renders no size
class and keeps its element, so the level was never at risk. That literal now gets its own
TODO, saying the class goes and to drop the size or set a textSize from '1' to '7'.

A bare isSize, or any other boolean size, was the one shape that got neither a move nor a
TODO, so it became size={true}, which does not typecheck. It now counts as a literal bestax's
size does not take and gets the same TODO, beside a <p> too. A unit test pins it.

The references stop promising a TODO for every size the codemod cannot read: beside a <p>
an unreadable size is left alone. The prop maps now name only the out-of-range literal,
and each unmappables recipe says what to do with one.
@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 5a687a5.

@github-actions

Copy link
Copy Markdown
Contributor

Preview Deployment

Preview URL: https://c748fefa.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) — 3 resolved · 0 open

# Severity Area Thread Location Outcome
1 🟡 Minor Correctness TODO claimed a size-driven heading for a size bestax ignores bestax-migrate/src/sources/_shared/specials-utils.ts:457 ✅ Verified fixed
2 🔵 Advisory Correctness rbx and RBC references promised a TODO a <p> never gets skills/bestax-migrate/references/rbx/prop-map.md:141 ✅ Verified fixed
3 🔵 Advisory Coverage Boolean-size guard reached by no test bestax-migrate/src/sources/_shared/specials-utils.ts:452 ✅ Verified fixed

What I checked

  • #1 — the TODO branch now tests !takes first, so an out-of-range literal gets its own message, which names the dropped size class and no heading. It matches the component: validTitleSizes and validSubTitleSizes are "1"–"6", so validSize is undefined and no is-* class renders. bloomer/__tests__/specials.test.ts:927-928 pins the message both ways — it contains "renders no size class" and does not contain "heading".
  • #2 — the unreadable-size clause is deleted from all three prop maps; the surviving sentence ("A literal outside 1 to 7 keeps size and gets a TODO") holds unconditionally, since an out-of-range literal makes takes false and so cannot reach the <p> short-circuit. The rbx and RBC unmappables.md dropped "and is flagged", and bloomer keeps its explicit exemption line at unmappables.md:292.
  • #3 — the literal.kind !== "boolean" guard is gone and the last arm is a plain else, so <Title isSize> now gets the out-of-range TODO instead of a silent size={true}, beside tag="p" too. That line no longer appears among the uncovered branches of specials-utils.ts (100 | 93.67 | 100 | 100).

Overall: this pass settled threads and reviewed no commits. All three previously open threads are fixed in the current code, each confirmed by reading the changed logic against Title.tsx and SubTitle.tsx and by a full green run of the bestax-migrate suite with coverage — 57 suites, 2395 tests. Nothing was refuted and nothing is left open.

Residual risk: not assessed — a verify pass settles the prior review findings and raises none. For a review of the commits pushed since, post a deep-review: fresh … steer and re-apply the label.

🏄 Paddled back out to check the three waves I called out last time, and they are all clean rides now — the TODO says what it means, the skill docs stopped over-promising, and that sneaky bare isSize got flagged instead of slipping through. Smooth water, good to go.

@github-actions github-actions Bot added the review-converged Deep review converged: no blocking findings, all review threads resolved, checks green label Oct 16, 2026
@allxsmith
allxsmith merged commit 7549699 into main Oct 16, 2026
76 checks passed
@allxsmith
allxsmith deleted the fix/1069-title-levels branch October 16, 2026 23:12
bestax-release-bot Bot pushed a commit that referenced this pull request Oct 16, 2026
## [5.34.1](https://github.com/allxsmith/bestax/compare/@allxsmith/bestax-bulma@5.34.0...@allxsmith/bestax-bulma@5.34.1) (2026-10-16)

### Bug Fixes

* **bestax-migrate:** keep a title's heading level when its size carries over ([#1071](#1071)) ([7549699](7549699))
* **bulma-ui:** wire Taginput's suggestions as a combobox ([#1084](#1084)) ([e30c33a](e30c33a)), closes [#942](#942) [#998](#998) [#1082](#1082)
* **docs:** pin react-scripts in CodeSandbox sandboxes and keep the sandbox notes in step ([#1074](#1074)) ([3ac8a65](3ac8a65))

### Features

* **docs:** open live examples in StackBlitz and CodeSandbox ([#1073](#1073)) ([730db1e](730db1e))
@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 5.34.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

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

### Bug Fixes

* **bestax-mcp:** leave the query behind when a component's own rows answered it ([ec8a2f1](ec8a2f1))
* **bestax-mcp:** say "matching" in the pointer answer only when there is a query ([2d28530](2d28530))
* **bestax-mcp:** say Button's variables style it for the colors and modifiers it accepts ([2b94042](2b94042))
* **bestax-migrate:** keep a title's heading level when its size carries over ([#1071](#1071)) ([7549699](7549699))
* **bulma-ui:** announce Autocomplete's empty content, and keep its listbox to options ([98cfaac](98cfaac)), closes [#1066](#1066)
* **bulma-ui:** describe a Tooltip's trigger with its text for screen readers ([5a7eb99](5a7eb99)), closes [#1031](#1031)
* **bulma-ui:** drop a key's fill in forced colors, so only its border draws it ([466ad38](466ad38)), closes [#1063](#1063)
* **bulma-ui:** hide a Tooltip with its stylesheet alone, without aria-hidden ([d4cbee4](d4cbee4))
* **bulma-ui:** hold Autocomplete's empty announcement while results load ([75d8fdf](75d8fdf))
* **bulma-ui:** keep a loading ToggleButton from toggling ([cf9f6e8](cf9f6e8))
* **bulma-ui:** keep EmptyState's left room only for an indicator, and follow py ([9a615d6](9a615d6)), closes [#1065](#1065)
* **bulma-ui:** keep SegmentedControl's fallback tab stop on the first segment after a reorder ([b32df32](b32df32))
* **bulma-ui:** key each key in Kbd.Group by its own React key ([b51c5c8](b51c5c8)), closes [#1063](#1063)
* **bulma-ui:** leave the keys alone on a SegmentedControl segment outside its row ([f477666](f477666))
* **bulma-ui:** mark a loading ToggleButton aria-disabled as well as aria-busy ([f87425f](f87425f))
* **bulma-ui:** open Fragments in Kbd.Group before placing its separators ([c595de2](c595de2)), closes [#1063](#1063)
* **bulma-ui:** stop the keys a SegmentedControl takes from reaching listeners above it ([6b9e797](6b9e797))
* **bulma-ui:** warn when Tab can't reach a Tooltip trigger that carries the link ([cfd21c7](cfd21c7))
* **bulma-ui:** wire Taginput's suggestions as a combobox ([#1084](#1084)) ([e30c33a](e30c33a)), closes [#942](#942) [#998](#998) [#1082](#1082)
* **docs:** address the deep review of the sandbox builders ([b7338d9](b7338d9))
* **docs:** close the CodeSandbox tab when its launch fails ([d1e6d1d](d1e6d1d))
* **docs:** compare the icon link as a string in the sandbox test ([9ac4737](9ac4737))
* **docs:** darken the live preview surface and follow the library stylesheet import ([363badf](363badf))
* **docs:** draw the CodeSandbox button icon as the cube mark ([8389e18](8389e18))
* **docs:** give both sandboxes the example window's dark page and padding ([33dfb4a](33dfb4a))
* **docs:** keep the live preview's spacing outside its dark surface ([7a158e1](7a158e1))
* **docs:** keep the live-preview margin off the homepage previews ([f18eed3](f18eed3))
* **docs:** load the CodeSandbox stylesheet from the CDN and darken example windows ([253f057](253f057))
* **docs:** match the preview's color scheme and keep the copy button on narrow screens ([c4d6d25](c4d6d25))
* **docs:** open CodeSandbox through its JSON define API ([6a65276](6a65276))
* **docs:** open the CodeSandbox tab on the click, and skip the sandbox when popups are blocked ([bcc0634](bcc0634))
* **docs:** pin react-scripts in CodeSandbox sandboxes and keep the sandbox notes in step ([#1074](#1074)) ([3ac8a65](3ac8a65))
* **docs:** restore the homepage preview margin, and reject a CodeSandbox reply without an id ([9e0991f](9e0991f))
* **docs:** send the copy and sandbox buttons the code the reader typed ([019edf0](019edf0))

### Features

* **bestax-mcp:** name the other component's call in get_component's theming hint ([cbedd5f](cbedd5f))
* **bestax-mcp:** point get_css_variables at the component whose element a component renders ([d4be1a8](d4be1a8))
* **bulma-ui:** add Buttons.ToggleButton ([0c8fb10](0c8fb10))
* **bulma-ui:** add EmptyState, the block a list shows when it has nothing in it ([c5929d2](c5929d2)), closes [#1065](#1065)
* **bulma-ui:** add Kbd, a key drawn as a keycap, and Kbd.Group for combinations ([98d1578](98d1578)), closes [#1063](#1063)
* **bulma-ui:** add SegmentedControl, a row of buttons where only one can be on ([b1be0e8](b1be0e8)), closes [#1040](#1040)
* **bulma-ui:** give Dropdown typeahead ([1bb35bf](1bb35bf)), closes [#1035](#1035)
* **docs:** open live examples in StackBlitz and CodeSandbox ([654b16c](654b16c))
* **docs:** open live examples in StackBlitz and CodeSandbox ([#1073](#1073)) ([730db1e](730db1e))
@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 2.25.4 🎉

The release is available on:

Your semantic-release bot 📦🚀

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

### Bug Fixes

* **bestax-migrate:** keep a title's heading level when its size carries over ([#1071](#1071)) ([7549699](7549699))
* **bulma-ui:** wire Taginput's suggestions as a combobox ([#1084](#1084)) ([e30c33a](e30c33a)), closes [#942](#942) [#998](#998) [#1082](#1082)
* **docs:** pin react-scripts in CodeSandbox sandboxes and keep the sandbox notes in step ([#1074](#1074)) ([3ac8a65](3ac8a65))

### Features

* **docs:** open live examples in StackBlitz and CodeSandbox ([#1073](#1073)) ([730db1e](730db1e))
@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 1.15.4 🎉

The release is available on:

Your semantic-release bot 📦🚀

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

### Bug Fixes

* **bestax-mcp:** leave the query behind when a component's own rows answered it ([ec8a2f1](ec8a2f1))
* **bestax-mcp:** release with every bulma-ui release so the published index keeps up ([#1027](#1027)) ([618e483](618e483))
* **bestax-mcp:** say "matching" in the pointer answer only when there is a query ([2d28530](2d28530))
* **bestax-mcp:** say Button's variables style it for the colors and modifiers it accepts ([2b94042](2b94042))
* **bestax-migrate:** carry size to Buttons, Tags and Message ([#1038](#1038)) ([7549264](7549264))
* **bestax-migrate:** keep a title's heading level when its size carries over ([#1071](#1071)) ([7549699](7549699))
* **bulma-ui:** announce Autocomplete's empty content, and keep its listbox to options ([98cfaac](98cfaac)), closes [#1066](#1066)
* **bulma-ui:** deprecate Autocomplete's unread selected and dropdown props ([#1091](#1091)) ([5a90eba](5a90eba)), closes [#1080](#1080)
* **bulma-ui:** describe a Tooltip's trigger with its text for screen readers ([5a7eb99](5a7eb99)), closes [#1031](#1031)
* **bulma-ui:** drop a Field label's for when nothing it holds takes it ([#1020](#1020)) ([3604c14](3604c14))
* **bulma-ui:** drop a key's fill in forced colors, so only its border draws it ([466ad38](466ad38)), closes [#1063](#1063)
* **bulma-ui:** give TimeInput's AM/PM column a real name for screen readers ([2b1122f](2b1122f))
* **bulma-ui:** hide a Tooltip with its stylesheet alone, without aria-hidden ([d4cbee4](d4cbee4))
* **bulma-ui:** hold Autocomplete's empty announcement while results load ([75d8fdf](75d8fdf))
* **bulma-ui:** keep a loading ToggleButton from toggling ([cf9f6e8](cf9f6e8))
* **bulma-ui:** keep a Notification's text clear of its close button ([#1017](#1017)) ([91ebb63](91ebb63))
* **bulma-ui:** keep a picker label's default when its override is undefined ([aa88e50](aa88e50))
* **bulma-ui:** keep EmptyState's left room only for an indicator, and follow py ([9a615d6](9a615d6)), closes [#1065](#1065)
* **bulma-ui:** keep SegmentedControl's fallback tab stop on the first segment after a reorder ([b32df32](b32df32))
* **bulma-ui:** keep Theme's component-variable check out of production ([537d90d](537d90d))
* **bulma-ui:** key each key in Kbd.Group by its own React key ([b51c5c8](b51c5c8)), closes [#1063](#1063)
* **bulma-ui:** leave the keys alone on a SegmentedControl segment outside its row ([f477666](f477666))
* **bulma-ui:** let Autocomplete's Enter submit, keep focus on a click, and open on a highlight ([#1090](#1090)) ([81f5982](81f5982)), closes [#1078](#1078) [#1089](#1089) [#1079](#1079) [#1081](#1081) [#1081](#1081)
* **bulma-ui:** mark a loading ToggleButton aria-disabled as well as aria-busy ([f87425f](f87425f))
* **bulma-ui:** name a composed DateRangeInputBase's group from a Field label ([75aa6cb](75aa6cb))
* **bulma-ui:** name a range Slider's thumbs from a hand-wired Field label's id ([355065b](355065b))
* **bulma-ui:** name Autocomplete's list from a hand-wired Field label's id ([ad46c06](ad46c06))
* **bulma-ui:** name Autocomplete's suggestion list from a surrounding Field's label ([190183f](190183f)), closes [#998](#998)
* **bulma-ui:** one Escape closes one layer inside a Modal or Sidebar ([#1086](#1086)) ([3ea7ac8](3ea7ac8)), closes [#1077](#1077) [#1077](#1077)
* **bulma-ui:** open Fragments in Kbd.Group before placing its separators ([c595de2](c595de2)), closes [#1063](#1063)
* **bulma-ui:** say a label placed in Field.Label reaches no thumbs or list ([07c2a99](07c2a99))
* **bulma-ui:** say the label prop needs wiring to reach thumbs or list in an inner Field ([9b33d8d](9b33d8d))
* **bulma-ui:** say which controls a hand-wired Field label's id reaches ([514127f](514127f))
* **bulma-ui:** stop the keys a SegmentedControl takes from reaching listeners above it ([6b9e797](6b9e797))
* **bulma-ui:** warn when Tab can't reach a Tooltip trigger that carries the link ([cfd21c7](cfd21c7))
* **bulma-ui:** warn when Theme is given a variable Bulma sets on the component ([bb8f9b8](bb8f9b8)), closes [#1021](#1021)
* **bulma-ui:** wire Taginput's suggestions as a combobox ([#1084](#1084)) ([e30c33a](e30c33a)), closes [#942](#942) [#998](#998) [#1082](#1082)
* **create-bestax:** bring the vite-ts tsconfigs up to create-vite 9 ([#1076](#1076)) ([dc6995c](dc6995c)), closes [#1049](#1049)
* **docs:** address the deep review of the sandbox builders ([b7338d9](b7338d9))
* **docs:** close the CodeSandbox tab when its launch fails ([d1e6d1d](d1e6d1d))
* **docs:** compare the icon link as a string in the sandbox test ([9ac4737](9ac4737))
* **docs:** darken the live preview surface and follow the library stylesheet import ([363badf](363badf))
* **docs:** draw the CodeSandbox button icon as the cube mark ([8389e18](8389e18))
* **docs:** give both sandboxes the example window's dark page and padding ([33dfb4a](33dfb4a))
* **docs:** give the mixin note the modifier caveat its lead carries ([1427f08](1427f08))
* **docs:** keep the live preview's spacing outside its dark surface ([7a158e1](7a158e1))
* **docs:** keep the live-preview margin off the homepage previews ([f18eed3](f18eed3))
* **docs:** keep the modifier caveat for mixin variables in the MCP index ([e227663](e227663))
* **docs:** load the CodeSandbox stylesheet from the CDN and darken example windows ([253f057](253f057))
* **docs:** match the preview's color scheme and keep the copy button on narrow screens ([c4d6d25](c4d6d25))
* **docs:** name the one edge of the rule for which variables Theme reaches ([b33ebfa](b33ebfa))
* **docs:** open CodeSandbox through its JSON define API ([6a65276](6a65276))
* **docs:** open the CodeSandbox tab on the click, and skip the sandbox when popups are blocked ([bcc0634](bcc0634))
* **docs:** pin react-scripts in CodeSandbox sandboxes and keep the sandbox notes in step ([#1074](#1074)) ([3ac8a65](3ac8a65))
* **docs:** qualify the guide and the theming skill on what Theme reaches ([9c2347b](9c2347b))
* **docs:** read only a component's own mixin as its home ([f40cd2c](f40cd2c))
* **docs:** refuse a CSS-variable scope the page cannot fully word ([c815602](c815602))
* **docs:** restore the homepage preview margin, and reject a CodeSandbox reply without an id ([9e0991f](9e0991f))
* **docs:** say where component-scoped Bulma variables have to be set ([771d5bd](771d5bd)), closes [#1021](#1021)
* **docs:** send the copy and sandbox buttons the code the reader typed ([019edf0](019edf0))

### Features

* **bestax-mcp:** name the other component's call in get_component's theming hint ([cbedd5f](cbedd5f))
* **bestax-mcp:** point get_css_variables at the component whose element a component renders ([d4be1a8](d4be1a8))
* **bulma-ui:** add Buttons.ToggleButton ([0c8fb10](0c8fb10))
* **bulma-ui:** add ContextMenu, a menu that opens on right-click or long press ([#1036](#1036)) ([85a3e77](85a3e77))
* **bulma-ui:** add EmptyState, the block a list shows when it has nothing in it ([c5929d2](c5929d2)), closes [#1065](#1065)
* **bulma-ui:** add HoverCard, a card that opens on hover or keyboard focus ([#1030](#1030)) ([0eb41df](0eb41df))
* **bulma-ui:** add Kbd, a key drawn as a keycap, and Kbd.Group for combinations ([98d1578](98d1578)), closes [#1063](#1063)
* **bulma-ui:** add SegmentedControl, a row of buttons where only one can be on ([b1be0e8](b1be0e8)), closes [#1040](#1040)
* **bulma-ui:** add ToggleButton, a button that stays pressed ([#1041](#1041)) ([582aff0](582aff0))
* **bulma-ui:** give Dropdown typeahead ([1bb35bf](1bb35bf)), closes [#1035](#1035)
* **bulma-ui:** let a Tooltip be hovered, dismissed with Escape, and opened by a tap ([#1033](#1033)) ([52aeeda](52aeeda))
* **bulma-ui:** let ConfigProvider set where portaled content goes ([#1032](#1032)) ([5e928ae](5e928ae))
* **docs:** open live examples in StackBlitz and CodeSandbox ([654b16c](654b16c))
* **docs:** open live examples in StackBlitz and CodeSandbox ([#1073](#1073)) ([730db1e](730db1e))
@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 4.2.17 🎉

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.

Two callers set a Title level with as alongside size, and render the wrong heading

1 participant