@orderly.network/ui-scaffold 2.11.2 → 2.12.0-alpha.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.
package/dist/index.mjs CHANGED
@@ -1,16 +1,16 @@
1
- import React6, { forwardRef, createContext, useCallback, useRef, useEffect, useMemo, useState, cloneElement, useContext, isValidElement } from 'react';
1
+ import React7, { forwardRef, createContext, useCallback, useRef, useEffect, useMemo, useState, cloneElement, useContext, isValidElement } from 'react';
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
3
  import { installExtension, ExtensionPositionEnum, tv, Flex, Text, Tooltip, useScreen, Button, cn, modal, toast, DropdownMenuRoot, DropdownMenuTrigger, DropdownMenuPortal, DropdownMenuContent, DropdownMenuGroup, EVMAvatar, Divider, DropdownMenuItem, ChevronDownIcon, Box, PopoverRoot, PopoverAnchor, PopoverContent, SimpleDialog, Checkbox, useObserverElement, SimpleSheet, Logo, VectorIcon, PeopleIcon, SwapHorizIcon, Sheet, SheetContent, ChevronLeftIcon, Dialog, DialogContent, DialogHeader, DialogTitle, DialogBody, Spinner, ChainIcon, ScrollArea, formatAddress, Popover, Grid, CopyIcon, TextField, inputFormatter, ExtensionSlot, EyeIcon, EyeCloseIcon, SimpleDialogFooter, TooltipProvider, TooltipRoot, TooltipTrigger, BellIcon, TooltipContent, PopoverTrigger, PopupUnionIcon, CloseRoundFillIcon, SpotIcon, PerpsIcon, SelectedChoicesFillIcon } from '@orderly.network/ui';
4
4
  import { useTranslation, i18n, useLocaleContext, Trans } from '@orderly.network/i18n';
5
- import { useWalletConnector, useAccount, useChains, useLocalStorage, useConfig, useTrack, useIndexPricesStream, WsNetworkStatus, useSubAccountQuery, useWsStatus, OrderlyContext, useMemoizedFn, useCollateral, usePositionStream, useMarginRatio, useLeverage, useMaintenanceStatus, useEventEmitter } from '@orderly.network/hooks';
5
+ import { useWalletConnector, useAccount, useChains, useLocalStorage, useConfig, useTrack, WsNetworkStatus, useIndexPricesStream, useWsStatus, useSubAccountQuery, OrderlyContext, useMemoizedFn, useCollateral, usePositionStream, useMarginRatio, useLeverage, useMaintenanceStatus, useEventEmitter } from '@orderly.network/hooks';
6
6
  import { useAppContext, useAppConfig } from '@orderly.network/react-app';
7
7
  import { AccountStatusEnum, ABSTRACT_CHAIN_ID_MAP, EMPTY_LIST, TrackerEventName, EMPTY_OBJECT } from '@orderly.network/types';
8
8
  import { ChainSelectorSheetId, ChainSelectorDialogId, ChainSelectorWidget } from '@orderly.network/ui-chain-selector';
9
9
  import { WalletConnectorSheetId, WalletConnectorModalId } from '@orderly.network/ui-connector';
10
+ import { useAnnouncement, NotificationUI as NotificationUI$1, AnnouncementCenterUI } from '@orderly.network/ui-notification';
10
11
  import { Decimal, getTimestamp, windowGuard } from '@orderly.network/utils';
11
12
  import jsQR from 'jsqr';
12
13
  import { qrcode } from '@akamfoad/qr';
13
- import { useAnnouncement, NotificationUI as NotificationUI$1, AnnouncementCenterUI } from '@orderly.network/ui-notification';
14
14
  import { format } from 'date-fns';
15
15
  import { UTCDateMini } from '@date-fns/utc';
16
16
 
