@funkit/connect 9.28.1 → 10.1.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/dist/clients/chunk-42XZD2Y3.js +1112 -0
  3. package/dist/clients/chunk-5UIZBNLC.js +1175 -0
  4. package/dist/clients/chunk-6PIIYPQK.js +702 -0
  5. package/dist/clients/chunk-BO7AZVPG.js +1112 -0
  6. package/dist/clients/chunk-BUCJRBW7.js +1472 -0
  7. package/dist/clients/{chunk-2NBYHUIW.js → chunk-ETB2YYFT.js} +1 -1
  8. package/dist/clients/{chunk-4O4YAFYK.js → chunk-HD4Y4NKC.js} +4 -4
  9. package/dist/clients/{chunk-CGHPNWIF.js → chunk-JNZY3GAA.js} +3 -1
  10. package/dist/clients/{chunk-7LKK5QMZ.js → chunk-ME4OAQIY.js} +1 -1
  11. package/dist/clients/chunk-PEVDOGEA.js +109 -0
  12. package/dist/clients/chunk-QIWGVVAW.js +1113 -0
  13. package/dist/clients/chunk-VJZW3MA3.js +94 -0
  14. package/dist/clients/chunk-WEETVC7U.js +1113 -0
  15. package/dist/clients/chunk-Y2KXVS36.js +230 -0
  16. package/dist/clients/{chunk-TQVRP3Z2.js → chunk-YFHTV7DT.js} +1 -1
  17. package/dist/clients/fanatics.css +1 -1
  18. package/dist/clients/fanatics.js +2 -2
  19. package/dist/clients/lighter.css +11 -11
  20. package/dist/clients/lighter.d.ts +12 -2
  21. package/dist/clients/lighter.js +21 -9
  22. package/dist/clients/polymarket/PolymarketDepositAccountDropdown.css +11 -11
  23. package/dist/clients/polymarket/PolymarketDepositAccountDropdown.js +5 -5
  24. package/dist/clients/polymarket/createPolymarketDepositConfig.js +2 -2
  25. package/dist/clients/polymarket/index.css +11 -11
  26. package/dist/clients/polymarket/index.js +5 -5
  27. package/dist/clients/polymarket/polymarket.js +1 -1
  28. package/dist/clients/polymarket/usePolymarketAccountBalances.d.ts +66 -0
  29. package/dist/components/FunPayments/FunPaymentMethods.d.ts +3 -1
  30. package/dist/domains/paymentMethods.d.ts +8 -1
  31. package/dist/domains/relay.d.ts +40 -0
  32. package/dist/hooks/queries/useWithdrawFops.d.ts +1 -0
  33. package/dist/hooks/useNewTokenBanner.d.ts +6 -1
  34. package/dist/hooks/usePaymentSources.d.ts +1 -0
  35. package/dist/index.css +11 -11
  36. package/dist/index.d.ts +1 -1
  37. package/dist/index.js +1351 -2047
  38. package/dist/locales/i18n.d.ts +2 -1
  39. package/dist/modals/CheckoutModal/LightningInvoice/LightningInvoice.d.ts +3 -3
  40. package/dist/modals/CheckoutModal/LightningInvoice/LightningInvoiceQrCode.d.ts +3 -2
  41. package/dist/modals/CheckoutModal/SourceChange/FormOfPaymentsList.d.ts +17 -6
  42. package/dist/modals/CheckoutModal/SourceChange/SourceChange.d.ts +7 -2
  43. package/dist/modals/CheckoutModal/buildRelayChains.d.ts +12 -0
  44. package/dist/modals/CheckoutModal/stepTransition.d.ts +1 -1
  45. package/dist/modals/WithdrawalModal/LighterWithdrawal.d.ts +32 -5
  46. package/dist/modals/WithdrawalModal/useWithdrawal.d.ts +3 -3
  47. package/dist/providers/FunkitCheckoutContext/types.d.ts +20 -2
  48. package/dist/providers/FunkitConfigContext.d.ts +2 -0
  49. package/dist/utils/checkout.d.ts +2 -1
  50. package/dist/wallets/walletConnectors/bifrostWallet/bifrostWallet.js +2 -2
  51. package/dist/wallets/walletConnectors/bitgetWallet/bitgetWallet.js +2 -2
  52. package/dist/wallets/walletConnectors/bybitWallet/bybitWallet.js +2 -2
  53. package/dist/wallets/walletConnectors/chunk-4NV5BYRP.js +95 -0
  54. package/dist/wallets/walletConnectors/chunk-AVDUNQUW.js +96 -0
  55. package/dist/wallets/walletConnectors/chunk-GUQM4QSL.js +66 -0
  56. package/dist/wallets/walletConnectors/chunk-IULPZP2Q.js +69 -0
  57. package/dist/wallets/walletConnectors/chunk-JPN6TWIT.js +92 -0
  58. package/dist/wallets/walletConnectors/chunk-KCRO2AGO.js +106 -0
  59. package/dist/wallets/walletConnectors/chunk-KI5Y2BBF.js +94 -0
  60. package/dist/wallets/walletConnectors/chunk-NR2OGDHQ.js +103 -0
  61. package/dist/wallets/walletConnectors/chunk-OEEGYENV.js +87 -0
  62. package/dist/wallets/walletConnectors/chunk-OX37G4YT.js +98 -0
  63. package/dist/wallets/walletConnectors/chunk-SWFF3TWJ.js +100 -0
  64. package/dist/wallets/walletConnectors/chunk-TKB2OY6G.js +99 -0
  65. package/dist/wallets/walletConnectors/chunk-W2LCLDPX.js +70 -0
  66. package/dist/wallets/walletConnectors/chunk-WAHGI5L7.js +96 -0
  67. package/dist/wallets/walletConnectors/chunk-WKNQMP4A.js +93 -0
  68. package/dist/wallets/walletConnectors/chunk-XCNHV3HS.js +110 -0
  69. package/dist/wallets/walletConnectors/chunk-YO2K4MBH.js +218 -0
  70. package/dist/wallets/walletConnectors/chunk-YQFGVZGR.js +92 -0
  71. package/dist/wallets/walletConnectors/clvWallet/clvWallet.js +2 -2
  72. package/dist/wallets/walletConnectors/coin98Wallet/coin98Wallet.js +2 -2
  73. package/dist/wallets/walletConnectors/coreWallet/coreWallet.js +2 -2
  74. package/dist/wallets/walletConnectors/foxWallet/foxWallet.js +2 -2
  75. package/dist/wallets/walletConnectors/frontierWallet/frontierWallet.js +2 -2
  76. package/dist/wallets/walletConnectors/gateWallet/gateWallet.js +2 -2
  77. package/dist/wallets/walletConnectors/index.js +57 -57
  78. package/dist/wallets/walletConnectors/metaMaskWallet/metaMaskWallet.js +2 -2
  79. package/dist/wallets/walletConnectors/okxWallet/okxWallet.js +2 -2
  80. package/dist/wallets/walletConnectors/rainbowWallet/rainbowWallet.js +2 -2
  81. package/dist/wallets/walletConnectors/roninWallet/roninWallet.js +2 -2
  82. package/dist/wallets/walletConnectors/safepalWallet/safepalWallet.js +2 -2
  83. package/dist/wallets/walletConnectors/subWallet/subWallet.js +2 -2
  84. package/dist/wallets/walletConnectors/tokenPocketWallet/tokenPocketWallet.js +2 -2
  85. package/dist/wallets/walletConnectors/trustWallet/trustWallet.js +2 -2
  86. package/dist/wallets/walletConnectors/zerionWallet/zerionWallet.js +2 -2
  87. package/package.json +4 -6
  88. /package/dist/clients/{chunk-LUHEVXPD.js → chunk-HMP3LHMW.js} +0 -0
@@ -0,0 +1,1175 @@
1
+ "use client";
2
+ import {
3
+ FunInput,
4
+ FunSkeletonBlock,
5
+ TooltipAnchorRefContext
6
+ } from "./chunk-BUCJRBW7.js";
7
+ import {
8
+ Box,
9
+ Text,
10
+ themeVars
11
+ } from "./chunk-PEVDOGEA.js";
12
+ import {
13
+ useFunkitTranslation
14
+ } from "./chunk-STLOQEN7.js";
15
+ import {
16
+ POLYMARKET_PERPS_ROUTING_ID,
17
+ POLYMARKET_PREDICTIONS_ROUTING_ID
18
+ } from "./chunk-YFHTV7DT.js";
19
+ import {
20
+ POLYGON_USDCE,
21
+ PUSD_TOKEN
22
+ } from "./chunk-6PIIYPQK.js";
23
+ import {
24
+ logger
25
+ } from "./chunk-AHYOV7AV.js";
26
+
27
+ // src/clients/polymarket/PolymarketDepositAccountDropdown.tsx
28
+ import React12 from "react";
29
+ import { getAddress } from "viem";
30
+ import { polygon } from "viem/chains";
31
+
32
+ // src/components/Dropdown/AccountSelectDropdown.tsx
33
+ import React11, { useEffect as useEffect4 } from "react";
34
+
35
+ // src/components/Dropdown/BaseDropdown.tsx
36
+ import { isMobile } from "@funkit/utils";
37
+ import * as DropdownMenu2 from "@radix-ui/react-dropdown-menu";
38
+ import React10, { useCallback as useCallback2, useEffect as useEffect3, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
39
+
40
+ // src/hooks/useScrollDivider.ts
41
+ import { useCallback, useEffect, useState } from "react";
42
+ var useScrollDivider = () => {
43
+ const [refElement, setRefElement] = useState(null);
44
+ const ref = useCallback((node) => setRefElement(node), []);
45
+ const [isTop, setIsTop] = useState(true);
46
+ const [isAtBottom, setIsAtBottom] = useState(false);
47
+ const [isScrollable, setIsScrollable] = useState(false);
48
+ const [isScrolling, setIsScrolling] = useState(false);
49
+ useEffect(() => {
50
+ const content = refElement;
51
+ if (!content || !window.ResizeObserver) {
52
+ return;
53
+ }
54
+ const handleScrollPositionChange = () => {
55
+ const { scrollTop, scrollHeight, clientHeight } = content;
56
+ setIsTop(scrollTop === 0);
57
+ setIsAtBottom(scrollTop + clientHeight >= scrollHeight - 1);
58
+ setIsScrollable(scrollHeight > clientHeight + 2);
59
+ };
60
+ const handleContentChange = () => {
61
+ handleScrollPositionChange();
62
+ setTimeout(handleScrollPositionChange, 500);
63
+ };
64
+ const onScrollChange = () => {
65
+ handleScrollPositionChange();
66
+ setIsScrolling(true);
67
+ };
68
+ const onScrollEnd = () => setIsScrolling(false);
69
+ content.addEventListener("scrollend", onScrollEnd);
70
+ content.addEventListener("scroll", onScrollChange);
71
+ const resizeObserver = new window.ResizeObserver(handleContentChange);
72
+ resizeObserver.observe(content);
73
+ const mutationObserver = new MutationObserver(handleContentChange);
74
+ mutationObserver.observe(content, {
75
+ childList: true,
76
+ subtree: true,
77
+ attributes: true,
78
+ attributeFilter: ["style", "class"]
79
+ });
80
+ handleScrollPositionChange();
81
+ return () => {
82
+ content.removeEventListener("scroll", onScrollChange);
83
+ content.removeEventListener("scrollend", onScrollEnd);
84
+ resizeObserver.unobserve(content);
85
+ mutationObserver.disconnect();
86
+ };
87
+ }, [refElement]);
88
+ return {
89
+ ref,
90
+ hasTopDivider: !isTop,
91
+ hasBottomDivider: isScrollable,
92
+ isAtBottom,
93
+ isScrolling,
94
+ isScrollable
95
+ };
96
+ };
97
+
98
+ // src/providers/FunkitProvider.tsx
99
+ import { LogLevel, initializeRelayClient } from "@funkit/fun-relay";
100
+ import { QueryClientProvider } from "@tanstack/react-query";
101
+ import React8, {
102
+ createContext,
103
+ useContext,
104
+ useEffect as useEffect2,
105
+ useMemo,
106
+ useRef
107
+ } from "react";
108
+
109
+ // src/utils/tokenMath.ts
110
+ import { formatCurrencyAndStringify } from "@funkit/utils";
111
+ import * as dnum from "dnum";
112
+ import { formatUnits } from "viem";
113
+ function floorToDecimals(value, decimals) {
114
+ const d = dnum.from(value, decimals);
115
+ return dnum.toNumber(d, decimals);
116
+ }
117
+ function formatUsdFlooredToCent(balanceUsd) {
118
+ return formatCurrencyAndStringify(floorToDecimals(balanceUsd, 2));
119
+ }
120
+
121
+ // src/components/Icons/CheckIcon.tsx
122
+ import React from "react";
123
+ var CheckIcon = ({
124
+ size = 16,
125
+ className
126
+ }) => /* @__PURE__ */ React.createElement(
127
+ "svg",
128
+ {
129
+ width: size,
130
+ height: size,
131
+ viewBox: "0 0 16 16",
132
+ fill: "none",
133
+ xmlns: "http://www.w3.org/2000/svg",
134
+ className
135
+ },
136
+ /* @__PURE__ */ React.createElement(
137
+ "path",
138
+ {
139
+ d: "M12.4919 4.88281L6.25757 11.1172L3.50781 8",
140
+ stroke: "currentColor",
141
+ strokeWidth: "1.5",
142
+ strokeLinecap: "round",
143
+ strokeLinejoin: "round",
144
+ pathLength: "100"
145
+ }
146
+ )
147
+ );
148
+
149
+ // src/components/Dropdown/BaseDropdownItem.tsx
150
+ import { noop } from "@funkit/utils";
151
+ import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
152
+ import React2 from "react";
153
+ import clsx from "clsx";
154
+
155
+ // src/components/Dropdown/BaseDropdownItem.css.ts
156
+ var disabledDropdownItemStyles = "BaseDropdownItem_disabledDropdownItemStyles__18hhw3k3 BaseDropdownItem__18hhw3k2";
157
+ var enabledDropdownItemStyles = "BaseDropdownItem_enabledDropdownItemStyles__18hhw3k1 BaseDropdownItem__18hhw3k0";
158
+
159
+ // src/components/Dropdown/BaseDropdownItem.tsx
160
+ function BaseDropdownItem({
161
+ iconComponent,
162
+ label,
163
+ description,
164
+ id,
165
+ onClick = noop,
166
+ isSelected = false,
167
+ isDisabled = false,
168
+ borderRadius = "connectButton",
169
+ horizontalIconGap = "dropdownItemIconGap",
170
+ tagComponent,
171
+ horizontalPadding = "dropdownItemPaddingX",
172
+ verticalPadding = "dropdownItemPaddingY"
173
+ }) {
174
+ return /* @__PURE__ */ React2.createElement(
175
+ DropdownMenu.Item,
176
+ {
177
+ disabled: isDisabled,
178
+ onSelect: () => onClick(id),
179
+ asChild: true
180
+ },
181
+ /* @__PURE__ */ React2.createElement(
182
+ Box,
183
+ {
184
+ width: "full",
185
+ display: "flex",
186
+ alignItems: "center",
187
+ justifyContent: "space-between",
188
+ gap: "24",
189
+ paddingY: verticalPadding,
190
+ paddingX: horizontalPadding,
191
+ className: clsx(
192
+ isDisabled ? disabledDropdownItemStyles : enabledDropdownItemStyles
193
+ ),
194
+ boxShadow: isSelected ? "selectedDropdownItem" : void 0,
195
+ borderRadius
196
+ },
197
+ /* @__PURE__ */ React2.createElement(
198
+ Box,
199
+ {
200
+ display: "flex",
201
+ alignItems: "center",
202
+ justifyContent: "flex-start",
203
+ gap: horizontalIconGap
204
+ },
205
+ iconComponent && /* @__PURE__ */ React2.createElement(Box, { display: "flex", alignItems: "center", justifyContent: "center" }, iconComponent),
206
+ /* @__PURE__ */ React2.createElement(Box, { display: "flex", flexDirection: "column", justifyContent: "center" }, /* @__PURE__ */ React2.createElement(
207
+ Text,
208
+ {
209
+ size: "dropdownItemFontSize",
210
+ weight: "medium",
211
+ color: isSelected ? "selectedDropdownItemText" : void 0
212
+ },
213
+ label
214
+ ), description != null && /* @__PURE__ */ React2.createElement(Text, { size: "12", color: "secondaryText" }, description))
215
+ ),
216
+ /* @__PURE__ */ React2.createElement(
217
+ Box,
218
+ {
219
+ display: "flex",
220
+ alignItems: "center",
221
+ justifyContent: "center",
222
+ gap: "16"
223
+ },
224
+ tagComponent,
225
+ /* @__PURE__ */ React2.createElement(
226
+ Box,
227
+ {
228
+ width: "16",
229
+ height: "16",
230
+ alignItems: "center",
231
+ justifyContent: "center",
232
+ color: isSelected ? "selectedDropdownItemText" : "transparent"
233
+ },
234
+ /* @__PURE__ */ React2.createElement(CheckIcon, null)
235
+ )
236
+ )
237
+ )
238
+ );
239
+ }
240
+ var BaseDropdownItem_default = BaseDropdownItem;
241
+
242
+ // src/components/Icons/CaretDownIcon.tsx
243
+ import clsx2 from "clsx";
244
+ import React3 from "react";
245
+
246
+ // src/components/Icons/CaretDownIcon.css.ts
247
+ var caretClosed = "CaretDownIcon_caretClosed__1gjdf1i3";
248
+ var caretOpened = "CaretDownIcon_caretOpened__1gjdf1i2";
249
+
250
+ // src/components/Icons/CaretDownIcon.tsx
251
+ var CaretDownIcon = () => {
252
+ return /* @__PURE__ */ React3.createElement(
253
+ "svg",
254
+ {
255
+ width: "8",
256
+ height: "5",
257
+ viewBox: "0 0 8 5",
258
+ fill: "none",
259
+ xmlns: "http://www.w3.org/2000/svg"
260
+ },
261
+ /* @__PURE__ */ React3.createElement(
262
+ "path",
263
+ {
264
+ d: "M3.45163 2.92973L0.879121 0.393174C0.654314 0.188182 0.317464 0.217886 0.126753 0.459527C-0.0639587 0.701168 -0.036324 1.06324 0.188483 1.26824L3.60944 4.64138C3.65478 4.68988 3.70789 4.72919 3.76623 4.7574C3.83874 4.79249 3.91764 4.80968 3.99714 4.80771C4.07647 4.80576 4.15489 4.78486 4.22578 4.74655C4.23264 4.74283 4.23943 4.73894 4.24614 4.7349C4.28505 4.71152 4.32107 4.68295 4.35332 4.64987L7.82907 1.18704C8.04528 0.97163 8.0581 0.608604 7.8577 0.376205C7.6573 0.143806 7.31956 0.130027 7.10335 0.345432L4.51922 2.91996C4.51922 2.94623 4 3.43025 4 3.43025L3.45163 2.92973Z",
265
+ fill: "currentColor"
266
+ }
267
+ )
268
+ );
269
+ };
270
+ var AnimatedCaretDownIcon = ({
271
+ expanded,
272
+ color = "primaryText",
273
+ compact = false
274
+ }) => {
275
+ const animationClassName = clsx2(
276
+ expanded !== void 0 && (expanded ? caretOpened : caretClosed)
277
+ );
278
+ if (compact) {
279
+ return /* @__PURE__ */ React3.createElement(
280
+ Box,
281
+ {
282
+ color,
283
+ width: "8",
284
+ height: "8",
285
+ display: "flex",
286
+ alignItems: "center",
287
+ justifyContent: "center",
288
+ className: animationClassName
289
+ },
290
+ /* @__PURE__ */ React3.createElement(CaretDownIcon, null)
291
+ );
292
+ }
293
+ return /* @__PURE__ */ React3.createElement(
294
+ Box,
295
+ {
296
+ color,
297
+ width: "16",
298
+ height: "16",
299
+ display: "flex",
300
+ alignItems: "center",
301
+ justifyContent: "center",
302
+ className: animationClassName
303
+ },
304
+ /* @__PURE__ */ React3.createElement(
305
+ Box,
306
+ {
307
+ width: "8",
308
+ height: "8",
309
+ display: "flex",
310
+ alignItems: "center",
311
+ justifyContent: "center"
312
+ },
313
+ /* @__PURE__ */ React3.createElement(CaretDownIcon, null)
314
+ )
315
+ );
316
+ };
317
+
318
+ // src/hooks/usePolymarketAccountBalances.ts
319
+ import {
320
+ skipToken,
321
+ useQuery,
322
+ useQueryClient
323
+ } from "@tanstack/react-query";
324
+ import * as dnum2 from "dnum";
325
+ var DEFAULT_BALANCE_REFETCH_MS = 1e3;
326
+ var polymarketAccountBalanceQueryKey = (address) => ["polymarket", "accountBalanceUsd", address ?? null];
327
+ var polymarketBalanceSettleUntilQueryKey = (address) => ["polymarket", "accountBalanceSettleUntil", address];
328
+ async function fetchAccountBalance(queryClient, getBalanceUsd, queryKey) {
329
+ const [, , address] = queryKey;
330
+ if (address === null) {
331
+ throw new Error("polymarket balance query ran without an address");
332
+ }
333
+ try {
334
+ const serverUsd = await getBalanceUsd();
335
+ const settleUntil = queryClient.getQueryData(
336
+ polymarketBalanceSettleUntilQueryKey(address)
337
+ );
338
+ const displayedUsd = queryClient.getQueryData(
339
+ polymarketAccountBalanceQueryKey(address)
340
+ );
341
+ if (settleUntil !== void 0 && Date.now() < settleUntil && displayedUsd !== void 0) {
342
+ return displayedUsd;
343
+ }
344
+ return serverUsd;
345
+ } catch (error) {
346
+ logger.warn("polymarket:accountBalance:fetchFailed", {
347
+ address,
348
+ error: String(error)
349
+ });
350
+ throw error;
351
+ }
352
+ }
353
+ function useAccountBalance(account, refetchIntervalMs) {
354
+ const queryClient = useQueryClient();
355
+ const getBalanceUsd = account?.getBalanceUsd;
356
+ const address = account?.address;
357
+ const query = useQuery({
358
+ queryKey: polymarketAccountBalanceQueryKey(address),
359
+ // `skipToken` disables the query when the account isn't configured (the
360
+ // perps-transfer config is optional). It is *not* a fallback for a missing
361
+ // balance — the getter is the single source of truth.
362
+ queryFn: getBalanceUsd && address ? ({ queryKey }) => fetchAccountBalance(queryClient, getBalanceUsd, queryKey) : skipToken,
363
+ refetchInterval: refetchIntervalMs,
364
+ // The poll interval is the freshness contract: a reader mounting within it
365
+ // (e.g. navigating between the deposit picker and the transfer step) reads
366
+ // the cached balance as-is instead of kicking off an extra mount fetch —
367
+ // that's what makes the navigation flash-free *and* fetch-free.
368
+ staleTime: refetchIntervalMs
369
+ });
370
+ return { balanceUsd: query.data };
371
+ }
372
+ function usePolymarketAccountBalances(accounts, options) {
373
+ const refetchIntervalMs = options?.refetchIntervalMs ?? DEFAULT_BALANCE_REFETCH_MS;
374
+ return {
375
+ predictions: useAccountBalance(accounts.predictions, refetchIntervalMs),
376
+ perps: useAccountBalance(accounts.perps, refetchIntervalMs)
377
+ };
378
+ }
379
+
380
+ // src/components/FunNoResults/FunNoResults.tsx
381
+ import React6 from "react";
382
+
383
+ // src/components/Icons/CoinsIcon.tsx
384
+ import React4 from "react";
385
+ var CoinsIcon = ({
386
+ size = 48,
387
+ bgColor = "#141C41",
388
+ iconColor = "#878A98"
389
+ }) => {
390
+ return /* @__PURE__ */ React4.createElement(
391
+ "svg",
392
+ {
393
+ width: size,
394
+ height: size,
395
+ viewBox: "0 0 48 49",
396
+ fill: "none",
397
+ xmlns: "http://www.w3.org/2000/svg"
398
+ },
399
+ /* @__PURE__ */ React4.createElement("g", { clipPath: "url(#clip0_30657_22302)" }, /* @__PURE__ */ React4.createElement(
400
+ "path",
401
+ {
402
+ d: "M24 1C36.9787 1 47.5 11.5213 47.5 24.5C47.5 37.4787 36.9787 48 24 48C11.0213 48 0.5 37.4787 0.5 24.5C0.5 11.5213 11.0213 1 24 1Z",
403
+ fill: bgColor,
404
+ stroke: bgColor
405
+ }
406
+ ), /* @__PURE__ */ React4.createElement("g", { clipPath: "url(#clip1_30657_22302)" }, /* @__PURE__ */ React4.createElement(
407
+ "path",
408
+ {
409
+ d: "M25 17C25 18.1046 22.5376 19 19.5 19C16.4624 19 14 18.1046 14 17M25 17C25 15.8954 22.5376 15 19.5 15C16.4624 15 14 15.8954 14 17M25 17V18.5M14 17V29C14 30.1046 16.4624 31 19.5 31M19.5 23C19.3315 23 19.1647 22.9972 19 22.9918C16.1967 22.9 14 22.0433 14 21M19.5 27C16.4624 27 14 26.1046 14 25M34 23.5C34 24.6046 31.5376 25.5 28.5 25.5C25.4624 25.5 23 24.6046 23 23.5M34 23.5C34 22.3954 31.5376 21.5 28.5 21.5C25.4624 21.5 23 22.3954 23 23.5M34 23.5V31C34 32.1046 31.5376 33 28.5 33C25.4624 33 23 32.1046 23 31V23.5M34 27.25C34 28.3546 31.5376 29.25 28.5 29.25C25.4624 29.25 23 28.3546 23 27.25",
410
+ stroke: iconColor,
411
+ strokeWidth: "1.5",
412
+ strokeLinecap: "round",
413
+ strokeLinejoin: "round"
414
+ }
415
+ ))),
416
+ /* @__PURE__ */ React4.createElement("defs", null, /* @__PURE__ */ React4.createElement("clipPath", { id: "clip0_30657_22302" }, /* @__PURE__ */ React4.createElement(
417
+ "rect",
418
+ {
419
+ width: "48",
420
+ height: "48",
421
+ fill: "white",
422
+ transform: "translate(0 0.5)"
423
+ }
424
+ )), /* @__PURE__ */ React4.createElement("clipPath", { id: "clip1_30657_22302" }, /* @__PURE__ */ React4.createElement(
425
+ "rect",
426
+ {
427
+ width: "24",
428
+ height: "24",
429
+ fill: "white",
430
+ transform: "translate(12 12)"
431
+ }
432
+ )))
433
+ );
434
+ };
435
+
436
+ // src/components/Icons/SearchSkeletonIcon.tsx
437
+ import React5 from "react";
438
+ var SearchSkeletonIcon = () => {
439
+ return /* @__PURE__ */ React5.createElement(
440
+ "svg",
441
+ {
442
+ width: "122",
443
+ height: "81",
444
+ viewBox: "0 0 122 81",
445
+ fill: "none",
446
+ xmlns: "http://www.w3.org/2000/svg"
447
+ },
448
+ /* @__PURE__ */ React5.createElement("g", { clipPath: "url(#clip0_7590_15835)" }, /* @__PURE__ */ React5.createElement(
449
+ "path",
450
+ {
451
+ fillRule: "evenodd",
452
+ clipRule: "evenodd",
453
+ d: "M99.5636 34.0159C92.9099 34.0159 87.5159 39.4099 87.5159 46.0636C87.5159 52.7174 92.9099 58.1114 99.5636 58.1114C106.217 58.1114 111.611 52.7174 111.611 46.0636C111.611 39.4099 106.217 34.0159 99.5636 34.0159ZM83.5 46.0636C83.5 37.1919 90.6919 30 99.5636 30C108.435 30 115.627 37.1919 115.627 46.0636C115.627 49.7758 114.368 53.1938 112.254 55.9139L120.912 64.5722C121.696 65.3564 121.696 66.6277 120.912 67.4119C120.128 68.196 118.856 68.196 118.072 67.4119L109.414 58.7536C106.694 60.8681 103.276 62.1273 99.5636 62.1273C90.6919 62.1273 83.5 54.9353 83.5 46.0636Z",
454
+ fill: "currentColor"
455
+ }
456
+ ), /* @__PURE__ */ React5.createElement(
457
+ "path",
458
+ {
459
+ d: "M117.5 8H4.5C2.29086 8 0.5 9.79086 0.5 12V20C0.5 22.2091 2.29086 24 4.5 24H117.5C119.709 24 121.5 22.2091 121.5 20V12C121.5 9.79086 119.709 8 117.5 8Z",
460
+ fill: "currentColor"
461
+ }
462
+ ), /* @__PURE__ */ React5.createElement(
463
+ "path",
464
+ {
465
+ d: "M71.5 30H4.5C2.29086 30 0.5 31.7909 0.5 34V42C0.5 44.2091 2.29086 46 4.5 46H71.5C73.7091 46 75.5 44.2091 75.5 42V34C75.5 31.7909 73.7091 30 71.5 30Z",
466
+ fill: "currentColor"
467
+ }
468
+ ), /* @__PURE__ */ React5.createElement(
469
+ "path",
470
+ {
471
+ d: "M71.5 52H4.5C2.29086 52 0.5 53.7909 0.5 56V64C0.5 66.2091 2.29086 68 4.5 68H71.5C73.7091 68 75.5 66.2091 75.5 64V56C75.5 53.7909 73.7091 52 71.5 52Z",
472
+ fill: "currentColor"
473
+ }
474
+ )),
475
+ /* @__PURE__ */ React5.createElement("defs", null, /* @__PURE__ */ React5.createElement("clipPath", { id: "clip0_7590_15835" }, /* @__PURE__ */ React5.createElement(
476
+ "rect",
477
+ {
478
+ width: "121",
479
+ height: "81",
480
+ fill: "white",
481
+ transform: "translate(0.5)"
482
+ }
483
+ )))
484
+ );
485
+ };
486
+
487
+ // src/components/FunNoResults/FunNoResults.tsx
488
+ var FunNoResults = ({
489
+ text,
490
+ title,
491
+ variant = "default",
492
+ actionButton
493
+ }) => {
494
+ return /* @__PURE__ */ React6.createElement(
495
+ Box,
496
+ {
497
+ display: "flex",
498
+ flexDirection: "column",
499
+ justifyContent: "center",
500
+ alignItems: "center",
501
+ gap: variant === "default" ? "12" : "16",
502
+ color: "secondaryText",
503
+ style: { flex: 1 }
504
+ },
505
+ variant === "default" && /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(SearchSkeletonIcon, null), /* @__PURE__ */ React6.createElement(Text, { color: "secondaryText", size: "10" }, text)),
506
+ variant === "actionable" && /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(
507
+ CoinsIcon,
508
+ {
509
+ bgColor: themeVars.colors.offBackground,
510
+ iconColor: themeVars.colors.actionColor
511
+ }
512
+ ), /* @__PURE__ */ React6.createElement(
513
+ Box,
514
+ {
515
+ display: "flex",
516
+ flexDirection: "column",
517
+ alignItems: "center",
518
+ gap: "12"
519
+ },
520
+ /* @__PURE__ */ React6.createElement(
521
+ Box,
522
+ {
523
+ display: "flex",
524
+ flexDirection: "column",
525
+ alignItems: "center",
526
+ textAlign: "center",
527
+ gap: "8"
528
+ },
529
+ title && /* @__PURE__ */ React6.createElement(Text, { size: "14", color: "primaryText" }, title),
530
+ /* @__PURE__ */ React6.createElement(Text, { color: "secondaryText", size: "12" }, text)
531
+ ),
532
+ actionButton && /* @__PURE__ */ React6.createElement(Box, null, actionButton)
533
+ ))
534
+ );
535
+ };
536
+
537
+ // src/components/Icons/SwitchIcon.tsx
538
+ import React7 from "react";
539
+ var SwitchIcon = () => {
540
+ return /* @__PURE__ */ React7.createElement(
541
+ "svg",
542
+ {
543
+ width: "15",
544
+ height: "14",
545
+ viewBox: "0 0 15 14",
546
+ fill: "none",
547
+ xmlns: "http://www.w3.org/2000/svg"
548
+ },
549
+ /* @__PURE__ */ React7.createElement(
550
+ "path",
551
+ {
552
+ fillRule: "evenodd",
553
+ clipRule: "evenodd",
554
+ d: "M0.96967 4.86358C0.676777 4.57069 0.676777 4.09582 0.96967 3.80292L3.63634 1.13626C3.92923 0.843363 4.4041 0.843363 4.697 1.13626L7.36366 3.80292C7.65656 4.09582 7.65656 4.57069 7.36366 4.86358C7.07077 5.15648 6.5959 5.15648 6.303 4.86358L4.91667 3.47725L4.91667 12.3333C4.91667 12.7475 4.58088 13.0833 4.16667 13.0833C3.75245 13.0833 3.41667 12.7475 3.41667 12.3333L3.41667 3.47725L2.03033 4.86358C1.73744 5.15648 1.26256 5.15648 0.96967 4.86358ZM7.63634 9.13626C7.92923 8.84336 8.4041 8.84336 8.697 9.13626L10.0833 10.5226V1.66659C10.0833 1.25237 10.4191 0.916586 10.8333 0.916586C11.2475 0.916586 11.5833 1.25237 11.5833 1.66659V10.5226L12.9697 9.13626C13.2626 8.84336 13.7374 8.84336 14.0303 9.13626C14.3232 9.42915 14.3232 9.90402 14.0303 10.1969L11.3637 12.8636C11.0708 13.1565 10.5959 13.1565 10.303 12.8636L7.63634 10.1969C7.34344 9.90402 7.34344 9.42915 7.63634 9.13626Z",
555
+ fill: "currentColor"
556
+ }
557
+ )
558
+ );
559
+ };
560
+
561
+ // src/providers/FunkitProvider.tsx
562
+ var ThemeIdContext = createContext(void 0);
563
+ var attr = "data-rk";
564
+ var createThemeRootProps = (id) => ({ [attr]: id || "" });
565
+ var useThemeRootProps = () => {
566
+ const id = useContext(ThemeIdContext);
567
+ return createThemeRootProps(id);
568
+ };
569
+
570
+ // src/components/Dropdown/BaseActiveDropdownItem.tsx
571
+ import React9 from "react";
572
+
573
+ // src/components/Dropdown/BaseActiveDropdownItem.css.ts
574
+ var baseStyles = "BaseActiveDropdownItem_baseStyles__1dewiqw0";
575
+
576
+ // src/components/Dropdown/BaseDropdown.css.ts
577
+ var BORDER_RADIUS = "dropdown";
578
+ var baseDropdownItemWrapperStyles = "BaseDropdown_baseDropdownItemWrapperStyles__1nns6ys3 sprinkles_borderRadius_dropdownItem__1rsrm2f17";
579
+ var scrollGradientWrapperStyles = "BaseDropdown_scrollGradientWrapperStyles__1nns6ys1";
580
+ var scrollableDropdownStyles = "BaseDropdown_scrollableDropdownStyles__1nns6ys0";
581
+
582
+ // src/components/Dropdown/BaseActiveDropdownItem.tsx
583
+ function BaseActiveDropdownItem({
584
+ iconComponent,
585
+ label,
586
+ isOpened,
587
+ onClick,
588
+ horizontalIconGap = "dropdownItemIconGap",
589
+ alwaysVisibleLabel,
590
+ tagComponent,
591
+ tagPosition = "start",
592
+ size = "regular",
593
+ color = "primaryText",
594
+ arrowColor = "secondaryText",
595
+ background,
596
+ labelStyle,
597
+ compactIcon = false
598
+ }) {
599
+ return /* @__PURE__ */ React9.createElement(
600
+ Box,
601
+ {
602
+ display: "flex",
603
+ alignItems: "center",
604
+ justifyContent: "space-between",
605
+ gap: "6",
606
+ cursor: "pointer",
607
+ onClick,
608
+ background: background ?? {
609
+ base: "dropdownActiveItemBackgroundBase",
610
+ hover: "dropdownActiveItemBackgroundHover"
611
+ },
612
+ borderColor: {
613
+ base: "dropdownActiveItemBorderBase",
614
+ hover: "dropdownActiveItemBorderHover"
615
+ },
616
+ borderWidth: size === "compact" ? "0" : "1",
617
+ borderRadius: BORDER_RADIUS,
618
+ borderStyle: "solid",
619
+ paddingY: size === "compact" ? "2" : size === "large" ? "10" : "dropdownActiveItemRegularSizePaddingY",
620
+ paddingX: size === "compact" ? "4" : size === "large" ? "8" : "dropdownPaddingX",
621
+ className: baseStyles
622
+ },
623
+ /* @__PURE__ */ React9.createElement(
624
+ Box,
625
+ {
626
+ display: "flex",
627
+ alignItems: "center",
628
+ justifyContent: "space-between",
629
+ gap: horizontalIconGap,
630
+ style: size === "compact" ? void 0 : { flex: "1 0 auto" }
631
+ },
632
+ alwaysVisibleLabel && /* @__PURE__ */ React9.createElement(Box, { style: { flex: 1 } }, /* @__PURE__ */ React9.createElement(Text, { color: "secondaryText", size: "12" }, alwaysVisibleLabel)),
633
+ /* @__PURE__ */ React9.createElement(
634
+ Box,
635
+ {
636
+ display: "flex",
637
+ alignItems: "center",
638
+ justifyContent: "space-between",
639
+ gap: horizontalIconGap,
640
+ background: {
641
+ base: "transparent",
642
+ hover: "alwaysVisibleLabelBackgroundHover"
643
+ },
644
+ ...alwaysVisibleLabel ? {} : { style: { flex: 1 } }
645
+ },
646
+ /* @__PURE__ */ React9.createElement(
647
+ Box,
648
+ {
649
+ display: "flex",
650
+ alignItems: "center",
651
+ justifyContent: "center",
652
+ gap: horizontalIconGap,
653
+ ...alwaysVisibleLabel ? { style: { flexDirection: "row-reverse" } } : {}
654
+ },
655
+ tagPosition === "start" && tagComponent,
656
+ /* @__PURE__ */ React9.createElement(Box, { display: "flex", alignItems: "center", gap: horizontalIconGap }, iconComponent && /* @__PURE__ */ React9.createElement(Box, { display: "flex", alignItems: "center", justifyContent: "center" }, iconComponent), /* @__PURE__ */ React9.createElement(
657
+ Text,
658
+ {
659
+ color,
660
+ size: "dropdownItemFontSize",
661
+ weight: "medium",
662
+ style: labelStyle
663
+ },
664
+ label
665
+ ))
666
+ ),
667
+ /* @__PURE__ */ React9.createElement(Box, { display: "flex", alignItems: "center", gap: "5" }, tagPosition === "end" && tagComponent, /* @__PURE__ */ React9.createElement(
668
+ AnimatedCaretDownIcon,
669
+ {
670
+ expanded: isOpened,
671
+ color: arrowColor,
672
+ compact: compactIcon
673
+ }
674
+ ))
675
+ )
676
+ )
677
+ );
678
+ }
679
+ var BaseActiveDropdownItem_default = BaseActiveDropdownItem;
680
+
681
+ // src/components/Dropdown/BaseDropdown.utils.ts
682
+ var NO_SELECTION_VALUE = "";
683
+ var ADDITIONAL_GROUP_KEY = "__additional__";
684
+ function buildAllOptions(options, allowUnselect, unselectLabel) {
685
+ if (allowUnselect) {
686
+ return [
687
+ {
688
+ label: unselectLabel ?? "",
689
+ value: NO_SELECTION_VALUE
690
+ },
691
+ ...options
692
+ ];
693
+ }
694
+ return options;
695
+ }
696
+ function filterOptions(allOptions, searchInput) {
697
+ const search = searchInput?.trim().toLowerCase() ?? "";
698
+ return allOptions.filter(
699
+ (option) => option.label.toLowerCase().includes(search)
700
+ );
701
+ }
702
+ function organizeDropdownGroups(filteredOptions, groups, additionalGroup, additionalGroupLabel) {
703
+ const organizedGroups = [];
704
+ if (!groups) {
705
+ organizedGroups.push({
706
+ key: ADDITIONAL_GROUP_KEY,
707
+ label: void 0,
708
+ options: filteredOptions
709
+ });
710
+ return {
711
+ organizedGroups,
712
+ organizedOptions: filteredOptions
713
+ };
714
+ }
715
+ const unselectOption = filteredOptions.find(
716
+ (option) => option.value === NO_SELECTION_VALUE
717
+ );
718
+ if (unselectOption) {
719
+ organizedGroups.push({
720
+ key: NO_SELECTION_VALUE,
721
+ label: void 0,
722
+ options: [unselectOption]
723
+ });
724
+ }
725
+ const optionsByValue = new Map(
726
+ filteredOptions.filter((option) => option.value !== NO_SELECTION_VALUE).map((option) => [option.value, option])
727
+ );
728
+ const inflatedGroups = groups.map((group) => ({
729
+ ...group,
730
+ // Only take the options that actually exist
731
+ // Note that this preserves the ordering of `group.values`
732
+ options: group.values.map((value) => optionsByValue.get(value)).filter((option) => !!option)
733
+ })).filter((group) => group.options.length > 0);
734
+ const hasNonEmptyGroup = inflatedGroups.length > 0;
735
+ for (const group of inflatedGroups) {
736
+ organizedGroups.push({
737
+ key: group.key,
738
+ label: group.label,
739
+ options: group.options
740
+ });
741
+ if (additionalGroup === "others") {
742
+ for (const option of group.options) {
743
+ optionsByValue.delete(option.value);
744
+ }
745
+ }
746
+ }
747
+ if (optionsByValue.size > 0) {
748
+ organizedGroups.push({
749
+ key: ADDITIONAL_GROUP_KEY,
750
+ // Only show additional group label if there actually are other groups
751
+ label: hasNonEmptyGroup ? additionalGroupLabel : void 0,
752
+ options: [...optionsByValue.values()]
753
+ });
754
+ }
755
+ const organizedOptions = organizedGroups.flatMap((group) => group.options);
756
+ return { organizedGroups, organizedOptions };
757
+ }
758
+
759
+ // src/components/Dropdown/BaseDropdown.tsx
760
+ var HORIZONTAL_ICON_GAP = "4";
761
+ var activeDropdownItemSize = {
762
+ compact: "18",
763
+ regular: "36",
764
+ large: "40"
765
+ };
766
+ function BaseDropdown({
767
+ activeItemProps,
768
+ value,
769
+ options,
770
+ groups,
771
+ additionalGroup = "others",
772
+ additionalGroupLabel,
773
+ allowUnselect = false,
774
+ unselectLabel,
775
+ onOptionSelected,
776
+ onOpen,
777
+ renderDropdownOption,
778
+ searchableOptions = false,
779
+ searchPlaceholder,
780
+ placeholder,
781
+ resetSearchOnClose = true,
782
+ openToTopOnMobile = true,
783
+ alwaysOpenToTop = false,
784
+ openDropdownFullWidth = true,
785
+ isLoading = false,
786
+ preloadIconUrls,
787
+ horizontalIconGap = HORIZONTAL_ICON_GAP,
788
+ openDropdownBackgroundColor = "openDropdownBackgroundColor",
789
+ size = "regular",
790
+ label,
791
+ maxDropdownHeight,
792
+ dropdownWidth,
793
+ dropdownAlign = "end",
794
+ testId
795
+ }) {
796
+ const { t } = useFunkitTranslation();
797
+ const themeRootProps = useThemeRootProps();
798
+ const isMobileDevice = isMobile();
799
+ const [isOpened, setIsOpened] = useState2(false);
800
+ const [searchInput, setSearchInput] = useState2("");
801
+ const { ref: scrollRef, hasTopDivider, isAtBottom } = useScrollDivider();
802
+ const allOptions = useMemo2(
803
+ () => buildAllOptions(options, allowUnselect, unselectLabel),
804
+ [options, allowUnselect, unselectLabel]
805
+ );
806
+ const selectedOption = allOptions.find((option) => option.value === value);
807
+ const prevIsOpenedRef = useRef2(false);
808
+ const portalThemeRef = useRef2(null);
809
+ const handleSearch = (event) => {
810
+ setSearchInput(event.target.value);
811
+ };
812
+ const filteredOptions = useMemo2(
813
+ () => filterOptions(allOptions, searchInput),
814
+ [allOptions, searchInput]
815
+ );
816
+ const { organizedGroups, organizedOptions } = useMemo2(
817
+ () => organizeDropdownGroups(
818
+ filteredOptions,
819
+ groups,
820
+ additionalGroup,
821
+ additionalGroupLabel
822
+ ),
823
+ [additionalGroup, additionalGroupLabel, filteredOptions, groups]
824
+ );
825
+ const handleOpenChange = useCallback2(
826
+ (open) => {
827
+ setIsOpened(open);
828
+ if (open) {
829
+ onOpen?.();
830
+ } else {
831
+ resetSearchOnClose && setSearchInput("");
832
+ }
833
+ },
834
+ [onOpen, resetSearchOnClose]
835
+ );
836
+ useEffect3(() => {
837
+ if (isOpened && !prevIsOpenedRef.current) {
838
+ prevIsOpenedRef.current = true;
839
+ if (selectedOption) {
840
+ const selectedOptionIndex = organizedOptions.findIndex(
841
+ (option) => option.value === selectedOption.value
842
+ );
843
+ if (selectedOptionIndex !== -1) {
844
+ requestAnimationFrame(() => {
845
+ const selectedOptionElement = document.getElementById(
846
+ `${selectedOption.value}-dropdown-item`
847
+ );
848
+ selectedOptionElement?.scrollIntoView({
849
+ behavior: "instant",
850
+ block: "center"
851
+ });
852
+ });
853
+ }
854
+ }
855
+ } else if (!isOpened) {
856
+ prevIsOpenedRef.current = false;
857
+ }
858
+ }, [isOpened, selectedOption, organizedOptions]);
859
+ const dropdownSide = alwaysOpenToTop || openToTopOnMobile && isMobileDevice ? "top" : "bottom";
860
+ return /* @__PURE__ */ React10.createElement(Box, { display: "flex", flexDirection: "column", gap: "4", testId }, label && /* @__PURE__ */ React10.createElement(Text, { size: "12", color: "secondaryText" }, label), /* @__PURE__ */ React10.createElement(
861
+ DropdownMenu2.Root,
862
+ {
863
+ open: isOpened,
864
+ onOpenChange: handleOpenChange,
865
+ modal: false
866
+ },
867
+ /* @__PURE__ */ React10.createElement(
868
+ Box,
869
+ {
870
+ position: "relative",
871
+ display: size === "compact" ? "flex" : void 0
872
+ },
873
+ isLoading ? /* @__PURE__ */ React10.createElement(FunSkeletonBlock, { height: activeDropdownItemSize[size] }) : /* @__PURE__ */ React10.createElement(DropdownMenu2.Trigger, { asChild: true }, /* @__PURE__ */ React10.createElement("div", null, /* @__PURE__ */ React10.createElement(
874
+ BaseActiveDropdownItem_default,
875
+ {
876
+ color: !selectedOption && !activeItemProps?.label && !!placeholder ? "secondaryText" : "primaryText",
877
+ ...activeItemProps,
878
+ size,
879
+ horizontalIconGap,
880
+ isOpened,
881
+ label: activeItemProps?.label ?? selectedOption?.label ?? placeholder ?? ""
882
+ }
883
+ ))),
884
+ /* @__PURE__ */ React10.createElement(DropdownMenu2.Portal, null, /* @__PURE__ */ React10.createElement(
885
+ DropdownMenu2.Content,
886
+ {
887
+ ...themeRootProps,
888
+ ref: portalThemeRef,
889
+ side: dropdownSide,
890
+ sideOffset: dropdownSide === "top" ? 8 : 6,
891
+ align: dropdownAlign,
892
+ className: "funkit-dropdown-content",
893
+ style: {
894
+ zIndex: `calc(${themeVars.modalZIndex} + 1)`,
895
+ width: dropdownWidth ? `${dropdownWidth}px` : openDropdownFullWidth ? "var(--radix-dropdown-menu-trigger-width)" : void 0,
896
+ transformOrigin: "var(--radix-dropdown-menu-content-transform-origin)"
897
+ },
898
+ onCloseAutoFocus: (e) => e.preventDefault()
899
+ },
900
+ /* @__PURE__ */ React10.createElement(TooltipAnchorRefContext.Provider, { value: portalThemeRef }, /* @__PURE__ */ React10.createElement(
901
+ Box,
902
+ {
903
+ background: openDropdownBackgroundColor,
904
+ borderColor: "transparent",
905
+ borderWidth: "1",
906
+ borderRadius: "dropdownList",
907
+ borderStyle: "solid",
908
+ boxShadow: "dropdown",
909
+ className: maxDropdownHeight ? scrollGradientWrapperStyles : void 0,
910
+ "data-fade-top": maxDropdownHeight && hasTopDivider ? "true" : "false",
911
+ "data-fade-bottom": maxDropdownHeight && !isAtBottom ? "true" : "false"
912
+ },
913
+ /* @__PURE__ */ React10.createElement(
914
+ Box,
915
+ {
916
+ className: maxDropdownHeight ? scrollableDropdownStyles : void 0,
917
+ ref: maxDropdownHeight ? scrollRef : void 0,
918
+ style: { maxHeight: maxDropdownHeight }
919
+ },
920
+ /* @__PURE__ */ React10.createElement(Box, { display: "flex", flexDirection: "column" }, searchableOptions && /* @__PURE__ */ React10.createElement(Box, { paddingTop: "8", paddingX: "8" }, /* @__PURE__ */ React10.createElement(
921
+ FunInput,
922
+ {
923
+ placeholder: searchPlaceholder ?? t("common.searchTokens"),
924
+ value: searchInput,
925
+ onChange: handleSearch,
926
+ prefixIcon: "SearchIcon"
927
+ }
928
+ )), organizedOptions.length === 0 ? /* @__PURE__ */ React10.createElement(FunNoResults, { text: t("common.noResultsFound") }) : /* @__PURE__ */ React10.createElement(
929
+ Box,
930
+ {
931
+ as: "ul",
932
+ display: "flex",
933
+ flexDirection: "column",
934
+ paddingY: size === "compact" ? "dropdownCompactPaddingY" : "dropdownPaddingY"
935
+ },
936
+ organizedGroups.map(
937
+ ({
938
+ key: groupKey,
939
+ label: groupLabel,
940
+ options: optionsInGroup
941
+ }, groupIndex) => /* @__PURE__ */ React10.createElement(React10.Fragment, { key: groupKey }, groupIndex > 0 && /* @__PURE__ */ React10.createElement(
942
+ Box,
943
+ {
944
+ height: "1",
945
+ background: "lightStroke",
946
+ marginY: "dropdownGroupDividerMarginY"
947
+ }
948
+ ), groupLabel && /* @__PURE__ */ React10.createElement(
949
+ Box,
950
+ {
951
+ paddingX: size === "compact" ? "dropdownCompactPaddingX" : "dropdownPaddingX"
952
+ },
953
+ /* @__PURE__ */ React10.createElement(
954
+ Box,
955
+ {
956
+ paddingX: "dropdownItemPaddingX",
957
+ paddingY: "dropdownItemPaddingY"
958
+ },
959
+ /* @__PURE__ */ React10.createElement(
960
+ Text,
961
+ {
962
+ color: "dropdownGroupHeader",
963
+ font: "dropdownGroupHeader",
964
+ size: "dropdownGroupHeader",
965
+ weight: "dropdownGroupHeader"
966
+ },
967
+ groupLabel
968
+ )
969
+ )
970
+ ), optionsInGroup.map((singleOption) => {
971
+ const isSelected = singleOption.value === selectedOption?.value;
972
+ return /* @__PURE__ */ React10.createElement(
973
+ Box,
974
+ {
975
+ key: singleOption.value,
976
+ paddingX: size === "compact" ? "dropdownCompactPaddingX" : "dropdownPaddingX"
977
+ },
978
+ /* @__PURE__ */ React10.createElement(
979
+ Box,
980
+ {
981
+ id: `${singleOption.value}-dropdown-item`,
982
+ as: "li",
983
+ background: {
984
+ base: isSelected ? "selectedDropdownItemBackground" : "transparent",
985
+ hover: "offBackground"
986
+ },
987
+ className: baseDropdownItemWrapperStyles,
988
+ onClick: () => {
989
+ onOptionSelected?.(singleOption);
990
+ }
991
+ },
992
+ renderDropdownOption(
993
+ singleOption,
994
+ isSelected
995
+ )
996
+ )
997
+ );
998
+ }))
999
+ )
1000
+ ))
1001
+ )
1002
+ ))
1003
+ )),
1004
+ preloadIconUrls && /* @__PURE__ */ React10.createElement(
1005
+ Box,
1006
+ {
1007
+ display: "none",
1008
+ "aria-hidden": true,
1009
+ style: { position: "absolute", top: "-100%", left: "-100%" }
1010
+ },
1011
+ preloadIconUrls.map((url, index) => /* @__PURE__ */ React10.createElement("img", { key: `${url}-${index}`, src: url, alt: "" }))
1012
+ )
1013
+ )
1014
+ ));
1015
+ }
1016
+ var BaseDropdown_default = BaseDropdown;
1017
+
1018
+ // src/components/Dropdown/AccountSelectDropdown.tsx
1019
+ var ACCOUNTS_GROUP = "accounts";
1020
+ var ACTION_GROUP = "action";
1021
+ function AccountSelectDropdown({
1022
+ accounts,
1023
+ selectedValue,
1024
+ onSelect,
1025
+ action,
1026
+ prefixLabel,
1027
+ label,
1028
+ size,
1029
+ dropdownWidth,
1030
+ testId
1031
+ }) {
1032
+ const actionIdCollidesWithAccount = !!action && accounts.some((account) => account.value === action.id);
1033
+ const actionId = action?.id;
1034
+ useEffect4(() => {
1035
+ if (actionIdCollidesWithAccount) {
1036
+ logger.warn("accountSelectDropdown:actionIdCollidesWithAccountValue", {
1037
+ actionId
1038
+ });
1039
+ }
1040
+ }, [actionIdCollidesWithAccount, actionId]);
1041
+ const options = [
1042
+ ...accounts.map((account) => ({
1043
+ value: account.value,
1044
+ label: account.label
1045
+ })),
1046
+ ...action ? [{ value: action.id, label: action.label }] : []
1047
+ ];
1048
+ const groups = action ? [
1049
+ {
1050
+ key: ACCOUNTS_GROUP,
1051
+ label: "",
1052
+ values: accounts.map((account) => account.value)
1053
+ },
1054
+ { key: ACTION_GROUP, label: "", values: [action.id] }
1055
+ ] : void 0;
1056
+ return /* @__PURE__ */ React11.createElement(
1057
+ BaseDropdown_default,
1058
+ {
1059
+ testId,
1060
+ label,
1061
+ size,
1062
+ dropdownWidth,
1063
+ value: selectedValue,
1064
+ options,
1065
+ groups,
1066
+ activeItemProps: { alwaysVisibleLabel: prefixLabel },
1067
+ renderDropdownOption: (option, isSelected) => {
1068
+ if (action && option.value === action.id) {
1069
+ return /* @__PURE__ */ React11.createElement(
1070
+ BaseDropdownItem_default,
1071
+ {
1072
+ id: option.value,
1073
+ label: option.label,
1074
+ iconComponent: action.icon && // Render the icon in the theme's primary text colour
1075
+ // (the icon uses `currentColor`), matching the label.
1076
+ /* @__PURE__ */ React11.createElement(Box, { display: "flex", color: "primaryText" }, action.icon),
1077
+ horizontalIconGap: "8",
1078
+ onClick: action.onSelect
1079
+ }
1080
+ );
1081
+ }
1082
+ const account = accounts.find((item) => item.value === option.value);
1083
+ return /* @__PURE__ */ React11.createElement(
1084
+ BaseDropdownItem_default,
1085
+ {
1086
+ id: option.value,
1087
+ label: option.label,
1088
+ description: account?.description,
1089
+ isSelected,
1090
+ onClick: onSelect
1091
+ }
1092
+ );
1093
+ }
1094
+ }
1095
+ );
1096
+ }
1097
+
1098
+ // src/clients/polymarket/PolymarketDepositAccountDropdown.tsx
1099
+ var ACCOUNT_DROPDOWN_OPTIONS_WIDTH = 264;
1100
+ var BALANCE_PLACEHOLDER = "\u2014";
1101
+ function formatBalance(balanceUsd) {
1102
+ return balanceUsd === void 0 ? BALANCE_PLACEHOLDER : formatUsdFlooredToCent(balanceUsd);
1103
+ }
1104
+ function PolymarketDepositAccountDropdown({
1105
+ onStepChange,
1106
+ modalState,
1107
+ dynamicRoutingId,
1108
+ applyDynamicTargetAssetCandidate,
1109
+ predictions,
1110
+ perps
1111
+ }) {
1112
+ const { t } = useFunkitTranslation();
1113
+ const balances = usePolymarketAccountBalances({ predictions, perps });
1114
+ const selectedRoutingId = dynamicRoutingId === POLYMARKET_PERPS_ROUTING_ID ? POLYMARKET_PERPS_ROUTING_ID : POLYMARKET_PREDICTIONS_ROUTING_ID;
1115
+ const accountCandidate = (routingId, recipient) => ({
1116
+ tokenAddress: POLYGON_USDCE,
1117
+ tokenChainId: polygon.id.toString(),
1118
+ tokenSymbol: PUSD_TOKEN.symbol,
1119
+ iconSrc: PUSD_TOKEN.iconSrc,
1120
+ dynamicRoutingId: routingId,
1121
+ customRecipient: recipient
1122
+ });
1123
+ const handleSelectAccount = (routingId) => {
1124
+ const isPerps = routingId === POLYMARKET_PERPS_ROUTING_ID;
1125
+ applyDynamicTargetAssetCandidate?.(
1126
+ accountCandidate(
1127
+ isPerps ? POLYMARKET_PERPS_ROUTING_ID : POLYMARKET_PREDICTIONS_ROUTING_ID,
1128
+ // Checksum so the recipient agrees with createPolymarketDepositConfig's
1129
+ // initial customRecipient (integrator addresses aren't guaranteed EIP-55).
1130
+ isPerps ? getAddress(perps.address) : getAddress(predictions.address)
1131
+ )
1132
+ );
1133
+ };
1134
+ return /* @__PURE__ */ React12.createElement(
1135
+ AccountSelectDropdown,
1136
+ {
1137
+ prefixLabel: t("perpsTransfer.depositTo"),
1138
+ dropdownWidth: ACCOUNT_DROPDOWN_OPTIONS_WIDTH,
1139
+ accounts: [
1140
+ {
1141
+ value: POLYMARKET_PREDICTIONS_ROUTING_ID,
1142
+ label: t("perpsTransfer.predictions"),
1143
+ description: formatBalance(balances.predictions.balanceUsd)
1144
+ },
1145
+ {
1146
+ value: POLYMARKET_PERPS_ROUTING_ID,
1147
+ label: t("perpsTransfer.perps"),
1148
+ description: formatBalance(balances.perps.balanceUsd)
1149
+ }
1150
+ ],
1151
+ selectedValue: selectedRoutingId,
1152
+ onSelect: handleSelectAccount,
1153
+ action: {
1154
+ id: "transfer-between-accounts",
1155
+ label: t("perpsTransfer.transferBetweenAccounts"),
1156
+ icon: /* @__PURE__ */ React12.createElement(SwitchIcon, null),
1157
+ // Navigation is absent on the loading skeleton; the action only fires
1158
+ // on the interactive screen. The transfer step reads balances from the
1159
+ // same shared cache, so none need to be threaded through here.
1160
+ onSelect: () => {
1161
+ if (onStepChange && modalState) {
1162
+ onStepChange({
1163
+ ...modalState,
1164
+ step: "perps_transfer" /* PERPS_TRANSFER */
1165
+ });
1166
+ }
1167
+ }
1168
+ }
1169
+ }
1170
+ );
1171
+ }
1172
+
1173
+ export {
1174
+ PolymarketDepositAccountDropdown
1175
+ };