Commit 989cb7c4 authored by tom's avatar tom

fix vertical navigation

parent 4ec38bb7
...@@ -41,6 +41,8 @@ const ChakraShowcases = () => { ...@@ -41,6 +41,8 @@ const ChakraShowcases = () => {
<Link>Primary</Link> <Link>Primary</Link>
<Link visual="secondary">Secondary</Link> <Link visual="secondary">Secondary</Link>
<Link visual="subtle">Subtle</Link> <Link visual="subtle">Subtle</Link>
<Link visual="navigation">Navigation</Link>
<Link visual="navigation" data-selected p={ 3 } borderRadius="base">Navigation selected</Link>
</HStack> </HStack>
</section> </section>
......
...@@ -5,8 +5,8 @@ import type { Props } from './types'; ...@@ -5,8 +5,8 @@ import type { Props } from './types';
import AppErrorBoundary from 'ui/shared/AppError/AppErrorBoundary'; import AppErrorBoundary from 'ui/shared/AppError/AppErrorBoundary';
import HeaderAlert from 'ui/snippets/header/HeaderAlert'; import HeaderAlert from 'ui/snippets/header/HeaderAlert';
// TODO @tom2drum fix main layout // TODO @tom2drum fix main layout
// import HeaderDesktop from 'ui/snippets/header/HeaderDesktop'; import HeaderDesktop from 'ui/snippets/header/HeaderDesktop';
// import HeaderMobile from 'ui/snippets/header/HeaderMobile'; import HeaderMobile from 'ui/snippets/header/HeaderMobile';
import * as Layout from './components'; import * as Layout from './components';
...@@ -17,7 +17,7 @@ const LayoutDefault = ({ children }: Props) => { ...@@ -17,7 +17,7 @@ const LayoutDefault = ({ children }: Props) => {
<Layout.NavBar/> <Layout.NavBar/>
{ /* <HeaderMobile/> */ } { /* <HeaderMobile/> */ }
<Layout.MainArea> <Layout.MainArea>
{ /* <Layout.SideBar/> */ } <Layout.SideBar/>
<Layout.MainColumn> <Layout.MainColumn>
<HeaderAlert/> <HeaderAlert/>
{ /* <HeaderDesktop/> */ } { /* <HeaderDesktop/> */ }
......
import { useColorModeValue } from 'toolkit/chakra/color-mode';
// TODO @tom2drum remove this
export default function useColors() {
return {
text: {
'default': useColorModeValue('gray.600', 'gray.400'),
active: useColorModeValue('blue.700', 'gray.50'),
hover: 'link_hovered',
},
bg: {
'default': 'transparent',
active: useColorModeValue('blue.50', 'gray.800'),
},
border: {
'default': 'border.divider',
active: useColorModeValue('blue.50', 'gray.800'),
},
};
}
import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps'; import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps';
import useColors from './useColors';
type Props = { type Props = {
isExpanded?: boolean; isExpanded?: boolean;
isCollapsed?: boolean; isCollapsed?: boolean;
...@@ -9,15 +7,12 @@ type Props = { ...@@ -9,15 +7,12 @@ type Props = {
}; };
export default function useNavLinkProps({ isExpanded, isCollapsed, isActive }: Props) { export default function useNavLinkProps({ isExpanded, isCollapsed, isActive }: Props) {
const colors = useColors();
return { return {
itemProps: { itemProps: {
visual: 'navigation' as const,
py: '9px', py: '9px',
display: 'flex', display: 'flex',
color: isActive ? colors.text.active : colors.text.default, ...(isActive ? { 'data-selected': true } : {}),
bgColor: isActive ? colors.bg.active : colors.bg.default,
_hover: { color: isActive ? colors.text.active : colors.text.hover },
borderRadius: 'base', borderRadius: 'base',
...getDefaultTransitionProps({ transitionProperty: 'width, padding' }), ...getDefaultTransitionProps({ transitionProperty: 'width, padding' }),
}, },
......
import { Link, Text, HStack, Tooltip, Box, useBreakpointValue } from '@chakra-ui/react'; import { Link, HStack, Box, useBreakpointValue, chakra } from '@chakra-ui/react';
import NextLink from 'next/link'; import NextLink from 'next/link';
import React from 'react'; import React from 'react';
...@@ -8,11 +8,11 @@ import { route } from 'nextjs-routes'; ...@@ -8,11 +8,11 @@ import { route } from 'nextjs-routes';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import { isInternalItem } from 'lib/hooks/useNavItems'; import { isInternalItem } from 'lib/hooks/useNavItems';
import { Tooltip } from 'toolkit/chakra/tooltip';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
import LightningLabel, { LIGHTNING_LABEL_CLASS_NAME } from '../LightningLabel'; import LightningLabel, { LIGHTNING_LABEL_CLASS_NAME } from '../LightningLabel';
import NavLinkIcon from '../NavLinkIcon'; import NavLinkIcon from '../NavLinkIcon';
import useColors from '../useColors';
import useNavLinkStyleProps from '../useNavLinkStyleProps'; import useNavLinkStyleProps from '../useNavLinkStyleProps';
import { checkRouteHighlight } from '../utils'; import { checkRouteHighlight } from '../utils';
...@@ -25,7 +25,6 @@ type Props = { ...@@ -25,7 +25,6 @@ type Props = {
const NavLink = ({ item, onClick, isCollapsed, isDisabled }: Props) => { const NavLink = ({ item, onClick, isCollapsed, isDisabled }: Props) => {
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const colors = useColors();
const isInternalLink = isInternalItem(item); const isInternalLink = isInternalItem(item);
const href = isInternalLink ? route(item.nextRoute) : item.url; const href = isInternalLink ? route(item.nextRoute) : item.url;
...@@ -51,28 +50,36 @@ const NavLink = ({ item, onClick, isCollapsed, isDisabled }: Props) => { ...@@ -51,28 +50,36 @@ const NavLink = ({ item, onClick, isCollapsed, isDisabled }: Props) => {
onClick={ onClick } onClick={ onClick }
_hover={{ _hover={{
[`& *:not(.${ LIGHTNING_LABEL_CLASS_NAME }, .${ LIGHTNING_LABEL_CLASS_NAME } *)`]: { [`& *:not(.${ LIGHTNING_LABEL_CLASS_NAME }, .${ LIGHTNING_LABEL_CLASS_NAME } *)`]: {
color: isDisabled ? 'inherit' : 'link_hovered', color: isDisabled ? 'inherit' : 'link.primary.hover',
}, },
}} }}
> >
<Tooltip <Tooltip
label={ item.text } content={ item.text }
hasArrow={ false } showArrow={ false }
isDisabled={ isMobile || isCollapsed === false || (isCollapsed === undefined && isXLScreen) } disabled={ isMobile || isCollapsed === false || (isCollapsed === undefined && isXLScreen) }
placement="right" positioning={{ placement: 'right', offset: { crossAxis: 0, mainAxis: 20 } }}
variant="nav" visual="navigation"
gutter={ 20 } contentProps={{
color={ isInternalLink && item.isActive ? colors.text.active : colors.text.hover } color: isInternalLink && item.isActive ? 'link.navigation.fg.selected' : 'link.navigation.fg.hover',
margin={ 0 } }}
interactive
> >
<HStack spacing={ 0 } overflow="hidden"> <HStack gap={ 0 } overflow="hidden">
<NavLinkIcon item={ item }/> <NavLinkIcon item={ item }/>
<Text { ...styleProps.textProps } as="span" ml={ 3 }> <chakra.span
{ ...styleProps.textProps }
ml={ 3 }
display={{ base: 'inline', lg: isExpanded ? 'inline' : 'none', xl: isCollapsed ? 'none' : 'inline' }}
>
<span>{ item.text }</span> <span>{ item.text }</span>
{ !isInternalLink && <IconSvg name="link_external" boxSize={ 3 } color="icon_link_external" verticalAlign="middle"/> } { !isInternalLink && <IconSvg name="link_external" boxSize={ 3 } color="icon_link_external" verticalAlign="middle"/> }
</Text> </chakra.span>
{ isHighlighted && ( { isHighlighted && (
<LightningLabel iconColor={ styleProps.itemProps.bgColor } isCollapsed={ isCollapsed }/> <LightningLabel
iconColor={ isInternalLink && item.isActive ? 'link.navigation.bg.selected' : 'link.navigation.bg' }
isCollapsed={ isCollapsed }
/>
) } ) }
</HStack> </HStack>
</Tooltip> </Tooltip>
......
import { import { Text, HStack, Box, VStack } from '@chakra-ui/react';
Text,
HStack,
Box,
PopoverTrigger,
PopoverContent,
PopoverBody,
VStack,
} from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { NavGroupItem } from 'types/client/navigation'; import type { NavGroupItem } from 'types/client/navigation';
import Popover from 'ui/shared/chakra/Popover'; import { PopoverBody, PopoverContent, PopoverRoot, PopoverTrigger } from 'toolkit/chakra/popover';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
import LightningLabel from '../LightningLabel'; import LightningLabel from '../LightningLabel';
...@@ -34,12 +26,12 @@ const NavLinkGroup = ({ item, isCollapsed }: Props) => { ...@@ -34,12 +26,12 @@ const NavLinkGroup = ({ item, isCollapsed }: Props) => {
return ( return (
<Box as="li" listStyleType="none" w="100%"> <Box as="li" listStyleType="none" w="100%">
<Popover <PopoverRoot
trigger="hover" // TODO @tom2drum fix trigger
placement="right-start" // trigger="hover"
positioning={{ placement: 'right-start', offset: { crossAxis: 8, mainAxis: 8 } }}
// should not be lazy to help google indexing pages // should not be lazy to help google indexing pages
isLazy={ false } lazyMount={ false }
gutter={ 8 }
> >
<PopoverTrigger> <PopoverTrigger>
<Box <Box
...@@ -49,8 +41,9 @@ const NavLinkGroup = ({ item, isCollapsed }: Props) => { ...@@ -49,8 +41,9 @@ const NavLinkGroup = ({ item, isCollapsed }: Props) => {
pr={{ lg: isExpanded ? 0 : '15px', xl: isCollapsed ? '15px' : 0 }} pr={{ lg: isExpanded ? 0 : '15px', xl: isCollapsed ? '15px' : 0 }}
aria-label={ `${ item.text } link group` } aria-label={ `${ item.text } link group` }
position="relative" position="relative"
bgColor={ item.isActive ? 'link.navigation.bg.selected' : 'link.navigation.bg' }
> >
<HStack spacing={ 0 } overflow="hidden"> <HStack gap={ 0 } overflow="hidden">
<NavLinkIcon item={ item }/> <NavLinkIcon item={ item }/>
<Text <Text
{ ...styleProps.textProps } { ...styleProps.textProps }
...@@ -59,7 +52,10 @@ const NavLinkGroup = ({ item, isCollapsed }: Props) => { ...@@ -59,7 +52,10 @@ const NavLinkGroup = ({ item, isCollapsed }: Props) => {
{ item.text } { item.text }
</Text> </Text>
{ isHighlighted && ( { isHighlighted && (
<LightningLabel iconColor={ styleProps.itemProps.bgColor } isCollapsed={ isCollapsed }/> <LightningLabel
iconColor={ item.isActive ? 'link.navigation.bg.selected' : 'link.navigation.bg' }
isCollapsed={ isCollapsed }
/>
) } ) }
<IconSvg <IconSvg
name="arrows/east-mini" name="arrows/east-mini"
...@@ -77,10 +73,10 @@ const NavLinkGroup = ({ item, isCollapsed }: Props) => { ...@@ -77,10 +73,10 @@ const NavLinkGroup = ({ item, isCollapsed }: Props) => {
</PopoverTrigger> </PopoverTrigger>
<PopoverContent width="252px" top={{ lg: isExpanded ? '-16px' : 0, xl: isCollapsed ? 0 : '-16px' }}> <PopoverContent width="252px" top={{ lg: isExpanded ? '-16px' : 0, xl: isCollapsed ? 0 : '-16px' }}>
<PopoverBody p={ 4 }> <PopoverBody p={ 4 }>
<Text variant="secondary" fontSize="sm" mb={ 1 } display={{ lg: isExpanded ? 'none' : 'block', xl: isCollapsed ? 'block' : 'none' }}> <Text color="text.secondary" fontSize="sm" mb={ 1 } display={{ lg: isExpanded ? 'none' : 'block', xl: isCollapsed ? 'block' : 'none' }}>
{ item.text } { item.text }
</Text> </Text>
<VStack spacing={ 1 } alignItems="start" as="ul"> <VStack gap={ 1 } alignItems="start" as="ul">
{ item.subItems.map((subItem, index) => Array.isArray(subItem) ? ( { item.subItems.map((subItem, index) => Array.isArray(subItem) ? (
<Box <Box
key={ index } key={ index }
...@@ -101,7 +97,7 @@ const NavLinkGroup = ({ item, isCollapsed }: Props) => { ...@@ -101,7 +97,7 @@ const NavLinkGroup = ({ item, isCollapsed }: Props) => {
</VStack> </VStack>
</PopoverBody> </PopoverBody>
</PopoverContent> </PopoverContent>
</Popover> </PopoverRoot>
</Box> </Box>
); );
}; };
......
import { Flex, Box, VStack, useColorModeValue } from '@chakra-ui/react'; import { Flex, Box, VStack } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import config from 'configs/app'; import config from 'configs/app';
...@@ -46,18 +46,12 @@ const NavigationDesktop = () => { ...@@ -46,18 +46,12 @@ const NavigationDesktop = () => {
} }
}, [ handleTogglerClick ]); }, [ handleTogglerClick ]);
const chevronIconStyles = {
bgColor: useColorModeValue('white', 'black'),
color: useColorModeValue('blackAlpha.400', 'whiteAlpha.400'),
borderColor: 'border.divider',
};
const isExpanded = isCollapsed === false; const isExpanded = isCollapsed === false;
return ( return (
<Flex <Flex
display={{ base: 'none', lg: 'flex' }} display={{ base: 'none', lg: 'flex' }}
role="group" className="group"
position="relative" position="relative"
flexDirection="column" flexDirection="column"
alignItems="stretch" alignItems="stretch"
...@@ -88,7 +82,7 @@ const NavigationDesktop = () => { ...@@ -88,7 +82,7 @@ const NavigationDesktop = () => {
{ Boolean(config.UI.navigation.featuredNetworks) && <NetworkMenu isCollapsed={ isCollapsed }/> } { Boolean(config.UI.navigation.featuredNetworks) && <NetworkMenu isCollapsed={ isCollapsed }/> }
</Box> </Box>
<Box as="nav" mt={ 6 } w="100%"> <Box as="nav" mt={ 6 } w="100%">
<VStack as="ul" spacing="1" alignItems="flex-start"> <VStack as="ul" gap="1" alignItems="flex-start">
{ mainNavItems.map((item) => { { mainNavItems.map((item) => {
if (isGroupItem(item)) { if (isGroupItem(item)) {
return <NavLinkGroup key={ item.text } item={ item } isCollapsed={ isCollapsed }/>; return <NavLinkGroup key={ item.text } item={ item } isCollapsed={ isCollapsed }/>;
...@@ -100,7 +94,7 @@ const NavigationDesktop = () => { ...@@ -100,7 +94,7 @@ const NavigationDesktop = () => {
</Box> </Box>
{ isAuth && ( { isAuth && (
<Box as="nav" borderTopWidth="1px" borderColor="border.divider" w="100%" mt={ 3 } pt={ 3 }> <Box as="nav" borderTopWidth="1px" borderColor="border.divider" w="100%" mt={ 3 } pt={ 3 }>
<VStack as="ul" spacing="1" alignItems="flex-start"> <VStack as="ul" gap="1" alignItems="flex-start">
<NavLinkRewards isCollapsed={ isCollapsed }/> <NavLinkRewards isCollapsed={ isCollapsed }/>
{ accountNavItems.map((item) => <NavLink key={ item.text } item={ item } isCollapsed={ isCollapsed }/>) } { accountNavItems.map((item) => <NavLink key={ item.text } item={ item } isCollapsed={ isCollapsed }/>) }
</VStack> </VStack>
...@@ -110,10 +104,12 @@ const NavigationDesktop = () => { ...@@ -110,10 +104,12 @@ const NavigationDesktop = () => {
name="arrows/east-mini" name="arrows/east-mini"
width={ 6 } width={ 6 }
height={ 6 } height={ 6 }
border="1px" _hover={{ color: 'link.primary.hover' }}
_hover={{ color: 'link_hovered' }}
borderRadius="base" borderRadius="base"
{ ...chevronIconStyles } bgColor={{ base: 'white', _dark: 'black' }}
color={{ base: 'blackAlpha.400', _dark: 'whiteAlpha.400' }}
borderWidth="1px"
borderColor="border.divider"
transform={{ lg: isExpanded ? 'rotate(0)' : 'rotate(180deg)', xl: isCollapsed ? 'rotate(180deg)' : 'rotate(0)' }} transform={{ lg: isExpanded ? 'rotate(0)' : 'rotate(180deg)', xl: isCollapsed ? 'rotate(180deg)' : 'rotate(0)' }}
{ ...getDefaultTransitionProps({ transitionProperty: 'transform, left' }) } { ...getDefaultTransitionProps({ transitionProperty: 'transform, left' }) }
transformOrigin="center" transformOrigin="center"
......
import { PopoverTrigger } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import Popover from 'ui/shared/chakra/Popover'; import { PopoverRoot, PopoverTrigger } from 'toolkit/chakra/popover';
import NetworkMenuButton from './NetworkMenuButton'; import NetworkMenuButton from './NetworkMenuButton';
import NetworkMenuContentDesktop from './NetworkMenuContentDesktop'; import NetworkMenuContentDesktop from './NetworkMenuContentDesktop';
...@@ -15,18 +14,23 @@ const NetworkMenu = ({ isCollapsed }: Props) => { ...@@ -15,18 +14,23 @@ const NetworkMenu = ({ isCollapsed }: Props) => {
const menu = useNetworkMenu(); const menu = useNetworkMenu();
return ( return (
<Popover openDelay={ 300 } placement="right-start" isLazy isOpen={ menu.isOpen } onClose={ menu.onClose }> <PopoverRoot
positioning={{ placement: 'right-start', offset: { crossAxis: 0, mainAxis: 8 } }}
lazyMount
open={ menu.open }
onOpenChange={ menu.onOpenChange }
>
<PopoverTrigger> <PopoverTrigger>
<NetworkMenuButton <NetworkMenuButton
marginLeft="auto" marginLeft="auto"
overflow="hidden" overflow="hidden"
width={{ base: 'auto', lg: isCollapsed === false ? 'auto' : '0px', xl: isCollapsed ? '0px' : 'auto' }} width={{ base: 'auto', lg: isCollapsed === false ? '36px' : '0px', xl: isCollapsed ? '0px' : '36px' }}
isActive={ menu.isOpen } isActive={ menu.open }
onClick={ menu.onToggle } onClick={ menu.onToggle }
/> />
</PopoverTrigger> </PopoverTrigger>
<NetworkMenuContentDesktop items={ menu.data } tabs={ menu.availableTabs }/> <NetworkMenuContentDesktop items={ menu.data } tabs={ menu.availableTabs }/>
</Popover> </PopoverRoot>
); );
}; };
......
import { Button, chakra } from '@chakra-ui/react'; import { chakra } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { useColorModeValue } from 'toolkit/chakra/color-mode'; import { IconButton } from 'toolkit/chakra/icon-button';
import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
interface Props { interface Props {
...@@ -13,35 +12,28 @@ interface Props { ...@@ -13,35 +12,28 @@ interface Props {
} }
const NetworkMenuButton = ({ isMobile, isActive, onClick, className }: Props, ref: React.ForwardedRef<HTMLButtonElement>) => { const NetworkMenuButton = ({ isMobile, isActive, onClick, className }: Props, ref: React.ForwardedRef<HTMLButtonElement>) => {
const defaultIconColor = useColorModeValue('gray.600', 'gray.400');
const bgColorMobile = useColorModeValue('blue.50', 'gray.800');
const iconColorMobile = useColorModeValue('blue.700', 'blue.50');
return ( return (
<Button <IconButton
className={ className } className={ className }
variant="unstyled" visual="plain"
display="inline-flex" display="inline-flex"
alignItems="center" alignItems="center"
ref={ ref } ref={ ref }
h="36px" h={ 9 }
borderRadius="base" borderRadius="base"
backgroundColor={ isActive ? bgColorMobile : 'none' } backgroundColor={ isActive ? { _light: 'blue.50', _dark: 'gray.400' } : 'none' }
onClick={ onClick } onClick={ onClick }
aria-label="Network menu" aria-label="Network menu"
aria-roledescription="menu" aria-roledescription="menu"
> >
<IconSvg <IconSvg
name="networks" name="networks"
width="36px" boxSize={ 4 }
height="36px" color={ isActive ? { _light: 'blue.700', _dark: 'blue.50' } : { _light: 'gray.600', _dark: 'gray.400' } }
padding="10px"
color={ isActive ? iconColorMobile : defaultIconColor }
_hover={{ color: isMobile ? undefined : 'link_hovered' }} _hover={{ color: isMobile ? undefined : 'link_hovered' }}
cursor="pointer" cursor="pointer"
{ ...getDefaultTransitionProps({ transitionProperty: 'margin' }) }
/> />
</Button> </IconButton>
); );
}; };
......
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