Skip to content

feat(ComplexSelector): stable theme target for the popup surface - #4821

Open
AKnassa wants to merge 2 commits into
facebook:mainfrom
AKnassa:rocky/issue-4804-complexselector-popup
Open

feat(ComplexSelector): stable theme target for the popup surface#4821
AKnassa wants to merge 2 commits into
facebook:mainfrom
AKnassa:rocky/issue-4804-complexselector-popup

Conversation

@AKnassa

@AKnassa AKnassa commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

What this does

Gives the ComplexSelector popup a stable astryx-complex-selector-popup class, so apps that do not use StyleX can style the popup the way they already style the trigger.

Refs #4804 (route A).

Why

The trigger takes className, but the popup surface rendered only hashed classes. A theme or plain stylesheet had no way to give the popup a border, a different background, a radius, or a width.

What changed

  • The popup content container carries the stable class and now paints the surface itself (usePopover with hasSurface: false plus the same background, radius, and shadow tokens, shared via an exported popoverSurfaceStyles). Styles aimed at the class land on the element that owns the popup's look, with nothing painting behind it. Rendered defaults are unchanged.
  • contentXstyle merges after the surface styles, so it can now override background, border, radius, and shadow too. Prop docs updated.
  • Because overrides genuinely replace the surface now, two niche cases behave differently on purpose: a translucent contentXstyle background no longer composites over an opaque default (the page shows through), and a themed width narrower than the trigger leaves the layer at the trigger's width for anchor positioning, so the strip beside the panel does not light-dismiss. No in-repo consumer relies on either; existing stories that widen the popup through contentXstyle render identically.
  • The component's theming table lists the new target.
  • New Storybook story "Themed popup surface" renders a flat, bordered, muted popup from defineTheme alone.
  • Tests cover class placement, surface paint ownership (injected-CSS probe on both the popup and the dialog wrapper), the override order, and theme CSS emission.

Example:

defineTheme({
  components: {
    'complex-selector-popup': {
      base: {borderWidth: '1px', borderColor: 'var(--color-border)', inlineSize: '288px'},
    },
  },
});

How to see it

4804-default-popup-open 4804-themed-popup-open 4804-themed-popup-zoom

Storybook, Core/ComplexSelector, "Themed popup surface": open the selector and the popup is a flat bordered panel. "Fruit ripeness selector" shows the defaults, unchanged.

Validation

  • ComplexSelector 8/8; popover-family collateral (Popover, DropdownMenu, Selector, MultiSelector, Typeahead, DateTimeInput) 406/406; full suite 9412/9414 with the 2 known pre-existing CLI case-sensitivity failures only
  • check:repo, strict eslint, prettier, core and storybook typechecks clean
  • Changeset included (patch)

The popup surface had no stable class: contentXstyle is StyleX-typed
and the surface element carried only hashed atomic classes, so
non-StyleX consumers could not style the popup's background, border,
radius, or width at all (route A of the RFC).

The popup content container now paints the surface itself (usePopover
hasSurface: false + the exported popoverSurfaceStyles, same tokens) and
carries themeProps('complex-selector-popup'), so defineTheme components
and plain stylesheets reach the element that owns the surface paint,
and contentXstyle can override it too. Rendered defaults unchanged.

Refs facebook#4804
@vercel

vercel Bot commented Aug 8, 2026

Copy link
Copy Markdown

@AKnassa is attempting to deploy a commit to the Meta Open Source Team on Vercel.

A member of the Team first needs to authorize it.

@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 Aug 8, 2026
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Aug 8, 2026
Self-review round on facebook#4821: the declares() helper could match a longer
atomic class sharing a prefix (.x14o matched .x14odbl rules), weakening
assertions in both directions; a boundary lookahead closes it. The
paint assertions now pin the exact surface tokens
(--color-background-popover, --radius-container, --shadow-low) so the
test states what the changeset promises: same tokens, same surface.
@github-actions

github-actions Bot commented Aug 8, 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

ComplexSelector (@astryxdesign/core) · View in Storybook
Metric Before After Delta
Bundle Size (ESM) N/A N/A N/A
Lines of Code N/A 363 -
Complexity N/A Very High (31) -
Popover (@astryxdesign/core) · View in Storybook
Metric Before After Delta
Bundle Size (ESM) N/A N/A N/A
Lines of Code N/A 542 -
Complexity N/A Very High (51) -

Bundle Size Summary

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

Accessibility Audit

Status: No accessibility violations detected.


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

@AKnassa
AKnassa marked this pull request as ready for review August 8, 2026 04:05
github-actions Bot added a commit that referenced this pull request Aug 8, 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:code-review High-risk change (new package/component/API) — needs human code review before merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant