From cfc3217467cc368736e19219af99b6a071e11784 Mon Sep 17 00:00:00 2001 From: AtelyPham Date: Fri, 4 Aug 2023 21:18:19 +0700 Subject: [PATCH 01/14] chore: remove unused component --- .../components/ListCard/WrapAssetListCard.tsx | 96 ------------------- .../src/components/ListCard/index.ts | 1 - .../src/components/ListCard/types.ts | 33 ------- 3 files changed, 130 deletions(-) delete mode 100644 libs/webb-ui-components/src/components/ListCard/WrapAssetListCard.tsx diff --git a/libs/webb-ui-components/src/components/ListCard/WrapAssetListCard.tsx b/libs/webb-ui-components/src/components/ListCard/WrapAssetListCard.tsx deleted file mode 100644 index eb163a6192..0000000000 --- a/libs/webb-ui-components/src/components/ListCard/WrapAssetListCard.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import { Typography } from '../../typography'; -import cx from 'classnames'; -import { forwardRef, useCallback, useEffect, useMemo, useState } from 'react'; - -import { Button } from '../buttons'; -import { ScrollArea } from '../ScrollArea'; -import { AssetListItem } from './AssetListItem'; -import { ListCardWrapper } from './ListCardWrapper'; -import { AssetType, WrapAssetListCardProps } from './types'; - -export const WrapAssetListCard = forwardRef< - HTMLDivElement, - WrapAssetListCardProps ->( - ( - { - assets, - isDisconnected, - onChange, - onClose, - onConnect, - title = `Select Unwrapping Asset`, - value: selectedAsset, - ...props - }, - ref - ) => { - const [, setRelayer] = useState(() => selectedAsset); - - useEffect(() => { - let subscribe = true; - - if (subscribe) { - setRelayer(selectedAsset); - } - - return () => { - subscribe = false; - }; - }, [selectedAsset, setRelayer]); - - const onItemChange = useCallback( - (nextItem: AssetType) => { - setRelayer(nextItem); - onChange?.(nextItem); - }, - [onChange, setRelayer] - ); - - const disconnectClsx = useMemo( - () => cx({ 'opacity-40 pointer-events-none': isDisconnected }), - [isDisconnected] - ); - - return ( - - {/** Token list */} - -
    - {assets.map((current, idx) => { - return ( - - ); - })} -
-
- - {/** Disconnect view */} - -
- ); - } -); diff --git a/libs/webb-ui-components/src/components/ListCard/index.ts b/libs/webb-ui-components/src/components/ListCard/index.ts index 4e91bb72e4..ee185deec5 100644 --- a/libs/webb-ui-components/src/components/ListCard/index.ts +++ b/libs/webb-ui-components/src/components/ListCard/index.ts @@ -5,4 +5,3 @@ export * from './ListItem'; export * from './RelayerListCard'; export * from './TokenListCard'; export * from './WithdrawListCard'; -export * from './WrapAssetListCard'; diff --git a/libs/webb-ui-components/src/components/ListCard/types.ts b/libs/webb-ui-components/src/components/ListCard/types.ts index a906ebb6db..4cfed5a1d7 100644 --- a/libs/webb-ui-components/src/components/ListCard/types.ts +++ b/libs/webb-ui-components/src/components/ListCard/types.ts @@ -170,39 +170,6 @@ export interface RelayerListCardProps extends Omit, 'onChange'> { onConnectWallet?: PropsOf<'button'>['onClick']; } -export interface WrapAssetListCardProps - extends Omit { - /** - * Optional card title to change the title of the card - */ - title: string; - - /** - * If `true`, the component will display in connected view - */ - isDisconnected?: boolean; - - /** - * The relayer list to display - */ - assets: AssetType[]; - - /** - * The current selected relayer, use to control the component - */ - value?: AssetType; - - /** - * The callback to control the state of the component - */ - onChange?: (nextAsset: AssetType) => void; - - /** - * The event handler when the relayer is disabled and user hit connect wallet button on the card - */ - onConnect?: PropsOf<'button'>['onClick']; -} - export interface TokenListCardProps extends Omit { /** From 40dcc67df7578ca4b8caaf1762edfdab268d7f15 Mon Sep 17 00:00:00 2001 From: AtelyPham Date: Mon, 7 Aug 2023 07:41:48 +0700 Subject: [PATCH 02/14] doc: add doc for MenuItem --- libs/webb-ui-components/src/components/MenuItem/MenuItem.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/webb-ui-components/src/components/MenuItem/MenuItem.tsx b/libs/webb-ui-components/src/components/MenuItem/MenuItem.tsx index bcbf662ee7..c6bc7720ba 100644 --- a/libs/webb-ui-components/src/components/MenuItem/MenuItem.tsx +++ b/libs/webb-ui-components/src/components/MenuItem/MenuItem.tsx @@ -6,7 +6,7 @@ import { twMerge } from 'tailwind-merge'; import { MenuItemProps } from './types'; /** - * The `MenuItem` component + * The dropdown `MenuItem` component (must be used inside the `Dropdown*` component) * * Props: * From d83539895ae88a60eb0e346f9b4917e1005d13d5 Mon Sep 17 00:00:00 2001 From: AtelyPham Date: Wed, 9 Aug 2023 18:47:06 +0700 Subject: [PATCH 03/14] chore: remove unsed components --- .../src/components/ListCard/ListItem.tsx | 5 +- .../src/components/ListCard/TokenListCard.tsx | 4 +- .../{AssetListItem.tsx => TokenListItem.tsx} | 87 ++++++--- .../components/ListCard/WithdrawListCard.tsx | 173 ------------------ .../src/components/ListCard/index.ts | 3 +- .../src/components/ListCard/types.ts | 51 +----- .../src/components/TokenSelector/types.ts | 4 +- libs/webb-ui-components/src/types/index.ts | 5 + .../src/utils/getRoundedAmountString.ts | 21 ++- 9 files changed, 96 insertions(+), 257 deletions(-) rename libs/webb-ui-components/src/components/ListCard/{AssetListItem.tsx => TokenListItem.tsx} (56%) delete mode 100644 libs/webb-ui-components/src/components/ListCard/WithdrawListCard.tsx diff --git a/libs/webb-ui-components/src/components/ListCard/ListItem.tsx b/libs/webb-ui-components/src/components/ListCard/ListItem.tsx index 0a1b42d75d..3e96e8e0bd 100644 --- a/libs/webb-ui-components/src/components/ListCard/ListItem.tsx +++ b/libs/webb-ui-components/src/components/ListCard/ListItem.tsx @@ -12,7 +12,10 @@ export const ListItem = forwardRef<
  • (
      {filteredSelect.map((current, idx) => ( - onItemChange(current)} diff --git a/libs/webb-ui-components/src/components/ListCard/AssetListItem.tsx b/libs/webb-ui-components/src/components/ListCard/TokenListItem.tsx similarity index 56% rename from libs/webb-ui-components/src/components/ListCard/AssetListItem.tsx rename to libs/webb-ui-components/src/components/ListCard/TokenListItem.tsx index d96b6eb89a..b058d1e8fa 100644 --- a/libs/webb-ui-components/src/components/ListCard/AssetListItem.tsx +++ b/libs/webb-ui-components/src/components/ListCard/TokenListItem.tsx @@ -1,18 +1,48 @@ import { TokenIcon } from '@webb-tools/icons'; +import React, { ComponentProps, forwardRef, useMemo, useRef } from 'react'; import { Typography } from '../../typography'; import { getRoundedAmountString } from '../../utils'; -import React, { - ComponentProps, - forwardRef, - useMemo, - useRef, - useState, -} from 'react'; +import { Button } from '../buttons'; import { ListItem } from './ListItem'; import { AssetType } from './types'; -import { Button } from '../buttons'; -export const AssetListItem = forwardRef< +const Balance = ({ + balance, + balanceInUsd, + subContent, +}: { + balance: number; + balanceInUsd?: number; + subContent?: string; +}) => { +
      + + {getRoundedAmountString(balance)} + + + {typeof balanceInUsd === 'number' ? ( + + ${getRoundedAmountString(balanceInUsd)} + + ) : typeof subContent === 'string' ? ( + + {subContent} + + ) : null} +
      ; +}; + +const TokenListItem = forwardRef< HTMLLIElement, AssetType & ComponentProps >( @@ -22,8 +52,6 @@ export const AssetListItem = forwardRef< ) => { const onTokenClickRef = useRef(onClick); - const [isHovered, setIsHovered] = useState(false); - const handleTokenIconClick = useMemo(() => { if (typeof onTokenClickRef.current === 'function') { return (event: React.MouseEvent) => { @@ -34,13 +62,7 @@ export const AssetListItem = forwardRef< }, []); return ( - setIsHovered(true)} - onMouseLeave={() => setIsHovered(false)} - > +
      {getRoundedAmountString(balance ?? 0)} - ) : isHovered ? ( - ) : ( - - -- - + <> + + + -- + + )} ); } ); + +export default TokenListItem; diff --git a/libs/webb-ui-components/src/components/ListCard/WithdrawListCard.tsx b/libs/webb-ui-components/src/components/ListCard/WithdrawListCard.tsx deleted file mode 100644 index 474cb2f339..0000000000 --- a/libs/webb-ui-components/src/components/ListCard/WithdrawListCard.tsx +++ /dev/null @@ -1,173 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -//@ts-ignore -import startImg from '../../assets/star.png'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -//@ts-ignore -import startDarkImg from '../../assets/star-dark.png'; -import { Typography } from '../../typography'; -import cx from 'classnames'; -import { forwardRef, MouseEventHandler, useMemo } from 'react'; - -import { Button } from '../buttons'; -import { ScrollArea } from '../ScrollArea'; -import { TokenPair } from '../TokenPair'; -import { ListCardWrapper } from './ListCardWrapper'; -import { ListItem } from './ListItem'; -import { WithDrawListCardProps } from './types'; - -export const WithDrawListCard = forwardRef< - HTMLDivElement, - WithDrawListCardProps ->( - ( - { - assetPairs, - isDisconnected, - onChange, - onClose, - onConnectWallet, - onRecoverWithSecretNote, - onSwitchWallet, - title = 'Select Asset to Withdraw', - value, - ...props - }, - ref - ) => { - return ( - - {/** Token list */} - {assetPairs && assetPairs.length > 0 && !isDisconnected && ( -
      - - Available shielded tokens - - -
        - {assetPairs.map((current, idx) => { - return ( - - - - ); - })} -
      -
      -
      - )} - - {(!assetPairs || !assetPairs.length) && ( -
      - - {isDisconnected - ? 'Connect your wallet to view available assets.' - : "Looks like you don't have any assets. When you make a deposit, it will show up here."} - - -
      - star - - star-dark -
      -
      - )} - - {/** Disconnect view */} - - - -
      - ); - } -); diff --git a/libs/webb-ui-components/src/components/ListCard/index.ts b/libs/webb-ui-components/src/components/ListCard/index.ts index ee185deec5..35487059f0 100644 --- a/libs/webb-ui-components/src/components/ListCard/index.ts +++ b/libs/webb-ui-components/src/components/ListCard/index.ts @@ -1,7 +1,6 @@ -export * from './AssetListItem'; export * from './ChainListCard'; export * from './ListCardWrapper'; export * from './ListItem'; export * from './RelayerListCard'; export * from './TokenListCard'; -export * from './WithdrawListCard'; +export { default as TokenListItem } from './TokenListItem'; diff --git a/libs/webb-ui-components/src/components/ListCard/types.ts b/libs/webb-ui-components/src/components/ListCard/types.ts index 4cfed5a1d7..4343370cc2 100644 --- a/libs/webb-ui-components/src/components/ListCard/types.ts +++ b/libs/webb-ui-components/src/components/ListCard/types.ts @@ -1,5 +1,5 @@ import { ComponentProps } from 'react'; -import { IWebbComponentBase, PropsOf } from '../../types'; +import { IWebbComponentBase, PropsOf, TokenType } from '../../types'; import { AvatarProps } from '../Avatar'; import { ScrollArea } from '../ScrollArea'; @@ -68,6 +68,12 @@ export type AssetType = { * Check if the token is added to metamask */ isTokenAddedToMetamask?: boolean; + + /** + * The token type + * @default 'unshielded' + */ + tokenType?: TokenType; }; export interface ListCardWrapperProps @@ -212,46 +218,3 @@ export interface TokenListCardProps */ txnType?: 'deposit' | 'transfer' | 'withdraw'; } - -export interface WithDrawListCardProps - extends Omit { - /** - * Optional card title to change the title of the card - */ - title: string; - - /** - * The asset pair list - */ - assetPairs?: AssetType[]; - - /** - * The current selected asset, use to control the component - */ - value?: AssetType; - - /** - * The callback to control the value of the component - */ - onChange?: (nextAsset: AssetType) => void; - - /** - * If `true`, the component will display in connected view - */ - isDisconnected?: boolean; - - /** - * Callback being invoked when user hits switch wallet button - */ - onSwitchWallet?: PropsOf<'div'>['onClick']; - - /** - * Callback being invoked when user hits recover from secret note - */ - onRecoverWithSecretNote?: PropsOf<'div'>['onClick']; - - /** - * Callback being invoked when user hits connect wallet button - */ - onConnectWallet?: PropsOf<'div'>['onClick']; -} diff --git a/libs/webb-ui-components/src/components/TokenSelector/types.ts b/libs/webb-ui-components/src/components/TokenSelector/types.ts index a13d652a0f..253a5fe150 100644 --- a/libs/webb-ui-components/src/components/TokenSelector/types.ts +++ b/libs/webb-ui-components/src/components/TokenSelector/types.ts @@ -1,6 +1,4 @@ -import { IWebbComponentBase, PropsOf } from '../../types'; - -export type TokenType = 'shielded' | 'unshielded'; +import { IWebbComponentBase, PropsOf, TokenType } from '../../types'; export interface TokenSelectorProps extends IWebbComponentBase, diff --git a/libs/webb-ui-components/src/types/index.ts b/libs/webb-ui-components/src/types/index.ts index 7abf44553a..ebd079fb42 100644 --- a/libs/webb-ui-components/src/types/index.ts +++ b/libs/webb-ui-components/src/types/index.ts @@ -156,6 +156,11 @@ export interface KeygenType { nextKeyId?: string; } +/** + * The supported token type + */ +export type TokenType = 'shielded' | 'unshielded'; + /***************** * UTILITY TYPES * *****************/ diff --git a/libs/webb-ui-components/src/utils/getRoundedAmountString.ts b/libs/webb-ui-components/src/utils/getRoundedAmountString.ts index cf3f5fa6d9..d8ad405002 100644 --- a/libs/webb-ui-components/src/utils/getRoundedAmountString.ts +++ b/libs/webb-ui-components/src/utils/getRoundedAmountString.ts @@ -1,5 +1,13 @@ import numbro from 'numbro'; +export interface RoundedAmountFormatOptions extends numbro.Format { + /** + * The default placeholder to use when formatting a value with no value + * @default '-' + */ + defaultPlaceholder?: string; +} + /** * Return dynamic 0.001 format based on number of digits * to display @@ -26,14 +34,20 @@ export function getDecimals(digit: number): number { export function getRoundedAmountString( num: number | undefined, digits = 3, - formatOption: numbro.Format = { roundingFunction: Math.floor } + formatOption: RoundedAmountFormatOptions = {} ): string { + const { + roundingFunction = Math.floor, + defaultPlaceholder = '-', + ...restOpts + } = formatOption; + if (num === 0) { return '0'; } if (!num) { - return '-'; + return defaultPlaceholder; } if (num < 0) { @@ -52,6 +66,7 @@ export function getRoundedAmountString( optionalMantissa: true, trimMantissa: true, thousandSeparated: true, - ...formatOption, + roundingFunction, + ...restOpts, }); } From d774f6b5deb25bb92a79cb02eb728c85e38f6b5b Mon Sep 17 00:00:00 2001 From: AtelyPham Date: Wed, 9 Aug 2023 22:19:27 +0700 Subject: [PATCH 04/14] feat: add subcomponents for TokenListItem --- .../src/components/Badge/Badge.tsx | 68 ++++++++++++++++++ .../src/components/Badge/index.ts | 6 ++ .../src/components/Badge/types.ts | 18 +++++ .../src/components/ListCard/TokenListItem.tsx | 69 ++++++++++++++++++- yarn.lock | 46 ++++++------- 5 files changed, 182 insertions(+), 25 deletions(-) create mode 100644 libs/webb-ui-components/src/components/Badge/Badge.tsx create mode 100644 libs/webb-ui-components/src/components/Badge/index.ts create mode 100644 libs/webb-ui-components/src/components/Badge/types.ts diff --git a/libs/webb-ui-components/src/components/Badge/Badge.tsx b/libs/webb-ui-components/src/components/Badge/Badge.tsx new file mode 100644 index 0000000000..75a0605022 --- /dev/null +++ b/libs/webb-ui-components/src/components/Badge/Badge.tsx @@ -0,0 +1,68 @@ +import { CheckboxBlankCircleLine } from '@webb-tools/icons'; +import { cloneElement, forwardRef } from 'react'; +import { BadgeColor, BadgeProps } from './types'; +import cx from 'classnames'; +import { twMerge } from 'tailwind-merge'; + +const classNames: { + [key in BadgeColor]: { + icon: string; + wrapper: string; + }; +} = { + green: { + icon: cx('fill-green-90 dark:fill-green-30'), + wrapper: cx('fill-green-10 dark:fill-green-120'), + }, + blue: { + icon: cx('fill-blue-90 dark:fill-blue-30'), + wrapper: cx('fill-blue-10 dark:fill-blue-120'), + }, + purple: { + icon: cx('fill-purpose-90 dark:fill-purpose-30'), + wrapper: cx('fill-purpose-10 dark:fill-purpose-120'), + }, + red: { + icon: cx('fill-red-90 dark:fill-red-30'), + wrapper: cx('fill-red-10 dark:fill-red-120'), + }, + yellow: { + icon: cx('fill-yellow-90 dark:fill-yellow-30'), + wrapper: cx('fill-yellow-10 dark:fill-yellow-120'), + }, +}; + +const Badge = forwardRef( + ({ icon = , color = 'blue', ...props }, ref) => { + return ( + + + + {cloneElement(icon, { + ...icon.props, + className: twMerge(icon.props.className, classNames[color].icon), + size: 'md', + })} + + + + ); + } +); + +export default Badge; diff --git a/libs/webb-ui-components/src/components/Badge/index.ts b/libs/webb-ui-components/src/components/Badge/index.ts new file mode 100644 index 0000000000..54c3c605b8 --- /dev/null +++ b/libs/webb-ui-components/src/components/Badge/index.ts @@ -0,0 +1,6 @@ +import Badge from './Badge'; + +export * from './Badge'; +export { default as Badge } from './Badge'; + +export default Badge; diff --git a/libs/webb-ui-components/src/components/Badge/types.ts b/libs/webb-ui-components/src/components/Badge/types.ts new file mode 100644 index 0000000000..7223042356 --- /dev/null +++ b/libs/webb-ui-components/src/components/Badge/types.ts @@ -0,0 +1,18 @@ +import { IconBase } from '@webb-tools/icons/types'; +import { PropsOf } from '../../types'; + +export type BadgeColor = 'green' | 'blue' | 'purple' | 'red' | 'yellow'; + +export interface BadgeProps extends PropsOf<'svg'> { + /** + * The icon to be used in the badge. + * @default + */ + icon?: React.ReactElement; + + /** + * The color of the badge. + * @default 'blue' + */ + color?: BadgeColor; +} diff --git a/libs/webb-ui-components/src/components/ListCard/TokenListItem.tsx b/libs/webb-ui-components/src/components/ListCard/TokenListItem.tsx index b058d1e8fa..ae801e1b43 100644 --- a/libs/webb-ui-components/src/components/ListCard/TokenListItem.tsx +++ b/libs/webb-ui-components/src/components/ListCard/TokenListItem.tsx @@ -2,9 +2,11 @@ import { TokenIcon } from '@webb-tools/icons'; import React, { ComponentProps, forwardRef, useMemo, useRef } from 'react'; import { Typography } from '../../typography'; import { getRoundedAmountString } from '../../utils'; +import { IconWithTooltip } from '../IconWithTooltip'; import { Button } from '../buttons'; import { ListItem } from './ListItem'; import { AssetType } from './types'; +import Badge from '../Badge'; const Balance = ({ balance, @@ -42,7 +44,51 @@ const Balance = ({
      ; }; -const TokenListItem = forwardRef< +const AddToWalletButton = ({ onClick }: { onClick: () => void }) => ( + <> + + + -- + + +); + +const BadgeInfo = ({ + variant, + children, +}: { + variant: 'info' | 'warning'; + children: React.ReactNode; +}) => { + let color: ComponentProps['color'] = 'blue'; + + switch (variant) { + case 'warning': { + color = 'yellow'; + break; + } + + default: { + color = 'blue'; + break; + } + } + + return } content={children} />; +}; + +const TokenListItem_ = forwardRef< HTMLLIElement, AssetType & ComponentProps >( @@ -101,7 +147,8 @@ const TokenListItem = forwardRef< @@ -119,4 +166,22 @@ const TokenListItem = forwardRef< } ); +interface ITokenListItem + extends React.ForwardRefExoticComponent< + AssetType & + ComponentProps & + React.RefAttributes + > { + Balance: typeof Balance; + AddToWalletButton: typeof AddToWalletButton; + BadgeInfo: typeof BadgeInfo; +} + +const TokenListItem = { + ...TokenListItem_, + Balance, + AddToWalletButton, + BadgeInfo, +} as ITokenListItem; + export default TokenListItem; diff --git a/yarn.lock b/yarn.lock index 926b4e4ec4..e6c2417082 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6824,12 +6824,12 @@ resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-7.0.25.tgz#a2754a8af5de78a47a0bc2193f3baf80e302ad7b" integrity sha512-abM0M+H19eZu0dRK+/2PB0W9b7xXFhiPddXpFCjIfJQFGPIwGBWVAFot1bKR5Mu4IB9OftkJYMRtYEEBrNep3A== -"@storybook/core-events@7.0.27": - version "7.0.27" - resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-7.0.27.tgz#94c7f8877998a25e8d14bafa51839fedfa442769" - integrity sha512-sNnqgO5i5DUIqeQfNbr987KWvAciMN9FmMBuYdKjVFMqWFyr44HTgnhfKwZZKl+VMDYkHA9Do7UGSYZIKy0P4g== +"@storybook/core-events@7.1.1": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-7.1.1.tgz#c2c30085bd254a27cdbd266a8e7755876abf9361" + integrity sha512-P5iI4zvCJo85de/sghglEHFK/GGkWAQQKzRFrz9kbVBX5LNaosfD7IYHIz/6ZWNPzxWR+RBOKcrRUfcArL4Njg== -"@storybook/core-events@7.2.1", "@storybook/core-events@^7.0.0": +"@storybook/core-events@7.2.1", "@storybook/core-events@^7.0.12": version "7.2.1" resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-7.2.1.tgz#05121c9bac6ac3989acc05b49116107331e0c398" integrity sha512-EUXYb3gyQ2EzpDAWkgfoDl1EPabj3OE6+zntsD/gwvzQU85BTocs10ksnRyS55bfrQpYbf+Z+gw2CZboyagLgg== @@ -7245,18 +7245,17 @@ ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/preview-api@^7.0.12": - version "7.1.1" - resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-7.1.1.tgz#5093b5a05ec75394193b05a45358193c0dff5e86" - integrity sha512-uI8TVuoFfg3EBdaKdRVUa17JfGdmK78JI3+byLZLkzl6nR+q846BWHgi8eJmU8MHmO5CFaqT2kts/e8T34JDgw== +"@storybook/preview-api@7.2.1": + version "7.2.1" + resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-7.2.1.tgz#0de54f11237d837db918d672e7f4c2bc34abf8f7" + integrity sha512-WKecuOdeh9+og6bPR9KoQf/JCeSRPCcfZv9uNfJzAp3IiTnS3UpfCz+HBZzZJQrisgbd7OulNY400HQUmxY2Ag== dependencies: - "@storybook/channel-postmessage" "7.1.1" - "@storybook/channels" "7.1.1" - "@storybook/client-logger" "7.1.1" - "@storybook/core-events" "7.1.1" + "@storybook/channels" "7.2.1" + "@storybook/client-logger" "7.2.1" + "@storybook/core-events" "7.2.1" "@storybook/csf" "^0.1.0" "@storybook/global" "^5.0.0" - "@storybook/types" "7.1.1" + "@storybook/types" "7.2.1" "@types/qs" "^6.9.5" dequal "^2.0.2" lodash "^4.17.21" @@ -7266,17 +7265,18 @@ ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/preview-api@7.2.1": - version "7.2.1" - resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-7.2.1.tgz#0de54f11237d837db918d672e7f4c2bc34abf8f7" - integrity sha512-WKecuOdeh9+og6bPR9KoQf/JCeSRPCcfZv9uNfJzAp3IiTnS3UpfCz+HBZzZJQrisgbd7OulNY400HQUmxY2Ag== +"@storybook/preview-api@^7.0.12": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-7.1.1.tgz#5093b5a05ec75394193b05a45358193c0dff5e86" + integrity sha512-uI8TVuoFfg3EBdaKdRVUa17JfGdmK78JI3+byLZLkzl6nR+q846BWHgi8eJmU8MHmO5CFaqT2kts/e8T34JDgw== dependencies: - "@storybook/channels" "7.2.1" - "@storybook/client-logger" "7.2.1" - "@storybook/core-events" "7.2.1" + "@storybook/channel-postmessage" "7.1.1" + "@storybook/channels" "7.1.1" + "@storybook/client-logger" "7.1.1" + "@storybook/core-events" "7.1.1" "@storybook/csf" "^0.1.0" "@storybook/global" "^5.0.0" - "@storybook/types" "7.2.1" + "@storybook/types" "7.1.1" "@types/qs" "^6.9.5" dequal "^2.0.2" lodash "^4.17.21" @@ -21212,7 +21212,7 @@ postcss-selector-not@^7.0.1: dependencies: postcss-selector-parser "^6.0.10" -postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: +postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: version "6.0.13" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz#d05d8d76b1e8e173257ef9d60b706a8e5e99bf1b" integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ== From 8dc65f723bb9de8be34981f5d8428b8063ff5fdd Mon Sep 17 00:00:00 2001 From: AtelyPham Date: Thu, 10 Aug 2023 01:24:06 +0700 Subject: [PATCH 05/14] chore: add Storybook and fix UI issues --- libs/icons/src/AlertFill.tsx | 1 - libs/icons/src/CheckboxBlankCircleLine.tsx | 2 +- .../src/components/Badge/Badge.tsx | 6 +- .../src/components/ListCard/ListItem.tsx | 9 +- .../src/components/ListCard/TokenListCard.tsx | 9 +- .../src/components/ListCard/TokenListItem.tsx | 181 ++++++++---------- .../src/components/ListCard/types.ts | 50 ++++- .../src/components/index.ts | 2 + .../molecules/TokenListItem.stories.tsx | 65 +++++++ 9 files changed, 204 insertions(+), 121 deletions(-) create mode 100644 libs/webb-ui-components/src/stories/molecules/TokenListItem.stories.tsx diff --git a/libs/icons/src/AlertFill.tsx b/libs/icons/src/AlertFill.tsx index 25c556d5c6..22705c212e 100644 --- a/libs/icons/src/AlertFill.tsx +++ b/libs/icons/src/AlertFill.tsx @@ -4,7 +4,6 @@ import { IconBase } from './types'; export const AlertFill = (props: IconBase) => { return createIcon({ ...props, - viewBox: '0 0 22 22', d: 'M12.865 3.00017L22.3912 19.5002C22.6674 19.9785 22.5035 20.5901 22.0252 20.8662C21.8732 20.954 21.7008 21.0002 21.5252 21.0002H2.47266C1.92037 21.0002 1.47266 20.5525 1.47266 20.0002C1.47266 19.8246 1.51886 19.6522 1.60663 19.5002L11.1329 3.00017C11.4091 2.52187 12.0206 2.358 12.4989 2.63414C12.651 2.72191 12.7772 2.84815 12.865 3.00017ZM10.9989 16.0002V18.0002H12.9989V16.0002H10.9989ZM10.9989 9.00017V14.0002H12.9989V9.00017H10.9989Z', displayName: 'AlertFill', }); diff --git a/libs/icons/src/CheckboxBlankCircleLine.tsx b/libs/icons/src/CheckboxBlankCircleLine.tsx index 5fcd8e9f33..e79441a3c9 100644 --- a/libs/icons/src/CheckboxBlankCircleLine.tsx +++ b/libs/icons/src/CheckboxBlankCircleLine.tsx @@ -4,7 +4,7 @@ import { IconBase } from './types'; export const CheckboxBlankCircleLine = (props: IconBase) => { return createIcon({ ...props, - d: 'M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 100-16.001A8 8 0 0012 20zm-.997-4L6.76 11.757l1.414-1.414 2.829 2.829 5.656-5.657 1.415 1.414L11.003 16z', + d: 'M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20Z', displayName: 'CheckboxBlankCircleLine', }); }; diff --git a/libs/webb-ui-components/src/components/Badge/Badge.tsx b/libs/webb-ui-components/src/components/Badge/Badge.tsx index 75a0605022..2673409c76 100644 --- a/libs/webb-ui-components/src/components/Badge/Badge.tsx +++ b/libs/webb-ui-components/src/components/Badge/Badge.tsx @@ -49,17 +49,13 @@ const Badge = forwardRef( rx={12} className={classNames[color].wrapper} /> - + {cloneElement(icon, { ...icon.props, className: twMerge(icon.props.className, classNames[color].icon), size: 'md', })} - ); } diff --git a/libs/webb-ui-components/src/components/ListCard/ListItem.tsx b/libs/webb-ui-components/src/components/ListCard/ListItem.tsx index 3e96e8e0bd..c956ab2296 100644 --- a/libs/webb-ui-components/src/components/ListCard/ListItem.tsx +++ b/libs/webb-ui-components/src/components/ListCard/ListItem.tsx @@ -12,11 +12,14 @@ export const ListItem = forwardRef<
    • ( }, ref ) => { - const [, setAsset] = useState(() => selectedAsset); - // Search text const [searchText, setSearchText] = useState(''); @@ -36,7 +34,9 @@ export const TokenListCard = forwardRef( (r) => r.name.toLowerCase().includes(searchText.toLowerCase()) || r.symbol.toString().includes(searchText.toLowerCase()) || - r.balance?.toString().includes(searchText.toLowerCase()) + r.assetBalanceProps?.balance + ?.toString() + .includes(searchText.toLowerCase()) ), [searchText] ); @@ -53,10 +53,9 @@ export const TokenListCard = forwardRef( return; } - setAsset(nextItem); onChange?.(nextItem); }, - [onChange, setAsset, unavailableTokens] + [onChange, unavailableTokens] ); const { filteredPopular, filteredSelect } = useMemo( diff --git a/libs/webb-ui-components/src/components/ListCard/TokenListItem.tsx b/libs/webb-ui-components/src/components/ListCard/TokenListItem.tsx index ae801e1b43..e07709173e 100644 --- a/libs/webb-ui-components/src/components/ListCard/TokenListItem.tsx +++ b/libs/webb-ui-components/src/components/ListCard/TokenListItem.tsx @@ -1,50 +1,49 @@ -import { TokenIcon } from '@webb-tools/icons'; +import { AlertFill, TokenIcon } from '@webb-tools/icons'; import React, { ComponentProps, forwardRef, useMemo, useRef } from 'react'; +import { PropsOf } from '../../types'; import { Typography } from '../../typography'; import { getRoundedAmountString } from '../../utils'; +import Badge from '../Badge'; import { IconWithTooltip } from '../IconWithTooltip'; import { Button } from '../buttons'; import { ListItem } from './ListItem'; -import { AssetType } from './types'; -import Badge from '../Badge'; - -const Balance = ({ - balance, - balanceInUsd, - subContent, -}: { - balance: number; - balanceInUsd?: number; - subContent?: string; -}) => { -
      - - {getRoundedAmountString(balance)} - +import { AssetBadgeInfoType, AssetBalanceType, AssetType } from './types'; - {typeof balanceInUsd === 'number' ? ( - - ${getRoundedAmountString(balanceInUsd)} +const Balance = ({ balance, balanceInUsd, subContent }: AssetBalanceType) => { + return ( +
      + + {getRoundedAmountString(balance)} - ) : typeof subContent === 'string' ? ( - - {subContent} - - ) : null} -
      ; + + {typeof balanceInUsd === 'number' ? ( + + ${getRoundedAmountString(balanceInUsd)} + + ) : typeof subContent === 'string' ? ( + + {subContent} + + ) : null} +
      + ); }; -const AddToWalletButton = ({ onClick }: { onClick: () => void }) => ( +const AddToWalletButton = ({ + onClick, +}: { + onClick: NonNullable['onClick']>; +}) => ( <> - - -- - - - )} + {typeof handleTokenIconClick === 'function' && !isDisabled ? ( + + ) : typeof assetBalanceProps === 'object' ? ( + + ) : typeof assetBadgeProps === 'object' ? ( + + ) : null} ); } ); -interface ITokenListItem - extends React.ForwardRefExoticComponent< - AssetType & - ComponentProps & - React.RefAttributes - > { - Balance: typeof Balance; - AddToWalletButton: typeof AddToWalletButton; - BadgeInfo: typeof BadgeInfo; -} - -const TokenListItem = { - ...TokenListItem_, - Balance, - AddToWalletButton, - BadgeInfo, -} as ITokenListItem; - export default TokenListItem; diff --git a/libs/webb-ui-components/src/components/ListCard/types.ts b/libs/webb-ui-components/src/components/ListCard/types.ts index 4343370cc2..fb3ec34fe2 100644 --- a/libs/webb-ui-components/src/components/ListCard/types.ts +++ b/libs/webb-ui-components/src/components/ListCard/types.ts @@ -48,6 +48,35 @@ export type RelayerType = { theme?: AvatarProps['theme']; }; +export type AssetBalanceType = { + /** + * The asset balance of user + */ + balance?: number; + + /** + * The asset balance in USD + */ + balanceInUsd?: number; + + /** + * The sub content below the balance + */ + subContent?: string; +}; + +export type AssetBadgeInfoType = { + /** + * The badge variant + */ + variant: 'info' | 'warning'; + + /** + * The badge content + */ + children: React.ReactNode; +}; + export type AssetType = { /** * The asset name @@ -60,20 +89,27 @@ export type AssetType = { symbol: string; /** - * The asset balance of user + * Callback when user hit the add token button */ - balance?: number; - - /** - * Check if the token is added to metamask - */ - isTokenAddedToMetamask?: boolean; + onAddToken?: PropsOf<'button'>['onClick']; /** * The token type * @default 'unshielded' */ tokenType?: TokenType; + + /** + * The asset balance props + * @type {AssetBalanceType} + */ + assetBalanceProps?: AssetBalanceType; + + /** + * The asset badge props + * @type {AssetBadgeInfoType} + */ + assetBadgeProps?: AssetBadgeInfoType; }; export interface ListCardWrapperProps diff --git a/libs/webb-ui-components/src/components/index.ts b/libs/webb-ui-components/src/components/index.ts index d68fe6b29f..0e2ddda1ea 100644 --- a/libs/webb-ui-components/src/components/index.ts +++ b/libs/webb-ui-components/src/components/index.ts @@ -1,5 +1,7 @@ export * from './Accordion'; export * from './Alert'; +export * from './Badge'; +export { default as Badge } from './Badge'; export * from './AmountMenu'; export * from './Avatar'; export * from './AvatarGroup'; diff --git a/libs/webb-ui-components/src/stories/molecules/TokenListItem.stories.tsx b/libs/webb-ui-components/src/stories/molecules/TokenListItem.stories.tsx new file mode 100644 index 0000000000..03efdf2737 --- /dev/null +++ b/libs/webb-ui-components/src/stories/molecules/TokenListItem.stories.tsx @@ -0,0 +1,65 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import TokenListItem from '../../components/ListCard/TokenListItem'; +import noop from 'lodash/noop'; + +const meta: Meta = { + title: 'Design System/V2 (WIP)/Molecules/TokenListItem', + component: TokenListItem, +}; + +// More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export +export default meta; + +type Story = StoryObj; + +// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args +export const Default: Story = { + render: () => , +}; + +export const Disabled: Story = { + render: () => , +}; + +export const WithBalance: Story = { + render: () => ( + + ), +}; + +export const AddTokenToWallet: Story = { + render: () => ( + + ), +}; + +export const WithWarningBadge: Story = { + render: () => ( + + ), +}; + +export const WithInfoBadge: Story = { + render: () => ( + + ), +}; From 6fa7d99ea0e890d670fc368e64475fa14c50c1c8 Mon Sep 17 00:00:00 2001 From: AtelyPham Date: Thu, 10 Aug 2023 01:31:13 +0700 Subject: [PATCH 06/14] chore: update webb token for Storybook --- .../src/stories/molecules/TokenListItem.stories.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/webb-ui-components/src/stories/molecules/TokenListItem.stories.tsx b/libs/webb-ui-components/src/stories/molecules/TokenListItem.stories.tsx index 03efdf2737..64da403705 100644 --- a/libs/webb-ui-components/src/stories/molecules/TokenListItem.stories.tsx +++ b/libs/webb-ui-components/src/stories/molecules/TokenListItem.stories.tsx @@ -41,8 +41,8 @@ export const AddTokenToWallet: Story = { export const WithWarningBadge: Story = { render: () => ( ( Date: Thu, 10 Aug 2023 02:10:05 +0700 Subject: [PATCH 07/14] fix: compative new API for TokenListItem --- .../DepositContainer/DepositContainer.tsx | 49 ++++++++++++------- .../TransferContainer/TransferContainer.tsx | 24 +++++---- .../WithdrawContainer/WithdrawContainer.tsx | 43 ++++++++-------- 3 files changed, 68 insertions(+), 48 deletions(-) diff --git a/apps/bridge-dapp/src/containers/DepositContainer/DepositContainer.tsx b/apps/bridge-dapp/src/containers/DepositContainer/DepositContainer.tsx index a204cf1fbe..68d0283df8 100644 --- a/apps/bridge-dapp/src/containers/DepositContainer/DepositContainer.tsx +++ b/apps/bridge-dapp/src/containers/DepositContainer/DepositContainer.tsx @@ -248,15 +248,19 @@ export const DepositContainer = forwardRef< return { name: currency.view.name, symbol: currency.view.symbol, - balance: balances[currency.id], - onTokenClick: () => addCurrency(currency), - isTokenAddedToMetamask: isTokenAddedToMetamask( + assetBalanceProps: + typeof balances[currency.id] === 'number' + ? { balance: balances[currency.id] } + : undefined, + onAddToken: isTokenAddedToMetamask( currency, activeChain, activeAccount?.address, currentResourceId - ), - }; + ) + ? undefined + : () => addCurrency(currency), + } satisfies AssetType; } ); }, [ @@ -283,8 +287,11 @@ export const DepositContainer = forwardRef< return { name: currency.name, symbol: currency.symbol, - balance: balances[currency.id], - }; + assetBalanceProps: + typeof balances[currency.id] === 'number' + ? { balance: balances[currency.id] } + : undefined, + } satisfies AssetType; }); }, [currencies, populatedSelectableWebbTokens, balances]); @@ -599,18 +606,22 @@ export const DepositContainer = forwardRef< } const tokens = getPossibleFungibleCurrencies(wrappableCurrency.id).map( - (currency): AssetType => ({ - name: currency.view.name, - balance: balances[currency.id] ?? 0, - symbol: currency.view.symbol, - onTokenClick: () => addCurrency(currency), - isTokenAddedToMetamask: isTokenAddedToMetamask( - currency, - activeChain, - activeAccount?.address, - currentResourceId - ), - }) + (currency): AssetType => + ({ + name: currency.view.name, + assetBalanceProps: { + balance: balances[currency.id] ?? 0, + }, + symbol: currency.view.symbol, + onAddToken: isTokenAddedToMetamask( + currency, + activeChain, + activeAccount?.address, + currentResourceId + ) + ? undefined + : () => addCurrency(currency), + } satisfies AssetType) ); return { diff --git a/apps/bridge-dapp/src/containers/TransferContainer/TransferContainer.tsx b/apps/bridge-dapp/src/containers/TransferContainer/TransferContainer.tsx index ca8dc5c932..1c81dcdf80 100644 --- a/apps/bridge-dapp/src/containers/TransferContainer/TransferContainer.tsx +++ b/apps/bridge-dapp/src/containers/TransferContainer/TransferContainer.tsx @@ -243,14 +243,16 @@ export const TransferContainer = forwardRef< acc.push({ name: currency.view.name, symbol: currency.view.symbol, - balance, - onTokenClick: () => addCurrency(currency), - isTokenAddedToMetamask: isTokenAddedToMetamask( + assetBalanceProps: + typeof balance === 'number' ? { balance } : undefined, + onAddToken: isTokenAddedToMetamask( currency, activeChain, activeAccount?.address, currentResourceId - ), + ) + ? undefined + : () => addCurrency(currency), }); return acc; @@ -398,7 +400,8 @@ export const TransferContainer = forwardRef< const onAmountChange = useCallback( (amount: string): void => { const parsedAmount = Number(amount); - const availableAmount = selectedBridgingAsset?.balance ?? 0; + const availableAmount = + selectedBridgingAsset?.assetBalanceProps?.balance ?? 0; if (isNaN(parsedAmount) || parsedAmount < 0) { setAmountError('Invalid amount'); @@ -413,7 +416,7 @@ export const TransferContainer = forwardRef< setTransferAmount(parsedAmount); setAmountError(''); }, - [selectedBridgingAsset?.balance] + [selectedBridgingAsset?.assetBalanceProps?.balance] ); // Callback for relayer input clicked @@ -481,9 +484,10 @@ export const TransferContainer = forwardRef< return ( typeof transferAmount === 'number' && transferAmount > 0 && - transferAmount <= (selectedBridgingAsset?.balance ?? 0) + transferAmount <= + (selectedBridgingAsset?.assetBalanceProps?.balance ?? 0) ); - }, [transferAmount, selectedBridgingAsset?.balance]); + }, [transferAmount, selectedBridgingAsset?.assetBalanceProps?.balance]); // The actual amount to be transferred const receivingAmount = useMemo(() => { @@ -912,7 +916,9 @@ export const TransferContainer = forwardRef< errorMessage: amountError, isDisabled: !selectedBridgingAsset || needSwitchChain, onMaxBtnClick: () => - setTransferAmount(selectedBridgingAsset?.balance ?? 0), + setTransferAmount( + selectedBridgingAsset?.assetBalanceProps?.balance ?? 0 + ), }; }, [ transferAmount, diff --git a/apps/bridge-dapp/src/containers/WithdrawContainer/WithdrawContainer.tsx b/apps/bridge-dapp/src/containers/WithdrawContainer/WithdrawContainer.tsx index a89732d63f..6e14c4eb9a 100644 --- a/apps/bridge-dapp/src/containers/WithdrawContainer/WithdrawContainer.tsx +++ b/apps/bridge-dapp/src/containers/WithdrawContainer/WithdrawContainer.tsx @@ -224,16 +224,16 @@ export const WithdrawContainer = forwardRef< return { symbol: fungibleCurrency.view.symbol, name: fungibleCurrency.view.name, - balance, - onTokenClick: () => addCurrency(fungibleCurrency), - balanceType: 'note', - isTokenAddedToMetamask: isTokenAddedToMetamask( + assetBalanceProps: typeof balance === 'number' ? { balance } : undefined, + onAddToken: isTokenAddedToMetamask( fungibleCurrency, activeChain, activeAccount?.address, currentResourceId - ), - }; + ) + ? undefined + : () => addCurrency(fungibleCurrency), + } satisfies AssetType; }, [ addCurrency, balancesFromNotes, @@ -251,15 +251,15 @@ export const WithdrawContainer = forwardRef< return { symbol: wrappableCurrency.view.symbol, name: wrappableCurrency.view.name, - onTokenClick: () => addCurrency(wrappableCurrency), - balanceType: 'wallet', - isTokenAddedToMetamask: isTokenAddedToMetamask( + onAddToken: isTokenAddedToMetamask( wrappableCurrency, activeChain, activeAccount?.address, currentResourceId - ), - }; + ) + ? undefined + : () => addCurrency(wrappableCurrency), + } satisfies AssetType; }, [ addCurrency, wrappableCurrency, @@ -732,15 +732,17 @@ export const WithdrawContainer = forwardRef< return { name: currency.view.name, symbol: currency.view.symbol, - balance, - onTokenClick: () => addCurrency(currency), - isTokenAddedToMetamask: isTokenAddedToMetamask( + assetBalanceProps: + typeof balance === 'number' ? { balance } : undefined, + onAddToken: isTokenAddedToMetamask( currency, activeChain, activeAccount?.address, currentResourceId - ), - }; + ) + ? undefined + : () => addCurrency(currency), + } satisfies AssetType; } ); @@ -785,14 +787,15 @@ export const WithdrawContainer = forwardRef< return { name: currency.view.name, symbol: currency.view.symbol, - onTokenClick: () => addCurrency(currency), - isTokenAddedToMetamask: isTokenAddedToMetamask( + onAddToken: isTokenAddedToMetamask( currency, activeChain, activeAccount?.address, currentResourceId - ), - }; + ) + ? undefined + : () => addCurrency(currency), + } satisfies AssetType; }); setMainComponent( From 554588d4d9d202f57eeef23b9dcca50650bf7115 Mon Sep 17 00:00:00 2001 From: AtelyPham Date: Fri, 11 Aug 2023 01:05:16 +0700 Subject: [PATCH 08/14] feat: add shielded opts for TokenListItem --- libs/icons/src/ShieldedAssetIcon.tsx | 41 +++++++++++++++++-- .../src/components/ListCard/TokenListItem.tsx | 34 +++++++++++++-- .../src/components/ListCard/types.ts | 10 +++++ .../molecules/TokenListItem.stories.tsx | 30 ++++++++++++++ 4 files changed, 107 insertions(+), 8 deletions(-) diff --git a/libs/icons/src/ShieldedAssetIcon.tsx b/libs/icons/src/ShieldedAssetIcon.tsx index 57d59d2de0..f61132a2b8 100644 --- a/libs/icons/src/ShieldedAssetIcon.tsx +++ b/libs/icons/src/ShieldedAssetIcon.tsx @@ -1,6 +1,6 @@ -import { twMerge } from 'tailwind-merge'; import cx from 'classnames'; -import { createIcon } from './create-icon'; +import { twMerge } from 'tailwind-merge'; +import { ChainIcon } from './ChainIcon'; import { IconBase } from './types'; const getSizeProps = (size: IconBase['size']) => { @@ -30,12 +30,17 @@ interface ShieldedAssetIconProps extends IconBase { * Whether to display the placeholder icon or not */ displayPlaceholder?: boolean; + + /** + * Chain name to display on the chain icon + */ + chainName?: string; } -const ShieldedAssetIcon = ({ +const ShieldedAssetIconInner = ({ displayPlaceholder, ...props -}: ShieldedAssetIconProps) => { +}: Omit) => { return ( { + if (typeof chainName === 'string' && !displayPlaceholder) { + return ( +
      + + +
      + ); + } + + return ( + + ); +}; + export default ShieldedAssetIcon; diff --git a/libs/webb-ui-components/src/components/ListCard/TokenListItem.tsx b/libs/webb-ui-components/src/components/ListCard/TokenListItem.tsx index e07709173e..3380c1eefc 100644 --- a/libs/webb-ui-components/src/components/ListCard/TokenListItem.tsx +++ b/libs/webb-ui-components/src/components/ListCard/TokenListItem.tsx @@ -1,4 +1,9 @@ -import { AlertFill, TokenIcon } from '@webb-tools/icons'; +import { + AlertFill, + ExternalLinkLine, + ShieldedAssetIcon, + TokenIcon, +} from '@webb-tools/icons'; import React, { ComponentProps, forwardRef, useMemo, useRef } from 'react'; import { PropsOf } from '../../types'; import { Typography } from '../../typography'; @@ -110,10 +115,13 @@ const TokenListItem = forwardRef< { assetBadgeProps, assetBalanceProps, + chainName, + explorerUrl, isDisabled, name, onAddToken, symbol, + tokenType = 'unshielded', ...props }, ref @@ -132,7 +140,15 @@ const TokenListItem = forwardRef< return (
      - + {tokenType === 'unshielded' ? ( + + ) : ( + + )}

      - {name} + {name}{' '} + {typeof explorerUrl === 'string' && ( + + + + )}

      diff --git a/libs/webb-ui-components/src/components/ListCard/types.ts b/libs/webb-ui-components/src/components/ListCard/types.ts index fb3ec34fe2..f407180cb8 100644 --- a/libs/webb-ui-components/src/components/ListCard/types.ts +++ b/libs/webb-ui-components/src/components/ListCard/types.ts @@ -110,6 +110,16 @@ export type AssetType = { * @type {AssetBadgeInfoType} */ assetBadgeProps?: AssetBadgeInfoType; + + /** + * The chain name of the asset (use to display the chain logo) + */ + chainName?: string; + + /** + * The asset explorer url + */ + explorerUrl?: string; }; export interface ListCardWrapperProps diff --git a/libs/webb-ui-components/src/stories/molecules/TokenListItem.stories.tsx b/libs/webb-ui-components/src/stories/molecules/TokenListItem.stories.tsx index 64da403705..83a97343ab 100644 --- a/libs/webb-ui-components/src/stories/molecules/TokenListItem.stories.tsx +++ b/libs/webb-ui-components/src/stories/molecules/TokenListItem.stories.tsx @@ -63,3 +63,33 @@ export const WithInfoBadge: Story = { /> ), }; + +export const ShieldedPoolItem: Story = { + render: () => ( + + ), +}; + +export const ShieldedPoolItemWithChain: Story = { + render: () => ( + + ), +}; From 9f38745d73f4b82d3f51ae0e297c60e3ec9cd48a Mon Sep 17 00:00:00 2001 From: AtelyPham Date: Fri, 11 Aug 2023 01:34:26 +0700 Subject: [PATCH 09/14] feat: update new chain list card with Storybook --- .../ChainListCardWrapper.tsx | 14 ++--- .../src/components/ListCard/ChainListCard.tsx | 62 ++++++++++++++----- .../components/ListCard/ListCardWrapper.tsx | 4 +- .../src/components/ListCard/index.ts | 2 +- .../src/components/ListCard/types.ts | 4 +- .../templates/ChainListCard.stories.tsx | 29 +++++++++ 6 files changed, 86 insertions(+), 29 deletions(-) create mode 100644 libs/webb-ui-components/src/stories/templates/ChainListCard.stories.tsx diff --git a/apps/bridge-dapp/src/components/ChainListCardWrapper/ChainListCardWrapper.tsx b/apps/bridge-dapp/src/components/ChainListCardWrapper/ChainListCardWrapper.tsx index 91cb3b6280..29fabecb80 100644 --- a/apps/bridge-dapp/src/components/ChainListCardWrapper/ChainListCardWrapper.tsx +++ b/apps/bridge-dapp/src/components/ChainListCardWrapper/ChainListCardWrapper.tsx @@ -1,12 +1,12 @@ +import { Bridge } from '@webb-tools/abstract-api-provider'; import { useWebContext } from '@webb-tools/api-provider-environment'; import { calculateTypedChainId } from '@webb-tools/sdk-core'; import { ChainListCard, useWebbUI } from '@webb-tools/webb-ui-components'; +import { ChainType } from '@webb-tools/webb-ui-components/components/ListCard/types'; import { FC, useCallback, useMemo } from 'react'; import { useConnectWallet } from '../../hooks'; -import { ChainListCardWrapperProps } from './types'; -import { getNativeCurrencyFromConfig } from '@webb-tools/dapp-config'; import { getActiveSourceChains } from '../../utils/getActiveSourceChains'; -import { Bridge } from '@webb-tools/abstract-api-provider'; +import { ChainListCardWrapperProps } from './types'; /** * The wrapper component for the ChainListCard component @@ -53,16 +53,10 @@ export const ChainListCardWrapper: FC = ({ if (chainsProps) return chainsProps; return getActiveSourceChains(apiConfig.chains).map((val) => { - const currency = getNativeCurrencyFromConfig( - apiConfig.currencies, - calculateTypedChainId(val.chainType, val.id) - ); - return { name: val.name, tag: val.tag, - symbol: currency?.symbol ?? 'Unknown', - }; + } satisfies ChainType; }); }, [apiConfig, chainsProps]); diff --git a/libs/webb-ui-components/src/components/ListCard/ChainListCard.tsx b/libs/webb-ui-components/src/components/ListCard/ChainListCard.tsx index b9145faf29..34b93135f4 100644 --- a/libs/webb-ui-components/src/components/ListCard/ChainListCard.tsx +++ b/libs/webb-ui-components/src/components/ListCard/ChainListCard.tsx @@ -1,18 +1,46 @@ -import { ChainIcon, InformationLine, Search } from '@webb-tools/icons'; +import { ChainIcon, Search } from '@webb-tools/icons'; import { forwardRef, useCallback, useEffect, useMemo, useState } from 'react'; import { twMerge } from 'tailwind-merge'; import { Typography } from '../../typography'; -import { Button } from '../buttons'; +import { Alert } from '../Alert'; import { Chip } from '../Chip'; import { Input } from '../Input'; +import { RadioGroup, RadioItem } from '../Radio'; import { ScrollArea } from '../ScrollArea'; +import { Button } from '../buttons'; import { ListCardWrapper } from './ListCardWrapper'; import { ListItem } from './ListItem'; import { ChainListCardProps, ChainType } from './types'; -import { RadioGroup, RadioItem } from '../Radio'; -import { Alert } from '../Alert'; -export const ChainListCard = forwardRef( +/** + * The ChainListCard component is used to display a list of chains. + * + * Props: + * - `chains`: The list of chains to display. + * - `chainType`: The type of chain to display. + * - `currentActiveChain`: The current active chain. + * - `defaultCategory`: The default category to display. + * - `onChange`: The callback function when the chain is changed. + * - `onClose`: The callback function when the card is closed. + * - `onlyCategory`: The category to display. + * - `overrideScrollAreaProps`: The props to override the scroll area. + * - `isConnectingToChain`: Whether the chain is connecting. + * - `value`: The selected chain. + * + * @example + * ```tsx + * setShowSourceChainList(false)} + * onlyCategory="test" + * /> + * ``` + */ +const ChainListCard = forwardRef( ( { chains, @@ -49,23 +77,21 @@ export const ChainListCard = forwardRef( return () => { subscribe = false; }; - }, [selectedChain, setChain]); + }, [selectedChain]); const onChainChange = useCallback( (nextChain: ChainType) => { setChain(nextChain); onChange?.(nextChain); }, - [onChange, setChain] + [onChange] ); const filteredChains = useMemo( () => chains - .filter( - (c) => - c.name.toLowerCase().includes(searchText.toLowerCase()) || - c.symbol.toLowerCase().includes(searchText.toLowerCase()) + .filter((c) => + c.name.toLowerCase().includes(searchText.toLowerCase()) ) // Filter by search text .filter((chain) => chain.tag === networkCategory), // Filter by network category [chains, searchText, networkCategory] @@ -142,13 +168,17 @@ export const ChainListCard = forwardRef( return ( onChainChange(currentChain)} >
      @@ -171,7 +201,9 @@ export const ChainListCard = forwardRef( {!isConnected && !isConnectingToChain ? (
      ) : null} @@ -238,3 +270,5 @@ export const ChainListCard = forwardRef( ); } ); + +export default ChainListCard; diff --git a/libs/webb-ui-components/src/components/ListCard/ListCardWrapper.tsx b/libs/webb-ui-components/src/components/ListCard/ListCardWrapper.tsx index 9943411278..d5da826f20 100644 --- a/libs/webb-ui-components/src/components/ListCard/ListCardWrapper.tsx +++ b/libs/webb-ui-components/src/components/ListCard/ListCardWrapper.tsx @@ -1,7 +1,7 @@ import { Close } from '@webb-tools/icons'; -import { Typography } from '../../typography'; import { forwardRef } from 'react'; import { twMerge } from 'tailwind-merge'; +import { Typography } from '../../typography'; import { ListCardWrapperProps } from './types'; @@ -11,7 +11,7 @@ export const ListCardWrapper = forwardRef(
      = { + title: 'Design System/V2 (WIP)/Templates/ChainListCard', + component: ChainListCard, +}; + +// More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export +export default meta; + +type Story = StoryObj; + +// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args +export const Default: Story = { + render: () => ( + ({ + name: chain.name, + tag: chain.tag, + needSwitchWallet: chain.chainType !== ChainType.EVM, + }))} + /> + ), +}; From d3b047356464875f01f705c098e9d22ba7ecf69f Mon Sep 17 00:00:00 2001 From: AtelyPham Date: Fri, 11 Aug 2023 17:52:29 +0700 Subject: [PATCH 10/14] feat: re-styling new V2 relayer list card --- .../src/components/ListCard/ListItem.tsx | 2 +- .../components/ListCard/RelayerListCard.tsx | 172 ++++++++++-------- .../src/components/ListCard/index.ts | 2 +- .../src/components/ListCard/types.ts | 10 +- .../src/components/Radio/RadioItem.tsx | 6 +- .../src/components/Radio/types.d.ts | 2 +- .../templates/RelayerListCard.stories.tsx | 50 +++++ 7 files changed, 157 insertions(+), 87 deletions(-) create mode 100644 libs/webb-ui-components/src/stories/templates/RelayerListCard.stories.tsx diff --git a/libs/webb-ui-components/src/components/ListCard/ListItem.tsx b/libs/webb-ui-components/src/components/ListCard/ListItem.tsx index c956ab2296..c2d90e149b 100644 --- a/libs/webb-ui-components/src/components/ListCard/ListItem.tsx +++ b/libs/webb-ui-components/src/components/ListCard/ListItem.tsx @@ -18,7 +18,7 @@ export const ListItem = forwardRef< cx({ 'hover:bg-blue-10 dark:hover:bg-blue-120': !isDisabled, - 'opacity-70': isDisabled, + 'opacity-50': isDisabled, }), className )} diff --git a/libs/webb-ui-components/src/components/ListCard/RelayerListCard.tsx b/libs/webb-ui-components/src/components/ListCard/RelayerListCard.tsx index e5bbd3c0ab..70e0ed9af3 100644 --- a/libs/webb-ui-components/src/components/ListCard/RelayerListCard.tsx +++ b/libs/webb-ui-components/src/components/ListCard/RelayerListCard.tsx @@ -1,9 +1,8 @@ import { ExternalLinkLine, Search } from '@webb-tools/icons'; +import cx from 'classnames'; +import { forwardRef, useCallback, useMemo, useState } from 'react'; import { Typography } from '../../typography'; import { shortenString } from '../../utils'; -import { getRoundedAmountString } from '../../utils'; -import cx from 'classnames'; -import { forwardRef, useCallback, useEffect, useMemo, useState } from 'react'; import { Avatar } from '../Avatar'; import { Button } from '../buttons'; @@ -12,8 +11,21 @@ import { ScrollArea } from '../ScrollArea'; import { ListCardWrapper } from './ListCardWrapper'; import { ListItem } from './ListItem'; import { RelayerListCardProps, RelayerType } from './types'; - -export const RelayerListCard = forwardRef( +import { RadioGroup, RadioItem } from '../Radio'; + +/** + * The relayer list card component + * + * Props: + * + * - `isDisconnected`: If the user is disconnected + * - `onChange`: The callback when the relayer is changed + * - `onClose`: The callback when the card is closed + * - `onConnectWallet`: The callback when the user clicks on the connect wallet button + * - `relayers`: The list of relayers + * - `value`: The selected relayer + */ +const RelayerListCard = forwardRef( ( { isDisconnected, @@ -26,39 +38,14 @@ export const RelayerListCard = forwardRef( }, ref ) => { - const [, setRelayer] = useState( - () => selectedRelayer - ); - // Search text const [searchText, setSearchText] = useState(''); - useEffect(() => { - let subscribe = true; - - if (subscribe) { - setRelayer(selectedRelayer); - } - - return () => { - subscribe = false; - }; - }, [selectedRelayer, setRelayer]); - - const onItemChange = useCallback( - (nextItem: RelayerType) => { - setRelayer(nextItem); - onChange?.(nextItem); - }, - [onChange, setRelayer] - ); - const filteredList = useMemo( () => relayers.filter( (r) => r.address.toLowerCase().includes(searchText.toLowerCase()) || - r.fee?.toString().includes(searchText.toLowerCase()) || r.percentage?.toString().includes(searchText.toLowerCase()) ), [relayers, searchText] @@ -69,6 +56,20 @@ export const RelayerListCard = forwardRef( [isDisconnected] ); + const handleValueChange = useMemo(() => { + if (typeof onChange !== 'function') { + return undefined; + } + + return (nextVal: string) => { + const nextRelayer = relayers.find((r) => r.address === nextVal); + + if (nextRelayer) { + onChange(nextRelayer); + } + }; + }, [onChange, relayers]); + return ( ( {/** Token list */} -
        - {filteredList.map((current, idx) => { - return ( - onItemChange(current)} - > -
        - - - - {shortenString(current.address)} - - - +
        - -
        - {current.fee && ( - - Fee:{' '} - {getRoundedAmountString( - parseFloat(current.fee.toString()) +
        + + + + {shortenString(current.address)} + + + + + +
        + + {typeof current.percentage === 'number' && ( + + Fee{' '} + + {current.percentage.toFixed(2)} % + + )} -
        - )} - - {current.percentage && ( - - {current.percentage.toFixed(2)} % - - )} -
        -
        - ); - })} -
      + + + + ); + })} +
    +
    {/** Disconnect view */} @@ -170,3 +186,5 @@ export const RelayerListCard = forwardRef( ); } ); + +export default RelayerListCard; diff --git a/libs/webb-ui-components/src/components/ListCard/index.ts b/libs/webb-ui-components/src/components/ListCard/index.ts index f08fa076ce..6d3ad09a5c 100644 --- a/libs/webb-ui-components/src/components/ListCard/index.ts +++ b/libs/webb-ui-components/src/components/ListCard/index.ts @@ -1,6 +1,6 @@ export { default as ChainListCard } from './ChainListCard'; export * from './ListCardWrapper'; export * from './ListItem'; -export * from './RelayerListCard'; +export { default as RelayerListCard } from './RelayerListCard'; export * from './TokenListCard'; export { default as TokenListItem } from './TokenListItem'; diff --git a/libs/webb-ui-components/src/components/ListCard/types.ts b/libs/webb-ui-components/src/components/ListCard/types.ts index 5cd245aba0..f2995e68cf 100644 --- a/libs/webb-ui-components/src/components/ListCard/types.ts +++ b/libs/webb-ui-components/src/components/ListCard/types.ts @@ -31,11 +31,6 @@ export type RelayerType = { */ externalUrl: string; - /** - * Relayer fee - */ - fee?: string | number; - /** * Relayer percentage */ @@ -46,6 +41,11 @@ export type RelayerType = { * @default 'polkadot' */ theme?: AvatarProps['theme']; + + /** + * Whether the relayer is disabled + */ + isDisabled?: boolean; }; export type AssetBalanceType = { diff --git a/libs/webb-ui-components/src/components/Radio/RadioItem.tsx b/libs/webb-ui-components/src/components/Radio/RadioItem.tsx index 949452e486..f7738a2e15 100644 --- a/libs/webb-ui-components/src/components/Radio/RadioItem.tsx +++ b/libs/webb-ui-components/src/components/Radio/RadioItem.tsx @@ -27,7 +27,7 @@ export const RadioItem = forwardRef( ( )} /> - {label && ( + {typeof label === 'string' || typeof label === 'number' ? ( ( > {label} + ) : ( + label )} ); diff --git a/libs/webb-ui-components/src/components/Radio/types.d.ts b/libs/webb-ui-components/src/components/Radio/types.d.ts index dba7c66d01..86c92d9645 100644 --- a/libs/webb-ui-components/src/components/Radio/types.d.ts +++ b/libs/webb-ui-components/src/components/Radio/types.d.ts @@ -25,7 +25,7 @@ export interface RadioItemProps extends PropsOf<'div'> { /** * The children as the label of radio button. */ - children?: string; + children?: React.ReactNode; /** * The object to override the props of the radio item. diff --git a/libs/webb-ui-components/src/stories/templates/RelayerListCard.stories.tsx b/libs/webb-ui-components/src/stories/templates/RelayerListCard.stories.tsx new file mode 100644 index 0000000000..aa79589663 --- /dev/null +++ b/libs/webb-ui-components/src/stories/templates/RelayerListCard.stories.tsx @@ -0,0 +1,50 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import RelayerListCard from '../../components/ListCard/RelayerListCard'; +import { randBoolean, randEthereumAddress, randNumber } from '@ngneat/falso'; + +const meta: Meta = { + title: 'Design System/V2 (WIP)/Templates/RelayerListCard', + component: RelayerListCard, +}; + +// More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export +export default meta; + +type Story = StoryObj; + +const addresses = Array.from( + new Set( + Array.from({ length: randNumber({ min: 10, max: 20 }) }).map(() => + randEthereumAddress() + ) + ) +); + +// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args +export const Default: Story = { + render: () => ( + ({ + address, + externalUrl: 'https://webb.tools', + percentage: randNumber({ min: 0, max: 10 }), + theme: 'ethereum', + isDisabled: randBoolean(), + }))} + /> + ), +}; + +export const Disconnected: Story = { + render: () => ( + ({ + address, + externalUrl: 'https://webb.tools', + percentage: randNumber({ min: 0, max: 10 }), + theme: 'ethereum', + }))} + /> + ), +}; From adec9d661cc566978617006bfba5e98d5a3332cc Mon Sep 17 00:00:00 2001 From: AtelyPham Date: Fri, 11 Aug 2023 18:14:07 +0700 Subject: [PATCH 11/14] fix: the width issue on radio item --- libs/webb-ui-components/src/components/Radio/RadioItem.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/webb-ui-components/src/components/Radio/RadioItem.tsx b/libs/webb-ui-components/src/components/Radio/RadioItem.tsx index f7738a2e15..00418b1e2c 100644 --- a/libs/webb-ui-components/src/components/Radio/RadioItem.tsx +++ b/libs/webb-ui-components/src/components/Radio/RadioItem.tsx @@ -27,7 +27,7 @@ export const RadioItem = forwardRef( Date: Fri, 11 Aug 2023 19:12:13 +0700 Subject: [PATCH 12/14] chore: update chain button font weight to match with wallet button --- libs/webb-ui-components/src/components/buttons/ChainButton.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/webb-ui-components/src/components/buttons/ChainButton.tsx b/libs/webb-ui-components/src/components/buttons/ChainButton.tsx index 09674151d5..2d8c5ebccd 100644 --- a/libs/webb-ui-components/src/components/buttons/ChainButton.tsx +++ b/libs/webb-ui-components/src/components/buttons/ChainButton.tsx @@ -31,7 +31,7 @@ const ChainButton = forwardRef( className={cx(`shrink-0 grow-0 ${getFlexBasic('lg')}`)} name={chain.name} /> -

    {shortName}

    +

    {shortName}

    Date: Fri, 11 Aug 2023 19:18:00 +0700 Subject: [PATCH 13/14] chore: update text color on dark mode for WalletButton --- .../src/components/buttons/WalletButton.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libs/webb-ui-components/src/components/buttons/WalletButton.tsx b/libs/webb-ui-components/src/components/buttons/WalletButton.tsx index 70a8a11dfd..8805638936 100644 --- a/libs/webb-ui-components/src/components/buttons/WalletButton.tsx +++ b/libs/webb-ui-components/src/components/buttons/WalletButton.tsx @@ -30,7 +30,12 @@ const WalletButton = forwardRef( `shrink-0 grow-0 ${getFlexBasic('lg')}` ), })} - + {isHex(address) ? `${shortenHex(address)}` : `${shortenString(address)})}`} From 824a89c78779d82f3adf5847fcefc21516faa6ad Mon Sep 17 00:00:00 2001 From: AtelyPham Date: Fri, 11 Aug 2023 19:44:52 +0700 Subject: [PATCH 14/14] chore: add icon for switch --- .../NavBlocksInfoContainer/NavBlocksInfoContainer.tsx | 7 +++++-- libs/icons/src/{RefreshIcon.tsx => RefreshLineIcon.tsx} | 6 ++++-- libs/icons/src/index.ts | 2 +- .../src/components/ListCard/TokenListItem.tsx | 2 ++ 4 files changed, 12 insertions(+), 5 deletions(-) rename libs/icons/src/{RefreshIcon.tsx => RefreshLineIcon.tsx} (87%) diff --git a/apps/stats-dapp/src/containers/NavBlocksInfoContainer/NavBlocksInfoContainer.tsx b/apps/stats-dapp/src/containers/NavBlocksInfoContainer/NavBlocksInfoContainer.tsx index 9c083883f4..611961da14 100644 --- a/apps/stats-dapp/src/containers/NavBlocksInfoContainer/NavBlocksInfoContainer.tsx +++ b/apps/stats-dapp/src/containers/NavBlocksInfoContainer/NavBlocksInfoContainer.tsx @@ -9,7 +9,7 @@ import { FileCodeLineIcon, GraphIcon, BlockIcon, - RefreshIcon, + RefreshLineIcon, Spinner, } from '@webb-tools/icons'; import { @@ -123,7 +123,10 @@ export const NavBoxInfoContainer = () => { )} - {' '} + {' '} {currentKey ? ( `Session: ${Number(currentKey?.session).toLocaleString()}` ) : ( diff --git a/libs/icons/src/RefreshIcon.tsx b/libs/icons/src/RefreshLineIcon.tsx similarity index 87% rename from libs/icons/src/RefreshIcon.tsx rename to libs/icons/src/RefreshLineIcon.tsx index eedbe72ea0..30ee720917 100644 --- a/libs/icons/src/RefreshIcon.tsx +++ b/libs/icons/src/RefreshLineIcon.tsx @@ -1,12 +1,14 @@ import { createIcon } from './create-icon'; import { IconBase } from './types'; -export const RefreshIcon = (props: IconBase) => { +const RefreshLineIcon = (props: IconBase) => { return createIcon({ ...props, path: ( ), - displayName: 'RefreshIcon', + displayName: 'RefreshLineIcon', }); }; + +export default RefreshLineIcon; diff --git a/libs/icons/src/index.ts b/libs/icons/src/index.ts index 9e58ef2d5f..0a4422ecbe 100644 --- a/libs/icons/src/index.ts +++ b/libs/icons/src/index.ts @@ -69,7 +69,7 @@ export * from './Mail'; export * from './Memu'; export * from './MoonLine'; export * from './QRCode'; -export * from './RefreshIcon'; +export { default as RefreshLineIcon } from './RefreshLineIcon'; export * from './Save'; export * from './SaveWithBg'; export * from './Search'; diff --git a/libs/webb-ui-components/src/components/ListCard/TokenListItem.tsx b/libs/webb-ui-components/src/components/ListCard/TokenListItem.tsx index 3380c1eefc..72efe9aae3 100644 --- a/libs/webb-ui-components/src/components/ListCard/TokenListItem.tsx +++ b/libs/webb-ui-components/src/components/ListCard/TokenListItem.tsx @@ -1,6 +1,7 @@ import { AlertFill, ExternalLinkLine, + RefreshLineIcon, ShieldedAssetIcon, TokenIcon, } from '@webb-tools/icons'; @@ -81,6 +82,7 @@ const BadgeInfo = ({ variant, children }: AssetBadgeInfoType) => { default: { color = 'blue'; + badgeIcon = ; break; } }