@@ -26,7 +26,7 @@ var __export = (target, all) => {
26
26
  var CommuntiyTelegramIcon, CommuntiyDiscordIcon, CommuntiyXIcon;
27
27
  var init_communtiyIcons = __esm({
28
28
  "src/components/icons/communtiyIcons.tsx"() {
29
- CommuntiyTelegramIcon = React6.forwardRef((props, ref) => {
29
+ CommuntiyTelegramIcon = React7.forwardRef((props, ref) => {
30
30
  const { size = 20, ...rest } = props;
31
31
  return /* @__PURE__ */ jsx(
32
32
  "svg",
@@ -49,7 +49,7 @@ var init_communtiyIcons = __esm({
49
49
  }
50
50
  );
51
51
  });
52
- CommuntiyDiscordIcon = React6.forwardRef((props, ref) => {
52
+ CommuntiyDiscordIcon = React7.forwardRef((props, ref) => {
53
53
  const { size = 20, ...rest } = props;
54
54
  return /* @__PURE__ */ jsx(
55
55
  "svg",
@@ -72,7 +72,7 @@ var init_communtiyIcons = __esm({
72
72
  }
73
73
  );
74
74
  });
75
- CommuntiyXIcon = React6.forwardRef(
75
+ CommuntiyXIcon = React7.forwardRef(
76
76
  (props, ref) => {
77
77
  const { size = 20, ...rest } = props;
78
78
  return /* @__PURE__ */ jsx(
@@ -105,7 +105,7 @@ var init_communtiyIcons = __esm({
105
105
  var OrderlyTextIcon;
106
106
  var init_orderlyNetworkTextIcon = __esm({
107
107
  "src/components/icons/orderlyNetworkTextIcon.tsx"() {
108
- OrderlyTextIcon = React6.forwardRef(
108
+ OrderlyTextIcon = React7.forwardRef(
109
109
  (props, ref) => {
110
110
  return /* @__PURE__ */ jsxs(
111
111
  "svg",
@@ -145,7 +145,7 @@ var init_orderlyNetworkTextIcon = __esm({
145
145
  var SignalIcon;
146
146
  var init_signal = __esm({
147
147
  "src/components/icons/signal.tsx"() {
148
- SignalIcon = React6.forwardRef(
148
+ SignalIcon = React7.forwardRef(
149
149
  (props, ref) => {
150
150
  const { size = 18, ...rest } = props;
151
151
  return /* @__PURE__ */ jsx(
@@ -1507,671 +1507,1252 @@ var MainLogo = (props) => {
1507
1507
  }
1508
1508
  return /* @__PURE__ */ jsx(OrderlyLogo, {});
1509
1509
  };
1510
- var useAccountValue = (mainAccountId) => {
1511
- const [accountValue, setAccountValue] = useState({});
1512
- const {
1513
- data: newPositions = [],
1514
- isLoading: isPositionLoading,
1515
- mutate: mutatePositions
1516
- } = useSubAccountQuery("/v1/client/aggregate/positions", {
1517
- // formatter: (data) => data,
1518
- errorRetryCount: 3,
1519
- accountId: mainAccountId
1520
- });
1521
- useEffect(() => {
1522
- if (isPositionLoading) {
1523
- return;
1510
+
1511
+ // src/components/footer/footer.ui.tsx
1512
+ init_icons();
1513
+ var Footer = (props) => {
1514
+ const { t } = useTranslation();
1515
+ const signalClsName = useMemo(() => {
1516
+ switch (props.wsStatus) {
1517
+ case WsNetworkStatus.Connected:
1518
+ return "oui-fill-success-light oui-text-success-light";
1519
+ case WsNetworkStatus.Disconnected:
1520
+ return "oui-fill-danger-light oui-text-danger-light";
1521
+ case WsNetworkStatus.Unstable:
1522
+ return "oui-fill-warning-light oui-text-warning-light";
1524
1523
  }
1525
- if (!newPositions || newPositions.length === 0) {
1526
- setAccountValue({});
1527
- return;
1524
+ }, [props.wsStatus]);
1525
+ const openUrl = (url) => {
1526
+ window.open(url, "_blank");
1527
+ };
1528
+ return /* @__PURE__ */ jsxs(
1529
+ Flex,
1530
+ {
1531
+ direction: "row",
1532
+ justify: "between",
1533
+ height: 28,
1534
+ px: 3,
1535
+ width: "100%",
1536
+ children: [
1537
+ /* @__PURE__ */ jsxs(Flex, { children: [
1538
+ /* @__PURE__ */ jsxs(
1539
+ Flex,
1540
+ {
1541
+ direction: "row",
1542
+ itemAlign: "center",
1543
+ gap: 1,
1544
+ className: signalClsName,
1545
+ children: [
1546
+ /* @__PURE__ */ jsx(
1547
+ SignalIcon,
1548
+ {
1549
+ fillOpacity: 1,
1550
+ fill: "currentColor"
1551
+ }
1552
+ ),
1553
+ /* @__PURE__ */ jsx(Text, { size: "2xs", children: t("scaffold.footer.operational") })
1554
+ ]
1555
+ }
1556
+ ),
1557
+ /* @__PURE__ */ jsx(
1558
+ Divider,
1559
+ {
1560
+ direction: "vertical",
1561
+ className: "oui-h-[18px] oui-px-1 oui-ml-2 oui-border-line-12"
1562
+ }
1563
+ ),
1564
+ /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
1565
+ /* @__PURE__ */ jsx(Text, { intensity: 54, size: "2xs", children: t("scaffold.footer.joinCommunity") }),
1566
+ /* @__PURE__ */ jsxs(Flex, { direction: "row", gap: 1, children: [
1567
+ typeof props.telegramUrl !== "undefined" && /* @__PURE__ */ jsx(
1568
+ CommuntiyTelegramIcon,
1569
+ {
1570
+ className: "oui-fill-base-contrast-54 hover:oui-fill-base-contrast oui-cursor-pointer",
1571
+ fill: "currentColor",
1572
+ fillOpacity: 1,
1573
+ onClick: (e) => openUrl(props.telegramUrl)
1574
+ }
1575
+ ),
1576
+ typeof props.discordUrl !== "undefined" && /* @__PURE__ */ jsx(
1577
+ CommuntiyDiscordIcon,
1578
+ {
1579
+ className: "oui-fill-base-contrast-54 hover:oui-fill-base-contrast oui-cursor-pointer",
1580
+ fill: "currentColor",
1581
+ fillOpacity: 1,
1582
+ onClick: (e) => openUrl(props.discordUrl)
1583
+ }
1584
+ ),
1585
+ typeof props.twitterUrl !== "undefined" && /* @__PURE__ */ jsx(
1586
+ CommuntiyXIcon,
1587
+ {
1588
+ className: "oui-fill-base-contrast-54 hover:oui-fill-base-contrast oui-cursor-pointer",
1589
+ fill: "currentColor",
1590
+ fillOpacity: 1,
1591
+ onClick: (e) => openUrl(props.twitterUrl)
1592
+ }
1593
+ )
1594
+ ] }),
1595
+ typeof props?.trailing !== "undefined" && /* @__PURE__ */ jsxs(Fragment, { children: [
1596
+ /* @__PURE__ */ jsx(
1597
+ Divider,
1598
+ {
1599
+ direction: "vertical",
1600
+ className: "oui-h-[18px] oui-border-line-12"
1601
+ }
1602
+ ),
1603
+ props?.trailing
1604
+ ] })
1605
+ ] })
1606
+ ] }),
1607
+ /* @__PURE__ */ jsxs(
1608
+ Flex,
1609
+ {
1610
+ direction: "row",
1611
+ gap: 1,
1612
+ className: "oui-scaffold-footer-powered-by",
1613
+ children: [
1614
+ /* @__PURE__ */ jsx(Text, { intensity: 54, size: "2xs", children: t("scaffold.footer.poweredBy") }),
1615
+ /* @__PURE__ */ jsx(OrderlyTextIcon, {})
1616
+ ]
1617
+ }
1618
+ )
1619
+ ]
1528
1620
  }
1529
- const value = newPositions.reduce(
1530
- (acc, position) => {
1531
- const accountId = position.account_id;
1532
- if (acc[accountId]) {
1533
- acc[accountId] = new Decimal(acc[accountId]).plus(position.unsettled_pnl).toNumber();
1534
- } else {
1535
- acc[accountId] = new Decimal(position.unsettled_pnl).toNumber();
1536
- }
1537
- return acc;
1538
- },
1539
- {}
1540
- );
1541
- setAccountValue(value);
1542
- }, [newPositions, isPositionLoading]);
1621
+ );
1622
+ };
1623
+ var useFooterScript = () => {
1624
+ const wsStatus = useWsStatus();
1543
1625
  return {
1544
- accountValue
1626
+ wsStatus
1545
1627
  };
1546
1628
  };
1547
-
1548
- // src/components/subAccount/subAccount.script.ts
1549
- var SubAccountScript = () => {
1550
- const [open2, setOpen] = useState(false);
1551
- const [mainAccountHolding, setMainAccountHolding] = useState(
1552
- []
1553
- );
1554
- const { wallet, connectedChain } = useWalletConnector();
1555
- const { data: indexPrices } = useIndexPricesStream();
1556
- const { isMobile } = useScreen();
1557
- const { state, account, subAccount, switchAccount } = useAccount();
1558
- const { t } = useTranslation();
1559
- const mainAccountId = state.mainAccountId;
1560
- const { accountValue } = useAccountValue(mainAccountId);
1561
- const currentAccountId = state.accountId;
1562
- const hasRefreshedRef = useRef(false);
1563
- const userAddress = useMemo(() => {
1564
- let address = state.address;
1565
- if (connectedChain?.id && ABSTRACT_CHAIN_ID_MAP.has(parseInt(connectedChain?.id))) {
1566
- address = account.getAdditionalInfo()?.AGWAddress;
1567
- }
1568
- return address;
1569
- }, [wallet, state, account, connectedChain]);
1570
- const subAccounts = useMemo(() => {
1571
- if (!state.subAccounts || !state.subAccounts.length) {
1572
- return [];
1629
+ var FooterWidget = (props) => {
1630
+ const state = useFooterScript();
1631
+ return /* @__PURE__ */ jsx(Footer, { ...state, ...props });
1632
+ };
1633
+ var ScaffoldContext = createContext(
1634
+ {}
1635
+ );
1636
+ var useScaffoldContext = () => {
1637
+ return useContext(ScaffoldContext);
1638
+ };
1639
+ var NotificationUI = (props) => {
1640
+ const { dataSource, showAnnouncement } = props;
1641
+ const { routerAdapter } = useScaffoldContext();
1642
+ const onItemClick = (url) => {
1643
+ if (!url) return;
1644
+ routerAdapter?.onRouteChange({
1645
+ href: url,
1646
+ name: url,
1647
+ target: "_blank"
1648
+ });
1649
+ };
1650
+ const notificationRef = useRef(null);
1651
+ const len = useMemo(() => dataSource?.length ?? 0, [dataSource]);
1652
+ const onClose = useCallback(() => {
1653
+ if (len === 0) {
1654
+ return;
1573
1655
  }
1574
- const currentSubAccount = state.subAccounts.find(
1575
- (subAccount2) => subAccount2.id === currentAccountId
1576
- );
1577
- if (currentSubAccount) {
1578
- return [
1579
- currentSubAccount,
1580
- ...state.subAccounts.filter(
1581
- (subAccount2) => subAccount2.id !== currentAccountId
1582
- )
1583
- ];
1656
+ windowGuard(() => {
1657
+ if (notificationRef.current) {
1658
+ const animationendHandler = () => {
1659
+ props.onClose();
1660
+ notificationRef.current.removeEventListener(
1661
+ "transitionend",
1662
+ animationendHandler
1663
+ );
1664
+ };
1665
+ notificationRef.current.addEventListener(
1666
+ "transitionend",
1667
+ animationendHandler
1668
+ );
1669
+ requestAnimationFrame(() => {
1670
+ notificationRef.current.style.transform = "translateY(120%)";
1671
+ });
1672
+ }
1673
+ });
1674
+ }, [props.onClose, len]);
1675
+ useEffect(() => {
1676
+ if (len === 0) {
1677
+ return;
1584
1678
  }
1585
- return [...state.subAccounts];
1586
- }, [state.subAccounts, currentAccountId]);
1587
- const _popup = useMemo(
1588
- () => ({ mode: isMobile ? "sheet" : "modal" }),
1589
- [isMobile]
1590
- );
1591
- const doCreatSubAccount = useCallback(
1592
- (nickName) => {
1593
- return subAccount.create(nickName);
1594
- },
1595
- [subAccount]
1596
- );
1597
- const onSwitch = useCallback(
1598
- (accountId) => {
1599
- return switchAccount(accountId).catch((error) => {
1600
- }).then((res) => {
1601
- toast.success(t("subAccount.modal.switch.success.description"));
1679
+ if (showAnnouncement) {
1680
+ windowGuard(() => {
1681
+ if (notificationRef.current) {
1682
+ requestAnimationFrame(() => {
1683
+ notificationRef.current.style.transform = "translateY(0)";
1684
+ });
1685
+ }
1602
1686
  });
1603
- },
1604
- [switchAccount]
1605
- );
1606
- const accountsWithValues = useMemo(() => {
1607
- const mainAccountUnsettlePnl = accountValue[mainAccountId] ?? 0;
1608
- const mainAccount = mainAccountId && state.address ? {
1609
- id: mainAccountId,
1610
- userAddress: state.address,
1611
- holding: mainAccountHolding,
1612
- accountValue: calculateAccountValue(
1613
- mainAccountHolding,
1614
- mainAccountUnsettlePnl,
1615
- indexPrices || EMPTY_OBJECT
1616
- )
1617
- } : void 0;
1618
- const updatedSubAccounts = subAccounts.map((subAccount2) => {
1619
- const subAccountUnsettlePnl = accountValue[subAccount2.id] ?? 0;
1620
- return {
1621
- ...subAccount2,
1622
- accountValue: calculateAccountValue(
1623
- subAccount2.holding || EMPTY_LIST,
1624
- subAccountUnsettlePnl,
1625
- indexPrices || EMPTY_OBJECT
1626
- )
1627
- };
1628
- });
1629
- return {
1630
- mainAccount,
1631
- subAccounts: updatedSubAccounts
1632
- };
1633
- }, [
1634
- mainAccountId,
1635
- state.address,
1636
- mainAccountHolding,
1637
- subAccounts,
1638
- accountValue,
1639
- indexPrices
1640
- ]);
1641
- useEffect(() => {
1642
- if (!open2) {
1643
- hasRefreshedRef.current = false;
1644
- return;
1645
- }
1646
- if (!hasRefreshedRef.current && mainAccountId) {
1647
- hasRefreshedRef.current = true;
1648
- subAccount.refresh().then((res) => {
1649
- setMainAccountHolding(res[mainAccountId] || []);
1650
- });
1651
- }
1652
- }, [open2, mainAccountId, subAccount]);
1653
- return {
1654
- userAddress,
1655
- mainAccount: accountsWithValues.mainAccount,
1656
- currentAccountId,
1657
- open: open2,
1658
- onOpenChange: setOpen,
1659
- popup: _popup,
1660
- createSubAccount: doCreatSubAccount,
1661
- subAccounts: accountsWithValues.subAccounts,
1662
- onSwitch
1663
- };
1664
- };
1665
- var calculateAccountValue = (holdings, unsettlePnl, indexPrices) => {
1666
- const holding = holdings.reduce((acc, holding2) => {
1667
- const price = getTokenIndexPrice(holding2.token, indexPrices);
1668
- if (!price) {
1669
- return acc;
1670
1687
  }
1671
- return new Decimal(holding2.holding).times(price).add(holding2.isolated_margin ?? 0).add(acc).toNumber();
1672
- }, 0);
1673
- return holding + unsettlePnl;
1674
- };
1675
- var getTokenIndexPrice = (token, indexPrices) => {
1676
- if (token === "USDC") {
1677
- return 1;
1678
- }
1679
- const symbol = `PERP_${token}_USDC`;
1680
- return indexPrices[symbol] ?? 0;
1681
- };
1682
- var SubAccountIcon = forwardRef(
1683
- (props, ref) => {
1684
- const { size = 20, ...rest } = props;
1685
- return /* @__PURE__ */ jsx(
1686
- "svg",
1687
- {
1688
- width: size,
1689
- height: size,
1690
- viewBox: "0 0 20 20",
1691
- fill: "currentColor",
1692
- xmlns: "http://www.w3.org/2000/svg",
1693
- ref,
1694
- ...rest,
1695
- children: /* @__PURE__ */ jsx(
1696
- "path",
1697
- {
1698
- d: "M10 2.5C8.16892 2.5 6.66667 4.00225 6.66667 5.83333C6.66667 7.66441 8.16892 9.16667 10 9.16667C11.8311 9.16667 13.3333 7.66441 13.3333 5.83333C13.3333 4.00225 11.8311 2.5 10 2.5ZM10 4.16667C10.9303 4.16667 11.6667 4.90299 11.6667 5.83333C11.6667 6.76368 10.9303 7.5 10 7.5C9.06965 7.5 8.33333 6.76368 8.33333 5.83333C8.33333 4.90299 9.06965 4.16667 10 4.16667ZM10 11.6667C8.54587 11.6667 6.82264 12.0082 5.37435 12.5798C4.65021 12.8656 3.99558 13.205 3.47168 13.641C2.94778 14.0769 2.5 14.6662 2.5 15.4167V17.5H17.5V16.6667V15.4167C17.5 14.6662 17.0522 14.0769 16.5283 13.641C16.0044 13.205 15.3498 12.8656 14.6257 12.5798C13.1774 12.0082 11.4541 11.6667 10 11.6667ZM10 13.3333C11.1784 13.3333 12.7884 13.645 14.0153 14.1292C14.6288 14.3713 15.1475 14.66 15.4622 14.9219C15.777 15.1838 15.8333 15.3622 15.8333 15.4167V15.8333H4.16667V15.4167C4.16667 15.3622 4.22299 15.1838 4.53776 14.9219C4.85253 14.66 5.37124 14.3713 5.9847 14.1292C7.21162 13.645 8.82163 13.3333 10 13.3333Z",
1699
- className: "oui-fill-base-contrast-98"
1700
- }
1701
- )
1702
- }
1703
- );
1688
+ }, [showAnnouncement, len]);
1689
+ if (len === 0) {
1690
+ return null;
1704
1691
  }
1705
- );
1706
- var SwapIcon = forwardRef((props, ref) => {
1707
- const { size = 20, ...rest } = props;
1708
1692
  return /* @__PURE__ */ jsx(
1709
- "svg",
1693
+ "div",
1710
1694
  {
1711
- width: size,
1712
- height: size,
1713
- viewBox: "0 0 20 20",
1714
- fill: "currentColor",
1715
- xmlns: "http://www.w3.org/2000/svg",
1716
- ref,
1717
- ...rest,
1718
- children: /* @__PURE__ */ jsx("path", { d: "M6 16L2 12L6 8L7.0625 9.0625L4.875 11.25H11V12.75H4.875L7.0625 14.9375L6 16ZM14 11L12.9375 9.9375L15.125 7.75H9V6.25H15.125L12.9375 4.0625L14 3L18 7L14 11Z" })
1695
+ ref: notificationRef,
1696
+ "data-state": showAnnouncement ? "open" : "closed",
1697
+ className: cn(
1698
+ "oui-fixed oui-bottom-[calc(env(safe-area-inset-bottom)+8px)] oui-left-2 oui-z-50 oui-w-[calc(100%_-_16px)] oui-translate-y-[120%] oui-rounded-lg oui-border oui-border-line-6 oui-bg-base-8 md:oui-bottom-10 md:oui-left-auto md:oui-right-3 md:oui-w-[420px]",
1699
+ "oui-transition-all oui-duration-300 oui-ease-in-out",
1700
+ showAnnouncement ? "oui-visible" : "oui-invisible"
1701
+ ),
1702
+ children: /* @__PURE__ */ jsx(
1703
+ NotificationUI$1,
1704
+ {
1705
+ dataSource,
1706
+ onClose,
1707
+ onItemClick
1708
+ }
1709
+ )
1719
1710
  }
1720
1711
  );
1721
- });
1722
- var AddIcon = forwardRef((props, ref) => {
1723
- const { size = 20, ...rest } = props;
1712
+ };
1713
+ var NotificationWidget = () => {
1714
+ const { announcementState } = useScaffoldContext();
1724
1715
  return /* @__PURE__ */ jsx(
1725
- "svg",
1716
+ NotificationUI,
1726
1717
  {
1727
- width: size,
1728
- height: size,
1729
- viewBox: "0 0 20 20",
1730
- fill: "currentColor",
1731
- xmlns: "http://www.w3.org/2000/svg",
1732
- ref,
1733
- ...rest,
1734
- children: /* @__PURE__ */ jsx("path", { d: "M9.25 14H10.75V10.75H14V9.25H10.75V6H9.25V9.25H6V10.75H9.25V14ZM4.5 17C4.0875 17 3.73437 16.8531 3.44062 16.5594C3.14687 16.2656 3 15.9125 3 15.5V4.5C3 4.0875 3.14687 3.73438 3.44062 3.44063C3.73437 3.14688 4.0875 3 4.5 3H15.5C15.9125 3 16.2656 3.14688 16.5594 3.44063C16.8531 3.73438 17 4.0875 17 4.5V15.5C17 15.9125 16.8531 16.2656 16.5594 16.5594C16.2656 16.8531 15.9125 17 15.5 17H4.5ZM4.5 15.5H15.5V4.5H4.5V15.5Z" })
1718
+ dataSource: announcementState.tips,
1719
+ onClose: announcementState.closeTips,
1720
+ showAnnouncement: announcementState.showAnnouncement
1735
1721
  }
1736
1722
  );
1723
+ };
1724
+
1725
+ // src/components/scaffold/scaffold.ui.tsx
1726
+ init_restrictedInfo();
1727
+ var menuItemVariants = tv({
1728
+ slots: {
1729
+ button: [
1730
+ "oui-min-h-10",
1731
+ "oui-px-3",
1732
+ "oui-py-2",
1733
+ "oui-rounded-md",
1734
+ "oui-w-full",
1735
+ "oui-text-left",
1736
+ "oui-text-base",
1737
+ "oui-text-base-contrast-36",
1738
+ // "oui-flex",
1739
+ "oui-group",
1740
+ // "oui-space-x-2",
1741
+ // "oui-items-center",
1742
+ "hover:oui-bg-base-8",
1743
+ "oui-transition-colors",
1744
+ "group-data-[state=closed]/bar:oui-w-[42px]",
1745
+ "oui-overflow-hidden"
1746
+ ],
1747
+ icon: []
1748
+ },
1749
+ variants: {
1750
+ mode: {
1751
+ "icon-only": {
1752
+ button: "oui-w-10",
1753
+ icon: "w-6 h-6"
1754
+ },
1755
+ full: {
1756
+ button: "oui-full",
1757
+ icon: "w-6 h-6"
1758
+ }
1759
+ },
1760
+ active: {
1761
+ true: {
1762
+ button: "oui-bg-base-5 hover:oui-bg-base-5"
1763
+ }
1764
+ },
1765
+ open: {
1766
+ true: {
1767
+ button: ""
1768
+ }
1769
+ }
1770
+ }
1737
1771
  });
1738
- var EditIcon = forwardRef((props, ref) => {
1739
- const { size = 12, ...rest } = props;
1740
- return /* @__PURE__ */ jsx(
1741
- "svg",
1772
+ var MenuItem = React7.memo((props) => {
1773
+ const { item, mode, open: open2, onClick, active, ...rest } = props;
1774
+ const { button } = menuItemVariants({
1775
+ mode,
1776
+ active: props.active,
1777
+ open: props.open
1778
+ });
1779
+ const children = /* @__PURE__ */ jsx(
1780
+ "button",
1742
1781
  {
1743
- width: size,
1744
- height: size,
1745
- viewBox: "0 0 12 12",
1746
- fill: "currentColor",
1747
- xmlns: "http://www.w3.org/2000/svg",
1748
- ref,
1749
- ...rest,
1750
- children: /* @__PURE__ */ jsx("path", { d: "M9.95551 2.00049C9.81619 2.00049 9.67686 2.05318 9.57074 2.15918L5.43256 6.29785L5.24945 7.25049L6.20209 7.06738L10.3403 2.9292C10.443 2.82645 10.4999 2.68968 10.4999 2.54443C10.4999 2.39918 10.443 2.26218 10.3403 2.15918C10.2341 2.05318 10.0948 2.00049 9.95551 2.00049ZM3.12494 2.25C2.37147 2.25 1.74994 2.87153 1.74994 3.625V9.375C1.74994 10.1285 2.37147 10.75 3.12494 10.75H8.87494C9.62841 10.75 10.2499 10.1285 10.2499 9.375V5.25C10.2509 5.18374 10.2386 5.11796 10.2139 5.05648C10.1892 4.99499 10.1525 4.93903 10.106 4.89185C10.0595 4.84466 10.0041 4.8072 9.94293 4.78162C9.8818 4.75605 9.8162 4.74288 9.74994 4.74288C9.68368 4.74288 9.61807 4.75605 9.55695 4.78162C9.49582 4.8072 9.44038 4.84466 9.39386 4.89185C9.34734 4.93903 9.31066 4.99499 9.28595 5.05648C9.26124 5.11796 9.249 5.18374 9.24994 5.25V9.375C9.24994 9.58803 9.08797 9.75 8.87494 9.75H3.12494C2.91191 9.75 2.74994 9.58803 2.74994 9.375V3.625C2.74994 3.41197 2.91191 3.25 3.12494 3.25H7.24994C7.3162 3.25094 7.38198 3.2387 7.44346 3.21399C7.50494 3.18928 7.5609 3.1526 7.60809 3.10608C7.65527 3.05956 7.69274 3.00412 7.71832 2.94299C7.74389 2.88186 7.75706 2.81626 7.75706 2.75C7.75706 2.68374 7.74389 2.61814 7.71832 2.55701C7.69274 2.49588 7.65527 2.44044 7.60809 2.39392C7.5609 2.3474 7.50494 2.31072 7.44346 2.28601C7.38198 2.2613 7.3162 2.24906 7.24994 2.25H3.12494Z" })
1782
+ "data-actived": props.active,
1783
+ disabled: item.disabled,
1784
+ className: button(),
1785
+ onClick: () => {
1786
+ props.onClick?.(item);
1787
+ },
1788
+ children: /* @__PURE__ */ jsxs(Flex, { itemAlign: "center", gap: 2, as: "span", children: [
1789
+ /* @__PURE__ */ jsx("div", { children: item.icon }),
1790
+ props.open && /* @__PURE__ */ jsx(
1791
+ Text.gradient,
1792
+ {
1793
+ color: props.active ? "brand" : "inherit",
1794
+ angle: 45,
1795
+ size: "base",
1796
+ className: "oui-break-all oui-animate-in oui-fade-in",
1797
+ children: item.name
1798
+ }
1799
+ )
1800
+ ] })
1751
1801
  }
1752
1802
  );
1803
+ if (props.open) {
1804
+ return /* @__PURE__ */ jsx("li", { className: "oui-min-w-[120px]", children });
1805
+ }
1806
+ return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(Tooltip, { content: item.name, side: "right", align: "center", sideOffset: 20, children }) });
1753
1807
  });
1754
- var AccountIdForCopy = (props) => {
1755
- const { t } = useTranslation();
1756
- const info = useMemo(() => {
1757
- return {
1758
- leading: props.accountId.slice(0, 6),
1759
- middle: props.accountId.slice(6, -4),
1760
- trailing: props.accountId.slice(-4)
1761
- };
1762
- }, [props.accountId]);
1763
- const copy = useCallback(() => {
1764
- navigator.clipboard.writeText(props.accountId);
1765
- toast.success(t("common.copy.copied"));
1766
- }, [props.accountId]);
1767
- return /* @__PURE__ */ jsxs(
1768
- Flex,
1808
+ MenuItem.displayName = "LeftMenuItem";
1809
+ var SideMenus = (props) => {
1810
+ return /* @__PURE__ */ jsxs(Box, { py: 6, children: [
1811
+ /* @__PURE__ */ jsx(
1812
+ "svg",
1813
+ {
1814
+ width: "18",
1815
+ height: "18",
1816
+ viewBox: "0 0 18 18",
1817
+ fill: "none",
1818
+ xmlns: "http://www.w3.org/2000/svg",
1819
+ className: "oui-pointer-events-none oui-invisible oui-absolute",
1820
+ children: /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs(
1821
+ "linearGradient",
1822
+ {
1823
+ id: "side-menu-gradient",
1824
+ x1: "15.7432",
1825
+ y1: "8.94726",
1826
+ x2: "2.24316",
1827
+ y2: "8.94726",
1828
+ gradientUnits: "userSpaceOnUse",
1829
+ children: [
1830
+ /* @__PURE__ */ jsx("stop", { stopColor: "rgb(var(--oui-gradient-brand-end))" }),
1831
+ /* @__PURE__ */ jsx("stop", { stopColor: "rgb(var(--oui-gradient-brand-start))", offset: "1" })
1832
+ ]
1833
+ }
1834
+ ) })
1835
+ }
1836
+ ),
1837
+ /* @__PURE__ */ jsx("ul", { className: "oui-space-y-4", children: props.menus?.map((item, index) => {
1838
+ if (item?.hide) {
1839
+ return null;
1840
+ }
1841
+ return /* @__PURE__ */ jsx(
1842
+ MenuItem,
1843
+ {
1844
+ item,
1845
+ open: props.open,
1846
+ active: item.href === props.current,
1847
+ onClick: props.onItemSelect
1848
+ },
1849
+ index
1850
+ );
1851
+ }) })
1852
+ ] });
1853
+ };
1854
+ var SideBarHeader = (props) => {
1855
+ const { title } = props;
1856
+ const titleElemet = typeof title === "string" ? /* @__PURE__ */ jsx(Text, { intensity: 54, size: "xs", children: title }) : title;
1857
+ const iconProps = {
1858
+ className: "oui-text-base-contrast-36 hover:oui-text-base-contrast-80 oui-cursor-pointer",
1859
+ onClick: props.onToggle
1860
+ };
1861
+ return /* @__PURE__ */ jsxs(
1862
+ Flex,
1769
1863
  {
1770
- className: "oui-min-h-[50px] oui-w-[180px]",
1771
- gap: 2,
1772
- justify: "between",
1864
+ justify: props.open ? "between" : "center",
1773
1865
  itemAlign: "center",
1866
+ className: "oui-h-6",
1867
+ children: [
1868
+ props.open ? titleElemet : null,
1869
+ props.open ? /* @__PURE__ */ jsx(CollapseIcon, { ...iconProps }) : /* @__PURE__ */ jsx(ExpandIcon, { ...iconProps })
1870
+ ]
1871
+ }
1872
+ );
1873
+ };
1874
+ var SideBar = (props) => {
1875
+ const { open: open2 = true, items, current, onItemSelect } = props;
1876
+ return /* @__PURE__ */ jsxs(
1877
+ Box,
1878
+ {
1879
+ "data-state": open2 ? "opened" : "closed",
1880
+ className: cn("oui-group/bar", props.className),
1881
+ style: props.style,
1774
1882
  children: [
1775
- /* @__PURE__ */ jsxs(Text, { className: "oui-w-full oui-break-all oui-text-2xs oui-text-base-contrast-36", children: [
1776
- /* @__PURE__ */ jsx(Text, { className: "oui-text-base-contrast", children: info.leading }),
1777
- /* @__PURE__ */ jsx(Text, { children: info.middle }),
1778
- /* @__PURE__ */ jsx(Text, { className: "oui-text-base-contrast", children: info.trailing })
1779
- ] }),
1780
1883
  /* @__PURE__ */ jsx(
1781
- CopyIcon,
1884
+ SideBarHeader,
1782
1885
  {
1783
- onClick: copy,
1784
- className: "oui-cursor-pointer oui-text-base-contrast-36 hover:oui-text-base-contrast"
1886
+ open: open2,
1887
+ title: props.title,
1888
+ onToggle: () => {
1889
+ props.onOpenChange?.(!open2);
1890
+ }
1891
+ }
1892
+ ),
1893
+ /* @__PURE__ */ jsx(
1894
+ SideMenus,
1895
+ {
1896
+ menus: items,
1897
+ current,
1898
+ onItemSelect,
1899
+ open: open2
1785
1900
  }
1786
1901
  )
1787
1902
  ]
1788
1903
  }
1789
1904
  );
1790
1905
  };
1791
- var AccountItem = (props) => {
1792
- const { t } = useTranslation();
1793
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(
1794
- Flex,
1906
+ SideBar.displayName = "SideBar";
1907
+ var ExpandIcon = (props) => /* @__PURE__ */ jsx(
1908
+ "svg",
1909
+ {
1910
+ width: "16",
1911
+ height: "16",
1912
+ viewBox: "0 0 16 16",
1913
+ fill: "currentColor",
1914
+ xmlns: "http://www.w3.org/2000/svg",
1915
+ ...props,
1916
+ children: /* @__PURE__ */ jsx("path", { d: "M6.326 8.826a.84.84 0 0 0-.6.234L2.16 12.627v-2.135H.492v4.167c0 .46.373.833.834.833h4.166v-1.667H3.357l3.567-3.567a.857.857 0 0 0 0-1.198.84.84 0 0 0-.598-.234M10.502.492V2.16h2.135L9.07 5.726a.857.857 0 0 0 0 1.199.86.86 0 0 0 1.197 0l3.568-3.568v2.135h1.667V1.326a.834.834 0 0 0-.834-.834z" })
1917
+ }
1918
+ );
1919
+ var CollapseIcon = (props) => /* @__PURE__ */ jsx(
1920
+ "svg",
1921
+ {
1922
+ width: "16",
1923
+ height: "16",
1924
+ viewBox: "0 0 16 16",
1925
+ fill: "currentColor",
1926
+ xmlns: "http://www.w3.org/2000/svg",
1927
+ ...props,
1928
+ children: /* @__PURE__ */ jsx("path", { d: "M14.668.492a.85.85 0 0 0-.599.234l-3.567 3.568V2.159H8.835v4.167c0 .46.373.833.833.833h4.167V5.492H11.7l3.569-3.567a.86.86 0 0 0 0-1.199.85.85 0 0 0-.6-.234m-12.5 8.334v1.666h2.135L.736 14.06a.86.86 0 0 0 0 1.198.86.86 0 0 0 1.198 0l3.568-3.567v2.134h1.666V9.66a.834.834 0 0 0-.833-.833z" })
1929
+ }
1930
+ );
1931
+ var useSideNavBuilder = (props) => {
1932
+ const [current, setCurrent] = useState(props?.items?.[0].href || "/");
1933
+ const { expanded, setExpand } = useScaffoldContext();
1934
+ return {
1935
+ items: [],
1936
+ current,
1937
+ open: expanded,
1938
+ onOpenChange: (open2) => {
1939
+ setExpand?.(open2);
1940
+ },
1941
+ onItemSelect: (item) => {
1942
+ if (item.href) {
1943
+ setCurrent(item.href);
1944
+ }
1945
+ },
1946
+ ...props
1947
+ };
1948
+ };
1949
+ var SideNavbarWidget = (props) => {
1950
+ const state = useSideNavBuilder(props);
1951
+ return /* @__PURE__ */ jsx(SideBar, { ...state });
1952
+ };
1953
+ var DefaultTradingViewTncLink = ({
1954
+ className
1955
+ }) => {
1956
+ return /* @__PURE__ */ jsx(
1957
+ "a",
1795
1958
  {
1796
- justify: "between",
1797
- itemAlign: "center",
1798
- width: "100%",
1959
+ href: "https://www.tradingview.com/",
1960
+ target: "_blank",
1961
+ rel: "noopener noreferrer",
1962
+ className: className ?? "",
1963
+ children: /* @__PURE__ */ jsx(Text, { intensity: 54, size: "2xs", children: "Charts powered by TradingView" })
1964
+ }
1965
+ );
1966
+ };
1967
+ var DesktopScaffold = (props) => {
1968
+ const {
1969
+ classNames,
1970
+ footerHeight,
1971
+ topNavbarRef,
1972
+ mainNavProps,
1973
+ topBar,
1974
+ announcementRef,
1975
+ // restrictedInfo,
1976
+ hasLeftSidebar,
1977
+ expand,
1978
+ leftSideProps,
1979
+ leftSidebar,
1980
+ footer,
1981
+ footerRef,
1982
+ sideBarCollaspedWidth,
1983
+ sideBarExpandWidth,
1984
+ footerProps,
1985
+ children
1986
+ } = props;
1987
+ const trailing = typeof footerProps?.trailing !== "undefined" ? footerProps?.trailing : /* @__PURE__ */ jsx(DefaultTradingViewTncLink, {});
1988
+ return /* @__PURE__ */ jsxs(
1989
+ "div",
1990
+ {
1991
+ style: {
1992
+ height: `calc(100vh - ${footerHeight}px)`
1993
+ },
1799
1994
  className: cn(
1800
- "oui-relative oui-cursor-pointer oui-rounded-[6px] oui-bg-base-6 oui-px-3 oui-py-4",
1801
- "oui-border oui-border-base-6",
1802
- props.isCurrent && " oui-border-[rgb(var(--oui-gradient-brand-start))] ",
1803
- !props.isCurrent && "hover:oui-border-base-contrast-16"
1995
+ "oui-scaffold-root oui-font-semibold",
1996
+ // default text and background color
1997
+ "oui-bg-base-10 oui-text-base-contrast",
1998
+ "oui-flex oui-flex-col",
1999
+ "oui-custom-scrollbar oui-overflow-auto",
2000
+ classNames?.root
1804
2001
  ),
1805
2002
  children: [
1806
2003
  /* @__PURE__ */ jsx(
1807
- "div",
1808
- {
1809
- className: "oui-absolute oui-inset-0 oui-z-0 ",
1810
- onClick: () => {
1811
- if (props.isCurrent) {
1812
- return;
1813
- }
1814
- props.onSwitch?.(props.accountId);
1815
- }
1816
- }
1817
- ),
1818
- props.isCurrent && /* @__PURE__ */ jsx(
1819
- "div",
2004
+ Box,
1820
2005
  {
2006
+ ref: topNavbarRef,
1821
2007
  className: cn(
1822
- "oui-absolute -oui-right-[1px] -oui-top-[1px] oui-leading-3",
1823
- "oui-text-[10px] oui-font-semibold oui-text-base-10",
1824
- "oui-rounded-[6px] oui-rounded-br-none oui-rounded-tl-none oui-bg-[rgb(var(--oui-gradient-brand-start))] oui-py-0.5 oui-pl-1 oui-pr-[5px]"
2008
+ "oui-scaffold-topNavbar oui-bg-base-9",
2009
+ classNames?.topNavbar
1825
2010
  ),
1826
- children: t("subAccount.modal.current")
2011
+ children: topBar ?? /* @__PURE__ */ jsx(MainNavWidget, { ...mainNavProps })
1827
2012
  }
1828
2013
  ),
1829
2014
  /* @__PURE__ */ jsxs(
1830
- Flex,
2015
+ "div",
1831
2016
  {
1832
- direction: "column",
1833
- itemAlign: "start",
1834
- gap: 1,
1835
- className: "oui-z-[2]",
2017
+ className: cn(
2018
+ "oui-scaffold-container",
2019
+ "oui-relative oui-h-full",
2020
+ // 1024px - 6px (scrollbar widt) = 1018px
2021
+ "oui-min-w-[1018px]",
2022
+ classNames?.container
2023
+ ),
1836
2024
  children: [
1837
- props.isMainAccount ? /* @__PURE__ */ jsx(Text, { className: "oui-text-xs oui-leading-3 oui-text-base-contrast", children: formatAddress(props.userAddress ?? "") }) : /* @__PURE__ */ jsxs(
1838
- Flex,
2025
+ /* @__PURE__ */ jsx(Box, { px: 2, ref: announcementRef, children: /* @__PURE__ */ jsx(
2026
+ RestrictedInfoWidget,
1839
2027
  {
1840
- justify: "start",
1841
- itemAlign: "center",
1842
- className: "oui-cursor-pointer oui-gap-[2px] oui-fill-base-contrast-54 hover:oui-fill-base-contrast",
1843
- onClick: (event) => {
1844
- props.onEdit?.({
1845
- accountId: props.accountId,
1846
- description: props.description ?? ""
1847
- });
1848
- event.stopPropagation();
1849
- event.preventDefault();
1850
- },
1851
- children: [
1852
- /* @__PURE__ */ jsx(Text, { className: "oui-text-xs oui-leading-3 oui-text-base-contrast", children: props.description }),
1853
- /* @__PURE__ */ jsx(EditIcon, { className: "oui-fill-base-contrast-54 hover:oui-fill-base-contrast" })
1854
- ]
2028
+ className: cn(
2029
+ "oui-scaffold-restricted-info",
2030
+ "oui-relative oui-z-[1]",
2031
+ "oui-mt-2",
2032
+ "oui-bg-base-9",
2033
+ "oui-min-w-[994px]"
2034
+ )
1855
2035
  }
1856
- ),
1857
- /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(AccountIdForCopy, { accountId: props.accountId }), children: /* @__PURE__ */ jsxs(Text, { className: "oui-text-2xs oui-leading-3 oui-text-base-contrast-36 hover:oui-text-base-contrast", children: [
1858
- "ID: ",
1859
- formatAddress(props.accountId)
1860
- ] }) })
2036
+ ) }),
2037
+ !hasLeftSidebar ? (
2038
+ // ----------No leftSidebar layout start ---------
2039
+ /* @__PURE__ */ jsx(Box, { height: "100%", className: cn(classNames?.content), children })
2040
+ ) : (
2041
+ // ----------No leftSidebar layout end ---------
2042
+ // ---------- left & body layout start ---------
2043
+ /* @__PURE__ */ jsxs(
2044
+ Grid,
2045
+ {
2046
+ className: cn(
2047
+ "oui-box-content oui-flex oui-transition-all xl:oui-grid",
2048
+ "oui-min-h-full oui-flex-1",
2049
+ classNames?.body
2050
+ ),
2051
+ style: {
2052
+ gridTemplateColumns: `${expand ? `${sideBarExpandWidth}px` : `${sideBarCollaspedWidth}px`} 1fr`
2053
+ // gridTemplateRows: "auto 1fr",
2054
+ // gridTemplateAreas: `"left main" "left main"`,
2055
+ },
2056
+ children: [
2057
+ /* @__PURE__ */ jsx("div", { className: cn(classNames?.leftSidebar), children: isValidElement(leftSidebar) ? leftSidebar : /* @__PURE__ */ jsx(SideNavbarWidget, { ...leftSideProps }) }),
2058
+ /* @__PURE__ */ jsx(
2059
+ Box,
2060
+ {
2061
+ width: "100%",
2062
+ className: cn("oui-overflow-hidden", classNames?.content),
2063
+ children
2064
+ }
2065
+ )
2066
+ ]
2067
+ }
2068
+ )
2069
+ )
1861
2070
  ]
1862
- },
1863
- props.accountId
2071
+ }
1864
2072
  ),
1865
- /* @__PURE__ */ jsxs(
1866
- Flex,
2073
+ /* @__PURE__ */ jsx(
2074
+ Box,
1867
2075
  {
1868
- className: "oui-text-xs oui-text-base-contrast",
1869
- itemAlign: "end",
1870
- gap: 1,
1871
- children: [
1872
- /* @__PURE__ */ jsx(Text.numeral, { rule: "price", dp: 2, children: props.accountValue ?? 0 }),
1873
- /* @__PURE__ */ jsx(Text, { children: "USDC" })
1874
- ]
2076
+ ref: footerRef,
2077
+ className: cn(
2078
+ "oui-scaffold-footer oui-w-full oui-bg-base-10",
2079
+ "oui-fixed oui-bottom-0 oui-z-50",
2080
+ "oui-border-t oui-border-line-12",
2081
+ classNames?.footer
2082
+ ),
2083
+ children: footer || /* @__PURE__ */ jsx(FooterWidget, { ...footerProps, trailing })
1875
2084
  }
1876
- )
2085
+ ),
2086
+ /* @__PURE__ */ jsx(NotificationWidget, {})
1877
2087
  ]
1878
2088
  }
1879
- ) });
1880
- };
1881
- var NickNameTextField = (props) => {
1882
- const { t } = useTranslation();
1883
- return /* @__PURE__ */ jsx(
1884
- TextField,
1885
- {
1886
- placeholder: `Sub-account ${(props.subAccountCount ?? 0) + 1}`,
1887
- fullWidth: true,
1888
- label: t("subAccount.modal.nickName.label"),
1889
- value: props.nickName,
1890
- onChange: (e) => {
1891
- const _value = e.target.value.replace(/[^a-zA-Z0-9@,\s_-]/g, "");
1892
- props.setNickName(_value);
1893
- },
1894
- formatters: [
1895
- inputFormatter.createRegexInputFormatter(/[^a-zA-Z0-9@,\s_-]/g)
1896
- ],
1897
- classNames: {
1898
- label: "oui-text-base-contrast-54 oui-text-xs",
1899
- input: "placeholder:oui-text-base-contrast-20 placeholder:oui-text-sm"
1900
- },
1901
- maxLength: 20,
1902
- minLength: 1,
1903
- autoComplete: "off",
1904
- helpText: t("subAccount.modal.create.nickname.role"),
1905
- className: "oui-mb-4",
1906
- color: props.invalid ? "danger" : void 0
1907
- }
1908
2089
  );
1909
2090
  };
1910
- var MAX_SUB_ACCOUNT_COUNT = 10;
1911
- var CreateSubAccount = (props) => {
1912
- const { t } = useTranslation();
1913
- const { isMobile } = useScreen();
1914
- const [open2, setOpen] = useState(false);
1915
- const [nickName, setNickName] = useState(void 0);
1916
- const { state } = useAccount();
1917
- const [invalid, setInvalid] = useState(false);
1918
- const [loading, setLoading] = useState(false);
1919
- const { widgetConfigs } = useAppContext();
1920
- const maxSubAccountCount = useMemo(() => {
1921
- return widgetConfigs?.subAccount?.maxSubAccountCount ?? MAX_SUB_ACCOUNT_COUNT;
1922
- }, [widgetConfigs]);
1923
- const subAccountCount = useMemo(() => {
1924
- return state.subAccounts?.length ?? 0;
1925
- }, [state]);
1926
- const trigger = useMemo(() => {
1927
- return subAccountCount >= maxSubAccountCount ? /* @__PURE__ */ jsx(
1928
- Tooltip,
1929
- {
1930
- className: "oui-max-w-[188px]",
1931
- content: t("subAccount.modal.create.max.description"),
1932
- children: /* @__PURE__ */ jsx(
1933
- AddIcon,
1934
- {
1935
- className: cn("oui-cursor-not-allowed oui-fill-base-contrast-20")
1936
- }
1937
- )
1938
- }
1939
- ) : /* @__PURE__ */ jsx(
1940
- AddIcon,
1941
- {
1942
- className: cn(
1943
- "oui-cursor-pointer oui-fill-base-contrast-54 hover:oui-fill-base-contrast"
1944
- ),
1945
- onClick: () => {
1946
- setOpen(true);
2091
+ var useAccountValue = (mainAccountId) => {
2092
+ const [accountValue, setAccountValue] = useState({});
2093
+ const {
2094
+ data: newPositions = [],
2095
+ isLoading: isPositionLoading,
2096
+ mutate: mutatePositions
2097
+ } = useSubAccountQuery("/v1/client/aggregate/positions", {
2098
+ // formatter: (data) => data,
2099
+ errorRetryCount: 3,
2100
+ accountId: mainAccountId
2101
+ });
2102
+ useEffect(() => {
2103
+ if (isPositionLoading) {
2104
+ return;
2105
+ }
2106
+ if (!newPositions || newPositions.length === 0) {
2107
+ setAccountValue({});
2108
+ return;
2109
+ }
2110
+ const value = newPositions.reduce(
2111
+ (acc, position) => {
2112
+ const accountId = position.account_id;
2113
+ if (acc[accountId]) {
2114
+ acc[accountId] = new Decimal(acc[accountId]).plus(position.unsettled_pnl).toNumber();
2115
+ } else {
2116
+ acc[accountId] = new Decimal(position.unsettled_pnl).toNumber();
1947
2117
  }
1948
- }
2118
+ return acc;
2119
+ },
2120
+ {}
1949
2121
  );
1950
- }, [subAccountCount, maxSubAccountCount]);
1951
- const header = /* @__PURE__ */ jsxs(
1952
- Flex,
1953
- {
1954
- py: 3,
1955
- direction: "column",
1956
- justify: "between",
1957
- itemAlign: "start",
1958
- width: "100%",
1959
- children: [
1960
- /* @__PURE__ */ jsx(Text, { weight: "semibold", children: t("subAccount.modal.create.title") }),
1961
- /* @__PURE__ */ jsx(Text, { className: "oui-text-2xs oui-text-base-contrast-36", children: t("subAccount.modal.create.description", {
1962
- subAccountCount,
1963
- remainingCount: maxSubAccountCount - subAccountCount
1964
- }) })
1965
- ]
1966
- }
1967
- );
1968
- const reset = () => {
1969
- setNickName("");
1970
- setInvalid(false);
1971
- setLoading(false);
2122
+ setAccountValue(value);
2123
+ }, [newPositions, isPositionLoading]);
2124
+ return {
2125
+ accountValue
1972
2126
  };
1973
- const validateNickName = (nickName2) => {
1974
- if (!nickName2 || !(nickName2.length >= 1 && nickName2.length <= 20)) {
1975
- setInvalid(true);
1976
- return true;
2127
+ };
2128
+
2129
+ // src/components/subAccount/subAccount.script.ts
2130
+ var SubAccountScript = () => {
2131
+ const [open2, setOpen] = useState(false);
2132
+ const [mainAccountHolding, setMainAccountHolding] = useState(
2133
+ []
2134
+ );
2135
+ const { wallet, connectedChain } = useWalletConnector();
2136
+ const { data: indexPrices } = useIndexPricesStream();
2137
+ const { isMobile } = useScreen();
2138
+ const { state, account, subAccount, switchAccount } = useAccount();
2139
+ const { t } = useTranslation();
2140
+ const mainAccountId = state.mainAccountId;
2141
+ const { accountValue } = useAccountValue(mainAccountId);
2142
+ const currentAccountId = state.accountId;
2143
+ const hasRefreshedRef = useRef(false);
2144
+ const userAddress = useMemo(() => {
2145
+ let address = state.address;
2146
+ if (connectedChain?.id && ABSTRACT_CHAIN_ID_MAP.has(parseInt(connectedChain?.id))) {
2147
+ address = account.getAdditionalInfo()?.AGWAddress;
1977
2148
  }
1978
- setInvalid(false);
1979
- return false;
1980
- };
1981
- const doCreatSubAccount = (nickName2) => {
1982
- let _nickName = `Sub-account ${subAccountCount + 1}`;
1983
- if (nickName2) {
1984
- _nickName = nickName2.trim();
2149
+ return address;
2150
+ }, [wallet, state, account, connectedChain]);
2151
+ const subAccounts = useMemo(() => {
2152
+ if (!state.subAccounts || !state.subAccounts.length) {
2153
+ return [];
1985
2154
  }
1986
- setLoading(true);
1987
- props.create(_nickName).then((res) => {
1988
- reset();
1989
- toast.success(t("subAccount.modal.create.success.description"));
1990
- setOpen(false);
1991
- }).catch((e) => {
1992
- toast.error(t("subAccount.modal.create.failed.description"));
1993
- }).finally(() => {
1994
- setLoading(false);
1995
- });
1996
- };
1997
- return /* @__PURE__ */ jsxs(Fragment, { children: [
1998
- trigger,
1999
- /* @__PURE__ */ jsx(
2000
- SimpleDialog,
2001
- {
2002
- title: header,
2003
- open: open2,
2004
- onOpenChange: (open3) => {
2005
- reset();
2006
- setOpen(open3);
2007
- },
2008
- size: isMobile ? "sm" : "xl",
2009
- actions: {
2010
- primary: {
2011
- label: t("common.confirm"),
2012
- disabled: invalid || loading,
2013
- loading,
2014
- onClick: () => {
2015
- const invalid2 = validateNickName(nickName);
2016
- if (invalid2) {
2017
- return;
2018
- }
2019
- doCreatSubAccount(nickName);
2020
- }
2021
- }
2022
- },
2023
- classNames: {
2024
- content: "oui-w-[360px]"
2025
- },
2155
+ const currentSubAccount = state.subAccounts.find(
2156
+ (subAccount2) => subAccount2.id === currentAccountId
2157
+ );
2158
+ if (currentSubAccount) {
2159
+ return [
2160
+ currentSubAccount,
2161
+ ...state.subAccounts.filter(
2162
+ (subAccount2) => subAccount2.id !== currentAccountId
2163
+ )
2164
+ ];
2165
+ }
2166
+ return [...state.subAccounts];
2167
+ }, [state.subAccounts, currentAccountId]);
2168
+ const _popup = useMemo(
2169
+ () => ({ mode: isMobile ? "sheet" : "modal" }),
2170
+ [isMobile]
2171
+ );
2172
+ const doCreatSubAccount = useCallback(
2173
+ (nickName) => {
2174
+ return subAccount.create(nickName);
2175
+ },
2176
+ [subAccount]
2177
+ );
2178
+ const onSwitch = useCallback(
2179
+ (accountId) => {
2180
+ return switchAccount(accountId).catch((error) => {
2181
+ }).then((res) => {
2182
+ toast.success(t("subAccount.modal.switch.success.description"));
2183
+ });
2184
+ },
2185
+ [switchAccount]
2186
+ );
2187
+ const accountsWithValues = useMemo(() => {
2188
+ const mainAccountUnsettlePnl = accountValue[mainAccountId] ?? 0;
2189
+ const mainAccount = mainAccountId && state.address ? {
2190
+ id: mainAccountId,
2191
+ userAddress: state.address,
2192
+ holding: mainAccountHolding,
2193
+ accountValue: calculateAccountValue(
2194
+ mainAccountHolding,
2195
+ mainAccountUnsettlePnl,
2196
+ indexPrices || EMPTY_OBJECT
2197
+ )
2198
+ } : void 0;
2199
+ const updatedSubAccounts = subAccounts.map((subAccount2) => {
2200
+ const subAccountUnsettlePnl = accountValue[subAccount2.id] ?? 0;
2201
+ return {
2202
+ ...subAccount2,
2203
+ accountValue: calculateAccountValue(
2204
+ subAccount2.holding || EMPTY_LIST,
2205
+ subAccountUnsettlePnl,
2206
+ indexPrices || EMPTY_OBJECT
2207
+ )
2208
+ };
2209
+ });
2210
+ return {
2211
+ mainAccount,
2212
+ subAccounts: updatedSubAccounts
2213
+ };
2214
+ }, [
2215
+ mainAccountId,
2216
+ state.address,
2217
+ mainAccountHolding,
2218
+ subAccounts,
2219
+ accountValue,
2220
+ indexPrices
2221
+ ]);
2222
+ useEffect(() => {
2223
+ if (!open2) {
2224
+ hasRefreshedRef.current = false;
2225
+ return;
2226
+ }
2227
+ if (!hasRefreshedRef.current && mainAccountId) {
2228
+ hasRefreshedRef.current = true;
2229
+ subAccount.refresh().then((res) => {
2230
+ setMainAccountHolding(res[mainAccountId] || []);
2231
+ });
2232
+ }
2233
+ }, [open2, mainAccountId, subAccount]);
2234
+ return {
2235
+ userAddress,
2236
+ mainAccount: accountsWithValues.mainAccount,
2237
+ currentAccountId,
2238
+ open: open2,
2239
+ onOpenChange: setOpen,
2240
+ popup: _popup,
2241
+ createSubAccount: doCreatSubAccount,
2242
+ subAccounts: accountsWithValues.subAccounts,
2243
+ onSwitch
2244
+ };
2245
+ };
2246
+ var calculateAccountValue = (holdings, unsettlePnl, indexPrices) => {
2247
+ const holding = holdings.reduce((acc, holding2) => {
2248
+ const price = getTokenIndexPrice(holding2.token, indexPrices);
2249
+ if (!price) {
2250
+ return acc;
2251
+ }
2252
+ return new Decimal(holding2.holding).times(price).add(holding2.isolated_margin ?? 0).add(acc).toNumber();
2253
+ }, 0);
2254
+ return holding + unsettlePnl;
2255
+ };
2256
+ var getTokenIndexPrice = (token, indexPrices) => {
2257
+ if (token === "USDC") {
2258
+ return 1;
2259
+ }
2260
+ const symbol = `PERP_${token}_USDC`;
2261
+ return indexPrices[symbol] ?? 0;
2262
+ };
2263
+ var SubAccountIcon = forwardRef(
2264
+ (props, ref) => {
2265
+ const { size = 20, ...rest } = props;
2266
+ return /* @__PURE__ */ jsx(
2267
+ "svg",
2268
+ {
2269
+ width: size,
2270
+ height: size,
2271
+ viewBox: "0 0 20 20",
2272
+ fill: "currentColor",
2273
+ xmlns: "http://www.w3.org/2000/svg",
2274
+ ref,
2275
+ ...rest,
2026
2276
  children: /* @__PURE__ */ jsx(
2027
- NickNameTextField,
2277
+ "path",
2028
2278
  {
2029
- nickName,
2030
- setNickName: (nickName2) => {
2031
- validateNickName(nickName2);
2032
- setNickName(nickName2);
2033
- },
2034
- subAccountCount,
2035
- invalid
2279
+ d: "M10 2.5C8.16892 2.5 6.66667 4.00225 6.66667 5.83333C6.66667 7.66441 8.16892 9.16667 10 9.16667C11.8311 9.16667 13.3333 7.66441 13.3333 5.83333C13.3333 4.00225 11.8311 2.5 10 2.5ZM10 4.16667C10.9303 4.16667 11.6667 4.90299 11.6667 5.83333C11.6667 6.76368 10.9303 7.5 10 7.5C9.06965 7.5 8.33333 6.76368 8.33333 5.83333C8.33333 4.90299 9.06965 4.16667 10 4.16667ZM10 11.6667C8.54587 11.6667 6.82264 12.0082 5.37435 12.5798C4.65021 12.8656 3.99558 13.205 3.47168 13.641C2.94778 14.0769 2.5 14.6662 2.5 15.4167V17.5H17.5V16.6667V15.4167C17.5 14.6662 17.0522 14.0769 16.5283 13.641C16.0044 13.205 15.3498 12.8656 14.6257 12.5798C13.1774 12.0082 11.4541 11.6667 10 11.6667ZM10 13.3333C11.1784 13.3333 12.7884 13.645 14.0153 14.1292C14.6288 14.3713 15.1475 14.66 15.4622 14.9219C15.777 15.1838 15.8333 15.3622 15.8333 15.4167V15.8333H4.16667V15.4167C4.16667 15.3622 4.22299 15.1838 4.53776 14.9219C4.85253 14.66 5.37124 14.3713 5.9847 14.1292C7.21162 13.645 8.82163 13.3333 10 13.3333Z",
2280
+ className: "oui-fill-base-contrast-98"
2036
2281
  }
2037
2282
  )
2038
2283
  }
2039
- )
2040
- ] });
2041
- };
2042
- var EditNickNameDialog = (props) => {
2043
- const { subAccount } = useAccount();
2044
- const [loading, setLoading] = useState(false);
2045
- const { t } = useTranslation();
2046
- const [newNickName, setNewNickName] = useState(void 0);
2047
- const [invalid, setInvalid] = useState(false);
2048
- const validateNickName = (nickName) => {
2049
- if (!nickName || !(nickName.length >= 1 && nickName.length <= 20)) {
2050
- setInvalid(true);
2051
- return true;
2284
+ );
2285
+ }
2286
+ );
2287
+ var SwapIcon = forwardRef((props, ref) => {
2288
+ const { size = 20, ...rest } = props;
2289
+ return /* @__PURE__ */ jsx(
2290
+ "svg",
2291
+ {
2292
+ width: size,
2293
+ height: size,
2294
+ viewBox: "0 0 20 20",
2295
+ fill: "currentColor",
2296
+ xmlns: "http://www.w3.org/2000/svg",
2297
+ ref,
2298
+ ...rest,
2299
+ children: /* @__PURE__ */ jsx("path", { d: "M6 16L2 12L6 8L7.0625 9.0625L4.875 11.25H11V12.75H4.875L7.0625 14.9375L6 16ZM14 11L12.9375 9.9375L15.125 7.75H9V6.25H15.125L12.9375 4.0625L14 3L18 7L14 11Z" })
2052
2300
  }
2053
- setInvalid(false);
2054
- };
2055
- useEffect(() => {
2056
- setNewNickName(props.nickName);
2057
- setInvalid(false);
2058
- setLoading(false);
2059
- }, [props.nickName, props.open]);
2301
+ );
2302
+ });
2303
+ var AddIcon = forwardRef((props, ref) => {
2304
+ const { size = 20, ...rest } = props;
2060
2305
  return /* @__PURE__ */ jsx(
2061
- SimpleDialog,
2306
+ "svg",
2062
2307
  {
2063
- title: /* @__PURE__ */ jsx(Text, { children: t("subAccount.modal.edit.title") }),
2064
- open: props.open,
2065
- onOpenChange: props.onOpenChange,
2066
- classNames: {
2067
- content: "oui-w-[360px]"
2068
- },
2069
- actions: {
2070
- primary: {
2071
- label: t("common.confirm"),
2072
- disabled: loading || invalid,
2073
- loading,
2074
- onClick: () => {
2075
- if (validateNickName(newNickName)) {
2076
- return;
2077
- }
2078
- setLoading(true);
2079
- subAccount?.update({
2080
- subAccountId: props.accountId,
2081
- description: newNickName
2082
- }).catch((e) => {
2083
- toast.error(t("subAccount.modal.edit.failed.description"));
2084
- }).then((res) => {
2085
- toast.success(t("subAccount.modal.edit.success.description"));
2086
- props.onOpenChange(false);
2087
- }).finally(() => {
2088
- setLoading(false);
2089
- });
2090
- }
2091
- },
2092
- secondary: {
2093
- label: t("common.cancel"),
2094
- onClick: () => props.onOpenChange(false)
2095
- }
2096
- },
2097
- children: /* @__PURE__ */ jsx(
2098
- NickNameTextField,
2099
- {
2100
- nickName: newNickName,
2101
- setNickName: (nickName) => {
2102
- validateNickName(nickName);
2103
- setNewNickName(nickName ?? "");
2104
- },
2105
- invalid
2106
- }
2107
- )
2308
+ width: size,
2309
+ height: size,
2310
+ viewBox: "0 0 20 20",
2311
+ fill: "currentColor",
2312
+ xmlns: "http://www.w3.org/2000/svg",
2313
+ ref,
2314
+ ...rest,
2315
+ children: /* @__PURE__ */ jsx("path", { d: "M9.25 14H10.75V10.75H14V9.25H10.75V6H9.25V9.25H6V10.75H9.25V14ZM4.5 17C4.0875 17 3.73437 16.8531 3.44062 16.5594C3.14687 16.2656 3 15.9125 3 15.5V4.5C3 4.0875 3.14687 3.73438 3.44062 3.44063C3.73437 3.14688 4.0875 3 4.5 3H15.5C15.9125 3 16.2656 3.14688 16.5594 3.44063C16.8531 3.73438 17 4.0875 17 4.5V15.5C17 15.9125 16.8531 16.2656 16.5594 16.5594C16.2656 16.8531 15.9125 17 15.5 17H4.5ZM4.5 15.5H15.5V4.5H4.5V15.5Z" })
2108
2316
  }
2109
2317
  );
2110
- };
2111
- function SubAccountUI(props) {
2112
- const { t } = useTranslation();
2113
- const { isMobile } = useScreen();
2114
- const timer = useRef(null);
2115
- const onMouseEnter = useCallback(() => {
2116
- if (timer.current) {
2117
- clearTimeout(timer.current);
2118
- timer.current = null;
2318
+ });
2319
+ var EditIcon = forwardRef((props, ref) => {
2320
+ const { size = 12, ...rest } = props;
2321
+ return /* @__PURE__ */ jsx(
2322
+ "svg",
2323
+ {
2324
+ width: size,
2325
+ height: size,
2326
+ viewBox: "0 0 12 12",
2327
+ fill: "currentColor",
2328
+ xmlns: "http://www.w3.org/2000/svg",
2329
+ ref,
2330
+ ...rest,
2331
+ children: /* @__PURE__ */ jsx("path", { d: "M9.95551 2.00049C9.81619 2.00049 9.67686 2.05318 9.57074 2.15918L5.43256 6.29785L5.24945 7.25049L6.20209 7.06738L10.3403 2.9292C10.443 2.82645 10.4999 2.68968 10.4999 2.54443C10.4999 2.39918 10.443 2.26218 10.3403 2.15918C10.2341 2.05318 10.0948 2.00049 9.95551 2.00049ZM3.12494 2.25C2.37147 2.25 1.74994 2.87153 1.74994 3.625V9.375C1.74994 10.1285 2.37147 10.75 3.12494 10.75H8.87494C9.62841 10.75 10.2499 10.1285 10.2499 9.375V5.25C10.2509 5.18374 10.2386 5.11796 10.2139 5.05648C10.1892 4.99499 10.1525 4.93903 10.106 4.89185C10.0595 4.84466 10.0041 4.8072 9.94293 4.78162C9.8818 4.75605 9.8162 4.74288 9.74994 4.74288C9.68368 4.74288 9.61807 4.75605 9.55695 4.78162C9.49582 4.8072 9.44038 4.84466 9.39386 4.89185C9.34734 4.93903 9.31066 4.99499 9.28595 5.05648C9.26124 5.11796 9.249 5.18374 9.24994 5.25V9.375C9.24994 9.58803 9.08797 9.75 8.87494 9.75H3.12494C2.91191 9.75 2.74994 9.58803 2.74994 9.375V3.625C2.74994 3.41197 2.91191 3.25 3.12494 3.25H7.24994C7.3162 3.25094 7.38198 3.2387 7.44346 3.21399C7.50494 3.18928 7.5609 3.1526 7.60809 3.10608C7.65527 3.05956 7.69274 3.00412 7.71832 2.94299C7.74389 2.88186 7.75706 2.81626 7.75706 2.75C7.75706 2.68374 7.74389 2.61814 7.71832 2.55701C7.69274 2.49588 7.65527 2.44044 7.60809 2.39392C7.5609 2.3474 7.50494 2.31072 7.44346 2.28601C7.38198 2.2613 7.3162 2.24906 7.24994 2.25H3.12494Z" })
2119
2332
  }
2120
- }, []);
2121
- const header = /* @__PURE__ */ jsx(Text, { weight: "semibold", children: t("subAccount.modal.title") });
2122
- const trigger = useMemo(() => {
2123
- if (props.customTrigger && isMobile) {
2124
- return /* @__PURE__ */ jsx("div", { onClick: () => props.onOpenChange(true), children: props.customTrigger });
2333
+ );
2334
+ });
2335
+ var AccountIdForCopy = (props) => {
2336
+ const { t } = useTranslation();
2337
+ const info = useMemo(() => {
2338
+ return {
2339
+ leading: props.accountId.slice(0, 6),
2340
+ middle: props.accountId.slice(6, -4),
2341
+ trailing: props.accountId.slice(-4)
2342
+ };
2343
+ }, [props.accountId]);
2344
+ const copy = useCallback(() => {
2345
+ navigator.clipboard.writeText(props.accountId);
2346
+ toast.success(t("common.copy.copied"));
2347
+ }, [props.accountId]);
2348
+ return /* @__PURE__ */ jsxs(
2349
+ Flex,
2350
+ {
2351
+ className: "oui-min-h-[50px] oui-w-[180px]",
2352
+ gap: 2,
2353
+ justify: "between",
2354
+ itemAlign: "center",
2355
+ children: [
2356
+ /* @__PURE__ */ jsxs(Text, { className: "oui-w-full oui-break-all oui-text-2xs oui-text-base-contrast-36", children: [
2357
+ /* @__PURE__ */ jsx(Text, { className: "oui-text-base-contrast", children: info.leading }),
2358
+ /* @__PURE__ */ jsx(Text, { children: info.middle }),
2359
+ /* @__PURE__ */ jsx(Text, { className: "oui-text-base-contrast", children: info.trailing })
2360
+ ] }),
2361
+ /* @__PURE__ */ jsx(
2362
+ CopyIcon,
2363
+ {
2364
+ onClick: copy,
2365
+ className: "oui-cursor-pointer oui-text-base-contrast-36 hover:oui-text-base-contrast"
2366
+ }
2367
+ )
2368
+ ]
2125
2369
  }
2126
- if (isMobile) {
2127
- return /* @__PURE__ */ jsx(
2128
- Flex,
2129
- {
2130
- className: "oui-size-8 oui-rounded-md oui-bg-base-6",
2131
- itemAlign: "center",
2132
- justify: "center",
2133
- children: /* @__PURE__ */ jsx(
2134
- SubAccountIcon,
2135
- {
2136
- className: cn("oui-cursor-pointer"),
2137
- onClick: () => props.onOpenChange(true)
2370
+ );
2371
+ };
2372
+ var AccountItem = (props) => {
2373
+ const { t } = useTranslation();
2374
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(
2375
+ Flex,
2376
+ {
2377
+ justify: "between",
2378
+ itemAlign: "center",
2379
+ width: "100%",
2380
+ className: cn(
2381
+ "oui-relative oui-cursor-pointer oui-rounded-[6px] oui-bg-base-6 oui-px-3 oui-py-4",
2382
+ "oui-border oui-border-base-6",
2383
+ props.isCurrent && " oui-border-[rgb(var(--oui-gradient-brand-start))] ",
2384
+ !props.isCurrent && "hover:oui-border-base-contrast-16"
2385
+ ),
2386
+ children: [
2387
+ /* @__PURE__ */ jsx(
2388
+ "div",
2389
+ {
2390
+ className: "oui-absolute oui-inset-0 oui-z-0 ",
2391
+ onClick: () => {
2392
+ if (props.isCurrent) {
2393
+ return;
2394
+ }
2395
+ props.onSwitch?.(props.accountId);
2138
2396
  }
2139
- )
2140
- }
2141
- );
2397
+ }
2398
+ ),
2399
+ props.isCurrent && /* @__PURE__ */ jsx(
2400
+ "div",
2401
+ {
2402
+ className: cn(
2403
+ "oui-absolute -oui-right-[1px] -oui-top-[1px] oui-leading-3",
2404
+ "oui-text-[10px] oui-font-semibold oui-text-base-10",
2405
+ "oui-rounded-[6px] oui-rounded-br-none oui-rounded-tl-none oui-bg-[rgb(var(--oui-gradient-brand-start))] oui-py-0.5 oui-pl-1 oui-pr-[5px]"
2406
+ ),
2407
+ children: t("subAccount.modal.current")
2408
+ }
2409
+ ),
2410
+ /* @__PURE__ */ jsxs(
2411
+ Flex,
2412
+ {
2413
+ direction: "column",
2414
+ itemAlign: "start",
2415
+ gap: 1,
2416
+ className: "oui-z-[2]",
2417
+ children: [
2418
+ props.isMainAccount ? /* @__PURE__ */ jsx(Text, { className: "oui-text-xs oui-leading-3 oui-text-base-contrast", children: formatAddress(props.userAddress ?? "") }) : /* @__PURE__ */ jsxs(
2419
+ Flex,
2420
+ {
2421
+ justify: "start",
2422
+ itemAlign: "center",
2423
+ className: "oui-cursor-pointer oui-gap-[2px] oui-fill-base-contrast-54 hover:oui-fill-base-contrast",
2424
+ onClick: (event) => {
2425
+ props.onEdit?.({
2426
+ accountId: props.accountId,
2427
+ description: props.description ?? ""
2428
+ });
2429
+ event.stopPropagation();
2430
+ event.preventDefault();
2431
+ },
2432
+ children: [
2433
+ /* @__PURE__ */ jsx(Text, { className: "oui-text-xs oui-leading-3 oui-text-base-contrast", children: props.description }),
2434
+ /* @__PURE__ */ jsx(EditIcon, { className: "oui-fill-base-contrast-54 hover:oui-fill-base-contrast" })
2435
+ ]
2436
+ }
2437
+ ),
2438
+ /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(AccountIdForCopy, { accountId: props.accountId }), children: /* @__PURE__ */ jsxs(Text, { className: "oui-text-2xs oui-leading-3 oui-text-base-contrast-36 hover:oui-text-base-contrast", children: [
2439
+ "ID: ",
2440
+ formatAddress(props.accountId)
2441
+ ] }) })
2442
+ ]
2443
+ },
2444
+ props.accountId
2445
+ ),
2446
+ /* @__PURE__ */ jsxs(
2447
+ Flex,
2448
+ {
2449
+ className: "oui-text-xs oui-text-base-contrast",
2450
+ itemAlign: "end",
2451
+ gap: 1,
2452
+ children: [
2453
+ /* @__PURE__ */ jsx(Text.numeral, { rule: "price", dp: 2, children: props.accountValue ?? 0 }),
2454
+ /* @__PURE__ */ jsx(Text, { children: "USDC" })
2455
+ ]
2456
+ }
2457
+ )
2458
+ ]
2142
2459
  }
2143
- return /* @__PURE__ */ jsx(SubAccountIcon, { className: cn("oui-cursor-pointer") });
2144
- }, [isMobile, props.customTrigger]);
2145
- const [editDialogOpen, setEditDialogOpen] = useState(false);
2146
- const [editAccountItem, setEditAccountItem] = useState(void 0);
2147
- const noSubAccount = /* @__PURE__ */ jsx(
2460
+ ) });
2461
+ };
2462
+ var NickNameTextField = (props) => {
2463
+ const { t } = useTranslation();
2464
+ return /* @__PURE__ */ jsx(
2465
+ TextField,
2466
+ {
2467
+ placeholder: `Sub-account ${(props.subAccountCount ?? 0) + 1}`,
2468
+ fullWidth: true,
2469
+ label: t("subAccount.modal.nickName.label"),
2470
+ value: props.nickName,
2471
+ onChange: (e) => {
2472
+ const _value = e.target.value.replace(/[^a-zA-Z0-9@,\s_-]/g, "");
2473
+ props.setNickName(_value);
2474
+ },
2475
+ formatters: [
2476
+ inputFormatter.createRegexInputFormatter(/[^a-zA-Z0-9@,\s_-]/g)
2477
+ ],
2478
+ classNames: {
2479
+ label: "oui-text-base-contrast-54 oui-text-xs",
2480
+ input: "placeholder:oui-text-base-contrast-20 placeholder:oui-text-sm"
2481
+ },
2482
+ maxLength: 20,
2483
+ minLength: 1,
2484
+ autoComplete: "off",
2485
+ helpText: t("subAccount.modal.create.nickname.role"),
2486
+ className: "oui-mb-4",
2487
+ color: props.invalid ? "danger" : void 0
2488
+ }
2489
+ );
2490
+ };
2491
+ var MAX_SUB_ACCOUNT_COUNT = 10;
2492
+ var CreateSubAccount = (props) => {
2493
+ const { t } = useTranslation();
2494
+ const { isMobile } = useScreen();
2495
+ const [open2, setOpen] = useState(false);
2496
+ const [nickName, setNickName] = useState(void 0);
2497
+ const { state } = useAccount();
2498
+ const [invalid, setInvalid] = useState(false);
2499
+ const [loading, setLoading] = useState(false);
2500
+ const { widgetConfigs } = useAppContext();
2501
+ const maxSubAccountCount = useMemo(() => {
2502
+ return widgetConfigs?.subAccount?.maxSubAccountCount ?? MAX_SUB_ACCOUNT_COUNT;
2503
+ }, [widgetConfigs]);
2504
+ const subAccountCount = useMemo(() => {
2505
+ return state.subAccounts?.length ?? 0;
2506
+ }, [state]);
2507
+ const trigger = useMemo(() => {
2508
+ return subAccountCount >= maxSubAccountCount ? /* @__PURE__ */ jsx(
2509
+ Tooltip,
2510
+ {
2511
+ className: "oui-max-w-[188px]",
2512
+ content: t("subAccount.modal.create.max.description"),
2513
+ children: /* @__PURE__ */ jsx(
2514
+ AddIcon,
2515
+ {
2516
+ className: cn("oui-cursor-not-allowed oui-fill-base-contrast-20")
2517
+ }
2518
+ )
2519
+ }
2520
+ ) : /* @__PURE__ */ jsx(
2521
+ AddIcon,
2522
+ {
2523
+ className: cn(
2524
+ "oui-cursor-pointer oui-fill-base-contrast-54 hover:oui-fill-base-contrast"
2525
+ ),
2526
+ onClick: () => {
2527
+ setOpen(true);
2528
+ }
2529
+ }
2530
+ );
2531
+ }, [subAccountCount, maxSubAccountCount]);
2532
+ const header = /* @__PURE__ */ jsxs(
2148
2533
  Flex,
2149
2534
  {
2535
+ py: 3,
2150
2536
  direction: "column",
2537
+ justify: "between",
2151
2538
  itemAlign: "start",
2152
- justify: "center",
2153
- px: 5,
2154
2539
  width: "100%",
2155
- className: "oui-h-[120px]",
2156
- children: /* @__PURE__ */ jsx(Text, { className: "oui-text-center oui-text-xs oui-font-semibold oui-text-base-contrast-36", children: t("subAccount.modal.noAccount.description") })
2540
+ children: [
2541
+ /* @__PURE__ */ jsx(Text, { weight: "semibold", children: t("subAccount.modal.create.title") }),
2542
+ /* @__PURE__ */ jsx(Text, { className: "oui-text-2xs oui-text-base-contrast-36", children: t("subAccount.modal.create.description", {
2543
+ subAccountCount,
2544
+ remainingCount: maxSubAccountCount - subAccountCount
2545
+ }) })
2546
+ ]
2157
2547
  }
2158
2548
  );
2159
- const renderSubAccount = () => {
2160
- if (!props.subAccounts?.length) {
2161
- return noSubAccount;
2549
+ const reset = () => {
2550
+ setNickName("");
2551
+ setInvalid(false);
2552
+ setLoading(false);
2553
+ };
2554
+ const validateNickName = (nickName2) => {
2555
+ if (!nickName2 || !(nickName2.length >= 1 && nickName2.length <= 20)) {
2556
+ setInvalid(true);
2557
+ return true;
2162
2558
  }
2163
- return /* @__PURE__ */ jsx(ScrollArea, { className: "oui-custom-scrollbar oui-max-h-[200px] oui-w-full oui-overflow-y-auto", children: /* @__PURE__ */ jsx(Flex, { direction: "column", gap: 2, itemAlign: "start", width: "100%", children: props.subAccounts.map((subAccount) => /* @__PURE__ */ jsx(
2164
- AccountItem,
2165
- {
2166
- accountId: subAccount.id,
2167
- description: subAccount.description,
2168
- isMainAccount: false,
2169
- isCurrent: subAccount.id === props.currentAccountId,
2170
- onSwitch: (accountId) => {
2171
- props.onSwitch?.(accountId);
2172
- },
2173
- accountValue: subAccount.accountValue ?? 0,
2174
- onEdit: () => {
2559
+ setInvalid(false);
2560
+ return false;
2561
+ };
2562
+ const doCreatSubAccount = (nickName2) => {
2563
+ let _nickName = `Sub-account ${subAccountCount + 1}`;
2564
+ if (nickName2) {
2565
+ _nickName = nickName2.trim();
2566
+ }
2567
+ setLoading(true);
2568
+ props.create(_nickName).then((res) => {
2569
+ reset();
2570
+ toast.success(t("subAccount.modal.create.success.description"));
2571
+ setOpen(false);
2572
+ }).catch((e) => {
2573
+ toast.error(t("subAccount.modal.create.failed.description"));
2574
+ }).finally(() => {
2575
+ setLoading(false);
2576
+ });
2577
+ };
2578
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
2579
+ trigger,
2580
+ /* @__PURE__ */ jsx(
2581
+ SimpleDialog,
2582
+ {
2583
+ title: header,
2584
+ open: open2,
2585
+ onOpenChange: (open3) => {
2586
+ reset();
2587
+ setOpen(open3);
2588
+ },
2589
+ size: isMobile ? "sm" : "xl",
2590
+ actions: {
2591
+ primary: {
2592
+ label: t("common.confirm"),
2593
+ disabled: invalid || loading,
2594
+ loading,
2595
+ onClick: () => {
2596
+ const invalid2 = validateNickName(nickName);
2597
+ if (invalid2) {
2598
+ return;
2599
+ }
2600
+ doCreatSubAccount(nickName);
2601
+ }
2602
+ }
2603
+ },
2604
+ classNames: {
2605
+ content: "oui-w-[360px]"
2606
+ },
2607
+ children: /* @__PURE__ */ jsx(
2608
+ NickNameTextField,
2609
+ {
2610
+ nickName,
2611
+ setNickName: (nickName2) => {
2612
+ validateNickName(nickName2);
2613
+ setNickName(nickName2);
2614
+ },
2615
+ subAccountCount,
2616
+ invalid
2617
+ }
2618
+ )
2619
+ }
2620
+ )
2621
+ ] });
2622
+ };
2623
+ var EditNickNameDialog = (props) => {
2624
+ const { subAccount } = useAccount();
2625
+ const [loading, setLoading] = useState(false);
2626
+ const { t } = useTranslation();
2627
+ const [newNickName, setNewNickName] = useState(void 0);
2628
+ const [invalid, setInvalid] = useState(false);
2629
+ const validateNickName = (nickName) => {
2630
+ if (!nickName || !(nickName.length >= 1 && nickName.length <= 20)) {
2631
+ setInvalid(true);
2632
+ return true;
2633
+ }
2634
+ setInvalid(false);
2635
+ };
2636
+ useEffect(() => {
2637
+ setNewNickName(props.nickName);
2638
+ setInvalid(false);
2639
+ setLoading(false);
2640
+ }, [props.nickName, props.open]);
2641
+ return /* @__PURE__ */ jsx(
2642
+ SimpleDialog,
2643
+ {
2644
+ title: /* @__PURE__ */ jsx(Text, { children: t("subAccount.modal.edit.title") }),
2645
+ open: props.open,
2646
+ onOpenChange: props.onOpenChange,
2647
+ classNames: {
2648
+ content: "oui-w-[360px]"
2649
+ },
2650
+ actions: {
2651
+ primary: {
2652
+ label: t("common.confirm"),
2653
+ disabled: loading || invalid,
2654
+ loading,
2655
+ onClick: () => {
2656
+ if (validateNickName(newNickName)) {
2657
+ return;
2658
+ }
2659
+ setLoading(true);
2660
+ subAccount?.update({
2661
+ subAccountId: props.accountId,
2662
+ description: newNickName
2663
+ }).catch((e) => {
2664
+ toast.error(t("subAccount.modal.edit.failed.description"));
2665
+ }).then((res) => {
2666
+ toast.success(t("subAccount.modal.edit.success.description"));
2667
+ props.onOpenChange(false);
2668
+ }).finally(() => {
2669
+ setLoading(false);
2670
+ });
2671
+ }
2672
+ },
2673
+ secondary: {
2674
+ label: t("common.cancel"),
2675
+ onClick: () => props.onOpenChange(false)
2676
+ }
2677
+ },
2678
+ children: /* @__PURE__ */ jsx(
2679
+ NickNameTextField,
2680
+ {
2681
+ nickName: newNickName,
2682
+ setNickName: (nickName) => {
2683
+ validateNickName(nickName);
2684
+ setNewNickName(nickName ?? "");
2685
+ },
2686
+ invalid
2687
+ }
2688
+ )
2689
+ }
2690
+ );
2691
+ };
2692
+ function SubAccountUI(props) {
2693
+ const { t } = useTranslation();
2694
+ const { isMobile } = useScreen();
2695
+ const timer = useRef(null);
2696
+ const onMouseEnter = useCallback(() => {
2697
+ if (timer.current) {
2698
+ clearTimeout(timer.current);
2699
+ timer.current = null;
2700
+ }
2701
+ }, []);
2702
+ const header = /* @__PURE__ */ jsx(Text, { weight: "semibold", children: t("subAccount.modal.title") });
2703
+ const trigger = useMemo(() => {
2704
+ if (props.customTrigger && isMobile) {
2705
+ return /* @__PURE__ */ jsx("div", { onClick: () => props.onOpenChange(true), children: props.customTrigger });
2706
+ }
2707
+ if (isMobile) {
2708
+ return /* @__PURE__ */ jsx(
2709
+ Flex,
2710
+ {
2711
+ className: "oui-size-8 oui-rounded-md oui-bg-base-6",
2712
+ itemAlign: "center",
2713
+ justify: "center",
2714
+ children: /* @__PURE__ */ jsx(
2715
+ SubAccountIcon,
2716
+ {
2717
+ className: cn("oui-cursor-pointer"),
2718
+ onClick: () => props.onOpenChange(true)
2719
+ }
2720
+ )
2721
+ }
2722
+ );
2723
+ }
2724
+ return /* @__PURE__ */ jsx(SubAccountIcon, { className: cn("oui-cursor-pointer") });
2725
+ }, [isMobile, props.customTrigger]);
2726
+ const [editDialogOpen, setEditDialogOpen] = useState(false);
2727
+ const [editAccountItem, setEditAccountItem] = useState(void 0);
2728
+ const noSubAccount = /* @__PURE__ */ jsx(
2729
+ Flex,
2730
+ {
2731
+ direction: "column",
2732
+ itemAlign: "start",
2733
+ justify: "center",
2734
+ px: 5,
2735
+ width: "100%",
2736
+ className: "oui-h-[120px]",
2737
+ children: /* @__PURE__ */ jsx(Text, { className: "oui-text-center oui-text-xs oui-font-semibold oui-text-base-contrast-36", children: t("subAccount.modal.noAccount.description") })
2738
+ }
2739
+ );
2740
+ const renderSubAccount = () => {
2741
+ if (!props.subAccounts?.length) {
2742
+ return noSubAccount;
2743
+ }
2744
+ return /* @__PURE__ */ jsx(ScrollArea, { className: "oui-custom-scrollbar oui-max-h-[200px] oui-w-full oui-overflow-y-auto", children: /* @__PURE__ */ jsx(Flex, { direction: "column", gap: 2, itemAlign: "start", width: "100%", children: props.subAccounts.map((subAccount) => /* @__PURE__ */ jsx(
2745
+ AccountItem,
2746
+ {
2747
+ accountId: subAccount.id,
2748
+ description: subAccount.description,
2749
+ isMainAccount: false,
2750
+ isCurrent: subAccount.id === props.currentAccountId,
2751
+ onSwitch: (accountId) => {
2752
+ props.onSwitch?.(accountId);
2753
+ },
2754
+ accountValue: subAccount.accountValue ?? 0,
2755
+ onEdit: () => {
2175
2756
  setEditAccountItem({
2176
2757
  accountId: subAccount.id,
2177
2758
  description: subAccount.description ?? ""
@@ -2466,14 +3047,7 @@ var LeftNavSheet = (props) => {
2466
3047
  }
2467
3048
  )
2468
3049
  ] }),
2469
- props.feedbackUrl && /* @__PURE__ */ jsx(
2470
- "div",
2471
- {
2472
- className: "oui-text-center oui-text-2xs oui-font-semibold oui-text-primary oui-underline",
2473
- onClick: () => openExternalLink(props.feedbackUrl),
2474
- children: t("leftNav.feedback")
2475
- }
2476
- )
3050
+ props.customFooter ?? /* @__PURE__ */ jsx(DefaultTradingViewTncLink, { className: "oui-text-center" })
2477
3051
  ] })
2478
3052
  ] })
2479
3053
  }
@@ -3528,732 +4102,113 @@ var MainNavMobile = (props) => {
3528
4102
  props.leading,
3529
4103
  languageSwitcher,
3530
4104
  scanQRCode,
3531
- chainMenu,
3532
- walletConnect,
3533
- props.trailing
3534
- ] })
3535
- ] });
3536
- };
3537
- return /* @__PURE__ */ jsx(
3538
- Flex,
3539
- {
3540
- width: "100%",
3541
- height: 44,
3542
- px: 3,
3543
- itemAlign: "center",
3544
- className: cn(props.className, props.classNames?.root),
3545
- children: renderContent()
3546
- }
3547
- );
3548
- };
3549
- var ScaffoldContext = createContext(
3550
- {}
3551
- );
3552
- var useScaffoldContext = () => {
3553
- return useContext(ScaffoldContext);
3554
- };
3555
- var NotificationUI = (props) => {
3556
- const { dataSource, showAnnouncement } = props;
3557
- const { routerAdapter } = useScaffoldContext();
3558
- const onItemClick = (url) => {
3559
- if (!url) return;
3560
- routerAdapter?.onRouteChange({
3561
- href: url,
3562
- name: url,
3563
- target: "_blank"
3564
- });
3565
- };
3566
- const notificationRef = useRef(null);
3567
- const len = useMemo(() => dataSource?.length ?? 0, [dataSource]);
3568
- const onClose = useCallback(() => {
3569
- if (len === 0) {
3570
- return;
3571
- }
3572
- windowGuard(() => {
3573
- if (notificationRef.current) {
3574
- const animationendHandler = () => {
3575
- props.onClose();
3576
- notificationRef.current.removeEventListener(
3577
- "transitionend",
3578
- animationendHandler
3579
- );
3580
- };
3581
- notificationRef.current.addEventListener(
3582
- "transitionend",
3583
- animationendHandler
3584
- );
3585
- requestAnimationFrame(() => {
3586
- notificationRef.current.style.transform = "translateY(120%)";
3587
- });
3588
- }
3589
- });
3590
- }, [props.onClose, len]);
3591
- useEffect(() => {
3592
- if (len === 0) {
3593
- return;
3594
- }
3595
- if (showAnnouncement) {
3596
- windowGuard(() => {
3597
- if (notificationRef.current) {
3598
- requestAnimationFrame(() => {
3599
- notificationRef.current.style.transform = "translateY(0)";
3600
- });
3601
- }
3602
- });
3603
- }
3604
- }, [showAnnouncement, len]);
3605
- if (len === 0) {
3606
- return null;
3607
- }
3608
- return /* @__PURE__ */ jsx(
3609
- "div",
3610
- {
3611
- ref: notificationRef,
3612
- "data-state": showAnnouncement ? "open" : "closed",
3613
- className: cn(
3614
- "oui-fixed oui-bottom-[calc(env(safe-area-inset-bottom)+8px)] oui-left-2 oui-z-50 oui-w-[calc(100%_-_16px)] oui-translate-y-[120%] oui-rounded-lg oui-border oui-border-line-6 oui-bg-base-8 md:oui-bottom-10 md:oui-left-auto md:oui-right-3 md:oui-w-[420px]",
3615
- "oui-transition-all oui-duration-300 oui-ease-in-out",
3616
- showAnnouncement ? "oui-visible" : "oui-invisible"
3617
- ),
3618
- children: /* @__PURE__ */ jsx(
3619
- NotificationUI$1,
3620
- {
3621
- dataSource,
3622
- onClose,
3623
- onItemClick
3624
- }
3625
- )
3626
- }
3627
- );
3628
- };
3629
- var NotificationWidget = () => {
3630
- const { announcementState } = useScaffoldContext();
3631
- return /* @__PURE__ */ jsx(
3632
- NotificationUI,
3633
- {
3634
- dataSource: announcementState.tips,
3635
- onClose: announcementState.closeTips,
3636
- showAnnouncement: announcementState.showAnnouncement
3637
- }
3638
- );
3639
- };
3640
- var LazyRestrictedInfoWidget = React6.lazy(
3641
- () => Promise.resolve().then(() => (init_restrictedInfo(), restrictedInfo_exports)).then((mod) => {
3642
- return { default: mod.RestrictedInfoWidget };
3643
- })
3644
- );
3645
- var LazyBottomNav = React6.lazy(
3646
- () => Promise.resolve().then(() => (init_bottomNav(), bottomNav_exports)).then((mod) => {
3647
- return { default: mod.BottomNav };
3648
- })
3649
- );
3650
- var MobileScaffold = (props) => {
3651
- const {
3652
- classNames,
3653
- topNavbarRef,
3654
- bottomNavHeight,
3655
- topBar,
3656
- mainNavProps,
3657
- routerAdapter,
3658
- bottomNavRef,
3659
- bottomNavProps,
3660
- bottomNav,
3661
- children
3662
- } = props;
3663
- return /* @__PURE__ */ jsxs(
3664
- "div",
3665
- {
3666
- style: {
3667
- paddingBottom: `calc(${bottomNavHeight}px + 12px + env(safe-area-inset-bottom))`
3668
- },
3669
- className: cn(
3670
- "oui-scaffold-root oui-w-full oui-bg-base-10 oui-pt-2",
3671
- classNames?.root
3672
- ),
3673
- children: [
3674
- /* @__PURE__ */ jsx(
3675
- "header",
3676
- {
3677
- ref: topNavbarRef,
3678
- className: cn(
3679
- "oui-scaffold-topNavbar",
3680
- "oui-sticky oui-top-0 oui-z-10 oui-w-full oui-bg-base-10",
3681
- classNames?.topNavbar
3682
- ),
3683
- children: topBar ?? /* @__PURE__ */ jsx(MainNavMobile, { ...mainNavProps, routerAdapter })
3684
- }
3685
- ),
3686
- /* @__PURE__ */ jsxs(
3687
- Box,
3688
- {
3689
- className: cn(
3690
- "oui-scaffold-container oui-overflow-hidden",
3691
- // "oui-relative",
3692
- // "oui-custom-scrollbar oui-overflow-y-auto",
3693
- classNames?.container
3694
- ),
3695
- children: [
3696
- /* @__PURE__ */ jsx(React6.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(LazyRestrictedInfoWidget, { className: "oui-mx-1 oui-mb-1 oui-bg-base-6" }) }),
3697
- /* @__PURE__ */ jsx(
3698
- Box,
3699
- {
3700
- height: "100%",
3701
- width: "100%",
3702
- className: cn("oui-scaffold-content", classNames?.content),
3703
- children
3704
- }
3705
- )
3706
- ]
3707
- }
3708
- ),
3709
- /* @__PURE__ */ jsx(
3710
- "footer",
3711
- {
3712
- ref: bottomNavRef,
3713
- className: cn(
3714
- "oui-scaffold-bottomNav",
3715
- "oui-fixed oui-bottom-0 oui-z-10",
3716
- "oui-w-full oui-bg-base-9",
3717
- // only effective on real device
3718
- "oui-pb-[calc(env(safe-area-inset-bottom))]",
3719
- classNames?.bottomNav
3720
- ),
3721
- children: bottomNav ?? /* @__PURE__ */ jsx(React6.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(
3722
- LazyBottomNav,
3723
- {
3724
- mainMenus: bottomNavProps?.mainMenus,
3725
- current: bottomNavProps?.current || mainNavProps?.initialMenu,
3726
- onRouteChange: routerAdapter?.onRouteChange
3727
- }
3728
- ) })
3729
- }
3730
- ),
3731
- /* @__PURE__ */ jsx(NotificationWidget, {})
3732
- ]
3733
- }
3734
- );
3735
- };
3736
- var useScaffoldScript = (options) => {
3737
- const { restrictedInfo, showAnnouncement } = useAppContext();
3738
- const [topNavbarRef, topNavbarHeight] = useRefAndHeight(48);
3739
- const [footerRef, footerHeight] = useRefAndHeight(29);
3740
- const [bottomNavRef, bottomNavHeight] = useRefAndHeight(64);
3741
- const [announcementRef, announcementHeight] = useRefAndHeight(0, [
3742
- showAnnouncement
3743
- ]);
3744
- const [expand, setExpand] = useLocalStorage(
3745
- "orderly_scaffold_expanded",
3746
- true
3747
- );
3748
- const { isMobile } = useScreen();
3749
- const sideBarExpandWidth = options.leftSideProps?.maxWidth || 185;
3750
- const sideBarCollaspedWidth = options.leftSideProps?.minWidth || 98;
3751
- const hasLeftSidebar = !!options.leftSidebar;
3752
- return {
3753
- topNavbarRef,
3754
- footerRef,
3755
- topNavbarHeight,
3756
- footerHeight,
3757
- announcementRef,
3758
- announcementHeight,
3759
- restrictedInfo,
3760
- expand,
3761
- setExpand,
3762
- isMobile,
3763
- sideBarExpandWidth,
3764
- sideBarCollaspedWidth,
3765
- hasLeftSidebar,
3766
- footerProps: options.footerProps,
3767
- routerAdapter: options.routerAdapter,
3768
- mainNavProps: options.mainNavProps,
3769
- bottomNavProps: options.bottomNavProps,
3770
- bottomNavRef,
3771
- bottomNavHeight
3772
- };
3773
- };
3774
- var useRefAndHeight = (defaultHeight, deps = []) => {
3775
- const ref = useRef(null);
3776
- const [height, setHeight] = useState(defaultHeight);
3777
- useObserverElement(ref.current, (entry) => {
3778
- setHeight(entry.contentRect.height);
3779
- });
3780
- useEffect(() => {
3781
- if (!ref.current) {
3782
- return;
3783
- }
3784
- const rect = ref.current?.getBoundingClientRect();
3785
- setHeight(rect.height);
3786
- }, [ref, ...deps]);
3787
- return [ref, height];
3788
- };
3789
-
3790
- // src/components/footer/footer.ui.tsx
3791
- init_icons();
3792
- var Footer = (props) => {
3793
- const { t } = useTranslation();
3794
- const signalClsName = useMemo(() => {
3795
- switch (props.wsStatus) {
3796
- case WsNetworkStatus.Connected:
3797
- return "oui-fill-success-light oui-text-success-light";
3798
- case WsNetworkStatus.Disconnected:
3799
- return "oui-fill-danger-light oui-text-danger-light";
3800
- case WsNetworkStatus.Unstable:
3801
- return "oui-fill-warning-light oui-text-warning-light";
3802
- }
3803
- }, [props.wsStatus]);
3804
- const openUrl = (url) => {
3805
- window.open(url, "_blank");
3806
- };
3807
- return /* @__PURE__ */ jsxs(
3808
- Flex,
3809
- {
3810
- direction: "row",
3811
- justify: "between",
3812
- height: 28,
3813
- px: 3,
3814
- width: "100%",
3815
- children: [
3816
- /* @__PURE__ */ jsxs(Flex, { children: [
3817
- /* @__PURE__ */ jsxs(
3818
- Flex,
3819
- {
3820
- direction: "row",
3821
- itemAlign: "center",
3822
- gap: 1,
3823
- className: signalClsName,
3824
- children: [
3825
- /* @__PURE__ */ jsx(
3826
- SignalIcon,
3827
- {
3828
- fillOpacity: 1,
3829
- fill: "currentColor"
3830
- }
3831
- ),
3832
- /* @__PURE__ */ jsx(Text, { size: "2xs", children: t("scaffold.footer.operational") })
3833
- ]
3834
- }
3835
- ),
3836
- /* @__PURE__ */ jsx(
3837
- Divider,
3838
- {
3839
- direction: "vertical",
3840
- className: "oui-h-[18px] oui-px-1 oui-ml-2 oui-border-line-12"
3841
- }
3842
- ),
3843
- /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
3844
- /* @__PURE__ */ jsx(Text, { intensity: 54, size: "2xs", children: t("scaffold.footer.joinCommunity") }),
3845
- /* @__PURE__ */ jsxs(Flex, { direction: "row", gap: 1, children: [
3846
- typeof props.telegramUrl !== "undefined" && /* @__PURE__ */ jsx(
3847
- CommuntiyTelegramIcon,
3848
- {
3849
- className: "oui-fill-base-contrast-54 hover:oui-fill-base-contrast oui-cursor-pointer",
3850
- fill: "currentColor",
3851
- fillOpacity: 1,
3852
- onClick: (e) => openUrl(props.telegramUrl)
3853
- }
3854
- ),
3855
- typeof props.discordUrl !== "undefined" && /* @__PURE__ */ jsx(
3856
- CommuntiyDiscordIcon,
3857
- {
3858
- className: "oui-fill-base-contrast-54 hover:oui-fill-base-contrast oui-cursor-pointer",
3859
- fill: "currentColor",
3860
- fillOpacity: 1,
3861
- onClick: (e) => openUrl(props.discordUrl)
3862
- }
3863
- ),
3864
- typeof props.twitterUrl !== "undefined" && /* @__PURE__ */ jsx(
3865
- CommuntiyXIcon,
3866
- {
3867
- className: "oui-fill-base-contrast-54 hover:oui-fill-base-contrast oui-cursor-pointer",
3868
- fill: "currentColor",
3869
- fillOpacity: 1,
3870
- onClick: (e) => openUrl(props.twitterUrl)
3871
- }
3872
- )
3873
- ] }),
3874
- typeof props?.trailing !== "undefined" && /* @__PURE__ */ jsxs(Fragment, { children: [
3875
- /* @__PURE__ */ jsx(
3876
- Divider,
3877
- {
3878
- direction: "vertical",
3879
- className: "oui-h-[18px] oui-border-line-12"
3880
- }
3881
- ),
3882
- props?.trailing
3883
- ] })
3884
- ] })
3885
- ] }),
3886
- /* @__PURE__ */ jsxs(
3887
- Flex,
3888
- {
3889
- direction: "row",
3890
- gap: 1,
3891
- className: "oui-scaffold-footer-powered-by",
3892
- children: [
3893
- /* @__PURE__ */ jsx(Text, { intensity: 54, size: "2xs", children: t("scaffold.footer.poweredBy") }),
3894
- /* @__PURE__ */ jsx(OrderlyTextIcon, {})
3895
- ]
3896
- }
3897
- )
3898
- ]
3899
- }
3900
- );
3901
- };
3902
- var useFooterScript = () => {
3903
- const wsStatus = useWsStatus();
3904
- return {
3905
- wsStatus
3906
- };
3907
- };
3908
- var FooterWidget = (props) => {
3909
- const state = useFooterScript();
3910
- return /* @__PURE__ */ jsx(Footer, { ...state, ...props });
3911
- };
3912
-
3913
- // src/components/scaffold/scaffold.ui.tsx
3914
- init_restrictedInfo();
3915
- var menuItemVariants = tv({
3916
- slots: {
3917
- button: [
3918
- "oui-min-h-10",
3919
- "oui-px-3",
3920
- "oui-py-2",
3921
- "oui-rounded-md",
3922
- "oui-w-full",
3923
- "oui-text-left",
3924
- "oui-text-base",
3925
- "oui-text-base-contrast-36",
3926
- // "oui-flex",
3927
- "oui-group",
3928
- // "oui-space-x-2",
3929
- // "oui-items-center",
3930
- "hover:oui-bg-base-8",
3931
- "oui-transition-colors",
3932
- "group-data-[state=closed]/bar:oui-w-[42px]",
3933
- "oui-overflow-hidden"
3934
- ],
3935
- icon: []
3936
- },
3937
- variants: {
3938
- mode: {
3939
- "icon-only": {
3940
- button: "oui-w-10",
3941
- icon: "w-6 h-6"
3942
- },
3943
- full: {
3944
- button: "oui-full",
3945
- icon: "w-6 h-6"
3946
- }
3947
- },
3948
- active: {
3949
- true: {
3950
- button: "oui-bg-base-5 hover:oui-bg-base-5"
3951
- }
3952
- },
3953
- open: {
3954
- true: {
3955
- button: ""
3956
- }
3957
- }
3958
- }
3959
- });
3960
- var MenuItem = React6.memo((props) => {
3961
- const { item, mode, open: open2, onClick, active, ...rest } = props;
3962
- const { button } = menuItemVariants({
3963
- mode,
3964
- active: props.active,
3965
- open: props.open
3966
- });
3967
- const children = /* @__PURE__ */ jsx(
3968
- "button",
3969
- {
3970
- "data-actived": props.active,
3971
- disabled: item.disabled,
3972
- className: button(),
3973
- onClick: () => {
3974
- props.onClick?.(item);
3975
- },
3976
- children: /* @__PURE__ */ jsxs(Flex, { itemAlign: "center", gap: 2, as: "span", children: [
3977
- /* @__PURE__ */ jsx("div", { children: item.icon }),
3978
- props.open && /* @__PURE__ */ jsx(
3979
- Text.gradient,
3980
- {
3981
- color: props.active ? "brand" : "inherit",
3982
- angle: 45,
3983
- size: "base",
3984
- className: "oui-break-all oui-animate-in oui-fade-in",
3985
- children: item.name
3986
- }
3987
- )
3988
- ] })
3989
- }
3990
- );
3991
- if (props.open) {
3992
- return /* @__PURE__ */ jsx("li", { className: "oui-min-w-[120px]", children });
3993
- }
3994
- return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(Tooltip, { content: item.name, side: "right", align: "center", sideOffset: 20, children }) });
3995
- });
3996
- MenuItem.displayName = "LeftMenuItem";
3997
- var SideMenus = (props) => {
3998
- return /* @__PURE__ */ jsxs(Box, { py: 6, children: [
3999
- /* @__PURE__ */ jsx(
4000
- "svg",
4001
- {
4002
- width: "18",
4003
- height: "18",
4004
- viewBox: "0 0 18 18",
4005
- fill: "none",
4006
- xmlns: "http://www.w3.org/2000/svg",
4007
- className: "oui-pointer-events-none oui-invisible oui-absolute",
4008
- children: /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs(
4009
- "linearGradient",
4010
- {
4011
- id: "side-menu-gradient",
4012
- x1: "15.7432",
4013
- y1: "8.94726",
4014
- x2: "2.24316",
4015
- y2: "8.94726",
4016
- gradientUnits: "userSpaceOnUse",
4017
- children: [
4018
- /* @__PURE__ */ jsx("stop", { stopColor: "rgb(var(--oui-gradient-brand-end))" }),
4019
- /* @__PURE__ */ jsx("stop", { stopColor: "rgb(var(--oui-gradient-brand-start))", offset: "1" })
4020
- ]
4021
- }
4022
- ) })
4023
- }
4024
- ),
4025
- /* @__PURE__ */ jsx("ul", { className: "oui-space-y-4", children: props.menus?.map((item, index) => {
4026
- if (item?.hide) {
4027
- return null;
4028
- }
4029
- return /* @__PURE__ */ jsx(
4030
- MenuItem,
4031
- {
4032
- item,
4033
- open: props.open,
4034
- active: item.href === props.current,
4035
- onClick: props.onItemSelect
4036
- },
4037
- index
4038
- );
4039
- }) })
4040
- ] });
4041
- };
4042
- var SideBarHeader = (props) => {
4043
- const { title } = props;
4044
- const titleElemet = typeof title === "string" ? /* @__PURE__ */ jsx(Text, { intensity: 54, size: "xs", children: title }) : title;
4045
- const iconProps = {
4046
- className: "oui-text-base-contrast-36 hover:oui-text-base-contrast-80 oui-cursor-pointer",
4047
- onClick: props.onToggle
4048
- };
4049
- return /* @__PURE__ */ jsxs(
4050
- Flex,
4051
- {
4052
- justify: props.open ? "between" : "center",
4053
- itemAlign: "center",
4054
- className: "oui-h-6",
4055
- children: [
4056
- props.open ? titleElemet : null,
4057
- props.open ? /* @__PURE__ */ jsx(CollapseIcon, { ...iconProps }) : /* @__PURE__ */ jsx(ExpandIcon, { ...iconProps })
4058
- ]
4059
- }
4060
- );
4061
- };
4062
- var SideBar = (props) => {
4063
- const { open: open2 = true, items, current, onItemSelect } = props;
4064
- return /* @__PURE__ */ jsxs(
4065
- Box,
4105
+ chainMenu,
4106
+ walletConnect,
4107
+ props.trailing
4108
+ ] })
4109
+ ] });
4110
+ };
4111
+ return /* @__PURE__ */ jsx(
4112
+ Flex,
4066
4113
  {
4067
- "data-state": open2 ? "opened" : "closed",
4068
- className: cn("oui-group/bar", props.className),
4069
- style: props.style,
4070
- children: [
4071
- /* @__PURE__ */ jsx(
4072
- SideBarHeader,
4073
- {
4074
- open: open2,
4075
- title: props.title,
4076
- onToggle: () => {
4077
- props.onOpenChange?.(!open2);
4078
- }
4079
- }
4080
- ),
4081
- /* @__PURE__ */ jsx(
4082
- SideMenus,
4083
- {
4084
- menus: items,
4085
- current,
4086
- onItemSelect,
4087
- open: open2
4088
- }
4089
- )
4090
- ]
4114
+ width: "100%",
4115
+ height: 44,
4116
+ px: 3,
4117
+ itemAlign: "center",
4118
+ className: cn(props.className, props.classNames?.root),
4119
+ children: renderContent()
4091
4120
  }
4092
4121
  );
4093
4122
  };
4094
- SideBar.displayName = "SideBar";
4095
- var ExpandIcon = (props) => /* @__PURE__ */ jsx(
4096
- "svg",
4097
- {
4098
- width: "16",
4099
- height: "16",
4100
- viewBox: "0 0 16 16",
4101
- fill: "currentColor",
4102
- xmlns: "http://www.w3.org/2000/svg",
4103
- ...props,
4104
- children: /* @__PURE__ */ jsx("path", { d: "M6.326 8.826a.84.84 0 0 0-.6.234L2.16 12.627v-2.135H.492v4.167c0 .46.373.833.834.833h4.166v-1.667H3.357l3.567-3.567a.857.857 0 0 0 0-1.198.84.84 0 0 0-.598-.234M10.502.492V2.16h2.135L9.07 5.726a.857.857 0 0 0 0 1.199.86.86 0 0 0 1.197 0l3.568-3.568v2.135h1.667V1.326a.834.834 0 0 0-.834-.834z" })
4105
- }
4123
+ var LazyRestrictedInfoWidget = React7.lazy(
4124
+ () => Promise.resolve().then(() => (init_restrictedInfo(), restrictedInfo_exports)).then((mod) => {
4125
+ return { default: mod.RestrictedInfoWidget };
4126
+ })
4106
4127
  );
4107
- var CollapseIcon = (props) => /* @__PURE__ */ jsx(
4108
- "svg",
4109
- {
4110
- width: "16",
4111
- height: "16",
4112
- viewBox: "0 0 16 16",
4113
- fill: "currentColor",
4114
- xmlns: "http://www.w3.org/2000/svg",
4115
- ...props,
4116
- children: /* @__PURE__ */ jsx("path", { d: "M14.668.492a.85.85 0 0 0-.599.234l-3.567 3.568V2.159H8.835v4.167c0 .46.373.833.833.833h4.167V5.492H11.7l3.569-3.567a.86.86 0 0 0 0-1.199.85.85 0 0 0-.6-.234m-12.5 8.334v1.666h2.135L.736 14.06a.86.86 0 0 0 0 1.198.86.86 0 0 0 1.198 0l3.568-3.567v2.134h1.666V9.66a.834.834 0 0 0-.833-.833z" })
4117
- }
4128
+ var LazyBottomNav = React7.lazy(
4129
+ () => Promise.resolve().then(() => (init_bottomNav(), bottomNav_exports)).then((mod) => {
4130
+ return { default: mod.BottomNav };
4131
+ })
4118
4132
  );
4119
- var useSideNavBuilder = (props) => {
4120
- const [current, setCurrent] = useState(props?.items?.[0].href || "/");
4121
- const { expanded, setExpand } = useScaffoldContext();
4122
- return {
4123
- items: [],
4124
- current,
4125
- open: expanded,
4126
- onOpenChange: (open2) => {
4127
- setExpand?.(open2);
4128
- },
4129
- onItemSelect: (item) => {
4130
- if (item.href) {
4131
- setCurrent(item.href);
4132
- }
4133
- },
4134
- ...props
4135
- };
4136
- };
4137
- var SideNavbarWidget = (props) => {
4138
- const state = useSideNavBuilder(props);
4139
- return /* @__PURE__ */ jsx(SideBar, { ...state });
4140
- };
4141
- var DesktopScaffold = (props) => {
4133
+ var MobileScaffold = (props) => {
4142
4134
  const {
4143
4135
  classNames,
4144
- footerHeight,
4145
4136
  topNavbarRef,
4146
- mainNavProps,
4137
+ bottomNavHeight,
4147
4138
  topBar,
4148
- announcementRef,
4149
- // restrictedInfo,
4150
- hasLeftSidebar,
4151
- expand,
4152
- leftSideProps,
4153
- leftSidebar,
4154
- footer,
4155
- footerRef,
4156
- sideBarCollaspedWidth,
4157
- sideBarExpandWidth,
4158
- footerProps,
4139
+ mainNavProps,
4140
+ routerAdapter,
4141
+ bottomNavRef,
4142
+ bottomNavProps,
4143
+ bottomNav,
4159
4144
  children
4160
4145
  } = props;
4161
4146
  return /* @__PURE__ */ jsxs(
4162
4147
  "div",
4163
4148
  {
4164
4149
  style: {
4165
- height: `calc(100vh - ${footerHeight}px)`
4150
+ paddingBottom: `calc(${bottomNavHeight}px + 12px + env(safe-area-inset-bottom))`
4166
4151
  },
4167
4152
  className: cn(
4168
- "oui-scaffold-root oui-font-semibold",
4169
- // default text and background color
4170
- "oui-bg-base-10 oui-text-base-contrast",
4171
- "oui-flex oui-flex-col",
4172
- "oui-custom-scrollbar oui-overflow-auto",
4153
+ "oui-scaffold-root oui-w-full oui-bg-base-10 oui-pt-2",
4173
4154
  classNames?.root
4174
4155
  ),
4175
4156
  children: [
4176
4157
  /* @__PURE__ */ jsx(
4177
- Box,
4158
+ "header",
4178
4159
  {
4179
4160
  ref: topNavbarRef,
4180
4161
  className: cn(
4181
- "oui-scaffold-topNavbar oui-bg-base-9",
4162
+ "oui-scaffold-topNavbar",
4163
+ "oui-sticky oui-top-0 oui-z-10 oui-w-full oui-bg-base-10",
4182
4164
  classNames?.topNavbar
4183
4165
  ),
4184
- children: topBar ?? /* @__PURE__ */ jsx(MainNavWidget, { ...mainNavProps })
4166
+ children: topBar ?? /* @__PURE__ */ jsx(MainNavMobile, { ...mainNavProps, routerAdapter })
4185
4167
  }
4186
4168
  ),
4187
4169
  /* @__PURE__ */ jsxs(
4188
- "div",
4170
+ Box,
4189
4171
  {
4190
4172
  className: cn(
4191
- "oui-scaffold-container",
4192
- "oui-relative oui-h-full",
4193
- // 1024px - 6px (scrollbar widt) = 1018px
4194
- "oui-min-w-[1018px]",
4173
+ "oui-scaffold-container oui-overflow-hidden",
4174
+ // "oui-relative",
4175
+ // "oui-custom-scrollbar oui-overflow-y-auto",
4195
4176
  classNames?.container
4196
4177
  ),
4197
4178
  children: [
4198
- /* @__PURE__ */ jsx(Box, { px: 2, ref: announcementRef, children: /* @__PURE__ */ jsx(
4199
- RestrictedInfoWidget,
4179
+ /* @__PURE__ */ jsx(React7.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(LazyRestrictedInfoWidget, { className: "oui-mx-1 oui-mb-1 oui-bg-base-6" }) }),
4180
+ /* @__PURE__ */ jsx(
4181
+ Box,
4200
4182
  {
4201
- className: cn(
4202
- "oui-scaffold-restricted-info",
4203
- "oui-relative oui-z-[1]",
4204
- "oui-mt-2",
4205
- "oui-bg-base-9",
4206
- "oui-min-w-[994px]"
4207
- )
4183
+ height: "100%",
4184
+ width: "100%",
4185
+ className: cn("oui-scaffold-content", classNames?.content),
4186
+ children
4208
4187
  }
4209
- ) }),
4210
- !hasLeftSidebar ? (
4211
- // ----------No leftSidebar layout start ---------
4212
- /* @__PURE__ */ jsx(Box, { height: "100%", className: cn(classNames?.content), children })
4213
- ) : (
4214
- // ----------No leftSidebar layout end ---------
4215
- // ---------- left & body layout start ---------
4216
- /* @__PURE__ */ jsxs(
4217
- Grid,
4218
- {
4219
- className: cn(
4220
- "oui-box-content oui-flex oui-transition-all xl:oui-grid",
4221
- "oui-min-h-full oui-flex-1",
4222
- classNames?.body
4223
- ),
4224
- style: {
4225
- gridTemplateColumns: `${expand ? `${sideBarExpandWidth}px` : `${sideBarCollaspedWidth}px`} 1fr`
4226
- // gridTemplateRows: "auto 1fr",
4227
- // gridTemplateAreas: `"left main" "left main"`,
4228
- },
4229
- children: [
4230
- /* @__PURE__ */ jsx("div", { className: cn(classNames?.leftSidebar), children: isValidElement(leftSidebar) ? leftSidebar : /* @__PURE__ */ jsx(SideNavbarWidget, { ...leftSideProps }) }),
4231
- /* @__PURE__ */ jsx(
4232
- Box,
4233
- {
4234
- width: "100%",
4235
- className: cn("oui-overflow-hidden", classNames?.content),
4236
- children
4237
- }
4238
- )
4239
- ]
4240
- }
4241
- )
4242
4188
  )
4243
4189
  ]
4244
4190
  }
4245
4191
  ),
4246
4192
  /* @__PURE__ */ jsx(
4247
- Box,
4193
+ "footer",
4248
4194
  {
4249
- ref: footerRef,
4195
+ ref: bottomNavRef,
4250
4196
  className: cn(
4251
- "oui-scaffold-footer oui-w-full oui-bg-base-10",
4252
- "oui-fixed oui-bottom-0 oui-z-50",
4253
- "oui-border-t oui-border-line-12",
4254
- classNames?.footer
4197
+ "oui-scaffold-bottomNav",
4198
+ "oui-fixed oui-bottom-0 oui-z-10",
4199
+ "oui-w-full oui-bg-base-9",
4200
+ // only effective on real device
4201
+ "oui-pb-[calc(env(safe-area-inset-bottom))]",
4202
+ classNames?.bottomNav
4255
4203
  ),
4256
- children: footer || /* @__PURE__ */ jsx(FooterWidget, { ...footerProps })
4204
+ children: bottomNav ?? /* @__PURE__ */ jsx(React7.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(
4205
+ LazyBottomNav,
4206
+ {
4207
+ mainMenus: bottomNavProps?.mainMenus,
4208
+ current: bottomNavProps?.current || mainNavProps?.initialMenu,
4209
+ onRouteChange: routerAdapter?.onRouteChange
4210
+ }
4211
+ ) })
4257
4212
  }
4258
4213
  ),
4259
4214
  /* @__PURE__ */ jsx(NotificationWidget, {})
@@ -4261,6 +4216,59 @@ var DesktopScaffold = (props) => {
4261
4216
  }
4262
4217
  );
4263
4218
  };
4219
+ var useScaffoldScript = (options) => {
4220
+ const { restrictedInfo, showAnnouncement } = useAppContext();
4221
+ const [topNavbarRef, topNavbarHeight] = useRefAndHeight(48);
4222
+ const [footerRef, footerHeight] = useRefAndHeight(29);
4223
+ const [bottomNavRef, bottomNavHeight] = useRefAndHeight(64);
4224
+ const [announcementRef, announcementHeight] = useRefAndHeight(0, [
4225
+ showAnnouncement
4226
+ ]);
4227
+ const [expand, setExpand] = useLocalStorage(
4228
+ "orderly_scaffold_expanded",
4229
+ true
4230
+ );
4231
+ const { isMobile } = useScreen();
4232
+ const sideBarExpandWidth = options.leftSideProps?.maxWidth || 185;
4233
+ const sideBarCollaspedWidth = options.leftSideProps?.minWidth || 98;
4234
+ const hasLeftSidebar = !!options.leftSidebar;
4235
+ return {
4236
+ topNavbarRef,
4237
+ footerRef,
4238
+ topNavbarHeight,
4239
+ footerHeight,
4240
+ announcementRef,
4241
+ announcementHeight,
4242
+ restrictedInfo,
4243
+ expand,
4244
+ setExpand,
4245
+ isMobile,
4246
+ sideBarExpandWidth,
4247
+ sideBarCollaspedWidth,
4248
+ hasLeftSidebar,
4249
+ footerProps: options.footerProps,
4250
+ routerAdapter: options.routerAdapter,
4251
+ mainNavProps: options.mainNavProps,
4252
+ bottomNavProps: options.bottomNavProps,
4253
+ bottomNavRef,
4254
+ bottomNavHeight
4255
+ };
4256
+ };
4257
+ var useRefAndHeight = (defaultHeight, deps = []) => {
4258
+ const ref = useRef(null);
4259
+ const [height, setHeight] = useState(defaultHeight);
4260
+ useObserverElement(ref.current, (entry) => {
4261
+ setHeight(entry.contentRect.height);
4262
+ });
4263
+ useEffect(() => {
4264
+ if (!ref.current) {
4265
+ return;
4266
+ }
4267
+ const rect = ref.current?.getBoundingClientRect();
4268
+ setHeight(rect.height);
4269
+ }, [ref, ...deps]);
4270
+ return [ref, height];
4271
+ };
4264
4272
 
4265
4273
  // src/utils/chain.ts
4266
4274
  function checkChainSupport(chainId, chains) {
@@ -4859,7 +4867,7 @@ var IdentityButton = (props) => {
4859
4867
  var AccountSummary = (props) => {
4860
4868
  const { keys, ...rest } = props;
4861
4869
  let canToggleIndex = 0;
4862
- const sizeRef = React6.useRef(0);
4870
+ const sizeRef = React7.useRef(0);
4863
4871
  useEffect(() => {
4864
4872
  const resizeObserver = new ResizeObserver((entries) => {
4865
4873
  if (Array.isArray(entries) && entries.length > 0) {