Skip to content

feat(ui): Add mosaic design systems foundations#8755

Open
alexcarpenter wants to merge 18 commits into
mainfrom
carp/mosaic-infra
Open

feat(ui): Add mosaic design systems foundations#8755
alexcarpenter wants to merge 18 commits into
mainfrom
carp/mosaic-infra

Conversation

@alexcarpenter
Copy link
Copy Markdown
Member

@alexcarpenter alexcarpenter commented Jun 5, 2026

Description

  • Mosaic design system foundations: token-driven cva(), MosaicProvider with theme context, sx prop for one-off overrides
  • Token primitives: color (oklch, light-dark), spacing (multiplier fn), radius scale, fontSize scale with paired line-heights (Tailwind v4 convention)
  • Theme helpers: spacing(n), alpha(color, %), mix(a, b, %), text(size) — all return literal CSS values, spreadable into style objects
  • Button reference component demonstrating variant composition via cva()

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:

Summary by CodeRabbit

  • New Features

    • Introduced the Mosaic design system: default tokens, theme resolver, provider + hook, theme helpers (spacing, alpha, mix, text) and a theme-aware variant utility (cva).
    • Added a Mosaic Button component with customizable variants for layout, typography, color, size, and states.
  • Documentation

    • Added a comprehensive Mosaic architecture guide with token details, patterns, and migration guidance.
  • Tests

    • Added an extensive test suite validating the variant utility and TypeScript typings.
  • Chores

    • Added a changeset declaring the new Mosaic foundations.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Jun 5, 2026

🦋 Changeset detected

Latest commit: 761ad3a

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

This PR includes changesets to release 2 packages
Name Type
@clerk/ui Minor
@clerk/chrome-extension 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
Copy link
Copy Markdown

vercel Bot commented Jun 5, 2026

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

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment Jun 5, 2026 7:50pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 5, 2026

Linter diff in the way? Review this PR in Change Stack to focus on meaningful changes and expand context only when needed.

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 Mosaic design-system foundations: frozen token defaults and resolver, MosaicProvider with Emotion cache and optional CSS layer wrapping, a theme-aware cva utility with tests, a reference Button component, architecture documentation, and a release changeset.

Changes

Mosaic Design System Implementation

Layer / File(s) Summary
Token types and theme resolution
packages/ui/src/mosaic/variables.ts
Defines frozen default token values and TypeScript types (MosaicTokens, MosaicVariables, MosaicTheme) and implements resolveVariables() to deep-merge overrides and provide helper functions (spacing, alpha, mix, text).
Theme provider and context delivery
packages/ui/src/mosaic/MosaicProvider.tsx
MosaicProvider resolves theme variables, creates an Emotion cache with optional insertion point and nonce, and conditionally wraps generated CSS in an @layer when cssLayerName is provided. Exports useMosaicTheme() to access the resolved theme from context.
CVA variant system implementation
packages/ui/src/mosaic/cva.ts
Adds cva with static and theme-aware overloads, variant resolution (including boolean coercion), base/variant/compound application, optional sx merging, and CSS-variable key sanitization.
CVA variant system test coverage
packages/ui/src/mosaic/__tests__/cva.test.ts
Vitest suite validating cva behavior across base styles, variants, defaultVariants, boolean and compound variants, deep merging (including pseudo-selectors), CSS variable sanitization, theme-aware configs, handling of unknown/null props, and TypeScript VariantProps inference.
Button component example
packages/ui/src/mosaic/Button.tsx
Reference Button using buttonStyles from cva, reads theme via useMosaicTheme(), applies computed css, and forwards native button props and ref.
Mosaic architecture documentation
references/mosaic-architecture.md
Documentation covering token model, resolveVariables, provider delivery via context, cva design and typing, component authoring pattern, coexistence rules with Emotion theming, and migration steps.
Documentation reference
AGENTS.md
Adds a reference link to references/mosaic-architecture.md in the References section.
Release changeset
.changeset/mosaic-design-system-foundations.md
Adds a minor-release changeset describing the Mosaic foundations and the new UI primitives.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • jacekradko

