-
Notifications
You must be signed in to change notification settings - Fork 637
[MNY-233] SDK: Add Last Used badge in Connect UI #8631
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🦋 Changeset detectedLatest commit: 97c0825 The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
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 |
WalkthroughAdds a "Last used" badge to the Connect Wallet UI: persists last-used wallet ID on connect/activate, exposes defensive storage helpers, provides a Badge component, updates wallet sorting to prioritize last-used, and threads a Changes
Sequence Diagram(s)sequenceDiagram
participant UI as Connect UI
participant Selector as WalletSelector
participant Sorter as sortWallets
participant Storage as localStorage (helpers)
participant Manager as Wallet Manager
UI->>Storage: getLastUsedWalletId() / getLastUsedSocialAuth()
Storage-->>UI: lastUsedWalletId / lastUsedSocialAuth
UI->>Selector: render wallet list (include lastUsed flags)
Selector->>Sorter: request sorted wallets
Sorter-->>Selector: ordered wallet list
Selector-->>UI: render wallet rows with lastUsedBadge where applicable
UI->>Manager: user connects or sets active wallet
Manager->>Storage: persist LAST_USED_WALLET_ID
Storage-->>Manager: ack
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 3❌ Failed checks (2 warnings, 1 inconclusive)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Warning Review ran into problems🔥 ProblemsErrors were encountered while retrieving linked issues. Errors (1)
Comment |
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx (1)
222-237: Badge may display incorrectly when no wallet was previously used.The condition
lastUsedWalletId !== "inApp" && !lastUsedWalletId?.startsWith("ecosystem.")evaluates totruewhenlastUsedWalletIdisnull(no previous usage), causing the badge to appear on "Connect a Wallet" even when there's no last-used wallet.🐛 Proposed fix to guard against null
<WalletTypeRowButton className="tw-select-connect-a-wallet-button" lastUsedBadge={ + !!lastUsedWalletId && lastUsedWalletId !== "inApp" && !lastUsedWalletId?.startsWith("ecosystem.") }
🧹 Nitpick comments (7)
packages/thirdweb/src/react/web/ui/components/badge.tsx (2)
32-47: Minor: Redundantcursorstyle.The
cursor: "default"on line 41 has no effect whenpointerEvents: "none"is set, since the element won't receive pointer events anyway.Suggested fix
style={{ position: "absolute", top: -10, right: -10, zIndex: 1, pointerEvents: "none", - cursor: "default", }}
49-49: Consider adding a brief comment for the constant.The purpose of
LAST_USED_BADGE_VERTICAL_RESERVED_SPACEmay not be immediately clear to future maintainers. A short comment explaining it reserves space for the badge's overflow above the container would help.Suggested improvement
+/** Vertical padding to reserve for the LastUsedBadge overflow above its container */ export const LAST_USED_BADGE_VERTICAL_RESERVED_SPACE = 12;packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (2)
6-17: Add explicit return type annotation.Per coding guidelines, functions should have explicit return types. This also documents the contract for consumers.
Suggested fix
-export function getLastUsedWalletId() { +export function getLastUsedWalletId(): WalletId | null {
19-30: Add explicit return type and simplify the type cast.The
& stringintersection is redundant—AuthArgsType["strategy"]is already a union of string literals ("email" | "phone" | "google" | "apple" | ... | "backend"). Remove it and add an explicit return type for consistency with the coding guidelines.Suggested fix
-export function getLastUsedSocialAuth() { +export function getLastUsedSocialAuth(): AuthArgsType["strategy"] | null { try { if (typeof window !== "undefined" && window.localStorage) { return window.localStorage.getItem(LAST_AUTH_PROVIDER_STORAGE_KEY) as - | (AuthArgsType["strategy"] & string) + | AuthArgsType["strategy"] | null; } } catch { // ignore } return null; }packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsx (1)
30-30: Consider makinglastUsedBadgeoptional with a default value.The prop is currently required, which means all existing callers of
InputSelectionUImust be updated. Since this is marked@internal, the impact may be limited, but making it optional with a default offalsewould be more defensive.Suggested change
- lastUsedBadge: boolean; + lastUsedBadge?: boolean;Then update line 77:
- {props.lastUsedBadge && <LastUsedBadge />} + {props.lastUsedBadge === true && <LastUsedBadge />}packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx (1)
16-16: Consider makinglastUsedBadgeoptional for consistency.Same suggestion as
InputSelectionUI- making this optional with a default offalsewould be more defensive and consistent with typical React patterns for feature flags.Suggested change
- lastUsedBadge: boolean; + lastUsedBadge?: boolean;packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx (1)
648-662: Consider extracting the "Last used" string for localization.The badge text "Last used" is hardcoded here and in
badge.tsx. For consistency with the existing locale pattern in this codebase, consider adding this string to theConnectLocaletype.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (13)
.changeset/three-fans-flow.mdpackages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.tspackages/thirdweb/src/react/web/ui/ConnectWallet/WalletEntryButton.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsxpackages/thirdweb/src/react/web/ui/components/badge.tsxpackages/thirdweb/src/react/web/utils/sortWallets.tspackages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsxpackages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsxpackages/thirdweb/src/stories/ConnectButton/others.stories.tsxpackages/thirdweb/src/stories/ConnectButton/themes.stories.tsxpackages/thirdweb/src/wallets/manager/index.ts
💤 Files with no reviewable changes (1)
- packages/thirdweb/src/react/web/ui/ConnectWallet/WalletEntryButton.tsx
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each TypeScript file to one stateless, single-responsibility function for clarity
Re-use shared types from@/typesor localtypes.tsbarrels
Prefer type aliases over interface except for nominal shapes in TypeScript
Avoidanyandunknownin TypeScript unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial,Pick, etc.) in TypeScript
**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity and testability
Re-use shared types from @/types or local types.ts barrel exports
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless unavoidable; narrow generics whenever possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.)
Comment only ambiguous logic in TypeScript files; avoid restating TypeScript types and signatures in prose
Files:
packages/thirdweb/src/react/web/ui/components/badge.tsxpackages/thirdweb/src/wallets/manager/index.tspackages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsxpackages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.tspackages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsxpackages/thirdweb/src/stories/ConnectButton/others.stories.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsxpackages/thirdweb/src/stories/ConnectButton/themes.stories.tsxpackages/thirdweb/src/react/web/utils/sortWallets.tspackages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
packages/thirdweb/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
packages/thirdweb/src/**/*.{ts,tsx}: Comment only ambiguous logic in SDK code; avoid restating TypeScript in prose
Load heavy dependencies inside async paths to keep initial bundle lean (e.g.const { jsPDF } = await import("jspdf");)Lazy-load heavy dependencies inside async paths to keep the initial bundle lean (e.g., const { jsPDF } = await import('jspdf');)
Files:
packages/thirdweb/src/react/web/ui/components/badge.tsxpackages/thirdweb/src/wallets/manager/index.tspackages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsxpackages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.tspackages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsxpackages/thirdweb/src/stories/ConnectButton/others.stories.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsxpackages/thirdweb/src/stories/ConnectButton/themes.stories.tsxpackages/thirdweb/src/react/web/utils/sortWallets.tspackages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
**/*.{js,jsx,ts,tsx,json}
📄 CodeRabbit inference engine (AGENTS.md)
Biome governs formatting and linting; its rules live in biome.json. Run
pnpm fix&pnpm lintbefore committing, ensure there are no linting errors
Files:
packages/thirdweb/src/react/web/ui/components/badge.tsxpackages/thirdweb/src/wallets/manager/index.tspackages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsxpackages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.tspackages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsxpackages/thirdweb/src/stories/ConnectButton/others.stories.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsxpackages/thirdweb/src/stories/ConnectButton/themes.stories.tsxpackages/thirdweb/src/react/web/utils/sortWallets.tspackages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Lazy-import optional features; avoid top-level side-effects
Files:
packages/thirdweb/src/react/web/ui/components/badge.tsxpackages/thirdweb/src/wallets/manager/index.tspackages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsxpackages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.tspackages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsxpackages/thirdweb/src/stories/ConnectButton/others.stories.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsxpackages/thirdweb/src/stories/ConnectButton/themes.stories.tsxpackages/thirdweb/src/react/web/utils/sortWallets.tspackages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
**/*.stories.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
Add Storybook stories (
*.stories.tsx) alongside new UI components for documentation
Files:
packages/thirdweb/src/stories/ConnectButton/others.stories.tsxpackages/thirdweb/src/stories/ConnectButton/themes.stories.tsx
**/*.stories.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
For new UI components, add Storybook stories (*.stories.tsx) alongside the code
Files:
packages/thirdweb/src/stories/ConnectButton/others.stories.tsxpackages/thirdweb/src/stories/ConnectButton/themes.stories.tsx
🧬 Code graph analysis (6)
packages/thirdweb/src/react/web/ui/components/badge.tsx (3)
packages/thirdweb/src/react/web/ui/components/basic.tsx (1)
Container(80-193)packages/thirdweb/src/react/core/design-system/index.ts (2)
radius(156-164)spacing(142-154)packages/thirdweb/src/react/web/ui/components/text.tsx (1)
Text(18-34)
packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx (3)
packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (2)
getLastUsedSocialAuth(19-30)getLastUsedWalletId(6-17)packages/thirdweb/src/wallets/types.ts (1)
authOptions(41-49)packages/thirdweb/src/react/web/ui/components/badge.tsx (1)
LastUsedBadge(32-47)
packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (3)
packages/thirdweb/src/wallets/manager/index.ts (1)
LAST_USED_WALLET_ID(27-27)packages/thirdweb/src/react/core/utils/storage.ts (1)
LAST_AUTH_PROVIDER_STORAGE_KEY(4-4)packages/thirdweb/src/wallets/in-app/core/authentication/types.ts (1)
AuthArgsType(82-85)
packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx (1)
packages/thirdweb/src/react/web/ui/components/badge.tsx (1)
LastUsedBadge(32-47)
packages/thirdweb/src/react/web/utils/sortWallets.ts (1)
packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (1)
getLastUsedWalletId(6-17)
packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx (5)
packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (1)
getLastUsedWalletId(6-17)packages/thirdweb/src/react/web/ui/components/basic.tsx (1)
Container(80-193)packages/thirdweb/src/react/core/design-system/index.ts (2)
spacing(142-154)iconSize(166-176)packages/thirdweb/src/react/web/ui/components/buttons.tsx (1)
IconButton(165-186)packages/thirdweb/src/react/web/ui/components/badge.tsx (1)
LAST_USED_BADGE_VERTICAL_RESERVED_SPACE(49-49)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Unit Tests
- GitHub Check: Size
- GitHub Check: Analyze (javascript)
🔇 Additional comments (20)
.changeset/three-fans-flow.md (1)
1-5: LGTM!Changeset is properly formatted with an appropriate patch version bump for this new feature.
packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx (1)
31-40: LGTM!The renamed
Customstory with updated theme colors provides a cleaner example of dark theme customization, including the newborderColorproperty which aligns with the badge styling needs.packages/thirdweb/src/stories/ConnectButton/others.stories.tsx (1)
1-34: LGTM!Well-structured Storybook file following existing patterns. The
WideModalandCompactModalstories provide good coverage for testing the modal size variations. This aligns with the coding guidelines to add stories alongside UI component changes.packages/thirdweb/src/react/web/ui/components/badge.tsx (1)
5-30: LGTM!The
Badgecomponent properly leverages design system tokens for spacing and radius. The hardcodedfontSize: 10is acceptable for this small decorative element.packages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsx (1)
155-157: LGTM!Setting
lastUsedBadge={false}is appropriate here since this is a WalletConnect URI input field, not a wallet selection context where "Last Used" would be meaningful.packages/thirdweb/src/react/web/utils/sortWallets.ts (1)
43-52: LGTM!The sorting logic correctly uses stable sort chaining, where later sorts take precedence. The last-used wallet will properly appear before recommended wallets due to running after the recommended sort pass.
packages/thirdweb/src/wallets/manager/index.ts (2)
221-224: LGTM!Correctly guards against storing "smart" as the last used wallet ID, preserving the underlying EOA wallet selection for UI display purposes.
152-152: The code correctly persistsLAST_USED_WALLET_IDto localStorage. In web contexts,createConnectionManager()receiveswebLocalStorage, which wrapswindow.localStorage. Both the manager'sstorage.setItem()call andgetLastUsedWalletId()'s direct read target the samewindow.localStorageobject, so there is no storage mismatch.packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsx (1)
77-78: LGTM!The conditional rendering integrates well with the existing
InputContainerwhich already hasposition: "relative"(line 74), allowing the absolutely-positionedLastUsedBadgeto render correctly.packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx (1)
32-36: LGTM!The
position: "relative"addition correctly anchors the absolutely-positionedLastUsedBadge, and the conditional rendering pattern is clean.packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx (6)
34-39: LGTM!Clean imports for the new last-used functionality.
105-106: LGTM!Using
useMemowith empty dependencies to read localStorage values once on mount is appropriate here, avoiding unnecessary re-reads while ensuring the values are stable throughout the component lifecycle.
149-163: LGTM!The sorting logic correctly prioritizes the last-used auth option when the current wallet matches the last-used wallet ID. The guard condition on line 150 ensures we only reorder options when relevant.
396-401: LGTM!The
position: relativestyle correctly enables the absolute-positionedLastUsedBadgeoverlay. The badge condition correctly matches the wallet and auth method.
428-430: LGTM!Badge condition correctly identifies when email was the last-used auth method for this wallet.
567-578: LGTM!Explicitly setting
lastUsedBadge={false}for the linking button is correct—linking is a special operation that shouldn't display the "Last used" badge.packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx (4)
22-22: LGTM!Clean import for the vertical spacing constant needed to accommodate the badge overlay.
536-560: LGTM!The reworked back navigation block with explicit styling provides better control over the layout. The
transform: translateX(-${spacing.xs})compensates for the button's internal padding to maintain visual alignment.
613-622: LGTM!Computing
lastUsedWalletIdviauseMemoinWalletSelectionis appropriate since it's a separate component fromWalletSelectorInner. The dynamicpaddingTopcorrectly reserves space for the badge in compact mode while avoiding unnecessary spacing in wide mode.
746-748: LGTM!Increasing
paddingInlinetospacing.mdprovides adequate horizontal space for the badge overlay positioning.
size-limit report 📦
|
Codecov Report❌ Patch coverage is ❌ Your patch status has failed because the patch coverage (25.16%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #8631 +/- ##
==========================================
- Coverage 53.00% 52.95% -0.06%
==========================================
Files 929 931 +2
Lines 62109 62239 +130
Branches 4077 4086 +9
==========================================
+ Hits 32921 32958 +37
- Misses 29089 29182 +93
Partials 99 99
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsx:
- Line 30: Tests are failing because the InputSelectionUI component now requires
the boolean prop lastUsedBadge; update the three render calls of
InputSelectionUI in InputSelectionUI.test.tsx to include a boolean value (e.g.,
lastUsedBadge={false} or lastUsedBadge={true}) so each test supplies the
required prop.
🧹 Nitpick comments (2)
packages/thirdweb/src/react/web/ui/components/badge.tsx (2)
20-24: Consider using design-system font size token.The hardcoded
fontSize: 10could use a design-system token for consistency. However, if 10px is intentionally smaller than the smallest token, this is acceptable.Suggested change
<Text style={{ - fontSize: 10, + fontSize: fontSize.xs, // or keep 10 if intentionally smaller whiteSpace: "nowrap", }} >This would require importing
fontSizefrom the design-system index.
40-41: Optional: Remove redundantcursorstyle.The
cursor: "default"style has no effect whenpointerEvents: "none"is set, since the element won't receive any pointer events.Suggested change
zIndex: 1, pointerEvents: "none", - cursor: "default", }}
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (13)
.changeset/three-fans-flow.mdpackages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.tspackages/thirdweb/src/react/web/ui/ConnectWallet/WalletEntryButton.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsxpackages/thirdweb/src/react/web/ui/components/badge.tsxpackages/thirdweb/src/react/web/utils/sortWallets.tspackages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsxpackages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsxpackages/thirdweb/src/stories/ConnectButton/others.stories.tsxpackages/thirdweb/src/stories/ConnectButton/themes.stories.tsxpackages/thirdweb/src/wallets/manager/index.ts
💤 Files with no reviewable changes (1)
- packages/thirdweb/src/react/web/ui/ConnectWallet/WalletEntryButton.tsx
✅ Files skipped from review due to trivial changes (1)
- .changeset/three-fans-flow.md
🚧 Files skipped from review as they are similar to previous changes (5)
- packages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsx
- packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts
- packages/thirdweb/src/stories/ConnectButton/others.stories.tsx
- packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx
- packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each TypeScript file to one stateless, single-responsibility function for clarity
Re-use shared types from@/typesor localtypes.tsbarrels
Prefer type aliases over interface except for nominal shapes in TypeScript
Avoidanyandunknownin TypeScript unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial,Pick, etc.) in TypeScript
**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity and testability
Re-use shared types from @/types or local types.ts barrel exports
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless unavoidable; narrow generics whenever possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.)
Comment only ambiguous logic in TypeScript files; avoid restating TypeScript types and signatures in prose
Files:
packages/thirdweb/src/stories/ConnectButton/themes.stories.tsxpackages/thirdweb/src/react/web/utils/sortWallets.tspackages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsxpackages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsxpackages/thirdweb/src/react/web/ui/components/badge.tsxpackages/thirdweb/src/wallets/manager/index.ts
packages/thirdweb/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
packages/thirdweb/src/**/*.{ts,tsx}: Comment only ambiguous logic in SDK code; avoid restating TypeScript in prose
Load heavy dependencies inside async paths to keep initial bundle lean (e.g.const { jsPDF } = await import("jspdf");)Lazy-load heavy dependencies inside async paths to keep the initial bundle lean (e.g., const { jsPDF } = await import('jspdf');)
Files:
packages/thirdweb/src/stories/ConnectButton/themes.stories.tsxpackages/thirdweb/src/react/web/utils/sortWallets.tspackages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsxpackages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsxpackages/thirdweb/src/react/web/ui/components/badge.tsxpackages/thirdweb/src/wallets/manager/index.ts
**/*.stories.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
Add Storybook stories (
*.stories.tsx) alongside new UI components for documentation
Files:
packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx
**/*.{js,jsx,ts,tsx,json}
📄 CodeRabbit inference engine (AGENTS.md)
Biome governs formatting and linting; its rules live in biome.json. Run
pnpm fix&pnpm lintbefore committing, ensure there are no linting errors
Files:
packages/thirdweb/src/stories/ConnectButton/themes.stories.tsxpackages/thirdweb/src/react/web/utils/sortWallets.tspackages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsxpackages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsxpackages/thirdweb/src/react/web/ui/components/badge.tsxpackages/thirdweb/src/wallets/manager/index.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Lazy-import optional features; avoid top-level side-effects
Files:
packages/thirdweb/src/stories/ConnectButton/themes.stories.tsxpackages/thirdweb/src/react/web/utils/sortWallets.tspackages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsxpackages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsxpackages/thirdweb/src/react/web/ui/components/badge.tsxpackages/thirdweb/src/wallets/manager/index.ts
**/*.stories.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
For new UI components, add Storybook stories (*.stories.tsx) alongside the code
Files:
packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx
🧬 Code graph analysis (3)
packages/thirdweb/src/react/web/utils/sortWallets.ts (1)
packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (1)
getLastUsedWalletId(6-17)
packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx (3)
packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (2)
getLastUsedSocialAuth(19-30)getLastUsedWalletId(6-17)packages/thirdweb/src/wallets/types.ts (1)
authOptions(41-49)packages/thirdweb/src/react/web/ui/components/badge.tsx (1)
LastUsedBadge(32-47)
packages/thirdweb/src/react/web/ui/components/badge.tsx (3)
packages/thirdweb/src/react/web/ui/components/basic.tsx (1)
Container(80-193)packages/thirdweb/src/react/core/design-system/index.ts (2)
radius(156-164)spacing(142-154)packages/thirdweb/src/react/web/ui/components/text.tsx (1)
Text(18-34)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
- GitHub Check: E2E Tests (pnpm, esbuild)
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: Lint Packages
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: Build Packages
- GitHub Check: Size
- GitHub Check: Unit Tests
- GitHub Check: Analyze (javascript)
🔇 Additional comments (9)
packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx (1)
31-40: LGTM!The story rename from
CustomBlacktoCustomappropriately reflects the updated color scheme, and the new dark purple theme colors (#0c0a2e,#2f2987) provide a more visually distinct custom theme example. AddingborderColoris a nice addition to demonstrate additional theming capabilities.packages/thirdweb/src/react/web/utils/sortWallets.ts (1)
3-3: LGTM! Last-used wallet sorting is correctly implemented.The new sorting pass correctly prioritizes the last used wallet while preserving the existing sort order (in-app wallets still take precedence as the final sort pass). The synchronous localStorage read via
getLastUsedWalletId()is acceptable here since it's a simple key lookup.Also applies to: 14-14, 43-52
packages/thirdweb/src/wallets/manager/index.ts (1)
27-27: LGTM! Last-used wallet persistence is correctly integrated.The
LAST_USED_WALLET_IDis properly persisted in both connection flows (handleConnectionandsetActiveWallet), consistently storing the EOA wallet ID rather than smart wallet IDs. The await ensures proper async sequencing.Also applies to: 151-152, 221-224
packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsx (1)
77-78: LGTM! Badge placement is correct.The
LastUsedBadgeis conditionally rendered inside theInputContainerwhich hasposition: relative, allowing the badge's absolute positioning to work correctly.packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx (4)
105-106: LGTM! Storage values are correctly memoized.Using
useMemowith an empty dependency array ensures the localStorage reads happen once on mount, avoiding unnecessary repeated reads during re-renders.
149-163: LGTM! Auth options sorting logic is correct.The sorting correctly prioritizes the last used social auth only when the current wallet matches the last used wallet ID, preventing incorrect badge/ordering when switching between wallets.
396-401: LGTM! Badge integration for social buttons.The
position: "relative"style enables proper badge positioning, and the condition correctly shows the badge only when both wallet ID and auth method match the last used values.
567-578: LGTM! Linking button correctly excludes the badge.The
lastUsedBadge={false}is appropriate for the linking flow since it represents a distinct action rather than a "last used" sign-in method.packages/thirdweb/src/react/web/ui/components/badge.tsx (1)
1-49: LGTM! Clean badge component implementation.The component structure follows existing patterns well, with proper use of design-system tokens and absolute positioning for overlay behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx:
- Around line 225-228: The badge logic for lastUsedBadge incorrectly shows when
lastUsedWalletId is null because null?.startsWith returns undefined and the
first truthy check fails; update the condition to explicitly ensure
lastUsedWalletId is not null/undefined before checking startsWith (e.g., use a
null check like lastUsedWalletId != null or Boolean(lastUsedWalletId) &&
!lastUsedWalletId.startsWith("ecosystem.") ) so lastUsedBadge is true only when
a real lastUsedWalletId exists and does not start with "ecosystem.".
🧹 Nitpick comments (3)
packages/thirdweb/src/react/web/ui/components/badge.tsx (1)
20-27: Consider using a design system token for font size.The
fontSize: 10is hardcoded while other styling uses design system tokens. Consider usingfontSize.xsor defining a token if 10px is intentional for badges.packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx (1)
400-401: Consider extracting the repeated badge condition.The condition
lastUsedWalletId === wallet.id && lastUsedSocialAuth === Xis repeated across multiple components. Consider extracting a helper function to improve maintainability.♻️ Suggested helper function
const isLastUsed = (authMethod: string) => lastUsedWalletId === wallet.id && lastUsedSocialAuth === authMethod; // Usage: lastUsedBadge={isLastUsed("email")} lastUsedBadge={isLastUsed("phone")} // etc.Also applies to: 428-430, 451-453, 475-477, 504-506, 520-522, 537-539, 553-555
packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx (1)
613-614: Consider passinglastUsedWalletIdas a prop instead of recomputing.
WalletSelectorInneralready computes this value at line 141. Passing it down as a prop would avoid the redundantuseMemocall and make the data flow more explicit.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (14)
.changeset/three-fans-flow.mdpackages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.tspackages/thirdweb/src/react/web/ui/ConnectWallet/WalletEntryButton.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsxpackages/thirdweb/src/react/web/ui/components/badge.tsxpackages/thirdweb/src/react/web/utils/sortWallets.tspackages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.test.tsxpackages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsxpackages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsxpackages/thirdweb/src/stories/ConnectButton/others.stories.tsxpackages/thirdweb/src/stories/ConnectButton/themes.stories.tsxpackages/thirdweb/src/wallets/manager/index.ts
💤 Files with no reviewable changes (1)
- packages/thirdweb/src/react/web/ui/ConnectWallet/WalletEntryButton.tsx
✅ Files skipped from review due to trivial changes (1)
- .changeset/three-fans-flow.md
🚧 Files skipped from review as they are similar to previous changes (6)
- packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsx
- packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts
- packages/thirdweb/src/wallets/manager/index.ts
- packages/thirdweb/src/stories/ConnectButton/others.stories.tsx
- packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx
- packages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsx
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each TypeScript file to one stateless, single-responsibility function for clarity
Re-use shared types from@/typesor localtypes.tsbarrels
Prefer type aliases over interface except for nominal shapes in TypeScript
Avoidanyandunknownin TypeScript unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial,Pick, etc.) in TypeScript
**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity and testability
Re-use shared types from @/types or local types.ts barrel exports
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless unavoidable; narrow generics whenever possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.)
Comment only ambiguous logic in TypeScript files; avoid restating TypeScript types and signatures in prose
Files:
packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsxpackages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsxpackages/thirdweb/src/react/web/ui/components/badge.tsxpackages/thirdweb/src/react/web/utils/sortWallets.tspackages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.test.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
packages/thirdweb/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
packages/thirdweb/src/**/*.{ts,tsx}: Comment only ambiguous logic in SDK code; avoid restating TypeScript in prose
Load heavy dependencies inside async paths to keep initial bundle lean (e.g.const { jsPDF } = await import("jspdf");)Lazy-load heavy dependencies inside async paths to keep the initial bundle lean (e.g., const { jsPDF } = await import('jspdf');)
Files:
packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsxpackages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsxpackages/thirdweb/src/react/web/ui/components/badge.tsxpackages/thirdweb/src/react/web/utils/sortWallets.tspackages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.test.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
**/*.{js,jsx,ts,tsx,json}
📄 CodeRabbit inference engine (AGENTS.md)
Biome governs formatting and linting; its rules live in biome.json. Run
pnpm fix&pnpm lintbefore committing, ensure there are no linting errors
Files:
packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsxpackages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsxpackages/thirdweb/src/react/web/ui/components/badge.tsxpackages/thirdweb/src/react/web/utils/sortWallets.tspackages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.test.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Lazy-import optional features; avoid top-level side-effects
Files:
packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsxpackages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsxpackages/thirdweb/src/react/web/ui/components/badge.tsxpackages/thirdweb/src/react/web/utils/sortWallets.tspackages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.test.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.test.{ts,tsx}: Place tests alongside code:foo.ts↔foo.test.tsin the same directory
Use real function invocations with stub data in tests; avoid brittle mocks
Use Mock Service Worker (MSW) for fetch/HTTP call interception in tests
Keep tests deterministic and side-effect free
Use predefined test accounts fromtest/src/test-wallets.tsin tests
UseFORKED_ETHEREUM_CHAINfor mainnet interactions andANVIL_CHAINfor isolated tests
**/*.test.{ts,tsx}: Co-locate tests with source files using the pattern foo.ts ↔ foo.test.ts
Use real function invocations with stub data in tests; avoid brittle mocks
For network interactions in tests, use Mock Service Worker (MSW) to intercept fetch/HTTP calls, mocking only scenarios that are hard to reproduce
Keep tests deterministic and side-effect free; Vitest is pre-configured
Files:
packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.test.tsx
🧬 Code graph analysis (4)
packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx (1)
packages/thirdweb/src/react/web/ui/components/badge.tsx (1)
LastUsedBadge(32-47)
packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx (3)
packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (2)
getLastUsedSocialAuth(19-30)getLastUsedWalletId(6-17)packages/thirdweb/src/wallets/types.ts (1)
authOptions(41-49)packages/thirdweb/src/react/web/ui/components/badge.tsx (1)
LastUsedBadge(32-47)
packages/thirdweb/src/react/web/utils/sortWallets.ts (1)
packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (1)
getLastUsedWalletId(6-17)
packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx (4)
packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (1)
getLastUsedWalletId(6-17)packages/thirdweb/src/react/core/design-system/index.ts (2)
spacing(142-154)iconSize(166-176)packages/thirdweb/src/react/web/ui/components/buttons.tsx (1)
IconButton(165-186)packages/thirdweb/src/react/web/ui/components/badge.tsx (1)
LAST_USED_BADGE_VERTICAL_RESERVED_SPACE(49-49)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Lint Packages
- GitHub Check: Analyze (javascript)
🔇 Additional comments (12)
packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.test.tsx (1)
18-18: LGTM!Test updates correctly pass the new required
lastUsedBadgeprop. Setting it tofalseis appropriate since these tests focus on SMS country code functionality rather than badge behavior.Also applies to: 35-35, 54-54
packages/thirdweb/src/react/web/utils/sortWallets.ts (1)
43-52: LGTM! The last-used prioritization is correctly placed.The sorting chain ensures the final priority order is: in-app > last-used > recommended > installed. This correctly shows the last-used wallet at the top while still keeping in-app wallets highest priority.
packages/thirdweb/src/react/web/ui/components/badge.tsx (1)
32-47: LGTM!The
LastUsedBadgecomponent is well-structured with appropriate absolute positioning and non-interactive styling (pointerEvents: "none").packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx (1)
16-16: LGTM!Clean integration of the
lastUsedBadgeprop. Theposition: "relative"correctly enables the absolutely-positioned badge overlay.Also applies to: 32-32, 36-36
packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx (3)
105-106: LGTM!Using
useMemowith empty dependencies correctly computes these values once on mount, avoiding unnecessary localStorage reads on re-renders while preserving the initial last-used state throughout the component lifecycle.
149-163: LGTM!The sorting logic correctly prioritizes the last-used social auth option only when the current wallet matches the last-used wallet ID. The early return on line 150-152 prevents unnecessary sorting when the context doesn't apply.
569-569: LGTM!Correctly sets
lastUsedBadge={false}for the linking button since it represents a different action flow and shouldn't display the last-used indicator.packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx (5)
3-3: LGTM!Imports are appropriate for the new "Last Used" badge functionality.
Also applies to: 22-22, 42-42
141-141: LGTM!Memoizing with an empty dependency array correctly captures the last-used wallet ID at mount time, ensuring the badge reflects the state from before the current session.
507-560: LGTM!Layout adjustments and the new back button UI for the expanded wallet group state are well-implemented. The padding changes appropriately accommodate the "Last Used" badge, and the back button provides a consistent navigation experience when the header is hidden.
621-622: LGTM!The conditional padding reservation for compact mode and the badge prop logic for individual wallet entries are correctly implemented. The direct ID comparison ensures the badge only appears on the exact wallet that was last used.
Also applies to: 650-650
746-748: LGTM!The
paddingInlineusage appropriately sets horizontal padding for the wallet list.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
packages/thirdweb/src/react/web/ui/components/badge.tsx (1)
32-47: Minor:cursor: "default"is redundant withpointerEvents: "none".When
pointerEvents: "none"is set, the element won't receive any pointer interactions, makingcursor: "default"ineffective since the cursor style won't apply to a non-interactive element.🧹 Suggested cleanup
style={{ position: "absolute", top: -10, right: -10, zIndex: 1, pointerEvents: "none", - cursor: "default", }}packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (1)
19-30: Consider simplifying the type assertion.The
& stringintersection in(AuthArgsType["strategy"] & string)appears unnecessary sinceAuthArgsType["strategy"]should already resolve to a string union type. The intersection withstringdoesn't add type safety here.🧹 Simplified type
export function getLastUsedSocialAuth() { try { if (typeof window !== "undefined" && window.localStorage) { - return window.localStorage.getItem(LAST_AUTH_PROVIDER_STORAGE_KEY) as - | (AuthArgsType["strategy"] & string) - | null; + return window.localStorage.getItem(LAST_AUTH_PROVIDER_STORAGE_KEY) as + | AuthArgsType["strategy"] + | null; } } catch { // ignore } return null; }
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (14)
.changeset/three-fans-flow.mdpackages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.tspackages/thirdweb/src/react/web/ui/ConnectWallet/WalletEntryButton.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsxpackages/thirdweb/src/react/web/ui/components/badge.tsxpackages/thirdweb/src/react/web/utils/sortWallets.tspackages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.test.tsxpackages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsxpackages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsxpackages/thirdweb/src/stories/ConnectButton/others.stories.tsxpackages/thirdweb/src/stories/ConnectButton/themes.stories.tsxpackages/thirdweb/src/wallets/manager/index.ts
💤 Files with no reviewable changes (1)
- packages/thirdweb/src/react/web/ui/ConnectWallet/WalletEntryButton.tsx
🚧 Files skipped from review as they are similar to previous changes (9)
- packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.test.tsx
- packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsx
- .changeset/three-fans-flow.md
- packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx
- packages/thirdweb/src/stories/ConnectButton/others.stories.tsx
- packages/thirdweb/src/react/web/utils/sortWallets.ts
- packages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsx
- packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx
- packages/thirdweb/src/wallets/manager/index.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each TypeScript file to one stateless, single-responsibility function for clarity
Re-use shared types from@/typesor localtypes.tsbarrels
Prefer type aliases over interface except for nominal shapes in TypeScript
Avoidanyandunknownin TypeScript unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial,Pick, etc.) in TypeScript
**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity and testability
Re-use shared types from @/types or local types.ts barrel exports
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless unavoidable; narrow generics whenever possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.)
Comment only ambiguous logic in TypeScript files; avoid restating TypeScript types and signatures in prose
Files:
packages/thirdweb/src/react/web/ui/components/badge.tsxpackages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.tspackages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
packages/thirdweb/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
packages/thirdweb/src/**/*.{ts,tsx}: Comment only ambiguous logic in SDK code; avoid restating TypeScript in prose
Load heavy dependencies inside async paths to keep initial bundle lean (e.g.const { jsPDF } = await import("jspdf");)Lazy-load heavy dependencies inside async paths to keep the initial bundle lean (e.g., const { jsPDF } = await import('jspdf');)
Files:
packages/thirdweb/src/react/web/ui/components/badge.tsxpackages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.tspackages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
**/*.{js,jsx,ts,tsx,json}
📄 CodeRabbit inference engine (AGENTS.md)
Biome governs formatting and linting; its rules live in biome.json. Run
pnpm fix&pnpm lintbefore committing, ensure there are no linting errors
Files:
packages/thirdweb/src/react/web/ui/components/badge.tsxpackages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.tspackages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Lazy-import optional features; avoid top-level side-effects
Files:
packages/thirdweb/src/react/web/ui/components/badge.tsxpackages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsxpackages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.tspackages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
🧬 Code graph analysis (3)
packages/thirdweb/src/react/web/ui/components/badge.tsx (3)
packages/thirdweb/src/react/web/ui/components/basic.tsx (1)
Container(80-193)packages/thirdweb/src/react/core/design-system/index.ts (2)
radius(156-164)spacing(142-154)packages/thirdweb/src/react/web/ui/components/text.tsx (1)
Text(18-34)
packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx (3)
packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (2)
getLastUsedSocialAuth(19-30)getLastUsedWalletId(6-17)packages/thirdweb/src/wallets/types.ts (1)
authOptions(41-49)packages/thirdweb/src/react/web/ui/components/badge.tsx (1)
LastUsedBadge(32-47)
packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (2)
packages/thirdweb/src/wallets/manager/index.ts (1)
LAST_USED_WALLET_ID(27-27)packages/thirdweb/src/wallets/in-app/core/authentication/types.ts (1)
AuthArgsType(82-85)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: E2E Tests (pnpm, esbuild)
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: Lint Packages
- GitHub Check: Analyze (javascript)
🔇 Additional comments (19)
packages/thirdweb/src/react/web/ui/components/badge.tsx (2)
1-30: LGTM! Badge component uses design tokens appropriately.The internal
Badgecomponent correctly leverages the design system'sradius.full,spacing["3xs"], andspacing.xstokens for consistent styling.Minor observation: Line 22 uses a hardcoded
fontSize: 10instead of a design-system token. Consider usingfontSize.xsor similar if a matching token exists, though this may be intentional for the small badge size.
49-49: Verify the reserved space constant aligns with badge positioning.The constant
LAST_USED_BADGE_VERTICAL_RESERVED_SPACE = 12is used to allocate space for the badge, butLastUsedBadgeusestop: -10. Ensure that consumers applying this constant correctly account for the badge's full overflow (badge height + offset).packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (1)
6-17: LGTM! Defensive localStorage access pattern.The function correctly handles:
- SSR environments (
typeof window !== "undefined")- Missing localStorage (
window.localStoragecheck)- Storage exceptions via try/catch
packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx (7)
105-106: LGTM! Proper memoization of localStorage reads.Using
useMemowith an empty dependency array ensures the localStorage values are read once on mount, which is appropriate since these values won't change during the component's lifecycle.
149-163: LGTM! Correct sorting logic to prioritize last-used auth method.The sorting comparator correctly:
- Only reorders when the current wallet matches the last-used wallet ID
- Moves the last-used auth method to the front of the list
- Preserves relative order of other items
396-411: LGTM! Badge integration on social login buttons.The
position: relativeenables correct absolute positioning of theLastUsedBadge, and the conditional rendering correctly checks both wallet ID and auth method match.
424-463: LGTM! Consistent badge propagation for email input/button variants.The
lastUsedBadgeprop is correctly passed to bothInputSelectionUIandWalletTypeRowButtonbased on the same condition (lastUsedWalletId === wallet.id && lastUsedSocialAuth === "email"), ensuring consistent behavior regardless of which UI variant is rendered.
465-516: LGTM! Phone input badge integration follows the same pattern.Consistent with the email implementation.
518-565: LGTM! Badge support for passkey, wallet, and guest login options.Each auth method correctly compares against its respective strategy string (
"passkey","wallet","guest").
567-578: LGTM! Linking flow correctly excludes the last-used badge.Hardcoding
lastUsedBadge={false}for the linking flow makes sense since linking a wallet is a distinct action from the user's previous sign-in method.packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx (9)
3-3: LGTM!
useMemoimport added to support memoization of localStorage reads.
22-22: LGTM!Import of the badge spacing constant for layout adjustments.
141-141: LGTM! Consistent memoization pattern.Same pattern as in
ConnectWalletSocialOptions.tsx- localStorage read memoized with empty deps.
222-238: LGTM! Correct badge condition for "Connect a Wallet" button.The condition correctly excludes:
"inApp"wallets (handled separately in social options)- Ecosystem wallets (
ecosystem.*) (also handled separately)This prevents duplicate badges when the last-used wallet was an in-app or ecosystem wallet.
508-519: LGTM!Header padding adjusted with design tokens.
536-562: Verify this back-navigation refactor is intentional.This segment significantly restructures the back navigation UI with new Container nesting and IconButton styling. While the changes appear functional, they seem more extensive than what's needed for badge support. Consider confirming this is intentional as part of this PR or if it should be a separate change.
614-624: LGTM! Badge space reservation for wallet list.The
paddingTopcorrectly appliesLAST_USED_BADGE_VERTICAL_RESERVED_SPACEin compact mode to prevent badge clipping, while wide mode uses 0 (likely handled differently in that layout).
649-663: LGTM! Badge passed to WalletEntryButton.The
badgeprop uses a string value ("Last used") instead of a boolean, which aligns withWalletEntryButton's existing API that likely supports arbitrary badge text.
747-748: LGTM!Padding adjustment for wallet list layout.

PR-Codex overview
This PR introduces a
Last Usedbadge in the Connect UI to indicate the most recently used sign-in method, enhancing user experience by providing quick access to their preferred wallet or authentication option.Detailed summary
LastUsedBadgecomponent to highlight the last used sign-in method.InputSelectionUIandWalletTypeRowButtonto acceptlastUsedBadgeprop.sortWalletsto prioritize the last used wallet.Summary by CodeRabbit
New Features
UI
Documentation
Tests
✏️ Tip: You can customize this high-level summary in your review settings.