@wallet-ui/react
Version:
React components for Wallet UI
669 lines (657 loc) • 26.5 kB
JavaScript
import React18, { createContext, useContext, useEffect, useId, useMemo, useState, useCallback } from 'react';
import { useConnect, useDisconnect, useWallets, getUiWalletAccountStorageKey, uiWalletAccountsAreSame, uiWalletAccountBelongsToUiWallet } from '@wallet-standard/react';
export * from '@wallet-standard/react';
import { Portal, useMachine, normalizeProps } from '@zag-js/react';
import * as menu from '@zag-js/menu';
import * as dialog from '@zag-js/dialog';
import { useWalletAccountTransactionSendingSigner } from '@solana/react';
export * from '@solana/react';
import { useStore } from '@nanostores/react';
import { createStorageAccount, createStorageCluster, handleCopyText } from '@wallet-ui/core';
export * from '@wallet-ui/core';
export * from '@solana/wallet-standard-features';
export * from '@wallet-standard/core';
// src/base-button.tsx
function BaseButton({ className, label, leftSection, onClick, rightSection, ...props }) {
return /* @__PURE__ */ React18.createElement("button", { "data-wu": "base-button", className: `${className ?? ""}`, onClick, ...props }, leftSection ? /* @__PURE__ */ React18.createElement("span", { "data-wu": "base-button-left-section" }, leftSection) : null, label, rightSection ? /* @__PURE__ */ React18.createElement("span", { "data-wu": "base-button-right-section" }, rightSection) : null);
}
var WalletUiContext = React18.createContext({});
// src/use-wallet-ui.tsx
function useWalletUi() {
return React18.useContext(WalletUiContext);
}
var WalletUiAccountContext = createContext({});
// src/use-wallet-ui-account.tsx
function useWalletUiAccount() {
return useContext(WalletUiAccountContext);
}
// src/use-wallet-ui-wallet.tsx
function useWalletUiWallet({ wallet }) {
const { connect: connectAccount } = useWalletUi();
const { setAccount } = useWalletUiAccount();
const [isConnecting, connect3] = useConnect(wallet);
const [isDisconnecting, disconnect] = useDisconnect(wallet);
useEffect(() => {
}, [isDisconnecting]);
return {
connect: async () => {
const connectedAccount = await connect3();
if (!connectedAccount.length) {
console.warn(`Connect to ${wallet.name} but there are no accounts.`);
return connectedAccount;
}
const first = connectedAccount[0];
setAccount(first);
connectAccount(first);
return connectedAccount;
},
disconnect,
isConnecting,
isDisconnecting
};
}
function WalletUiIcon({ className, wallet, ...props }) {
if (!wallet) {
return null;
}
return /* @__PURE__ */ React18.createElement("img", { "data-wu": "wallet-ui-icon", src: wallet.icon, alt: wallet.name, className: className ?? "", ...props });
}
// src/base-dropdown.tsx
var BaseDropdownItemType = /* @__PURE__ */ ((BaseDropdownItemType2) => {
BaseDropdownItemType2["Item"] = "Item";
BaseDropdownItemType2["WalletConnect"] = "WalletConnect";
BaseDropdownItemType2["WalletCopy"] = "WalletCopy";
BaseDropdownItemType2["WalletDisconnect"] = "WalletDisconnect";
BaseDropdownItemType2["WalletNeeded"] = "WalletNeeded";
return BaseDropdownItemType2;
})(BaseDropdownItemType || {});
function BaseDropdown({ buttonProps, dropdown, items, showIndicator }) {
const api = dropdown.api;
const trigger = /* @__PURE__ */ React18.createElement(
BaseButton,
{
...api.getTriggerProps(),
rightSection: showIndicator ? /* @__PURE__ */ React18.createElement("span", { ...api.getIndicatorProps() }, /* @__PURE__ */ React18.createElement(BaseDropdownChevronDown, null)) : null,
...buttonProps
}
);
return /* @__PURE__ */ React18.createElement("div", { "data-wu": "base-dropdown" }, trigger, /* @__PURE__ */ React18.createElement("div", { ...api.getPositionerProps(), "data-wu": "base-dropdown-wrapper" }, /* @__PURE__ */ React18.createElement("div", { ...api.getContentProps(), "data-wu": "base-dropdown-list", "data-part": "content" }, items.map((item) => {
return /* @__PURE__ */ React18.createElement(
BaseDropdownItem,
{
...api.getItemProps({ value: item.value }),
key: item.value,
item,
afterClick: () => {
if (item.disabled) {
return;
}
if (item.closeMenu !== false) {
dropdown.close();
}
}
}
);
}))));
}
function BaseDropdownItem({ afterClick, item }) {
if (!item.wallet) {
return /* @__PURE__ */ React18.createElement(BaseDropdownItemRender, { afterClick, item });
}
switch (item.type) {
case "Item" /* Item */:
return /* @__PURE__ */ React18.createElement(BaseDropdownItemRender, { afterClick, item });
case "WalletConnect" /* WalletConnect */:
return /* @__PURE__ */ React18.createElement(BaseDropdownItemWalletConnect, { afterClick, item, wallet: item.wallet });
case "WalletCopy" /* WalletCopy */:
return /* @__PURE__ */ React18.createElement(BaseDropdownItemRender, { afterClick, item });
case "WalletDisconnect" /* WalletDisconnect */:
return /* @__PURE__ */ React18.createElement(BaseDropdownItemWalletDisconnect, { afterClick, item, wallet: item.wallet });
}
}
function BaseDropdownItemWalletConnect({
afterClick,
item,
wallet
}) {
const { connect: connect3 } = useWalletUiWallet({ wallet });
return /* @__PURE__ */ React18.createElement(
BaseDropdownItemRender,
{
afterClick,
item: {
...item,
handler: async () => {
await connect3();
return await item.handler();
},
leftSection: wallet ? /* @__PURE__ */ React18.createElement(WalletUiIcon, { wallet }) : void 0
}
}
);
}
function BaseDropdownItemWalletDisconnect({
afterClick,
item,
wallet
}) {
const { disconnect } = useWalletUiWallet({ wallet });
return /* @__PURE__ */ React18.createElement(
BaseDropdownItemRender,
{
afterClick,
item: {
...item,
handler: async () => {
await disconnect();
return await item.handler();
}
}
}
);
}
function BaseDropdownItemRender({ afterClick, item }) {
function onClick() {
if (item.disabled) {
return;
}
void item.handler().then(() => {
afterClick();
});
}
return /* @__PURE__ */ React18.createElement("button", { type: "button", "data-wu": "base-dropdown-item", "data-part": "item", onClick }, item.leftSection ? /* @__PURE__ */ React18.createElement("span", { "data-wu": "base-dropdown-item-left-section" }, item.leftSection) : null, item.label, item.rightSection ? /* @__PURE__ */ React18.createElement("span", { "data-wu": "base-dropdown-item-right-section" }, item.rightSection) : null);
}
function BaseDropdownChevronDown(props) {
return /* @__PURE__ */ React18.createElement(
"svg",
{
xmlns: "http://www.w3.org/2000/svg",
width: 12,
height: 12,
viewBox: "0 0 24 24",
fill: "none",
stroke: "currentColor",
strokeWidth: "2",
strokeLinecap: "round",
strokeLinejoin: "round",
...props
},
/* @__PURE__ */ React18.createElement("path", { d: "m6 9 6 6 6-6" })
);
}
function BaseSvg({ ...props }) {
return /* @__PURE__ */ React18.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", ...props }, props.children);
}
// src/wallet-ui-icon-close.tsx
function WalletUiIconClose({ ...props }) {
return /* @__PURE__ */ React18.createElement(
BaseSvg,
{
fill: "none",
stroke: "currentColor",
strokeWidth: "3",
width: 12,
height: 12,
viewBox: "0 0 14 14",
...props
},
/* @__PURE__ */ React18.createElement("path", { d: "M14 12.461 8.3 6.772l5.234-5.233L12.006 0 6.772 5.234 1.54 0 0 1.539l5.234 5.233L0 12.006l1.539 1.528L6.772 8.3l5.69 5.7L14 12.461z" })
);
}
// src/base-modal.tsx
function BaseModal({ modal, buttonLabel, buttonProps = {}, ...props }) {
const api = modal.api;
return /* @__PURE__ */ React18.createElement(React18.Fragment, null, buttonLabel ? /* @__PURE__ */ React18.createElement(BaseButton, { label: buttonLabel, ...buttonProps, ...api.getTriggerProps() }) : null, api.open && /* @__PURE__ */ React18.createElement(Portal, null, /* @__PURE__ */ React18.createElement("div", { ...api.getBackdropProps() }), /* @__PURE__ */ React18.createElement("div", { ...api.getPositionerProps() }, /* @__PURE__ */ React18.createElement("div", { ...api.getContentProps() }, /* @__PURE__ */ React18.createElement("header", null, /* @__PURE__ */ React18.createElement("button", { ...api.getCloseTriggerProps() }, /* @__PURE__ */ React18.createElement(WalletUiIconClose, null))), props.description ? /* @__PURE__ */ React18.createElement("p", { ...api.getDescriptionProps() }, props.description) : null, /* @__PURE__ */ React18.createElement("main", null, props.children)))));
}
function useBaseDropdown() {
const service = useMachine(menu.machine, { id: useId() });
const api = menu.connect(service, normalizeProps);
return {
api,
close: () => service.send({ type: "CLOSE" }),
open: () => service.send({ type: "OPEN" })
};
}
function useBaseModal() {
const service = useMachine(dialog.machine, { id: useId(), modal: true });
const api = dialog.connect(service, normalizeProps);
return {
api,
close: () => service.send({ type: "CLOSE" }),
open: () => service.send({ type: "OPEN" })
};
}
var WalletUiClusterContext = createContext({});
// src/use-wallet-ui-cluster.tsx
function useWalletUiCluster() {
return useContext(WalletUiClusterContext);
}
function getDropdownItemsWallets({
wallets,
connect: connect3
}) {
return wallets.length ? wallets.map((wallet) => ({
handler: async () => {
const account = wallet.accounts.length > 0 ? wallet.accounts[0] : void 0;
if (!account) {
return;
}
connect3(account);
await Promise.resolve();
},
label: wallet.name,
type: "WalletConnect" /* WalletConnect */,
value: wallet.name,
wallet
})) : [
{
handler: async () => {
window.open("https://solana.com/solana-wallets", "_blank");
await Promise.resolve();
},
label: "You'll need a wallet on Solana to continue",
type: "WalletNeeded" /* WalletNeeded */,
value: "no-wallets"
}
];
}
function useWalletUiDropdown() {
const dropdown = useBaseDropdown();
const { account, connect: connect3, copy, disconnect, connected, wallet, wallets } = useWalletUi();
const itemsWallets = useMemo(() => getDropdownItemsWallets({ connect: connect3, wallets }), [wallets, connect3]);
const itemsConnected = useMemo(
() => [
{
handler: async () => {
copy();
void await Promise.resolve();
},
label: "Copy Address",
type: "WalletCopy" /* WalletCopy */,
value: "copy"
},
{
handler: async () => {
disconnect();
dropdown.close();
await Promise.resolve();
},
label: "Disconnect",
type: "WalletDisconnect" /* WalletDisconnect */,
value: "disconnect",
wallet
},
...itemsWallets
],
[copy, disconnect, dropdown, wallet, itemsWallets]
);
const items = useMemo(() => {
return connected ? itemsConnected : itemsWallets;
}, [connected, itemsConnected, itemsWallets]);
const buttonProps = useMemo(() => {
return {
label: connected ? (account ? ellipsify(account.address) : wallet?.name) ?? "Connected" : "Select Wallet",
leftSection: connected ? /* @__PURE__ */ React18.createElement(WalletUiIcon, { wallet }) : void 0
};
}, [account, connected, wallet]);
return {
buttonProps,
connected,
dropdown,
items
};
}
function ellipsify(str = "", len = 4, delimiter = "..") {
const strLen = str.length;
const limit = len * 2 + delimiter.length;
return strLen >= limit ? str.substring(0, len) + delimiter + str.substring(strLen - len, strLen) : str;
}
function useWalletUiSigner({
account
}) {
const { cluster } = useWalletUi();
return useWalletAccountTransactionSendingSigner(account, cluster.id);
}
function useWalletUiWallets() {
const readonlyWallets = useWallets();
return useMemo(
() => readonlyWallets.filter((wallet) => wallet.chains.some((i) => i.startsWith("solana:"))).sort((a, b) => a.name.localeCompare(b.name)),
[readonlyWallets]
);
}
var wasSetterInvoked = false;
function getSavedWalletAccount(wallets, savedWalletNameAndAddress) {
if (wasSetterInvoked) {
return;
}
if (!savedWalletNameAndAddress || typeof savedWalletNameAndAddress !== "string") {
return;
}
const [savedWalletName, savedAccountAddress] = savedWalletNameAndAddress.split(":");
if (!savedWalletName || !savedAccountAddress) {
return;
}
const wallet = wallets.find((w) => w.name === savedWalletName);
if (!wallet) {
return;
}
return wallet.accounts.find((a) => a.address === savedAccountAddress);
}
function WalletUiAccountContextProvider({
children,
cluster,
storage = createStorageAccount()
}) {
const wallets = useWallets();
const accountId = useStore(storage.value);
const [account, setAccountInternal] = useState(
() => getSavedWalletAccount(wallets, accountId)
);
const setAccount = useCallback(
(setStateAction) => {
setAccountInternal((prevAccount) => {
wasSetterInvoked = true;
const nextWalletAccount = typeof setStateAction === "function" ? setStateAction(prevAccount) : setStateAction;
const accountKey = nextWalletAccount ? getUiWalletAccountStorageKey(nextWalletAccount) : void 0;
storage.set(accountKey ? accountKey : void 0);
return nextWalletAccount;
});
},
[storage]
);
useEffect(() => {
const savedWalletAccount = getSavedWalletAccount(wallets, accountId);
if (savedWalletAccount) {
setAccountInternal(savedWalletAccount);
}
}, [accountId, wallets]);
const walletAccount = useMemo(() => {
if (account) {
for (const uiWallet of wallets) {
for (const uiWalletAccount of uiWallet.accounts) {
if (uiWalletAccountsAreSame(account, uiWalletAccount)) {
return uiWalletAccount;
}
}
if (uiWalletAccountBelongsToUiWallet(account, uiWallet) && uiWallet.accounts[0]) {
return uiWallet.accounts[0];
}
}
}
}, [account, wallets]);
useEffect(() => {
if (account && !walletAccount) {
setAccountInternal(void 0);
}
}, [account, walletAccount]);
const wallet = useMemo(() => {
if (!walletAccount) {
return void 0;
}
for (const uiWallet of wallets) {
for (const uiWalletAccount of uiWallet.accounts) {
if (uiWalletAccountsAreSame(walletAccount, uiWalletAccount)) {
return uiWallet;
}
}
if (uiWalletAccountBelongsToUiWallet(walletAccount, uiWallet) && uiWallet.accounts[0]) {
return uiWallet;
}
}
}, [walletAccount, wallets]);
const accountKeys = useMemo(() => {
if (!walletAccount) {
return [];
}
return [cluster.id, getUiWalletAccountStorageKey(walletAccount)].filter(Boolean);
}, [walletAccount, cluster.id]);
return /* @__PURE__ */ React18.createElement(
WalletUiAccountContext.Provider,
{
value: useMemo(
() => ({
account: walletAccount,
accountKeys,
cluster,
setAccount,
wallet
}),
[accountKeys, cluster, setAccount, wallet, walletAccount]
)
},
children
);
}
function WalletUiClusterContextProvider({
clusters,
render,
storage = createStorageCluster()
}) {
const clusterId = useStore(storage.value);
if (!clusters.length) {
throw new Error("No clusters provided");
}
const found = clusters.find((c) => c.id === clusterId);
const first = clusters[0];
const value = {
cluster: found ?? first,
clusters,
setCluster: (clusterId2) => {
const cluster = clusters.find((c) => c.id === clusterId2);
if (!cluster) {
throw new Error(`Cluster ${clusterId2} not found`);
}
storage.set(clusterId2);
}
};
return /* @__PURE__ */ React18.createElement(WalletUiClusterContext.Provider, { value }, render(value));
}
function WalletUiContextProvider({ children }) {
const { account, accountKeys, cluster, setAccount, wallet } = useWalletUiAccount();
const wallets = useWalletUiWallets();
const connected = Boolean(wallet && wallet?.accounts.length > 0);
function connect3(account2) {
setAccount(account2);
}
function disconnect() {
setAccount(void 0);
}
function copy() {
if (!account) {
return;
}
handleCopyText(account.address);
}
const value = {
account,
accountKeys,
cluster,
connect: connect3,
connected,
copy,
disconnect,
wallet,
wallets
};
return /* @__PURE__ */ React18.createElement(WalletUiContext.Provider, { value }, children);
}
// src/wallet-ui.tsx
function createWalletUiConfig(props) {
return { ...props };
}
function WalletUi({ children, config: { accountStorage, clusters, clusterStorage, ...config } }) {
return /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(
WalletUiClusterContextProvider,
{
clusters,
storage: clusterStorage,
render: ({ cluster }) => {
return /* @__PURE__ */ React18.createElement(WalletUiAccountContextProvider, { cluster, storage: accountStorage }, /* @__PURE__ */ React18.createElement(WalletUiContextProvider, { ...config }, children));
}
}
));
}
function WalletUiDropdown({ ...props }) {
const { buttonProps, items, dropdown } = useWalletUiDropdown();
return /* @__PURE__ */ React18.createElement(BaseDropdown, { ...props, buttonProps: { ...buttonProps }, dropdown, items });
}
// src/wallet-ui-account-guard.tsx
function WalletUiAccountGuard({ fallback = /* @__PURE__ */ React18.createElement(WalletUiDropdown, null), render }) {
const { account, accountKeys, cluster, wallet } = useWalletUiAccount();
return account ? render({ account, accountKeys, cluster, wallet }) : fallback;
}
function WalletUiClusterDropdown({ buttonProps, ...props }) {
const dropdown = useBaseDropdown();
const { cluster, clusters, setCluster } = useWalletUiCluster();
return /* @__PURE__ */ React18.createElement(
BaseDropdown,
{
buttonProps: { ...buttonProps, label: cluster.label },
items: clusters.map((cluster2) => ({
handler: async () => {
setCluster(cluster2.id);
await Promise.resolve();
},
label: cluster2.label,
type: "Item" /* Item */,
value: cluster2.id
})),
dropdown,
...props
}
);
}
function WalletUiIconNoWallet({ ...props }) {
return /* @__PURE__ */ React18.createElement(BaseSvg, { fill: "none", height: 100, width: 100, viewBox: "0 0 97 96", ...props }, /* @__PURE__ */ React18.createElement("circle", { cx: "48.5", cy: "48", r: "48", fill: "url(#paint0_linear_880_5115)", fillOpacity: "0.1" }), /* @__PURE__ */ React18.createElement(
"circle",
{
cx: "48.5",
cy: "48",
r: "47",
stroke: "url(#paint1_linear_880_5115)",
strokeOpacity: "0.4",
strokeWidth: "2"
}
), /* @__PURE__ */ React18.createElement("g", { clipPath: "url(#clip0_880_5115)" }, /* @__PURE__ */ React18.createElement(
"path",
{
d: "M65.5769 28.1523H31.4231C27.6057 28.1523 24.5 31.258 24.5 35.0754V60.9215C24.5 64.7389 27.6057 67.8446 31.4231 67.8446H65.5769C69.3943 67.8446 72.5 64.7389 72.5 60.9215V35.0754C72.5 31.258 69.3943 28.1523 65.5769 28.1523ZM69.7308 52.1523H59.5769C57.2865 52.1523 55.4231 50.289 55.4231 47.9985C55.4231 45.708 57.2864 43.8446 59.5769 43.8446H69.7308V52.1523ZM69.7308 41.0754H59.5769C55.7595 41.0754 52.6539 44.1811 52.6539 47.9985C52.6539 51.8159 55.7595 54.9215 59.5769 54.9215H69.7308V60.9215C69.7308 63.2119 67.8674 65.0754 65.5769 65.0754H31.4231C29.1327 65.0754 27.2692 63.212 27.2692 60.9215V35.0754C27.2692 32.785 29.1326 30.9215 31.4231 30.9215H65.5769C67.8673 30.9215 69.7308 32.7849 69.7308 35.0754V41.0754Z",
fill: "url(#paint2_linear_880_5115)"
}
), /* @__PURE__ */ React18.createElement(
"path",
{
d: "M61.4231 46.6172H59.577C58.8123 46.6172 58.1924 47.2371 58.1924 48.0018C58.1924 48.7665 58.8123 49.3863 59.577 49.3863H61.4231C62.1878 49.3863 62.8077 48.7664 62.8077 48.0018C62.8077 47.2371 62.1878 46.6172 61.4231 46.6172Z",
fill: "url(#paint3_linear_880_5115)"
}
)), /* @__PURE__ */ React18.createElement("defs", null, /* @__PURE__ */ React18.createElement(
"linearGradient",
{
id: "paint0_linear_880_5115",
x1: "3.41664",
y1: "98.0933",
x2: "103.05",
y2: "8.42498",
gradientUnits: "userSpaceOnUse"
},
/* @__PURE__ */ React18.createElement("stop", { stopColor: "#9945FF" }),
/* @__PURE__ */ React18.createElement("stop", { offset: "0.14", stopColor: "#8A53F4" }),
/* @__PURE__ */ React18.createElement("stop", { offset: "0.42", stopColor: "#6377D6" }),
/* @__PURE__ */ React18.createElement("stop", { offset: "0.79", stopColor: "#24B0A7" }),
/* @__PURE__ */ React18.createElement("stop", { offset: "0.99", stopColor: "#00D18C" }),
/* @__PURE__ */ React18.createElement("stop", { offset: "1", stopColor: "#00D18C" })
), /* @__PURE__ */ React18.createElement(
"linearGradient",
{
id: "paint1_linear_880_5115",
x1: "3.41664",
y1: "98.0933",
x2: "103.05",
y2: "8.42498",
gradientUnits: "userSpaceOnUse"
},
/* @__PURE__ */ React18.createElement("stop", { stopColor: "#9945FF" }),
/* @__PURE__ */ React18.createElement("stop", { offset: "0.14", stopColor: "#8A53F4" }),
/* @__PURE__ */ React18.createElement("stop", { offset: "0.42", stopColor: "#6377D6" }),
/* @__PURE__ */ React18.createElement("stop", { offset: "0.79", stopColor: "#24B0A7" }),
/* @__PURE__ */ React18.createElement("stop", { offset: "0.99", stopColor: "#00D18C" }),
/* @__PURE__ */ React18.createElement("stop", { offset: "1", stopColor: "#00D18C" })
), /* @__PURE__ */ React18.createElement(
"linearGradient",
{
id: "paint2_linear_880_5115",
x1: "25.9583",
y1: "68.7101",
x2: "67.2337",
y2: "23.7879",
gradientUnits: "userSpaceOnUse"
},
/* @__PURE__ */ React18.createElement("stop", { stopColor: "#9945FF" }),
/* @__PURE__ */ React18.createElement("stop", { offset: "0.14", stopColor: "#8A53F4" }),
/* @__PURE__ */ React18.createElement("stop", { offset: "0.42", stopColor: "#6377D6" }),
/* @__PURE__ */ React18.createElement("stop", { offset: "0.79", stopColor: "#24B0A7" }),
/* @__PURE__ */ React18.createElement("stop", { offset: "0.99", stopColor: "#00D18C" }),
/* @__PURE__ */ React18.createElement("stop", { offset: "1", stopColor: "#00D18C" })
), /* @__PURE__ */ React18.createElement(
"linearGradient",
{
id: "paint3_linear_880_5115",
x1: "58.3326",
y1: "49.4467",
x2: "61.0002",
y2: "45.4453",
gradientUnits: "userSpaceOnUse"
},
/* @__PURE__ */ React18.createElement("stop", { stopColor: "#9945FF" }),
/* @__PURE__ */ React18.createElement("stop", { offset: "0.14", stopColor: "#8A53F4" }),
/* @__PURE__ */ React18.createElement("stop", { offset: "0.42", stopColor: "#6377D6" }),
/* @__PURE__ */ React18.createElement("stop", { offset: "0.79", stopColor: "#24B0A7" }),
/* @__PURE__ */ React18.createElement("stop", { offset: "0.99", stopColor: "#00D18C" }),
/* @__PURE__ */ React18.createElement("stop", { offset: "1", stopColor: "#00D18C" })
), /* @__PURE__ */ React18.createElement("clipPath", { id: "clip0_880_5115" }, /* @__PURE__ */ React18.createElement("rect", { width: "48", height: "48", fill: "white", transform: "translate(24.5 24)" }))));
}
function WalletUiLabel({ className, wallet, ...props }) {
if (!wallet) {
return null;
}
return /* @__PURE__ */ React18.createElement("span", { "data-wu": "wallet-ui-label", className: `${className ?? ""}`, ...props }, wallet.name);
}
function WalletUiListButton({ className, select, wallet, ...props }) {
const [pending, setPending] = React18.useState(false);
function handleSelect() {
if (!select) {
return;
}
setPending(true);
const account = wallet.accounts.length > 0 ? wallet.accounts[0] : void 0;
if (!account) {
return;
}
void select(account).finally(() => setPending(false));
}
return /* @__PURE__ */ React18.createElement(
"button",
{
disabled: pending,
"data-wu": "wallet-ui-list-button",
className: `${pending ? "pending" : ""} ${className ?? ""}`,
onClick: handleSelect,
...props
},
/* @__PURE__ */ React18.createElement(WalletUiIcon, { wallet }),
/* @__PURE__ */ React18.createElement(WalletUiLabel, { wallet })
);
}
// src/wallet-ui-list.tsx
function WalletUiList({ className, select, wallets, ...props }) {
return /* @__PURE__ */ React18.createElement("div", { "data-wu": "wallet-ui-list", className: `${className ?? ""}`, ...props }, wallets.map((wallet) => /* @__PURE__ */ React18.createElement(WalletUiListButton, { key: wallet.name, select, wallet })));
}
function WalletUiModal({ wallets, select, ...props }) {
return /* @__PURE__ */ React18.createElement(BaseModal, { description: "Connect a wallet on Solana to continue", ...props }, /* @__PURE__ */ React18.createElement(WalletUiList, { wallets, select }));
}
function WalletUiModalTrigger({ label = "Select Wallet", modal, ...props }) {
return /* @__PURE__ */ React18.createElement(BaseButton, { label, onClick: () => void modal.open(), ...props });
}
export { BaseButton, BaseDropdown, BaseDropdownChevronDown, BaseDropdownItemType, BaseModal, BaseSvg, WalletUi, WalletUiAccountContext, WalletUiAccountContextProvider, WalletUiAccountGuard, WalletUiClusterContext, WalletUiClusterContextProvider, WalletUiClusterDropdown, WalletUiContext, WalletUiContextProvider, WalletUiDropdown, WalletUiIcon, WalletUiIconClose, WalletUiIconNoWallet, WalletUiLabel, WalletUiList, WalletUiListButton, WalletUiModal, WalletUiModalTrigger, createWalletUiConfig, ellipsify, useBaseDropdown, useBaseModal, useWalletUi, useWalletUiAccount, useWalletUiCluster, useWalletUiDropdown, useWalletUiSigner, useWalletUiWallet, useWalletUiWallets };
//# sourceMappingURL=index.node.mjs.map
//# sourceMappingURL=index.node.mjs.map