-
Notifications
You must be signed in to change notification settings - Fork 603
[MNY-269] SDK: autofocus token search input when token selector modal opens in BuyWidget, SwapWidget and BridgeWidget #8266
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: 5ff6063 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 |
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. |
WalkthroughAdds Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant SelectTokenUI
participant Modal
participant SearchInput
participant Input
User->>SelectTokenUI: Open token selector (desktop)
SelectTokenUI->>Modal: render Modal (autoFocusCrossIcon=false)
Note right of Modal #ffd6a5: Close icon will not auto-focus
Modal->>SearchInput: render SearchInput (autoFocus=true)
SearchInput->>Input: set autoFocus=true
Input->>User: focus placed on search field
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Warning Review ran into problems🔥 ProblemsErrors were encountered while retrieving linked issues. Errors (1)
Comment |
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 (4)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/SearchInput.tsx (1)
10-15
: Add TSDoc for the new public prop.The
autoFocus
prop is part of the public API but lacks documentation. As per coding guidelines, every public symbol requires comprehensive TSDoc.Consider adding documentation:
export function SearchInput(props: { value: string; onChange: (value: string) => void; placeholder: string; + /** + * Whether the input should be autofocused when rendered. + * @default false + */ autoFocus: boolean; }) {Based on coding guidelines.
packages/thirdweb/src/react/web/ui/components/Modal.tsx (1)
32-44
: Add documentation for the new prop.The
autoFocusCrossIcon
prop modifies public API behavior but lacks documentation explaining its purpose and default value.Consider adding TSDoc:
crossContainerStyles?: React.CSSProperties; + /** + * Whether to autofocus the modal's close icon when opened. + * Set to false when another element (e.g., search input) should receive focus instead. + * @default true + */ autoFocusCrossIcon?: boolean; }> = (props) => {packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx (1)
69-81
: Inconsistent use of Variant wrapper.The
Sell_Base_USDC
story (lines 69-81) rendersSwapWidget
directly while all other stories use theVariant
wrapper. This inconsistency breaks the uniform dual-theme preview pattern established in this file.Apply this diff to use the Variant wrapper consistently:
export function Sell_Base_USDC() { return ( - <SwapWidget + <Variant client={storyClient} prefill={{ sellToken: {packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.stories.tsx (1)
14-16
: Inconsistent use of Variant wrapper.The
BasicUsage
story rendersSwapWidget
directly while other stories use theVariant
wrapper. This inconsistency breaks the uniform dual-theme preview pattern established in this file.Apply this diff to use the Variant wrapper consistently:
export function BasicUsage() { - return <SwapWidget client={storyClient} persistTokenSelections={false} />; + return <Variant client={storyClient} persistTokenSelections={false} />; }
🧹 Nitpick comments (2)
packages/thirdweb/src/react/web/ui/components/Modal.tsx (1)
147-155
: Consider using nullish coalescing for cleaner default value handling.The ternary expression can be simplified using the nullish coalescing operator.
Apply this diff:
<IconButton aria-label="Close" - autoFocus={ - props.autoFocusCrossIcon === undefined - ? true - : props.autoFocusCrossIcon - } + autoFocus={props.autoFocusCrossIcon ?? true} type="button" >packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx (1)
118-132
: Consider extracting the Variant wrapper to reduce duplication.The
Variant
component is duplicated across multiple story files (SwapWidget.Prefill.stories.tsx, SwapWidget.stories.tsx, BuyWidget.stories.tsx, bridge-widget-script.stories.tsx). This duplication increases maintenance burden when the dual-theme preview pattern needs to change.Consider extracting this wrapper to a shared utility file (e.g.,
packages/thirdweb/src/stories/utils.tsx
) and importing it across all story files:// packages/thirdweb/src/stories/utils.tsx export function DualThemeVariant<T extends { theme?: "light" | "dark" | unknown }>( Component: React.ComponentType<T>, ) { return function Variant(props: T) { return ( <div style={{ display: "flex", flexDirection: "column", gap: "40px", alignItems: "center", }} > <Component {...props} theme="dark" /> <Component {...props} theme="light" /> </div> ); }; }Then in story files:
import { DualThemeVariant } from "../../utils.js"; const Variant = DualThemeVariant(SwapWidget);
📜 Review details
Configuration used: CodeRabbit 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 (9)
packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
(1 hunks)packages/thirdweb/src/react/web/ui/Bridge/swap-widget/SearchInput.tsx
(2 hunks)packages/thirdweb/src/react/web/ui/Bridge/swap-widget/select-token-ui.tsx
(1 hunks)packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
(1 hunks)packages/thirdweb/src/react/web/ui/components/Modal.tsx
(2 hunks)packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
(6 hunks)packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx
(7 hunks)packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.stories.tsx
(6 hunks)packages/thirdweb/src/stories/BuyWidget.stories.tsx
(1 hunks)
🧰 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 file to one stateless, single-responsibility function for clarity
Re-use shared types from@/types
or localtypes.ts
barrels
Prefer type aliases over interface except for nominal shapes
Avoidany
andunknown
unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial
,Pick
, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
**/*.{ts,tsx}
: Use explicit function declarations and explicit return types in TypeScript
Limit each file to one stateless, single‑responsibility function
Re‑use shared types from@/types
where applicable
Prefertype
aliases overinterface
except for nominal shapes
Avoidany
andunknown
unless unavoidable; narrow generics when possible
Prefer composition over inheritance; use utility types (Partial, Pick, etc.)
Lazy‑import optional features and avoid top‑level side‑effects to reduce bundle size
Files:
packages/thirdweb/src/react/web/ui/components/Modal.tsx
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/select-token-ui.tsx
packages/thirdweb/src/stories/BuyWidget.stories.tsx
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.stories.tsx
packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/SearchInput.tsx
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)
Files:
packages/thirdweb/src/react/web/ui/components/Modal.tsx
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/select-token-ui.tsx
packages/thirdweb/src/stories/BuyWidget.stories.tsx
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.stories.tsx
packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/SearchInput.tsx
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx
packages/thirdweb/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
packages/thirdweb/**/*.{ts,tsx}
: Every public symbol must have comprehensive TSDoc with at least one compiling@example
and a custom tag (@beta
,@internal
,@experimental
, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
Lazy‑load heavy dependencies inside async paths (e.g.,const { jsPDF } = await import("jspdf")
)
Files:
packages/thirdweb/src/react/web/ui/components/Modal.tsx
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/select-token-ui.tsx
packages/thirdweb/src/stories/BuyWidget.stories.tsx
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.stories.tsx
packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/SearchInput.tsx
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx
**/*.stories.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
For new UI components, add Storybook stories (
*.stories.tsx
) alongside the code
Files:
packages/thirdweb/src/stories/BuyWidget.stories.tsx
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.stories.tsx
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx
🧠 Learnings (3)
📚 Learning: 2025-09-24T11:08:43.783Z
Learnt from: MananTank
PR: thirdweb-dev/js#8106
File: packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx:34-41
Timestamp: 2025-09-24T11:08:43.783Z
Learning: In BridgeWidgetProps for packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx, the Swap onError callback signature requires a non-undefined SwapPreparedQuote parameter (unlike Buy's onError which allows undefined quote). This is intentional - SwapWidget's onError is only called when a quote is available.
Applied to files:
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx
📚 Learning: 2025-09-24T11:09:45.142Z
Learnt from: MananTank
PR: thirdweb-dev/js#8106
File: packages/thirdweb/src/script-exports/readme.md:6-7
Timestamp: 2025-09-24T11:09:45.142Z
Learning: For thirdweb Bridge Widget script exports, the module is exported with globalName: "BridgeWidget" in tsup config, making the global API `BridgeWidget.render()` rather than `window.thirdweb.BridgeWidget.render()`.
Applied to files:
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
📚 Learning: 2025-10-03T23:36:00.631Z
Learnt from: MananTank
PR: thirdweb-dev/js#8181
File: packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx:27-27
Timestamp: 2025-10-03T23:36:00.631Z
Learning: In packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx, the component intentionally uses a hardcoded English locale (connectLocaleEn) rather than reading from the provider, as BuyWidget is designed to be English-only and does not require internationalization support.
Applied to files:
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
🧬 Code graph analysis (4)
packages/thirdweb/src/react/web/ui/components/Modal.tsx (1)
packages/thirdweb/src/react/web/ui/components/buttons.tsx (1)
IconButton
(165-186)
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx (1)
packages/thirdweb/src/script-exports/bridge-widget-script.tsx (2)
BridgeWidgetScript
(62-72)BridgeWidgetScriptProps
(18-60)
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.stories.tsx (2)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/SwapWidget.tsx (2)
SwapWidgetProps
(33-171)SwapWidget
(245-266)packages/thirdweb/src/exports/react.ts (2)
SwapWidgetProps
(151-151)SwapWidget
(150-150)
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx (2)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/SwapWidget.tsx (2)
SwapWidget
(245-266)SwapWidgetProps
(33-171)packages/thirdweb/src/exports/react.ts (2)
SwapWidget
(150-150)SwapWidgetProps
(151-151)
⏰ 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). (1)
- GitHub Check: Analyze (javascript)
🔇 Additional comments (8)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx (1)
205-225
: LGTM!Setting
autoFocusCrossIcon={false}
correctly prevents the modal's close icon from stealing focus, allowing the search input withinSelectToken
to receive focus instead. This aligns with the PR objective to autofocus the token search input on desktop.packages/thirdweb/src/react/web/ui/Bridge/swap-widget/select-token-ui.tsx (1)
493-501
: LGTM!The desktop-only autofocus implementation (
autoFocus={!props.isMobile}
) correctly addresses the PR objective. Mobile devices are appropriately excluded, as autofocus with on-screen keyboards can be disruptive on smaller screens.packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx (1)
213-237
: LGTM!Consistent with the same change in
swap-ui.tsx
, settingautoFocusCrossIcon={false}
ensures the search input within the token selection modal receives focus instead of the close icon.packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx (1)
3-6
: LGTM!The type-only import of
SwapWidgetProps
follows TypeScript best practices and aligns with the coding guidelines.packages/thirdweb/src/stories/BuyWidget.stories.tsx (1)
143-149
: LGTM!Adding
alignItems: "center"
to theVariant
wrapper ensures consistent centering of widget previews in Storybook, which improves the visual presentation of dual-theme stories.packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.stories.tsx (1)
3-6
: LGTM!The type-only import of
SwapWidgetProps
follows TypeScript best practices and aligns with the coding guidelines.packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx (2)
2-5
: LGTM!The type-only import of
BridgeWidgetScriptProps
follows TypeScript best practices and aligns with the coding guidelines.
13-70
: LGTM!All stories consistently use the
Variant
wrapper for dual-theme previews, which provides a uniform viewing experience across all BridgeWidgetScript stories.
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 (4)
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx (1)
69-81
: Inconsistent usage of Variant wrapper.The
Sell_Base_USDC
story directly rendersSwapWidget
while all other stories in this file use theVariant
wrapper. This inconsistency makes the story behavior differ from others.Apply this diff to align with other stories:
export function Sell_Base_USDC() { return ( - <SwapWidget + <Variant client={storyClient} prefill={{ sellToken: {packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.stories.tsx (2)
14-16
: Inconsistent usage of Variant wrapper.The
BasicUsage
story directly rendersSwapWidget
while other stories in this file use theVariant
wrapper. This inconsistency makes the story behavior differ from others (single instance vs. dual-theme instances).Apply this diff if dual-theme rendering is intended:
export function BasicUsage() { - return <SwapWidget client={storyClient} persistTokenSelections={false} />; + return <Variant client={storyClient} persistTokenSelections={false} />; }
28-37
: Theme override bug: Variant ignores theme props.The
LightMode
andCustomTheme
stories pass theme-related props (theme="light"
and custom theme object), but theVariant
component hardcodestheme="dark"
andtheme="light"
on lines 79-80, completely overriding the passed themes. These stories don't demonstrate what their names suggest.Either:
- Remove
Variant
wrapper from theme-specific stories and renderSwapWidget
directly to preserve the custom themes, or- Rename these stories to clarify they show both themes (e.g.,
CustomTheme_DualView
) and adjust expectations.Example fix for option 1:
export function LightMode() { - return ( - <Variant - client={storyClient} - currency="JPY" - theme="light" - persistTokenSelections={false} - /> - ); + return <SwapWidget client={storyClient} currency="JPY" theme="light" persistTokenSelections={false} />; } export function CustomTheme() { - return ( - <Variant - client={storyClient} - currency="JPY" - persistTokenSelections={false} - theme={lightTheme({ - colors: { - modalBg: "#FFFFF0", - tertiaryBg: "#DBE4C9", - borderColor: "#8AA624", - secondaryText: "#3E3F29", - accentText: "#E43636", - }, - })} - /> - ); + return <SwapWidget + client={storyClient} + currency="JPY" + persistTokenSelections={false} + theme={lightTheme({ + colors: { + modalBg: "#FFFFF0", + tertiaryBg: "#DBE4C9", + borderColor: "#8AA624", + secondaryText: "#3E3F29", + accentText: "#E43636", + }, + })} + />; }Also applies to: 50-67
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx (1)
53-70
: Theme override bug: Variant ignores custom theme.The
CustomTheme
story passes a custom theme object with specific colors, but theVariant
component hardcodestheme="dark"
andtheme="light"
on lines 82-83, completely overriding the custom theme. The story doesn't demonstrate custom theming as its name suggests.Either:
- Remove
Variant
wrapper and renderBridgeWidgetScript
directly to preserve the custom theme, or- Rename the story to clarify it shows both themes regardless of input (e.g.,
CustomTheme_DualView
).Example fix for option 1:
export function CustomTheme() { - return ( - <Variant - clientId={storyClient.clientId} - buy={{ chainId: 8453, amount: "0.1" }} - theme={{ - type: "light", - colors: { - modalBg: "#FFFFF0", - tertiaryBg: "#DBE4C9", - borderColor: "#8AA624", - secondaryText: "#3E3F29", - accentText: "#E43636", - }, - }} - /> - ); + return <BridgeWidgetScript + clientId={storyClient.clientId} + buy={{ chainId: 8453, amount: "0.1" }} + theme={{ + type: "light", + colors: { + modalBg: "#FFFFF0", + tertiaryBg: "#DBE4C9", + borderColor: "#8AA624", + secondaryText: "#3E3F29", + accentText: "#E43636", + }, + }} + />; }
♻️ Duplicate comments (2)
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.stories.tsx (1)
69-83
: Extract duplicated Variant component to shared utility.The
Variant
component is duplicated across multiple story files (here, SwapWidget.Prefill.stories.tsx, and bridge-widget-script.stories.tsx). Extract this to a shared utility file to follow the DRY principle.packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx (1)
72-86
: Extract duplicated Variant component to shared utility.The
Variant
component is duplicated across three story files (SwapWidget.stories.tsx, SwapWidget.Prefill.stories.tsx, and here). Extract this to a shared utility file to follow the DRY principle.
🧹 Nitpick comments (1)
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx (1)
118-132
: Extract duplicated Variant component to shared utility.The
Variant
component is duplicated across multiple story files (SwapWidget.stories.tsx, SwapWidget.Prefill.stories.tsx, and bridge-widget-script.stories.tsx). Extract this to a shared utility file likestories/utils.tsx
to follow the DRY principle.Example shared utility:
// In stories/utils.tsx or stories/components.tsx export function DualThemeVariant<T>(props: T & { children: (props: T) => React.ReactNode }) { const { children, ...componentProps } = props; return ( <div style={{ display: "flex", flexDirection: "column", gap: "40px", alignItems: "center", }} > {children({ ...componentProps, theme: "dark" } as T)} {children({ ...componentProps, theme: "light" } as T)} </div> ); }
📜 Review details
Configuration used: CodeRabbit 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 (10)
.changeset/happy-trees-doubt.md
(1 hunks)packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
(1 hunks)packages/thirdweb/src/react/web/ui/Bridge/swap-widget/SearchInput.tsx
(2 hunks)packages/thirdweb/src/react/web/ui/Bridge/swap-widget/select-token-ui.tsx
(1 hunks)packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
(1 hunks)packages/thirdweb/src/react/web/ui/components/Modal.tsx
(2 hunks)packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
(6 hunks)packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx
(7 hunks)packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.stories.tsx
(6 hunks)packages/thirdweb/src/stories/BuyWidget.stories.tsx
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
- packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
- packages/thirdweb/src/react/web/ui/Bridge/swap-widget/select-token-ui.tsx
- packages/thirdweb/src/react/web/ui/components/Modal.tsx
- packages/thirdweb/src/stories/BuyWidget.stories.tsx
- packages/thirdweb/src/react/web/ui/Bridge/swap-widget/SearchInput.tsx
- packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.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 file to one stateless, single-responsibility function for clarity
Re-use shared types from@/types
or localtypes.ts
barrels
Prefer type aliases over interface except for nominal shapes
Avoidany
andunknown
unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial
,Pick
, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
**/*.{ts,tsx}
: Use explicit function declarations and explicit return types in TypeScript
Limit each file to one stateless, single‑responsibility function
Re‑use shared types from@/types
where applicable
Prefertype
aliases overinterface
except for nominal shapes
Avoidany
andunknown
unless unavoidable; narrow generics when possible
Prefer composition over inheritance; use utility types (Partial, Pick, etc.)
Lazy‑import optional features and avoid top‑level side‑effects to reduce bundle size
Files:
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.stories.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)
Files:
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.stories.tsx
**/*.stories.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
For new UI components, add Storybook stories (
*.stories.tsx
) alongside the code
Files:
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.stories.tsx
packages/thirdweb/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
packages/thirdweb/**/*.{ts,tsx}
: Every public symbol must have comprehensive TSDoc with at least one compiling@example
and a custom tag (@beta
,@internal
,@experimental
, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
Lazy‑load heavy dependencies inside async paths (e.g.,const { jsPDF } = await import("jspdf")
)
Files:
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.stories.tsx
.changeset/*.md
📄 CodeRabbit inference engine (AGENTS.md)
.changeset/*.md
: Each change inpackages/*
must include a changeset for the appropriate package
Version bump rules: patch for non‑API changes; minor for new/modified public API
Files:
.changeset/happy-trees-doubt.md
🧠 Learnings (3)
📚 Learning: 2025-09-24T11:08:43.783Z
Learnt from: MananTank
PR: thirdweb-dev/js#8106
File: packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx:34-41
Timestamp: 2025-09-24T11:08:43.783Z
Learning: In BridgeWidgetProps for packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx, the Swap onError callback signature requires a non-undefined SwapPreparedQuote parameter (unlike Buy's onError which allows undefined quote). This is intentional - SwapWidget's onError is only called when a quote is available.
Applied to files:
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx
📚 Learning: 2025-09-24T11:09:45.142Z
Learnt from: MananTank
PR: thirdweb-dev/js#8106
File: packages/thirdweb/src/script-exports/readme.md:6-7
Timestamp: 2025-09-24T11:09:45.142Z
Learning: For thirdweb Bridge Widget script exports, the module is exported with globalName: "BridgeWidget" in tsup config, making the global API `BridgeWidget.render()` rather than `window.thirdweb.BridgeWidget.render()`.
Applied to files:
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
📚 Learning: 2025-10-03T23:36:00.631Z
Learnt from: MananTank
PR: thirdweb-dev/js#8181
File: packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx:27-27
Timestamp: 2025-10-03T23:36:00.631Z
Learning: In packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx, the component intentionally uses a hardcoded English locale (connectLocaleEn) rather than reading from the provider, as BuyWidget is designed to be English-only and does not require internationalization support.
Applied to files:
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
🧬 Code graph analysis (3)
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx (2)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/SwapWidget.tsx (2)
SwapWidget
(245-266)SwapWidgetProps
(33-171)packages/thirdweb/src/exports/react.ts (2)
SwapWidget
(150-150)SwapWidgetProps
(151-151)
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx (1)
packages/thirdweb/src/script-exports/bridge-widget-script.tsx (2)
BridgeWidgetScript
(62-72)BridgeWidgetScriptProps
(18-60)
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.stories.tsx (2)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/SwapWidget.tsx (2)
SwapWidgetProps
(33-171)SwapWidget
(245-266)packages/thirdweb/src/exports/react.ts (2)
SwapWidgetProps
(151-151)SwapWidget
(150-150)
⏰ 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: Analyze (javascript)
- GitHub Check: Unit Tests
- GitHub Check: Size
- GitHub Check: Lint Packages
🔇 Additional comments (1)
.changeset/happy-trees-doubt.md (1)
1-5
: LGTM!The changeset correctly documents the autofocus enhancement as a patch version bump, which is appropriate for this non-breaking behavioral improvement.
size-limit report 📦
|
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
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/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx (1)
71-80
: Inconsistent pattern with other stories.The
Sell_Base_USDC
story still renders<SwapWidget>
directly, while all other stories in this file use the<Variant>
wrapper to test both dark and light themes side-by-side.Apply this diff to align with the established pattern:
export function Sell_Base_USDC() { return ( - <SwapWidget + <Variant client={storyClient} prefill={{ sellToken: { chainId: 8453, tokenAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", }, }} /> ); }
🧹 Nitpick comments (2)
packages/thirdweb/src/stories/BuyWidget.stories.tsx (1)
141-155
: Add explicit return type to Variant function.The
Variant
function lacks an explicit return type, which is required by the coding guidelines for TypeScript files.Apply this diff to add the return type:
-function Variant(props: BuyWidgetProps) { +function Variant(props: BuyWidgetProps): React.JSX.Element { return (As per coding guidelines.
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx (1)
118-132
: Add explicit return type.The
Variant
function should have an explicit return type per coding guidelines.As per coding guidelines
Apply this diff:
-function Variant(props: SwapWidgetProps) { +function Variant(props: SwapWidgetProps): React.ReactElement { return (
📜 Review details
Configuration used: CodeRabbit 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 (10)
.changeset/happy-trees-doubt.md
(1 hunks)packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
(1 hunks)packages/thirdweb/src/react/web/ui/Bridge/swap-widget/SearchInput.tsx
(2 hunks)packages/thirdweb/src/react/web/ui/Bridge/swap-widget/select-token-ui.tsx
(1 hunks)packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
(1 hunks)packages/thirdweb/src/react/web/ui/components/Modal.tsx
(2 hunks)packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
(6 hunks)packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx
(7 hunks)packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.stories.tsx
(6 hunks)packages/thirdweb/src/stories/BuyWidget.stories.tsx
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
- packages/thirdweb/src/react/web/ui/Bridge/swap-widget/SearchInput.tsx
- packages/thirdweb/src/react/web/ui/components/Modal.tsx
- packages/thirdweb/src/react/web/ui/Bridge/swap-widget/select-token-ui.tsx
- packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.stories.tsx
- .changeset/happy-trees-doubt.md
🧰 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 file to one stateless, single-responsibility function for clarity
Re-use shared types from@/types
or localtypes.ts
barrels
Prefer type aliases over interface except for nominal shapes
Avoidany
andunknown
unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial
,Pick
, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
**/*.{ts,tsx}
: Use explicit function declarations and explicit return types in TypeScript
Limit each file to one stateless, single‑responsibility function
Re‑use shared types from@/types
where applicable
Prefertype
aliases overinterface
except for nominal shapes
Avoidany
andunknown
unless unavoidable; narrow generics when possible
Prefer composition over inheritance; use utility types (Partial, Pick, etc.)
Lazy‑import optional features and avoid top‑level side‑effects to reduce bundle size
Files:
packages/thirdweb/src/stories/BuyWidget.stories.tsx
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)
Files:
packages/thirdweb/src/stories/BuyWidget.stories.tsx
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx
**/*.stories.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
For new UI components, add Storybook stories (
*.stories.tsx
) alongside the code
Files:
packages/thirdweb/src/stories/BuyWidget.stories.tsx
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx
packages/thirdweb/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
packages/thirdweb/**/*.{ts,tsx}
: Every public symbol must have comprehensive TSDoc with at least one compiling@example
and a custom tag (@beta
,@internal
,@experimental
, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
Lazy‑load heavy dependencies inside async paths (e.g.,const { jsPDF } = await import("jspdf")
)
Files:
packages/thirdweb/src/stories/BuyWidget.stories.tsx
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx
🧠 Learnings (3)
📚 Learning: 2025-09-24T11:09:45.142Z
Learnt from: MananTank
PR: thirdweb-dev/js#8106
File: packages/thirdweb/src/script-exports/readme.md:6-7
Timestamp: 2025-09-24T11:09:45.142Z
Learning: For thirdweb Bridge Widget script exports, the module is exported with globalName: "BridgeWidget" in tsup config, making the global API `BridgeWidget.render()` rather than `window.thirdweb.BridgeWidget.render()`.
Applied to files:
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
📚 Learning: 2025-10-03T23:36:00.631Z
Learnt from: MananTank
PR: thirdweb-dev/js#8181
File: packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx:27-27
Timestamp: 2025-10-03T23:36:00.631Z
Learning: In packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx, the component intentionally uses a hardcoded English locale (connectLocaleEn) rather than reading from the provider, as BuyWidget is designed to be English-only and does not require internationalization support.
Applied to files:
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
📚 Learning: 2025-09-24T11:08:43.783Z
Learnt from: MananTank
PR: thirdweb-dev/js#8106
File: packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx:34-41
Timestamp: 2025-09-24T11:08:43.783Z
Learning: In BridgeWidgetProps for packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx, the Swap onError callback signature requires a non-undefined SwapPreparedQuote parameter (unlike Buy's onError which allows undefined quote). This is intentional - SwapWidget's onError is only called when a quote is available.
Applied to files:
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx
🧬 Code graph analysis (2)
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx (1)
packages/thirdweb/src/script-exports/bridge-widget-script.tsx (2)
BridgeWidgetScript
(69-79)BridgeWidgetScriptProps
(19-67)
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx (2)
packages/thirdweb/src/exports/react.ts (2)
SwapWidget
(152-152)SwapWidgetProps
(153-153)packages/thirdweb/src/react/web/ui/Bridge/swap-widget/SwapWidget.tsx (2)
SwapWidget
(248-269)SwapWidgetProps
(33-174)
⏰ 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: Unit Tests
- GitHub Check: Build Packages
- GitHub Check: E2E Tests (pnpm, esbuild)
- GitHub Check: Lint Packages
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: Size
- GitHub Check: Analyze (javascript)
🔇 Additional comments (4)
packages/thirdweb/src/stories/BuyWidget.stories.tsx (1)
143-149
: LGTM! Layout change appropriately centers content.The addition of
alignItems: "center"
properly centers the BuyWidget components horizontally within the flex container, replacing the removed globallayout: "centered"
parameter with local styling.packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx (1)
208-208
: LGTM!The
autoFocusCrossIcon={false}
prop correctly disables autofocus on the modal's close button, allowing the token search input to receive focus instead. This aligns with the PR objective to enable immediate keyboard search when the token selector modal opens.packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx (1)
207-207
: LGTM!Consistent with the FundWallet implementation, this change correctly prevents the close button from stealing focus, enabling the token search input to autofocus when the modal opens.
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx (1)
3-6
: LGTM!The import expansion to include
SwapWidgetProps
type is appropriate for the newVariant
component's type annotations.
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
Show resolved
Hide resolved
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #8266 +/- ##
==========================================
- Coverage 54.90% 54.89% -0.01%
==========================================
Files 919 919
Lines 60613 60622 +9
Branches 4115 4126 +11
==========================================
Hits 33278 33278
- Misses 27234 27242 +8
- Partials 101 102 +1
🚀 New features to boost your workflow:
|
Merge activity
|
… opens in BuyWidget, SwapWidget and BridgeWidget (#8266) <!-- ## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes" If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000): ## Notes for the reviewer Anything important to call out? Be sure to also clarify these in your comments. ## How to test Unit tests, playground, etc. --> <!-- start pr-codex --> --- ## PR-Codex overview This PR enhances user experience by adding autofocus functionality to token selection inputs in various components and refactoring the `BuyWidget` and `SwapWidget` to utilize a common `Variant` component for rendering with different themes. ### Detailed summary - Added `autoFocus` to token search inputs in `BuyWidget`, `SwapWidget`, and `BridgeWidget`. - Refactored `BuyWidget` to use a `Variant` component for theme rendering. - Refactored `SwapWidget` to use a `Variant` component for theme rendering. - Introduced `autoFocusCrossIcon` prop in `Modal` component. - Updated `SearchInput` to accept `autoFocus` prop. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Token search input now auto-focuses on desktop when opening token selector modals in Buy, Swap, and Bridge widgets. * Modal gained a configurable option to control initial focus of the close (cross) button. * **Bug Fixes / UX** * Prevents unwanted focus on the modal close icon by default when configured, improving keyboard/voicing navigation. * **Chores** * Storybook examples updated for consistent light/dark variants and layout metadata. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
872f37e
to
5ff6063
Compare
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/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx (1)
69-81
: Inconsistent rendering: UseVariant
wrapper for dual-theme display.The
Sell_Base_USDC
story still rendersSwapWidget
directly, while all other stories have been refactored to use theVariant
wrapper. This inconsistency means this story won't display both light and dark themes like the others.Apply this diff to align with the refactoring pattern:
export function Sell_Base_USDC() { return ( - <SwapWidget + <Variant client={storyClient} prefill={{ sellToken: { chainId: 8453, tokenAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", }, }} /> ); }
♻️ Duplicate comments (1)
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx (1)
72-86
: Restore story theming behavior: Variant ignores thetheme
prop.The
Variant
component hardcodestheme="dark"
andtheme="light"
, completely discarding anytheme
supplied via props. This causes:
LightTheme
story (line 26) to render both themes instead of only lightCustomTheme
story (lines 58-67) to ignore the custom theme and render default themesThe stories no longer demonstrate what their names suggest.
Apply the fix from the previous review to respect the caller-provided theme:
function Variant(props: BridgeWidgetScriptProps) { + const { theme, ...rest } = props; + const themesToRender = + theme === undefined ? (["dark", "light"] as const) : [theme]; + return ( <div style={{ display: "flex", flexDirection: "column", gap: "40px", alignItems: "center", }} > - <BridgeWidgetScript {...props} theme="dark" /> - <BridgeWidgetScript {...props} theme="light" /> + {themesToRender.map((t, idx) => ( + <BridgeWidgetScript key={typeof t === "string" ? t : `custom-${idx}`} {...rest} theme={t} /> + ))} </div> ); }
🧹 Nitpick comments (2)
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx (1)
118-132
: Add explicit return type annotation.The
Variant
component is missing an explicit return type annotation, which is required per the coding guidelines for TypeScript files.Apply this diff to add the return type:
-function Variant(props: SwapWidgetProps) { +function Variant(props: SwapWidgetProps): JSX.Element { return (Optionally, consider adding a brief comment explaining the purpose of this internal helper:
/** * Internal helper that renders SwapWidget in both dark and light themes for story comparison. */ function Variant(props: SwapWidgetProps): JSX.Element {As per coding guidelines.
packages/thirdweb/src/react/web/ui/components/Modal.tsx (1)
44-44
: Consider adding a brief inline comment.While the prop name is descriptive, a brief comment would clarify its purpose for future maintainers (e.g.,
/** If false, disables autofocus on close button to allow other elements to receive initial focus */
).
📜 Review details
Configuration used: CodeRabbit 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 (10)
.changeset/happy-trees-doubt.md
(1 hunks)packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
(1 hunks)packages/thirdweb/src/react/web/ui/Bridge/swap-widget/SearchInput.tsx
(2 hunks)packages/thirdweb/src/react/web/ui/Bridge/swap-widget/select-token-ui.tsx
(1 hunks)packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
(1 hunks)packages/thirdweb/src/react/web/ui/components/Modal.tsx
(2 hunks)packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
(6 hunks)packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx
(7 hunks)packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.stories.tsx
(6 hunks)packages/thirdweb/src/stories/BuyWidget.stories.tsx
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- .changeset/happy-trees-doubt.md
🚧 Files skipped from review as they are similar to previous changes (6)
- packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
- packages/thirdweb/src/react/web/ui/Bridge/swap-widget/SearchInput.tsx
- packages/thirdweb/src/react/web/ui/Bridge/swap-widget/select-token-ui.tsx
- packages/thirdweb/src/stories/BuyWidget.stories.tsx
- packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.stories.tsx
- packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
🧰 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 file to one stateless, single-responsibility function for clarity
Re-use shared types from@/types
or localtypes.ts
barrels
Prefer type aliases over interface except for nominal shapes
Avoidany
andunknown
unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial
,Pick
, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
**/*.{ts,tsx}
: Use explicit function declarations and explicit return types in TypeScript
Limit each file to one stateless, single‑responsibility function
Re‑use shared types from@/types
where applicable
Prefertype
aliases overinterface
except for nominal shapes
Avoidany
andunknown
unless unavoidable; narrow generics when possible
Prefer composition over inheritance; use utility types (Partial, Pick, etc.)
Lazy‑import optional features and avoid top‑level side‑effects to reduce bundle size
Files:
packages/thirdweb/src/react/web/ui/components/Modal.tsx
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)
Files:
packages/thirdweb/src/react/web/ui/components/Modal.tsx
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
packages/thirdweb/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
packages/thirdweb/**/*.{ts,tsx}
: Every public symbol must have comprehensive TSDoc with at least one compiling@example
and a custom tag (@beta
,@internal
,@experimental
, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
Lazy‑load heavy dependencies inside async paths (e.g.,const { jsPDF } = await import("jspdf")
)
Files:
packages/thirdweb/src/react/web/ui/components/Modal.tsx
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
**/*.stories.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
For new UI components, add Storybook stories (
*.stories.tsx
) alongside the code
Files:
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
🧠 Learnings (3)
📚 Learning: 2025-09-24T11:08:43.783Z
Learnt from: MananTank
PR: thirdweb-dev/js#8106
File: packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx:34-41
Timestamp: 2025-09-24T11:08:43.783Z
Learning: In BridgeWidgetProps for packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx, the Swap onError callback signature requires a non-undefined SwapPreparedQuote parameter (unlike Buy's onError which allows undefined quote). This is intentional - SwapWidget's onError is only called when a quote is available.
Applied to files:
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx
📚 Learning: 2025-09-24T11:09:45.142Z
Learnt from: MananTank
PR: thirdweb-dev/js#8106
File: packages/thirdweb/src/script-exports/readme.md:6-7
Timestamp: 2025-09-24T11:09:45.142Z
Learning: For thirdweb Bridge Widget script exports, the module is exported with globalName: "BridgeWidget" in tsup config, making the global API `BridgeWidget.render()` rather than `window.thirdweb.BridgeWidget.render()`.
Applied to files:
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
📚 Learning: 2025-10-03T23:36:00.631Z
Learnt from: MananTank
PR: thirdweb-dev/js#8181
File: packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx:27-27
Timestamp: 2025-10-03T23:36:00.631Z
Learning: In packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx, the component intentionally uses a hardcoded English locale (connectLocaleEn) rather than reading from the provider, as BuyWidget is designed to be English-only and does not require internationalization support.
Applied to files:
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx
🧬 Code graph analysis (3)
packages/thirdweb/src/react/web/ui/components/Modal.tsx (1)
packages/thirdweb/src/react/web/ui/components/buttons.tsx (1)
IconButton
(165-186)
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx (2)
packages/thirdweb/src/exports/react.ts (2)
SwapWidget
(152-152)SwapWidgetProps
(153-153)packages/thirdweb/src/react/web/ui/Bridge/swap-widget/SwapWidget.tsx (2)
SwapWidget
(248-269)SwapWidgetProps
(33-174)
packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx (1)
packages/thirdweb/src/script-exports/bridge-widget-script.tsx (2)
BridgeWidgetScript
(69-79)BridgeWidgetScriptProps
(19-67)
⏰ 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, webpack)
- GitHub Check: Lint Packages
- GitHub Check: Build Packages
- GitHub Check: Size
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: Unit Tests
- GitHub Check: E2E Tests (pnpm, esbuild)
- GitHub Check: Analyze (javascript)
🔇 Additional comments (3)
packages/thirdweb/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx (1)
3-6
: LGTM! Correct type import.The addition of
SwapWidgetProps
type import is correct and properly uses thetype
modifier for type-only imports.packages/thirdweb/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx (1)
2-5
: LGTM: Type import supports proper typing of the Variant component.The addition of
BridgeWidgetScriptProps
to the imports enables proper typing of theVariant
helper function introduced below.packages/thirdweb/src/react/web/ui/components/Modal.tsx (1)
147-155
: Logic is correct; consider nullish coalescing for brevity.The conditional autofocus logic preserves backward compatibility by defaulting to
true
whenautoFocusCrossIcon
is undefined. Focus management is properly implemented: when the Modal's close button disables autofocus (autoFocusCrossIcon={false}
), the SearchInput component in SelectToken compensates withautoFocus={!props.isMobile}
, ensuring keyboard accessibility on desktop.Optionally refactor to use the nullish coalescing operator for more idiomatic TypeScript:
<Dialog.Close asChild> <IconButton aria-label="Close" - autoFocus={ - props.autoFocusCrossIcon === undefined - ? true - : props.autoFocusCrossIcon - } + autoFocus={props.autoFocusCrossIcon ?? true} type="button" >
PR-Codex overview
This PR enhances the user experience by adding autofocus functionality to token search inputs across various components, ensuring that users can quickly start searching for tokens when the respective modals open.
Detailed summary
autoFocus
to token search inputs inBuyWidget
,SwapWidget
, andBridgeWidget
.Modal
component to includeautoFocusCrossIcon
prop.SearchInput
component to acceptautoFocus
prop.SwapWidget
andBridgeWidgetScript
to use aVariant
component for consistent styling.Summary by CodeRabbit
New Features
Bug Fixes / UX
Chores