Skip to content

feat(swingset): Scaffold component documentation package#8797

Merged
kylemac merged 20 commits into
mainfrom
carp/swingset
Jun 10, 2026
Merged

feat(swingset): Scaffold component documentation package#8797
kylemac merged 20 commits into
mainfrom
carp/swingset

Conversation

@alexcarpenter

@alexcarpenter alexcarpenter commented Jun 10, 2026

Copy link
Copy Markdown
Member

Description

Scaffolds new component documentation package that is used to document and iterate on mosaic design system components.

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 Swingset: an interactive component explorer with live stories, knobs, variable panels, theme toggle, and embedded previews.
    • Added MDX-driven docs with Story embedding and auto-generated prop tables; dynamic docs viewer and story canvas for live interaction.
  • Documentation

    • Added a README explaining setup, story authoring, registry registration, and documentation wiring.
  • Chores

    • Added dev script and local package configs to run the Swingset dev server.

@vercel

vercel Bot commented Jun 10, 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 Jun 10, 2026 4:18pm

Request Review

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro

Run ID: 464d625a-13a3-4a05-8ba2-5a06694d676a

📥 Commits

Reviewing files that changed from the base of the PR and between f64dfa4 and f2f0f90.

📒 Files selected for processing (19)
  • packages/swingset/src/app/layout.tsx
  • packages/swingset/src/components/ClientRoot.tsx
  • packages/swingset/src/components/CodeBlock.tsx
  • packages/swingset/src/components/DocsViewer.tsx
  • packages/swingset/src/components/KnobPanel.tsx
  • packages/swingset/src/components/PropTable.tsx
  • packages/swingset/src/components/StoryCanvas.tsx
  • packages/swingset/src/components/StoryEmbed.tsx
  • packages/swingset/src/components/VariablesPanel.tsx
  • packages/swingset/src/components/app-sidebar.tsx
  • packages/swingset/src/components/ui/breadcrumb.tsx
  • packages/swingset/src/components/ui/input.tsx
  • packages/swingset/src/components/ui/label.tsx
  • packages/swingset/src/components/ui/select.tsx
  • packages/swingset/src/components/ui/sheet.tsx
  • packages/swingset/src/components/ui/sidebar.tsx
  • packages/swingset/src/lib/generateKnobs.ts
  • packages/swingset/src/lib/registry.ts
  • packages/swingset/src/lib/utils.ts
🚧 Files skipped from review as they are similar to previous changes (19)
  • packages/swingset/src/components/ui/input.tsx
  • packages/swingset/src/lib/generateKnobs.ts
  • packages/swingset/src/lib/utils.ts
  • packages/swingset/src/components/app-sidebar.tsx
  • packages/swingset/src/components/ui/breadcrumb.tsx
  • packages/swingset/src/components/ui/label.tsx
  • packages/swingset/src/components/ClientRoot.tsx
  • packages/swingset/src/components/DocsViewer.tsx
  • packages/swingset/src/components/VariablesPanel.tsx
  • packages/swingset/src/components/KnobPanel.tsx
  • packages/swingset/src/components/CodeBlock.tsx
  • packages/swingset/src/lib/registry.ts
  • packages/swingset/src/components/StoryCanvas.tsx
  • packages/swingset/src/components/ui/sheet.tsx
  • packages/swingset/src/app/layout.tsx
  • packages/swingset/src/components/PropTable.tsx
  • packages/swingset/src/components/StoryEmbed.tsx
  • packages/swingset/src/components/ui/select.tsx
  • packages/swingset/src/components/ui/sidebar.tsx

📝 Walkthrough

Walkthrough

Adds the @clerk/swingset Next.js-based component explorer with MDX docs, story registry and lookup, interactive story canvas (knobs + variables), PropTable generated from CVA metadata, a suite of UI primitives, Mosaic Button implementation, and updated cva to expose variant metadata.

Changes

Swingset Component Explorer

