-
Notifications
You must be signed in to change notification settings - Fork 615
Playground: Fix Pay components incomplete code gen, cleanup #8078
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
Playground: Fix Pay components incomplete code gen, cleanup #8078
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
WalkthroughAdds a shared code-generation utility and updates multiple CodeGen components to use it. Moves widget selection out of payOptions into an explicit widget prop across payments playground components. Refactors import assembly, props emission, and theming logic for generated code. Adjusts Prettier print width for code formatting. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant UI as Playground UI
participant LS as LeftSection
participant RS as RightSection
participant CG as CodeGen (payments)
participant Lib as code-gen utils
UI->>LS: render(widget, options)
UI->>RS: render(widget, options)
RS->>CG: render({ widget, options })
CG->>Lib: stringifyImports(imports)
CG->>Lib: stringifyProps(props)
CG-->>RS: code string with imports + <Component {...props} />
RS-->>UI: display Code tab
sequenceDiagram
autonumber
participant SW as SwapWidget CodeGen
participant WS as Wallet Sign-In CodeGen
participant Lib as code-gen utils
SW->>Lib: stringifyImports + stringifyProps + quotes
WS->>Lib: stringifyImports + stringifyProps + stringifyIgnoreFalsy + quotes
Note over SW,WS: Both generators emit imports via a centralized imports map and produce final JSX with shared helpers
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests
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. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #8078 +/- ##
=======================================
Coverage 56.34% 56.34%
=======================================
Files 906 906
Lines 59171 59171
Branches 4175 4175
=======================================
Hits 33342 33342
Misses 25723 25723
Partials 106 106
🚀 New features to boost your workflow:
|
size-limit report 📦
|
8fb5927 to
364c631
Compare
Merge activity
|
<!--
## 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 primarily focuses on refactoring the payment components in the `playground-web` application, updating widget properties and enhancing code generation functions for better modularity and readability.
### Detailed summary
- Changed `lockedWidget` to `widget` in multiple components: `CheckoutPlayground`, `TransactionPlayground`, `BuyPlayground`, `LeftSection`, and `RightSection`.
- Added new functions in `code-gen.ts` for `stringifyProps`, `quotes`, `stringifyImports`, and `stringifyIgnoreFalsy`.
- Updated `CodeGen` components to accept `widget` as a prop.
- Refactored `getCode` function in `CodeGen` to use the new `widget` parameter.
- Removed unused imports and functions from `CodeGen` and `LeftSection`.
> ✨ 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
- Code generator now supports explicit widget selection (buy, checkout, transaction) with unified, props-driven output.
- Enhanced theming in generated snippets, including dark/light themes with overrides.
- Refactor
- Migrated playground code generation to centralized utilities for imports and props.
- Simplified widget configuration by removing it from options and passing it as a direct prop.
- Streamlined Payments UI; removed “Sponsor gas fees” section.
- Style
- Improved code snippet formatting with wider line wrap for cleaner display.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
364c631 to
fddb791
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: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/playground-web/src/app/wallets/sign-in/components/CodeGen.tsx (1)
108-116: Bug: wrong casing and negation flips showThirdwebBranding default.Using
ShowThirdwebBranding(capital S) and!means the snippet will often hide branding unintentionally.Apply this diff:
- showThirdwebBranding: !connectOptions.ShowThirdwebBranding - ? false - : undefined, + showThirdwebBranding: + connectOptions.showThirdwebBranding === false ? false : undefined,
🧹 Nitpick comments (15)
apps/playground-web/src/app/bridge/swap-widget/components/code.tsx (1)
30-34: Import map + inline prop emission LGTM.
- Module split into "thirdweb" and "thirdweb/react" is accurate.
- Using stringifyImports and stringifyProps keeps output predictable.
If imports ever grow, consider ensuring deterministic ordering/dedup in the library-level stringifyImports to avoid cosmetic diffs across runs.
Also applies to: 74-74, 82-82
apps/playground-web/src/app/payments/components/RightSection.tsx (1)
114-119: Avoid empty-string fallback for transaction “to” address.claimTo with to: "" risks invalid address errors. Prefer the zero address or gate until account exists.
Apply one of:
- to: account?.address || "", + to: account?.address || "0x0000000000000000000000000000000000000000",or render TransactionWidget only when account?.address is present.
apps/playground-web/src/lib/code-gen.ts (4)
12-15: Stable prop order for cleaner diffs.Sort props alphabetically before joining to keep generated output stable:
- return Object.entries(_props) - .map(([key, value]) => `${key}={${value}}`) - .join("\n"); + return Object.entries(_props) + .sort(([a], [b]) => a.localeCompare(b)) + .map(([key, value]) => `${key}={${value}}`) + .join("\n");
17-19: Escape strings via JSON.stringify.Protects against embedded quotes/newlines without changing call sites.
-export function quotes(value: string) { - return `"${value}"`; -} +export function quotes(value: string) { + return JSON.stringify(value); +}
21-29: Deterministic, de-duplicated imports.Prevents import churn across runs and envs.
-export function stringifyImports(imports: Record<string, string[]>) { - let code = ""; - for (const key in imports) { - if (imports[key].length > 0) { - code += `import { ${imports[key].join(", ")} } from "${key}";\n`; - } - } - return code; -} +export function stringifyImports(imports: Record<string, string[]>) { + let code = ""; + for (const key of Object.keys(imports).sort()) { + const names = Array.from(new Set(imports[key])).sort(); + if (names.length > 0) { + code += `import { ${names.join(", ")} } from "${key}";\n`; + } + } + return code; +}
42-43: Prettier-friendly JSON for object literals.Indented output reads better in the Code tab.
- return JSON.stringify(_value); + return JSON.stringify(_value, null, 2);apps/playground-web/src/app/payments/components/LeftSection.tsx (2)
125-155: Gating by props.widget is correct; UI logic reads clearly.Buy/Checkout shared selectors and mode-specific blocks are cleanly separated.
The “Payment Methods” checkbox group is duplicated in Buy/Checkout blocks. Consider extracting a tiny PaymentMethods section or a toggle helper to reduce repetition.
Also applies to: 159-237, 241-339, 343-354
347-351: Minor copy tweak: “an ERC1155”.Grammar nit in user-facing text.
- This demo uses a ERC1155 NFT claim transaction. Check the + This demo uses an ERC1155 NFT claim transaction. Check theapps/playground-web/src/app/wallets/sign-in/components/CodeGen.tsx (2)
17-23: Add explicit return types per TS guidelines.Tighten types for clarity and editor tooling.
-function CodeLoading() { +function CodeLoading(): JSX.Element { ... } -export function CodeGen(props: { connectOptions: ConnectPlaygroundOptions }) { +export function CodeGen( + props: { connectOptions: ConnectPlaygroundOptions }, +): JSX.Element { ... } -function getCode(connectOptions: ConnectPlaygroundOptions) { +function getCode(connectOptions: ConnectPlaygroundOptions): string { ... }Also applies to: 25-38, 40-41
11-15: Optional: prefer next/dynamic over React.lazy in app router.
next/dynamicavoids server-component pitfalls and lets you setssr: falseand a built-in loading fallback.-const CodeClient = lazy(() => - import("../../../../components/code/code.client").then((m) => ({ - default: m.CodeClient, - })), -); +import dynamic from "next/dynamic"; +const CodeClient = dynamic( + () => import("../../../../components/code/code.client").then((m) => m.CodeClient), + { ssr: false, loading: () => <CodeLoading /> }, +);apps/playground-web/src/app/payments/components/CodeGen.tsx (5)
41-44: Annotate return type for getCode.-function getCode( +function getCode( widget: "buy" | "checkout" | "transaction", options: BridgeComponentsPlaygroundOptions, -) +) : string {
45-53: Prefer exhaustive switch for componentName mapping.Avoid an empty-string fallback; enforce compile-time exhaustiveness.
- const componentName = - widget === "buy" - ? "BuyWidget" - : widget === "checkout" - ? "CheckoutWidget" - : widget === "transaction" - ? "TransactionWidget" - : ""; + const componentName = (() => { + switch (widget) { + case "buy": + return "BuyWidget"; + case "checkout": + return "CheckoutWidget"; + case "transaction": + return "TransactionWidget"; + default: { + const _exhaustive: never = widget; + return _exhaustive; + } + } + })();
55-59: Unused import in generated snippet.
"thirdweb/wallets": ["createWallet"]isn’t used anywhere in the emitted code; it will produce dead imports.const imports = { "thirdweb/chains": [] as string[], "thirdweb/react": [componentName] as string[], thirdweb: ["createThirdwebClient", "defineChain"] as string[], - "thirdweb/wallets": ["createWallet"] as string[], };
16-23: Add explicit return types to exported/local functions.-function CodeLoading() { +function CodeLoading(): JSX.Element { ... } -export function CodeGen(props: { - widget: "buy" | "checkout" | "transaction"; - options: BridgeComponentsPlaygroundOptions; -}) { +export function CodeGen(props: { + widget: "buy" | "checkout" | "transaction"; + options: BridgeComponentsPlaygroundOptions; +}): JSX.Element { ... } -function getCode( +function getCode( widget: "buy" | "checkout" | "transaction", options: BridgeComponentsPlaygroundOptions, -) +) : string {Also applies to: 24-27, 41-44
130-142: Optional: extract getCode to shared lib to reduce duplication.Both CodeGen files follow near‑identical patterns; consider moving getCode templates to
apps/playground-web/src/lib/code-gen.*with widget‑specific hooks.
📜 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 (11)
apps/playground-web/src/app/bridge/swap-widget/components/code.tsx(4 hunks)apps/playground-web/src/app/payments/commerce/CheckoutPlayground.tsx(1 hunks)apps/playground-web/src/app/payments/components/CodeGen.tsx(2 hunks)apps/playground-web/src/app/payments/components/LeftSection.tsx(6 hunks)apps/playground-web/src/app/payments/components/RightSection.tsx(5 hunks)apps/playground-web/src/app/payments/components/types.ts(0 hunks)apps/playground-web/src/app/payments/fund-wallet/BuyPlayground.tsx(1 hunks)apps/playground-web/src/app/payments/transactions/TransactionPlayground.tsx(1 hunks)apps/playground-web/src/app/wallets/sign-in/components/CodeGen.tsx(6 hunks)apps/playground-web/src/lib/code-gen.ts(1 hunks)packages/ui/src/components/code/getCodeHtml.tsx(1 hunks)
💤 Files with no reviewable changes (1)
- apps/playground-web/src/app/payments/components/types.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{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@/typesor localtypes.tsbarrels
Prefer type aliases over interface except for nominal shapes
Avoidanyandunknownunless 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@/typeswhere applicable
Prefertypealiases overinterfaceexcept for nominal shapes
Avoidanyandunknownunless 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:
apps/playground-web/src/app/payments/fund-wallet/BuyPlayground.tsxapps/playground-web/src/app/wallets/sign-in/components/CodeGen.tsxapps/playground-web/src/app/payments/commerce/CheckoutPlayground.tsxapps/playground-web/src/lib/code-gen.tsapps/playground-web/src/app/payments/components/CodeGen.tsxpackages/ui/src/components/code/getCodeHtml.tsxapps/playground-web/src/app/payments/transactions/TransactionPlayground.tsxapps/playground-web/src/app/payments/components/LeftSection.tsxapps/playground-web/src/app/bridge/swap-widget/components/code.tsxapps/playground-web/src/app/payments/components/RightSection.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)
Files:
apps/playground-web/src/app/payments/fund-wallet/BuyPlayground.tsxapps/playground-web/src/app/wallets/sign-in/components/CodeGen.tsxapps/playground-web/src/app/payments/commerce/CheckoutPlayground.tsxapps/playground-web/src/lib/code-gen.tsapps/playground-web/src/app/payments/components/CodeGen.tsxpackages/ui/src/components/code/getCodeHtml.tsxapps/playground-web/src/app/payments/transactions/TransactionPlayground.tsxapps/playground-web/src/app/payments/components/LeftSection.tsxapps/playground-web/src/app/bridge/swap-widget/components/code.tsxapps/playground-web/src/app/payments/components/RightSection.tsx
apps/{dashboard,playground-web}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
apps/{dashboard,playground-web}/**/*.{ts,tsx}: Import UI primitives from@/components/ui/*(Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
UseNavLinkfor internal navigation with automatic active states in dashboard and playground apps
Use Tailwind CSS only – no inline styles or CSS modules
Usecn()from@/lib/utilsfor conditional class logic
Use design system tokens (e.g.,bg-card,border-border,text-muted-foreground)
Server Components (Node edge): Start files withimport "server-only";
Client Components (browser): Begin files with'use client';
Always callgetAuthToken()to retrieve JWT from cookies on server side
UseAuthorization: Bearerheader – never embed tokens in URLs
Return typed results (e.g.,Project[],User[]) – avoidany
Wrap client-side data fetching calls in React Query (@tanstack/react-query)
Use descriptive, stablequeryKeysfor React Query cache hits
ConfigurestaleTime/cacheTimein React Query based on freshness (default ≥ 60s)
Keep tokens secret via internal API routes or server actions
Never importposthog-jsin server components
Files:
apps/playground-web/src/app/payments/fund-wallet/BuyPlayground.tsxapps/playground-web/src/app/wallets/sign-in/components/CodeGen.tsxapps/playground-web/src/app/payments/commerce/CheckoutPlayground.tsxapps/playground-web/src/lib/code-gen.tsapps/playground-web/src/app/payments/components/CodeGen.tsxapps/playground-web/src/app/payments/transactions/TransactionPlayground.tsxapps/playground-web/src/app/payments/components/LeftSection.tsxapps/playground-web/src/app/bridge/swap-widget/components/code.tsxapps/playground-web/src/app/payments/components/RightSection.tsx
🧠 Learnings (10)
📚 Learning: 2025-09-18T20:09:57.064Z
Learnt from: MananTank
PR: thirdweb-dev/js#8069
File: apps/playground-web/src/app/bridge/swap-widget/components/types.ts:3-12
Timestamp: 2025-09-18T20:09:57.064Z
Learning: The SwapWidgetPlaygroundOptions type should not include persistTokenSelections - the playground intentionally hardcodes persistTokenSelections={false} and doesn't expose it as a configurable option to users.
Applied to files:
apps/playground-web/src/app/payments/fund-wallet/BuyPlayground.tsx
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to **/*.{ts,tsx} : Lazy‑import optional features and avoid top‑level side‑effects to reduce bundle size
Applied to files:
apps/playground-web/src/app/wallets/sign-in/components/CodeGen.tsx
📚 Learning: 2025-05-30T17:14:25.332Z
Learnt from: MananTank
PR: thirdweb-dev/js#7227
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/OpenEditionMetadata.tsx:26-26
Timestamp: 2025-05-30T17:14:25.332Z
Learning: The ModuleCardUIProps interface already includes a client prop of type ThirdwebClient, so when components use `Omit<ModuleCardUIProps, "children" | "updateButton">`, they inherit the client prop without needing to add it explicitly.
Applied to files:
apps/playground-web/src/app/wallets/sign-in/components/CodeGen.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/components/*.client.tsx : Client components must start with `'use client';` before imports.
Applied to files:
apps/playground-web/src/app/wallets/sign-in/components/CodeGen.tsx
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to apps/{dashboard,playground}/**/*.{ts,tsx} : Client Components must start with `'use client'`; handle interactivity with hooks and browser APIs
Applied to files:
apps/playground-web/src/app/payments/components/CodeGen.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).
Applied to files:
apps/playground-web/src/app/payments/components/LeftSection.tsx
📚 Learning: 2025-07-31T16:17:42.753Z
Learnt from: MananTank
PR: thirdweb-dev/js#7768
File: apps/playground-web/src/app/navLinks.ts:1-1
Timestamp: 2025-07-31T16:17:42.753Z
Learning: Configuration files that import and reference React components (like icon components from lucide-react) need the "use client" directive, even if they primarily export static data, because the referenced components need to be executed in a client context when used by other client components.
Applied to files:
apps/playground-web/src/app/payments/components/LeftSection.tsx
📚 Learning: 2025-07-07T21:21:47.488Z
Learnt from: saminacodes
PR: thirdweb-dev/js#7543
File: apps/portal/src/app/pay/page.mdx:4-4
Timestamp: 2025-07-07T21:21:47.488Z
Learning: In the thirdweb-dev/js repository, lucide-react icons must be imported with the "Icon" suffix (e.g., ExternalLinkIcon, RocketIcon) as required by the new linting rule, contrary to the typical lucide-react convention of importing without the suffix.
Applied to files:
apps/playground-web/src/app/payments/components/LeftSection.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Icons come from `lucide-react` or the project-specific `…/icons` exports – never embed raw SVG.
Applied to files:
apps/playground-web/src/app/payments/components/LeftSection.tsx
📚 Learning: 2025-09-17T11:14:35.659Z
Learnt from: MananTank
PR: thirdweb-dev/js#8044
File: packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx:919-930
Timestamp: 2025-09-17T11:14:35.659Z
Learning: In the thirdweb codebase, useCustomTheme() hook can be used inside styled-components callbacks, contrary to the general React Rules of Hooks. This is a valid pattern in their implementation.
Applied to files:
apps/playground-web/src/app/bridge/swap-widget/components/code.tsx
🧬 Code graph analysis (7)
apps/playground-web/src/app/payments/fund-wallet/BuyPlayground.tsx (2)
apps/playground-web/src/app/payments/components/LeftSection.tsx (1)
LeftSection(21-492)apps/playground-web/src/app/payments/components/RightSection.tsx (1)
RightSection(29-162)
apps/playground-web/src/app/wallets/sign-in/components/CodeGen.tsx (1)
apps/playground-web/src/lib/code-gen.ts (2)
quotes(17-19)stringifyImports(21-29)
apps/playground-web/src/app/payments/commerce/CheckoutPlayground.tsx (1)
apps/playground-web/src/app/payments/components/RightSection.tsx (1)
RightSection(29-162)
apps/playground-web/src/app/payments/components/CodeGen.tsx (2)
apps/playground-web/src/app/payments/components/types.ts (1)
BridgeComponentsPlaygroundOptions(33-61)apps/playground-web/src/lib/code-gen.ts (3)
quotes(17-19)stringifyImports(21-29)stringifyProps(1-15)
apps/playground-web/src/app/payments/transactions/TransactionPlayground.tsx (1)
apps/playground-web/src/app/payments/components/RightSection.tsx (1)
RightSection(29-162)
apps/playground-web/src/app/bridge/swap-widget/components/code.tsx (1)
apps/playground-web/src/lib/code-gen.ts (2)
stringifyImports(21-29)stringifyProps(1-15)
apps/playground-web/src/app/payments/components/RightSection.tsx (1)
apps/playground-web/src/app/payments/components/CodeGen.tsx (1)
CodeGen(24-39)
🔇 Additional comments (17)
packages/ui/src/components/code/getCodeHtml.tsx (1)
28-28: Wider Prettier wrap looks good.printWidth: 80 is fine and should improve readability in the preview.
Please sanity-check that long prop lists in Code tabs don’t overflow their container at common widths (e.g., 360–768px).
apps/playground-web/src/app/payments/transactions/TransactionPlayground.tsx (1)
39-45: Good migration to widget prop.Usage is consistent with the new RightSection/LeftSection contract.
apps/playground-web/src/app/bridge/swap-widget/components/code.tsx (1)
3-3: Centralizing code-gen helpers is the right call.Importing quotes/stringifyImports/stringifyProps reduces duplication and keeps formatting consistent across generators.
apps/playground-web/src/app/payments/components/RightSection.tsx (1)
32-33: Widget-driven rendering is clean and explicit.Direct branching on props.widget and passing it to CodeGen removes hidden coupling.
Also applies to: 56-75, 77-103, 105-127, 156-158
apps/playground-web/src/app/payments/commerce/CheckoutPlayground.tsx (1)
39-45: Consistent widget prop usage.Matches the new Left/Right section contracts; defaults are intact.
apps/playground-web/src/app/payments/fund-wallet/BuyPlayground.tsx (1)
38-41: Prop rename to widget is correct and consistent — verification incompleteChange passing widget="buy" looks correct; automated search errored (rg PCRE). Run the fixed check below and paste the output.
#!/bin/bash set -euo pipefail root="apps/playground-web/src/app" echo "Scanning $root for LeftSection/RightSection without widget, lockedWidget, and payOptions.widget..." python3 - <<'PY' import os root="apps/playground-web/src/app" exts=('.tsx','.ts','.jsx','.js','.md','.mdx') tags=("LeftSection","RightSection") missing=[] locked=[] payopts=[] for dirpath,dirnames,filenames in os.walk(root): for fname in filenames: if not fname.endswith(exts): continue path=os.path.join(dirpath,fname) try: txt=open(path,encoding='utf-8',errors='ignore').read() except Exception: continue for tag in tags: start=0 while True: idx=txt.find(f"<{tag}", start) if idx==-1: break gt=txt.find(">", idx) if gt==-1: break opening=txt[idx:gt+1] if "widget=" not in opening and "widget =" not in opening: lineno = txt.count("\n",0,idx)+1 missing.append(f"{path}:{lineno}: {tag} opening missing widget -> {opening.strip()[:200]}") start=gt+1 if "lockedWidget" in txt: for i,line in enumerate(txt.splitlines(),1): if "lockedWidget" in line: locked.append(f"{path}:{i}: {line.strip()}") if "payOptions.widget" in txt: for i,line in enumerate(txt.splitlines(),1): if "payOptions.widget" in line: payopts.append(f"{path}:{i}: {line.strip()}") print("Missing widget attributes for LeftSection/RightSection:") print("\\n".join(missing) if missing else "None found.") print("\\nlockedWidget occurrences:") print("\\n".join(locked) if locked else "None found.") print("\\npayOptions.widget occurrences:") print("\\n".join(payopts) if payopts else "None found.") PYapps/playground-web/src/app/wallets/sign-in/components/CodeGen.tsx (6)
2-7: Good move: centralized code‑gen helpers.Switching to quotes/stringifyProps/stringifyImports/stringifyIgnoreFalsy from "@/lib/code-gen" reduces duplication and keeps output consistent.
43-47: Imports map re-org looks correct.New module paths for chains/react/wallets align with the broader refactor.
58-66: Conditional wallet imports — LGTM.Importing inAppWallet/createWallet only when used keeps snippets minimal.
77-88: Theme import logic — LGTM; verify default for dark theme.Emitting lightTheme only when needed and falling back to "light" is fine. For dark theme without overrides, you omit the prop; confirm the widget defaults to dark so the preview matches the UI controls.
93-95: Correct: add ethereum only when AA is enabled.
127-127: Imports emission via stringifyImports — nice.Keeps ordering stable and skips empty groups.
apps/playground-web/src/app/payments/components/CodeGen.tsx (5)
3-7: Good: unified code‑gen helpers.
24-27: API change to accept explicit widget — LGTM.Clearer than inferring from options; narrows code paths.
61-81: Theme logic — verify defaults.For dark with no overrides you omit
theme, while for light you emit"light". Confirm the widgets default to dark so UI and code match.
131-139: Shared imports/props emission — LGTM.stringifyImports + stringifyProps produces clean, copy‑pastable snippets.
93-128: Emit a Chain object — don't pass only an ID to defineChainWidgets expect a Chain object: use a predefined chain export (e.g., import { sepolia } from "thirdweb/chains") or call defineChain({ id: , rpc: "...", ... }) (import { defineChain } from "thirdweb/chains"). File apps/playground-web/src/app/payments/components/CodeGen.tsx (lines 93–128) currently emits defineChain(${options.payOptions.buyTokenChain.id}) — update the codegen to output either the chain constant for built‑in chains or defineChain({ id: ..., ... }) for custom chains.
⛔ Skipped due to learnings
Learnt from: MananTank PR: thirdweb-dev/js#7298 File: apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx:424-424 Timestamp: 2025-06-06T23:46:08.795Z Learning: The thirdweb project has an ESLint rule that restricts direct usage of `defineChain`. When it's necessary to use `defineChain` directly, it's acceptable to disable the rule with `// eslint-disable-next-line no-restricted-syntax`.
| @@ -1,5 +1,10 @@ | |||
| import { lazy, Suspense } from "react"; | |||
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.
Add 'use client' — this file uses React.lazy/Suspense patterns.
Mark as a Client Component to avoid Next.js app router errors.
+ 'use client';
import { lazy, Suspense } from "react";📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import { lazy, Suspense } from "react"; | |
| 'use client'; | |
| import { lazy, Suspense } from "react"; |
🤖 Prompt for AI Agents
In apps/playground-web/src/app/payments/components/CodeGen.tsx around line 1,
the file uses React.lazy and Suspense and must be marked as a Next.js Client
Component; add the directive 'use client' as the very first line in the file
(before any imports) so the app router treats it as a client component and avoid
server-side rendering errors, then save and run/typecheck to verify no other
client-only hooks are used.
| const transaction = | ||
| widget === "transaction" | ||
| ? `claimTo({ | ||
| contract: nftContract, | ||
| quantity: 1n, | ||
| to: account?.address || "", | ||
| tokenId: 2n, | ||
| })` | ||
| : undefined; |
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.
Broken snippet: references undefined vars (nftContract, account).
The generated transaction value will not compile as-is. Gate it on provided data or emit a self-contained example with required imports/variables.
Minimal safe fix using the existing options field:
- const transaction =
- widget === "transaction"
- ? `claimTo({
-contract: nftContract,
-quantity: 1n,
-to: account?.address || "",
-tokenId: 2n,
-})`
- : undefined;
+ const transaction =
+ widget === "transaction" && options.payOptions.transactionData
+ ? options.payOptions.transactionData
+ : undefined;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const transaction = | |
| widget === "transaction" | |
| ? `claimTo({ | |
| contract: nftContract, | |
| quantity: 1n, | |
| to: account?.address || "", | |
| tokenId: 2n, | |
| })` | |
| : undefined; | |
| const transaction = | |
| widget === "transaction" && options.payOptions.transactionData | |
| ? options.payOptions.transactionData | |
| : undefined; |
🤖 Prompt for AI Agents
In apps/playground-web/src/app/payments/components/CodeGen.tsx around lines 83
to 91, the generated transaction snippet references undefined variables
(nftContract, account) and will not compile; update the code to only emit the
claimTo(...) snippet when the required values exist by gating on provided data
(e.g., options.nftContract and options.account?.address) or replace it with a
self-contained example using local placeholders and required imports; the
minimal safe fix is to conditionally set transaction to undefined unless
options.nftContract and options.account?.address are present, otherwise produce
a complete example string that defines necessary variables/imports so the
snippet compiles.
| {previewTab === "code" && ( | ||
| <CodeGen widget={props.widget} options={props.options} /> | ||
| )} |
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.
🧩 Analysis chain
Verify all CodeGen usages pass widget.
Prevents regressions after the prop rename.
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "CodeGen usages missing widget prop:"
rg -nP '<CodeGen\b(?![^>]*\bwidget=)' apps | sed -n '1,200p' || trueLength of output: 119
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Searching for <CodeGen ...> usages under apps/ and checking if the opening tag contains 'widget=' (captures +40 lines after match):"
matches=$(rg -nS '<CodeGen' apps || true)
if [[ -z "$matches" ]]; then
echo "No <CodeGen ...> occurrences found under apps/."
exit 0
fi
echo "Found occurrences:"
echo "$matches"
echo
echo "Checking each occurrence for 'widget' prop in nearby lines:"
missing_count=0
while IFS=: read -r file line rest; do
start=$(( line > 3 ? line-2 : 1 ))
snippet=$(sed -n "${start},$((line+40))p" "$file" || true)
if ! printf '%s' "$snippet" | rg -q 'widget\s*='; then
missing_count=$((missing_count+1))
echo "---- Missing widget prop: $file:$line ----"
printf '%s\n' "$snippet"
echo "-------------------------------------------"
echo
fi
done <<< "$matches"
if [[ "$missing_count" -eq 0 ]]; then
echo "No CodeGen usages missing 'widget' prop found."
else
echo "Total occurrences missing 'widget' prop: $missing_count"
fiLength of output: 819
Add missing widget prop to CodeGen usages
Two CodeGen usages do not pass the widget prop — update them to include widget to avoid regressions after the prop rename:
-
apps/playground-web/src/app/wallets/sign-in/button/RightSection.tsx:227
Current: {previewTab === "code" && }
Change: add widget (e.g. ) -
apps/playground-web/src/app/bridge/swap-widget/components/right-section.tsx:67
Current: {previewTab === "code" && }
Change: add widget (e.g. )
Note: apps/playground-web/src/app/payments/components/RightSection.tsx:157 already passes widget.
🤖 Prompt for AI Agents
In apps/playground-web/src/app/payments/components/RightSection.tsx (lines
156-158), apps/playground-web/src/app/wallets/sign-in/button/RightSection.tsx
(line 227), and
apps/playground-web/src/app/bridge/swap-widget/components/right-section.tsx
(line 67), the CodeGen component usages must include the renamed widget prop;
update the two missing usages to pass the widget from the component's props
while keeping their existing props (e.g. add the widget prop sourced from
props.widget to the CodeGen calls that currently only pass connectOptions or
options).
| @@ -1,4 +1,10 @@ | |||
| import { lazy, Suspense } from "react"; | |||
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.
Add 'use client' — React.lazy requires a Client Component in Next.js app router.
This file uses React.lazy/Suspense; without 'use client' it will error at runtime/compile-time.
Apply this diff at the very top:
+ 'use client';
import { lazy, Suspense } from "react";📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import { lazy, Suspense } from "react"; | |
| 'use client'; | |
| import { lazy, Suspense } from "react"; |
🤖 Prompt for AI Agents
In apps/playground-web/src/app/wallets/sign-in/components/CodeGen.tsx around
line 1, this file uses React.lazy and Suspense which require a Next.js Client
Component; add the directive 'use client' as the very first line of the file
(above all imports) so the file is treated as a Client Component and avoids
runtime/compile errors.

PR-Codex overview
This PR primarily focuses on refactoring the handling of
widgetproperties across various components and introducing utility functions for code generation, enhancing readability and maintainability.Detailed summary
lockedWidgettowidgetin multiple components (CheckoutPlayground,TransactionPlayground,BuyPlayground,RightSection,LeftSection).code-gen.tsfor handling props and imports.CodeGencomponents to utilize the newwidgetprop.CodeGencomponents.Summary by CodeRabbit
New Features
Refactor
Style