Commit bb7df432 authored by tom's avatar tom

refactor routed tabs

parent f129e6d4
......@@ -4,12 +4,12 @@ import React from 'react';
import PageNextJs from 'nextjs/PageNextJs';
// const Blocks = dynamic(() => import('ui/pages/Blocks'), { ssr: false });
const Blocks = dynamic(() => import('ui/pages/Blocks'), { ssr: false });
const Page: NextPage = () => {
return (
<PageNextJs pathname="/blocks">
{ /* <Blocks/> */ }
<Blocks/>
</PageNextJs>
);
};
......
......@@ -8,4 +8,10 @@ export const menuButton: TabItemMenu = {
component: null,
};
export const getTabValue = (tab: TabItem): string => tab.id.toString();
export const getTabValue = (tab: TabItem): string => {
if (Array.isArray(tab.id)) {
return tab.id[0];
}
return tab.id;
};
import { pickBy } from 'es-toolkit';
import { useRouter } from 'next/router';
import React from 'react';
import type { Props as AdaptiveTabsProps } from '../AdaptiveTabs/AdaptiveTabs';
import AdaptiveTabs from '../AdaptiveTabs/AdaptiveTabs';
import { getTabValue } from '../AdaptiveTabs/utils';
import useActiveTabFromQuery from './useActiveTabFromQuery';
interface Props extends AdaptiveTabsProps {}
const RoutedTabs = (props: Props) => {
const { tabs, onValueChange, ...rest } = props;
const router = useRouter();
const activeTab = useActiveTabFromQuery(props.tabs);
const tabsRef = React.useRef<HTMLDivElement>(null);
const handleValueChange = React.useCallback(({ value }: { value: string }) => {
const nextTab = tabs.find((tab) => getTabValue(tab) === value);
if (!nextTab) {
return;
}
const queryForPathname = pickBy(router.query, (value, key) => router.pathname.includes(`[${ key }]`));
router.push(
{ pathname: router.pathname, query: { ...queryForPathname, tab: value } },
undefined,
{ shallow: true },
);
onValueChange?.({ value });
}, [ tabs, router, onValueChange ]);
React.useEffect(() => {
if (router.query.scroll_to_tabs) {
tabsRef?.current?.scrollIntoView(true);
delete router.query.scroll_to_tabs;
router.push(
{
pathname: router.pathname,
query: router.query,
},
undefined,
{ shallow: true },
);
}
// replicate componentDidMount
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<AdaptiveTabs
{ ...rest }
tabs={ tabs }
onValueChange={ handleValueChange }
defaultValue={ activeTab ? getTabValue(activeTab) : undefined }
/>
);
};
export default React.memo(RoutedTabs);
import { useRouter } from 'next/router';
import type { TabItem } from '../AdaptiveTabs/types';
import getQueryParamString from 'lib/router/getQueryParamString';
export default function useActiveTabFromQuery(tabs: Array<TabItem>) {
const router = useRouter();
const tabFromQuery = getQueryParamString(router.query.tab);
if (!tabFromQuery) {
return;
}
return tabs.find((tab) => {
if (Array.isArray(tab.id)) {
return tab.id.includes(tabFromQuery);
}
return tab.id === tabFromQuery || ('subTabs' in tab && tab.subTabs?.some((id) => id === tabFromQuery));
});
}
......@@ -15,6 +15,7 @@ export const recipe = defineSlotRecipe({
},
list: {
display: 'inline-flex',
width: '100%',
position: 'relative',
isolation: 'isolate',
'--tabs-indicator-shadow': 'shadows.xs',
......
......@@ -2,20 +2,16 @@ import React from 'react';
import config from 'configs/app';
import { Heading } from 'toolkit/chakra/heading';
import AdaptiveTabs from 'toolkit/components/AdaptiveTabs/AdaptiveTabs';
import LatestOptimisticDeposits from 'ui/home/latestDeposits/LatestOptimisticDeposits';
import LatestTxs from 'ui/home/LatestTxs';
import LatestWatchlistTxs from 'ui/home/LatestWatchlistTxs';
import TabsWithScroll from 'ui/shared/Tabs/TabsWithScroll';
import useAuth from 'ui/snippets/auth/useIsAuth';
import LatestArbitrumDeposits from './latestDeposits/LatestArbitrumDeposits';
const rollupFeature = config.features.rollup;
const TAB_LIST_PROPS = {
mb: { base: 3, lg: 3 },
};
const TransactionsHome = () => {
const isAuth = useAuth();
if ((rollupFeature.isEnabled && (rollupFeature.type === 'optimistic' || rollupFeature.type === 'arbitrum')) || isAuth) {
......@@ -30,7 +26,7 @@ const TransactionsHome = () => {
return (
<>
<Heading level="3" mb={ 3 }>Transactions</Heading>
<TabsWithScroll tabs={ tabs } lazyBehavior="keepMounted" tabListProps={ TAB_LIST_PROPS }/>
<AdaptiveTabs tabs={ tabs } unmountOnExit={ false } listProps={{ mb: 3 }}/>
</>
);
}
......
......@@ -7,11 +7,11 @@ import useIsMobile from 'lib/hooks/useIsMobile';
import getQueryParamString from 'lib/router/getQueryParamString';
import { BLOCK } from 'stubs/block';
import { generateListStub } from 'stubs/utils';
import RoutedTabs from 'toolkit/components/RoutedTabs/RoutedTabs';
import BlocksContent from 'ui/blocks/BlocksContent';
import BlocksTabSlot from 'ui/blocks/BlocksTabSlot';
import PageTitle from 'ui/shared/Page/PageTitle';
import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
import RoutedTabs from 'ui/shared/Tabs/RoutedTabs';
const TAB_LIST_PROPS = {
marginBottom: 0,
......@@ -70,17 +70,22 @@ const BlocksPageContent = () => {
})();
const tabs: Array<RoutedTab> = [
{ id: 'blocks', title: 'All', component: <BlocksContent type="block" query={ blocksQuery }/> },
{ id: 'reorgs', title: 'Forked', component: <BlocksContent type="reorg" query={ reorgsQuery }/> },
{ id: 'uncles', title: 'Uncles', component: <BlocksContent type="uncle" query={ unclesQuery }/> },
{ id: 'blocks', title: 'All', component: <div>All</div> },
{ id: 'reorgs', title: 'Forked', component: <div>Forked</div> },
{ id: 'uncles', title: 'Uncles', component: <div>Uncles</div> },
];
// const tabs: Array<RoutedTab> = [
// { id: 'blocks', title: 'All', component: <BlocksContent type="block" query={ blocksQuery }/> },
// { id: 'reorgs', title: 'Forked', component: <BlocksContent type="reorg" query={ reorgsQuery }/> },
// { id: 'uncles', title: 'Uncles', component: <BlocksContent type="uncle" query={ unclesQuery }/> },
// ];
return (
<>
<PageTitle title="Blocks" withTextAd/>
<RoutedTabs
tabs={ tabs }
tabListProps={ isMobile ? undefined : TAB_LIST_PROPS }
listProps={ isMobile ? undefined : TAB_LIST_PROPS }
rightSlot={ <BlocksTabSlot pagination={ pagination }/> }
stickyEnabled={ !isMobile }
/>
......
import { Image, chakra } from '@chakra-ui/react';
import { chakra } from '@chakra-ui/react';
import React from 'react';
import config from 'configs/app';
import useApiQuery from 'lib/api/useApiQuery';
import { HOMEPAGE_STATS } from 'stubs/stats';
import Skeleton from 'ui/shared/chakra/Skeleton';
import { Image } from 'toolkit/chakra/image';
import { Skeleton } from 'toolkit/chakra/skeleton';
import TokenLogoPlaceholder from './TokenLogoPlaceholder';
......@@ -23,7 +24,7 @@ const NativeTokenIcon = ({ isLoading, className, type }: Props) => {
});
if (isLoading || statsQueryResult.isPlaceholderData) {
return <Skeleton borderRadius="base" className={ className }/>;
return <Skeleton borderRadius="base" loading className={ className }/>;
}
const src = type === 'secondary' ? statsQueryResult.data?.secondary_coin_image : statsQueryResult.data?.coin_image;
......@@ -32,10 +33,10 @@ const NativeTokenIcon = ({ isLoading, className, type }: Props) => {
<Image
borderRadius="base"
className={ className }
src={ src || '' }
src={ src || undefined }
alt={ `${ config.chain.currency.symbol } logo` }
fallback={ <TokenLogoPlaceholder borderRadius="base" className={ className }/> }
fallbackStrategy={ src ? 'onError' : 'beforeLoadOrError' }
// fallbackStrategy={ src ? 'onError' : 'beforeLoadOrError' }
/>
);
};
......
......@@ -4,10 +4,10 @@ import React from 'react';
import useIsMobile from 'lib/hooks/useIsMobile';
import { Heading } from 'toolkit/chakra/heading';
import { Skeleton } from 'toolkit/chakra/skeleton';
import { Tooltip } from 'toolkit/chakra/tooltip';
import { useDisclosure } from 'toolkit/hooks/useDisclosure';
import TextAd from 'ui/shared/ad/TextAd';
import Skeleton from 'ui/shared/chakra/Skeleton';
import IconSvg from 'ui/shared/IconSvg';
import LinkInternal from 'ui/shared/links/LinkInternal';
......@@ -42,7 +42,7 @@ const BackLink = (props: BackLinkProp & { isLoading?: boolean }) => {
mr={ 3 }
my={ 2 }
verticalAlign="text-bottom"
loading={ props.isLoading }
loading
/>
);
}
......@@ -139,7 +139,6 @@ const PageTitle = ({ title, contentAfter, withTextAd, backLink, className, isLoa
>
<Heading
ref={ headingRef }
as="h1"
level="1"
whiteSpace="normal"
wordBreak="break-all"
......
This diff is collapsed.
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