@0xsquid/ui 0.15.3 → 0.15.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/index.js CHANGED
@@ -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', }) {
@@ -6748,7 +6765,8 @@ function SwapStepItem({ descriptionBlocks, showStepSeparator = false, link, stat
6748
6765
  return 'tw-text-grey-300';
6749
6766
  }
6750
6767
  }, [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) => {
6768
+ 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((block, index) => {
6769
+ const { type, value } = block;
6752
6770
  if (type === 'string') {
6753
6771
  return (
6754
6772
  // Instead of displaying the string into a single <BodyText />
@@ -6760,7 +6778,7 @@ function SwapStepItem({ descriptionBlocks, showStepSeparator = false, link, stat
6760
6778
  .map((word, i) => (jsxRuntime.jsx(BodyText, { size: "small", className: "!tw-leading-[13px]", children: word }, i))));
6761
6779
  }
6762
6780
  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));
6781
+ 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));
6764
6782
  }
6765
6783
  return null;
6766
6784
  }) })] }), showStepSeparator && (jsxRuntime.jsx("span", { className: cn(separatorClassMap[status]), style: transitionStyle, children: jsxRuntime.jsx(SwapStepSeparator, {}) }))] }));
@@ -6878,7 +6896,8 @@ function SwapProgressViewHeader({ title, description, }) {
6878
6896
  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
6897
  }
6880
6898
 
6881
- const SwapStepsCollapsed = React.forwardRef(({ steps, currentStepIndex: _newStepIndex, onOpen, onClose }, ref) => {
6899
+ const SwapStepsCollapsed = React.forwardRef((props, ref) => {
6900
+ const { steps, currentStepIndex: _newStepIndex, onOpen, onClose, footerButton, } = props;
6882
6901
  const newStepIndex = Math.round(_newStepIndex);
6883
6902
  React.useImperativeHandle(ref, () => ({
6884
6903
  handleToggleRouteSteps,
@@ -6945,7 +6964,7 @@ const SwapStepsCollapsed = React.forwardRef(({ steps, currentStepIndex: _newStep
6945
6964
  scrollbarWidth: 'none',
6946
6965
  }, 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,
6947
6966
  // 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" }) })] }) })] }) }) }));
6967
+ 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", 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
6968
  });
6950
6969
 
6951
6970
  function TokenPair({ firstToken, secondToken }) {
@@ -42247,7 +42266,7 @@ const swapProgressButtonTexts = {
42247
42266
  [SwapState.PARTIAL_SUCCESS]: 'Cancel',
42248
42267
  [SwapState.NEEDS_GAS]: 'Go to Axelarscan',
42249
42268
  };
42250
- function SwapProgressView({ steps, isOpen = true, handleClose, handleComplete, socialLink, supportLink, fromAmount, fromChain, fromToken, toAmount, toChain, toToken, fromAddressFormatted, toAddressFormatted, swapState, estimatedTimeToComplete, }) {
42269
+ function SwapProgressView({ steps, isOpen = true, handleClose, handleComplete, socialLink, supportLink, fromAmount, fromChain, fromToken, toAmount, toChain, toToken, fromAddressFormatted, toAddressFormatted, swapState, estimatedTimeToComplete, footerButton, }) {
42251
42270
  const [showSwapInfoSection, setShowSwapInfoSection] = React.useState(true);
42252
42271
  const isFirstRenderRef = React.useRef(true);
42253
42272
  const { timer, stopTimer, startTimer } = useTimer({
@@ -42305,9 +42324,10 @@ function SwapProgressView({ steps, isOpen = true, handleClose, handleComplete, s
42305
42324
  }, secondToken: {
42306
42325
  bgColor: toToken.bgColor,
42307
42326
  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" }))] }));
42327
+ } })) }), 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
42328
  }
42310
- const TrackTransactionView = React.forwardRef(({ swapState, rawSteps, onOpen, onClose, onTxStart, onTxEnd }, ref) => {
42329
+ const TrackTransactionView = React.forwardRef((props, ref) => {
42330
+ const { swapState, rawSteps, onOpen, onClose, onTxStart, onTxEnd, footerButton, } = props;
42311
42331
  const { currentStepIndex, steps } = React.useMemo(() => {
42312
42332
  if (swapState === SwapState.COMPLETED) {
42313
42333
  onTxEnd();
@@ -42346,7 +42366,7 @@ const TrackTransactionView = React.forwardRef(({ swapState, rawSteps, onOpen, on
42346
42366
  currentStepIndex: 0,
42347
42367
  };
42348
42368
  }, [swapState, rawSteps]);
42349
- return rawSteps.length > 0 ? (jsxRuntime.jsx(SwapStepsCollapsed, { ref: ref, steps: steps, currentStepIndex: currentStepIndex, onClose: onClose, onOpen: onOpen })) : null;
42369
+ return rawSteps.length > 0 ? (jsxRuntime.jsx(SwapStepsCollapsed, { ref: ref, steps: steps, currentStepIndex: currentStepIndex, onClose: onClose, onOpen: onOpen, footerButton: footerButton })) : null;
42350
42370
  });
42351
42371
  const SwapDetailItemValues = ({ fromContent, toContent, }) => {
42352
42372
  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 +42393,11 @@ const lightTheme = {
42373
42393
  'status-positive': '#11D421',
42374
42394
  'status-negative': '#FF5B4D',
42375
42395
  '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
42396
  };
42384
42397
 
42398
+ // list of the theme variables that need to be replaced
42399
+ // from the user readable theme config
42400
+ // to the internal theme config
42385
42401
  const themeKeysToReplace = [
42386
42402
  {
42387
42403
  userKey: 'content',
@@ -42391,24 +42407,20 @@ const themeKeysToReplace = [
42391
42407
  userKey: 'accent',
42392
42408
  internalKey: 'royal',
42393
42409
  },
42394
- {
42395
- userKey: 'transparent',
42396
- internalKey: 'material',
42397
- },
42398
42410
  {
42399
42411
  userKey: 'status-warning',
42400
42412
  internalKey: 'status-partial',
42401
42413
  },
42402
42414
  ];
42403
42415
  /**
42404
- * Parsing the user readable config to css variables
42416
+ * Parses the user readable config to css variables
42405
42417
  * Also maps the public theme variables to the internal theme variables
42418
+ * and adds the material-* variants
42406
42419
  * example user theme:
42407
42420
  * {
42408
42421
  * 'content-100': '#000',
42409
42422
  * 'content-200': '#000',
42410
42423
  * 'accent-400': '#000',
42411
- * 'transparent-light-thin': '#000'
42412
42424
  * }
42413
42425
  * Resulting in:
42414
42426
  * {
@@ -42423,10 +42435,9 @@ const parseSquidTheme = (userTheme) => {
42423
42435
  var _a;
42424
42436
  if (!userTheme)
42425
42437
  return undefined;
42426
- const squidTheme = Object.entries(userTheme).reduce((internalKeys, [userKey, userValue]) => {
42438
+ let squidTheme = Object.entries(userTheme).reduce((internalKeys, [userKey, userValue]) => {
42427
42439
  // content-* -> grey-*
42428
42440
  // accent-* -> royal-*
42429
- // transparent-* -> material-*
42430
42441
  const keyToReplace = themeKeysToReplace.find((k) => userKey.includes(k.userKey));
42431
42442
  if (keyToReplace) {
42432
42443
  const newKey = userKey.replace(keyToReplace.userKey, keyToReplace.internalKey);
@@ -42437,6 +42448,23 @@ const parseSquidTheme = (userTheme) => {
42437
42448
  }
42438
42449
  return internalKeys;
42439
42450
  }, {});
42451
+ // add material-{light,dark}-{thin,average,thick} colors to the squid theme object
42452
+ // using the following formula:
42453
+ // material-light-thin -> grey-100 + 10% opacity
42454
+ // material-light-average -> grey-100 + 33% opacity
42455
+ // material-light-thick -> grey-100 + 66% opacity
42456
+ // material-dark-thin -> grey-900 + 10% opacity
42457
+ // material-dark-average -> grey-900 + 33% opacity
42458
+ // material-dark-thick -> grey-900 + 66% opacity
42459
+ const materialVariants = {
42460
+ 'material-light-thin': getHexColorFromOpacityPercentage(squidTheme['grey-100'], 0.1),
42461
+ 'material-light-average': getHexColorFromOpacityPercentage(squidTheme['grey-100'], 0.33),
42462
+ 'material-light-thick': getHexColorFromOpacityPercentage(squidTheme['grey-100'], 0.66),
42463
+ 'material-dark-thin': getHexColorFromOpacityPercentage(squidTheme['grey-900'], 0.1),
42464
+ 'material-dark-average': getHexColorFromOpacityPercentage(squidTheme['grey-900'], 0.33),
42465
+ 'material-dark-thick': getHexColorFromOpacityPercentage(squidTheme['grey-900'], 0.66),
42466
+ };
42467
+ squidTheme = Object.assign(Object.assign({}, squidTheme), materialVariants);
42440
42468
  const styleKeys = Object.keys(themeTypesKeys);
42441
42469
  const parsed = styleKeys.map((sk) => {
42442
42470
  const themeItem = themeTypesKeys[sk];
@@ -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;
@@ -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
  * {
@@ -16,7 +16,8 @@ export declare const LargeShowDetailOnHoverOnly: Story;
16
16
  export declare const LargeWithSecondaryImage: Story;
17
17
  export declare const LargeSelected: Story;
18
18
  export declare const LargeWithCustomIconAsImage: Story;
19
- export declare const LargeLoading: Story;
19
+ export declare const SubtitleLoading: Story;
20
+ export declare const ImageAndBadgeLoading: Story;
20
21
  export declare const Small: Story;
21
22
  export declare const SmallInteractive: Story;
22
23
  export declare const SmallWithLongTitle: Story;
@@ -18,6 +18,7 @@ export declare const ErrorWithSeparator: Story;
18
18
  export declare const Warning: Story;
19
19
  export declare const WarningWithSeparator: Story;
20
20
  export declare const CustomDescription: Story;
21
+ export declare const CustomDescriptionWithRoundedImage: Story;
21
22
  export declare const CustomDescriptionWithSeparator: Story;
22
23
  export declare const Link: Story;
23
24
  export declare const LongDescription: 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', }) {
@@ -6728,7 +6745,8 @@ function SwapStepItem({ descriptionBlocks, showStepSeparator = false, link, stat
6728
6745
  return 'tw-text-grey-300';
6729
6746
  }
6730
6747
  }, [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) => {
6748
+ 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((block, index) => {
6749
+ const { type, value } = block;
6732
6750
  if (type === 'string') {
6733
6751
  return (
6734
6752
  // Instead of displaying the string into a single <BodyText />
@@ -6740,7 +6758,7 @@ function SwapStepItem({ descriptionBlocks, showStepSeparator = false, link, stat
6740
6758
  .map((word, i) => (jsx(BodyText, { size: "small", className: "!tw-leading-[13px]", children: word }, i))));
6741
6759
  }
6742
6760
  else if (type === 'image') {
6743
- return (jsx("img", { src: value, className: "tw-h-squid-m tw-w-squid-m tw-rounded-squid-xxs" }, index));
6761
+ 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));
6744
6762
  }
6745
6763
  return null;
6746
6764
  }) })] }), showStepSeparator && (jsx("span", { className: cn(separatorClassMap[status]), style: transitionStyle, children: jsx(SwapStepSeparator, {}) }))] }));
@@ -6858,7 +6876,8 @@ function SwapProgressViewHeader({ title, description, }) {
6858
6876
  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
6877
  }
6860
6878
 
6861
- const SwapStepsCollapsed = forwardRef(({ steps, currentStepIndex: _newStepIndex, onOpen, onClose }, ref) => {
6879
+ const SwapStepsCollapsed = forwardRef((props, ref) => {
6880
+ const { steps, currentStepIndex: _newStepIndex, onOpen, onClose, footerButton, } = props;
6862
6881
  const newStepIndex = Math.round(_newStepIndex);
6863
6882
  useImperativeHandle(ref, () => ({
6864
6883
  handleToggleRouteSteps,
@@ -6925,7 +6944,7 @@ const SwapStepsCollapsed = forwardRef(({ steps, currentStepIndex: _newStepIndex,
6925
6944
  scrollbarWidth: 'none',
6926
6945
  }, 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,
6927
6946
  // 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" }) })] }) })] }) }) }));
6947
+ 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", 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
6948
  });
6930
6949
 
6931
6950
  function TokenPair({ firstToken, secondToken }) {
@@ -42227,7 +42246,7 @@ const swapProgressButtonTexts = {
42227
42246
  [SwapState.PARTIAL_SUCCESS]: 'Cancel',
42228
42247
  [SwapState.NEEDS_GAS]: 'Go to Axelarscan',
42229
42248
  };
42230
- function SwapProgressView({ steps, isOpen = true, handleClose, handleComplete, socialLink, supportLink, fromAmount, fromChain, fromToken, toAmount, toChain, toToken, fromAddressFormatted, toAddressFormatted, swapState, estimatedTimeToComplete, }) {
42249
+ function SwapProgressView({ steps, isOpen = true, handleClose, handleComplete, socialLink, supportLink, fromAmount, fromChain, fromToken, toAmount, toChain, toToken, fromAddressFormatted, toAddressFormatted, swapState, estimatedTimeToComplete, footerButton, }) {
42231
42250
  const [showSwapInfoSection, setShowSwapInfoSection] = useState(true);
42232
42251
  const isFirstRenderRef = useRef(true);
42233
42252
  const { timer, stopTimer, startTimer } = useTimer({
@@ -42285,9 +42304,10 @@ function SwapProgressView({ steps, isOpen = true, handleClose, handleComplete, s
42285
42304
  }, secondToken: {
42286
42305
  bgColor: toToken.bgColor,
42287
42306
  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" }))] }));
42307
+ } })) }), 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
42308
  }
42290
- const TrackTransactionView = forwardRef(({ swapState, rawSteps, onOpen, onClose, onTxStart, onTxEnd }, ref) => {
42309
+ const TrackTransactionView = forwardRef((props, ref) => {
42310
+ const { swapState, rawSteps, onOpen, onClose, onTxStart, onTxEnd, footerButton, } = props;
42291
42311
  const { currentStepIndex, steps } = useMemo(() => {
42292
42312
  if (swapState === SwapState.COMPLETED) {
42293
42313
  onTxEnd();
@@ -42326,7 +42346,7 @@ const TrackTransactionView = forwardRef(({ swapState, rawSteps, onOpen, onClose,
42326
42346
  currentStepIndex: 0,
42327
42347
  };
42328
42348
  }, [swapState, rawSteps]);
42329
- return rawSteps.length > 0 ? (jsx(SwapStepsCollapsed, { ref: ref, steps: steps, currentStepIndex: currentStepIndex, onClose: onClose, onOpen: onOpen })) : null;
42349
+ return rawSteps.length > 0 ? (jsx(SwapStepsCollapsed, { ref: ref, steps: steps, currentStepIndex: currentStepIndex, onClose: onClose, onOpen: onOpen, footerButton: footerButton })) : null;
42330
42350
  });
42331
42351
  const SwapDetailItemValues = ({ fromContent, toContent, }) => {
42332
42352
  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 +42373,11 @@ const lightTheme = {
42353
42373
  'status-positive': '#11D421',
42354
42374
  'status-negative': '#FF5B4D',
42355
42375
  '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
42376
  };
42364
42377
 
42378
+ // list of the theme variables that need to be replaced
42379
+ // from the user readable theme config
42380
+ // to the internal theme config
42365
42381
  const themeKeysToReplace = [
42366
42382
  {
42367
42383
  userKey: 'content',
@@ -42371,24 +42387,20 @@ const themeKeysToReplace = [
42371
42387
  userKey: 'accent',
42372
42388
  internalKey: 'royal',
42373
42389
  },
42374
- {
42375
- userKey: 'transparent',
42376
- internalKey: 'material',
42377
- },
42378
42390
  {
42379
42391
  userKey: 'status-warning',
42380
42392
  internalKey: 'status-partial',
42381
42393
  },
42382
42394
  ];
42383
42395
  /**
42384
- * Parsing the user readable config to css variables
42396
+ * Parses the user readable config to css variables
42385
42397
  * Also maps the public theme variables to the internal theme variables
42398
+ * and adds the material-* variants
42386
42399
  * example user theme:
42387
42400
  * {
42388
42401
  * 'content-100': '#000',
42389
42402
  * 'content-200': '#000',
42390
42403
  * 'accent-400': '#000',
42391
- * 'transparent-light-thin': '#000'
42392
42404
  * }
42393
42405
  * Resulting in:
42394
42406
  * {
@@ -42403,10 +42415,9 @@ const parseSquidTheme = (userTheme) => {
42403
42415
  var _a;
42404
42416
  if (!userTheme)
42405
42417
  return undefined;
42406
- const squidTheme = Object.entries(userTheme).reduce((internalKeys, [userKey, userValue]) => {
42418
+ let squidTheme = Object.entries(userTheme).reduce((internalKeys, [userKey, userValue]) => {
42407
42419
  // content-* -> grey-*
42408
42420
  // accent-* -> royal-*
42409
- // transparent-* -> material-*
42410
42421
  const keyToReplace = themeKeysToReplace.find((k) => userKey.includes(k.userKey));
42411
42422
  if (keyToReplace) {
42412
42423
  const newKey = userKey.replace(keyToReplace.userKey, keyToReplace.internalKey);
@@ -42417,6 +42428,23 @@ const parseSquidTheme = (userTheme) => {
42417
42428
  }
42418
42429
  return internalKeys;
42419
42430
  }, {});
42431
+ // add material-{light,dark}-{thin,average,thick} colors to the squid theme object
42432
+ // using the following formula:
42433
+ // material-light-thin -> grey-100 + 10% opacity
42434
+ // material-light-average -> grey-100 + 33% opacity
42435
+ // material-light-thick -> grey-100 + 66% opacity
42436
+ // material-dark-thin -> grey-900 + 10% opacity
42437
+ // material-dark-average -> grey-900 + 33% opacity
42438
+ // material-dark-thick -> grey-900 + 66% opacity
42439
+ const materialVariants = {
42440
+ 'material-light-thin': getHexColorFromOpacityPercentage(squidTheme['grey-100'], 0.1),
42441
+ 'material-light-average': getHexColorFromOpacityPercentage(squidTheme['grey-100'], 0.33),
42442
+ 'material-light-thick': getHexColorFromOpacityPercentage(squidTheme['grey-100'], 0.66),
42443
+ 'material-dark-thin': getHexColorFromOpacityPercentage(squidTheme['grey-900'], 0.1),
42444
+ 'material-dark-average': getHexColorFromOpacityPercentage(squidTheme['grey-900'], 0.33),
42445
+ 'material-dark-thick': getHexColorFromOpacityPercentage(squidTheme['grey-900'], 0.66),
42446
+ };
42447
+ squidTheme = Object.assign(Object.assign({}, squidTheme), materialVariants);
42420
42448
  const styleKeys = Object.keys(themeTypesKeys);
42421
42449
  const parsed = styleKeys.map((sk) => {
42422
42450
  const themeItem = themeTypesKeys[sk];
@@ -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;
@@ -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
  * {
@@ -16,7 +16,8 @@ export declare const LargeShowDetailOnHoverOnly: Story;
16
16
  export declare const LargeWithSecondaryImage: Story;
17
17
  export declare const LargeSelected: Story;
18
18
  export declare const LargeWithCustomIconAsImage: Story;
19
- export declare const LargeLoading: Story;
19
+ export declare const SubtitleLoading: Story;
20
+ export declare const ImageAndBadgeLoading: Story;
20
21
  export declare const Small: Story;
21
22
  export declare const SmallInteractive: Story;
22
23
  export declare const SmallWithLongTitle: Story;
@@ -18,6 +18,7 @@ export declare const ErrorWithSeparator: Story;
18
18
  export declare const Warning: Story;
19
19
  export declare const WarningWithSeparator: Story;
20
20
  export declare const CustomDescription: Story;
21
+ export declare const CustomDescriptionWithRoundedImage: Story;
21
22
  export declare const CustomDescriptionWithSeparator: Story;
22
23
  export declare const Link: Story;
23
24
  export declare const LongDescription: 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
@@ -824,6 +824,10 @@ video {
824
824
  margin-top: 0.25rem;
825
825
  }
826
826
 
827
+ .tw-block {
828
+ display: block;
829
+ }
830
+
827
831
  .tw-flex {
828
832
  display: flex;
829
833
  }
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[];
@@ -459,11 +463,17 @@ interface SwapProgressViewHeaderProps {
459
463
  }
460
464
  declare function SwapProgressViewHeader({ title, description, }: SwapProgressViewHeaderProps): react_jsx_runtime.JSX.Element;
461
465
 
466
+ type SwapStepsCollapsedFooterButton = {
467
+ label: string;
468
+ link?: string;
469
+ onClick?: () => void;
470
+ };
462
471
  interface SwapStepsCollapsedProps {
463
472
  steps: SwapStep[];
464
473
  currentStepIndex: number;
465
474
  onOpen?: () => void;
466
475
  onClose?: () => void;
476
+ footerButton?: SwapStepsCollapsedFooterButton;
467
477
  }
468
478
  declare const SwapStepsCollapsed: React$1.ForwardRefExoticComponent<SwapStepsCollapsedProps & React$1.RefAttributes<{
469
479
  handleToggleRouteSteps: () => void;
@@ -510,7 +520,7 @@ type Token = {
510
520
  logoUrl: string;
511
521
  bgColor: string;
512
522
  };
513
- declare function SwapProgressView({ steps, isOpen, handleClose, handleComplete, socialLink, supportLink, fromAmount, fromChain, fromToken, toAmount, toChain, toToken, fromAddressFormatted, toAddressFormatted, swapState, estimatedTimeToComplete, }: {
523
+ declare function SwapProgressView({ steps, isOpen, handleClose, handleComplete, socialLink, supportLink, fromAmount, fromChain, fromToken, toAmount, toChain, toToken, fromAddressFormatted, toAddressFormatted, swapState, estimatedTimeToComplete, footerButton, }: {
514
524
  steps: SwapStep[];
515
525
  handleClose?: () => void;
516
526
  handleComplete?: () => void;
@@ -527,6 +537,7 @@ declare function SwapProgressView({ steps, isOpen, handleClose, handleComplete,
527
537
  toAddressFormatted: string;
528
538
  swapState: SwapState;
529
539
  estimatedTimeToComplete?: string;
540
+ footerButton?: SwapStepsCollapsedFooterButton;
530
541
  }): react_jsx_runtime.JSX.Element;
531
542
 
532
543
  type SquidTheme = {
@@ -544,12 +555,6 @@ type SquidTheme = {
544
555
  'status-positive': string;
545
556
  'status-negative': string;
546
557
  '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
558
  };
554
559
 
555
560
  declare function SquidConfigProvider({ theme, children, themeType, }: {
@@ -568,4 +573,4 @@ declare function useDropdownMenu(props?: {
568
573
  openDropdownButtonRef: React.RefObject<HTMLButtonElement>;
569
574
  };
570
575
 
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 };
576
+ 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, 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.4",
9
9
  "author": "",
10
10
  "license": "MIT",
11
11
  "resolutions": {