Repository navigation
fix(bulma-ui): keep menuitemcheckbox and menuitemradio items in Dropdown's arrow-key order - #786
Conversation
…own's arrow-key order Dropdown found its navigable items by [role="menuitem"], so an item a caller gave menuitemcheckbox or menuitemradio (the right roles for a filter or sort menu) rendered but the arrow keys skipped it. The selector now takes all three menu-item roles, and the docs say so. Closes #714
|
deep-review: read-only: don't install, build or run tests; CI covers them on this head. Priorities:
|
|
Warning Review limit reachedNext included review available in 57 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Repository: allxsmith/bestax/.coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (4)
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. Comment |
Preview DeploymentPreview URL: https://82c859cd.bestax.pages.dev |
There was a problem hiding this comment.
Deep review — 0 blocking · 3 advisory
| No. | Severity | Area | Finding | Location |
|---|---|---|---|---|
| 1 | 🔵 Advisory | Accessibility | Reachable is not the same as operable: with the default as="a" (no href) a focused item is not activated by Enter/Space, because handleMenuKeyDown has no activation case — so the filter/sort pattern the docs now recommend needs as="button" to be usable from the keyboard |
bulma-ui/src/components/Dropdown.tsx:265 |
| 2 | 🔵 Advisory | Robustness | The selector matches the role attribute exactly, so a role token list (role="menuitemcheckbox menuitem", valid ARIA fallback syntax) or a non-lowercase spelling still drops the item silently — the same failure this PR fixes, in a rarer spelling |
bulma-ui/src/components/Dropdown.tsx:189 |
| 3 | 🔵 Advisory | API | closeOnClick defaults to true, so a menuitemcheckbox filter menu closes on the first toggle; a real multi-select filter menu needs closeOnClick=false |
bulma-ui/src/components/Dropdown.tsx:83 |
Overall: The change is sound and minimal, and it is the right one of the two shapes #714 offered — a three-role allowlist beats an unforgeable marker here, because it keeps an item deliberately given role="presentation" or role="none" out of the arrow-key order, which a marker would have forced back in. Every keyboard entry point routes through the single getMenuItems() at line 182: the pending-focus effect (line 204), ArrowDown/ArrowUp on the trigger (lines 224, 236), and ArrowDown/ArrowUp/Home/End inside the menu (line 281). The old selector appears nowhere else in the file except the default role set on the item itself at line 498, so no second selector is left behind. querySelectorAll with a comma-separated selector list returns document order, not selector-group order, so the widened selector cannot reorder a mixed menu; the checkbox → radio → default walk in the new test pins exactly that, and on main it fails at the very first assertion. Docs and the MCP index agree: gen-mcp-index.mjs:603 lifts the Accessibility section body of the page verbatim, the two strings match character for character, and neither gen:catalog nor gen:eslint-meta carries accessibility prose, so no other generated artefact is stale. A reviewer should look first at advisory 1 — this PR makes such an item reachable, but in the default anchor form it is still not keyboard-operable.
Residual risk:
- Other roles a caller might set are still skipped — refuted as a defect. The interactive children ARIA 1.2 permits inside a menu are exactly
menuitem,menuitemcheckboxandmenuitemradio(groupandseparatorbeing the non-interactive rest), so the allowlist is complete for anything valid in the menu, and skippingpresentation/none/optionis the correct outcome rather than a gap. - The root cause — a caller role winning over the default at line 498 — is untouched. Deliberate per the PR body, and defensible: the fix puts the allowlist in the consumer of the role instead of making the role unforgeable. The one narrow spelling gap that leaves is advisory 2, named rather than refuted.
- Adjacent components with the same failure class — refuted.
Dropdownis the only place inbulma-ui/srcthat keys navigation on a role attribute.Modal.tsx:49and_pickerInternals/useFocusTrap.ts:40both use the tag and tabindex basedFOCUSABLE_SELECTOR, andTimeWheels.tsx:966selects its own wheel elements, so none of them can be defeated by a caller-supplied role. - The widened selector capturing something it should not — refuted for markup the library emits: only
Dropdown.Itemsets any of the three roles, and the pre-existing scope (the dropdown root, not the menu) is unchanged, so a nestedDropdownbehaves exactly as before. Hand-rolled markup carrying one of these roles now joins the list withouttabIndex, where.focus()is a no-op and an arrow key looks stuck — but that was already true for the plain menuitem role, so the diff widens the surface without introducing the shape. - Gates and staleness — checked statically, not run, per the read-only steer: the new selector adds no branches, so the 99 percent threshold is unaffected; the caller role and
aria-checked="true"both typecheck against the anchor prop type, andDropdownItemis already imported in the test file, sotypecheck:testsis clean. No story was added and none is required — CI checks only that a story exists, and no prop changed. No file underskills/mentions Dropdown keyboard behaviour, so there is nothing to sync there.
🏄 Six lines of selector, one honest test, docs and the MCP index paddling in sync — clean little set, no wipeout in sight. Only thing still out past the break is that you can glide over to a menuitemcheckbox and still not pop it with Enter unless you ride
as="button", and that wave was already rolling before this PR. Send it.
…ild one Reachable isn't operable yet: an anchor item can't be activated with Enter or Space (#787), so the page states the fact and leaves the filter-menu recommendation for that fix.
|
Thanks for the deep review. Where each advisory landed:
|
Preview DeploymentPreview URL: https://40e275b4.bestax.pages.dev |
|
deep-review: fresh Read-only: do not install, build or run tests; CI is green on this head. |
There was a problem hiding this comment.
Deep review — 0 blocking · 4 advisory
| No. | Severity | Area | Finding | Location |
|---|---|---|---|---|
| 1 | 🔵 Advisory | Accessibility | role="menuitem" is set before the forwarded-props spread, so a spread carrying a role key whose value is undefined erases it — React reads that as "remove the attribute". A caller writing role as a conditional that falls back to undefined renders an item with no role, which loses menu semantics and drops out of the arrow-key order. Same failure class as #714, in the one spelling the widened selector cannot reach; the type guard two lines below is the pattern that would close it |
bulma-ui/src/components/Dropdown.tsx:498 |
| 2 | 🔵 Advisory | Robustness | The selector matches the role value exactly, so an ARIA fallback token list — role="menuitemcheckbox menuitem", valid syntax — still drops the item silently |
bulma-ui/src/components/Dropdown.tsx:189 |
| 3 | 🔵 Advisory | Coverage | The new test asserts focus order only — it never asserts the caller roles reached the DOM. If role ever stopped forwarding, all three items would render role="menuitem" and the test would keep passing vacuously while the behaviour it guards was gone |
bulma-ui/src/components/__tests__/Dropdown.test.tsx:839 |
| 4 | 🔵 Advisory | API | closeOnClick defaults to true, so a menuitemcheckbox filter menu closes on the first toggle — a real multi-select filter menu has to pass closeOnClick as false |
bulma-ui/src/components/Dropdown.tsx:83 |
Overall: The change is sound, and it is the smaller of the two shapes #714 offered — correctly chosen: a three-role allowlist keeps an item deliberately given role="presentation" or role="none" out of the arrow-key order, which the alternative, an unforgeable internal marker, would have forced back in. Every keyboard entry point funnels through the single getMenuItems() at line 182 — the pending-focus effect at 204, ArrowDown/ArrowUp on the trigger at 224 and 236, and ArrowDown/ArrowUp/Home/End inside the menu at 281 — so one selector edit covers all of them, and querySelectorAll with a comma-separated list returns document order, not selector-group order, so a mixed menu cannot be reordered. The new test exercises the strongest path — open via the trigger, then three menu-level ArrowDowns including wrap-around — and does fail on main at its very first assertion, since getMenuItems() there returns only the default item. The riskiest thing left is advisory 1: the root cause #714 named, a caller role outranking the default, is untouched by design, and the undefined spelling of it is a live, silent a11y break that these docs make marginally easier to walk into.
Verification here was static, per the read-only steer: no install, build, or test run. CI is green on
8ff920f2.
Residual risk:
- A forwarded
rolekey holdingundefined— open, advisory 1. Line 498 sets the default before the spread at 500, so the spread wins and the attribute is removed. The comment at 501–521 documents exactly this hazard fortypeand places that default after the spread with a nullish fallback;rolehas the same shape and no such guard. #714 flagged the asymmetry in its own text. Not introduced or worsened by this diff, and deliberate per the PR body. - ARIA fallback role token lists — open, advisory 2. Rare, and a
~=selector would need all three tokens anyway, so it reads as a trade-off rather than an oversight. - Other roles a caller might set are still skipped — refuted. The interactive children ARIA 1.2 permits inside
role="menu"are exactlymenuitem,menuitemcheckboxandmenuitemradio;groupandseparatorare the non-interactive rest. The allowlist is therefore complete for anything valid in a menu, and excludingpresentation,noneandoptionis the correct outcome, not a gap. - Adjacent components with the same failure class — refuted.
menuitemappears inbulma-ui/srconly inDropdown.tsx.Modal.tsx:49and_pickerInternals/useFocusTrap.ts:40,50both use the tag-and-tabindexFOCUSABLE_SELECTOR,TimeWheels.tsx:966selects its own wheel elements, andNavbar.tsxruns noquerySelectorat all — its keyboard handling is a per-itemonKeyDownat 599. None can be defeated by a caller-supplied role. - The widened selector capturing something it should not — refuted. The scope is still the dropdown root, unchanged by this diff, so nested-dropdown behaviour is exactly as before; attribute matching is exact, so the menu own
role="menu"is not swept in; and onlyDropdown.Itememits any of the three roles in library markup. Hand-rolled markup carrying one of them joins the list withouttabIndex, but that was already true for plainmenuitem. - Stale generated artefacts — refuted. The accessibility prose lives in exactly two places:
docs/docs/api/components/dropdown.md:189and theaccessibilityfield ofbestax-mcp/data/components/Dropdown.json, whichgen-mcp-index.mjslifts verbatim from that section. The two strings are identical after8ff920f2. Neither the skill catalog noreslint-plugin/src/generated/contains accessibility prose at all — zero hits for the word — so nothing else is stale. No story is required: CI checks only that one exists, and no prop changed. - Release scoping of the
bestax-mcp/dataedit — refuted as a defect. Regenerating that index under afix(bulma-ui)or a baredocs:commit is established practice onmain— the whole Avatar role series did it — so this matches the repo rather than diverging from it. - Enter/Space activation of an anchor item — out of scope per the steer, tracked by #787. Worth keeping in view only because this PR makes such an item reachable without making it operable; the trimmed docs line no longer recommends the pattern, which defuses most of the trap.
🏄 Four lines of selector, one honest test that actually wipes out on
main, docs and the MCP index paddling in perfect sync — clean little set, totally good to send. Just know the break still has a rock under it: hand an item a conditionalrolethat falls back toundefinedand it vanishes from the lineup entirely, same as before. Not this wave to worry about, but do not paddle out over it blind.
…defined
Dropdown.Item set role="menuitem" before spreading forwarded props, so
role={undefined} arriving through a spread erased it and the item left
the menu and its arrow-key order. The default now reads through the
spread, the way type already does. The role test also asserts the
caller roles reach the DOM.
|
Thanks for the fresh review. Where each advisory landed:
|
|
deep-review: fresh Read-only: do not install, build or run tests; CI covers them on this head. |
Preview DeploymentPreview URL: https://b627b8cd.bestax.pages.dev |
There was a problem hiding this comment.
Deep review — 0 blocking · 5 advisory
| # | Severity | Area | Finding | Location |
|---|---|---|---|---|
| 1 | 🔵 Advisory | Robustness | tabIndex={0} is still set before the spread — the same erasure this commit fixes for role, one line above it. A spread carrying tabIndex: undefined removes it; the item now keeps role="menuitem" unconditionally, so it stays in getMenuItems() while .focus() no-ops on a hrefless <a>, and arrow navigation gets stuck on the previous item instead of skipping past |
bulma-ui/src/components/Dropdown.tsx:497 |
| 2 | 🔵 Advisory | Robustness | The selector still matches the role value exactly, so an ARIA fallback token list — role="menuitemcheckbox menuitem", valid syntax — drops the item silently. Carried from the previous pass; a ~= selector would need all three tokens anyway, so it reads as a trade-off |
bulma-ui/src/components/Dropdown.tsx:189 |
| 3 | 🔵 Advisory | API | Behaviour change worth knowing: role={undefined} no longer opts an item out of menu semantics. role="none" / role="presentation" is now the only way to keep a decorative Dropdown.Item out of the arrow-key order. Intended, and the right default — just undocumented |
bulma-ui/src/components/Dropdown.tsx:502 |
| 4 | 🔵 Advisory | Accessibility | Reachable is still not operable: in the default as="a" form a focused item is not activated by Enter/Space — tracked by #787, and the docs line was correctly trimmed in 8ff920f2 to stop recommending the pattern |
bulma-ui/src/components/Dropdown.tsx:265 |
| 5 | 🔵 Advisory | API | closeOnClick defaults to true, so a menuitemcheckbox filter menu closes on the first toggle unless the caller passes closeOnClick={false} |
bulma-ui/src/components/Dropdown.tsx:83 |
Overall: Sound, and 08fb375e closes the one live hole the previous pass left open. The role default now reads through the spread with ?? and lands after it, matching the type guard a dozen lines below in shape, so the only remaining way to lose a role is to pass a real value — and the widened three-role selector then keeps the two ARIA-valid alternatives in the arrow-key order. The coverage gap is closed too: both new tests now assert the rendered role attribute, so the focus-order assertions can no longer pass vacuously. The riskiest thing left is advisory 1 — the sibling attribute one line up has the same shape and a slightly worse failure mode — but it is pre-existing and untouched by this diff, so it belongs in a follow-up rather than here.
Verification was static plus CI evidence, per the read-only steer — no install, build or test run locally. On this head the React 18 and React 19 compatibility jobs are both green, and each of them runs
build,typecheck,typecheck:testsandtestfor@allxsmith/bestax-bulma(.github/workflows/ci.yml:207-227), so the new tests pass and both theforwarded as { role?: React.AriaRole }cast and thestring | undefinedrole in the test typecheck on both majors.Build and Testwas still in progress when this review was written.
Residual risk:
- A forwarded
rolekey holdingundefined— refuted; this is the fix.rolenow sits below{...forwarded}and reads through it with a nullish fallback, so the spread can no longer win. The first new test pins it with a genuine undefined-valued key (const role = undefined as string | undefined, which JSX emits as{role: undefined}), and on8ff920f2that renders noroleat all and fails at the very first assertion. - Type safety of the new line — refuted.
AriaRolein@types/reactends in| (string & {})(index.d.ts:2792), sostring | undefinedis assignable, andtypecheckplustypecheck:testsboth ran green in the React 18 and React 19 legs. - The sibling defaults set before the spread — open, advisory 1.
tabIndexreachesforwardeduntouched:useBulmaClassesnever names it, and it is absent fromANCHOR_ONLY_ATTRS, soomitAttrscannot strip it either.data-testidshares the placement but has no behavioural consequence beyond test selectors. - Role spelling and case — token lists are advisory 2; case variance is refuted, because
roleis not one of the legacy attributes whose selector values match case-insensitively in HTML, and ARIA role values are case-sensitive by spec, sorole="MENUITEM"is invalid ARIA rather than a missed match. - Other roles a caller might set — refuted. The interactive children ARIA 1.2 permits inside
role="menu"are exactlymenuitem,menuitemcheckboxandmenuitemradio;groupandseparatorare the non-interactive rest. Excludingpresentation,noneandoptionis the correct outcome, not a gap. - Adjacent components with the same navigation shape — refuted.
menuitemappears inbulma-ui/srconly inDropdown.tsx;Modal.tsxand_pickerInternals/useFocusTrap.tsuse the tag-and-tabindexFOCUSABLE_SELECTOR, andTimeWheels.tsxselects its own wheel elements. None can be defeated by a caller-supplied role. - Stale generated artefacts — refuted.
08fb375etouches only source and tests, so the accessibility prose is unchanged since8ff920f2;docs/docs/api/components/dropdown.md:189and theaccessibilityfield ofbestax-mcp/data/components/Dropdown.jsonremain identical. Nothing underskills/oreslint-plugin/src/generated/mentionsmenuitemat all. No story is required — CI checks only that one exists, and no public prop changed. - Coverage of the new branch — refuted statically. The nullish fallback adds one branch and both arms are exercised: the undefined arm by the first new test, the caller-supplied arm by the second, which asserts
menuitemcheckboxandmenuitemradioon the DOM.
🏄 Third wave of the set and the cleanest one yet — the
roledefault finally sits downstream of the spread wheretypehas been chilling all along, and the tests now actually check the roles landed instead of just vibing on focus order. Good to send. Only thing still bobbing out there istabIndexsitting up-current of that same spread; catch that one on the next paddle-out.
|
Thanks for the fresh review. Nothing blocking and no open threads, so this PR stands as is:
|
## [5.16.10](https://github.com/allxsmith/bestax/compare/@allxsmith/bestax-bulma@5.16.9...@allxsmith/bestax-bulma@5.16.10) (2026-09-27) ### Bug Fixes * **bestax-migrate:** carry the ref escape hatch onto plain tags, and cut the roster guard back ([3aee721](3aee721)) * **bestax-migrate:** flag every unmapped innerRef, and hold the carve-out to the library ([69f7773](69f7773)) * **bestax-migrate:** flag innerRef on a plain Navbar.Item, and test the roster's polarity ([bd5c403](bd5c403)), closes [#734](#734) * **bestax-migrate:** keep JSX text, directives and quoted classes as written when reprinting ([c9f860b](c9f860b)) * **bestax-migrate:** keep one of each prop when Breadcrumb.Item merges onto its anchor ([7da699e](7da699e)) * **bestax-migrate:** keep one ref on a plain tag, and report what the Table.Container fold drops ([04044e3](04044e3)) * **bestax-migrate:** merge Breadcrumb.Item onto its anchor the way collapseOntoChild does ([e41e0fb](e41e0fb)) * **bestax-migrate:** name every ref-forwarding component in the codemod's TODOs ([4a32258](4a32258)), closes [pre-#661](https://github.com/pre-/issues/661) [#734](#734) * **bestax-migrate:** report an older bestax-bulma the app already declares ([c2d67a6](c2d67a6)) * **bulma-ui:** keep menuitemcheckbox and menuitemradio items in Dropdown's arrow-key order ([#786](#786)) ([064155a](064155a)) * **bulma-ui:** render the four burger spans Bulma v1 positions ([#785](#785)) ([8e4e1e6](8e4e1e6)) * **bulma-ui:** stop shipping test-only exports, and document notification() ([#781](#781)) ([5f95398](5f95398)) * **create-bestax:** say that the codemod flags an unmapped innerRef ([8778a04](8778a04)) * **create-bestax:** ship the corrected ref roster to scaffolded apps ([1e0ac82](1e0ac82)), closes [#661](#661) [#597](#597) * **create-bestax:** stop the ref guidance over-claiming the form controls ([f920004](f920004)), closes [#666](#666) * **create-bestax:** tell scaffolded apps the migrate skill covers raw Bulma classes ([3769180](3769180)) * **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)) ### Features * **bestax-mcp:** look up the bestax component and props for a Bulma class string ([4a4b246](4a4b246)), closes [#744](#744) * **bestax-mcp:** say a Bulma field wraps its children only when horizontal ([929bc82](929bc82)) * **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-migrate:** add bulma-classes as a migration source ([c3603d1](c3603d1)), closes [#743](#743) * **bestax-migrate:** convert .select and .breadcrumb with the element inside them ([d76c569](d76c569)) * **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 conditional classes in clsx and classnames calls ([8948cce](8948cce)) * **bestax-migrate:** fold .table-container and .fixed-grid into the component inside ([#761](#761)) ([72504f5](72504f5)), closes [#743](#743) * **eslint-plugin:** add an opt-in rule for plain elements styled with a Bulma component class ([#750](#750)) ([0bb4d80](0bb4d80))
|
🎉 This PR is included in version 5.16.10 🎉 The release is available on: Your semantic-release bot 📦🚀 |
# [2.12.0](https://github.com/allxsmith/bestax/compare/bestax-migrate@2.11.0...bestax-migrate@2.12.0) (2026-09-27) ### Bug Fixes * **bulma-ui:** keep menuitemcheckbox and menuitemradio items in Dropdown's arrow-key order ([#786](#786)) ([064155a](064155a)) * **bulma-ui:** render the four burger spans Bulma v1 positions ([#785](#785)) ([8e4e1e6](8e4e1e6)) * **bulma-ui:** stop shipping test-only exports, and document notification() ([#781](#781)) ([5f95398](5f95398)) ### Features * **bestax-migrate:** convert conditional classes in clsx and classnames calls ([8948cce](8948cce))
|
🎉 This PR is included in version 2.12.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
# [1.7.0](https://github.com/allxsmith/bestax/compare/bestax-mcp@1.6.0...bestax-mcp@1.7.0) (2026-09-27) ### Bug Fixes * **bestax-mcp:** give .image's ratios their reason in the lookup ([3ea4d0c](3ea4d0c)) * **bestax-migrate:** say why .image's ratios stay classes ([2fbfbd5](2fbfbd5)) * **bulma-ui:** apply textColor helper class on Navbar Menu, Start, End, and Burger ([#792](#792)) ([feb83c8](feb83c8)) * **bulma-ui:** avoid empty class attribute on several components ([#793](#793)) ([7c5c316](7c5c316)) * **bulma-ui:** keep menuitemcheckbox and menuitemradio items in Dropdown's arrow-key order ([#786](#786)) ([064155a](064155a)) * **bulma-ui:** merge className into Navbar.Divider instead of overwriting it ([#791](#791)) ([fcc0d51](fcc0d51)) * **bulma-ui:** render the four burger spans Bulma v1 positions ([#785](#785)) ([8e4e1e6](8e4e1e6)) * **bulma-ui:** stop shipping test-only exports, and document notification() ([#781](#781)) ([5f95398](5f95398)) * **eslint-plugin:** report .image with the message for a class the codemod converts ([d27c19b](d27c19b)) ### Features * **bestax-mcp:** look up .image as Image, with the props it takes from its <img> ([3e63230](3e63230)) * **bestax-migrate:** convert an .image and its <img> to Image ([d4f3673](d4f3673)), closes [#793](#793) * **bestax-migrate:** convert conditional classes in clsx and classnames calls ([8948cce](8948cce)) * **bestax-migrate:** convert navbar dividers with classes, and navbar text colors ([#796](#796)) ([c97c7e9](c97c7e9)) * **bulma-ui:** let Card.Header.Title and Card.FooterItem render Bulma's own tags ([#794](#794)) ([47ecdb6](47ecdb6))
|
🎉 This PR is included in version 1.7.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
## [1.1.4](https://github.com/allxsmith/bestax/compare/@allxsmith/eslint-plugin-bestax@1.1.3...@allxsmith/eslint-plugin-bestax@1.1.4) (2026-09-27) ### Bug Fixes * **bestax-mcp:** give .image's ratios their reason in the lookup ([3ea4d0c](3ea4d0c)) * **bestax-migrate:** say why .image's ratios stay classes ([2fbfbd5](2fbfbd5)) * **bulma-ui:** apply textColor helper class on Navbar Menu, Start, End, and Burger ([#792](#792)) ([feb83c8](feb83c8)) * **bulma-ui:** avoid empty class attribute on several components ([#793](#793)) ([7c5c316](7c5c316)) * **bulma-ui:** keep menuitemcheckbox and menuitemradio items in Dropdown's arrow-key order ([#786](#786)) ([064155a](064155a)) * **bulma-ui:** merge className into Navbar.Divider instead of overwriting it ([#791](#791)) ([fcc0d51](fcc0d51)) * **bulma-ui:** render the four burger spans Bulma v1 positions ([#785](#785)) ([8e4e1e6](8e4e1e6)) * **bulma-ui:** stop shipping test-only exports, and document notification() ([#781](#781)) ([5f95398](5f95398)) * **eslint-plugin:** report .image with the message for a class the codemod converts ([d27c19b](d27c19b)) ### Features * **bestax-mcp:** look up .image as Image, with the props it takes from its <img> ([3e63230](3e63230)) * **bestax-migrate:** convert an .image and its <img> to Image ([d4f3673](d4f3673)), closes [#793](#793) * **bestax-migrate:** convert conditional classes in clsx and classnames calls ([8948cce](8948cce)) * **bestax-migrate:** convert navbar dividers with classes, and navbar text colors ([#796](#796)) ([c97c7e9](c97c7e9)) * **bulma-ui:** let Card.Header.Title and Card.FooterItem render Bulma's own tags ([#794](#794)) ([47ecdb6](47ecdb6))
## [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))
|
🎉 This PR is included in version 4.2.13 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Pull Request
Description
Dropdownkeyboard navigation now includes items with any of the three menu-item roles, so aDropdown.Itemgivenrole="menuitemcheckbox"orrole="menuitemradio"is reachable with the arrow keys.@allxsmith/bestax-bulma)create-bestax)@allxsmith/bestax-docs)getMenuItems()selected[role="menuitem"].Dropdown.Itemsets that role before spreading forwarded props, so a caller'srolewins, and an item with either of the other two roles rendered fine but was never reachable. It now selects all three, the smaller of the two fixes #714 proposed and the one that matches what the roles mean.menuitemcheckbox, amenuitemradioand a default item. The arrow keys walk all three and wrap around. It fails onmain, where focus never reaches the checkbox item, and passes with the fix.aria-checked, for a filter or sort menu. The MCP index entry is regenerated to match.Related Issue(s)
Closes #714
Type of Change
Checklist
CLAUDE.mdfiles are updatedScreenshots / Demos
None; keyboard behavior only.
Additional Context
aria-checkedstays the caller's to manage.Dropdown.Itemdoesn't track checked state, and this PR doesn't add it.