@0xsquid/ui 0.15.3 → 0.15.5

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.
Files changed (27) hide show
  1. package/dist/cjs/index.js +106 -47
  2. package/dist/cjs/types/components/layout/SwapStepsCollapsed.d.ts +6 -0
  3. package/dist/cjs/types/components/lists/ListItem.d.ts +2 -1
  4. package/dist/cjs/types/components/lists/SwapStepItem.d.ts +1 -0
  5. package/dist/cjs/types/components/views/SwapProgressView.d.ts +3 -1
  6. package/dist/cjs/types/services/internal/colorService.d.ts +2 -2
  7. package/dist/cjs/types/stories/layout/SwapStepsCollapsed.stories.d.ts +1 -0
  8. package/dist/cjs/types/stories/lists/ListItem.stories.d.ts +4 -1
  9. package/dist/cjs/types/stories/lists/SwapStepItem.stories.d.ts +2 -0
  10. package/dist/cjs/types/stories/views/SwapProgressView.stories.d.ts +1 -0
  11. package/dist/cjs/types/types/components.d.ts +5 -1
  12. package/dist/cjs/types/types/config.d.ts +0 -6
  13. package/dist/esm/index.js +107 -49
  14. package/dist/esm/types/components/layout/SwapStepsCollapsed.d.ts +6 -0
  15. package/dist/esm/types/components/lists/ListItem.d.ts +2 -1
  16. package/dist/esm/types/components/lists/SwapStepItem.d.ts +1 -0
  17. package/dist/esm/types/components/views/SwapProgressView.d.ts +3 -1
  18. package/dist/esm/types/services/internal/colorService.d.ts +2 -2
  19. package/dist/esm/types/stories/layout/SwapStepsCollapsed.stories.d.ts +1 -0
  20. package/dist/esm/types/stories/lists/ListItem.stories.d.ts +4 -1
  21. package/dist/esm/types/stories/lists/SwapStepItem.stories.d.ts +2 -0
  22. package/dist/esm/types/stories/views/SwapProgressView.stories.d.ts +1 -0
  23. package/dist/esm/types/types/components.d.ts +5 -1
  24. package/dist/esm/types/types/config.d.ts +0 -6
  25. package/dist/index.css +33 -17
  26. package/dist/index.d.ts +17 -10
  27. package/package.json +1 -1
package/dist/cjs/index.js CHANGED
@@ -2570,8 +2570,25 @@ const mainImageSizeClassMap = {
2570
2570
  sm: 'tw-w-8 tw-h-8',
2571
2571
  md: 'tw-w-10 tw-h-10',
2572
2572
  };
2573
+ const loadingSkeletonClassName = 'tw-bg-grey-500';
2573
2574
  function BadgeImage({ imageUrl, badgeUrl, size = 'sm', extraMarginForBadge, rounded = false, }) {
2574
- return imageUrl ? (jsxRuntime.jsxs("div", { className: cn('tw-relative', extraMarginForBadge && badgeUrl ? 'tw-mr-1.5' : null, mainImageSizeClassMap[size]), children: [jsxRuntime.jsx("img", { src: imageUrl, alt: "", className: cn('tw-h-full tw-w-full', rounded ? ' tw-rounded-full' : 'tw-rounded-squid-xs') }), badgeUrl ? (jsxRuntime.jsx("img", { src: badgeUrl, alt: "", className: cn('tw-absolute -tw-right-1/3 tw-bottom-0 tw-z-10 tw-m-0 -tw-translate-x-1/3 tw-rounded-md tw-border-[1px] tw-border-grey-800', badgeSizeClassMap[size]) })) : null] })) : null;
2575
+ const [imagesLoadState, setImageLoadState] = React.useState({
2576
+ badgeLoaded: false,
2577
+ mainImageLoaded: false,
2578
+ });
2579
+ const badgeImageClassName = cn('tw-absolute -tw-right-1/3 tw-bottom-0 tw-z-10 tw-m-0 -tw-translate-x-1/3 tw-rounded-md tw-border-[1px] tw-border-grey-800', badgeSizeClassMap[size]);
2580
+ const mainImageClassName = cn('tw-h-full tw-w-full tw-absolute', rounded ? ' tw-rounded-full' : 'tw-rounded-squid-xs');
2581
+ return imageUrl ? (jsxRuntime.jsxs("div", { className: cn('tw-relative', extraMarginForBadge && badgeUrl ? 'tw-mr-1.5' : null, mainImageSizeClassMap[size]), children: [!imagesLoadState.mainImageLoaded && (jsxRuntime.jsx("div", { className: cn(mainImageClassName, loadingSkeletonClassName) })), jsxRuntime.jsx("img", { src: imageUrl, alt: "", onLoad: () => {
2582
+ // update state when image is fully loaded
2583
+ setImageLoadState((prevState) => (Object.assign(Object.assign({}, prevState), { mainImageLoaded: true })));
2584
+ }, className: cn(mainImageClassName,
2585
+ // hide main image while it is loading, and display it when it is loaded
2586
+ imagesLoadState.mainImageLoaded ? 'tw-block' : 'tw-hidden') }), badgeUrl ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [!imagesLoadState.badgeLoaded && (jsxRuntime.jsx("div", { className: cn(badgeImageClassName, loadingSkeletonClassName) })), jsxRuntime.jsx("img", { src: badgeUrl, alt: "", onLoad: () => {
2587
+ // update state when badge image is fully loaded
2588
+ setImageLoadState((prevState) => (Object.assign(Object.assign({}, prevState), { badgeLoaded: true })));
2589
+ }, className: cn(badgeImageClassName,
2590
+ // hide badge image while it is loading, and display it when it is loaded
2591
+ imagesLoadState.mainImageLoaded ? 'tw-block' : 'tw-hidden') })] })) : null] })) : null;
2575
2592
  }
2576
2593
 
