@0xsquid/ui 0.16.1 → 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
@@ -2591,8 +2591,8 @@ function BadgeImage({ imageUrl, badgeUrl, size = 'sm', extraMarginForBadge, roun
2591
2591
  imagesLoadState.badgeLoaded ? 'tw-block' : 'tw-hidden') })] })) : null] })) : null;
2592
2592
  }
2593
2593
 
2594
- function LoadingSkeleton({ className, height = '20', }) {
2595
- return (jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "100", height: height, viewBox: "0 0 100 20", fill: "none", className: className, children: [jsxRuntime.jsx("g", { clipPath: "url(#clip0_1246_29063)", children: jsxRuntime.jsx("rect", { width: "100", height: "20", fill: "url(#paint0_linear_1246_29063)" }) }), jsxRuntime.jsxs("defs", { children: [jsxRuntime.jsxs("linearGradient", { id: "paint0_linear_1246_29063", x1: "0", y1: "10", x2: "100", y2: "10", gradientUnits: "userSpaceOnUse", className: "tw-animate-loading-gradient tw-text-material-light-thin", children: [jsxRuntime.jsx("stop", { stopColor: "currentColor" }), jsxRuntime.jsx("stop", { offset: "0.395881", stopColor: "currentColor" }), jsxRuntime.jsx("stop", { offset: "0.597867", stopColor: "currentColor", className: "group-data-[squid-theme-type=dark]:tw-text-material-light-average group-data-[squid-theme-type=light]:tw-text-transparent" }), jsxRuntime.jsx("stop", { offset: "0.697004", stopColor: "currentColor" })] }), jsxRuntime.jsx("clipPath", { id: "clip0_1246_29063", children: jsxRuntime.jsx("path", { d: "M0 10C0 4.47715 4.47715 0 10 0H90C95.5228 0 100 4.47715 100 10C100 15.5228 95.5229 20 90 20H10C4.47716 20 0 15.5228 0 10Z", fill: "white" }) })] }), ' '] }));
2594
+ function LoadingSkeleton({ className, height = '20', width = '100', }) {
2595
+ return (jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: width, height: height, viewBox: "0 0 100 20", fill: "none", className: className, children: [jsxRuntime.jsx("g", { clipPath: "url(#clip0_1246_29063)", children: jsxRuntime.jsx("rect", { width: "100", height: "20", fill: "url(#paint0_linear_1246_29063)" }) }), jsxRuntime.jsxs("defs", { children: [jsxRuntime.jsxs("linearGradient", { id: "paint0_linear_1246_29063", x1: "0", y1: "10", x2: "100", y2: "10", gradientUnits: "userSpaceOnUse", className: "tw-animate-loading-gradient tw-text-material-light-thin", children: [jsxRuntime.jsx("stop", { stopColor: "currentColor" }), jsxRuntime.jsx("stop", { offset: "0.395881", stopColor: "currentColor" }), jsxRuntime.jsx("stop", { offset: "0.597867", stopColor: "currentColor", className: "group-data-[squid-theme-type=dark]:tw-text-material-light-average group-data-[squid-theme-type=light]:tw-text-transparent" }), jsxRuntime.jsx("stop", { offset: "0.697004", stopColor: "currentColor" })] }), jsxRuntime.jsx("clipPath", { id: "clip0_1246_29063", children: jsxRuntime.jsx("path", { d: "M0 10C0 4.47715 4.47715 0 10 0H90C95.5228 0 100 4.47715 100 10C100 15.5228 95.5229 20 90 20H10C4.47716 20 0 15.5228 0 10Z", fill: "white" }) })] }), ' '] }));
2596
2596
  }
2597
2597
 
