Skip to content

Commit f916d7a

Browse files
authored
Fix TransactionButton loading state layout (#2897)
1 parent 7882b22 commit f916d7a

File tree

2 files changed

+54
-61
lines changed

2 files changed

+54
-61
lines changed

.changeset/brave-knives-hunt.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+
Fixes TransactionButton loading state layout shift

packages/thirdweb/src/react/web/ui/TransactionButton/index.tsx

Lines changed: 49 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -107,59 +107,42 @@ export function TransactionButton(props: TransactionButtonProps) {
107107

108108
const sendTransaction = useSendTransactionCore(undefined, gasless);
109109

110-
if (!isPending) {
111-
return (
112-
<Button
113-
gap="xs"
114-
disabled={!account || disabled}
115-
variant={"primary"}
116-
data-is-loading={isPending}
117-
onClick={async (e) => {
118-
if (onClick) {
119-
onClick(e);
120-
}
121-
try {
122-
setIsPending(true);
123-
const resolvedTx = await transaction();
124-
125-
if (wallet && wallet.getChain()?.id !== resolvedTx.chain.id) {
126-
await wallet?.switchChain(resolvedTx.chain);
127-
}
110+
return (
111+
<Button
112+
gap="xs"
113+
disabled={!account || disabled || isPending}
114+
variant={"primary"}
115+
data-is-loading={isPending}
116+
onClick={async (e) => {
117+
if (onClick) {
118+
onClick(e);
119+
}
120+
try {
121+
setIsPending(true);
122+
const resolvedTx = await transaction();
128123

129-
const result = await sendTransaction.mutateAsync(resolvedTx);
124+
if (wallet && wallet.getChain()?.id !== resolvedTx.chain.id) {
125+
await wallet?.switchChain(resolvedTx.chain);
126+
}
130127

131-
if (onTransactionSent) {
132-
onTransactionSent(result);
133-
}
128+
const result = await sendTransaction.mutateAsync(resolvedTx);
134129

135-
if (onTransactionConfirmed) {
136-
const receipt = await doWaitForReceipt(result);
137-
onTransactionConfirmed(receipt);
138-
}
139-
} catch (error) {
140-
if (onError) {
141-
onError(error as Error);
142-
}
143-
} finally {
144-
setIsPending(false);
130+
if (onTransactionSent) {
131+
onTransactionSent(result);
145132
}
146-
}}
147-
style={{
148-
opacity: !account || disabled ? 0.5 : 1,
149-
minWidth: "150px",
150-
...buttonProps.style,
151-
}}
152-
{...buttonProps}
153-
>
154-
{children}
155-
</Button>
156-
);
157-
}
158133

159-
return (
160-
<Button
161-
disabled={true}
162-
variant={"primary"}
134+
if (onTransactionConfirmed) {
135+
const receipt = await doWaitForReceipt(result);
136+
onTransactionConfirmed(receipt);
137+
}
138+
} catch (error) {
139+
if (onError) {
140+
onError(error as Error);
141+
}
142+
} finally {
143+
setIsPending(false);
144+
}
145+
}}
163146
style={{
164147
opacity: !account || disabled ? 0.5 : 1,
165148
minWidth: "150px",
@@ -168,19 +151,24 @@ export function TransactionButton(props: TransactionButtonProps) {
168151
}}
169152
{...buttonProps}
170153
>
171-
<div
172-
style={{
173-
position: "absolute",
174-
display: "flex",
175-
alignItems: "center",
176-
height: "100%",
177-
top: 0,
178-
bottom: 0,
179-
margin: "auto",
180-
}}
181-
>
182-
<Spinner size="md" color="primaryButtonText" />
183-
</div>
154+
<span style={{ visibility: isPending ? "hidden" : "visible" }}>
155+
{children}
156+
</span>
157+
{isPending && (
158+
<div
159+
style={{
160+
position: "absolute",
161+
display: "flex",
162+
alignItems: "center",
163+
height: "100%",
164+
top: 0,
165+
bottom: 0,
166+
margin: "auto",
167+
}}
168+
>
169+
<Spinner size="md" color="primaryButtonText" />
170+
</div>
171+
)}
184172
</Button>
185173
);
186174
}

0 commit comments

Comments
 (0)