Commit c51631f0 authored by tom's avatar tom

skeletons for L2 deposits

parent 60463634
import type { NextPage } from 'next'; import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import Head from 'next/head'; import Head from 'next/head';
import React from 'react'; import React from 'react';
import getNetworkTitle from 'lib/networks/getNetworkTitle'; import getNetworkTitle from 'lib/networks/getNetworkTitle';
import L2Deposits from 'ui/pages/L2Deposits'; import Page from 'ui/shared/Page/Page';
const L2Deposits = dynamic(() => import('ui/pages/L2Deposits'), { ssr: false });
const DepositsPage: NextPage = () => { const DepositsPage: NextPage = () => {
const title = getNetworkTitle(); const title = getNetworkTitle();
...@@ -12,7 +15,9 @@ const DepositsPage: NextPage = () => { ...@@ -12,7 +15,9 @@ const DepositsPage: NextPage = () => {
<Head> <Head>
<title>{ title }</title> <title>{ title }</title>
</Head> </Head>
<L2Deposits/> <Page>
<L2Deposits/>
</Page>
</> </>
); );
}; };
......
import type { L2DepositsItem } from 'types/api/l2Deposits';
import { ADDRESS_HASH } from './addressParams';
import { TX_HASH } from './tx';
export const L2_DEPOSIT_ITEM: L2DepositsItem = {
l1_block_number: 9045233,
l1_block_timestamp: '2023-05-22T18:00:36.000000Z',
l1_tx_hash: TX_HASH,
l1_tx_origin: ADDRESS_HASH,
l2_tx_gas_limit: '100000',
l2_tx_hash: TX_HASH,
};
...@@ -14,5 +14,4 @@ export type L2DepositsResponse = { ...@@ -14,5 +14,4 @@ export type L2DepositsResponse = {
l1_block_number: number; l1_block_number: number;
tx_hash: string; tx_hash: string;
}; };
total: number;
} }
import { Box, Icon } from '@chakra-ui/react'; import { Skeleton } from '@chakra-ui/react';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import React from 'react'; import React from 'react';
...@@ -10,33 +10,35 @@ import blockIcon from 'icons/block.svg'; ...@@ -10,33 +10,35 @@ import blockIcon from 'icons/block.svg';
import txIcon from 'icons/transactions.svg'; import txIcon from 'icons/transactions.svg';
import dayjs from 'lib/date/dayjs'; import dayjs from 'lib/date/dayjs';
import AddressIcon from 'ui/shared/address/AddressIcon'; import AddressIcon from 'ui/shared/address/AddressIcon';
import Icon from 'ui/shared/chakra/Icon';
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic'; import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import LinkExternal from 'ui/shared/LinkExternal'; import LinkExternal from 'ui/shared/LinkExternal';
import LinkInternal from 'ui/shared/LinkInternal'; import LinkInternal from 'ui/shared/LinkInternal';
import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid'; import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid';
type Props = { item: L2DepositsItem }; type Props = { item: L2DepositsItem; isLoading?: boolean };
const DepositsListItem = ({ item }: Props) => { const DepositsListItem = ({ item, isLoading }: Props) => {
const timeAgo = dayjs(item.l1_block_timestamp).fromNow(); const timeAgo = dayjs(item.l1_block_timestamp).fromNow();
return ( return (
<ListItemMobileGrid.Container> <ListItemMobileGrid.Container>
<ListItemMobileGrid.Label>L1 block No</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>L1 block No</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value> <ListItemMobileGrid.Value py="3px">
<LinkExternal <LinkExternal
href={ appConfig.L2.L1BaseUrl + route({ pathname: '/block/[height_or_hash]', query: { height_or_hash: item.l1_block_number.toString() } }) } href={ appConfig.L2.L1BaseUrl + route({ pathname: '/block/[height_or_hash]', query: { height_or_hash: item.l1_block_number.toString() } }) }
fontWeight={ 600 } fontWeight={ 600 }
display="inline-flex" display="inline-flex"
isLoading={ isLoading }
> >
<Icon as={ blockIcon } boxSize={ 6 } mr={ 1 }/> <Icon as={ blockIcon } boxSize={ 6 } isLoading={ isLoading }/>
{ item.l1_block_number } <Skeleton isLoaded={ !isLoading } ml={ 1 }>{ item.l1_block_number }</Skeleton>
</LinkExternal> </LinkExternal>
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
<ListItemMobileGrid.Label>L2 txn hash</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>L2 txn hash</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value> <ListItemMobileGrid.Value py="3px">
<LinkInternal <LinkInternal
href={ route({ pathname: '/tx/[hash]', query: { hash: item.l2_tx_hash } }) } href={ route({ pathname: '/tx/[hash]', query: { hash: item.l2_tx_hash } }) }
display="flex" display="flex"
...@@ -44,43 +46,56 @@ const DepositsListItem = ({ item }: Props) => { ...@@ -44,43 +46,56 @@ const DepositsListItem = ({ item }: Props) => {
alignItems="center" alignItems="center"
overflow="hidden" overflow="hidden"
w="100%" w="100%"
isLoading={ isLoading }
> >
<Icon as={ txIcon } boxSize={ 6 } mr={ 1 }/> <Icon as={ txIcon } boxSize={ 6 } isLoading={ isLoading }/>
<Box w="calc(100% - 36px)" overflow="hidden" whiteSpace="nowrap"><HashStringShortenDynamic hash={ item.l2_tx_hash }/></Box> <Skeleton isLoaded={ !isLoading } w="calc(100% - 36px)" overflow="hidden" whiteSpace="nowrap" ml={ 1 }>
<HashStringShortenDynamic hash={ item.l2_tx_hash }/>
</Skeleton>
</LinkInternal> </LinkInternal>
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
<ListItemMobileGrid.Label>Age</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value>{ timeAgo }</ListItemMobileGrid.Value>
<ListItemMobileGrid.Label>L1 txn hash</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value> <ListItemMobileGrid.Value>
<Skeleton isLoaded={ !isLoading } display="inline-block">{ timeAgo }</Skeleton>
</ListItemMobileGrid.Value>
<ListItemMobileGrid.Label isLoading={ isLoading }>L1 txn hash</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value py="3px">
<LinkExternal <LinkExternal
href={ appConfig.L2.L1BaseUrl + route({ pathname: '/tx/[hash]', query: { hash: item.l1_tx_hash } }) } href={ appConfig.L2.L1BaseUrl + route({ pathname: '/tx/[hash]', query: { hash: item.l1_tx_hash } }) }
maxW="100%" maxW="100%"
display="inline-flex" display="inline-flex"
overflow="hidden" overflow="hidden"
isLoading={ isLoading }
> >
<Icon as={ txIcon } boxSize={ 6 } mr={ 1 }/> <Icon as={ txIcon } boxSize={ 6 } isLoading={ isLoading }/>
<Box w="calc(100% - 44px)" overflow="hidden" whiteSpace="nowrap"><HashStringShortenDynamic hash={ item.l1_tx_hash }/></Box> <Skeleton isLoaded={ !isLoading } w="calc(100% - 44px)" overflow="hidden" whiteSpace="nowrap" ml={ 1 }>
<HashStringShortenDynamic hash={ item.l1_tx_hash }/>
</Skeleton>
</LinkExternal> </LinkExternal>
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
<ListItemMobileGrid.Label>L1 txn origin</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>L1 txn origin</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value> <ListItemMobileGrid.Value py="3px">
<LinkExternal <LinkExternal
href={ appConfig.L2.L1BaseUrl + route({ pathname: '/address/[hash]', query: { hash: item.l1_tx_origin } }) } href={ appConfig.L2.L1BaseUrl + route({ pathname: '/address/[hash]', query: { hash: item.l1_tx_origin } }) }
maxW="100%" maxW="100%"
display="inline-flex" display="inline-flex"
overflow="hidden" overflow="hidden"
isLoading={ isLoading }
> >
<AddressIcon address={{ hash: item.l1_tx_origin, is_contract: false, implementation_name: '' }} mr={ 2 }/> <AddressIcon address={{ hash: item.l1_tx_origin, is_contract: false, implementation_name: '' }} isLoading={ isLoading }/>
<Box w="calc(100% - 44px)" overflow="hidden" whiteSpace="nowrap"><HashStringShortenDynamic hash={ item.l1_tx_origin }/></Box> <Skeleton isLoaded={ !isLoading } w="calc(100% - 44px)" overflow="hidden" whiteSpace="nowrap" ml={ 2 }>
<HashStringShortenDynamic hash={ item.l1_tx_origin }/>
</Skeleton>
</LinkExternal> </LinkExternal>
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
<ListItemMobileGrid.Label>Gas limit</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Gas limit</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value>{ BigNumber(item.l2_tx_gas_limit).toFormat() }</ListItemMobileGrid.Value> <ListItemMobileGrid.Value>
<Skeleton isLoaded={ !isLoading } display="inline-block">{ BigNumber(item.l2_tx_gas_limit).toFormat() }</Skeleton>
</ListItemMobileGrid.Value>
</ListItemMobileGrid.Container> </ListItemMobileGrid.Container>
); );
......
...@@ -10,9 +10,10 @@ import DepositsTableItem from './DepositsTableItem'; ...@@ -10,9 +10,10 @@ import DepositsTableItem from './DepositsTableItem';
type Props = { type Props = {
items: Array<L2DepositsItem>; items: Array<L2DepositsItem>;
top: number; top: number;
isLoading?: boolean;
} }
const DepositsTable = ({ items, top }: Props) => { const DepositsTable = ({ items, top, isLoading }: Props) => {
return ( return (
<Table variant="simple" size="sm" style={{ tableLayout: 'auto' }} minW="950px"> <Table variant="simple" size="sm" style={{ tableLayout: 'auto' }} minW="950px">
<Thead top={ top }> <Thead top={ top }>
...@@ -26,8 +27,8 @@ const DepositsTable = ({ items, top }: Props) => { ...@@ -26,8 +27,8 @@ const DepositsTable = ({ items, top }: Props) => {
</Tr> </Tr>
</Thead> </Thead>
<Tbody> <Tbody>
{ items.map((item) => ( { items.map((item, index) => (
<DepositsTableItem key={ item.l2_tx_hash } item={ item }/> <DepositsTableItem key={ item.l2_tx_hash + (isLoading ? index : '') } item={ item } isLoading={ isLoading }/>
)) } )) }
</Tbody> </Tbody>
</Table> </Table>
......
import { Box, Td, Tr, Text, Icon } from '@chakra-ui/react'; import { Td, Tr, Skeleton } from '@chakra-ui/react';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import React from 'react'; import React from 'react';
...@@ -10,13 +10,14 @@ import blockIcon from 'icons/block.svg'; ...@@ -10,13 +10,14 @@ import blockIcon from 'icons/block.svg';
import txIcon from 'icons/transactions.svg'; import txIcon from 'icons/transactions.svg';
import dayjs from 'lib/date/dayjs'; import dayjs from 'lib/date/dayjs';
import AddressIcon from 'ui/shared/address/AddressIcon'; import AddressIcon from 'ui/shared/address/AddressIcon';
import Icon from 'ui/shared/chakra/Icon';
import HashStringShorten from 'ui/shared/HashStringShorten'; import HashStringShorten from 'ui/shared/HashStringShorten';
import LinkExternal from 'ui/shared/LinkExternal'; import LinkExternal from 'ui/shared/LinkExternal';
import LinkInternal from 'ui/shared/LinkInternal'; import LinkInternal from 'ui/shared/LinkInternal';
type Props = { item: L2DepositsItem }; type Props = { item: L2DepositsItem; isLoading?: boolean };
const WithdrawalsTableItem = ({ item }: Props) => { const WithdrawalsTableItem = ({ item, isLoading }: Props) => {
const timeAgo = dayjs(item.l1_block_timestamp).fromNow(); const timeAgo = dayjs(item.l1_block_timestamp).fromNow();
return ( return (
...@@ -26,9 +27,12 @@ const WithdrawalsTableItem = ({ item }: Props) => { ...@@ -26,9 +27,12 @@ const WithdrawalsTableItem = ({ item }: Props) => {
href={ appConfig.L2.L1BaseUrl + route({ pathname: '/block/[height_or_hash]', query: { height_or_hash: item.l1_block_number.toString() } }) } href={ appConfig.L2.L1BaseUrl + route({ pathname: '/block/[height_or_hash]', query: { height_or_hash: item.l1_block_number.toString() } }) }
fontWeight={ 600 } fontWeight={ 600 }
display="inline-flex" display="inline-flex"
isLoading={ isLoading }
> >
<Icon as={ blockIcon } boxSize={ 6 } mr={ 1 }/> <Icon as={ blockIcon } boxSize={ 6 } isLoading={ isLoading }/>
{ item.l1_block_number } <Skeleton isLoaded={ !isLoading } ml={ 1 }>
{ item.l1_block_number }
</Skeleton>
</LinkExternal> </LinkExternal>
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
...@@ -39,13 +43,16 @@ const WithdrawalsTableItem = ({ item }: Props) => { ...@@ -39,13 +43,16 @@ const WithdrawalsTableItem = ({ item }: Props) => {
alignItems="center" alignItems="center"
overflow="hidden" overflow="hidden"
w="100%" w="100%"
isLoading={ isLoading }
> >
<Icon as={ txIcon } boxSize={ 6 } mr={ 1 }/> <Icon as={ txIcon } boxSize={ 6 } isLoading={ isLoading }/>
<Box w="calc(100% - 36px)" overflow="hidden" whiteSpace="nowrap"><HashStringShorten hash={ item.l2_tx_hash }/></Box> <Skeleton isLoaded={ !isLoading } w="calc(100% - 36px)" ml={ 1 } overflow="hidden" whiteSpace="nowrap">
<HashStringShorten hash={ item.l2_tx_hash }/>
</Skeleton>
</LinkInternal> </LinkInternal>
</Td> </Td>
<Td verticalAlign="middle" pr={ 12 }> <Td verticalAlign="middle" pr={ 12 }>
<Text variant="secondary">{ timeAgo }</Text> <Skeleton isLoaded={ !isLoading } color="text_secondary" display="inline-block"><span>{ timeAgo }</span></Skeleton>
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
<LinkExternal <LinkExternal
...@@ -53,9 +60,12 @@ const WithdrawalsTableItem = ({ item }: Props) => { ...@@ -53,9 +60,12 @@ const WithdrawalsTableItem = ({ item }: Props) => {
maxW="100%" maxW="100%"
display="inline-flex" display="inline-flex"
overflow="hidden" overflow="hidden"
isLoading={ isLoading }
> >
<Icon as={ txIcon } boxSize={ 6 } mr={ 1 }/> <Icon as={ txIcon } boxSize={ 6 } isLoading={ isLoading }/>
<Box w="calc(100% - 44px)" overflow="hidden" whiteSpace="nowrap"><HashStringShorten hash={ item.l1_tx_hash }/></Box> <Skeleton isLoaded={ !isLoading } w="calc(100% - 44px)" overflow="hidden" whiteSpace="nowrap" ml={ 1 }>
<HashStringShorten hash={ item.l1_tx_hash }/>
</Skeleton>
</LinkExternal> </LinkExternal>
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
...@@ -64,13 +74,18 @@ const WithdrawalsTableItem = ({ item }: Props) => { ...@@ -64,13 +74,18 @@ const WithdrawalsTableItem = ({ item }: Props) => {
maxW="100%" maxW="100%"
display="inline-flex" display="inline-flex"
overflow="hidden" overflow="hidden"
isLoading={ isLoading }
> >
<AddressIcon address={{ hash: item.l1_tx_origin, is_contract: false, implementation_name: '' }} mr={ 2 }/> <AddressIcon address={{ hash: item.l1_tx_origin, is_contract: false, implementation_name: '' }} isLoading={ isLoading }/>
<Box w="calc(100% - 44px)" overflow="hidden" whiteSpace="nowrap"><HashStringShorten hash={ item.l1_tx_origin }/></Box> <Skeleton isLoaded={ !isLoading } w="calc(100% - 44px)" overflow="hidden" whiteSpace="nowrap" ml={ 2 }>
<HashStringShorten hash={ item.l1_tx_origin }/>
</Skeleton>
</LinkExternal> </LinkExternal>
</Td> </Td>
<Td verticalAlign="middle" isNumeric> <Td verticalAlign="middle" isNumeric>
<Text variant="secondary">{ BigNumber(item.l2_tx_gas_limit).toFormat() }</Text> <Skeleton isLoaded={ !isLoading } color="text_secondary" display="inline-block">
<span>{ BigNumber(item.l2_tx_gas_limit).toFormat() }</span>
</Skeleton>
</Td> </Td>
</Tr> </Tr>
); );
......
import { Flex, Hide, Show, Skeleton, Text } from '@chakra-ui/react'; import { Box, Hide, Show, Skeleton } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import useApiQuery from 'lib/api/useApiQuery'; import useApiQuery from 'lib/api/useApiQuery';
import useIsMobile from 'lib/hooks/useIsMobile';
import useQueryWithPages from 'lib/hooks/useQueryWithPages'; import useQueryWithPages from 'lib/hooks/useQueryWithPages';
import { rightLineArrow, nbsp } from 'lib/html-entities'; import { rightLineArrow, nbsp } from 'lib/html-entities';
import { L2_DEPOSIT_ITEM } from 'stubs/L2';
import { generateListStub } from 'stubs/utils';
import DepositsListItem from 'ui/l2Deposits/DepositsListItem'; import DepositsListItem from 'ui/l2Deposits/DepositsListItem';
import DepositsTable from 'ui/l2Deposits/DepositsTable'; import DepositsTable from 'ui/l2Deposits/DepositsTable';
import ActionBar from 'ui/shared/ActionBar'; import ActionBar from 'ui/shared/ActionBar';
import DataListDisplay from 'ui/shared/DataListDisplay'; import DataListDisplay from 'ui/shared/DataListDisplay';
import Page from 'ui/shared/Page/Page';
import PageTitle from 'ui/shared/Page/PageTitle'; import PageTitle from 'ui/shared/Page/PageTitle';
import Pagination from 'ui/shared/Pagination'; import Pagination from 'ui/shared/Pagination';
const L2Deposits = () => { const L2Deposits = () => {
const isMobile = useIsMobile(); const { data, isError, isPlaceholderData, isPaginationVisible, pagination } = useQueryWithPages({
const { data, isError, isLoading, isPaginationVisible, pagination } = useQueryWithPages({
resourceName: 'l2_deposits', resourceName: 'l2_deposits',
options: {
placeholderData: generateListStub<'l2_deposits'>(
L2_DEPOSIT_ITEM,
50,
{
next_page_params: {
items_count: 50,
l1_block_number: 9045200,
tx_hash: '',
},
},
),
},
}); });
const countersQuery = useApiQuery('l2_deposits_count'); const countersQuery = useApiQuery('l2_deposits_count', {
queryOptions: {
placeholderData: 1927029,
},
});
const content = data?.items ? ( const content = data?.items ? (
<> <>
<Show below="lg" ssr={ false }>{ data.items.map((item => <DepositsListItem key={ item.l2_tx_hash } item={ item }/>)) }</Show> <Show below="lg" ssr={ false }>
<Hide below="lg" ssr={ false }><DepositsTable items={ data.items } top={ isPaginationVisible ? 80 : 0 }/></Hide> { data.items.map(((item, index) => (
<DepositsListItem
key={ item.l2_tx_hash + (isPlaceholderData ? index : '') }
isLoading={ isPlaceholderData }
item={ item }
/>
))) }
</Show>
<Hide below="lg" ssr={ false }>
<DepositsTable items={ data.items } top={ isPaginationVisible ? 80 : 0 } isLoading={ isPlaceholderData }/>
</Hide>
</> </>
) : null; ) : null;
const text = (() => { const text = (() => {
if (countersQuery.isLoading) {
return (
<Skeleton
w={{ base: '100%', lg: '320px' }}
h="24px"
mb={{ base: 7, lg: isPaginationVisible ? 0 : 7 }}
mt={{ base: 1, lg: isPaginationVisible ? 0 : 7 }}
/>
);
}
if (countersQuery.isError) { if (countersQuery.isError) {
return null; return null;
} }
return ( return (
<Text mb={{ base: 6, lg: isPaginationVisible ? 0 : 6 }} lineHeight={{ base: '24px', lg: '32px' }}> <Skeleton
A total of { countersQuery.data.toLocaleString() } deposits found isLoaded={ !countersQuery.isPlaceholderData }
</Text> display="inline-block"
>
A total of { countersQuery.data?.toLocaleString() } deposits found
</Skeleton>
); );
})(); })();
const actionBar = ( const actionBar = (
<> <>
{ (isMobile || !isPaginationVisible) && text } <Box mb={ 6 } display={{ base: 'flex', lg: 'none' }}>
{ isPaginationVisible && ( { text }
<ActionBar mt={ -6 }> </Box>
<Flex alignItems="center" justifyContent="space-between" w="100%"> <ActionBar mt={ -6 }>
{ !isMobile && text } <Box display={{ base: 'none', lg: 'flex' }}>
<Pagination ml="auto" { ...pagination }/> { text }
</Flex> </Box>
</ActionBar> { isPaginationVisible && <Pagination ml="auto" { ...pagination }/> }
) } </ActionBar>
</> </>
); );
return ( return (
<Page> <>
<PageTitle title={ `Deposits (L1${ nbsp }${ rightLineArrow }${ nbsp }L2)` } withTextAd/> <PageTitle title={ `Deposits (L1${ nbsp }${ rightLineArrow }${ nbsp }L2)` } withTextAd/>
<DataListDisplay <DataListDisplay
isError={ isError } isError={ isError }
isLoading={ isLoading } isLoading={ false }
items={ data?.items } items={ data?.items }
skeletonProps={{ skeletonDesktopColumns: Array(7).fill(`${ 100 / 7 }%`), skeletonDesktopMinW: '950px' }} skeletonProps={{ skeletonDesktopColumns: Array(7).fill(`${ 100 / 7 }%`), skeletonDesktopMinW: '950px' }}
emptyText="There are no withdrawals." emptyText="There are no withdrawals."
content={ content } content={ content }
actionBar={ actionBar } actionBar={ actionBar }
/> />
</Page> </>
); );
}; };
......
import { Link, Icon, chakra } from '@chakra-ui/react'; import { Link, Icon, chakra, Box, Skeleton } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import arrowIcon from 'icons/arrows/north-east.svg'; import arrowIcon from 'icons/arrows/north-east.svg';
...@@ -7,9 +7,19 @@ interface Props { ...@@ -7,9 +7,19 @@ interface Props {
href: string; href: string;
className?: string; className?: string;
children: React.ReactNode; children: React.ReactNode;
isLoading?: boolean;
} }
const LinkExternal = ({ href, children, className }: Props) => { const LinkExternal = ({ href, children, className, isLoading }: Props) => {
if (isLoading) {
return (
<Box className={ className } fontSize="sm" lineHeight={ 5 } display="inline-block" alignItems="center">
{ children }
<Skeleton boxSize={ 4 } verticalAlign="middle"/>
</Box>
);
}
return ( return (
<Link className={ className } fontSize="sm" lineHeight={ 5 } display="inline-block" alignItems="center" target="_blank" href={ href }> <Link className={ className } fontSize="sm" lineHeight={ 5 } display="inline-block" alignItems="center" target="_blank" href={ href }>
{ children } { children }
......
import type { LinkProps } from '@chakra-ui/react'; import type { LinkProps } from '@chakra-ui/react';
import { Link } from '@chakra-ui/react'; import { Flex, Link } from '@chakra-ui/react';
import type { LinkProps as NextLinkProps } from 'next/link'; import type { LinkProps as NextLinkProps } from 'next/link';
import NextLink from 'next/link'; import NextLink from 'next/link';
import type { LegacyRef } from 'react'; import type { LegacyRef } from 'react';
import React from 'react'; import React from 'react';
// NOTE! use this component only for links to pages that are completely implemented in new UI // NOTE! use this component only for links to pages that are completely implemented in new UI
const LinkInternal = (props: LinkProps, ref: LegacyRef<HTMLAnchorElement>) => { const LinkInternal = (props: LinkProps & { isLoading?: boolean }, ref: LegacyRef<HTMLAnchorElement>) => {
if (props.isLoading) {
return <Flex alignItems="center">{ props.children }</Flex>;
}
if (!props.href) { if (!props.href) {
return <Link { ...props } ref={ ref }/>; return <Link { ...props } ref={ ref }/>;
} }
......
...@@ -20,7 +20,8 @@ const Container = chakra(({ isAnimated, children, className }: ContainerProps) = ...@@ -20,7 +20,8 @@ const Container = chakra(({ isAnimated, children, className }: ContainerProps) =
rowGap={ 2 } rowGap={ 2 }
columnGap={ 2 } columnGap={ 2 }
gridTemplateColumns="86px auto" gridTemplateColumns="86px auto"
gridTemplateRows="minmax(30px, max-content)" gridTemplateRows="30px"
alignItems="start"
paddingY={ 4 } paddingY={ 4 }
borderColor="divider" borderColor="divider"
borderTopWidth="1px" borderTopWidth="1px"
...@@ -29,6 +30,7 @@ const Container = chakra(({ isAnimated, children, className }: ContainerProps) = ...@@ -29,6 +30,7 @@ const Container = chakra(({ isAnimated, children, className }: ContainerProps) =
}} }}
className={ className } className={ className }
fontSize="sm" fontSize="sm"
lineHeight="20px"
> >
{ children } { children }
</Grid> </Grid>
...@@ -47,7 +49,6 @@ const Label = chakra(({ children, className, isLoading }: LabelProps) => { ...@@ -47,7 +49,6 @@ const Label = chakra(({ children, className, isLoading }: LabelProps) => {
className={ className } className={ className }
isLoaded={ !isLoading } isLoaded={ !isLoading }
fontWeight={ 500 } fontWeight={ 500 }
lineHeight="20px"
my="5px" my="5px"
justifySelf="start" justifySelf="start"
> >
......
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