Skip to content

Commit 2a78c45

Browse files
committed
ui improvements
1 parent b2d6429 commit 2a78c45

File tree

3 files changed

+263
-151
lines changed

3 files changed

+263
-151
lines changed

packages/thirdweb/src/react/web/ui/Bridge/swap-widget/common.tsx

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,28 @@ export function DecimalRenderer(props: {
88
integerSize: "md" | "sm";
99
fractionSize: "sm" | "xs";
1010
}) {
11+
if (Number(props.value) > 1000) {
12+
return (
13+
<Text size={props.integerSize} color={props.color} weight={props.weight}>
14+
{compactFormatter.format(Number(props.value))}
15+
</Text>
16+
);
17+
}
1118
const [integerPart, fractionPart] = props.value.split(".");
19+
1220
return (
1321
<div style={{ display: "flex", alignItems: "baseline" }}>
1422
<Text size={props.integerSize} color={props.color} weight={props.weight}>
15-
{integerPart}.
23+
{integerPart}
1624
</Text>
1725
<Text size={props.fractionSize} color={props.color} weight={props.weight}>
18-
{fractionPart || "00000"}
26+
.{fractionPart || "00"}
1927
</Text>
2028
</div>
2129
);
2230
}
31+
32+
const compactFormatter = new Intl.NumberFormat("en-US", {
33+
notation: "compact",
34+
maximumFractionDigits: 2,
35+
});

packages/thirdweb/src/react/web/ui/Bridge/swap-widget/select-token-ui.tsx

Lines changed: 89 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import {
1010
radius,
1111
spacing,
1212
} from "../../../../core/design-system/index.js";
13+
import { CoinsIcon } from "../../ConnectWallet/icons/CoinsIcon.js";
14+
import { WalletDotIcon } from "../../ConnectWallet/icons/WalletDotIcon.js";
1315
import { formatTokenAmount } from "../../ConnectWallet/screens/formatTokenBalance.js";
1416
import { Container, Line, ModalHeader } from "../../components/basic.js";
1517
import { Button } from "../../components/buttons.js";
@@ -98,7 +100,7 @@ export function SelectToken(props: SelectTokenUIProps) {
98100
{...props}
99101
ownedTokens={filteredOwnedTokens || []}
100102
allTokens={tokensQuery.data || []}
101-
isPending={isFetching}
103+
isFetching={isFetching}
102104
selectedChain={selectedChain}
103105
setSelectedChain={setSelectedChain}
104106
search={search}
@@ -120,7 +122,7 @@ export function SelectTokenUI(
120122
props: SelectTokenUIProps & {
121123
ownedTokens: TokenBalance[];
122124
allTokens: Token[];
123-
isPending: boolean;
125+
isFetching: boolean;
124126
selectedChain: BridgeChain | undefined;
125127
setSelectedChain: (chain: BridgeChain) => void;
126128
search: string;
@@ -134,21 +136,47 @@ export function SelectTokenUI(
134136
"select-token",
135137
);
136138

139+
// show tokens with icons first
140+
const sortedOwnedTokens = useMemo(() => {
141+
return props.ownedTokens.sort((a, b) => {
142+
if (a.icon_uri && !b.icon_uri) {
143+
return -1;
144+
}
145+
if (!a.icon_uri && b.icon_uri) {
146+
return 1;
147+
}
148+
return 0;
149+
});
150+
}, [props.ownedTokens]);
151+
137152
const otherTokens = useMemo(() => {
138153
const ownedTokenSet = new Set(
139-
props.ownedTokens.map((t) =>
154+
sortedOwnedTokens.map((t) =>
140155
`${t.token_address}-${t.chain_id}`.toLowerCase(),
141156
),
142157
);
143158
return props.allTokens.filter(
144159
(token) =>
145160
!ownedTokenSet.has(`${token.address}-${token.chainId}`.toLowerCase()),
146161
);
147-
}, [props.allTokens, props.ownedTokens]);
162+
}, [props.allTokens, sortedOwnedTokens]);
163+
164+
// show tokens with icons first
165+
const sortedOtherTokens = useMemo(() => {
166+
return otherTokens.sort((a, b) => {
167+
if (a.iconUri && !b.iconUri) {
168+
return -1;
169+
}
170+
if (!a.iconUri && b.iconUri) {
171+
return 1;
172+
}
173+
return 0;
174+
});
175+
}, [otherTokens]);
148176

149177
const noTokensFound =
150-
!props.isPending &&
151-
otherTokens.length === 0 &&
178+
!props.isFetching &&
179+
sortedOtherTokens.length === 0 &&
152180
props.ownedTokens.length === 0;
153181

154182
if (screen === "select-token") {
@@ -196,21 +224,43 @@ export function SelectTokenUI(
196224
<Container
197225
flex="column"
198226
style={{
199-
maxHeight: "400px",
200-
minHeight: "300px",
227+
height: "400px",
201228
overflowY: "auto",
202229
scrollbarWidth: "none",
203230
paddingBottom: spacing.md,
204231
}}
205232
>
206-
{props.isPending &&
233+
{props.isFetching &&
207234
new Array(20).fill(0).map(() => (
208235
// biome-ignore lint/correctness/useJsxKeyInIterable: ok
209236
<TokenButtonSkeleton />
210237
))}
211238

212-
{!props.isPending &&
213-
props.ownedTokens.map((token) => (
239+
{!props.isFetching && sortedOwnedTokens.length > 0 && (
240+
<Container
241+
px="xs"
242+
py="xs"
243+
flex="row"
244+
gap="xs"
245+
center="y"
246+
color="secondaryText"
247+
>
248+
<WalletDotIcon size={iconSize.sm} />
249+
<Text
250+
size="sm"
251+
color="secondaryText"
252+
weight={500}
253+
style={{
254+
overflow: "unset",
255+
}}
256+
>
257+
Your Tokens
258+
</Text>
259+
</Container>
260+
)}
261+
262+
{!props.isFetching &&
263+
sortedOwnedTokens.map((token) => (
214264
<TokenButton
215265
key={token.token_address}
216266
token={token}
@@ -223,8 +273,34 @@ export function SelectTokenUI(
223273
/>
224274
))}
225275

226-
{!props.isPending &&
227-
otherTokens.map((token) => (
276+
{!props.isFetching && sortedOwnedTokens.length > 0 && (
277+
<Container
278+
px="xs"
279+
py="xs"
280+
flex="row"
281+
gap="xs"
282+
center="y"
283+
color="secondaryText"
284+
style={{
285+
marginTop: spacing.sm,
286+
}}
287+
>
288+
<CoinsIcon size={iconSize.sm} />
289+
<Text
290+
size="sm"
291+
color="secondaryText"
292+
weight={500}
293+
style={{
294+
overflow: "unset",
295+
}}
296+
>
297+
Other Tokens
298+
</Text>
299+
</Container>
300+
)}
301+
302+
{!props.isFetching &&
303+
sortedOtherTokens.map((token) => (
228304
<TokenButton
229305
key={token.address}
230306
token={token}

0 commit comments

Comments
 (0)