2598
2598
  /******************************************************************************
@@ -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
 
@@ -6679,13 +6691,26 @@ function ListItem(_a) {
6679
6691
  },
6680
6692
  }
6681
6693
  : {};
6694
+ // There are two possible ways to handle loading state:
6695
+ // Can be boolean or string
6696
+ // If boolean and true, it will show a full loading skeleton
6697
+ // If it's a non empty string, means that we want to display the skeleton + some text
6698
+ const loadingComponent = () => {
6699
+ if ((loading === null || loading === void 0 ? void 0 : loading.subtitle) === true) {
6700
+ return (jsxRuntime.jsx(LoadingSkeleton, { className: "tw-text-grey-500", height: "10", width: "50" }));
6701
+ }
6702
+ if (typeof (loading === null || loading === void 0 ? void 0 : loading.subtitle) === 'string' && loading.subtitle.length > 0) {
6703
+ return (jsxRuntime.jsxs("span", { className: "tw-flex tw-items-center tw-gap-squid-xxs", children: [jsxRuntime.jsx(LoadingSkeleton, { className: "tw-text-grey-500", width: "50" }), jsxRuntime.jsx(CaptionText, { className: subtitleClassName, children: loading.subtitle })] }));
6704
+ }
6705
+ return null;
6706
+ };
6682
6707
  const isInteractive = !!props.onClick;
6683
6708
  const ItemTag = isInteractive ? 'button' : 'div';
6684
6709
  const itemProps = isInteractive ? props : {};
6685
6710
  return (jsxRuntime.jsx("li", Object.assign({}, containerProps, { className: cn('tw-flex tw-max-w-full tw-bg-grey-900 tw-text-grey-300', listItemSizeMap[size], className), children: jsxRuntime.jsxs(ItemTag, Object.assign({}, itemProps, { className: cn('tw-group/list-item tw-flex tw-w-full tw-max-w-full tw-items-center tw-justify-start tw-gap-squid-xs tw-rounded-squid-s tw-px-squid-xs tw-py-squid-xxs', isSelected && 'tw-bg-material-light-thin', isInteractive && 'hover:tw-bg-material-light-thin'), children: [size === 'large' ? (jsxRuntime.jsx("div", { className: "tw-h-10 tw-w-10", children: mainIcon ? (mainIcon) : (jsxRuntime.jsx(BadgeImage, { extraMarginForBadge: false, imageUrl: mainImageUrl, badgeUrl: secondaryImageUrl, size: "md", rounded: rounded })) })) : (jsxRuntime.jsx("div", { className: "tw-flex tw-min-h-[30px] tw-min-w-[30px] tw-items-center tw-justify-center", children: mainIcon ? (mainIcon) : (jsxRuntime.jsx("img", { src: mainImageUrl, className: "tw-h-[30px] tw-w-[30px] tw-rounded-squid-xs" })) })), jsxRuntime.jsxs("div", { className: cn('tw-flex tw-h-[40px] tw-flex-1 tw-flex-col tw-items-start tw-justify-center tw-gap-squid-xxs',
6686
6711
  // 'large' variant has extra padding
6687
6712
  size === 'large' ? 'tw-w-[56%] tw-pl-squid-xxs' : 'tw-w-[67%]'), children: [typeof itemTitle === 'string' ? (jsxRuntime.jsx(BodyText, { size: "small", className: cn('tw-max-w-full tw-truncate', subtitle && 'tw-h-[17px] !tw-leading-[17px]'), children: itemTitle })) : (itemTitle), size === 'large' &&
6688
- ((loading === null || loading === void 0 ? void 0 : loading.subtitle) ? (jsxRuntime.jsx(LoadingSkeleton, { className: "-tw-translate-x-6 tw-text-grey-500", height: "10" })) : subtitle ? (jsxRuntime.jsxs(CaptionText, { className: subtitleClassName, children: [subtitleOnHover && (jsxRuntime.jsx(CaptionText, { className: cn(subtitleClassName, 'tw-hidden group-hover/list-item:tw-block'), children: subtitleOnHover })), subtitle] })) : null)] }), showDetail && (jsxRuntime.jsxs(DetailTag, Object.assign({}, detailProps, { className: cn('tw-flex tw-w-fit tw-items-center tw-justify-center tw-rounded-squid-xs', size === 'large' ? 'tw-h-squid-xl' : 'tw-h-squid-l', showDetailOnHoverOnly
6713
+ ((loading === null || loading === void 0 ? void 0 : loading.subtitle) ? (loadingComponent()) : subtitle ? (jsxRuntime.jsxs(CaptionText, { className: subtitleClassName, children: [subtitleOnHover && (jsxRuntime.jsx(CaptionText, { className: cn(subtitleClassName, 'tw-hidden group-hover/list-item:tw-block'), children: subtitleOnHover })), subtitle] })) : null)] }), showDetail && (jsxRuntime.jsxs(DetailTag, Object.assign({}, detailProps, { className: cn('tw-flex tw-w-fit tw-items-center tw-justify-center tw-rounded-squid-xs', size === 'large' ? 'tw-h-squid-xl' : 'tw-h-squid-l', showDetailOnHoverOnly
6689
6714
  ? 'tw-opacity-0 hover:tw-opacity-100 focus:tw-opacity-100 group-hover/list-item:tw-opacity-100 group-focus/list-item:tw-opacity-100'
6690
6715
  : 'tw-flex', isDetailInteractive && 'hover:tw-bg-material-light-thin', detailButtonClassName), children: [!!detail && (jsxRuntime.jsx(CaptionText, { className: "min-tw-w-4 min-tw-h-4 tw-px-squid-xxs tw-leading-[10px]", children: detail })), icon ? (jsxRuntime.jsx("span", { className: "tw-flex tw-items-center tw-justify-center tw-px-[3px] tw-py-2", children: icon })) : null] })))] })) })));
6691
6716
  }
@@ -6895,9 +6920,9 @@ function LogoContainer({ children }) {
6895
6920
  return (jsxRuntime.jsx("div", { className: "tw-flex tw-h-[60px] tw-w-[60px] tw-items-center tw-justify-center", children: children }));
6896
6921
  }
6897
6922
 
6898
- 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, }) {
6899
6924
  var _a, _b;
6900
- 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: {
6901
6926
  decimals: (_a = token === null || token === void 0 ? void 0 : token.decimals) !== null && _a !== void 0 ? _a : 18,
6902
6927
  symbol: (_b = token === null || token === void 0 ? void 0 : token.symbol) !== null && _b !== void 0 ? _b : '',
6903
6928
  price: tokenPrice,
@@ -1,4 +1,5 @@
1
- export declare function LoadingSkeleton({ className, height, }: {
1
+ export declare function LoadingSkeleton({ className, height, width, }: {
2
2
  className?: string;
3
3
  height?: string;
4
+ width?: string;
4
5
  }): import("react/jsx-runtime").JSX.Element;
@@ -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 {};
@@ -16,7 +16,7 @@ interface ListItemProps extends React.HTMLAttributes<HTMLButtonElement> {
16
16
  rounded?: boolean;
17
17
  detailButtonClassName?: string;
18
18
  loading?: {
19
- subtitle?: boolean;
19
+ subtitle?: boolean | string;
20
20
  };
21
21
  containerProps?: React.HTMLAttributes<HTMLLIElement>;
22
22
  }
@@ -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
@@ -2571,8 +2571,8 @@ function BadgeImage({ imageUrl, badgeUrl, size = 'sm', extraMarginForBadge, roun
2571
2571
  imagesLoadState.badgeLoaded ? 'tw-block' : 'tw-hidden') })] })) : null] })) : null;
2572
2572
  }
2573
2573
 
2574
- function LoadingSkeleton({ className, height = '20', }) {
2575
- return (jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "100", height: height, viewBox: "0 0 100 20", fill: "none", className: className, children: [jsx("g", { clipPath: "url(#clip0_1246_29063)", children: jsx("rect", { width: "100", height: "20", fill: "url(#paint0_linear_1246_29063)" }) }), jsxs("defs", { children: [jsxs("linearGradient", { id: "paint0_linear_1246_29063", x1: "0", y1: "10", x2: "100", y2: "10", gradientUnits: "userSpaceOnUse", className: "tw-animate-loading-gradient tw-text-material-light-thin", children: [jsx("stop", { stopColor: "currentColor" }), jsx("stop", { offset: "0.395881", stopColor: "currentColor" }), jsx("stop", { offset: "0.597867", stopColor: "currentColor", className: "group-data-[squid-theme-type=dark]:tw-text-material-light-average group-data-[squid-theme-type=light]:tw-text-transparent" }), jsx("stop", { offset: "0.697004", stopColor: "currentColor" })] }), jsx("clipPath", { id: "clip0_1246_29063", children: jsx("path", { d: "M0 10C0 4.47715 4.47715 0 10 0H90C95.5228 0 100 4.47715 100 10C100 15.5228 95.5229 20 90 20H10C4.47716 20 0 15.5228 0 10Z", fill: "white" }) })] }), ' '] }));
2574
+ function LoadingSkeleton({ className, height = '20', width = '100', }) {
2575
+ return (jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: width, height: height, viewBox: "0 0 100 20", fill: "none", className: className, children: [jsx("g", { clipPath: "url(#clip0_1246_29063)", children: jsx("rect", { width: "100", height: "20", fill: "url(#paint0_linear_1246_29063)" }) }), jsxs("defs", { children: [jsxs("linearGradient", { id: "paint0_linear_1246_29063", x1: "0", y1: "10", x2: "100", y2: "10", gradientUnits: "userSpaceOnUse", className: "tw-animate-loading-gradient tw-text-material-light-thin", children: [jsx("stop", { stopColor: "currentColor" }), jsx("stop", { offset: "0.395881", stopColor: "currentColor" }), jsx("stop", { offset: "0.597867", stopColor: "currentColor", className: "group-data-[squid-theme-type=dark]:tw-text-material-light-average group-data-[squid-theme-type=light]:tw-text-transparent" }), jsx("stop", { offset: "0.697004", stopColor: "currentColor" })] }), jsx("clipPath", { id: "clip0_1246_29063", children: jsx("path", { d: "M0 10C0 4.47715 4.47715 0 10 0H90C95.5228 0 100 4.47715 100 10C100 15.5228 95.5229 20 90 20H10C4.47716 20 0 15.5228 0 10Z", fill: "white" }) })] }), ' '] }));
2576
2576
  }
2577
2577
 
2578
2578
  /******************************************************************************
@@ -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
 
@@ -6659,13 +6671,26 @@ function ListItem(_a) {
6659
6671
  },
6660
6672
  }
6661
6673
  : {};
6674
+ // There are two possible ways to handle loading state:
6675
+ // Can be boolean or string
6676
+ // If boolean and true, it will show a full loading skeleton
6677
+ // If it's a non empty string, means that we want to display the skeleton + some text
6678
+ const loadingComponent = () => {
6679
+ if ((loading === null || loading === void 0 ? void 0 : loading.subtitle) === true) {
6680
+ return (jsx(LoadingSkeleton, { className: "tw-text-grey-500", height: "10", width: "50" }));
6681
+ }
6682
+ if (typeof (loading === null || loading === void 0 ? void 0 : loading.subtitle) === 'string' && loading.subtitle.length > 0) {
6683
+ return (jsxs("span", { className: "tw-flex tw-items-center tw-gap-squid-xxs", children: [jsx(LoadingSkeleton, { className: "tw-text-grey-500", width: "50" }), jsx(CaptionText, { className: subtitleClassName, children: loading.subtitle })] }));
6684
+ }
6685
+ return null;
6686
+ };
6662
6687
  const isInteractive = !!props.onClick;
6663
6688
  const ItemTag = isInteractive ? 'button' : 'div';
6664
6689
  const itemProps = isInteractive ? props : {};
6665
6690
  return (jsx("li", Object.assign({}, containerProps, { className: cn('tw-flex tw-max-w-full tw-bg-grey-900 tw-text-grey-300', listItemSizeMap[size], className), children: jsxs(ItemTag, Object.assign({}, itemProps, { className: cn('tw-group/list-item tw-flex tw-w-full tw-max-w-full tw-items-center tw-justify-start tw-gap-squid-xs tw-rounded-squid-s tw-px-squid-xs tw-py-squid-xxs', isSelected && 'tw-bg-material-light-thin', isInteractive && 'hover:tw-bg-material-light-thin'), children: [size === 'large' ? (jsx("div", { className: "tw-h-10 tw-w-10", children: mainIcon ? (mainIcon) : (jsx(BadgeImage, { extraMarginForBadge: false, imageUrl: mainImageUrl, badgeUrl: secondaryImageUrl, size: "md", rounded: rounded })) })) : (jsx("div", { className: "tw-flex tw-min-h-[30px] tw-min-w-[30px] tw-items-center tw-justify-center", children: mainIcon ? (mainIcon) : (jsx("img", { src: mainImageUrl, className: "tw-h-[30px] tw-w-[30px] tw-rounded-squid-xs" })) })), jsxs("div", { className: cn('tw-flex tw-h-[40px] tw-flex-1 tw-flex-col tw-items-start tw-justify-center tw-gap-squid-xxs',
6666
6691
  // 'large' variant has extra padding
6667
6692
  size === 'large' ? 'tw-w-[56%] tw-pl-squid-xxs' : 'tw-w-[67%]'), children: [typeof itemTitle === 'string' ? (jsx(BodyText, { size: "small", className: cn('tw-max-w-full tw-truncate', subtitle && 'tw-h-[17px] !tw-leading-[17px]'), children: itemTitle })) : (itemTitle), size === 'large' &&
6668
- ((loading === null || loading === void 0 ? void 0 : loading.subtitle) ? (jsx(LoadingSkeleton, { className: "-tw-translate-x-6 tw-text-grey-500", height: "10" })) : subtitle ? (jsxs(CaptionText, { className: subtitleClassName, children: [subtitleOnHover && (jsx(CaptionText, { className: cn(subtitleClassName, 'tw-hidden group-hover/list-item:tw-block'), children: subtitleOnHover })), subtitle] })) : null)] }), showDetail && (jsxs(DetailTag, Object.assign({}, detailProps, { className: cn('tw-flex tw-w-fit tw-items-center tw-justify-center tw-rounded-squid-xs', size === 'large' ? 'tw-h-squid-xl' : 'tw-h-squid-l', showDetailOnHoverOnly
6693
+ ((loading === null || loading === void 0 ? void 0 : loading.subtitle) ? (loadingComponent()) : subtitle ? (jsxs(CaptionText, { className: subtitleClassName, children: [subtitleOnHover && (jsx(CaptionText, { className: cn(subtitleClassName, 'tw-hidden group-hover/list-item:tw-block'), children: subtitleOnHover })), subtitle] })) : null)] }), showDetail && (jsxs(DetailTag, Object.assign({}, detailProps, { className: cn('tw-flex tw-w-fit tw-items-center tw-justify-center tw-rounded-squid-xs', size === 'large' ? 'tw-h-squid-xl' : 'tw-h-squid-l', showDetailOnHoverOnly
6669
6694
  ? 'tw-opacity-0 hover:tw-opacity-100 focus:tw-opacity-100 group-hover/list-item:tw-opacity-100 group-focus/list-item:tw-opacity-100'
6670
6695
  : 'tw-flex', isDetailInteractive && 'hover:tw-bg-material-light-thin', detailButtonClassName), children: [!!detail && (jsx(CaptionText, { className: "min-tw-w-4 min-tw-h-4 tw-px-squid-xxs tw-leading-[10px]", children: detail })), icon ? (jsx("span", { className: "tw-flex tw-items-center tw-justify-center tw-px-[3px] tw-py-2", children: icon })) : null] })))] })) })));
6671
6696
  }
@@ -6875,9 +6900,9 @@ function LogoContainer({ children }) {
6875
6900
  return (jsx("div", { className: "tw-flex tw-h-[60px] tw-w-[60px] tw-items-center tw-justify-center", children: children }));
6876
6901
  }
6877
6902
 
6878
- 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, }) {
6879
6904
  var _a, _b;
6880
- 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: {
6881
6906
  decimals: (_a = token === null || token === void 0 ? void 0 : token.decimals) !== null && _a !== void 0 ? _a : 18,
6882
6907
  symbol: (_b = token === null || token === void 0 ? void 0 : token.symbol) !== null && _b !== void 0 ? _b : '',
6883
6908
  price: tokenPrice,
@@ -1,4 +1,5 @@
1
- export declare function LoadingSkeleton({ className, height, }: {
1
+ export declare function LoadingSkeleton({ className, height, width, }: {
2
2
  className?: string;
3
3
  height?: string;
4
+ width?: string;
4
5
  }): import("react/jsx-runtime").JSX.Element;
@@ -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 {};
@@ -16,7 +16,7 @@ interface ListItemProps extends React.HTMLAttributes<HTMLButtonElement> {
16
16
  rounded?: boolean;
17
17
  detailButtonClassName?: string;
18
18
  loading?: {
19
- subtitle?: boolean;
19
+ subtitle?: boolean | string;
20
20
  };
21
21
  containerProps?: React.HTMLAttributes<HTMLLIElement>;
22
22
  }
@@ -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.css CHANGED
@@ -1373,11 +1373,6 @@ video {
1373
1373
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
1374
1374
  }
1375
1375
 
1376
- .-tw-translate-x-6 {
1377
- --tw-translate-x: -1.5rem;
1378
- transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
1379
- }
1380
-
1381
1376
  .tw-rotate-180 {
1382
1377
  --tw-rotate: 180deg;
1383
1378
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
package/dist/index.d.ts CHANGED
@@ -13,9 +13,10 @@ interface BadgeImageProps {
13
13
  type BadgeSize = 'sm' | 'md';
14
14
  declare function BadgeImage({ imageUrl, badgeUrl, size, extraMarginForBadge, rounded, }: BadgeImageProps): react_jsx_runtime.JSX.Element | null;
15
15
 
16
- declare function LoadingSkeleton({ className, height, }: {
16
+ declare function LoadingSkeleton({ className, height, width, }: {
17
17
  className?: string;
18
18
  height?: string;
19
+ width?: string;
19
20
  }): react_jsx_runtime.JSX.Element;
20
21
 
21
22
  interface UsdAmountProps {
@@ -37,19 +38,6 @@ interface ArrowButtonProps extends React.HTMLAttributes<HTMLButtonElement> {
37
38
  }
38
39
  declare function ArrowButton({ label, disabled, ...props }: ArrowButtonProps): react_jsx_runtime.JSX.Element;
39
40
 
40
- type AssetsButtonVariant = 'primary' | 'accent';
41
- interface AssetsButtonProps {
42
- tokenImageUrl?: string;
43
- chainImageUrl?: string;
44
- tokenSymbol?: string;
45
- chainBgColor?: string;
46
- tokenBgColor?: string;
47
- tokenTextColor?: string;
48
- onClick?: () => void;
49
- variant?: AssetsButtonVariant;
50
- }
51
- declare function AssetsButton({ chainImageUrl, tokenImageUrl, tokenSymbol, chainBgColor: _chainBgColor, tokenBgColor: _tokenBgColor, tokenTextColor, onClick, variant, }: AssetsButtonProps): react_jsx_runtime.JSX.Element;
52
-
53
41
  type TextSize = 'small' | 'medium' | 'large';
54
42
  type SwitchSize = 'small' | 'large';
55
43
  type ButtonVariant = 'primary' | 'secondary' | 'tertiary';
@@ -82,6 +70,19 @@ declare enum SwapState {
82
70
  }
83
71
  type ThemeType = 'light' | 'dark';
84
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;
85
86
 
86
87
  interface BoostButtonProps {
87
88
  boostMode: BoostMode;
@@ -128,8 +129,9 @@ interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
128
129
  isError?: boolean;
129
130
  containerClassName?: string;
130
131
  actionButtonProps?: InputActionButtonProps;
132
+ autoFocusTimeout?: number;
131
133
  }
132
- 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;
133
135
  type InputActionButtonProps = {
134
136
  onClick?: () => void;
135
137
  variant?: ButtonVariant;
@@ -219,8 +221,11 @@ interface DetailsToolbarProps {
219
221
  }) => void;
220
222
  onInvertSwapButtonClick?: () => void;
221
223
  onFeeButtonClick?: () => void;
222
- isFlipButtonDisabled?: boolean;
223
- flipButtonDisabledMessage?: string;
224
+ flipButton?: {
225
+ disabledMessage: string;
226
+ isDisabled: boolean;
227
+ tooltipDisplayDelayMs: number;
228
+ };
224
229
  feeInUsd?: string;
225
230
  estimatedTime?: string;
226
231
  canToggleBoostMode?: boolean;
@@ -233,7 +238,7 @@ interface DetailsToolbarProps {
233
238
  };
234
239
  boostTooltipDisplayDelayMs?: number;
235
240
  }
236
- 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;
237
242
 
238
243
  interface DropdownMenuItemProps {
239
244
  label: string;
@@ -277,7 +282,7 @@ interface ListItemProps extends React.HTMLAttributes<HTMLButtonElement> {
277
282
  rounded?: boolean;
278
283
  detailButtonClassName?: string;
279
284
  loading?: {
280
- subtitle?: boolean;
285
+ subtitle?: boolean | string;
281
286
  };
282
287
  containerProps?: React.HTMLAttributes<HTMLLIElement>;
283
288
  }
@@ -464,8 +469,9 @@ interface SwapConfigurationProps {
464
469
  };
465
470
  criticalPriceImpactPercentage?: number;
466
471
  emptyAddressLabel?: string;
472
+ assetsButtonVariant?: AssetsButtonVariant;
467
473
  }
468
- 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;
469
475
 
470
476
  interface SwapProgressViewHeaderProps {
471
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.1",
8
+ "version": "0.17.0",
9
9
  "author": "",
10
10
  "license": "MIT",
11
11
  "resolutions": {