2577
2594
  function LoadingSkeleton({ className, height = '20', }) {
@@ -6631,8 +6648,9 @@ const listItemSizeMap = {
6631
6648
  small: 'tw-h-list-item-small tw-px-squid-xs',
6632
6649
  large: 'tw-h-list-item-large tw-px-squid-xs',
6633
6650
  };
6651
+ const subtitleClassName = 'tw-h-[14px] tw-max-w-full tw-truncate !tw-leading-[16px] tw-text-grey-500';
6634
6652
  function ListItem(_a) {
6635
- var { itemTitle, mainImageUrl, subtitle, detail, icon, secondaryImageUrl, size = 'large', mainIcon, className, isSelected, onDetailClick, showDetailOnHoverOnly, rounded = false, detailButtonClassName, loading, containerProps } = _a, props = __rest(_a, ["itemTitle", "mainImageUrl", "subtitle", "detail", "icon", "secondaryImageUrl", "size", "mainIcon", "className", "isSelected", "onDetailClick", "showDetailOnHoverOnly", "rounded", "detailButtonClassName", "loading", "containerProps"]);
6653
+ var { itemTitle, mainImageUrl, subtitle, subtitleOnHover, detail, icon, secondaryImageUrl, size = 'large', mainIcon, className, isSelected, onDetailClick, showDetailOnHoverOnly, rounded = false, detailButtonClassName, loading, containerProps } = _a, props = __rest(_a, ["itemTitle", "mainImageUrl", "subtitle", "subtitleOnHover", "detail", "icon", "secondaryImageUrl", "size", "mainIcon", "className", "isSelected", "onDetailClick", "showDetailOnHoverOnly", "rounded", "detailButtonClassName", "loading", "containerProps"]);
6636
6654
  // 'small' variant does not have detail
6637
6655
  const showDetail = size === 'large' && (!!detail || !!icon || showDetailOnHoverOnly);
6638
6656
  const isDetailInteractive = !!onDetailClick;
@@ -6652,7 +6670,7 @@ function ListItem(_a) {
6652
6670
  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',
6653
6671
  // 'large' variant has extra padding
6654
6672
  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' &&
6655
- ((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.jsx(CaptionText, { className: "tw-h-[14px] tw-max-w-full tw-truncate !tw-leading-[16px] tw-text-grey-500", children: 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
6673
+ ((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: [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
6656
6674
  ? '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'
6657
6675
  : '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] })))] })) })));
6658
6676
  }
@@ -6697,6 +6715,7 @@ function SwapStepSeparator() {
6697
6715
  return (jsxRuntime.jsx("span", { className: "tw-flex tw-h-squid-m tw-w-squid-xxl tw-items-center tw-justify-center tw-self-stretch tw-py-0.5", children: jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "4", height: "21", viewBox: "0 0 4 21", fill: "none", children: jsxRuntime.jsx("path", { d: "M2 2.5V18.5", stroke: "currentColor", "stroke-width": "4", "stroke-linecap": "round" }) }) }));
6698
6716
  }
6699
6717
 
6718
+ const STEP_ITEM_HEIGHT = 52;
6700
6719
  const statusBgClassMap = {
6701
6720
  executed: '!tw-bg-grey-300',
6702
6721
  ongoing: '!tw-bg-grey-300',
@@ -6748,22 +6767,26 @@ function SwapStepItem({ descriptionBlocks, showStepSeparator = false, link, stat
6748
6767
  return 'tw-text-grey-300';
6749
6768
  }
6750
6769
  }, [status]);
6751
- return (jsxRuntime.jsxs("li", { className: "tw-flex tw-w-list-item-large tw-flex-col tw-items-start tw-text-grey-300 tw-transition-colors tw-duration-1000", children: [jsxRuntime.jsxs("a", { href: link, target: "_blank", style: transitionStyle, className: cn('tw-group/swap-step-item tw-flex tw-w-full tw-items-center tw-rounded-squid-xs', !!link && 'hover:tw-bg-material-light-thin', statusTextClass), children: [jsxRuntime.jsx("span", { className: "tw-relative tw-flex tw-min-h-squid-l tw-items-center tw-justify-center tw-gap-squid-xxs tw-px-squid-xs", children: jsxRuntime.jsx(Chip, { style: transitionStyle, className: cn('tw-w-squid-xl', statusBgClassMap[status]), icon: chipContent }) }), jsxRuntime.jsx("div", { className: "tw-flex tw-min-h-squid-l tw-flex-1 tw-flex-wrap tw-items-center tw-justify-start tw-gap-squid-xxs tw-py-squid-xxs", children: descriptionBlocks.map(({ type, value }, index) => {
6752
- if (type === 'string') {
6753
- return (
6754
- // Instead of displaying the string into a single <BodyText />
6755
- // we split it into multiple <BodyText />
6756
- // for edge case where the string is too long to fit in one line
6757
- value
6758
- .trim()
6759
- .split(' ')
6760
- .map((word, i) => (jsxRuntime.jsx(BodyText, { size: "small", className: "!tw-leading-[13px]", children: word }, i))));
6761
- }
6762
- else if (type === 'image') {
6763
- return (jsxRuntime.jsx("img", { src: value, className: "tw-h-squid-m tw-w-squid-m tw-rounded-squid-xxs" }, index));
6764
- }
6765
- return null;
6766
- }) })] }), showStepSeparator && (jsxRuntime.jsx("span", { className: cn(separatorClassMap[status]), style: transitionStyle, children: jsxRuntime.jsx(SwapStepSeparator, {}) }))] }));
6770
+ return (jsxRuntime.jsx("li", { style: {
6771
+ maxHeight: `${STEP_ITEM_HEIGHT}px`,
6772
+ minHeight: `${STEP_ITEM_HEIGHT}px`,
6773
+ }, className: "tw-relative tw-flex tw-w-list-item-large tw-flex-col tw-items-start tw-justify-center tw-text-grey-300 tw-transition-colors tw-duration-1000", children: jsxRuntime.jsxs("a", { href: link, target: "_blank", style: Object.assign(Object.assign({}, transitionStyle), { maxHeight: `${STEP_ITEM_HEIGHT}px` }), className: cn('tw-group/swap-step-item tw-flex tw-w-full tw-items-center tw-rounded-squid-xs tw-py-squid-xxs', !!link && 'hover:tw-bg-material-light-thin', statusTextClass), children: [jsxRuntime.jsxs("span", { className: "tw-relative tw-flex tw-min-h-squid-l tw-items-center tw-justify-center tw-gap-squid-xxs tw-px-squid-xs", children: [jsxRuntime.jsx(Chip, { style: transitionStyle, className: cn('tw-w-squid-xl', statusBgClassMap[status]), icon: chipContent }), showStepSeparator && (jsxRuntime.jsx("span", { className: cn(separatorClassMap[status], 'tw-absolute tw-left-0 tw-top-full tw-mt-0.5'), style: transitionStyle, children: jsxRuntime.jsx(SwapStepSeparator, {}) }))] }), jsxRuntime.jsx("div", { className: "tw-flex tw-min-h-squid-l tw-flex-1 tw-flex-wrap tw-items-center tw-justify-start tw-gap-squid-xxs tw-py-squid-xxs tw-pr-squid-xs", children: descriptionBlocks.map((block, index) => {
6774
+ const { type, value } = block;
6775
+ if (type === 'string') {
6776
+ return (
6777
+ // Instead of displaying the string into a single <BodyText />
6778
+ // we split it into multiple <BodyText />
6779
+ // for edge case where the string is too long to fit in one line
6780
+ value
6781
+ .trim()
6782
+ .split(' ')
6783
+ .map((word, i) => (jsxRuntime.jsx(BodyText, { size: "small", className: "!tw-leading-[13px]", children: word }, i))));
6784
+ }
6785
+ else if (type === 'image') {
6786
+ return (jsxRuntime.jsx("img", { src: value, className: cn('tw-h-squid-m tw-w-squid-m', block.rounded ? 'tw-rounded-full' : 'tw-rounded-squid-xxs') }, index));
6787
+ }
6788
+ return null;
6789
+ }) })] }) }));
6767
6790
  }
6768
6791
 
6769
6792
  const borderRadiusClassMap = {
@@ -6878,8 +6901,10 @@ function SwapProgressViewHeader({ title, description, }) {
6878
6901
  return (jsxRuntime.jsxs("header", { className: "tw-flex tw-h-[95px] tw-w-full tw-flex-col tw-gap-squid-s tw-bg-grey-800 tw-px-squid-m tw-py-squid-s", children: [jsxRuntime.jsx(BodyText, { size: "large", className: "tw-h-squid-m !tw-leading-[20px] tw-text-grey-300", children: title }), jsxRuntime.jsx(CaptionText, { className: "tw-h-squid-l tw-text-grey-500", children: description })] }));
6879
6902
  }
6880
6903
 
6881
- const SwapStepsCollapsed = React.forwardRef(({ steps, currentStepIndex: _newStepIndex, onOpen, onClose }, ref) => {
6882
- const newStepIndex = Math.round(_newStepIndex);
6904
+ const STEPS_LIST_HEIGHT = 400;
6905
+ const SwapStepsCollapsed = React.forwardRef((props, ref) => {
6906
+ const { steps, currentStepIndex: _newStepIndex, onOpen, onClose, footerButton, } = props;
6907
+ const newStepIndex = Math.round(_newStepIndex < 0 ? 0 : _newStepIndex);
6883
6908
  React.useImperativeHandle(ref, () => ({
6884
6909
  handleToggleRouteSteps,
6885
6910
  }));
@@ -6899,6 +6924,16 @@ const SwapStepsCollapsed = React.forwardRef(({ steps, currentStepIndex: _newStep
6899
6924
  clearTimeout(timeoutId);
6900
6925
  };
6901
6926
  }, [isShowRouteAnimationRunning]);
6927
+ React.useEffect(() => {
6928
+ var _a;
6929
+ if (!isRouteVisible)
6930
+ return;
6931
+ // scroll in the steps list so the current step is visible at the middle
6932
+ (_a = routeStepsListRef.current) === null || _a === void 0 ? void 0 : _a.scrollTo({
6933
+ top: -((newStepIndex - 1) * STEP_ITEM_HEIGHT) + STEPS_LIST_HEIGHT / 2,
6934
+ behavior: 'smooth',
6935
+ });
6936
+ }, [newStepIndex]);
6902
6937
  const routeStepsListRef = React.useRef(null);
6903
6938
  const handleToggleRouteSteps = () => {
6904
6939
  if (isRouteVisible) {
@@ -6929,9 +6964,13 @@ const SwapStepsCollapsed = React.forwardRef(({ steps, currentStepIndex: _newStep
6929
6964
  }, onClick: handleToggleRouteSteps, className: "tw-absolute tw-inset-0 tw-h-[60px] tw-cursor-pointer tw-rounded-squid-l tw-border tw-border-material-light-thin" }), jsxRuntime.jsx("div", { onClick: isShowRouteAnimationRunning ? undefined : handleToggleRouteSteps, style: {
6930
6965
  [CSS_VARS.COLLAPSE_ROUTE_DURATION]: `${ANIMATION_DURATIONS.HIDE_ROUTE}ms`,
6931
6966
  [CSS_VARS.EXPAND_ROUTE_DURATION]: `${ANIMATION_DURATIONS.SHOW_ROUTE}ms`,
6932
- }, className: cn('tw-relative tw-h-[60px] tw-max-h-[535px] tw-w-full tw-overflow-hidden tw-rounded-squid-l tw-border tw-border-material-light-thin tw-bg-grey-800 tw-backdrop-blur-2xl', isShowRouteAnimationRunning
6933
- ? 'tw-animate-expand-route'
6934
- : 'tw-animate-collapse-route'), children: jsxRuntime.jsxs("div", { className: "tw-flex tw-max-h-[535px] tw-grow-0 tw-flex-col tw-gap-squid-xxs tw-pt-[52px]", style: {
6967
+ }, className: cn('tw-relative tw-h-[60px] tw-max-h-[535px] tw-w-full tw-overflow-hidden tw-rounded-squid-l tw-border tw-border-material-light-thin tw-bg-grey-800 tw-backdrop-blur-2xl', isRouteVisible &&
6968
+ (isShowRouteAnimationRunning
6969
+ ? 'tw-animate-expand-route'
6970
+ : 'tw-animate-collapse-route')), children: jsxRuntime.jsxs("div", { className: cn('tw-flex tw-flex-col tw-gap-squid-xxs', isRouteVisible || isShowRouteAnimationRunning
6971
+ ? 'tw-max-h-[535px]'
6972
+ : ''), style: {
6973
+ paddingTop: `${STEP_ITEM_HEIGHT}px`,
6935
6974
  transition: isShowRouteAnimationRunning
6936
6975
  ? `transform ${ANIMATION_DURATIONS.SHOW_ROUTE}ms ${ANIMATION_TIMINGS.CHANGE_SWAP_STEP}`
6937
6976
  : isRouteVisible
@@ -6939,13 +6978,16 @@ const SwapStepsCollapsed = React.forwardRef(({ steps, currentStepIndex: _newStep
6939
6978
  : `transform ${ANIMATION_DURATIONS.CHANGE_SWAP_STEP}ms ${ANIMATION_TIMINGS.CHANGE_SWAP_STEP}`,
6940
6979
  transform: isShowRouteAnimationRunning
6941
6980
  ? 'translateY(0)'
6942
- : `translateY(calc(-100% + 85px + ${(newStepIndex + 1) * 50}px))`,
6943
- }, children: [jsxRuntime.jsx("div", { className: cn('tw-absolute tw-top-0 tw-z-10 tw-flex tw-h-[52px] tw-w-full tw-items-center tw-justify-center tw-gap-squid-xs tw-self-stretch tw-bg-transparent tw-p-squid-xs'), children: jsxRuntime.jsx("button", { onClick: handleToggleRouteSteps, className: "tw-flex tw-h-squid-xl tw-w-40 tw-items-center tw-justify-center tw-rounded-squid-xs tw-px-10 hover:tw-bg-material-light-thin", children: jsxRuntime.jsx("span", { className: "tw-flex tw-h-8 tw-w-8 tw-items-center tw-justify-center tw-text-grey-300", children: jsxRuntime.jsx(ChevronLargeDownIcon, { size: "32" }) }) }) }), jsxRuntime.jsx("ul", { ref: routeStepsListRef, style: {
6981
+ : `translateY(calc(-100% + 69px + ${(newStepIndex + 1) * STEP_ITEM_HEIGHT}px))`,
6982
+ }, children: [jsxRuntime.jsx("div", { style: {
6983
+ display: isRouteVisible ? 'flex' : 'none',
6984
+ height: `${STEP_ITEM_HEIGHT}px`,
6985
+ }, className: cn('tw-absolute tw-top-0 tw-z-10 tw-flex tw-w-full tw-items-center tw-justify-center tw-gap-squid-xs tw-self-stretch tw-bg-grey-800 tw-p-squid-xs'), children: jsxRuntime.jsx("button", { onClick: handleToggleRouteSteps, className: "tw-flex tw-h-squid-xl tw-w-40 tw-items-center tw-justify-center tw-rounded-squid-xs tw-px-10 hover:tw-bg-material-light-thin", children: jsxRuntime.jsx("span", { className: "tw-flex tw-h-8 tw-w-8 tw-items-center tw-justify-center tw-text-grey-300", children: jsxRuntime.jsx(ChevronLargeDownIcon, { size: "32" }) }) }) }), jsxRuntime.jsx("ul", { ref: routeStepsListRef, style: {
6944
6986
  zIndex: isRouteVisible ? 0 : -10,
6945
6987
  scrollbarWidth: 'none',
6946
- }, className: "tw-relative tw-flex tw-max-h-[413px] tw-w-[400px] tw-flex-1 tw-grow-0 tw-flex-col-reverse tw-items-center tw-self-stretch tw-overflow-y-auto tw-overflow-x-hidden tw-px-squid-xs tw-py-[15px]", children: steps.map((step, index) => (jsxRuntime.jsx(SwapStepItem, { descriptionBlocks: step.descriptionBlocks,
6988
+ }, className: "tw-relative tw-flex tw-w-[400px] tw-flex-1 tw-grow-0 tw-flex-col-reverse tw-items-center tw-self-stretch tw-overflow-y-auto tw-overflow-x-hidden tw-px-squid-xs tw-pb-squid-xxs", children: steps.map((step, index) => (jsxRuntime.jsx(SwapStepItem, { descriptionBlocks: step.descriptionBlocks,
6947
6989
  // show separator for all steps except the first one
6948
- showStepSeparator: index > 0, link: step.link, status: newStepIndex < index ? 'pending' : step.status }, index))) }), jsxRuntime.jsx("footer", { className: "tw-flex tw-w-full tw-items-end tw-justify-center tw-gap-squid-xs tw-self-stretch tw-p-squid-s", children: jsxRuntime.jsx(Button, { size: "md", variant: "secondary", label: "View on Squidscan", className: "tw-w-full" }) })] }) })] }) }) }));
6990
+ showStepSeparator: index > 0, link: step.link, status: newStepIndex < index ? 'pending' : step.status }, index))) }), jsxRuntime.jsx("footer", { className: "tw-flex tw-max-h-[55px] tw-min-h-[55px] tw-w-full tw-justify-center tw-gap-squid-xs tw-self-stretch tw-px-squid-s tw-pb-squid-s", children: jsxRuntime.jsx(Button, { size: "md", variant: "secondary", onClick: footerButton === null || footerButton === void 0 ? void 0 : footerButton.onClick, link: footerButton === null || footerButton === void 0 ? void 0 : footerButton.link, label: footerButton === null || footerButton === void 0 ? void 0 : footerButton.label, className: "tw-w-full" }) })] }) })] }) }) }));
6949
6991
  });
6950
6992
 
