Skip to content

Commit 01004e8

Browse files
committed
[MNY-353] SDK: TransactionWidget UI improvements (#8607)
<!-- ## 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 focuses on UI improvements for the `TransactionWidget` in the `thirdweb` package, enhancing user experience with better layout, spacing, and loading indicators. ### Detailed summary - Changed the `chain` in `simpleBuyRequest` from `baseSepolia` to `base`. - Updated the story names and added new stories for `TransactionWidget`. - Improved layout and spacing in `TransactionPayment`. - Replaced static loading elements with `Skeleton` components for better loading states. - Enhanced button styles and added a loading spinner. - Refined contract info and address display for better clarity. > ✨ 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 * **UI Improvements** * Improved TransactionWidget loading states with clearer visual spinner components * Enhanced visual presentation and layout of transaction details, addresses, and network information * Refined typography, spacing, and styling throughout the widget for better readability and consistency <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent f497b61 commit 01004e8

File tree

4 files changed

+135
-149
lines changed

4 files changed

+135
-149
lines changed

.changeset/easy-teams-agree.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"thirdweb": patch
3+
---
4+
5+
TransactionWidget UI improvements

packages/thirdweb/src/react/web/ui/Bridge/TransactionPayment.tsx

Lines changed: 113 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { getWalletBalance } from "../../../../wallets/utils/getWalletBalance.js"
1616
import { useCustomTheme } from "../../../core/design-system/CustomThemeProvider.js";
1717
import {
1818
fontSize,
19+
radius,
1920
spacing,
2021
type Theme,
2122
} from "../../../core/design-system/index.js";
@@ -29,7 +30,9 @@ import { formatCurrencyAmount } from "../ConnectWallet/screens/formatTokenBalanc
2930
import { Container, Line } from "../components/basic.js";
3031
import { Button } from "../components/buttons.js";
3132
import { ChainName } from "../components/ChainName.js";
33+
import { Skeleton } from "../components/Skeleton.js";
3234
import { Spacer } from "../components/Spacer.js";
35+
import { Spinner } from "../components/Spinner.js";
3336
import { Text } from "../components/text.js";
3437
import type { PayEmbedConnectOptions } from "../PayEmbed.js";
3538
import { ChainIcon } from "./common/TokenAndChain.js";
@@ -161,36 +164,34 @@ export function TransactionPayment({
161164

162165
<Spacer y="md" />
163166

164-
<Line />
167+
<Line dashed />
165168

166-
<Spacer y="md" />
169+
<Spacer y="lg" />
167170

168171
{/* Loading Rows */}
169-
<SkeletonRow theme={theme} width="60%" />
170-
<Spacer y="xs" />
171-
<SkeletonRow theme={theme} width="40%" />
172-
<Spacer y="xs" />
173-
<SkeletonRow theme={theme} width="50%" />
174-
<Spacer y="xs" />
175-
<SkeletonRow theme={theme} width="45%" />
176-
<Spacer y="xs" />
177-
<SkeletonRow theme={theme} width="55%" />
172+
<Container flex="column" gap="sm">
173+
<SkeletonRow valueWidth="110px" labelWidth="60px" />
174+
<SkeletonRow valueWidth="40%" labelWidth="90px" />
175+
<SkeletonRow valueWidth="50%" labelWidth="60px" />
176+
<SkeletonRow valueWidth="45%" labelWidth="90px" />
177+
</Container>
178178

179-
<Spacer y="md" />
179+
<Spacer y="lg" />
180180

181-
<Line />
181+
<Line dashed />
182182

183183
<Spacer y="lg" />
184184

185185
{/* Loading Button */}
186-
<div
187-
style={{
188-
backgroundColor: theme.colors.skeletonBg,
189-
borderRadius: spacing.md,
190-
height: "48px",
191-
width: "100%",
192-
}}
193-
/>
186+
<Button
187+
fullWidth
188+
variant="primary"
189+
gap="xs"
190+
disabled
191+
style={{ borderRadius: radius.full, fontSize: fontSize.md }}
192+
>
193+
<Spinner size="sm" /> Loading
194+
</Button>
194195

195196
{showThirdwebBranding ? (
196197
<div>
@@ -227,7 +228,7 @@ export function TransactionPayment({
227228
{/* Function Name */}
228229
<Text
229230
color="secondaryText"
230-
size="md"
231+
size="sm"
231232
style={{
232233
backgroundColor: theme.colors.tertiaryBg,
233234
borderRadius: spacing.sm,
@@ -242,15 +243,15 @@ export function TransactionPayment({
242243

243244
<Spacer y="md" />
244245

245-
<Line />
246+
<Line dashed />
246247

247-
<Spacer y="md" />
248+
<Spacer y="lg" />
248249

249-
{/* Contract Info */}
250-
{contractName !== "UnknownContract" &&
251-
contractName !== undefined &&
252-
contractName !== "Unknown Contract" && (
253-
<>
250+
<Container flex="column" gap="sm">
251+
{/* Contract Info */}
252+
{contractName !== "UnknownContract" &&
253+
contractName !== undefined &&
254+
contractName !== "Unknown Contract" && (
254255
<Container
255256
flex="row"
256257
style={{
@@ -265,70 +266,62 @@ export function TransactionPayment({
265266
{contractName}
266267
</Text>
267268
</Container>
269+
)}
268270

269-
<Spacer y="xs" />
270-
</>
271-
)}
272-
273-
{/* Address */}
274-
<Container
275-
flex="row"
276-
style={{
277-
alignItems: "center",
278-
justifyContent: "space-between",
279-
}}
280-
>
281-
<Text color="secondaryText" size="sm">
282-
Address
283-
</Text>
284-
<a
285-
href={`https://thirdweb.com/${transaction.chain.id}/${transaction.to}`}
286-
rel="noopener noreferrer"
271+
{/* Address */}
272+
<Container
273+
flex="row"
287274
style={{
288-
color: theme.colors.accentText,
289-
fontFamily: "monospace",
290-
fontSize: fontSize.sm,
291-
textDecoration: "none",
275+
alignItems: "center",
276+
justifyContent: "space-between",
292277
}}
293-
target="_blank"
294278
>
295-
{shortenAddress(transaction.to as string)}
296-
</a>
297-
</Container>
298-
299-
<Spacer y="xs" />
300-
301-
{/* Network */}
302-
<Container
303-
flex="row"
304-
style={{
305-
alignItems: "center",
306-
justifyContent: "space-between",
307-
}}
308-
>
309-
<Text color="secondaryText" size="sm">
310-
Network
311-
</Text>
312-
<Container center="y" flex="row" gap="3xs">
313-
<ChainIcon chain={transaction.chain} client={client} size="xs" />
314-
<ChainName
315-
chain={transaction.chain}
316-
client={client}
317-
color="primaryText"
318-
short
319-
size="sm"
279+
<Text color="secondaryText" size="sm">
280+
Address
281+
</Text>
282+
<a
283+
href={`https://thirdweb.com/${transaction.chain.id}/${transaction.to}`}
284+
rel="noopener noreferrer"
320285
style={{
286+
color: theme.colors.accentText,
321287
fontFamily: "monospace",
288+
fontSize: fontSize.sm,
289+
textDecoration: "none",
322290
}}
323-
/>
291+
target="_blank"
292+
>
293+
{shortenAddress(transaction.to as string)}
294+
</a>
324295
</Container>
325-
</Container>
326296

327-
<Spacer y="xs" />
297+
{/* Network */}
298+
<Container
299+
flex="row"
300+
style={{
301+
alignItems: "center",
302+
justifyContent: "space-between",
303+
}}
304+
>
305+
<Text color="secondaryText" size="sm">
306+
Network
307+
</Text>
308+
<Container center="y" flex="row" gap="3xs">
309+
<ChainIcon chain={transaction.chain} client={client} size="xs" />
310+
<ChainName
311+
chain={transaction.chain}
312+
client={client}
313+
color="primaryText"
314+
short
315+
size="sm"
316+
style={{
317+
fontFamily: "monospace",
318+
}}
319+
/>
320+
</Container>
321+
</Container>
328322

329-
{/* Cost */}
330-
{transactionDataQuery.data?.txCostDisplay && (
331-
<>
323+
{/* Cost */}
324+
{transactionDataQuery.data?.txCostDisplay && (
332325
<Container
333326
flex="row"
334327
style={{
@@ -344,19 +337,19 @@ export function TransactionPayment({
344337
size="sm"
345338
style={{
346339
fontFamily: "monospace",
340+
overflow: "hidden",
341+
textOverflow: "ellipsis",
342+
whiteSpace: "nowrap",
343+
maxWidth: "60%",
347344
}}
348345
>
349346
{transactionDataQuery.data?.txCostDisplay}
350347
</Text>
351348
</Container>
349+
)}
352350

353-
<Spacer y="xs" />
354-
</>
355-
)}
356-
357-
{/* Network Fees */}
358-
{transactionDataQuery.data?.gasCostDisplay && (
359-
<>
351+
{/* Network Fees */}
352+
{transactionDataQuery.data?.gasCostDisplay && (
360353
<Container
361354
flex="row"
362355
style={{
@@ -377,12 +370,12 @@ export function TransactionPayment({
377370
{transactionDataQuery.data?.gasCostDisplay}
378371
</Text>
379372
</Container>
373+
)}
374+
</Container>
380375

381-
<Spacer y="md" />
382-
</>
383-
)}
376+
<Spacer y="lg" />
384377

385-
<Line />
378+
<Line dashed />
386379

387380
<Spacer y="lg" />
388381

@@ -432,7 +425,7 @@ export function TransactionPayment({
432425
}}
433426
style={{
434427
fontSize: fontSize.md,
435-
padding: `${spacing.sm} ${spacing.md}`,
428+
borderRadius: radius.full,
436429
}}
437430
variant="primary"
438431
>
@@ -443,6 +436,9 @@ export function TransactionPayment({
443436
client={client}
444437
connectButton={{
445438
label: buttonLabel,
439+
style: {
440+
borderRadius: radius.full,
441+
},
446442
}}
447443
theme={theme}
448444
{...connectOptions}
@@ -467,67 +463,39 @@ export function TransactionPayment({
467463
);
468464
}
469465

470-
const SkeletonHeader = (props: { theme: Theme }) => (
466+
const SkeletonHeader = (_props: { theme: Theme }) => (
471467
<Container
472468
center="y"
473469
flex="row"
474-
gap="3xs"
470+
gap="sm"
475471
style={{
476472
justifyContent: "space-between",
477473
}}
478474
>
479-
{/* USD Value Skeleton */}
480-
<div
481-
style={{
482-
backgroundColor: props.theme.colors.skeletonBg,
483-
borderRadius: spacing.xs,
484-
height: "32px",
485-
width: "80px",
486-
}}
475+
<Skeleton
476+
height="32px"
477+
width="60px"
478+
style={{ borderRadius: radius.full }}
487479
/>
488-
489-
{/* Function Name Skeleton */}
490-
<div
491-
style={{
492-
backgroundColor: props.theme.colors.skeletonBg,
493-
borderRadius: spacing.sm,
494-
height: "24px",
495-
width: "120px",
496-
}}
480+
<Skeleton
481+
height="32px"
482+
width="180px"
483+
style={{ borderRadius: radius.full }}
497484
/>
498485
</Container>
499486
);
500487

501-
// Skeleton component for loading state
502-
const SkeletonRow = ({
503-
width = "100%",
504-
theme,
505-
}: {
506-
width?: string;
507-
theme: Theme;
508-
}) => (
509-
<Container
510-
flex="row"
511-
style={{
512-
alignItems: "center",
513-
justifyContent: "space-between",
514-
}}
515-
>
516-
<div
517-
style={{
518-
backgroundColor: theme.colors.skeletonBg,
519-
borderRadius: spacing.xs,
520-
height: "16px",
521-
width: "30%",
522-
}}
523-
/>
524-
<div
488+
function SkeletonRow(props: { labelWidth?: string; valueWidth?: string }) {
489+
return (
490+
<Container
491+
flex="row"
525492
style={{
526-
backgroundColor: theme.colors.skeletonBg,
527-
borderRadius: spacing.xs,
528-
height: "16px",
529-
width,
493+
alignItems: "center",
494+
justifyContent: "space-between",
530495
}}
531-
/>
532-
</Container>
533-
);
496+
>
497+
<Skeleton height="16px" width={props.labelWidth} />
498+
<Skeleton height="16px" width={props.valueWidth} />
499+
</Container>
500+
);
501+
}

0 commit comments

Comments
 (0)