Skip to content

feat(ui): add Mosaic Item component - #9234

Merged
alexcarpenter merged 15 commits into
mainfrom
carp/mosaic-item
Jul 30, 2026
Merged

feat(ui): add Mosaic Item component#9234
alexcarpenter merged 15 commits into
mainfrom
carp/mosaic-item

Conversation

@alexcarpenter

@alexcarpenter alexcarpenter commented Jul 23, 2026

Copy link
Copy Markdown
Member

Description

Adds a new Item component to Mosaic, styled with StyleX following the Button migration (themeProps + stylex.props + mergeStyleProps; public contract is the .cl-item* classes plus data-* axes). It's a row for lists of accounts, organizations, and settings (org switcher, account switcher, settings rows), composed via dot syntax.

Preview: https://swingset-git-carp-mosaic-item.clerkstage.dev/components/item

Parts

  • Item.Root — the row; renders a <div> or a custom element via render
  • Item.Media — fixed-width leading/trailing slot that centers an icon, image, or avatar
  • Item.Content, Item.Title, Item.Description, Item.Actions
  • Item.Header, Item.HeaderTitle, Item.HeaderActions — a header row above a group
  • Item.Group (role="list"), Item.Separator

Behavior

  • variant (entity default | action) sets the row's vertical density (entity 8px, action 10px) and, on interactive rows, promotes the title color: action titles start faded and darken to neutral on hover. Reflected as data-variant.
  • Polymorphism uses the repo's render prop (via useRender), not shadcn's asChild. A plain Item.Root is a static <div>; passing render makes the row a link or button and opts it into cursor + hover affordances, reflected as data-interactive.
  • The action hover treatment is scoped with StyleX's when API and a marker set only on interactive action rows, so no other row's title is affected.

Docs

Swingset docs added (item.stories.tsx + item.mdx) and wired into registry.ts / DocsViewer.tsx.

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:

@changeset-bot

changeset-bot Bot commented Jul 23, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c8a8e3e

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

@vercel

vercel Bot commented Jul 23, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
swingset Ready Ready Preview Jul 29, 2026 11:41pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
clerk-js-sandbox Skipped Skipped Jul 29, 2026 11:41pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a composable Mosaic Item component with typed subcomponents, StyleX styling, polymorphic rendering, ref forwarding, and tests. Exports it through Mosaic barrels, adds Storybook stories and MDX documentation, registers the stories and docs in Swingset, updates Mosaic TypeScript paths and styling documentation, adjusts avatar and color tokens, and includes a changeset entry.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

  • clerk/javascript#9221: Extends the same Swingset documentation and story registry mappings for another Mosaic component.
  • clerk/javascript#9230: Modifies the shared Mosaic Avatar stylesheet used by the new Item stories.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the new Mosaic Item component feature.
Description check ✅ Passed The description matches the Item component, docs, and registry updates in the changeset.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Actionable comments posted: 4

🧹 Nitpick comments (2)
packages/ui/src/mosaic/components/item/index.ts (1)

1-2: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Avoid introducing the Item re-export barrel.

The new directory index.ts adds an unnecessary re-export boundary and the public entry consumes it. Export directly from item.tsx instead to avoid a future circular-dependency edge.

  • packages/ui/src/mosaic/components/item/index.ts#L1-L2: remove the local re-export barrel.
  • packages/ui/src/mosaic/styles/index.ts#L10-L11: re-export from ../components/item/item directly.

As per coding guidelines, “Avoid barrel files (index.ts re-exports) as they can cause circular dependencies.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/src/mosaic/components/item/index.ts` around lines 1 - 2, Remove
the Item re-export barrel from packages/ui/src/mosaic/components/item/index.ts
lines 1-2. Update packages/ui/src/mosaic/styles/index.ts lines 10-11 to
re-export Item, ItemMediaProps, and ItemProps directly from
../components/item/item, preserving the existing public exports.

Source: Coding guidelines

packages/swingset/src/stories/item.stories.tsx (1)

17-49: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add explicit return types to the story components.

Annotate BuildingIcon, ArrowIcon, and the exported stories with the project’s JSX element return type instead of relying on inference.

As per coding guidelines, “Always define explicit return types for functions, especially public APIs.”

Also applies to: 51-153

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/swingset/src/stories/item.stories.tsx` around lines 17 - 49,
Annotate BuildingIcon, ArrowIcon, and every exported story component in this
file with the project’s established JSX element return type. Apply the same
explicit return-type convention consistently across the story definitions,
including the stories referenced in the additional range, without changing their
rendering behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.changeset/mosaic-item.md:
- Around line 1-2: Add a non-empty changeset for the new public `Item` export
from `@clerk/ui`, specifying the appropriate package bump and a concise release
note describing the API addition. Replace the current empty frontmatter in
`.changeset/mosaic-item.md` while preserving valid changeset formatting.

In `@packages/swingset/src/stories/item.mdx`:
- Around line 37-53: Add the required public Button import and provide a
BuildingIcon import or local definition in the Item usage example so the snippet
is self-contained and compiles when copied; preserve the existing Item.Group
structure and usage.

In `@packages/ui/src/mosaic/components/item/item.tsx`:
- Around line 149-151: Remove the role="list" assignment from Item.Group in
packages/ui/src/mosaic/components/item/item.tsx (lines 149-151), since it cannot
guarantee listitem children; update the corresponding semantic-role assertion in
packages/ui/src/mosaic/components/item/item.test.tsx (lines 91-101), and remove
or revise the role="list" documentation claim in
packages/swingset/src/stories/item.mdx (line 67).
- Around line 16-168: Integrate the Item surface with the customization contract
by defining stable element descriptors for Root and each slot component: Media,
Content, Title, Description, Actions, Footer, Group, and Separator. Pass the
appropriate descriptor through each renderElement call and wrap the exported
primitive components with the repository’s makeCustomizable HOC so appearance
elements overrides can target every Item element.

---

Nitpick comments:
In `@packages/swingset/src/stories/item.stories.tsx`:
- Around line 17-49: Annotate BuildingIcon, ArrowIcon, and every exported story
component in this file with the project’s established JSX element return type.
Apply the same explicit return-type convention consistently across the story
definitions, including the stories referenced in the additional range, without
changing their rendering behavior.

In `@packages/ui/src/mosaic/components/item/index.ts`:
- Around line 1-2: Remove the Item re-export barrel from
packages/ui/src/mosaic/components/item/index.ts lines 1-2. Update
packages/ui/src/mosaic/styles/index.ts lines 10-11 to re-export Item,
ItemMediaProps, and ItemProps directly from ../components/item/item, preserving
the existing public exports.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 41e7b2f0-ab0b-49bc-bdbf-bed0f2e18d58

📥 Commits

Reviewing files that changed from the base of the PR and between 17d1db1 and d37de13.

📒 Files selected for processing (10)
  • .changeset/mosaic-item.md
  • packages/swingset/src/components/DocsViewer.tsx
  • packages/swingset/src/lib/registry.ts
  • packages/swingset/src/stories/item.mdx
  • packages/swingset/src/stories/item.stories.tsx
  • packages/ui/src/mosaic/components/item/index.ts
  • packages/ui/src/mosaic/components/item/item.styles.ts
  • packages/ui/src/mosaic/components/item/item.test.tsx
  • packages/ui/src/mosaic/components/item/item.tsx
  • packages/ui/src/mosaic/styles/index.ts
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • clerk/clerk_go (manual)
  • clerk/dashboard (manual)
  • clerk/accounts (manual)
  • clerk/backoffice (manual)
  • clerk/clerk (manual)
  • clerk/clerk-docs (manual)
  • clerk/cloudflare-workers (manual)
  • clerk/clerk-ios (auto-detected)
  • clerk/cli (auto-detected)
  • clerk/clerk-android (auto-detected)

Comment thread .changeset/mosaic-item.md
Comment thread packages/swingset/src/stories/item.mdx
Comment thread packages/ui/src/mosaic/components/item/item.tsx
Comment thread packages/ui/src/mosaic/components/item/item.tsx Outdated
@pkg-pr-new

pkg-pr-new Bot commented Jul 23, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@9234

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@9234

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@9234

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@9234

@clerk/electron

npm i https://pkg.pr.new/@clerk/electron@9234

@clerk/electron-passkeys

npm i https://pkg.pr.new/@clerk/electron-passkeys@9234

@clerk/eslint-plugin

npm i https://pkg.pr.new/@clerk/eslint-plugin@9234

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@9234

@clerk/expo-google-signin

npm i https://pkg.pr.new/@clerk/expo-google-signin@9234

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@9234

@clerk/express

npm i https://pkg.pr.new/@clerk/express@9234

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@9234

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@9234

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@9234

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@9234

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@9234

@clerk/react

npm i https://pkg.pr.new/@clerk/react@9234

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@9234

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@9234

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@9234

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@9234

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@9234

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@9234

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@9234

commit: c8a8e3e

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

API Changes Report

Generated by Break Check on 2026-07-29T23:42:13.181Z

Summary

Metric Count
Packages analyzed 19
Packages with changes 0
🔴 Breaking changes 0
🟡 Non-breaking changes 0
🟢 Additions 0

No API Changes Detected

All packages have stable APIs with no detected changes.


Report generated by Break Check

Last ran on c8a8e3e.