6951
6993
  function TokenPair({ firstToken, secondToken }) {
@@ -42247,7 +42289,7 @@ const swapProgressButtonTexts = {
42247
42289
  [SwapState.PARTIAL_SUCCESS]: 'Cancel',
42248
42290
  [SwapState.NEEDS_GAS]: 'Go to Axelarscan',
42249
42291
  };
42250
- function SwapProgressView({ steps, isOpen = true, handleClose, handleComplete, socialLink, supportLink, fromAmount, fromChain, fromToken, toAmount, toChain, toToken, fromAddressFormatted, toAddressFormatted, swapState, estimatedTimeToComplete, }) {
42292
+ function SwapProgressView({ steps, isOpen = true, handleClose, handleComplete, socialLink, supportLink, fromAmount, fromChain, fromToken, toAmount, toChain, toToken, fromAddressFormatted, toAddressFormatted, swapState, estimatedTimeToComplete, footerButton, }) {
42251
42293
  const [showSwapInfoSection, setShowSwapInfoSection] = React.useState(true);
42252
42294
  const isFirstRenderRef = React.useRef(true);
42253
42295
  const { timer, stopTimer, startTimer } = useTimer({
@@ -42305,9 +42347,10 @@ function SwapProgressView({ steps, isOpen = true, handleClose, handleComplete, s
42305
42347
  }, secondToken: {
42306
42348
  bgColor: toToken.bgColor,
42307
42349
  imageUrl: toToken.logoUrl,
42308
- } })) }), jsxRuntime.jsx(SwapProgressViewHeader, { title: headerTitle, description: headerDescription }), jsxRuntime.jsxs("ul", { className: "tw-flex tw-h-[195px] tw-w-full tw-flex-col tw-items-center tw-justify-center tw-gap-squid-xxs tw-rounded-squid-l tw-py-squid-s", children: [jsxRuntime.jsx(SwapDetailListItem, { icon: jsxRuntime.jsx(ArrowsSwapIcon, {}), label: "Swap", detail: jsxRuntime.jsx(SwapDetailItemValues, { fromContent: jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("img", { className: "tw-h-squid-m tw-w-squid-m tw-rounded-full", src: fromToken.logoUrl }), jsxRuntime.jsx(CaptionText, { children: fromAmount })] }), toContent: jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("img", { className: "tw-h-squid-m tw-w-squid-m tw-rounded-full", src: toToken.logoUrl }), jsxRuntime.jsx(CaptionText, { children: toAmount })] }) }) }), jsxRuntime.jsx(SwapDetailListItem, { icon: jsxRuntime.jsx(ChainLink, { size: "24", strokeWidth: "1.5" }), label: "Chain", detail: jsxRuntime.jsx(SwapDetailItemValues, { fromContent: jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("img", { className: "tw-h-squid-m tw-w-squid-m tw-rounded-squid-xxs", src: fromChain.logoUrl }), jsxRuntime.jsx(CaptionText, { children: fromChain.networkName })] }), toContent: jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("img", { className: "tw-h-squid-m tw-w-squid-m tw-rounded-squid-xxs", src: toChain.logoUrl }), jsxRuntime.jsx(CaptionText, { children: toChain.networkName })] }) }) }), jsxRuntime.jsx(SwapDetailListItem, { icon: jsxRuntime.jsx(WalletFilledIcon, { size: "24" }), label: "Wallet", detail: jsxRuntime.jsx(SwapDetailItemValues, { fromContent: fromAddressFormatted, toContent: toAddressFormatted }) }), jsxRuntime.jsx(SwapDetailListItem, { icon: jsxRuntime.jsx(TimeFliesIcon, {}), label: "Time to complete", detail: swapState === SwapState.PROGRESS ? (jsxRuntime.jsx(SwapDetailItemValues, { fromContent: timer, toContent: estimatedTimeToComplete })) : swapState === SwapState.COMPLETED ? (jsxRuntime.jsx(CaptionText, { children: timer })) : (jsxRuntime.jsx(CaptionText, { children: estimatedTimeToComplete })) })] })] }), jsxRuntime.jsx(TrackTransactionView, { ref: trackTransactionViewRef, onTxEnd: () => stopTimer(), onTxStart: () => startTimer(), rawSteps: steps, onClose: handleRouteStepsClosed, onOpen: handleRouteStepsOpen, swapState: swapState }), !showSwapInfoSection ? (jsxRuntime.jsx(Button, { size: "lg", variant: "primary", label: "Cancel", onClick: handleCollapseRouteSteps, className: "tw-min-h-button" })) : swapState === SwapState.PARTIAL_SUCCESS ? (jsxRuntime.jsxs("div", { className: "tw-flex tw-w-full tw-items-center tw-gap-squid-xxs", children: [jsxRuntime.jsx(Button, { size: "lg", variant: "secondary", label: swapProgressButtonTexts[swapState], onClick: handleClose, className: "tw-min-h-button" }), jsxRuntime.jsx(Button, { size: "lg", variant: "primary", label: "Complete", onClick: handleComplete, className: "tw-min-h-button" })] })) : (jsxRuntime.jsx(Button, { size: "lg", variant: "primary", label: swapProgressButtonTexts[swapState], onClick: handleClose, className: "tw-min-h-button" }))] }));
42350
+ } })) }), jsxRuntime.jsx(SwapProgressViewHeader, { title: headerTitle, description: headerDescription }), jsxRuntime.jsxs("ul", { className: "tw-flex tw-h-[195px] tw-w-full tw-flex-col tw-items-center tw-justify-center tw-gap-squid-xxs tw-rounded-squid-l tw-py-squid-s", children: [jsxRuntime.jsx(SwapDetailListItem, { icon: jsxRuntime.jsx(ArrowsSwapIcon, {}), label: "Swap", detail: jsxRuntime.jsx(SwapDetailItemValues, { fromContent: jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("img", { className: "tw-h-squid-m tw-w-squid-m tw-rounded-full", src: fromToken.logoUrl }), jsxRuntime.jsx(CaptionText, { children: fromAmount })] }), toContent: jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("img", { className: "tw-h-squid-m tw-w-squid-m tw-rounded-full", src: toToken.logoUrl }), jsxRuntime.jsx(CaptionText, { children: toAmount })] }) }) }), jsxRuntime.jsx(SwapDetailListItem, { icon: jsxRuntime.jsx(ChainLink, { size: "24", strokeWidth: "1.5" }), label: "Chain", detail: jsxRuntime.jsx(SwapDetailItemValues, { fromContent: jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("img", { className: "tw-h-squid-m tw-w-squid-m tw-rounded-squid-xxs", src: fromChain.logoUrl }), jsxRuntime.jsx(CaptionText, { children: fromChain.networkName })] }), toContent: jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("img", { className: "tw-h-squid-m tw-w-squid-m tw-rounded-squid-xxs", src: toChain.logoUrl }), jsxRuntime.jsx(CaptionText, { children: toChain.networkName })] }) }) }), jsxRuntime.jsx(SwapDetailListItem, { icon: jsxRuntime.jsx(WalletFilledIcon, { size: "24" }), label: "Wallet", detail: jsxRuntime.jsx(SwapDetailItemValues, { fromContent: fromAddressFormatted, toContent: toAddressFormatted }) }), jsxRuntime.jsx(SwapDetailListItem, { icon: jsxRuntime.jsx(TimeFliesIcon, {}), label: "Time to complete", detail: swapState === SwapState.PROGRESS ? (jsxRuntime.jsx(SwapDetailItemValues, { fromContent: timer, toContent: estimatedTimeToComplete })) : swapState === SwapState.COMPLETED ? (jsxRuntime.jsx(CaptionText, { children: timer })) : (jsxRuntime.jsx(CaptionText, { children: estimatedTimeToComplete })) })] })] }), jsxRuntime.jsx(TrackTransactionView, { ref: trackTransactionViewRef, onTxEnd: () => stopTimer(), onTxStart: () => startTimer(), rawSteps: steps, onClose: handleRouteStepsClosed, onOpen: handleRouteStepsOpen, swapState: swapState, footerButton: footerButton }), !showSwapInfoSection ? (jsxRuntime.jsx(Button, { size: "lg", variant: "primary", label: "Cancel", onClick: handleCollapseRouteSteps, className: "tw-min-h-button" })) : swapState === SwapState.PARTIAL_SUCCESS ? (jsxRuntime.jsxs("div", { className: "tw-flex tw-w-full tw-items-center tw-gap-squid-xxs", children: [jsxRuntime.jsx(Button, { size: "lg", variant: "secondary", label: swapProgressButtonTexts[swapState], onClick: handleClose, className: "tw-min-h-button" }), jsxRuntime.jsx(Button, { size: "lg", variant: "primary", label: "Complete", onClick: handleComplete, className: "tw-min-h-button" })] })) : (jsxRuntime.jsx(Button, { size: "lg", variant: "primary", label: swapProgressButtonTexts[swapState], onClick: handleClose, className: "tw-min-h-button" }))] }));
42309
42351
  }
