Skip to content

feat(ui): composed profile components (release)#9144

Open
alexcarpenter wants to merge 10 commits into
mainfrom
carp/profile-release
Open

feat(ui): composed profile components (release)#9144
alexcarpenter wants to merge 10 commits into
mainfrom
carp/profile-release

Conversation

@alexcarpenter

@alexcarpenter alexcarpenter commented Jul 13, 2026

Copy link
Copy Markdown
Member

Integration branch for the composed profile components feature.

The 7-PR review stack merges into this branch bottom-up; this PR merges the assembled feature into main as a single unit. Nothing lands in main until this merges.

Rebased onto latest main, so the final integration is conflict-free. The stack table (added to every PR below) tracks progress.


Stack

Reviewed as a stack. The 7 PRs merge bottom-up into release branch #9144, which integrates into main as a single unit.

# PR Layer
#9144 👈 release → main (integration)
1 #9130 moduleManager getter across build boundary
2 #9131 shared profile UI infra
3 #9132 extract Section components from profile pages
4 #9133 composed shell + providers infra
5 #9134 composed UserProfile
6 #9135 composed OrganizationProfile
7 #9136 expose @clerk/ui/experimental (public API)

@vercel

vercel Bot commented Jul 13, 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 21, 2026 3:48pm
swingset Ready Ready Preview, Comment Jul 21, 2026 3:48pm

Request Review

@changeset-bot

changeset-bot Bot commented Jul 13, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 3464ff9

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

This PR includes changesets to release 23 packages
Name Type
@clerk/ui Minor
@clerk/clerk-js Patch
@clerk/shared Patch
@clerk/react Patch
@clerk/astro Patch
@clerk/chrome-extension Patch
@clerk/swingset Patch
@clerk/vue Patch
@clerk/electron Patch
@clerk/expo Patch
@clerk/backend Patch
@clerk/expo-passkeys Patch
@clerk/express Patch
@clerk/fastify Patch
@clerk/headless Patch
@clerk/hono Patch
@clerk/localizations Patch
@clerk/msw Patch
@clerk/nextjs Patch
@clerk/nuxt Patch
@clerk/react-router Patch
@clerk/tanstack-react-start Patch
@clerk/testing 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

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The change introduces experimental composable UserProfile and OrganizationProfile exports through @clerk/ui/experimental. It adds providers, panels, sections, routing, runtime module-manager access, shared style-cache handling, profile layout primitives, and conditional rendering logic. It also refactors account and security pages, improves Web3 error handling and animation lifecycle management, and adds unit, Vitest, and Playwright coverage for composed flows and exports.

Estimated code review effort: 5 (Critical) | ~120 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.70% 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
Title check ✅ Passed The title clearly summarizes the main change: releasing composed profile components in ui.
Description check ✅ Passed The description matches the changeset and accurately explains this integration release branch.
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.

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

@pkg-pr-new

pkg-pr-new Bot commented Jul 13, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/electron

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

@clerk/electron-passkeys

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

@clerk/eslint-plugin

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

@clerk/expo

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

@clerk/expo-google-signin

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 3464ff9

@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

API Changes Report

Generated by Break Check on 2026-07-21T16:13:37.875Z

Summary

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

🤖 This report was reviewed by claude-sonnet-4-6.


@clerk/ui

Current version: 1.25.6
Recommended bump: MINOR → 1.26.0

Subpath ./experimental

🟢 Additions (1)

Added: ./experimental

New subpath export ./experimental (27 exported members)

Subpath ./internal

🟡 Non-breaking Changes (1)

Modified: ElementsConfig
// ... 391 unchanged lines elided ...
    profileSectionPrimaryButton: WithOptions<ProfileSectionId>;
    profileSectionButtonGroup: WithOptions<ProfileSectionId>;
    profilePage: WithOptions<ProfilePageId>;
+   profilePageContent: WithOptions;
    formattedPhoneNumber: WithOptions;
    formattedPhoneNumberFlag: WithOptions;
    formattedPhoneNumberText: WithOptions;
// ... 158 unchanged lines elided ...

