Commit e4a5483f authored by tom's avatar tom

mud address tab

parent 67f0e1c2
......@@ -4,12 +4,12 @@ import React from 'react';
import PageNextJs from 'nextjs/PageNextJs';
// const MudWorlds = dynamic(() => import('ui/pages/MudWorlds'), { ssr: false });
const MudWorlds = dynamic(() => import('ui/pages/MudWorlds'), { ssr: false });
const Page: NextPage = () => {
return (
<PageNextJs pathname="/mud-worlds">
{ /* <MudWorlds/> */ }
<MudWorlds/>
</PageNextJs>
);
};
......
......@@ -5,7 +5,7 @@ import { Skeleton } from './skeleton';
export interface IconButtonProps extends ButtonProps {}
// TODO @tom2drum variants for icon buttons: prev-next, top-bar, copy-to-clipboard
// TODO @tom2drum variants for icon buttons: prev-next, top-bar, copy-to-clipboard, filter column
// TODO @tom2drum fix loading state for outlined variant
export const IconButton = React.forwardRef<HTMLDivElement, IconButtonProps>(
......
......@@ -51,6 +51,19 @@ export const PopoverCloseTrigger = React.forwardRef<
);
});
export const PopoverCloseTriggerWrapper = React.forwardRef<
HTMLButtonElement,
ChakraPopover.CloseTriggerProps
>(function PopoverCloseTriggerWrapper(props, ref) {
return (
<ChakraPopover.CloseTrigger
ref={ ref }
{ ...props }
asChild
/>
);
});
export const PopoverRoot = (props: ChakraPopover.RootProps) => {
const positioning = {
placement: 'bottom-start' as const,
......
......@@ -95,13 +95,13 @@ export default function useContractTabs(data: Address | undefined, isPlaceholder
title: 'Custom ABI',
component: <ContractMethodsCustom isLoading={ contractQuery.isPlaceholderData }/>,
},
// hasMudTab && {
// id: 'mud_system' as const,
// title: 'MUD System',
// component: mudSystemsQuery.isPlaceholderData ?
// <ContentLoader/> :
// <ContractMethodsMudSystem items={ mudSystemsQuery.data?.items ?? [] }/>,
// },
hasMudTab && {
id: 'mud_system' as const,
title: 'MUD System',
component: mudSystemsQuery.isPlaceholderData ?
<ContentLoader/> :
<ContractMethodsMudSystem items={ mudSystemsQuery.data?.items ?? [] }/>,
},
].filter(Boolean),
isLoading: contractQuery.isPlaceholderData,
};
......
import { Box, useColorModeValue, chakra, Grid } from '@chakra-ui/react';
import { Box, chakra, Grid } from '@chakra-ui/react';
import React from 'react';
import { route } from 'nextjs-routes';
import useIsMobile from 'lib/hooks/useIsMobile';
import isBrowser from 'lib/isBrowser';
import { Link } from 'toolkit/chakra/link';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
import IconSvg from 'ui/shared/IconSvg';
import LinkInternal from 'ui/shared/links/LinkInternal';
import useAddressQuery from '../utils/useAddressQuery';
......@@ -17,9 +17,11 @@ type TableViewProps = {
hash: string;
tableId: string;
tableName: string;
recordId?: never;
recordName?: never;
};
type RecordViewProps = TableViewProps & {
type RecordViewProps = Omit<TableViewProps, 'recordId' | 'recordName'> & {
recordId: string;
recordName: string;
};
......@@ -32,8 +34,6 @@ type BreadcrumbItemProps = {
};
const BreadcrumbItem = ({ text, href, isLast, scrollRef }: BreadcrumbItemProps) => {
const iconColor = useColorModeValue('gray.300', 'gray.600');
const currentUrl = isBrowser() ? window.location.href : '';
const onLinkClick = React.useCallback(() => {
......@@ -60,7 +60,7 @@ const BreadcrumbItem = ({ text, href, isLast, scrollRef }: BreadcrumbItemProps)
return (
<Grid gap={ 2 } overflow="hidden" templateColumns="auto 24px" alignItems="center">
<LinkInternal
<Link
href={ href }
onClick={ onLinkClick }
overflow="hidden"
......@@ -68,8 +68,8 @@ const BreadcrumbItem = ({ text, href, isLast, scrollRef }: BreadcrumbItemProps)
whiteSpace="nowrap"
>
{ text }
</LinkInternal>
{ !isLast && <IconSvg name="arrows/east" boxSize={ 6 } color={ iconColor }/> }
</Link>
{ !isLast && <IconSvg name="arrows/east" boxSize={ 6 } color={{ _light: 'gray.300', _dark: 'gray.600' }}/> }
</Grid>
);
};
......@@ -103,7 +103,7 @@ const AddressMudBreadcrumbs = (props: TableViewProps | RecordViewProps) => {
isLast={ !('recordId' in props) }
scrollRef={ props.scrollRef }
/>
{ ('recordId' in props) && (
{ ('recordId' in props && typeof props.recordId === 'string') && ('recordName' in props && typeof props.recordName === 'string') && (
<BreadcrumbItem
text={ props.recordName }
href={ route({ pathname: '/address/[hash]', query: { ...queryParams, table_id: props.tableId, record_id: props.recordId } }) }
......
import { Box, Td, Tr, Flex, Text, Table, Show, Hide, Divider, VStack } from '@chakra-ui/react';
import { Box, Flex, Separator, Text, VStack } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import React from 'react';
import useApiQuery from 'lib/api/useApiQuery';
import dayjs from 'lib/date/dayjs';
import getQueryParamString from 'lib/router/getQueryParamString';
import { TableRoot, TableRow, TableCell } from 'toolkit/chakra/table';
import ContentLoader from 'ui/shared/ContentLoader';
import DataFetchAlert from 'ui/shared/DataFetchAlert';
import TruncatedValue from 'ui/shared/TruncatedValue';
......@@ -53,29 +54,29 @@ const AddressMudRecord = ({ tableId, recordId, isQueryEnabled = true, scrollRef
scrollRef={ scrollRef }
/>
) }
<Show above="lg" ssr={ false }>
<Table borderRadius="8px" style={{ tableLayout: 'auto' }} width="100%" overflow="hidden">
<Box hideBelow="lg">
<TableRoot borderRadius="8px" style={{ tableLayout: 'auto' }} width="100%" overflow="hidden">
{ data?.schema.key_names.length && data?.schema.key_names.map((keyName, index) => (
<Tr key={ keyName } borderBottomStyle={ index === data.schema.key_names.length - 1 ? 'hidden' : 'solid' }>
<Td fontWeight={ 600 } whiteSpace="nowrap" fontSize="sm">
<TableRow key={ keyName } borderBottomStyle={ index === data.schema.key_names.length - 1 ? 'hidden' : 'solid' }>
<TableCell fontWeight={ 600 } whiteSpace="nowrap" fontSize="sm">
{ keyName } ({ data.schema.key_types[index] })
</Td>
<Td colSpan={ 2 } fontSize="sm">
</TableCell>
<TableCell colSpan={ 2 } fontSize="sm">
<Flex justifyContent="space-between">
<TruncatedValue value={ getValueString(data.record.decoded[keyName]) } mr={ 2 }/>
{ index === 0 && <Box color="text_secondary">{ dayjs(data.record.timestamp).format('lll') }</Box> }
</Flex>
</Td>
</Tr>
</TableCell>
</TableRow>
)) }
<AddressMudRecordValues data={ data }/>
</Table>
</Show>
<Hide above="lg" ssr={ false }>
</TableRoot>
</Box>
<Box hideFrom="lg">
<>
{ data?.schema.key_names.length && data?.schema.key_names.map((keyName, index) => (
<VStack gap={ 1 } key={ keyName } alignItems="start" fontSize="sm">
<Divider/>
<Separator/>
<Text fontWeight={ 600 } whiteSpace="nowrap">
{ keyName } ({ data.schema.key_types[index] })
</Text>
......@@ -83,11 +84,11 @@ const AddressMudRecord = ({ tableId, recordId, isQueryEnabled = true, scrollRef
{ index === 0 && <Box color="text_secondary">{ dayjs(data.record.timestamp).format('lll') }</Box> }
</VStack>
)) }
<Table borderRadius="8px" style={{ tableLayout: 'auto' }} width="100%" mt={ 2 } overflow="hidden">
<TableRoot borderRadius="8px" style={{ tableLayout: 'auto' }} width="100%" mt={ 2 } overflow="hidden">
<AddressMudRecordValues data={ data }/>
</Table>
</TableRoot>
</>
</Hide>
</Box>
</>
);
};
......
import { Box, Td, Tr, useColorModeValue } from '@chakra-ui/react';
import { Box } from '@chakra-ui/react';
import React from 'react';
import type { AddressMudRecord } from 'types/api/address';
import { TableCell, TableRow } from 'toolkit/chakra/table';
import { getValueString } from './utils';
type Props = {
......@@ -10,7 +12,7 @@ type Props = {
};
const AddressMudRecordValues = ({ data }: Props) => {
const valuesBgColor = useColorModeValue('blackAlpha.50', 'whiteAlpha.50');
const valuesBgColor = { _light: 'blackAlpha.50', _dark: 'whiteAlpha.50' };
if (!data?.schema.value_names.length) {
return null;
......@@ -18,22 +20,22 @@ const AddressMudRecordValues = ({ data }: Props) => {
return (
<>
<Tr backgroundColor={ valuesBgColor } borderBottomStyle="hidden" >
<Td fontWeight={ 600 } w="100px" fontSize="sm">Field</Td>
<Td fontWeight={ 600 } w="90px" fontSize="sm">Type</Td>
<Td fontWeight={ 600 } fontSize="sm">Value</Td>
</Tr>
<TableRow backgroundColor={ valuesBgColor } borderBottomStyle="hidden" >
<TableCell fontWeight={ 600 } w="100px" fontSize="sm">Field</TableCell>
<TableCell fontWeight={ 600 } w="90px" fontSize="sm">Type</TableCell>
<TableCell fontWeight={ 600 } fontSize="sm">Value</TableCell>
</TableRow>
{
data?.schema.value_names.map((valName, index) => (
<Tr key={ valName } backgroundColor={ valuesBgColor } borderBottomStyle="hidden">
<Td fontWeight={ 400 } w="100px" py={ 0 } pb={ 4 } pr={ 0 }wordBreak="break-all">{ valName }</Td>
<Td fontWeight={ 400 } w="90px" py={ 0 } pb={ 4 } wordBreak="break-all">{ data.schema.value_types[index] }</Td>
<Td fontWeight={ 400 } wordBreak="break-word" py={ 0 } pb={ 4 }>
<TableRow key={ valName } backgroundColor={ valuesBgColor } borderBottomStyle="hidden">
<TableCell fontWeight={ 400 } w="100px" py={ 0 } pb={ 4 } pr={ 0 } wordBreak="break-all">{ valName }</TableCell>
<TableCell fontWeight={ 400 } w="90px" py={ 0 } pb={ 4 } wordBreak="break-all">{ data.schema.value_types[index] }</TableCell>
<TableCell fontWeight={ 400 } wordBreak="break-word" py={ 0 } pb={ 4 }>
<Box>
{ getValueString(data.record.decoded[valName]) }
</Box>
</Td>
</Tr>
</TableCell>
</TableRow>
))
}
</>
......
......@@ -16,7 +16,7 @@ const AddressMudRecordsKeyFilter = ({ value = '', handleFilterChange, columnName
return (
<TableColumnFilterWrapper
columnName={ columnName }
isActive={ Boolean(value) }
selected={ Boolean(value) }
isLoading={ isLoading }
w="350px"
>
......
......@@ -8,10 +8,9 @@ type Props = {
handleFilterChange: (val: string) => void;
title: string;
columnName: string;
onClose?: () => void;
};
const AddressMudRecordsKeyFilter = ({ value = '', handleFilterChange, columnName, title, onClose }: Props) => {
const AddressMudRecordsKeyFilterContent = ({ value = '', handleFilterChange, columnName, title }: Props) => {
const [ filterValue, setFilterValue ] = React.useState<string>(value);
const onFilter = React.useCallback(() => {
......@@ -23,11 +22,10 @@ const AddressMudRecordsKeyFilter = ({ value = '', handleFilterChange, columnName
title={ title }
isFilled={ filterValue !== value }
onFilter={ onFilter }
onClose={ onClose }
>
<FilterInput
initialValue={ value }
size="xs"
size="sm"
onChange={ setFilterValue }
placeholder={ columnName }
/>
......@@ -35,4 +33,4 @@ const AddressMudRecordsKeyFilter = ({ value = '', handleFilterChange, columnName
);
};
export default AddressMudRecordsKeyFilter;
export default AddressMudRecordsKeyFilterContent;
import type { StyleProps } from '@chakra-ui/react';
import { Box, Link, Table, Tbody, Td, Th, Tr, Flex, useColorModeValue, useBoolean, Tooltip } from '@chakra-ui/react';
import { Box, Flex } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import React from 'react';
......@@ -10,10 +9,13 @@ import { route } from 'nextjs-routes';
import capitalizeFirstLetter from 'lib/capitalizeFirstLetter';
import dayjs from 'lib/date/dayjs';
import useIsMobile from 'lib/hooks/useIsMobile';
import { middot } from 'lib/html-entities';
import { Link } from 'toolkit/chakra/link';
import { TableBody, TableCell, TableColumnHeader, TableHeaderSticky, TableRoot, TableRow } from 'toolkit/chakra/table';
import type { TableColumnHeaderProps } from 'toolkit/chakra/table';
import { Tooltip } from 'toolkit/chakra/tooltip';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
import IconSvg from 'ui/shared/IconSvg';
import LinkInternal from 'ui/shared/links/LinkInternal';
import { default as Thead } from 'ui/shared/TheadSticky';
import AddressMudRecordsKeyFilter from './AddressMudRecordsKeyFilter';
import { getNameTypeText, getValueString } from './utils';
......@@ -49,8 +51,8 @@ const AddressMudRecordsTable = ({
const totalColsCut = data.schema.key_names.length + data.schema.value_names.length;
const isMobile = useIsMobile(false);
const [ colsCutCount, setColsCutCount ] = React.useState<number>(isMobile ? MIN_CUT_COUNT : 0);
const [ isOpened, setIsOpened ] = useBoolean(false);
const [ hasCut, setHasCut ] = useBoolean(isMobile ? totalColsCut > MIN_CUT_COUNT : true);
const [ isOpened, setIsOpened ] = React.useState(false);
const [ hasCut, setHasCut ] = React.useState(isMobile ? totalColsCut > MIN_CUT_COUNT : true);
const containerRef = React.useRef<HTMLTableElement>(null);
const tableRef = React.useRef<HTMLTableElement>(null);
......@@ -59,7 +61,7 @@ const AddressMudRecordsTable = ({
const toggleIsOpen = React.useCallback(() => {
isOpened && tableRef.current?.scroll({ left: 0 });
setIsOpened.toggle();
setIsOpened((prev) => !prev);
toggleTableHasHorizontalScroll();
}, [ setIsOpened, toggleTableHasHorizontalScroll, isOpened ]);
......@@ -95,15 +97,13 @@ const AddressMudRecordsTable = ({
[ toggleSorting ],
);
const keyBgColor = useColorModeValue('blackAlpha.50', 'whiteAlpha.50');
React.useEffect(() => {
if (hasCut && !colsCutCount && containerRef.current) {
const count = Math.floor((containerRef.current.getBoundingClientRect().width - CUT_COL_WIDTH) / COL_MIN_WIDTH);
if (totalColsCut > MIN_CUT_COUNT && count - 1 < totalColsCut) {
setColsCutCount(count - 1);
} else {
setHasCut.off();
setHasCut(false);
}
}
}, [ colsCutCount, data.schema, hasCut, setHasCut, totalColsCut ]);
......@@ -114,7 +114,7 @@ const AddressMudRecordsTable = ({
const values = (isOpened || !hasCut) ? data.schema.value_names : data.schema.value_names.slice(0, colsCutCount - data.schema.key_names.length);
const colsCount = (isOpened || !hasCut) ? totalColsCut : colsCutCount;
const tdStyles: StyleProps = {
const tdStyles: TableColumnHeaderProps = {
wordBreak: 'break-word',
whiteSpace: 'normal',
minW: `${ colW }px`,
......@@ -130,23 +130,23 @@ const AddressMudRecordsTable = ({
}
const cutButton = (
<Th width={ `${ CUT_COL_WIDTH }px ` } verticalAlign="baseline">
<Tooltip label={ isOpened ? 'Hide columns' : 'Show all columns' }>
<Link onClick={ toggleIsOpen } aria-label="show/hide columns">...</Link>
<TableColumnHeader width={ `${ CUT_COL_WIDTH }px ` } verticalAlign="baseline">
<Tooltip content={ isOpened ? 'Hide columns' : 'Show all columns' }>
<Link onClick={ toggleIsOpen } aria-label="show/hide columns">{ middot }{ middot }{ middot }</Link>
</Tooltip>
</Th>
</TableColumnHeader>
);
return (
// can't implement both horizontal table scroll and sticky header
<Box maxW="100%" overflowX={ hasHorizontalScroll ? 'scroll' : 'unset' } whiteSpace="nowrap" ref={ tableRef }>
<Table style={{ tableLayout: 'fixed' }}>
<Thead top={ hasHorizontalScroll ? 0 : top } display={ hasHorizontalScroll ? 'table' : 'table-header-group' } w="100%">
<Tr >
<TableRoot style={{ tableLayout: 'fixed' }}>
<TableHeaderSticky top={ hasHorizontalScroll ? 0 : top } display={ hasHorizontalScroll ? 'table' : 'table-header-group' } w="100%">
<TableRow>
{ keys.map((keyName, index) => {
const text = getNameTypeText(keyName, data.schema.key_types[index]);
return (
<Th key={ keyName } { ...tdStyles }>
<TableColumnHeader key={ keyName } { ...tdStyles }>
{ index < 2 ? (
<Flex alignItems="center">
<Link
......@@ -178,46 +178,47 @@ const AddressMudRecordsTable = ({
</Box>
</Flex>
) : text }
</Th>
</TableColumnHeader>
);
}) }
{ values.map((valName, index) => (
<Th key={ valName } { ...tdStyles }>
<TableColumnHeader key={ valName } { ...tdStyles }>
{ capitalizeFirstLetter(valName) } ({ data.schema.value_types[index] })
</Th>
</TableColumnHeader>
)) }
{ hasCut && !isOpened && cutButton }
<Th { ...tdStyles } w={ `${ colW }px` }>Modified</Th>
<TableColumnHeader { ...tdStyles } w={ `${ colW }px` }>Modified</TableColumnHeader>
{ hasCut && isOpened && cutButton }
</Tr>
</Thead>
<Tbody display={ hasHorizontalScroll ? 'table' : 'table-row-group' } w="100%">
</TableRow>
</TableHeaderSticky>
<TableBody display={ hasHorizontalScroll ? 'table' : 'table-row-group' } w="100%">
{ data.items.map((item) => (
<Tr key={ item.id }>
<TableRow key={ item.id }>
{ keys.map((keyName, index) => (
<Td key={ keyName } backgroundColor={ keyBgColor } { ...tdStyles }>
<TableCell key={ keyName } backgroundColor={{ _light: 'blackAlpha.50', _dark: 'whiteAlpha.50' }} { ...tdStyles }>
{ index === 0 ? (
<LinkInternal
<Link
onClick={ onRecordClick }
data-id={ item.id }
fontWeight={ 700 }
href={ route({ pathname: '/address/[hash]', query: { hash, tab: 'mud', table_id: data.table.table_id, record_id: item.id } }) }
display="inline"
>
{ getValueString(item.decoded[keyName]) }
</LinkInternal>
</Link>
) : getValueString(item.decoded[keyName]) }
<CopyToClipboard text={ item.decoded[keyName] }/>
</Td>
<CopyToClipboard text={ String(item.decoded[keyName]) }/>
</TableCell>
)) }
{ values.map((valName) =>
<Td key={ valName } { ...tdStyles }>{ getValueString(item.decoded[valName]) }</Td>) }
{ hasCut && !isOpened && <Td width={ `${ CUT_COL_WIDTH }px ` }></Td> }
<Td { ...tdStyles } color="text_secondary" w={ `${ colW }px` }>{ dayjs(item.timestamp).format('lll') }</Td>
{ hasCut && isOpened && <Td width={ `${ CUT_COL_WIDTH }px ` }></Td> }
</Tr>
<TableCell key={ valName } { ...tdStyles }>{ getValueString(item.decoded[valName]) }</TableCell>) }
{ hasCut && !isOpened && <TableCell width={ `${ CUT_COL_WIDTH }px ` }></TableCell> }
<TableCell { ...tdStyles } color="text.secondary" w={ `${ colW }px` }>{ dayjs(item.timestamp).format('lll') }</TableCell>
{ hasCut && isOpened && <TableCell width={ `${ CUT_COL_WIDTH }px ` }></TableCell> }
</TableRow>
)) }
</Tbody>
</Table>
</TableBody>
</TableRoot>
</Box>
);
};
......
import { Box, HStack, Tag, TagCloseButton, chakra, useBoolean } from '@chakra-ui/react';
import { Box, HStack, chakra } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import React from 'react';
......@@ -7,6 +7,7 @@ import type { AddressMudRecordsFilter, AddressMudRecordsSorting } from 'types/ap
import useIsMobile from 'lib/hooks/useIsMobile';
import { apos, nbsp } from 'lib/html-entities';
import getQueryParamString from 'lib/router/getQueryParamString';
import { Tag } from 'toolkit/chakra/tag';
import ActionBar, { ACTION_BAR_HEIGHT_DESKTOP } from 'ui/shared/ActionBar';
import ContentLoader from 'ui/shared/ContentLoader';
import DataListDisplay from 'ui/shared/DataListDisplay';
......@@ -36,7 +37,7 @@ const AddressMudTable = ({ scrollRef, tableId, isQueryEnabled = true }: Props) =
React.useState<AddressMudRecordsSorting | undefined>(getSortParamsFromQuery<AddressMudRecordsSorting>(router.query, SORT_SEQUENCE));
const [ filters, setFilters ] = React.useState<AddressMudRecordsFilter>({});
const isMobile = useIsMobile();
const [ tableHasHorizontalScroll, setTableHasHorizontalScroll ] = useBoolean(isMobile);
const [ tableHasHorizontalScroll, setTableHasHorizontalScroll ] = React.useState(isMobile);
const hash = getQueryParamString(router.query.hash);
......@@ -52,6 +53,10 @@ const AddressMudTable = ({ scrollRef, tableId, isQueryEnabled = true }: Props) =
},
});
const handleTableHasHorizontalScroll = React.useCallback(() => {
setTableHasHorizontalScroll((prev) => !prev);
}, []);
const toggleSorting = React.useCallback((val: AddressMudRecordsSorting['sort']) => {
const newSorting = { sort: val, order: getNextOrderValue(sorting?.sort === val ? sorting.order : undefined) };
setSorting(newSorting);
......@@ -83,15 +88,22 @@ const AddressMudTable = ({ scrollRef, tableId, isQueryEnabled = true }: Props) =
{ Object.entries(filters).map(([ key, value ]) => {
const index = key as FilterKeys === 'filter_key0' ? 0 : 1;
return (
<Tag display="inline-flex" key={ key } maxW="360px" colorScheme="blue">
<chakra.span color="text_secondary" >{
<Tag
display="inline-flex"
key={ key }
maxW="360px"
// TODO @tom2drum style filter tags
colorScheme="blue"
closable
onClose={ onRemoveFilterClick(key as FilterKeys) }
>
<chakra.span color="text.secondary" >{
getNameTypeText(data?.schema.key_names[index] || '', data?.schema.key_types[index] || '') }
</chakra.span>
<chakra.span color="text" overflow="hidden" textOverflow="ellipsis" whiteSpace="nowrap">
{ nbsp }
{ value }
</chakra.span>
<TagCloseButton onClick={ onRemoveFilterClick(key as FilterKeys) }/>
</Tag>
);
}) }
......@@ -126,7 +138,7 @@ const AddressMudTable = ({ scrollRef, tableId, isQueryEnabled = true }: Props) =
toggleSorting={ toggleSorting }
setFilters={ setFilters }
filters={ filters }
toggleTableHasHorizontalScroll={ setTableHasHorizontalScroll.toggle }
toggleTableHasHorizontalScroll={ handleTableHasHorizontalScroll }
scrollRef={ scrollRef }
hash={ hash }
/>
......@@ -146,17 +158,18 @@ const AddressMudTable = ({ scrollRef, tableId, isQueryEnabled = true }: Props) =
) }
<DataListDisplay
isError={ isError }
items={ data?.items }
itemsNum={ data?.items.length }
emptyText={ emptyText }
filterProps={{
emptyFilteredText: `Couldn${ apos }t find records that match your filter query.`,
hasActiveFilters: Object.values(filters).some(Boolean),
}}
content={ content }
actionBar={ actionBar }
showActionBarIfEmpty={ !isMobile }
mt={ data?.items.length ? 0 : 2 }
/>
>
{ content }
</DataListDisplay>
</>
);
};
......
import { Hide, Show } from '@chakra-ui/react';
import { Box } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import React from 'react';
......@@ -50,11 +50,11 @@ const AddressMudTables = ({ scrollRef, isQueryEnabled = true }: Props) => {
<FilterInput
w={{ base: '100%', lg: '360px' }}
minW={{ base: 'auto', lg: '250px' }}
size="xs"
size="sm"
onChange={ setSearchTerm }
placeholder="Search by name, namespace or table ID..."
initialValue={ searchTerm }
isLoading={ isInitialLoading }
loading={ isInitialLoading }
/>
);
......@@ -67,7 +67,7 @@ const AddressMudTables = ({ scrollRef, isQueryEnabled = true }: Props) => {
const content = data?.items ? (
<>
<Hide below="lg" ssr={ false }>
<Box hideBelow="lg">
<AddressMudTablesTable
items={ data.items }
isLoading={ isPlaceholderData }
......@@ -75,8 +75,8 @@ const AddressMudTables = ({ scrollRef, isQueryEnabled = true }: Props) => {
scrollRef={ scrollRef }
hash={ hash }
/>
</Hide>
<Show below="lg" ssr={ false }>
</Box>
<Box hideFrom="lg">
{ data.items.map((item, index) => (
<AddressMudTablesListItem
key={ item.table.table_id + (isPlaceholderData ? String(index) : '') }
......@@ -85,22 +85,23 @@ const AddressMudTables = ({ scrollRef, isQueryEnabled = true }: Props) => {
hash={ hash }
/>
)) }
</Show>
</Box>
</>
) : null;
return (
<DataListDisplay
isError={ isError }
items={ data?.items }
itemsNum={ data?.items?.length }
emptyText="There are no tables for this address."
filterProps={{
emptyFilteredText: `Couldn${ apos }t find tables that match your filter query.`,
hasActiveFilters: Boolean(searchTerm),
}}
content={ content }
actionBar={ actionBar }
/>
>
{ content }
</DataListDisplay>
);
};
......
import { Divider, Text, useBoolean, Flex, Link, VStack, chakra, Box, Grid, GridItem } from '@chakra-ui/react';
import { Text, Flex, VStack, chakra, Box, Grid, GridItem, Separator } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import React from 'react';
......@@ -6,11 +6,11 @@ import type { AddressMudTableItem } from 'types/api/address';
import { route } from 'nextjs-routes';
import Skeleton from 'ui/shared/chakra/Skeleton';
import Tag from 'ui/shared/chakra/Tag';
import { Badge } from 'toolkit/chakra/badge';
import { Link } from 'toolkit/chakra/link';
import { Skeleton } from 'toolkit/chakra/skeleton';
import HashStringShorten from 'ui/shared/HashStringShorten';
import IconSvg from 'ui/shared/IconSvg';
import LinkInternal from 'ui/shared/links/LinkInternal';
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
type Props = {
......@@ -21,10 +21,14 @@ type Props = {
};
const AddressMudTablesListItem = ({ item, isLoading, scrollRef, hash }: Props) => {
const [ isOpened, setIsOpened ] = useBoolean(false);
const [ isOpened, setIsOpened ] = React.useState(false);
const router = useRouter();
const handleIconClick = React.useCallback(() => {
setIsOpened((prev) => !prev);
}, []);
const onTableClick = React.useCallback((e: React.MouseEvent) => {
if (e.metaKey || e.ctrlKey) {
// Allow opening in a new tab/window with right-click or ctrl/cmd+click
......@@ -48,14 +52,14 @@ const AddressMudTablesListItem = ({ item, isLoading, scrollRef, hash }: Props) =
return (
<ListItemMobile rowGap={ 3 } fontSize="sm" py={ 3 }>
<Flex w="100%">
<Skeleton isLoaded={ !isLoading }>
<Skeleton loading={ isLoading }>
<Link display="block">
<IconSvg
name="arrows/east-mini"
transform={ isOpened ? 'rotate(270deg)' : 'rotate(180deg)' }
boxSize={ 6 }
cursor="pointer"
onClick={ setIsOpened.toggle }
onClick={ handleIconClick }
transitionDuration="faster"
aria-label="View schema"
/>
......@@ -63,21 +67,21 @@ const AddressMudTablesListItem = ({ item, isLoading, scrollRef, hash }: Props) =
</Skeleton>
<Box flexGrow="1">
<Flex justifyContent="space-between" height={ 6 } alignItems="center" mb={ 3 }>
<Skeleton isLoaded={ !isLoading }>
<LinkInternal
<Skeleton loading={ isLoading }>
<Link
onClick={ onTableClick }
data-id={ item.table.table_id }
fontWeight={ 500 }
href={ route({ pathname: '/address/[hash]', query: { hash, tab: 'mud', table_id: item.table.table_id } }) }
>
{ item.table.table_full_name }
</LinkInternal>
</Link>
</Skeleton>
<Skeleton isLoaded={ !isLoading } color="text_secondary">
<Skeleton loading={ isLoading } color="text.secondary">
{ item.table.table_type }
</Skeleton>
</Flex>
<Skeleton isLoaded={ !isLoading } color="text_secondary">
<Skeleton loading={ isLoading } color="text.secondary">
<HashStringShorten hash={ item.table.table_id } type="long"/>
</Skeleton>
</Box>
......@@ -90,14 +94,14 @@ const AddressMudTablesListItem = ({ item, isLoading, scrollRef, hash }: Props) =
<Text lineHeight="24px">Key</Text>
<VStack gap={ 1 } alignItems="start">
{ item.schema.key_names.map((name, index) => (
<Tag key={ name }>
<Badge key={ name }>
<chakra.span fontWeight={ 700 }>{ item.schema.key_types[index] }</chakra.span> { name }
</Tag>
</Badge>
)) }
</VStack>
</>
) }
<GridItem colSpan={ 2 }><Divider/></GridItem>
<GridItem colSpan={ 2 }><Separator/></GridItem>
<Text lineHeight="24px">Value</Text>
<VStack gap={ 1 } alignItems="start">
{ item.schema.value_names.map((name, index) => (
......
import { Table, Tbody, Th, Tr } from '@chakra-ui/react';
import React from 'react';
import type { AddressMudTables } from 'types/api/address';
import { default as Thead } from 'ui/shared/TheadSticky';
import { TableBody, TableColumnHeader, TableHeaderSticky, TableRoot, TableRow } from 'toolkit/chakra/table';
import AddressMudTablesTableItem from './AddressMudTablesTableItem';
......@@ -18,16 +17,16 @@ type Props = {
//sorry for the naming
const AddressMudTablesTable = ({ items, isLoading, top, scrollRef, hash }: Props) => {
return (
<Table style={{ tableLayout: 'auto' }}>
<Thead top={ top }>
<Tr>
<Th width="24px"></Th>
<Th>Full name</Th>
<Th>Table ID</Th>
<Th>Type</Th>
</Tr>
</Thead>
<Tbody>
<TableRoot style={{ tableLayout: 'auto' }}>
<TableHeaderSticky top={ top }>
<TableRow>
<TableColumnHeader width="24px"></TableColumnHeader>
<TableColumnHeader>Full name</TableColumnHeader>
<TableColumnHeader>Table ID</TableColumnHeader>
<TableColumnHeader>Type</TableColumnHeader>
</TableRow>
</TableHeaderSticky>
<TableBody>
{ items.map((item, index) => (
<AddressMudTablesTableItem
key={ item.table.table_id + (isLoading ? String(index) : '') }
......@@ -37,8 +36,8 @@ const AddressMudTablesTable = ({ items, isLoading, top, scrollRef, hash }: Props
hash={ hash }
/>
)) }
</Tbody>
</Table>
</TableBody>
</TableRoot>
);
};
......
import { Td, Tr, Text, useBoolean, Link, Table, VStack, chakra } from '@chakra-ui/react';
import { Text, VStack, chakra } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import React from 'react';
......@@ -6,10 +6,11 @@ import type { AddressMudTableItem } from 'types/api/address';
import { route } from 'nextjs-routes';
import Skeleton from 'ui/shared/chakra/Skeleton';
import Tag from 'ui/shared/chakra/Tag';
import { Badge } from 'toolkit/chakra/badge';
import { Link } from 'toolkit/chakra/link';
import { Skeleton } from 'toolkit/chakra/skeleton';
import { TableBody, TableCell, TableRoot, TableRow } from 'toolkit/chakra/table';
import IconSvg from 'ui/shared/IconSvg';
import LinkInternal from 'ui/shared/links/LinkInternal';
type Props = {
item: AddressMudTableItem;
......@@ -19,10 +20,14 @@ type Props = {
};
const AddressMudTablesTableItem = ({ item, isLoading, scrollRef, hash }: Props) => {
const [ isOpened, setIsOpened ] = useBoolean(false);
const [ isOpened, setIsOpened ] = React.useState(false);
const router = useRouter();
const handleIconClick = React.useCallback(() => {
setIsOpened((prev) => !prev);
}, []);
const onTableClick = React.useCallback((e: React.MouseEvent) => {
if (e.metaKey || e.ctrlKey) {
// Allow opening in a new tab/window with right-click or ctrl/cmd+click
......@@ -44,67 +49,68 @@ const AddressMudTablesTableItem = ({ item, isLoading, scrollRef, hash }: Props)
return (
<>
<Tr borderBottomStyle={ isOpened ? 'hidden' : 'unset' }>
<Td verticalAlign="middle">
<Skeleton isLoaded={ !isLoading }>
<TableRow borderBottomStyle={ isOpened ? 'hidden' : 'unset' }>
<TableCell verticalAlign="middle">
<Skeleton loading={ isLoading }>
<Link display="block">
<IconSvg
name="arrows/east-mini"
transform={ isOpened ? 'rotate(270deg)' : 'rotate(180deg)' }
boxSize={ 6 }
cursor="pointer"
onClick={ setIsOpened.toggle }
onClick={ handleIconClick }
transitionDuration="faster"
aria-label="View schema"
/>
</Link>
</Skeleton>
</Td>
<Td verticalAlign="middle">
<Skeleton isLoaded={ !isLoading }>
<LinkInternal
</TableCell>
<TableCell verticalAlign="middle">
<Skeleton loading={ isLoading }>
<Link
href={ route({ pathname: '/address/[hash]', query: { hash, tab: 'mud', table_id: item.table.table_id } }) }
data-id={ item.table.table_id }
onClick={ onTableClick }
fontWeight={ 700 }
>
{ item.table.table_full_name }
</LinkInternal>
</Link>
</Skeleton>
</Td>
<Td verticalAlign="middle">
<Skeleton isLoaded={ !isLoading }>
</TableCell>
<TableCell verticalAlign="middle">
<Skeleton loading={ isLoading }>
{ item.table.table_id }
</Skeleton>
</Td>
<Td verticalAlign="middle">
<Skeleton isLoaded={ !isLoading }>
</TableCell>
<TableCell verticalAlign="middle">
<Skeleton loading={ isLoading }>
{ item.table.table_type }
</Skeleton>
</Td>
</Tr>
</TableCell>
</TableRow>
{ isOpened && (
<Tr>
<Td pt={ 0 }></Td>
<Td colSpan={ 3 } pt={ 0 }>
<Table>
<TableRow>
<TableCell pt={ 0 }></TableCell>
<TableCell colSpan={ 3 } pt={ 0 }>
<TableRoot>
<TableBody>
{ Boolean(item.schema.key_names.length) && (
<Tr>
<Td width="80px" fontSize="sm" fontWeight={ 600 } py={ 2 } pl={ 0 } verticalAlign="middle">Key</Td>
<Td py={ 2 }>
<TableRow>
<TableCell width="80px" fontSize="sm" fontWeight={ 600 } py={ 2 } pl={ 0 } verticalAlign="middle">Key</TableCell>
<TableCell py={ 2 }>
<VStack gap={ 1 } alignItems="start">
{ item.schema.key_names.map((name, index) => (
<Tag key={ name }>
<Badge key={ name }>
<chakra.span fontWeight={ 700 }>{ item.schema.key_types[index] }</chakra.span> { name }
</Tag>
</Badge>
)) }
</VStack>
</Td>
</Tr>
</TableCell>
</TableRow>
) }
<Tr borderBottomStyle="hidden">
<Td width="80px" fontSize="sm" fontWeight={ 600 } py={ 2 } pl={ 0 } >Value</Td>
<Td fontSize="sm" py={ 2 }>
<TableRow borderBottomStyle="hidden">
<TableCell width="80px" fontSize="sm" fontWeight={ 600 } py={ 2 } pl={ 0 } >Value</TableCell>
<TableCell fontSize="sm" py={ 2 }>
<VStack gap={ 1 } alignItems="start">
{ item.schema.value_names.map((name, index) => (
<Text key={ name }>
......@@ -112,11 +118,12 @@ const AddressMudTablesTableItem = ({ item, isLoading, scrollRef, hash }: Props)
</Text>
)) }
</VStack>
</Td>
</Tr>
</Table>
</Td>
</Tr>
</TableCell>
</TableRow>
</TableBody>
</TableRoot>
</TableCell>
</TableRow>
) }
</>
);
......
......@@ -6,7 +6,7 @@ import type { MudWorldItem } from 'types/api/mudWorlds';
import config from 'configs/app';
import { currencyUnits } from 'lib/units';
import Skeleton from 'ui/shared/chakra/Skeleton';
import { Skeleton } from 'toolkit/chakra/skeleton';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
......@@ -31,15 +31,15 @@ const MudWorldsListItem = ({
mr={ 2 }
truncation="constant_long"
/>
<HStack spacing={ 3 } maxW="100%" alignItems="flex-start">
<Skeleton isLoaded={ !isLoading } fontSize="sm" fontWeight={ 500 } flexShrink={ 0 }>{ `Balance ${ currencyUnits.ether }` }</Skeleton>
<Skeleton isLoaded={ !isLoading } fontSize="sm" color="text_secondary" minW="0" whiteSpace="pre-wrap">
<HStack gap={ 3 } maxW="100%" alignItems="flex-start">
<Skeleton loading={ isLoading } fontSize="sm" fontWeight={ 500 } flexShrink={ 0 }>{ `Balance ${ currencyUnits.ether }` }</Skeleton>
<Skeleton loading={ isLoading } fontSize="sm" color="text_secondary" minW="0" whiteSpace="pre-wrap">
<span>{ addressBalance.dp(8).toFormat() }</span>
</Skeleton>
</HStack>
<HStack spacing={ 3 }>
<Skeleton isLoaded={ !isLoading } fontSize="sm" fontWeight={ 500 }>Txn count</Skeleton>
<Skeleton isLoaded={ !isLoading } fontSize="sm" color="text_secondary">
<HStack gap={ 3 }>
<Skeleton loading={ isLoading } fontSize="sm" fontWeight={ 500 }>Txn count</Skeleton>
<Skeleton loading={ isLoading } fontSize="sm" color="text_secondary">
<span>{ Number(item.transaction_count).toLocaleString() }</span>
</Skeleton>
</HStack>
......
import { Table, Tbody, Th, Tr } from '@chakra-ui/react';
import React from 'react';
import type { MudWorldItem } from 'types/api/mudWorlds';
import { currencyUnits } from 'lib/units';
import { default as Thead } from 'ui/shared/TheadSticky';
import { TableBody, TableColumnHeader, TableHeaderSticky, TableRoot, TableRow } from 'toolkit/chakra/table';
import MudWorldsTableItem from './MudWorldsTableItem';
......@@ -16,15 +15,15 @@ type Props = {
const MudWorldsTable = ({ items, top, isLoading }: Props) => {
return (
<Table style={{ tableLayout: 'auto' }}>
<Thead top={ top }>
<Tr>
<Th>Address</Th>
<Th isNumeric>{ `Balance ${ currencyUnits.ether }` }</Th>
<Th isNumeric>Txn count</Th>
</Tr>
</Thead>
<Tbody>
<TableRoot style={{ tableLayout: 'auto' }}>
<TableHeaderSticky top={ top }>
<TableRow>
<TableColumnHeader>Address</TableColumnHeader>
<TableColumnHeader isNumeric>{ `Balance ${ currencyUnits.ether }` }</TableColumnHeader>
<TableColumnHeader isNumeric>Txn count</TableColumnHeader>
</TableRow>
</TableHeaderSticky>
<TableBody>
{ items.map((item, index) => (
<MudWorldsTableItem
key={ String(item.address.hash) + (isLoading ? index : '') }
......@@ -32,8 +31,8 @@ const MudWorldsTable = ({ items, top, isLoading }: Props) => {
isLoading={ isLoading }
/>
)) }
</Tbody>
</Table>
</TableBody>
</TableRoot>
);
};
......
import { Text, Td, Tr } from '@chakra-ui/react';
import { Text } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import React from 'react';
import type { MudWorldItem } from 'types/api/mudWorlds';
import config from 'configs/app';
import Skeleton from 'ui/shared/chakra/Skeleton';
import { Skeleton } from 'toolkit/chakra/skeleton';
import { TableCell, TableRow } from 'toolkit/chakra/table';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
type Props = { item: MudWorldItem; isLoading?: boolean };
......@@ -15,22 +16,22 @@ const MudWorldsTableItem = ({ item, isLoading }: Props) => {
const addressBalanceChunks = addressBalance.dp(8).toFormat().split('.');
return (
<Tr>
<Td verticalAlign="middle">
<TableRow>
<TableCell verticalAlign="middle">
<AddressEntity address={ item.address } isLoading={ isLoading } fontWeight={ 700 }/>
</Td>
<Td isNumeric>
<Skeleton isLoaded={ !isLoading } display="inline-block" maxW="100%">
</TableCell>
<TableCell isNumeric>
<Skeleton loading={ isLoading } display="inline-block" maxW="100%">
<Text lineHeight="24px" as="span">{ addressBalanceChunks[0] + (addressBalanceChunks[1] ? '.' : '') }</Text>
<Text lineHeight="24px" variant="secondary" as="span">{ addressBalanceChunks[1] }</Text>
<Text lineHeight="24px" color="text.secondary" as="span">{ addressBalanceChunks[1] }</Text>
</Skeleton>
</Td>
<Td isNumeric>
<Skeleton isLoaded={ !isLoading } display="inline-block" lineHeight="24px">
</TableCell>
<TableCell isNumeric>
<Skeleton loading={ isLoading } display="inline-block" lineHeight="24px">
{ Number(item.transaction_count).toLocaleString() }
</Skeleton>
</Td>
</Tr>
</TableCell>
</TableRow>
);
};
......
......@@ -153,12 +153,12 @@ const AddressPageContent = () => {
const tabs: Array<TabItemRegular> = React.useMemo(() => {
return [
// config.features.mudFramework.isEnabled && mudTablesCountQuery.data && mudTablesCountQuery.data > 0 && {
// id: 'mud',
// title: 'MUD',
// count: mudTablesCountQuery.data,
// component: <AddressMud scrollRef={ tabsScrollRef } shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>,
// },
config.features.mudFramework.isEnabled && mudTablesCountQuery.data && mudTablesCountQuery.data > 0 && {
id: 'mud',
title: 'MUD',
count: mudTablesCountQuery.data,
component: <AddressMud scrollRef={ tabsScrollRef } shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>,
},
{
id: 'txs',
title: 'Transactions',
......
import { Hide, Show } from '@chakra-ui/react';
import { Box } from '@chakra-ui/react';
import React from 'react';
import { MUD_WORLD } from 'stubs/mud';
......@@ -30,7 +30,7 @@ const MudWorlds = () => {
const content = data?.items ? (
<>
<Show below="lg" ssr={ false }>
<Box hideFrom="lg">
{ data.items.map(((item, index) => (
<MudWorldsListItem
key={ item.address.hash + (isPlaceholderData ? String(index) : '') }
......@@ -38,10 +38,10 @@ const MudWorlds = () => {
isLoading={ isPlaceholderData }
/>
))) }
</Show>
<Hide below="lg" ssr={ false }>
</Box>
<Box hideBelow="lg">
<MudWorldsTable items={ data.items } top={ pagination.isVisible ? ACTION_BAR_HEIGHT_DESKTOP : 0 } isLoading={ isPlaceholderData }/>
</Hide>
</Box>
</>
) : null;
......@@ -56,11 +56,12 @@ const MudWorlds = () => {
<PageTitle title="MUD worlds" withTextAd/>
<DataListDisplay
isError={ isError }
items={ data?.items }
itemsNum={ data?.items.length }
emptyText="There are no MUD worlds."
content={ content }
actionBar={ actionBar }
/>
>
{ content }
</DataListDisplay>
</>
);
};
......
......@@ -21,6 +21,7 @@ const ClearButton = ({ onClick, isDisabled, isVisible = true, className }: Props
size="sm"
onClick={ onClick }
opacity={ isVisible ? 1 : 0 }
visibility={ isVisible ? 'visible' : 'hidden' }
>
<IconSvg
name="status/error"
......
......@@ -2,11 +2,13 @@ import {
chakra,
Flex,
Text,
Link,
Button,
} from '@chakra-ui/react';
import React from 'react';
import { Button } from 'toolkit/chakra/button';
import { Link } from 'toolkit/chakra/link';
import { PopoverCloseTriggerWrapper } from 'toolkit/chakra/popover';
type Props = {
title: string;
isFilled?: boolean;
......@@ -14,19 +16,17 @@ type Props = {
hasReset?: boolean;
onFilter: () => void;
onReset?: () => void;
onClose?: () => void;
children: React.ReactNode;
};
const TableColumnFilter = ({ title, isFilled, isTouched, hasReset, onFilter, onReset, onClose, children }: Props) => {
const TableColumnFilter = ({ title, isFilled, isTouched, hasReset, onFilter, onReset, children }: Props) => {
const onFilterClick = React.useCallback(() => {
onClose && onClose();
onFilter();
}, [ onClose, onFilter ]);
}, [ onFilter ]);
return (
<>
<Flex alignItems="center" justifyContent="space-between">
<Text color="text_secondary" fontWeight="600">{ title }</Text>
<Text color="text.secondary" fontWeight="600">{ title }</Text>
{ hasReset && (
<Link
onClick={ onReset }
......@@ -41,13 +41,15 @@ const TableColumnFilter = ({ title, isFilled, isTouched, hasReset, onFilter, onR
) }
</Flex>
{ children }
<PopoverCloseTriggerWrapper>
<Button
isDisabled={ !isTouched }
disabled={ !isTouched }
onClick={ onFilterClick }
w="fit-content"
>
Filter
</Button>
</PopoverCloseTriggerWrapper>
</>
);
};
......
import {
PopoverTrigger,
PopoverContent,
PopoverBody,
useDisclosure,
chakra,
Portal,
Button,
} from '@chakra-ui/react';
import { chakra } from '@chakra-ui/react';
import React from 'react';
import Popover from 'ui/shared/chakra/Popover';
import { Button } from 'toolkit/chakra/button';
import { PopoverBody, PopoverContent, PopoverRoot, PopoverTrigger } from 'toolkit/chakra/popover';
import IconSvg from 'ui/shared/IconSvg';
interface Props {
columnName: string;
isActive?: boolean;
isLoading?: boolean;
selected?: boolean;
className?: string;
children: React.ReactNode;
value?: string;
}
const TableColumnFilterWrapper = ({ columnName, isActive, className, children, isLoading, value }: Props) => {
const { isOpen, onToggle, onClose } = useDisclosure();
const content = React.Children.only(children) as React.ReactElement & {
ref?: React.Ref<React.ReactNode>;
};
const modifiedContent = React.cloneElement(
content,
{ onClose },
);
const TableColumnFilterWrapper = ({ columnName, className, children, isLoading, selected, value }: Props) => {
return (
<Popover isOpen={ isOpen } onClose={ onClose } placement="bottom-start" isLazy lazyBehavior="unmount">
<PopoverRoot>
<PopoverTrigger>
<Button
onClick={ onToggle }
aria-label={ `filter by ${ columnName }` }
variant="ghost"
variant="dropdown"
borderWidth="0"
h="20px"
isActive={ Boolean(value) || isActive }
isDisabled={ isLoading }
minW="auto"
disabled={ isLoading }
selected={ selected }
borderRadius="4px"
color="text_secondary"
fontSize="sm"
size="sm"
fontWeight={ 500 }
leftIcon={ <IconSvg name="filter" w="19px" h="19px"/> }
padding={ 0 }
sx={{
css={{
'span:only-child': {
mx: 0,
},
......@@ -58,17 +39,16 @@ const TableColumnFilterWrapper = ({ columnName, isActive, className, children, i
},
}}
>
<IconSvg name="filter" w="19px" h="19px"/>
{ Boolean(value) && <chakra.span>{ value }</chakra.span> }
</Button>
</PopoverTrigger>
<Portal>
<PopoverContent className={ className }>
<PopoverBody px={ 4 } py={ 6 } display="flex" flexDir="column" rowGap={ 3 }>
{ modifiedContent }
<PopoverBody display="flex" flexDir="column" rowGap={ 3 }>
{ children }
</PopoverBody>
</PopoverContent>
</Portal>
</Popover>
</PopoverRoot>
);
};
......
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