Skip to content

feat(ui): Add experimental mosaic components export#9045

Open
alexcarpenter wants to merge 17 commits into
mainfrom
feat/mosaic-experimental-export
Open

feat(ui): Add experimental mosaic components export#9045
alexcarpenter wants to merge 17 commits into
mainfrom
feat/mosaic-experimental-export

Conversation

@alexcarpenter

@alexcarpenter alexcarpenter commented Jun 30, 2026

Copy link
Copy Markdown
Member

Description

New @clerk/ui/experimental/mosaic entry.

Exports:

  • MosaicProvider — styling/appearance + emotion cache.
  • OrganizationProfile (compound: .GeneralPanel/.LeaveSection/.DeleteSection) — client-only, consumer needs 'use client' (property access on client ref can't cross RSC boundary).
  • flat parts OrganizationProfile{GeneralPanel,LeaveSection,DeleteSection} — each own client ref, drop straight into RSC, no consumer 'use client'.

Entry carries 'use client' (hooks/context/emotion). Components gate on Clerk loaded → render null til ready, so no server markup; UI after hydration.

Preview: https://swingset-git-feat-mosaic-experimental-export.clerkstage.dev/

Summary by CodeRabbit

  • New Features
    • Split the organization profile experience into General, Leave, and Delete sections.
    • Added an experimental Mosaic entrypoint exporting organization profile components.
    • Updated the sidebar menu to clearly distinguish hook-style vs component-style entries.
  • Bug Fixes
    • Improved Mosaic styling stability with deterministic style insertion, scoped CSS reset, and optional support for emitting generated styles into a named CSS layer.
    • Updated Icon overrides to use element-based overrides and correctly merge class names.

@changeset-bot

changeset-bot Bot commented Jun 30, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 98ef8ea

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

This PR includes changesets to release 3 packages
Name Type
@clerk/ui Patch
@clerk/chrome-extension Patch
@clerk/swingset Patch

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 Jun 30, 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 6, 2026 2:13pm
swingset Error Error Jul 6, 2026 2:13pm

Request Review

@coderabbitai

coderabbitai Bot commented Jun 30, 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

The PR restructures Mosaic organization profile into compound section components, updates MosaicProvider styling insertion and reset behavior, adds an experimental Mosaic entrypoint, and rewires swingset stories, registry entries, and docs to the new organization-profile structure.

Changes

Organization Profile section/controller restructure

Layer / File(s) Summary
Delete section machine, controller, view and component
packages/ui/src/mosaic/organization/organization-profile-delete-section.{machine,controller,tsx,view}.tsx, packages/ui/src/mosaic/organization/__tests__/organization-profile-delete-section.*, packages/ui/src/mosaic/machine/__tests__/delete-organization-machine.ts
Renames the delete-organization flow to organization-profile delete section types, updates the controller to navigate after successful deletion, adds the new section component, and updates the view and tests.
Leave section machine, controller, view and component
packages/ui/src/mosaic/organization/organization-profile-leave-section.{machine,controller,tsx,view}.tsx, packages/ui/src/mosaic/organization/__tests__/organization-profile-leave-section.*
Renames the leave-organization flow to organization-profile leave section types, replaces membership-destroy behavior with self-leave plus revalidation and navigation, adds the new section component, and updates the view and tests.
Compound OrganizationProfile export, controller, hooks and panels
packages/ui/src/mosaic/organization/{organization-profile.controller.tsx,organization-profile.tsx,organization-profile-general-panel*.tsx}, packages/ui/src/mosaic/aio/organization-profile.tsx, packages/ui/src/mosaic/hooks/useMosaic{Environment,Router}.ts, packages/ui/src/mosaic/organization/__tests__/organization-profile*.test.tsx
Adds the organization profile controller and root gate, exports OrganizationProfile as a compound namespace with attached sections, introduces the general panel wrapper, and adds the supporting hooks and equivalence tests.

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

MosaicProvider insertion point and CSS reset

Layer / File(s) Summary
Insertion point and reset injection
packages/ui/src/mosaic/MosaicProvider.tsx, packages/ui/src/mosaic/__tests__/MosaicProvider.test.tsx, packages/ui/src/mosaic/__tests__/MosaicProvider.ssr.test.tsx
Creates the insertion anchor when missing, defines the zero-specificity reset CSS, injects it through MosaicProvider, and updates tests for reset content, layering, and insertion-point reuse.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Public experimental/mosaic export surface

Layer / File(s) Summary
experimental entrypoint and icon override contract
packages/ui/src/experimental/mosaic.ts, packages/ui/src/experimental/__tests__/mosaic.test.tsx, packages/ui/package.json, packages/ui/tsdown.config.mts, .changeset/open-heads-brush.md, packages/ui/src/mosaic/appearance.ts, packages/ui/src/mosaic/components/icon.tsx, packages/ui/src/mosaic/__tests__/icon.test.tsx, packages/swingset/src/stories/icon.stories.tsx, packages/ui/src/mosaic/slot-recipe.ts
Introduces the experimental/mosaic module, package export wiring, build entrypoint, equivalence test, changeset, and the element-based icon override API and cloning behavior.

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

Swingset storybook, registry, and docs restructuring

Layer / File(s) Summary
Registry, docs, and story files
packages/swingset/src/lib/registry.ts, packages/swingset/src/components/DocsViewer.tsx, packages/swingset/src/stories/organization-profile*, references/mosaic-architecture.md
Changes registry imports and modules, docs module grouping, organization-profile story files and MDX composition, and the architecture reference naming convention.
Layer ordering and sidebar usage labels
packages/swingset/src/components/Composition.tsx, packages/swingset/src/components/app-sidebar.tsx
Updates the composition layer ranking and the sidebar label rendering for hooks and components.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

  • clerk/javascript#8838: Initial Mosaic organization-profile layering and story wiring that this PR renames and restructures.
  • clerk/javascript#9017: Related organization-profile controller and machine changes that use Clerk-backed hooks and post-action revalidation.
  • clerk/javascript#9041: Directly connected legacy delete/leave Mosaic section removal and replacement with the new organization-profile-specific modules.

Suggested reviewers: wobsoriano

Poem

A rabbit hops through mosaic tiles anew,
Delete and leave now wear a sectioned view. 🐇
A style tag blooms where insertion points grow,
Compound exports bundle the helpers in a row.
Through swingset stories the carrots align —
Hop, ship, and let this refactor shine! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.71% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately reflects the main change: adding an experimental Mosaic export in @clerk/ui.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Biome (2.5.1)
packages/swingset/src/lib/registry.ts

File contains syntax errors that prevent linting: Line 54: Expected an expression but instead found '}'.


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

@pkg-pr-new

pkg-pr-new Bot commented Jun 30, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/electron

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

@clerk/electron-passkeys

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

@clerk/eslint-plugin

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

@clerk/expo

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 27cb37a

@alexcarpenter

Copy link
Copy Markdown
Member Author

!snapshot

@alexcarpenter

Copy link
Copy Markdown
Member Author

!snapshot

@github-actions

This comment has been minimized.

@alexcarpenter

Copy link
Copy Markdown
Member Author

!snapshot

@github-actions

This comment has been minimized.

@alexcarpenter

Copy link
Copy Markdown
Member Author

!snapshot

@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

Hey @alexcarpenter - the snapshot version command generated the following package versions:

Package Version
@clerk/astro 3.4.11-snapshot.v20260630204952
@clerk/backend 3.9.1-snapshot.v20260630204952
@clerk/chrome-extension 3.1.47-snapshot.v20260630204952
@clerk/clerk-js 6.23.1-snapshot.v20260630204952
@clerk/electron 0.0.8-snapshot.v20260630204952
@clerk/electron-passkeys 0.0.4-snapshot.v20260630204952
@clerk/eslint-plugin 0.2.1-snapshot.v20260630204952
@clerk/expo 3.6.5-snapshot.v20260630204952
@clerk/expo-passkeys 1.1.13-snapshot.v20260630204952
@clerk/express 2.1.35-snapshot.v20260630204952
@clerk/fastify 3.1.45-snapshot.v20260630204952
@clerk/headless 0.0.7-snapshot.v20260630204952
@clerk/hono 0.1.45-snapshot.v20260630204952
@clerk/localizations 4.12.1-snapshot.v20260630204952
@clerk/msw 0.0.43-snapshot.v20260630204952
@clerk/nextjs 7.5.12-snapshot.v20260630204952
@clerk/nuxt 2.6.11-snapshot.v20260630204952
@clerk/react 6.11.4-snapshot.v20260630204952
@clerk/react-router 3.5.4-snapshot.v20260630204952
@clerk/shared 4.23.1-snapshot.v20260630204952
@clerk/swingset 0.0.13-snapshot.v20260630204952
@clerk/tanstack-react-start 1.4.12-snapshot.v20260630204952
@clerk/testing 2.2.2-snapshot.v20260630204952
@clerk/ui 1.24.1-snapshot.v20260630204952
@clerk/upgrade 2.0.5-snapshot.v20260630204952
@clerk/vue 2.4.11-snapshot.v20260630204952

Tip: Use the snippet copy button below to quickly install the required packages.
@clerk/astro

npm i @clerk/astro@3.4.11-snapshot.v20260630204952 --save-exact

@clerk/backend

npm i @clerk/backend@3.9.1-snapshot.v20260630204952 --save-exact

@clerk/chrome-extension

npm i @clerk/chrome-extension@3.1.47-snapshot.v20260630204952 --save-exact

@clerk/clerk-js

npm i @clerk/clerk-js@6.23.1-snapshot.v20260630204952 --save-exact

@clerk/electron

npm i @clerk/electron@0.0.8-snapshot.v20260630204952 --save-exact

@clerk/electron-passkeys

npm i @clerk/electron-passkeys@0.0.4-snapshot.v20260630204952 --save-exact

@clerk/eslint-plugin

npm i @clerk/eslint-plugin@0.2.1-snapshot.v20260630204952 --save-exact

@clerk/expo

npm i @clerk/expo@3.6.5-snapshot.v20260630204952 --save-exact

@clerk/expo-passkeys

npm i @clerk/expo-passkeys@1.1.13-snapshot.v20260630204952 --save-exact

@clerk/express

npm i @clerk/express@2.1.35-snapshot.v20260630204952 --save-exact

@clerk/fastify

npm i @clerk/fastify@3.1.45-snapshot.v20260630204952 --save-exact

@clerk/headless

npm i @clerk/headless@0.0.7-snapshot.v20260630204952 --save-exact

@clerk/hono

npm i @clerk/hono@0.1.45-snapshot.v20260630204952 --save-exact

@clerk/localizations

npm i @clerk/localizations@4.12.1-snapshot.v20260630204952 --save-exact

@clerk/msw

npm i @clerk/msw@0.0.43-snapshot.v20260630204952 --save-exact

@clerk/nextjs

npm i @clerk/nextjs@7.5.12-snapshot.v20260630204952 --save-exact

@clerk/nuxt

npm i @clerk/nuxt@2.6.11-snapshot.v20260630204952 --save-exact

@clerk/react

npm i @clerk/react@6.11.4-snapshot.v20260630204952 --save-exact

@clerk/react-router

npm i @clerk/react-router@3.5.4-snapshot.v20260630204952 --save-exact

@clerk/shared

npm i @clerk/shared@4.23.1-snapshot.v20260630204952 --save-exact

@clerk/swingset

npm i @clerk/swingset@0.0.13-snapshot.v20260630204952 --save-exact

@clerk/tanstack-react-start

npm i @clerk/tanstack-react-start@1.4.12-snapshot.v20260630204952 --save-exact

@clerk/testing

npm i @clerk/testing@2.2.2-snapshot.v20260630204952 --save-exact

@clerk/ui

npm i @clerk/ui@1.24.1-snapshot.v20260630204952 --save-exact

@clerk/upgrade

npm i @clerk/upgrade@2.0.5-snapshot.v20260630204952 --save-exact

@clerk/vue

npm i @clerk/vue@2.4.11-snapshot.v20260630204952 --save-exact

Comment on lines +6 to +10
import { expandConditions } from './conditions';
import { useMosaicTheme } from './MosaicProvider';
import { resolveSlotClassName, resolveSlotCss } from './resolveSlot';
import { defaultMosaicVariables, resolveVariables } from './variables';
import type { MosaicTheme } from './variables';
import { defaultMosaicVariables, resolveVariables } from './variables';

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

just a sorting change

…imental exports

Rename the experimental Mosaic parts and their files so the source symbols match how they are exported from @clerk/ui/experimental/mosaic:

- DeleteOrganization -> OrganizationProfileDeleteSection
- LeaveOrganization -> OrganizationProfileLeaveSection
- OrganizationProfileGeneral -> OrganizationProfileGeneralPanel
- OrganizationProfile unchanged

The rename cascades through each part's view, controller, and machine symbols and their co-located tests. The experimental entry no longer needs to alias on re-export.

In @clerk/swingset, flatten the AIO/Panels/Sections sidebar groups into a single Organization group, and render each entry by its export name (components as <Name />, hooks as useName()), wrapping long names instead of overflowing.

Public export names from @clerk/ui/experimental/mosaic are unchanged, so there is no user-facing impact.
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

API Changes Report

Generated by Break Check on 2026-07-06T14:15:12.166Z

Summary

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

@clerk/ui

Current version: 1.24.2
Recommended bump: MINOR → 1.25.0

Subpath ./experimental/mosaic

🟢 Additions (1)

Added: ./experimental/mosaic

New subpath export ./experimental/mosaic (15 exported members)


Report generated by Break Check

Last ran on 98ef8ea.

@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 (5)
packages/ui/src/experimental/mosaic.ts (1)

3-40: 🧹 Nitpick | 🔵 Trivial

Docs team should review this public entrypoint JSDoc.

This module-level doc will surface in generated Clerk Docs, so please confirm the RSC/client-boundary wording and exported surface stay aligned with the intended public API.

As per path instructions, public/reference-facing APIs may appear in generated docs.

🤖 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/experimental/mosaic.ts` around lines 3 - 40, The module JSDoc
in Mosaic’s experimental entrypoint needs a docs review to ensure its client/RSC
boundary explanation and exported API description match the actual public
surface. Update the comment around the top-level exports from mosaic.ts so it
accurately reflects what consumers can import and how OrganizationProfile versus
the flat panel/section exports should be used, keeping the wording aligned with
the intended Clerk Docs output.

Source: Path instructions

packages/ui/src/mosaic/sections/organization-profile-delete-section.tsx (1)

6-18: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding JSDoc for this public flat export.

OrganizationProfileDeleteSection is one of the flat exports intended for direct RSC usage per the PR summary. Since Clerk Docs generates reference pages from JSDoc on public/reference-facing APIs, consider documenting this component (purpose, usage note about requiring MosaicProvider, etc.) so it renders correctly in generated docs.

As per path instructions, "If a PR adds or changes public/reference-facing API surface area, check whether the corresponding JSDoc is present, accurate, and aligned with the implementation" and reference-facing changes "may need Docs-team review."

🤖 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/sections/organization-profile-delete-section.tsx`
around lines 6 - 18, Add JSDoc to the public flat export
OrganizationProfileDeleteSection so Docs can generate a reference page for it.
Document its purpose, the direct RSC usage intent, and the requirement that it
be rendered within MosaicProvider, keeping the description aligned with the
implementation and other reference-facing exports in this area.

Source: Path instructions

packages/ui/src/mosaic/aio/organization-profile.tsx (1)

9-30: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add JSDoc on the OrganizationProfile compound export.

OrganizationProfile is the primary public export of the new experimental/mosaic entrypoint (compound with .GeneralPanel, .LeaveSection, .DeleteSection). Since it's reference-facing, consider adding a JSDoc block (purpose, required MosaicProvider ancestor, 'use client' requirement noted in the PR description, and documenting the attached parts) so generated docs reflect this API accurately.

As per path instructions, "If a PR adds or changes public/reference-facing API surface area, check whether the corresponding JSDoc is present, accurate, and aligned with the implementation."

🤖 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/aio/organization-profile.tsx` around lines 9 - 30, Add
a JSDoc block to the public OrganizationProfile export so the reference docs
capture this compound API accurately. Document that OrganizationProfile is the
primary experimental/mosaic entrypoint, that it requires a MosaicProvider
ancestor and a client-only environment, and list the attached compound parts
(GeneralPanel, LeaveSection, DeleteSection). Place the comment on the
OrganizationProfile binding in organization-profile.tsx so it stays aligned with
the implementation and its Object.assign-based export shape.

Source: Path instructions

packages/ui/src/mosaic/panels/organization-profile-general-panel.tsx (1)

7-14: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding JSDoc for this public flat export.

Same as OrganizationProfileDeleteSectionOrganizationProfileGeneralPanel is one of the flat exports intended for direct RSC usage. Documenting it would help keep generated reference docs accurate for this new public surface.

As per path instructions, reference-facing exports should have JSDoc so generated docs reflect the implementation.

🤖 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/panels/organization-profile-general-panel.tsx` around
lines 7 - 14, Add JSDoc to the public flat export
OrganizationProfileGeneralPanel so generated reference docs include it for
direct RSC usage. Update the function declaration in
OrganizationProfileGeneralPanel to include a concise descriptive comment,
matching the documentation style used by OrganizationProfileDeleteSection and
other reference-facing exports.

Source: Path instructions

packages/ui/src/mosaic/sections/organization-profile-delete-section.controller.tsx (1)

23-42: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate post-action navigation logic vs. leave controller.

The revalidate + fire-and-forget router.navigate(afterLeaveUrl) block (Lines 36-42) is duplicated nearly verbatim in organization-profile-leave-section.controller.tsx. Consider extracting a small shared hook (e.g., useAfterOrgActionNavigate(afterLeaveUrl)) since more sections are being added to this namespace.

♻️ Sketch of a shared helper
// packages/ui/src/mosaic/hooks/useAfterOrgActionNavigate.ts
export function useAfterOrgActionNavigate() {
  const router = useMosaicRouter();
  const afterLeaveUrl = useMosaicEnvironment()?.displayConfig.afterLeaveOrganizationUrl;
  return () => {
    if (afterLeaveUrl) {
      void router.navigate(afterLeaveUrl);
    }
  };
}
🤖 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/sections/organization-profile-delete-section.controller.tsx`
around lines 23 - 42, The post-action navigation/revalidate logic inside
useOrganizationProfileDeleteSectionController is duplicated in the leave
controller, so extract the shared “after org action” behavior into a reusable
hook or helper and call it from both controllers. Keep the existing
destroy/revalidate flow in organizationProfileDeleteSectionMachine’s context,
but move the afterLeaveUrl lookup and fire-and-forget router.navigate behavior
into a shared function such as useAfterOrgActionNavigate so future organization
sections can reuse it.
🤖 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/__tests__/MosaicProvider.test.tsx`:
- Around line 85-94: The MosaicProvider reset test only covers the unlayered CSS
path; extend the existing test around MosaicProvider/styleText to also assert
the layered reset output when cssLayerName is provided and that the nonce value
is forwarded to the generated style tag. Use the existing `MosaicProvider`
render setup and `styleText()` assertions to verify both the wrapped CSS branch
and nonce propagation, alongside the current `:where([data-cl-slot])` reset
checks.

---

Nitpick comments:
In `@packages/ui/src/experimental/mosaic.ts`:
- Around line 3-40: The module JSDoc in Mosaic’s experimental entrypoint needs a
docs review to ensure its client/RSC boundary explanation and exported API
description match the actual public surface. Update the comment around the
top-level exports from mosaic.ts so it accurately reflects what consumers can
import and how OrganizationProfile versus the flat panel/section exports should
be used, keeping the wording aligned with the intended Clerk Docs output.

In `@packages/ui/src/mosaic/aio/organization-profile.tsx`:
- Around line 9-30: Add a JSDoc block to the public OrganizationProfile export
so the reference docs capture this compound API accurately. Document that
OrganizationProfile is the primary experimental/mosaic entrypoint, that it
requires a MosaicProvider ancestor and a client-only environment, and list the
attached compound parts (GeneralPanel, LeaveSection, DeleteSection). Place the
comment on the OrganizationProfile binding in organization-profile.tsx so it
stays aligned with the implementation and its Object.assign-based export shape.

In `@packages/ui/src/mosaic/panels/organization-profile-general-panel.tsx`:
- Around line 7-14: Add JSDoc to the public flat export
OrganizationProfileGeneralPanel so generated reference docs include it for
direct RSC usage. Update the function declaration in
OrganizationProfileGeneralPanel to include a concise descriptive comment,
matching the documentation style used by OrganizationProfileDeleteSection and
other reference-facing exports.

In
`@packages/ui/src/mosaic/sections/organization-profile-delete-section.controller.tsx`:
- Around line 23-42: The post-action navigation/revalidate logic inside
useOrganizationProfileDeleteSectionController is duplicated in the leave
controller, so extract the shared “after org action” behavior into a reusable
hook or helper and call it from both controllers. Keep the existing
destroy/revalidate flow in organizationProfileDeleteSectionMachine’s context,
but move the afterLeaveUrl lookup and fire-and-forget router.navigate behavior
into a shared function such as useAfterOrgActionNavigate so future organization
sections can reuse it.

In `@packages/ui/src/mosaic/sections/organization-profile-delete-section.tsx`:
- Around line 6-18: Add JSDoc to the public flat export
OrganizationProfileDeleteSection so Docs can generate a reference page for it.
Document its purpose, the direct RSC usage intent, and the requirement that it
be rendered within MosaicProvider, keeping the description aligned with the
implementation and other reference-facing exports in this area.
🪄 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), Repository UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: e135a058-7b33-4d86-98fd-ad4eaf44879e