Static analyzer: Breaking change in type alias ElementsConfig: Type changed: {button:import("@clerk/ui").~WithOptions<string>;input:import("@clerk/ui").~WithOptions;checkbox:import("@clerk/ui").~W…{button:import("@clerk/ui").~WithOptions<string>;input:import("@clerk/ui").~WithOptions;checkbox:import("@clerk/ui").~W…

🤖 AI review (reclassified as non-breaking) (80%): The elided diff shows 475 vs 476 lines, indicating one new property was added to ElementsConfig; ElementsConfig is used only as a mapped-type source to produce the output type Elements, so consumers only read derived values and never construct ElementsConfig directly, making the addition of a property non-breaking.


Report generated by Break Check

Last ran on 3464ff9.

@alexcarpenter

Copy link
Copy Markdown
Member Author

!snapshot

@github-actions

Copy link
Copy Markdown
Contributor

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

Package Version
@clerk/astro 3.4.19-snapshot.v20260716135136
@clerk/backend 3.11.7-snapshot.v20260716135136
@clerk/chrome-extension 3.1.54-snapshot.v20260716135136
@clerk/clerk-js 6.25.5-snapshot.v20260716135136
@clerk/electron 0.0.15-snapshot.v20260716135136
@clerk/electron-passkeys 0.0.4-snapshot.v20260716135136
@clerk/eslint-plugin 0.2.1-snapshot.v20260716135136
@clerk/expo 3.7.7-snapshot.v20260716135136
@clerk/expo-passkeys 1.2.6-snapshot.v20260716135136
@clerk/express 2.1.43-snapshot.v20260716135136
@clerk/fastify 3.1.53-snapshot.v20260716135136
@clerk/headless 0.0.13-snapshot.v20260716135136
@clerk/hono 0.1.53-snapshot.v20260716135136
@clerk/localizations 4.13.5-snapshot.v20260716135136
@clerk/msw 0.0.49-snapshot.v20260716135136
@clerk/nextjs 7.5.20-snapshot.v20260716135136
@clerk/nuxt 2.6.19-snapshot.v20260716135136
@clerk/react 6.12.5-snapshot.v20260716135136
@clerk/react-router 3.5.12-snapshot.v20260716135136
@clerk/shared 4.25.5-snapshot.v20260716135136
@clerk/swingset 0.0.20-snapshot.v20260716135136
@clerk/tanstack-react-start 1.4.20-snapshot.v20260716135136
@clerk/testing 2.2.10-snapshot.v20260716135136
@clerk/ui 1.26.0-snapshot.v20260716135136
@clerk/upgrade 2.0.5-snapshot.v20260716135136
@clerk/vue 2.4.17-snapshot.v20260716135136

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

npm i @clerk/astro@3.4.19-snapshot.v20260716135136 --save-exact

@clerk/backend

npm i @clerk/backend@3.11.7-snapshot.v20260716135136 --save-exact

@clerk/chrome-extension

npm i @clerk/chrome-extension@3.1.54-snapshot.v20260716135136 --save-exact

@clerk/clerk-js

npm i @clerk/clerk-js@6.25.5-snapshot.v20260716135136 --save-exact

@clerk/electron

npm i @clerk/electron@0.0.15-snapshot.v20260716135136 --save-exact

@clerk/electron-passkeys

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

@clerk/eslint-plugin

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

@clerk/expo

npm i @clerk/expo@3.7.7-snapshot.v20260716135136 --save-exact

@clerk/expo-passkeys

npm i @clerk/expo-passkeys@1.2.6-snapshot.v20260716135136 --save-exact

@clerk/express

npm i @clerk/express@2.1.43-snapshot.v20260716135136 --save-exact

@clerk/fastify

npm i @clerk/fastify@3.1.53-snapshot.v20260716135136 --save-exact

@clerk/headless

npm i @clerk/headless@0.0.13-snapshot.v20260716135136 --save-exact

@clerk/hono

npm i @clerk/hono@0.1.53-snapshot.v20260716135136 --save-exact

@clerk/localizations

npm i @clerk/localizations@4.13.5-snapshot.v20260716135136 --save-exact

@clerk/msw

npm i @clerk/msw@0.0.49-snapshot.v20260716135136 --save-exact

@clerk/nextjs

npm i @clerk/nextjs@7.5.20-snapshot.v20260716135136 --save-exact

@clerk/nuxt

npm i @clerk/nuxt@2.6.19-snapshot.v20260716135136 --save-exact

@clerk/react

npm i @clerk/react@6.12.5-snapshot.v20260716135136 --save-exact

@clerk/react-router

npm i @clerk/react-router@3.5.12-snapshot.v20260716135136 --save-exact

@clerk/shared

npm i @clerk/shared@4.25.5-snapshot.v20260716135136 --save-exact

@clerk/swingset

npm i @clerk/swingset@0.0.20-snapshot.v20260716135136 --save-exact

@clerk/tanstack-react-start

npm i @clerk/tanstack-react-start@1.4.20-snapshot.v20260716135136 --save-exact

@clerk/testing

npm i @clerk/testing@2.2.10-snapshot.v20260716135136 --save-exact

@clerk/ui

npm i @clerk/ui@1.26.0-snapshot.v20260716135136 --save-exact

@clerk/upgrade

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

@clerk/vue

npm i @clerk/vue@2.4.17-snapshot.v20260716135136 --save-exact

@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: 3

🧹 Nitpick comments (5)
packages/ui/src/composed/OrganizationProfile/OrganizationProfileProvider.tsx (1)

31-55: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Memoize the context value to avoid needless consumer re-renders.

orgProfileCtxValue (including a brand-new customPages: [] array) is recreated on every render and passed straight into OrganizationProfileContext.Provider. Any consumer relying on referential identity (e.g. a useEffect/useMemo dependency on customPages or the context object itself) will re-run needlessly on every re-render of this provider.

♻️ Suggested fix
-  const orgProfileCtxValue = {
-    componentName: 'OrganizationProfile' as const,
-    mode: 'mounted' as const,
-    routing: 'hash' as const,
-    path: undefined,
-    afterLeaveOrganizationUrl,
-    apiKeysProps,
-    customPages: [],
-  };
+  const orgProfileCtxValue = useMemo(
+    () => ({
+      componentName: 'OrganizationProfile' as const,
+      mode: 'mounted' as const,
+      routing: 'hash' as const,
+      path: undefined,
+      afterLeaveOrganizationUrl,
+      apiKeysProps,
+      customPages: [],
+    }),
+    [afterLeaveOrganizationUrl, apiKeysProps],
+  );

As per coding guidelines, **/*.{tsx,jsx} should "Minimize re-renders in React components" and "Use proper useMemo for expensive computations in React 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/ui/src/composed/OrganizationProfile/OrganizationProfileProvider.tsx`
around lines 31 - 55, Memoize orgProfileCtxValue in OrganizationProfileProvider
so its object identity remains stable across renders, including the customPages
array. Use React’s memoization hook with dependencies covering
afterLeaveOrganizationUrl and apiKeysProps, while keeping the existing context
fields and provider behavior unchanged.

Source: Coding guidelines

packages/ui/src/experimental/index.ts (1)

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

Replace the chained wildcard barrels with deliberate public exports.

The intermediate and published barrels together expose future symbols and collisions through @clerk/ui/experimental.

  • packages/ui/src/experimental/index.ts#L10-L10: explicitly export the supported experimental components from their leaf modules.
  • packages/ui/src/composed/index.ts#L1-L2: remove the intermediate wildcard aggregation or replace it with an explicit internal export list.

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

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

In `@packages/ui/src/experimental/index.ts` at line 10, Replace the wildcard
export in packages/ui/src/experimental/index.ts at line 10 with explicit exports
of the supported experimental components from their leaf modules. In
packages/ui/src/composed/index.ts at lines 1-2, remove the wildcard aggregation
or replace it with an explicit internal export list so future symbols and
collisions are not exposed.

Source: Coding guidelines

integration/tests/composed-components.test.ts (1)

31-45: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add an integration fixture without a local 'use client' boundary.

This page becomes a Client Component, so it cannot verify the advertised ability to import and render these exports directly from a React Server Component. Add a minimal server page that imports the experimental components and asserts they render.

As per coding guidelines, include tests for all new features.

🤖 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 `@integration/tests/composed-components.test.ts` around lines 31 - 45, Update
the composedUserProfilePage fixture to remove the local 'use client' directive
and keep it as a minimal React Server Component that imports and renders the
experimental UserProfile exports. Ensure the integration test asserts successful
rendering from this server page, covering the direct server-component import
path for all newly supported components.

Source: Coding guidelines

packages/ui/src/elements/ProfileCard/ProfilePagePanel.tsx (1)

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

Add explicit return types to exported components.

  • packages/ui/src/elements/ProfileCard/ProfilePagePanel.tsx#L18-L18: annotate the component return type.
  • packages/ui/src/components/ConfigureSSO/ConfigureSSO.tsx#L46-L46: annotate the newly exported component return type.
  • packages/ui/src/elements/ProfileCard/ProfileCardPage.tsx#L26-L26: annotate the exported component return type.

As per coding guidelines, exported TypeScript APIs require explicit return types; based on learnings, this repository enforces that for exported functions.

🤖 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/elements/ProfileCard/ProfilePagePanel.tsx` at line 18, Add
explicit return type annotations to the exported components ProfilePagePanel,
ConfigureSSO, and ProfileCardPage. Update each component declaration at
packages/ui/src/elements/ProfileCard/ProfilePagePanel.tsx:18-18,
packages/ui/src/components/ConfigureSSO/ConfigureSSO.tsx:46-46, and
packages/ui/src/elements/ProfileCard/ProfileCardPage.tsx:26-26, using the
appropriate React component return type while preserving their existing
behavior.

Sources: Coding guidelines, Learnings

packages/ui/src/composed/UserProfile/UserProfileProvider.tsx (1)

29-37: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Memoize the context value to avoid re-rendering the whole composed subtree.

userProfileCtxValue is a new object every render, so all descendants consuming UserProfileContext re-render on every UserProfileProvider render regardless of whether any field changed. ProfileProviderShell already memoizes its comparable derived values (router, options), so this is inconsistent with the pattern elsewhere in the layer.

As per coding guidelines, "**/*.{jsx,tsx}": "Use proper useMemo for expensive computations in React components" and "Minimize re-renders in React components."

♻️ Proposed fix
+import { useMemo } from 'react';
 ...
-  const userProfileCtxValue = {
-    componentName: 'UserProfile' as const,
-    mode: 'mounted' as const,
-    routing: 'hash' as const,
-    path: undefined,
-    additionalOAuthScopes,
-    apiKeysProps,
-    customPages: [],
-  };
+  const userProfileCtxValue = useMemo(
+    () => ({
+      componentName: 'UserProfile' as const,
+      mode: 'mounted' as const,
+      routing: 'hash' as const,
+      path: undefined,
+      additionalOAuthScopes,
+      apiKeysProps,
+      customPages: [],
+    }),
+    [additionalOAuthScopes, apiKeysProps],
+  );
🤖 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/composed/UserProfile/UserProfileProvider.tsx` around lines 29
- 37, Memoize the userProfileCtxValue object in UserProfileProvider with
React.useMemo, using all values included in the context object—especially
additionalOAuthScopes and apiKeysProps—as dependencies; preserve the existing
constant fields and empty customPages value.

Source: Coding guidelines

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

Inline comments:
In `@integration/tests/composed-components.test.ts`:
- Around line 127-130: Update the afterAll cleanup blocks around fake users,
organizations, and related temporary entities to use try/finally so each entity
deletion is attempted safely and app.teardown() always runs independently of API
cleanup failures. Preserve the existing cleanup targets and ordering where
possible while ensuring failures in assertions or deletion do not prevent
subsequent cleanup.

In `@packages/ui/src/composed/__tests__/action-animation.test.tsx`:
- Around line 16-26: Replace any-based animation helper types with
Parameters<Element['animate']> call tuples and Keyframe/Keyframe[] types in
findAddAnimationCall and the corresponding helpers in
packages/ui/src/composed/__tests__/action-animation.test.tsx (lines 16-26) and
packages/ui/src/composed/__tests__/auto-animate-strictmode.test.tsx (lines
28-48). In packages/ui/src/composed/__tests__/auto-animate-strictmode.test.tsx
(lines 62-68), replace the as any mock result with an Animation-typed fixture or
narrow Partial<Animation> cast.

In `@packages/ui/src/styledSystem/createEmotionCache.ts`:
- Around line 3-4: Update the Emotion insert override in createEmotionCache so
its assigned function inherits cache.insert’s parameter types instead of
declaring an explicit any; keep sheet typed as Emotion’s StyleSheet and remove
the now-unused SerializedStyles import.

---

Nitpick comments:
In `@integration/tests/composed-components.test.ts`:
- Around line 31-45: Update the composedUserProfilePage fixture to remove the
local 'use client' directive and keep it as a minimal React Server Component
that imports and renders the experimental UserProfile exports. Ensure the
integration test asserts successful rendering from this server page, covering
the direct server-component import path for all newly supported components.

In
`@packages/ui/src/composed/OrganizationProfile/OrganizationProfileProvider.tsx`:
- Around line 31-55: Memoize orgProfileCtxValue in OrganizationProfileProvider
so its object identity remains stable across renders, including the customPages
array. Use React’s memoization hook with dependencies covering
afterLeaveOrganizationUrl and apiKeysProps, while keeping the existing context
fields and provider behavior unchanged.

In `@packages/ui/src/composed/UserProfile/UserProfileProvider.tsx`:
- Around line 29-37: Memoize the userProfileCtxValue object in
UserProfileProvider with React.useMemo, using all values included in the context
object—especially additionalOAuthScopes and apiKeysProps—as dependencies;
preserve the existing constant fields and empty customPages value.

In `@packages/ui/src/elements/ProfileCard/ProfilePagePanel.tsx`:
- Line 18: Add explicit return type annotations to the exported components
ProfilePagePanel, ConfigureSSO, and ProfileCardPage. Update each component
declaration at packages/ui/src/elements/ProfileCard/ProfilePagePanel.tsx:18-18,
packages/ui/src/components/ConfigureSSO/ConfigureSSO.tsx:46-46, and
packages/ui/src/elements/ProfileCard/ProfileCardPage.tsx:26-26, using the
appropriate React component return type while preserving their existing
behavior.

In `@packages/ui/src/experimental/index.ts`:
- Line 10: Replace the wildcard export in packages/ui/src/experimental/index.ts
at line 10 with explicit exports of the supported experimental components from
their leaf modules. In packages/ui/src/composed/index.ts at lines 1-2, remove
the wildcard aggregation or replace it with an explicit internal export list so
future symbols and collisions are not exposed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro Plus

Run ID: 4b6a5164-137f-461f-85b0-6ad847013b23

📥 Commits

Reviewing files that changed from the base of the PR and between 430ae23 and 3464ff9.

⛔ Files ignored due to path filters (1)
  • packages/ui/src/experimental/__tests__/__snapshots__/flat-exports.test.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (85)
  • .changeset/profile-section-components.md
  • .changeset/shared-moduleManager-registry.md
  • integration/tests/composed-components.test.ts
  • packages/clerk-js/src/core/clerk.ts
  • packages/react/src/__tests__/isomorphicClerk.test.ts
  • packages/react/src/isomorphicClerk.ts
  • packages/shared/src/types/clerk.ts
  • packages/ui/package.json
  • packages/ui/src/components/ConfigureSSO/ConfigureSSO.tsx
  • packages/ui/src/components/OrganizationProfile/OrganizationBillingPage.tsx
  • packages/ui/src/components/OrganizationProfile/OrganizationGeneralPage.tsx
  • packages/ui/src/components/OrganizationProfile/OrganizationMembers.tsx
  • packages/ui/src/components/UserProfile/APIKeysPage.tsx
  • packages/ui/src/components/UserProfile/AccountPage.tsx
  • packages/ui/src/components/UserProfile/AccountSections.tsx
  • packages/ui/src/components/UserProfile/BillingPage.tsx
  • packages/ui/src/components/UserProfile/SecurityPage.tsx
  • packages/ui/src/components/UserProfile/SecuritySections.tsx
  • packages/ui/src/components/UserProfile/Web3Form.tsx
  • packages/ui/src/components/UserProfile/__tests__/AccountSections.test.tsx
  • packages/ui/src/components/UserProfile/__tests__/SecuritySections.test.tsx
  • packages/ui/src/components/UserProfile/__tests__/Web3Section.test.tsx
  • packages/ui/src/composed/APIKeysSection.tsx
  • packages/ui/src/composed/BillingSection.tsx
  • packages/ui/src/composed/OrganizationProfile/APIKeys.tsx
  • packages/ui/src/composed/OrganizationProfile/Billing.tsx
  • packages/ui/src/composed/OrganizationProfile/General.tsx
  • packages/ui/src/composed/OrganizationProfile/GeneralDeleteOrganization.tsx
  • packages/ui/src/composed/OrganizationProfile/GeneralLeaveOrganization.tsx
  • packages/ui/src/composed/OrganizationProfile/GeneralOrganizationProfile.tsx
  • packages/ui/src/composed/OrganizationProfile/GeneralVerifiedDomains.tsx
  • packages/ui/src/composed/OrganizationProfile/Members.tsx
  • packages/ui/src/composed/OrganizationProfile/OrganizationProfileProvider.tsx
  • packages/ui/src/composed/OrganizationProfile/Security.tsx
  • packages/ui/src/composed/OrganizationProfile/index.tsx
  • packages/ui/src/composed/PageContext.tsx
  • packages/ui/src/composed/ProfileProviderShell.tsx
  • packages/ui/src/composed/UserProfile/APIKeys.tsx
  • packages/ui/src/composed/UserProfile/Account.tsx
  • packages/ui/src/composed/UserProfile/AccountConnectedAccounts.tsx
  • packages/ui/src/composed/UserProfile/AccountEmails.tsx
  • packages/ui/src/composed/UserProfile/AccountEnterpriseAccounts.tsx
  • packages/ui/src/composed/UserProfile/AccountPhone.tsx
  • packages/ui/src/composed/UserProfile/AccountProfile.tsx
  • packages/ui/src/composed/UserProfile/AccountUsername.tsx
  • packages/ui/src/composed/UserProfile/AccountWeb3.tsx
  • packages/ui/src/composed/UserProfile/Billing.tsx
  • packages/ui/src/composed/UserProfile/Security.tsx
  • packages/ui/src/composed/UserProfile/SecurityActiveDevices.tsx
  • packages/ui/src/composed/UserProfile/SecurityDelete.tsx
  • packages/ui/src/composed/UserProfile/SecurityMfa.tsx
  • packages/ui/src/composed/UserProfile/SecurityPasskeys.tsx
  • packages/ui/src/composed/UserProfile/SecurityPassword.tsx
  • packages/ui/src/composed/UserProfile/UserProfileProvider.tsx
  • packages/ui/src/composed/UserProfile/index.tsx
  • packages/ui/src/composed/__tests__/OrganizationProfile.test.tsx
  • packages/ui/src/composed/__tests__/OrganizationProfileSections.test.tsx
  • packages/ui/src/composed/__tests__/UserProfile.test.tsx
  • packages/ui/src/composed/__tests__/UserProfileSections.test.tsx
  • packages/ui/src/composed/__tests__/action-animation.test.tsx
  • packages/ui/src/composed/__tests__/auto-animate-strictmode.test.tsx
  • packages/ui/src/composed/__tests__/composed-provider-wiring.test.tsx
  • packages/ui/src/composed/__tests__/hotload-vs-bundle-risks.test.tsx
  • packages/ui/src/composed/__tests__/stub-limitations.test.ts
  • packages/ui/src/composed/__tests__/style-cache-sharing.test.tsx
  • packages/ui/src/composed/createSection.tsx
  • packages/ui/src/composed/index.ts
  • packages/ui/src/composed/stubRouter.ts
  • packages/ui/src/composed/useBillingRouter.ts
  • packages/ui/src/composed/useRequirePage.ts
  • packages/ui/src/customizables/elementDescriptors.ts
  • packages/ui/src/elements/Animated.tsx
  • packages/ui/src/elements/AppearanceOverrides.tsx
  • packages/ui/src/elements/ProfileCard/ProfileCardPage.tsx
  • packages/ui/src/elements/ProfileCard/ProfilePagePanel.tsx
  • packages/ui/src/elements/ProfileCard/__tests__/ProfilePagePanel.test.tsx
  • packages/ui/src/elements/ProfileCard/index.ts
  • packages/ui/src/experimental/__tests__/flat-exports.test.ts
  • packages/ui/src/experimental/index.ts
  • packages/ui/src/hooks/useSafeState.ts
  • packages/ui/src/internal/appearance.ts
  • packages/ui/src/internal/styleCacheStore.ts
  • packages/ui/src/styledSystem/StyleCacheProvider.tsx
  • packages/ui/src/styledSystem/createEmotionCache.ts
  • packages/ui/tsdown.config.mts
🔗 Linked repositories identified

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

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

Comment on lines +127 to +130
test.afterAll(async () => {
await fakeUser.deleteIfExists();
await app.teardown();
});

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.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Make E2E cleanup failure-safe.

Failed assertions can leak delFakeUser or delOrg, while failed entity cleanup can skip app.teardown(). Use try/finally for temporary entities and guarantee application teardown independently of API cleanup failures.

As per coding guidelines, implement proper test isolation and cleanup.

Also applies to: 219-243, 357-362, 404-438

🤖 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 `@integration/tests/composed-components.test.ts` around lines 127 - 130, Update
the afterAll cleanup blocks around fake users, organizations, and related
temporary entities to use try/finally so each entity deletion is attempted
safely and app.teardown() always runs independently of API cleanup failures.
Preserve the existing cleanup targets and ordering where possible while ensuring
failures in assertions or deletion do not prevent subsequent cleanup.

Source: Coding guidelines

Comment on lines +16 to +26
function findAddAnimationCall(calls: any[]) {
return calls.find(call => {
const keyframes = call[0];
if (!Array.isArray(keyframes)) {
return false;
}
return keyframes.some(
(kf: any) => kf.opacity === 0 && typeof kf.transform === 'string' && kf.transform.includes('scale'),
);
});
}

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.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== action-animation.test.tsx ==\n'
sed -n '1,220p' packages/ui/src/composed/__tests__/action-animation.test.tsx

printf '\n== auto-animate-strictmode.test.tsx ==\n'
sed -n '1,240p' packages/ui/src/composed/__tests__/auto-animate-strictmode.test.tsx

printf '\n== search for Animation typing patterns ==\n'
rg -n "Parameters<.*animate|Keyframe|Animation\s*\{|mockImplementation\(\s*\(\)\s*=>\s*\(\{.*finished" packages/ui/src -g '*.{ts,tsx}'

Repository: clerk/javascript

Length of output: 7864


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,220p' packages/ui/src/composed/__tests__/action-animation.test.tsx
printf '\n---\n'
sed -n '1,240p' packages/ui/src/composed/__tests__/auto-animate-strictmode.test.tsx
printf '\n---\n'
rg -n "Parameters<.*animate|Keyframe|Animation\\b|mockImplementation\\(\\s*\\(\\)\\s*=>\\s*\\(\\{.*finished" packages/ui/src -g '*.{ts,tsx}'

Repository: clerk/javascript

Length of output: 11158


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'tsconfig files:\n'
fd -a "tsconfig*.json" .
printf '\npackage files mentioning lib/dom:\n'
rg -n '"lib"|dom' packages/ui/tsconfig*.json tsconfig*.json package.json -g 'tsconfig*.json' -g 'package.json' || true

Repository: clerk/javascript

Length of output: 3656


Type these animation test helpers instead of using any

  • packages/ui/src/composed/__tests__/action-animation.test.tsx#L16-L26 and packages/ui/src/composed/__tests__/auto-animate-strictmode.test.tsx#L28-L48: type the call tuples as Parameters<Element['animate']> and the keyframes as Keyframe[]/Keyframe so the assertions stay aligned with the DOM API.
  • packages/ui/src/composed/__tests__/auto-animate-strictmode.test.tsx#L62-L68: replace the as any mock result with an Animation-typed fixture or a narrow Partial<Animation> cast.
📍 Affects 2 files
  • packages/ui/src/composed/__tests__/action-animation.test.tsx#L16-L26 (this comment)
  • packages/ui/src/composed/__tests__/auto-animate-strictmode.test.tsx#L28-L48
  • packages/ui/src/composed/__tests__/auto-animate-strictmode.test.tsx#L62-L68
🤖 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/composed/__tests__/action-animation.test.tsx` around lines 16
- 26, Replace any-based animation helper types with
Parameters<Element['animate']> call tuples and Keyframe/Keyframe[] types in
findAddAnimationCall and the corresponding helpers in
packages/ui/src/composed/__tests__/action-animation.test.tsx (lines 16-26) and
packages/ui/src/composed/__tests__/auto-animate-strictmode.test.tsx (lines
28-48). In packages/ui/src/composed/__tests__/auto-animate-strictmode.test.tsx
(lines 62-68), replace the as any mock result with an Animation-typed fixture or
narrow Partial<Animation> cast.

Source: Coding guidelines

Comment on lines +3 to +4
// eslint-disable-next-line no-restricted-imports
import type { SerializedStyles } from '@emotion/react';

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.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '--- file outline ---\n'
ast-grep outline packages/ui/src/styledSystem/createEmotionCache.ts --view expanded || true

printf '\n--- file contents ---\n'
cat -n packages/ui/src/styledSystem/createEmotionCache.ts

Repository: clerk/javascript

Length of output: 245


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
p = Path('packages/ui/src/styledSystem/createEmotionCache.ts')
print(p.read_text())
PY

Repository: clerk/javascript

Length of output: 1826


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n "cache\.insert|type Cache|insert\(" packages/ui/src packages/ui/src/styledSystem -g '*.ts' -g '*.tsx' || true

Repository: clerk/javascript

Length of output: 1235


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n '"`@emotion/cache`"|`@emotion/cache`' package.json packages -g 'package.json' -g 'pnpm-lock.yaml' -g 'yarn.lock' -g 'package-lock.json' || true

Repository: clerk/javascript

Length of output: 216


🏁 Script executed:

#!/bin/bash
set -euo pipefail

cat -n package.json | sed -n '1,220p'

Repository: clerk/javascript

Length of output: 11839


🏁 Script executed:

#!/bin/bash
set -euo pipefail

cat -n packages/ui/package.json | sed -n '1,220p'

Repository: clerk/javascript

Length of output: 6230


🌐 Web query:

@emotion/cache EmotionCache insert sheet type SerializedStyles Sheet TypeScript

💡 Result:

In Emotion, the EmotionCache interface and its associated methods govern how styles are processed and injected into the DOM. The core mechanism for style insertion involves the insert method within the EmotionCache instance [1][2]. EmotionCache Interface The EmotionCache is created using the createCache function and includes the following primary properties and methods: - insert: (selector: string, serialized: SerializedStyles, sheet: StyleSheet, shouldCache: boolean) => string | void [1][2] - sheet: An instance of StyleSheet, which handles the actual interaction with the DOM (appending/prepending style tags) [1][3]. - key: A string used as a prefix for class names and the data-emotion attribute [4][5]. - inserted: A record tracking which styles have already been processed to avoid redundant injections [1][2]. The insert Method The insert method is responsible for taking serialized styles and managing their placement [1]. - Parameters: - selector: The CSS selector for the styles (e.g., a class name selector) [1]. - serialized: An object of type SerializedStyles, which contains the name and the actual CSS rules [1][6]. - sheet: The StyleSheet instance where the rule should be added [1]. - shouldCache: A boolean indicating whether the result should be recorded in the cache's inserted object [1]. SerializedStyles Type The SerializedStyles type typically consists of at least a name (a unique hash of the styles) and the styles themselves (the CSS string) [1][6]. It is often generated by Emotion's internal serialization utilities when you use css or styled components [6][7]. StyleSheet The StyleSheet class (from @emotion/sheet) is the low-level manager for style tags [3]. It provides methods such as: - insert(rule: string): Injects a single CSS rule into the stylesheet [3]. - flush: Removes all styles managed by the sheet [3]. - hydrate(nodes: Node[]): Used for server-side rendering (SSR) to attach the cache to existing style tags [1][3]. In typical usage, you do not call insert manually; instead, Emotion handles this automatically when your components render. If you need custom behavior—such as changing where styles are injected—you configure the cache via createCache using options like container, insertionPoint, or prepend [4][5][3].

Citations:


Remove the explicit any from the Emotion insert override. Let the assignment inherit cache.insert’s parameter types; sheet stays typed as Emotion’s StyleSheet, and the SerializedStyles import becomes unnecessary.

🤖 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/styledSystem/createEmotionCache.ts` around lines 3 - 4,
Update the Emotion insert override in createEmotionCache so its assigned
function inherits cache.insert’s parameter types instead of declaring an
explicit any; keep sheet typed as Emotion’s StyleSheet and remove the now-unused
SerializedStyles import.

Source: Coding guidelines

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.

1 participant