fix: improve auth UI customization options in react sdk#301
fix: improve auth UI customization options in react sdk#301Nitin-kumar-yadav1307 wants to merge 4 commits into
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds provider, theme, branding, and label configuration to UrAuth; refactors styling to use computed theme/colors; updates demo to use new props and useAuth logout; and expands tests for provider/branding/label-driven behaviors. ChangesConfigurable Authentication UI
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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: 2
🧹 Nitpick comments (3)
sdks/urbackend-react/src/components/UrAuth.tsx (3)
586-605: ⚡ Quick winUseless ternary - both branches are identical.
Line 589:
{mode === 'reset' ? text.passwordLabel : text.passwordLabel}evaluates to the same value regardless of condition. Simplify to just{text.passwordLabel}.Suggested fix
- <label style={styles.label}>{mode === 'reset' ? text.passwordLabel : text.passwordLabel}</label> + <label style={styles.label}>{text.passwordLabel}</label>🤖 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 `@sdks/urbackend-react/src/components/UrAuth.tsx` around lines 586 - 605, The label rendering in UrAuth.tsx uses a redundant ternary expression `{mode === 'reset' ? text.passwordLabel : text.passwordLabel}` inside the component's JSX; replace the ternary with the plain value `text.passwordLabel` to simplify the code where the password label is rendered (within the conditional block that checks `(mode === 'signin' || mode === 'signup' || mode === 'reset')`), leaving the surrounding JSX (including the signin-only forgot button that calls `setMode('forgot')` and `clearError()`) unchanged.
491-511: ⚡ Quick winHeader condition is always true due to fallback values.
headerTitleandheaderSubtitlealways have values (via fallback chain to'urBackend'and mode-based text). This makes the condition|| headerTitle || headerSubtitlealways true, so the header is always rendered.If the header should always render, simplify by removing the condition. If it should only render when branding is explicitly provided, remove the
|| headerTitle || headerSubtitlepart:Option A: Always show header (simplify)
- {(branding?.logo || branding?.brandName || branding?.appName || branding?.title || branding?.subtitle || headerTitle || headerSubtitle) && ( - <div style={styles.header}> + <div style={styles.header}>Option B: Only show when branding provided
- {(branding?.logo || branding?.brandName || branding?.appName || branding?.title || branding?.subtitle || headerTitle || headerSubtitle) && ( + {(branding?.logo || branding?.brandName || branding?.appName || branding?.title || branding?.subtitle) && (🤖 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 `@sdks/urbackend-react/src/components/UrAuth.tsx` around lines 491 - 511, The current render condition always evaluates to true because headerTitle and headerSubtitle are never empty; update the logic in the JSX that controls the header (the conditional wrapping the <div style={styles.header}> block) to match intended behavior: either simplify by removing the entire condition so the header always renders, or restrict rendering to explicit branding by removing "|| headerTitle || headerSubtitle" from the boolean expression so it only shows when branding?.logo, branding?.brandName, branding?.appName, branding?.title, or branding?.subtitle are present; adjust references to headerTitle/headerSubtitle accordingly in the block that renders brandRow, brandLogo, brandTitle, and brandSubtitle.
354-366: ⚡ Quick winUseless ternary in gradient - both branches are identical.
The ternary
${theme === 'dark' ? '#111111' : '#111111'}always evaluates to'#111111'. If both themes should use the same value, remove the ternary. If different themes need different gradient endpoints, fix the values.Suggested fix (assuming same value for both themes)
- background: `linear-gradient(180deg, ${primaryColor} 0%, ${theme === 'dark' ? '`#111111`' : '`#111111`'} 100%)`, + background: `linear-gradient(180deg, ${primaryColor} 0%, `#111111` 100%)`,🤖 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 `@sdks/urbackend-react/src/components/UrAuth.tsx` around lines 354 - 366, The gradient background in the style object inside UrAuth uses an unnecessary ternary (`${theme === 'dark' ? '`#111111`' : '`#111111`'}`) that always yields '`#111111`'; update the background property in the component (the style block where background is defined) to either use a single literal value (`linear-gradient(180deg, ${primaryColor} 0%, `#111111` 100%)`) if both themes should match, or replace the ternary endpoints with the correct dark/light color values if they should differ (e.g., use a distinct variable like themeColors.backgroundDark / themeColors.backgroundLight).
🤖 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 `@examples/react-sdk-demo/src/App.tsx`:
- Line 86: The line forces a string cast on user.avatarUrl which is typed
unknown; instead validate at runtime and only use it when it is actually a
string. In the App component (the JSX rendering that uses user.avatarUrl) remove
the `as string` cast and change the rendering logic to check `typeof
user?.avatarUrl === 'string' && user.avatarUrl` (or use a string
fallback/placeholder) before passing it to the img src so non-string values
aren’t rendered into the src attribute.
In `@sdks/urbackend-react/src/components/UrAuth.tsx`:
- Around line 170-183: When providers is an object the current logic forces
isEmailPasswordEnabled to false when providers.emailPassword is undefined,
ignoring the enableEmailPassword prop; update the object-branch assignment in
the UrAuth component so isEmailPasswordEnabled falls back to the incoming prop
(enableEmailPassword) instead of false (i.e., set isEmailPasswordEnabled =
providers.emailPassword !== undefined ? providers.emailPassword :
enableEmailPassword) while keeping the existing handling for google/github via
providers.google and providers.github.
---
Nitpick comments:
In `@sdks/urbackend-react/src/components/UrAuth.tsx`:
- Around line 586-605: The label rendering in UrAuth.tsx uses a redundant
ternary expression `{mode === 'reset' ? text.passwordLabel :
text.passwordLabel}` inside the component's JSX; replace the ternary with the
plain value `text.passwordLabel` to simplify the code where the password label
is rendered (within the conditional block that checks `(mode === 'signin' ||
mode === 'signup' || mode === 'reset')`), leaving the surrounding JSX (including
the signin-only forgot button that calls `setMode('forgot')` and `clearError()`)
unchanged.
- Around line 491-511: The current render condition always evaluates to true
because headerTitle and headerSubtitle are never empty; update the logic in the
JSX that controls the header (the conditional wrapping the <div
style={styles.header}> block) to match intended behavior: either simplify by
removing the entire condition so the header always renders, or restrict
rendering to explicit branding by removing "|| headerTitle || headerSubtitle"
from the boolean expression so it only shows when branding?.logo,
branding?.brandName, branding?.appName, branding?.title, or branding?.subtitle
are present; adjust references to headerTitle/headerSubtitle accordingly in the
block that renders brandRow, brandLogo, brandTitle, and brandSubtitle.
- Around line 354-366: The gradient background in the style object inside UrAuth
uses an unnecessary ternary (`${theme === 'dark' ? '`#111111`' : '`#111111`'}`) that
always yields '`#111111`'; update the background property in the component (the
style block where background is defined) to either use a single literal value
(`linear-gradient(180deg, ${primaryColor} 0%, `#111111` 100%)`) if both themes
should match, or replace the ternary endpoints with the correct dark/light color
values if they should differ (e.g., use a distinct variable like
themeColors.backgroundDark / themeColors.backgroundLight).
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: 58a1af5f-09fb-4827-bd59-0301b06a21cb
⛔ Files ignored due to path filters (7)
package-lock.jsonis excluded by!**/package-lock.jsonsdks/urbackend-react/dist/index.d.mtsis excluded by!**/dist/**sdks/urbackend-react/dist/index.d.tsis excluded by!**/dist/**sdks/urbackend-react/dist/index.jsis excluded by!**/dist/**sdks/urbackend-react/dist/index.js.mapis excluded by!**/dist/**,!**/*.mapsdks/urbackend-react/dist/index.mjsis excluded by!**/dist/**sdks/urbackend-react/dist/index.mjs.mapis excluded by!**/dist/**,!**/*.map
📒 Files selected for processing (3)
examples/react-sdk-demo/src/App.tsxsdks/urbackend-react/src/components/UrAuth.tsxsdks/urbackend-react/tests/UrAuth.test.tsx
|
yh please resolve Coderabbit's comments |
|
Yes |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
sdks/urbackend-react/src/components/UrAuth.tsx (3)
156-165:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAllow explicit empty-string overrides for aliased labels.
These alias fallbacks use
||, so''is treated as “missing.” That makesloginTab,signupTab,loginTitle,signupTitle,loginButton, andsignupButtonimpossible to intentionally blank out, even though this PR is expanding copy customization. Use??here so onlynull/undefinedfall back.Suggested fix
const text = { ...defaultLabels, ...labels, - loginTab: labels?.signInTab || labels?.loginTab || defaultLabels.loginTab, - loginTitle: labels?.signInTitle || labels?.loginTitle || defaultLabels.loginTitle, - loginButton: labels?.signInButton || labels?.loginButton || defaultLabels.loginButton, - signupTab: labels?.signUpTab || labels?.signupTab || defaultLabels.signupTab, - signupTitle: labels?.signUpTitle || labels?.signupTitle || defaultLabels.signupTitle, - signupButton: labels?.signUpButton || labels?.signupButton || defaultLabels.signupButton, + loginTab: labels?.signInTab ?? labels?.loginTab ?? defaultLabels.loginTab, + loginTitle: labels?.signInTitle ?? labels?.loginTitle ?? defaultLabels.loginTitle, + loginButton: labels?.signInButton ?? labels?.loginButton ?? defaultLabels.loginButton, + signupTab: labels?.signUpTab ?? labels?.signupTab ?? defaultLabels.signupTab, + signupTitle: labels?.signUpTitle ?? labels?.signupTitle ?? defaultLabels.signupTitle, + signupButton: labels?.signUpButton ?? labels?.signupButton ?? defaultLabels.signupButton, };🤖 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 `@sdks/urbackend-react/src/components/UrAuth.tsx` around lines 156 - 165, The current construction of the text object uses logical OR (||) for aliased label fallbacks (e.g., loginTab, loginTitle, loginButton, signupTab, signupTitle, signupButton) which treats empty strings as missing; change those fallback expressions to use nullish coalescing (??) so that only null/undefined fall back to the defaults and explicit empty-string overrides are respected (update the loginTab/loginTitle/loginButton/signupTab/signupTitle/signupButton expressions inside the text object to use ?? between labels aliases and defaultLabels).
536-543:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winForgot/reset subtitles are still outside the labels API.
The forgot screen reuses
text.loginTitle, and the reset screen uses a raw template literal. That leaves these two visible strings uncustomizable even though this PR is expanding label/text overrides for the auth UI. Add dedicated label keys for the forgot/reset subtitles and render them throughtextlike the rest of the screen copy.🤖 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 `@sdks/urbackend-react/src/components/UrAuth.tsx` around lines 536 - 543, The forgot/reset subtitle strings are not using the labels API; replace the hardcoded uses of text.loginTitle and the template literal `Enter the code sent to ${email}` in the JSX block that checks (mode === 'forgot' || mode === 'reset') so both subtitles come from the text prop (e.g., add and use text.forgotSubtitle and text.resetSubtitle) and interpolate email into text.resetSubtitle where needed; update any defaults/provider of text to include these new keys so the component renders them via text.forgotSubtitle when mode==='forgot' and text.resetSubtitle when mode==='reset'.
353-358:⚠️ Potential issue | 🟠 Major | ⚡ Quick winThe primary CTA still hardcodes black into branded themes.
primaryColoronly controls the first gradient stop; the second stop is always#111111. In dark mode that fades into the same color asthemeColors.primaryText, so the lower half of the button can lose contrast. It also darkens every custom brand color instead of respecting the configured theme.Suggested fix
primaryBtn: { width: '100%', padding: '14px', borderRadius: '0', - background: `linear-gradient(180deg, ${primaryColor} 0%, ${theme === 'dark' ? '`#111111`' : '`#111111`'} 100%)`, + background: primaryColor, color: themeColors.primaryText, fontSize: '15px',🤖 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 `@sdks/urbackend-react/src/components/UrAuth.tsx` around lines 353 - 358, The gradient for primaryBtn currently hardcodes '`#111111`' as the second stop which overrides branded colors; update the background declaration in primaryBtn to stop using '`#111111`' and instead use a proper brand-aware color (e.g., use primaryColor for both stops or a computed darker/lighter variant of primaryColor) so the gradient respects the configured theme; if needed add a small helper to derive a tint/shade from primaryColor and reference that (keep usage within the primaryBtn style and ensure it no longer references the literal '`#111111`' and maintains appropriate contrast with themeColors.primaryText).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@sdks/urbackend-react/src/components/UrAuth.tsx`:
- Around line 156-165: The current construction of the text object uses logical
OR (||) for aliased label fallbacks (e.g., loginTab, loginTitle, loginButton,
signupTab, signupTitle, signupButton) which treats empty strings as missing;
change those fallback expressions to use nullish coalescing (??) so that only
null/undefined fall back to the defaults and explicit empty-string overrides are
respected (update the
loginTab/loginTitle/loginButton/signupTab/signupTitle/signupButton expressions
inside the text object to use ?? between labels aliases and defaultLabels).
- Around line 536-543: The forgot/reset subtitle strings are not using the
labels API; replace the hardcoded uses of text.loginTitle and the template
literal `Enter the code sent to ${email}` in the JSX block that checks (mode ===
'forgot' || mode === 'reset') so both subtitles come from the text prop (e.g.,
add and use text.forgotSubtitle and text.resetSubtitle) and interpolate email
into text.resetSubtitle where needed; update any defaults/provider of text to
include these new keys so the component renders them via text.forgotSubtitle
when mode==='forgot' and text.resetSubtitle when mode==='reset'.
- Around line 353-358: The gradient for primaryBtn currently hardcodes '`#111111`'
as the second stop which overrides branded colors; update the background
declaration in primaryBtn to stop using '`#111111`' and instead use a proper
brand-aware color (e.g., use primaryColor for both stops or a computed
darker/lighter variant of primaryColor) so the gradient respects the configured
theme; if needed add a small helper to derive a tint/shade from primaryColor and
reference that (keep usage within the primaryBtn style and ensure it no longer
references the literal '`#111111`' and maintains appropriate contrast with
themeColors.primaryText).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: eae743e2-f243-467d-86fe-99b7e6316864
📒 Files selected for processing (2)
examples/react-sdk-demo/src/App.tsxsdks/urbackend-react/src/components/UrAuth.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
- examples/react-sdk-demo/src/App.tsx
|
@yash-pouranik check it out |
yash-pouranik
left a comment
There was a problem hiding this comment.
Seems good to me.
|
have a look |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Get current PR details and open review comments
gh pr view 301 --repo geturbackend/urBackend
echo "=== PR Review Comments ==="
gh api repos/geturbackend/urBackend/pulls/301/comments --jq '.[] | {id: .id, path: .path, line: .line, body: .body[0:300], user: .user.login}' 2>/dev/null
echo "=== PR Issue Comments ==="
gh api repos/geturbackend/urBackend/issues/301/comments --jq '.[] | {id: .id, body: .body[0:400], user: .user.login}' 2>/dev/null
echo "=== PR Reviews ==="
gh api repos/geturbackend/urBackend/pulls/301/reviews --jq '.[] | {id: .id, state: .state, user: .user.login, body: .body[0:300]}' 2>/dev/nullLength of output: 7631 🏁 Script executed: #!/bin/bash
# Read the relevant sections of App.tsx
echo "=== App.tsx avatar section ==="
cat examples/react-sdk-demo/src/App.tsx
echo ""
echo "=== UrAuth.tsx enableEmailPassword section (lines 160-230) ==="
sed -n '160,240p' sdks/urbackend-react/src/components/UrAuth.tsxLength of output: 8894 🏁 Script executed: #!/bin/bash
# Get full bodies of the two open inline comments
echo "=== Comment 1 (App.tsx avatarUrl) ==="
gh api repos/geturbackend/urBackend/pulls/comments/3396377832 --jq '.body'
echo ""
echo "=== Comment 2 (UrAuth.tsx enableEmailPassword) ==="
gh api repos/geturbackend/urBackend/pulls/comments/3396377850 --jq '.body'
echo ""
echo "=== Check resolution status ==="
gh api repos/geturbackend/urBackend/pulls/301/comments --jq '.[] | {id: .id, path: .path, line: .line, in_reply_to_id: .in_reply_to_id, user: .user.login}' 2>/dev/nullLength of output: 5681 🏁 Script executed: #!/bin/bash
# Resolve comment 2 (UrAuth.tsx enableEmailPassword) - it's already fixed in the code
# Find the review thread ID for this comment to resolve it
gh api repos/geturbackend/urBackend/pulls/301/reviews --jq '.[] | select(.user.login == "coderabbitai[bot]") | {id: .id, state: .state}'
# Get the pull request review threads to find which can be resolved
gh api graphql -f query='
{
repository(owner: "geturbackend", name: "urBackend") {
pullRequest(number: 301) {
reviewThreads(first: 20) {
nodes {
id
isResolved
comments(first: 1) {
nodes {
databaseId
body
}
}
}
}
}
}
}'Length of output: 5955
✅ Fixed —
|
|
last update |
|
have a look |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
cat examples/react-sdk-demo/src/App.tsxLength of output: 5777 🏁 Script executed: #!/bin/bash
# Resolve the open review thread for the avatarUrl comment (ID: 3396377832)
gh api graphql -f query='
{
repository(owner: "geturbackend", name: "urBackend") {
pullRequest(number: 301) {
reviewThreads(first: 20) {
nodes {
id
isResolved
comments(first: 1) {
nodes {
databaseId
body
}
}
}
}
}
}
}'Length of output: 5604
The {typeof user?.avatarUrl === 'string' && user?.avatarUrl ? (
<img src={user.avatarUrl} alt="Avatar" ... />Both previously raised issues are now resolved:
The PR looks good to go! 🎉 🐇 ≧◡≦ |
🚀 Pull Request Description
Fixes #297
Summary
This PR improves the customization capabilities of the React SDK authentication UI by removing several hardcoded behaviors and introducing configurable branding and authentication options.
The goal is to provide a more flexible and production-ready authentication experience while maintaining backward compatibility through sensible defaults.
📋 Changes Made
Authentication Provider Customization
Added support for enabling or disabling authentication providers independently:
Branding & Theme Customization
Added support for authentication UI branding customization:
Custom Labels & Text
Added support for overriding default authentication UI text:
Demo Application Update
Updated the React SDK demo application to demonstrate the new customization capabilities.
📁 Files Changed
Source Changes
sdks/urbackend-react/src/components/UrAuth.tsxexamples/react-sdk-demo/src/App.tsxBuild Output
sdks/urbackend-react/dist/index.d.mtssdks/urbackend-react/dist/index.d.tssdks/urbackend-react/dist/index.jssdks/urbackend-react/dist/index.js.mapsdks/urbackend-react/dist/index.mjssdks/urbackend-react/dist/index.mjs.mapDependency Updates
package-lock.json🧪 Testing & Validation
🔄 Backward Compatibility
This change is fully backward compatible.
All new customization options are optional and default to the existing behavior, ensuring that current integrations continue to work without modification.
💡 Motivation
The authentication UI was previously too rigid for many real-world applications. Developers could not customize authentication providers, branding, colors, or authentication text, making the SDK less flexible for production use.
This PR addresses those limitations by introducing configurable authentication providers, branding options, theme customization, and custom labels while preserving the existing developer experience.
Summary by CodeRabbit
New Features
Bug Fixes
Tests