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

Merge pull request #28 from blockscout/redesign-w-fixes

redesign fixes
parents 4fb75da4 f664b91f
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
}, },
"dependencies": { "dependencies": {
"@chakra-ui/icons": "^2.0.2", "@chakra-ui/icons": "^2.0.2",
"@chakra-ui/react": "^2.1.2", "@chakra-ui/react": "^2.2.1",
"@chakra-ui/theme-tools": "^2.0.2", "@chakra-ui/theme-tools": "^2.0.2",
"@emotion/react": "^11", "@emotion/react": "^11",
"@emotion/styled": "^11", "@emotion/styled": "^11",
......
...@@ -40,7 +40,7 @@ const variantFloating: PartsStyleFunction<typeof parts> = (props: StyleFunctionP ...@@ -40,7 +40,7 @@ const variantFloating: PartsStyleFunction<typeof parts> = (props: StyleFunctionP
// label's styles // label's styles
label: { label: {
top: '20px', top: '20px',
left: '20px', left: '22px',
zIndex: 2, zIndex: 2,
position: 'absolute', position: 'absolute',
color: mode('gray.500', 'whiteAlpha.400')(props), color: mode('gray.500', 'whiteAlpha.400')(props),
......
...@@ -21,6 +21,7 @@ const Table: ComponentMultiStyleConfig = { ...@@ -21,6 +21,7 @@ const Table: ComponentMultiStyleConfig = {
borderTopLeftRadius: 'md', borderTopLeftRadius: 'md',
borderTopRightRadius: 'md', borderTopRightRadius: 'md',
overflow: 'hidden', overflow: 'hidden',
fontVariant: 'normal',
}, },
}, },
sizes: { sizes: {
......
import React from 'react'; import React from 'react';
import Jazzicon, { jsNumberForAddress } from 'react-jazzicon'; import Jazzicon, { jsNumberForAddress } from 'react-jazzicon';
import { Box, Link, HStack, VStack, Image, Text, Icon } from '@chakra-ui/react'; import { Box, Link, HStack, VStack, Image, Text, Icon, Tooltip } from '@chakra-ui/react';
import CopyToClipboard from '../CopyToClipboard/CopyToClipboard'; import AddressWithDots from '../shared/AddressWithDots';
import CopyToClipboard from '../shared/CopyToClipboard';
import type { TWatchlistItem } from '../../data/watchlist'; import type { TWatchlistItem } from '../../data/watchlist';
import { nbsp } from '../../lib/html-entities'; import { nbsp } from '../../lib/html-entities';
import TokensIcon from '../../icons/tokens.svg'; import TokensIcon from '../../icons/tokens.svg';
...@@ -11,22 +12,22 @@ import WalletIcon from '../../icons/wallet.svg'; ...@@ -11,22 +12,22 @@ import WalletIcon from '../../icons/wallet.svg';
const WatchListAddressItem = ({ item }: {item: TWatchlistItem}) => { const WatchListAddressItem = ({ item }: {item: TWatchlistItem}) => {
const image = <Jazzicon diameter={ 50 } seed={ jsNumberForAddress(item.address) }/> const image = <Jazzicon diameter={ 24 } seed={ jsNumberForAddress(item.address) }/>
return ( return (
<HStack spacing={ 3 } align="top"> <HStack spacing={ 3 } align="top">
<Box width="50px">{ image }</Box> <Box width="24px">{ image }</Box>
<VStack spacing={ 2 } align="stretch" overflow="hidden"> <VStack spacing={ 2 } align="stretch" overflow="hidden">
<HStack spacing={ 2 } alignContent="center"> <HStack spacing={ 2 } alignContent="center">
<Link <Link
href="#" href="#"
color="blue.500" color="blue.500"
title={ item.address }
overflow="hidden" overflow="hidden"
textOverflow="ellipsis"
fontWeight={ 600 } fontWeight={ 600 }
lineHeight="24px" lineHeight="24px"
> >
{ item.address } <Tooltip hasArrow label={ item.address }>
<AddressWithDots address={ item.address }/>
</Tooltip>
</Link> </Link>
<CopyToClipboard text={ item.address }/> <CopyToClipboard text={ item.address }/>
</HStack> </HStack>
......
...@@ -7,6 +7,7 @@ import { ...@@ -7,6 +7,7 @@ import {
Switch, Switch,
Icon, Icon,
HStack, HStack,
Tooltip,
} from '@chakra-ui/react' } from '@chakra-ui/react'
import EditIcon from '../../icons/edit.svg'; import EditIcon from '../../icons/edit.svg';
...@@ -35,9 +36,11 @@ const WatchlistTableItem = ({ item, onEditClick, onDeleteClick }: Props) => { ...@@ -35,9 +36,11 @@ const WatchlistTableItem = ({ item, onEditClick, onDeleteClick }: Props) => {
<Tr alignItems="top" key={ item.address }> <Tr alignItems="top" key={ item.address }>
<Td><WatchListAddressItem item={ item }/></Td> <Td><WatchListAddressItem item={ item }/></Td>
<Td> <Td>
<Tag variant="gray" lineHeight="24px" title={ item.tag }> <Tooltip hasArrow label={ item.tag }>
{ item.tag } <Tag variant="gray" lineHeight="24px">
</Tag> { item.tag }
</Tag>
</Tooltip>
</Td> </Td>
<Td><Switch colorScheme="blue" size="md" isChecked={ item.notification }/></Td> <Td><Switch colorScheme="blue" size="md" isChecked={ item.notification }/></Td>
<Td> <Td>
......
...@@ -27,7 +27,7 @@ const WatchlistTable = ({ data, onDeleteClick, onEditClick }: Props) => { ...@@ -27,7 +27,7 @@ const WatchlistTable = ({ data, onDeleteClick, onEditClick }: Props) => {
<Tr> <Tr>
<Th width="70%">Address</Th> <Th width="70%">Address</Th>
<Th width="30%">Private tag</Th> <Th width="30%">Private tag</Th>
<Th width="108px">Notification</Th> <Th width="160px">Email notification</Th>
<Th width="108px"></Th> <Th width="108px"></Th>
</Tr> </Tr>
</Thead> </Thead>
......
...@@ -19,8 +19,8 @@ const AccountNavLink = ({ text, pathname, icon }: Props) => { ...@@ -19,8 +19,8 @@ const AccountNavLink = ({ text, pathname, icon }: Props) => {
as="li" as="li"
listStyleType="none" listStyleType="none"
w="220px" w="220px"
px={ 5 } px={ 4 }
py={ 4 } py={ 2.5 }
color={ isActive ? 'blue.600' : 'gray.600' } color={ isActive ? 'blue.600' : 'gray.600' }
bgColor={ isActive ? 'blue.50' : 'transparent' } bgColor={ isActive ? 'blue.50' : 'transparent' }
_hover={{ color: 'blue.600' }} _hover={{ color: 'blue.600' }}
......
...@@ -18,7 +18,7 @@ const navItems = [ ...@@ -18,7 +18,7 @@ const navItems = [
const AccountNavigation = () => { const AccountNavigation = () => {
return ( return (
<Box as="nav"> <Box as="nav">
<VStack as="ul" spacing="3"> <VStack as="ul" spacing="2">
{ navItems.map((item) => <AccountNavLink key={ item.text } { ...item }/>) } { navItems.map((item) => <AccountNavLink key={ item.text } { ...item }/>) }
</VStack> </VStack>
</Box> </Box>
......
...@@ -20,8 +20,8 @@ const MainNavLink = ({ text, pathname, icon }: Props) => { ...@@ -20,8 +20,8 @@ const MainNavLink = ({ text, pathname, icon }: Props) => {
as="li" as="li"
listStyleType="none" listStyleType="none"
w="220px" w="220px"
px={ 5 } px={ 4 }
py={ 4 } py={ 2.5 }
color={ isActive ? 'blue.600' : 'gray.600' } color={ isActive ? 'blue.600' : 'gray.600' }
bgColor={ isActive ? 'blue.50' : 'transparent' } bgColor={ isActive ? 'blue.50' : 'transparent' }
borderRadius="base" borderRadius="base"
......
...@@ -18,7 +18,7 @@ const navItems = [ ...@@ -18,7 +18,7 @@ const navItems = [
const MainNavigation = () => { const MainNavigation = () => {
return ( return (
<Box as="nav"> <Box as="nav">
<VStack as="ul" spacing="3"> <VStack as="ul" spacing="2">
{ navItems.map((item) => <MainNavLink key={ item.text } { ...item }/>) } { navItems.map((item) => <MainNavLink key={ item.text } { ...item }/>) }
</VStack> </VStack>
</Box> </Box>
......
// this component trims address like 0x123...4567 (always 4 chars after dots)
// or shows full address, if fits
// i can't do this with pure css. if you can, feel free to replace it
// if i use <span text-overflow=ellipsis>some chars</span><span>last 4 chars</span>
// i have an unremovable gap between dots and second span
// so i did it with js
import React, { useCallback, useEffect, useRef } from 'react';
import _debounce from 'lodash/debounce';
const TAIL_LENGTH = 4;
const HEAD_MIN_LENGTH = 4;
const AddressWithDots = ({ address }: {address: string}) => {
const addressRef = useRef<HTMLSpanElement>(null);
const calculateString = useCallback(() => {
const addressEl = addressRef.current;
if (!addressEl) {
return;
}
const parent = addressRef?.current?.parentNode as HTMLElement;
if (!parent) {
return;
}
const shadowEl = document.createElement('span');
shadowEl.style.opacity = '0';
parent.appendChild(shadowEl);
shadowEl.textContent = address;
const parentWidth = getWidth(parent);
if (getWidth(shadowEl) > parentWidth) {
for (let i = 1; i <= address.length - TAIL_LENGTH - HEAD_MIN_LENGTH; i++) {
const res = address.slice(0, address.length - i - TAIL_LENGTH) + '...' + address.slice(-TAIL_LENGTH);
shadowEl.textContent = res;
if (getWidth(shadowEl) < parentWidth || i === address.length - TAIL_LENGTH - HEAD_MIN_LENGTH) {
addressRef.current.textContent = res;
break;
}
}
} else {
addressRef.current.textContent = address;
}
parent.removeChild(shadowEl);
}, [ address ]);
useEffect(() => {
calculateString();
const resizeHandler = _debounce(calculateString, 50)
window.addEventListener('resize', resizeHandler)
return function cleanup() {
window.removeEventListener('resize', resizeHandler)
};
}, [ calculateString ]);
return <span ref={ addressRef }>{ address }</span>;
}
function getWidth(el: HTMLElement) {
return el.getBoundingClientRect().width;
}
export default AddressWithDots;
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