rujira.ui 1.0.5 → 1.0.7
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/lib/cjs/assets/images/spinnie.gif +0 -0
- package/lib/cjs/assets/images/txsimulate.gif +0 -0
- package/lib/cjs/assets/tokens/index.js +21 -0
- package/lib/cjs/components/AssetLabel.js +9 -0
- package/lib/cjs/components/balance/OmniBalance.js +34 -0
- package/lib/cjs/components/bridges/BuyModal.js +8 -0
- package/lib/cjs/components/bridges/DepositModal.js +144 -0
- package/lib/cjs/components/buttons/Button.js +52 -0
- package/lib/cjs/components/buttons/Popout.js +63 -0
- package/lib/cjs/components/buttons/TxButton.js +232 -0
- package/lib/cjs/components/buttons/__Popout.js +39 -0
- package/lib/cjs/components/cards/Card.js +12 -0
- package/lib/cjs/components/cards/GradientCard.js +12 -0
- package/lib/cjs/components/cards/ShareCard.js +16 -0
- package/lib/cjs/components/chart/RangeLiquidityChart.js +118 -0
- package/lib/cjs/components/footer/Footer.js +15 -0
- package/lib/cjs/components/header/Accounts.js +129 -0
- package/lib/cjs/components/header/Header.js +197 -0
- package/lib/cjs/components/header/Pending.js +47 -0
- package/lib/cjs/components/header/QuickLauncher.js +15 -0
- package/lib/cjs/components/header/ResolveLink.js +17 -0
- package/lib/cjs/components/icons/IconDenom.js +391 -0
- package/lib/cjs/components/icons/Icons.js +350 -0
- package/lib/cjs/components/icons/NetworkIcon.js +44 -0
- package/lib/cjs/components/icons/Networks.js +145 -0
- package/lib/cjs/components/icons/ProviderIcon.js +54 -0
- package/lib/cjs/components/icons/Wallets.js +140 -0
- package/lib/cjs/components/inputs/Checkbox.js +15 -0
- package/lib/cjs/components/inputs/DecimalInput.js +53 -0
- package/lib/cjs/components/inputs/DenomInput.js +29 -0
- package/lib/cjs/components/inputs/Input.js +29 -0
- package/lib/cjs/components/inputs/Numeric.js +36 -0
- package/lib/cjs/components/inputs/Radio.js +15 -0
- package/lib/cjs/components/inputs/Select.js +32 -0
- package/lib/cjs/components/inputs/SwapSelect.js +85 -0
- package/lib/cjs/components/inputs/Textarea.js +28 -0
- package/lib/cjs/components/inputs/Toggle.js +17 -0
- package/lib/cjs/components/loader/Loader.js +9 -0
- package/lib/cjs/components/loader/LoaderWithContent.js +11 -0
- package/lib/cjs/components/logos/RujiraLogo.js +10 -0
- package/lib/cjs/components/notices/Warning.js +14 -0
- package/lib/cjs/components/numbers/Decimal.js +33 -0
- package/lib/cjs/components/numbers/Fiat.js +22 -0
- package/lib/cjs/components/pagination/Pagination.js +15 -0
- package/lib/cjs/components/progress/Progress.js +13 -0
- package/lib/cjs/components/slider/Slider.js +9 -0
- package/lib/cjs/components/table/SortItem.js +52 -0
- package/lib/cjs/context/GlobalModal.js +48 -0
- package/lib/cjs/helpers/index.js +186 -0
- package/lib/cjs/helpers/index.test.js +51 -0
- package/lib/cjs/helpers/number.js +8 -0
- package/lib/cjs/hooks/useClickOutside.js +22 -0
- package/lib/cjs/hooks/useEventCallback.js +14 -0
- package/lib/cjs/hooks/useEventListener.js +57 -0
- package/lib/cjs/hooks/useIsTouchDevice.js +20 -0
- package/lib/cjs/hooks/useIsomorphicLayoutEffect.js +18 -0
- package/lib/cjs/hooks/useLocalStorage.js +123 -0
- package/lib/cjs/hooks/useQueryParam.js +36 -0
- package/lib/cjs/hooks/useWindowSize.js +51 -0
- package/lib/cjs/i18n/I18nProvider.js +54 -0
- package/lib/cjs/i18n/TranslationProvider.js +10 -0
- package/lib/cjs/i18n/config.js +101 -0
- package/lib/cjs/i18n/index.js +16 -0
- package/lib/cjs/i18n/locales/de/borrow.json +49 -0
- package/lib/cjs/i18n/locales/de/common.json +127 -0
- package/lib/cjs/i18n/locales/de/ecosystem.json +56 -0
- package/lib/cjs/i18n/locales/de/header.json +86 -0
- package/lib/cjs/i18n/locales/de/index.json +55 -0
- package/lib/cjs/i18n/locales/de/leagues.json +20 -0
- package/lib/cjs/i18n/locales/de/merge.json +41 -0
- package/lib/cjs/i18n/locales/de/portfolio.json +102 -0
- package/lib/cjs/i18n/locales/de/strategies.json +158 -0
- package/lib/cjs/i18n/locales/de/swap.json +30 -0
- package/lib/cjs/i18n/locales/de/trade.json +222 -0
- package/lib/cjs/i18n/locales/en/borrow.json +49 -0
- package/lib/cjs/i18n/locales/en/common.json +126 -0
- package/lib/cjs/i18n/locales/en/ecosystem.json +56 -0
- package/lib/cjs/i18n/locales/en/header.json +86 -0
- package/lib/cjs/i18n/locales/en/index.json +55 -0
- package/lib/cjs/i18n/locales/en/leagues.json +20 -0
- package/lib/cjs/i18n/locales/en/merge.json +41 -0
- package/lib/cjs/i18n/locales/en/portfolio.json +102 -0
- package/lib/cjs/i18n/locales/en/strategies.json +158 -0
- package/lib/cjs/i18n/locales/en/swap.json +30 -0
- package/lib/cjs/i18n/locales/en/trade.json +220 -0
- package/lib/cjs/i18n/useTranslation.js +21 -0
- package/lib/cjs/index.js +73 -0
- package/lib/cjs/package.json +3 -0
- package/lib/cjs/wallets/config/gaia.js +51 -0
- package/lib/cjs/wallets/config/index.js +9 -0
- package/lib/cjs/wallets/config/kujira.js +62 -0
- package/lib/cjs/wallets/config/noble.js +47 -0
- package/lib/cjs/wallets/config/osmo.js +51 -0
- package/lib/cjs/wallets/config/thor.js +50 -0
- package/lib/cjs/wallets/index.js +19 -0
- package/lib/cjs/wallets/providers/brave.js +4 -0
- package/lib/cjs/wallets/providers/coinbase.js +4 -0
- package/lib/cjs/wallets/providers/cosmos.js +152 -0
- package/lib/cjs/wallets/providers/ctrl.js +125 -0
- package/lib/cjs/wallets/providers/daodao.js +12 -0
- package/lib/cjs/wallets/providers/eip1193.js +155 -0
- package/lib/cjs/wallets/providers/eip6963.js +20 -0
- package/lib/cjs/wallets/providers/eip712.js +63 -0
- package/lib/cjs/wallets/providers/index.js +62 -0
- package/lib/cjs/wallets/providers/keplr.js +82 -0
- package/lib/cjs/wallets/providers/leap.js +36 -0
- package/lib/cjs/wallets/providers/ledger/Modal.js +23 -0
- package/lib/cjs/wallets/providers/ledger.js +93 -0
- package/lib/cjs/wallets/providers/metamask.js +4 -0
- package/lib/cjs/wallets/providers/okx.js +79 -0
- package/lib/cjs/wallets/providers/rabby.js +4 -0
- package/lib/cjs/wallets/providers/station.js +6 -0
- package/lib/cjs/wallets/providers/ton.js +57 -0
- package/lib/cjs/wallets/providers/tronlink.js +59 -0
- package/lib/cjs/wallets/providers/trust.js +4 -0
- package/lib/cjs/wallets/providers/utils.js +32 -0
- package/lib/cjs/wallets/providers/utxo.js +107 -0
- package/lib/cjs/wallets/providers/vulticonnect.js +161 -0
- package/lib/cjs/wallets/providers/vultisig.js +45 -0
- package/lib/cjs/wallets/providers/xaman.js +70 -0
- package/lib/cjs/wallets/storage.js +58 -0
- package/lib/esm/assets/images/spinnie.gif +0 -0
- package/lib/esm/assets/images/txsimulate.gif +0 -0
- package/lib/esm/components/balance/OmniBalance.d.ts +7 -2
- package/lib/esm/components/balance/OmniBalance.d.ts.map +1 -1
- package/lib/esm/components/balance/OmniBalance.js +9 -3
- package/lib/esm/components/bridges/DepositModal.d.ts +4 -0
- package/lib/esm/components/bridges/DepositModal.d.ts.map +1 -1
- package/lib/esm/components/bridges/DepositModal.js +26 -17
- package/lib/esm/components/buttons/TxButton.d.ts +1 -0
- package/lib/esm/components/buttons/TxButton.d.ts.map +1 -1
- package/lib/esm/components/buttons/TxButton.js +81 -20
- package/lib/esm/components/header/Accounts.d.ts +1 -1
- package/lib/esm/components/header/Accounts.d.ts.map +1 -1
- package/lib/esm/components/header/Accounts.js +7 -7
- package/lib/esm/components/header/Header.js +1 -1
- package/lib/esm/components/icons/ProviderIcon.d.ts +8 -0
- package/lib/esm/components/icons/ProviderIcon.d.ts.map +1 -0
- package/lib/esm/components/icons/ProviderIcon.js +50 -0
- package/lib/esm/components/inputs/DecimalInput.d.ts.map +1 -1
- package/lib/esm/components/inputs/DecimalInput.js +3 -3
- package/lib/esm/components/inputs/DenomInput.d.ts.map +1 -1
- package/lib/esm/components/inputs/DenomInput.js +2 -2
- package/lib/esm/components/inputs/Numeric.d.ts +9 -1
- package/lib/esm/components/inputs/Numeric.d.ts.map +1 -1
- package/lib/esm/components/inputs/Numeric.js +16 -4
- package/lib/esm/components/loader/LoaderWithContent.d.ts +8 -0
- package/lib/esm/components/loader/LoaderWithContent.d.ts.map +1 -0
- package/lib/esm/components/loader/LoaderWithContent.js +7 -0
- package/lib/esm/components/numbers/Decimal.d.ts.map +1 -1
- package/lib/esm/components/numbers/Decimal.js +8 -5
- package/lib/esm/helpers/index.d.ts +14 -0
- package/lib/esm/helpers/index.d.ts.map +1 -1
- package/lib/esm/helpers/index.js +17 -0
- package/lib/esm/helpers/index.test.d.ts +2 -0
- package/lib/esm/helpers/index.test.d.ts.map +1 -0
- package/lib/esm/helpers/index.test.js +49 -0
- package/lib/esm/i18n/locales/de/borrow.json +0 -1
- package/lib/esm/i18n/locales/de/common.json +21 -1
- package/lib/esm/i18n/locales/de/index.json +0 -2
- package/lib/esm/i18n/locales/de/portfolio.json +6 -1
- package/lib/esm/i18n/locales/de/strategies.json +3 -4
- package/lib/esm/i18n/locales/de/trade.json +35 -1
- package/lib/esm/i18n/locales/en/borrow.json +0 -1
- package/lib/esm/i18n/locales/en/common.json +20 -1
- package/lib/esm/i18n/locales/en/index.json +0 -2
- package/lib/esm/i18n/locales/en/portfolio.json +6 -1
- package/lib/esm/i18n/locales/en/strategies.json +3 -4
- package/lib/esm/i18n/locales/en/trade.json +33 -1
- package/lib/esm/index.d.ts +3 -0
- package/lib/esm/index.d.ts.map +1 -1
- package/lib/esm/index.js +2 -2
- package/lib/esm/package.json +3 -0
- package/lib/esm/wallets/providers/tronlink.d.ts +1 -0
- package/lib/esm/wallets/providers/tronlink.d.ts.map +1 -1
- package/lib/esm/wallets/providers/tronlink.js +2 -1
- package/lib/esm/wallets/providers/vulticonnect.d.ts.map +1 -1
- package/lib/esm/wallets/providers/vulticonnect.js +6 -2
- package/package.json +1 -1
- package/src/assets/images/spinnie.gif +0 -0
- package/src/assets/images/txsimulate.gif +0 -0
- package/src/components/balance/OmniBalance.tsx +43 -12
- package/src/components/bridges/DepositModal.tsx +129 -60
- package/src/components/buttons/TxButton.tsx +129 -23
- package/src/components/header/Accounts.tsx +15 -21
- package/src/components/header/Header.tsx +1 -1
- package/src/components/icons/ProviderIcon.tsx +145 -0
- package/src/components/inputs/DecimalInput.tsx +11 -8
- package/src/components/inputs/DenomInput.tsx +4 -3
- package/src/components/inputs/Numeric.tsx +48 -10
- package/src/components/loader/LoaderWithContent.tsx +21 -0
- package/src/components/numbers/Decimal.tsx +9 -5
- package/src/helpers/index.test.ts +64 -0
- package/src/helpers/index.ts +32 -0
- package/src/i18n/locales/de/borrow.json +0 -1
- package/src/i18n/locales/de/common.json +21 -1
- package/src/i18n/locales/de/index.json +0 -2
- package/src/i18n/locales/de/portfolio.json +6 -1
- package/src/i18n/locales/de/strategies.json +3 -5
- package/src/i18n/locales/de/trade.json +35 -1
- package/src/i18n/locales/en/borrow.json +0 -1
- package/src/i18n/locales/en/common.json +20 -1
- package/src/i18n/locales/en/index.json +0 -2
- package/src/i18n/locales/en/portfolio.json +6 -1
- package/src/i18n/locales/en/strategies.json +3 -5
- package/src/i18n/locales/en/trade.json +33 -1
- package/src/index.ts +2 -0
- package/src/scss/base/_colors.scss +3 -0
- package/src/scss/base/_typography.scss +1 -1
- package/src/scss/components/_button.scss +14 -0
- package/src/scss/components/_header.scss +10 -0
- package/src/scss/components/_input.scss +3 -2
- package/src/scss/components/_warning.scss +4 -0
- package/src/scss/styledcomponents/_card.scss +9 -0
- package/src/wallets/providers/tronlink.ts +3 -1
- package/src/wallets/providers/vulticonnect.ts +6 -2
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.wink = exports.rkuji = exports.nstk = exports.nami = exports.mnta = exports.lvn = exports.kuji = exports.fuzn = exports.auto = void 0;
|
|
4
|
+
const auto_png_1 = require("./auto.png");
|
|
5
|
+
exports.auto = auto_png_1.default;
|
|
6
|
+
const fuzn_png_1 = require("./fuzn.png");
|
|
7
|
+
exports.fuzn = fuzn_png_1.default;
|
|
8
|
+
const kuji_png_1 = require("./kuji.png");
|
|
9
|
+
exports.kuji = kuji_png_1.default;
|
|
10
|
+
const lvn_png_1 = require("./lvn.png");
|
|
11
|
+
exports.lvn = lvn_png_1.default;
|
|
12
|
+
const mnta_png_1 = require("./mnta.png");
|
|
13
|
+
exports.mnta = mnta_png_1.default;
|
|
14
|
+
const nami_png_1 = require("./nami.png");
|
|
15
|
+
exports.nami = nami_png_1.default;
|
|
16
|
+
const nstk_png_1 = require("./nstk.png");
|
|
17
|
+
exports.nstk = nstk_png_1.default;
|
|
18
|
+
const rkuji_png_1 = require("./rkuji.png");
|
|
19
|
+
exports.rkuji = rkuji_png_1.default;
|
|
20
|
+
const wink_png_1 = require("./wink.png");
|
|
21
|
+
exports.wink = wink_png_1.default;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AssetLabel = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const AssetLabel = ({ asset, Container }) => asset ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [asset.metadata.symbol, ((asset.metadata.symbol === "USDT" && asset.chain !== "ETH") ||
|
|
6
|
+
(asset.metadata.symbol === "ETH" && asset.chain !== "ETH") ||
|
|
7
|
+
(asset.metadata.symbol === "USDC" && asset.chain !== "ETH")) &&
|
|
8
|
+
asset.type === "SECURED" && (0, jsx_runtime_1.jsxs)(Container, { children: [".", asset.chain] })] })) : null;
|
|
9
|
+
exports.AssetLabel = AssetLabel;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OmniBalance = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const react_tooltip_1 = require("react-tooltip");
|
|
7
|
+
const rujira_js_1 = require("rujira.js");
|
|
8
|
+
const helpers_1 = require("../../helpers");
|
|
9
|
+
const ProviderIcon_1 = require("../icons/ProviderIcon");
|
|
10
|
+
const NetworkIcon_1 = require("../icons/NetworkIcon");
|
|
11
|
+
const Decimal_1 = require("../numbers/Decimal");
|
|
12
|
+
const accountSorter = (a, b) => {
|
|
13
|
+
const aIsSecured = a.asset.type === "SECURED";
|
|
14
|
+
const bIsSecured = b.asset.type === "SECURED";
|
|
15
|
+
if (aIsSecured && !bIsSecured)
|
|
16
|
+
return -1;
|
|
17
|
+
if (!aIsSecured && bIsSecured)
|
|
18
|
+
return 1;
|
|
19
|
+
return Number(b.balance - a.balance);
|
|
20
|
+
};
|
|
21
|
+
const OmniBalance = ({ balance, onClick, className, accountProviders, }) => {
|
|
22
|
+
const tooltipId = (0, react_1.useId)();
|
|
23
|
+
const providerLookup = (0, react_1.useMemo)(() => new Map(accountProviders?.map(({ address, provider }) => [address, provider])), [accountProviders]);
|
|
24
|
+
const sortedAccounts = balance?.accounts
|
|
25
|
+
? [...balance.accounts].sort(accountSorter)
|
|
26
|
+
: [];
|
|
27
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "omni-balance", children: [(0, jsx_runtime_1.jsx)(Decimal_1.Decimal, { amount: balance?.balance || 0n, className: className, onClick: () => balance && onClick?.(balance) }), sortedAccounts.length > 1 && ((0, jsx_runtime_1.jsx)("div", { className: "omni-balance__networks", children: sortedAccounts.map((x) => {
|
|
28
|
+
const n = x.asset.type === "SECURED" ? "THOR" : x.asset.chain;
|
|
29
|
+
const provider = providerLookup.get(x.address);
|
|
30
|
+
const tipId = `${tooltipId}-${n}`;
|
|
31
|
+
return ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("button", { "data-tooltip-id": tipId, className: `omni-balance__network-button omni-balance__network-button--${n.toLowerCase()}`, onClick: () => onClick?.(x), children: (0, jsx_runtime_1.jsx)(NetworkIcon_1.NetworkIcon, { network: n }) }), (0, jsx_runtime_1.jsx)(react_tooltip_1.Tooltip, { id: tipId, className: "tooltip", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex ai-c gap-1", children: [provider && ((0, jsx_runtime_1.jsx)(ProviderIcon_1.ProviderIcon, { provider: provider, selected: true, className: "w-3 h-3 block" })), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "condensed fs-16 fw-500", children: (0, helpers_1.nFormatter)(x.balance, 6) }), (0, jsx_runtime_1.jsxs)("div", { className: "fs-14 lh-16 color-grey", children: ["on ", (0, rujira_js_1.networkLabel)(n)] })] })] }) })] }, n));
|
|
32
|
+
}) }))] }));
|
|
33
|
+
};
|
|
34
|
+
exports.OmniBalance = OmniBalance;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BuyModal = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const BuyModal = () => {
|
|
6
|
+
return (0, jsx_runtime_1.jsx)("h3", { className: "h3", children: "Buy Crypto" });
|
|
7
|
+
};
|
|
8
|
+
exports.BuyModal = BuyModal;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DepositModal = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const rujira_js_1 = require("rujira.js");
|
|
7
|
+
const i18n_1 = require("../../i18n");
|
|
8
|
+
const LoaderWithContent_1 = require("../loader/LoaderWithContent");
|
|
9
|
+
const IconDenom_1 = require("../icons/IconDenom");
|
|
10
|
+
const Icons_1 = require("../icons/Icons");
|
|
11
|
+
const Input_1 = require("../inputs/Input");
|
|
12
|
+
const clsx_1 = require("clsx");
|
|
13
|
+
const date_fns_1 = require("date-fns");
|
|
14
|
+
const react_hot_toast_1 = require("react-hot-toast");
|
|
15
|
+
const __1 = require("../..");
|
|
16
|
+
const deposited_gif_1 = require("../../assets/images/deposited.gif");
|
|
17
|
+
const filters_gif_1 = require("../../assets/images/filters.gif");
|
|
18
|
+
const filters_png_1 = require("../../assets/images/filters.png");
|
|
19
|
+
const swap_gif_1 = require("../../assets/images/swap.gif");
|
|
20
|
+
const Select_1 = require("../inputs/Select");
|
|
21
|
+
const DepositModal = ({ title = "deposit", options, targets, selected, dismiss, Submit, queryClient, amount, target, label, inboundAddresses, }) => {
|
|
22
|
+
const { t } = (0, i18n_1.useTranslation)("common");
|
|
23
|
+
const [token, setToken] = (0, react_1.useState)(selected ? selected.asset.metadata.symbol : undefined);
|
|
24
|
+
const [asset, setAsset] = (0, react_1.useState)(selected?.asset);
|
|
25
|
+
const [tx, setTx] = (0, react_1.useState)();
|
|
26
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "deposit-modal", children: [(token || asset) && !selected && !tx && ((0, jsx_runtime_1.jsxs)("button", { className: "transparent color-white hover-primary1 flex ai-c mb-1 fs-14 fw-500 pointer", onClick: () => {
|
|
27
|
+
setAsset(undefined);
|
|
28
|
+
setToken(undefined);
|
|
29
|
+
}, children: [(0, jsx_runtime_1.jsx)(Icons_1.AngleLeft, { className: "block w-2 h-2 mr-0.5" }), t("back")] })), (0, jsx_runtime_1.jsxs)("h3", { className: "h3 flex ai-b mb-0", children: [asset && ((0, jsx_runtime_1.jsx)(IconDenom_1.IconDenom, { denom: asset.metadata.symbol, className: "as-c w-4 h-4 mr-1" })), t(title), " ", asset && asset.metadata.symbol, asset && ((0, jsx_runtime_1.jsx)("small", { className: "ml-1 color-grey fw-400", children: t("toRujira") }))] }), label, (0, jsx_runtime_1.jsxs)("div", { className: "mt-3", children: [!token && ((0, jsx_runtime_1.jsx)(TokenSelect, { options: options, onSelect: (a) => {
|
|
30
|
+
setToken(a.metadata.symbol);
|
|
31
|
+
setAsset(a);
|
|
32
|
+
} })), asset && !tx && ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(Confirm, { asset: asset, amount: amount, balance: selected ||
|
|
33
|
+
options.find((a) => a.asset.asset === asset.asset)?.balance, target: target, targets: targets, Submit: Submit, onSuccess: setTx, queryClient: queryClient, inboundAddresses: inboundAddresses }) })), tx && (0, jsx_runtime_1.jsx)(Success, { tx: tx, dismiss: dismiss })] })] }));
|
|
34
|
+
};
|
|
35
|
+
exports.DepositModal = DepositModal;
|
|
36
|
+
const TokenSelect = ({ options, onSelect }) => {
|
|
37
|
+
const { t } = (0, i18n_1.useTranslation)("common");
|
|
38
|
+
const [search, setSearch] = (0, react_1.useState)("");
|
|
39
|
+
const [all, setAll] = (0, react_1.useState)(!options.length);
|
|
40
|
+
const filtered = options.filter((i) => {
|
|
41
|
+
const q = i.asset.metadata.symbol
|
|
42
|
+
.toLowerCase()
|
|
43
|
+
.includes(search.toLowerCase());
|
|
44
|
+
return all ? q : q && i.balance;
|
|
45
|
+
});
|
|
46
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex", children: [(0, jsx_runtime_1.jsx)(Input_1.Input, { containerClassName: "grow", label: t("search"), value: search, onChange: (e) => setSearch(e.currentTarget.value), children: search !== "" && ((0, jsx_runtime_1.jsx)(Icons_1.MinusCircle, { className: "input-container__clear", onClick: () => setSearch("") })) }), (0, jsx_runtime_1.jsx)(__1.Toggle, { label: t("showAll"), className: "toggle--xs color-white as-c ml-1", checked: all, onChange: (e) => setAll(e.currentTarget.checked) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "deposit-modal__content row wrap pad-mini mt-1.5", children: [filtered.map((i) => ((0, jsx_runtime_1.jsx)("div", { className: "col-12 col-md-col-6", children: (0, jsx_runtime_1.jsxs)("button", { className: "card card--hover-border mt-0.5 mb-0.5 p-2 flex ai-c", onClick: () => {
|
|
47
|
+
onSelect(i.asset);
|
|
48
|
+
setSearch("");
|
|
49
|
+
}, children: [(0, jsx_runtime_1.jsx)(IconDenom_1.IconDenom, { denom: i.asset.metadata.symbol, className: "block w-4 h-4" }), (0, jsx_runtime_1.jsx)("p", { className: "ml-1 fw-600 color-white", children: i.asset.metadata.symbol }), (0, jsx_runtime_1.jsxs)("div", { className: "ml-a text-right", children: [i.balance ? ((0, jsx_runtime_1.jsx)("div", { className: "tag tag--teal tag--borderless", children: (0, jsx_runtime_1.jsx)(__1.Decimal, { amount: i.balance.balance, decimals: i.asset.metadata.decimals }) })) : null, (0, jsx_runtime_1.jsx)("br", {}), i.valueUsd ? ((0, jsx_runtime_1.jsx)("small", { className: "color-grey", children: (0, jsx_runtime_1.jsx)(__1.Fiat, { symbol: "$", className: "fs-12 mr-1", amount: i.valueUsd, decimals: i.asset.metadata.decimals }) })) : null] })] }) }, i.asset.asset))), filtered.length === 0 && ((0, jsx_runtime_1.jsx)("p", { className: "color-grey my-2 w-full text-center", children: t("noBalancesFound") }))] })] }));
|
|
50
|
+
};
|
|
51
|
+
const Confirm = ({ asset, balance, targets, target: target_, Submit, onSuccess, queryClient, amount: requestAmount, inboundAddresses, }) => {
|
|
52
|
+
const { t } = (0, i18n_1.useTranslation)("common");
|
|
53
|
+
const ref = (0, react_1.useRef)(null);
|
|
54
|
+
const [amount, setAmount] = (0, react_1.useState)(requestAmount || 0n);
|
|
55
|
+
const [target, setTarget] = (0, react_1.useState)(target_ || "");
|
|
56
|
+
const [custom, setCustom] = (0, react_1.useState)("");
|
|
57
|
+
const [direct, setDirect] = (0, react_1.useState)(false);
|
|
58
|
+
const [advanced, setAdvanced] = (0, react_1.useState)(false);
|
|
59
|
+
const [hoverAd, setHoverAd] = (0, react_1.useState)(false);
|
|
60
|
+
const [quote, setQuote] = (0, react_1.useState)();
|
|
61
|
+
const [account, setAccount] = (0, react_1.useState)(balance?.accounts[0]);
|
|
62
|
+
const dustThreshold = inboundAddresses?.find((a) => a.chain === account?.asset.chain)?.dustThreshold;
|
|
63
|
+
(0, react_1.useEffect)(() => {
|
|
64
|
+
if (ref.current && target === "custom") {
|
|
65
|
+
ref.current.focus();
|
|
66
|
+
}
|
|
67
|
+
}, [target, ref]);
|
|
68
|
+
const canSwap = asset.chain !== account?.asset.chain ||
|
|
69
|
+
asset.metadata.symbol !== account.asset.metadata.symbol;
|
|
70
|
+
const shouldSwap = canSwap && !direct;
|
|
71
|
+
// Determine the actual destination address
|
|
72
|
+
const destination = target === "custom" ? custom : target;
|
|
73
|
+
const isCustomAddressInvalid = target === "custom" && custom !== "" && !(0, rujira_js_1.validateAddress)("THOR", custom);
|
|
74
|
+
// Fetch swap quote when conditions are met
|
|
75
|
+
(0, react_1.useEffect)(() => {
|
|
76
|
+
setQuote(undefined);
|
|
77
|
+
if (!account)
|
|
78
|
+
return;
|
|
79
|
+
if (!shouldSwap)
|
|
80
|
+
return;
|
|
81
|
+
if (!amount)
|
|
82
|
+
return;
|
|
83
|
+
if (direct)
|
|
84
|
+
return;
|
|
85
|
+
setQuote("loading");
|
|
86
|
+
queryClient.thorchain
|
|
87
|
+
.getSwapQuote({
|
|
88
|
+
fromAsset: account.asset.asset,
|
|
89
|
+
toAsset: asset.asset,
|
|
90
|
+
amount: amount,
|
|
91
|
+
streamingInterval: 1n,
|
|
92
|
+
streamingQuantity: 0n,
|
|
93
|
+
destination,
|
|
94
|
+
})
|
|
95
|
+
.then(setQuote)
|
|
96
|
+
.catch(setQuote);
|
|
97
|
+
}, [account, amount, destination, asset, direct]);
|
|
98
|
+
const depositAmount = typeof quote === "object" && "memo" in quote
|
|
99
|
+
? quote.expectedAmountOut
|
|
100
|
+
: amount;
|
|
101
|
+
const depositFee = (typeof quote === "object" && "memo" in quote && quote.fees?.total) || 0n;
|
|
102
|
+
const price = asset.price?.current || 0n;
|
|
103
|
+
const feeValue = price ? (price * depositFee) / 10n ** 12n : 0n;
|
|
104
|
+
const receivedValue = price ? (price * depositAmount) / 10n ** 12n : 0n;
|
|
105
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [balance && balance.accounts.length > 0 ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("h2", { className: "fs-14 fw-500 color-grey mb-1 ml-1", children: t("selectSourceAccount") }), (0, jsx_runtime_1.jsx)("div", { className: "br-1 p-2 bg-black mb-2 flex dir-c gap-y-1", children: balance.accounts.map((x) => ((0, jsx_runtime_1.jsxs)("div", { onClick: () => {
|
|
106
|
+
setAccount(x);
|
|
107
|
+
}, className: (0, clsx_1.default)({
|
|
108
|
+
"flex ai-c fs-14 condensed pointer": true,
|
|
109
|
+
"color-grey": account !== x,
|
|
110
|
+
"color-white": account === x,
|
|
111
|
+
}), children: [(0, jsx_runtime_1.jsx)(__1.Radio, { checked: account === x, readOnly: true }), (0, jsx_runtime_1.jsx)("div", { "data-tooltip-content": x.address, "data-tooltip-id": "modal-tip", onClick: () => {
|
|
112
|
+
react_hot_toast_1.default.success("Address copied to clipboard");
|
|
113
|
+
navigator.clipboard.writeText(x.address);
|
|
114
|
+
}, className: "inconsolata mx-1", children: x.address.substring(0, 6) + "…" + x.address.slice(-6) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex ai-c gap-0.5", children: [(0, jsx_runtime_1.jsx)(__1.NetworkIcon, { network: x.asset.chain, className: "w-2 h-2" }), (0, jsx_runtime_1.jsx)("span", { className: "", children: (0, rujira_js_1.networkLabel)(x.asset.chain) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex dir-r ai-e ml-a", children: [(0, jsx_runtime_1.jsx)("div", { className: (0, clsx_1.default)({
|
|
115
|
+
"tag tag--md ml-a": true,
|
|
116
|
+
"tag--teal": account === x,
|
|
117
|
+
}), children: (0, jsx_runtime_1.jsx)(__1.Decimal, { amount: x.balance, symbol: x.asset.metadata.symbol, symbolClassName: "condensed fw-500" }) }), x.valueUsd ? ((0, jsx_runtime_1.jsxs)("div", { className: "iflex ml-0.5 ml-sm-1 fs-13 color-grey", style: { marginBottom: "0.05rem" }, children: ["(", (0, jsx_runtime_1.jsx)(__1.Fiat, { amount: x.valueUsd, symbol: "$", decimals: 8, className: "fs-12 color-grey" }), ")"] })) : null] })] }, x.address + x.asset.chain))) })] })) : null, (0, jsx_runtime_1.jsx)(__1.DenomInput, { className: "mt-2.5 bg-black", symbol: asset.metadata.symbol, amount: amount, decimals: 8, onChangeAmount: setAmount, max: BigInt(account?.balance || 0), maxLabel: `${t("balance")}:`, fiat: { price, symbol: "$" } }), (0, jsx_runtime_1.jsxs)("div", { className: "row wrap mt-1.5 mt-sm-2 condensed fs-14 px-2 gap-y-1", children: [(0, jsx_runtime_1.jsx)("div", { className: (0, clsx_1.default)("col-12 col-xs-4 text-center text-xs-left fw-500", amount > 0n && amount < (dustThreshold ?? 0n)
|
|
118
|
+
? "color-red"
|
|
119
|
+
: "color-grey"), children: t("minimumDeposit") }), (0, jsx_runtime_1.jsx)("div", { className: "col-12 col-xs-8 text-center text-xs-right color-grey", children: (dustThreshold ?? 0n) > 0n && ((0, jsx_runtime_1.jsx)(__1.Decimal, { amount: dustThreshold, symbol: account?.asset.metadata.symbol, className: (0, clsx_1.default)("pointer", {
|
|
120
|
+
"color-red": amount > 0n && amount < dustThreshold,
|
|
121
|
+
"color-grey": amount > 0n && amount > dustThreshold,
|
|
122
|
+
}), symbolClassName: (0, clsx_1.default)("fs-14 condensed fw-500", {
|
|
123
|
+
"color-red": amount > 0n && amount < dustThreshold,
|
|
124
|
+
"color-grey": amount > 0n && amount > dustThreshold,
|
|
125
|
+
}), onClick: () => setAmount(dustThreshold ?? 0n) })) }), (0, jsx_runtime_1.jsx)("div", { className: "col-12 col-xs-4 text-center text-xs-left color-grey fw-500", children: t("swapFee") }), (0, jsx_runtime_1.jsx)("div", { className: "col-12 col-xs-8 text-center text-xs-right color-teal", children: (0, jsx_runtime_1.jsx)(LoaderWithContent_1.LoaderWithContent, { loading: quote === "loading", content: (0, jsx_runtime_1.jsxs)("div", { className: "color-grey", children: [(0, jsx_runtime_1.jsx)(__1.Decimal, { amount: depositFee, symbol: direct
|
|
126
|
+
? account?.asset.metadata.symbol
|
|
127
|
+
: asset.metadata.symbol, className: direct || !shouldSwap ? "color-grey" : undefined, symbolClassName: "color-grey fs-14 condensed fw-500" }), (0, jsx_runtime_1.jsxs)("div", { className: "iflex ml-1 fs-13 color-grey", children: ["(", (0, jsx_runtime_1.jsx)(__1.Fiat, { amount: feeValue ?? 0n, symbol: "$", decimals: 8, className: "numeric-input__value color-grey fs-12" }), ")"] })] }) }) }), (0, jsx_runtime_1.jsx)("div", { className: "col-12 col-xs-4 text-center text-xs-left color-grey fw-500", children: t("receivedAmount") }), (0, jsx_runtime_1.jsx)("div", { className: "col-12 col-xs-8 text-center text-xs-right color-teal", children: (0, jsx_runtime_1.jsx)(LoaderWithContent_1.LoaderWithContent, { loading: quote === "loading", content: (0, jsx_runtime_1.jsxs)("div", { className: "color-white", children: [(0, jsx_runtime_1.jsx)(__1.Decimal, { amount: depositAmount, symbol: direct
|
|
128
|
+
? account?.asset.metadata.symbol
|
|
129
|
+
: asset.metadata.symbol, symbolClassName: "color-grey fs-14 condensed fw-500" }), (0, jsx_runtime_1.jsxs)("div", { className: "iflex ml-1 fs-13 color-grey", children: ["(", (0, jsx_runtime_1.jsx)(__1.Fiat, { amount: receivedValue ?? 0n, symbol: "$", decimals: 8, className: "numeric-input__value color-grey fs-12" }), ")"] })] }) }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex w-full jc-c ai-c gap-0.5 pointer color-grey hover-white", onMouseEnter: () => setHoverAd(true), onMouseLeave: () => setHoverAd(false), onClick: () => setAdvanced((prev) => !prev), children: [(0, jsx_runtime_1.jsx)("img", { src: hoverAd ? filters_gif_1.default : filters_png_1.default, className: (0, clsx_1.default)({
|
|
130
|
+
"w-2 h-2": true,
|
|
131
|
+
"filter-grey": !hoverAd,
|
|
132
|
+
"filter-white": hoverAd,
|
|
133
|
+
}) }), advanced ? t("hideAdvancedOptions") : t("showAdvancedOptions")] })] }), advanced && ((0, jsx_runtime_1.jsxs)("div", { className: "br-1 p-2 bg-black mt-1 row wrap condensed fs-14 px-2 gap-y-1", children: [(0, jsx_runtime_1.jsx)("div", { className: "col-12 col-xs-4 text-center text-xs-left color-grey fw-500", children: t("destination") }), (0, jsx_runtime_1.jsx)("div", { className: "col-12 col-xs-8 text-center text-xs-right", children: (0, jsx_runtime_1.jsxs)(Select_1.Select, { containerClassName: "fs-14", className: "select--inline text-right", value: target, onChange: (e) => setTarget(e.currentTarget.value), children: [targets.map((x) => ((0, jsx_runtime_1.jsx)("option", { value: x, className: "bg-darkGrey", children: x }, x))), (0, jsx_runtime_1.jsx)("option", { className: "bg-darkGrey", value: "custom", children: t("customAddress") })] }) }), target === "custom" && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: "col-12 col-xs-4 text-center text-xs-left color-grey fw-500", children: t("customDestination") }), (0, jsx_runtime_1.jsx)("div", { className: "col-12 col-xs-8 text-center text-xs-right", children: (0, jsx_runtime_1.jsx)(Input_1.Input, { containerClassName: "fs-14", value: custom, onChange: (e) => setCustom(e.currentTarget.value), className: "input--inline text-right", innerRef: ref }) })] })), canSwap && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [asset.chain === "THOR" ? null : ((0, jsx_runtime_1.jsx)("div", { className: "col-12 text-center text-xs-right", children: (0, jsx_runtime_1.jsx)(__1.Toggle, { className: "toggle--xs", label: `Deposit ${account?.asset.chain}.${account?.asset.metadata.symbol} directly`, checked: direct, onChange: () => setDirect((prev) => !prev) }) })), direct && ((0, jsx_runtime_1.jsxs)(__1.Warning, { className: "warning--sm condensed flex ai-c mt-1", color: "orange", children: [(0, jsx_runtime_1.jsx)("img", { src: swap_gif_1.default, alt: "", className: "filter-orange block no-shrink", style: { width: "2.5rem", height: "2.5rem" } }), (0, jsx_runtime_1.jsxs)("small", { className: "text-left fs-14", children: ["You are depositing a version of", " ", (0, jsx_runtime_1.jsx)("span", { className: "color-white", children: asset.metadata.symbol }), " ", "that is not the standard on Rujira. Our products use the", " ", (0, jsx_runtime_1.jsx)("span", { className: "color-white", children: "Ethereum" }), " version of", " ", (0, jsx_runtime_1.jsx)("span", { className: "color-white", children: asset.metadata.symbol }), "."] })] }))] })), isCustomAddressInvalid && ((0, jsx_runtime_1.jsx)("div", { className: "flex dir-r jc-c grow mt-1", children: (0, jsx_runtime_1.jsxs)(__1.Warning, { color: "red", className: "condensed iflex grow", children: [(0, jsx_runtime_1.jsx)(__1.Icons.ExclamationTriangle, { className: "color-red" }), (0, jsx_runtime_1.jsx)("span", { className: "warning__msg", children: t("invalidThorAddress") })] }) }))] })), (0, jsx_runtime_1.jsx)(Submit, { selected: account, amount: amount, target: target !== "custom" ? target : custom, swapMemo: "memo", onSuccess: onSuccess, disabled: isCustomAddressInvalid, isDangerous: false, quote: quote, shouldSwap: shouldSwap })] }));
|
|
134
|
+
};
|
|
135
|
+
const Success = ({ tx, dismiss, }) => {
|
|
136
|
+
const { t } = (0, i18n_1.useTranslation)("common");
|
|
137
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { className: "mt-2 flex ai-c br-2 bg-teal-10 p-2", children: [(0, jsx_runtime_1.jsx)("img", { src: deposited_gif_1.default, alt: "", className: "filter-teal block w-6 h-a no-shrink" }), (0, jsx_runtime_1.jsx)("span", { className: "color-teal fs-18 fw-600 mx-1", children: t("depositStarted") })] }), (0, jsx_runtime_1.jsx)("div", { className: "table table--no-hover mt-1", children: (0, jsx_runtime_1.jsxs)("tbody", { children: [(0, jsx_runtime_1.jsxs)("tr", { children: [(0, jsx_runtime_1.jsxs)("td", { className: "color-grey", children: [(0, rujira_js_1.networkLabel)(tx.network), " ", t("depositEta")] }), (0, jsx_runtime_1.jsx)("td", { children: (0, date_fns_1.formatDuration)((0, date_fns_1.intervalToDuration)({
|
|
138
|
+
start: 0,
|
|
139
|
+
end: (0, rujira_js_1.networkConfirmationTime)(tx.network),
|
|
140
|
+
}), { format: ["hours", "minutes", "seconds"], zero: false }) })] }), (0, jsx_runtime_1.jsxs)("tr", { children: [(0, jsx_runtime_1.jsx)("td", { className: "color-grey", children: t("viewTx") }), (0, jsx_runtime_1.jsx)("td", { children: (0, jsx_runtime_1.jsxs)("a", { href: (0, rujira_js_1.networkTxLink)(tx), target: "_blank", className: "color-white hover-primary1 no-underline", children: [(0, rujira_js_1.networkExplorerLabel)(tx.network), (0, jsx_runtime_1.jsx)(Icons_1.External, { className: "inline-block w-1.5 h-1.5 ml-0.5" })] }) })] }), (0, jsx_runtime_1.jsxs)("tr", { children: [(0, jsx_runtime_1.jsx)("td", { className: "color-grey", children: t("trackDeposit") }), (0, jsx_runtime_1.jsx)("td", { children: (0, jsx_runtime_1.jsxs)("a", { href: (0, rujira_js_1.networkTxLink)({
|
|
141
|
+
network: "THOR",
|
|
142
|
+
txHash: tx.txHash.replace(/^0x/, "").toUpperCase(),
|
|
143
|
+
}), target: "_blank", className: "color-white hover-primary1 no-underline", children: ["THORChain.net", (0, jsx_runtime_1.jsx)(Icons_1.External, { className: "inline-block w-1.5 h-1.5 ml-0.5" })] }) })] })] }) }), (0, jsx_runtime_1.jsx)("div", { className: "modal__footer p-3 text-right", children: (0, jsx_runtime_1.jsx)(__1.Button, { label: "Close", onClick: dismiss }) })] }));
|
|
144
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Button = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const clsx_1 = require("clsx");
|
|
6
|
+
const react_1 = require("motion/react");
|
|
7
|
+
const react_2 = require("react");
|
|
8
|
+
const fixedForwardRef = react_2.forwardRef;
|
|
9
|
+
const UnwrappedAnyComponent = (props, ref) => {
|
|
10
|
+
const { as: Comp = "button", label, children, className, ...rest } = props;
|
|
11
|
+
// Remove button--outline if button--waiting is present
|
|
12
|
+
const processedClassName = className?.includes("button--waiting")
|
|
13
|
+
? className.replace(/button--outline/g, "").trim()
|
|
14
|
+
: className;
|
|
15
|
+
const mouseX = (0, react_1.useMotionValue)(0);
|
|
16
|
+
const mouseY = (0, react_1.useMotionValue)(0);
|
|
17
|
+
function handleMouseMove({ currentTarget, clientX, clientY }) {
|
|
18
|
+
const { left, top } = currentTarget.getBoundingClientRect();
|
|
19
|
+
mouseX.set(clientX - left);
|
|
20
|
+
mouseY.set(clientY - top);
|
|
21
|
+
}
|
|
22
|
+
let gradient = "214, 21, 235, 1";
|
|
23
|
+
if (className?.includes("button--grey")) {
|
|
24
|
+
gradient = "96, 125, 139, 1";
|
|
25
|
+
}
|
|
26
|
+
else if (className?.includes("button--red")) {
|
|
27
|
+
gradient = "244, 81, 30, 1";
|
|
28
|
+
}
|
|
29
|
+
else if (className?.includes("button--blue")) {
|
|
30
|
+
gradient = "96, 251, 208, 1";
|
|
31
|
+
}
|
|
32
|
+
else if (className?.includes("button--dark")) {
|
|
33
|
+
gradient = "214, 21, 235, 0.25";
|
|
34
|
+
}
|
|
35
|
+
else if (className?.includes("button--orange")) {
|
|
36
|
+
gradient = "245, 123, 0, 0.25";
|
|
37
|
+
}
|
|
38
|
+
const buttonElement = ((0, jsx_runtime_1.jsxs)(Comp, { ...rest, ref: ref, onMouseMove: handleMouseMove, className: (0, clsx_1.default)({
|
|
39
|
+
button: !className?.includes("transparent"),
|
|
40
|
+
[`${processedClassName}`]: processedClassName,
|
|
41
|
+
}), children: [!className?.includes("transparent") && ((0, jsx_runtime_1.jsx)(react_1.motion.div, { className: "button__motion", style: {
|
|
42
|
+
background: (0, react_1.useMotionTemplate) `
|
|
43
|
+
radial-gradient(
|
|
44
|
+
150px circle at ${mouseX}px ${mouseY}px,
|
|
45
|
+
rgba(${gradient}),
|
|
46
|
+
transparent 100%
|
|
47
|
+
)
|
|
48
|
+
`,
|
|
49
|
+
} })), label && (0, jsx_runtime_1.jsx)("span", { children: label }), children] }));
|
|
50
|
+
return className?.includes("button--waiting") ? ((0, jsx_runtime_1.jsx)("div", { className: "button-container", children: buttonElement })) : (buttonElement);
|
|
51
|
+
};
|
|
52
|
+
exports.Button = fixedForwardRef(UnwrappedAnyComponent);
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Popout = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const clsx_1 = require("clsx");
|
|
6
|
+
const react_1 = require("react");
|
|
7
|
+
const Icons_1 = require("../icons/Icons");
|
|
8
|
+
const Button_1 = require("./Button");
|
|
9
|
+
const react_dom_1 = require("react-dom");
|
|
10
|
+
const Popout = ({ children, className, buttonClassName }) => {
|
|
11
|
+
const [open, setOpen] = (0, react_1.useState)(false);
|
|
12
|
+
const container = (0, react_1.useRef)(null);
|
|
13
|
+
const navElement = document.getElementById("popout");
|
|
14
|
+
(0, react_1.useEffect)(() => {
|
|
15
|
+
if (open) {
|
|
16
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
17
|
+
window.addEventListener("resize", position);
|
|
18
|
+
navElement.classList.add("open");
|
|
19
|
+
position();
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
23
|
+
}
|
|
24
|
+
return () => {
|
|
25
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
26
|
+
window.removeEventListener("resize", position);
|
|
27
|
+
navElement.classList.remove("open");
|
|
28
|
+
};
|
|
29
|
+
}, [open]);
|
|
30
|
+
const handleClickOutside = (e) => {
|
|
31
|
+
if (navElement.contains(e.target)) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
setOpen(false);
|
|
35
|
+
e.stopPropagation();
|
|
36
|
+
e.stopImmediatePropagation();
|
|
37
|
+
return false;
|
|
38
|
+
};
|
|
39
|
+
const position = () => {
|
|
40
|
+
const containerElementElement = container.current;
|
|
41
|
+
if (navElement && containerElementElement) {
|
|
42
|
+
const rightPosition = window.scrollX +
|
|
43
|
+
window.innerWidth -
|
|
44
|
+
containerElementElement.getBoundingClientRect().left -
|
|
45
|
+
parseInt(getComputedStyle(containerElementElement).borderLeftWidth, 10);
|
|
46
|
+
const bottomPosition = -window.scrollY +
|
|
47
|
+
window.innerHeight -
|
|
48
|
+
containerElementElement.getBoundingClientRect().top -
|
|
49
|
+
parseInt(getComputedStyle(containerElementElement).borderTopWidth, 10) -
|
|
50
|
+
containerElementElement.offsetHeight;
|
|
51
|
+
navElement.style.right = `${rightPosition + 4}px`;
|
|
52
|
+
navElement.style.bottom = `${bottomPosition - 4}px`;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
return ((0, jsx_runtime_1.jsxs)("div", { ref: container, className: (0, clsx_1.default)({
|
|
56
|
+
popout: true,
|
|
57
|
+
[`${className}`]: className,
|
|
58
|
+
}), children: [(0, jsx_runtime_1.jsx)(Button_1.Button, { onClick: () => setOpen(!open), className: (0, clsx_1.default)({
|
|
59
|
+
"button--grey button--small": !buttonClassName,
|
|
60
|
+
[`${buttonClassName}`]: buttonClassName,
|
|
61
|
+
}), children: !open ? (0, jsx_runtime_1.jsx)(Icons_1.Ellipsis, {}) : (0, jsx_runtime_1.jsx)(Icons_1.AngleLeft, {}) }), open && (0, react_dom_1.createPortal)(children, navElement)] }));
|
|
62
|
+
};
|
|
63
|
+
exports.Popout = Popout;
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TxButtonTip = exports.TxButton = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const clsx_1 = require("clsx");
|
|
6
|
+
const react_1 = require("react");
|
|
7
|
+
const react_hot_toast_1 = require("react-hot-toast");
|
|
8
|
+
const react_i18next_1 = require("react-i18next");
|
|
9
|
+
const react_tooltip_1 = require("react-tooltip");
|
|
10
|
+
const rujira_js_1 = require("rujira.js");
|
|
11
|
+
const txfail_gif_1 = require("../../assets/images/txfail.gif");
|
|
12
|
+
const txsign_gif_1 = require("../../assets/images/txsign.gif");
|
|
13
|
+
const txsuccess_gif_1 = require("../../assets/images/txsuccess.gif");
|
|
14
|
+
const unlock_gif_1 = require("../../assets/images/unlock.gif");
|
|
15
|
+
const i18n_1 = require("../../i18n");
|
|
16
|
+
const Loader_1 = require("../loader/Loader");
|
|
17
|
+
const Warning_1 = require("../notices/Warning");
|
|
18
|
+
const Decimal_1 = require("../numbers/Decimal");
|
|
19
|
+
const Button_1 = require("./Button");
|
|
20
|
+
const txsimulate_gif_1 = require("../../assets/images/txsimulate.gif");
|
|
21
|
+
const exclamation_gif_1 = require("../../assets/images/exclamation.gif");
|
|
22
|
+
// Helper to identify spacing/layout classes
|
|
23
|
+
const SPACING_CLASS_REGEX = /^(m|p)(l|r|t|b|x|y)?-\d+$/;
|
|
24
|
+
const isSpacingClass = (className) => SPACING_CLASS_REGEX.test(className);
|
|
25
|
+
// Separate spacing classes from styling classes
|
|
26
|
+
const separateClasses = (className) => {
|
|
27
|
+
const classes = className?.split(" ") || [];
|
|
28
|
+
return {
|
|
29
|
+
spacing: classes.filter(isSpacingClass),
|
|
30
|
+
styling: classes.filter((c) => !isSpacingClass(c)),
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
// Add chains here that do not require the extra reset step, for USDT allowance approvals,
|
|
34
|
+
// when there is already a non-zero allowance approved. We default to the 3-step process
|
|
35
|
+
// to avoid failing deposits for future chain integrations.
|
|
36
|
+
const TWO_STEP_ALLOWANCE_CHAINS = new Set(["BSC", "AVAX"]);
|
|
37
|
+
const TxButton = (props) => {
|
|
38
|
+
const { t } = (0, i18n_1.useTranslation)("common");
|
|
39
|
+
const { accountProvider, msg, onSuccess, onError, SimulationComponent = DefaultSimulationComponent, children, toastOpts = {}, className, hideSimulation, onClick, ...rest } = props;
|
|
40
|
+
const [simulation, setSimulation] = (0, react_1.useState)();
|
|
41
|
+
const [simulationError, setSimulationError] = (0, react_1.useState)();
|
|
42
|
+
const [isSimulating, setIsSimulating] = (0, react_1.useState)(false);
|
|
43
|
+
const simulationSeqRef = (0, react_1.useRef)(0);
|
|
44
|
+
const { loading, success, error } = toastOpts;
|
|
45
|
+
const [isSigning, setIsSigning] = (0, react_1.useState)(false);
|
|
46
|
+
const [isSuccess, setIsSuccess] = (0, react_1.useState)(false);
|
|
47
|
+
const [isRejected, setIsRejected] = (0, react_1.useState)(false);
|
|
48
|
+
const [allowanceWasReset, setAllowanceWasReset] = (0, react_1.useState)(false);
|
|
49
|
+
const doSimulate = (msg) => {
|
|
50
|
+
setSimulationError(undefined);
|
|
51
|
+
setSimulation(undefined);
|
|
52
|
+
if (msg) {
|
|
53
|
+
const seq = ++simulationSeqRef.current;
|
|
54
|
+
setIsSimulating(true);
|
|
55
|
+
const signer = accountProvider.signer(msg.account.address);
|
|
56
|
+
signer
|
|
57
|
+
.simulate(msg)
|
|
58
|
+
.then((sim) => {
|
|
59
|
+
//ignore stale simulations
|
|
60
|
+
if (seq !== simulationSeqRef.current)
|
|
61
|
+
return;
|
|
62
|
+
setIsSimulating(false);
|
|
63
|
+
setSimulation(sim);
|
|
64
|
+
})
|
|
65
|
+
.catch((err) => {
|
|
66
|
+
//ignore stale simulation errors
|
|
67
|
+
if (seq !== simulationSeqRef.current)
|
|
68
|
+
return;
|
|
69
|
+
setIsSimulating(false);
|
|
70
|
+
console.error(err);
|
|
71
|
+
setSimulationError(err);
|
|
72
|
+
onError && onError(new rujira_js_1.TxError(msg, err, "simulation"));
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
(0, react_1.useEffect)(() => {
|
|
77
|
+
setIsSimulating(false);
|
|
78
|
+
const timeout = setTimeout(() => doSimulate(msg), 1000);
|
|
79
|
+
return () => clearTimeout(timeout);
|
|
80
|
+
}, [msg]);
|
|
81
|
+
const handleSign = (e) => {
|
|
82
|
+
if (isSigning || isSuccess || isRejected)
|
|
83
|
+
return;
|
|
84
|
+
if (!simulation)
|
|
85
|
+
throw new Error(`Simulation required`);
|
|
86
|
+
if (!msg)
|
|
87
|
+
throw new Error(`Msg required`);
|
|
88
|
+
setIsSigning(true);
|
|
89
|
+
const signer = accountProvider.signer(msg.account.address);
|
|
90
|
+
if (onClick)
|
|
91
|
+
onClick(e);
|
|
92
|
+
const p = signer
|
|
93
|
+
.signAndBroadcast(simulation, msg)
|
|
94
|
+
.then((res) => {
|
|
95
|
+
onSuccess && onSuccess(res);
|
|
96
|
+
setIsSigning(false);
|
|
97
|
+
setIsSuccess(true);
|
|
98
|
+
setTimeout(() => {
|
|
99
|
+
setIsSuccess(false);
|
|
100
|
+
}, 3000);
|
|
101
|
+
return res;
|
|
102
|
+
})
|
|
103
|
+
.catch((err) => {
|
|
104
|
+
console.error(err);
|
|
105
|
+
onError && onError(new rujira_js_1.TxError(msg, err, "signAndBroadcast"));
|
|
106
|
+
setIsSigning(false);
|
|
107
|
+
setIsRejected(true);
|
|
108
|
+
setTimeout(() => {
|
|
109
|
+
setIsRejected(false);
|
|
110
|
+
}, 3000);
|
|
111
|
+
throw err;
|
|
112
|
+
});
|
|
113
|
+
react_hot_toast_1.default.promise(p, {
|
|
114
|
+
loading: loading || t("submittingTransaction"),
|
|
115
|
+
success: success || ((res) => successHandler(res, t)),
|
|
116
|
+
error: error ||
|
|
117
|
+
((err) => {
|
|
118
|
+
console.error(err);
|
|
119
|
+
const defaultError = t("errorSubmittingTransaction");
|
|
120
|
+
switch (typeof err) {
|
|
121
|
+
case "string":
|
|
122
|
+
return (0, rujira_js_1.translateError)(err) || defaultError;
|
|
123
|
+
case "object":
|
|
124
|
+
return "message" in err
|
|
125
|
+
? (0, rujira_js_1.translateError)(err.message) || defaultError
|
|
126
|
+
: defaultError;
|
|
127
|
+
default:
|
|
128
|
+
return defaultError;
|
|
129
|
+
}
|
|
130
|
+
}),
|
|
131
|
+
});
|
|
132
|
+
};
|
|
133
|
+
const disabled = !msg || !simulation || !!simulationError || rest.disabled;
|
|
134
|
+
// Separate spacing classes (always applied) from styling classes (conditionally applied)
|
|
135
|
+
const { spacing: spacingClasses, styling: stylingClasses } = separateClasses(className);
|
|
136
|
+
// Determine if tooltip should be shown
|
|
137
|
+
const showTooltip = simulationError && simulationError.message !== "";
|
|
138
|
+
const allowanceMsg = (0, react_1.useMemo)(() => {
|
|
139
|
+
if (!msg)
|
|
140
|
+
return null;
|
|
141
|
+
if (!simulationError)
|
|
142
|
+
return null;
|
|
143
|
+
if (!(simulationError instanceof rujira_js_1.InsufficientAllowanceError))
|
|
144
|
+
return null;
|
|
145
|
+
return new rujira_js_1.MsgErc20IncreaseAllowance(msg.account, simulationError);
|
|
146
|
+
}, [msg, simulationError]);
|
|
147
|
+
const resetAllowanceMsg = (0, react_1.useMemo)(() => {
|
|
148
|
+
if (!msg)
|
|
149
|
+
return null;
|
|
150
|
+
if (!simulationError)
|
|
151
|
+
return null;
|
|
152
|
+
if (!(simulationError instanceof rujira_js_1.InsufficientAllowanceError))
|
|
153
|
+
return null;
|
|
154
|
+
if (simulationError.current === 0n)
|
|
155
|
+
return null;
|
|
156
|
+
if (simulationError.asset.symbol.toUpperCase() !== "USDT")
|
|
157
|
+
return null;
|
|
158
|
+
if (TWO_STEP_ALLOWANCE_CHAINS.has(msg.account.network))
|
|
159
|
+
return null;
|
|
160
|
+
return new rujira_js_1.MsgErc20ResetAllowance(msg.account, simulationError);
|
|
161
|
+
}, [msg, simulationError]);
|
|
162
|
+
if (resetAllowanceMsg)
|
|
163
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(exports.TxButton, { ...props, toastOpts: {
|
|
164
|
+
loading: t("resettingAllowance"),
|
|
165
|
+
success: t("allowanceReset"),
|
|
166
|
+
}, label: t("stepReset"), msg: resetAllowanceMsg, onSuccess: () => {
|
|
167
|
+
setAllowanceWasReset(true);
|
|
168
|
+
doSimulate(msg);
|
|
169
|
+
} }), (0, jsx_runtime_1.jsx)(ResetAllowanceWarning, { error: simulationError })] }));
|
|
170
|
+
if (allowanceMsg)
|
|
171
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(exports.TxButton, { ...props, toastOpts: {
|
|
172
|
+
loading: t("increasingAllowance"),
|
|
173
|
+
success: t("allowanceIncreased"),
|
|
174
|
+
}, label: allowanceWasReset ? t("stepApprove2of3") : t("stepApprove"), msg: allowanceMsg, onSuccess: () => doSimulate(msg) }), (0, jsx_runtime_1.jsx)(InsufficientAllowanceWarning, { isStep2: allowanceWasReset })] }));
|
|
175
|
+
const modProps = {
|
|
176
|
+
...rest,
|
|
177
|
+
...(rest.label && {
|
|
178
|
+
label: `${isSuccess
|
|
179
|
+
? t("success")
|
|
180
|
+
: isSigning
|
|
181
|
+
? t("waiting")
|
|
182
|
+
: isRejected
|
|
183
|
+
? t("rejected")
|
|
184
|
+
: isSimulating
|
|
185
|
+
? t("simulating")
|
|
186
|
+
: rest.label}`,
|
|
187
|
+
}),
|
|
188
|
+
};
|
|
189
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(Button_1.Button, { ...modProps, onClick: handleSign, className: (0, clsx_1.default)(stylingClasses.length > 0 ? stylingClasses : "button", spacingClasses, {
|
|
190
|
+
"button--grey": disabled && !isSimulating && !stylingClasses.includes("transparent"),
|
|
191
|
+
"button--waiting": (isSigning || isRejected || isSuccess || isSimulating) &&
|
|
192
|
+
!className?.includes("transparent"),
|
|
193
|
+
"button--success": isSuccess,
|
|
194
|
+
"button--rejected": isRejected,
|
|
195
|
+
"button--simulating": isSimulating,
|
|
196
|
+
}), style: {
|
|
197
|
+
cursor: isSigning || isSuccess || isRejected || isSimulating ? "default" : undefined,
|
|
198
|
+
...rest.style,
|
|
199
|
+
}, disabled: disabled, "data-tooltip-id": "tx-button-tip", "data-tooltip-html": showTooltip
|
|
200
|
+
? `<p class="fs-12 lh-16 fw-400 w-36 mb-0.5">${(0, rujira_js_1.translateError)(simulationError.message)}</p>`
|
|
201
|
+
: undefined, children: [(isSuccess || isRejected || isSigning || isSimulating || !!simulationError) &&
|
|
202
|
+
!className?.includes("transparent") && ((0, jsx_runtime_1.jsx)("img", { className: "w-4 h-4 filter-white big", src: isSimulating ? txsimulate_gif_1.default : !!simulationError ? exclamation_gif_1.default : isSigning ? txsign_gif_1.default : isSuccess ? txsuccess_gif_1.default : txfail_gif_1.default, alt: "lock" })), (isSigning || isRejected || isSuccess) &&
|
|
203
|
+
className?.includes("transparent") ? ((0, jsx_runtime_1.jsx)(Loader_1.Loader, { className: "w-full h-full" })) : (((!isSigning && !isRejected && !isSuccess) ||
|
|
204
|
+
className?.includes("transparent")) &&
|
|
205
|
+
children)] }), hideSimulation ? null : msg ? ((0, jsx_runtime_1.jsx)(SimulationComponent, { simulation: simulation, error: simulationError })) : null] }));
|
|
206
|
+
};
|
|
207
|
+
exports.TxButton = TxButton;
|
|
208
|
+
const TxButtonTip = () => ((0, jsx_runtime_1.jsx)(react_tooltip_1.Tooltip, { id: "tx-button-tip", className: "tooltip", float: true, style: { zIndex: 203 } }));
|
|
209
|
+
exports.TxButtonTip = TxButtonTip;
|
|
210
|
+
const DefaultSimulationComponent = ({ simulation, error, isSimulating, }) => {
|
|
211
|
+
const { t } = (0, i18n_1.useTranslation)("common");
|
|
212
|
+
if (error instanceof rujira_js_1.InsufficientAllowanceError) {
|
|
213
|
+
return (0, jsx_runtime_1.jsx)(InsufficientAllowanceWarning, {});
|
|
214
|
+
}
|
|
215
|
+
if (error)
|
|
216
|
+
return (0, jsx_runtime_1.jsx)("span", { children: "\u00A0" });
|
|
217
|
+
if (!simulation && !isSimulating)
|
|
218
|
+
return (0, jsx_runtime_1.jsx)("span", { children: "\u00A0" });
|
|
219
|
+
return ((0, jsx_runtime_1.jsx)("small", { className: "fs-12 text-center mt-1 color-grey block", children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [t("networkFee"), " ", simulation ? ((0, jsx_runtime_1.jsx)(Decimal_1.Decimal, { subscript: true, amount: simulation.amount, decimals: simulation.decimals, symbol: simulation.symbol, className: "color-white" })) : ((0, jsx_runtime_1.jsx)("span", { children: t("calculating") }))] }) }));
|
|
220
|
+
};
|
|
221
|
+
const InsufficientAllowanceWarning = ({ isStep2 = false, }) => {
|
|
222
|
+
const { t } = (0, i18n_1.useTranslation)("common");
|
|
223
|
+
return ((0, jsx_runtime_1.jsxs)(Warning_1.Warning, { className: "warning warning--borderless mt-2 condensed flex ai-c", color: "teal", children: [(0, jsx_runtime_1.jsx)("img", { src: unlock_gif_1.default, alt: "lock", style: { height: "2.25rem" } }), (0, jsx_runtime_1.jsx)("div", { className: "text-left", children: t(isStep2
|
|
224
|
+
? "insufficientAllowanceWarningStep2"
|
|
225
|
+
: "insufficientAllowanceWarning") })] }));
|
|
226
|
+
};
|
|
227
|
+
const ResetAllowanceWarning = ({ error, }) => {
|
|
228
|
+
return ((0, jsx_runtime_1.jsxs)(Warning_1.Warning, { className: "warning warning--borderless mt-2 condensed flex ai-c", color: "teal", children: [(0, jsx_runtime_1.jsx)("img", { src: unlock_gif_1.default, alt: "lock", style: { height: "2.25rem" } }), (0, jsx_runtime_1.jsx)("div", { className: "text-left", children: (0, jsx_runtime_1.jsx)(react_i18next_1.Trans, { i18nKey: "common:resetAllowanceWarning", components: {
|
|
229
|
+
allowance: ((0, jsx_runtime_1.jsx)(Decimal_1.Decimal, { amount: error.current, decimals: error.asset.decimals, symbol: error.asset.symbol, className: "color-white" })),
|
|
230
|
+
} }) })] }));
|
|
231
|
+
};
|
|
232
|
+
const successHandler = (res, t) => res.label ? ((0, jsx_runtime_1.jsx)("p", { children: res.label })) : ((0, jsx_runtime_1.jsxs)("p", { children: [t("transactionSucceeded"), (0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)("a", { href: (0, rujira_js_1.networkTxLink)(res), target: "_blank", className: "color-white no-underline fs-12", children: res.txHash.slice(0, 8) + "..." + res.txHash.slice(-8) })] }));
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.usePopout = exports.Popout = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const react_dom_1 = require("react-dom");
|
|
7
|
+
const Popout = ({ children, position, visible }) => {
|
|
8
|
+
const node = (0, react_1.useRef)(null);
|
|
9
|
+
if (!visible)
|
|
10
|
+
return null;
|
|
11
|
+
return (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsx)("nav", { ref: node, className: "popout condensed", style: {
|
|
12
|
+
top: position.top - (node.current?.offsetHeight || 0) + 8,
|
|
13
|
+
left: position.left - (node.current?.offsetWidth || 0),
|
|
14
|
+
}, children: children }), document.body);
|
|
15
|
+
};
|
|
16
|
+
exports.Popout = Popout;
|
|
17
|
+
const usePopout = () => {
|
|
18
|
+
const [popoutState, setPopoutState] = (0, react_1.useState)({
|
|
19
|
+
content: "",
|
|
20
|
+
position: { top: 0, left: 0 },
|
|
21
|
+
visible: false,
|
|
22
|
+
});
|
|
23
|
+
const showPopout = (content, target) => {
|
|
24
|
+
const rect = target.getBoundingClientRect();
|
|
25
|
+
setPopoutState({
|
|
26
|
+
content,
|
|
27
|
+
position: {
|
|
28
|
+
top: rect.top + window.scrollY + rect.height,
|
|
29
|
+
left: rect.left + window.scrollX,
|
|
30
|
+
},
|
|
31
|
+
visible: true,
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
const hidePopout = () => {
|
|
35
|
+
setPopoutState((prev) => ({ ...prev, visible: false }));
|
|
36
|
+
};
|
|
37
|
+
return { popoutState, showPopout, hidePopout };
|
|
38
|
+
};
|
|
39
|
+
exports.usePopout = usePopout;
|