Commit c2996843 authored by tom goriunov's avatar tom goriunov Committed by GitHub

Merge pull request #76 from blockscout/text-component-theming

design refinements
parents 66b9d630 39cd85ea
<svg width="143" height="26" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.513 1a1 1 0 0 0-1-1H6.068a1 1 0 0 0-1 1v3.417a1 1 0 0 1-1 1H1.49a1 1 0 0 0-1 1V25a1 1 0 0 0 1 1h3.445a1 1 0 0 0 1-1V6.417a1 1 0 0 1 1-1h2.578a1 1 0 0 0 1-1V1Zm10.926 0a1 1 0 0 0-1-1h-3.445a1 1 0 0 0-1 1v3.417a1 1 0 0 0 1 1h2.389a1 1 0 0 1 1 1V25a1 1 0 0 0 1 1h3.444a1 1 0 0 0 1-1V6.417a1 1 0 0 0-1-1H22.44a1 1 0 0 1-1-1V1Zm-5.52 10.369a1 1 0 0 0-1-1h-3.445a1 1 0 0 0-1 1v8.524a1 1 0 0 0 1 1h3.445a1 1 0 0 0 1-1v-8.524Z"/><path d="M35.113 5.893h6.228c2.638 0 4.065 1.434 4.065 3.498.02.645-.15 1.28-.486 1.825a3.12 3.12 0 0 1-1.395 1.221v.067a3.548 3.548 0 0 1 1.842 1.364c.453.652.687 1.44.666 2.242 0 2.308-1.544 4.122-4.346 4.122h-6.574V5.893Zm6.27 5.827c.996 0 1.71-.761 1.71-1.92 0-1.158-.714-1.92-1.71-1.92h-3.95v3.84h3.95Zm.282 6.54c1.19 0 2.054-.94 2.054-2.306 0-1.367-.865-2.285-2.054-2.285h-4.232v4.592h4.232ZM48.93 7.599h-1.303V5.436h3.59v14.786h-2.293L48.931 7.6Zm4.409 7.324c0-3.248 2.317-5.644 5.517-5.644s5.535 2.374 5.535 5.644-2.313 5.623-5.535 5.623-5.517-2.375-5.517-5.623Zm4.911 3.495h1.236c1.406 0 2.638-1.546 2.638-3.495 0-1.948-1.236-3.52-2.638-3.52H58.25c-1.405 0-2.638 1.6-2.638 3.52s1.233 3.495 2.638 3.495Zm7.63-3.518c0-3.314 2.21-5.621 5.388-5.621 2.552 0 4.562 1.366 4.887 4.16h-2.227c-.217-1.412-1.19-2.039-2.184-2.039h-1.082c-1.384 0-2.508 1.568-2.508 3.52s1.124 3.54 2.508 3.54h1.082a2.163 2.163 0 0 0 1.494-.597c.409-.386.662-.916.711-1.487h2.227c-.308 2.755-2.335 4.189-4.942 4.189-3.17-.02-5.353-2.349-5.353-5.664Zm12.348-9.464h2.27v8.156h1.647l3.07-4.01h2.595l-3.784 4.951 3.957 5.69h-2.725l-3.308-4.704h-1.452v4.703h-2.27V5.436ZM89.02 17.029h2.185c.108.94.67 1.546 1.853 1.546h1.43c1.017 0 1.493-.538 1.493-1.255 0-.717-.39-1.142-1.32-1.28l-2.403-.32c-2.032-.246-2.94-1.5-2.94-3.136 0-2.15 1.544-3.315 4.303-3.315 2.64 0 4.24 1.098 4.324 3.54h-2.184c-.108-.92-.475-1.569-1.6-1.569h-1.3c-.973 0-1.428.538-1.428 1.232 0 .695.433 1.165 1.363 1.3l2.425.32c1.968.246 2.876 1.343 2.876 3.046 0 2.195-1.406 3.404-4.52 3.404-3.012.004-4.473-1.184-4.556-3.513ZM99.524 14.9c0-3.314 2.205-5.621 5.387-5.621 2.552 0 4.563 1.366 4.887 4.16h-2.227c-.216-1.412-1.189-2.039-2.184-2.039h-1.081c-1.387 0-2.512 1.568-2.512 3.52s1.125 3.54 2.512 3.54h1.081a2.165 2.165 0 0 0 1.495-.597 2.32 2.32 0 0 0 .711-1.487h2.227c-.309 2.755-2.336 4.189-4.943 4.189-3.166-.02-5.353-2.349-5.353-5.664Zm11.738.023c0-3.248 2.314-5.644 5.514-5.644 3.201 0 5.539 2.374 5.539 5.644s-2.314 5.623-5.539 5.623c-3.225 0-5.514-2.375-5.514-5.623Zm4.909 3.495h1.236c1.405 0 2.641-1.546 2.641-3.495 0-1.948-1.236-3.52-2.641-3.52h-1.236c-1.406 0-2.638 1.6-2.638 3.52s1.239 3.495 2.644 3.495h-.006Zm8.029-2.128V9.595h2.27v6.295c0 1.545.757 2.464 1.752 2.464h1.235c1.06 0 2.011-1.008 2.011-2.464V9.595h2.274v10.64h-2.209V18.78c-.618 1.098-1.708 1.77-3.373 1.77-2.49-.003-3.96-1.504-3.96-4.26Zm13.32 1.456v-6.08h-1.99v-2.07h1.99V6.612h2.292v2.982h2.681v2.061h-2.681v5.42c0 .695.216 1.031.951 1.031h1.817v2.128h-2.472c-1.662-.003-2.588-.899-2.588-2.49Z"/></svg>
\ No newline at end of file
<svg viewBox="0 0 143 26" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.513 1a1 1 0 0 0-1-1H6.068a1 1 0 0 0-1 1v3.417a1 1 0 0 1-1 1H1.49a1 1 0 0 0-1 1V25a1 1 0 0 0 1 1h3.445a1 1 0 0 0 1-1V6.417a1 1 0 0 1 1-1h2.578a1 1 0 0 0 1-1V1Zm10.926 0a1 1 0 0 0-1-1h-3.445a1 1 0 0 0-1 1v3.417a1 1 0 0 0 1 1h2.389a1 1 0 0 1 1 1V25a1 1 0 0 0 1 1h3.444a1 1 0 0 0 1-1V6.417a1 1 0 0 0-1-1H22.44a1 1 0 0 1-1-1V1Zm-5.52 10.369a1 1 0 0 0-1-1h-3.445a1 1 0 0 0-1 1v8.524a1 1 0 0 0 1 1h3.445a1 1 0 0 0 1-1v-8.524Z"/><path d="M35.113 5.893h6.228c2.638 0 4.065 1.434 4.065 3.498.02.645-.15 1.28-.486 1.825a3.12 3.12 0 0 1-1.395 1.221v.067a3.548 3.548 0 0 1 1.842 1.364c.453.652.687 1.44.666 2.242 0 2.308-1.544 4.122-4.346 4.122h-6.574V5.893Zm6.27 5.827c.996 0 1.71-.761 1.71-1.92 0-1.158-.714-1.92-1.71-1.92h-3.95v3.84h3.95Zm.282 6.54c1.19 0 2.054-.94 2.054-2.306 0-1.367-.865-2.285-2.054-2.285h-4.232v4.592h4.232ZM48.93 7.599h-1.303V5.436h3.59v14.786h-2.293L48.931 7.6Zm4.409 7.324c0-3.248 2.317-5.644 5.517-5.644s5.535 2.374 5.535 5.644-2.313 5.623-5.535 5.623-5.517-2.375-5.517-5.623Zm4.911 3.495h1.236c1.406 0 2.638-1.546 2.638-3.495 0-1.948-1.236-3.52-2.638-3.52H58.25c-1.405 0-2.638 1.6-2.638 3.52s1.233 3.495 2.638 3.495Zm7.63-3.518c0-3.314 2.21-5.621 5.388-5.621 2.552 0 4.562 1.366 4.887 4.16h-2.227c-.217-1.412-1.19-2.039-2.184-2.039h-1.082c-1.384 0-2.508 1.568-2.508 3.52s1.124 3.54 2.508 3.54h1.082a2.163 2.163 0 0 0 1.494-.597c.409-.386.662-.916.711-1.487h2.227c-.308 2.755-2.335 4.189-4.942 4.189-3.17-.02-5.353-2.349-5.353-5.664Zm12.348-9.464h2.27v8.156h1.647l3.07-4.01h2.595l-3.784 4.951 3.957 5.69h-2.725l-3.308-4.704h-1.452v4.703h-2.27V5.436ZM89.02 17.029h2.185c.108.94.67 1.546 1.853 1.546h1.43c1.017 0 1.493-.538 1.493-1.255 0-.717-.39-1.142-1.32-1.28l-2.403-.32c-2.032-.246-2.94-1.5-2.94-3.136 0-2.15 1.544-3.315 4.303-3.315 2.64 0 4.24 1.098 4.324 3.54h-2.184c-.108-.92-.475-1.569-1.6-1.569h-1.3c-.973 0-1.428.538-1.428 1.232 0 .695.433 1.165 1.363 1.3l2.425.32c1.968.246 2.876 1.343 2.876 3.046 0 2.195-1.406 3.404-4.52 3.404-3.012.004-4.473-1.184-4.556-3.513ZM99.524 14.9c0-3.314 2.205-5.621 5.387-5.621 2.552 0 4.563 1.366 4.887 4.16h-2.227c-.216-1.412-1.189-2.039-2.184-2.039h-1.081c-1.387 0-2.512 1.568-2.512 3.52s1.125 3.54 2.512 3.54h1.081a2.165 2.165 0 0 0 1.495-.597 2.32 2.32 0 0 0 .711-1.487h2.227c-.309 2.755-2.336 4.189-4.943 4.189-3.166-.02-5.353-2.349-5.353-5.664Zm11.738.023c0-3.248 2.314-5.644 5.514-5.644 3.201 0 5.539 2.374 5.539 5.644s-2.314 5.623-5.539 5.623c-3.225 0-5.514-2.375-5.514-5.623Zm4.909 3.495h1.236c1.405 0 2.641-1.546 2.641-3.495 0-1.948-1.236-3.52-2.641-3.52h-1.236c-1.406 0-2.638 1.6-2.638 3.52s1.239 3.495 2.644 3.495h-.006Zm8.029-2.128V9.595h2.27v6.295c0 1.545.757 2.464 1.752 2.464h1.235c1.06 0 2.011-1.008 2.011-2.464V9.595h2.274v10.64h-2.209V18.78c-.618 1.098-1.708 1.77-3.373 1.77-2.49-.003-3.96-1.504-3.96-4.26Zm13.32 1.456v-6.08h-1.99v-2.07h1.99V6.612h2.292v2.982h2.681v2.061h-2.681v5.42c0 .695.216 1.031.951 1.031h1.817v2.128h-2.472c-1.662-.003-2.588-.899-2.588-2.49Z"/></svg>
\ No newline at end of file
<svg width="20" height="20" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M0 2.632a2.632 2.632 0 1 1 5.263 0 2.632 2.632 0 0 1-5.263 0Zm7.368 0a2.632 2.632 0 1 1 5.263 0 2.632 2.632 0 0 1-5.263 0Zm10-2.632a2.632 2.632 0 1 0 0 5.263 2.632 2.632 0 0 0 0-5.263ZM0 10a2.632 2.632 0 1 1 5.263 0A2.632 2.632 0 0 1 0 10Zm7.368 0a2.632 2.632 0 1 1 5.263 0 2.632 2.632 0 0 1-5.263 0Zm10-2.632a2.632 2.632 0 1 0 0 5.264 2.632 2.632 0 0 0 0-5.264Zm-2.631 10a2.632 2.632 0 1 1 5.263 0 2.632 2.632 0 0 1-5.263 0ZM2.632 14.737a2.632 2.632 0 1 0 0 5.263 2.632 2.632 0 0 0 0-5.263Zm7.368 0A2.632 2.632 0 1 0 10 20a2.632 2.632 0 0 0 0-5.263Z" fill="currentColor"/></svg>
\ No newline at end of file
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M0 2.632a2.632 2.632 0 1 1 5.263 0 2.632 2.632 0 0 1-5.263 0Zm7.368 0a2.632 2.632 0 1 1 5.263 0 2.632 2.632 0 0 1-5.263 0Zm10-2.632a2.632 2.632 0 1 0 0 5.263 2.632 2.632 0 0 0 0-5.263ZM0 10a2.632 2.632 0 1 1 5.263 0A2.632 2.632 0 0 1 0 10Zm7.368 0a2.632 2.632 0 1 1 5.263 0 2.632 2.632 0 0 1-5.263 0Zm10-2.632a2.632 2.632 0 1 0 0 5.264 2.632 2.632 0 0 0 0-5.264Zm-2.631 10a2.632 2.632 0 1 1 5.263 0 2.632 2.632 0 0 1-5.263 0ZM2.632 14.737a2.632 2.632 0 1 0 0 5.263 2.632 2.632 0 0 0 0-5.263Zm7.368 0A2.632 2.632 0 1 0 10 20a2.632 2.632 0 0 0 0-5.263Z" fill="currentColor"/></svg>
\ No newline at end of file
import type { Types } from 'typescript-cookie';
import { Cookies } from 'typescript-cookie';
import isBrowser from './isBrowser';
export enum NAMES {
NAV_BAR_COLLAPSED='nav_bar_collapsed'
}
export function get(name?: string | undefined | null) {
if (!isBrowser()) {
return () => {};
}
return Cookies.get(name);
}
export function set(name: string, value: string, attributes: Types.CookieAttributes = {}) {
attributes.path = '/';
return Cookies.set(name, value, attributes);
}
export default function isBrowser() {
return typeof window !== 'undefined';
}
......@@ -63,6 +63,7 @@ const variants = {
const Button: ComponentStyleConfig = {
baseStyle: {
fontWeight: 'normal',
borderRadius: 'base',
},
variants,
sizes: {
......
import type { ComponentStyleConfig } from '@chakra-ui/theme';
import type { SystemStyleInterpolation } from '@chakra-ui/theme-tools';
import { mode } from '@chakra-ui/theme-tools';
const baseStyle = {
fontWeight: '500',
letterSpacing: '-0.5px',
const baseStyle: SystemStyleInterpolation = (props) => {
return {
fontWeight: '500',
color: mode('blackAlpha.800', 'whiteAlpha.800')(props),
};
};
// WIP
// designer promised to sync theme and page mock-ups
// so that's not the final point yet
const sizes = {
lg: {
fontSize: '32px',
lineHeight: '40px',
letterSpacing: '-0.5px',
},
md: {
fontSize: '24px',
lineHeight: '32px',
},
sm: {
fontSize: '18px',
lineHeight: '24px',
},
};
......
......@@ -33,8 +33,9 @@ const variantOutline: PartsStyleFunction<typeof parts> = (props) => {
field: getOutlinedFieldStyles(props),
addon: {
border: '2px solid',
borderColor: mode('gray.100', 'whiteAlpha.200')(props),
bg: mode('gray.100', 'whiteAlpha.200')(props),
borderColor: 'transparent',
bg: mode('blackAlpha.100', 'whiteAlpha.200')(props),
color: mode('blackAlpha.800', 'whiteAlpha.800')(props),
...transitionProps,
},
};
......
......@@ -11,15 +11,15 @@ const variantSimple: PartsStyleFunction<typeof parts> = (props) => {
return {
th: {
border: 0,
color: mode('gray.500', 'gray.50')(props),
color: mode('gray.600', 'gray.50')(props),
...transitionProps,
},
thead: {
backgroundColor: mode('gray.50', 'whiteAlpha.200')(props),
backgroundColor: mode('blackAlpha.100', 'whiteAlpha.200')(props),
...transitionProps,
},
td: {
borderColor: mode('gray.200', 'whiteAlpha.200')(props),
borderColor: mode('blackAlpha.200', 'whiteAlpha.200')(props),
...transitionProps,
},
};
......@@ -45,8 +45,8 @@ const Table: ComponentMultiStyleConfig = {
},
table: {
tableLayout: 'fixed',
borderTopLeftRadius: 'md',
borderTopRightRadius: 'md',
borderTopLeftRadius: 'base',
borderTopRightRadius: 'base',
overflow: 'hidden',
fontVariant: 'normal',
},
......
......@@ -3,21 +3,23 @@ import type { ComponentStyleConfig } from '@chakra-ui/theme';
import type {
PartsStyleFunction,
} from '@chakra-ui/theme-tools';
import { getColor } from '@chakra-ui/theme-tools';
import { mode } from '@chakra-ui/theme-tools';
const variantSoftRounded: PartsStyleFunction<typeof parts> = (props) => {
const { colorScheme: c, theme } = props;
return {
tab: {
borderRadius: '12px',
fontWeight: 'semibold',
color: 'gray.600',
borderRadius: 'base',
fontWeight: '600',
color: mode('blue.700', 'gray.400')(props),
_selected: {
color: getColor(theme, `${ c }.700`),
bg: getColor(theme, `${ c }.50`),
color: mode('blue.700', 'gray.50')(props),
bg: mode('blue.50', 'gray.800')(props),
_hover: {
color: mode('blue.700', 'gray.50')(props),
},
},
_hover: {
color: getColor(theme, `${ c }.400`),
color: 'blue.400',
},
},
};
......
......@@ -10,7 +10,7 @@ const variantGray: PartsStyleFunction<typeof parts> = (props) => {
return {
container: {
bg: mode('gray.200', 'gray.600')(props),
bg: mode('blackAlpha.100', 'whiteAlpha.400')(props),
color: mode('gray.600', 'gray.50')(props),
...transitionProps,
},
......@@ -27,7 +27,7 @@ const Tag: ComponentStyleConfig = {
display: 'inline-block',
overflow: 'hidden',
textOverflow: 'ellipsis',
borderRadius: 'md',
borderRadius: 'sm',
},
},
variants,
......
......@@ -2,14 +2,36 @@ import type { ComponentStyleConfig } from '@chakra-ui/theme';
import type { SystemStyleFunction } from '@chakra-ui/theme-tools';
import { mode } from '@chakra-ui/theme-tools';
const variantPrimary: SystemStyleFunction = (props) => ({
color: mode('blackAlpha.800', 'whiteAlpha.800')(props),
});
const variantSecondary: SystemStyleFunction = (props) => ({
color: mode('gray.500', 'gray.400')(props),
});
const variantAlternate: SystemStyleFunction = (props) => ({
color: mode('blue.600', 'blue.300')(props),
});
const variantInherit = {
color: 'inherit',
};
const variants = {
primary: variantPrimary,
secondary: variantSecondary,
alternate: variantAlternate,
inherit: variantInherit,
};
const defaultProps = {
variant: 'primary',
};
const Text: ComponentStyleConfig = {
variants: {
secondary: variantSecondary,
},
defaultProps,
variants,
};
export default Text;
import { Tooltip as TooltipComponent } from '@chakra-ui/react';
import type { ComponentStyleConfig } from '@chakra-ui/theme';
import type { SystemStyleFunction } from '@chakra-ui/theme-tools';
import { mode } from '@chakra-ui/theme-tools';
const variantNav: SystemStyleFunction = (props) => {
return {
bg: mode('blue.50', 'gray.800')(props),
color: 'blue.400',
padding: '15px 12px',
minWidth: '120px',
borderRadius: 'base',
fontSize: '14px',
lineHeight: '20px',
textAlign: 'center',
boxShadow: 'none',
fontWeight: '500',
};
};
const variants = {
nav: variantNav,
};
const Tooltip: ComponentStyleConfig = {
variants,
baseStyle: {
maxWidth: 'unset',
},
......
......@@ -2,8 +2,8 @@ const borders = {
radii: {
none: '0',
sm: '4px',
md: '8px',
base: '12px',
base: '8px',
md: '12px',
lg: '24px',
full: '9999px',
},
......
export default function getDefaultTransitionProps() {
export default function getDefaultTransitionProps(props?: {transitionProperty: string}) {
return {
transitionProperty: 'background-color, color, border-color',
transitionProperty: `background-color, color, border-color${ props?.transitionProperty ? ', ' + props.transitionProperty : '' }`,
transitionDuration: 'normal',
transitionTimingFunction: 'ease',
};
......
......@@ -36,7 +36,10 @@ export default function getOutlinedFieldStyles(props: StyleFunctionProps) {
borderColor: getColor(theme, fc),
boxShadow: '0px 4px 6px -1px rgba(0, 0, 0, 0.1), 0px 2px 4px -1px rgba(0, 0, 0, 0.06)',
},
':placeholder-shown:not(:focus-visible):not(:hover)': { borderColor: mode('gray.100', 'whiteAlpha.200')(props) },
_placeholder: {
color: mode('blackAlpha.600', 'whiteAlpha.600')(props),
},
':placeholder-shown:not(:focus-visible):not(:hover)': { borderColor: mode('blackAlpha.100', 'whiteAlpha.200')(props) },
':-webkit-autofill': { transition: 'background-color 5000s ease-in-out 0s' },
':-webkit-autofill:hover': { transition: 'background-color 5000s ease-in-out 0s' },
':-webkit-autofill:focus': { transition: 'background-color 5000s ease-in-out 0s' },
......
......@@ -20,9 +20,9 @@ const Header = () => {
<InputGroup>
<InputLeftAddon w="111px">All filters</InputLeftAddon>
<InputLeftElement w={ 6 } ml="132px" mr={ 2.5 }>
<SearchIcon w={ 5 } h={ 5 } color="gray.500"/>
<SearchIcon w={ 5 } h={ 5 } color={ useColorModeValue('blackAlpha.600', 'whiteAlpha.600') }/>
</InputLeftElement>
<Input paddingInlineStart="50px" placeholder="Search by addresses / transactions / block / token... "/>
<Input paddingInlineStart="50px" placeholder="Search by addresses / transactions / block / token... " ml="1px"/>
</InputGroup>
<ColorModeToggler/>
<Center minWidth="50px" width="50px" height="50px" bg={ useColorModeValue('blackAlpha.100', 'white') } borderRadius="50%" overflow="hidden">
......
import { Link, Icon, Text, HStack } from '@chakra-ui/react';
import NextLink from 'next/link';
import { useRouter } from 'next/router';
import React from 'react';
import useColors from './useColors';
interface Props {
pathname: string;
text: string;
icon: React.FunctionComponent<React.SVGAttributes<SVGElement>>;
}
const AccountNavLink = ({ text, pathname, icon }: Props) => {
const router = useRouter();
const isActive = router.pathname === pathname;
const colors = useColors();
return (
<NextLink href={ pathname } passHref>
<Link
as="li"
listStyleType="none"
w="220px"
px={ 4 }
py={ 2.5 }
color={ isActive ? colors.text.active : colors.text.default }
bgColor={ isActive ? colors.bg.active : colors.bg.default }
_hover={{ color: isActive ? colors.text.active : colors.text.hover }}
borderRadius="base"
>
<HStack spacing={ 3 }>
<Icon as={ icon } boxSize="30px"/>
<Text>{ text }</Text>
</HStack>
</Link>
</NextLink>
);
};
export default AccountNavLink;
import { Box, VStack } from '@chakra-ui/react';
import React from 'react';
import ABIIcon from 'icons/ABI.svg';
import ApiKeysIcon from 'icons/API.svg';
import PrivateTagIcon from 'icons/privattags.svg';
import PublicTagIcon from 'icons/publictags.svg';
import WatchlistIcon from 'icons/watchlist.svg';
import AccountNavLink from './AccountNavLink';
const navItems = [
{ text: 'Watchlist', pathname: '/watchlist', icon: WatchlistIcon },
{ text: 'Private tags', pathname: '/private-tags', icon: PrivateTagIcon },
{ text: 'Public tags', pathname: '/public-tags', icon: PublicTagIcon },
{ text: 'API keys', pathname: '/api-keys', icon: ApiKeysIcon },
{ text: 'Custom ABI', pathname: '/custom-abi', icon: ABIIcon },
];
const AccountNavigation = () => {
return (
<Box as="nav">
<VStack as="ul" spacing="2">
{ navItems.map((item) => <AccountNavLink key={ item.text } { ...item }/>) }
</VStack>
</Box>
);
};
export default AccountNavigation;
import { Box, VStack } from '@chakra-ui/react';
import React from 'react';
import AppsIcon from 'icons/apps.svg';
import BlocksIcon from 'icons/block.svg';
import BlockscoutIcon from 'icons/blockscout.svg';
import TokensIcon from 'icons/token.svg';
import TransactionsIcon from 'icons/transactions.svg';
import MainNavLink from './MainNavLink';
const navItems = [
{ text: 'Blocks', pathname: '/blocks', icon: BlocksIcon },
{ text: 'Transactions', pathname: '/transactions', icon: TransactionsIcon },
{ text: 'Tokens', pathname: '/tokens', icon: TokensIcon },
{ text: 'Apps', pathname: '/apps', icon: AppsIcon },
{ text: 'Blockscout', pathname: '/blockscout', icon: BlockscoutIcon },
];
const MainNavigation = () => {
return (
<Box as="nav">
<VStack as="ul" spacing="2">
{ navItems.map((item) => <MainNavLink key={ item.text } { ...item }/>) }
</VStack>
</Box>
);
};
export default MainNavigation;
import { VStack, Text, HStack, Icon, Link, useColorModeValue } from '@chakra-ui/react';
import { VStack, Text, Stack, Icon, Link, useColorModeValue } from '@chakra-ui/react';
import React from 'react';
import ghIcon from 'icons/social/git.svg';
......@@ -14,33 +14,42 @@ const SOCIAL_LINKS = [
{ link: '#stats', icon: statsIcon },
];
const NavFooter = () => {
interface Props {
isCollapsed: boolean;
}
const NavFooter = ({ isCollapsed }: Props) => {
return (
<VStack
as="footer"
spacing={ 8 }
borderTop="1px solid"
borderColor={ useColorModeValue('blackAlpha.200', 'whiteAlpha.200') }
width={ isCollapsed ? '20px' : '180px' }
paddingTop={ 8 }
w="100%"
alignItems="baseline"
marginTop={ 20 }
alignItems="flex-start"
color="gray.500"
fontSize="xs"
{ ...getDefaultTransitionProps() }
{ ...getDefaultTransitionProps({ transitionProperty: 'width' }) }
>
<HStack>
<Stack direction={ isCollapsed ? 'column' : 'row' }>
{ SOCIAL_LINKS.map(sl => {
return (
<Link href={ sl.link } key={ sl.link } variant="secondary">
<Link href={ sl.link } key={ sl.link } variant="secondary" w={ 5 } h={ 5 }>
<Icon as={ sl.icon } boxSize={ 5 }/>
</Link>
);
}) }
</HStack>
<Text>
Blockscout is a tool for inspecting and analyzing EVM based blockchains. Blockchain explorer for Ethereum Networks.
</Text>
<Text>Version: <Link color="blue.500">v4.2.1-beta</Link></Text>
</Stack>
{ !isCollapsed && (
<>
<Text variant="secondary">
Blockscout is a tool for inspecting and analyzing EVM based blockchains. Blockchain explorer for Ethereum Networks.
</Text>
<Text variant="secondary">Version: <Link>v4.2.1-beta</Link></Text>
</>
) }
</VStack>
);
};
......
import { ChevronRightIcon } from '@chakra-ui/icons';
import { Link, Icon, Text, HStack } from '@chakra-ui/react';
import { Link, Icon, Text, HStack, Tooltip } from '@chakra-ui/react';
import NextLink from 'next/link';
import { useRouter } from 'next/router';
import React from 'react';
import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps';
import useColors from './useColors';
interface Props {
isCollapsed: boolean;
pathname: string;
text: string;
icon: React.FunctionComponent<React.SVGAttributes<SVGElement>>;
}
const MainNavLink = ({ text, pathname, icon }: Props) => {
const NavLink = ({ text, pathname, icon, isCollapsed }: Props) => {
const router = useRouter();
const isActive = router.pathname === pathname;
......@@ -20,27 +22,37 @@ const MainNavLink = ({ text, pathname, icon }: Props) => {
return (
<NextLink href={ pathname } passHref>
<Link
as="li"
listStyleType="none"
w="220px"
px={ 4 }
w={ isCollapsed ? '60px' : '180px' }
px={ isCollapsed ? '15px' : 3 }
py={ 2.5 }
color={ isActive ? colors.text.active : colors.text.default }
bgColor={ isActive ? colors.bg.active : colors.bg.default }
_hover={{ color: isActive ? colors.text.active : colors.text.hover }}
borderRadius="base"
whiteSpace="nowrap"
{ ...getDefaultTransitionProps({ transitionProperty: 'width, padding' }) }
>
<HStack justifyContent="space-between">
<Tooltip
label={ text }
hasArrow={ false }
isDisabled={ !isCollapsed }
placement="right"
variant="nav"
gutter={ 15 }
color={ isActive ? colors.text.active : colors.text.hover }
>
<HStack spacing={ 3 }>
<Icon as={ icon } boxSize="30px"/>
<Text>{ text }</Text>
{ !isCollapsed && <Text variant="inherit">{ text }</Text> }
</HStack>
<ChevronRightIcon boxSize={ 6 }/>
</HStack>
</Tooltip>
</Link>
</NextLink>
);
};
export default MainNavLink;
export default React.memo(NavLink);
import { VStack, HStack, Icon, useColorModeValue } from '@chakra-ui/react';
import { ChevronLeftIcon } from '@chakra-ui/icons';
import { Flex, Icon, Box, VStack, useColorModeValue } from '@chakra-ui/react';
import React from 'react';
import abiIcon from 'icons/ABI.svg';
import apiKeysIcon from 'icons/API.svg';
import appsIcon from 'icons/apps.svg';
import blocksIcon from 'icons/block.svg';
import gearIcon from 'icons/gear.svg';
import logoIcon from 'icons/logo.svg';
import networksIcon from 'icons/networks.svg';
import privateTagIcon from 'icons/privattags.svg';
import publicTagIcon from 'icons/publictags.svg';
import tokensIcon from 'icons/token.svg';
import transactionsIcon from 'icons/transactions.svg';
import watchlistIcon from 'icons/watchlist.svg';
import * as cookies from 'lib/cookies';
import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps';
import getDefaultTransitionProps from '../../theme/utils/getDefaultTransitionProps';
import AccountNavigation from './AccountNavigation';
import MainNavigation from './MainNavigation';
import NavFooter from './NavFooter';
import NavLink from './NavLink';
const mainNavItems = [
{ text: 'Blocks', pathname: '/blocks', icon: blocksIcon },
{ text: 'Transactions', pathname: '/transactions', icon: transactionsIcon },
{ text: 'Tokens', pathname: '/tokens', icon: tokensIcon },
{ text: 'Apps', pathname: '/apps', icon: appsIcon },
{ text: 'Other', pathname: '/other', icon: gearIcon },
];
const accountNavItems = [
{ text: 'Watchlist', pathname: '/watchlist', icon: watchlistIcon },
{ text: 'Private tags', pathname: '/private-tags', icon: privateTagIcon },
{ text: 'Public tags', pathname: '/public-tags', icon: publicTagIcon },
{ text: 'API keys', pathname: '/api-keys', icon: apiKeysIcon },
{ text: 'Custom ABI', pathname: '/custom-abi', icon: abiIcon },
];
const Navigation = () => {
const [ isCollapsed, setCollapsedState ] = React.useState(cookies.get(cookies.NAMES.NAV_BAR_COLLAPSED) === 'true');
const handleTogglerClick = React.useCallback(() => {
setCollapsedState((flag) => !flag);
cookies.set(cookies.NAMES.NAV_BAR_COLLAPSED, isCollapsed ? 'false' : 'true');
}, [ isCollapsed ]);
const logoColor = useColorModeValue('blue.600', 'white');
return (
<VStack
alignItems="flex-start"
spacing={ 12 }
<Flex
position="relative"
flexDirection="column"
alignItems="center"
borderRight="1px solid"
borderColor={ useColorModeValue('blackAlpha.200', 'whiteAlpha.200') }
px={ 10 }
px={ isCollapsed ? 4 : 6 }
py={ 12 }
width="300px"
{ ...getDefaultTransitionProps() }
width={ isCollapsed ? '92px' : '229px' }
{ ...getDefaultTransitionProps({ transitionProperty: 'width, padding' }) }
>
<HStack as="header" justifyContent="space-between" w="100%" px={ 4 } mb={ 2 } h={ 10 } alignItems="center">
<Icon
as={ logoIcon }
width="142px"
height="26px"
color={ useColorModeValue('blue.600', 'white') }
{ ...getDefaultTransitionProps() }
/>
<Box
as="header"
display="flex"
justifyContent="center"
alignItems="center"
flexDirection="row"
w="100%"
px={ 3 }
h={ 10 }
>
<Box
width={ isCollapsed ? '0' : '113px' }
display="inline-flex"
overflow="hidden"
{ ...getDefaultTransitionProps({ transitionProperty: 'width' }) }
>
<Icon
as={ logoIcon }
width="113px"
height="20px"
color={ logoColor }
{ ...getDefaultTransitionProps() }
/>
</Box>
<Icon
as={ networksIcon }
width="20px"
height="20px"
width="16px"
height="16px"
color={ useColorModeValue('gray.500', 'white') }
{ ...getDefaultTransitionProps() }
marginLeft={ isCollapsed ? '0px' : '27px' }
{ ...getDefaultTransitionProps({ transitionProperty: 'margin' }) }
/>
</HStack>
<MainNavigation/>
<AccountNavigation/>
<NavFooter/>
</VStack>
</Box>
<Box as="nav" mt={ 14 }>
<VStack as="ul" spacing="2" alignItems="flex-start" overflow="hidden">
{ mainNavItems.map((item) => <NavLink key={ item.text } { ...item } isCollapsed={ isCollapsed }/>) }
</VStack>
</Box>
<Box as="nav" mt={ 12 }>
<VStack as="ul" spacing="2" alignItems="flex-start" overflow="hidden">
{ accountNavItems.map((item) => <NavLink key={ item.text } { ...item } isCollapsed={ isCollapsed }/>) }
</VStack>
</Box>
<NavFooter isCollapsed={ isCollapsed }/>
<ChevronLeftIcon
width={ 6 }
height={ 6 }
bgColor={ useColorModeValue('white', 'black') }
border="1px"
color={ useColorModeValue('blackAlpha.400', 'whiteAlpha.400') }
_hover={{ color: 'blue.400' }}
borderColor={ useColorModeValue('blackAlpha.200', 'whiteAlpha.200') }
borderRadius="base"
transform={ isCollapsed ? 'rotate(180deg)' : 'rotate(0)' }
{ ...getDefaultTransitionProps({ transitionProperty: 'transform, left' }) }
transformOrigin="center"
position="fixed"
top="104px"
left={ isCollapsed ? '80px' : '216px' }
cursor="pointer"
onClick={ handleTogglerClick }
/>
</Flex>
);
};
......
......@@ -3,13 +3,13 @@ import { useColorModeValue } from '@chakra-ui/react';
export default function useColors() {
return {
text: {
'default': useColorModeValue('gray.600', 'gray.300'),
active: useColorModeValue('blue.700', 'gray.300'),
'default': useColorModeValue('gray.600', 'gray.400'),
active: useColorModeValue('blue.700', 'gray.50'),
hover: 'blue.400',
},
bg: {
'default': 'transparent',
active: useColorModeValue('blue.50', 'whiteAlpha.200'),
active: useColorModeValue('blue.50', 'gray.800'),
},
};
}
......@@ -13,7 +13,7 @@ const Page = ({ children }: Props) => {
<HStack
w="100%"
minH="100vh"
spacing={ 16 }
spacing={ 12 }
alignItems="stretch"
paddingRight="60px"
>
......
......@@ -3400,6 +3400,11 @@ type-fest@^0.21.3:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==
typescript-cookie@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/typescript-cookie/-/typescript-cookie-1.0.4.tgz#22715aa394275e967fd734fa1417e24870504985"
integrity sha512-vZo252VmoEleD/dbE9Wb2lMK63V3M/8aqFbp2Pdb4Oxq8YqqADJ7iMh8THZenFXN+uZJPE8RXkztEaHkOptH4w==
typescript@4.7.2:
version "4.7.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.2.tgz#1f9aa2ceb9af87cca227813b4310fff0b51593c4"
......
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