📥 Commits

Reviewing files that changed from the base of the PR and between feac5f3 and 2fb9cbd.

📒 Files selected for processing (51)
  • .changeset/open-heads-brush.md
  • packages/swingset/src/components/Composition.tsx
  • packages/swingset/src/components/DocsViewer.tsx
  • packages/swingset/src/components/app-sidebar.tsx
  • packages/swingset/src/lib/registry.ts
  • packages/swingset/src/stories/delete-organization.stories.tsx
  • packages/swingset/src/stories/leave-organization.stories.tsx
  • packages/swingset/src/stories/organization-profile-delete-section.mdx
  • packages/swingset/src/stories/organization-profile-delete-section.stories.tsx
  • packages/swingset/src/stories/organization-profile-general-panel.mdx
  • packages/swingset/src/stories/organization-profile-general-panel.stories.tsx
  • packages/swingset/src/stories/organization-profile-general.mdx
  • packages/swingset/src/stories/organization-profile-general.stories.tsx
  • packages/swingset/src/stories/organization-profile-leave-section.mdx
  • packages/swingset/src/stories/organization-profile-leave-section.stories.tsx
  • packages/swingset/src/stories/organization-profile.mdx
  • packages/swingset/src/stories/organization-profile.stories.tsx
  • packages/ui/package.json
  • packages/ui/src/experimental/__tests__/mosaic.test.tsx
  • packages/ui/src/experimental/mosaic.ts
  • packages/ui/src/mosaic/MosaicProvider.tsx
  • packages/ui/src/mosaic/__tests__/MosaicProvider.test.tsx
  • packages/ui/src/mosaic/aio/__tests__/organization-profile.controller.test.tsx
  • packages/ui/src/mosaic/aio/__tests__/organization-profile.test.tsx
  • packages/ui/src/mosaic/aio/organization-profile.controller.tsx
  • packages/ui/src/mosaic/aio/organization-profile.tsx
  • packages/ui/src/mosaic/hooks/useMosaicEnvironment.ts
  • packages/ui/src/mosaic/hooks/useMosaicRouter.ts
  • packages/ui/src/mosaic/machine/__tests__/delete-organization-machine.ts
  • packages/ui/src/mosaic/panels/organization-profile-general-panel-view.tsx
  • packages/ui/src/mosaic/panels/organization-profile-general-panel.tsx
  • packages/ui/src/mosaic/panels/organization-profile-general.tsx
  • packages/ui/src/mosaic/sections/__tests__/organization-profile-delete-section.controller.test.tsx
  • packages/ui/src/mosaic/sections/__tests__/organization-profile-delete-section.machine.test.ts
  • packages/ui/src/mosaic/sections/__tests__/organization-profile-delete-section.view.test.tsx
  • packages/ui/src/mosaic/sections/__tests__/organization-profile-leave-section.controller.test.tsx
  • packages/ui/src/mosaic/sections/__tests__/organization-profile-leave-section.machine.test.ts
  • packages/ui/src/mosaic/sections/__tests__/organization-profile-leave-section.view.test.tsx
  • packages/ui/src/mosaic/sections/delete-organization.tsx
  • packages/ui/src/mosaic/sections/leave-organization.controller.tsx
  • packages/ui/src/mosaic/sections/leave-organization.tsx
  • packages/ui/src/mosaic/sections/organization-profile-delete-section.controller.tsx
  • packages/ui/src/mosaic/sections/organization-profile-delete-section.machine.ts
  • packages/ui/src/mosaic/sections/organization-profile-delete-section.tsx
  • packages/ui/src/mosaic/sections/organization-profile-delete-section.view.tsx
  • packages/ui/src/mosaic/sections/organization-profile-leave-section.controller.tsx
  • packages/ui/src/mosaic/sections/organization-profile-leave-section.machine.ts
  • packages/ui/src/mosaic/sections/organization-profile-leave-section.tsx
  • packages/ui/src/mosaic/sections/organization-profile-leave-section.view.tsx
  • packages/ui/src/mosaic/slot-recipe.ts
  • packages/ui/tsdown.config.mts