42310
- const TrackTransactionView = React.forwardRef(({ swapState, rawSteps, onOpen, onClose, onTxStart, onTxEnd }, ref) => {
42352
+ const TrackTransactionView = React.forwardRef((props, ref) => {
42353
+ const { swapState, rawSteps, onOpen, onClose, onTxStart, onTxEnd, footerButton, } = props;
42311
42354
  const { currentStepIndex, steps } = React.useMemo(() => {
42312
42355
  if (swapState === SwapState.COMPLETED) {
42313
42356
  onTxEnd();
@@ -42341,12 +42384,19 @@ const TrackTransactionView = React.forwardRef(({ swapState, rawSteps, onOpen, on
42341
42384
  currentStepIndex: rawSteps.length - 1,
42342
42385
  };
42343
42386
  }
42387
+ if (swapState === SwapState.ERROR) {
42388
+ const firstErrorStepIndex = rawSteps.findIndex((s) => s.status === 'error');
42389
+ return {
42390
+ steps: rawSteps,
42391
+ currentStepIndex: firstErrorStepIndex,
42392
+ };
42393
+ }
42344
42394
  return {
42345
42395
  steps: rawSteps,
42346
42396
  currentStepIndex: 0,
42347
42397
  };
42348
42398
  }, [swapState, rawSteps]);
42349
- return rawSteps.length > 0 ? (jsxRuntime.jsx(SwapStepsCollapsed, { ref: ref, steps: steps, currentStepIndex: currentStepIndex, onClose: onClose, onOpen: onOpen })) : null;
42399
+ return rawSteps.length > 0 ? (jsxRuntime.jsx(SwapStepsCollapsed, { ref: ref, steps: steps, currentStepIndex: currentStepIndex, onClose: onClose, onOpen: onOpen, footerButton: footerButton })) : null;
42350
42400
  });
42351
42401
  const SwapDetailItemValues = ({ fromContent, toContent, }) => {
42352
42402
  return (jsxRuntime.jsxs("div", { className: "tw-flex tw-items-center tw-justify-center tw-gap-squid-xxs", children: [typeof fromContent === 'string' ? (jsxRuntime.jsx(CaptionText, { children: fromContent })) : (fromContent), jsxRuntime.jsx("span", { className: "tw-text-grey-500", children: jsxRuntime.jsx(ChevronLargeRightIcon, {}) }), typeof toContent === 'string' ? (jsxRuntime.jsx(CaptionText, { children: toContent })) : (toContent)] }));
@@ -42373,15 +42423,11 @@ const lightTheme = {
42373
42423
  'status-positive': '#11D421',
42374
42424
  'status-negative': '#FF5B4D',
42375
42425
  'status-warning': '#EC9213',
42376
- // transparent
42377
- 'transparent-light-thin': '#17191C1A', // 10% opacity
42378
- 'transparent-light-average': '#17191C54', // 33% opacity
42379
- 'transparent-light-thick': '#17191CA8', // 66% opacity
42380
- 'transparent-dark-thin': '#FBFBFD1A', // 10% opacity
42381
- 'transparent-dark-average': '#FBFCFD54', // 33% opacity
42382
- 'transparent-dark-thick': '#FBFCFDA8', // 66% opacity
42383
42426
  };
42384
42427
 
42428
+ // list of the theme variables that need to be replaced
42429
+ // from the user readable theme config
42430
+ // to the internal theme config
42385
42431
  const themeKeysToReplace = [
42386
42432
  {
42387
42433
  userKey: 'content',
@@ -42391,24 +42437,20 @@ const themeKeysToReplace = [
42391
42437
  userKey: 'accent',
42392
42438
  internalKey: 'royal',
42393
42439
  },
42394
- {
42395
- userKey: 'transparent',
42396
- internalKey: 'material',
42397
- },
42398
42440
  {
42399
42441
  userKey: 'status-warning',
42400
42442
  internalKey: 'status-partial',
42401
42443
  },
42402
42444
  ];
42403
42445
  /**
42404
- * Parsing the user readable config to css variables
42446
+ * Parses the user readable config to css variables
42405
42447
  * Also maps the public theme variables to the internal theme variables
42448
+ * and adds the material-* variants
42406
42449
  * example user theme:
42407
42450
  * {
42408
42451
  * 'content-100': '#000',
42409
42452
  * 'content-200': '#000',
42410
42453
  * 'accent-400': '#000',
42411
- * 'transparent-light-thin': '#000'
42412
42454
  * }
42413
42455
  * Resulting in:
42414
42456
  * {
@@ -42423,10 +42465,9 @@ const parseSquidTheme = (userTheme) => {
42423
42465
  var _a;
42424
42466
  if (!userTheme)
42425
42467
  return undefined;
42426
- const squidTheme = Object.entries(userTheme).reduce((internalKeys, [userKey, userValue]) => {
42468
+ let squidTheme = Object.entries(userTheme).reduce((internalKeys, [userKey, userValue]) => {
42427
42469
  // content-* -> grey-*
42428
42470
  // accent-* -> royal-*
42429
- // transparent-* -> material-*
42430
42471
  const keyToReplace = themeKeysToReplace.find((k) => userKey.includes(k.userKey));
42431
42472
  if (keyToReplace) {
42432
42473
  const newKey = userKey.replace(keyToReplace.userKey, keyToReplace.internalKey);
@@ -42437,6 +42478,23 @@ const parseSquidTheme = (userTheme) => {
42437
42478
  }
42438
42479
  return internalKeys;
42439
42480
  }, {});
42481
+ // add material-{light,dark}-{thin,average,thick} colors to the squid theme object
42482
+ // using the following formula:
42483
+ // material-light-thin -> grey-100 + 10% opacity
42484
+ // material-light-average -> grey-100 + 33% opacity
42485
+ // material-light-thick -> grey-100 + 66% opacity
42486
+ // material-dark-thin -> grey-900 + 10% opacity
42487
+ // material-dark-average -> grey-900 + 33% opacity
42488
+ // material-dark-thick -> grey-900 + 66% opacity
42489
+ const materialVariants = {
42490
+ 'material-light-thin': getHexColorFromOpacityPercentage(squidTheme['grey-100'], 0.1),
42491
+ 'material-light-average': getHexColorFromOpacityPercentage(squidTheme['grey-100'], 0.33),
42492
+ 'material-light-thick': getHexColorFromOpacityPercentage(squidTheme['grey-100'], 0.66),
42493
+ 'material-dark-thin': getHexColorFromOpacityPercentage(squidTheme['grey-900'], 0.1),
42494
+ 'material-dark-average': getHexColorFromOpacityPercentage(squidTheme['grey-900'], 0.33),
42495
+ 'material-dark-thick': getHexColorFromOpacityPercentage(squidTheme['grey-900'], 0.66),
42496
+ };
42497
+ squidTheme = Object.assign(Object.assign({}, squidTheme), materialVariants);
42440
42498
  const styleKeys = Object.keys(themeTypesKeys);
42441
42499
  const parsed = styleKeys.map((sk) => {
42442
42500
  const themeItem = themeTypesKeys[sk];
@@ -42563,6 +42621,7 @@ exports.NavigationBar = NavigationBar;
42563
42621
  exports.NumericInput = NumericInput;
42564
42622
  exports.ProductCard = ProductCard;
42565
42623
  exports.ProfileHeaderBackground = ProfileHeaderBackground;
42624
+ exports.STEP_ITEM_HEIGHT = STEP_ITEM_HEIGHT;
42566
42625
  exports.SectionTitle = SectionTitle;
42567
42626
  exports.SettingsButton = SettingsButton;
42568
42627
  exports.SettingsItem = SettingsItem;
@@ -1,10 +1,16 @@
1
1
  /// <reference types="react" />
2
2
  import { SwapStep } from '../../types/components';
3
+ export type SwapStepsCollapsedFooterButton = {
4
+ label: string;
5
+ link?: string;
6
+ onClick?: () => void;
7
+ };
3
8
  interface SwapStepsCollapsedProps {
4
9
  steps: SwapStep[];
5
10
  currentStepIndex: number;
6
11
  onOpen?: () => void;
7
12
  onClose?: () => void;
13
+ footerButton?: SwapStepsCollapsedFooterButton;
8
14
  }
9
15
  export declare const SwapStepsCollapsed: import("react").ForwardRefExoticComponent<SwapStepsCollapsedProps & import("react").RefAttributes<{
10
16
  handleToggleRouteSteps: () => void;
@@ -4,6 +4,7 @@ interface ListItemProps extends React.HTMLAttributes<HTMLButtonElement> {
4
4
  mainImageUrl?: string;
5
5
  secondaryImageUrl?: string;
6
6
  subtitle?: string;
7
+ subtitleOnHover?: React.ReactNode;
7
8
  detail?: string;
8
9
  icon?: React.ReactNode;
9
10
  size?: ListItemSize;
@@ -20,5 +21,5 @@ interface ListItemProps extends React.HTMLAttributes<HTMLButtonElement> {
20
21
  containerProps?: React.HTMLAttributes<HTMLLIElement>;
21
22
  }
22
23
  type ListItemSize = 'small' | 'large';
23
- export declare function ListItem({ itemTitle, mainImageUrl, subtitle, detail, icon, secondaryImageUrl, size, mainIcon, className, isSelected, onDetailClick, showDetailOnHoverOnly, rounded, detailButtonClassName, loading, containerProps, ...props }: ListItemProps): import("react/jsx-runtime").JSX.Element;
24
+ export declare function ListItem({ itemTitle, mainImageUrl, subtitle, subtitleOnHover, detail, icon, secondaryImageUrl, size, mainIcon, className, isSelected, onDetailClick, showDetailOnHoverOnly, rounded, detailButtonClassName, loading, containerProps, ...props }: ListItemProps): import("react/jsx-runtime").JSX.Element;
24
25
  export {};
@@ -5,5 +5,6 @@ interface SwapStepItemProps {
5
5
  link?: string;
6
6
  status?: SwapStepItemStatus;
7
7
  }
8
+ export declare const STEP_ITEM_HEIGHT = 52;
8
9
  export declare function SwapStepItem({ descriptionBlocks, showStepSeparator, link, status, }: SwapStepItemProps): import("react/jsx-runtime").JSX.Element;
9
10
  export {};
@@ -1,4 +1,5 @@
1
1
  import { SwapState, SwapStep } from '../../types/components';
2
+ import { SwapStepsCollapsedFooterButton } from '../layout/SwapStepsCollapsed';
2
3
  type ChainData = {
3
4
  networkName: string;
4
5
  logoUrl: string;
@@ -9,7 +10,7 @@ type Token = {
9
10
  logoUrl: string;
10
11
  bgColor: string;
11
12
  };
12
- export declare function SwapProgressView({ steps, isOpen, handleClose, handleComplete, socialLink, supportLink, fromAmount, fromChain, fromToken, toAmount, toChain, toToken, fromAddressFormatted, toAddressFormatted, swapState, estimatedTimeToComplete, }: {
13
+ export declare function SwapProgressView({ steps, isOpen, handleClose, handleComplete, socialLink, supportLink, fromAmount, fromChain, fromToken, toAmount, toChain, toToken, fromAddressFormatted, toAddressFormatted, swapState, estimatedTimeToComplete, footerButton, }: {
13
14
  steps: SwapStep[];
14
15
  handleClose?: () => void;
15
16
  handleComplete?: () => void;
@@ -26,5 +27,6 @@ export declare function SwapProgressView({ steps, isOpen, handleClose, handleCom
26
27
  toAddressFormatted: string;
27
28
  swapState: SwapState;
28
29
  estimatedTimeToComplete?: string;
30
+ footerButton?: SwapStepsCollapsedFooterButton;
29
31
  }): import("react/jsx-runtime").JSX.Element;
30
32
  export {};
@@ -1,13 +1,13 @@
1
1
  import { SquidTheme } from '../../types/config';
2
2
  /**
3
- * Parsing the user readable config to css variables
3
+ * Parses the user readable config to css variables
4
4
  * Also maps the public theme variables to the internal theme variables
5
+ * and adds the material-* variants
5
6
  * example user theme:
6
7
  * {
7
8
  * 'content-100': '#000',
8
9
  * 'content-200': '#000',
9
10
  * 'accent-400': '#000',
10
- * 'transparent-light-thin': '#000'
11
11
  * }
12
12
  * Resulting in:
13
13
  * {
@@ -10,3 +10,4 @@ export declare const ShortRoute: Story;
10
10
  export declare const LongRoute: Story;
11
11
  export declare const Error: Story;
12
12
  export declare const Warning: Story;
13
+ export declare const LongDescriptionSteps: Story;
@@ -9,6 +9,8 @@ export declare const LargeWithLongTitle: Story;
9
9
  export declare const LargeWithLongTitleAndSubtitle: Story;
10
10
  export declare const LargeRoundedFull: Story;
11
11
  export declare const LargeWithSubtitle: Story;
12
+ export declare const SubtitleOnHover: Story;
13
+ export declare const SubtitleOnHoverTokenBalance: Story;
12
14
  export declare const LargeWithDetail: Story;
13
15
  export declare const LargeWithIcon: Story;
14
16
  export declare const LargeWithDetailAndIconInteractive: Story;
@@ -16,7 +18,8 @@ export declare const LargeShowDetailOnHoverOnly: Story;
16
18
  export declare const LargeWithSecondaryImage: Story;
17
19
  export declare const LargeSelected: Story;
18
20
  export declare const LargeWithCustomIconAsImage: Story;
19
- export declare const LargeLoading: Story;
21
+ export declare const SubtitleLoading: Story;
22
+ export declare const ImageAndBadgeLoading: Story;
20
23
  export declare const Small: Story;
21
24
  export declare const SmallInteractive: Story;
22
25
  export declare const SmallWithLongTitle: Story;
@@ -5,6 +5,7 @@ export default meta;
5
5
  type Story = StoryObj<typeof meta>;
6
6
  export declare const Executed: Story;
7
7
  export declare const ExecutedWithSeparator: Story;
8
+ export declare const ExecutedWithSeparatorAndLink: Story;
8
9
  export declare const Success: Story;
9
10
  export declare const SuccessWithSeparator: Story;
10
11
  export declare const Pending: Story;
@@ -18,6 +19,7 @@ export declare const ErrorWithSeparator: Story;
18
19
  export declare const Warning: Story;
19
20
  export declare const WarningWithSeparator: Story;
20
21
  export declare const CustomDescription: Story;
22
+ export declare const CustomDescriptionWithRoundedImage: Story;
21
23
  export declare const CustomDescriptionWithSeparator: Story;
22
24
  export declare const Link: Story;
23
25
  export declare const LongDescription: Story;
@@ -5,6 +5,7 @@ export default meta;
5
5
  type Story = StoryObj<typeof meta>;
6
6
  export declare const WithControls: Story;
7
7
  export declare const ShortRoute: Story;
8
+ export declare const LongDescriptionSteps: Story;
8
9
  export declare const LongRoute: Story;
9
10
  export declare const Completed: Story;
10
11
  export declare const Error: Story;
@@ -5,8 +5,12 @@ export type ButtonSize = 'md' | 'lg';
5
5
  export type SwapDirection = 'from' | 'to';
6
6
  export type BoostMode = 'normal' | 'boost';
7
7
  export type SwapStepDescriptionBlock = {
8
- type: 'string' | 'image';
8
+ type: 'string';
9
9
  value: string;
10
+ } | {
11
+ type: 'image';
12
+ value: string;
13
+ rounded?: boolean;
10
14
  };
11
15
  export type SwapStep = {
12
16
  descriptionBlocks: SwapStepDescriptionBlock[];
@@ -41,12 +41,6 @@ export type SquidTheme = {
41
41
  'status-positive': string;
42
42
  'status-negative': string;
43
43
  'status-warning': string;
44
- 'transparent-light-thin': string;
45
- 'transparent-light-average': string;
46
- 'transparent-light-thick': string;
47
- 'transparent-dark-thin': string;
48
- 'transparent-dark-average': string;
49
- 'transparent-dark-thick': string;
50
44
  };
51
45
  export declare const SQUID_THEME_CSS_VARIABLE_PREFIX = "--squid-theme-";
52
46
  /**
package/dist/esm/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
- import { useMemo, useRef, useState, useEffect, useCallback, forwardRef, useImperativeHandle } from 'react';
3
+ import { useState, useMemo, useRef, useEffect, useCallback, forwardRef, useImperativeHandle } from 'react';
4
4
 
5
5
  function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f);}else for(f in e)e[f]&&(n&&(n+=" "),n+=f);return n}function clsx(){for(var e,t,f=0,n="",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n}
6
6
 
@@ -2550,8 +2550,25 @@ const mainImageSizeClassMap = {
2550
2550
  sm: 'tw-w-8 tw-h-8',
2551
2551
  md: 'tw-w-10 tw-h-10',
2552
2552
  };
2553
+ const loadingSkeletonClassName = 'tw-bg-grey-500';
2553
2554
  function BadgeImage({ imageUrl, badgeUrl, size = 'sm', extraMarginForBadge, rounded = false, }) {
2554
- return imageUrl ? (jsxs("div", { className: cn('tw-relative', extraMarginForBadge && badgeUrl ? 'tw-mr-1.5' : null, mainImageSizeClassMap[size]), children: [jsx("img", { src: imageUrl, alt: "", className: cn('tw-h-full tw-w-full', rounded ? ' tw-rounded-full' : 'tw-rounded-squid-xs') }), badgeUrl ? (jsx("img", { src: badgeUrl, alt: "", className: cn('tw-absolute -tw-right-1/3 tw-bottom-0 tw-z-10 tw-m-0 -tw-translate-x-1/3 tw-rounded-md tw-border-[1px] tw-border-grey-800', badgeSizeClassMap[size]) })) : null] })) : null;
2555
+ const [imagesLoadState, setImageLoadState] = useState({
2556
+ badgeLoaded: false,
2557
+ mainImageLoaded: false,
2558
+ });
2559
+ const badgeImageClassName = cn('tw-absolute -tw-right-1/3 tw-bottom-0 tw-z-10 tw-m-0 -tw-translate-x-1/3 tw-rounded-md tw-border-[1px] tw-border-grey-800', badgeSizeClassMap[size]);
2560
+ const mainImageClassName = cn('tw-h-full tw-w-full tw-absolute', rounded ? ' tw-rounded-full' : 'tw-rounded-squid-xs');
2561
+ return imageUrl ? (jsxs("div", { className: cn('tw-relative', extraMarginForBadge && badgeUrl ? 'tw-mr-1.5' : null, mainImageSizeClassMap[size]), children: [!imagesLoadState.mainImageLoaded && (jsx("div", { className: cn(mainImageClassName, loadingSkeletonClassName) })), jsx("img", { src: imageUrl, alt: "", onLoad: () => {
2562
+ // update state when image is fully loaded
2563
+ setImageLoadState((prevState) => (Object.assign(Object.assign({}, prevState), { mainImageLoaded: true })));
2564
+ }, className: cn(mainImageClassName,
2565
+ // hide main image while it is loading, and display it when it is loaded
2566
+ imagesLoadState.mainImageLoaded ? 'tw-block' : 'tw-hidden') }), badgeUrl ? (jsxs(Fragment, { children: [!imagesLoadState.badgeLoaded && (jsx("div", { className: cn(badgeImageClassName, loadingSkeletonClassName) })), jsx("img", { src: badgeUrl, alt: "", onLoad: () => {
2567
+ // update state when badge image is fully loaded
2568
+ setImageLoadState((prevState) => (Object.assign(Object.assign({}, prevState), { badgeLoaded: true })));
2569
+ }, className: cn(badgeImageClassName,
2570
+ // hide badge image while it is loading, and display it when it is loaded
2571
+ imagesLoadState.mainImageLoaded ? 'tw-block' : 'tw-hidden') })] })) : null] })) : null;
2555
2572
  }
2556
2573
 
2557
2574
  function LoadingSkeleton({ className, height = '20', }) {
@@ -6611,8 +6628,9 @@ const listItemSizeMap = {
6611
6628
  small: 'tw-h-list-item-small tw-px-squid-xs',
6612
6629
  large: 'tw-h-list-item-large tw-px-squid-xs',
6613
6630
  };
6631
+ const subtitleClassName = 'tw-h-[14px] tw-max-w-full tw-truncate !tw-leading-[16px] tw-text-grey-500';
6614
6632
  function ListItem(_a) {
6615
- var { itemTitle, mainImageUrl, subtitle, detail, icon, secondaryImageUrl, size = 'large', mainIcon, className, isSelected, onDetailClick, showDetailOnHoverOnly, rounded = false, detailButtonClassName, loading, containerProps } = _a, props = __rest(_a, ["itemTitle", "mainImageUrl", "subtitle", "detail", "icon", "secondaryImageUrl", "size", "mainIcon", "className", "isSelected", "onDetailClick", "showDetailOnHoverOnly", "rounded", "detailButtonClassName", "loading", "containerProps"]);
6633
+ var { itemTitle, mainImageUrl, subtitle, subtitleOnHover, detail, icon, secondaryImageUrl, size = 'large', mainIcon, className, isSelected, onDetailClick, showDetailOnHoverOnly, rounded = false, detailButtonClassName, loading, containerProps } = _a, props = __rest(_a, ["itemTitle", "mainImageUrl", "subtitle", "subtitleOnHover", "detail", "icon", "secondaryImageUrl", "size", "mainIcon", "className", "isSelected", "onDetailClick", "showDetailOnHoverOnly", "rounded", "detailButtonClassName", "loading", "containerProps"]);
6616
6634
  // 'small' variant does not have detail
6617
6635
  const showDetail = size === 'large' && (!!detail || !!icon || showDetailOnHoverOnly);
6618
6636
  const isDetailInteractive = !!onDetailClick;
@@ -6632,7 +6650,7 @@ function ListItem(_a) {
6632
6650
  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',
6633
6651
  // 'large' variant has extra padding
6634
6652
  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' &&
6635
- ((loading === null || loading === void 0 ? void 0 : loading.subtitle) ? (jsx(LoadingSkeleton, { className: "-tw-translate-x-6 tw-text-grey-500", height: "10" })) : subtitle ? (jsx(CaptionText, { className: "tw-h-[14px] tw-max-w-full tw-truncate !tw-leading-[16px] tw-text-grey-500", children: 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
6653
+ ((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: [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
6636
6654
  ? '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'
6637
6655
  : '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] })))] })) })));
6638
6656
  }
@@ -6677,6 +6695,7 @@ function SwapStepSeparator() {
6677
6695
  return (jsx("span", { className: "tw-flex tw-h-squid-m tw-w-squid-xxl tw-items-center tw-justify-center tw-self-stretch tw-py-0.5", children: jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "4", height: "21", viewBox: "0 0 4 21", fill: "none", children: jsx("path", { d: "M2 2.5V18.5", stroke: "currentColor", "stroke-width": "4", "stroke-linecap": "round" }) }) }));
6678
6696
  }
6679
6697
 
6698
+ const STEP_ITEM_HEIGHT = 52;
6680
6699
  const statusBgClassMap = {
6681
6700
  executed: '!tw-bg-grey-300',
6682
6701
  ongoing: '!tw-bg-grey-300',
@@ -6728,22 +6747,26 @@ function SwapStepItem({ descriptionBlocks, showStepSeparator = false, link, stat
6728
6747
  return 'tw-text-grey-300';
6729
6748
  }
6730
6749
  }, [status]);
6731
- return (jsxs("li", { className: "tw-flex tw-w-list-item-large tw-flex-col tw-items-start tw-text-grey-300 tw-transition-colors tw-duration-1000", children: [jsxs("a", { href: link, target: "_blank", style: transitionStyle, className: cn('tw-group/swap-step-item tw-flex tw-w-full tw-items-center tw-rounded-squid-xs', !!link && 'hover:tw-bg-material-light-thin', statusTextClass), children: [jsx("span", { className: "tw-relative tw-flex tw-min-h-squid-l tw-items-center tw-justify-center tw-gap-squid-xxs tw-px-squid-xs", children: jsx(Chip, { style: transitionStyle, className: cn('tw-w-squid-xl', statusBgClassMap[status]), icon: chipContent }) }), jsx("div", { className: "tw-flex tw-min-h-squid-l tw-flex-1 tw-flex-wrap tw-items-center tw-justify-start tw-gap-squid-xxs tw-py-squid-xxs", children: descriptionBlocks.map(({ type, value }, index) => {
6732
- if (type === 'string') {
6733
- return (
6734
- // Instead of displaying the string into a single <BodyText />
6735
- // we split it into multiple <BodyText />
6736
- // for edge case where the string is too long to fit in one line
6737
- value
6738
- .trim()
6739
- .split(' ')
6740
- .map((word, i) => (jsx(BodyText, { size: "small", className: "!tw-leading-[13px]", children: word }, i))));
6741
- }
6742
- else if (type === 'image') {
6743
- return (jsx("img", { src: value, className: "tw-h-squid-m tw-w-squid-m tw-rounded-squid-xxs" }, index));
6744
- }
6745
- return null;
6746
- }) })] }), showStepSeparator && (jsx("span", { className: cn(separatorClassMap[status]), style: transitionStyle, children: jsx(SwapStepSeparator, {}) }))] }));
6750
+ return (jsx("li", { style: {
6751
+ maxHeight: `${STEP_ITEM_HEIGHT}px`,
6752
+ minHeight: `${STEP_ITEM_HEIGHT}px`,
6753
+ }, className: "tw-relative tw-flex tw-w-list-item-large tw-flex-col tw-items-start tw-justify-center tw-text-grey-300 tw-transition-colors tw-duration-1000", children: jsxs("a", { href: link, target: "_blank", style: Object.assign(Object.assign({}, transitionStyle), { maxHeight: `${STEP_ITEM_HEIGHT}px` }), className: cn('tw-group/swap-step-item tw-flex tw-w-full tw-items-center tw-rounded-squid-xs tw-py-squid-xxs', !!link && 'hover:tw-bg-material-light-thin', statusTextClass), children: [jsxs("span", { className: "tw-relative tw-flex tw-min-h-squid-l tw-items-center tw-justify-center tw-gap-squid-xxs tw-px-squid-xs", children: [jsx(Chip, { style: transitionStyle, className: cn('tw-w-squid-xl', statusBgClassMap[status]), icon: chipContent }), showStepSeparator && (jsx("span", { className: cn(separatorClassMap[status], 'tw-absolute tw-left-0 tw-top-full tw-mt-0.5'), style: transitionStyle, children: jsx(SwapStepSeparator, {}) }))] }), jsx("div", { className: "tw-flex tw-min-h-squid-l tw-flex-1 tw-flex-wrap tw-items-center tw-justify-start tw-gap-squid-xxs tw-py-squid-xxs tw-pr-squid-xs", children: descriptionBlocks.map((block, index) => {
6754
+ const { type, value } = block;
6755
+ if (type === 'string') {
6756
+ return (
6757
+ // Instead of displaying the string into a single <BodyText />
6758
+ // we split it into multiple <BodyText />
6759
+ // for edge case where the string is too long to fit in one line
6760
+ value
6761
+ .trim()
6762
+ .split(' ')
6763
+ .map((word, i) => (jsx(BodyText, { size: "small", className: "!tw-leading-[13px]", children: word }, i))));
6764
+ }
6765
+ else if (type === 'image') {
6766
+ return (jsx("img", { src: value, className: cn('tw-h-squid-m tw-w-squid-m', block.rounded ? 'tw-rounded-full' : 'tw-rounded-squid-xxs') }, index));
6767
+ }
6768
+ return null;
6769
+ }) })] }) }));
6747
6770
  }
6748
6771
 
6749
6772
  const borderRadiusClassMap = {
@@ -6858,8 +6881,10 @@ function SwapProgressViewHeader({ title, description, }) {
6858
6881
  return (jsxs("header", { className: "tw-flex tw-h-[95px] tw-w-full tw-flex-col tw-gap-squid-s tw-bg-grey-800 tw-px-squid-m tw-py-squid-s", children: [jsx(BodyText, { size: "large", className: "tw-h-squid-m !tw-leading-[20px] tw-text-grey-300", children: title }), jsx(CaptionText, { className: "tw-h-squid-l tw-text-grey-500", children: description })] }));
6859
6882
  }
6860
6883
 
6861
- const SwapStepsCollapsed = forwardRef(({ steps, currentStepIndex: _newStepIndex, onOpen, onClose }, ref) => {
6862
- const newStepIndex = Math.round(_newStepIndex);
6884
+ const STEPS_LIST_HEIGHT = 400;
6885
+ const SwapStepsCollapsed = forwardRef((props, ref) => {
6886
+ const { steps, currentStepIndex: _newStepIndex, onOpen, onClose, footerButton, } = props;
6887
+ const newStepIndex = Math.round(_newStepIndex < 0 ? 0 : _newStepIndex);
6863
6888
  useImperativeHandle(ref, () => ({
6864
6889
  handleToggleRouteSteps,
6865
6890
  }));
@@ -6879,6 +6904,16 @@ const SwapStepsCollapsed = forwardRef(({ steps, currentStepIndex: _newStepIndex,
6879
6904
  clearTimeout(timeoutId);
6880
6905
  };
6881
6906
  }, [isShowRouteAnimationRunning]);
6907
+ useEffect(() => {
6908
+ var _a;
6909
+ if (!isRouteVisible)
6910
+ return;
6911
+ // scroll in the steps list so the current step is visible at the middle
6912
+ (_a = routeStepsListRef.current) === null || _a === void 0 ? void 0 : _a.scrollTo({
6913
+ top: -((newStepIndex - 1) * STEP_ITEM_HEIGHT) + STEPS_LIST_HEIGHT / 2,
6914
+ behavior: 'smooth',
6915
+ });
6916
+ }, [newStepIndex]);
6882
6917
  const routeStepsListRef = useRef(null);
6883
6918
  const handleToggleRouteSteps = () => {
6884
6919
  if (isRouteVisible) {
@@ -6909,9 +6944,13 @@ const SwapStepsCollapsed = forwardRef(({ steps, currentStepIndex: _newStepIndex,
6909
6944
  }, onClick: handleToggleRouteSteps, className: "tw-absolute tw-inset-0 tw-h-[60px] tw-cursor-pointer tw-rounded-squid-l tw-border tw-border-material-light-thin" }), jsx("div", { onClick: isShowRouteAnimationRunning ? undefined : handleToggleRouteSteps, style: {
6910
6945
  [CSS_VARS.COLLAPSE_ROUTE_DURATION]: `${ANIMATION_DURATIONS.HIDE_ROUTE}ms`,
6911
6946
  [CSS_VARS.EXPAND_ROUTE_DURATION]: `${ANIMATION_DURATIONS.SHOW_ROUTE}ms`,
6912
- }, className: cn('tw-relative tw-h-[60px] tw-max-h-[535px] tw-w-full tw-overflow-hidden tw-rounded-squid-l tw-border tw-border-material-light-thin tw-bg-grey-800 tw-backdrop-blur-2xl', isShowRouteAnimationRunning
6913
- ? 'tw-animate-expand-route'
6914
- : 'tw-animate-collapse-route'), children: jsxs("div", { className: "tw-flex tw-max-h-[535px] tw-grow-0 tw-flex-col tw-gap-squid-xxs tw-pt-[52px]", style: {
6947
+ }, className: cn('tw-relative tw-h-[60px] tw-max-h-[535px] tw-w-full tw-overflow-hidden tw-rounded-squid-l tw-border tw-border-material-light-thin tw-bg-grey-800 tw-backdrop-blur-2xl', isRouteVisible &&
6948
+ (isShowRouteAnimationRunning
6949
+ ? 'tw-animate-expand-route'
6950
+ : 'tw-animate-collapse-route')), children: jsxs("div", { className: cn('tw-flex tw-flex-col tw-gap-squid-xxs', isRouteVisible || isShowRouteAnimationRunning
6951
+ ? 'tw-max-h-[535px]'
6952
+ : ''), style: {
6953
+ paddingTop: `${STEP_ITEM_HEIGHT}px`,
6915
6954
  transition: isShowRouteAnimationRunning
6916
6955
  ? `transform ${ANIMATION_DURATIONS.SHOW_ROUTE}ms ${ANIMATION_TIMINGS.CHANGE_SWAP_STEP}`
6917
6956
  : isRouteVisible
@@ -6919,13 +6958,16 @@ const SwapStepsCollapsed = forwardRef(({ steps, currentStepIndex: _newStepIndex,
6919
6958
  : `transform ${ANIMATION_DURATIONS.CHANGE_SWAP_STEP}ms ${ANIMATION_TIMINGS.CHANGE_SWAP_STEP}`,
6920
6959
  transform: isShowRouteAnimationRunning
6921
6960
  ? 'translateY(0)'
6922
- : `translateY(calc(-100% + 85px + ${(newStepIndex + 1) * 50}px))`,
6923
- }, children: [jsx("div", { className: cn('tw-absolute tw-top-0 tw-z-10 tw-flex tw-h-[52px] tw-w-full tw-items-center tw-justify-center tw-gap-squid-xs tw-self-stretch tw-bg-transparent tw-p-squid-xs'), children: jsx("button", { onClick: handleToggleRouteSteps, className: "tw-flex tw-h-squid-xl tw-w-40 tw-items-center tw-justify-center tw-rounded-squid-xs tw-px-10 hover:tw-bg-material-light-thin", children: jsx("span", { className: "tw-flex tw-h-8 tw-w-8 tw-items-center tw-justify-center tw-text-grey-300", children: jsx(ChevronLargeDownIcon, { size: "32" }) }) }) }), jsx("ul", { ref: routeStepsListRef, style: {
6961
+ : `translateY(calc(-100% + 69px + ${(newStepIndex + 1) * STEP_ITEM_HEIGHT}px))`,
6962
+ }, children: [jsx("div", { style: {
6963
+ display: isRouteVisible ? 'flex' : 'none',
6964
+ height: `${STEP_ITEM_HEIGHT}px`,
6965
+ }, className: cn('tw-absolute tw-top-0 tw-z-10 tw-flex tw-w-full tw-items-center tw-justify-center tw-gap-squid-xs tw-self-stretch tw-bg-grey-800 tw-p-squid-xs'), children: jsx("button", { onClick: handleToggleRouteSteps, className: "tw-flex tw-h-squid-xl tw-w-40 tw-items-center tw-justify-center tw-rounded-squid-xs tw-px-10 hover:tw-bg-material-light-thin", children: jsx("span", { className: "tw-flex tw-h-8 tw-w-8 tw-items-center tw-justify-center tw-text-grey-300", children: jsx(ChevronLargeDownIcon, { size: "32" }) }) }) }), jsx("ul", { ref: routeStepsListRef, style: {
6924
6966
  zIndex: isRouteVisible ? 0 : -10,
6925
6967
  scrollbarWidth: 'none',
6926
- }, className: "tw-relative tw-flex tw-max-h-[413px] tw-w-[400px] tw-flex-1 tw-grow-0 tw-flex-col-reverse tw-items-center tw-self-stretch tw-overflow-y-auto tw-overflow-x-hidden tw-px-squid-xs tw-py-[15px]", children: steps.map((step, index) => (jsx(SwapStepItem, { descriptionBlocks: step.descriptionBlocks,
6968
+ }, className: "tw-relative tw-flex tw-w-[400px] tw-flex-1 tw-grow-0 tw-flex-col-reverse tw-items-center tw-self-stretch tw-overflow-y-auto tw-overflow-x-hidden tw-px-squid-xs tw-pb-squid-xxs", children: steps.map((step, index) => (jsx(SwapStepItem, { descriptionBlocks: step.descriptionBlocks,
6927
6969
  // show separator for all steps except the first one
6928
- showStepSeparator: index > 0, link: step.link, status: newStepIndex < index ? 'pending' : step.status }, index))) }), jsx("footer", { className: "tw-flex tw-w-full tw-items-end tw-justify-center tw-gap-squid-xs tw-self-stretch tw-p-squid-s", children: jsx(Button, { size: "md", variant: "secondary", label: "View on Squidscan", className: "tw-w-full" }) })] }) })] }) }) }));
6970
+ showStepSeparator: index > 0, link: step.link, status: newStepIndex < index ? 'pending' : step.status }, index))) }), jsx("footer", { className: "tw-flex tw-max-h-[55px] tw-min-h-[55px] tw-w-full tw-justify-center tw-gap-squid-xs tw-self-stretch tw-px-squid-s tw-pb-squid-s", children: jsx(Button, { size: "md", variant: "secondary", onClick: footerButton === null || footerButton === void 0 ? void 0 : footerButton.onClick, link: footerButton === null || footerButton === void 0 ? void 0 : footerButton.link, label: footerButton === null || footerButton === void 0 ? void 0 : footerButton.label, className: "tw-w-full" }) })] }) })] }) }) }));
6929
6971
  });
6930
6972
 
6931
6973
  function TokenPair({ firstToken, secondToken }) {
@@ -42227,7 +42269,7 @@ const swapProgressButtonTexts = {
42227
42269
  [SwapState.PARTIAL_SUCCESS]: 'Cancel',
42228
42270
  [SwapState.NEEDS_GAS]: 'Go to Axelarscan',
42229
42271
  };
42230
- function SwapProgressView({ steps, isOpen = true, handleClose, handleComplete, socialLink, supportLink, fromAmount, fromChain, fromToken, toAmount, toChain, toToken, fromAddressFormatted, toAddressFormatted, swapState, estimatedTimeToComplete, }) {
42272
+ function SwapProgressView({ steps, isOpen = true, handleClose, handleComplete, socialLink, supportLink, fromAmount, fromChain, fromToken, toAmount, toChain, toToken, fromAddressFormatted, toAddressFormatted, swapState, estimatedTimeToComplete, footerButton, }) {
42231
42273
  const [showSwapInfoSection, setShowSwapInfoSection] = useState(true);
42232
42274
  const isFirstRenderRef = useRef(true);
42233
42275
  const { timer, stopTimer, startTimer } = useTimer({
@@ -42285,9 +42327,10 @@ function SwapProgressView({ steps, isOpen = true, handleClose, handleComplete, s
42285
42327
  }, secondToken: {
42286
42328
  bgColor: toToken.bgColor,
42287
42329
  imageUrl: toToken.logoUrl,
42288
- } })) }), jsx(SwapProgressViewHeader, { title: headerTitle, description: headerDescription }), jsxs("ul", { className: "tw-flex tw-h-[195px] tw-w-full tw-flex-col tw-items-center tw-justify-center tw-gap-squid-xxs tw-rounded-squid-l tw-py-squid-s", children: [jsx(SwapDetailListItem, { icon: jsx(ArrowsSwapIcon, {}), label: "Swap", detail: jsx(SwapDetailItemValues, { fromContent: jsxs(Fragment, { children: [jsx("img", { className: "tw-h-squid-m tw-w-squid-m tw-rounded-full", src: fromToken.logoUrl }), jsx(CaptionText, { children: fromAmount })] }), toContent: jsxs(Fragment, { children: [jsx("img", { className: "tw-h-squid-m tw-w-squid-m tw-rounded-full", src: toToken.logoUrl }), jsx(CaptionText, { children: toAmount })] }) }) }), jsx(SwapDetailListItem, { icon: jsx(ChainLink, { size: "24", strokeWidth: "1.5" }), label: "Chain", detail: jsx(SwapDetailItemValues, { fromContent: jsxs(Fragment, { children: [jsx("img", { className: "tw-h-squid-m tw-w-squid-m tw-rounded-squid-xxs", src: fromChain.logoUrl }), jsx(CaptionText, { children: fromChain.networkName })] }), toContent: jsxs(Fragment, { children: [jsx("img", { className: "tw-h-squid-m tw-w-squid-m tw-rounded-squid-xxs", src: toChain.logoUrl }), jsx(CaptionText, { children: toChain.networkName })] }) }) }), jsx(SwapDetailListItem, { icon: jsx(WalletFilledIcon, { size: "24" }), label: "Wallet", detail: jsx(SwapDetailItemValues, { fromContent: fromAddressFormatted, toContent: toAddressFormatted }) }), jsx(SwapDetailListItem, { icon: jsx(TimeFliesIcon, {}), label: "Time to complete", detail: swapState === SwapState.PROGRESS ? (jsx(SwapDetailItemValues, { fromContent: timer, toContent: estimatedTimeToComplete })) : swapState === SwapState.COMPLETED ? (jsx(CaptionText, { children: timer })) : (jsx(CaptionText, { children: estimatedTimeToComplete })) })] })] }), jsx(TrackTransactionView, { ref: trackTransactionViewRef, onTxEnd: () => stopTimer(), onTxStart: () => startTimer(), rawSteps: steps, onClose: handleRouteStepsClosed, onOpen: handleRouteStepsOpen, swapState: swapState }), !showSwapInfoSection ? (jsx(Button, { size: "lg", variant: "primary", label: "Cancel", onClick: handleCollapseRouteSteps, className: "tw-min-h-button" })) : swapState === SwapState.PARTIAL_SUCCESS ? (jsxs("div", { className: "tw-flex tw-w-full tw-items-center tw-gap-squid-xxs", children: [jsx(Button, { size: "lg", variant: "secondary", label: swapProgressButtonTexts[swapState], onClick: handleClose, className: "tw-min-h-button" }), jsx(Button, { size: "lg", variant: "primary", label: "Complete", onClick: handleComplete, className: "tw-min-h-button" })] })) : (jsx(Button, { size: "lg", variant: "primary", label: swapProgressButtonTexts[swapState], onClick: handleClose, className: "tw-min-h-button" }))] }));
42330
+ } })) }), jsx(SwapProgressViewHeader, { title: headerTitle, description: headerDescription }), jsxs("ul", { className: "tw-flex tw-h-[195px] tw-w-full tw-flex-col tw-items-center tw-justify-center tw-gap-squid-xxs tw-rounded-squid-l tw-py-squid-s", children: [jsx(SwapDetailListItem, { icon: jsx(ArrowsSwapIcon, {}), label: "Swap", detail: jsx(SwapDetailItemValues, { fromContent: jsxs(Fragment, { children: [jsx("img", { className: "tw-h-squid-m tw-w-squid-m tw-rounded-full", src: fromToken.logoUrl }), jsx(CaptionText, { children: fromAmount })] }), toContent: jsxs(Fragment, { children: [jsx("img", { className: "tw-h-squid-m tw-w-squid-m tw-rounded-full", src: toToken.logoUrl }), jsx(CaptionText, { children: toAmount })] }) }) }), jsx(SwapDetailListItem, { icon: jsx(ChainLink, { size: "24", strokeWidth: "1.5" }), label: "Chain", detail: jsx(SwapDetailItemValues, { fromContent: jsxs(Fragment, { children: [jsx("img", { className: "tw-h-squid-m tw-w-squid-m tw-rounded-squid-xxs", src: fromChain.logoUrl }), jsx(CaptionText, { children: fromChain.networkName })] }), toContent: jsxs(Fragment, { children: [jsx("img", { className: "tw-h-squid-m tw-w-squid-m tw-rounded-squid-xxs", src: toChain.logoUrl }), jsx(CaptionText, { children: toChain.networkName })] }) }) }), jsx(SwapDetailListItem, { icon: jsx(WalletFilledIcon, { size: "24" }), label: "Wallet", detail: jsx(SwapDetailItemValues, { fromContent: fromAddressFormatted, toContent: toAddressFormatted }) }), jsx(SwapDetailListItem, { icon: jsx(TimeFliesIcon, {}), label: "Time to complete", detail: swapState === SwapState.PROGRESS ? (jsx(SwapDetailItemValues, { fromContent: timer, toContent: estimatedTimeToComplete })) : swapState === SwapState.COMPLETED ? (jsx(CaptionText, { children: timer })) : (jsx(CaptionText, { children: estimatedTimeToComplete })) })] })] }), jsx(TrackTransactionView, { ref: trackTransactionViewRef, onTxEnd: () => stopTimer(), onTxStart: () => startTimer(), rawSteps: steps, onClose: handleRouteStepsClosed, onOpen: handleRouteStepsOpen, swapState: swapState, footerButton: footerButton }), !showSwapInfoSection ? (jsx(Button, { size: "lg", variant: "primary", label: "Cancel", onClick: handleCollapseRouteSteps, className: "tw-min-h-button" })) : swapState === SwapState.PARTIAL_SUCCESS ? (jsxs("div", { className: "tw-flex tw-w-full tw-items-center tw-gap-squid-xxs", children: [jsx(Button, { size: "lg", variant: "secondary", label: swapProgressButtonTexts[swapState], onClick: handleClose, className: "tw-min-h-button" }), jsx(Button, { size: "lg", variant: "primary", label: "Complete", onClick: handleComplete, className: "tw-min-h-button" })] })) : (jsx(Button, { size: "lg", variant: "primary", label: swapProgressButtonTexts[swapState], onClick: handleClose, className: "tw-min-h-button" }))] }));
42289
42331
  }
42290
- const TrackTransactionView = forwardRef(({ swapState, rawSteps, onOpen, onClose, onTxStart, onTxEnd }, ref) => {
42332
+ const TrackTransactionView = forwardRef((props, ref) => {
42333
+ const { swapState, rawSteps, onOpen, onClose, onTxStart, onTxEnd, footerButton, } = props;
42291
42334
  const { currentStepIndex, steps } = useMemo(() => {
42292
42335
  if (swapState === SwapState.COMPLETED) {
42293
42336
  onTxEnd();
@@ -42321,12 +42364,19 @@ const TrackTransactionView = forwardRef(({ swapState, rawSteps, onOpen, onClose,
42321
42364
  currentStepIndex: rawSteps.length - 1,
42322
42365
  };
42323
42366
  }
42367
+ if (swapState === SwapState.ERROR) {
42368
+ const firstErrorStepIndex = rawSteps.findIndex((s) => s.status === 'error');
42369
+ return {
42370
+ steps: rawSteps,
42371
+ currentStepIndex: firstErrorStepIndex,
42372
+ };
42373
+ }
42324
42374
  return {
42325
42375
  steps: rawSteps,
42326
42376
  currentStepIndex: 0,
42327
42377
  };
42328
42378
  }, [swapState, rawSteps]);
42329
- return rawSteps.length > 0 ? (jsx(SwapStepsCollapsed, { ref: ref, steps: steps, currentStepIndex: currentStepIndex, onClose: onClose, onOpen: onOpen })) : null;
42379
+ return rawSteps.length > 0 ? (jsx(SwapStepsCollapsed, { ref: ref, steps: steps, currentStepIndex: currentStepIndex, onClose: onClose, onOpen: onOpen, footerButton: footerButton })) : null;
42330
42380
  });
42331
42381
  const SwapDetailItemValues = ({ fromContent, toContent, }) => {
42332
42382
  return (jsxs("div", { className: "tw-flex tw-items-center tw-justify-center tw-gap-squid-xxs", children: [typeof fromContent === 'string' ? (jsx(CaptionText, { children: fromContent })) : (fromContent), jsx("span", { className: "tw-text-grey-500", children: jsx(ChevronLargeRightIcon, {}) }), typeof toContent === 'string' ? (jsx(CaptionText, { children: toContent })) : (toContent)] }));
@@ -42353,15 +42403,11 @@ const lightTheme = {
42353
42403
  'status-positive': '#11D421',
42354
42404
  'status-negative': '#FF5B4D',
42355
42405
  'status-warning': '#EC9213',
42356
- // transparent
42357
- 'transparent-light-thin': '#17191C1A', // 10% opacity
42358
- 'transparent-light-average': '#17191C54', // 33% opacity
42359
- 'transparent-light-thick': '#17191CA8', // 66% opacity
42360
- 'transparent-dark-thin': '#FBFBFD1A', // 10% opacity
42361
- 'transparent-dark-average': '#FBFCFD54', // 33% opacity
42362
- 'transparent-dark-thick': '#FBFCFDA8', // 66% opacity
42363
42406
  };
42364
42407
 
42408
+ // list of the theme variables that need to be replaced
42409
+ // from the user readable theme config
42410
+ // to the internal theme config
42365
42411
  const themeKeysToReplace = [
42366
42412
  {
42367
42413
  userKey: 'content',
@@ -42371,24 +42417,20 @@ const themeKeysToReplace = [
42371
42417
  userKey: 'accent',
42372
42418
  internalKey: 'royal',
42373
42419
  },
42374
- {
42375
- userKey: 'transparent',
42376
- internalKey: 'material',
42377
- },
42378
42420
  {
42379
42421
  userKey: 'status-warning',
42380
42422
  internalKey: 'status-partial',
42381
42423
  },
42382
42424
  ];
42383
42425
  /**
42384
- * Parsing the user readable config to css variables
42426
+ * Parses the user readable config to css variables
42385
42427
  * Also maps the public theme variables to the internal theme variables
42428
+ * and adds the material-* variants
42386
42429
  * example user theme:
42387
42430
  * {
42388
42431
  * 'content-100': '#000',
42389
42432
  * 'content-200': '#000',
42390
42433
  * 'accent-400': '#000',
42391
- * 'transparent-light-thin': '#000'
42392
42434
  * }
42393
42435
  * Resulting in:
42394
42436
  * {
@@ -42403,10 +42445,9 @@ const parseSquidTheme = (userTheme) => {
42403
42445
  var _a;
42404
42446
  if (!userTheme)
42405
42447
  return undefined;
42406
- const squidTheme = Object.entries(userTheme).reduce((internalKeys, [userKey, userValue]) => {
42448
+ let squidTheme = Object.entries(userTheme).reduce((internalKeys, [userKey, userValue]) => {
42407
42449
  // content-* -> grey-*
42408
42450
  // accent-* -> royal-*
42409
- // transparent-* -> material-*
42410
42451
  const keyToReplace = themeKeysToReplace.find((k) => userKey.includes(k.userKey));
42411
42452
  if (keyToReplace) {
42412
42453
  const newKey = userKey.replace(keyToReplace.userKey, keyToReplace.internalKey);
@@ -42417,6 +42458,23 @@ const parseSquidTheme = (userTheme) => {
42417
42458
  }
42418
42459
  return internalKeys;
42419
42460
  }, {});
42461
+ // add material-{light,dark}-{thin,average,thick} colors to the squid theme object
42462
+ // using the following formula:
42463
+ // material-light-thin -> grey-100 + 10% opacity
42464
+ // material-light-average -> grey-100 + 33% opacity
42465
+ // material-light-thick -> grey-100 + 66% opacity
42466
+ // material-dark-thin -> grey-900 + 10% opacity
42467
+ // material-dark-average -> grey-900 + 33% opacity
42468
+ // material-dark-thick -> grey-900 + 66% opacity
42469
+ const materialVariants = {
42470
+ 'material-light-thin': getHexColorFromOpacityPercentage(squidTheme['grey-100'], 0.1),
42471
+ 'material-light-average': getHexColorFromOpacityPercentage(squidTheme['grey-100'], 0.33),
42472
+ 'material-light-thick': getHexColorFromOpacityPercentage(squidTheme['grey-100'], 0.66),
42473
+ 'material-dark-thin': getHexColorFromOpacityPercentage(squidTheme['grey-900'], 0.1),
42474
+ 'material-dark-average': getHexColorFromOpacityPercentage(squidTheme['grey-900'], 0.33),
42475
+ 'material-dark-thick': getHexColorFromOpacityPercentage(squidTheme['grey-900'], 0.66),
42476
+ };
42477
+ squidTheme = Object.assign(Object.assign({}, squidTheme), materialVariants);
42420
42478
  const styleKeys = Object.keys(themeTypesKeys);
42421
42479
  const parsed = styleKeys.map((sk) => {
42422
42480
  const themeItem = themeTypesKeys[sk];
@@ -42512,4 +42570,4 @@ function SquidConfigProvider({ theme = lightTheme, children, themeType = 'light'
42512
42570
  return (jsx("div", { style: parsedStyle, "data-squid-theme-type": themeType, className: "tw-group tw-relative tw-font-geist", children: children }));
42513
42571
  }
42514
42572
 
42515
- export { AddressButton, ArrowButton, AssetsButton, BadgeImage, BodyText, Boost, BoostButton, BorderedContainer, Button, CaptionText, Chip, DetailsToolbar, DropdownMenu, DropdownMenuItem, ErrorMessage, FeeButton, HeadingText, HistoryItem, InfoBox, Input, ListItem, LoadingSkeleton, Menu, MenuItem, Modal, ModalContent, ModalContentDivider, NavigationBar, NumericInput, ProductCard, ProfileHeaderBackground, SectionTitle, SettingsButton, SettingsItem, SettingsSlider, SquidConfigProvider, SwapConfiguration, SwapDetailListItem, SwapProgressView, SwapProgressViewHeader, SwapStepItem, SwapStepsCollapsed, Switch, TokenPair, Tooltip, UsdAmount, useDropdownMenu };
42573
+ export { AddressButton, ArrowButton, AssetsButton, BadgeImage, BodyText, Boost, BoostButton, BorderedContainer, Button, CaptionText, Chip, DetailsToolbar, DropdownMenu, DropdownMenuItem, ErrorMessage, FeeButton, HeadingText, HistoryItem, InfoBox, Input, ListItem, LoadingSkeleton, Menu, MenuItem, Modal, ModalContent, ModalContentDivider, NavigationBar, NumericInput, ProductCard, ProfileHeaderBackground, STEP_ITEM_HEIGHT, SectionTitle, SettingsButton, SettingsItem, SettingsSlider, SquidConfigProvider, SwapConfiguration, SwapDetailListItem, SwapProgressView, SwapProgressViewHeader, SwapStepItem, SwapStepsCollapsed, Switch, TokenPair, Tooltip, UsdAmount, useDropdownMenu };
@@ -1,10 +1,16 @@
1
1
  /// <reference types="react" />
2
2
  import { SwapStep } from '../../types/components';
3
+ export type SwapStepsCollapsedFooterButton = {
4
+ label: string;
5
+ link?: string;
6
+ onClick?: () => void;
7
+ };
3
8
  interface SwapStepsCollapsedProps {
4
9
  steps: SwapStep[];
5
10
  currentStepIndex: number;
6
11
  onOpen?: () => void;
7
12
  onClose?: () => void;
13
+ footerButton?: SwapStepsCollapsedFooterButton;
8
14
  }
9
15
  export declare const SwapStepsCollapsed: import("react").ForwardRefExoticComponent<SwapStepsCollapsedProps & import("react").RefAttributes<{
10
16
  handleToggleRouteSteps: () => void;
@@ -4,6 +4,7 @@ interface ListItemProps extends React.HTMLAttributes<HTMLButtonElement> {
4
4
  mainImageUrl?: string;
5
5
  secondaryImageUrl?: string;
6
6
  subtitle?: string;
7
+ subtitleOnHover?: React.ReactNode;
7
8
  detail?: string;
8
9
  icon?: React.ReactNode;
9
10
  size?: ListItemSize;
@@ -20,5 +21,5 @@ interface ListItemProps extends React.HTMLAttributes<HTMLButtonElement> {
20
21
  containerProps?: React.HTMLAttributes<HTMLLIElement>;
21
22
  }
22
23
  type ListItemSize = 'small' | 'large';
23
- export declare function ListItem({ itemTitle, mainImageUrl, subtitle, detail, icon, secondaryImageUrl, size, mainIcon, className, isSelected, onDetailClick, showDetailOnHoverOnly, rounded, detailButtonClassName, loading, containerProps, ...props }: ListItemProps): import("react/jsx-runtime").JSX.Element;
24
+ export declare function ListItem({ itemTitle, mainImageUrl, subtitle, subtitleOnHover, detail, icon, secondaryImageUrl, size, mainIcon, className, isSelected, onDetailClick, showDetailOnHoverOnly, rounded, detailButtonClassName, loading, containerProps, ...props }: ListItemProps): import("react/jsx-runtime").JSX.Element;
24
25
  export {};
@@ -5,5 +5,6 @@ interface SwapStepItemProps {
5
5
  link?: string;
6
6
  status?: SwapStepItemStatus;
7
7
  }
8
+ export declare const STEP_ITEM_HEIGHT = 52;
8
9
  export declare function SwapStepItem({ descriptionBlocks, showStepSeparator, link, status, }: SwapStepItemProps): import("react/jsx-runtime").JSX.Element;
9
10
  export {};
@@ -1,4 +1,5 @@
1
1
  import { SwapState, SwapStep } from '../../types/components';
2
+ import { SwapStepsCollapsedFooterButton } from '../layout/SwapStepsCollapsed';
2
3
  type ChainData = {
3
4
  networkName: string;
4
5
  logoUrl: string;
@@ -9,7 +10,7 @@ type Token = {
9
10
  logoUrl: string;
10
11
  bgColor: string;
11
12
  };
12
- export declare function SwapProgressView({ steps, isOpen, handleClose, handleComplete, socialLink, supportLink, fromAmount, fromChain, fromToken, toAmount, toChain, toToken, fromAddressFormatted, toAddressFormatted, swapState, estimatedTimeToComplete, }: {
13
+ export declare function SwapProgressView({ steps, isOpen, handleClose, handleComplete, socialLink, supportLink, fromAmount, fromChain, fromToken, toAmount, toChain, toToken, fromAddressFormatted, toAddressFormatted, swapState, estimatedTimeToComplete, footerButton, }: {
13
14
  steps: SwapStep[];
14
15
  handleClose?: () => void;
15
16
  handleComplete?: () => void;
@@ -26,5 +27,6 @@ export declare function SwapProgressView({ steps, isOpen, handleClose, handleCom
26
27
  toAddressFormatted: string;
27
28
  swapState: SwapState;
28
29
  estimatedTimeToComplete?: string;
30
+ footerButton?: SwapStepsCollapsedFooterButton;
29
31
  }): import("react/jsx-runtime").JSX.Element;
30
32
  export {};
@@ -1,13 +1,13 @@
1
1
  import { SquidTheme } from '../../types/config';
2
2
  /**
3
- * Parsing the user readable config to css variables
3
+ * Parses the user readable config to css variables
4
4
  * Also maps the public theme variables to the internal theme variables
5
+ * and adds the material-* variants
5
6
  * example user theme:
6
7
  * {
7
8
  * 'content-100': '#000',
8
9
  * 'content-200': '#000',
9
10
  * 'accent-400': '#000',
10
- * 'transparent-light-thin': '#000'
11
11
  * }
12
12
  * Resulting in:
13
13
  * {
@@ -10,3 +10,4 @@ export declare const ShortRoute: Story;
10
10
  export declare const LongRoute: Story;
11
11
  export declare const Error: Story;
12
12
  export declare const Warning: Story;
13
+ export declare const LongDescriptionSteps: Story;
@@ -9,6 +9,8 @@ export declare const LargeWithLongTitle: Story;
9
9
  export declare const LargeWithLongTitleAndSubtitle: Story;
10
10
  export declare const LargeRoundedFull: Story;
11
11
  export declare const LargeWithSubtitle: Story;
12
+ export declare const SubtitleOnHover: Story;
13
+ export declare const SubtitleOnHoverTokenBalance: Story;
12
14
  export declare const LargeWithDetail: Story;
13
15
  export declare const LargeWithIcon: Story;
14
16
  export declare const LargeWithDetailAndIconInteractive: Story;
@@ -16,7 +18,8 @@ export declare const LargeShowDetailOnHoverOnly: Story;
16
18
  export declare const LargeWithSecondaryImage: Story;
17
19
  export declare const LargeSelected: Story;
18
20
  export declare const LargeWithCustomIconAsImage: Story;
19
- export declare const LargeLoading: Story;
21
+ export declare const SubtitleLoading: Story;
22
+ export declare const ImageAndBadgeLoading: Story;
20
23
  export declare const Small: Story;
21
24
  export declare const SmallInteractive: Story;
22
25
  export declare const SmallWithLongTitle: Story;
@@ -5,6 +5,7 @@ export default meta;
5
5
  type Story = StoryObj<typeof meta>;
6
6
  export declare const Executed: Story;
7
7
  export declare const ExecutedWithSeparator: Story;
8
+ export declare const ExecutedWithSeparatorAndLink: Story;
8
9
  export declare const Success: Story;
9
10
  export declare const SuccessWithSeparator: Story;
10
11
  export declare const Pending: Story;
@@ -18,6 +19,7 @@ export declare const ErrorWithSeparator: Story;
18
19
  export declare const Warning: Story;
19
20
  export declare const WarningWithSeparator: Story;
20
21
  export declare const CustomDescription: Story;
22
+ export declare const CustomDescriptionWithRoundedImage: Story;
21
23
  export declare const CustomDescriptionWithSeparator: Story;
22
24
  export declare const Link: Story;
23
25
  export declare const LongDescription: Story;
@@ -5,6 +5,7 @@ export default meta;
5
5
  type Story = StoryObj<typeof meta>;
6
6
  export declare const WithControls: Story;
7
7
  export declare const ShortRoute: Story;
8
+ export declare const LongDescriptionSteps: Story;
8
9
  export declare const LongRoute: Story;
9
10
  export declare const Completed: Story;
10
11
  export declare const Error: Story;
@@ -5,8 +5,12 @@ export type ButtonSize = 'md' | 'lg';
5
5
  export type SwapDirection = 'from' | 'to';
6
6
  export type BoostMode = 'normal' | 'boost';
7
7
  export type SwapStepDescriptionBlock = {
8
- type: 'string' | 'image';
8
+ type: 'string';
9
9
  value: string;
10
+ } | {
11
+ type: 'image';
12
+ value: string;
13
+ rounded?: boolean;
10
14
  };
11
15
  export type SwapStep = {
12
16
  descriptionBlocks: SwapStepDescriptionBlock[];
@@ -41,12 +41,6 @@ export type SquidTheme = {
41
41
  'status-positive': string;
42
42
  'status-negative': string;
43
43
  'status-warning': string;
44
- 'transparent-light-thin': string;
45
- 'transparent-light-average': string;
46
- 'transparent-light-thick': string;
47
- 'transparent-dark-thin': string;
48
- 'transparent-dark-average': string;
49
- 'transparent-dark-thick': string;
50
44
  };
51
45
  export declare const SQUID_THEME_CSS_VARIABLE_PREFIX = "--squid-theme-";
52
46
  /**
package/dist/index.css CHANGED
@@ -741,6 +741,10 @@ video {
741
741
  top: 11px;
742
742
  }
743
743
 
744
+ .tw-top-full {
745
+ top: 100%;
746
+ }
747
+
744
748
  .tw-top-squid-xxs {
745
749
  top: 0.3125rem;
746
750
  }
@@ -820,10 +824,22 @@ video {
820
824
  margin-right: 1px;
821
825
  }
822
826
 
827
+ .tw-mt-0 {
828
+ margin-top: 0px;
829
+ }
830
+
831
+ .tw-mt-0\.5 {
832
+ margin-top: 0.125rem;
833
+ }
834
+
823
835
  .tw-mt-1 {
824
836
  margin-top: 0.25rem;
825
837
  }
826
838
 
839
+ .tw-block {
840
+ display: block;
841
+ }
842
+
827
843
  .tw-flex {
828
844
  display: flex;
829
845
  }
@@ -1016,10 +1032,6 @@ video {
1016
1032
  max-height: 205px;
1017
1033
  }
1018
1034
 
1019
- .tw-max-h-\[413px\] {
1020
- max-height: 413px;
1021
- }
1022
-
1023
1035
  .tw-max-h-\[535px\] {
1024
1036
  max-height: 535px;
1025
1037
  }
@@ -1028,6 +1040,10 @@ video {
1028
1040
  max-height: 540px;
1029
1041
  }
1030
1042
 
1043
+ .tw-max-h-\[55px\] {
1044
+ max-height: 55px;
1045
+ }
1046
+
1031
1047
  .tw-max-h-\[600px\] {
1032
1048
  max-height: 600px;
1033
1049
  }
@@ -1060,6 +1076,10 @@ video {
1060
1076
  min-height: 30px;
1061
1077
  }
1062
1078
 
1079
+ .tw-min-h-\[55px\] {
1080
+ min-height: 55px;
1081
+ }
1082
+
1063
1083
  .tw-min-h-button {
1064
1084
  min-height: 3.75rem;
1065
1085
  }
@@ -2029,10 +2049,6 @@ video {
2029
2049
  padding: 1.875rem;
2030
2050
  }
2031
2051
 
2032
- .tw-p-squid-s {
2033
- padding: 0.9375rem;
2034
- }
2035
-
2036
2052
  .tw-p-squid-xs {
2037
2053
  padding: 0.625rem;
2038
2054
  }
@@ -2101,6 +2117,11 @@ video {
2101
2117
  padding-right: 1.25rem;
2102
2118
  }
2103
2119
 
2120
+ .tw-px-squid-s {
2121
+ padding-left: 0.9375rem;
2122
+ padding-right: 0.9375rem;
2123
+ }
2124
+
2104
2125
  .tw-px-squid-xs {
2105
2126
  padding-left: 0.625rem;
2106
2127
  padding-right: 0.625rem;
@@ -2131,11 +2152,6 @@ video {
2131
2152
  padding-bottom: 0.5rem;
2132
2153
  }
2133
2154
 
2134
- .tw-py-\[15px\] {
2135
- padding-top: 15px;
2136
- padding-bottom: 15px;
2137
- }
2138
-
2139
2155
  .tw-py-squid-s {
2140
2156
  padding-top: 0.9375rem;
2141
2157
  padding-bottom: 0.9375rem;
@@ -2252,10 +2268,6 @@ video {
2252
2268
  padding-right: 0.625rem;
2253
2269
  }
2254
2270
 
2255
- .tw-pt-\[52px\] {
2256
- padding-top: 52px;
2257
- }
2258
-
2259
2271
  .tw-pt-\[5px\] {
2260
2272
  padding-top: 5px;
2261
2273
  }
@@ -2814,6 +2826,10 @@ input[type='number'] {
2814
2826
  display: block;
2815
2827
  }
2816
2828
 
2829
+ .tw-group\/list-item:hover .group-hover\/list-item\:tw-block {
2830
+ display: block;
2831
+ }
2832
+
2817
2833
  .tw-group\/history-item:hover .group-hover\/history-item\:tw-hidden {
2818
2834
  display: none;
2819
2835
  }
package/dist/index.d.ts CHANGED
@@ -55,8 +55,12 @@ type ButtonSize = 'md' | 'lg';
55
55
  type SwapDirection = 'from' | 'to';
56
56
  type BoostMode = 'normal' | 'boost';
57
57
  type SwapStepDescriptionBlock = {
58
- type: 'string' | 'image';
58
+ type: 'string';
59
59
  value: string;
60
+ } | {
61
+ type: 'image';
62
+ value: string;
63
+ rounded?: boolean;
60
64
  };
61
65
  type SwapStep = {
62
66
  descriptionBlocks: SwapStepDescriptionBlock[];
@@ -254,6 +258,7 @@ interface ListItemProps extends React.HTMLAttributes<HTMLButtonElement> {
254
258
  mainImageUrl?: string;
255
259
  secondaryImageUrl?: string;
256
260
  subtitle?: string;
261
+ subtitleOnHover?: React.ReactNode;
257
262
  detail?: string;
258
263
  icon?: React.ReactNode;
259
264
  size?: ListItemSize;
@@ -270,7 +275,7 @@ interface ListItemProps extends React.HTMLAttributes<HTMLButtonElement> {
270
275
  containerProps?: React.HTMLAttributes<HTMLLIElement>;
271
276
  }
272
277
  type ListItemSize = 'small' | 'large';
273
- declare function ListItem({ itemTitle, mainImageUrl, subtitle, detail, icon, secondaryImageUrl, size, mainIcon, className, isSelected, onDetailClick, showDetailOnHoverOnly, rounded, detailButtonClassName, loading, containerProps, ...props }: ListItemProps): react_jsx_runtime.JSX.Element;
278
+ declare function ListItem({ itemTitle, mainImageUrl, subtitle, subtitleOnHover, detail, icon, secondaryImageUrl, size, mainIcon, className, isSelected, onDetailClick, showDetailOnHoverOnly, rounded, detailButtonClassName, loading, containerProps, ...props }: ListItemProps): react_jsx_runtime.JSX.Element;
274
279
 
275
280
  interface MenuItemProps {
276
281
  label: string;
@@ -342,6 +347,7 @@ interface SwapStepItemProps {
342
347
  link?: string;
343
348
  status?: SwapStepItemStatus;
344
349
  }
350
+ declare const STEP_ITEM_HEIGHT = 52;
345
351
  declare function SwapStepItem({ descriptionBlocks, showStepSeparator, link, status, }: SwapStepItemProps): react_jsx_runtime.JSX.Element;
346
352
 
347
353
  interface DropdownMenuProps {
@@ -459,11 +465,17 @@ interface SwapProgressViewHeaderProps {
459
465
  }
460
466
  declare function SwapProgressViewHeader({ title, description, }: SwapProgressViewHeaderProps): react_jsx_runtime.JSX.Element;
461
467
 
468
+ type SwapStepsCollapsedFooterButton = {
469
+ label: string;
470
+ link?: string;
471
+ onClick?: () => void;
472
+ };
462
473
  interface SwapStepsCollapsedProps {
463
474
  steps: SwapStep[];
464
475
  currentStepIndex: number;
465
476
  onOpen?: () => void;
466
477
  onClose?: () => void;
478
+ footerButton?: SwapStepsCollapsedFooterButton;
467
479
  }
468
480
  declare const SwapStepsCollapsed: React$1.ForwardRefExoticComponent<SwapStepsCollapsedProps & React$1.RefAttributes<{
469
481
  handleToggleRouteSteps: () => void;
@@ -510,7 +522,7 @@ type Token = {
510
522
  logoUrl: string;
511
523
  bgColor: string;
512
524
  };
513
- declare function SwapProgressView({ steps, isOpen, handleClose, handleComplete, socialLink, supportLink, fromAmount, fromChain, fromToken, toAmount, toChain, toToken, fromAddressFormatted, toAddressFormatted, swapState, estimatedTimeToComplete, }: {
525
+ declare function SwapProgressView({ steps, isOpen, handleClose, handleComplete, socialLink, supportLink, fromAmount, fromChain, fromToken, toAmount, toChain, toToken, fromAddressFormatted, toAddressFormatted, swapState, estimatedTimeToComplete, footerButton, }: {
514
526
  steps: SwapStep[];
515
527
  handleClose?: () => void;
516
528
  handleComplete?: () => void;
@@ -527,6 +539,7 @@ declare function SwapProgressView({ steps, isOpen, handleClose, handleComplete,
527
539
  toAddressFormatted: string;
528
540
  swapState: SwapState;
529
541
  estimatedTimeToComplete?: string;
542
+ footerButton?: SwapStepsCollapsedFooterButton;
530
543
  }): react_jsx_runtime.JSX.Element;
531
544
 
532
545
  type SquidTheme = {
@@ -544,12 +557,6 @@ type SquidTheme = {
544
557
  'status-positive': string;
545
558
  'status-negative': string;
546
559
  'status-warning': string;
547
- 'transparent-light-thin': string;
548
- 'transparent-light-average': string;
549
- 'transparent-light-thick': string;
550
- 'transparent-dark-thin': string;
551
- 'transparent-dark-average': string;
552
- 'transparent-dark-thick': string;
553
560
  };
554
561
 
555
562
  declare function SquidConfigProvider({ theme, children, themeType, }: {
@@ -568,4 +575,4 @@ declare function useDropdownMenu(props?: {
568
575
  openDropdownButtonRef: React.RefObject<HTMLButtonElement>;
569
576
  };
570
577
 
571
- export { AddressButton, ArrowButton, AssetsButton, BadgeImage, BodyText, Boost, BoostButton, BorderedContainer, Button, CaptionText, Chip, DetailsToolbar, DropdownMenu, DropdownMenuItem, type DropdownMenuItemProps, ErrorMessage, FeeButton, HeadingText, HistoryItem, InfoBox, Input, ListItem, LoadingSkeleton, Menu, MenuItem, Modal, ModalContent, ModalContentDivider, NavigationBar, NumericInput, ProductCard, ProfileHeaderBackground, SectionTitle, SettingsButton, type SettingsButtonProps, type SettingsControl, SettingsItem, type SettingsItemProps, SettingsSlider, type SettingsSliderProps, SquidConfigProvider, type SquidTheme, SwapConfiguration, SwapDetailListItem, SwapProgressView, SwapProgressViewHeader, SwapState, type SwapStep, SwapStepItem, type SwapStepItemStatus, SwapStepsCollapsed, Switch, type ThemeType, TokenPair, Tooltip, type TooltipProps, type TooltipThreshold, type TooltipWidth, UsdAmount, useDropdownMenu };
578
+ export { AddressButton, ArrowButton, AssetsButton, BadgeImage, BodyText, Boost, BoostButton, BorderedContainer, Button, CaptionText, Chip, DetailsToolbar, DropdownMenu, DropdownMenuItem, type DropdownMenuItemProps, ErrorMessage, FeeButton, HeadingText, HistoryItem, InfoBox, Input, ListItem, LoadingSkeleton, Menu, MenuItem, Modal, ModalContent, ModalContentDivider, NavigationBar, NumericInput, ProductCard, ProfileHeaderBackground, STEP_ITEM_HEIGHT, SectionTitle, SettingsButton, type SettingsButtonProps, type SettingsControl, SettingsItem, type SettingsItemProps, SettingsSlider, type SettingsSliderProps, SquidConfigProvider, type SquidTheme, SwapConfiguration, SwapDetailListItem, SwapProgressView, SwapProgressViewHeader, SwapState, type SwapStep, SwapStepItem, type SwapStepItemStatus, SwapStepsCollapsed, type SwapStepsCollapsedFooterButton, Switch, type ThemeType, TokenPair, Tooltip, type TooltipProps, type TooltipThreshold, type TooltipWidth, UsdAmount, useDropdownMenu };
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.15.3",
8
+ "version": "0.15.5",
9
9
  "author": "",
10
10
  "license": "MIT",
11
11
  "resolutions": {