Skip to content

fix(docsite): show DropdownMenuRadioGroup in properties preview - #5976

Open
Kyujenius wants to merge 6 commits into
facebook:mainfrom
Kyujenius:fix/dropdown-menu-radio-group-preview
Open

fix(docsite): show DropdownMenuRadioGroup in properties preview#5976
Kyujenius wants to merge 6 commits into
facebook:mainfrom
Kyujenius:fix/dropdown-menu-radio-group-preview

Conversation

@Kyujenius

@Kyujenius Kyujenius commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Give DropdownMenuRadioGroup a playground wrapper (DropdownMenu with a Sort trigger, mounted open) and two DropdownMenuRadioItem children, so the Properties preview shows both choices on first load instead of an empty container.
  • Bridge the wrapper's onOpenChange back into preview state so selecting still closes the menu and the trigger reopens it.
  • Stop DropdownMenu from moving focus into a controlled menu that mounts already open, so the preview (or any page that renders a menu open on load) does not drop keyboard users into it.
  • Cover the generated component registry, the preview's render-time first-load state, and the menu's mount-open focus rule.

Fixes #5888

Notes

  • The trigger label stays Sort after selection by design. DropdownMenu reads only button.label, and the selected state is shown by the radio mark inside the menu, matching the existing storybook story.
  • The focus change lives in core, not the preview: DropdownMenu's compound path treated a controlled isMenuOpen that is true at mount like a programmatic open and focused the first item. A mount is not an open anyone asked for, so it now leaves focus alone; the exemption ends with the first close, and every later open follows the modality rules from fix(dropdown-menu): follow input modality for initial focus so pointer opens don't highlight the first item #4594 (keyboard/programmatic → first item, pointer → menu container). Items-array mode was unaffected and is unchanged.
  • Two changesets, both @astryxdesign/core patches: the .doc.mjs playground change and the DropdownMenu focus change.

AST-009 classification. No real-AT trigger. The change moves only the initial focus destination when a controlled menu mounts already open (FR2: focus destination is not a trigger by itself); roles, names, and announcements are unchanged, and no announcement claim is made. Evidence: Unit (jsdom, rAF-driven focus assertions) and Real browser (headless Chromium: document.activeElement on load and after a post-mount open).

Verification

