Commit 81bf03c8 authored by tom's avatar tom

tx token transfers tab

parent 3148fc64
...@@ -36,7 +36,7 @@ const RESTRICTED_MODULES = { ...@@ -36,7 +36,7 @@ const RESTRICTED_MODULES = {
'Image', 'Popover', 'PopoverTrigger', 'PopoverContent', 'PopoverBody', 'PopoverFooter', 'Image', 'Popover', 'PopoverTrigger', 'PopoverContent', 'PopoverBody', 'PopoverFooter',
'DrawerRoot', 'DrawerBody', 'DrawerContent', 'DrawerOverlay', 'DrawerBackdrop', 'DrawerTrigger', 'Drawer', 'DrawerRoot', 'DrawerBody', 'DrawerContent', 'DrawerOverlay', 'DrawerBackdrop', 'DrawerTrigger', 'Drawer',
'Alert', 'AlertIcon', 'AlertTitle', 'AlertDescription', 'Alert', 'AlertIcon', 'AlertTitle', 'AlertDescription',
'Heading', 'Badge', 'Tabs', 'Show', 'Hide', 'Heading', 'Badge', 'Tabs', 'Show', 'Hide', 'Checkbox',
'Table', 'TableRoot', 'TableBody', 'TableHeader', 'TableRow', 'TableCell', 'Table', 'TableRoot', 'TableBody', 'TableHeader', 'TableRow', 'TableCell',
'Menu', 'MenuRoot', 'MenuTrigger', 'MenuContent', 'MenuItem', 'MenuTriggerItem', 'MenuRadioItemGroup', 'MenuContextTrigger', 'Menu', 'MenuRoot', 'MenuTrigger', 'MenuContent', 'MenuItem', 'MenuTriggerItem', 'MenuRadioItemGroup', 'MenuContextTrigger',
], ],
......
...@@ -21,4 +21,20 @@ export const Radio = React.forwardRef<HTMLInputElement, RadioProps>( ...@@ -21,4 +21,20 @@ export const Radio = React.forwardRef<HTMLInputElement, RadioProps>(
}, },
); );
export const RadioGroup = ChakraRadioGroup.Root; export interface RadioGroupProps extends ChakraRadioGroup.RootProps {}
export const RadioGroup = React.forwardRef<HTMLDivElement, RadioGroupProps>(
function RadioGroup(props, ref) {
const { orientation = 'horizontal', ...rest } = props;
return (
<ChakraRadioGroup.Root
ref={ ref }
orientation={ orientation }
display="flex"
flexDirection={ orientation === 'horizontal' ? 'row' : 'column' }
gap={ orientation === 'horizontal' ? 4 : 2 }
{ ...rest }
/>
);
},
);
...@@ -126,16 +126,16 @@ const colors: ExcludeUndefined<ThemingConfig['tokens']>['colors'] = { ...@@ -126,16 +126,16 @@ const colors: ExcludeUndefined<ThemingConfig['tokens']>['colors'] = {
black: { value: '#101112' }, black: { value: '#101112' },
white: { value: '#ffffff' }, white: { value: '#ffffff' },
whiteAlpha: { whiteAlpha: {
'50': { value: 'RGBA(16, 17, 18, 0.04)' }, '50': { value: 'RGBA(255, 255, 255, 0.04)' },
'100': { value: 'RGBA(16, 17, 18, 0.06)' }, '100': { value: 'RGBA(255, 255, 255, 0.06)' },
'200': { value: 'RGBA(16, 17, 18, 0.08)' }, '200': { value: 'RGBA(255, 255, 255, 0.08)' },
'300': { value: 'RGBA(16, 17, 18, 0.16)' }, '300': { value: 'RGBA(255, 255, 255, 0.16)' },
'400': { value: 'RGBA(16, 17, 18, 0.24)' }, '400': { value: 'RGBA(255, 255, 255, 0.24)' },
'500': { value: 'RGBA(16, 17, 18, 0.36)' }, '500': { value: 'RGBA(255, 255, 255, 0.36)' },
'600': { value: 'RGBA(16, 17, 18, 0.48)' }, '600': { value: 'RGBA(255, 255, 255, 0.48)' },
'700': { value: 'RGBA(16, 17, 18, 0.64)' }, '700': { value: 'RGBA(255, 255, 255, 0.64)' },
'800': { value: 'RGBA(16, 17, 18, 0.80)' }, '800': { value: 'RGBA(255, 255, 255, 0.80)' },
'900': { value: 'RGBA(16, 17, 18, 0.92)' }, '900': { value: 'RGBA(255, 255, 255, 0.92)' },
}, },
blackAlpha: { blackAlpha: {
'50': { value: 'RGBA(16, 17, 18, 0.04)' }, '50': { value: 'RGBA(16, 17, 18, 0.04)' },
......
...@@ -112,7 +112,7 @@ const semanticTokens: ThemingConfig['semanticTokens'] = { ...@@ -112,7 +112,7 @@ const semanticTokens: ThemingConfig['semanticTokens'] = {
active: { value: { _light: '{colors.link.primary.hover}' } }, active: { value: { _light: '{colors.link.primary.hover}' } },
}, },
bg: { bg: {
DEFAULT: { value: 'transparent' }, DEFAULT: { value: { _light: '{colors.white}', _dark: '{colors.black}' } },
selected: { value: { _light: '{colors.blue.50}', _dark: '{colors.gray.800}' } }, selected: { value: { _light: '{colors.blue.50}', _dark: '{colors.gray.800}' } },
}, },
border: { border: {
...@@ -339,6 +339,22 @@ const semanticTokens: ThemingConfig['semanticTokens'] = { ...@@ -339,6 +339,22 @@ const semanticTokens: ThemingConfig['semanticTokens'] = {
fg: { value: { _light: '{colors.blackAlpha.700}', _dark: '{colors.whiteAlpha.700}' } }, fg: { value: { _light: '{colors.blackAlpha.700}', _dark: '{colors.whiteAlpha.700}' } },
}, },
}, },
checkbox: {
icon: {
bg: {
checked: { value: { _light: '{colors.blue.500}', _dark: '{colors.gray.300}' } },
hover: { value: { _light: '{colors.blue.600}', _dark: '{colors.gray.400}' } },
},
},
},
radio: {
icon: {
bg: {
checked: { value: { _light: '{colors.blue.500}', _dark: '{colors.gray.300}' } },
hover: { value: { _light: '{colors.blue.600}', _dark: '{colors.gray.400}' } },
},
},
},
heading: { heading: {
DEFAULT: { value: { _light: '{colors.blackAlpha.800}', _dark: '{colors.whiteAlpha.800}' } }, DEFAULT: { value: { _light: '{colors.blackAlpha.800}', _dark: '{colors.whiteAlpha.800}' } },
}, },
......
import { defineSlotRecipe } from '@chakra-ui/react';
import { recipe as checkmarkRecipe } from './checkmark.recipe';
export const recipe = defineSlotRecipe({
slots: [ 'root', 'control', 'label' ],
className: 'chakra-checkbox',
base: {
root: {
display: 'inline-flex',
gap: '2',
alignItems: 'center',
verticalAlign: 'top',
position: 'relative',
},
control: checkmarkRecipe.base,
label: {
fontWeight: 'normal',
userSelect: 'none',
_disabled: {
opacity: '0.5',
},
},
},
variants: {
size: {
xs: {
root: { gap: '1' },
label: { textStyle: 'xs' },
control: checkmarkRecipe.variants?.size?.xs,
},
sm: {
root: { gap: '1' },
label: { textStyle: 'sm' },
control: checkmarkRecipe.variants?.size?.sm,
},
md: {
root: { gap: '2' },
label: { textStyle: 'md' },
control: checkmarkRecipe.variants?.size?.md,
},
},
variant: {
solid: {
control: checkmarkRecipe.variants?.variant?.solid,
},
},
},
defaultVariants: {
variant: 'solid',
size: 'md',
},
});
import { defineRecipe } from '@chakra-ui/react';
// TODO @tom2drum dark mode + border color
export const recipe = defineRecipe({
className: 'chakra-checkmark',
base: {
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
flexShrink: '0',
color: 'white',
borderWidth: '2px',
borderColor: 'transparent',
focusVisibleRing: 'outside',
_icon: {
boxSize: 'full',
},
_disabled: {
opacity: '0.5',
},
},
variants: {
size: {
xs: {
boxSize: '3',
borderRadius: '2px',
},
sm: {
boxSize: '4',
borderRadius: '2px',
},
md: {
boxSize: '5',
borderRadius: 'sm',
},
},
variant: {
solid: {
borderColor: 'border',
'&:is([data-state=checked], [data-state=indeterminate])': {
bg: 'checkbox.icon.bg.checked',
color: 'white',
borderColor: 'checkbox.icon.bg.checked',
_hover: {
bg: 'checkbox.icon.bg.hover',
borderColor: 'checkbox.icon.bg.hover',
},
},
},
},
},
defaultVariants: {
variant: 'solid',
size: 'md',
},
});
...@@ -2,6 +2,8 @@ import { recipe as accordion } from './accordion.recipe'; ...@@ -2,6 +2,8 @@ import { recipe as accordion } from './accordion.recipe';
import { recipe as alert } from './alert.recipe'; import { recipe as alert } from './alert.recipe';
import { recipe as badge } from './badge.recipe'; import { recipe as badge } from './badge.recipe';
import { recipe as button } from './button.recipe'; import { recipe as button } from './button.recipe';
import { recipe as checkbox } from './checkbox.recipe';
import { recipe as checkmark } from './checkmark.recipe';
import { recipe as closeButton } from './close-button.recipe'; import { recipe as closeButton } from './close-button.recipe';
import { recipe as dialog } from './dialog.recipe'; import { recipe as dialog } from './dialog.recipe';
import { recipe as drawer } from './drawer.recipe'; import { recipe as drawer } from './drawer.recipe';
...@@ -13,6 +15,8 @@ import { recipe as nativeSelect } from './native-select.recipe'; ...@@ -13,6 +15,8 @@ import { recipe as nativeSelect } from './native-select.recipe';
import { recipe as pinInput } from './pin-input.recipe'; import { recipe as pinInput } from './pin-input.recipe';
import { recipe as popover } from './popover.recipe'; import { recipe as popover } from './popover.recipe';
import { recipe as progressCircle } from './progress-circle.recipe'; import { recipe as progressCircle } from './progress-circle.recipe';
import { recipe as radioGroup } from './radio-group.recipe';
import { recipe as radiomark } from './radiomark.recipe';
import { recipe as select } from './select.recipe'; import { recipe as select } from './select.recipe';
import { recipe as skeleton } from './skeleton.recipe'; import { recipe as skeleton } from './skeleton.recipe';
import { recipe as spinner } from './spinner.recipe'; import { recipe as spinner } from './spinner.recipe';
...@@ -27,9 +31,11 @@ import { recipe as tooltip } from './tooltip.recipe'; ...@@ -27,9 +31,11 @@ import { recipe as tooltip } from './tooltip.recipe';
export const recipes = { export const recipes = {
badge, badge,
button, button,
checkmark,
closeButton, closeButton,
input, input,
link, link,
radiomark,
skeleton, skeleton,
spinner, spinner,
textarea, textarea,
...@@ -38,6 +44,7 @@ export const recipes = { ...@@ -38,6 +44,7 @@ export const recipes = {
export const slotRecipes = { export const slotRecipes = {
accordion, accordion,
alert, alert,
checkbox,
dialog, dialog,
drawer, drawer,
field, field,
...@@ -46,6 +53,7 @@ export const slotRecipes = { ...@@ -46,6 +53,7 @@ export const slotRecipes = {
pinInput, pinInput,
popover, popover,
progressCircle, progressCircle,
radioGroup,
select, select,
'switch': switchRecipe, 'switch': switchRecipe,
table, table,
......
import { defineSlotRecipe } from '@chakra-ui/react';
import { recipe as radiomarkRecipe } from './radiomark.recipe';
export const recipe = defineSlotRecipe({
slots: [ 'item', 'itemControl', 'label' ],
base: {
item: {
display: 'inline-flex',
alignItems: 'center',
position: 'relative',
fontWeight: 'normal',
_disabled: {
cursor: 'disabled',
},
},
itemControl: radiomarkRecipe.base,
label: {
userSelect: 'none',
textStyle: 'md',
_disabled: {
opacity: '0.5',
},
},
},
variants: {
variant: {
solid: {
itemControl: radiomarkRecipe.variants?.variant?.solid,
},
},
size: {
xs: {
item: { textStyle: 'xs', gap: '1' },
itemControl: radiomarkRecipe.variants?.size?.xs,
},
sm: {
item: { textStyle: 'sm', gap: '1' },
itemControl: radiomarkRecipe.variants?.size?.sm,
},
md: {
item: { textStyle: 'md', gap: '2' },
itemControl: radiomarkRecipe.variants?.size?.md,
},
},
},
defaultVariants: {
size: 'md',
variant: 'solid',
},
});
import { defineRecipe } from '@chakra-ui/react';
// TODO @tom2drum dark mode + border color
export const recipe = defineRecipe({
base: {
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
flexShrink: 0,
verticalAlign: 'top',
color: 'white',
borderWidth: '2px',
borderColor: 'transparent',
borderRadius: 'full',
cursor: 'radio',
_focusVisible: {
outline: '2px solid',
outlineColor: 'colorPalette.focusRing',
outlineOffset: '2px',
},
_disabled: {
opacity: '0.5',
cursor: 'disabled',
},
'& .dot': {
height: '100%',
width: '100%',
borderRadius: 'full',
bg: 'currentColor',
scale: '0.4',
},
},
variants: {
variant: {
solid: {
borderWidth: '2px',
borderColor: 'border',
_checked: {
bg: 'radio.icon.bg.checked',
color: 'white',
borderColor: 'radio.icon.bg.checked',
_hover: {
bg: 'radio.icon.bg.hover',
borderColor: 'radio.icon.bg.hover',
},
},
},
},
size: {
xs: {
boxSize: '3',
},
sm: {
boxSize: '4',
},
md: {
boxSize: '5',
},
},
},
defaultVariants: {
variant: 'solid',
size: 'md',
},
});
...@@ -24,9 +24,11 @@ import AccordionsShowcase from 'ui/showcases/Accordion'; ...@@ -24,9 +24,11 @@ import AccordionsShowcase from 'ui/showcases/Accordion';
import AlertsShowcase from 'ui/showcases/Alerts'; import AlertsShowcase from 'ui/showcases/Alerts';
import BadgesShowcase from 'ui/showcases/Badges'; import BadgesShowcase from 'ui/showcases/Badges';
import ButtonShowcase from 'ui/showcases/Button'; import ButtonShowcase from 'ui/showcases/Button';
import CheckboxesShowcase from 'ui/showcases/Checkbox';
import LinksShowcase from 'ui/showcases/Links'; import LinksShowcase from 'ui/showcases/Links';
import MenusShowcase from 'ui/showcases/Menu'; import MenusShowcase from 'ui/showcases/Menu';
import PaginationShowcase from 'ui/showcases/Pagination'; import PaginationShowcase from 'ui/showcases/Pagination';
import RadiosShowcase from 'ui/showcases/Radio';
import SelectsShowcase from 'ui/showcases/Select'; import SelectsShowcase from 'ui/showcases/Select';
import TabsShowcase from 'ui/showcases/Tabs'; import TabsShowcase from 'ui/showcases/Tabs';
import TagsShowcase from 'ui/showcases/Tags'; import TagsShowcase from 'ui/showcases/Tags';
...@@ -50,9 +52,11 @@ const ChakraShowcases = () => { ...@@ -50,9 +52,11 @@ const ChakraShowcases = () => {
<TabsTrigger value="alerts">Alerts</TabsTrigger> <TabsTrigger value="alerts">Alerts</TabsTrigger>
<TabsTrigger value="badges">Badges</TabsTrigger> <TabsTrigger value="badges">Badges</TabsTrigger>
<TabsTrigger value="buttons">Buttons</TabsTrigger> <TabsTrigger value="buttons">Buttons</TabsTrigger>
<TabsTrigger value="checkboxes">Checkboxes</TabsTrigger>
<TabsTrigger value="links">Links</TabsTrigger> <TabsTrigger value="links">Links</TabsTrigger>
<TabsTrigger value="menus">Menus</TabsTrigger> <TabsTrigger value="menus">Menus</TabsTrigger>
<TabsTrigger value="pagination">Pagination</TabsTrigger> <TabsTrigger value="pagination">Pagination</TabsTrigger>
<TabsTrigger value="radios">Radios</TabsTrigger>
<TabsTrigger value="selects">Selects</TabsTrigger> <TabsTrigger value="selects">Selects</TabsTrigger>
<TabsTrigger value="tabs">Tabs</TabsTrigger> <TabsTrigger value="tabs">Tabs</TabsTrigger>
<TabsTrigger value="tags">Tags</TabsTrigger> <TabsTrigger value="tags">Tags</TabsTrigger>
...@@ -63,10 +67,12 @@ const ChakraShowcases = () => { ...@@ -63,10 +67,12 @@ const ChakraShowcases = () => {
<AlertsShowcase/> <AlertsShowcase/>
<BadgesShowcase/> <BadgesShowcase/>
<ButtonShowcase/> <ButtonShowcase/>
<CheckboxesShowcase/>
<LinksShowcase/> <LinksShowcase/>
<MenusShowcase/> <MenusShowcase/>
<TabsShowcase/> <TabsShowcase/>
<PaginationShowcase/> <PaginationShowcase/>
<RadiosShowcase/>
<SelectsShowcase/> <SelectsShowcase/>
<TooltipsShowcase/> <TooltipsShowcase/>
<TagsShowcase/> <TagsShowcase/>
......
...@@ -58,7 +58,7 @@ const TransactionPageContent = () => { ...@@ -58,7 +58,7 @@ const TransactionPageContent = () => {
// config.features.suave.isEnabled && data?.wrapped ? // config.features.suave.isEnabled && data?.wrapped ?
// { id: 'wrapped', title: 'Regular tx details', component: <TxDetailsWrapped data={ data.wrapped }/> } : // { id: 'wrapped', title: 'Regular tx details', component: <TxDetailsWrapped data={ data.wrapped }/> } :
// undefined, // undefined,
// { id: 'token_transfers', title: 'Token transfers', component: <TxTokenTransfer txQuery={ txQuery }/> }, { id: 'token_transfers', title: 'Token transfers', component: <TxTokenTransfer txQuery={ txQuery }/> },
// config.features.userOps.isEnabled ? // config.features.userOps.isEnabled ?
// { id: 'user_ops', title: 'User operations', component: <TxUserOps txQuery={ txQuery }/> } : // { id: 'user_ops', title: 'User operations', component: <TxUserOps txQuery={ txQuery }/> } :
// undefined, // undefined,
...@@ -74,12 +74,12 @@ const TransactionPageContent = () => { ...@@ -74,12 +74,12 @@ const TransactionPageContent = () => {
const tabIndex = useTabIndexFromQuery(tabs); const tabIndex = useTabIndexFromQuery(tabs);
// const tags = ( const tags = (
// <EntityTags <EntityTags
// isLoading={ isPlaceholderData } isLoading={ isPlaceholderData }
// tags={ data?.transaction_tag ? [ { slug: data.transaction_tag, name: data.transaction_tag, tagType: 'private_tag' as const, ordinal: 10 } ] : [] } tags={ data?.transaction_tag ? [ { slug: data.transaction_tag, name: data.transaction_tag, tagType: 'private_tag' as const, ordinal: 10 } ] : [] }
// /> />
// ); );
const backLink = React.useMemo(() => { const backLink = React.useMemo(() => {
const hasGoBackLink = appProps.referrer && appProps.referrer.includes('/txs'); const hasGoBackLink = appProps.referrer && appProps.referrer.includes('/txs');
...@@ -121,7 +121,7 @@ const TransactionPageContent = () => { ...@@ -121,7 +121,7 @@ const TransactionPageContent = () => {
<PageTitle <PageTitle
title="Transaction details" title="Transaction details"
backLink={ backLink } backLink={ backLink }
// contentAfter={ tags } contentAfter={ tags }
secondRow={ titleSecondRow } secondRow={ titleSecondRow }
/> />
{ content } { content }
......
import { import { Text, Stack } from '@chakra-ui/react';
Text,
Radio,
RadioGroup,
Stack,
} from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { AddressFromToFilter } from 'types/api/address'; import type { AddressFromToFilter } from 'types/api/address';
import type { TokenType } from 'types/api/token'; import type { TokenType } from 'types/api/token';
import useIsInitialLoading from 'lib/hooks/useIsInitialLoading'; import useIsInitialLoading from 'lib/hooks/useIsInitialLoading';
import { Radio, RadioGroup } from 'toolkit/chakra/radio';
import PopoverFilter from 'ui/shared/filters/PopoverFilter'; import PopoverFilter from 'ui/shared/filters/PopoverFilter';
import TokenTypeFilter from 'ui/shared/filters/TokenTypeFilter'; import TokenTypeFilter from 'ui/shared/filters/TokenTypeFilter';
...@@ -34,20 +30,24 @@ const TokenTransferFilter = ({ ...@@ -34,20 +30,24 @@ const TokenTransferFilter = ({
}: Props) => { }: Props) => {
const isInitialLoading = useIsInitialLoading(isLoading); const isInitialLoading = useIsInitialLoading(isLoading);
const handleAddressFilterChange = React.useCallback(({ value }: { value: string }) => {
onAddressFilterChange?.(value);
}, [ onAddressFilterChange ]);
return ( return (
<PopoverFilter appliedFiltersNum={ appliedFiltersNum } contentProps={{ w: '220px' }} isLoading={ isInitialLoading }> <PopoverFilter appliedFiltersNum={ appliedFiltersNum } contentProps={{ w: '220px' }} isLoading={ isInitialLoading }>
{ withAddressFilter && ( { withAddressFilter && (
<> <>
<Text variant="secondary" fontWeight={ 600 }>Address</Text> <Text color="text.secondary" fontWeight={ 600 }>Address</Text>
<RadioGroup <RadioGroup
size="lg" size="lg"
onChange={ onAddressFilterChange } onValueChange={ handleAddressFilterChange }
defaultValue={ defaultAddressFilter || 'all' } defaultValue={ defaultAddressFilter || 'all' }
paddingBottom={ 4 } paddingBottom={ 4 }
borderBottom="1px solid" borderBottom="1px solid"
borderColor="border.divider" borderColor="border.divider"
> >
<Stack spacing={ 4 }> <Stack gap={ 4 }>
<Radio value="all"><Text fontSize="md">All</Text></Radio> <Radio value="all"><Text fontSize="md">All</Text></Radio>
<Radio value="from"><Text fontSize="md">Outgoing transfers</Text></Radio> <Radio value="from"><Text fontSize="md">Outgoing transfers</Text></Radio>
<Radio value="to"><Text fontSize="md">Incoming transfers</Text></Radio> <Radio value="to"><Text fontSize="md">Incoming transfers</Text></Radio>
......
...@@ -5,9 +5,9 @@ import type { TokenTransfer } from 'types/api/tokenTransfer'; ...@@ -5,9 +5,9 @@ import type { TokenTransfer } from 'types/api/tokenTransfer';
import getCurrencyValue from 'lib/getCurrencyValue'; import getCurrencyValue from 'lib/getCurrencyValue';
import { getTokenTypeName } from 'lib/token/tokenTypes'; import { getTokenTypeName } from 'lib/token/tokenTypes';
import { Badge } from 'toolkit/chakra/badge';
import { Skeleton } from 'toolkit/chakra/skeleton';
import AddressFromTo from 'ui/shared/address/AddressFromTo'; import AddressFromTo from 'ui/shared/address/AddressFromTo';
import Skeleton from 'ui/shared/chakra/Skeleton';
import Tag from 'ui/shared/chakra/Tag';
import NftEntity from 'ui/shared/entities/nft/NftEntity'; import NftEntity from 'ui/shared/entities/nft/NftEntity';
import TokenEntity from 'ui/shared/entities/token/TokenEntity'; import TokenEntity from 'ui/shared/entities/token/TokenEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
...@@ -46,7 +46,7 @@ const TokenTransferListItem = ({ ...@@ -46,7 +46,7 @@ const TokenTransferListItem = ({
}) : { usd: null, valueStr: null }; }) : { usd: null, valueStr: null };
return ( return (
<ListItemMobile rowGap={ 3 } isAnimated> <ListItemMobile rowGap={ 3 }>
<Flex w="100%" justifyContent="space-between"> <Flex w="100%" justifyContent="space-between">
<Flex flexWrap="wrap" rowGap={ 1 } mr={ showTxInfo && txHash ? 2 : 0 } columnGap={ 2 } overflow="hidden"> <Flex flexWrap="wrap" rowGap={ 1 } mr={ showTxInfo && txHash ? 2 : 0 } columnGap={ 2 } overflow="hidden">
{ token && ( { token && (
...@@ -58,10 +58,10 @@ const TokenTransferListItem = ({ ...@@ -58,10 +58,10 @@ const TokenTransferListItem = ({
noCopy noCopy
w="auto" w="auto"
/> />
<Tag flexShrink={ 0 } isLoading={ isLoading }>{ getTokenTypeName(token.type) }</Tag> <Badge flexShrink={ 0 } loading={ isLoading }>{ getTokenTypeName(token.type) }</Badge>
</> </>
) } ) }
<Tag colorScheme="orange" isLoading={ isLoading }>{ getTokenTransferTypeText(type) }</Tag> <Badge colorScheme="orange" loading={ isLoading }>{ getTokenTransferTypeText(type) }</Badge>
</Flex> </Flex>
{ showTxInfo && txHash && ( { showTxInfo && txHash && (
<TxAdditionalInfo hash={ txHash } isMobile isLoading={ isLoading }/> <TxAdditionalInfo hash={ txHash } isMobile isLoading={ isLoading }/>
...@@ -97,8 +97,8 @@ const TokenTransferListItem = ({ ...@@ -97,8 +97,8 @@ const TokenTransferListItem = ({
/> />
{ valueStr && ( { valueStr && (
<Flex columnGap={ 2 } w="100%"> <Flex columnGap={ 2 } w="100%">
<Skeleton isLoaded={ !isLoading } fontWeight={ 500 } flexShrink={ 0 }>Value</Skeleton> <Skeleton loading={ isLoading } fontWeight={ 500 } flexShrink={ 0 }>Value</Skeleton>
<Skeleton isLoaded={ !isLoading } color="text_secondary"> <Skeleton loading={ isLoading } color="text.secondary">
<span>{ valueStr }</span> <span>{ valueStr }</span>
{ usd && <span> (${ usd })</span> } { usd && <span> (${ usd })</span> }
</Skeleton> </Skeleton>
......
import { Table, Tbody, Tr, Th } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { TokenTransfer } from 'types/api/tokenTransfer'; import type { TokenTransfer } from 'types/api/tokenTransfer';
import { AddressHighlightProvider } from 'lib/contexts/addressHighlight'; import { AddressHighlightProvider } from 'lib/contexts/addressHighlight';
import { TableBody, TableColumnHeader, TableHeaderSticky, TableRoot, TableRow } from 'toolkit/chakra/table';
import * as SocketNewItemsNotice from 'ui/shared/SocketNewItemsNotice'; import * as SocketNewItemsNotice from 'ui/shared/SocketNewItemsNotice';
import { default as Thead } from 'ui/shared/TheadSticky';
import TokenTransferTableItem from 'ui/shared/TokenTransfer/TokenTransferTableItem'; import TokenTransferTableItem from 'ui/shared/TokenTransfer/TokenTransferTableItem';
interface Props { interface Props {
...@@ -34,18 +33,18 @@ const TokenTransferTable = ({ ...@@ -34,18 +33,18 @@ const TokenTransferTable = ({
return ( return (
<AddressHighlightProvider> <AddressHighlightProvider>
<Table minW="950px"> <TableRoot minW="950px">
<Thead top={ top }> <TableHeaderSticky top={ top }>
<Tr> <TableRow>
{ showTxInfo && <Th width="44px"></Th> } { showTxInfo && <TableColumnHeader width="44px"></TableColumnHeader> }
<Th width="230px">Token</Th> <TableColumnHeader width="230px">Token</TableColumnHeader>
<Th width="160px">Token ID</Th> <TableColumnHeader width="160px">Token ID</TableColumnHeader>
{ showTxInfo && <Th width="200px">Txn hash</Th> } { showTxInfo && <TableColumnHeader width="200px">Txn hash</TableColumnHeader> }
<Th width="60%">From/To</Th> <TableColumnHeader width="60%">From/To</TableColumnHeader>
<Th width="40%" isNumeric>Value</Th> <TableColumnHeader width="40%" isNumeric>Value</TableColumnHeader>
</Tr> </TableRow>
</Thead> </TableHeaderSticky>
<Tbody> <TableBody>
{ showSocketInfo && ( { showSocketInfo && (
<SocketNewItemsNotice.Desktop <SocketNewItemsNotice.Desktop
url={ window.location.href } url={ window.location.href }
...@@ -65,8 +64,8 @@ const TokenTransferTable = ({ ...@@ -65,8 +64,8 @@ const TokenTransferTable = ({
isLoading={ isLoading } isLoading={ isLoading }
/> />
)) } )) }
</Tbody> </TableBody>
</Table> </TableRoot>
</AddressHighlightProvider> </AddressHighlightProvider>
); );
}; };
......
import { Tr, Td, Flex, Box } from '@chakra-ui/react'; import { Flex, Box } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { TokenTransfer } from 'types/api/tokenTransfer'; import type { TokenTransfer } from 'types/api/tokenTransfer';
import getCurrencyValue from 'lib/getCurrencyValue'; import getCurrencyValue from 'lib/getCurrencyValue';
import { getTokenTypeName } from 'lib/token/tokenTypes'; import { getTokenTypeName } from 'lib/token/tokenTypes';
import { Badge } from 'toolkit/chakra/badge';
import { Skeleton } from 'toolkit/chakra/skeleton';
import { TableCell, TableRow } from 'toolkit/chakra/table';
import AddressFromTo from 'ui/shared/address/AddressFromTo'; import AddressFromTo from 'ui/shared/address/AddressFromTo';
import Skeleton from 'ui/shared/chakra/Skeleton';
import Tag from 'ui/shared/chakra/Tag';
import NftEntity from 'ui/shared/entities/nft/NftEntity'; import NftEntity from 'ui/shared/entities/nft/NftEntity';
import TokenEntity from 'ui/shared/entities/token/TokenEntity'; import TokenEntity from 'ui/shared/entities/token/TokenEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
...@@ -45,15 +46,15 @@ const TokenTransferTableItem = ({ ...@@ -45,15 +46,15 @@ const TokenTransferTableItem = ({
}) : { usd: null, valueStr: null }; }) : { usd: null, valueStr: null };
return ( return (
<Tr alignItems="top"> <TableRow alignItems="top">
{ showTxInfo && txHash && ( { showTxInfo && txHash && (
<Td> <TableCell>
<Box my="3px"> <Box my="3px">
<TxAdditionalInfo hash={ txHash } isLoading={ isLoading }/> <TxAdditionalInfo hash={ txHash } isLoading={ isLoading }/>
</Box> </Box>
</Td> </TableCell>
) } ) }
<Td> <TableCell>
{ token ? ( { token ? (
<> <>
<TokenEntity <TokenEntity
...@@ -64,13 +65,13 @@ const TokenTransferTableItem = ({ ...@@ -64,13 +65,13 @@ const TokenTransferTableItem = ({
mt={ 1 } mt={ 1 }
/> />
<Flex columnGap={ 2 } rowGap={ 2 } mt={ 2 } flexWrap="wrap"> <Flex columnGap={ 2 } rowGap={ 2 } mt={ 2 } flexWrap="wrap">
<Tag isLoading={ isLoading }>{ getTokenTypeName(token.type) }</Tag> <Badge loading={ isLoading }>{ getTokenTypeName(token.type) }</Badge>
<Tag colorScheme="orange" isLoading={ isLoading }>{ getTokenTransferTypeText(type) }</Tag> <Badge colorScheme="orange" loading={ isLoading }>{ getTokenTransferTypeText(type) }</Badge>
</Flex> </Flex>
</> </>
) : 'N/A' } ) : 'N/A' }
</Td> </TableCell>
<Td> <TableCell>
{ total && 'token_id' in total && total.token_id !== null && token && ( { total && 'token_id' in total && total.token_id !== null && token && (
<NftEntity <NftEntity
hash={ token.address } hash={ token.address }
...@@ -78,9 +79,9 @@ const TokenTransferTableItem = ({ ...@@ -78,9 +79,9 @@ const TokenTransferTableItem = ({
isLoading={ isLoading } isLoading={ isLoading }
/> />
) } ) }
</Td> </TableCell>
{ showTxInfo && txHash && ( { showTxInfo && txHash && (
<Td> <TableCell>
<TxEntity <TxEntity
hash={ txHash } hash={ txHash }
isLoading={ isLoading } isLoading={ isLoading }
...@@ -98,9 +99,9 @@ const TokenTransferTableItem = ({ ...@@ -98,9 +99,9 @@ const TokenTransferTableItem = ({
mt="10px" mt="10px"
display="inline-block" display="inline-block"
/> />
</Td> </TableCell>
) } ) }
<Td> <TableCell>
<AddressFromTo <AddressFromTo
from={ from } from={ from }
to={ to } to={ to }
...@@ -109,20 +110,20 @@ const TokenTransferTableItem = ({ ...@@ -109,20 +110,20 @@ const TokenTransferTableItem = ({
mt={ 1 } mt={ 1 }
mode={{ lg: 'compact', xl: 'long' }} mode={{ lg: 'compact', xl: 'long' }}
/> />
</Td> </TableCell>
<Td isNumeric verticalAlign="top"> <TableCell isNumeric verticalAlign="top">
{ valueStr && ( { valueStr && (
<Skeleton isLoaded={ !isLoading } display="inline-block" mt="7px" wordBreak="break-all"> <Skeleton loading={ isLoading } display="inline-block" mt="7px" wordBreak="break-all">
{ valueStr } { valueStr }
</Skeleton> </Skeleton>
) } ) }
{ usd && ( { usd && (
<Skeleton isLoaded={ !isLoading } color="text_secondary" mt="10px" ml="auto" w="min-content"> <Skeleton loading={ isLoading } color="text.secondary" mt="10px" ml="auto" w="min-content">
<span>${ usd }</span> <span>${ usd }</span>
</Skeleton> </Skeleton>
) } ) }
</Td> </TableCell>
</Tr> </TableRow>
); );
}; };
......
import type { As } from '@chakra-ui/react'; import { Box, Circle } from '@chakra-ui/react';
import { Box, Button, Circle, useColorModeValue } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import Skeleton from 'ui/shared/chakra/Skeleton'; import type { ButtonProps } from 'toolkit/chakra/button';
import { Button } from 'toolkit/chakra/button';
import { Skeleton } from 'toolkit/chakra/skeleton';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
const FilterIcon = <IconSvg name="filter" boxSize={ 5 } mr={{ base: 0, lg: 2 }}/>; interface Props extends ButtonProps {
interface Props {
isActive?: boolean;
isLoading?: boolean; isLoading?: boolean;
appliedFiltersNum?: number; appliedFiltersNum?: number;
onClick: () => void;
as?: As;
} }
const FilterButton = ({ isActive, isLoading, appliedFiltersNum, onClick, as }: Props, ref: React.ForwardedRef<HTMLButtonElement>) => { const FilterButton = ({ isLoading, appliedFiltersNum, ...rest }: Props, ref: React.ForwardedRef<HTMLButtonElement>) => {
const badgeColor = useColorModeValue('white', 'black');
const badgeBgColor = useColorModeValue('blue.700', 'gray.50');
if (isLoading) { if (isLoading) {
return <Skeleton w={{ base: 9, lg: '78px' }} h={ 8 } borderRadius="base" flexShrink={ 0 }/>; return <Skeleton loading w={{ base: 9, lg: '78px' }} h={ 8 } borderRadius="base" flexShrink={ 0 }/>;
} }
const num = ( const numElement = appliedFiltersNum ? (
<Circle <Circle
className="AppliedFiltersNum" className="AppliedFiltersNum"
bg={ isActive ? 'link_hovered' : badgeBgColor }
size={ 5 } size={ 5 }
color={ badgeColor } bg={{ _light: 'blue.700', _dark: 'gray.50' }}
color={{ _light: 'white', _dark: 'black' }}
> >
{ appliedFiltersNum } { appliedFiltersNum }
</Circle> </Circle>
); ) : null;
return ( return (
<Button <Button
ref={ ref } ref={ ref }
rightIcon={ appliedFiltersNum ? num : undefined }
size="sm" size="sm"
fontWeight="500" fontWeight="medium"
variant="outline" gap={ 1 }
colorScheme="gray" variant="dropdown"
onClick={ onClick }
isActive={ isActive }
selected={ Boolean(appliedFiltersNum) } selected={ Boolean(appliedFiltersNum) }
px={ 1.5 }
flexShrink={ 0 } flexShrink={ 0 }
as={ as }
pointerEvents="all" pointerEvents="all"
_hover={ isActive ? { { ...rest }
color: 'link_hovered',
'.AppliedFiltersNum': {
bg: 'link_hovered',
},
} : undefined }
> >
{ FilterIcon } <IconSvg name="filter" boxSize={ 5 }/>
<Box display={{ base: 'none', lg: 'block' }}>Filter</Box> <Box display={{ base: 'none', lg: 'block' }}>Filter</Box>
{ numElement }
</Button> </Button>
); );
}; };
......
import type { PopoverContentProps } from '@chakra-ui/react'; import type { PopoverContentProps } from '@chakra-ui/react';
import {
PopoverTrigger,
PopoverContent,
PopoverBody,
useDisclosure,
} from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import Popover from 'ui/shared/chakra/Popover'; import { PopoverBody, PopoverContent, PopoverTrigger, PopoverRoot } from 'toolkit/chakra/popover';
import FilterButton from 'ui/shared/filters/FilterButton'; import FilterButton from 'ui/shared/filters/FilterButton';
interface Props { interface Props {
...@@ -18,24 +12,20 @@ interface Props { ...@@ -18,24 +12,20 @@ interface Props {
} }
const PopoverFilter = ({ appliedFiltersNum, children, contentProps, isLoading }: Props) => { const PopoverFilter = ({ appliedFiltersNum, children, contentProps, isLoading }: Props) => {
const { isOpen, onToggle, onClose } = useDisclosure();
return ( return (
<Popover isOpen={ isOpen } onClose={ onClose } placement="bottom-start" isLazy> <PopoverRoot>
<PopoverTrigger> <PopoverTrigger>
<FilterButton <FilterButton
isActive={ isOpen }
onClick={ onToggle }
appliedFiltersNum={ appliedFiltersNum } appliedFiltersNum={ appliedFiltersNum }
isLoading={ isLoading } isLoading={ isLoading }
/> />
</PopoverTrigger> </PopoverTrigger>
<PopoverContent { ...contentProps }> <PopoverContent { ...contentProps }>
<PopoverBody px={ 4 } py={ 6 } display="flex" flexDir="column" rowGap={ 5 }> <PopoverBody display="flex" flexDir="column" rowGap={ 5 }>
{ children } { children }
</PopoverBody> </PopoverBody>
</PopoverContent> </PopoverContent>
</Popover> </PopoverRoot>
); );
}; };
......
import { CheckboxGroup, Checkbox, Text, Flex, Link, useCheckboxGroup } from '@chakra-ui/react'; import { CheckboxGroup, Text, Flex, useCheckboxGroup, Fieldset } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { NFTTokenType, TokenType } from 'types/api/token'; import type { NFTTokenType, TokenType } from 'types/api/token';
import { import { TOKEN_TYPES, TOKEN_TYPE_IDS, NFT_TOKEN_TYPE_IDS } from 'lib/token/tokenTypes';
TOKEN_TYPES, TOKEN_TYPE_IDS, NFT_TOKEN_TYPE_IDS } from 'lib/token/tokenTypes'; import { Checkbox } from 'toolkit/chakra/checkbox';
import { Link } from 'toolkit/chakra/link';
type Props<T extends TokenType | NFTTokenType> = { type Props<T extends TokenType | NFTTokenType> = {
onChange: (nextValue: Array<T>) => void; onChange: (nextValue: Array<T>) => void;
...@@ -22,15 +23,15 @@ const TokenTypeFilter = <T extends TokenType | NFTTokenType>({ nftOnly, onChange ...@@ -22,15 +23,15 @@ const TokenTypeFilter = <T extends TokenType | NFTTokenType>({ nftOnly, onChange
onChange([]); onChange([]);
}, [ onChange, setValue, value.length ]); }, [ onChange, setValue, value.length ]);
const handleChange = React.useCallback((nextValue: Array<T>) => { const handleChange = React.useCallback((nextValue: Array<string>) => {
setValue(nextValue); setValue(nextValue as Array<T>);
onChange(nextValue); onChange(nextValue as Array<T>);
}, [ onChange, setValue ]); }, [ onChange, setValue ]);
return ( return (
<> <>
<Flex justifyContent="space-between" fontSize="sm"> <Flex justifyContent="space-between" fontSize="sm">
<Text fontWeight={ 600 } variant="secondary">Type</Text> <Text fontWeight={ 600 } color="text.secondary">Type</Text>
<Link <Link
onClick={ handleReset } onClick={ handleReset }
cursor={ value.length > 0 ? 'pointer' : 'unset' } cursor={ value.length > 0 ? 'pointer' : 'unset' }
...@@ -42,13 +43,24 @@ const TokenTypeFilter = <T extends TokenType | NFTTokenType>({ nftOnly, onChange ...@@ -42,13 +43,24 @@ const TokenTypeFilter = <T extends TokenType | NFTTokenType>({ nftOnly, onChange
Reset Reset
</Link> </Link>
</Flex> </Flex>
<CheckboxGroup size="lg" onChange={ handleChange } value={ value }> <Fieldset.Root>
<CheckboxGroup defaultValue={ defaultValue } onValueChange={ handleChange } value={ value } name="token_type">
<Fieldset.Content>
{ (nftOnly ? NFT_TOKEN_TYPE_IDS : TOKEN_TYPE_IDS).map((id) => (
<Checkbox key={ id } value={ id }>
{ TOKEN_TYPES[id] }
</Checkbox>
)) }
</Fieldset.Content>
</CheckboxGroup>
</Fieldset.Root>
{ /* <CheckboxGroup size="lg" onChange={ handleChange } value={ value }>
{ (nftOnly ? NFT_TOKEN_TYPE_IDS : TOKEN_TYPE_IDS).map((id) => ( { (nftOnly ? NFT_TOKEN_TYPE_IDS : TOKEN_TYPE_IDS).map((id) => (
<Checkbox key={ id } value={ id }> <Checkbox key={ id } value={ id }>
<Text fontSize="md">{ TOKEN_TYPES[id] }</Text> <Text fontSize="md">{ TOKEN_TYPES[id] }</Text>
</Checkbox> </Checkbox>
)) } )) }
</CheckboxGroup> </CheckboxGroup> */ }
</> </>
); );
}; };
......
import React from 'react';
import { Checkbox } from 'toolkit/chakra/checkbox';
import { Section, Container, SectionHeader, SamplesStack, Sample } from './parts';
const CheckboxesShowcase = () => {
return (
<Container value="checkboxes">
<Section>
<SectionHeader>Variant</SectionHeader>
<SamplesStack>
<Sample label="variant: subtle">
<Checkbox>Option 1</Checkbox>
<Checkbox checked>Option 2</Checkbox>
<Checkbox disabled>Option 3</Checkbox>
<Checkbox checked disabled>Option 4</Checkbox>
</Sample>
</SamplesStack>
</Section>
<Section>
<SectionHeader>Size</SectionHeader>
<SamplesStack>
<Sample label="size: xs">
<Checkbox size="xs">Option 1</Checkbox>
<Checkbox size="xs">Option 2</Checkbox>
</Sample>
<Sample label="size: sm">
<Checkbox size="sm">Option 1</Checkbox>
<Checkbox size="sm">Option 2</Checkbox>
</Sample>
<Sample label="size: md">
<Checkbox size="md">Option 1</Checkbox>
<Checkbox size="md">Option 2</Checkbox>
</Sample>
</SamplesStack>
</Section>
</Container>
);
};
export default React.memo(CheckboxesShowcase);
import React from 'react';
import { Radio, RadioGroup } from 'toolkit/chakra/radio';
import { Section, Container, SectionHeader, SamplesStack, Sample } from './parts';
const RadiosShowcase = () => {
return (
<Container value="radios">
<Section>
<SectionHeader>Variant</SectionHeader>
<SamplesStack>
<Sample label="variant: subtle">
<RadioGroup defaultValue="1">
<Radio value="1">Option 1</Radio>
<Radio value="2">Option 2</Radio>
</RadioGroup>
</Sample>
</SamplesStack>
</Section>
<Section>
<SectionHeader>Size</SectionHeader>
<SamplesStack>
<Sample label="size: xs">
<RadioGroup defaultValue="1" size="xs">
<Radio value="1">Option 1</Radio>
<Radio value="2">Option 2</Radio>
</RadioGroup>
</Sample>
<Sample label="size: sm">
<RadioGroup defaultValue="1" size="sm">
<Radio value="1">Option 1</Radio>
<Radio value="2">Option 2</Radio>
</RadioGroup>
</Sample>
<Sample label="size: md">
<RadioGroup defaultValue="1" size="md">
<Radio value="1">Option 1</Radio>
<Radio value="2">Option 2</Radio>
</RadioGroup>
</Sample>
</SamplesStack>
</Section>
<Section>
<SectionHeader>Orientation</SectionHeader>
<SamplesStack>
<Sample label="orientation: horizontal">
<RadioGroup defaultValue="1" orientation="horizontal">
<Radio value="1">Option 1</Radio>
<Radio value="2">Option 2</Radio>
</RadioGroup>
</Sample>
<Sample label="orientation: vertical">
<RadioGroup defaultValue="1" orientation="vertical">
<Radio value="1">Option 1</Radio>
<Radio value="2">Option 2</Radio>
</RadioGroup>
</Sample>
</SamplesStack>
</Section>
<Section>
<SectionHeader>Disabled</SectionHeader>
<SamplesStack>
<Sample label="disabled: true">
<RadioGroup defaultValue="1" disabled>
<Radio value="1">Option 1</Radio>
<Radio value="2">Option 2</Radio>
</RadioGroup>
</Sample>
</SamplesStack>
</Section>
</Container>
);
};
export default React.memo(RadiosShowcase);
import { createListCollection } from '@chakra-ui/react'; import { createListCollection } from '@chakra-ui/react';
import { noop } from 'es-toolkit';
import React from 'react'; import React from 'react';
import { SelectContent, SelectItem, SelectRoot, SelectControl, SelectValueText } from 'toolkit/chakra/select'; import { SelectContent, SelectItem, SelectRoot, SelectControl, SelectValueText } from 'toolkit/chakra/select';
import Sort from 'ui/shared/sort/Sort'; import Sort from 'ui/shared/sort/Sort';
import TokenTransferFilter from 'ui/shared/TokenTransfer/TokenTransferFilter';
import { SORT_OPTIONS } from 'ui/txs/useTxsSort'; import { SORT_OPTIONS } from 'ui/txs/useTxsSort';
import { Section, Container, SectionHeader, SamplesStack, Sample, SectionSubHeader } from './parts'; import { Section, Container, SectionHeader, SamplesStack, Sample, SectionSubHeader } from './parts';
...@@ -75,6 +77,15 @@ const SelectsShowcase = () => { ...@@ -75,6 +77,15 @@ const SelectsShowcase = () => {
/> />
</Sample> </Sample>
</SamplesStack> </SamplesStack>
<SectionSubHeader>Token transfers filter</SectionSubHeader>
<SamplesStack>
<Sample>
<TokenTransferFilter defaultTypeFilters={ [ ] } onTypeFilterChange={ noop } withAddressFilter/>
<TokenTransferFilter defaultTypeFilters={ [ ] } onTypeFilterChange={ noop } appliedFiltersNum={ 2 }/>
<TokenTransferFilter defaultTypeFilters={ [ ] } onTypeFilterChange={ noop } appliedFiltersNum={ 2 } isLoading/>
</Sample>
</SamplesStack>
</Section> </Section>
</Container> </Container>
); );
......
import { Hide, Show } from '@chakra-ui/react'; import { Box } from '@chakra-ui/react';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
...@@ -72,12 +72,12 @@ const TxTokenTransfer = ({ txQuery, tokenTransferFilter }: Props) => { ...@@ -72,12 +72,12 @@ const TxTokenTransfer = ({ txQuery, tokenTransferFilter }: Props) => {
const content = tokenTransferQuery.data?.items ? ( const content = tokenTransferQuery.data?.items ? (
<> <>
<Hide below="lg" ssr={ false }> <Box hideBelow="lg">
<TokenTransferTable data={ items } top={ isActionBarHidden ? 0 : ACTION_BAR_HEIGHT_DESKTOP } isLoading={ tokenTransferQuery.isPlaceholderData }/> <TokenTransferTable data={ items } top={ isActionBarHidden ? 0 : ACTION_BAR_HEIGHT_DESKTOP } isLoading={ tokenTransferQuery.isPlaceholderData }/>
</Hide> </Box>
<Show below="lg" ssr={ false }> <Box hideFrom="lg">
<TokenTransferList data={ items } isLoading={ tokenTransferQuery.isPlaceholderData }/> <TokenTransferList data={ items } isLoading={ tokenTransferQuery.isPlaceholderData }/>
</Show> </Box>
</> </>
) : null; ) : null;
...@@ -96,15 +96,16 @@ const TxTokenTransfer = ({ txQuery, tokenTransferFilter }: Props) => { ...@@ -96,15 +96,16 @@ const TxTokenTransfer = ({ txQuery, tokenTransferFilter }: Props) => {
return ( return (
<DataListDisplay <DataListDisplay
isError={ txQuery.isError || tokenTransferQuery.isError } isError={ txQuery.isError || tokenTransferQuery.isError }
items={ items } itemsNum={ items.length }
emptyText="There are no token transfers." emptyText="There are no token transfers."
filterProps={{ filterProps={{
emptyFilteredText: `Couldn${ apos }t find any token transfer that matches your query.`, emptyFilteredText: `Couldn${ apos }t find any token transfer that matches your query.`,
hasActiveFilters: Boolean(numActiveFilters), hasActiveFilters: Boolean(numActiveFilters),
}} }}
content={ content }
actionBar={ actionBar } actionBar={ actionBar }
/> >
{ content }
</DataListDisplay>
); );
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment