Skip to content

Design imprvs: chain list dropdown #2828

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion configs/app/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,12 @@ const UI = Object.freeze({
hiddenLinks,
highlightedRoutes,
otherLinks: parseEnvJson<Array<NavItemExternal>>(getEnvValue('NEXT_PUBLIC_OTHER_LINKS')) || [],
featuredNetworks: getExternalAssetFilePath('NEXT_PUBLIC_FEATURED_NETWORKS'),
layout: (getEnvValue('NEXT_PUBLIC_NAVIGATION_LAYOUT') || 'vertical') as NavigationLayout,
},
featuredNetworks: {
items: getExternalAssetFilePath('NEXT_PUBLIC_FEATURED_NETWORKS'),
allLink: getEnvValue('NEXT_PUBLIC_FEATURED_NETWORKS_ALL_LINK'),
},
footer: {
links: getExternalAssetFilePath('NEXT_PUBLIC_FOOTER_LINKS'),
frontendVersion: getEnvValue('NEXT_PUBLIC_GIT_TAG'),
Expand Down
1 change: 1 addition & 0 deletions configs/envs/.env.base
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ NEXT_PUBLIC_DEFI_DROPDOWN_ITEMS=[{'text':'Swapscout','icon':'swap','dappId':'swa
NEXT_PUBLIC_DEX_POOLS_ENABLED=true
NEXT_PUBLIC_FAULT_PROOF_ENABLED=true
NEXT_PUBLIC_FEATURED_NETWORKS=https://github.com/blockscout/frontend-configs/main/configs/featured-networks/eth.json
NEXT_PUBLIC_FEATURED_NETWORKS_ALL_LINK=https://chains.blockscout.com/
NEXT_PUBLIC_FOOTER_LINKS=https://github.com/blockscout/frontend-configs/main/configs/footer-links/base-mainnet.json
NEXT_PUBLIC_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/sherblockHolmesBadge
NEXT_PUBLIC_GAS_REFUEL_PROVIDER_CONFIG={'name': 'Need gas?', 'url_template': 'https://smolrefuel.com/?outboundChain={chainId}&partner=blockscout&utm_source=blockscout&disableBridges=true', 'dapp_id': 'smol-refuel', 'logo': 'https://blockscout-content.s3.amazonaws.com/smolrefuel-logo-action-button.png'}
Expand Down
2 changes: 2 additions & 0 deletions configs/envs/.env.eth
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ NEXT_PUBLIC_APP_ENV=development
NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL=ws

# Instance ENVs
NEXT_PUBLIC_NAVIGATION_LAYOUT=horizontal
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=eth.blockscout.com
Expand All @@ -20,6 +21,7 @@ NEXT_PUBLIC_DATA_AVAILABILITY_ENABLED=true
NEXT_PUBLIC_DEFI_DROPDOWN_ITEMS=[{'text':'Swapscout','icon':'swap','dappId':'swapscout'},{'text':'Revokescout','icon':'integration/partial','dappId':'revokescout'},{'text':'Payment link','icon':'payment_link','dappId':'peanut-protocol'}]
NEXT_PUBLIC_DEX_POOLS_ENABLED=true
NEXT_PUBLIC_FEATURED_NETWORKS=https://github.com/blockscout/frontend-configs/main/configs/featured-networks/eth.json
NEXT_PUBLIC_FEATURED_NETWORKS_ALL_LINK=https://chains.blockscout.com/
NEXT_PUBLIC_FOOTER_LINKS=https://github.com/blockscout/frontend-configs/main/configs/footer-links/eth-mainnet.json
NEXT_PUBLIC_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/sherblockHolmesBadge
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/sherblockHolmesBadge
Expand Down
7 changes: 7 additions & 0 deletions deploy/tools/envs-validator/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,13 @@ const schema = yup
.array()
.json()
.of(featuredNetworkSchema),
NEXT_PUBLIC_FEATURED_NETWORKS_ALL_LINK: yup
.string()
.when('NEXT_PUBLIC_FEATURED_NETWORKS', {
is: (value: Array<unknown> | undefined) => value && value.length > 0,
then: (schema) => schema.test(urlTest),
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_FEATURED_NETWORKS_ALL_LINK can only be set when NEXT_PUBLIC_FEATURED_NETWORKS is configured'),
}),
NEXT_PUBLIC_OTHER_LINKS: yup
.array()
.transform(replaceQuotes)
Expand Down
1 change: 1 addition & 0 deletions deploy/tools/envs-validator/test/.env.base
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.blocks
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://example.com
NEXT_PUBLIC_DATA_AVAILABILITY_ENABLED=true
NEXT_PUBLIC_FEATURED_NETWORKS=https://example.com
NEXT_PUBLIC_FEATURED_NETWORKS_ALL_LINK=https://example.com
NEXT_PUBLIC_NAVIGATION_HIGHLIGHTED_ROUTES=['/accounts','/apps']
NEXT_PUBLIC_NAVIGATION_LAYOUT=horizontal
NEXT_PUBLIC_FONT_FAMILY_HEADING={'name':'Montserrat','url':'https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700&display=swap'}
Expand Down
1 change: 1 addition & 0 deletions deploy/values/review/values.yaml.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ frontend:
env:
NEXT_PUBLIC_APP_ENV: review
NEXT_PUBLIC_FEATURED_NETWORKS: https://github.com/blockscout/frontend-configs/dev/configs/featured-networks/eth-sepolia.json
NEXT_PUBLIC_FEATURED_NETWORKS_ALL_LINK: https://chains.blockscout.com/
NEXT_PUBLIC_NETWORK_LOGO: https://github.com/blockscout/frontend-configs/main/configs/network-logos/sepolia.svg
NEXT_PUBLIC_NETWORK_ICON: https://github.com/blockscout/frontend-configs/main/configs/network-icons/sepolia.png
NEXT_PUBLIC_API_HOST: eth-sepolia.k8s-dev.blockscout.com
Expand Down
9 changes: 8 additions & 1 deletion docs/ENVS.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ All json-like values should be single-quoted. If it contains a hash (`#`) or a d
- [UI configuration](#ui-configuration)
- [Homepage](#homepage)
- [Navigation](#navigation)
- [Featured networks](#featured-networks)
- [Footer](#footer)
- [Favicon](#favicon)
- [Meta](#meta)
Expand Down Expand Up @@ -161,12 +162,18 @@ _Note_ Here, all values are arrays of up to two strings. The first string repres
| NEXT_PUBLIC_NETWORK_LOGO_DARK | `string` | Network logo for dark color mode; if not provided, **inverted** regular logo will be used instead | - | - | `https://placekitten.com/240/40` | v1.0.x+ |
| NEXT_PUBLIC_NETWORK_ICON | `string` | Network icon; used as a replacement for regular network logo when nav bar is collapsed; if not provided, placeholder will be shown; *Note* the icon size should be at least 60px by 60px | - | - | `https://placekitten.com/60/60` | v1.0.x+ |
| NEXT_PUBLIC_NETWORK_ICON_DARK | `string` | Network icon for dark color mode; if not provided, **inverted** regular icon will be used instead | - | - | `https://placekitten.com/60/60` | v1.0.x+ |
| NEXT_PUBLIC_FEATURED_NETWORKS | `string` | URL of configuration file (`.json` format only) or file content string representation. It 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` \| `[{'title':'Astar(EVM)','url':'https://astar.blockscout.com/','group':'Mainnets','icon':'https://example.com/astar.svg'}]` | v1.0.x+ |
| NEXT_PUBLIC_OTHER_LINKS | `Array<{url: string; text: string}>` | List of links for the "Other" navigation menu | - | - | `[{'url':'https://blockscout.com','text':'Blockscout'}]` | v1.0.x+ |
| 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']` | v1.16.0+ |
| NEXT_PUBLIC_NAVIGATION_HIGHLIGHTED_ROUTES | `Array<string>` | List of menu item routes that should have a lightning label | - | - | `['/accounts']` | v1.31.0+ |
| NEXT_PUBLIC_NAVIGATION_LAYOUT | `vertical \| horizontal` | Navigation menu layout type | - | `vertical` | `horizontal` | v1.32.0+ |

### Featured networks

| Variable | Type| Description | Compulsoriness | Default value | Example value | Version |
| --- | --- | --- | --- | --- | --- | --- |
| NEXT_PUBLIC_FEATURED_NETWORKS | `string` | URL of configuration file (`.json` format only) or file content string representation. It 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` \| `[{'title':'Astar(EVM)','url':'https://astar.blockscout.com/','group':'Mainnets','icon':'https://example.com/astar.svg'}]` | v1.0.x+ |
| NEXT_PUBLIC_FEATURED_NETWORKS_ALL_LINK | `string` | Link to the all chains resource. Will be displayed at the bottom of featured networks list. | Works only if NEXT_PUBLIC_FEATURED_NETWORKS is set | - | `https://example.com` | v2.3.0+ |

#### Featured network configuration properties

| Variable | Type| Description | Compulsoriness | Default value | Example value |
Expand Down
5 changes: 2 additions & 3 deletions toolkit/theme/foundations/semanticTokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,10 @@ const semanticTokens: ThemingConfig['semanticTokens'] = {
},
segmented: {
fg: {
DEFAULT: { value: { _light: '{colors.blue.600}', _dark: '{colors.blue.300}' } },
selected: { value: { _light: '{colors.blue.700}', _dark: '{colors.gray.50}' } },
DEFAULT: { value: { _light: '{colors.blackAlpha.800}', _dark: '{colors.whiteAlpha.800}' } },
},
border: {
DEFAULT: { value: { _light: '{colors.blue.50}', _dark: '{colors.gray.800}' } },
DEFAULT: { value: { _light: '{colors.blue.50}', _dark: '{colors.whiteAlpha.100}' } },
},
},
},
Expand Down
2 changes: 1 addition & 1 deletion toolkit/theme/recipes/tabs.recipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ export const recipe = defineSlotRecipe({
_selected: {
color: 'tabs.segmented.fg.selected',
bg: 'tabs.segmented.border',
borderColor: 'tabs.segmented.border',
borderColor: 'transparent',
_hover: {
color: 'tabs.segmented.fg.selected',
},
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 0 additions & 8 deletions ui/snippets/header/Burger.pw.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@ test('base view', async({ render, page }) => {

await component.getByRole('button', { name: 'Menu button' }).click();
await expect(page).toHaveScreenshot();

await page.getByRole('button', { name: 'Network menu' }).click();
await page.mouse.move(0, 0);
await expect(page).toHaveScreenshot();
});

test.describe('dark mode', () => {
Expand All @@ -47,10 +43,6 @@ test.describe('dark mode', () => {

await component.getByRole('button', { name: 'Menu button' }).click();
await expect(page).toHaveScreenshot();

await page.getByRole('button', { name: 'Network menu' }).click();
await page.mouse.move(0, 0);
await expect(page).toHaveScreenshot();
});
});

Expand Down
31 changes: 2 additions & 29 deletions ui/snippets/header/Burger.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { Box, Flex } from '@chakra-ui/react';
import React from 'react';

import config from 'configs/app';
import { DrawerBody, DrawerContent, DrawerRoot, DrawerTrigger } from 'toolkit/chakra/drawer';
import { IconButton } from 'toolkit/chakra/icon-button';
import { useDisclosure } from 'toolkit/hooks/useDisclosure';
Expand All @@ -10,26 +8,13 @@ import NavigationMobile from 'ui/snippets/navigation/mobile/NavigationMobile';
import RollupStageBadge from 'ui/snippets/navigation/RollupStageBadge';
import TestnetBadge from 'ui/snippets/navigation/TestnetBadge';
import NetworkLogo from 'ui/snippets/networkMenu/NetworkLogo';
import NetworkMenuButton from 'ui/snippets/networkMenu/NetworkMenuButton';
import NetworkMenuContentMobile from 'ui/snippets/networkMenu/NetworkMenuContentMobile';
import useNetworkMenu from 'ui/snippets/networkMenu/useNetworkMenu';

interface Props {
isMarketplaceAppPage?: boolean;
}

const Burger = ({ isMarketplaceAppPage }: Props) => {
const { open, onOpen, onClose, onOpenChange } = useDisclosure();
const networkMenu = useNetworkMenu();

const handleNetworkMenuButtonClick = React.useCallback(() => {
networkMenu.onToggle();
}, [ networkMenu ]);

const handleNetworkLogoClick = React.useCallback((event: React.SyntheticEvent) => {
networkMenu.open && event.preventDefault();
networkMenu.onClose();
}, [ networkMenu ]);

return (
<DrawerRoot
Expand All @@ -52,20 +37,8 @@ const Burger = ({ isMarketplaceAppPage }: Props) => {
<DrawerBody display="flex" flexDirection="column" overflowX="hidden" overflowY="auto">
<TestnetBadge alignSelf="flex-start"/>
<RollupStageBadge alignSelf="flex-start"/>
<Flex alignItems="center" justifyContent="space-between">
<NetworkLogo onClick={ handleNetworkLogoClick }/>
{ config.UI.navigation.featuredNetworks ? (
<NetworkMenuButton
w={ 9 }
isActive={ networkMenu.open }
onClick={ handleNetworkMenuButtonClick }
/>
) : <Box boxSize={ 9 }/> }
</Flex>
{ networkMenu.open ?
<NetworkMenuContentMobile tabs={ networkMenu.availableTabs } items={ networkMenu.data }/> :
<NavigationMobile onNavLinkClick={ onClose } isMarketplaceAppPage={ isMarketplaceAppPage }/>
}
<NetworkLogo/>
<NavigationMobile onNavLinkClick={ onClose } isMarketplaceAppPage={ isMarketplaceAppPage }/>
</DrawerBody>
</DrawerContent>
</DrawerRoot>
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import React from 'react';

import type { FeaturedNetwork, NetworkGroup } from 'types/networks';

import config from 'configs/app';
import { Link } from 'toolkit/chakra/link';
import { PopoverBody, PopoverContent } from 'toolkit/chakra/popover';
import { Skeleton } from 'toolkit/chakra/skeleton';
import { TabsContent, TabsList, TabsRoot, TabsTrigger } from 'toolkit/chakra/tabs';
Expand All @@ -14,7 +16,7 @@ interface Props {
items?: Array<FeaturedNetwork>;
}

const NetworkMenuPopup = ({ items, tabs }: Props) => {
const NetworkMenuContent = ({ items, tabs }: Props) => {
const selectedNetwork = items?.find(({ isActive }) => isActive);
const defaultTab = tabs.find((tab) => selectedNetwork?.group === tab);

Expand Down Expand Up @@ -50,14 +52,16 @@ const NetworkMenuPopup = ({ items, tabs }: Props) => {
</>
) : (
<TabsRoot
variant="secondary"
variant="segmented"
width="full"
fitted
size="sm"
lazyMount
value={ value }
onValueChange={ handleTabChange }
>
{ tabs.length > 1 && (
<TabsList columnGap={ 2 } mb={ 4 }>
<TabsList mb={ 2 } width="full">
{ tabs.map((tab) => (
<TabsTrigger
key={ tab }
Expand All @@ -72,7 +76,7 @@ const NetworkMenuPopup = ({ items, tabs }: Props) => {
<Box>
{ tabs.map((tab) => (
<TabsContent key={ tab } value={ tab } p={ 0 }>
<VStack as="ul" gap={ 1 } alignItems="stretch" maxH="516px" overflowY="scroll">
<VStack as="ul" gap={ 1 } alignItems="stretch" overflowY="scroll" maxH="516px">
{ items
.filter((network) => network.group === tab)
.map((network) => (
Expand All @@ -81,6 +85,19 @@ const NetworkMenuPopup = ({ items, tabs }: Props) => {
{ ...network }
/>
)) }
{ config.UI.featuredNetworks.allLink && (
<Link
href={ config.UI.featuredNetworks.allLink }
external
noIcon
variant="secondary"
my={ 2 }
px={ 2 }
fontSize="xs"
>
View all chains
</Link>
) }
</VStack>
</TabsContent>
)) }
Expand All @@ -89,12 +106,12 @@ const NetworkMenuPopup = ({ items, tabs }: Props) => {
);

return (
<PopoverContent w="330px">
<PopoverContent w="290px" maxH="unset">
<PopoverBody>
{ content }
</PopoverBody>
</PopoverContent>
);
};

export default React.memo(NetworkMenuPopup);
export default React.memo(NetworkMenuContent);
86 changes: 0 additions & 86 deletions ui/snippets/networkMenu/NetworkMenuContentMobile.tsx

This file was deleted.

Loading
Loading