Check Result Evidence
Two choices on first load Pass Docsite /components/DropdownMenuRadioGroup?tab=properties: Newest (checked) and Oldest rendered without a click.
Selection, close, reopen Pass Selecting Oldest moves the check, closes the menu, and updates the value knob; the trigger reopens it.
Initial focus (mount-open) Pass Headless Chromium on the docsite page and on the new core-dropdownmenu--mounted-open story: document.activeElement is <body> on load.
Post-mount open still focuses the first item Pass After a close, Enter on the trigger focuses Newest (#4594 unchanged).

Screenshot

AS-IS
스크린샷 2026-09-04 오전 2 35 51

TO-BE (video: open Sort, select Oldest)

  • updated at 2026-09-05 : default as opened
  • updated at 2026-09-06: default as not focused on Dropdown Items
2026-09-05.mov
2026-09-06-final.mov

@vercel

vercel Bot commented Sep 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
astryx Ready Ready Preview Sep 6, 2026 10:59am UTC

Request Review

@github-actions github-actions Bot added community Authored by a community contributor (not on the eng/design team) needs:code-review High-risk change (new package/component/API) — needs human code review before merge labels Sep 3, 2026
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Sep 3, 2026

@cixzhang cixzhang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for putting this under a real DropdownMenu; that preserves the menu semantics and keyboard owner. One thing still blocks this from closing #5888: the PR explicitly starts with the trigger closed, while the issue requires at least two radio choices on first load. Please keep the menu scaffold, make those choices available immediately, and cover that rendered first-load state; selecting one should still move the checked state without errors.

If you'd rather talk it through with someone, we're in Discord.

[Reviewed by Robohands]

@Kyujenius

Kyujenius commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

@cixzhang

Correcting my note above: isMenuOpen is viable and my reason for ruling it out was wrong — wrapperProps already holds the wrapper's value in state and injects a real onChange, so wrapper.props is only the seed. The open pair is
just the one that was never wired.

However, I'd rather not add isMenuOpen as a second hardcoded name there. Following #5982, generate-data.mjs could derive a wrapper's value/onChange-style pairs from the wrapper component's documented props — no authoring-type change, since PlaygroundConfig is generated and already carries overlayControl for the same purpose on the previewed component. Either way I'd add the first-load coverage at render time.

Is that in scope for #5888, or would you prefer this PR stay minimal with a separate issue for the bridge?

@github-actions github-actions Bot added the needs:design-review Affects visuals — Design should review label Sep 5, 2026
github-actions Bot added a commit that referenced this pull request Sep 5, 2026
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

PR Analysis Report

📚 Storybook Preview

View Storybook for this PR
GitHub Pages may take up to a minute to hydrate after deploy.

🧪 Sandbox Preview

View Sandbox for this PR
GitHub Pages may take up to a minute to hydrate after deploy.

Modified Components

DropdownMenu (@astryxdesign/core) · View in Storybook
Metric Before After Delta
Bundle Size (ESM) N/A N/A N/A
Lines of Code N/A 2108 -
Complexity N/A Very High (238) -

Bundle Size Summary

Package Size (ESM) Size (CJS) Gzipped
@astryxdesign/core N/A 4.8KB 1.2KB

Accessibility Audit

Status: No accessibility violations detected.

Visual Regression

Status: No visual change across 2 compared shot(s).


Generated by PR Enrichment workflow | Storybook | Sandbox | View full report

@cixzhang cixzhang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for making the choices immediately available and keeping them inside a real menu. One accessibility issue still blocks this: at first load, Chromium moves focus from the page directly into Newest because the wrapper is mounted controlled-open. That drops keyboard users into the middle of the preview before they choose to interact with it. Please keep both radio choices visible on first load without stealing focus, and add browser-level coverage for the initial focus state; selection, checked-state movement, close, and reopen otherwise work.

If you'd rather talk it through, we're in Discord.

[Reviewed by Robohands]

@Kyujenius

Copy link
Copy Markdown
Contributor Author

@cixzhang Fixed in core: a controlled DropdownMenu that mounts with isMenuOpen true no longer moves focus into the first item; only an open after mount does, so #4594 behavior is unchanged.

Covered by three jsdom tests, a new MountedOpen story, and headless Chromium on the docsite page and the story — document.activeElement stays on <body> at load. AST-009 classification (FR2, no real-AT trigger) is in the PR body.

github-actions Bot added a commit that referenced this pull request Sep 6, 2026

@cixzhang cixzhang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for fixing the first-load visibility and focus theft. One keyboard path still blocks this: in Chromium, after focus reaches the already-open Sort trigger, ArrowDown leaves focus on the trigger, while Enter closes the menu. Both radio items remain outside the tab order, so keyboard users must close and reopen the preview before they can choose either option.

Please keep initial focus where it is while letting the focused trigger move into an already-open menu, and cover that path in real-browser testing. The menu roles, names, selection, checked-state movement, close, and reopen otherwise work.

If you'd rather talk it through, we're in Discord.

[Reviewed by Robohands]

Rijul202 added a commit to Rijul202/astryx that referenced this pull request Sep 6, 2026
LayoutFooter renders an empty landmark bar on its own, so the docsite
properties-tab preview showed an empty stage on first load. Seed
representative footer content and wrap it in a Layout parent via
playground defaults, mirroring the sibling LayoutHeader fixture, plus
docsite tests covering the non-empty preview state and registry shape.

Scoped to LayoutFooter only; the DropdownMenuRadioGroup half is dropped
here so the radio-item accessibility fix can converge in facebook#5976 (per
maintainer review on facebook#5975).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: 1f322fc5-62a9-4f66-ad77-ef2b16a940ff
@github-actions
github-actions Bot requested a review from cixzhang September 6, 2026 10:56
@Kyujenius

Copy link
Copy Markdown
Contributor Author

@cixzhang Thanks for the clear repro — that path was a gap I'd missed.

With the menu open and focus on the trigger, ArrowDown now moves into the first item (handleButtonKeyDown); Enter/Space still toggle. Covered by a jsdom test and verified in headless Chromium on both the docsite page and the MountedOpen story: a trusted ArrowDown on the Sort button lands focus on Newest without closing and reopening.

@cixzhang cixzhang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks, this now fixes the full path for me: initial focus stays put, ArrowDown enters cleanly, selection moves, and close/reopen preserves it.

[Reviewed by Robohands]

@github-actions github-actions Bot removed the needs:code-review High-risk change (new package/component/API) — needs human code review before merge label Sep 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot. community Authored by a community contributor (not on the eng/design team) needs:design-review Affects visuals — Design should review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] DropdownMenuRadioGroup Properties preview renders no working component

2 participants