Layer / File(s) Summary
Project and toolchain setup
packages/swingset/package.json, package.json, packages/swingset/tsconfig.json, packages/swingset/next.config.mjs, packages/swingset/postcss.config.mjs, packages/swingset/components.json, packages/swingset/next-env.d.ts, .changeset/*
Package scripts (dev:swingset), Next.js MDX + Emotion, PostCSS/Tailwind, TypeScript config and path aliases, components generator config, and changeset entry.
App shell & globals
packages/swingset/src/app/layout.tsx, packages/swingset/src/app/page.tsx, packages/swingset/src/app/globals.css, packages/swingset/src/types/global.d.ts
Root layout with dev script injection, home redirect, global CSS variables/themes, Shiki variables, and ambient MDX/Emotion typings.
Dynamic component/docs routes
packages/swingset/src/app/components/[component]/page.tsx, packages/swingset/src/app/components/[component]/[story]/page.tsx
Route handlers that extract slugs from params and render DocsViewer or StoryCanvas.
MDX runtime & code highlighting
packages/swingset/mdx-components.tsx, packages/swingset/src/components/CodeBlock.tsx, packages/swingset/src/components/DocsViewer.tsx
MDX component overrides (pre→CodeBlock, Story→StoryEmbed, PropTable), Shiki highlighting with copy button, and slug-to-MDX dynamic loading with fallback.
Story contracts & registry
packages/swingset/src/lib/types.ts, packages/swingset/src/lib/registry.ts
Types for knobs and story modules, explicit registry assembly, findStory/getStoryNames/getSidebarGroups utilities.
Utilities
packages/swingset/src/lib/slug.ts, packages/swingset/src/lib/utils.ts, packages/swingset/src/lib/generateKnobs.ts
Slug normalization, cn (clsx + twMerge) helper, variant→knob conversion and knob initialization.
Interactive story canvas
packages/swingset/src/components/StoryCanvas.tsx, packages/swingset/src/components/StoryEmbed.tsx, packages/swingset/src/components/KnobPanel.tsx, packages/swingset/src/components/VariablesPanel.tsx, packages/swingset/src/components/PropTable.tsx
Canvas resolves stories, renders inside MosaicProvider, provides KnobPanel and VariablesPanel to edit props and mosaic variables, and PropTable derives prop rows from CVA metadata.
Client navigation & theme
packages/swingset/src/components/ClientRoot.tsx, packages/swingset/src/components/app-sidebar.tsx, packages/swingset/src/components/ThemeProvider.tsx, packages/swingset/src/components/ThemeToggle.tsx, packages/swingset/src/hooks/use-mobile.ts
ClientRoot with breadcrumb generation, AppSidebar groups and active state, ThemeProvider/ThemeToggle wiring, and useIsMobile hook.
Base UI primitives
packages/swingset/src/components/ui/* (button, input, label, separator, switch, skeleton, collapsible, sheet, select, tabs, tooltip, breadcrumb, sidebar)
Thin, styled wrappers around Base UI primitives with cva styles, data-slot attributes, and composition helpers used across the explorer UI.
Button story & MDX docs
packages/swingset/src/stories/button.stories.tsx, packages/swingset/src/stories/button.mdx
Button story module (meta, Primary/Sizes/Disabled) and MDX page embedding stories and PropTable.
Swingset README
packages/swingset/README.md
Developer-facing documentation: dev commands, story/docs authoring workflow, PropTable/knob guidance, and architecture overview.

Mosaic Button & CVA metadata

Layer / File(s) Summary
Mosaic Button component
packages/ui/src/mosaic/Button.tsx
Button with cva-driven styles, color/size/disabled variants, ButtonProps typing and forwardRef render using Mosaic theme.
CVA metadata exposure
packages/ui/src/mosaic/cva.ts
cva updated to pre-resolve config when provided as a function and attach _variants and _defaultVariants on returned function for tooling (PropTable) to consume.

Reference docs fix

Layer / File(s) Summary
Mosaic architecture docs
references/mosaic-architecture.md
Adds missing closing code-fence in documentation.

Sequence Diagram (high-level interaction)

sequenceDiagram
  participant Browser
  participant NextApp
  participant DocsViewer
  participant Registry
  participant MosaicProvider
  Browser->>NextApp: navigate /components/:component or /components/:component/:story
  NextApp->>DocsViewer: render MDX for component (slug)
  NextApp->>Registry: findStory(componentSlug, storySlug)
  Registry-->>NextApp: story module & export
  NextApp->>MosaicProvider: render story with knob values / variables
  MosaicProvider-->>Browser: rendered story UI
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • clerk/javascript#8755: Mosaic foundations and cva metadata that swingset's PropTable and MosaicProvider usage depend on.

Suggested reviewers

  • wobsoriano
  • austincalvelage
  • Ephem

"🐰 I bounced through code with joy and glee,
stories, knobs, and buttons blooming for me.
I nibble a prop, hop on a tab, then cheer—
the explorer's alive; bring the stories near!"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.91% 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 clearly and concisely describes the main change: scaffolding a new component documentation package called swingset.
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.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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.

@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

API Changes Report

Generated by Break Check on 2026-06-10T16:24:10.361Z

Summary

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

Note
Break Check could not snapshot 3 subpaths; the diff below excludes them.

  • @clerk/astro ./env: Internal Error: Unable to determine module for: /home/runner/_work/javascript/javascript/packages/astro/env.d.ts You have encountered a software defect. Please consider reporting the issue to the maintainers of this application.
  • @clerk/shared ./cookie: Internal Error: Unable to follow symbol for "Cookies" You have encountered a software defect. Please consider reporting the issue to the maintainers of this application.
  • @clerk/testing ./cypress: Symbol not found for identifier: Cypress

No API Changes Detected

All packages have stable APIs with no detected changes.


Report generated by Break Check

Last ran on 142b54e.

@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

Note

Due to the large number of review comments, Critical severity comments were prioritized as inline comments.

Caution

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

⚠️ Outside diff range comments (6)
packages/swingset/src/components/ui/separator.tsx (1)

1-22: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Add JSDoc for exported component.

This component is exported as a public API but lacks JSDoc documentation. Per coding guidelines, all public package APIs must be documented with JSDoc.

📝 Suggested JSDoc structure
+/**
+ * A visual separator component supporting horizontal and vertical orientations.
+ * 
+ * `@param` {SeparatorPrimitive.Props} props - Separator props including orientation
+ * `@returns` {React.JSX.Element} The rendered separator element
+ */
 function Separator({ className, orientation = 'horizontal', ...props }: SeparatorPrimitive.Props): React.JSX.Element {
🤖 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/components/ui/separator.tsx` around lines 1 - 22, Add a
JSDoc block above the exported Separator component describing the component and
its public API: document the function name Separator, list the props (including
className, orientation with default 'horizontal', and other spread props),
describe the component behavior (renders a styled SeparatorPrimitive with
data-slot 'separator'), and mark it as an exported public component; include
types for the props (referencing SeparatorPrimitive.Props) and a short example
or usage note as appropriate per package docs.

Source: Coding guidelines

packages/swingset/src/components/ui/skeleton.tsx (2)

1-14: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Add missing React import.

The component uses React.ComponentProps on line 3 but does not import React. This will cause a type error.

🔧 Suggested fix
+import * as React from 'react';
+
 import { cn } from '`@/lib/utils`';
🤖 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/components/ui/skeleton.tsx` around lines 1 - 14, The
file uses React types (React.ComponentProps in the Skeleton component) but lacks
a React import; add an import for React (e.g., import React from 'react') at the
top of the file so the type reference for React.ComponentProps resolves and the
Skeleton component compiles correctly.

1-14: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Add JSDoc for exported component.

This component is exported as a public API but lacks JSDoc documentation. Per coding guidelines, all public package APIs must be documented with JSDoc.

📝 Suggested JSDoc structure
+/**
+ * A loading skeleton placeholder component with pulse animation.
+ * 
+ * `@param` {React.ComponentProps<'div'>} props - Standard div element props
+ * `@returns` {React.JSX.Element} The rendered skeleton element
+ */
 function Skeleton({ className, ...props }: React.ComponentProps<'div'>): React.JSX.Element {
🤖 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/components/ui/skeleton.tsx` around lines 1 - 14, Add a
JSDoc block above the exported Skeleton component describing its purpose and
public API: document the Skeleton function (exported symbol Skeleton), its props
parameter (React.ComponentProps<'div'>) including the className and spread
props, mention that it renders a div with data-slot='skeleton' and the default
classes ('bg-muted animate-pulse rounded-md') merged via cn, and include `@param`
and `@returns` tags (and an optional `@example` showing basic usage). Ensure the
JSDoc sits immediately above the function declaration so the component is
documented as a public API.

Source: Coding guidelines

packages/swingset/src/components/ui/label.tsx (1)

1-21: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Add JSDoc for exported component.

This component is exported as a public API but lacks JSDoc documentation. Per coding guidelines, all public package APIs must be documented with JSDoc.

📝 Suggested JSDoc structure
+/**
+ * A form label component with accessibility and theming support.
+ * Automatically handles disabled states via peer/group selectors.
+ * 
+ * `@param` {React.ComponentProps<'label'>} props - Standard label element props
+ * `@returns` {React.JSX.Element} The rendered label element
+ */
 function Label({ className, ...props }: React.ComponentProps<'label'>): React.JSX.Element {
🤖 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/components/ui/label.tsx` around lines 1 - 21, The
exported React component Label lacks JSDoc; add a JSDoc block immediately above
the Label function that documents the component purpose, its props (using the
existing type React.ComponentProps<'label'> or `@param`
{React.ComponentProps<'label'>} props), any important data- attributes (e.g.,
data-slot='label'), and what it returns (JSX.Element), and mark it as part of
the public API; ensure the JSDoc includes a short description, `@param` for props,
and `@returns` so the exported Label is documented per package guidelines.

Source: Coding guidelines

packages/swingset/src/components/ui/input.tsx (1)

1-21: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Add JSDoc for exported component.

This component is exported as a public API but lacks JSDoc documentation. Per coding guidelines, all public package APIs must be documented with JSDoc including purpose, parameters, and usage examples.

📝 Suggested JSDoc structure
+/**
+ * A styled input component wrapping Base UI's Input primitive.
+ * Provides consistent styling with theme-aware states (focus, disabled, invalid).
+ * 
+ * `@param` {React.ComponentProps<'input'>} props - Standard input element props
+ * `@returns` {React.JSX.Element} The rendered input element
+ * 
+ * `@example`
+ * ```tsx
+ * <Input type="email" placeholder="Enter email" />
+ * ```
+ */
 function Input({ className, type, ...props }: React.ComponentProps<'input'>): React.JSX.Element {
🤖 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/components/ui/input.tsx` around lines 1 - 21, The
exported Input component lacks JSDoc; add a JSDoc block above the Input function
explaining its purpose, parameters (props like className, type and other input
props), return type, and a short usage example (e.g., <Input type="email"
placeholder="Enter email" />); ensure the JSDoc references the Input component
name and mentions it is exported, so the public API is properly documented for
consumers and tooling.

Source: Coding guidelines

packages/swingset/src/components/ui/sidebar.tsx (1)

1-690: 🛠️ Refactor suggestion | 🟠 Major | 🏗️ Heavy lift

Split large sidebar file into smaller modules.

This file is 690 lines, significantly exceeding the 150-200 line guideline for component files. The sidebar system includes 25+ exported components and should be split into logical modules for better maintainability.

Consider this structure:

  • sidebar-context.tsx - Context, provider, and hook
  • sidebar-core.tsx - Main Sidebar, Trigger, Rail, Inset
  • sidebar-layout.tsx - Header, Footer, Content, Separator, Input
  • sidebar-group.tsx - Group components (Group, Label, Action, Content)
  • sidebar-menu.tsx - Menu components (Menu, MenuItem, Button, Action, Badge, Skeleton)
  • sidebar-submenu.tsx - Submenu components (Sub, SubItem, SubButton)
  • sidebar-variants.ts - CVA variants
  • index.ts - Re-export all components
🤖 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/components/ui/sidebar.tsx` around lines 1 - 690, The
Sidebar file is too large and should be split into smaller modules: extract the
context, provider, and hook (SidebarContext, SidebarProvider, useSidebar) into
sidebar-context.tsx; move core components (Sidebar, SidebarTrigger, SidebarRail,
SidebarInset) into sidebar-core.tsx; put layout pieces (SidebarHeader,
SidebarFooter, SidebarContent, SidebarSeparator, SidebarInput) into
sidebar-layout.tsx; group-related components (SidebarGroup, SidebarGroupLabel,
SidebarGroupAction, SidebarGroupContent) into sidebar-group.tsx; menu components
(SidebarMenu, SidebarMenuItem, SidebarMenuButton, SidebarMenuAction,
SidebarMenuBadge, SidebarMenuSkeleton) into sidebar-menu.tsx; submenu components
(SidebarMenuSub, SidebarMenuSubItem, SidebarMenuSubButton) into
sidebar-submenu.tsx; isolate CVA variants (sidebarMenuButtonVariants) into
sidebar-variants.ts; and create an index.ts that re-exports everything; ensure
each new file imports shared utilities (useRender, mergeProps, cn, cva,
useIsMobile, Button, Input, Tooltip, Sheet, etc.) and preserve original prop
types and exports (export { Sidebar, SidebarProvider, useSidebar, ... }) so
consumers are unchanged.

Source: Coding guidelines

🟡 Minor comments (5)
packages/swingset/src/hooks/use-mobile.ts-5-5 (1)

5-5: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add explicit return type annotation for the exported hook.

The useIsMobile hook is exported but lacks an explicit return type annotation. As per coding guidelines, public APIs should have explicit return types for clarity and type safety.

📝 Proposed fix
-export function useIsMobile() {
+export function useIsMobile(): boolean {
   const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined);
🤖 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/hooks/use-mobile.ts` at line 5, The exported hook
useIsMobile lacks an explicit return type; update its signature to include the
correct return type (e.g., boolean) so the public API is typed explicitly —
change the declaration of useIsMobile to include the return type (useIsMobile():
boolean) and adjust any internal returns if necessary to satisfy the type.

Source: Coding guidelines

packages/swingset/mdx-components.tsx-7-14 (1)

7-14: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add runtime validation for type assertion safety.

The type assertion on line 9 assumes the code element has className and children props matching the expected shape, but there's no runtime validation. If MDX generates a code element with a different structure, this could fail silently or throw at runtime.

🛡️ Proposed fix with type guard
+function hasCodeProps(
+  props: unknown
+): props is { className?: string; children: string } {
+  return (
+    typeof props === 'object' &&
+    props !== null &&
+    'children' in props &&
+    typeof props.children === 'string'
+  );
+}
+
 function PreBlock({ children }: { children?: React.ReactNode }) {
   if (React.isValidElement(children) && (children as React.ReactElement).type === 'code') {
-    const { className, children: code } = (children as React.ReactElement<{ className?: string; children: string }>)
-      .props;
+    if (!hasCodeProps(children.props)) {
+      return <pre>{children}</pre>;
+    }
+    const { className, children: code } = children.props;
     return <CodeBlock className={className}>{code}</CodeBlock>;
   }
   return <pre>{children}</pre>;
 }

As per coding guidelines: "Implement type guards for unknown types using the pattern function isType(value: unknown): value is Type."

🤖 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/mdx-components.tsx` around lines 7 - 14, The PreBlock
function assumes children is a ReactElement with props { className?: string;
children: string }—add a runtime type guard to validate that before casting:
implement an isCodeElement(value: unknown): value is React.ReactElement<{
className?: string; children: string }> that checks React.isValidElement(value),
typeof value.props === 'object', 'children' in value.props and typeof
value.props.children === 'string' (and optionally typeof value.props.className
=== 'string' || value.props.className === undefined); use this guard in PreBlock
where you currently cast (children as React.ReactElement...) so you only extract
className and code when isCodeElement(children) returns true, otherwise fall
back to the <pre>{children}</pre> path.
packages/swingset/src/components/CodeBlock.tsx-32-32 (1)

32-32: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add cleanup for timer on component unmount.

The timerRef holds a timeout that may still be pending when the component unmounts. This can cause a warning about setting state on an unmounted component.

🔧 Proposed fix

Add a cleanup effect after the timer ref declaration:

 const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);

+useEffect(() => {
+  return () => {
+    if (timerRef.current) {
+      clearTimeout(timerRef.current);
+    }
+  };
+}, []);
+
 useEffect(() => {

As per coding guidelines: "Implement proper cleanup in useEffect hooks."

🤖 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/components/CodeBlock.tsx` at line 32, The timerRef in
CodeBlock.tsx may hold a pending timeout when the component unmounts; add a
useEffect cleanup that clears the timeout stored in timerRef (use
clearTimeout(timerRef.current)) and sets timerRef.current to null to prevent
callbacks from running after unmount and avoid setState-on-unmounted warnings;
update any places that set timerRef (via setTimeout) to be compatible with this
cleanup and ensure the effect has an empty dependency array so it runs once on
mount and cleans on unmount.
packages/swingset/src/components/ui/breadcrumb.tsx-55-66 (1)

55-66: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove role='link' from non-interactive current page element.

Line 59 applies role='link' to a <span> element representing the current page. This is an accessibility violation—the current page should not be presented as a link (interactive element). Remove the role='link' attribute and rely on aria-current='page' to indicate the current location.

♿ Proposed fix
 function BreadcrumbPage({ className, ...props }: React.ComponentProps<'span'>) {
   return (
     <span
       data-slot='breadcrumb-page'
-      role='link'
       aria-disabled='true'
       aria-current='page'
       className={cn('text-foreground font-normal', className)}
       {...props}
     />
   );
 }

Also add explicit return type:

🔧 Add return type
-function BreadcrumbPage({ className, ...props }: React.ComponentProps<'span'>) {
+function BreadcrumbPage({ className, ...props }: React.ComponentProps<'span'>): React.JSX.Element {
🤖 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/components/ui/breadcrumb.tsx` around lines 55 - 66, In
BreadcrumbPage, remove the incorrect interactive semantics by deleting
role='link' from the <span> used for the current page and keep
aria-current='page' and aria-disabled='true' to convey non-interactive state;
also add an explicit return type for the function (e.g., React.ReactElement or
JSX.Element) on BreadcrumbPage to make its signature explicit.

Source: Coding guidelines

packages/swingset/src/app/page.tsx-5-7 (1)

5-7: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Consider a more resilient redirect target.

The hardcoded redirect to /components/button assumes that the button component exists. If the button component is removed or renamed, this route will break.

Consider either:

  • Making this redirect dynamic based on the first available component from the registry
  • Rendering a landing page instead of redirecting
🤖 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/app/page.tsx` around lines 5 - 7, HomePage currently
calls redirect('/components/button') which is brittle; update the HomePage
function to either (A) query the components registry (e.g., use the existing
componentsRegistry, getComponentList, getAllComponents, or similar API) to pick
the first available component slug and redirect to `/components/{slug}`,
handling the empty-list case by falling back to a sensible default, or (B) stop
redirecting and render a safe landing page UI instead. Locate the redirect call
inside the HomePage component and replace it with logic that checks the registry
for available components and redirects dynamically or returns a landing page
when none exist.
🧹 Nitpick comments (20)
packages/swingset/README.md (3)

26-28: ⚡ Quick win

Add missing type import for clarity.

The example casts props to MyComponentProps on line 27, but this type is never imported or defined. For a complete, runnable example, consider adding the import or noting that it should be imported from the component module.

📝 Suggested addition
 /** `@jsxImportSource` `@emotion/react` */
 import type { StoryMeta } from '`@/lib/types`';
-import { MyComponent, myComponentStyles } from '`@clerk/ui/mosaic/components/my-component`';
+import { MyComponent, myComponentStyles, type MyComponentProps } from '`@clerk/ui/mosaic/components/my-component`';
🤖 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/README.md` around lines 26 - 28, The example's Default
function casts props to MyComponentProps but that type is not imported or
defined; update the README example to import or declare MyComponentProps from
the component module used by MyComponent so the example compiles — e.g., add an
import statement for MyComponentProps (or a short local type declaration) and
ensure MyComponent and MyComponentProps are referenced consistently in the
Default(props: Record<string, unknown>) example.

7-9: ⚡ Quick win

Add language identifier to code block.

Per markdown linting, fenced code blocks should specify a language for proper syntax highlighting.

📝 Suggested fix
-```
+```bash
 pnpm dev --filter `@clerk/swingset`
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

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/README.md around lines 7 - 9, The fenced code block
containing the command "pnpm dev --filter @clerk/swingset" in
packages/swingset/README.md needs a language identifier for markdown linting;
update the triple-backtick fence to include "bash" (i.e., ```bash) so the block
becomes a bash-highlighted code block and satisfies the linter.


</details>

<!-- cr-comment:v1:6ca9168e45c7875681860910 -->

_Source: Linters/SAST tools_

---

`87-87`: _💤 Low value_

**Add language identifier to code block.**

Per markdown linting, fenced code blocks should specify a language. For directory tree structures, you can use `text` or `plaintext`.





<details>
<summary>📝 Suggested fix</summary>

```diff
-```
+```text
 src/
   app/                 Next.js App Router
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

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/README.md at line 87, The fenced code block is missing a
language identifier; update the opening fence from totext (or

plain text. Locate the block that starts with ``` and replace it with ```text
while keeping the block content unchanged (e.g., the snippet showing the src/
app/ Next.js tree).

Source: Linters/SAST tools

packages/ui/src/mosaic/Button.tsx (1)

54-54: 💤 Low value

Remove redundant disabled || false coercion.

The disabled || false coercion is redundant since buttonStyles already specifies defaultVariants: { disabled: false }. The variant system will handle the undefined case automatically.

♻️ Simplification
-      disabled={disabled || false}
+      disabled={disabled}
🤖 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/Button.tsx` at line 54, Remove the redundant boolean
coercion in the Button component: the prop usage disabled={disabled || false}
should be simplified to just pass disabled (or omit it) because buttonStyles has
defaultVariants: { disabled: false } and the variant system will handle
undefined; update the Button component where disabled is forwarded (prop name
disabled in the component and any JSX usage in Button.tsx) to stop forcing ||
false so the variant system controls the default.
packages/shared/src/types/clerk.ts (1)

703-717: ⚡ Quick win

Document the new experimental public API surface more explicitly.

Line 703 and Line 2305 introduce new public API entries, but the exported props type is undocumented and the new methods are not explicitly tagged as @experimental. Please add concise JSDoc so generated reference docs stay clear and consistent.

Suggested patch
   /**
    * Mounts the experimental MosaicOrganizationProfile component at the target element.
+   * `@experimental` This API is experimental and may change without notice.
    * `@param` targetNode Target node to mount the MosaicOrganizationProfile component.
    * `@param` props configuration parameters.
    */
   __experimental_mountMosaicOrganizationProfile: (
@@
   /**
    * Unmounts the experimental MosaicOrganizationProfile component from the target element.
+   * `@experimental` This API is experimental and may change without notice.
    * `@param` targetNode Target node to unmount the MosaicOrganizationProfile component from.
    */
   __experimental_unmountMosaicOrganizationProfile: (targetNode: HTMLDivElement) => void;
@@
+/**
+ * Props for mounting the experimental MosaicOrganizationProfile component.
+ *
+ * `@experimental` This API is experimental and may change without notice.
+ */
 export type __experimental_MosaicOrganizationProfileProps = {
   appearance?: ClerkAppearanceTheme;
 };

As per coding guidelines, public APIs in packages/**/src/**/*.{ts,tsx} should have comprehensive JSDoc, and public/reference-facing JSDoc changes may need Docs-team review.

Also applies to: 2305-2307

🤖 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/shared/src/types/clerk.ts` around lines 703 - 717, The new
experimental API lacks descriptive JSDoc: add concise JSDoc comments for
__experimental_mountMosaicOrganizationProfile and
__experimental_unmountMosaicOrganizationProfile that include a short
description, mark them with `@experimental`, document parameters (targetNode:
HTMLDivElement and props?: __experimental_MosaicOrganizationProfileProps) and
return type, and add JSDoc for the exported type
__experimental_MosaicOrganizationProfileProps describing each prop and its
purpose; ensure wording is reference-doc friendly and note that
public/reference-facing JSDoc changes may require Docs-team review.

Source: Coding guidelines

packages/ui/src/contexts/components/__experimental_MosaicOrganizationProfile.ts (1)

17-22: 💤 Low value

Remove redundant destructuring and reconstruction.

Lines 17-22 destructure componentName from context, then immediately reconstruct it in the return object. Since the validation on line 11 already narrows the type and confirms componentName is present, you can return the validated context directly.

Proposed simplification
-  const { componentName, ...ctx } = context;
-
-  return {
-    ...ctx,
-    componentName,
-  };
+  return context;
🤖 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/contexts/components/__experimental_MosaicOrganizationProfile.ts`
around lines 17 - 22, The current code needlessly destructures componentName
from context into ctx then reassembles it; instead, stop the redundant
destructuring and return the already-validated context directly. In the function
that currently does "const { componentName, ...ctx } = context; return { ...ctx,
componentName }", replace that logic with a direct return of the validated
context variable (context) to preserve type narrowing and avoid creating an
unnecessary ctx copy.
packages/swingset/src/components/StoryCanvas.tsx (1)

28-33: ⚡ Quick win

Consider including found in the dependency array or computing it inside the effect.

The useEffect uses found from the outer scope but doesn't list it in the dependency array. While this works correctly now (since found is deterministic based on componentSlug/storySlug), it violates React's exhaustive-deps rule and could cause stale-closure bugs if the registry lookup logic becomes dynamic in the future.

🔧 Suggested fix

Option 1: Include found in the dependency array (may cause unnecessary re-runs if object identity changes):

   useEffect(() => {
     if (!found) return;
     const nextKnobs = generateKnobs(found.mod.meta);
     setKnobs(nextKnobs);
     setKnobValues(initKnobValues(nextKnobs));
-  }, [componentSlug, storySlug]);
+  }, [componentSlug, storySlug, found]);

Option 2 (preferred): Compute found inside the effect to avoid external dependency:

   useEffect(() => {
+    const found = findStory(componentSlug, storySlug);
     if (!found) return;
     const nextKnobs = generateKnobs(found.mod.meta);
     setKnobs(nextKnobs);
     setKnobValues(initKnobValues(nextKnobs));
   }, [componentSlug, storySlug]);
🤖 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/components/StoryCanvas.tsx` around lines 28 - 33, The
effect currently closes over found but doesn't declare it as a dependency; to
fix, move the computation of found into the useEffect body (so useEffect
computes found from componentSlug/storySlug locally) and keep the dependency
array as [componentSlug, storySlug]; update the effect that calls
generateKnobs(found.mod.meta), setKnobs, and setKnobValues(initKnobValues(...))
to use the locally computed found and early-return if it's falsy, referencing
symbols useEffect, found, generateKnobs, setKnobs, initKnobValues, componentSlug
and storySlug.
packages/swingset/src/components/StoryEmbed.tsx (1)

15-15: 💤 Low value

Consider more specific typing for story component.

The type assertion as React.ComponentType<Record<string, unknown>> is very permissive. Since stories are typed via StoryModule, consider using a more specific type that reflects the actual story function signature or letting TypeScript infer from the module definition.

💡 Alternative approach
-const StoryComp = storyModule[name] as React.ComponentType<Record<string, unknown>>;
+const StoryComp = storyModule[name] as React.ComponentType<any>;

Or define a more specific type in types.ts if all stories share a common prop shape.

🤖 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/components/StoryEmbed.tsx` at line 15, The current
assertion "as React.ComponentType<Record<string, unknown>>" for StoryComp is too
broad; update the typing to use the actual story module types instead of a
generic record: change the cast to derive the component type from
storyModule/StoryModule (e.g., use the exported StoryModule generic or the
specific story function type) so TypeScript can infer props, or create a shared
story-props type in types.ts and use that (e.g.,
React.ComponentType<StoryProps>) and apply it to StoryComp to reflect the real
signature.
packages/swingset/src/components/CodeBlock.tsx (1)

12-20: ⚡ Quick win

Add explicit return type annotation.

Helper functions should have explicit return types for clarity.

✨ Proposed fix
-function getHighlighter(): Promise<Highlighter> {
+function getHighlighter(): Promise<Highlighter> {

Wait, this already has a return type. Let me re-check... yes, line 12 already has : Promise<Highlighter>. Skip this comment.

🤖 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/components/CodeBlock.tsx` around lines 12 - 20, The
helper function getHighlighter already declares an explicit return type
Promise<Highlighter>, so no change is necessary; leave the function signature
(getHighlighter) and its return type as-is and proceed without modification.

Source: Coding guidelines

packages/swingset/mdx-components.tsx (1)

7-14: ⚡ Quick win

Add explicit return type annotation.

Internal helper functions should have explicit return types.

✨ Proposed fix
-function PreBlock({ children }: { children?: React.ReactNode }) {
+function PreBlock({ children }: { children?: React.ReactNode }): React.JSX.Element {
   if (React.isValidElement(children) && (children as React.ReactElement).type === 'code') {

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

🤖 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/mdx-components.tsx` around lines 7 - 14, The PreBlock
component lacks an explicit return type; update its signature (function
PreBlock) to declare a return type, e.g. : JSX.Element (or React.ReactElement |
null if you prefer nullability), so the component's return type is explicit and
consistent with project guidelines; keep the existing props typing for children
and do not change the implementation inside the function.

Source: Coding guidelines

packages/swingset/src/components/DocsViewer.tsx (1)

5-7: 💤 Low value

Reconsider the type assertion on dynamic().

next/dynamic already returns a properly typed component. The as React.ComponentType assertion may be unnecessary and could mask type issues. Consider letting TypeScript infer the type or using a more specific type that matches the dynamic import return value.

💡 Suggested improvement
-const docModules: Record<string, React.ComponentType> = {
-  button: dynamic(() => import('../stories/button.mdx')) as React.ComponentType,
+const docModules: Record<string, React.ComponentType> = {
+  button: dynamic(() => import('../stories/button.mdx')),
 };
🤖 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/components/DocsViewer.tsx` around lines 5 - 7, The
explicit "as React.ComponentType" cast on the dynamic import is unnecessary and
can hide type errors; remove the assertion from the dynamic(...) call and let
TypeScript infer the type, or make the container type align with dynamic's
return type (e.g. change docModules to Record<string, ReturnType<typeof
dynamic>> or Record<string, React.ComponentType<any>>). Update the docModules
declaration and the entry using dynamic(() => import('../stories/button.mdx'))
accordingly so you no longer assert the component with "as React.ComponentType".
packages/swingset/src/components/app-sidebar.tsx (2)

26-90: ⚡ Quick win

Add explicit return type annotation.

The component function should declare an explicit return type per TypeScript guidelines for functions.

♻️ Suggested addition
-export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
+export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>): JSX.Element {
   const pathname = usePathname();
🤖 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/components/app-sidebar.tsx` around lines 26 - 90, The
AppSidebar component is missing an explicit return type; update the function
signature for AppSidebar to include a JSX return type (e.g., : JSX.Element or :
React.ReactElement) so TypeScript enforces the component's return contract
(update the signature on the exported function AppSidebar that currently
deconstructs props and returns the Sidebar JSX).

Source: Coding guidelines


24-24: ⚖️ Poor tradeoff

Module-level getSidebarGroups() eagerly loads all story modules.

The module-level call to getSidebarGroups() at line 24 causes all story modules to be eagerly imported when this client component loads. This is noted in page.tsx as the reason for using a redirect instead of rendering sidebar groups from a Server Component.

For the current scope of a component explorer, this is likely acceptable. However, if the number of components grows significantly, consider lazy-loading story modules on-demand or splitting the sidebar into smaller client components.

🤖 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/components/app-sidebar.tsx` at line 24, The
module-level call to getSidebarGroups() (assigned to groups) eagerly imports all
story modules; move this call into the client component lifecycle so story
modules are loaded on demand—e.g., replace the top-level const groups =
getSidebarGroups() with a lazy load inside the AppSidebar component using
useState/useEffect (or React.lazy/dynamic import) to call getSidebarGroups() at
mount or when needed, or split the sidebar into smaller client components that
each import their portions; update references to groups within the component to
use the state value returned by the lazy load.
packages/swingset/src/app/components/[component]/page.tsx (1)

7-10: ⚡ Quick win

Add explicit return type annotation.

The async page function should declare an explicit return type per TypeScript guidelines for functions.

♻️ Suggested addition
-export default async function ComponentPage({ params }: Props) {
+export default async function ComponentPage({ params }: Props): Promise<JSX.Element> {
   const { component } = await params;
   return <DocsViewer slug={component} />;
 }
🤖 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/app/components/`[component]/page.tsx around lines 7 -
10, Add an explicit return type to the async page function ComponentPage so
TypeScript knows the component's return shape; change the signature for
ComponentPage({ params }: Props) to declare a return type of
Promise<JSX.Element> (or Promise<React.ReactNode> if you prefer), ensuring the
exported async function ComponentPage is annotated and still returns the
DocsViewer JSX node with slug={component}.

Source: Coding guidelines

packages/swingset/src/app/components/[component]/[story]/page.tsx (1)

7-15: ⚡ Quick win

Add explicit return type annotation.

The async page function should declare an explicit return type per TypeScript guidelines for functions.

♻️ Suggested addition
-export default async function StoryPage({ params }: Props) {
+export default async function StoryPage({ params }: Props): Promise<JSX.Element> {
   const { component, story } = await params;
   return (
     <StoryCanvas
🤖 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/app/components/`[component]/[story]/page.tsx around
lines 7 - 15, Add an explicit return type to the async page function StoryPage:
update the function signature for StoryPage({ params }: Props) to declare its
return type (e.g., Promise<JSX.Element> or Promise<React.ReactNode>) so the
compiler knows the resolved JSX type returned by StoryCanvas; ensure the
exported async function signature includes that Promise-returning type while
leaving the body and usage of componentSlug/storySlug and StoryCanvas unchanged.

Source: Coding guidelines

packages/swingset/src/components/ThemeToggle.tsx (1)

9-34: ⚡ Quick win

Add explicit return type annotation.

The component function should declare an explicit return type per TypeScript guidelines for functions.

♻️ Suggested addition
-export function ThemeToggle() {
+export function ThemeToggle(): JSX.Element {
   const { resolvedTheme, setTheme } = useTheme();
🤖 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/components/ThemeToggle.tsx` around lines 9 - 34, Add an
explicit return type to the ThemeToggle component by annotating its function
signature (e.g., change export function ThemeToggle() to export function
ThemeToggle(): JSX.Element or React.ReactElement) so the component's return type
is declared; if your project requires it, ensure the appropriate React types are
available/imported (or use React.FC) and update the function signature for
ThemeToggle accordingly.

Source: Coding guidelines

packages/swingset/src/components/ClientRoot.tsx (1)

20-29: ⚡ Quick win

Add explicit return type annotations.

Both useBreadcrumb and ClientRoot should declare explicit return types per TypeScript guidelines for functions.

♻️ Suggested additions
-function useBreadcrumb() {
+function useBreadcrumb(): string[] {
   const pathname = usePathname();
   // ...
 }

-export function ClientRoot({ children }: { children: React.ReactNode }) {
+export function ClientRoot({ children }: { children: React.ReactNode }): JSX.Element {
   const crumbs = useBreadcrumb();
   // ...
 }

Also applies to: 31-70

🤖 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/components/ClientRoot.tsx` around lines 20 - 29, Both
functions lack explicit TypeScript return types; add them to satisfy guidelines
by annotating useBreadcrumb to return string[] (function useBreadcrumb():
string[]) and annotate ClientRoot to return a JSX element (e.g., function
ClientRoot(): JSX.Element or React.ReactElement). Update the function signatures
for useBreadcrumb and ClientRoot accordingly and ensure any necessary React
types are imported if not already present.

Source: Coding guidelines

packages/swingset/src/app/layout.tsx (1)

17-31: ⚡ Quick win

Add explicit return type to exported function.

The RootLayout function is exported but lacks an explicit return type annotation. Per coding guidelines, exported functions should have explicit return types for clarity and type safety.

♻️ Suggested fix
-export default function RootLayout({ children }: { children: React.ReactNode }) {
+export default function RootLayout({ children }: { children: React.ReactNode }): React.JSX.Element {
   return (
🤖 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/app/layout.tsx` around lines 17 - 31, The exported
function RootLayout currently lacks an explicit return type; update its
signature to include a React return type (e.g., React.ReactElement or
React.JSX.Element) so the declaration becomes: export default function
RootLayout({ children }: { children: React.ReactNode }): React.JSX.Element { ...
} ensuring the return type covers the JSX returned by RootLayout and satisfies
the project's typing rules.

Source: Coding guidelines

packages/swingset/next.config.mjs (1)

30-33: 💤 Low value

Consider making the webpack alias more maintainable.

The hardcoded relative path '../ui/src/mosaic' couples this config to the current monorepo structure. If packages are reorganized, this alias will silently break.

♻️ Alternative approaches

Option 1: Use TypeScript path mapping instead (more portable):

In tsconfig.json:

{
  "compilerOptions": {
    "paths": {
      "`@clerk/ui/mosaic`": ["../ui/src/mosaic"]
    }
  }
}

Option 2: Add a runtime validation:

  webpack(config) {
+   const mosaicPath = resolve(__dirname, '../ui/src/mosaic');
+   if (!require('fs').existsSync(mosaicPath)) {
+     throw new Error(`Mosaic path not found: ${mosaicPath}`);
+   }
-   config.resolve.alias['`@clerk/ui/mosaic`'] = resolve(__dirname, '../ui/src/mosaic');
+   config.resolve.alias['`@clerk/ui/mosaic`'] = mosaicPath;
    return config;
  },
🤖 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/next.config.mjs` around lines 30 - 33, The webpack alias
currently hardcodes a relative path ('../ui/src/mosaic') which is brittle;
update the alias in next.config.mjs (config.resolve.alias['`@clerk/ui/mosaic`'])
to a more maintainable resolution strategy — either rely on TypeScript path
mapping (add an entry for "`@clerk/ui/mosaic`" in tsconfig.json paths and remove
the hardcoded alias) or compute the path at runtime using a robust lookup (e.g.,
use require.resolve or a package-based resolution strategy to locate the
`@clerk/ui/mosaic` module) and add a runtime existence check to log/throw a clear
error if resolution fails.
packages/swingset/src/components/ThemeProvider.tsx (1)

6-17: ⚡ Quick win

Add explicit return type to exported function.

The ThemeProvider function is exported but lacks an explicit return type annotation. Per coding guidelines, exported functions should have explicit return types for type safety and API clarity.

♻️ Suggested fix
-export function ThemeProvider({ children }: { children: React.ReactNode }) {
+export function ThemeProvider({ children }: { children: React.ReactNode }): React.JSX.Element {
   return (
🤖 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/components/ThemeProvider.tsx` around lines 6 - 17, The
exported function ThemeProvider lacks an explicit return type; update its
signature to include a JSX return type (e.g., React.ReactElement or JSX.Element)
so the exported API is explicitly typed—locate the ThemeProvider declaration and
add the return type annotation after the parameter list while leaving the
internals (NextThemesProvider,
attribute/defaultTheme/enableSystem/disableTransitionOnChange and {children})
unchanged.

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro

Run ID: 11c9a89a-2617-4b42-ad92-b2651287775f

📥 Commits

Reviewing files that changed from the base of the PR and between 1028d82 and ee8505d.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (62)
  • packages/clerk-js/sandbox/app.ts
  • packages/clerk-js/sandbox/template.html
  • packages/clerk-js/src/core/clerk.ts
  • packages/shared/src/types/clerk.ts
  • packages/swingset/README.md
  • packages/swingset/components.json
  • packages/swingset/mdx-components.tsx
  • packages/swingset/next-env.d.ts
  • packages/swingset/next.config.mjs
  • packages/swingset/package.json
  • packages/swingset/postcss.config.mjs
  • packages/swingset/src/app/components/[component]/[story]/page.tsx
  • packages/swingset/src/app/components/[component]/page.tsx
  • packages/swingset/src/app/globals.css
  • packages/swingset/src/app/layout.tsx
  • packages/swingset/src/app/page.tsx
  • packages/swingset/src/components/ClientRoot.tsx
  • packages/swingset/src/components/CodeBlock.tsx
  • packages/swingset/src/components/DocsViewer.tsx
  • packages/swingset/src/components/KnobPanel.tsx
  • packages/swingset/src/components/PropTable.tsx
  • packages/swingset/src/components/StoryCanvas.tsx
  • packages/swingset/src/components/StoryEmbed.tsx
  • packages/swingset/src/components/ThemeProvider.tsx
  • packages/swingset/src/components/ThemeToggle.tsx
  • packages/swingset/src/components/VariablesPanel.tsx
  • packages/swingset/src/components/app-sidebar.tsx
  • packages/swingset/src/components/ui/breadcrumb.tsx
  • packages/swingset/src/components/ui/button.tsx
  • packages/swingset/src/components/ui/collapsible.tsx
  • packages/swingset/src/components/ui/input.tsx
  • packages/swingset/src/components/ui/label.tsx
  • packages/swingset/src/components/ui/select.tsx
  • packages/swingset/src/components/ui/separator.tsx
  • packages/swingset/src/components/ui/sheet.tsx
  • packages/swingset/src/components/ui/sidebar.tsx
  • packages/swingset/src/components/ui/skeleton.tsx
  • packages/swingset/src/components/ui/switch.tsx
  • packages/swingset/src/components/ui/tabs.tsx
  • packages/swingset/src/components/ui/tooltip.tsx
  • packages/swingset/src/hooks/use-mobile.ts
  • packages/swingset/src/lib/generateKnobs.ts
  • packages/swingset/src/lib/registry.ts
  • packages/swingset/src/lib/slug.ts
  • packages/swingset/src/lib/types.ts
  • packages/swingset/src/lib/utils.ts
  • packages/swingset/src/stories/button.mdx
  • packages/swingset/src/stories/button.stories.tsx
  • packages/swingset/src/types/global.d.ts
  • packages/swingset/tsconfig.json
  • packages/ui/src/components/MosaicOrganizationProfile/MosaicOrganizationProfile.tsx
  • packages/ui/src/components/MosaicOrganizationProfile/index.ts
  • packages/ui/src/contexts/ClerkUIComponentsContext.tsx
  • packages/ui/src/contexts/components/__experimental_MosaicOrganizationProfile.ts
  • packages/ui/src/contexts/components/index.ts
  • packages/ui/src/customizables/parseAppearance.ts
  • packages/ui/src/lazyModules/components.ts
  • packages/ui/src/mosaic/Button.tsx
  • packages/ui/src/mosaic/__tests__/cva.test.ts
  • packages/ui/src/mosaic/cva.ts
  • packages/ui/src/types.ts
  • references/mosaic-architecture.md

Comment thread packages/ui/src/mosaic/__tests__/cva.test.ts Outdated
…rp/swingset PR

Strip out the experimental mountMosaicOrganizationProfile method and all related
wiring that was unintentionally added to this PR. The PR should only contain the
new swingset component explorer and mosaic UI foundation (cva, Button, tests).

Reverted:
- __experimental_mountMosaicOrganizationProfile from clerk-js/core/clerk.ts
- Related sandbox wiring in clerk-js
- New types in shared/src/types/clerk.ts

Removed from packages/ui:
- MosaicOrganizationProfile component files
- Context and lazy module wiring
- Type definitions

Resolved merge conflict in cva.test.ts (kept HEAD version).
@changeset-bot

changeset-bot Bot commented Jun 10, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 142b54e

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 requested a deployment to Preview June 10, 2026 15:08 Abandoned
- Fix VariablesPanel to use 'rounded' instead of 'radius'
- Fix control flow statements to use explicit curly braces
- Fix function naming consistency (setRounded instead of setRadius)
- Add dependency to useEffect hook
- Add eslint-disable comment for label-has-associated-control
- Reorganize imports to match linting requirements
- Auto-fix import sorting with ESLint
- Fix floating promises with void operator
- Add button type attributes
- Fix PropTable type casting for default values
- Fix label a11y comment placement
- Add explicit button type in CodeBlock and SidebarRail
@pkg-pr-new

pkg-pr-new Bot commented Jun 10, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/expo

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 142b54e

@vercel vercel Bot requested a deployment to Preview June 10, 2026 16:18 Abandoned
@kylemac kylemac merged commit 81f7c65 into main Jun 10, 2026
46 checks passed
@kylemac kylemac deleted the carp/swingset branch June 10, 2026 16:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants