Commit e3ec6ffb authored by Max Alekseenko's avatar Max Alekseenko

add lightning label

parent 4b906f03
......@@ -24,6 +24,11 @@ const hiddenLinks = (() => {
return result;
})();
const lightningLabels = (() => {
const parsedValue = parseEnvJson<Array<NavigationLinkId>>(getEnvValue('NEXT_PUBLIC_MENU_LIGTHNING_LABELS'));
return Array.isArray(parsedValue) ? parsedValue : [];
})();
const defaultColorTheme = (() => {
const envValue = getEnvValue('NEXT_PUBLIC_COLOR_THEME_DEFAULT') as ColorThemeId | undefined;
return COLOR_THEMES.find((theme) => theme.id === envValue);
......@@ -43,6 +48,7 @@ const UI = Object.freeze({
dark: getExternalAssetFilePath('NEXT_PUBLIC_NETWORK_ICON_DARK'),
},
hiddenLinks,
lightningLabels,
otherLinks: parseEnvJson<Array<NavItemExternal>>(getEnvValue('NEXT_PUBLIC_OTHER_LINKS')) || [],
featuredNetworks: getExternalAssetFilePath('NEXT_PUBLIC_FEATURED_NETWORKS'),
},
......
......@@ -28,6 +28,7 @@ NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs']
NEXT_PUBLIC_FEATURED_NETWORKS=https://raw.githubusercontent.com/blockscout/frontend-configs/dev/configs/featured-networks/eth-goerli.json
NEXT_PUBLIC_NETWORK_LOGO=https://raw.githubusercontent.com/blockscout/frontend-configs/dev/configs/network-logos/goerli.svg
NEXT_PUBLIC_NETWORK_ICON=https://raw.githubusercontent.com/blockscout/frontend-configs/dev/configs/network-icons/goerli.svg
NEXT_PUBLIC_MENU_LIGTHNING_LABELS=['/accounts','/apps']
## footer
##views
NEXT_PUBLIC_VIEWS_NFT_MARKETPLACES=[{'name':'LooksRare','collection_url':'https://goerli.looksrare.org/collections/{hash}','instance_url':'https://goerli.looksrare.org/collections/{hash}/{id}','logo_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/nft-marketplace-logos/looks-rare.png'}]
......
......@@ -128,6 +128,7 @@ Please be aware that all environment variables prefixed with `NEXT_PUBLIC_` will
| NEXT_PUBLIC_FEATURED_NETWORKS | `string` | URL of configuration file (`.json` format only) which contains list of featured networks that will be shown in the network menu. See [below](#featured-network-configuration-properties) list of available properties for particular network | - | - | `https://example.com/featured_networks_config.json` |
| NEXT_PUBLIC_OTHER_LINKS | `Array<{url: string; text: string}>` | List of links for the "Other" navigation menu | - | - | `[{'url':'https://blockscout.com','text':'Blockscout'}]` |
| NEXT_PUBLIC_NAVIGATION_HIDDEN_LINKS | `Array<LinkId>` | List of external links hidden in the navigation. Supported ids are `eth_rpc_api`, `rpc_api` | - | - | `['eth_rpc_api']` |
| NEXT_PUBLIC_MENU_LIGTHNING_LABELS | `Array<string>` | List of menu item routes that should have a lightning label | - | - | `['/accounts']` |
#### Featured network configuration properties
......
<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.375 16v-5.006H.676L7.697 0h7.9v6l.027 10H5.374Z" fill="currentColor"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.72 6.01V0L2.63 10.15h4.02V16l6.66-9.99H8.72Z" fill="#ED8936"/>
</svg>
......@@ -71,6 +71,7 @@
| "integration/full"
| "integration/partial"
| "key"
| "lightning_sidebar"
| "lightning"
| "link"
| "lock"
......
import { useColorModeValue } from '@chakra-ui/react';
import React from 'react';
import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps';
import IconSvg from 'ui/shared/IconSvg';
const LightningLabel = ({ bgColor, isCollapsed }: { bgColor?: string; isCollapsed?: boolean }) => {
const themeBgColor = useColorModeValue('white', 'black');
const defaultTransitionProps = getDefaultTransitionProps({ transitionProperty: 'color' });
const color = React.useMemo(() => {
if (isCollapsed) {
return (bgColor && bgColor !== 'transparent') ? bgColor : themeBgColor;
}
return 'transparent';
}, [ bgColor, themeBgColor, isCollapsed ]);
return (
<IconSvg
className="lightning-label"
name="lightning_sidebar"
boxSize={ 4 }
ml={ isCollapsed ? 0 : 1 }
position={ isCollapsed ? 'absolute' : 'relative' }
top={ isCollapsed ? '10px' : '0' }
right={ isCollapsed ? '15px' : '0' }
color={ color }
{ ...defaultTransitionProps }
/>
);
};
export default LightningLabel;
......@@ -10,8 +10,10 @@ import useIsMobile from 'lib/hooks/useIsMobile';
import { isInternalItem } from 'lib/hooks/useNavItems';
import IconSvg from 'ui/shared/IconSvg';
import LightningLabel from './LightningLabel';
import NavLinkIcon from './NavLinkIcon';
import useColors from './useColors';
import useLightningLabel from './useLightningLabel';
import useNavLinkStyleProps from './useNavLinkStyleProps';
type Props = {
......@@ -34,6 +36,8 @@ const NavLink = ({ item, isCollapsed, px, className, onClick, disableActiveState
const isXLScreen = useBreakpointValue({ base: false, xl: true });
const href = isInternalLink ? route(item.nextRoute) : item.url;
const hasLightningLabel = useLightningLabel(item);
const content = (
<Link
href={ href }
......@@ -41,12 +45,13 @@ const NavLink = ({ item, isCollapsed, px, className, onClick, disableActiveState
{ ...styleProps.itemProps }
w={{ base: '100%', lg: isExpanded ? '100%' : '60px', xl: isCollapsed ? '60px' : '100%' }}
display="flex"
position="relative"
px={ px || { base: 3, lg: isExpanded ? 3 : '15px', xl: isCollapsed ? '15px' : 3 } }
aria-label={ `${ item.text } link` }
whiteSpace="nowrap"
onClick={ onClick }
_hover={{
'& *': {
'& *:not(.lightning-label, .lightning-label *)': {
color: 'link_hovered',
},
}}
......@@ -60,12 +65,15 @@ const NavLink = ({ item, isCollapsed, px, className, onClick, disableActiveState
gutter={ 20 }
color={ isInternalLink && item.isActive ? colors.text.active : colors.text.hover }
>
<HStack spacing={ 3 } overflow="hidden">
<HStack spacing={ 0 } overflow="hidden">
<NavLinkIcon item={ item }/>
<Text { ...styleProps.textProps } as="span">
<Text { ...styleProps.textProps } as="span" ml={ 3 }>
<span>{ item.text }</span>
{ !isInternalLink && <IconSvg name="arrows/north-east" boxSize={ 4 } color="text_secondary" verticalAlign="middle"/> }
</Text>
{ hasLightningLabel && (
<LightningLabel bgColor={ styleProps.itemProps.bgColor } isCollapsed={ isCollapsed }/>
) }
</HStack>
</Tooltip>
</Link>
......
......@@ -15,8 +15,10 @@ import type { NavGroupItem } from 'types/client/navigation-items';
import IconSvg from 'ui/shared/IconSvg';
import LightningLabel from './LightningLabel';
import NavLink from './NavLink';
import NavLinkIcon from './NavLinkIcon';
import useLightningLabel from './useLightningLabel';
import useNavLinkStyleProps from './useNavLinkStyleProps';
type Props = {
......@@ -29,6 +31,8 @@ const NavLinkGroupDesktop = ({ item, isCollapsed }: Props) => {
const styleProps = useNavLinkStyleProps({ isCollapsed, isExpanded, isActive: item.isActive });
const hasLightningLabel = useLightningLabel(item.subItems);
return (
<Box as="li" listStyleType="none" w="100%">
<Popover
......@@ -45,13 +49,17 @@ const NavLinkGroupDesktop = ({ item, isCollapsed }: Props) => {
aria-label={ `${ item.text } link group` }
position="relative"
>
<HStack spacing={ 3 } overflow="hidden">
<HStack spacing={ 0 } overflow="hidden">
<NavLinkIcon item={ item }/>
<Text
{ ...styleProps.textProps }
ml={ 3 }
>
{ item.text }
</Text>
{ hasLightningLabel && (
<LightningLabel bgColor={ styleProps.itemProps.bgColor } isCollapsed={ isCollapsed }/>
) }
<IconSvg
name="arrows/east-mini"
position="absolute"
......
......@@ -10,7 +10,9 @@ import type { NavGroupItem } from 'types/client/navigation-items';
import IconSvg from 'ui/shared/IconSvg';
import LightningLabel from './LightningLabel';
import NavLinkIcon from './NavLinkIcon';
import useLightningLabel from './useLightningLabel';
import useNavLinkStyleProps from './useNavLinkStyleProps';
type Props = {
......@@ -22,6 +24,8 @@ type Props = {
const NavLinkGroup = ({ item, onClick, isExpanded }: Props) => {
const styleProps = useNavLinkStyleProps({ isActive: item.isActive, isExpanded });
const hasLightningLabel = useLightningLabel(item.subItems);
return (
<Box as="li" listStyleType="none" w="100%" onClick={ onClick }>
<Box
......@@ -31,13 +35,15 @@ const NavLinkGroup = ({ item, onClick, isExpanded }: Props) => {
aria-label={ `${ item.text } link group` }
>
<Flex justifyContent="space-between" width="100%" alignItems="center" pr={ 1 }>
<HStack spacing={ 3 } overflow="hidden">
<HStack spacing={ 0 } overflow="hidden">
<NavLinkIcon item={ item }/>
<Text
{ ...styleProps.textProps }
ml={ 3 }
>
{ item.text }
</Text>
{ hasLightningLabel && (<LightningLabel bgColor={ styleProps.itemProps.bgColor }/>) }
</HStack>
<IconSvg name="arrows/east-mini" transform="rotate(180deg)" boxSize={ 6 }/>
</Flex>
......
import type { NavItem } from 'types/client/navigation-items';
import config from 'configs/app';
import { isInternalItem } from 'lib/hooks/useNavItems';
export default function useLightningLabel(item: NavItem | Array<NavItem> | Array<Array<NavItem>>) {
function checkForLightningLabel(item: NavItem | Array<NavItem> | Array<Array<NavItem>>): boolean {
if (Array.isArray(item)) {
return item.some((subItem) => checkForLightningLabel(subItem));
}
return isInternalItem(item) && (config.UI.sidebar.lightningLabels.includes(item.nextRoute.pathname));
}
return checkForLightningLabel(item);
}
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