@alexcarpenter alexcarpenter changed the title feat(ui): add Mosaic Item component with StyleX styling feat(ui): add Mosaic Item component Jul 24, 2026

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/ui/src/mosaic/components/item/item.styles.ts`:
- Around line 77-87: Update the description style in the stylex.create
definition to enable the required legacy WebKit box layout alongside
WebkitLineClamp, preserving the existing two-line clamp and other styling.

In `@packages/ui/src/mosaic/components/item/item.tsx`:
- Around line 8-11: The Item public API is incomplete: add typed variant and
size props, map them to the component’s styling axes, implement the Item.Footer
slot, and assign it on the exported Item component. Update the associated tests
and documentation to cover these APIs, using the existing Item styling and slot
patterns.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: b43b47ad-829e-418f-807a-8b03e013113d

📥 Commits

Reviewing files that changed from the base of the PR and between d37de13 and 45d7685.

📒 Files selected for processing (11)
  • .changeset/mosaic-item.md
  • packages/swingset/src/components/DocsViewer.tsx
  • packages/swingset/src/lib/registry.ts
  • packages/swingset/src/stories/item.mdx
  • packages/swingset/src/stories/item.stories.tsx
  • packages/ui/src/mosaic/components/item/index.ts
  • packages/ui/src/mosaic/components/item/item.styles.ts
  • packages/ui/src/mosaic/components/item/item.test.tsx
  • packages/ui/src/mosaic/components/item/item.tsx
  • packages/ui/src/mosaic/styles/index.ts
  • packages/ui/tsconfig.mosaic.json
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • clerk/clerk_go (manual)
  • clerk/dashboard (manual)
  • clerk/accounts (manual)
  • clerk/backoffice (manual)
  • clerk/clerk (manual)
  • clerk/clerk-docs (manual)
  • clerk/cloudflare-workers (manual)
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/ui/src/mosaic/components/item/index.ts
  • packages/ui/src/mosaic/styles/index.ts
  • .changeset/mosaic-item.md
  • packages/swingset/src/components/DocsViewer.tsx

Comment thread packages/ui/src/mosaic/components/item/item.styles.ts
Comment thread packages/ui/src/mosaic/components/item/item.tsx Outdated

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
references/mosaic-architecture.md (1)

124-126: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a migration guide for the styling-contract transition.

The documentation introduces new .cl-*/data-* selectors alongside the legacy data-cl-* contract, but provides no before/after migration example. Add a short migration section explaining which selectors apply to legacy and StyleX-authored components.

As per coding guidelines, Markdown files must include migration guides for breaking changes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@references/mosaic-architecture.md` around lines 124 - 126, Add a concise
migration section near “Appearance & cascade” documenting the transition from
legacy data-cl-* selectors to the new .cl-* and data-* contract. Include a
before/after example and clearly state which selectors apply to Emotion
slot-recipe components versus StyleX-authored components, including that StyleX
uses className/style and does not read appearance.elements.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@references/mosaic-architecture.md`:
- Line 9: Update the styling contract statements in the overview and API
sections to scope `.cl-<slot>` classes and `data-<axis>` attributes to
StyleX-authored parts only. Explicitly distinguish legacy slot-recipe
components, which retain the `data-cl-slot` and `data-cl-*` contract, and remove
any wording that implies every Mosaic part emits the StyleX class contract.

---

Nitpick comments:
In `@references/mosaic-architecture.md`:
- Around line 124-126: Add a concise migration section near “Appearance &
cascade” documenting the transition from legacy data-cl-* selectors to the new
.cl-* and data-* contract. Include a before/after example and clearly state
which selectors apply to Emotion slot-recipe components versus StyleX-authored
components, including that StyleX uses className/style and does not read
appearance.elements.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: bb2d4296-cad5-49f0-b9e0-a57c3da0ef98

📥 Commits

Reviewing files that changed from the base of the PR and between 45d7685 and 497a792.

📒 Files selected for processing (1)
  • references/mosaic-architecture.md
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • clerk/clerk_go (manual)
  • clerk/dashboard (manual)
  • clerk/accounts (manual)
  • clerk/backoffice (manual)
  • clerk/clerk (manual)
  • clerk/clerk-docs (manual)
  • clerk/cloudflare-workers (manual)

Comment thread references/mosaic-architecture.md
The Mosaic StyleX build resolved @clerk/headless types against its published
dist .d.ts re-export barrels, which rolldown-plugin-dts can't follow when
inlining a bundled dependency. Since @clerk/headless is private and must be
inlined, map it to source in tsconfig.mosaic.json (the monorepo default, same
pattern already used for @/core/*), so Mosaic components can import headless
types directly.
Add a Mosaic `Item` component for lists of accounts, organizations, and
settings rows. Composed via dot syntax (`Item.Media`, `Item.Content`,
`Item.Title`, `Item.Description`, `Item.Actions`, `Item.Footer`,
`Item.Group`, `Item.Separator`) with `default`/`outline`/`muted` variants and
`default`/`sm` sizes. Per-slot StyleX styles compile into the shared sheet, and
a `render` prop allows an item to render as a link or button. Includes swingset
docs and stories.
Replace the Item size prop with a variant-driven density: entity (8px)
and action (10px). Add JSDoc to every Item part and fix the Header parts'
display names.
The group wraps interactive rows that carry their own semantics and can
include a header, so a list role (with no listitem children) was
misleading. Leave the wrapper unlabelled.
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.

2 participants