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 { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import type { RenderOptions } from '@testing-library/react';
......@@ -8,7 +7,7 @@ import React from 'react';
import { AppContextProvider } from 'lib/contexts/app';
import { ScrollDirectionProvider } from 'lib/contexts/scrollDirection';
import { SocketProvider } from 'lib/socket/context';
import theme from 'theme/theme';
import { Provider as ChakraProvider } from 'toolkit/chakra/provider';
import 'lib/setLocale';
......@@ -32,7 +31,7 @@ const TestApp = ({ children }: { children: React.ReactNode }) => {
}));
return (
<ChakraProvider theme={ theme }>
<ChakraProvider>
<QueryClientProvider client={ queryClient }>
<AppContextProvider pageProps={ PAGE_PROPS }>
<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> = {
// service routes, added only to make typescript happy
'/login': 'Regular page',
'/sprite': 'Regular page',
'/chakra': 'Regular page',
'/api/metrics': 'Regular page',
'/api/monitoring/invalid-api-schema': 'Regular page',
'/api/log': 'Regular page',
......
......@@ -67,6 +67,7 @@ const TEMPLATE_MAP: Record<Route['pathname'], string> = {
// service routes, added only to make typescript happy
'/login': DEFAULT_TEMPLATE,
'/sprite': DEFAULT_TEMPLATE,
'/chakra': DEFAULT_TEMPLATE,
'/api/metrics': DEFAULT_TEMPLATE,
'/api/monitoring/invalid-api-schema': DEFAULT_TEMPLATE,
'/api/log': DEFAULT_TEMPLATE,
......
......@@ -64,6 +64,7 @@ const TEMPLATE_MAP: Record<Route['pathname'], string> = {
// service routes, added only to make typescript happy
'/login': '%network_name% login',
'/sprite': '%network_name% SVG sprite',
'/chakra': '%network_name% Chakra UI showcase',
'/api/metrics': '%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',
......
......@@ -62,6 +62,7 @@ export const PAGE_TYPE_DICT: Record<Route['pathname'], string> = {
// service routes, added only to make typescript happy
'/login': 'Login',
'/sprite': 'Sprite',
'/chakra': 'Chakra UI showcase',
'/api/metrics': 'Node API: Prometheus metrics',
'/api/monitoring/invalid-api-schema': 'Node API: Prometheus metrics',
'/api/log': 'Node API: Request log',
......
import type { ColorMode } from '@chakra-ui/react';
import type { ColorThemeId } from 'types/settings';
import type { ColorMode } from 'toolkit/chakra/color-mode';
interface ColorTheme {
id: ColorThemeId;
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;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment