Commit 6c0e4529 authored by tom's avatar tom

CutLink for lists

parent eb7637a9
import { Flex, type FlexProps } from '@chakra-ui/react';
import React from 'react';
import type { LinkProps } from 'toolkit/chakra/link';
import { Link } from 'toolkit/chakra/link';
interface Props<T> extends FlexProps {
items: Array<T>;
renderItem: (item: T, index: number) => React.ReactNode;
linkProps?: LinkProps;
cutLength?: number;
}
const CUT_LENGTH = 3;
const CutLinkList = <T,>(props: Props<T>) => {
const { items, renderItem, linkProps, cutLength = CUT_LENGTH, ...rest } = props;
const [ isExpanded, setIsExpanded ] = React.useState(false);
const handleToggle = React.useCallback(() => {
setIsExpanded((flag) => !flag);
}, []);
return (
<Flex flexDir="column" w="100%" { ...rest }>
{ items.slice(0, isExpanded ? undefined : cutLength).map(renderItem) }
{ items.length > cutLength && (
<Link
textStyle="sm"
textDecorationLine="underline"
textDecorationStyle="dashed"
w="fit-content"
onClick={ handleToggle }
{ ...linkProps }
>
{ isExpanded ? 'Hide' : 'Show all' }
</Link>
) }
</Flex>
);
};
export default React.memo(CutLinkList) as typeof CutLinkList;
...@@ -20,7 +20,7 @@ import { currencyUnits } from 'lib/units'; ...@@ -20,7 +20,7 @@ import { currencyUnits } from 'lib/units';
import { Link } from 'toolkit/chakra/link'; import { Link } from 'toolkit/chakra/link';
import { Skeleton } from 'toolkit/chakra/skeleton'; import { Skeleton } from 'toolkit/chakra/skeleton';
import { Tooltip } from 'toolkit/chakra/tooltip'; import { Tooltip } from 'toolkit/chakra/tooltip';
import CutLink from 'toolkit/components/CutLink/CutLink'; import CutLinkDetails from 'toolkit/components/CutLink/CutLinkDetails';
import OptimisticL2TxnBatchDA from 'ui/shared/batch/OptimisticL2TxnBatchDA'; import OptimisticL2TxnBatchDA from 'ui/shared/batch/OptimisticL2TxnBatchDA';
import BlockGasUsed from 'ui/shared/block/BlockGasUsed'; import BlockGasUsed from 'ui/shared/block/BlockGasUsed';
import CopyToClipboard from 'ui/shared/CopyToClipboard'; import CopyToClipboard from 'ui/shared/CopyToClipboard';
...@@ -545,7 +545,7 @@ const BlockDetails = ({ query }: Props) => { ...@@ -545,7 +545,7 @@ const BlockDetails = ({ query }: Props) => {
) } ) }
{ /* ADDITIONAL INFO */ } { /* ADDITIONAL INFO */ }
<CutLink loading={ isPlaceholderData } mt={ 6 } gridColumn={{ base: undefined, lg: '1 / 3' }}> <CutLinkDetails loading={ isPlaceholderData } mt={ 6 } gridColumn={{ base: undefined, lg: '1 / 3' }}>
<GridItem colSpan={{ base: undefined, lg: 2 }} mt={{ base: 1, lg: 4 }}/> <GridItem colSpan={{ base: undefined, lg: 2 }} mt={{ base: 1, lg: 4 }}/>
{ rollupFeature.isEnabled && rollupFeature.type === 'zkSync' && data.zksync && { rollupFeature.isEnabled && rollupFeature.type === 'zkSync' && data.zksync &&
...@@ -744,7 +744,7 @@ const BlockDetails = ({ query }: Props) => { ...@@ -744,7 +744,7 @@ const BlockDetails = ({ query }: Props) => {
) } ) }
</> </>
) } ) }
</CutLink> </CutLinkDetails>
</Grid> </Grid>
); );
......
/* eslint-disable react/jsx-no-bind */
/* eslint-disable max-len */ /* eslint-disable max-len */
import { Box } from '@chakra-ui/react'; import { Box, Text } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import * as addressMock from 'mocks/address/address'; import * as addressMock from 'mocks/address/address';
...@@ -10,7 +11,8 @@ import * as ensMock from 'mocks/ens/domain'; ...@@ -10,7 +11,8 @@ import * as ensMock from 'mocks/ens/domain';
import * as poolMock from 'mocks/pools/pool'; import * as poolMock from 'mocks/pools/pool';
import * as txMock from 'mocks/txs/tx'; import * as txMock from 'mocks/txs/tx';
import { Link } from 'toolkit/chakra/link'; import { Link } from 'toolkit/chakra/link';
import CutLink from 'toolkit/components/CutLink/CutLink'; import CutLinkDetails from 'toolkit/components/CutLink/CutLinkDetails';
import CutLinkList from 'toolkit/components/CutLink/CutLinkList';
import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import BlobEntity from 'ui/shared/entities/blob/BlobEntity'; import BlobEntity from 'ui/shared/entities/blob/BlobEntity';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
...@@ -96,15 +98,24 @@ const LinkShowcase = () => { ...@@ -96,15 +98,24 @@ const LinkShowcase = () => {
<SectionSubHeader>Cut link</SectionSubHeader> <SectionSubHeader>Cut link</SectionSubHeader>
<SamplesStack> <SamplesStack>
<Sample label="Default" flexDirection="column" alignItems="flex-start"> <Sample label="Show details" flexDirection="column" alignItems="flex-start">
<CutLink id="CutLink_1"> <CutLinkDetails id="CutLink_1">
<Box maxW="500px">{ TEXT }</Box> <Box maxW="500px">{ TEXT }</Box>
</CutLink> </CutLinkDetails>
</Sample> <CutLinkDetails id="CutLink_2" loading>
<Sample label="Loading" flexDirection="column" alignItems="flex-start">
<CutLink id="CutLink_2" loading>
<Box maxW="500px">{ TEXT }</Box> <Box maxW="500px">{ TEXT }</Box>
</CutLink> </CutLinkDetails>
</Sample>
<Sample label="Expand all list" flexDirection="row" alignItems="flex-start" flexWrap="nowrap">
<CutLinkList
items={ [ 'foo', 'bar', 'baz', 'qux', 'quux', 'corge', 'grault', 'garply', 'waldo', 'fred', 'plugh', 'xyzzy', 'thud' ] }
renderItem={ (item) => <Text>{ item }</Text> }
/>
<CutLinkList
items={ [ 'foo', 'bar', 'baz', 'qux', 'quux', 'corge', 'grault', 'garply', 'waldo', 'fred', 'plugh', 'xyzzy', 'thud' ] }
renderItem={ (item) => <Text>{ item }</Text> }
linkProps={{ loading: true }}
/>
</Sample> </Sample>
</SamplesStack> </SamplesStack>
......
import { Flex } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { Link } from 'toolkit/chakra/link'; import CutLinkList from 'toolkit/components/CutLink/CutLinkList';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem'; import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
...@@ -9,13 +8,9 @@ interface Props { ...@@ -9,13 +8,9 @@ interface Props {
items: Array<string>; items: Array<string>;
} }
const CUT_LENGTH = 2;
const TxAllowedPeekers = ({ items }: Props) => { const TxAllowedPeekers = ({ items }: Props) => {
const [ isExpanded, setIsExpanded ] = React.useState(false); const renderItem = React.useCallback((item: string) => {
return <AddressEntity key={ item } address={{ hash: item, is_contract: true }}/>;
const handleCutLinkClick = React.useCallback(() => {
setIsExpanded((flag) => !flag);
}, []); }, []);
return ( return (
...@@ -26,22 +21,12 @@ const TxAllowedPeekers = ({ items }: Props) => { ...@@ -26,22 +21,12 @@ const TxAllowedPeekers = ({ items }: Props) => {
Allowed peekers Allowed peekers
</DetailsInfoItem.Label> </DetailsInfoItem.Label>
<DetailsInfoItem.Value> <DetailsInfoItem.Value>
<Flex flexDir="column" rowGap={ 3 } w="100%"> <CutLinkList
{ items items={ items }
.slice(0, isExpanded ? undefined : CUT_LENGTH) renderItem={ renderItem }
.map((item) => <AddressEntity key={ item } address={{ hash: item, is_contract: true }}/>) } cutLength={ 2 }
</Flex> rowGap={ 3 }
{ items.length > CUT_LENGTH && ( />
<Link
display="inline-block"
fontSize="sm"
textDecorationLine="underline"
textDecorationStyle="dashed"
onClick={ handleCutLinkClick }
>
{ isExpanded ? 'Hide' : 'Show all' }
</Link>
) }
</DetailsInfoItem.Value> </DetailsInfoItem.Value>
</> </>
); );
......
...@@ -29,7 +29,7 @@ import { Badge } from 'toolkit/chakra/badge'; ...@@ -29,7 +29,7 @@ import { Badge } from 'toolkit/chakra/badge';
import { Link } from 'toolkit/chakra/link'; import { Link } from 'toolkit/chakra/link';
import { Skeleton } from 'toolkit/chakra/skeleton'; import { Skeleton } from 'toolkit/chakra/skeleton';
import { Tooltip } from 'toolkit/chakra/tooltip'; import { Tooltip } from 'toolkit/chakra/tooltip';
import CutLink from 'toolkit/components/CutLink/CutLink'; import CutLinkDetails from 'toolkit/components/CutLink/CutLinkDetails';
import CopyToClipboard from 'ui/shared/CopyToClipboard'; import CopyToClipboard from 'ui/shared/CopyToClipboard';
import CurrencyValue from 'ui/shared/CurrencyValue'; import CurrencyValue from 'ui/shared/CurrencyValue';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem'; import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
...@@ -168,7 +168,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => { ...@@ -168,7 +168,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
<DetailsInfoItem.Value> <DetailsInfoItem.Value>
<TxStatus status={ data.status } errorText={ data.status === 'error' ? data.result : undefined } isLoading={ isLoading }/> <TxStatus status={ data.status } errorText={ data.status === 'error' ? data.result : undefined } isLoading={ isLoading }/>
{ data.method && ( { data.method && (
<Badge colorScheme={ data.method === 'Multicall' ? 'teal' : 'gray' } loading={ isLoading } truncated ml={ 3 }> <Badge colorPalette={ data.method === 'Multicall' ? 'teal' : 'gray' } loading={ isLoading } truncated ml={ 3 }>
{ data.method } { data.method }
</Badge> </Badge>
) } ) }
...@@ -783,7 +783,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => { ...@@ -783,7 +783,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
) } ) }
<TxInfoScrollFees data={ data } isLoading={ isLoading }/> <TxInfoScrollFees data={ data } isLoading={ isLoading }/>
<CutLink loading={ isLoading } mt={ 6 } gridColumn={{ base: undefined, lg: '1 / 3' }} isExpanded={ isExpanded } onClick={ handleCutLinkClick }> <CutLinkDetails loading={ isLoading } mt={ 6 } gridColumn={{ base: undefined, lg: '1 / 3' }} isExpanded={ isExpanded } onClick={ handleCutLinkClick }>
<GridItem colSpan={{ base: undefined, lg: 2 }} mt={{ base: 1, lg: 4 }}/> <GridItem colSpan={{ base: undefined, lg: 2 }} mt={{ base: 1, lg: 4 }}/>
{ data.arbitrum?.contains_message && data.arbitrum?.message_related_info && ( { data.arbitrum?.contains_message && data.arbitrum?.message_related_info && (
...@@ -893,7 +893,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => { ...@@ -893,7 +893,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
) } ) }
{ data.zksync && <ZkSyncL2TxnBatchHashesInfo data={ data.zksync } isLoading={ isLoading }/> } { data.zksync && <ZkSyncL2TxnBatchHashesInfo data={ data.zksync } isLoading={ isLoading }/> }
</CutLink> </CutLinkDetails>
</Grid> </Grid>
); );
}; };
......
import { Flex, Text } from '@chakra-ui/react'; import { Text } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { Link } from 'toolkit/chakra/link'; import CutLinkList from 'toolkit/components/CutLink/CutLinkList';
import NftEntity from 'ui/shared/entities/nft/NftEntity'; import NftEntity from 'ui/shared/entities/nft/NftEntity';
interface Props { interface Props {
...@@ -11,40 +11,23 @@ interface Props { ...@@ -11,40 +11,23 @@ interface Props {
} }
const TxStateTokenIdList = ({ items, tokenAddress, isLoading }: Props) => { const TxStateTokenIdList = ({ items, tokenAddress, isLoading }: Props) => {
const [ isCut, setIsCut ] = React.useState(true); const renderItem = React.useCallback((item: typeof items[number], index: number) => {
if (item.total.token_id !== null) {
return <NftEntity key={ index } hash={ tokenAddress } id={ item.total.token_id } isLoading={ isLoading }/>;
}
const handleToggle = React.useCallback(() => { return <Text key={ index } color="text.secondary">N/A</Text>;
setIsCut((prev) => !prev); }, [ isLoading, tokenAddress ]);
}, []);
return ( return (
<Flex flexDir="column" rowGap={ 2 }> <CutLinkList
{ items.slice(0, isCut ? 3 : items.length).map((item, index) => { items={ items }
if (item.total.token_id !== null) { renderItem={ renderItem }
return ( linkProps={{
<NftEntity pb: { base: '5px', md: 0 },
key={ index } }}
hash={ tokenAddress } rowGap={ 2 }
id={ item.total.token_id } />
isLoading={ isLoading }
/>
);
} else {
return <Text key={ index } color="text_secondary">N/A</Text>;
}
}) }
{ items.length > 3 && (
<Link
fontWeight={ 400 }
textDecoration="underline dashed"
_hover={{ textDecoration: 'underline dashed', color: 'link_hovered' }}
onClick={ handleToggle }
pb={{ base: '5px', md: 0 }}
>
View { isCut ? 'more' : 'less' }
</Link>
) }
</Flex>
); );
}; };
......
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