Poem

🐰 Mosaic hops in with tokens bright and keen,
cva stitches styles where variants convene,
Provider hums themes into context's nest,
Buttons wear tokens, tests ensure the rest,
A rabbit applauds the interface scene!

🚥 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(ui): Add mosaic design systems foundations' accurately and clearly summarizes the primary change: introducing the foundational pieces of a new Mosaic design system including tokens, provider, utilities, and a reference component.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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 and usage tips.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Jun 5, 2026

Open in StackBlitz

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/expo

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 761ad3a

@alexcarpenter alexcarpenter marked this pull request as ready for review June 5, 2026 17:28
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 5, 2026

Break Check: no API changes detected across the tracked packages.

Last ran on 761ad3a. Pushes that change no tracked declarations (no API surface change vs. base) are skipped and don't update this comment.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (1)
packages/ui/src/mosaic/__tests__/cva.test.ts (1)

255-282: ⚡ Quick win

Add an sx merge test to cover a key cva execution path.

This suite is strong, but it doesn’t currently assert sx override/deep-merge behavior, which is part of cva runtime composition.

Suggested additional test
+  it('applies sx overrides after variant and compound resolution', () => {
+    const styles = cva({
+      base: { color: 'black', '&:hover': { color: 'blue' } },
+      variants: {
+        size: {
+          sm: { fontSize: 12, '&:hover': { textDecoration: 'underline' } },
+        },
+      },
+    });
+
+    const res = styles({
+      size: 'sm',
+      sx: { color: 'red', '&:hover': { color: 'green' } },
+    })(mockTheme);
+
+    expect(res).toEqual({
+      color: 'red',
+      fontSize: 12,
+      '&:hover': { color: 'green', textDecoration: 'underline' },
+    });
+  });

As per coding guidelines: "Implement comprehensive testing including unit, integration, and E2E tests" and "Verify proper error handling and edge cases."

🤖 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/__tests__/cva.test.ts` around lines 255 - 282, Add a
unit test that asserts cva's `sx` deep-merge and override behavior: define a
`styles` via `cva(...)` (or the existing theme-function variant) that sets
`base` and a `size` variant, then call the returned function with `{ size: 'sm',
sx: { ... } }` and pass `mockTheme`; assert the final result merges `sx` over
base/variant values (i.e., `sx` overrides same keys and deeply merges nested
objects like `padding`, `color`, or `fontSize`). Use the existing test pattern
(symbols: `cva`, `styles`, `mockTheme`, `sx`) and add a new `it` block verifying
the merged output matches expected object shape.
🤖 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__/cva.test.ts`:
- Line 309: The test line uses an unsafe cast (`as any`) when calling styles;
remove `as any` and instead cast via `unknown` and narrow to the expected props
shape or use a typed helper variable so the call to styles receives the
correctly typed props (e.g., declare the test input as unknown, perform a
narrow/type assertion to the styles props type, then call
styles(input)(mockTheme)). Update the test around the styles(...) invocation
(and its mockTheme usage) to use the narrowed/typed value rather than `any`.

In `@packages/ui/src/mosaic/cva.ts`:
- Around line 70-73: The applyBase function currently mutates nested objects
from base by using Object.assign; change it to deep-clone the base StyleRule
before merging so nested objects are not shared—inside applyBase (function
applyBase(target: StyleRule, base?: StyleRule)) create a deep copy of base
(e.g., structuredClone(base) or a safe cloneDeep utility/fallback) and then
merge/assign that clone into target instead of assigning base directly to
prevent variant merges from mutating shared nested objects.

In `@packages/ui/src/mosaic/MosaicProvider.tsx`:
- Line 10: The module reads document at top-level (const el =
document.querySelector(...)) causing SSR/SSG crashes; update MosaicProvider.tsx
to guard all DOM access (the top-level const el and the logic around the style
insertion at the block covering lines ~27-29) by either wrapping DOM queries in
a typeof document !== 'undefined' check or moving them into a React effect
(e.g., useEffect inside the MosaicProvider component) so they only run in the
browser; ensure the unique identifiers (the variable el and the style insertion
logic in MosaicProvider) are the only places changed and preserve existing
behavior when running in the browser.

In `@packages/ui/src/mosaic/variables.ts`:
- Around line 54-56: The loop over overrides prematurely stops because it uses
break when encountering dangerous keys; change the logic in the for (const k in
overrides) loop so that it skips unsafe properties (e.g., '__proto__',
'constructor', 'prototype') with continue instead of break and only processes
own properties (use Object.prototype.hasOwnProperty.call(overrides, k)) before
reading const value = overrides[k]; this preserves processing of subsequent
valid override keys.

In `@references/mosaic-architecture.md`:
- Around line 18-26: The public architecture doc references outdated Mosaic
API/file names and token shapes: replace mentions of
packages/ui/src/mosaic/tokens.ts and parseVariables with
packages/ui/src/mosaic/variables.ts and resolveVariables(...), update the token
examples to use the actual runtime theme types (e.g., spacing as a function
accessed via theme.spacing(n) instead of theme.spacing.md), and adjust the
MosaicTheme example to match typeof defaultMosaicTokens and the current
defaultMosaicTokens shape; update all occurrences (lines referenced:
18/34/49/93/99/261/264/267) so examples and migration notes reflect the real
symbols resolveVariables, defaultMosaicTokens, and the spacing(n) API.
- Around line 220-228: The fenced code block starting with triple backticks in
the mosaic-architecture.md snippet lacks a language tag (violates MD040); update
the opening fence to include a language identifier (e.g., "text" or "markdown")
so the block becomes ```text and keep the existing content unchanged; ensure the
modified block surrounds the lines containing "StyleCacheProvider ...
MosaicComponent → css={styles({ intent: 'primary' })(theme)}" to satisfy the
linter.

---

Nitpick comments:
In `@packages/ui/src/mosaic/__tests__/cva.test.ts`:
- Around line 255-282: Add a unit test that asserts cva's `sx` deep-merge and
override behavior: define a `styles` via `cva(...)` (or the existing
theme-function variant) that sets `base` and a `size` variant, then call the
returned function with `{ size: 'sm', sx: { ... } }` and pass `mockTheme`;
assert the final result merges `sx` over base/variant values (i.e., `sx`
overrides same keys and deeply merges nested objects like `padding`, `color`, or
`fontSize`). Use the existing test pattern (symbols: `cva`, `styles`,
`mockTheme`, `sx`) and add a new `it` block verifying the merged output matches
expected object shape.
🪄 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

Run ID: c13bf295-8dcc-4dfe-a8a5-d9780ead1a94

📥 Commits

Reviewing files that changed from the base of the PR and between 5bf43a2 and fd0ad55.

📒 Files selected for processing (7)
  • AGENTS.md
  • packages/ui/src/mosaic/Button.tsx
  • packages/ui/src/mosaic/MosaicProvider.tsx
  • packages/ui/src/mosaic/__tests__/cva.test.ts
  • packages/ui/src/mosaic/cva.ts
  • packages/ui/src/mosaic/variables.ts
  • references/mosaic-architecture.md

Comment thread packages/ui/src/mosaic/__tests__/cva.test.ts Outdated
Comment thread packages/ui/src/mosaic/cva.ts
Comment thread packages/ui/src/mosaic/MosaicProvider.tsx Outdated
Comment thread packages/ui/src/mosaic/variables.ts
Comment thread references/mosaic-architecture.md Outdated
Comment thread references/mosaic-architecture.md Outdated
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