Commit 49a53378 authored by tom's avatar tom

fix some ts errors

parent f17360fa
import { ChakraProvider } from '@chakra-ui/react';
import { GrowthBookProvider } from '@growthbook/growthbook-react'; import { GrowthBookProvider } from '@growthbook/growthbook-react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import type { RenderOptions } from '@testing-library/react'; import type { RenderOptions } from '@testing-library/react';
...@@ -8,7 +7,7 @@ import React from 'react'; ...@@ -8,7 +7,7 @@ import React from 'react';
import { AppContextProvider } from 'lib/contexts/app'; import { AppContextProvider } from 'lib/contexts/app';
import { ScrollDirectionProvider } from 'lib/contexts/scrollDirection'; import { ScrollDirectionProvider } from 'lib/contexts/scrollDirection';
import { SocketProvider } from 'lib/socket/context'; import { SocketProvider } from 'lib/socket/context';
import theme from 'theme/theme'; import { Provider as ChakraProvider } from 'toolkit/chakra/provider';
import 'lib/setLocale'; import 'lib/setLocale';
...@@ -32,7 +31,7 @@ const TestApp = ({ children }: { children: React.ReactNode }) => { ...@@ -32,7 +31,7 @@ const TestApp = ({ children }: { children: React.ReactNode }) => {
})); }));
return ( return (
<ChakraProvider theme={ theme }> <ChakraProvider>
<QueryClientProvider client={ queryClient }> <QueryClientProvider client={ queryClient }>
<AppContextProvider pageProps={ PAGE_PROPS }> <AppContextProvider pageProps={ PAGE_PROPS }>
<ScrollDirectionProvider> <ScrollDirectionProvider>
......
import {
ChakraProvider as ChakraProviderDefault,
cookieStorageManagerSSR,
localStorageManager,
} from '@chakra-ui/react';
import type { ChakraProviderProps } from '@chakra-ui/react';
import React from 'react';
import theme from 'theme/theme';
interface Props extends ChakraProviderProps {
cookies?: string;
}
export function ChakraProvider({ cookies, children }: Props) {
const colorModeManager =
typeof cookies === 'string' ?
cookieStorageManagerSSR(typeof document !== 'undefined' ? document.cookie : cookies) :
localStorageManager;
return (
<ChakraProviderDefault colorModeManager={ colorModeManager } theme={ theme }>
{ children }
</ChakraProviderDefault>
);
}
...@@ -64,6 +64,7 @@ const OG_TYPE_DICT: Record<Route['pathname'], OGPageType> = { ...@@ -64,6 +64,7 @@ const OG_TYPE_DICT: Record<Route['pathname'], OGPageType> = {
// service routes, added only to make typescript happy // service routes, added only to make typescript happy
'/login': 'Regular page', '/login': 'Regular page',
'/sprite': 'Regular page', '/sprite': 'Regular page',
'/chakra': 'Regular page',
'/api/metrics': 'Regular page', '/api/metrics': 'Regular page',
'/api/monitoring/invalid-api-schema': 'Regular page', '/api/monitoring/invalid-api-schema': 'Regular page',
'/api/log': 'Regular page', '/api/log': 'Regular page',
......
...@@ -67,6 +67,7 @@ const TEMPLATE_MAP: Record<Route['pathname'], string> = { ...@@ -67,6 +67,7 @@ const TEMPLATE_MAP: Record<Route['pathname'], string> = {
// service routes, added only to make typescript happy // service routes, added only to make typescript happy
'/login': DEFAULT_TEMPLATE, '/login': DEFAULT_TEMPLATE,
'/sprite': DEFAULT_TEMPLATE, '/sprite': DEFAULT_TEMPLATE,
'/chakra': DEFAULT_TEMPLATE,
'/api/metrics': DEFAULT_TEMPLATE, '/api/metrics': DEFAULT_TEMPLATE,
'/api/monitoring/invalid-api-schema': DEFAULT_TEMPLATE, '/api/monitoring/invalid-api-schema': DEFAULT_TEMPLATE,
'/api/log': DEFAULT_TEMPLATE, '/api/log': DEFAULT_TEMPLATE,
......
...@@ -64,6 +64,7 @@ const TEMPLATE_MAP: Record<Route['pathname'], string> = { ...@@ -64,6 +64,7 @@ const TEMPLATE_MAP: Record<Route['pathname'], string> = {
// service routes, added only to make typescript happy // service routes, added only to make typescript happy
'/login': '%network_name% login', '/login': '%network_name% login',
'/sprite': '%network_name% SVG sprite', '/sprite': '%network_name% SVG sprite',
'/chakra': '%network_name% Chakra UI showcase',
'/api/metrics': '%network_name% node API prometheus metrics', '/api/metrics': '%network_name% node API prometheus metrics',
'/api/monitoring/invalid-api-schema': '%network_name% node API prometheus metrics', '/api/monitoring/invalid-api-schema': '%network_name% node API prometheus metrics',
'/api/log': '%network_name% node API request log', '/api/log': '%network_name% node API request log',
......
...@@ -62,6 +62,7 @@ export const PAGE_TYPE_DICT: Record<Route['pathname'], string> = { ...@@ -62,6 +62,7 @@ export const PAGE_TYPE_DICT: Record<Route['pathname'], string> = {
// service routes, added only to make typescript happy // service routes, added only to make typescript happy
'/login': 'Login', '/login': 'Login',
'/sprite': 'Sprite', '/sprite': 'Sprite',
'/chakra': 'Chakra UI showcase',
'/api/metrics': 'Node API: Prometheus metrics', '/api/metrics': 'Node API: Prometheus metrics',
'/api/monitoring/invalid-api-schema': 'Node API: Prometheus metrics', '/api/monitoring/invalid-api-schema': 'Node API: Prometheus metrics',
'/api/log': 'Node API: Request log', '/api/log': 'Node API: Request log',
......
import type { ColorMode } from '@chakra-ui/react';
import type { ColorThemeId } from 'types/settings'; import type { ColorThemeId } from 'types/settings';
import type { ColorMode } from 'toolkit/chakra/color-mode';
interface ColorTheme { interface ColorTheme {
id: ColorThemeId; id: ColorThemeId;
label: string; label: string;
......
/node_modules
/dist
\ No newline at end of file
import type { AlertProps } from '@chakra-ui/react';
import { Alert, AlertIcon, AlertTitle } from '@chakra-ui/react';
import React from 'react';
import { test, expect } from 'playwright/lib';
test.use({ viewport: { width: 400, height: 720 } });
const TEST_CASES: Array<AlertProps> = [
{
status: 'info',
},
{
status: 'warning',
},
{
status: 'success',
},
{
status: 'error',
},
{
status: 'info',
colorScheme: 'gray',
},
];
TEST_CASES.forEach((props) => {
const testName = Object.entries(props).map(([ key, value ]) => `${ key }=${ value }`).join(', ');
test(`${ testName } +@dark-mode`, async({ render }) => {
const component = await render(
<Alert { ...props }>
<AlertIcon/>
<AlertTitle>
This is alert text
</AlertTitle>
</Alert>,
);
await expect(component).toHaveScreenshot();
});
});
import { alertAnatomy as parts } from '@chakra-ui/anatomy';
import type { StyleFunctionProps } from '@chakra-ui/styled-system';
import { createMultiStyleConfigHelpers, cssVar } from '@chakra-ui/styled-system';
import { transparentize } from '@chakra-ui/theme-tools';
const { definePartsStyle, defineMultiStyleConfig } =
createMultiStyleConfigHelpers(parts.keys);
const $fg = cssVar('alert-fg');
const $bg = cssVar('alert-bg');
function getBg(props: StyleFunctionProps) {
const { theme, colorScheme: c } = props;
const darkBg = transparentize(`${ c }.200`, 0.16)(theme);
return {
light: `colors.${ c }.100`,
dark: darkBg,
};
}
const baseStyle = definePartsStyle({
container: {
bg: $bg.reference,
borderRadius: 'md',
px: 6,
py: 3,
},
title: {
fontWeight: 'bold',
lineHeight: '6',
marginEnd: '2',
},
description: {
lineHeight: '6',
},
icon: {
color: $fg.reference,
flexShrink: 0,
marginEnd: '3',
w: '5',
h: '6',
},
spinner: {
color: $fg.reference,
flexShrink: 0,
marginEnd: '3',
w: '5',
h: '5',
},
});
const variantSubtle = definePartsStyle((props) => {
const { colorScheme } = props;
const bg = getBg(props);
return {
container: {
[$fg.variable]: colorScheme === 'gray' ? 'colors.blackAlpha.800' : `colors.${ colorScheme }.500`,
[$bg.variable]: colorScheme === 'gray' ? 'colors.blackAlpha.100' : bg.light,
_dark: {
[$fg.variable]: colorScheme === 'gray' ? 'colors.whiteAlpha.800' : `colors.${ colorScheme }.200`,
[$bg.variable]: colorScheme === 'gray' ? 'colors.whiteAlpha.200' : bg.dark,
},
},
};
});
const variantSolid = definePartsStyle((props) => {
const { colorScheme: c } = props;
return {
container: {
[$fg.variable]: `colors.white`,
[$bg.variable]: `colors.${ c }.500`,
_dark: {
[$fg.variable]: `colors.gray.900`,
[$bg.variable]: `colors.${ c }.200`,
},
color: $fg.reference,
},
};
});
const variants = {
subtle: variantSubtle,
solid: variantSolid,
};
const Alert = defineMultiStyleConfig({
baseStyle,
variants,
defaultProps: {
variant: 'subtle',
colorScheme: 'blue',
},
});
export default Alert;
import { defineStyle, defineStyleConfig } from '@chakra-ui/styled-system';
import { mode } from '@chakra-ui/theme-tools';
const baseStyle = defineStyle({
fontSize: 'xs',
borderRadius: 'sm',
fontWeight: 'bold',
});
const variantSubtle = defineStyle((props) => {
const { colorScheme: c } = props;
if (c === 'gray') {
return {
bg: mode('blackAlpha.50', 'whiteAlpha.100')(props),
color: mode('blackAlpha.800', 'whiteAlpha.800')(props),
};
}
if (c === 'gray-blue') {
return {
bg: mode('gray.100', 'gray.800')(props),
color: mode('blackAlpha.800', 'whiteAlpha.800')(props),
_hover: {
opacity: 0.76,
},
};
}
if (c === 'black-blue') {
return {
bg: mode('blue.50', 'blue.800')(props),
color: mode('blackAlpha.800', 'whiteAlpha.800')(props),
};
}
if (c === 'black-purple') {
return {
bg: mode('purple.100', 'purple.800')(props),
color: mode('blackAlpha.800', 'whiteAlpha.800')(props),
};
}
return {
bg: mode(`${ c }.50`, `${ c }.800`)(props),
color: mode(`${ c }.500`, `${ c }.100`)(props),
};
});
const variants = {
subtle: variantSubtle,
};
const Badge = defineStyleConfig({
baseStyle,
variants,
defaultProps: {
variant: 'subtle',
colorScheme: 'gray',
},
});
export default Badge;
import { Box, Button, Flex } from '@chakra-ui/react';
import React from 'react';
import { test, expect } from 'playwright/lib';
test.use({ viewport: { width: 150, height: 350 } });
[
{ variant: 'solid', states: [ 'default', 'disabled', 'hovered', 'active' ] },
{ variant: 'outline', colorScheme: 'gray', withDarkMode: true, states: [ 'default', 'disabled', 'hovered', 'active', 'selected' ] },
{ variant: 'outline', colorScheme: 'blue', withDarkMode: true, states: [ 'default', 'disabled', 'hovered', 'active', 'selected' ] },
{ variant: 'simple', withDarkMode: true, states: [ 'default', 'hovered' ] },
{ variant: 'ghost', withDarkMode: true, states: [ 'default', 'hovered', 'active' ] },
{ variant: 'subtle', states: [ 'default', 'hovered' ] },
{ variant: 'subtle', colorScheme: 'gray', states: [ 'default', 'hovered' ], withDarkMode: true },
{ variant: 'hero', states: [ 'default', 'hovered' ], withDarkMode: true },
{ variant: 'header', states: [ 'default', 'hovered', 'selected' ], withDarkMode: true },
{ variant: 'radio_group', states: [ 'default', 'hovered', 'selected' ], withDarkMode: true },
].forEach(({ variant, colorScheme, withDarkMode, states }) => {
test.describe(`variant ${ variant }${ colorScheme ? ` with ${ colorScheme } color scheme` : '' }${ withDarkMode ? ' +@dark-mode' : '' }`, () => {
test('base view', async({ render }) => {
const component = await render(
<Flex p={ 2 } flexDir="column" rowGap={ 3 }>
{ states?.map((state) => {
switch (state) {
case 'default': {
return (
<Box>
<Box color="text_secondary" fontSize="sm">Default:</Box>
<Button variant={ variant } colorScheme={ colorScheme }>Click me</Button>
</Box>
);
}
case 'disabled': {
return (
<Box>
<Box color="text_secondary" fontSize="sm">Disabled:</Box>
<Button variant={ variant } colorScheme={ colorScheme } isDisabled>Click me</Button>
</Box>
);
}
case 'active': {
return (
<Box>
<Box color="text_secondary" fontSize="sm">Active:</Box>
<Button variant={ variant } colorScheme={ colorScheme } isActive>Click me</Button>
</Box>
);
}
case 'hovered': {
return (
<Box>
<Box color="text_secondary" fontSize="sm">Hovered:</Box>
<Button variant={ variant } colorScheme={ colorScheme }>Hover me</Button>
</Box>
);
}
case 'selected': {
return (
<Box>
<Box color="text_secondary" fontSize="sm">Selected:</Box>
<Button variant={ variant } colorScheme={ colorScheme } data-selected="true">Click me</Button>
</Box>
);
}
default: {
return null;
}
}
}) }
</Flex>,
);
await component.getByText('Hover me').hover();
await expect(component).toHaveScreenshot();
});
});
});
import { defineStyle, defineStyleConfig } from '@chakra-ui/styled-system';
import { mode } from '@chakra-ui/theme-tools';
import { runIfFn } from '@chakra-ui/utils';
import config from 'configs/app';
const variantSolid = defineStyle((props) => {
const { colorScheme: c } = props;
const bg = `${ c }.600`;
const color = 'white';
const hoverBg = `${ c }.400`;
const activeBg = hoverBg;
return {
bg,
color,
_hover: {
bg: hoverBg,
_disabled: {
bg,
},
},
_disabled: {
opacity: 0.2,
},
// According to design there is no "active" or "pressed" state
// It is simply should be the same as the "hover" state
_active: { bg: activeBg },
fontWeight: 600,
};
});
const variantOutline = defineStyle((props) => {
const { colorScheme: c } = props;
const isGrayTheme = c === 'gray';
const bg = 'transparent';
const color = isGrayTheme ? mode('blackAlpha.800', 'whiteAlpha.800')(props) : mode(`${ c }.600`, `${ c }.300`)(props);
const borderColor = isGrayTheme ? mode('gray.200', 'gray.600')(props) : mode(`${ c }.600`, `${ c }.300`)(props);
const selectedBg = isGrayTheme ? mode('blue.50', 'gray.600')(props) : mode(`${ c }.50`, 'gray.600')(props);
const selectedColor = mode('blue.600', 'gray.50')(props);
return {
color,
fontWeight: props.fontWeight || 600,
borderWidth: props.borderWidth || '2px',
borderStyle: 'solid',
borderColor,
bg,
_hover: {
color: 'link_hovered',
borderColor: 'link_hovered',
bg,
span: {
color: 'link_hovered',
},
_disabled: {
color,
borderColor,
},
},
_disabled: {
opacity: 0.2,
},
// According to design there is no "active" or "pressed" state
// It is simply should be the same as the "hover" state
_active: {
color: 'link_hovered',
borderColor: 'link_hovered',
bg,
span: {
color: 'link_hovered',
},
_disabled: {
color: 'link_hovered',
borderColor: 'link_hovered',
},
},
// We have a special state for this button variant that serves as a popover trigger.
// When any items (filters) are selected in the popover, the button should change its background and text color.
// The last CSS selector is for redefining styles for the TabList component.
[`
&[data-selected=true],
&[data-selected=true][aria-selected=true]
`]: {
bg: selectedBg,
color: selectedColor,
borderColor: selectedBg,
},
};
});
const variantRadioGroup = defineStyle((props) => {
const outline = runIfFn(variantOutline, props);
const bgColor = mode('blue.50', 'gray.800')(props);
const selectedTextColor = mode('blue.700', 'gray.50')(props);
return {
...outline,
fontWeight: 500,
cursor: 'pointer',
bgColor: 'none',
borderColor: bgColor,
_hover: {
borderColor: bgColor,
color: 'link_hovered',
},
_active: {
bgColor: 'none',
},
_notFirst: {
borderLeftWidth: 0,
},
// We have a special state for this button variant that serves as a popover trigger.
// When any items (filters) are selected in the popover, the button should change its background and text color.
// The last CSS selector is for redefining styles for the TabList component.
[`
&[data-selected=true],
&[data-selected=true][aria-selected=true]
`]: {
cursor: 'initial',
bgColor,
borderColor: bgColor,
color: selectedTextColor,
_hover: {
color: selectedTextColor,
},
},
};
});
const variantSimple = defineStyle((props) => {
const outline = runIfFn(variantOutline, props);
return {
color: outline.color,
_hover: {
color: outline._hover.color,
},
};
});
const variantGhost = defineStyle((props) => {
const { colorScheme: c } = props;
const activeBg = mode(`${ c }.50`, 'gray.800')(props);
return {
bg: 'transparent',
color: mode(`${ c }.700`, 'gray.400')(props),
_active: {
color: mode(`${ c }.700`, 'gray.50')(props),
bg: mode(`${ c }.50`, 'gray.800')(props),
},
_hover: {
color: `${ c }.400`,
_active: {
bg: props.isActive ? activeBg : 'transparent',
color: mode(`${ c }.700`, 'gray.50')(props),
},
},
};
});
const variantSubtle = defineStyle((props) => {
const { colorScheme: c } = props;
if (c === 'gray') {
return {
bg: mode('blackAlpha.200', 'whiteAlpha.200')(props),
color: mode('blackAlpha.800', 'whiteAlpha.800')(props),
_hover: {
color: 'link_hovered',
_disabled: {
color: mode('blackAlpha.800', 'whiteAlpha.800')(props),
bg: mode('blackAlpha.200', 'whiteAlpha.200')(props),
},
},
};
}
return {
bg: `${ c }.100`,
color: `${ c }.600`,
_hover: {
color: 'link_hovered',
},
};
});
// for buttons in the hero banner
const variantHero = defineStyle((props) => {
const buttonConfig = config.UI.homepage.heroBanner?.button;
return {
bg: mode(
buttonConfig?._default?.background?.[0] || 'blue.600',
buttonConfig?._default?.background?.[1] || buttonConfig?._default?.background?.[0] || 'blue.600',
)(props),
color: mode(
buttonConfig?._default?.text_color?.[0] || 'white',
buttonConfig?._default?.text_color?.[1] || buttonConfig?._default?.text_color?.[0] || 'white',
)(props),
_hover: {
bg: mode(
buttonConfig?._hover?.background?.[0] || 'blue.400',
buttonConfig?._hover?.background?.[1] || buttonConfig?._hover?.background?.[0] || 'blue.400',
)(props),
color: mode(
buttonConfig?._hover?.text_color?.[0] || 'white',
buttonConfig?._hover?.text_color?.[1] || buttonConfig?._hover?.text_color?.[0] || 'white',
)(props),
},
'&[data-selected=true]': {
bg: mode(
buttonConfig?._selected?.background?.[0] || 'blue.50',
buttonConfig?._selected?.background?.[1] || buttonConfig?._selected?.background?.[0] || 'blue.50',
)(props),
color: mode(
buttonConfig?._selected?.text_color?.[0] || 'blackAlpha.800',
buttonConfig?._selected?.text_color?.[1] || buttonConfig?._selected?.text_color?.[0] || 'blackAlpha.800',
)(props),
},
};
});
// for buttons in the page header
const variantHeader = defineStyle((props) => {
return {
bgColor: 'transparent',
color: mode('blackAlpha.800', 'gray.400')(props),
borderColor: mode('gray.300', 'gray.600')(props),
borderWidth: props.borderWidth || '2px',
borderStyle: 'solid',
_hover: {
color: 'link_hovered',
borderColor: 'link_hovered',
},
'&[data-selected=true]': {
bgColor: mode('blackAlpha.50', 'whiteAlpha.100')(props),
color: mode('blackAlpha.800', 'whiteAlpha.800')(props),
borderColor: 'transparent',
borderWidth: props.borderWidth || '0px',
},
'&[data-selected=true][data-warning=true]': {
bgColor: mode('orange.100', 'orange.900')(props),
color: mode('blackAlpha.800', 'whiteAlpha.800')(props),
borderColor: 'transparent',
borderWidth: props.borderWidth || '0px',
},
};
});
const variants = {
solid: variantSolid,
outline: variantOutline,
simple: variantSimple,
ghost: variantGhost,
subtle: variantSubtle,
hero: variantHero,
header: variantHeader,
radio_group: variantRadioGroup,
};
const baseStyle = defineStyle({
fontWeight: 600,
borderRadius: 'base',
overflow: 'hidden',
_focusVisible: {
boxShadow: { base: 'none', lg: 'outline' },
},
});
const sizes = {
lg: defineStyle({
h: 12,
minW: 'unset',
fontSize: 'lg',
px: 6,
}),
md: defineStyle({
h: 10,
minW: 'unset',
fontSize: 'md',
px: 4,
}),
sm: defineStyle({
h: 8,
minW: 'unset',
fontSize: 'sm',
px: 3,
}),
xs: defineStyle({
h: 6,
minW: 'unset',
fontSize: 'xs',
px: 2,
}),
};
const Button = defineStyleConfig({
baseStyle,
variants,
sizes,
defaultProps: {
variant: 'solid',
size: 'md',
colorScheme: 'blue',
},
});
export default Button;
import { checkboxAnatomy as parts } from '@chakra-ui/anatomy';
import {
createMultiStyleConfigHelpers,
defineStyle,
cssVar,
} from '@chakra-ui/styled-system';
import { mode } from '@chakra-ui/theme-tools';
import { runIfFn } from '@chakra-ui/utils';
const { definePartsStyle, defineMultiStyleConfig } =
createMultiStyleConfigHelpers(parts.keys);
const $size = cssVar('checkbox-size');
const baseStyleControl = defineStyle((props) => {
const { colorScheme: c } = props;
return {
_checked: {
bg: mode(`${ c }.500`, `${ c }.300`)(props),
borderColor: mode(`${ c }.500`, `${ c }.300`)(props),
_hover: {
bg: mode(`${ c }.600`, `${ c }.400`)(props),
borderColor: mode(`${ c }.600`, `${ c }.400`)(props),
},
},
_indeterminate: {
bg: mode(`${ c }.500`, `${ c }.300`)(props),
borderColor: mode(`${ c }.500`, `${ c }.300`)(props),
},
};
});
const sizes = {
sm: definePartsStyle({
control: { [$size.variable]: 'sizes.3' },
label: { fontSize: 'sm' },
icon: { fontSize: '3xs' },
}),
md: definePartsStyle({
control: { [$size.variable]: 'sizes.4' },
label: { fontSize: 'md' },
icon: { fontSize: '2xs' },
}),
lg: definePartsStyle({
control: { [$size.variable]: 'sizes.5' },
label: { fontSize: 'md' },
icon: { fontSize: '2xs' },
}),
};
const baseStyleLabel = defineStyle({
_disabled: { opacity: 0.2 },
});
const baseStyle = definePartsStyle((props) => ({
label: baseStyleLabel,
control: runIfFn(baseStyleControl, props),
}));
const Checkbox = defineMultiStyleConfig({
baseStyle,
sizes,
});
export default Checkbox;
import { drawerAnatomy as parts } from '@chakra-ui/anatomy';
import {
createMultiStyleConfigHelpers,
defineStyle,
} from '@chakra-ui/styled-system';
import { mode } from '@chakra-ui/theme-tools';
import { runIfFn } from '@chakra-ui/utils';
const { definePartsStyle, defineMultiStyleConfig } =
createMultiStyleConfigHelpers(parts.keys);
import getDefaultTransitionProps from '../utils/getDefaultTransitionProps';
const transitionProps = getDefaultTransitionProps();
const baseStyleOverlay = defineStyle({
...transitionProps,
bg: 'blackAlpha.800',
zIndex: 'overlay',
});
const baseStyleDialog = defineStyle((props) => {
const { isFullHeight } = props;
return {
...(isFullHeight && { height: '100vh' }),
...transitionProps,
zIndex: 'modal',
maxH: '100vh',
bg: mode('white', 'gray.900')(props),
color: 'inherit',
boxShadow: mode('lg', 'dark-lg')(props),
};
});
const baseStyle = definePartsStyle((props) => ({
overlay: baseStyleOverlay,
dialog: runIfFn(baseStyleDialog, props),
}));
const Drawer = defineMultiStyleConfig({
baseStyle,
});
export default Drawer;
const sizes = {
sm: {
field: {
px: '0',
height: '36px',
},
},
md: {
field: {
px: '0',
height: '56px',
},
},
lg: {
field: {
px: '0',
height: '76px',
},
},
};
const FancySelect = {
sizes,
};
export default FancySelect;
import { formAnatomy as parts } from '@chakra-ui/anatomy';
import { createMultiStyleConfigHelpers } from '@chakra-ui/styled-system';
import type { StyleFunctionProps } from '@chakra-ui/theme-tools';
import getFormStyles from '../utils/getFormStyles';
import FancySelect from './FancySelect';
import FormLabel from './FormLabel';
import Input from './Input';
import Textarea from './Textarea';
const { definePartsStyle, defineMultiStyleConfig } =
createMultiStyleConfigHelpers(parts.keys);
function getFloatingVariantStylesForSize(size: 'md' | 'lg', props: StyleFunctionProps) {
const formStyles = getFormStyles(props);
const activeLabelStyles = {
...FormLabel.variants?.floating?.(props)._focusWithin,
...FormLabel.sizes?.[size](props)._focusWithin,
};
const activeInputStyles = (() => {
switch (size) {
case 'md': {
return {
paddingTop: '26px',
paddingBottom: '10px',
};
}
case 'lg': {
return {
paddingTop: '38px',
paddingBottom: '18px',
};
}
}
})();
const inputPx = (() => {
switch (size) {
case 'md': {
return '16px';
}
case 'lg': {
return '24px';
}
}
})();
return {
container: {
// active styles
_focusWithin: {
label: activeLabelStyles,
'input, textarea': activeInputStyles,
},
'&[data-active=true] label': activeLabelStyles,
// label styles
label: FormLabel.sizes?.[size](props) || {},
'input:not(:placeholder-shown) + label, textarea:not(:placeholder-shown) + label': activeLabelStyles,
'textarea:not(:placeholder-shown) + label': {
bgColor: formStyles.input.filled.bgColor,
},
[`
input[readonly] + label,
textarea[readonly] + label,
&[aria-readonly=true] label
`]: {
bgColor: formStyles.input.readOnly.bgColor,
},
[`
input[aria-invalid=true] + label,
textarea[aria-invalid=true] + label,
&[aria-invalid=true] label
`]: {
color: formStyles.placeholder.error.color,
},
[`
input[disabled] + label,
textarea[disabled] + label,
&[aria-disabled=true] label
`]: {
color: formStyles.placeholder.disabled.color,
},
// input styles
input: Input.sizes?.[size].field,
'input[aria-autocomplete=list]': FancySelect.sizes[size].field,
textarea: Textarea.sizes?.[size],
'input, textarea': {
padding: inputPx,
},
'input:not(:placeholder-shown), textarea:not(:placeholder-shown)': activeInputStyles,
// indicator styles
'input:not(:placeholder-shown) + label .chakra-form__required-indicator, textarea:not(:placeholder-shown) + label .chakra-form__required-indicator': {
color: formStyles.placeholder.default.color,
},
[`
input[aria-invalid=true] + label .chakra-form__required-indicator,
textarea[aria-invalid=true] + label .chakra-form__required-indicator,
&[aria-invalid=true] .chakra-form__required-indicator
`]: {
color: formStyles.placeholder.error.color,
},
[`
input[disabled] + label .chakra-form__required-indicator,
textarea[disabled] + label .chakra-form__required-indicator,
&[aria-disabled=true] .chakra-form__required-indicator
`]: {
color: formStyles.placeholder.disabled.color,
},
},
};
}
const baseStyle = definePartsStyle(() => {
return {
requiredIndicator: {
marginStart: 0,
color: 'gray.500',
},
};
});
const variantFloating = definePartsStyle((props) => {
return {
container: {
label: FormLabel.variants?.floating(props) || {},
},
};
});
const sizes = {
lg: definePartsStyle((props) => {
if (props.variant === 'floating') {
return getFloatingVariantStylesForSize('lg', props);
}
return {};
}),
md: definePartsStyle((props) => {
if (props.variant === 'floating') {
return getFloatingVariantStylesForSize('md', props);
}
return {};
}),
};
const variants = {
floating: variantFloating,
};
const Form = defineMultiStyleConfig({
baseStyle,
variants,
sizes,
defaultProps: {
size: 'md',
},
});
export default Form;
import { FormControl, Input, FormLabel } from '@chakra-ui/react';
import React from 'react';
import { test, expect } from 'playwright/lib';
test.use({ viewport: { width: 500, height: 300 } });
test.describe('floating label size md +@dark-mode', () => {
test('empty', async({ render }) => {
const component = await render(
<FormControl variant="floating" id="name" isRequired size="md">
<Input required value=""/>
<FormLabel>Smart contract / Address (0x...)</FormLabel>
</FormControl>,
);
await expect(component).toHaveScreenshot();
await component.locator('input').focus();
await expect(component).toHaveScreenshot();
});
test('empty error', async({ render }) => {
const component = await render(
<FormControl variant="floating" id="name" isRequired size="md">
<Input required value="" isInvalid/>
<FormLabel>Smart contract / Address (0x...)</FormLabel>
</FormControl>,
);
await expect(component).toHaveScreenshot();
await component.locator('input').focus();
await expect(component).toHaveScreenshot();
});
test('filled', async({ render }) => {
const component = await render(
<FormControl variant="floating" id="name" isRequired size="md">
<Input required value="foo"/>
<FormLabel>Smart contract / Address (0x...)</FormLabel>
</FormControl>,
);
await expect(component).toHaveScreenshot();
});
test('filled disabled', async({ render }) => {
const component = await render(
<FormControl variant="floating" id="name" isRequired size="md">
<Input required value="foo" isDisabled/>
<FormLabel>Smart contract / Address (0x...)</FormLabel>
</FormControl>,
);
await expect(component).toHaveScreenshot();
});
test('filled read-only', async({ render }) => {
const component = await render(
<FormControl variant="floating" id="name" isRequired size="md">
<Input required value="foo" isReadOnly/>
<FormLabel>Smart contract / Address (0x...)</FormLabel>
</FormControl>,
);
await expect(component).toHaveScreenshot();
});
test('filled error', async({ render }) => {
const component = await render(
<FormControl variant="floating" id="name" isRequired size="md">
<Input required value="foo" isInvalid/>
<FormLabel>Smart contract / Address (0x...)</FormLabel>
</FormControl>,
);
await expect(component).toHaveScreenshot();
});
});
test.describe('floating label size lg +@dark-mode', () => {
test('empty', async({ render }) => {
const component = await render(
<FormControl variant="floating" id="name" isRequired size="lg">
<Input required value=""/>
<FormLabel>Smart contract / Address (0x...)</FormLabel>
</FormControl>,
);
await expect(component).toHaveScreenshot();
await component.locator('input').focus();
await expect(component).toHaveScreenshot();
});
test('filled', async({ render }) => {
const component = await render(
<FormControl variant="floating" id="name" isRequired size="lg">
<Input required value="foo"/>
<FormLabel>Smart contract / Address (0x...)</FormLabel>
</FormControl>,
);
await expect(component).toHaveScreenshot();
await component.locator('input').focus();
await expect(component).toHaveScreenshot();
});
});
import { defineStyle, defineStyleConfig } from '@chakra-ui/styled-system';
import getFormStyles from '../utils/getFormStyles';
const baseStyle = defineStyle({
display: 'flex',
fontSize: 'md',
marginEnd: '3',
mb: '2',
fontWeight: 'medium',
transitionProperty: 'common',
transitionDuration: 'normal',
opacity: 1,
_disabled: {
opacity: 0.2,
},
});
const variantFloating = defineStyle((props) => {
const formStyles = getFormStyles(props);
return {
left: '2px',
top: '2px',
zIndex: 2,
position: 'absolute',
borderRadius: 'base',
boxSizing: 'border-box',
color: formStyles.placeholder.default.color,
backgroundColor: props.bgColor || props.backgroundColor || 'transparent',
pointerEvents: 'none',
margin: 0,
transformOrigin: 'top left',
transitionProperty: 'font-size, line-height, padding, top, background-color',
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
_focusWithin: {
backgroundColor: props.bgColor || props.backgroundColor || 'transparent',
color: formStyles.placeholder.default.color,
fontSize: 'xs',
lineHeight: '16px',
borderTopRightRadius: 'none',
'& svg': {
width: '16px',
height: '16px',
},
},
'& svg': {
transitionProperty: 'width, height',
transitionDuration: 'normal',
transitionTimingFunction: 'ease',
width: '24px',
height: '24px',
mr: '2',
},
};
});
const variants = {
floating: variantFloating,
};
const sizes = {
lg: defineStyle((props) => {
if (props.variant === 'floating') {
return {
fontSize: 'md',
lineHeight: '24px',
padding: '26px 4px 26px 24px',
right: '22px',
_focusWithin: {
padding: '16px 0 2px 24px',
},
'&[data-fancy=true]': {
right: '36px',
},
};
}
return {};
}),
md: defineStyle((props) => {
if (props.variant === 'floating') {
return {
fontSize: 'md',
lineHeight: '20px',
padding: '18px 4px 18px 16px',
right: '22px',
_focusWithin: {
padding: '10px 0 2px 16px',
},
'&[data-fancy=true]': {
right: '36px',
},
};
}
return {};
}),
};
const FormLabel = defineStyleConfig({
variants,
baseStyle,
sizes,
});
export default FormLabel;
import { defineStyle, defineStyleConfig } from '@chakra-ui/styled-system';
import type { SystemStyleInterpolation } from '@chakra-ui/theme-tools';
import { mode } from '@chakra-ui/theme-tools';
const baseStyle: SystemStyleInterpolation = (props) => {
return {
fontWeight: '500',
color: mode('blackAlpha.800', 'whiteAlpha.800')(props),
};
};
const sizes = {
'2xl': defineStyle({
fontSize: '48px',
lineHeight: '60px',
}),
xl: defineStyle({
fontSize: '40px',
lineHeight: '48px',
}),
lg: defineStyle({
fontSize: '32px',
lineHeight: '40px',
letterSpacing: '-0.5px',
}),
md: defineStyle({
fontSize: '24px',
lineHeight: '32px',
}),
sm: defineStyle({
fontSize: '18px',
lineHeight: '24px',
}),
xs: defineStyle({
fontSize: '14px',
lineHeight: '20px',
}),
};
const Heading = defineStyleConfig({
sizes,
baseStyle,
});
export default Heading;
import { inputAnatomy as parts } from '@chakra-ui/anatomy';
import { Input as InputComponent } from '@chakra-ui/react';
import {
createMultiStyleConfigHelpers,
defineStyle,
} from '@chakra-ui/styled-system';
import { mode } from '@chakra-ui/theme-tools';
const { definePartsStyle, defineMultiStyleConfig } =
createMultiStyleConfigHelpers(parts.keys);
import getDefaultTransitionProps from '../utils/getDefaultTransitionProps';
import getOutlinedFieldStyles from '../utils/getOutlinedFieldStyles';
const size = {
xs: defineStyle({
fontSize: 'md',
lineHeight: '24px',
px: '8px',
py: '4px',
h: '32px',
borderRadius: 'base',
}),
sm: defineStyle({
fontSize: 'md',
lineHeight: '24px',
px: '8px',
py: '12px',
h: '40px',
borderRadius: 'base',
}),
// TEMPORARY INPUT SIZE!!!
// soon we will migrate to the new size and get rid off this one
// lg -> 60
// md -> 48
// sm -> 40
// xs ->32
sm_md: defineStyle({
fontSize: 'md',
lineHeight: '24px',
px: '8px',
py: '12px',
h: '48px',
borderRadius: 'base',
}),
md: defineStyle({
fontSize: 'md',
lineHeight: '20px',
px: '20px',
py: '20px',
h: '60px',
borderRadius: 'base',
}),
lg: defineStyle({
fontSize: 'md',
lineHeight: '20px',
px: '24px',
py: '28px',
h: '80px',
borderRadius: 'base',
}),
};
const variantOutline = definePartsStyle((props) => {
const transitionProps = getDefaultTransitionProps();
return {
field: getOutlinedFieldStyles(props),
addon: {
border: '2px solid',
borderColor: 'transparent',
bg: mode('blackAlpha.100', 'whiteAlpha.200')(props),
color: mode('blackAlpha.800', 'whiteAlpha.800')(props),
...transitionProps,
},
};
});
const sizes = {
xs: definePartsStyle({
field: size.xs,
addon: size.xs,
}),
sm: definePartsStyle({
field: size.sm,
addon: size.sm,
}),
sm_md: definePartsStyle({
field: size.sm_md,
addon: size.sm_md,
}),
md: definePartsStyle({
field: size.md,
addon: size.md,
}),
lg: definePartsStyle({
field: size.lg,
addon: size.lg,
}),
};
const variants = {
outline: variantOutline,
};
const Input = defineMultiStyleConfig({
sizes,
variants,
defaultProps: {
size: 'md',
},
});
InputComponent.defaultProps = {
...InputComponent.defaultProps,
placeholder: ' ',
};
export default Input;
import type { SystemStyleInterpolation } from '@chakra-ui/styled-system';
import { defineStyle, defineStyleConfig } from '@chakra-ui/styled-system';
import { mode } from '@chakra-ui/theme-tools';
import getDefaultTransitionProps from '../utils/getDefaultTransitionProps';
const baseStyle = defineStyle(getDefaultTransitionProps());
const variantPrimary = defineStyle((props) => {
return {
color: 'link',
_hover: {
color: 'link_hovered',
textDecorationStyle: props.textDecorationStyle || 'solid',
},
};
});
const variantSecondary = defineStyle((props) => {
return {
color: mode('gray.600', 'gray.500')(props),
_hover: {
color: mode('gray.600', 'gray.400')(props),
},
};
});
const variants: Record<string, SystemStyleInterpolation> = {
primary: variantPrimary,
secondary: variantSecondary,
};
const defaultProps = {
variant: 'primary',
};
const Link = defineStyleConfig({
variants,
defaultProps,
baseStyle,
});
export default Link;
import { menuAnatomy as parts } from '@chakra-ui/anatomy';
import {
createMultiStyleConfigHelpers,
cssVar,
defineStyle,
} from '@chakra-ui/styled-system';
const { defineMultiStyleConfig, definePartsStyle } =
createMultiStyleConfigHelpers(parts.keys);
const $bg = cssVar('menu-bg');
const $shadow = cssVar('menu-shadow');
const baseStyleList = defineStyle({
[$bg.variable]: '#fff',
[$shadow.variable]: 'shadows.2xl',
_dark: {
[$bg.variable]: 'colors.gray.900',
[$shadow.variable]: 'shadows.dark-lg',
},
borderWidth: '0',
bg: $bg.reference,
boxShadow: $shadow.reference,
});
const baseStyleItem = defineStyle({
_focus: {
[$bg.variable]: 'transparent',
_dark: {
[$bg.variable]: 'transparent',
},
},
_hover: {
[$bg.variable]: 'colors.blue.50',
_dark: {
[$bg.variable]: 'colors.whiteAlpha.100',
},
},
bg: $bg.reference,
});
const baseStyle = definePartsStyle({
list: baseStyleList,
item: baseStyleItem,
});
const Menu = defineMultiStyleConfig({
baseStyle,
});
export default Menu;
import { modalAnatomy as parts } from '@chakra-ui/anatomy';
import { Modal as ModalComponent } from '@chakra-ui/react';
import {
createMultiStyleConfigHelpers,
defineStyle,
} from '@chakra-ui/styled-system';
import { mode } from '@chakra-ui/theme-tools';
import { runIfFn } from '@chakra-ui/utils';
const { defineMultiStyleConfig, definePartsStyle } =
createMultiStyleConfigHelpers(parts.keys);
const baseStyleDialog = defineStyle(() => {
return {
padding: 8,
borderRadius: 'lg',
bg: 'dialog.bg',
margin: 'auto',
};
});
const baseStyleDialogContainer = defineStyle({
'::-webkit-scrollbar': { display: 'none' },
'scrollbar-width': 'none',
// '@supports (height: -webkit-fill-available)': { height: '-webkit-fill-available' },
});
const baseStyleHeader = defineStyle((props) => ({
padding: 0,
marginBottom: 8,
fontSize: '2xl',
lineHeight: 10,
color: mode('blackAlpha.800', 'whiteAlpha.800')(props),
}));
const baseStyleBody = defineStyle({
padding: 0,
marginBottom: 8,
flex: 'initial',
});
const baseStyleFooter = defineStyle({
padding: 0,
justifyContent: 'flex-start',
});
const baseStyleCloseButton = defineStyle((props) => {
return {
top: 8,
right: 8,
height: 10,
width: 10,
color: mode('gray.700', 'gray.500')(props),
_hover: { color: 'link_hovered' },
_active: { bg: 'none' },
};
});
const baseStyleOverlay = defineStyle({
bg: 'blackAlpha.800',
});
const baseStyle = definePartsStyle((props) => ({
dialog: runIfFn(baseStyleDialog),
dialogContainer: baseStyleDialogContainer,
header: runIfFn(baseStyleHeader, props),
body: baseStyleBody,
footer: baseStyleFooter,
closeButton: runIfFn(baseStyleCloseButton, props),
overlay: baseStyleOverlay,
}));
const sizes = {
sm: definePartsStyle({
dialogContainer: {
height: '100%',
},
dialog: {
maxW: '536px',
},
}),
md: definePartsStyle({
dialogContainer: {
height: '100%',
},
dialog: {
maxW: '760px',
},
}),
full: definePartsStyle({
dialogContainer: {
height: '100%',
},
dialog: {
maxW: '100vw',
my: '0',
borderRadius: '0',
padding: '80px 16px 32px 16px',
height: '100%',
overflowY: 'scroll',
},
closeButton: {
top: 4,
right: 6,
width: 6,
height: 6,
},
header: {
mb: 6,
},
}),
};
const Modal = defineMultiStyleConfig({
sizes,
baseStyle,
});
export default Modal;
ModalComponent.defaultProps = {
...ModalComponent.defaultProps,
isCentered: true,
};
import { defineStyle, defineStyleConfig } from '@chakra-ui/styled-system';
import getOutlinedFieldStyles from '../utils/getOutlinedFieldStyles';
const baseStyle = defineStyle({
textAlign: 'center',
bgColor: 'dialog.bg',
});
const sizes = {
md: defineStyle({
fontSize: 'md',
w: 10,
h: 10,
borderRadius: 'md',
}),
};
const variants = {
outline: defineStyle(
(props) => getOutlinedFieldStyles(props),
),
};
const PinInput = defineStyleConfig({
baseStyle,
sizes,
variants,
defaultProps: {
size: 'md',
},
});
export default PinInput;
import { popoverAnatomy as parts } from '@chakra-ui/anatomy';
import {
createMultiStyleConfigHelpers,
defineStyle,
} from '@chakra-ui/styled-system';
import { cssVar, mode } from '@chakra-ui/theme-tools';
const { defineMultiStyleConfig, definePartsStyle } =
createMultiStyleConfigHelpers(parts.keys);
const $popperBg = cssVar('popper-bg');
const $arrowBg = cssVar('popper-arrow-bg');
const $arrowShadowColor = cssVar('popper-arrow-shadow-color');
const baseStylePopper = defineStyle({
zIndex: 'popover',
});
const baseStyleContent = defineStyle((props) => {
const bg = mode('white', 'gray.900')(props);
const shadowColor = mode('blackAlpha.200', 'whiteAlpha.300')(props);
return {
[$popperBg.variable]: `colors.${ bg }`,
bg: $popperBg.reference,
[$arrowBg.variable]: $popperBg.reference,
[$arrowShadowColor.variable]: `colors.${ shadowColor }`,
_dark: {
[$popperBg.variable]: `colors.gray.900`,
[$arrowShadowColor.variable]: `colors.whiteAlpha.300`,
boxShadow: 'dark-lg',
},
width: 'xs',
border: 'none',
borderColor: 'inherit',
borderRadius: 'md',
boxShadow: '2xl',
zIndex: 'inherit',
_focusVisible: {
outline: 0,
boxShadow: '2xl',
},
};
});
const baseStyleHeader = defineStyle({
px: 3,
py: 2,
borderBottomWidth: '1px',
});
const baseStyleBody = defineStyle({
px: 4,
py: 4,
});
const baseStyleFooter = defineStyle({
px: 3,
py: 2,
borderTopWidth: '1px',
});
const baseStyleCloseButton = defineStyle({
position: 'absolute',
borderRadius: 'md',
top: 1,
insetEnd: 2,
padding: 2,
});
const baseStyle = definePartsStyle((props) => ({
popper: baseStylePopper,
content: baseStyleContent(props),
header: baseStyleHeader,
body: baseStyleBody,
footer: baseStyleFooter,
arrow: {},
closeButton: baseStyleCloseButton,
}));
const Popover = defineMultiStyleConfig({
baseStyle,
});
export default Popover;
import { radioAnatomy as parts } from '@chakra-ui/anatomy';
import {
createMultiStyleConfigHelpers,
defineStyle,
} from '@chakra-ui/styled-system';
const { defineMultiStyleConfig, definePartsStyle } =
createMultiStyleConfigHelpers(parts.keys);
const baseStyleLabel = defineStyle({
_disabled: { opacity: 0.2 },
width: 'fit-content',
});
const baseStyleContainer = defineStyle({
width: 'fit-content',
});
const baseStyle = definePartsStyle({
label: baseStyleLabel,
container: baseStyleContainer,
});
const sizes = {
md: definePartsStyle({
control: { w: '4', h: '4' },
label: { fontSize: 'md' },
}),
lg: definePartsStyle({
control: { w: '5', h: '5' },
label: { fontSize: 'md' },
}),
sm: definePartsStyle({
control: { width: '3', height: '3' },
label: { fontSize: 'sm' },
}),
};
const Radio = defineMultiStyleConfig({
baseStyle,
sizes,
});
export default Radio;
import { selectAnatomy as parts } from '@chakra-ui/anatomy';
import {
createMultiStyleConfigHelpers,
defineStyle,
} from '@chakra-ui/styled-system';
import { mode } from '@chakra-ui/theme-tools';
import Input from './Input';
const { defineMultiStyleConfig, definePartsStyle } =
createMultiStyleConfigHelpers(parts.keys);
const variantOutline = definePartsStyle((props) => {
return {
field: {
...Input.variants?.outline(props).field,
borderColor: mode('gray.200', 'gray.600')(props),
_hover: {
borderColor: mode('gray.300', 'gray.500')(props),
},
_focusVisible: {
borderColor: mode('gray.200', 'gray.600')(props),
boxShadow: 'none',
},
cursor: 'pointer',
},
};
});
const iconSpacing = defineStyle({
paddingInlineEnd: '8',
});
const sizes = {
lg: {
...Input.sizes?.lg,
field: {
...Input.sizes?.lg.field,
...iconSpacing,
},
},
md: {
...Input.sizes?.md,
field: {
...Input.sizes?.md.field,
...iconSpacing,
},
},
sm: {
...Input.sizes?.sm,
field: {
...Input.sizes?.sm.field,
...iconSpacing,
},
},
xs: {
...Input.sizes?.xs,
field: {
...Input.sizes?.xs.field,
...iconSpacing,
fontSize: 'sm',
lineHeight: '20px',
},
},
};
const Select = defineMultiStyleConfig({
variants: {
...Input.variants,
outline: variantOutline,
},
sizes,
defaultProps: {
size: 'xs',
},
});
export default Select;
// eslint-disable-next-line no-restricted-imports
import { Skeleton as SkeletonComponent } from '@chakra-ui/react';
import {
defineStyle,
defineStyleConfig,
} from '@chakra-ui/styled-system';
import { keyframes } from '@chakra-ui/system';
import { getColor, mode } from '@chakra-ui/theme-tools';
const shine = () =>
keyframes({
to: { backgroundPositionX: '-200%' },
});
const baseStyle = defineStyle((props) => {
const defaultStartColor = mode('blackAlpha.50', 'whiteAlpha.50')(props);
const defaultEndColor = mode('blackAlpha.100', 'whiteAlpha.100')(props);
const {
startColor = defaultStartColor,
endColor = defaultEndColor,
theme,
} = props;
const start = getColor(theme, startColor);
const end = getColor(theme, endColor);
return {
opacity: 1,
borderRadius: 'md',
borderColor: start,
background: `linear-gradient(90deg, ${ start } 8%, ${ end } 18%, ${ start } 33%)`,
backgroundSize: '200% 100%',
};
});
const Skeleton = defineStyleConfig({
baseStyle,
});
export default Skeleton;
SkeletonComponent.defaultProps = {
...SkeletonComponent.defaultProps,
speed: 1,
animation: `1s linear infinite ${ shine() }`,
};
import { defineStyle, defineStyleConfig } from '@chakra-ui/styled-system';
import { mode } from '@chakra-ui/theme-tools';
const baseStyle = defineStyle((props) => {
const { emptyColor, color } = props;
return {
borderColor: color || 'blue.500',
borderBottomColor: emptyColor || mode('blackAlpha.200', 'whiteAlpha.200')(props),
borderLeftColor: emptyColor || mode('blackAlpha.200', 'whiteAlpha.200')(props),
};
});
const Spinner = defineStyleConfig({
baseStyle,
defaultProps: {
size: 'md',
},
});
export default Spinner;
import { switchAnatomy as parts } from '@chakra-ui/anatomy';
import { defineStyle, createMultiStyleConfigHelpers } from '@chakra-ui/styled-system';
import { mode } from '@chakra-ui/theme-tools';
const { defineMultiStyleConfig, definePartsStyle } =
createMultiStyleConfigHelpers(parts.keys);
const baseStyleTrack = defineStyle((props) => {
const { colorScheme: c } = props;
return {
_checked: {
bg: mode(`${ c }.500`, `${ c }.300`)(props),
_hover: {
bg: mode(`${ c }.600`, `${ c }.400`)(props),
},
},
_focusVisible: {
boxShadow: 'none',
},
};
});
const baseStyle = definePartsStyle((props) => ({
track: baseStyleTrack(props),
}));
const Switch = defineMultiStyleConfig({
baseStyle,
});
export default Switch;
import { tableAnatomy as parts } from '@chakra-ui/anatomy';
import {
createMultiStyleConfigHelpers,
} from '@chakra-ui/styled-system';
import { mode } from '@chakra-ui/theme-tools';
import getDefaultTransitionProps from '../utils/getDefaultTransitionProps';
const { defineMultiStyleConfig, definePartsStyle } =
createMultiStyleConfigHelpers(parts.keys);
const variantSimple = definePartsStyle((props) => {
const transitionProps = getDefaultTransitionProps();
return {
th: {
border: 0,
color: mode('blackAlpha.700', 'whiteAlpha.700')(props),
backgroundColor: mode('blackAlpha.100', 'whiteAlpha.200')(props),
...transitionProps,
},
thead: {
...transitionProps,
},
td: {
borderColor: 'border.divider',
...transitionProps,
},
};
});
const sizes = {
sm: definePartsStyle({
th: {
px: '6px',
py: '10px',
fontSize: 'sm',
_first: {
pl: 3,
},
_last: {
pr: 3,
},
},
td: {
px: '6px',
py: 4,
fontSize: 'sm',
fontWeight: 500,
lineHeight: 5,
_first: {
pl: 3,
},
_last: {
pr: 3,
},
},
}),
};
const variants = {
simple: variantSimple,
};
const baseStyle = definePartsStyle({
th: {
textTransform: 'none',
fontFamily: 'body',
fontWeight: '500',
overflow: 'hidden',
color: 'gray.500',
letterSpacing: 'none',
_first: {
borderTopLeftRadius: '8px',
},
_last: {
borderTopRightRadius: '8px',
},
},
td: {
fontSize: 'md',
verticalAlign: 'top',
},
table: {
tableLayout: 'fixed',
borderTopLeftRadius: 'base',
borderTopRightRadius: 'base',
overflow: 'unset',
fontVariant: 'normal',
fontVariantLigatures: 'no-contextual',
},
});
const Table = defineMultiStyleConfig({
baseStyle,
sizes,
variants,
defaultProps: {
size: 'sm',
variant: 'simple',
},
});
export default Table;
import { tabsAnatomy as parts } from '@chakra-ui/anatomy';
import {
createMultiStyleConfigHelpers,
} from '@chakra-ui/styled-system';
import { mode } from '@chakra-ui/theme-tools';
const { defineMultiStyleConfig, definePartsStyle } =
createMultiStyleConfigHelpers(parts.keys);
import Button from './Button/Button';
const variantSoftRounded = definePartsStyle((props) => {
return {
tab: {
borderRadius: 'base',
fontWeight: '600',
color: mode('blue.700', 'gray.400')(props),
_selected: {
color: mode('blue.700', 'gray.50')(props),
bg: mode('blue.50', 'gray.800')(props),
_hover: {
color: mode('blue.700', 'gray.50')(props),
},
},
_hover: {
color: 'link_hovered',
},
_focusVisible: {
boxShadow: { base: 'none', lg: 'outline' },
},
},
};
});
const variantOutline = definePartsStyle((props) => {
return {
tab: {
...Button.variants?.outline(props),
...Button.baseStyle,
_selected: Button.variants?.outline(props)._active,
},
};
});
const variantRadioGroup = definePartsStyle((props) => {
return {
tab: {
...Button.baseStyle,
...Button.variants?.radio_group(props),
_selected: Button.variants?.radio_group(props)?.[`
&[data-selected=true],
&[data-selected=true][aria-selected=true]
`],
borderRadius: 'none',
'&[role="tab"]': {
_first: {
borderTopLeftRadius: 'base',
borderBottomLeftRadius: 'base',
},
_last: {
borderTopRightRadius: 'base',
borderBottomRightRadius: 'base',
},
},
},
};
});
const sizes = {
sm: definePartsStyle({
tab: Button.sizes?.sm,
}),
md: definePartsStyle({
tab: Button.sizes?.md,
}),
};
const variants = {
'soft-rounded': variantSoftRounded,
outline: variantOutline,
radio_group: variantRadioGroup,
};
const Tabs = defineMultiStyleConfig({
sizes,
variants,
});
export default Tabs;
import { Box, Tag } from '@chakra-ui/react';
import React from 'react';
import { test, expect } from 'playwright/lib';
[ 'blue', 'gray', 'gray-blue', 'orange', 'green', 'purple', 'cyan', 'teal' ].forEach((colorScheme) => {
test(`${ colorScheme } color scheme +@dark-mode`, async({ render }) => {
const component = await render(<Tag colorScheme={ colorScheme }>content</Tag>);
await expect(component.getByText(/content/i)).toHaveScreenshot();
});
});
test('with long text', async({ render }) => {
const component = await render(
<Box w="100px">
<Tag>this is very looooooooooong text</Tag>
</Box>,
);
await expect(component.getByText(/this/i)).toHaveScreenshot();
});
import { tagAnatomy as parts } from '@chakra-ui/anatomy';
import {
createMultiStyleConfigHelpers,
defineStyle,
} from '@chakra-ui/styled-system';
import { mode } from '@chakra-ui/theme-tools';
import getDefaultTransitionProps from '../../utils/getDefaultTransitionProps';
import Badge from '../Badge';
const transitionProps = getDefaultTransitionProps();
const { defineMultiStyleConfig, definePartsStyle } =
createMultiStyleConfigHelpers(parts.keys);
const variants = {
subtle: definePartsStyle((props) => ({
container: Badge.variants?.subtle(props),
})),
select: definePartsStyle((props) => ({
container: {
bg: mode('gray.100', 'gray.800')(props),
color: mode('gray.500', 'whiteAlpha.800')(props),
cursor: 'pointer',
_hover: {
color: 'blue.400',
opacity: 0.76,
},
[`
&[data-selected=true],
&[data-selected=true][aria-selected=true]
`]: {
bg: mode('blue.500', 'blue.900')(props),
color: 'whiteAlpha.800',
},
},
})),
};
const sizes = {
sm: definePartsStyle({
container: {
minH: 6,
minW: 6,
fontSize: 'sm',
px: 1,
py: '2px',
lineHeight: 5,
},
}),
md: definePartsStyle({
container: {
minH: 8,
minW: 8,
fontSize: 'sm',
px: '6px',
py: '6px',
lineHeight: 5,
},
}),
};
const baseStyleContainer = defineStyle({
display: 'inline-block',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
borderRadius: 'sm',
...transitionProps,
});
const baseStyle = definePartsStyle({
container: baseStyleContainer,
});
const Tag = defineMultiStyleConfig({
baseStyle,
variants,
sizes,
defaultProps: {
size: 'sm',
variant: 'subtle',
colorScheme: 'gray',
},
});
export default Tag;
import type { SystemStyleInterpolation } from '@chakra-ui/styled-system';
import { defineStyle, defineStyleConfig } from '@chakra-ui/styled-system';
import { mode } from '@chakra-ui/theme-tools';
const variantPrimary = defineStyle((props) => ({
color: mode('blackAlpha.800', 'whiteAlpha.800')(props),
}));
const variantSecondary = defineStyle((props) => ({
color: mode('gray.500', 'gray.400')(props),
}));
const variantInherit = {
color: 'inherit',
};
const variants: Record<string, SystemStyleInterpolation> = {
primary: variantPrimary,
secondary: variantSecondary,
inherit: variantInherit,
};
const defaultProps = {
variant: 'primary',
};
const Text = defineStyleConfig({
defaultProps,
variants,
});
export default Text;
import { Textarea as TextareaComponent } from '@chakra-ui/react';
import { defineStyle, defineStyleConfig } from '@chakra-ui/styled-system';
import getOutlinedFieldStyles from '../utils/getOutlinedFieldStyles';
const sizes = {
md: defineStyle({
fontSize: 'md',
lineHeight: '20px',
h: '160px',
borderRadius: 'base',
}),
lg: defineStyle({
fontSize: 'md',
lineHeight: '20px',
px: '24px',
py: '28px',
h: '160px',
borderRadius: 'base',
}),
};
const Textarea = defineStyleConfig({
sizes,
variants: {
outline: defineStyle(getOutlinedFieldStyles),
},
defaultProps: {
variant: 'outline',
},
});
TextareaComponent.defaultProps = {
...TextareaComponent.defaultProps,
placeholder: ' ',
};
export default Textarea;
import { Box, Tooltip, Icon } from '@chakra-ui/react';
import React from 'react';
import { test, expect } from 'playwright/lib';
test('base view +@dark-mode', async({ render, page }) => {
const component = await render(
<Box m={ 10 }>
<Tooltip label="Tooltip content">
trigger
</Tooltip>
</Box>,
);
await component.getByText(/trigger/i).hover();
await expect(page).toHaveScreenshot({ clip: { x: 0, y: 40, width: 130, height: 64 } });
});
// was not able to reproduce in tests issue when Icon is used as trigger for tooltip
// https://github.com/chakra-ui/chakra-ui/issues/7107
test.fixme('with icon', async({ render, page }) => {
const component = await render(
<Box m={ 10 }>
<Tooltip label="Tooltip content">
<Icon viewBox="0 0 20 20" boxSize={ 5 } aria-label="Trigger">
<circle cx="10" cy="10" r="10"/>
</Icon>
</Tooltip>
</Box>,
);
const tooltip = page.getByText(/tooltip content/i);
await expect(tooltip).toBeHidden();
await component.locator('svg[aria-label="Trigger"]').hover();
await expect(tooltip).toBeVisible();
});
import { Tooltip as TooltipComponent } from '@chakra-ui/react';
import { defineStyle, defineStyleConfig } from '@chakra-ui/styled-system';
import { mode, cssVar } from '@chakra-ui/theme-tools';
const $bg = cssVar('tooltip-bg');
const $fg = cssVar('tooltip-fg');
const $arrowBg = cssVar('popper-arrow-bg');
const variantNav = defineStyle((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 baseStyle = defineStyle((props) => {
const bg = mode('gray.700', 'gray.200')(props);
const fg = mode('white', 'black')(props);
return {
bg: $bg.reference,
color: $fg.reference,
[$bg.variable]: `colors.${ bg }`,
[$fg.variable]: `colors.${ fg }`,
[$arrowBg.variable]: $bg.reference,
maxWidth: props.maxWidth || props.maxW || 'calc(100vw - 8px)',
marginX: '4px',
};
});
const Tooltip = defineStyleConfig({
variants,
baseStyle,
});
TooltipComponent.defaultProps = { ...TooltipComponent.defaultProps, hasArrow: true };
export default Tooltip;
import Alert from './Alert/Alert';
import Badge from './Badge';
import Button from './Button/Button';
import Checkbox from './Checkbox';
import Drawer from './Drawer';
import Form from './Form';
import FormLabel from './FormLabel';
import Heading from './Heading';
import Input from './Input';
import Link from './Link';
import Menu from './Menu';
import Modal from './Modal';
import PinInput from './PinInput';
import Popover from './Popover';
import Radio from './Radio';
import Select from './Select';
import Skeleton from './Skeleton';
import Spinner from './Spinner';
import Switch from './Switch';
import Table from './Table';
import Tabs from './Tabs';
import Tag from './Tag/Tag';
import Text from './Text';
import Textarea from './Textarea';
import Tooltip from './Tooltip/Tooltip';
const components = {
Alert,
Badge,
Button,
Checkbox,
Drawer,
Heading,
Input,
Form,
FormLabel,
Link,
Menu,
Modal,
PinInput,
Popover,
Radio,
Select,
Skeleton,
Spinner,
Switch,
Tabs,
Table,
Tag,
Text,
Textarea,
Tooltip,
};
export default components;
import { type ThemeConfig } from '@chakra-ui/react';
import appConfig from 'configs/app';
const config: ThemeConfig = {
initialColorMode: appConfig.UI.colorTheme.default?.colorMode ?? 'system',
useSystemColorMode: false,
disableTransitionOnChange: false,
};
export default config;
const borders = {
radii: {
none: '0',
sm: '4px',
base: '8px',
md: '12px',
lg: '16px',
xl: '24px',
full: '9999px',
},
};
export default borders;
const breakpoints = {
// maybe we need them in future
sm: '415px',
// md: '768px',
lg: '1000px',
xl: '1440px',
'2xl': '1920px',
// these breakpoint are needed just to make others work
'3xl': '3000px',
};
export default breakpoints;
const colors = {
green: {
'100': '#C6F6D5',
'400': '#48BB78',
'500': '#38A169',
'600': '#25855A',
},
blue: {
'50': '#EBF8FF',
'100': '#BEE3F8',
'200': '#90CDF4',
'300': '#63B3ED',
'400': '#4299E1',
'500': '#3182CE',
'600': '#2B6CB0',
'700': '#2C5282',
'800': '#2A4365',
'900': '#1A365D',
},
red: {
'500': '#E53E3E',
'100': '#FED7D7',
},
orange: {
'100': '#FEEBCB',
},
gray: {
'50': '#F7FAFC', // <-
'100': '#EDF2F7',
'200': '#E2E8F0',
'300': '#CBD5E0',
'400': '#A0AEC0',
'500': '#718096',
'600': '#4A5568',
'700': '#2D3748',
'800': '#1A202C',
'900': '#171923',
},
black: '#101112',
white: '#ffffff',
blackAlpha: {
'50': 'RGBA(16, 17, 18, 0.04)',
'100': 'RGBA(16, 17, 18, 0.06)',
'200': 'RGBA(16, 17, 18, 0.08)',
'300': 'RGBA(16, 17, 18, 0.16)',
'400': 'RGBA(16, 17, 18, 0.24)',
'500': 'RGBA(16, 17, 18, 0.36)',
'600': 'RGBA(16, 17, 18, 0.48)',
'700': 'RGBA(16, 17, 18, 0.64)',
'800': 'RGBA(16, 17, 18, 0.80)',
'900': 'RGBA(16, 17, 18, 0.92)',
},
github: '#171923',
telegram: '#2775CA',
linkedin: '#1564BA',
discord: '#9747FF',
slack: '#1BA27A',
twitter: '#000000',
opensea: '#2081E2',
facebook: '#4460A0',
medium: '#231F20',
reddit: '#FF4500',
celo: '#FCFF52',
};
export default colors;
import { getCSSVar } from '@chakra-ui/styled-system';
import { mode } from '@chakra-ui/theme-tools';
import type { StyleFunctionProps } from '@chakra-ui/theme-tools';
const scrollbar = (props: StyleFunctionProps) => {
const bgColor = mode('blackAlpha.300', 'whiteAlpha.300')(props);
const resizerUrl = mode('url(/static/resizer_light.png)', 'url(/static/resizer_dark.png)')(props);
return {
'body *::-webkit-scrollbar': {
width: '20px',
},
'body *::-webkit-scrollbar-track': {
backgroundColor: 'transparent',
},
'body *::-webkit-scrollbar-thumb': {
backgroundColor: bgColor,
borderRadius: '20px',
border: `8px solid rgba(0,0,0,0)`,
backgroundClip: 'content-box',
minHeight: '32px',
},
'body *::-webkit-scrollbar-button': {
display: 'none',
},
'body *::-webkit-scrollbar-corner': {
backgroundColor: 'transparent',
},
'body *::-webkit-resizer': {
backgroundImage: resizerUrl,
backgroundSize: '20px',
},
'body *': {
scrollbarWidth: 'thin',
scrollbarColor: `${ getCSSVar(props.theme, 'colors', bgColor) } transparent`,
},
};
};
export default scrollbar;
const semanticTokens = {
colors: {
divider: {
'default': 'blackAlpha.200',
_dark: 'whiteAlpha.200',
},
text: {
'default': 'blackAlpha.800',
_dark: 'whiteAlpha.800',
},
text_secondary: {
'default': 'gray.500',
_dark: 'gray.400',
},
link: {
'default': 'blue.600',
_dark: 'blue.300',
},
link_hovered: {
'default': 'blue.400',
},
icon_link_external: {
'default': 'gray.300',
_dark: 'gray.500',
},
icon_info: {
'default': 'gray.400',
_dark: 'gray.500',
},
error: {
'default': 'red.500',
_dark: 'red.500',
},
dialog_bg: {
'default': 'white',
_dark: 'gray.900',
},
},
shadows: {
action_bar: '0 4px 4px -4px rgb(0 0 0 / 10%), 0 2px 4px -4px rgb(0 0 0 / 6%)',
},
};
export default semanticTokens;
const transitionDuration = {
'ultra-fast': '50ms',
faster: '100ms',
fast: '150ms',
normal: '200ms',
slow: '300ms',
slower: '400ms',
'ultra-slow': '500ms',
};
const transition = {
duration: transitionDuration,
};
export default transition;
import { theme } from '@chakra-ui/react';
import config from 'configs/app';
export const BODY_TYPEFACE = config.UI.fonts.body?.name ?? 'Inter';
export const HEADING_TYPEFACE = config.UI.fonts.heading?.name ?? 'Poppins';
const typography = {
fonts: {
heading: `${ HEADING_TYPEFACE }, ${ theme.fonts.heading }`,
body: `${ BODY_TYPEFACE }, ${ theme.fonts.body }`,
},
textStyles: {
h2: {
fontSize: [ '32px' ],
fontWeight: '500',
lineHeight: '40px',
fontFamily: 'heading',
},
h3: {
fontSize: '24px',
fontWeight: '500',
lineHeight: '32px',
fontFamily: 'heading',
},
h4: {
fontSize: 'md',
fontWeight: '500',
lineHeight: '24px',
fontFamily: 'heading',
},
},
};
export default typography;
const zIndices = {
hide: -1,
auto: 'auto',
base: 0,
docked: 10,
dropdown: 1000,
sticky: 1100,
sticky1: 1101,
sticky2: 1102,
banner: 1200,
overlay: 1300,
modal: 1400,
popover: 1500,
tooltip: 1550, // otherwise tooltips will not be visible in modals
skipLink: 1600,
toast: 1700,
};
export default zIndices;
import type { StyleFunctionProps } from '@chakra-ui/theme-tools';
import { mode } from '@chakra-ui/theme-tools';
import scrollbar from './foundations/scrollbar';
import addressEntity from './globals/address-entity';
import recaptcha from './globals/recaptcha';
import getDefaultTransitionProps from './utils/getDefaultTransitionProps';
const global = (props: StyleFunctionProps) => ({
body: {
bg: mode('white', 'black')(props),
...getDefaultTransitionProps(),
'-webkit-tap-highlight-color': 'transparent',
'font-variant-ligatures': 'no-contextual',
},
mark: {
bgColor: mode('green.100', 'green.800')(props),
color: 'inherit',
},
'svg *::selection': {
color: 'none',
background: 'none',
},
form: {
w: '100%',
},
...scrollbar(props),
...addressEntity(props),
...recaptcha(),
});
export default global;
import { mode } from '@chakra-ui/theme-tools';
import type { StyleFunctionProps } from '@chakra-ui/theme-tools';
const styles = (props: StyleFunctionProps) => {
return {
'.address-entity': {
'&.address-entity_highlighted': {
_before: {
content: `" "`,
position: 'absolute',
py: 1,
pl: 1,
pr: 0,
top: '-5px',
left: '-5px',
width: `100%`,
height: '100%',
borderRadius: 'base',
borderColor: mode('blue.200', 'blue.600')(props),
borderWidth: '1px',
borderStyle: 'dashed',
bgColor: mode('blue.50', 'blue.900')(props),
zIndex: -1,
},
},
},
'.address-entity_no-copy': {
'&.address-entity_highlighted': {
_before: {
pr: 2,
},
},
},
};
};
export default styles;
const styles = () => {
return {
'.grecaptcha-badge': {
visibility: 'hidden',
},
'div:has(div):has(iframe[title="recaptcha challenge expires in two minutes"])': {
'&::after': {
content: `" "`,
display: 'block',
position: 'fixed',
top: 0,
left: 0,
width: '100vw',
height: '100vh',
zIndex: 100000,
bgColor: 'blackAlpha.300',
},
},
};
};
export default styles;
{
"name": "@blockscout/chakra-theme",
"version": "1.32.0",
"main": "./dist/index.js",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/blockscout/frontend.git",
"directory": "theme"
},
"scripts": {
"build": "yarn webpack-cli -c ./webpack.config.js"
},
"devDependencies": {
"typescript": "5.4.2",
"ts-loader": "^9.4.4",
"webpack": "^5.94.0",
"webpack-cli": "^5.1.4",
"tsconfig-paths-webpack-plugin": "^4.1.0"
},
"files": [
"/dist"
]
}
import { extendTheme } from '@chakra-ui/react';
import components from './components/index';
import config from './config';
import borders from './foundations/borders';
import breakpoints from './foundations/breakpoints';
import colors from './foundations/colors';
import semanticTokens from './foundations/semanticTokens';
import transition from './foundations/transition';
import typography from './foundations/typography';
import zIndices from './foundations/zIndices';
import global from './global';
const overrides = {
...typography,
...borders,
colors,
components,
config,
styles: {
global,
},
breakpoints,
transition,
zIndices,
semanticTokens,
};
export default extendTheme(overrides);
{
"extends": "../tsconfig.json",
"compilerOptions": {
"noEmit": false,
"target": "es2016",
"module": "CommonJS",
"moduleResolution": "node",
"paths": {
"nextjs-routes": ["./nextjs/nextjs-routes.d.ts"],
}
},
"include": [
"../types/**/*.ts",
"../configs/app/**/*.ts",
"../global.d.ts",
"./theme.ts",
"./components/**/*.pw.tsx",
],
"tsc-alias": {
"verbose": true,
"resolveFullPaths": true,
}
}
\ No newline at end of file
// TODO @tom2drum remove this
export default function getDefaultTransitionProps(props?: { transitionProperty: string }) {
return {
transitionProperty: `background-color, color, border-color${ props?.transitionProperty ? ', ' + props.transitionProperty : '' }`,
transitionDuration: 'normal',
transitionTimingFunction: 'ease',
};
}
import type { StyleFunctionProps } from '@chakra-ui/theme-tools';
import { mode, transparentize } from '@chakra-ui/theme-tools';
export default function getFormStyles(props: StyleFunctionProps) {
return {
input: {
empty: {
// there is no text in the empty input
// color: ???,
bgColor: props.bgColor || mode('white', 'black')(props),
borderColor: mode('gray.100', 'gray.700')(props),
},
hover: {
color: mode('gray.800', 'gray.50')(props),
bgColor: props.bgColor || mode('white', 'black')(props),
borderColor: mode('gray.200', 'gray.500')(props),
},
focus: {
color: mode('gray.800', 'gray.50')(props),
bgColor: props.bgColor || mode('white', 'black')(props),
borderColor: mode('blue.400', 'blue.400')(props),
},
filled: {
color: mode('gray.800', 'gray.50')(props),
bgColor: props.bgColor || mode('white', 'black')(props),
borderColor: mode('gray.300', 'gray.600')(props),
},
readOnly: {
color: mode('gray.800', 'gray.50')(props),
bgColor: mode('gray.200', 'gray.800')(props),
borderColor: mode('gray.200', 'gray.800')(props),
},
// we use opacity to show the disabled state
disabled: {
opacity: 0.2,
},
error: {
color: mode('gray.800', 'gray.50')(props),
bgColor: props.bgColor || mode('white', 'black')(props),
borderColor: mode('red.500', 'red.500')(props),
},
},
placeholder: {
'default': {
color: mode('gray.500', 'gray.500')(props),
},
disabled: {
color: transparentize('gray.500', 0.2)(props.theme),
},
error: {
color: mode('red.500', 'red.500')(props),
},
},
};
}
import type { StyleFunctionProps } from '@chakra-ui/theme-tools';
import { mode } from '@chakra-ui/theme-tools';
import getDefaultTransitionProps from './getDefaultTransitionProps';
import getFormStyles from './getFormStyles';
export default function getOutlinedFieldStyles(props: StyleFunctionProps) {
const formStyles = getFormStyles(props);
const transitionProps = getDefaultTransitionProps();
return {
border: '2px solid',
// filled input
...formStyles.input.filled,
...transitionProps,
_hover: {
...formStyles.input.hover,
},
_readOnly: {
boxShadow: 'none !important',
userSelect: 'all',
pointerEvents: 'none',
...formStyles.input.readOnly,
_hover: {
...formStyles.input.readOnly,
},
_focus: {
...formStyles.input.readOnly,
},
},
_disabled: {
...formStyles.input.disabled,
cursor: 'not-allowed',
':-webkit-autofill': {
// background color for disabled input which value was selected from browser autocomplete popup
'-webkit-box-shadow': `0 0 0px 1000px ${ mode('rgba(16, 17, 18, 0.08)', 'rgba(255, 255, 255, 0.08)')(props) } inset`,
},
},
_invalid: {
...formStyles.input.error,
boxShadow: `none`,
_placeholder: {
color: formStyles.placeholder.error.color,
},
},
_focusVisible: {
...formStyles.input.focus,
zIndex: 1,
boxShadow: 'md',
},
_placeholder: {
color: formStyles.placeholder.default.color,
},
// not filled input
':placeholder-shown:not(:focus-visible):not(:hover):not([aria-invalid=true]):not([aria-readonly=true])': {
...formStyles.input.empty,
},
// not filled input with type="date"
':not(:placeholder-shown)[value=""]:not(:focus-visible):not(:hover):not([aria-invalid=true]):not([aria-readonly=true])': {
...formStyles.input.empty,
},
':-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' },
};
}
const path = require('path');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const config = {
mode: 'production',
entry: path.resolve(__dirname) + '/theme.ts',
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
plugins: [ new TsconfigPathsPlugin({ configFile: './tsconfig.json' }) ],
},
output: {
filename: 'index.js',
path: path.resolve(__dirname) + '/dist',
library: {
type: 'commonjs',
},
},
optimization: {
minimize: false,
},
};
module.exports = config;
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@discoveryjs/json-ext@^0.5.0":
version "0.5.7"
resolved "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz"
integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
"@jridgewell/gen-mapping@^0.3.5":
version "0.3.5"
resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz"
integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==
dependencies:
"@jridgewell/set-array" "^1.2.1"
"@jridgewell/sourcemap-codec" "^1.4.10"
"@jridgewell/trace-mapping" "^0.3.24"
"@jridgewell/resolve-uri@^3.1.0":
version "3.1.2"
resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz"
integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==
"@jridgewell/set-array@^1.2.1":
version "1.2.1"
resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz"
integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==
"@jridgewell/source-map@^0.3.3":
version "0.3.6"
resolved "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz"
integrity sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==
dependencies:
"@jridgewell/gen-mapping" "^0.3.5"
"@jridgewell/trace-mapping" "^0.3.25"
"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14":
version "1.5.0"
resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz"
integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==
"@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25":
version "0.3.25"
resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz"
integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==
dependencies:
"@jridgewell/resolve-uri" "^3.1.0"
"@jridgewell/sourcemap-codec" "^1.4.14"
"@types/estree@^1.0.5":
version "1.0.5"
resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz"
integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
"@types/json-schema@^7.0.8":
version "7.0.15"
resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz"
integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
"@types/node@*":
version "20.14.11"
resolved "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz"
integrity sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==
dependencies:
undici-types "~5.26.4"
"@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.12.1":
version "1.12.1"
resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz"
integrity sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==
dependencies:
"@webassemblyjs/helper-numbers" "1.11.6"
"@webassemblyjs/helper-wasm-bytecode" "1.11.6"
"@webassemblyjs/floating-point-hex-parser@1.11.6":
version "1.11.6"
resolved "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz"
integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==
"@webassemblyjs/helper-api-error@1.11.6":
version "1.11.6"
resolved "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz"
integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==
"@webassemblyjs/helper-buffer@1.12.1":
version "1.12.1"
resolved "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz"
integrity sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==
"@webassemblyjs/helper-numbers@1.11.6":
version "1.11.6"
resolved "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz"
integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==
dependencies:
"@webassemblyjs/floating-point-hex-parser" "1.11.6"
"@webassemblyjs/helper-api-error" "1.11.6"
"@xtuc/long" "4.2.2"
"@webassemblyjs/helper-wasm-bytecode@1.11.6":
version "1.11.6"
resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz"
integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==
"@webassemblyjs/helper-wasm-section@1.12.1":
version "1.12.1"
resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz"
integrity sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==
dependencies:
"@webassemblyjs/ast" "1.12.1"
"@webassemblyjs/helper-buffer" "1.12.1"
"@webassemblyjs/helper-wasm-bytecode" "1.11.6"
"@webassemblyjs/wasm-gen" "1.12.1"
"@webassemblyjs/ieee754@1.11.6":
version "1.11.6"
resolved "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz"
integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==
dependencies:
"@xtuc/ieee754" "^1.2.0"
"@webassemblyjs/leb128@1.11.6":
version "1.11.6"
resolved "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz"
integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==
dependencies:
"@xtuc/long" "4.2.2"
"@webassemblyjs/utf8@1.11.6":
version "1.11.6"
resolved "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz"
integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==
"@webassemblyjs/wasm-edit@^1.12.1":
version "1.12.1"
resolved "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz"
integrity sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==
dependencies:
"@webassemblyjs/ast" "1.12.1"
"@webassemblyjs/helper-buffer" "1.12.1"
"@webassemblyjs/helper-wasm-bytecode" "1.11.6"
"@webassemblyjs/helper-wasm-section" "1.12.1"
"@webassemblyjs/wasm-gen" "1.12.1"
"@webassemblyjs/wasm-opt" "1.12.1"
"@webassemblyjs/wasm-parser" "1.12.1"
"@webassemblyjs/wast-printer" "1.12.1"
"@webassemblyjs/wasm-gen@1.12.1":
version "1.12.1"
resolved "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz"
integrity sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==
dependencies:
"@webassemblyjs/ast" "1.12.1"
"@webassemblyjs/helper-wasm-bytecode" "1.11.6"
"@webassemblyjs/ieee754" "1.11.6"
"@webassemblyjs/leb128" "1.11.6"
"@webassemblyjs/utf8" "1.11.6"
"@webassemblyjs/wasm-opt@1.12.1":
version "1.12.1"
resolved "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz"
integrity sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==
dependencies:
"@webassemblyjs/ast" "1.12.1"
"@webassemblyjs/helper-buffer" "1.12.1"
"@webassemblyjs/wasm-gen" "1.12.1"
"@webassemblyjs/wasm-parser" "1.12.1"
"@webassemblyjs/wasm-parser@1.12.1", "@webassemblyjs/wasm-parser@^1.12.1":
version "1.12.1"
resolved "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz"
integrity sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==
dependencies:
"@webassemblyjs/ast" "1.12.1"
"@webassemblyjs/helper-api-error" "1.11.6"
"@webassemblyjs/helper-wasm-bytecode" "1.11.6"
"@webassemblyjs/ieee754" "1.11.6"
"@webassemblyjs/leb128" "1.11.6"
"@webassemblyjs/utf8" "1.11.6"
"@webassemblyjs/wast-printer@1.12.1":
version "1.12.1"
resolved "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz"
integrity sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==
dependencies:
"@webassemblyjs/ast" "1.12.1"
"@xtuc/long" "4.2.2"
"@webpack-cli/configtest@^2.1.1":
version "2.1.1"
resolved "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz"
integrity sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==
"@webpack-cli/info@^2.0.2":
version "2.0.2"
resolved "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz"
integrity sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==
"@webpack-cli/serve@^2.0.5":
version "2.0.5"
resolved "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz"
integrity sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==
"@xtuc/ieee754@^1.2.0":
version "1.2.0"
resolved "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz"
integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==
"@xtuc/long@4.2.2":
version "4.2.2"
resolved "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz"
integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
acorn-import-attributes@^1.9.5:
version "1.9.5"
resolved "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz"
integrity sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==
acorn@^8.7.1, acorn@^8.8.2:
version "8.12.1"
resolved "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz"
integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==
ajv-keywords@^3.5.2:
version "3.5.2"
resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz"
integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==
ajv@^6.12.5:
version "6.12.6"
resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz"
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
dependencies:
fast-deep-equal "^3.1.1"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
ansi-styles@^4.1.0:
version "4.3.0"
resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz"
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
dependencies:
color-convert "^2.0.1"
braces@^3.0.3:
version "3.0.3"
resolved "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz"
integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==
dependencies:
fill-range "^7.1.1"
browserslist@^4.21.10:
version "4.23.2"
resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz"
integrity sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==
dependencies:
caniuse-lite "^1.0.30001640"
electron-to-chromium "^1.4.820"
node-releases "^2.0.14"
update-browserslist-db "^1.1.0"
buffer-from@^1.0.0:
version "1.1.2"
resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz"
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
caniuse-lite@^1.0.30001640:
version "1.0.30001643"
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz"
integrity sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg==
chalk@^4.1.0:
version "4.1.2"
resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz"
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
dependencies:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
chrome-trace-event@^1.0.2:
version "1.0.4"
resolved "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz"
integrity sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==
clone-deep@^4.0.1:
version "4.0.1"
resolved "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz"
integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==
dependencies:
is-plain-object "^2.0.4"
kind-of "^6.0.2"
shallow-clone "^3.0.0"
color-convert@^2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz"
integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
dependencies:
color-name "~1.1.4"
color-name@~1.1.4:
version "1.1.4"
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
colorette@^2.0.14:
version "2.0.20"
resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz"
integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==
commander@^10.0.1:
version "10.0.1"
resolved "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz"
integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==
commander@^2.20.0:
version "2.20.3"
resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
cross-spawn@^7.0.3:
version "7.0.6"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f"
integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==
dependencies:
path-key "^3.1.0"
shebang-command "^2.0.0"
which "^2.0.1"
electron-to-chromium@^1.4.820:
version "1.5.0"
resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.0.tgz"
integrity sha512-Vb3xHHYnLseK8vlMJQKJYXJ++t4u1/qJ3vykuVrVjvdiOEhYyT1AuP4x03G8EnPmYvYOhe9T+dADTmthjRQMkA==
enhanced-resolve@^5.0.0, enhanced-resolve@^5.17.1, enhanced-resolve@^5.7.0:
version "5.17.1"
resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz"
integrity sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==
dependencies:
graceful-fs "^4.2.4"
tapable "^2.2.0"
envinfo@^7.7.3:
version "7.13.0"
resolved "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz"
integrity sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==
es-module-lexer@^1.2.1:
version "1.5.4"
resolved "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz"
integrity sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==
escalade@^3.1.2:
version "3.1.2"
resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz"
integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==
eslint-scope@5.1.1:
version "5.1.1"
resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz"
integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
dependencies:
esrecurse "^4.3.0"
estraverse "^4.1.1"
esrecurse@^4.3.0:
version "4.3.0"
resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz"
integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
dependencies:
estraverse "^5.2.0"
estraverse@^4.1.1:
version "4.3.0"
resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz"
integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
estraverse@^5.2.0:
version "5.3.0"
resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz"
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
events@^3.2.0:
version "3.3.0"
resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz"
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
fast-deep-equal@^3.1.1:
version "3.1.3"
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
fast-json-stable-stringify@^2.0.0:
version "2.1.0"
resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz"
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
fastest-levenshtein@^1.0.12:
version "1.0.16"
resolved "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz"
integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==
fill-range@^7.1.1:
version "7.1.1"
resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz"
integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==
dependencies:
to-regex-range "^5.0.1"
find-up@^4.0.0:
version "4.1.0"
resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz"
integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
dependencies:
locate-path "^5.0.0"
path-exists "^4.0.0"
flat@^5.0.2:
version "5.0.2"
resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz"
integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==
function-bind@^1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz"
integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
glob-to-regexp@^0.4.1:
version "0.4.1"
resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz"
integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==
graceful-fs@^4.1.2, graceful-fs@^4.2.11, graceful-fs@^4.2.4:
version "4.2.11"
resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz"
integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
has-flag@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz"
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
hasown@^2.0.2:
version "2.0.2"
resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz"
integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
dependencies:
function-bind "^1.1.2"
import-local@^3.0.2:
version "3.2.0"
resolved "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz"
integrity sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==
dependencies:
pkg-dir "^4.2.0"
resolve-cwd "^3.0.0"
interpret@^3.1.1:
version "3.1.1"
resolved "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz"
integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==
is-core-module@^2.13.0:
version "2.15.0"
resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz"
integrity sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==
dependencies:
hasown "^2.0.2"
is-number@^7.0.0:
version "7.0.0"
resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz"
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
is-plain-object@^2.0.4:
version "2.0.4"
resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz"
integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==
dependencies:
isobject "^3.0.1"
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz"
integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
isobject@^3.0.1:
version "3.0.1"
resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz"
integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==
jest-worker@^27.4.5:
version "27.5.1"
resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz"
integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==
dependencies:
"@types/node" "*"
merge-stream "^2.0.0"
supports-color "^8.0.0"
json-parse-even-better-errors@^2.3.1:
version "2.3.1"
resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz"
integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==
json-schema-traverse@^0.4.1:
version "0.4.1"
resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json5@^2.2.2:
version "2.2.3"
resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz"
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
kind-of@^6.0.2:
version "6.0.3"
resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz"
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
loader-runner@^4.2.0:
version "4.3.0"
resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz"
integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==
locate-path@^5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz"
integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==
dependencies:
p-locate "^4.1.0"
merge-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz"
integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
micromatch@^4.0.0:
version "4.0.8"
resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz"
integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==
dependencies:
braces "^3.0.3"
picomatch "^2.3.1"
mime-db@1.52.0:
version "1.52.0"
resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz"
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
mime-types@^2.1.27:
version "2.1.35"
resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz"
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
dependencies:
mime-db "1.52.0"
minimist@^1.2.6:
version "1.2.8"
resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
neo-async@^2.6.2:
version "2.6.2"
resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz"
integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
node-releases@^2.0.14:
version "2.0.18"
resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz"
integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==
p-limit@^2.2.0:
version "2.3.0"
resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz"
integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
dependencies:
p-try "^2.0.0"
p-locate@^4.1.0:
version "4.1.0"
resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz"
integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==
dependencies:
p-limit "^2.2.0"
p-try@^2.0.0:
version "2.2.0"
resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz"
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
path-exists@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz"
integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
path-key@^3.1.0:
version "3.1.1"
resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz"
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
path-parse@^1.0.7:
version "1.0.7"
resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
picocolors@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz"
integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==
picomatch@^2.3.1:
version "2.3.1"
resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
pkg-dir@^4.2.0:
version "4.2.0"
resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz"
integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==
dependencies:
find-up "^4.0.0"
punycode@^2.1.0:
version "2.3.1"
resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz"
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
randombytes@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz"
integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
dependencies:
safe-buffer "^5.1.0"
rechoir@^0.8.0:
version "0.8.0"
resolved "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz"
integrity sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==
dependencies:
resolve "^1.20.0"
resolve-cwd@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz"
integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==
dependencies:
resolve-from "^5.0.0"
resolve-from@^5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz"
integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
resolve@^1.20.0:
version "1.22.8"
resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz"
integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==
dependencies:
is-core-module "^2.13.0"
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
safe-buffer@^5.1.0:
version "5.2.1"
resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
schema-utils@^3.1.1, schema-utils@^3.2.0:
version "3.3.0"
resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz"
integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==
dependencies:
"@types/json-schema" "^7.0.8"
ajv "^6.12.5"
ajv-keywords "^3.5.2"
semver@^7.3.4:
version "7.6.3"
resolved "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz"
integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==
serialize-javascript@^6.0.1:
version "6.0.2"
resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz"
integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==
dependencies:
randombytes "^2.1.0"
shallow-clone@^3.0.0:
version "3.0.1"
resolved "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz"
integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==
dependencies:
kind-of "^6.0.2"
shebang-command@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz"
integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
dependencies:
shebang-regex "^3.0.0"
shebang-regex@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
source-map-support@~0.5.20:
version "0.5.21"
resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz"
integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==
dependencies:
buffer-from "^1.0.0"
source-map "^0.6.0"
source-map@^0.6.0:
version "0.6.1"
resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
source-map@^0.7.4:
version "0.7.4"
resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz"
integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==
strip-bom@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz"
integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==
supports-color@^7.1.0:
version "7.2.0"
resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz"
integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
dependencies:
has-flag "^4.0.0"
supports-color@^8.0.0:
version "8.1.1"
resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz"
integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
dependencies:
has-flag "^4.0.0"
supports-preserve-symlinks-flag@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
tapable@^2.1.1, tapable@^2.2.0:
version "2.2.1"
resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz"
integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==
terser-webpack-plugin@^5.3.10:
version "5.3.10"
resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz"
integrity sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==
dependencies:
"@jridgewell/trace-mapping" "^0.3.20"
jest-worker "^27.4.5"
schema-utils "^3.1.1"
serialize-javascript "^6.0.1"
terser "^5.26.0"
terser@^5.26.0:
version "5.31.3"
resolved "https://registry.npmjs.org/terser/-/terser-5.31.3.tgz"
integrity sha512-pAfYn3NIZLyZpa83ZKigvj6Rn9c/vd5KfYGX7cN1mnzqgDcxWvrU5ZtAfIKhEXz9nRecw4z3LXkjaq96/qZqAA==
dependencies:
"@jridgewell/source-map" "^0.3.3"
acorn "^8.8.2"
commander "^2.20.0"
source-map-support "~0.5.20"
to-regex-range@^5.0.1:
version "5.0.1"
resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz"
integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
dependencies:
is-number "^7.0.0"
ts-loader@^9.4.4:
version "9.5.1"
resolved "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz"
integrity sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==
dependencies:
chalk "^4.1.0"
enhanced-resolve "^5.0.0"
micromatch "^4.0.0"
semver "^7.3.4"
source-map "^0.7.4"
tsconfig-paths-webpack-plugin@^4.1.0:
version "4.1.0"
resolved "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.1.0.tgz"
integrity sha512-xWFISjviPydmtmgeUAuXp4N1fky+VCtfhOkDUFIv5ea7p4wuTomI4QTrXvFBX2S4jZsmyTSrStQl+E+4w+RzxA==
dependencies:
chalk "^4.1.0"
enhanced-resolve "^5.7.0"
tsconfig-paths "^4.1.2"
tsconfig-paths@^4.1.2:
version "4.2.0"
resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz"
integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==
dependencies:
json5 "^2.2.2"
minimist "^1.2.6"
strip-bom "^3.0.0"
typescript@5.4.2:
version "5.4.2"
resolved "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz"
integrity sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==
undici-types@~5.26.4:
version "5.26.5"
resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz"
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
update-browserslist-db@^1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz"
integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==
dependencies:
escalade "^3.1.2"
picocolors "^1.0.1"
uri-js@^4.2.2:
version "4.4.1"
resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz"
integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
dependencies:
punycode "^2.1.0"
watchpack@^2.4.1:
version "2.4.1"
resolved "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz"
integrity sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==
dependencies:
glob-to-regexp "^0.4.1"
graceful-fs "^4.1.2"
webpack-cli@^5.1.4:
version "5.1.4"
resolved "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz"
integrity sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==
dependencies:
"@discoveryjs/json-ext" "^0.5.0"
"@webpack-cli/configtest" "^2.1.1"
"@webpack-cli/info" "^2.0.2"
"@webpack-cli/serve" "^2.0.5"
colorette "^2.0.14"
commander "^10.0.1"
cross-spawn "^7.0.3"
envinfo "^7.7.3"
fastest-levenshtein "^1.0.12"
import-local "^3.0.2"
interpret "^3.1.1"
rechoir "^0.8.0"
webpack-merge "^5.7.3"
webpack-merge@^5.7.3:
version "5.10.0"
resolved "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz"
integrity sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==
dependencies:
clone-deep "^4.0.1"
flat "^5.0.2"
wildcard "^2.0.0"
webpack-sources@^3.2.3:
version "3.2.3"
resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz"
integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==
webpack@^5.94.0:
version "5.94.0"
resolved "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz"
integrity sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==
dependencies:
"@types/estree" "^1.0.5"
"@webassemblyjs/ast" "^1.12.1"
"@webassemblyjs/wasm-edit" "^1.12.1"
"@webassemblyjs/wasm-parser" "^1.12.1"
acorn "^8.7.1"
acorn-import-attributes "^1.9.5"
browserslist "^4.21.10"
chrome-trace-event "^1.0.2"
enhanced-resolve "^5.17.1"
es-module-lexer "^1.2.1"
eslint-scope "5.1.1"
events "^3.2.0"
glob-to-regexp "^0.4.1"
graceful-fs "^4.2.11"
json-parse-even-better-errors "^2.3.1"
loader-runner "^4.2.0"
mime-types "^2.1.27"
neo-async "^2.6.2"
schema-utils "^3.2.0"
tapable "^2.1.1"
terser-webpack-plugin "^5.3.10"
watchpack "^2.4.1"
webpack-sources "^3.2.3"
which@^2.0.1:
version "2.0.2"
resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz"
integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
dependencies:
isexe "^2.0.0"
wildcard@^2.0.0:
version "2.0.1"
resolved "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz"
integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==
import type { ThemingConfig } from '@chakra-ui/react'; export const zIndex = {
import type { ExcludeUndefined } from 'types/utils';
export const zIndex: ExcludeUndefined<ThemingConfig['tokens']>['zIndex'] = {
hide: { value: -1 }, hide: { value: -1 },
auto: { value: 'auto' }, auto: { value: 'auto' },
base: { value: 0 }, base: { value: 0 },
......
...@@ -60,6 +60,12 @@ export const recipe = defineSlotRecipe({ ...@@ -60,6 +60,12 @@ export const recipe = defineSlotRecipe({
outline: { outline: {
field: selectSlotRecipe.variants?.variant.outline.trigger, field: selectSlotRecipe.variants?.variant.outline.trigger,
}, },
filter: {
field: selectSlotRecipe.variants?.variant.filter.trigger,
},
sort: {
field: selectSlotRecipe.variants?.variant.sort.trigger,
},
}, },
size: { size: {
......
import type { AlertStatus } from '@chakra-ui/react'; import type { AlertProps } from 'toolkit/chakra/alert';
export interface AddressMetadataInfo { export interface AddressMetadataInfo {
addresses: Record<string, { addresses: Record<string, {
...@@ -37,7 +37,7 @@ export interface AddressMetadataTagApi extends Omit<AddressMetadataTag, 'meta'> ...@@ -37,7 +37,7 @@ export interface AddressMetadataTagApi extends Omit<AddressMetadataTag, 'meta'>
data?: string; data?: string;
alertBgColor?: string; alertBgColor?: string;
alertTextColor?: string; alertTextColor?: string;
alertStatus?: AlertStatus; alertStatus?: AlertProps['status'];
} | null; } | null;
} }
......
...@@ -31,7 +31,7 @@ const AddressCsvExportLink = ({ className, address, params, isLoading }: Props) ...@@ -31,7 +31,7 @@ const AddressCsvExportLink = ({ className, address, params, isLoading }: Props)
if (isInitialLoading) { if (isInitialLoading) {
return ( return (
<Flex className={ className } flexShrink={ 0 } alignItems="center"> <Flex className={ className } flexShrink={ 0 } alignItems="center">
<Skeleton boxSize={{ base: 8, lg: 6 }}/> <Skeleton loading boxSize={{ base: 8, lg: 6 }}/>
<Skeleton loading hideBelow="lg" w="112px" h={ 6 } ml={ 1 }/> <Skeleton loading hideBelow="lg" w="112px" h={ 6 } ml={ 1 }/>
</Flex> </Flex>
); );
......
import { Button } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import Skeleton from 'ui/shared/chakra/Skeleton'; import { Button } from 'toolkit/chakra/button';
import { Link } from 'toolkit/chakra/link';
interface Props { interface Props {
isLoading: boolean; isLoading: boolean;
...@@ -12,29 +12,21 @@ interface Props { ...@@ -12,29 +12,21 @@ interface Props {
} }
const ContractDetailsVerificationButton = ({ isLoading, addressHash, isPartiallyVerified }: Props) => { const ContractDetailsVerificationButton = ({ isLoading, addressHash, isPartiallyVerified }: Props) => {
if (isLoading) {
return (
<Skeleton
w="130px"
h={ 8 }
mr={ isPartiallyVerified ? 0 : 3 }
ml={ isPartiallyVerified ? 0 : 'auto' }
borderRadius="base"
flexShrink={ 0 }
/>
);
}
return ( return (
<Button <Link
size="sm"
mr={ isPartiallyVerified ? 0 : 3 }
ml={ isPartiallyVerified ? 0 : 'auto' }
flexShrink={ 0 }
as="a"
href={ route({ pathname: '/address/[hash]/contract-verification', query: { hash: addressHash } }) } href={ route({ pathname: '/address/[hash]/contract-verification', query: { hash: addressHash } }) }
asChild
> >
Verify & publish <Button
</Button> size="sm"
mr={ isPartiallyVerified ? 0 : 3 }
ml={ isPartiallyVerified ? 0 : 'auto' }
flexShrink={ 0 }
loadingSkeleton={ isLoading }
>
Verify & publish
</Button>
</Link>
); );
}; };
......
...@@ -6,7 +6,7 @@ import { test, expect } from 'playwright/lib'; ...@@ -6,7 +6,7 @@ import { test, expect } from 'playwright/lib';
import AddressQrCode from './AddressQrCode'; import AddressQrCode from './AddressQrCode';
test('default view +@mobile +@dark-mode', async({ render, page }) => { test('default view +@mobile +@dark-mode', async({ render, page }) => {
await render(<AddressQrCode address={ addressMock.withoutName }/>); await render(<AddressQrCode hash={ addressMock.withoutName.hash }/>);
await page.getByRole('button', { name: /qr code/i }).click(); await page.getByRole('button', { name: /qr code/i }).click();
await expect(page).toHaveScreenshot(); await expect(page).toHaveScreenshot();
}); });
import {
chakra,
Flex,
Text,
} from '@chakra-ui/react';
import React from 'react';
import { Button } from 'toolkit/chakra/button';
import ColumnFilterWrapper from './ColumnFilterWrapper';
type Props = {
columnName: string;
title: string;
isActive?: boolean;
isFilled?: boolean;
onFilter: () => void;
onReset?: () => void;
onClose?: () => void;
isLoading?: boolean;
className?: string;
children: React.ReactNode;
};
type ContentProps = {
title: string;
isFilled?: boolean;
onFilter: () => void;
onReset?: () => void;
onClose?: () => void;
children: React.ReactNode;
};
const ColumnFilterContent = ({ title, isFilled, onFilter, onReset, onClose, children }: ContentProps) => {
const onFilterClick = React.useCallback(() => {
onClose && onClose();
onFilter();
}, [ onClose, onFilter ]);
return (
<>
<Flex alignItems="center" justifyContent="space-between" mb={ 3 }>
<Text color="text_secondary" fontWeight="600">{ title }</Text>
<Button
variant="link"
onClick={ onReset }
disabled={ !isFilled }
>
Reset
</Button>
</Flex>
{ children }
<Button
disabled={ !isFilled }
mt={ 4 }
onClick={ onFilterClick }
w="fit-content"
>
Filter
</Button>
</>
);
};
const ColumnFilter = ({ columnName, isActive, className, isLoading, ...props }: Props) => {
return (
<ColumnFilterWrapper
isActive={ isActive }
columnName={ columnName }
className={ className }
isLoading={ isLoading }
>
<ColumnFilterContent { ...props }/>
</ColumnFilterWrapper>
);
};
export default chakra(ColumnFilter);
import {
PopoverTrigger,
PopoverContent,
PopoverBody,
useDisclosure,
IconButton,
chakra,
} from '@chakra-ui/react';
import React from 'react';
import Popover from 'ui/shared/chakra/Popover';
import IconSvg from 'ui/shared/IconSvg';
interface Props {
columnName: string;
isActive?: boolean;
isLoading?: boolean;
className?: string;
children: React.ReactNode;
}
const ColumnFilterWrapper = ({ columnName, isActive, className, children, isLoading }: Props) => {
const { isOpen, onToggle, onClose } = useDisclosure();
const child = React.Children.only(children) as React.ReactElement & {
ref?: React.Ref<React.ReactNode>;
};
const modifiedChildren = React.cloneElement(
child,
{ onClose },
);
return (
<Popover isOpen={ isOpen } onClose={ onClose } placement="bottom-start" isLazy lazyBehavior="unmount">
<PopoverTrigger>
<IconButton
onClick={ onToggle }
aria-label={ `filter by ${ columnName }` }
variant="ghost"
w="30px"
h="30px"
icon={ <IconSvg name="filter" w="20px" h="20px"/> }
isActive={ isActive }
isDisabled={ isLoading }
/>
</PopoverTrigger>
<PopoverContent className={ className }>
<PopoverBody px={ 4 } py={ 6 } display="flex" flexDir="column" rowGap={ 5 }>
{ modifiedChildren }
</PopoverBody>
</PopoverContent>
</Popover>
);
};
export default chakra(ColumnFilterWrapper);
...@@ -39,7 +39,8 @@ const TypeFilter = ({ value = [ RESET_VALUE ], handleFilterChange }: Props) => { ...@@ -39,7 +39,8 @@ const TypeFilter = ({ value = [ RESET_VALUE ], handleFilterChange }: Props) => {
const onReset = React.useCallback(() => setCurrentValue([ RESET_VALUE ]), []); const onReset = React.useCallback(() => setCurrentValue([ RESET_VALUE ]), []);
const onFilter = React.useCallback(() => { const onFilter = React.useCallback(() => {
handleFilterChange(FILTER_PARAM, currentValue.filter(item => item !== RESET_VALUE)); const value: Array<AdvancedFilterType> = currentValue.filter(item => item !== RESET_VALUE);
handleFilterChange(FILTER_PARAM, value);
}, [ handleFilterChange, currentValue ]); }, [ handleFilterChange, currentValue ]);
return ( return (
......
import { Image, Center, useColorModeValue } from '@chakra-ui/react'; import { Center } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { Image } from 'toolkit/chakra/image';
interface Props { interface Props {
src: string; src: string;
} }
const BlobDataImage = ({ src }: Props) => { const BlobDataImage = ({ src }: Props) => {
const bgColor = useColorModeValue('blackAlpha.50', 'whiteAlpha.50');
return ( return (
<Center <Center
bgColor={ bgColor } bgColor={{ _light: 'blackAlpha.50', _dark: 'whiteAlpha.50' }}
p={ 4 } p={ 4 }
minH="200px" minH="200px"
w="100%" w="100%"
......
...@@ -84,7 +84,7 @@ const ChainIndicators = () => { ...@@ -84,7 +84,7 @@ const ChainIndicators = () => {
const valueTitle = (() => { const valueTitle = (() => {
if (isPlaceholderData) { if (isPlaceholderData) {
return <Skeleton h="36px" w="215px"/>; return <Skeleton loading h="36px" w="215px"/>;
} }
if (!hasData) { if (!hasData) {
......
...@@ -6,7 +6,7 @@ import { ...@@ -6,7 +6,7 @@ import {
import React from 'react'; import React from 'react';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import Skeleton from 'ui/shared/chakra/Skeleton'; import { Skeleton } from 'toolkit/chakra/skeleton';
import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1'; import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
...@@ -66,11 +66,11 @@ const LatestDepositsItem = ({ l1BlockNumber, l1TxHash, l2TxHash, timestamp, isLo ...@@ -66,11 +66,11 @@ const LatestDepositsItem = ({ l1BlockNumber, l1TxHash, l2TxHash, timestamp, isLo
/> />
</Flex> </Flex>
<Grid gridTemplateColumns="56px auto"> <Grid gridTemplateColumns="56px auto">
<Skeleton isLoaded={ !isLoading } my="5px" w="fit-content"> <Skeleton loading={ isLoading } my="5px" w="fit-content">
L1 txn L1 txn
</Skeleton> </Skeleton>
{ l1TxLink } { l1TxLink }
<Skeleton isLoaded={ !isLoading } my="3px" w="fit-content"> <Skeleton loading={ isLoading } my="3px" w="fit-content">
L2 txn L2 txn
</Skeleton> </Skeleton>
{ l2TxLink } { l2TxLink }
...@@ -82,7 +82,7 @@ const LatestDepositsItem = ({ l1BlockNumber, l1TxHash, l2TxHash, timestamp, isLo ...@@ -82,7 +82,7 @@ const LatestDepositsItem = ({ l1BlockNumber, l1TxHash, l2TxHash, timestamp, isLo
return ( return (
<Grid width="100%" columnGap={ 4 } rowGap={ 2 } templateColumns="max-content max-content auto" w="100%"> <Grid width="100%" columnGap={ 4 } rowGap={ 2 } templateColumns="max-content max-content auto" w="100%">
{ l1BlockLink } { l1BlockLink }
<Skeleton isLoaded={ !isLoading } w="fit-content" h="fit-content" my="5px"> <Skeleton loading={ isLoading } w="fit-content" h="fit-content" my="5px">
L1 txn L1 txn
</Skeleton> </Skeleton>
{ l1TxLink } { l1TxLink }
...@@ -94,7 +94,7 @@ const LatestDepositsItem = ({ l1BlockNumber, l1TxHash, l2TxHash, timestamp, isLo ...@@ -94,7 +94,7 @@ const LatestDepositsItem = ({ l1BlockNumber, l1TxHash, l2TxHash, timestamp, isLo
h="fit-content" h="fit-content"
my="2px" my="2px"
/> />
<Skeleton isLoaded={ !isLoading } w="fit-content" h="fit-content" my="2px"> <Skeleton loading={ isLoading } w="fit-content" h="fit-content" my="2px">
L2 txn L2 txn
</Skeleton> </Skeleton>
{ l2TxLink } { l2TxLink }
......
...@@ -28,7 +28,7 @@ const getTooltipText = (canRate: boolean | undefined) => { ...@@ -28,7 +28,7 @@ const getTooltipText = (canRate: boolean | undefined) => {
const TriggerButton = ( const TriggerButton = (
{ rating, count, fullView, canRate, onClick, ...rest }: Props, { rating, count, fullView, canRate, onClick, ...rest }: Props,
ref: React.ForwardedRef<HTMLDivElement>, ref: React.ForwardedRef<HTMLButtonElement>,
) => { ) => {
const onFocusCapture = usePreventFocusAfterModalClosing(); const onFocusCapture = usePreventFocusAfterModalClosing();
......
...@@ -3,8 +3,8 @@ import { capitalize } from 'es-toolkit'; ...@@ -3,8 +3,8 @@ import { capitalize } from 'es-toolkit';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
import type { TabItemRegular } from 'toolkit/components/AdaptiveTabs/types';
import type { PaginationParams } from 'ui/shared/pagination/types'; import type { PaginationParams } from 'ui/shared/pagination/types';
import type { RoutedTab } from 'ui/shared/Tabs/types';
import config from 'configs/app'; import config from 'configs/app';
import { useAppContext } from 'lib/contexts/app'; import { useAppContext } from 'lib/contexts/app';
...@@ -57,7 +57,7 @@ const BlockPageContent = () => { ...@@ -57,7 +57,7 @@ const BlockPageContent = () => {
(tab === 'withdrawals' && blockWithdrawalsQuery.pagination.isVisible) (tab === 'withdrawals' && blockWithdrawalsQuery.pagination.isVisible)
); );
const tabs: Array<RoutedTab> = React.useMemo(() => ([ const tabs: Array<TabItemRegular> = React.useMemo(() => ([
{ {
id: 'index', id: 'index',
title: 'Details', title: 'Details',
......
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
import type { RoutedTab } from 'ui/shared/Tabs/types'; import type { TabItemRegular } from 'toolkit/components/AdaptiveTabs/types';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import getQueryParamString from 'lib/router/getQueryParamString'; import getQueryParamString from 'lib/router/getQueryParamString';
...@@ -69,7 +69,7 @@ const BlocksPageContent = () => { ...@@ -69,7 +69,7 @@ const BlocksPageContent = () => {
return blocksQuery.pagination; return blocksQuery.pagination;
})(); })();
const tabs: Array<RoutedTab> = [ const tabs: Array<TabItemRegular> = [
{ id: 'blocks', title: 'All', component: <BlocksContent type="block" query={ blocksQuery }/> }, { id: 'blocks', title: 'All', component: <BlocksContent type="block" query={ blocksQuery }/> },
{ id: 'reorgs', title: 'Forked', component: <BlocksContent type="reorg" query={ reorgsQuery }/> }, { id: 'reorgs', title: 'Forked', component: <BlocksContent type="reorg" query={ reorgsQuery }/> },
{ id: 'uncles', title: 'Uncles', component: <BlocksContent type="uncle" query={ unclesQuery }/> }, { id: 'uncles', title: 'Uncles', component: <BlocksContent type="uncle" query={ unclesQuery }/> },
......
import React from 'react'; import React from 'react';
import type { RoutedTab } from 'ui/shared/Tabs/types'; import type { TabItemRegular } from 'toolkit/components/AdaptiveTabs/types';
import RoutedTabs from 'toolkit/components/RoutedTabs/RoutedTabs'; import RoutedTabs from 'toolkit/components/RoutedTabs/RoutedTabs';
import PrivateAddressTags from 'ui/privateTags/PrivateAddressTags'; import PrivateAddressTags from 'ui/privateTags/PrivateAddressTags';
...@@ -8,7 +8,7 @@ import PrivateTransactionTags from 'ui/privateTags/PrivateTransactionTags'; ...@@ -8,7 +8,7 @@ import PrivateTransactionTags from 'ui/privateTags/PrivateTransactionTags';
import PageTitle from 'ui/shared/Page/PageTitle'; import PageTitle from 'ui/shared/Page/PageTitle';
import useRedirectForInvalidAuthToken from 'ui/snippets/auth/useRedirectForInvalidAuthToken'; import useRedirectForInvalidAuthToken from 'ui/snippets/auth/useRedirectForInvalidAuthToken';
const TABS: Array<RoutedTab> = [ const TABS: Array<TabItemRegular> = [
{ id: 'address', title: 'Address', component: <PrivateAddressTags/> }, { id: 'address', title: 'Address', component: <PrivateAddressTags/> },
{ id: 'tx', title: 'Transaction', component: <PrivateTransactionTags/> }, { id: 'tx', title: 'Transaction', component: <PrivateTransactionTags/> },
]; ];
......
...@@ -3,7 +3,7 @@ import { capitalize } from 'es-toolkit'; ...@@ -3,7 +3,7 @@ import { capitalize } from 'es-toolkit';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
import type { RoutedTab } from 'ui/shared/Tabs/types'; import type { TabItemRegular } from 'toolkit/components/AdaptiveTabs/types';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
...@@ -95,7 +95,7 @@ const Transactions = () => { ...@@ -95,7 +95,7 @@ const Transactions = () => {
const isAuth = useIsAuth(); const isAuth = useIsAuth();
const tabs: Array<RoutedTab> = [ const tabs: Array<TabItemRegular> = [
{ {
id: 'validated', id: 'validated',
title: verifiedTitle, title: verifiedTitle,
......
import { Box, Button, Flex, Grid, GridItem, useColorModeValue } from '@chakra-ui/react'; import { Box, Flex, Grid, GridItem } from '@chakra-ui/react';
import { pickBy } from 'es-toolkit'; import { pickBy } from 'es-toolkit';
import React from 'react'; import React from 'react';
...@@ -7,17 +7,18 @@ import type { FormSubmitResultGrouped } from '../types'; ...@@ -7,17 +7,18 @@ import type { FormSubmitResultGrouped } from '../types';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import { Button } from 'toolkit/chakra/button';
import { Link } from 'toolkit/chakra/link';
import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import EntityTag from 'ui/shared/EntityTags/EntityTag'; import EntityTag from 'ui/shared/EntityTags/EntityTag';
interface Props { interface Props {
data: FormSubmitResultGrouped; data: FormSubmitResultGrouped;
} }
const PublicTagsSubmitResultWithErrors = ({ data }: Props) => { const PublicTagsSubmitResultWithErrors = ({ data }: Props) => {
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const bgColorSuccess = useColorModeValue('green.50', 'green.800'); const bgColorSuccess = { _light: 'green.50', _dark: 'green.800' };
const bgColorError = useColorModeValue('red.50', 'red.800'); const bgColorError = { _light: 'red.50', _dark: 'red.800' };
return ( return (
<Flex flexDir="column" rowGap={ 3 }> <Flex flexDir="column" rowGap={ 3 }>
...@@ -68,18 +69,21 @@ const PublicTagsSubmitResultWithErrors = ({ data }: Props) => { ...@@ -68,18 +69,21 @@ const PublicTagsSubmitResultWithErrors = ({ data }: Props) => {
{ item.error && <Box color="red.500" mt={ 1 } fontSize="sm">{ item.error }</Box> } { item.error && <Box color="red.500" mt={ 1 } fontSize="sm">{ item.error }</Box> }
</Box> </Box>
{ item.error && ( { item.error && (
<Button <Link
variant="outline"
size="sm"
flexShrink={ 0 }
mt={{ base: 1, lg: 6 }}
ml={{ base: 0, lg: 6 }}
w="min-content"
as="a"
href={ route({ pathname: '/public-tags/submit', query: startOverButtonQuery }) } href={ route({ pathname: '/public-tags/submit', query: startOverButtonQuery }) }
asChild
> >
Start over <Button
</Button> variant="outline"
size="sm"
flexShrink={ 0 }
mt={{ base: 1, lg: 6 }}
ml={{ base: 0, lg: 6 }}
w="min-content"
>
Start over
</Button>
</Link>
) } ) }
{ !item.error && !isMobile && <Box w="95px" ml={ 6 } flexShrink={ 0 }/> } { !item.error && !isMobile && <Box w="95px" ml={ 6 } flexShrink={ 0 }/> }
</Flex> </Flex>
......
import { Box, Tooltip, chakra } from '@chakra-ui/react'; import { Box, chakra } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { Tooltip } from 'toolkit/chakra/tooltip';
import IconSvg from './IconSvg'; import IconSvg from './IconSvg';
type Props = { type Props = {
...@@ -10,7 +12,7 @@ type Props = { ...@@ -10,7 +12,7 @@ type Props = {
const ContractCertifiedLabel = ({ iconSize, className }: Props) => { const ContractCertifiedLabel = ({ iconSize, className }: Props) => {
return ( return (
<Tooltip label="This contract has been certified by the chain developers"> <Tooltip content="This contract has been certified by the chain developers">
<Box className={ className }> <Box className={ className }>
<IconSvg name="certified" color="green.500" boxSize={ iconSize } cursor="pointer"/> <IconSvg name="certified" color="green.500" boxSize={ iconSize } cursor="pointer"/>
</Box> </Box>
......
...@@ -10,7 +10,7 @@ const Identicon = dynamic<{ bg: string; string: string; size: number }>( ...@@ -10,7 +10,7 @@ const Identicon = dynamic<{ bg: string; string: string; size: number }>(
return typeof lib === 'object' && 'default' in lib ? lib.default : lib; return typeof lib === 'object' && 'default' in lib ? lib.default : lib;
}, },
{ {
loading: () => <Skeleton w="100%" h="100%"/>, loading: () => <Skeleton loading w="100%" h="100%"/>,
ssr: false, ssr: false,
}, },
); );
......
...@@ -35,7 +35,7 @@ const DefaultView = () => { ...@@ -35,7 +35,7 @@ const DefaultView = () => {
<IconSvg name="certified" color="green.500" boxSize={ 6 } cursor="pointer"/> <IconSvg name="certified" color="green.500" boxSize={ 6 } cursor="pointer"/>
<EntityTags <EntityTags
tags={ [ tags={ [
{ slug: 'example', name: 'Example label', tagType: 'custom' }, { slug: 'example', name: 'Example label', tagType: 'custom', ordinal: 0 },
] } ] }
flexGrow={ 1 } flexGrow={ 1 }
/> />
......
...@@ -30,14 +30,14 @@ const LongNameAndManyTags = () => { ...@@ -30,14 +30,14 @@ const LongNameAndManyTags = () => {
<IconSvg name="certified" color="green.500" boxSize={ 6 } cursor="pointer" flexShrink={ 0 }/> <IconSvg name="certified" color="green.500" boxSize={ 6 } cursor="pointer" flexShrink={ 0 }/>
<EntityTags <EntityTags
tags={ [ tags={ [
{ slug: 'example', name: 'Example with long name', tagType: 'custom' }, { slug: 'example', name: 'Example with long name', tagType: 'custom', ordinal: 0 },
...formatUserTags({ ...formatUserTags({
private_tags: [ privateTag ], private_tags: [ privateTag ],
public_tags: [ publicTag ], public_tags: [ publicTag ],
watchlist_names: [ watchlistName ], watchlist_names: [ watchlistName ],
}), }),
{ slug: 'after_1', name: 'Another tag', tagType: 'custom' }, { slug: 'after_1', name: 'Another tag', tagType: 'custom', ordinal: 0 },
{ slug: 'after_2', name: 'And yet more', tagType: 'custom' }, { slug: 'after_2', name: 'And yet more', tagType: 'custom', ordinal: 0 },
] } ] }
flexGrow={ 1 } flexGrow={ 1 }
/> />
......
import React from 'react'; import React from 'react';
import Tag from 'ui/shared/chakra/Tag'; import { Badge } from 'toolkit/chakra/badge';
import PageTitle from '../PageTitle'; import PageTitle from '../PageTitle';
...@@ -14,7 +14,7 @@ const WithTextAd = () => { ...@@ -14,7 +14,7 @@ const WithTextAd = () => {
<PageTitle <PageTitle
title="Block" title="Block"
backLink={ backLink } backLink={ backLink }
contentAfter={ <Tag key="custom" colorScheme="orange" variant="solid">Awesome</Tag> } contentAfter={ <Badge key="custom" colorPalette="orange" variant="solid">Awesome</Badge> }
withTextAd withTextAd
/> />
); );
......
import type { HTMLChakraProps } from '@chakra-ui/react';
import { chakra } from '@chakra-ui/react'; import { chakra } from '@chakra-ui/react';
import type { StyleProps } from '@chakra-ui/styled-system';
import React from 'react'; import React from 'react';
const TextSeparator = ({ id, ...props }: StyleProps & { id?: string }) => { const TextSeparator = ({ id, ...props }: HTMLChakraProps<'span'> & { id?: string }) => {
return <chakra.span mx={ 3 } id={ id } { ...props }>|</chakra.span>; return <chakra.span mx={ 3 } id={ id } { ...props }>|</chakra.span>;
}; };
......
...@@ -61,7 +61,7 @@ const TokenTransferListItem = ({ ...@@ -61,7 +61,7 @@ const TokenTransferListItem = ({
<Badge flexShrink={ 0 } loading={ isLoading }>{ getTokenTypeName(token.type) }</Badge> <Badge flexShrink={ 0 } loading={ isLoading }>{ getTokenTypeName(token.type) }</Badge>
</> </>
) } ) }
<Badge colorScheme="orange" loading={ isLoading }>{ getTokenTransferTypeText(type) }</Badge> <Badge colorPalette="orange" loading={ isLoading }>{ getTokenTransferTypeText(type) }</Badge>
</Flex> </Flex>
{ showTxInfo && txHash && ( { showTxInfo && txHash && (
<TxAdditionalInfo hash={ txHash } isMobile isLoading={ isLoading }/> <TxAdditionalInfo hash={ txHash } isMobile isLoading={ isLoading }/>
......
...@@ -66,7 +66,7 @@ const TokenTransferTableItem = ({ ...@@ -66,7 +66,7 @@ const TokenTransferTableItem = ({
/> />
<Flex columnGap={ 2 } rowGap={ 2 } mt={ 2 } flexWrap="wrap"> <Flex columnGap={ 2 } rowGap={ 2 } mt={ 2 } flexWrap="wrap">
<Badge loading={ isLoading }>{ getTokenTypeName(token.type) }</Badge> <Badge loading={ isLoading }>{ getTokenTypeName(token.type) }</Badge>
<Badge colorScheme="orange" loading={ isLoading }>{ getTokenTransferTypeText(type) }</Badge> <Badge colorPalette="orange" loading={ isLoading }>{ getTokenTransferTypeText(type) }</Badge>
</Flex> </Flex>
</> </>
) : 'N/A' } ) : 'N/A' }
......
...@@ -40,7 +40,7 @@ const init = () => { ...@@ -40,7 +40,7 @@ const init = () => {
'--w3m-font-family': `${ BODY_TYPEFACE }, sans-serif`, '--w3m-font-family': `${ BODY_TYPEFACE }, sans-serif`,
'--w3m-accent': colors.blue[600].value, '--w3m-accent': colors.blue[600].value,
'--w3m-border-radius-master': '2px', '--w3m-border-radius-master': '2px',
'--w3m-z-index': zIndex.popover.value, '--w3m-z-index': zIndex?.popover?.value,
}, },
featuredWalletIds: [], featuredWalletIds: [],
allowUnsupportedChain: true, allowUnsupportedChain: true,
......
...@@ -4,6 +4,7 @@ import React from 'react'; ...@@ -4,6 +4,7 @@ import React from 'react';
import { test, expect } from 'playwright/lib'; import { test, expect } from 'playwright/lib';
import AddressFromToIcon from './AddressFromToIcon'; import AddressFromToIcon from './AddressFromToIcon';
import type { TxCourseType } from './utils';
test.use({ viewport: { width: 36, height: 36 } }); test.use({ viewport: { width: 36, height: 36 } });
...@@ -11,7 +12,7 @@ test.use({ viewport: { width: 36, height: 36 } }); ...@@ -11,7 +12,7 @@ test.use({ viewport: { width: 36, height: 36 } });
test(`${ type } txn type +@dark-mode`, async({ render }) => { test(`${ type } txn type +@dark-mode`, async({ render }) => {
const component = await render( const component = await render(
<Box p={ 2 }> <Box p={ 2 }>
<AddressFromToIcon type={ type }/> <AddressFromToIcon type={ type as TxCourseType }/>
</Box>, </Box>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
......
import { useColorModeValue, useToken, chakra } from '@chakra-ui/react'; import { useToken, chakra } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { useColorModeValue } from 'toolkit/chakra/color-mode';
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
const d = 'M2 87.8491C2 87.8491 33.0576 108.005 66.5621 87.8491C100.067 67.693 104.693 112.847 115.444 112.847C126.196 112.847 127.564 -14.2956 150.132 4.10659C172.701 22.5087 204.973 118.132 231.009 87.8491C257.044 57.5664 282.524 27.2837 300.355 57.5664C318.185 87.8491 419.225 111.026 439.651 57.5664C460.077 4.10659 479.504 244.505 516.708 244.505C553.911 244.505 560.47 122.168 589.929 144.014C619.388 165.861 604.48 198.172 633.774 198.172C663.068 198.172 704.562 89 704.562 89'; const d = 'M2 87.8491C2 87.8491 33.0576 108.005 66.5621 87.8491C100.067 67.693 104.693 112.847 115.444 112.847C126.196 112.847 127.564 -14.2956 150.132 4.10659C172.701 22.5087 204.973 118.132 231.009 87.8491C257.044 57.5664 282.524 27.2837 300.355 57.5664C318.185 87.8491 419.225 111.026 439.651 57.5664C460.077 4.10659 479.504 244.505 516.708 244.505C553.911 244.505 560.47 122.168 589.929 144.014C619.388 165.861 604.48 198.172 633.774 198.172C663.068 198.172 704.562 89 704.562 89';
const INCREMENT = 3; const INCREMENT = 3;
...@@ -10,9 +12,9 @@ const ChartLineLoader = ({ className }: { className?: string }) => { ...@@ -10,9 +12,9 @@ const ChartLineLoader = ({ className }: { className?: string }) => {
const raf = React.useRef<number>(); const raf = React.useRef<number>();
const offset = React.useRef(0); const offset = React.useRef(0);
const lineBgColor = useToken('colors', useColorModeValue('gray.200', 'gray.500')); const [ lineBgColor ] = useToken('colors', useColorModeValue('gray.200', 'gray.500'));
const lineFgColor = useToken('colors', useColorModeValue('gray.400', 'gray.300')); const [ lineFgColor ] = useToken('colors', useColorModeValue('gray.400', 'gray.300'));
const gradientStopColor = useToken('colors', useColorModeValue('whiteAlpha.200', 'blackAlpha.100')); const [ gradientStopColor ] = useToken('colors', useColorModeValue('whiteAlpha.200', 'blackAlpha.100'));
React.useEffect(() => { React.useEffect(() => {
const length = ref.current?.getTotalLength() || 0; const length = ref.current?.getTotalLength() || 0;
......
...@@ -17,7 +17,7 @@ interface Props { ...@@ -17,7 +17,7 @@ interface Props {
} }
const ChartSelectionX = ({ anchorEl, height, scale, data, onSelect }: Props) => { const ChartSelectionX = ({ anchorEl, height, scale, data, onSelect }: Props) => {
const borderColor = useToken('colors', 'blue.200'); const [ borderColor ] = useToken('colors', 'blue.200');
const ref = React.useRef(null); const ref = React.useRef(null);
const isActive = React.useRef(false); const isActive = React.useRef(false);
......
import { useToken, useColorModeValue } from '@chakra-ui/react'; import { useToken } from '@chakra-ui/react';
import * as d3 from 'd3'; import * as d3 from 'd3';
import React from 'react'; import React from 'react';
import { useColorModeValue } from 'toolkit/chakra/color-mode';
interface Props { interface Props {
limits: [[number, number], [number, number]]; limits: [[number, number], [number, number]];
anchor: SVGSVGElement | null; anchor: SVGSVGElement | null;
...@@ -10,7 +12,7 @@ interface Props { ...@@ -10,7 +12,7 @@ interface Props {
export default function useBrushX({ limits, anchor, setRange }: Props) { export default function useBrushX({ limits, anchor, setRange }: Props) {
const brushRef = React.useRef<d3.BrushBehavior<unknown>>(); const brushRef = React.useRef<d3.BrushBehavior<unknown>>();
const brushSelectionBg = useToken('colors', useColorModeValue('blackAlpha.400', 'whiteAlpha.500')); const [ brushSelectionBg ] = useToken('colors', useColorModeValue('blackAlpha.400', 'whiteAlpha.500'));
React.useEffect(() => { React.useEffect(() => {
if (!anchor || brushRef.current || limits[1][0] === 0) { if (!anchor || brushRef.current || limits[1][0] === 0) {
......
import { PopoverTrigger, chakra, useDisclosure, useRadioGroup } from '@chakra-ui/react';
import React from 'react';
import type { SelectOption } from './types';
import Popover from 'ui/shared/chakra/Popover';
import SelectButton from './SelectButton';
import SelectContent from './SelectContent';
interface InjectedProps<Value extends string> {
isOpen: boolean;
onToggle: () => void;
value: Value;
}
export interface Props<Value extends string> {
className?: string;
isLoading?: boolean;
options: Array<SelectOption<Value>>;
name: string;
defaultValue?: Value;
onChange: (value: Value) => void;
children?: (props: InjectedProps<Value>) => React.ReactNode;
}
// TODO @tom2drum remove this component
const Select = <Value extends string>({ className, isLoading, options, name, defaultValue, onChange, children }: Props<Value>) => {
const { isOpen, onToggle, onClose } = useDisclosure();
const handleChange = React.useCallback((value: Value) => {
onChange(value);
onClose();
}, [ onChange, onClose ]);
const { value, getRootProps, getRadioProps, setValue } = useRadioGroup({
name,
defaultValue,
onChange: handleChange,
});
React.useEffect(() => {
if (defaultValue) {
setValue(defaultValue);
}
}, [ defaultValue, setValue ]);
return (
<Popover isOpen={ isOpen } onClose={ onClose } placement="bottom-start" isLazy>
<PopoverTrigger>
{ children?.({ isOpen, onToggle, value: value as Value }) || (
<SelectButton
className={ className }
onClick={ onToggle }
isOpen={ isOpen }
isLoading={ isLoading }
label={ options.find((option) => option.value === value)?.label || String(value) }
/>
) }
</PopoverTrigger>
<SelectContent options={ options } getRootProps={ getRootProps } getRadioProps={ getRadioProps } value={ value }/>
</Popover>
);
};
export default React.memo(chakra(Select));
import { Box, Button } from '@chakra-ui/react';
import React from 'react';
import Skeleton from 'ui/shared/chakra/Skeleton';
import IconSvg from 'ui/shared/IconSvg';
interface Props {
className?: string;
onClick: () => void;
isOpen: boolean;
isLoading?: boolean;
label: string;
}
const SelectButton = ({ className, onClick, isOpen, isLoading, label }: Props, ref: React.Ref<HTMLButtonElement>) => {
if (isLoading) {
return <Skeleton className={ className } h={ 8 } borderRadius="base" flexShrink={ 0 }/>;
}
return (
<Button
ref={ ref }
className={ className }
variant="outline"
size="sm"
colorScheme="gray"
fontWeight="500"
lineHeight={ 5 }
display="flex"
alignItems="center"
justifyContent="space-between"
columnGap={ 1 }
onClick={ onClick }
isActive={ isOpen }
pl={ 2 }
pr={ 1 }
py={ 1 }
flexShrink={ 0 }
>
<Box maxW="calc(100% - 20px)" overflow="hidden" textOverflow="ellipsis">{ label }</Box>
<IconSvg name="arrows/east-mini" boxSize={ 5 } transform={ isOpen ? 'rotate(90deg)' : 'rotate(-90deg)' } flexShrink={ 0 }/>
</Button>
);
};
export default React.forwardRef(SelectButton);
import type { useRadioGroup } from '@chakra-ui/react';
import { PopoverBody, PopoverContent } from '@chakra-ui/react';
import React from 'react';
import type { SelectOption as TSelectOption } from './types';
import SelectOption from './SelectOption';
interface Props {
options: Array<TSelectOption>;
getRootProps: ReturnType<typeof useRadioGroup>['getRootProps'];
getRadioProps: ReturnType<typeof useRadioGroup>['getRadioProps'];
value: string | number;
}
const SelectContent = ({ options, getRootProps, getRadioProps, value }: Props) => {
const root = getRootProps();
return (
<PopoverContent w="fit-content" minW="150px">
<PopoverBody { ...root } py={ 2 } px={ 0 } display="flex" flexDir="column">
{ options.map((option) => {
const radio = getRadioProps({ value: option.value });
return (
<SelectOption key={ option.value } { ...radio } isChecked={ radio.isChecked || (!option.value && !value) }>
{ option.label }
</SelectOption>
);
}) }
</PopoverBody>
</PopoverContent>
);
};
export default React.memo(SelectContent);
import type { UseRadioProps } from '@chakra-ui/react';
import { Box, useRadio, useColorModeValue } from '@chakra-ui/react';
import React from 'react';
import IconSvg from '../IconSvg';
interface Props extends UseRadioProps {
children: React.ReactNode;
}
const SelectOption = (props: Props) => {
const { getInputProps, getRadioProps } = useRadio(props);
const input = getInputProps();
const checkbox = getRadioProps();
const bgColorHover = useColorModeValue('blue.50', 'whiteAlpha.100');
return (
<Box
as="label"
px={ 4 }
py={ 2 }
cursor="pointer"
display="flex"
columnGap={ 2 }
alignItems="center"
_hover={{
bgColor: bgColorHover,
}}
>
{ props.isChecked ? <IconSvg name="check" boxSize={ 5 }/> : <Box boxSize={ 5 }/> }
<input { ...input }/>
<Box { ...checkbox }>
{ props.children }
</Box>
</Box>
);
};
export default React.memo(SelectOption);
import { Box, Button, useDisclosure } from '@chakra-ui/react'; import { Box } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { Button } from 'toolkit/chakra/button';
import { useDisclosure } from 'toolkit/hooks/useDisclosure';
import AuthModal from './AuthModal'; import AuthModal from './AuthModal';
import useIsAuth from './useIsAuth'; import useIsAuth from './useIsAuth';
...@@ -21,7 +24,7 @@ const AuthModalStory = ({ flow }: Props) => { ...@@ -21,7 +24,7 @@ const AuthModalStory = ({ flow }: Props) => {
return ( return (
<> <>
<Button onClick={ authModal.onOpen }>{ flow === 'email_login' ? 'Log in' : 'Link email' }</Button> <Button onClick={ authModal.onOpen }>{ flow === 'email_login' ? 'Log in' : 'Link email' }</Button>
{ authModal.isOpen && <AuthModal initialScreen={ initialScreen } onClose={ handleClose }/> } { authModal.open && <AuthModal initialScreen={ initialScreen } onClose={ handleClose }/> }
<Box>Status: { isAuth ? 'Authenticated' : 'Not authenticated' }</Box> <Box>Status: { isAuth ? 'Authenticated' : 'Not authenticated' }</Box>
</> </>
); );
......
import { Center, Link } from '@chakra-ui/react'; import { Center } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { Link } from 'toolkit/chakra/link';
import { Skeleton } from 'toolkit/chakra/skeleton'; import { Skeleton } from 'toolkit/chakra/skeleton';
import type { IconName } from 'ui/shared/IconSvg'; import type { IconName } from 'ui/shared/IconSvg';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
...@@ -15,7 +16,7 @@ type Props = { ...@@ -15,7 +16,7 @@ type Props = {
const FooterLinkItem = ({ icon, iconSize, text, url, isLoading }: Props) => { const FooterLinkItem = ({ icon, iconSize, text, url, isLoading }: Props) => {
if (isLoading) { if (isLoading) {
return <Skeleton my="3px">{ text }</Skeleton>; return <Skeleton loading my="3px">{ text }</Skeleton>;
} }
return ( return (
......
import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps';
type Props = { type Props = {
isExpanded?: boolean; isExpanded?: boolean;
isCollapsed?: boolean; isCollapsed?: boolean;
...@@ -14,7 +12,6 @@ export default function useNavLinkStyleProps({ isExpanded, isCollapsed, isActive ...@@ -14,7 +12,6 @@ export default function useNavLinkStyleProps({ isExpanded, isCollapsed, isActive
display: 'flex', display: 'flex',
...(isActive ? { 'data-selected': true } : {}), ...(isActive ? { 'data-selected': true } : {}),
borderRadius: 'base', borderRadius: 'base',
...getDefaultTransitionProps({ transitionProperty: 'width, padding' }),
}, },
textProps: { textProps: {
variant: 'inherit', variant: 'inherit',
......
...@@ -5,7 +5,6 @@ import config from 'configs/app'; ...@@ -5,7 +5,6 @@ import config from 'configs/app';
import { useAppContext } from 'lib/contexts/app'; import { useAppContext } from 'lib/contexts/app';
import * as cookies from 'lib/cookies'; import * as cookies from 'lib/cookies';
import useNavItems, { isGroupItem } from 'lib/hooks/useNavItems'; import useNavItems, { isGroupItem } from 'lib/hooks/useNavItems';
import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
import useIsAuth from 'ui/snippets/auth/useIsAuth'; import useIsAuth from 'ui/snippets/auth/useIsAuth';
import NetworkLogo from 'ui/snippets/networkMenu/NetworkLogo'; import NetworkLogo from 'ui/snippets/networkMenu/NetworkLogo';
...@@ -60,7 +59,6 @@ const NavigationDesktop = () => { ...@@ -60,7 +59,6 @@ const NavigationDesktop = () => {
px={{ lg: isExpanded ? 6 : 4, xl: isCollapsed ? 4 : 6 }} px={{ lg: isExpanded ? 6 : 4, xl: isCollapsed ? 4 : 6 }}
py={ 12 } py={ 12 }
width={{ lg: isExpanded ? '229px' : '92px', xl: isCollapsed ? '92px' : '229px' }} width={{ lg: isExpanded ? '229px' : '92px', xl: isCollapsed ? '92px' : '229px' }}
{ ...getDefaultTransitionProps({ transitionProperty: 'width, padding' }) }
onClick={ handleContainerClick } onClick={ handleContainerClick }
> >
<TestnetBadge position="absolute" pl={ 3 } w="49px" top="34px"/> <TestnetBadge position="absolute" pl={ 3 } w="49px" top="34px"/>
...@@ -111,7 +109,6 @@ const NavigationDesktop = () => { ...@@ -111,7 +109,6 @@ const NavigationDesktop = () => {
borderWidth="1px" borderWidth="1px"
borderColor="border.divider" borderColor="border.divider"
transform={{ lg: isExpanded ? 'rotate(0)' : 'rotate(180deg)', xl: isCollapsed ? 'rotate(180deg)' : 'rotate(0)' }} transform={{ lg: isExpanded ? 'rotate(0)' : 'rotate(180deg)', xl: isCollapsed ? 'rotate(180deg)' : 'rotate(0)' }}
{ ...getDefaultTransitionProps({ transitionProperty: 'transform, left' }) }
transformOrigin="center" transformOrigin="center"
position="absolute" position="absolute"
top="104px" top="104px"
......
import { Tabs, VStack, Flex, Box } from '@chakra-ui/react'; import { VStack, Flex, Box } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { FeaturedNetwork, NetworkGroup } from 'types/networks'; import type { FeaturedNetwork, NetworkGroup } from 'types/networks';
import { PopoverBody, PopoverContent } from 'toolkit/chakra/popover'; import { PopoverBody, PopoverContent } from 'toolkit/chakra/popover';
import { Skeleton } from 'toolkit/chakra/skeleton'; import { Skeleton } from 'toolkit/chakra/skeleton';
import { TabsContent, TabsList, TabsRoot, TabsTrigger } from 'toolkit/chakra/tabs';
import NetworkMenuLink from './NetworkMenuLink'; import NetworkMenuLink from './NetworkMenuLink';
...@@ -27,28 +28,28 @@ const NetworkMenuPopup = ({ items, tabs }: Props) => { ...@@ -27,28 +28,28 @@ const NetworkMenuPopup = ({ items, tabs }: Props) => {
<> <>
<Flex alignItems="center"> <Flex alignItems="center">
<Flex h="32px" w="105px" bgColor={{ base: 'blackAlpha.50', _dark: 'whiteAlpha.50' }} borderRadius="base" px={ 4 } py={ 2 }> <Flex h="32px" w="105px" bgColor={{ base: 'blackAlpha.50', _dark: 'whiteAlpha.50' }} borderRadius="base" px={ 4 } py={ 2 }>
<Skeleton h="16px" w="100%"/> <Skeleton loading h="16px" w="100%"/>
</Flex> </Flex>
<Skeleton h="16px" w="68px" mx={ 4 }/> <Skeleton loading h="16px" w="68px" mx={ 4 }/>
<Skeleton h="16px" w="45px" mx={ 4 }/> <Skeleton loading h="16px" w="45px" mx={ 4 }/>
</Flex> </Flex>
<Flex mt={ 3 } flexDir="column" rowGap={ 2 }> <Flex mt={ 3 } flexDir="column" rowGap={ 2 }>
<Flex mx={ 3 } my={ 2 } alignItems="center"> <Flex mx={ 3 } my={ 2 } alignItems="center">
<Skeleton h="30px" w="30px" borderRadius="full"/> <Skeleton loading h="30px" w="30px" borderRadius="full"/>
<Skeleton h="16px" w="120px" ml={ 3 }/> <Skeleton loading h="16px" w="120px" ml={ 3 }/>
</Flex> </Flex>
<Flex mx={ 3 } my={ 2 } alignItems="center"> <Flex mx={ 3 } my={ 2 } alignItems="center">
<Skeleton h="30px" w="30px" borderRadius="full"/> <Skeleton loading h="30px" w="30px" borderRadius="full"/>
<Skeleton h="16px" w="180px" ml={ 3 }/> <Skeleton loading h="16px" w="180px" ml={ 3 }/>
</Flex> </Flex>
<Flex mx={ 3 } my={ 2 } alignItems="center"> <Flex mx={ 3 } my={ 2 } alignItems="center">
<Skeleton h="30px" w="30px" borderRadius="full"/> <Skeleton loading h="30px" w="30px" borderRadius="full"/>
<Skeleton h="16px" w="150px" ml={ 3 }/> <Skeleton loading h="16px" w="150px" ml={ 3 }/>
</Flex> </Flex>
</Flex> </Flex>
</> </>
) : ( ) : (
<Tabs.Root <TabsRoot
variant="secondary" variant="secondary"
size="sm" size="sm"
lazyMount lazyMount
...@@ -56,21 +57,21 @@ const NetworkMenuPopup = ({ items, tabs }: Props) => { ...@@ -56,21 +57,21 @@ const NetworkMenuPopup = ({ items, tabs }: Props) => {
onValueChange={ handleTabChange } onValueChange={ handleTabChange }
> >
{ tabs.length > 1 && ( { tabs.length > 1 && (
<Tabs.List columnGap={ 2 } mb={ 4 }> <TabsList columnGap={ 2 } mb={ 4 }>
{ tabs.map((tab) => ( { tabs.map((tab) => (
<Tabs.Trigger <TabsTrigger
key={ tab } key={ tab }
textTransform="capitalize" textTransform="capitalize"
value={ tab } value={ tab }
> >
{ tab } { tab }
</Tabs.Trigger> </TabsTrigger>
)) } )) }
</Tabs.List> </TabsList>
) } ) }
<Box> <Box>
{ tabs.map((tab) => ( { tabs.map((tab) => (
<Tabs.Content key={ tab } value={ tab } p={ 0 }> <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" maxH="516px" overflowY="scroll">
{ items { items
.filter((network) => network.group === tab) .filter((network) => network.group === tab)
...@@ -81,10 +82,10 @@ const NetworkMenuPopup = ({ items, tabs }: Props) => { ...@@ -81,10 +82,10 @@ const NetworkMenuPopup = ({ items, tabs }: Props) => {
/> />
)) } )) }
</VStack> </VStack>
</Tabs.Content> </TabsContent>
)) } )) }
</Box> </Box>
</Tabs.Root> </TabsRoot>
); );
return ( return (
......
...@@ -31,16 +31,16 @@ const NetworkMenuContentMobile = ({ items, tabs }: Props) => { ...@@ -31,16 +31,16 @@ const NetworkMenuContentMobile = ({ items, tabs }: Props) => {
const content = !items || items.length === 0 ? ( const content = !items || items.length === 0 ? (
<Flex mt={ 6 } flexDir="column" rowGap={ 2 }> <Flex mt={ 6 } flexDir="column" rowGap={ 2 }>
<Flex mx={ 3 } my={ 2 } alignItems="center"> <Flex mx={ 3 } my={ 2 } alignItems="center">
<Skeleton h="30px" w="30px" borderRadius="full"/> <Skeleton loading h="30px" w="30px" borderRadius="full"/>
<Skeleton h="20px" w="60px" ml={ 3 }/> <Skeleton loading h="20px" w="60px" ml={ 3 }/>
</Flex> </Flex>
<Flex mx={ 3 } my={ 2 } alignItems="center"> <Flex mx={ 3 } my={ 2 } alignItems="center">
<Skeleton h="30px" w="30px" borderRadius="full"/> <Skeleton loading h="30px" w="30px" borderRadius="full"/>
<Skeleton h="20px" w="120px" ml={ 3 }/> <Skeleton loading h="20px" w="120px" ml={ 3 }/>
</Flex> </Flex>
<Flex mx={ 3 } my={ 2 } alignItems="center"> <Flex mx={ 3 } my={ 2 } alignItems="center">
<Skeleton h="30px" w="30px" borderRadius="full"/> <Skeleton loading h="30px" w="30px" borderRadius="full"/>
<Skeleton h="20px" w="80px" ml={ 3 }/> <Skeleton loading h="20px" w="80px" ml={ 3 }/>
</Flex> </Flex>
</Flex> </Flex>
) : ( ) : (
......
import { LightMode } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { test, expect } from 'playwright/lib'; import { test, expect } from 'playwright/lib';
...@@ -20,9 +19,9 @@ test('input on regular page +@mobile +@dark-mode', async({ render, page }) => { ...@@ -20,9 +19,9 @@ test('input on regular page +@mobile +@dark-mode', async({ render, page }) => {
test('input on home page +@mobile +@dark-mode', async({ render, page }) => { test('input on home page +@mobile +@dark-mode', async({ render, page }) => {
await render( await render(
<LightMode> <div className="light">
<SearchBarInput { ...props } isHomepage/> <SearchBarInput { ...props } isHomepage/>
</LightMode>, </div>,
); );
const input = page.getByPlaceholder(/search by/i); const input = page.getByPlaceholder(/search by/i);
await expect(input).toHaveScreenshot(); await expect(input).toHaveScreenshot();
......
...@@ -4,6 +4,7 @@ import type { OptimisticL2WithdrawalStatus } from 'types/api/optimisticL2'; ...@@ -4,6 +4,7 @@ import type { OptimisticL2WithdrawalStatus } from 'types/api/optimisticL2';
import config from 'configs/app'; import config from 'configs/app';
import { Button } from 'toolkit/chakra/button'; import { Button } from 'toolkit/chakra/button';
import { Link } from 'toolkit/chakra/link';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import VerificationSteps from 'ui/shared/verificationSteps/VerificationSteps'; import VerificationSteps from 'ui/shared/verificationSteps/VerificationSteps';
...@@ -71,17 +72,19 @@ const TxDetailsWithdrawalStatusOptimistic = ({ status, l1TxHash }: Props) => { ...@@ -71,17 +72,19 @@ const TxDetailsWithdrawalStatusOptimistic = ({ status, l1TxHash }: Props) => {
} }
})(); })();
// TODO @tom2drum Button as <a> tags
const rightSlot = hasClaimButton ? ( const rightSlot = hasClaimButton ? (
<Button <Link
variant="outline"
size="sm"
as="a"
href={ rollupFeature.L2WithdrawalUrl } href={ rollupFeature.L2WithdrawalUrl }
asChild
target="_blank" target="_blank"
> >
Claim funds <Button
</Button> variant="outline"
size="sm"
>
Claim funds
</Button>
</Link>
) : null; ) : null;
return ( return (
......
...@@ -22,7 +22,7 @@ const TxTranslationType = ({ types, isLoading, translatationType }: Props) => { ...@@ -22,7 +22,7 @@ const TxTranslationType = ({ types, isLoading, translatationType }: Props) => {
} }
return ( return (
<Badge colorScheme="purple" loading={ isLoading }> <Badge colorPalette="purple" loading={ isLoading }>
{ camelCaseToSentence(translatationType) } { camelCaseToSentence(translatationType) }
</Badge> </Badge>
); );
......
import { Alert, Button, useDisclosure } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { Alert } from 'toolkit/chakra/alert';
import { Button } from 'toolkit/chakra/button';
import { useDisclosure } from 'toolkit/hooks/useDisclosure';
import AuthModal from 'ui/snippets/auth/AuthModal'; import AuthModal from 'ui/snippets/auth/AuthModal';
const VerifiedAddressesEmailAlert = () => { const VerifiedAddressesEmailAlert = () => {
...@@ -11,16 +13,17 @@ const VerifiedAddressesEmailAlert = () => { ...@@ -11,16 +13,17 @@ const VerifiedAddressesEmailAlert = () => {
<Alert <Alert
status="warning" status="warning"
mb={ 6 } mb={ 6 }
display="flex" // TODO @tom2drum check this alert
flexDirection={{ base: 'column', md: 'row' }} // display="flex"
alignItems={{ base: 'flex-start', lg: 'center' }} // flexDirection={{ base: 'column', md: 'row' }}
columnGap={ 2 } // alignItems={{ base: 'flex-start', lg: 'center' }}
rowGap={ 2 } // columnGap={ 2 }
// rowGap={ 2 }
> >
You need a valid email address to verify contracts. Please add your email to your account. You need a valid email address to verify contracts. Please add your email to your account.
<Button variant="outline" size="sm" onClick={ authModal.onOpen }>Add email</Button> <Button variant="outline" size="sm" onClick={ authModal.onOpen }>Add email</Button>
</Alert> </Alert>
{ authModal.isOpen && <AuthModal initialScreen={{ type: 'email', isAuth: true }} onClose={ authModal.onClose }/> } { authModal.open && <AuthModal initialScreen={{ type: 'email', isAuth: true }} onClose={ authModal.onClose }/> }
</> </>
); );
}; };
......
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