@liberfi.io/ui-chain-select 0.1.12 → 0.1.13
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.d.mts +47 -28
- package/dist/index.d.ts +47 -28
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -15
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import * as
|
|
3
|
-
import {
|
|
2
|
+
import * as react from 'react';
|
|
3
|
+
import { ReactNode } from 'react';
|
|
4
4
|
import * as jotai from 'jotai';
|
|
5
5
|
import * as jotai_utils from 'jotai/utils';
|
|
6
|
+
import { atomWithStorage } from 'jotai/utils';
|
|
7
|
+
import * as _liberfi_io_types from '@liberfi.io/types';
|
|
8
|
+
import { Chain, ChainNamespace } from '@liberfi.io/types';
|
|
6
9
|
|
|
7
10
|
declare global {
|
|
8
11
|
interface Window {
|
|
@@ -11,47 +14,68 @@ declare global {
|
|
|
11
14
|
};
|
|
12
15
|
}
|
|
13
16
|
}
|
|
14
|
-
declare const _default: "0.1.
|
|
17
|
+
declare const _default: "0.1.13";
|
|
15
18
|
|
|
16
|
-
type
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
candidates?: Chain[];
|
|
20
|
-
onSelectChain?: (chain: Chain) => void | Promise<void>;
|
|
21
|
-
isSwitching?: boolean;
|
|
22
|
-
className?: string;
|
|
19
|
+
type ChainAtoms = {
|
|
20
|
+
chainAtom: ReturnType<typeof atomWithStorage<Chain>>;
|
|
21
|
+
chainNamespaceAtom: ReturnType<typeof atomWithStorage<ChainNamespace>>;
|
|
23
22
|
};
|
|
24
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Creates chain state atoms with optional storage key prefix.
|
|
25
|
+
* Use a prefix when multiple independent chain selectors must coexist on the same origin.
|
|
26
|
+
*/
|
|
27
|
+
declare function createChainAtoms(storageKeyPrefix?: string): ChainAtoms;
|
|
28
|
+
/** Default atoms (used when not inside ChainSelectProvider) */
|
|
29
|
+
declare const defaultChainAtoms: ChainAtoms;
|
|
30
|
+
/** Current chain (default instance, key "chain") */
|
|
31
|
+
declare const chainAtom: jotai.WritableAtom<Chain, [Chain | typeof jotai_utils.RESET | ((prev: Chain) => Chain | typeof jotai_utils.RESET)], void>;
|
|
32
|
+
/** Current chain namespace (default instance, key "chainNamespace") */
|
|
33
|
+
declare const chainNamespaceAtom: jotai.WritableAtom<ChainNamespace, [typeof jotai_utils.RESET | ChainNamespace | ((prev: ChainNamespace) => typeof jotai_utils.RESET | ChainNamespace)], void>;
|
|
25
34
|
|
|
26
|
-
type
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
35
|
+
type ChainSelectStateContextValue = ReturnType<typeof createChainAtoms>;
|
|
36
|
+
declare const ChainSelectStateContext: react.Context<ChainAtoms>;
|
|
37
|
+
type ChainSelectProviderProps = {
|
|
38
|
+
/** Optional storage key prefix so multiple instances can coexist (e.g. "app1_") */
|
|
39
|
+
storageKeyPrefix?: string;
|
|
40
|
+
children: ReactNode;
|
|
41
|
+
};
|
|
42
|
+
declare function ChainSelectProvider({ storageKeyPrefix, children, }: ChainSelectProviderProps): react_jsx_runtime.JSX.Element;
|
|
43
|
+
|
|
44
|
+
type ChainAvatarProps = {
|
|
45
|
+
chain: Chain;
|
|
32
46
|
className?: string;
|
|
33
47
|
};
|
|
34
|
-
declare function
|
|
48
|
+
declare function ChainAvatar({ chain, className }: ChainAvatarProps): react_jsx_runtime.JSX.Element;
|
|
35
49
|
|
|
36
|
-
type
|
|
50
|
+
type ChainSelectUIProps = {
|
|
37
51
|
size?: "sm" | "md" | "lg";
|
|
38
|
-
candidates: Chain[];
|
|
39
52
|
chain?: Chain;
|
|
53
|
+
candidates?: Chain[];
|
|
40
54
|
onSelectChain?: (chain: Chain) => void | Promise<void>;
|
|
41
55
|
isSwitching?: boolean;
|
|
42
56
|
className?: string;
|
|
43
57
|
};
|
|
44
|
-
declare function
|
|
58
|
+
declare function ChainSelectUI({ size, chain, candidates, onSelectChain, isSwitching, className, }: ChainSelectUIProps): react_jsx_runtime.JSX.Element;
|
|
45
59
|
|
|
46
60
|
type ChainSelectWidgetProps = {
|
|
47
61
|
size?: "sm" | "md" | "lg";
|
|
48
62
|
className?: string;
|
|
63
|
+
/** Optional list of chains to show. Defaults to [SOLANA, ETHEREUM, BINANCE] when not provided. */
|
|
64
|
+
candidates?: Chain[];
|
|
49
65
|
onSwitchChain?: (chain: Chain) => Promise<void>;
|
|
66
|
+
/** Called when switching chain succeeds; caller can toast / analytics here */
|
|
67
|
+
onSuccess?: (chain: Chain) => void;
|
|
68
|
+
/** Called when switching chain fails; caller can toast / modal / report here */
|
|
69
|
+
onError?: (error: unknown) => void;
|
|
50
70
|
};
|
|
51
|
-
declare function ChainSelectWidget({ size, className, onSwitchChain, }: ChainSelectWidgetProps): react_jsx_runtime.JSX.Element;
|
|
71
|
+
declare function ChainSelectWidget({ size, className, candidates, onSwitchChain, onSuccess, onError, }: ChainSelectWidgetProps): react_jsx_runtime.JSX.Element;
|
|
52
72
|
|
|
53
73
|
type UseSelectChainOptions = {
|
|
54
74
|
onSwitchChain?: (chain: Chain) => Promise<void>;
|
|
75
|
+
/** Called when switching chain succeeds; caller can toast / analytics here */
|
|
76
|
+
onSuccess?: (chain: Chain) => void;
|
|
77
|
+
/** Called when switching chain fails; caller can toast / modal / report here */
|
|
78
|
+
onError?: (error: unknown) => void;
|
|
55
79
|
};
|
|
56
80
|
declare function useSelectChain(options?: UseSelectChainOptions): {
|
|
57
81
|
selectChain: (chain: Chain) => Promise<void>;
|
|
@@ -63,9 +87,4 @@ declare function useCurrentChain(): {
|
|
|
63
87
|
chainNamespace: _liberfi_io_types.ChainNamespace;
|
|
64
88
|
};
|
|
65
89
|
|
|
66
|
-
|
|
67
|
-
declare const chainAtom: jotai.WritableAtom<Chain, [Chain | typeof jotai_utils.RESET | ((prev: Chain) => Chain | typeof jotai_utils.RESET)], void>;
|
|
68
|
-
/** current chain namespace */
|
|
69
|
-
declare const chainNamespaceAtom: jotai.WritableAtom<ChainNamespace, [typeof jotai_utils.RESET | ChainNamespace | ((prev: ChainNamespace) => typeof jotai_utils.RESET | ChainNamespace)], void>;
|
|
70
|
-
|
|
71
|
-
export { ChainSelectDesktopUI, type ChainSelectDesktopUIProps, ChainSelectMobileUI, type ChainSelectMobileUIProps, ChainSelectUI, type ChainSelectUIProps, ChainSelectWidget, type ChainSelectWidgetProps, type UseSelectChainOptions, chainAtom, chainNamespaceAtom, useCurrentChain, useSelectChain, _default as version };
|
|
90
|
+
export { type ChainAtoms, ChainAvatar, type ChainAvatarProps, ChainSelectProvider, type ChainSelectProviderProps, ChainSelectStateContext, type ChainSelectStateContextValue, ChainSelectUI, type ChainSelectUIProps, ChainSelectWidget, type ChainSelectWidgetProps, type UseSelectChainOptions, chainAtom, chainNamespaceAtom, createChainAtoms, defaultChainAtoms, useCurrentChain, useSelectChain, _default as version };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import * as
|
|
3
|
-
import {
|
|
2
|
+
import * as react from 'react';
|
|
3
|
+
import { ReactNode } from 'react';
|
|
4
4
|
import * as jotai from 'jotai';
|
|
5
5
|
import * as jotai_utils from 'jotai/utils';
|
|
6
|
+
import { atomWithStorage } from 'jotai/utils';
|
|
7
|
+
import * as _liberfi_io_types from '@liberfi.io/types';
|
|
8
|
+
import { Chain, ChainNamespace } from '@liberfi.io/types';
|
|
6
9
|
|
|
7
10
|
declare global {
|
|
8
11
|
interface Window {
|
|
@@ -11,47 +14,68 @@ declare global {
|
|
|
11
14
|
};
|
|
12
15
|
}
|
|
13
16
|
}
|
|
14
|
-
declare const _default: "0.1.
|
|
17
|
+
declare const _default: "0.1.13";
|
|
15
18
|
|
|
16
|
-
type
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
candidates?: Chain[];
|
|
20
|
-
onSelectChain?: (chain: Chain) => void | Promise<void>;
|
|
21
|
-
isSwitching?: boolean;
|
|
22
|
-
className?: string;
|
|
19
|
+
type ChainAtoms = {
|
|
20
|
+
chainAtom: ReturnType<typeof atomWithStorage<Chain>>;
|
|
21
|
+
chainNamespaceAtom: ReturnType<typeof atomWithStorage<ChainNamespace>>;
|
|
23
22
|
};
|
|
24
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Creates chain state atoms with optional storage key prefix.
|
|
25
|
+
* Use a prefix when multiple independent chain selectors must coexist on the same origin.
|
|
26
|
+
*/
|
|
27
|
+
declare function createChainAtoms(storageKeyPrefix?: string): ChainAtoms;
|
|
28
|
+
/** Default atoms (used when not inside ChainSelectProvider) */
|
|
29
|
+
declare const defaultChainAtoms: ChainAtoms;
|
|
30
|
+
/** Current chain (default instance, key "chain") */
|
|
31
|
+
declare const chainAtom: jotai.WritableAtom<Chain, [Chain | typeof jotai_utils.RESET | ((prev: Chain) => Chain | typeof jotai_utils.RESET)], void>;
|
|
32
|
+
/** Current chain namespace (default instance, key "chainNamespace") */
|
|
33
|
+
declare const chainNamespaceAtom: jotai.WritableAtom<ChainNamespace, [typeof jotai_utils.RESET | ChainNamespace | ((prev: ChainNamespace) => typeof jotai_utils.RESET | ChainNamespace)], void>;
|
|
25
34
|
|
|
26
|
-
type
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
35
|
+
type ChainSelectStateContextValue = ReturnType<typeof createChainAtoms>;
|
|
36
|
+
declare const ChainSelectStateContext: react.Context<ChainAtoms>;
|
|
37
|
+
type ChainSelectProviderProps = {
|
|
38
|
+
/** Optional storage key prefix so multiple instances can coexist (e.g. "app1_") */
|
|
39
|
+
storageKeyPrefix?: string;
|
|
40
|
+
children: ReactNode;
|
|
41
|
+
};
|
|
42
|
+
declare function ChainSelectProvider({ storageKeyPrefix, children, }: ChainSelectProviderProps): react_jsx_runtime.JSX.Element;
|
|
43
|
+
|
|
44
|
+
type ChainAvatarProps = {
|
|
45
|
+
chain: Chain;
|
|
32
46
|
className?: string;
|
|
33
47
|
};
|
|
34
|
-
declare function
|
|
48
|
+
declare function ChainAvatar({ chain, className }: ChainAvatarProps): react_jsx_runtime.JSX.Element;
|
|
35
49
|
|
|
36
|
-
type
|
|
50
|
+
type ChainSelectUIProps = {
|
|
37
51
|
size?: "sm" | "md" | "lg";
|
|
38
|
-
candidates: Chain[];
|
|
39
52
|
chain?: Chain;
|
|
53
|
+
candidates?: Chain[];
|
|
40
54
|
onSelectChain?: (chain: Chain) => void | Promise<void>;
|
|
41
55
|
isSwitching?: boolean;
|
|
42
56
|
className?: string;
|
|
43
57
|
};
|
|
44
|
-
declare function
|
|
58
|
+
declare function ChainSelectUI({ size, chain, candidates, onSelectChain, isSwitching, className, }: ChainSelectUIProps): react_jsx_runtime.JSX.Element;
|
|
45
59
|
|
|
46
60
|
type ChainSelectWidgetProps = {
|
|
47
61
|
size?: "sm" | "md" | "lg";
|
|
48
62
|
className?: string;
|
|
63
|
+
/** Optional list of chains to show. Defaults to [SOLANA, ETHEREUM, BINANCE] when not provided. */
|
|
64
|
+
candidates?: Chain[];
|
|
49
65
|
onSwitchChain?: (chain: Chain) => Promise<void>;
|
|
66
|
+
/** Called when switching chain succeeds; caller can toast / analytics here */
|
|
67
|
+
onSuccess?: (chain: Chain) => void;
|
|
68
|
+
/** Called when switching chain fails; caller can toast / modal / report here */
|
|
69
|
+
onError?: (error: unknown) => void;
|
|
50
70
|
};
|
|
51
|
-
declare function ChainSelectWidget({ size, className, onSwitchChain, }: ChainSelectWidgetProps): react_jsx_runtime.JSX.Element;
|
|
71
|
+
declare function ChainSelectWidget({ size, className, candidates, onSwitchChain, onSuccess, onError, }: ChainSelectWidgetProps): react_jsx_runtime.JSX.Element;
|
|
52
72
|
|
|
53
73
|
type UseSelectChainOptions = {
|
|
54
74
|
onSwitchChain?: (chain: Chain) => Promise<void>;
|
|
75
|
+
/** Called when switching chain succeeds; caller can toast / analytics here */
|
|
76
|
+
onSuccess?: (chain: Chain) => void;
|
|
77
|
+
/** Called when switching chain fails; caller can toast / modal / report here */
|
|
78
|
+
onError?: (error: unknown) => void;
|
|
55
79
|
};
|
|
56
80
|
declare function useSelectChain(options?: UseSelectChainOptions): {
|
|
57
81
|
selectChain: (chain: Chain) => Promise<void>;
|
|
@@ -63,9 +87,4 @@ declare function useCurrentChain(): {
|
|
|
63
87
|
chainNamespace: _liberfi_io_types.ChainNamespace;
|
|
64
88
|
};
|
|
65
89
|
|
|
66
|
-
|
|
67
|
-
declare const chainAtom: jotai.WritableAtom<Chain, [Chain | typeof jotai_utils.RESET | ((prev: Chain) => Chain | typeof jotai_utils.RESET)], void>;
|
|
68
|
-
/** current chain namespace */
|
|
69
|
-
declare const chainNamespaceAtom: jotai.WritableAtom<ChainNamespace, [typeof jotai_utils.RESET | ChainNamespace | ((prev: ChainNamespace) => typeof jotai_utils.RESET | ChainNamespace)], void>;
|
|
70
|
-
|
|
71
|
-
export { ChainSelectDesktopUI, type ChainSelectDesktopUIProps, ChainSelectMobileUI, type ChainSelectMobileUIProps, ChainSelectUI, type ChainSelectUIProps, ChainSelectWidget, type ChainSelectWidgetProps, type UseSelectChainOptions, chainAtom, chainNamespaceAtom, useCurrentChain, useSelectChain, _default as version };
|
|
90
|
+
export { type ChainAtoms, ChainAvatar, type ChainAvatarProps, ChainSelectProvider, type ChainSelectProviderProps, ChainSelectStateContext, type ChainSelectStateContextValue, ChainSelectUI, type ChainSelectUIProps, ChainSelectWidget, type ChainSelectWidgetProps, type UseSelectChainOptions, chainAtom, chainNamespaceAtom, createChainAtoms, defaultChainAtoms, useCurrentChain, useSelectChain, _default as version };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var
|
|
1
|
+
'use strict';var react=require('react'),utils=require('jotai/utils'),types=require('@liberfi.io/types'),jsxRuntime=require('react/jsx-runtime'),ui=require('@liberfi.io/ui'),utils$1=require('@liberfi.io/utils'),jotai=require('jotai');typeof window<"u"&&(window.__LIBERFI_VERSION__=window.__LIBERFI_VERSION__||{},window.__LIBERFI_VERSION__["@liberfi.io/ui-chain-select"]="0.1.13");var M="0.1.13";var v={getOnInit:true};function f(e=""){let o=`${e}chain`,t=`${e}chainNamespace`;return {chainAtom:utils.atomWithStorage(o,types.Chain.SOLANA,void 0,v),chainNamespaceAtom:utils.atomWithStorage(t,types.ChainNamespace.SOLANA,void 0,v)}}var u=f(""),I=u,Se=u.chainAtom,ge=u.chainNamespaceAtom;var h=react.createContext(I);function we({storageKeyPrefix:e="",children:o}){let t=react.useMemo(()=>f(e),[e]);return jsxRuntime.jsx(h.Provider,{value:t,children:o})}function p({chain:e,className:o}){switch(e){case types.Chain.SOLANA:return jsxRuntime.jsx(ui.SolanaIcon,{className:o});case types.Chain.ETHEREUM:return jsxRuntime.jsx(ui.EthereumIcon,{className:o});case types.Chain.BINANCE:return jsxRuntime.jsx(ui.BinanceIcon,{className:o});default:return jsxRuntime.jsx(ui.Avatar,{className:o,src:utils$1.chainIcon(e),name:utils$1.capitalizeString(utils$1.chainSlug(e)??"")})}}var y=[types.Chain.SOLANA,types.Chain.ETHEREUM,types.Chain.BINANCE];function _({size:e,candidates:o,chain:t=o[0],onSelectChain:a,isSwitching:i,className:r}){let{isOpen:n,onClose:m,onOpenChange:c}=ui.useDisclosure(),d=react.useCallback(s=>{a?.(s),m();},[a,m]);return jsxRuntime.jsxs(ui.Popover,{isOpen:n,onOpenChange:c,placement:"bottom-end",className:r,classNames:{content:"w-38 bg-content1 border border-border"},children:[jsxRuntime.jsx(ui.PopoverTrigger,{children:jsxRuntime.jsx(ui.Button,{isLoading:i,size:e,variant:"bordered",radius:"full",style:{borderColor:utils$1.chainColor(t)?`${utils$1.chainColor(t)}60`:void 0},startContent:jsxRuntime.jsx(p,{chain:t,className:ui.clsx(e==="sm"?"w-4 h-4":e==="lg"?"w-6 h-6":"w-5 h-5")}),children:utils$1.chainDisplayName(t)})}),jsxRuntime.jsx(ui.PopoverContent,{className:"w-40 flex flex-col gap-1 p-1 rounded-md",children:o.map(s=>jsxRuntime.jsxs("div",{className:ui.clsx("w-full hover:bg-content2/80 cursor-pointer rounded-md px-3","flex gap-2 items-center",e==="sm"?"h-8":e==="lg"?"h-12":"h-10",s===t?"bg-content2 text-foreground":"text-neutral"),onClick:()=>d(s),children:[jsxRuntime.jsx(p,{chain:s,className:ui.clsx(e==="sm"?"w-4 h-4":e==="lg"?"w-6 h-6":"w-5 h-5")}),utils$1.chainDisplayName(s)]},s))})]})}function U({size:e,candidates:o,chain:t=types.Chain.SOLANA,onSelectChain:a,isSwitching:i,className:r}){return jsxRuntime.jsx("div",{className:ui.clsx("flex items-center gap-1",r),children:o.map(n=>jsxRuntime.jsx(ui.Button,{isIconOnly:true,isDisabled:i,radius:"full",className:ui.clsx("min-w-0 min-h-0 border",e==="sm"?"w-6 h-6":e==="md"||e===void 0?"w-7 h-7":"w-8 h-8",n===t?"bg-content1 scale-110 hover:opacity-100":"bg-transparent scale-90 opacity-50 hover:opacity-100 border-transparent"),style:n===t&&utils$1.chainColor(n)?{borderColor:`${utils$1.chainColor(n)}60`}:void 0,onPress:()=>a?.(n),children:jsxRuntime.jsx(p,{chain:n,className:ui.clsx(e==="sm"?"w-4 h-4":e==="md"||e===void 0?"w-5 h-5":"w-6 h-6")})},n))})}function D({size:e,chain:o=types.Chain.SOLANA,candidates:t=y,onSelectChain:a,isSwitching:i,className:r}){let{isMobile:n}=ui.useScreen();return n?jsxRuntime.jsx(U,{size:e,chain:o,onSelectChain:a,isSwitching:i,candidates:t,className:r}):jsxRuntime.jsx(_,{size:e,chain:o,onSelectChain:a,isSwitching:i,candidates:t,className:r})}function k(e){let{chainAtom:o,chainNamespaceAtom:t}=react.useContext(h),a=jotai.useSetAtom(o),i=jotai.useSetAtom(t),[r,n]=react.useState(false);return {selectChain:react.useCallback(async c=>{try{n(!0),await e?.onSwitchChain?.(c),i(utils$1.chainToNamespace(c)),a(c),e?.onSuccess?.(c);}catch(d){e?.onError?.(d);}finally{n(false);}},[a,i,e?.onSwitchChain,e?.onSuccess,e?.onError]),isSwitching:r}}function B(){let{chainAtom:e,chainNamespaceAtom:o}=react.useContext(h),t=jotai.useAtomValue(e),a=jotai.useAtomValue(o);return react.useMemo(()=>({chain:t,chainNamespace:a}),[t,a])}function po({size:e,className:o,candidates:t,onSwitchChain:a,onSuccess:i,onError:r}){let{chain:n}=B(),{selectChain:m,isSwitching:c}=k({onSwitchChain:a,onSuccess:i,onError:r});return jsxRuntime.jsx(D,{chain:n,candidates:t,onSelectChain:m,isSwitching:c,size:e,className:o})}exports.ChainAvatar=p;exports.ChainSelectProvider=we;exports.ChainSelectStateContext=h;exports.ChainSelectUI=D;exports.ChainSelectWidget=po;exports.chainAtom=Se;exports.chainNamespaceAtom=ge;exports.createChainAtoms=f;exports.defaultChainAtoms=I;exports.useCurrentChain=B;exports.useSelectChain=k;exports.version=M;//# sourceMappingURL=index.js.map
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/version.ts","../src/components/chain-avatar.tsx","../src/components/chain-select.desktop.ui.tsx","../src/components/chain-select.mobile.ui.tsx","../src/components/chain-select.ui.tsx","../src/states.ts","../src/hooks/useSelectChain.tsx","../src/hooks/useCurrentChain.tsx","../src/components/chain-select.widget.tsx"],"names":["version_default","ChainAvatar","chain","className","Chain","jsx","SolanaIcon","EthereumIcon","BinanceIcon","Avatar","capitalizeString","chainSlug","ChainSelectDesktopUI","size","candidates","onSelectChain","isSwitching","isOpen","onClose","onOpenChange","useDisclosure","handleSelect","useCallback","jsxs","Popover","PopoverTrigger","Button","chainColor","clsx","chainDisplayName","PopoverContent","it","ChainSelectMobileUI","DEFAULT_CANDIDATES","ChainSelectUI","isMobile","useScreen","chainAtom","atomWithStorage","chainNamespaceAtom","ChainNamespace","useSelectChain","options","setChain","useSetAtom","setChainNamespace","setIsSwitching","useState","useCurrentChain","useAtomValue","chainNamespace","useMemo","ChainSelectWidget","onSwitchChain","selectChain"],"mappings":"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","file":"index.js","sourcesContent":["declare global {\n interface Window {\n __LIBERFI_VERSION__?: {\n [key: string]: string;\n };\n }\n}\nif (typeof window !== \"undefined\") {\n window.__LIBERFI_VERSION__ = window.__LIBERFI_VERSION__ || {};\n window.__LIBERFI_VERSION__[\"@liberfi.io/ui-chain-select\"] = \"0.1.12\";\n}\n\nexport default \"0.1.12\";\n","import { Chain } from \"@liberfi.io/types\";\nimport { Avatar, BinanceIcon, EthereumIcon, SolanaIcon } from \"@liberfi.io/ui\";\nimport { capitalizeString, chainSlug } from \"@liberfi.io/utils\";\n\nexport type ChainAvatarProps = {\n chain: Chain;\n className?: string;\n};\n\nexport function ChainAvatar({ chain, className }: ChainAvatarProps) {\n switch (chain) {\n case Chain.SOLANA:\n return <SolanaIcon className={className} />;\n case Chain.ETHEREUM:\n return <EthereumIcon className={className} />;\n case Chain.BINANCE:\n return <BinanceIcon className={className} />;\n default:\n return (\n <Avatar\n className={className}\n name={capitalizeString(chainSlug(chain) ?? \"\")}\n />\n );\n }\n}\n","import { useCallback } from \"react\";\nimport { Chain } from \"@liberfi.io/types\";\nimport {\n Button,\n clsx,\n Popover,\n PopoverContent,\n PopoverTrigger,\n useDisclosure,\n} from \"@liberfi.io/ui\";\nimport { chainColor, chainDisplayName } from \"@liberfi.io/utils\";\nimport { ChainAvatar } from \"./chain-avatar\";\n\nexport type ChainSelectDesktopUIProps = {\n size?: \"sm\" | \"md\" | \"lg\";\n candidates: Chain[];\n chain?: Chain;\n onSelectChain?: (chain: Chain) => void | Promise<void>;\n isSwitching?: boolean;\n className?: string;\n};\n\nexport function ChainSelectDesktopUI({\n size,\n candidates,\n chain = candidates[0],\n onSelectChain,\n isSwitching,\n className,\n}: ChainSelectDesktopUIProps) {\n const { isOpen, onClose, onOpenChange } = useDisclosure();\n\n const handleSelect = useCallback(\n (chain: Chain) => {\n onSelectChain?.(chain);\n onClose();\n },\n [onSelectChain, onClose],\n );\n\n return (\n <Popover\n isOpen={isOpen}\n onOpenChange={onOpenChange}\n placement=\"bottom-end\"\n className={className}\n classNames={{ content: \"w-38 bg-content1 border border-border\" }}\n >\n <PopoverTrigger>\n <Button\n isLoading={isSwitching}\n size={size}\n variant=\"bordered\"\n radius=\"full\"\n style={{\n borderColor: chainColor(chain)\n ? `${chainColor(chain)}60`\n : undefined,\n }}\n startContent={\n <ChainAvatar\n chain={chain}\n className={clsx(\n size === \"sm\"\n ? \"w-4 h-4\"\n : size === \"lg\"\n ? \"w-6 h-6\"\n : \"w-5 h-5\",\n )}\n />\n }\n >\n {chainDisplayName(chain)}\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-40 flex flex-col gap-1 p-1 rounded-md\">\n {candidates.map((it) => (\n <div\n key={it}\n className={clsx(\n \"w-full hover:bg-content2/80 cursor-pointer rounded-md px-3\",\n \"flex gap-2 items-center\",\n size === \"sm\" ? \"h-8\" : size === \"lg\" ? \"h-12\" : \"h-10\",\n it === chain ? \"bg-content2 text-foreground\" : \"text-neutral\",\n )}\n onClick={() => handleSelect(it)}\n >\n <ChainAvatar\n chain={it}\n className={clsx(\n size === \"sm\"\n ? \"w-4 h-4\"\n : size === \"lg\"\n ? \"w-6 h-6\"\n : \"w-5 h-5\",\n )}\n />\n {chainDisplayName(it)}\n </div>\n ))}\n </PopoverContent>\n </Popover>\n );\n}\n","import { Chain } from \"@liberfi.io/types\";\nimport { Button, clsx } from \"@liberfi.io/ui\";\nimport { chainColor } from \"@liberfi.io/utils\";\nimport { ChainAvatar } from \"./chain-avatar\";\n\nexport type ChainSelectMobileUIProps = {\n size?: \"sm\" | \"md\" | \"lg\";\n candidates: Chain[];\n chain?: Chain;\n onSelectChain?: (chain: Chain) => void | Promise<void>;\n isSwitching?: boolean;\n className?: string;\n};\n\nexport function ChainSelectMobileUI({\n size,\n candidates,\n chain = Chain.SOLANA,\n onSelectChain,\n isSwitching,\n className,\n}: ChainSelectMobileUIProps) {\n return (\n <div className={clsx(\"flex items-center gap-1\", className)}>\n {candidates.map((it) => (\n <Button\n isIconOnly\n isDisabled={isSwitching}\n radius=\"full\"\n className={clsx(\n \"min-w-0 min-h-0 border\",\n size === \"sm\"\n ? \"w-6 h-6\"\n : size === \"md\" || size === undefined\n ? \"w-7 h-7\"\n : \"w-8 h-8\",\n it === chain\n ? \"bg-content1 scale-110 hover:opacity-100\"\n : \"bg-transparent scale-90 opacity-50 hover:opacity-100 border-transparent\",\n )}\n style={\n it === chain && chainColor(it)\n ? { borderColor: `${chainColor(it)}60` }\n : undefined\n }\n key={it}\n onPress={() => onSelectChain?.(it)}\n >\n <ChainAvatar\n chain={it}\n className={clsx(\n size === \"sm\"\n ? \"w-4 h-4\"\n : size === \"md\" || size === undefined\n ? \"w-5 h-5\"\n : \"w-6 h-6\",\n )}\n />\n </Button>\n ))}\n </div>\n );\n}\n","import { Chain } from \"@liberfi.io/types\";\nimport { useScreen } from \"@liberfi.io/ui\";\nimport { ChainSelectDesktopUI } from \"./chain-select.desktop.ui\";\nimport { ChainSelectMobileUI } from \"./chain-select.mobile.ui\";\n\nconst DEFAULT_CANDIDATES = [Chain.SOLANA, Chain.ETHEREUM, Chain.BINANCE];\n\nexport type ChainSelectUIProps = {\n size?: \"sm\" | \"md\" | \"lg\";\n chain?: Chain;\n candidates?: Chain[];\n onSelectChain?: (chain: Chain) => void | Promise<void>;\n isSwitching?: boolean;\n className?: string;\n};\n\nexport function ChainSelectUI({\n size,\n chain = Chain.SOLANA,\n candidates = DEFAULT_CANDIDATES,\n onSelectChain,\n isSwitching,\n className,\n}: ChainSelectUIProps) {\n const { isMobile } = useScreen();\n\n if (isMobile) {\n return (\n <ChainSelectMobileUI\n size={size}\n chain={chain}\n onSelectChain={onSelectChain}\n isSwitching={isSwitching}\n candidates={candidates}\n className={className}\n />\n );\n } else {\n return (\n <ChainSelectDesktopUI\n size={size}\n chain={chain}\n onSelectChain={onSelectChain}\n isSwitching={isSwitching}\n candidates={candidates}\n className={className}\n />\n );\n }\n}\n","import { atomWithStorage } from \"jotai/utils\";\nimport { Chain, ChainNamespace } from \"@liberfi.io/types\";\n\n/** current chain */\nexport const chainAtom = atomWithStorage<Chain>(\n \"chain\",\n Chain.SOLANA,\n undefined,\n {\n getOnInit: true,\n },\n);\n\n/** current chain namespace */\nexport const chainNamespaceAtom = atomWithStorage<ChainNamespace>(\n \"chainNamespace\",\n ChainNamespace.SOLANA,\n undefined,\n {\n getOnInit: true,\n },\n);\n","import { useCallback, useState } from \"react\";\nimport { useSetAtom } from \"jotai\";\nimport { Chain, ChainNamespace } from \"@liberfi.io/types\";\nimport { chainAtom, chainNamespaceAtom } from \"../states\";\n\nexport type UseSelectChainOptions = {\n onSwitchChain?: (chain: Chain) => Promise<void>;\n};\n\nexport function useSelectChain(options?: UseSelectChainOptions) {\n const setChain = useSetAtom(chainAtom);\n const setChainNamespace = useSetAtom(chainNamespaceAtom);\n const [isSwitching, setIsSwitching] = useState(false);\n\n const selectChain = useCallback(\n async (chain: Chain) => {\n try {\n setIsSwitching(true);\n await options?.onSwitchChain?.(chain);\n\n switch (chain) {\n case Chain.ETHEREUM:\n case Chain.BINANCE:\n setChainNamespace(ChainNamespace.EVM);\n break;\n case Chain.SOLANA:\n setChainNamespace(ChainNamespace.SOLANA);\n break;\n default:\n throw new Error(`Unsupported chain: ${chain}`);\n }\n setChain(chain);\n } finally {\n setIsSwitching(false);\n }\n },\n [setChain, setChainNamespace, options?.onSwitchChain],\n );\n\n return { selectChain, isSwitching };\n}\n","import { useMemo } from \"react\";\nimport { useAtomValue } from \"jotai\";\nimport { chainAtom, chainNamespaceAtom } from \"../states\";\n\nexport function useCurrentChain() {\n const chain = useAtomValue(chainAtom);\n const chainNamespace = useAtomValue(chainNamespaceAtom);\n return useMemo(() => ({ chain, chainNamespace }), [chain, chainNamespace]);\n}\n","import { Chain } from \"@liberfi.io/types\";\nimport { useSelectChain, useCurrentChain } from \"../hooks\";\nimport { ChainSelectUI } from \"./chain-select.ui\";\n\nexport type ChainSelectWidgetProps = {\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n onSwitchChain?: (chain: Chain) => Promise<void>;\n};\n\nexport function ChainSelectWidget({\n size,\n className,\n onSwitchChain,\n}: ChainSelectWidgetProps) {\n const { chain } = useCurrentChain();\n const { selectChain, isSwitching } = useSelectChain({ onSwitchChain });\n\n return (\n <ChainSelectUI\n chain={chain}\n onSelectChain={selectChain}\n isSwitching={isSwitching}\n size={size}\n className={className}\n />\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/version.ts","../src/states.ts","../src/chain-select.context.tsx","../src/components/chain-avatar.tsx","../src/constants.ts","../src/components/chain-select.desktop.ui.tsx","../src/components/chain-select.mobile.ui.tsx","../src/components/chain-select.ui.tsx","../src/hooks/useSelectChain.tsx","../src/hooks/useCurrentChain.tsx","../src/components/chain-select.widget.tsx"],"names":["version_default","storageOptions","createChainAtoms","storageKeyPrefix","chainKey","chainNamespaceKey","atomWithStorage","Chain","ChainNamespace","defaultAtoms","defaultChainAtoms","chainAtom","chainNamespaceAtom","ChainSelectStateContext","createContext","ChainSelectProvider","children","value","useMemo","jsx","ChainAvatar","chain","className","SolanaIcon","EthereumIcon","BinanceIcon","Avatar","chainIcon","capitalizeString","chainSlug","DEFAULT_CANDIDATES","ChainSelectDesktopUI","size","candidates","onSelectChain","isSwitching","isOpen","onClose","onOpenChange","useDisclosure","handleSelect","useCallback","jsxs","Popover","PopoverTrigger","Button","chainColor","clsx","chainDisplayName","PopoverContent","it","ChainSelectMobileUI","ChainSelectUI","isMobile","useScreen","useSelectChain","options","useContext","setChain","useSetAtom","setChainNamespace","setIsSwitching","useState","chainToNamespace","e","useCurrentChain","useAtomValue","chainNamespace","ChainSelectWidget","onSwitchChain","onSuccess","onError","selectChain"],"mappings":"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","file":"index.js","sourcesContent":["declare global {\n interface Window {\n __LIBERFI_VERSION__?: {\n [key: string]: string;\n };\n }\n}\nif (typeof window !== \"undefined\") {\n window.__LIBERFI_VERSION__ = window.__LIBERFI_VERSION__ || {};\n window.__LIBERFI_VERSION__[\"@liberfi.io/ui-chain-select\"] = \"0.1.13\";\n}\n\nexport default \"0.1.13\";\n","import { atomWithStorage } from \"jotai/utils\";\nimport { Chain, ChainNamespace } from \"@liberfi.io/types\";\n\nconst storageOptions = { getOnInit: true as const };\n\nexport type ChainAtoms = {\n chainAtom: ReturnType<typeof atomWithStorage<Chain>>;\n chainNamespaceAtom: ReturnType<typeof atomWithStorage<ChainNamespace>>;\n};\n\n/**\n * Creates chain state atoms with optional storage key prefix.\n * Use a prefix when multiple independent chain selectors must coexist on the same origin.\n */\nexport function createChainAtoms(storageKeyPrefix: string = \"\"): ChainAtoms {\n const chainKey = `${storageKeyPrefix}chain`;\n const chainNamespaceKey = `${storageKeyPrefix}chainNamespace`;\n return {\n chainAtom: atomWithStorage<Chain>(\n chainKey,\n Chain.SOLANA,\n undefined,\n storageOptions,\n ),\n chainNamespaceAtom: atomWithStorage<ChainNamespace>(\n chainNamespaceKey,\n ChainNamespace.SOLANA,\n undefined,\n storageOptions,\n ),\n };\n}\n\nconst defaultAtoms = createChainAtoms(\"\");\n\n/** Default atoms (used when not inside ChainSelectProvider) */\nexport const defaultChainAtoms = defaultAtoms;\n\n/** Current chain (default instance, key \"chain\") */\nexport const chainAtom = defaultAtoms.chainAtom;\n\n/** Current chain namespace (default instance, key \"chainNamespace\") */\nexport const chainNamespaceAtom = defaultAtoms.chainNamespaceAtom;\n","import { createContext, useMemo, type ReactNode } from \"react\";\nimport { createChainAtoms, defaultChainAtoms } from \"./states\";\n\nexport type ChainSelectStateContextValue = ReturnType<typeof createChainAtoms>;\n\nexport const ChainSelectStateContext =\n createContext<ChainSelectStateContextValue>(defaultChainAtoms);\n\nexport type ChainSelectProviderProps = {\n /** Optional storage key prefix so multiple instances can coexist (e.g. \"app1_\") */\n storageKeyPrefix?: string;\n children: ReactNode;\n};\n\nexport function ChainSelectProvider({\n storageKeyPrefix = \"\",\n children,\n}: ChainSelectProviderProps) {\n const value = useMemo(\n () => createChainAtoms(storageKeyPrefix),\n [storageKeyPrefix],\n );\n return (\n <ChainSelectStateContext.Provider value={value}>\n {children}\n </ChainSelectStateContext.Provider>\n );\n}\n","import { Chain } from \"@liberfi.io/types\";\nimport { Avatar, BinanceIcon, EthereumIcon, SolanaIcon } from \"@liberfi.io/ui\";\nimport { capitalizeString, chainIcon, chainSlug } from \"@liberfi.io/utils\";\n\nexport type ChainAvatarProps = {\n chain: Chain;\n className?: string;\n};\n\nexport function ChainAvatar({ chain, className }: ChainAvatarProps) {\n switch (chain) {\n case Chain.SOLANA:\n return <SolanaIcon className={className} />;\n case Chain.ETHEREUM:\n return <EthereumIcon className={className} />;\n case Chain.BINANCE:\n return <BinanceIcon className={className} />;\n default:\n return (\n <Avatar\n className={className}\n src={chainIcon(chain)}\n name={capitalizeString(chainSlug(chain) ?? \"\")}\n />\n );\n }\n}\n","import { Chain } from \"@liberfi.io/types\";\n\n/** Default chain list when candidates are not provided */\nexport const DEFAULT_CANDIDATES: Chain[] = [\n Chain.SOLANA,\n Chain.ETHEREUM,\n Chain.BINANCE,\n];\n","import { useCallback } from \"react\";\nimport { Chain } from \"@liberfi.io/types\";\nimport {\n Button,\n clsx,\n Popover,\n PopoverContent,\n PopoverTrigger,\n useDisclosure,\n} from \"@liberfi.io/ui\";\nimport { chainColor, chainDisplayName } from \"@liberfi.io/utils\";\nimport { ChainAvatar } from \"./chain-avatar\";\n\nexport type ChainSelectDesktopUIProps = {\n size?: \"sm\" | \"md\" | \"lg\";\n candidates: Chain[];\n chain?: Chain;\n onSelectChain?: (chain: Chain) => void | Promise<void>;\n isSwitching?: boolean;\n className?: string;\n};\n\nexport function ChainSelectDesktopUI({\n size,\n candidates,\n chain = candidates[0],\n onSelectChain,\n isSwitching,\n className,\n}: ChainSelectDesktopUIProps) {\n const { isOpen, onClose, onOpenChange } = useDisclosure();\n\n const handleSelect = useCallback(\n (chain: Chain) => {\n onSelectChain?.(chain);\n onClose();\n },\n [onSelectChain, onClose],\n );\n\n return (\n <Popover\n isOpen={isOpen}\n onOpenChange={onOpenChange}\n placement=\"bottom-end\"\n className={className}\n classNames={{ content: \"w-38 bg-content1 border border-border\" }}\n >\n <PopoverTrigger>\n <Button\n isLoading={isSwitching}\n size={size}\n variant=\"bordered\"\n radius=\"full\"\n style={{\n borderColor: chainColor(chain)\n ? `${chainColor(chain)}60`\n : undefined,\n }}\n startContent={\n <ChainAvatar\n chain={chain}\n className={clsx(\n size === \"sm\"\n ? \"w-4 h-4\"\n : size === \"lg\"\n ? \"w-6 h-6\"\n : \"w-5 h-5\",\n )}\n />\n }\n >\n {chainDisplayName(chain)}\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-40 flex flex-col gap-1 p-1 rounded-md\">\n {candidates.map((it) => (\n <div\n key={it}\n className={clsx(\n \"w-full hover:bg-content2/80 cursor-pointer rounded-md px-3\",\n \"flex gap-2 items-center\",\n size === \"sm\" ? \"h-8\" : size === \"lg\" ? \"h-12\" : \"h-10\",\n it === chain ? \"bg-content2 text-foreground\" : \"text-neutral\",\n )}\n onClick={() => handleSelect(it)}\n >\n <ChainAvatar\n chain={it}\n className={clsx(\n size === \"sm\"\n ? \"w-4 h-4\"\n : size === \"lg\"\n ? \"w-6 h-6\"\n : \"w-5 h-5\",\n )}\n />\n {chainDisplayName(it)}\n </div>\n ))}\n </PopoverContent>\n </Popover>\n );\n}\n","import { Chain } from \"@liberfi.io/types\";\nimport { Button, clsx } from \"@liberfi.io/ui\";\nimport { chainColor } from \"@liberfi.io/utils\";\nimport { ChainAvatar } from \"./chain-avatar\";\n\nexport type ChainSelectMobileUIProps = {\n size?: \"sm\" | \"md\" | \"lg\";\n candidates: Chain[];\n chain?: Chain;\n onSelectChain?: (chain: Chain) => void | Promise<void>;\n isSwitching?: boolean;\n className?: string;\n};\n\nexport function ChainSelectMobileUI({\n size,\n candidates,\n chain = Chain.SOLANA,\n onSelectChain,\n isSwitching,\n className,\n}: ChainSelectMobileUIProps) {\n return (\n <div className={clsx(\"flex items-center gap-1\", className)}>\n {candidates.map((it) => (\n <Button\n isIconOnly\n isDisabled={isSwitching}\n radius=\"full\"\n className={clsx(\n \"min-w-0 min-h-0 border\",\n size === \"sm\"\n ? \"w-6 h-6\"\n : size === \"md\" || size === undefined\n ? \"w-7 h-7\"\n : \"w-8 h-8\",\n it === chain\n ? \"bg-content1 scale-110 hover:opacity-100\"\n : \"bg-transparent scale-90 opacity-50 hover:opacity-100 border-transparent\",\n )}\n style={\n it === chain && chainColor(it)\n ? { borderColor: `${chainColor(it)}60` }\n : undefined\n }\n key={it}\n onPress={() => onSelectChain?.(it)}\n >\n <ChainAvatar\n chain={it}\n className={clsx(\n size === \"sm\"\n ? \"w-4 h-4\"\n : size === \"md\" || size === undefined\n ? \"w-5 h-5\"\n : \"w-6 h-6\",\n )}\n />\n </Button>\n ))}\n </div>\n );\n}\n","import { Chain } from \"@liberfi.io/types\";\nimport { useScreen } from \"@liberfi.io/ui\";\nimport { DEFAULT_CANDIDATES } from \"../constants\";\nimport { ChainSelectDesktopUI } from \"./chain-select.desktop.ui\";\nimport { ChainSelectMobileUI } from \"./chain-select.mobile.ui\";\n\nexport type ChainSelectUIProps = {\n size?: \"sm\" | \"md\" | \"lg\";\n chain?: Chain;\n candidates?: Chain[];\n onSelectChain?: (chain: Chain) => void | Promise<void>;\n isSwitching?: boolean;\n className?: string;\n};\n\nexport function ChainSelectUI({\n size,\n chain = Chain.SOLANA,\n candidates = DEFAULT_CANDIDATES,\n onSelectChain,\n isSwitching,\n className,\n}: ChainSelectUIProps) {\n const { isMobile } = useScreen();\n\n if (isMobile) {\n return (\n <ChainSelectMobileUI\n size={size}\n chain={chain}\n onSelectChain={onSelectChain}\n isSwitching={isSwitching}\n candidates={candidates}\n className={className}\n />\n );\n } else {\n return (\n <ChainSelectDesktopUI\n size={size}\n chain={chain}\n onSelectChain={onSelectChain}\n isSwitching={isSwitching}\n candidates={candidates}\n className={className}\n />\n );\n }\n}\n","import { useCallback, useContext, useState } from \"react\";\nimport { useSetAtom } from \"jotai\";\nimport { Chain } from \"@liberfi.io/types\";\nimport { chainToNamespace } from \"@liberfi.io/utils\";\nimport { ChainSelectStateContext } from \"../chain-select.context\";\n\nexport type UseSelectChainOptions = {\n onSwitchChain?: (chain: Chain) => Promise<void>;\n /** Called when switching chain succeeds; caller can toast / analytics here */\n onSuccess?: (chain: Chain) => void;\n /** Called when switching chain fails; caller can toast / modal / report here */\n onError?: (error: unknown) => void;\n};\n\nexport function useSelectChain(options?: UseSelectChainOptions) {\n const { chainAtom, chainNamespaceAtom } = useContext(ChainSelectStateContext);\n const setChain = useSetAtom(chainAtom);\n const setChainNamespace = useSetAtom(chainNamespaceAtom);\n const [isSwitching, setIsSwitching] = useState(false);\n\n const selectChain = useCallback(\n async (chain: Chain) => {\n try {\n setIsSwitching(true);\n await options?.onSwitchChain?.(chain);\n\n setChainNamespace(chainToNamespace(chain));\n setChain(chain);\n options?.onSuccess?.(chain);\n } catch (e) {\n options?.onError?.(e);\n } finally {\n setIsSwitching(false);\n }\n },\n [\n setChain,\n setChainNamespace,\n options?.onSwitchChain,\n options?.onSuccess,\n options?.onError,\n ],\n );\n\n return { selectChain, isSwitching };\n}\n","import { useMemo, useContext } from \"react\";\nimport { useAtomValue } from \"jotai\";\nimport { ChainSelectStateContext } from \"../chain-select.context\";\n\nexport function useCurrentChain() {\n const { chainAtom, chainNamespaceAtom } = useContext(ChainSelectStateContext);\n const chain = useAtomValue(chainAtom);\n const chainNamespace = useAtomValue(chainNamespaceAtom);\n return useMemo(() => ({ chain, chainNamespace }), [chain, chainNamespace]);\n}\n","import { Chain } from \"@liberfi.io/types\";\nimport { useSelectChain, useCurrentChain } from \"../hooks\";\nimport { ChainSelectUI } from \"./chain-select.ui\";\n\nexport type ChainSelectWidgetProps = {\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n /** Optional list of chains to show. Defaults to [SOLANA, ETHEREUM, BINANCE] when not provided. */\n candidates?: Chain[];\n onSwitchChain?: (chain: Chain) => Promise<void>;\n /** Called when switching chain succeeds; caller can toast / analytics here */\n onSuccess?: (chain: Chain) => void;\n /** Called when switching chain fails; caller can toast / modal / report here */\n onError?: (error: unknown) => void;\n};\n\nexport function ChainSelectWidget({\n size,\n className,\n candidates,\n onSwitchChain,\n onSuccess,\n onError,\n}: ChainSelectWidgetProps) {\n const { chain } = useCurrentChain();\n const { selectChain, isSwitching } = useSelectChain({\n onSwitchChain,\n onSuccess,\n onError,\n });\n\n return (\n <ChainSelectUI\n chain={chain}\n candidates={candidates}\n onSelectChain={selectChain}\n isSwitching={isSwitching}\n size={size}\n className={className}\n />\n );\n}\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {Chain,ChainNamespace}from'@liberfi.io/types';import {
|
|
1
|
+
import {createContext,useMemo,useContext,useState,useCallback}from'react';import {atomWithStorage}from'jotai/utils';import {Chain,ChainNamespace}from'@liberfi.io/types';import {jsx,jsxs}from'react/jsx-runtime';import {Avatar,BinanceIcon,EthereumIcon,SolanaIcon,useScreen,clsx,Button,useDisclosure,Popover,PopoverTrigger,PopoverContent}from'@liberfi.io/ui';import {capitalizeString,chainIcon,chainSlug,chainToNamespace,chainColor,chainDisplayName}from'@liberfi.io/utils';import {useSetAtom,useAtomValue}from'jotai';typeof window<"u"&&(window.__LIBERFI_VERSION__=window.__LIBERFI_VERSION__||{},window.__LIBERFI_VERSION__["@liberfi.io/ui-chain-select"]="0.1.13");var M="0.1.13";var v={getOnInit:true};function f(e=""){let o=`${e}chain`,t=`${e}chainNamespace`;return {chainAtom:atomWithStorage(o,Chain.SOLANA,void 0,v),chainNamespaceAtom:atomWithStorage(t,ChainNamespace.SOLANA,void 0,v)}}var u=f(""),I=u,Se=u.chainAtom,ge=u.chainNamespaceAtom;var h=createContext(I);function we({storageKeyPrefix:e="",children:o}){let t=useMemo(()=>f(e),[e]);return jsx(h.Provider,{value:t,children:o})}function p({chain:e,className:o}){switch(e){case Chain.SOLANA:return jsx(SolanaIcon,{className:o});case Chain.ETHEREUM:return jsx(EthereumIcon,{className:o});case Chain.BINANCE:return jsx(BinanceIcon,{className:o});default:return jsx(Avatar,{className:o,src:chainIcon(e),name:capitalizeString(chainSlug(e)??"")})}}var y=[Chain.SOLANA,Chain.ETHEREUM,Chain.BINANCE];function _({size:e,candidates:o,chain:t=o[0],onSelectChain:a,isSwitching:i,className:r}){let{isOpen:n,onClose:m,onOpenChange:c}=useDisclosure(),d=useCallback(s=>{a?.(s),m();},[a,m]);return jsxs(Popover,{isOpen:n,onOpenChange:c,placement:"bottom-end",className:r,classNames:{content:"w-38 bg-content1 border border-border"},children:[jsx(PopoverTrigger,{children:jsx(Button,{isLoading:i,size:e,variant:"bordered",radius:"full",style:{borderColor:chainColor(t)?`${chainColor(t)}60`:void 0},startContent:jsx(p,{chain:t,className:clsx(e==="sm"?"w-4 h-4":e==="lg"?"w-6 h-6":"w-5 h-5")}),children:chainDisplayName(t)})}),jsx(PopoverContent,{className:"w-40 flex flex-col gap-1 p-1 rounded-md",children:o.map(s=>jsxs("div",{className:clsx("w-full hover:bg-content2/80 cursor-pointer rounded-md px-3","flex gap-2 items-center",e==="sm"?"h-8":e==="lg"?"h-12":"h-10",s===t?"bg-content2 text-foreground":"text-neutral"),onClick:()=>d(s),children:[jsx(p,{chain:s,className:clsx(e==="sm"?"w-4 h-4":e==="lg"?"w-6 h-6":"w-5 h-5")}),chainDisplayName(s)]},s))})]})}function U({size:e,candidates:o,chain:t=Chain.SOLANA,onSelectChain:a,isSwitching:i,className:r}){return jsx("div",{className:clsx("flex items-center gap-1",r),children:o.map(n=>jsx(Button,{isIconOnly:true,isDisabled:i,radius:"full",className:clsx("min-w-0 min-h-0 border",e==="sm"?"w-6 h-6":e==="md"||e===void 0?"w-7 h-7":"w-8 h-8",n===t?"bg-content1 scale-110 hover:opacity-100":"bg-transparent scale-90 opacity-50 hover:opacity-100 border-transparent"),style:n===t&&chainColor(n)?{borderColor:`${chainColor(n)}60`}:void 0,onPress:()=>a?.(n),children:jsx(p,{chain:n,className:clsx(e==="sm"?"w-4 h-4":e==="md"||e===void 0?"w-5 h-5":"w-6 h-6")})},n))})}function D({size:e,chain:o=Chain.SOLANA,candidates:t=y,onSelectChain:a,isSwitching:i,className:r}){let{isMobile:n}=useScreen();return n?jsx(U,{size:e,chain:o,onSelectChain:a,isSwitching:i,candidates:t,className:r}):jsx(_,{size:e,chain:o,onSelectChain:a,isSwitching:i,candidates:t,className:r})}function k(e){let{chainAtom:o,chainNamespaceAtom:t}=useContext(h),a=useSetAtom(o),i=useSetAtom(t),[r,n]=useState(false);return {selectChain:useCallback(async c=>{try{n(!0),await e?.onSwitchChain?.(c),i(chainToNamespace(c)),a(c),e?.onSuccess?.(c);}catch(d){e?.onError?.(d);}finally{n(false);}},[a,i,e?.onSwitchChain,e?.onSuccess,e?.onError]),isSwitching:r}}function B(){let{chainAtom:e,chainNamespaceAtom:o}=useContext(h),t=useAtomValue(e),a=useAtomValue(o);return useMemo(()=>({chain:t,chainNamespace:a}),[t,a])}function po({size:e,className:o,candidates:t,onSwitchChain:a,onSuccess:i,onError:r}){let{chain:n}=B(),{selectChain:m,isSwitching:c}=k({onSwitchChain:a,onSuccess:i,onError:r});return jsx(D,{chain:n,candidates:t,onSelectChain:m,isSwitching:c,size:e,className:o})}export{p as ChainAvatar,we as ChainSelectProvider,h as ChainSelectStateContext,D as ChainSelectUI,po as ChainSelectWidget,Se as chainAtom,ge as chainNamespaceAtom,f as createChainAtoms,I as defaultChainAtoms,B as useCurrentChain,k as useSelectChain,M as version};//# sourceMappingURL=index.mjs.map
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/version.ts","../src/components/chain-avatar.tsx","../src/components/chain-select.desktop.ui.tsx","../src/components/chain-select.mobile.ui.tsx","../src/components/chain-select.ui.tsx","../src/states.ts","../src/hooks/useSelectChain.tsx","../src/hooks/useCurrentChain.tsx","../src/components/chain-select.widget.tsx"],"names":["version_default","ChainAvatar","chain","className","Chain","jsx","SolanaIcon","EthereumIcon","BinanceIcon","Avatar","capitalizeString","chainSlug","ChainSelectDesktopUI","size","candidates","onSelectChain","isSwitching","isOpen","onClose","onOpenChange","useDisclosure","handleSelect","useCallback","jsxs","Popover","PopoverTrigger","Button","chainColor","clsx","chainDisplayName","PopoverContent","it","ChainSelectMobileUI","DEFAULT_CANDIDATES","ChainSelectUI","isMobile","useScreen","chainAtom","atomWithStorage","chainNamespaceAtom","ChainNamespace","useSelectChain","options","setChain","useSetAtom","setChainNamespace","setIsSwitching","useState","useCurrentChain","useAtomValue","chainNamespace","useMemo","ChainSelectWidget","onSwitchChain","selectChain"],"mappings":"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","file":"index.mjs","sourcesContent":["declare global {\n interface Window {\n __LIBERFI_VERSION__?: {\n [key: string]: string;\n };\n }\n}\nif (typeof window !== \"undefined\") {\n window.__LIBERFI_VERSION__ = window.__LIBERFI_VERSION__ || {};\n window.__LIBERFI_VERSION__[\"@liberfi.io/ui-chain-select\"] = \"0.1.12\";\n}\n\nexport default \"0.1.12\";\n","import { Chain } from \"@liberfi.io/types\";\nimport { Avatar, BinanceIcon, EthereumIcon, SolanaIcon } from \"@liberfi.io/ui\";\nimport { capitalizeString, chainSlug } from \"@liberfi.io/utils\";\n\nexport type ChainAvatarProps = {\n chain: Chain;\n className?: string;\n};\n\nexport function ChainAvatar({ chain, className }: ChainAvatarProps) {\n switch (chain) {\n case Chain.SOLANA:\n return <SolanaIcon className={className} />;\n case Chain.ETHEREUM:\n return <EthereumIcon className={className} />;\n case Chain.BINANCE:\n return <BinanceIcon className={className} />;\n default:\n return (\n <Avatar\n className={className}\n name={capitalizeString(chainSlug(chain) ?? \"\")}\n />\n );\n }\n}\n","import { useCallback } from \"react\";\nimport { Chain } from \"@liberfi.io/types\";\nimport {\n Button,\n clsx,\n Popover,\n PopoverContent,\n PopoverTrigger,\n useDisclosure,\n} from \"@liberfi.io/ui\";\nimport { chainColor, chainDisplayName } from \"@liberfi.io/utils\";\nimport { ChainAvatar } from \"./chain-avatar\";\n\nexport type ChainSelectDesktopUIProps = {\n size?: \"sm\" | \"md\" | \"lg\";\n candidates: Chain[];\n chain?: Chain;\n onSelectChain?: (chain: Chain) => void | Promise<void>;\n isSwitching?: boolean;\n className?: string;\n};\n\nexport function ChainSelectDesktopUI({\n size,\n candidates,\n chain = candidates[0],\n onSelectChain,\n isSwitching,\n className,\n}: ChainSelectDesktopUIProps) {\n const { isOpen, onClose, onOpenChange } = useDisclosure();\n\n const handleSelect = useCallback(\n (chain: Chain) => {\n onSelectChain?.(chain);\n onClose();\n },\n [onSelectChain, onClose],\n );\n\n return (\n <Popover\n isOpen={isOpen}\n onOpenChange={onOpenChange}\n placement=\"bottom-end\"\n className={className}\n classNames={{ content: \"w-38 bg-content1 border border-border\" }}\n >\n <PopoverTrigger>\n <Button\n isLoading={isSwitching}\n size={size}\n variant=\"bordered\"\n radius=\"full\"\n style={{\n borderColor: chainColor(chain)\n ? `${chainColor(chain)}60`\n : undefined,\n }}\n startContent={\n <ChainAvatar\n chain={chain}\n className={clsx(\n size === \"sm\"\n ? \"w-4 h-4\"\n : size === \"lg\"\n ? \"w-6 h-6\"\n : \"w-5 h-5\",\n )}\n />\n }\n >\n {chainDisplayName(chain)}\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-40 flex flex-col gap-1 p-1 rounded-md\">\n {candidates.map((it) => (\n <div\n key={it}\n className={clsx(\n \"w-full hover:bg-content2/80 cursor-pointer rounded-md px-3\",\n \"flex gap-2 items-center\",\n size === \"sm\" ? \"h-8\" : size === \"lg\" ? \"h-12\" : \"h-10\",\n it === chain ? \"bg-content2 text-foreground\" : \"text-neutral\",\n )}\n onClick={() => handleSelect(it)}\n >\n <ChainAvatar\n chain={it}\n className={clsx(\n size === \"sm\"\n ? \"w-4 h-4\"\n : size === \"lg\"\n ? \"w-6 h-6\"\n : \"w-5 h-5\",\n )}\n />\n {chainDisplayName(it)}\n </div>\n ))}\n </PopoverContent>\n </Popover>\n );\n}\n","import { Chain } from \"@liberfi.io/types\";\nimport { Button, clsx } from \"@liberfi.io/ui\";\nimport { chainColor } from \"@liberfi.io/utils\";\nimport { ChainAvatar } from \"./chain-avatar\";\n\nexport type ChainSelectMobileUIProps = {\n size?: \"sm\" | \"md\" | \"lg\";\n candidates: Chain[];\n chain?: Chain;\n onSelectChain?: (chain: Chain) => void | Promise<void>;\n isSwitching?: boolean;\n className?: string;\n};\n\nexport function ChainSelectMobileUI({\n size,\n candidates,\n chain = Chain.SOLANA,\n onSelectChain,\n isSwitching,\n className,\n}: ChainSelectMobileUIProps) {\n return (\n <div className={clsx(\"flex items-center gap-1\", className)}>\n {candidates.map((it) => (\n <Button\n isIconOnly\n isDisabled={isSwitching}\n radius=\"full\"\n className={clsx(\n \"min-w-0 min-h-0 border\",\n size === \"sm\"\n ? \"w-6 h-6\"\n : size === \"md\" || size === undefined\n ? \"w-7 h-7\"\n : \"w-8 h-8\",\n it === chain\n ? \"bg-content1 scale-110 hover:opacity-100\"\n : \"bg-transparent scale-90 opacity-50 hover:opacity-100 border-transparent\",\n )}\n style={\n it === chain && chainColor(it)\n ? { borderColor: `${chainColor(it)}60` }\n : undefined\n }\n key={it}\n onPress={() => onSelectChain?.(it)}\n >\n <ChainAvatar\n chain={it}\n className={clsx(\n size === \"sm\"\n ? \"w-4 h-4\"\n : size === \"md\" || size === undefined\n ? \"w-5 h-5\"\n : \"w-6 h-6\",\n )}\n />\n </Button>\n ))}\n </div>\n );\n}\n","import { Chain } from \"@liberfi.io/types\";\nimport { useScreen } from \"@liberfi.io/ui\";\nimport { ChainSelectDesktopUI } from \"./chain-select.desktop.ui\";\nimport { ChainSelectMobileUI } from \"./chain-select.mobile.ui\";\n\nconst DEFAULT_CANDIDATES = [Chain.SOLANA, Chain.ETHEREUM, Chain.BINANCE];\n\nexport type ChainSelectUIProps = {\n size?: \"sm\" | \"md\" | \"lg\";\n chain?: Chain;\n candidates?: Chain[];\n onSelectChain?: (chain: Chain) => void | Promise<void>;\n isSwitching?: boolean;\n className?: string;\n};\n\nexport function ChainSelectUI({\n size,\n chain = Chain.SOLANA,\n candidates = DEFAULT_CANDIDATES,\n onSelectChain,\n isSwitching,\n className,\n}: ChainSelectUIProps) {\n const { isMobile } = useScreen();\n\n if (isMobile) {\n return (\n <ChainSelectMobileUI\n size={size}\n chain={chain}\n onSelectChain={onSelectChain}\n isSwitching={isSwitching}\n candidates={candidates}\n className={className}\n />\n );\n } else {\n return (\n <ChainSelectDesktopUI\n size={size}\n chain={chain}\n onSelectChain={onSelectChain}\n isSwitching={isSwitching}\n candidates={candidates}\n className={className}\n />\n );\n }\n}\n","import { atomWithStorage } from \"jotai/utils\";\nimport { Chain, ChainNamespace } from \"@liberfi.io/types\";\n\n/** current chain */\nexport const chainAtom = atomWithStorage<Chain>(\n \"chain\",\n Chain.SOLANA,\n undefined,\n {\n getOnInit: true,\n },\n);\n\n/** current chain namespace */\nexport const chainNamespaceAtom = atomWithStorage<ChainNamespace>(\n \"chainNamespace\",\n ChainNamespace.SOLANA,\n undefined,\n {\n getOnInit: true,\n },\n);\n","import { useCallback, useState } from \"react\";\nimport { useSetAtom } from \"jotai\";\nimport { Chain, ChainNamespace } from \"@liberfi.io/types\";\nimport { chainAtom, chainNamespaceAtom } from \"../states\";\n\nexport type UseSelectChainOptions = {\n onSwitchChain?: (chain: Chain) => Promise<void>;\n};\n\nexport function useSelectChain(options?: UseSelectChainOptions) {\n const setChain = useSetAtom(chainAtom);\n const setChainNamespace = useSetAtom(chainNamespaceAtom);\n const [isSwitching, setIsSwitching] = useState(false);\n\n const selectChain = useCallback(\n async (chain: Chain) => {\n try {\n setIsSwitching(true);\n await options?.onSwitchChain?.(chain);\n\n switch (chain) {\n case Chain.ETHEREUM:\n case Chain.BINANCE:\n setChainNamespace(ChainNamespace.EVM);\n break;\n case Chain.SOLANA:\n setChainNamespace(ChainNamespace.SOLANA);\n break;\n default:\n throw new Error(`Unsupported chain: ${chain}`);\n }\n setChain(chain);\n } finally {\n setIsSwitching(false);\n }\n },\n [setChain, setChainNamespace, options?.onSwitchChain],\n );\n\n return { selectChain, isSwitching };\n}\n","import { useMemo } from \"react\";\nimport { useAtomValue } from \"jotai\";\nimport { chainAtom, chainNamespaceAtom } from \"../states\";\n\nexport function useCurrentChain() {\n const chain = useAtomValue(chainAtom);\n const chainNamespace = useAtomValue(chainNamespaceAtom);\n return useMemo(() => ({ chain, chainNamespace }), [chain, chainNamespace]);\n}\n","import { Chain } from \"@liberfi.io/types\";\nimport { useSelectChain, useCurrentChain } from \"../hooks\";\nimport { ChainSelectUI } from \"./chain-select.ui\";\n\nexport type ChainSelectWidgetProps = {\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n onSwitchChain?: (chain: Chain) => Promise<void>;\n};\n\nexport function ChainSelectWidget({\n size,\n className,\n onSwitchChain,\n}: ChainSelectWidgetProps) {\n const { chain } = useCurrentChain();\n const { selectChain, isSwitching } = useSelectChain({ onSwitchChain });\n\n return (\n <ChainSelectUI\n chain={chain}\n onSelectChain={selectChain}\n isSwitching={isSwitching}\n size={size}\n className={className}\n />\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/version.ts","../src/states.ts","../src/chain-select.context.tsx","../src/components/chain-avatar.tsx","../src/constants.ts","../src/components/chain-select.desktop.ui.tsx","../src/components/chain-select.mobile.ui.tsx","../src/components/chain-select.ui.tsx","../src/hooks/useSelectChain.tsx","../src/hooks/useCurrentChain.tsx","../src/components/chain-select.widget.tsx"],"names":["version_default","storageOptions","createChainAtoms","storageKeyPrefix","chainKey","chainNamespaceKey","atomWithStorage","Chain","ChainNamespace","defaultAtoms","defaultChainAtoms","chainAtom","chainNamespaceAtom","ChainSelectStateContext","createContext","ChainSelectProvider","children","value","useMemo","jsx","ChainAvatar","chain","className","SolanaIcon","EthereumIcon","BinanceIcon","Avatar","chainIcon","capitalizeString","chainSlug","DEFAULT_CANDIDATES","ChainSelectDesktopUI","size","candidates","onSelectChain","isSwitching","isOpen","onClose","onOpenChange","useDisclosure","handleSelect","useCallback","jsxs","Popover","PopoverTrigger","Button","chainColor","clsx","chainDisplayName","PopoverContent","it","ChainSelectMobileUI","ChainSelectUI","isMobile","useScreen","useSelectChain","options","useContext","setChain","useSetAtom","setChainNamespace","setIsSwitching","useState","chainToNamespace","e","useCurrentChain","useAtomValue","chainNamespace","ChainSelectWidget","onSwitchChain","onSuccess","onError","selectChain"],"mappings":"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","file":"index.mjs","sourcesContent":["declare global {\n interface Window {\n __LIBERFI_VERSION__?: {\n [key: string]: string;\n };\n }\n}\nif (typeof window !== \"undefined\") {\n window.__LIBERFI_VERSION__ = window.__LIBERFI_VERSION__ || {};\n window.__LIBERFI_VERSION__[\"@liberfi.io/ui-chain-select\"] = \"0.1.13\";\n}\n\nexport default \"0.1.13\";\n","import { atomWithStorage } from \"jotai/utils\";\nimport { Chain, ChainNamespace } from \"@liberfi.io/types\";\n\nconst storageOptions = { getOnInit: true as const };\n\nexport type ChainAtoms = {\n chainAtom: ReturnType<typeof atomWithStorage<Chain>>;\n chainNamespaceAtom: ReturnType<typeof atomWithStorage<ChainNamespace>>;\n};\n\n/**\n * Creates chain state atoms with optional storage key prefix.\n * Use a prefix when multiple independent chain selectors must coexist on the same origin.\n */\nexport function createChainAtoms(storageKeyPrefix: string = \"\"): ChainAtoms {\n const chainKey = `${storageKeyPrefix}chain`;\n const chainNamespaceKey = `${storageKeyPrefix}chainNamespace`;\n return {\n chainAtom: atomWithStorage<Chain>(\n chainKey,\n Chain.SOLANA,\n undefined,\n storageOptions,\n ),\n chainNamespaceAtom: atomWithStorage<ChainNamespace>(\n chainNamespaceKey,\n ChainNamespace.SOLANA,\n undefined,\n storageOptions,\n ),\n };\n}\n\nconst defaultAtoms = createChainAtoms(\"\");\n\n/** Default atoms (used when not inside ChainSelectProvider) */\nexport const defaultChainAtoms = defaultAtoms;\n\n/** Current chain (default instance, key \"chain\") */\nexport const chainAtom = defaultAtoms.chainAtom;\n\n/** Current chain namespace (default instance, key \"chainNamespace\") */\nexport const chainNamespaceAtom = defaultAtoms.chainNamespaceAtom;\n","import { createContext, useMemo, type ReactNode } from \"react\";\nimport { createChainAtoms, defaultChainAtoms } from \"./states\";\n\nexport type ChainSelectStateContextValue = ReturnType<typeof createChainAtoms>;\n\nexport const ChainSelectStateContext =\n createContext<ChainSelectStateContextValue>(defaultChainAtoms);\n\nexport type ChainSelectProviderProps = {\n /** Optional storage key prefix so multiple instances can coexist (e.g. \"app1_\") */\n storageKeyPrefix?: string;\n children: ReactNode;\n};\n\nexport function ChainSelectProvider({\n storageKeyPrefix = \"\",\n children,\n}: ChainSelectProviderProps) {\n const value = useMemo(\n () => createChainAtoms(storageKeyPrefix),\n [storageKeyPrefix],\n );\n return (\n <ChainSelectStateContext.Provider value={value}>\n {children}\n </ChainSelectStateContext.Provider>\n );\n}\n","import { Chain } from \"@liberfi.io/types\";\nimport { Avatar, BinanceIcon, EthereumIcon, SolanaIcon } from \"@liberfi.io/ui\";\nimport { capitalizeString, chainIcon, chainSlug } from \"@liberfi.io/utils\";\n\nexport type ChainAvatarProps = {\n chain: Chain;\n className?: string;\n};\n\nexport function ChainAvatar({ chain, className }: ChainAvatarProps) {\n switch (chain) {\n case Chain.SOLANA:\n return <SolanaIcon className={className} />;\n case Chain.ETHEREUM:\n return <EthereumIcon className={className} />;\n case Chain.BINANCE:\n return <BinanceIcon className={className} />;\n default:\n return (\n <Avatar\n className={className}\n src={chainIcon(chain)}\n name={capitalizeString(chainSlug(chain) ?? \"\")}\n />\n );\n }\n}\n","import { Chain } from \"@liberfi.io/types\";\n\n/** Default chain list when candidates are not provided */\nexport const DEFAULT_CANDIDATES: Chain[] = [\n Chain.SOLANA,\n Chain.ETHEREUM,\n Chain.BINANCE,\n];\n","import { useCallback } from \"react\";\nimport { Chain } from \"@liberfi.io/types\";\nimport {\n Button,\n clsx,\n Popover,\n PopoverContent,\n PopoverTrigger,\n useDisclosure,\n} from \"@liberfi.io/ui\";\nimport { chainColor, chainDisplayName } from \"@liberfi.io/utils\";\nimport { ChainAvatar } from \"./chain-avatar\";\n\nexport type ChainSelectDesktopUIProps = {\n size?: \"sm\" | \"md\" | \"lg\";\n candidates: Chain[];\n chain?: Chain;\n onSelectChain?: (chain: Chain) => void | Promise<void>;\n isSwitching?: boolean;\n className?: string;\n};\n\nexport function ChainSelectDesktopUI({\n size,\n candidates,\n chain = candidates[0],\n onSelectChain,\n isSwitching,\n className,\n}: ChainSelectDesktopUIProps) {\n const { isOpen, onClose, onOpenChange } = useDisclosure();\n\n const handleSelect = useCallback(\n (chain: Chain) => {\n onSelectChain?.(chain);\n onClose();\n },\n [onSelectChain, onClose],\n );\n\n return (\n <Popover\n isOpen={isOpen}\n onOpenChange={onOpenChange}\n placement=\"bottom-end\"\n className={className}\n classNames={{ content: \"w-38 bg-content1 border border-border\" }}\n >\n <PopoverTrigger>\n <Button\n isLoading={isSwitching}\n size={size}\n variant=\"bordered\"\n radius=\"full\"\n style={{\n borderColor: chainColor(chain)\n ? `${chainColor(chain)}60`\n : undefined,\n }}\n startContent={\n <ChainAvatar\n chain={chain}\n className={clsx(\n size === \"sm\"\n ? \"w-4 h-4\"\n : size === \"lg\"\n ? \"w-6 h-6\"\n : \"w-5 h-5\",\n )}\n />\n }\n >\n {chainDisplayName(chain)}\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-40 flex flex-col gap-1 p-1 rounded-md\">\n {candidates.map((it) => (\n <div\n key={it}\n className={clsx(\n \"w-full hover:bg-content2/80 cursor-pointer rounded-md px-3\",\n \"flex gap-2 items-center\",\n size === \"sm\" ? \"h-8\" : size === \"lg\" ? \"h-12\" : \"h-10\",\n it === chain ? \"bg-content2 text-foreground\" : \"text-neutral\",\n )}\n onClick={() => handleSelect(it)}\n >\n <ChainAvatar\n chain={it}\n className={clsx(\n size === \"sm\"\n ? \"w-4 h-4\"\n : size === \"lg\"\n ? \"w-6 h-6\"\n : \"w-5 h-5\",\n )}\n />\n {chainDisplayName(it)}\n </div>\n ))}\n </PopoverContent>\n </Popover>\n );\n}\n","import { Chain } from \"@liberfi.io/types\";\nimport { Button, clsx } from \"@liberfi.io/ui\";\nimport { chainColor } from \"@liberfi.io/utils\";\nimport { ChainAvatar } from \"./chain-avatar\";\n\nexport type ChainSelectMobileUIProps = {\n size?: \"sm\" | \"md\" | \"lg\";\n candidates: Chain[];\n chain?: Chain;\n onSelectChain?: (chain: Chain) => void | Promise<void>;\n isSwitching?: boolean;\n className?: string;\n};\n\nexport function ChainSelectMobileUI({\n size,\n candidates,\n chain = Chain.SOLANA,\n onSelectChain,\n isSwitching,\n className,\n}: ChainSelectMobileUIProps) {\n return (\n <div className={clsx(\"flex items-center gap-1\", className)}>\n {candidates.map((it) => (\n <Button\n isIconOnly\n isDisabled={isSwitching}\n radius=\"full\"\n className={clsx(\n \"min-w-0 min-h-0 border\",\n size === \"sm\"\n ? \"w-6 h-6\"\n : size === \"md\" || size === undefined\n ? \"w-7 h-7\"\n : \"w-8 h-8\",\n it === chain\n ? \"bg-content1 scale-110 hover:opacity-100\"\n : \"bg-transparent scale-90 opacity-50 hover:opacity-100 border-transparent\",\n )}\n style={\n it === chain && chainColor(it)\n ? { borderColor: `${chainColor(it)}60` }\n : undefined\n }\n key={it}\n onPress={() => onSelectChain?.(it)}\n >\n <ChainAvatar\n chain={it}\n className={clsx(\n size === \"sm\"\n ? \"w-4 h-4\"\n : size === \"md\" || size === undefined\n ? \"w-5 h-5\"\n : \"w-6 h-6\",\n )}\n />\n </Button>\n ))}\n </div>\n );\n}\n","import { Chain } from \"@liberfi.io/types\";\nimport { useScreen } from \"@liberfi.io/ui\";\nimport { DEFAULT_CANDIDATES } from \"../constants\";\nimport { ChainSelectDesktopUI } from \"./chain-select.desktop.ui\";\nimport { ChainSelectMobileUI } from \"./chain-select.mobile.ui\";\n\nexport type ChainSelectUIProps = {\n size?: \"sm\" | \"md\" | \"lg\";\n chain?: Chain;\n candidates?: Chain[];\n onSelectChain?: (chain: Chain) => void | Promise<void>;\n isSwitching?: boolean;\n className?: string;\n};\n\nexport function ChainSelectUI({\n size,\n chain = Chain.SOLANA,\n candidates = DEFAULT_CANDIDATES,\n onSelectChain,\n isSwitching,\n className,\n}: ChainSelectUIProps) {\n const { isMobile } = useScreen();\n\n if (isMobile) {\n return (\n <ChainSelectMobileUI\n size={size}\n chain={chain}\n onSelectChain={onSelectChain}\n isSwitching={isSwitching}\n candidates={candidates}\n className={className}\n />\n );\n } else {\n return (\n <ChainSelectDesktopUI\n size={size}\n chain={chain}\n onSelectChain={onSelectChain}\n isSwitching={isSwitching}\n candidates={candidates}\n className={className}\n />\n );\n }\n}\n","import { useCallback, useContext, useState } from \"react\";\nimport { useSetAtom } from \"jotai\";\nimport { Chain } from \"@liberfi.io/types\";\nimport { chainToNamespace } from \"@liberfi.io/utils\";\nimport { ChainSelectStateContext } from \"../chain-select.context\";\n\nexport type UseSelectChainOptions = {\n onSwitchChain?: (chain: Chain) => Promise<void>;\n /** Called when switching chain succeeds; caller can toast / analytics here */\n onSuccess?: (chain: Chain) => void;\n /** Called when switching chain fails; caller can toast / modal / report here */\n onError?: (error: unknown) => void;\n};\n\nexport function useSelectChain(options?: UseSelectChainOptions) {\n const { chainAtom, chainNamespaceAtom } = useContext(ChainSelectStateContext);\n const setChain = useSetAtom(chainAtom);\n const setChainNamespace = useSetAtom(chainNamespaceAtom);\n const [isSwitching, setIsSwitching] = useState(false);\n\n const selectChain = useCallback(\n async (chain: Chain) => {\n try {\n setIsSwitching(true);\n await options?.onSwitchChain?.(chain);\n\n setChainNamespace(chainToNamespace(chain));\n setChain(chain);\n options?.onSuccess?.(chain);\n } catch (e) {\n options?.onError?.(e);\n } finally {\n setIsSwitching(false);\n }\n },\n [\n setChain,\n setChainNamespace,\n options?.onSwitchChain,\n options?.onSuccess,\n options?.onError,\n ],\n );\n\n return { selectChain, isSwitching };\n}\n","import { useMemo, useContext } from \"react\";\nimport { useAtomValue } from \"jotai\";\nimport { ChainSelectStateContext } from \"../chain-select.context\";\n\nexport function useCurrentChain() {\n const { chainAtom, chainNamespaceAtom } = useContext(ChainSelectStateContext);\n const chain = useAtomValue(chainAtom);\n const chainNamespace = useAtomValue(chainNamespaceAtom);\n return useMemo(() => ({ chain, chainNamespace }), [chain, chainNamespace]);\n}\n","import { Chain } from \"@liberfi.io/types\";\nimport { useSelectChain, useCurrentChain } from \"../hooks\";\nimport { ChainSelectUI } from \"./chain-select.ui\";\n\nexport type ChainSelectWidgetProps = {\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n /** Optional list of chains to show. Defaults to [SOLANA, ETHEREUM, BINANCE] when not provided. */\n candidates?: Chain[];\n onSwitchChain?: (chain: Chain) => Promise<void>;\n /** Called when switching chain succeeds; caller can toast / analytics here */\n onSuccess?: (chain: Chain) => void;\n /** Called when switching chain fails; caller can toast / modal / report here */\n onError?: (error: unknown) => void;\n};\n\nexport function ChainSelectWidget({\n size,\n className,\n candidates,\n onSwitchChain,\n onSuccess,\n onError,\n}: ChainSelectWidgetProps) {\n const { chain } = useCurrentChain();\n const { selectChain, isSwitching } = useSelectChain({\n onSwitchChain,\n onSuccess,\n onError,\n });\n\n return (\n <ChainSelectUI\n chain={chain}\n candidates={candidates}\n onSelectChain={selectChain}\n isSwitching={isSwitching}\n size={size}\n className={className}\n />\n );\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liberfi.io/ui-chain-select",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
4
4
|
"description": "Chain Management for Liberfi React SDK",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -14,36 +14,28 @@
|
|
|
14
14
|
"access": "public"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@
|
|
18
|
-
"
|
|
19
|
-
"@liberfi.io/
|
|
20
|
-
"@liberfi.io/ui": "0.1.21",
|
|
21
|
-
"@liberfi.io/utils": "0.1.18"
|
|
17
|
+
"@liberfi.io/types": "0.1.22",
|
|
18
|
+
"@liberfi.io/ui": "0.1.22",
|
|
19
|
+
"@liberfi.io/utils": "0.1.19"
|
|
22
20
|
},
|
|
23
21
|
"devDependencies": {
|
|
24
|
-
"@tailwindcss/cli": "^4.1.13",
|
|
25
|
-
"@tailwindcss/postcss": "^4.1.13",
|
|
26
22
|
"@types/node": "^24.5.0",
|
|
27
23
|
"@types/react": "^19.1.13",
|
|
28
24
|
"@types/react-dom": "^19.1.9",
|
|
29
|
-
"autoprefixer": "^10.4.21",
|
|
30
25
|
"jotai": "^2.15.1",
|
|
31
|
-
"postcss": "^8.5.6",
|
|
32
26
|
"react": "^19.1.1",
|
|
33
27
|
"react-dom": "^19.1.1",
|
|
34
|
-
"tailwindcss": "^4.1.13",
|
|
35
28
|
"tsup": "^8.5.0",
|
|
36
29
|
"typescript": "^5.9.2",
|
|
37
|
-
"tsconfig": "0.1.
|
|
30
|
+
"tsconfig": "0.1.10"
|
|
38
31
|
},
|
|
39
32
|
"peerDependencies": {
|
|
33
|
+
"jotai": ">=2.15.1",
|
|
40
34
|
"react": ">=18",
|
|
41
|
-
"react-dom": ">=18"
|
|
42
|
-
"jotai": ">=2.15.1"
|
|
35
|
+
"react-dom": ">=18"
|
|
43
36
|
},
|
|
44
37
|
"scripts": {
|
|
45
38
|
"build": "tsup",
|
|
46
|
-
"build:css": "pnpm dlx @tailwindcss/cli -i ./src/tailwind/tailwind.css -o ./dist/styles.css",
|
|
47
39
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
48
40
|
}
|
|
49
41
|
}
|