feat(expo): add native component theming via Expo config plugin#8243
feat(expo): add native component theming via Expo config plugin#8243chriscanin wants to merge 3 commits intomainfrom
Conversation
Adds support for customizing native Clerk UI components (sign-in, sign-up,
user profile) on both iOS and Android via a JSON theme configuration file
referenced in the Expo plugin config:
["@clerk/expo", { "theme": "./clerk-theme.json" }]
The JSON schema supports:
- colors: 15 semantic color tokens (primary, background, danger, etc.)
- darkColors: dark mode color overrides (iOS uses @Environment colorScheme,
Android uses ClerkTheme.darkColors)
- fonts: fontFamily string or per-style overrides (iOS only)
- design: borderRadius
Plugin changes:
- Reads and validates the JSON at prebuild time
- iOS: Embeds theme in Info.plist; removes UIUserInterfaceStyle when
darkColors is present to enable system dark mode
- Android: Copies JSON to app assets directory
Native changes:
- iOS: Parses theme from Info.plist, builds light/dark ClerkTheme objects,
applies via .environment(\.clerkTheme) with colorScheme switching
- Android: Parses theme from assets JSON, sets Clerk.customTheme
- Both: AuthView now uses Clerk.customTheme instead of null
🦋 Changeset detectedLatest commit: b5af733 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
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 |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…erkDesign signature Two fixes needed to make the Android theme actually take effect: 1. Call loadThemeFromAssets() AFTER Clerk.initialize() instead of before. Clerk.initialize() accepts a `theme` parameter that defaults to null and assigns it to Clerk.customTheme on every call, which was wiping out the theme we just loaded. 2. Use the real ClerkDesign(borderRadius: Dp) constructor signature. The previous code passed nonexistent fontFamily and nullable borderRadius parameters that don't compile against clerk-android-ui.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository YAML (base), Organization UI (inherited) Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
✅ Files skipped from review due to trivial changes (1)
📝 WalkthroughWalkthroughAdds native theming support across the Expo Clerk integration. A new Expo config plugin ( Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/expo/app.plugin.js`:
- Line 621: HEX_COLOR_REGEX currently allows 3-character hex colors but iOS
colorFromHex only supports 6- and 8-character forms, causing valid-looking
inputs to return nil; update HEX_COLOR_REGEX to remove the 3-char alternative so
it only matches 6- or 8-digit hex (e.g., change
/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/ to a pattern that omits the
{3} branch), and run/update any tests or callers that assume 3-char acceptance;
alternatively, if you prefer to keep 3-char support, implement expansion logic
in the native colorFromHex parser to expand 3-char shorthand to 6-char before
parsing.
🪄 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
Run ID: 4526911d-c482-4634-a181-3952e94714b2
📒 Files selected for processing (5)
packages/expo/android/src/main/java/expo/modules/clerk/ClerkAuthActivity.ktpackages/expo/android/src/main/java/expo/modules/clerk/ClerkAuthExpoView.ktpackages/expo/android/src/main/java/expo/modules/clerk/ClerkExpoModule.ktpackages/expo/app.plugin.jspackages/expo/ios/ClerkViewFactory.swift
| 'shadow', | ||
| ]; | ||
|
|
||
| const HEX_COLOR_REGEX = /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/; |
There was a problem hiding this comment.
Validation allows 3-char hex but parsers don't support it.
HEX_COLOR_REGEX accepts 3-character hex colors (e.g., #FFF), but the iOS colorFromHex function only handles 6 and 8 character hex strings—3-char hex falls through to default and returns nil. This causes colors to silently fail to apply despite passing validation.
Either remove 3-char support from the regex or add expansion logic in the native parsers.
Proposed fix: Remove 3-char hex from regex
-const HEX_COLOR_REGEX = /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/;
+const HEX_COLOR_REGEX = /^#([0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const HEX_COLOR_REGEX = /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/; | |
| const HEX_COLOR_REGEX = /^#([0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/expo/app.plugin.js` at line 621, HEX_COLOR_REGEX currently allows
3-character hex colors but iOS colorFromHex only supports 6- and 8-character
forms, causing valid-looking inputs to return nil; update HEX_COLOR_REGEX to
remove the 3-char alternative so it only matches 6- or 8-digit hex (e.g., change
/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/ to a pattern that omits the
{3} branch), and run/update any tests or callers that assume 3-char acceptance;
alternatively, if you prefer to keep 3-char support, implement expansion logic
in the native colorFromHex parser to expand 3-char shorthand to 6-char before
parsing.
@clerk/agent-toolkit
@clerk/astro
@clerk/backend
@clerk/chrome-extension
@clerk/clerk-js
@clerk/dev-cli
@clerk/expo
@clerk/expo-passkeys
@clerk/express
@clerk/fastify
@clerk/hono
@clerk/localizations
@clerk/nextjs
@clerk/nuxt
@clerk/react
@clerk/react-router
@clerk/shared
@clerk/tanstack-react-start
@clerk/testing
@clerk/ui
@clerk/upgrade
@clerk/vue
commit: |
Adds support for customizing native Clerk UI components (sign-in, sign-up, user profile) on both iOS and Android via a JSON theme configuration file referenced in the Expo plugin config:
["@clerk/expo", { "theme": "./clerk-theme.json" }]
The JSON schema supports:
Plugin changes:
Native changes:
Description
Checklist
pnpm testruns as expected.pnpm buildruns as expected.Type of change