Skip to content

fix(core): registered icons reach swizzled copies; icon and theme registries are one per React (AST-110 FR3) - #11096

Open
cixzhang wants to merge 3 commits into
mainfrom
fix/public-registries-shared
Open

cixzhang wants to merge 3 commits into
mainfrom
fix/public-registries-shared

Conversation

@cixzhang

@cixzhang cixzhang commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

User impact

A product engineer who registers icons with registerIcons() and then swizzles Icon, CodeBlock, Table or Timestamp gets a copy that cannot see them: those copies carry their own icon registry, which starts empty, so a product's registered icon, or a library key such as richtext:bold, fell back to the default icon in the copy while the package showed the product's icon. After this change copies of Core on one React share the icon registry.

The theme registry moves to the same per-React store. Swizzled components already read themes through @astryxdesign/core/theme, so for them nothing changes; what changes is that themes registered by name are shared by every Core bundle loaded on one React.

Problem and solution fit

  • Why can't the copy see them? Icon/globalIconRegistry.tsx and theme/themeRegistry.ts keep their registries in module scope, and a swizzled copy carries its own copy of each.
  • Why one per React and not one per page? Icon entries are React elements and components, and a theme can carry them too (its icons). A registry shared across two Reacts on one page would let one React render the other's elements, so both registries are one per React (spec:AST-110 FR3: state that holds React components or elements is kept one per React).
  • Both modules are importable from server components, so the per-React helper must be too. sharedForReact moves out of the client-only utils/sharedContext.ts into its own server-safe module, utils/sharedForReact.ts, and keys by React's createElement, which both the client and the server builds export (it had no callers yet). The server and client builds of React are separate module instances, so a server registration and a client registration stay in separate stores, as each module's own state did before.

The icon registry → sharedForReact('icon/global-icon-registry/state', 1, …); the theme registry → sharedForReact('theme/theme-registry/themes', 1, …). The public functions and their behavior within one copy are unchanged. The source-check baseline loses the two F8 entries.

Expected behavior and authority

spec:AST-110 FR3 (approved, authority: draft).

Evidence

  • Red first (theme/registries.shared.test.ts, first commit): a theme registered in one load is null in a second load on the same React, and an icon registered in one load is undefined in the other. Both pass after. A third case — a theme and an icon registered on one React, read from a second React on the same page — passes before and after: the second React sees neither, so no React renders another React's elements.
  • sharedContexts.test.tsx's per-React case now loads the moved helper.
  • The theme, Icon, Indicator, shared-context and shared-realm suites pass (39 files, 1992 tests). Core's tsc passes for the source and build configurations.

Scope

Components: Icon, CodeBlock, Table, Timestamp (the swizzled copies that carry the icon registry)

  • One defect group (the public registries); no API change.
  • Public text contains no internal Meta context.

Testing

  • pnpm exec vitest run --project ui packages/core/src/theme packages/core/src/Icon packages/core/src/Indicator packages/core/src/Layer/sharedContexts.test.tsx packages/core/src/utils/sharedRealm.test.ts
  • pnpm exec vitest run --project node scripts/shared-identity.test.mjs
  • tsc --noEmit -p packages/core (and tsconfig.build.json)

@vercel

vercel Bot commented Nov 10, 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 Nov 10, 2026 9:11pm UTC

Request Review

@astracat-bot

astracat-bot Bot commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

AI review status for this pull request.

Review status Updated
🟢 Reviewed (for maintainers only) Nov 10, 2026, 9:25 PM UTC

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Nov 10, 2026
@cixzhang

Copy link
Copy Markdown
Contributor Author

/approve-spec 1fc1f09

@github-actions

github-actions Bot commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

PR Analysis Report

🔎 Preview · 6a423aa

Storybook · Sandbox · built from this PR's head

Current run: Heavy CI deferred: runs when marked ready and before merge. Lint, typecheck and any path-filtered checks ran on this push.


Generated by PR Enrichment workflow | View current CI run

@astracat-bot astracat-bot Bot 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.

Requesting changes: the icon registry fix is sound, but the release note also claims a theme fix that swizzled components never needed.

  • The changeset (.changeset/public-registries-swizzle-shared.md) and the title say swizzled copies could not find a theme by name, but no component that astryx swizzle offers copies theme/themeRegistry.ts, because every copied theme lookup already imports getRegisteredTheme or registerTheme from @astryxdesign/core/theme; limit the swizzle claim to icons in the Icon, CodeBlock, Table and Timestamp copies, and describe the theme change as sharing themes across Core bundles loaded on one React.

The code can stay as it is: the new tests fail before the change and pass after it, and no public API changes. Three new source comments run longer than the comment style allows (inline, non-blocking).

[Automated review]

@cixzhang cixzhang changed the title fix(core): the icon and theme registries are one per React across swizzled copies (AST-110 FR3) fix(core): registered icons reach swizzled copies; icon and theme registries are one per React (AST-110 FR3) Nov 10, 2026
@cixzhang

Copy link
Copy Markdown
Contributor Author

/approve-spec 6a423aa

@astracat-bot astracat-bot Bot 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.

Approved pending CI: the heavy CI jobs (build and tests) have not run on this head yet; they are deferred and run before merge.

The release note now matches the change: registered icons reach the swizzled Icon, CodeBlock, Table and Timestamp copies, and the theme registry is shared by Core bundles on one React. The new registry tests fail before the change and pass after it, and no public API changes.

[Automated review]

@cixzhang cixzhang added ci:run A maintainer lets this outside contributor's pull request run CI (AST-030 FR17) ci:run-a11y Run the accessibility suite on this PR; write access, next push (AST-030 FR12) labels Nov 10, 2026

This branch was successfully deployed

1 active deployment
Preview — 6a423aac Deployed Nov 10, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:run A maintainer lets this outside contributor's pull request run CI (AST-030 FR17) ci:run-a11y Run the accessibility suite on this PR; write access, next push (AST-030 FR12) CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant