Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

feat(ui): migrate Mosaic Icon to StyleX#9245

Open
alexcarpenter wants to merge 2 commits into
carp/mosaic-typography-stylexclerk/javascript:carp/mosaic-typography-stylexfrom
carp/mosaic-icon-stylexclerk/javascript:carp/mosaic-icon-stylexCopy head branch name to clipboard
Open

feat(ui): migrate Mosaic Icon to StyleX#9245
alexcarpenter wants to merge 2 commits into
carp/mosaic-typography-stylexclerk/javascript:carp/mosaic-typography-stylexfrom
carp/mosaic-icon-stylexclerk/javascript:carp/mosaic-icon-stylexCopy head branch name to clipboard

Conversation

@alexcarpenter

Copy link
Copy Markdown
Member

Description

Stacked on #9244 (base branch carp/mosaic-typography-stylex) — Icon's story needs the meta.styleEngine field that PR adds. Retarget to main once it merges.

Moves Icon off the Emotion slot-recipe engine onto StyleX. Same contract as the components migrated before it: a stable .cl-icon class plus a data-size attribute, with the consumer's className/style merged last.

The appearance.icons override path loses a layer. It only wrapped itself in Emotion's ClassNames to serialize the recipe's css into a real class — an override is authored in a consumer file with no jsx pragma, so its own css prop would be ignored. stylex.props() already returns a className, so the override is now cloned with the same merged props the built-in glyph gets:

const props = mergeStyleProps(themeProps('icon', { size }), stylex.props(styles.base, sizes[size]), className, style);

if (override) {
  const overrideClassName = (override.props as { className?: string }).className;
  return React.cloneElement(override, { ...rest, ...mergeStyleProps(props, overrideClassName) });
}

Everything the override path guaranteed is unchanged: overrides stay plain elements (so they serialize across the RSC boundary), Mosaic's sizing applies to them exactly as to the built-in glyph, the element's own className survives, call-site svg props are forwarded, and ref is still deliberately not forwarded to an override.

Consumers target .cl-icon + data-size instead of data-cl-slot="icon" and appearance.elements.icon, matching Button, Heading, and Text.

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

@vercel

vercel Bot commented Jul 24, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment Jul 24, 2026 8:23pm
swingset Ready Ready Preview, Comment Jul 24, 2026 8:23pm

Request Review

@changeset-bot

changeset-bot Bot commented Jul 24, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 3643f2a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Same contract as the other migrated components: a stable `.cl-icon` class plus
a `data-size` attr, with the consumer's `className`/`style` merged last.

The `appearance.icons` override path loses a layer. It only wrapped itself in
Emotion's `ClassNames` to serialize the recipe's `css` into a real class, since
an override authored in a consumer file has no jsx pragma to process a `css`
prop. `stylex.props()` already returns a className, so the override is now
cloned directly with the same merged props the built-in glyph gets.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Morty Proxy This is a proxified and sanitized view of the page, visit original site.