Commit ab9dc1e4 authored by tom's avatar tom

fix setting menu

parent 7979e416
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
"start": "next start", "start": "next start",
"start:docker:local": "docker run -p 3000:3000 --env-file .env.local blockscout-frontend:local", "start:docker:local": "docker run -p 3000:3000 --env-file .env.local blockscout-frontend:local",
"start:docker:preset": "./tools/scripts/docker.preset.sh", "start:docker:preset": "./tools/scripts/docker.preset.sh",
"chakra:snippets:add": "chakra snippet add --outdir ./toolkit/chakra",
"chakra:typegen": "chakra typegen ./toolkit/theme/theme.ts",
"lint:eslint": "eslint .", "lint:eslint": "eslint .",
"lint:eslint:fix": "eslint . --fix", "lint:eslint:fix": "eslint . --fix",
"lint:tsc": "tsc -p ./tsconfig.json", "lint:tsc": "tsc -p ./tsconfig.json",
......
...@@ -29,7 +29,7 @@ export const Switch = React.forwardRef<HTMLInputElement, SwitchProps>( ...@@ -29,7 +29,7 @@ export const Switch = React.forwardRef<HTMLInputElement, SwitchProps>(
{ trackLabel.on } { trackLabel.on }
</ChakraSwitch.Indicator> </ChakraSwitch.Indicator>
) } ) }
</ChakraSwitch.Control> </ChakraSwitch.Control >
{ children != null && ( { children != null && (
<ChakraSwitch.Label>{ children }</ChakraSwitch.Label> <ChakraSwitch.Label>{ children }</ChakraSwitch.Label>
) } ) }
......
...@@ -117,6 +117,15 @@ const semanticTokens: ThemingConfig['semanticTokens'] = { ...@@ -117,6 +117,15 @@ const semanticTokens: ThemingConfig['semanticTokens'] = {
}, },
}, },
}, },
'switch': {
primary: {
bg: {
DEFAULT: { value: { base: '{colors.gray.300}', _dark: '{colors.whiteAlpha.400}' } },
checked: { value: { base: '{colors.blue.500}', _dark: '{colors.blue.300}' } },
hover: { value: { base: '{colors.blue.600}', _dark: '{colors.blue.400}' } },
},
},
},
text: { text: {
primary: { value: { base: '{colors.blackAlpha.800}', _dark: '{colors.whiteAlpha.800}' } }, primary: { value: { base: '{colors.blackAlpha.800}', _dark: '{colors.whiteAlpha.800}' } },
secondary: { value: { base: '{colors.gray.500}', _dark: '{colors.gray.400}' } }, secondary: { value: { base: '{colors.gray.500}', _dark: '{colors.gray.400}' } },
......
...@@ -3,6 +3,7 @@ import { recipe as link } from './link.recipe'; ...@@ -3,6 +3,7 @@ import { recipe as link } from './link.recipe';
import { recipe as popover } from './popover.recipe'; import { recipe as popover } from './popover.recipe';
import { recipe as progressCircle } from './progress-circle.recipe'; import { recipe as progressCircle } from './progress-circle.recipe';
import { recipe as skeleton } from './skeleton.recipe'; import { recipe as skeleton } from './skeleton.recipe';
import { recipe as switchRecipe } from './switch.recipe';
import { recipe as tabs } from './tabs.recipe'; import { recipe as tabs } from './tabs.recipe';
import { recipe as tooltip } from './tooltip.recipe'; import { recipe as tooltip } from './tooltip.recipe';
...@@ -15,6 +16,7 @@ export const recipes = { ...@@ -15,6 +16,7 @@ export const recipes = {
export const slotRecipes = { export const slotRecipes = {
popover, popover,
progressCircle, progressCircle,
'switch': switchRecipe,
tabs, tabs,
tooltip, tooltip,
}; };
...@@ -6,7 +6,7 @@ export const recipe = defineRecipe({ ...@@ -6,7 +6,7 @@ export const recipe = defineRecipe({
variants: { variants: {
loading: { loading: {
'true': { 'true': {
borderRadius: 'l2', borderRadius: 'sm',
boxShadow: 'none', boxShadow: 'none',
backgroundClip: 'padding-box', backgroundClip: 'padding-box',
cursor: 'default', cursor: 'default',
......
import { defineSlotRecipe } from '@chakra-ui/react';
export const recipe = defineSlotRecipe({
slots: [ 'root', 'label', 'indicator', 'control', 'thumb' ],
className: 'chakra-switch',
base: {
root: {
display: 'inline-flex',
gap: '2.5',
alignItems: 'center',
position: 'relative',
verticalAlign: 'middle',
'--switch-diff': 'calc(var(--switch-width) - var(--switch-height))',
'--switch-x': {
base: 'var(--switch-diff)',
_rtl: 'calc(var(--switch-diff) * -1)',
},
},
label: {
lineHeight: '1',
userSelect: 'none',
fontSize: 'sm',
fontWeight: '400',
_disabled: {
opacity: '0.5',
},
},
indicator: {
position: 'absolute',
height: 'var(--switch-height)',
width: 'var(--switch-height)',
fontSize: 'var(--switch-indicator-font-size)',
flexShrink: 0,
userSelect: 'none',
display: 'grid',
placeContent: 'center',
transition: 'inset-inline-start 0.12s ease',
insetInlineStart: 'calc(var(--switch-x) - 2px)',
_checked: {
insetInlineStart: '2px',
},
},
control: {
display: 'inline-flex',
gap: '0.5rem',
flexShrink: 0,
justifyContent: 'flex-start',
cursor: 'switch',
borderRadius: 'full',
position: 'relative',
width: 'var(--switch-width)',
height: 'var(--switch-height)',
_disabled: {
opacity: '0.5',
cursor: 'not-allowed',
},
_invalid: {
outline: '2px solid',
outlineColor: 'border.error',
outlineOffset: '2px',
},
},
thumb: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexShrink: 0,
transitionProperty: 'translate',
transitionDuration: 'fast',
borderRadius: 'inherit',
_checked: {
translate: 'var(--switch-x) 0',
},
},
},
variants: {
variant: {
primary: {
control: {
borderRadius: 'full',
bg: 'switch.primary.bg',
focusVisibleRing: 'outside',
_checked: {
bg: 'switch.primary.bg.checked',
_hover: {
bg: 'switch.primary.bg.hover',
},
},
},
thumb: {
bg: 'white',
width: 'var(--switch-height)',
height: 'var(--switch-height)',
scale: '0.8',
boxShadow: 'sm',
_checked: {
bg: 'white',
},
},
},
},
size: {
sm: {
root: {
'--switch-width': '26px',
'--switch-height': 'sizes.4',
'--switch-indicator-font-size': 'fontSizes.sm',
},
},
md: {
root: {
'--switch-width': '34px',
'--switch-height': 'sizes.5',
'--switch-indicator-font-size': 'fontSizes.md',
},
},
},
},
defaultVariants: {
variant: 'primary',
size: 'md',
},
});
...@@ -31,7 +31,7 @@ const TopBar = () => { ...@@ -31,7 +31,7 @@ const TopBar = () => {
<Separator mr={ 3 } ml={{ base: 2, sm: 3 }} height={ 4 } orientation="vertical"/> <Separator mr={ 3 } ml={{ base: 2, sm: 3 }} height={ 4 } orientation="vertical"/>
</> </>
) } */ } ) } */ }
{ /* <Settings/> */ } <Settings/>
{ config.UI.navigation.layout === 'horizontal' && Boolean(config.UI.navigation.featuredNetworks) && ( { config.UI.navigation.layout === 'horizontal' && Boolean(config.UI.navigation.featuredNetworks) && (
<Box display={{ base: 'none', lg: 'flex' }}> <Box display={{ base: 'none', lg: 'flex' }}>
<Separator mx={ 3 } height={ 4 } orientation="vertical"/> <Separator mx={ 3 } height={ 4 } orientation="vertical"/>
......
import { Box, IconButton, PopoverBody, PopoverContent, PopoverTrigger, useDisclosure } from '@chakra-ui/react'; import { Box, useDisclosure } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import Popover from 'ui/shared/chakra/Popover'; import { IconButton } from 'toolkit/chakra/icon-button';
import { PopoverBody, PopoverContent, PopoverRoot, PopoverTrigger } from 'toolkit/chakra/popover';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
import SettingsAddressFormat from './SettingsAddressFormat'; import SettingsAddressFormat from './SettingsAddressFormat';
...@@ -9,30 +10,44 @@ import SettingsColorTheme from './SettingsColorTheme'; ...@@ -9,30 +10,44 @@ import SettingsColorTheme from './SettingsColorTheme';
import SettingsIdentIcon from './SettingsIdentIcon'; import SettingsIdentIcon from './SettingsIdentIcon';
const Settings = () => { const Settings = () => {
const { isOpen, onToggle, onClose } = useDisclosure(); // TODO tom2drum refactor to separate hook
const { open, onOpen, onClose } = useDisclosure();
const handleOpenChange = React.useCallback(({ open }: { open: boolean }) => {
if (open) {
onOpen();
} else {
onClose();
}
}, [ onOpen, onClose ]);
return ( return (
<Popover placement="bottom-start" trigger="click" isOpen={ isOpen } onClose={ onClose }> <PopoverRoot
positioning={{ placement: 'bottom-start' }}
lazyMount
open={ open }
onOpenChange={ handleOpenChange }
>
<PopoverTrigger> <PopoverTrigger>
<IconButton <IconButton
variant="simple" visual="plain"
colorScheme="blue" color="link.primary"
_hover={{ color: 'link.primary.hover' }}
borderRadius="none"
aria-label="User settings" aria-label="User settings"
icon={ <IconSvg name="gear_slim" boxSize={ 5 }/> } >
p="1px" <IconSvg name="gear_slim" boxSize={ 5 } p="1px"/>
boxSize={ 5 } </IconButton>
onClick={ onToggle }
/>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent overflowY="hidden" w="auto" fontSize="sm"> <PopoverContent overflowY="hidden" w="auto" fontSize="sm">
<PopoverBody boxShadow="2xl" p={ 4 }> <PopoverBody>
<SettingsColorTheme onSelect={ onClose }/> <SettingsColorTheme onSelect={ onClose }/>
<Box borderColor="border.divider" borderWidth="1px" my={ 3 }/> <Box borderColor="border.divider" borderWidth="1px" my={ 3 }/>
<SettingsIdentIcon/> <SettingsIdentIcon/>
<SettingsAddressFormat/> <SettingsAddressFormat/>
</PopoverBody> </PopoverBody>
</PopoverContent> </PopoverContent>
</Popover> </PopoverRoot>
); );
}; };
......
import { FormLabel, FormControl, Switch } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import config from 'configs/app'; import config from 'configs/app';
import { BECH_32_SEPARATOR } from 'lib/address/bech32'; import { BECH_32_SEPARATOR } from 'lib/address/bech32';
import { useSettingsContext } from 'lib/contexts/settings'; import { useSettingsContext } from 'lib/contexts/settings';
import { Switch } from 'toolkit/chakra/switch';
const SettingsAddressFormat = () => { const SettingsAddressFormat = () => {
const settingsContext = useSettingsContext(); const settingsContext = useSettingsContext();
...@@ -15,12 +15,18 @@ const SettingsAddressFormat = () => { ...@@ -15,12 +15,18 @@ const SettingsAddressFormat = () => {
const { addressFormat, toggleAddressFormat } = settingsContext; const { addressFormat, toggleAddressFormat } = settingsContext;
return ( return (
<FormControl display="flex" alignItems="center" columnGap={ 2 } mt={ 4 }> <Switch
<FormLabel htmlFor="address-format" m="0" fontWeight={ 400 } fontSize="sm" lineHeight={ 5 }> id="address-format"
defaultChecked={ addressFormat === 'bech32' }
onChange={ toggleAddressFormat } mt={ 4 }
size="sm"
flexDirection="row-reverse"
gap={ 2 }
fontWeight="400"
color="text.secondary"
>
Show { config.UI.views.address.hashFormat.bech32Prefix }{ BECH_32_SEPARATOR } format Show { config.UI.views.address.hashFormat.bech32Prefix }{ BECH_32_SEPARATOR } format
</FormLabel> </Switch>
<Switch id="address-format" defaultChecked={ addressFormat === 'bech32' } onChange={ toggleAddressFormat }/>
</FormControl>
); );
}; };
......
import { Box, Flex, useColorMode } from '@chakra-ui/react'; import { Box, Flex } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import * as cookies from 'lib/cookies'; import * as cookies from 'lib/cookies';
import { COLOR_THEMES } from 'lib/settings/colorTheme'; import { COLOR_THEMES } from 'lib/settings/colorTheme';
import { useColorMode } from 'toolkit/chakra/color-mode';
import SettingsSample from './SettingsSample'; import SettingsSample from './SettingsSample';
...@@ -70,7 +71,7 @@ const SettingsColorTheme = ({ onSelect }: Props) => { ...@@ -70,7 +71,7 @@ const SettingsColorTheme = ({ onSelect }: Props) => {
return ( return (
<div> <div>
<Box fontWeight={ 600 }>Color theme</Box> <Box fontWeight={ 600 }>Color theme</Box>
<Box color="text_secondary" mt={ 1 } mb={ 2 }>{ activeTheme?.label }</Box> <Box color="text.secondary" mt={ 1 } mb={ 2 }>{ activeTheme?.label }</Box>
<Flex> <Flex>
{ COLOR_THEMES.map((theme) => ( { COLOR_THEMES.map((theme) => (
<SettingsSample <SettingsSample
......
...@@ -33,7 +33,7 @@ const SettingsIdentIcon = () => { ...@@ -33,7 +33,7 @@ const SettingsIdentIcon = () => {
return ( return (
<div> <div>
<Box fontWeight={ 600 }>Address settings</Box> <Box fontWeight={ 600 }>Address settings</Box>
<Box color="text_secondary" mt={ 1 } mb={ 2 }>{ activeIdenticon?.label }</Box> <Box color="text.secondary" mt={ 1 } mb={ 2 }>{ activeIdenticon?.label }</Box>
<Flex> <Flex>
{ IDENTICONS.map((identicon) => ( { IDENTICONS.map((identicon) => (
<SettingsSample <SettingsSample
......
import { import { Box } from '@chakra-ui/react';
Box,
Tooltip,
useColorModeValue,
useToken,
} from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { Tooltip } from 'toolkit/chakra/tooltip';
interface Props { interface Props {
onClick?: (event: React.MouseEvent<HTMLDivElement>) => void; onClick?: (event: React.MouseEvent<HTMLDivElement>) => void;
isActive: boolean; isActive: boolean;
...@@ -14,18 +11,14 @@ interface Props { ...@@ -14,18 +11,14 @@ interface Props {
label: string; label: string;
} }
const TOOLTIP_OFFSET: [ number, number ] = [ 0, 10 ];
const SettingsSample = ({ label, value, bg, onClick, isActive }: Props) => { const SettingsSample = ({ label, value, bg, onClick, isActive }: Props) => {
const bgColor = useColorModeValue('white', 'gray.900'); const bgColor = { base: 'white', _dark: 'gray.900' };
const activeBgColor = useColorModeValue('blue.50', 'whiteAlpha.100'); const activeBgColor = { base: 'blue.50', _dark: 'whiteAlpha.100' };
const activeBorderColor = { base: 'blackAlpha.800', _dark: 'gray.50' };
const activeBorderColor = useToken('colors', useColorModeValue('blackAlpha.800', 'gray.50'));
const hoverBorderColor = useToken('colors', 'link_hovered');
return ( return (
<Box p="9px" bgColor={ isActive ? activeBgColor : 'transparent' } borderRadius="base"> <Box p="9px" bgColor={ isActive ? activeBgColor : 'transparent' } borderRadius="base">
<Tooltip label={ label } offset={ TOOLTIP_OFFSET }> <Tooltip content={ label }>
<Box <Box
bg={ bg } bg={ bg }
boxSize="22px" boxSize="22px"
...@@ -37,6 +30,7 @@ const SettingsSample = ({ label, value, bg, onClick, isActive }: Props) => { ...@@ -37,6 +30,7 @@ const SettingsSample = ({ label, value, bg, onClick, isActive }: Props) => {
_before={{ _before={{
position: 'absolute', position: 'absolute',
display: 'block', display: 'block',
boxSizing: 'content-box',
content: '""', content: '""',
top: '-3px', top: '-3px',
left: '-3px', left: '-3px',
...@@ -49,7 +43,7 @@ const SettingsSample = ({ label, value, bg, onClick, isActive }: Props) => { ...@@ -49,7 +43,7 @@ const SettingsSample = ({ label, value, bg, onClick, isActive }: Props) => {
}} }}
_hover={{ _hover={{
_before: { _before: {
borderColor: isActive ? activeBorderColor : hoverBorderColor, borderColor: isActive ? activeBorderColor : 'link.primary.hover',
}, },
}} }}
data-value={ value } data-value={ value }
......
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