@0xsquid/ui 0.16.2 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/index.js CHANGED
@@ -2918,9 +2918,19 @@ function SearchIcon() {
2918
2918
  }
2919
2919
 
2920
2920
  function Input(_a) {
2921
- var { placeholder = 'Search', showIcon = true, className, icon, isError = false, containerClassName, actionButtonProps } = _a, props = __rest(_a, ["placeholder", "showIcon", "className", "icon", "isError", "containerClassName", "actionButtonProps"]);
2921
+ var { placeholder = 'Search', showIcon = true, className, icon, isError = false, containerClassName, actionButtonProps, autoFocusTimeout } = _a, props = __rest(_a, ["placeholder", "showIcon", "className", "icon", "isError", "containerClassName", "actionButtonProps", "autoFocusTimeout"]);
2922
2922
  const showActionButton = !!actionButtonProps;
2923
- return (jsxRuntime.jsxs("div", { className: cn('tw-relative tw-w-full tw-text-grey-600', containerClassName), children: [jsxRuntime.jsx("input", Object.assign({}, props, { "aria-invalid": isError, className: cn('tw-relative tw-h-10 tw-w-full tw-rounded-full tw-border tw-border-material-light-thin tw-bg-grey-900 tw-text-body-small tw-font-typography-regular tw-text-grey-300 placeholder:tw-text-grey-600 invalid:tw-outline-status-negative', showIcon ? 'tw-pl-[40px]' : 'tw-px-2.5', showActionButton ? 'tw-pr-[70px]' : 'tw-pr-2.5', isError && '!tw-outline-status-negative', className), placeholder: placeholder })), showIcon ? (jsxRuntime.jsx("div", { className: "tw-absolute tw-inset-y-0 tw-left-0 tw-flex tw-h-full tw-w-[44px] tw-items-center tw-justify-center tw-px-squid-xs", children: icon || jsxRuntime.jsx(SearchIcon, {}) })) : null, showActionButton ? (jsxRuntime.jsx("div", { className: "tw-absolute tw-inset-y-0 tw-right-1.5 tw-flex tw-items-center tw-justify-center", children: jsxRuntime.jsx(InputActionButton, Object.assign({}, actionButtonProps)) })) : null] }));
2923
+ const inputRef = React.useRef(null);
2924
+ React.useEffect(() => {
2925
+ if (!autoFocusTimeout)
2926
+ return;
2927
+ const timeoutId = setTimeout(() => {
2928
+ var _a;
2929
+ (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
2930
+ }, autoFocusTimeout);
2931
+ return () => clearTimeout(timeoutId);
2932
+ }, [autoFocusTimeout]);
2933
+ return (jsxRuntime.jsxs("div", { className: cn('tw-relative tw-w-full tw-text-grey-600', containerClassName), children: [jsxRuntime.jsx("input", Object.assign({}, props, { ref: inputRef, "aria-invalid": isError, className: cn('tw-relative tw-h-10 tw-w-full tw-rounded-full tw-border tw-border-material-light-thin tw-bg-grey-900 tw-text-body-small tw-font-typography-regular tw-text-grey-300 placeholder:tw-text-grey-600 invalid:tw-outline-status-negative', showIcon ? 'tw-pl-[40px]' : 'tw-px-2.5', showActionButton ? 'tw-pr-[70px]' : 'tw-pr-2.5', isError && '!tw-outline-status-negative', className), placeholder: placeholder })), showIcon ? (jsxRuntime.jsx("div", { className: "tw-absolute tw-inset-y-0 tw-left-0 tw-flex tw-h-full tw-w-[44px] tw-items-center tw-justify-center tw-px-squid-xs", children: icon || jsxRuntime.jsx(SearchIcon, {}) })) : null, showActionButton ? (jsxRuntime.jsx("div", { className: "tw-absolute tw-inset-y-0 tw-right-1.5 tw-flex tw-items-center tw-justify-center", children: jsxRuntime.jsx(InputActionButton, Object.assign({}, actionButtonProps)) })) : null] }));
2924
2934
  }
2925
2935
  const InputActionButton = ({ onClick, variant = 'tertiary', label = 'Paste', }) => {
2926
2936
  return (jsxRuntime.jsx(Button, { size: "md", variant: variant, onClick: onClick, className: "!tw-h-[30px] !tw-w-fit !tw-min-w-0", children: jsxRuntime.jsx(CaptionText, { children: label }) }));
@@ -6506,7 +6516,7 @@ const detailStateClassMap = {
6506
6516
  error: 'tw-opacity-33 tw-pointer-events-none',
6507
6517
  full: '',
6508
6518
  };
6509
- function DetailsToolbar({ errorMessage, boostMode = 'normal', onToggleBoostMode, onInvertSwapButtonClick, onFeeButtonClick, feeInUsd, estimatedTime, canToggleBoostMode, boostDisabledMessage, helpButton, isLoading, isEmpty, boostTooltipDisplayDelayMs = 0, isFlipButtonDisabled, flipButtonDisabledMessage, }) {
6519
+ function DetailsToolbar({ errorMessage, boostMode = 'normal', onToggleBoostMode, onInvertSwapButtonClick, onFeeButtonClick, feeInUsd, estimatedTime, canToggleBoostMode, boostDisabledMessage, helpButton, isLoading, isEmpty, boostTooltipDisplayDelayMs = 0, flipButton, }) {
6510
6520
  const state = React.useMemo(() => {
6511
6521
  if (errorMessage)
6512
6522
  return 'error';
@@ -6517,7 +6527,9 @@ function DetailsToolbar({ errorMessage, boostMode = 'normal', onToggleBoostMode,
6517
6527
  return 'full';
6518
6528
  }, [errorMessage, isLoading, isEmpty]);
6519
6529
  const detailClassName = cn('tw-w-[190px]', detailStateClassMap[state]);
6520
- return (jsxRuntime.jsx("aside", { className: cn('tw-flex tw-h-[50px] tw-w-card tw-items-center tw-justify-around tw-border-t tw-border-t-material-light-thin tw-bg-grey-900 tw-py-squid-xxs tw-text-grey-500', state === 'error' ? 'tw-px-squid-l' : 'tw-px-squid-m'), children: state === 'error' && errorMessage ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ErrorMessage, { message: errorMessage }), helpButton ? (jsxRuntime.jsx(Button, { onClick: helpButton.onClick, size: "md", variant: "tertiary", label: helpButton.label })) : null] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: detailClassName, children: jsxRuntime.jsx(FeeButton, { feeInUsd: feeInUsd, onClick: onFeeButtonClick }) }), jsxRuntime.jsx("div", { className: "tw-flex tw-h-squid-xl tw-w-squid-xxl tw-items-center tw-justify-center", children: state === 'loading' ? (jsxRuntime.jsx(Loader, { size: "32" })) : (jsxRuntime.jsx(Tooltip, { tooltipContent: isFlipButtonDisabled ? flipButtonDisabledMessage : undefined, tooltipWidth: "max", children: jsxRuntime.jsx("button", { disabled: isFlipButtonDisabled, onClick: onInvertSwapButtonClick, className: "tw-group/flip-button tw-flex tw-h-squid-xl tw-min-w-[60px] tw-items-center tw-justify-center tw-rounded-squid-m tw-bg-transparent tw-px-squid-xs tw-py-squid-xxs tw-text-grey-300 hover:tw-bg-material-light-thin disabled:tw-cursor-not-allowed", children: jsxRuntime.jsx(ChevronLargeDownIcon, { className: cn('tw-transition-transform tw-duration-150', !isFlipButtonDisabled &&
6530
+ return (jsxRuntime.jsx("aside", { className: cn('tw-flex tw-h-[50px] tw-w-card tw-items-center tw-justify-around tw-border-t tw-border-t-material-light-thin tw-bg-grey-900 tw-py-squid-xxs tw-text-grey-500', state === 'error' ? 'tw-px-squid-l' : 'tw-px-squid-m'), children: state === 'error' && errorMessage ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ErrorMessage, { message: errorMessage }), helpButton ? (jsxRuntime.jsx(Button, { onClick: helpButton.onClick, size: "md", variant: "tertiary", label: helpButton.label })) : null] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: detailClassName, children: jsxRuntime.jsx(FeeButton, { feeInUsd: feeInUsd, onClick: onFeeButtonClick }) }), jsxRuntime.jsx("div", { className: "tw-flex tw-h-squid-xl tw-w-squid-xxl tw-items-center tw-justify-center", children: state === 'loading' ? (jsxRuntime.jsx(Loader, { size: "32" })) : (jsxRuntime.jsx(Tooltip, { tooltipContent: (flipButton === null || flipButton === void 0 ? void 0 : flipButton.isDisabled)
6531
+ ? flipButton.disabledMessage
6532
+ : undefined, tooltipWidth: "max", displayDelayMs: flipButton === null || flipButton === void 0 ? void 0 : flipButton.tooltipDisplayDelayMs, children: jsxRuntime.jsx("button", { disabled: flipButton === null || flipButton === void 0 ? void 0 : flipButton.isDisabled, onClick: onInvertSwapButtonClick, className: "tw-group/flip-button tw-flex tw-h-squid-xl tw-min-w-[60px] tw-items-center tw-justify-center tw-rounded-squid-m tw-bg-transparent tw-px-squid-xs tw-py-squid-xxs tw-text-grey-300 hover:tw-bg-material-light-thin disabled:tw-cursor-not-allowed", children: jsxRuntime.jsx(ChevronLargeDownIcon, { className: cn('tw-transition-transform tw-duration-150', !(flipButton === null || flipButton === void 0 ? void 0 : flipButton.isDisabled) &&
6521
6533
  'group-hover/flip-button:tw-rotate-180') }) }) })) }), jsxRuntime.jsx("div", { className: detailClassName, children: jsxRuntime.jsx(Boost, { estimatedTime: estimatedTime !== null && estimatedTime !== void 0 ? estimatedTime : '0s', boostMode: boostMode, onToggleBoostMode: onToggleBoostMode, canToggleBoostMode: state === 'loading' ? false : canToggleBoostMode, boostDisabledMessage: boostDisabledMessage, boostTooltipDisplayDelayMs: boostTooltipDisplayDelayMs }) })] })) }));
6522
6534
  }
6523
6535
 
@@ -6908,9 +6920,9 @@ function LogoContainer({ children }) {
6908
6920
  return (jsxRuntime.jsx("div", { className: "tw-flex tw-h-[60px] tw-w-[60px] tw-items-center tw-justify-center", children: children }));
6909
6921
  }
6910
6922
 
6911
- function SwapConfiguration({ amount, tokenPrice = 0, isFetching = false, chain, token, direction, onAmountChange, onWalletButtonClick, onAssetsButtonClick, address, emptyAddressLabel = 'Connect wallet', balance, criticalPriceImpactPercentage, error, priceImpactPercentage, amountUsd, }) {
6923
+ function SwapConfiguration({ amount, tokenPrice = 0, isFetching = false, chain, token, direction, onAmountChange, onWalletButtonClick, onAssetsButtonClick, address, emptyAddressLabel = 'Connect wallet', balance, criticalPriceImpactPercentage, error, priceImpactPercentage, amountUsd, assetsButtonVariant, }) {
6912
6924
  var _a, _b;
6913
- return (jsxRuntime.jsxs("section", { className: "tw-relative tw-h-[205px] tw-max-h-[205px] tw-w-card tw-overflow-hidden tw-border-t tw-border-t-material-light-thin tw-bg-grey-900 tw-pb-squid-m", children: [jsxRuntime.jsx("header", { className: "tw-flex tw-items-center tw-gap-1 tw-px-squid-l tw-py-squid-xs tw-leading-5 tw-text-grey-300", children: jsxRuntime.jsxs("button", { onClick: onWalletButtonClick, className: "-tw-ml-squid-xs tw-flex tw-h-squid-l tw-items-center tw-gap-squid-xxs tw-rounded-squid-s tw-px-squid-xs tw-text-grey-600 hover:tw-bg-material-light-thin", children: [jsxRuntime.jsx(BodyText, { className: "tw-text-grey-500", size: "small", children: direction === 'from' ? 'Pay' : 'Receive' }), jsxRuntime.jsx(BodyText, { size: "small", children: ":" }), jsxRuntime.jsxs("div", { className: "tw-flex tw-items-center tw-gap-1", children: [jsxRuntime.jsx(BodyText, { size: "small", className: address ? 'tw-text-grey-300' : 'tw-text-royal-400', children: address ? address : emptyAddressLabel }), jsxRuntime.jsx(ChevronArrowIcon, { className: address ? 'tw-text-grey-600' : 'tw-text-royal-400' })] })] }) }), jsxRuntime.jsx("div", { className: "tw-px-squid-l", children: jsxRuntime.jsx(AssetsButton, { onClick: onAssetsButtonClick, chainImageUrl: chain === null || chain === void 0 ? void 0 : chain.iconUrl, tokenImageUrl: token === null || token === void 0 ? void 0 : token.iconUrl, tokenSymbol: token === null || token === void 0 ? void 0 : token.symbol, chainBgColor: chain === null || chain === void 0 ? void 0 : chain.bgColor, tokenBgColor: token === null || token === void 0 ? void 0 : token.bgColor, tokenTextColor: token === null || token === void 0 ? void 0 : token.textColor }) }), isFetching && (jsxRuntime.jsx("div", { className: "tw-absolute tw-bottom-4 tw-left-squid-l tw-z-10 tw-overflow-hidden", children: jsxRuntime.jsx("div", { className: "tw-h-[94px] tw-w-[1260px] tw-animate-move-loading-cover-to-right tw-bg-dark-cover" }) })), jsxRuntime.jsx(NumericInput, { token: {
6925
+ return (jsxRuntime.jsxs("section", { className: "tw-relative tw-h-[205px] tw-max-h-[205px] tw-w-card tw-overflow-hidden tw-border-t tw-border-t-material-light-thin tw-bg-grey-900 tw-pb-squid-m", children: [jsxRuntime.jsx("header", { className: "tw-flex tw-items-center tw-gap-1 tw-px-squid-l tw-py-squid-xs tw-leading-5 tw-text-grey-300", children: jsxRuntime.jsxs("button", { onClick: onWalletButtonClick, className: "-tw-ml-squid-xs tw-flex tw-h-squid-l tw-items-center tw-gap-squid-xxs tw-rounded-squid-s tw-px-squid-xs tw-text-grey-600 hover:tw-bg-material-light-thin", children: [jsxRuntime.jsx(BodyText, { className: "tw-text-grey-500", size: "small", children: direction === 'from' ? 'Pay' : 'Receive' }), jsxRuntime.jsx(BodyText, { size: "small", children: ":" }), jsxRuntime.jsxs("div", { className: "tw-flex tw-items-center tw-gap-1", children: [jsxRuntime.jsx(BodyText, { size: "small", className: address ? 'tw-text-grey-300' : 'tw-text-royal-400', children: address ? address : emptyAddressLabel }), jsxRuntime.jsx(ChevronArrowIcon, { className: address ? 'tw-text-grey-600' : 'tw-text-royal-400' })] })] }) }), jsxRuntime.jsx("div", { className: "tw-px-squid-l", children: jsxRuntime.jsx(AssetsButton, { onClick: onAssetsButtonClick, chainImageUrl: chain === null || chain === void 0 ? void 0 : chain.iconUrl, tokenImageUrl: token === null || token === void 0 ? void 0 : token.iconUrl, tokenSymbol: token === null || token === void 0 ? void 0 : token.symbol, chainBgColor: chain === null || chain === void 0 ? void 0 : chain.bgColor, tokenBgColor: token === null || token === void 0 ? void 0 : token.bgColor, tokenTextColor: token === null || token === void 0 ? void 0 : token.textColor, variant: assetsButtonVariant }) }), isFetching && (jsxRuntime.jsx("div", { className: "tw-absolute tw-bottom-4 tw-left-squid-l tw-z-10 tw-overflow-hidden", children: jsxRuntime.jsx("div", { className: "tw-h-[94px] tw-w-[1260px] tw-animate-move-loading-cover-to-right tw-bg-dark-cover" }) })), jsxRuntime.jsx(NumericInput, { token: {
6914
6926
  decimals: (_a = token === null || token === void 0 ? void 0 : token.decimals) !== null && _a !== void 0 ? _a : 18,
6915
6927
  symbol: (_b = token === null || token === void 0 ? void 0 : token.symbol) !== null && _b !== void 0 ? _b : '',
6916
6928
  price: tokenPrice,
@@ -1,4 +1,4 @@
1
- type AssetsButtonVariant = 'primary' | 'accent';
1
+ import { AssetsButtonVariant } from '../../types/components';
2
2
  interface AssetsButtonProps {
3
3
  tokenImageUrl?: string;
4
4
  chainImageUrl?: string;
@@ -7,8 +7,9 @@ interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
7
7
  isError?: boolean;
8
8
  containerClassName?: string;
9
9
  actionButtonProps?: InputActionButtonProps;
10
+ autoFocusTimeout?: number;
10
11
  }
11
- export declare function Input({ placeholder, showIcon, className, icon, isError, containerClassName, actionButtonProps, ...props }: InputProps): import("react/jsx-runtime").JSX.Element;
12
+ export declare function Input({ placeholder, showIcon, className, icon, isError, containerClassName, actionButtonProps, autoFocusTimeout, ...props }: InputProps): import("react/jsx-runtime").JSX.Element;
12
13
  type InputActionButtonProps = {
13
14
  onClick?: () => void;
14
15
  variant?: ButtonVariant;
@@ -7,8 +7,11 @@ interface DetailsToolbarProps {
7
7
  }) => void;
8
8
  onInvertSwapButtonClick?: () => void;
9
9
  onFeeButtonClick?: () => void;
10
- isFlipButtonDisabled?: boolean;
11
- flipButtonDisabledMessage?: string;
10
+ flipButton?: {
11
+ disabledMessage: string;
12
+ isDisabled: boolean;
13
+ tooltipDisplayDelayMs: number;
14
+ };
12
15
  feeInUsd?: string;
13
16
  estimatedTime?: string;
14
17
  canToggleBoostMode?: boolean;
@@ -21,5 +24,5 @@ interface DetailsToolbarProps {
21
24
  };
22
25
  boostTooltipDisplayDelayMs?: number;
23
26
  }
24
- export declare function DetailsToolbar({ errorMessage, boostMode, onToggleBoostMode, onInvertSwapButtonClick, onFeeButtonClick, feeInUsd, estimatedTime, canToggleBoostMode, boostDisabledMessage, helpButton, isLoading, isEmpty, boostTooltipDisplayDelayMs, isFlipButtonDisabled, flipButtonDisabledMessage, }: DetailsToolbarProps): import("react/jsx-runtime").JSX.Element;
27
+ export declare function DetailsToolbar({ errorMessage, boostMode, onToggleBoostMode, onInvertSwapButtonClick, onFeeButtonClick, feeInUsd, estimatedTime, canToggleBoostMode, boostDisabledMessage, helpButton, isLoading, isEmpty, boostTooltipDisplayDelayMs, flipButton, }: DetailsToolbarProps): import("react/jsx-runtime").JSX.Element;
25
28
  export {};
@@ -1,4 +1,4 @@
1
- import { SwapDirection } from '../../types/components';
1
+ import { AssetsButtonVariant, SwapDirection } from '../../types/components';
2
2
  interface SwapConfigurationProps {
3
3
  direction: SwapDirection;
4
4
  priceImpactPercentage?: string;
@@ -28,6 +28,7 @@ interface SwapConfigurationProps {
28
28
  };
29
29
  criticalPriceImpactPercentage?: number;
30
30
  emptyAddressLabel?: string;
31
+ assetsButtonVariant?: AssetsButtonVariant;
31
32
  }
32
- export declare function SwapConfiguration({ amount, tokenPrice, isFetching, chain, token, direction, onAmountChange, onWalletButtonClick, onAssetsButtonClick, address, emptyAddressLabel, balance, criticalPriceImpactPercentage, error, priceImpactPercentage, amountUsd, }: SwapConfigurationProps): import("react/jsx-runtime").JSX.Element;
33
+ export declare function SwapConfiguration({ amount, tokenPrice, isFetching, chain, token, direction, onAmountChange, onWalletButtonClick, onAssetsButtonClick, address, emptyAddressLabel, balance, criticalPriceImpactPercentage, error, priceImpactPercentage, amountUsd, assetsButtonVariant, }: SwapConfigurationProps): import("react/jsx-runtime").JSX.Element;
33
34
  export {};
@@ -7,3 +7,4 @@ export declare const Default: Story;
7
7
  export declare const WithoutIcon: Story;
8
8
  export declare const WithActionButton: Story;
9
9
  export declare const Error: Story;
10
+ export declare const FocusAfter3Seconds: Story;
@@ -3,7 +3,8 @@ import { SwapConfiguration } from '../../components/layout/SwapConfiguration';
3
3
  declare const meta: Meta<typeof SwapConfiguration>;
4
4
  export default meta;
5
5
  type Story = StoryObj<typeof meta>;
6
- export declare const Empty: Story;
6
+ export declare const EmptyVariantPrimary: Story;
7
+ export declare const EmptyVariantAccent: Story;
7
8
  export declare const ChainOnly: Story;
8
9
  export declare const ChainAndToken: Story;
9
10
  export declare const WithSwapAmountUsd: Story;
@@ -32,3 +32,4 @@ export type DetailsToolbarState = 'full' | 'loading' | 'empty' | 'error';
32
32
  export type ThemeType = 'light' | 'dark';
33
33
  export type SwapStepItemStatus = 'pending' | 'waiting' | 'ongoing' | 'executed' | 'success' | 'error' | 'warning';
34
34
  export type InputMode = 'token' | 'price';
35
+ export type AssetsButtonVariant = 'primary' | 'accent';
package/dist/esm/index.js CHANGED
@@ -2898,9 +2898,19 @@ function SearchIcon() {
2898
2898
  }
2899
2899
 
2900
2900
  function Input(_a) {
2901
- var { placeholder = 'Search', showIcon = true, className, icon, isError = false, containerClassName, actionButtonProps } = _a, props = __rest(_a, ["placeholder", "showIcon", "className", "icon", "isError", "containerClassName", "actionButtonProps"]);
2901
+ var { placeholder = 'Search', showIcon = true, className, icon, isError = false, containerClassName, actionButtonProps, autoFocusTimeout } = _a, props = __rest(_a, ["placeholder", "showIcon", "className", "icon", "isError", "containerClassName", "actionButtonProps", "autoFocusTimeout"]);
2902
2902
  const showActionButton = !!actionButtonProps;
2903
- return (jsxs("div", { className: cn('tw-relative tw-w-full tw-text-grey-600', containerClassName), children: [jsx("input", Object.assign({}, props, { "aria-invalid": isError, className: cn('tw-relative tw-h-10 tw-w-full tw-rounded-full tw-border tw-border-material-light-thin tw-bg-grey-900 tw-text-body-small tw-font-typography-regular tw-text-grey-300 placeholder:tw-text-grey-600 invalid:tw-outline-status-negative', showIcon ? 'tw-pl-[40px]' : 'tw-px-2.5', showActionButton ? 'tw-pr-[70px]' : 'tw-pr-2.5', isError && '!tw-outline-status-negative', className), placeholder: placeholder })), showIcon ? (jsx("div", { className: "tw-absolute tw-inset-y-0 tw-left-0 tw-flex tw-h-full tw-w-[44px] tw-items-center tw-justify-center tw-px-squid-xs", children: icon || jsx(SearchIcon, {}) })) : null, showActionButton ? (jsx("div", { className: "tw-absolute tw-inset-y-0 tw-right-1.5 tw-flex tw-items-center tw-justify-center", children: jsx(InputActionButton, Object.assign({}, actionButtonProps)) })) : null] }));
2903
+ const inputRef = useRef(null);
2904
+ useEffect(() => {
2905
+ if (!autoFocusTimeout)
2906
+ return;
2907
+ const timeoutId = setTimeout(() => {
2908
+ var _a;
2909
+ (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
2910
+ }, autoFocusTimeout);
2911
+ return () => clearTimeout(timeoutId);
2912
+ }, [autoFocusTimeout]);
2913
+ return (jsxs("div", { className: cn('tw-relative tw-w-full tw-text-grey-600', containerClassName), children: [jsx("input", Object.assign({}, props, { ref: inputRef, "aria-invalid": isError, className: cn('tw-relative tw-h-10 tw-w-full tw-rounded-full tw-border tw-border-material-light-thin tw-bg-grey-900 tw-text-body-small tw-font-typography-regular tw-text-grey-300 placeholder:tw-text-grey-600 invalid:tw-outline-status-negative', showIcon ? 'tw-pl-[40px]' : 'tw-px-2.5', showActionButton ? 'tw-pr-[70px]' : 'tw-pr-2.5', isError && '!tw-outline-status-negative', className), placeholder: placeholder })), showIcon ? (jsx("div", { className: "tw-absolute tw-inset-y-0 tw-left-0 tw-flex tw-h-full tw-w-[44px] tw-items-center tw-justify-center tw-px-squid-xs", children: icon || jsx(SearchIcon, {}) })) : null, showActionButton ? (jsx("div", { className: "tw-absolute tw-inset-y-0 tw-right-1.5 tw-flex tw-items-center tw-justify-center", children: jsx(InputActionButton, Object.assign({}, actionButtonProps)) })) : null] }));
2904
2914
  }
2905
2915
  const InputActionButton = ({ onClick, variant = 'tertiary', label = 'Paste', }) => {
2906
2916
  return (jsx(Button, { size: "md", variant: variant, onClick: onClick, className: "!tw-h-[30px] !tw-w-fit !tw-min-w-0", children: jsx(CaptionText, { children: label }) }));
@@ -6486,7 +6496,7 @@ const detailStateClassMap = {
6486
6496
  error: 'tw-opacity-33 tw-pointer-events-none',
6487
6497
  full: '',
6488
6498
  };
6489
- function DetailsToolbar({ errorMessage, boostMode = 'normal', onToggleBoostMode, onInvertSwapButtonClick, onFeeButtonClick, feeInUsd, estimatedTime, canToggleBoostMode, boostDisabledMessage, helpButton, isLoading, isEmpty, boostTooltipDisplayDelayMs = 0, isFlipButtonDisabled, flipButtonDisabledMessage, }) {
6499
+ function DetailsToolbar({ errorMessage, boostMode = 'normal', onToggleBoostMode, onInvertSwapButtonClick, onFeeButtonClick, feeInUsd, estimatedTime, canToggleBoostMode, boostDisabledMessage, helpButton, isLoading, isEmpty, boostTooltipDisplayDelayMs = 0, flipButton, }) {
6490
6500
  const state = useMemo(() => {
6491
6501
  if (errorMessage)
6492
6502
  return 'error';
@@ -6497,7 +6507,9 @@ function DetailsToolbar({ errorMessage, boostMode = 'normal', onToggleBoostMode,
6497
6507
  return 'full';
6498
6508
  }, [errorMessage, isLoading, isEmpty]);
6499
6509
  const detailClassName = cn('tw-w-[190px]', detailStateClassMap[state]);
6500
- return (jsx("aside", { className: cn('tw-flex tw-h-[50px] tw-w-card tw-items-center tw-justify-around tw-border-t tw-border-t-material-light-thin tw-bg-grey-900 tw-py-squid-xxs tw-text-grey-500', state === 'error' ? 'tw-px-squid-l' : 'tw-px-squid-m'), children: state === 'error' && errorMessage ? (jsxs(Fragment, { children: [jsx(ErrorMessage, { message: errorMessage }), helpButton ? (jsx(Button, { onClick: helpButton.onClick, size: "md", variant: "tertiary", label: helpButton.label })) : null] })) : (jsxs(Fragment, { children: [jsx("div", { className: detailClassName, children: jsx(FeeButton, { feeInUsd: feeInUsd, onClick: onFeeButtonClick }) }), jsx("div", { className: "tw-flex tw-h-squid-xl tw-w-squid-xxl tw-items-center tw-justify-center", children: state === 'loading' ? (jsx(Loader, { size: "32" })) : (jsx(Tooltip, { tooltipContent: isFlipButtonDisabled ? flipButtonDisabledMessage : undefined, tooltipWidth: "max", children: jsx("button", { disabled: isFlipButtonDisabled, onClick: onInvertSwapButtonClick, className: "tw-group/flip-button tw-flex tw-h-squid-xl tw-min-w-[60px] tw-items-center tw-justify-center tw-rounded-squid-m tw-bg-transparent tw-px-squid-xs tw-py-squid-xxs tw-text-grey-300 hover:tw-bg-material-light-thin disabled:tw-cursor-not-allowed", children: jsx(ChevronLargeDownIcon, { className: cn('tw-transition-transform tw-duration-150', !isFlipButtonDisabled &&
6510
+ return (jsx("aside", { className: cn('tw-flex tw-h-[50px] tw-w-card tw-items-center tw-justify-around tw-border-t tw-border-t-material-light-thin tw-bg-grey-900 tw-py-squid-xxs tw-text-grey-500', state === 'error' ? 'tw-px-squid-l' : 'tw-px-squid-m'), children: state === 'error' && errorMessage ? (jsxs(Fragment, { children: [jsx(ErrorMessage, { message: errorMessage }), helpButton ? (jsx(Button, { onClick: helpButton.onClick, size: "md", variant: "tertiary", label: helpButton.label })) : null] })) : (jsxs(Fragment, { children: [jsx("div", { className: detailClassName, children: jsx(FeeButton, { feeInUsd: feeInUsd, onClick: onFeeButtonClick }) }), jsx("div", { className: "tw-flex tw-h-squid-xl tw-w-squid-xxl tw-items-center tw-justify-center", children: state === 'loading' ? (jsx(Loader, { size: "32" })) : (jsx(Tooltip, { tooltipContent: (flipButton === null || flipButton === void 0 ? void 0 : flipButton.isDisabled)
6511
+ ? flipButton.disabledMessage
6512
+ : undefined, tooltipWidth: "max", displayDelayMs: flipButton === null || flipButton === void 0 ? void 0 : flipButton.tooltipDisplayDelayMs, children: jsx("button", { disabled: flipButton === null || flipButton === void 0 ? void 0 : flipButton.isDisabled, onClick: onInvertSwapButtonClick, className: "tw-group/flip-button tw-flex tw-h-squid-xl tw-min-w-[60px] tw-items-center tw-justify-center tw-rounded-squid-m tw-bg-transparent tw-px-squid-xs tw-py-squid-xxs tw-text-grey-300 hover:tw-bg-material-light-thin disabled:tw-cursor-not-allowed", children: jsx(ChevronLargeDownIcon, { className: cn('tw-transition-transform tw-duration-150', !(flipButton === null || flipButton === void 0 ? void 0 : flipButton.isDisabled) &&
6501
6513
  'group-hover/flip-button:tw-rotate-180') }) }) })) }), jsx("div", { className: detailClassName, children: jsx(Boost, { estimatedTime: estimatedTime !== null && estimatedTime !== void 0 ? estimatedTime : '0s', boostMode: boostMode, onToggleBoostMode: onToggleBoostMode, canToggleBoostMode: state === 'loading' ? false : canToggleBoostMode, boostDisabledMessage: boostDisabledMessage, boostTooltipDisplayDelayMs: boostTooltipDisplayDelayMs }) })] })) }));
6502
6514
  }
6503
6515
 
@@ -6888,9 +6900,9 @@ function LogoContainer({ children }) {
6888
6900
  return (jsx("div", { className: "tw-flex tw-h-[60px] tw-w-[60px] tw-items-center tw-justify-center", children: children }));
6889
6901
  }
6890
6902
 
6891
- function SwapConfiguration({ amount, tokenPrice = 0, isFetching = false, chain, token, direction, onAmountChange, onWalletButtonClick, onAssetsButtonClick, address, emptyAddressLabel = 'Connect wallet', balance, criticalPriceImpactPercentage, error, priceImpactPercentage, amountUsd, }) {
6903
+ function SwapConfiguration({ amount, tokenPrice = 0, isFetching = false, chain, token, direction, onAmountChange, onWalletButtonClick, onAssetsButtonClick, address, emptyAddressLabel = 'Connect wallet', balance, criticalPriceImpactPercentage, error, priceImpactPercentage, amountUsd, assetsButtonVariant, }) {
6892
6904
  var _a, _b;
6893
- return (jsxs("section", { className: "tw-relative tw-h-[205px] tw-max-h-[205px] tw-w-card tw-overflow-hidden tw-border-t tw-border-t-material-light-thin tw-bg-grey-900 tw-pb-squid-m", children: [jsx("header", { className: "tw-flex tw-items-center tw-gap-1 tw-px-squid-l tw-py-squid-xs tw-leading-5 tw-text-grey-300", children: jsxs("button", { onClick: onWalletButtonClick, className: "-tw-ml-squid-xs tw-flex tw-h-squid-l tw-items-center tw-gap-squid-xxs tw-rounded-squid-s tw-px-squid-xs tw-text-grey-600 hover:tw-bg-material-light-thin", children: [jsx(BodyText, { className: "tw-text-grey-500", size: "small", children: direction === 'from' ? 'Pay' : 'Receive' }), jsx(BodyText, { size: "small", children: ":" }), jsxs("div", { className: "tw-flex tw-items-center tw-gap-1", children: [jsx(BodyText, { size: "small", className: address ? 'tw-text-grey-300' : 'tw-text-royal-400', children: address ? address : emptyAddressLabel }), jsx(ChevronArrowIcon, { className: address ? 'tw-text-grey-600' : 'tw-text-royal-400' })] })] }) }), jsx("div", { className: "tw-px-squid-l", children: jsx(AssetsButton, { onClick: onAssetsButtonClick, chainImageUrl: chain === null || chain === void 0 ? void 0 : chain.iconUrl, tokenImageUrl: token === null || token === void 0 ? void 0 : token.iconUrl, tokenSymbol: token === null || token === void 0 ? void 0 : token.symbol, chainBgColor: chain === null || chain === void 0 ? void 0 : chain.bgColor, tokenBgColor: token === null || token === void 0 ? void 0 : token.bgColor, tokenTextColor: token === null || token === void 0 ? void 0 : token.textColor }) }), isFetching && (jsx("div", { className: "tw-absolute tw-bottom-4 tw-left-squid-l tw-z-10 tw-overflow-hidden", children: jsx("div", { className: "tw-h-[94px] tw-w-[1260px] tw-animate-move-loading-cover-to-right tw-bg-dark-cover" }) })), jsx(NumericInput, { token: {
6905
+ return (jsxs("section", { className: "tw-relative tw-h-[205px] tw-max-h-[205px] tw-w-card tw-overflow-hidden tw-border-t tw-border-t-material-light-thin tw-bg-grey-900 tw-pb-squid-m", children: [jsx("header", { className: "tw-flex tw-items-center tw-gap-1 tw-px-squid-l tw-py-squid-xs tw-leading-5 tw-text-grey-300", children: jsxs("button", { onClick: onWalletButtonClick, className: "-tw-ml-squid-xs tw-flex tw-h-squid-l tw-items-center tw-gap-squid-xxs tw-rounded-squid-s tw-px-squid-xs tw-text-grey-600 hover:tw-bg-material-light-thin", children: [jsx(BodyText, { className: "tw-text-grey-500", size: "small", children: direction === 'from' ? 'Pay' : 'Receive' }), jsx(BodyText, { size: "small", children: ":" }), jsxs("div", { className: "tw-flex tw-items-center tw-gap-1", children: [jsx(BodyText, { size: "small", className: address ? 'tw-text-grey-300' : 'tw-text-royal-400', children: address ? address : emptyAddressLabel }), jsx(ChevronArrowIcon, { className: address ? 'tw-text-grey-600' : 'tw-text-royal-400' })] })] }) }), jsx("div", { className: "tw-px-squid-l", children: jsx(AssetsButton, { onClick: onAssetsButtonClick, chainImageUrl: chain === null || chain === void 0 ? void 0 : chain.iconUrl, tokenImageUrl: token === null || token === void 0 ? void 0 : token.iconUrl, tokenSymbol: token === null || token === void 0 ? void 0 : token.symbol, chainBgColor: chain === null || chain === void 0 ? void 0 : chain.bgColor, tokenBgColor: token === null || token === void 0 ? void 0 : token.bgColor, tokenTextColor: token === null || token === void 0 ? void 0 : token.textColor, variant: assetsButtonVariant }) }), isFetching && (jsx("div", { className: "tw-absolute tw-bottom-4 tw-left-squid-l tw-z-10 tw-overflow-hidden", children: jsx("div", { className: "tw-h-[94px] tw-w-[1260px] tw-animate-move-loading-cover-to-right tw-bg-dark-cover" }) })), jsx(NumericInput, { token: {
6894
6906
  decimals: (_a = token === null || token === void 0 ? void 0 : token.decimals) !== null && _a !== void 0 ? _a : 18,
6895
6907
  symbol: (_b = token === null || token === void 0 ? void 0 : token.symbol) !== null && _b !== void 0 ? _b : '',
6896
6908
  price: tokenPrice,
@@ -1,4 +1,4 @@
1
- type AssetsButtonVariant = 'primary' | 'accent';
1
+ import { AssetsButtonVariant } from '../../types/components';
2
2
  interface AssetsButtonProps {
3
3
  tokenImageUrl?: string;
4
4
  chainImageUrl?: string;
@@ -7,8 +7,9 @@ interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
7
7
  isError?: boolean;
8
8
  containerClassName?: string;
9
9
  actionButtonProps?: InputActionButtonProps;
10
+ autoFocusTimeout?: number;
10
11
  }
11
- export declare function Input({ placeholder, showIcon, className, icon, isError, containerClassName, actionButtonProps, ...props }: InputProps): import("react/jsx-runtime").JSX.Element;
12
+ export declare function Input({ placeholder, showIcon, className, icon, isError, containerClassName, actionButtonProps, autoFocusTimeout, ...props }: InputProps): import("react/jsx-runtime").JSX.Element;
12
13
  type InputActionButtonProps = {
13
14
  onClick?: () => void;
14
15
  variant?: ButtonVariant;
@@ -7,8 +7,11 @@ interface DetailsToolbarProps {
7
7
  }) => void;
8
8
  onInvertSwapButtonClick?: () => void;
9
9
  onFeeButtonClick?: () => void;
10
- isFlipButtonDisabled?: boolean;
11
- flipButtonDisabledMessage?: string;
10
+ flipButton?: {
11
+ disabledMessage: string;
12
+ isDisabled: boolean;
13
+ tooltipDisplayDelayMs: number;
14
+ };
12
15
  feeInUsd?: string;
13
16
  estimatedTime?: string;
14
17
  canToggleBoostMode?: boolean;
@@ -21,5 +24,5 @@ interface DetailsToolbarProps {
21
24
  };
22
25
  boostTooltipDisplayDelayMs?: number;
23
26
  }
24
- export declare function DetailsToolbar({ errorMessage, boostMode, onToggleBoostMode, onInvertSwapButtonClick, onFeeButtonClick, feeInUsd, estimatedTime, canToggleBoostMode, boostDisabledMessage, helpButton, isLoading, isEmpty, boostTooltipDisplayDelayMs, isFlipButtonDisabled, flipButtonDisabledMessage, }: DetailsToolbarProps): import("react/jsx-runtime").JSX.Element;
27
+ export declare function DetailsToolbar({ errorMessage, boostMode, onToggleBoostMode, onInvertSwapButtonClick, onFeeButtonClick, feeInUsd, estimatedTime, canToggleBoostMode, boostDisabledMessage, helpButton, isLoading, isEmpty, boostTooltipDisplayDelayMs, flipButton, }: DetailsToolbarProps): import("react/jsx-runtime").JSX.Element;
25
28
  export {};
@@ -1,4 +1,4 @@
1
- import { SwapDirection } from '../../types/components';
1
+ import { AssetsButtonVariant, SwapDirection } from '../../types/components';
2
2
  interface SwapConfigurationProps {
3
3
  direction: SwapDirection;
4
4
  priceImpactPercentage?: string;
@@ -28,6 +28,7 @@ interface SwapConfigurationProps {
28
28
  };
29
29
  criticalPriceImpactPercentage?: number;
30
30
  emptyAddressLabel?: string;
31
+ assetsButtonVariant?: AssetsButtonVariant;
31
32
  }
32
- export declare function SwapConfiguration({ amount, tokenPrice, isFetching, chain, token, direction, onAmountChange, onWalletButtonClick, onAssetsButtonClick, address, emptyAddressLabel, balance, criticalPriceImpactPercentage, error, priceImpactPercentage, amountUsd, }: SwapConfigurationProps): import("react/jsx-runtime").JSX.Element;
33
+ export declare function SwapConfiguration({ amount, tokenPrice, isFetching, chain, token, direction, onAmountChange, onWalletButtonClick, onAssetsButtonClick, address, emptyAddressLabel, balance, criticalPriceImpactPercentage, error, priceImpactPercentage, amountUsd, assetsButtonVariant, }: SwapConfigurationProps): import("react/jsx-runtime").JSX.Element;
33
34
  export {};
@@ -7,3 +7,4 @@ export declare const Default: Story;
7
7
  export declare const WithoutIcon: Story;
8
8
  export declare const WithActionButton: Story;
9
9
  export declare const Error: Story;
10
+ export declare const FocusAfter3Seconds: Story;
@@ -3,7 +3,8 @@ import { SwapConfiguration } from '../../components/layout/SwapConfiguration';
3
3
  declare const meta: Meta<typeof SwapConfiguration>;
4
4
  export default meta;
5
5
  type Story = StoryObj<typeof meta>;
6
- export declare const Empty: Story;
6
+ export declare const EmptyVariantPrimary: Story;
7
+ export declare const EmptyVariantAccent: Story;
7
8
  export declare const ChainOnly: Story;
8
9
  export declare const ChainAndToken: Story;
9
10
  export declare const WithSwapAmountUsd: Story;
@@ -32,3 +32,4 @@ export type DetailsToolbarState = 'full' | 'loading' | 'empty' | 'error';
32
32
  export type ThemeType = 'light' | 'dark';
33
33
  export type SwapStepItemStatus = 'pending' | 'waiting' | 'ongoing' | 'executed' | 'success' | 'error' | 'warning';
34
34
  export type InputMode = 'token' | 'price';
35
+ export type AssetsButtonVariant = 'primary' | 'accent';
package/dist/index.d.ts CHANGED
@@ -38,19 +38,6 @@ interface ArrowButtonProps extends React.HTMLAttributes<HTMLButtonElement> {
38
38
  }
39
39
  declare function ArrowButton({ label, disabled, ...props }: ArrowButtonProps): react_jsx_runtime.JSX.Element;
40
40
 
41
- type AssetsButtonVariant = 'primary' | 'accent';
42
- interface AssetsButtonProps {
43
- tokenImageUrl?: string;
44
- chainImageUrl?: string;
45
- tokenSymbol?: string;
46
- chainBgColor?: string;
47
- tokenBgColor?: string;
48
- tokenTextColor?: string;
49
- onClick?: () => void;
50
- variant?: AssetsButtonVariant;
51
- }
52
- declare function AssetsButton({ chainImageUrl, tokenImageUrl, tokenSymbol, chainBgColor: _chainBgColor, tokenBgColor: _tokenBgColor, tokenTextColor, onClick, variant, }: AssetsButtonProps): react_jsx_runtime.JSX.Element;
53
-
54
41
  type TextSize = 'small' | 'medium' | 'large';
55
42
  type SwitchSize = 'small' | 'large';
56
43
  type ButtonVariant = 'primary' | 'secondary' | 'tertiary';
@@ -83,6 +70,19 @@ declare enum SwapState {
83
70
  }
84
71
  type ThemeType = 'light' | 'dark';
85
72
  type SwapStepItemStatus = 'pending' | 'waiting' | 'ongoing' | 'executed' | 'success' | 'error' | 'warning';
73
+ type AssetsButtonVariant = 'primary' | 'accent';
74
+
75
+ interface AssetsButtonProps {
76
+ tokenImageUrl?: string;
77
+ chainImageUrl?: string;
78
+ tokenSymbol?: string;
79
+ chainBgColor?: string;
80
+ tokenBgColor?: string;
81
+ tokenTextColor?: string;
82
+ onClick?: () => void;
83
+ variant?: AssetsButtonVariant;
84
+ }
85
+ declare function AssetsButton({ chainImageUrl, tokenImageUrl, tokenSymbol, chainBgColor: _chainBgColor, tokenBgColor: _tokenBgColor, tokenTextColor, onClick, variant, }: AssetsButtonProps): react_jsx_runtime.JSX.Element;
86
86
 
87
87
  interface BoostButtonProps {
88
88
  boostMode: BoostMode;
@@ -129,8 +129,9 @@ interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
129
129
  isError?: boolean;
130
130
  containerClassName?: string;
131
131
  actionButtonProps?: InputActionButtonProps;
132
+ autoFocusTimeout?: number;
132
133
  }
133
- declare function Input({ placeholder, showIcon, className, icon, isError, containerClassName, actionButtonProps, ...props }: InputProps): react_jsx_runtime.JSX.Element;
134
+ declare function Input({ placeholder, showIcon, className, icon, isError, containerClassName, actionButtonProps, autoFocusTimeout, ...props }: InputProps): react_jsx_runtime.JSX.Element;
134
135
  type InputActionButtonProps = {
135
136
  onClick?: () => void;
136
137
  variant?: ButtonVariant;
@@ -220,8 +221,11 @@ interface DetailsToolbarProps {
220
221
  }) => void;
221
222
  onInvertSwapButtonClick?: () => void;
222
223
  onFeeButtonClick?: () => void;
223
- isFlipButtonDisabled?: boolean;
224
- flipButtonDisabledMessage?: string;
224
+ flipButton?: {
225
+ disabledMessage: string;
226
+ isDisabled: boolean;
227
+ tooltipDisplayDelayMs: number;
228
+ };
225
229
  feeInUsd?: string;
226
230
  estimatedTime?: string;
227
231
  canToggleBoostMode?: boolean;
@@ -234,7 +238,7 @@ interface DetailsToolbarProps {
234
238
  };
235
239
  boostTooltipDisplayDelayMs?: number;
236
240
  }
237
- declare function DetailsToolbar({ errorMessage, boostMode, onToggleBoostMode, onInvertSwapButtonClick, onFeeButtonClick, feeInUsd, estimatedTime, canToggleBoostMode, boostDisabledMessage, helpButton, isLoading, isEmpty, boostTooltipDisplayDelayMs, isFlipButtonDisabled, flipButtonDisabledMessage, }: DetailsToolbarProps): react_jsx_runtime.JSX.Element;
241
+ declare function DetailsToolbar({ errorMessage, boostMode, onToggleBoostMode, onInvertSwapButtonClick, onFeeButtonClick, feeInUsd, estimatedTime, canToggleBoostMode, boostDisabledMessage, helpButton, isLoading, isEmpty, boostTooltipDisplayDelayMs, flipButton, }: DetailsToolbarProps): react_jsx_runtime.JSX.Element;
238
242
 
239
243
  interface DropdownMenuItemProps {
240
244
  label: string;
@@ -465,8 +469,9 @@ interface SwapConfigurationProps {
465
469
  };
466
470
  criticalPriceImpactPercentage?: number;
467
471
  emptyAddressLabel?: string;
472
+ assetsButtonVariant?: AssetsButtonVariant;
468
473
  }
469
- declare function SwapConfiguration({ amount, tokenPrice, isFetching, chain, token, direction, onAmountChange, onWalletButtonClick, onAssetsButtonClick, address, emptyAddressLabel, balance, criticalPriceImpactPercentage, error, priceImpactPercentage, amountUsd, }: SwapConfigurationProps): react_jsx_runtime.JSX.Element;
474
+ declare function SwapConfiguration({ amount, tokenPrice, isFetching, chain, token, direction, onAmountChange, onWalletButtonClick, onAssetsButtonClick, address, emptyAddressLabel, balance, criticalPriceImpactPercentage, error, priceImpactPercentage, amountUsd, assetsButtonVariant, }: SwapConfigurationProps): react_jsx_runtime.JSX.Element;
470
475
 
471
476
  interface SwapProgressViewHeaderProps {
472
477
  title: string;
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "url": "git+https://github.com/0xsquid/squid-ui.git"
6
6
  },
7
7
  "description": "Squid's UI components",
8
- "version": "0.16.2",
8
+ "version": "0.17.0",
9
9
  "author": "",
10
10
  "license": "MIT",
11
11
  "resolutions": {