Repository navigation
feat(registry)!: adopt the new Remix APIs in the HeroUI preset - #343
Draft
leoafarias wants to merge 27 commits into
Draft
leoafarias wants to merge 27 commits into
leoafarias wants to merge 27 commits into
Conversation
HeroUiRadio and HeroUiSwitch take the label RemixRadio and RemixSwitch now draw inside their tap target, so pointing at the label hovers, presses, and toggles the control and one semantics node carries its name. The group composition drops its label row; HeroUiControlRow becomes HeroUiDescribedControl, which lays out only the description beneath the label.
Tabs, toggles, toggle group items, select and menu rows, the menu trigger, and the accordion and disclosure triggers paint HeroUI's focus ring as an outline effect instead of an always-present transparent inside border. The ring takes no layout space, so focus no longer resizes a part or needs padding reduced by the ring width, and it is the measured gap-then-ring outside the part. Toggle group items and the surface accordion, whose parent clips, draw ring-inset inside the part. heroUiRingBorder and heroUiInsideRing are gone.
The select content takes remixAnchorWidth() as its minimum width, the port of min-w-(--trigger-width), so the popover is at least as wide as the trigger instead of as wide as its widest item.
RemixMenuTrigger.control makes a real HeroUiButton the menu trigger, so the dropdown no longer needs a label standing in for it. The tests pin one tab stop, focus returning to the button, one expandable semantics node, and a disabled button not opening the menu.
… 768px The toast sets actionPlacement to below under maxWidth(768), inclusive like max-width: 768px, and adds mt-2 below 640px by restating the action style under maxWidth(639), because an action replaces rather than merges.
… button A HeroUiButton that opens a popover with openOnTap: false passes the same FocusNode as the popover's triggerFocusNode and its own focusNode, so the button is the only tab stop and takes focus back on close. The recipe doc, the worksheet, and the popover test show it.
…gers The gallery's dropdown trigger is an AcmeButton through RemixMenuTrigger.control, and its popover button shares a focus node with the popover. The fixture tests pin that the menu opens, a row reports its action, and focus returns to each button.
…kill ADR 0002's verdict rows for focus rings, the select width, radio and switch labels, and the dropdown trigger now say they shipped and are adopted. The HeroUI reference covers labeled controls, the button triggers and shared popover focus node, the select width, the toast action placement, and that Mix's .animate does not yet honor reduced motion.
A labeled radio or switch group sits under IntrinsicWidth in an alert dialog's content, and Remix's labeled-control helper used a LayoutBuilder that cannot report intrinsic sizes. The two tests fail until the Remix fix for that reaches this branch.
…fects The selected pill takes heroUiSurfaceEffects() instead of plain box shadows, so it follows the --surface-shadow token (none in dark) and combines with the focus ring field by field. heroUiSurfaceBoxShadows is removed, and the dark mode approximation with it.
onNot(Breakpoint.minWidth(sm)) is the complement of sm:mt-0, so the margin reaches the last fraction below 640px where maxWidth(639) missed 639 to 640. The recipe doc and the test spell out the caller pattern: restate heroUiButtonStyle() in the base action and in the below-sm fragment, and assert the restated size, fill, and gap.
The inset check only repeated the shadow parsing, so expectFocusRing takes an inset flag. The dropdown button's height comes from the measured secondary button instead of a literal.
The decided table stays as written, and a dated Adoption revision lists the four approximations it replaces and what remains, with the surface accordion's inside ring attributed as an approximation. The select alignment claim is softened, the corner crop of the inside rings is recorded, the toast caller pattern is documented, and the reduced-motion note no longer links a closed Mix PR.
This was referenced Oct 27, 2026
…bels Besides laying out without an exception, the radio and switch groups under IntrinsicWidth and IntrinsicHeight take a finite size that contains every label.
The variant holds the 640px-and-up breakpoint, so onNot(fromSm, ...) reads as the below-sm fragment it is.
…s ends The inside ring survives the group's clip except at the joined pill's rounded ends, as toggle_button_group.yaml records.
… notes The revision quotes the popover row's verdict as decided, names the five rows it supersedes, and folds the tab shadow into the ring row, where it matches upstream. Reduced motion says only that Mix 2.3.1's .animate does not read it. The toast example restates a HeroUI variant, and toast.yaml says the 640 and 768px heights are derived from the CSS and cites the 768px rule in the published @heroui/react 3.2.6 toast.js.
…-adopt-remix-apis
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Draft, stacked on #339. Do not merge until remix 1.0.0-beta.14 and naked_ui 1.3.0 are on pub.dev. The preset uses APIs that exist only in those releases, and the registry
remix:floor moves in the beta.14 release PR, not here.The HeroUI preset adopts the Remix and Naked UI APIs from the follow-up PRs, so it stops approximating what they now express.
label. The label is inside the tap target, so hover, press, focus, and semantics cover one target.HeroUiControlRowbecomesHeroUiDescribedControl, which lays out only the description beneath the label.containerEffects,triggerEffects) on tabs, toggles, toggle group items, select and menu rows, the menu trigger, and the accordion and disclosure triggers.ring-insetdoes. The surface accordion's trigger also draws it inside, as an approximation.containerEffects(heroUiSurfaceEffects()), so it follows--surface-shadow(none in dark) and combines with the focus ring.remixAnchorWidth()as itsminWidth.HeroUiButtonis the dropdown trigger throughRemixMenuTrigger.control, and a popover button shares oneFocusNodewith the popover. The gallery fixture uses both.actionPlacement: below, inclusive likemax-width: 768px). Below 640px it addsmt-2throughonNot(Breakpoint.minWidth(640)), the exact complement ofsm:mt-0.skills/using-remix/references/heroui.mdrecord what this closes.Not done:
.animate(...)transitions still ignore reduced motion, because Mix 2.3.1's.animatedoes not read it. This is tracked as a Mix follow-up.toast.yaml.Validation
Continuation validation (2026-10-27)
Merged final integration
a6adc9592(including #347–#350, the effects-test focus baseline correction and the scoped Vanilla consumer-host fix). Independent review of combined treef40536ba9found no merge-delta issues. The strict complete local gate on that exact combined tree passes all 8 CI legs, with zero failed steps and unchanged clean initial/final SHA. Flutter counts: naked_ui1124 (3 existing skips), remix3132, registry_source2422; final HeroUI consumer fixture17 pass. Fresh GitHub CI on this PR is green; older pass counts below belong to their recorded earlier heads. Draft/release requirements are unchanged.flutter testinregistry_source: 2326 pass. The new behavior tests fail against the previous recipes. They include the intrinsic-sizing regression tests: a labeledHeroUiRadioGroupunderIntrinsicWidthand aHeroUiSwitchGroupunderIntrinsicHeight, which pass with feat(remix)!: add label to RemixRadio and RemixSwitch #332's labeled-control fix.dart analyze registry_source, rootdart format,generate:check,build_registry --check, thenopen-code:registry:buildandopen-code:apps:check, andmelos run ci:checks(includesdocs:checkandheroui:parity:check): pass.dart run tool/check_open_code.dart --preset heroui --source checkout: pass.Related Issues
Depends on #318, #326, #331, #332, #335, #337, and #338, all merged into the #339 stack.
Checklist
///).Breaking Change
This breaks installs of the HeroUI preset from #324. The preset needs remix 1.0.0-beta.14 and naked_ui 1.3.0.
HeroUiControlRowis replaced byHeroUiDescribedControl.label,controlWidth, andinvalidare gone; pass the label toHeroUiRadioorHeroUiSwitchinstead.descriptionInset, which is the control width plus 12.heroUiRingBorderandheroUiInsideRingare removed.heroUiSurfaceBoxShadowsis removed; usecontainerEffects(heroUiSurfaceEffects()).actionmust restateheroUiButtonStyle()in the baseaction, and again, with.margin(.top(2)), in anonNot(Breakpoint.minWidth(640))fragment, the same variant the recipe uses.radio_groupandswitch_groupnow depend onthemein the registry.HeroUiRadioandHeroUiSwitchneed alabelor asemanticLabelinstead of a requiredsemanticLabel, andHeroUiSwitchgainsinvalid.