💤 Files with no reviewable changes (8)
  • packages/ui/src/mosaic/sections/delete-organization.tsx
  • packages/swingset/src/stories/delete-organization.stories.tsx
  • packages/swingset/src/stories/leave-organization.stories.tsx
  • packages/ui/src/mosaic/sections/leave-organization.tsx
  • packages/ui/src/mosaic/panels/organization-profile-general.tsx
  • packages/swingset/src/stories/organization-profile-general.mdx
  • packages/ui/src/mosaic/sections/leave-organization.controller.tsx
  • packages/swingset/src/stories/organization-profile-general.stories.tsx

Comment thread packages/ui/src/mosaic/__tests__/MosaicProvider.test.tsx
const icons = React.useMemo(() => appearance?.icons ?? {}, [appearance]);
const cache = React.useMemo(() => {
const el = getInsertionPoint();
const el = ensureInsertionPoint();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

cssLayerName only wraps the reset <style> below; styles generated through this cache are inserted unlayered, so they outrank a consumer's layered app styles. StyleCacheProvider solves this by wrapping cache.insert with @layer, and this memo already mirrors its prepend logic, so it looks like the insert wrap got left behind; mirroring it (or sharing a cache factory) fixes it.

🤖 Generated with Claude Code

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

fixed in 61d1f45

also changed how the icon overrides work to be serialize-able too.

Wrap the Mosaic Emotion cache's insert with @layer so generated component styles carry the same layer as the reset (mirroring StyleCacheProvider). Previously only the reset was layered, so component styles were inserted unlayered and outranked a consumer's @layer-ed app styles.

Change appearance.icons overrides from render functions to React elements, injected via cloneElement. Elements serialize across the RSC server/client boundary, so consumers can supply icon overrides from a Server Component.

@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

🤖 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/icon.tsx`:
- Around line 40-66: The override path in Icon drops the forwarded ref, so refs
only work for the built-in SVG branch. Update the MosaicIcon forwardRef handler
to pass the received ref into React.cloneElement for the override element,
alongside the existing props/className/data-cl-slot injection, and add a
regression test that verifies consumer refs resolve for overridden icons as well
as the default glyph.
🪄 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), Repository UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 52840a83-c54e-4ee9-9912-011db6c6f5fb

📥 Commits

Reviewing files that changed from the base of the PR and between c1e7c00 and 61d1f45.

📒 Files selected for processing (7)
  • packages/swingset/src/stories/icon.stories.tsx
  • packages/ui/src/mosaic/MosaicProvider.tsx
  • packages/ui/src/mosaic/__tests__/MosaicProvider.ssr.test.tsx
  • packages/ui/src/mosaic/__tests__/MosaicProvider.test.tsx
  • packages/ui/src/mosaic/__tests__/icon.test.tsx
  • packages/ui/src/mosaic/appearance.ts
  • packages/ui/src/mosaic/components/icon.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/ui/src/mosaic/MosaicProvider.tsx

Comment thread packages/ui/src/mosaic/components/icon.tsx

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/swingset/src/lib/registry.ts (1)

35-55: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Fix the broken import block in packages/swingset/src/lib/registry.ts
Restore the missing import { before Default as OrganizationProfileGeneralDefault; as written, this file won’t parse. The leftover block also points at ../stories/organization-profile-general.stories, which no longer exists, so remove it or switch it to the renamed panel story if that’s the intended import.

🤖 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/lib/registry.ts` around lines 35 - 55, The import block
in registry.ts is broken because the OrganizationProfileGeneralDefault entry is
missing its import opening and still references a non-existent
organization-profile-general.stories module. Fix the import group around
OrganizationProfileGeneralDefault and organizationProfileGeneralMeta so it
parses correctly, and either remove that import or update it to use the renamed
organization-profile-general-panel.stories source consistently with the other
story imports.

Source: Linters/SAST tools

🤖 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.

Outside diff comments:
In `@packages/swingset/src/lib/registry.ts`:
- Around line 35-55: The import block in registry.ts is broken because the
OrganizationProfileGeneralDefault entry is missing its import opening and still
references a non-existent organization-profile-general.stories module. Fix the
import group around OrganizationProfileGeneralDefault and
organizationProfileGeneralMeta so it parses correctly, and either remove that
import or update it to use the renamed
organization-profile-general-panel.stories source consistently with the other
story imports.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro Plus

Run ID: 5c024363-df5e-4e48-be7c-52e6fd92c56e

📥 Commits

Reviewing files that changed from the base of the PR and between 27cb37a and 98ef8ea.

📒 Files selected for processing (3)
  • packages/swingset/src/components/DocsViewer.tsx
  • packages/swingset/src/lib/registry.ts
  • packages/ui/package.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/swingset/src/components/DocsViewer.tsx
  • packages/ui/package.json

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