Commit 5cc749a9 authored by tom goriunov's avatar tom goriunov Committed by GitHub

Merge pull request #546 from blockscout/fancy-select

fancy select
parents 8fa9ba9f 2722b0c0
{
"foo": "bar"
}
\ No newline at end of file
{
"foo": "bar",
"baz": ["baz","baz","baz"]
}
\ No newline at end of file
{
"id": 1,
"title": "iPhone 9",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce nec leo odio. Vivamus iaculis faucibus tempus. Duis dapibus, ligula eu consequat ornare, sapien nisl laoreet arcu, eu pharetra dolor urna eget ligula. Sed facilisis pretium risus in finibus. Maecenas egestas orci euismod venenatis aliquam. Vivamus sed pretium dui, vitae porta ipsum. Donec elit tortor, imperdiet eu nulla at, condimentum consequat nisi. Phasellus mollis sem aliquam dolor lacinia bibendum. Mauris pulvinar vestibulum sodales. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nullam vitae facilisis odio. Mauris in ultricies nulla. Sed ornare consequat nulla. Cras pellentesque, erat at gravida rutrum, erat neque facilisis magna, et iaculis enim tortor ornare felis. Quisque mollis dignissim magna. In vitae ultricies felis. Quisque in ipsum non lorem ornare elementum vel vitae nisl. Integer luctus pulvinar dui a eleifend. Aliquam iaculis odio vitae metus ullamcorper, sed semper turpis consectetur. In convallis, justo a aliquet rhoncus, erat metus fringilla turpis, eget imperdiet purus est quis magna. Curabitur ornare mattis malesuada. In vitae lacinia est. Sed sit amet magna eget dolor tempus euismod.",
"price": 549,
"discountPercentage": 12.96,
"rating": 4.69,
"stock": 94,
"brand": "Apple",
"category": "smartphones",
"thumbnail": "https://i.dummyjson.com/data/products/1/thumbnail.jpg",
"images": [
"https://i.dummyjson.com/data/products/1/1.jpg",
"https://i.dummyjson.com/data/products/1/2.jpg",
"https://i.dummyjson.com/data/products/1/3.jpg",
"https://i.dummyjson.com/data/products/1/4.jpg",
"https://i.dummyjson.com/data/products/1/thumbnail.jpg"
]
}
\ No newline at end of file
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;
......@@ -4,6 +4,7 @@ import type { StyleFunctionProps } from '@chakra-ui/theme-tools';
import { getColor } from '@chakra-ui/theme-tools';
import getDefaultFormColors from '../utils/getDefaultFormColors';
import FancySelect from './FancySelect';
import FormLabel from './FormLabel';
import Input from './Input';
import Textarea from './Textarea';
......@@ -57,22 +58,32 @@ function getFloatingVariantStylesForSize(size: 'md' | 'lg', props: StyleFunction
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,
'input[aria-invalid=true] + label, textarea[aria-invalid=true] + label': {
[`
input[aria-invalid=true] + label,
textarea[aria-invalid=true] + label,
&[aria-invalid=true] label
`]: {
color: getColor(theme, errorColor),
},
// 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,
'input[disabled] + label, textarea[disabled] + label': {
[`
input[disabled] + label,
textarea[disabled] + label,
&[aria-disabled=true] label
`]: {
backgroundColor: 'transparent',
},
......@@ -80,7 +91,11 @@ function getFloatingVariantStylesForSize(size: 'md' | 'lg', props: StyleFunction
'input:not(:placeholder-shown) + label .chakra-form__required-indicator, textarea:not(:placeholder-shown) + label .chakra-form__required-indicator': {
color: getColor(theme, focusPlaceholderColor),
},
'input[aria-invalid=true] + label .chakra-form__required-indicator, textarea[aria-invalid=true] + label .chakra-form__required-indicator': {
[`
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: getColor(theme, errorColor),
},
},
......
......@@ -63,6 +63,9 @@ const sizes = {
_focusWithin: {
padding: '16px 24px 2px 24px',
},
'&[data-fancy=true]': {
right: '36px',
},
};
}
......@@ -78,6 +81,9 @@ const sizes = {
_focusWithin: {
padding: '10px 16px 2px 16px',
},
'&[data-fancy=true]': {
right: '36px',
},
};
}
......
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react';
import TestApp from 'playwright/TestApp';
import ContractVerificationForm from './ContractVerificationForm';
const hooksConfig = {
router: {
query: {},
},
};
test('flatten source code method +@dark-mode +@mobile', async({ mount, page }) => {
const component = await mount(
<TestApp>
<ContractVerificationForm/>
</TestApp>,
{ hooksConfig },
);
await page.getByText(/flattened source code/i).click();
await page.getByText(/optimization enabled/i).click();
await page.getByText(/add contract libraries/i).click();
await page.locator('button[aria-label="add"]').click();
await expect(component).toHaveScreenshot();
});
test('standard input json method', async({ mount, page }) => {
const component = await mount(
<TestApp>
<ContractVerificationForm/>
</TestApp>,
{ hooksConfig },
);
await page.getByText(/via standard/i).click();
await expect(component).toHaveScreenshot();
});
test('sourcify method +@dark-mode +@mobile', async({ mount, page }) => {
const component = await mount(
<TestApp>
<ContractVerificationForm/>
</TestApp>,
{ hooksConfig },
);
await page.getByText(/via sourcify/i).click();
await page.getByText(/upload files/i).click();
await page.locator('input[name="sources"]').setInputFiles([
'./playwright/mocks/file_mock_1.json',
'./playwright/mocks/file_mock_2.json',
'./playwright/mocks/file_mock_with_very_long_name.json',
]);
await expect(component).toHaveScreenshot();
});
test('multi-part files method', async({ mount, page }) => {
const component = await mount(
<TestApp>
<ContractVerificationForm/>
</TestApp>,
{ hooksConfig },
);
await page.getByText(/via multi-part files/i).click();
await expect(component).toHaveScreenshot();
});
test('vyper contract method', async({ mount, page }) => {
const component = await mount(
<TestApp>
<ContractVerificationForm/>
</TestApp>,
{ hooksConfig },
);
await page.getByText(/vyper contract/i).click();
await expect(component).toHaveScreenshot();
});
......@@ -26,7 +26,6 @@ const ContractVerificationFieldCode = ({ isVyper }: Props) => {
isInvalid={ Boolean(error) }
isDisabled={ formState.isSubmitting }
required
maxLength={ 255 }
/>
<InputPlaceholder text="Contract code" error={ error }/>
</FormControl>
......@@ -40,6 +39,7 @@ const ContractVerificationFieldCode = ({ isVyper }: Props) => {
control={ control }
render={ renderControl }
rules={{ required: true }}
defaultValue=""
/>
{ isVyper ? null : (
<>
......
import { Code, Select, Checkbox } from '@chakra-ui/react';
import { Code, Checkbox } from '@chakra-ui/react';
import React from 'react';
import type { ControllerRenderProps } from 'react-hook-form';
import { useFormContext, Controller } from 'react-hook-form';
import type { FormFields } from '../types';
import useIsMobile from 'lib/hooks/useIsMobile';
import FancySelect from 'ui/shared/FancySelect/FancySelect';
import ContractVerificationFormRow from '../ContractVerificationFormRow';
const COMPILERS = [
......@@ -25,27 +28,38 @@ interface Props {
const ContractVerificationFieldCompiler = ({ isVyper }: Props) => {
const [ isNightly, setIsNightly ] = React.useState(false);
const { formState, control } = useFormContext<FormFields>();
const { formState, control, getValues, resetField } = useFormContext<FormFields>();
const isMobile = useIsMobile();
const options = React.useMemo(() => (
[
...COMPILERS, ...(isNightly ? COMPILERS_NIGHTLY : []),
].map((option) => ({ label: option, value: option }))
), [ isNightly ]);
const handleCheckboxChange = React.useCallback(() => {
if (isNightly) {
const field = getValues('compiler');
field.value.includes('nightly') && resetField('compiler', { defaultValue: null });
}
setIsNightly(prev => !prev);
}, []);
}, [ getValues, isNightly, resetField ]);
const renderControl = React.useCallback(({ field }: {field: ControllerRenderProps<FormFields, 'compiler'>}) => {
const error = 'compiler' in formState.errors ? formState.errors.compiler : undefined;
return (
<Select
<FancySelect
{ ...field }
size={{ base: 'md', lg: 'lg' }}
options={ options }
size={ isMobile ? 'md' : 'lg' }
placeholder="Compiler"
isInvalid={ Boolean(error) }
isDisabled={ formState.isSubmitting }
>
{ [ ...COMPILERS, ...(isNightly ? COMPILERS_NIGHTLY : []) ].map((option) => <option key={ option } value={ option }>{ option }</option>) }
</Select>
error={ error }
isRequired
/>
);
}, [ formState.errors, formState.isSubmitting, isNightly ]);
}, [ formState.errors, formState.isSubmitting, isMobile, options ]);
return (
<ContractVerificationFormRow>
......
import { Link, Select } from '@chakra-ui/react';
import { Link } from '@chakra-ui/react';
import React from 'react';
import type { ControllerRenderProps } from 'react-hook-form';
import { useFormContext, Controller } from 'react-hook-form';
import type { FormFields } from '../types';
import useIsMobile from 'lib/hooks/useIsMobile';
import FancySelect from 'ui/shared/FancySelect/FancySelect';
import ContractVerificationFormRow from '../ContractVerificationFormRow';
const VERSIONS = [
......@@ -15,22 +18,27 @@ const VERSIONS = [
const ContractVerificationFieldEvmVersion = () => {
const { formState, control } = useFormContext<FormFields>();
const isMobile = useIsMobile();
const options = React.useMemo(() => (
VERSIONS.map((option) => ({ label: option, value: option }))
), [ ]);
const renderControl = React.useCallback(({ field }: {field: ControllerRenderProps<FormFields, 'evm_version'>}) => {
const error = 'evm_version' in formState.errors ? formState.errors.evm_version : undefined;
return (
<Select
<FancySelect
{ ...field }
size={{ base: 'md', lg: 'lg' }}
options={ options }
size={ isMobile ? 'md' : 'lg' }
placeholder="EVM Version"
isInvalid={ Boolean(error) }
isDisabled={ formState.isSubmitting }
>
{ VERSIONS.map((option) => <option key={ option } value={ option }>{ option }</option>) }
</Select>
error={ error }
isRequired
/>
);
}, [ formState.errors, formState.isSubmitting ]);
}, [ formState.errors, formState.isSubmitting, isMobile, options ]);
return (
<ContractVerificationFormRow>
......
......@@ -39,6 +39,7 @@ const ContractVerificationFieldLibraries = () => {
size="lg"
onChange={ handleCheckboxChange }
mt={ 9 }
isDisabled={ formState.isSubmitting }
>
Add contract libraries
</Checkbox>
......@@ -52,6 +53,7 @@ const ContractVerificationFieldLibraries = () => {
onAddFieldClick={ handleAddFieldClick }
onRemoveFieldClick={ handleRemoveFieldClick }
error={ 'libraries' in formState.errors ? formState.errors.libraries?.[index] : undefined }
isDisabled={ formState.isSubmitting }
/>
)) }
</>
......
......@@ -24,9 +24,10 @@ interface Props {
};
onAddFieldClick: (index: number) => void;
onRemoveFieldClick: (index: number) => void;
isDisabled?: boolean;
}
const ContractVerificationFieldLibraryItem = ({ control, index, fieldsLength, onAddFieldClick, onRemoveFieldClick, error }: Props) => {
const ContractVerificationFieldLibraryItem = ({ control, index, fieldsLength, onAddFieldClick, onRemoveFieldClick, error, isDisabled }: Props) => {
const ref = React.useRef<HTMLDivElement>(null);
const renderNameControl = React.useCallback(({ field }: {field: ControllerRenderProps<FormFields, `libraries.${ number }.name`>}) => {
......@@ -36,13 +37,14 @@ const ContractVerificationFieldLibraryItem = ({ control, index, fieldsLength, on
{ ...field }
required
isInvalid={ Boolean(error?.name) }
isDisabled={ isDisabled }
maxLength={ 255 }
autoComplete="off"
/>
<InputPlaceholder text="Library name (.sol file)" error={ error?.name }/>
</FormControl>
);
}, [ error?.name ]);
}, [ error?.name, isDisabled ]);
const renderAddressControl = React.useCallback(({ field }: {field: ControllerRenderProps<FormFields, `libraries.${ number }.address`>}) => {
return (
......@@ -50,13 +52,14 @@ const ContractVerificationFieldLibraryItem = ({ control, index, fieldsLength, on
<Input
{ ...field }
isInvalid={ Boolean(error?.address) }
isDisabled={ isDisabled }
required
autoComplete="off"
/>
<InputPlaceholder text="Library address (0x...)" error={ error?.address }/>
</FormControl>
);
}, [ error?.address ]);
}, [ error?.address, isDisabled ]);
const handleAddButtonClick = React.useCallback(() => {
onAddFieldClick(index);
......@@ -84,6 +87,7 @@ const ContractVerificationFieldLibraryItem = ({ control, index, fieldsLength, on
h="30px"
onClick={ handleRemoveButtonClick }
icon={ <Icon as={ minusIcon } w="20px" h="20px"/> }
isDisabled={ isDisabled }
/>
) }
{ fieldsLength < LIMIT && (
......@@ -94,6 +98,7 @@ const ContractVerificationFieldLibraryItem = ({ control, index, fieldsLength, on
h="30px"
onClick={ handleAddButtonClick }
icon={ <Icon as={ plusIcon } w="20px" h="20px"/> }
isDisabled={ isDisabled }
/>
) }
</Flex>
......
......@@ -41,6 +41,7 @@ const ContractVerificationFieldName = ({ hint }: Props) => {
control={ control }
render={ renderControl }
rules={{ required: true }}
defaultValue=""
/>
{ hint ? <span>{ hint }</span> : (
<>
......
......@@ -29,13 +29,13 @@ const ContractVerificationFieldOptimization = () => {
const renderInputControl = React.useCallback(({ field }: {field: ControllerRenderProps<FormFields, 'optimization_runs'>}) => {
return (
<FormControl variant="floating" id={ field.name } size={{ base: 'md', lg: 'lg' }}>
<FormControl variant="floating" id={ field.name } size={{ base: 'md', lg: 'lg' }} isRequired>
<Input
{ ...field }
required
maxLength={ 255 }
isDisabled={ formState.isSubmitting }
autoComplete="off"
type="number"
/>
<InputPlaceholder text="Optimization runs"/>
</FormControl>
......@@ -58,6 +58,7 @@ const ContractVerificationFieldOptimization = () => {
control={ control }
render={ renderInputControl }
rules={{ required: true }}
defaultValue=""
/>
</ContractVerificationFormRow>
) }
......
import type { Option } from 'ui/shared/FancySelect/types';
export type VerificationMethod = 'flatten_source_code' | 'standard_input' | 'sourcify' | 'multi_part_file' | 'vyper_contract'
export interface ContractLibrary {
......@@ -8,8 +10,8 @@ export interface FormFieldsFlattenSourceCode {
method: 'flatten_source_code';
is_yul: boolean;
name: string;
compiler: string;
evm_version: string;
compiler: Option;
evm_version: Option;
is_optimization_enabled: boolean;
optimization_runs: string;
code: string;
......@@ -20,7 +22,7 @@ export interface FormFieldsFlattenSourceCode {
export interface FormFieldsStandardInput {
method: 'standard_input';
name: string;
compiler: string;
compiler: Option;
sources: Array<File>;
}
......@@ -31,8 +33,8 @@ export interface FormFieldsSourcify {
export interface FormFieldsMultiPartFile {
method: 'multi_part_file';
compiler: string;
evm_version: string;
compiler: Option;
evm_version: Option;
is_optimization_enabled: boolean;
optimization_runs: string;
sources: Array<File>;
......@@ -41,7 +43,7 @@ export interface FormFieldsMultiPartFile {
export interface FormFieldsVyperContract {
method: 'vyper_contract';
name: string;
compiler: string;
compiler: Option;
code: string;
abi_encoded_args: string;
}
......
import { test, expect } from '@playwright/experimental-ct-react';
import _noop from 'lodash/noop';
import React from 'react';
import TestApp from 'playwright/TestApp';
import FancySelect from './FancySelect';
const OPTIONS = [
{ value: 'v0.8.17+commit.8df45f5f', label: 'v0.8.17+commit.8df45f5f' },
{ value: 'v0.8.16+commit.07a7930e', label: 'v0.8.16+commit.07a7930e' },
{ value: 'v0.8.15+commit.e14f2714', label: 'v0.8.15+commit.e14f2714' },
];
test.use({ viewport: { width: 500, height: 300 } });
const defaultProps = {
options: OPTIONS,
isRequired: true,
placeholder: 'Compiler',
name: 'compiler',
onChange: _noop,
};
[ 'md' as const, 'lg' as const ].forEach((size) => {
test.describe(`size ${ size } +@dark-mode`, () => {
test('empty', async({ mount, page }) => {
const component = await mount(
<TestApp>
<FancySelect
{ ...defaultProps }
size={ size }
value={ null }
/>
</TestApp>,
);
await expect(component).toHaveScreenshot();
await component.getByLabel(/compiler/i).focus();
await component.getByLabel(/compiler/i).type('1');
await expect(page).toHaveScreenshot();
});
test('filled', async({ mount }) => {
const component = await mount(
<TestApp>
<FancySelect
{ ...defaultProps }
size={ size }
value={ OPTIONS[0] }
/>
</TestApp>,
);
await expect(component).toHaveScreenshot();
});
test('error', async({ mount }) => {
const component = await mount(
<TestApp>
<FancySelect
{ ...defaultProps }
size={ size }
value={ null }
error={{
type: 'unknown',
message: 'cannot be empty',
}}
/>
</TestApp>,
);
await expect(component).toHaveScreenshot();
await component.getByLabel(/compiler/i).focus();
await component.getByLabel(/compiler/i).type('1');
await expect(component).toHaveScreenshot();
});
test('disabled', async({ mount }) => {
const component = await mount(
<TestApp>
<FancySelect
{ ...defaultProps }
size={ size }
value={ OPTIONS[0] }
isDisabled
/>
</TestApp>,
);
await expect(component).toHaveScreenshot();
});
});
});
import { FormControl, useToken, useColorMode } from '@chakra-ui/react';
import type { Size, CSSObjectWithLabel, OptionsOrGroups, GroupBase, SingleValue, MultiValue } from 'chakra-react-select';
import { Select } from 'chakra-react-select';
import React from 'react';
import type { FieldError, FieldErrorsImpl, Merge } from 'react-hook-form';
import type { Option } from './types';
import { getChakraStyles } from 'ui/shared/FancySelect/utils';
import InputPlaceholder from 'ui/shared/InputPlaceholder';
interface Props {
size?: Size; // we don't have styles for sm select/input with floating label yet
options: OptionsOrGroups<Option, GroupBase<Option>>;
placeholder: string;
name: string;
onChange: (newValue: SingleValue<Option> | MultiValue<Option>) => void;
onBlur?: () => void;
isDisabled?: boolean;
isRequired?: boolean;
error?: Merge<FieldError, FieldErrorsImpl<Option>> | undefined;
value?: SingleValue<Option> | MultiValue<Option>;
}
const FancySelect = ({ size = 'md', options, placeholder, name, onChange, onBlur, isDisabled, isRequired, error, value }: Props) => {
const menuZIndex = useToken('zIndices', 'dropdown');
const { colorMode } = useColorMode();
const styles = React.useMemo(() => ({
menuPortal: (provided: CSSObjectWithLabel) => ({ ...provided, zIndex: menuZIndex }),
}), [ menuZIndex ]);
const chakraStyles = React.useMemo(() => getChakraStyles(colorMode), [ colorMode ]);
return (
<FormControl
variant="floating"
size={ size }
isRequired={ isRequired }
{ ...(error ? { 'aria-invalid': true } : {}) }
{ ...(isDisabled ? { 'aria-disabled': true } : {}) }
{ ...(value ? { 'data-active': true } : {}) }
>
<Select
menuPortalTarget={ window.document.body }
placeholder=""
name={ name }
options={ options }
size={ size }
styles={ styles }
chakraStyles={ chakraStyles }
useBasicStyles
onChange={ onChange }
onBlur={ onBlur }
isDisabled={ isDisabled }
isRequired={ isRequired }
isInvalid={ Boolean(error) }
value={ value }
/>
<InputPlaceholder
text={ placeholder }
error={ error }
isFancy
/>
</FormControl>
);
};
export default React.memo(React.forwardRef(FancySelect));
export interface Option {
label: string;
value: string;
}
import type { ColorMode } from '@chakra-ui/react';
import type { Size, ChakraStylesConfig } from 'chakra-react-select';
import type { Option } from './types';
function getValueContainerStyles(size?: Size) {
switch (size) {
case 'sm':
case 'md': {
return {
paddingLeft: 4,
};
}
case 'lg': {
return {
paddingLeft: 6,
};
}
default: {
return {};
}
}
}
function getSingleValueStyles(size?: Size) {
switch (size) {
case 'sm':
case 'md': {
return {
top: '26px',
};
}
case 'lg': {
return {
top: '38px',
};
}
default: {
return {};
}
}
}
const getChakraStyles: (colorMode: ColorMode) => ChakraStylesConfig<Option> = (colorMode) => {
const emptyInputBorderColor = colorMode === 'dark' ? 'gray.700' : 'gray.100';
const filledInputBorderColor = colorMode === 'dark' ? 'gray.600' : 'gray.300';
return {
control: (provided, state) => ({
...provided,
borderColor: state.hasValue ? filledInputBorderColor : emptyInputBorderColor,
}),
inputContainer: (provided) => ({
...provided,
py: 0,
mx: 0,
}),
valueContainer: (provided, state) => ({
...provided,
...getValueContainerStyles(state.selectProps.size),
py: 0,
}),
singleValue: (provided, state) => ({
...provided,
mx: 0,
transform: 'none',
...getSingleValueStyles(state.selectProps.size),
}),
};
};
export { getChakraStyles };
......@@ -5,9 +5,11 @@ import type { FieldError } from 'react-hook-form';
interface Props {
text: string;
error?: Partial<FieldError>;
className?: string;
isFancy?: boolean;
}
const InputPlaceholder = ({ text, error }: Props) => {
const InputPlaceholder = ({ text, error, className, isFancy }: Props) => {
let errorMessage = error?.message;
if (!errorMessage && error?.type === 'pattern') {
......@@ -15,11 +17,14 @@ const InputPlaceholder = ({ text, error }: Props) => {
}
return (
<FormLabel>
<FormLabel
className={ className }
{ ...(isFancy ? { 'data-fancy': true } : {}) }
>
<chakra.span>{ text }</chakra.span>
{ errorMessage && <chakra.span order={ 3 } whiteSpace="pre"> - { errorMessage }</chakra.span> }
</FormLabel>
);
};
export default InputPlaceholder;
export default chakra(InputPlaceholder);
......@@ -40,6 +40,7 @@ const FileInput = <Values extends FieldValues, Names extends Path<Values>>({ chi
ref={ ref }
accept={ accept }
multiple={ multiple }
name={ field.name }
/>
{ children }
</InputGroup>
......
......@@ -1017,6 +1017,13 @@
dependencies:
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.12.0", "@babel/runtime@^7.8.7":
version "7.20.13"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.13.tgz#7055ab8a7cff2b8f6058bf6ae45ff84ad2aded4b"
integrity sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==
dependencies:
regenerator-runtime "^0.13.11"
"@babel/runtime@^7.17.2", "@babel/runtime@^7.5.5":
version "7.20.7"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.7.tgz#fcb41a5a70550e04a7b708037c7c32f7f356d8fd"
......@@ -1894,7 +1901,7 @@
source-map "^0.5.7"
stylis "4.1.3"
"@emotion/cache@^11.10.5":
"@emotion/cache@^11.10.5", "@emotion/cache@^11.4.0":
version "11.10.5"
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.10.5.tgz#c142da9351f94e47527ed458f7bbbbe40bb13c12"
integrity sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==
......@@ -1934,7 +1941,7 @@
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.0.tgz#f580f9beb67176fa57aae70b08ed510e1b18980f"
integrity sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==
"@emotion/react@^11.10.4":
"@emotion/react@^11.10.4", "@emotion/react@^11.8.1":
version "11.10.5"
resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.10.5.tgz#95fff612a5de1efa9c0d535384d3cfa115fe175d"
integrity sha512-TZs6235tCJ/7iF6/rvTaOH4oxQg2gMAcdHemjwLKIjKz4rRuYe1HJ2TQJKnAcRAfOUDdU8XoDadCe1rl72iv8A==
......@@ -2363,6 +2370,18 @@
"@ethersproject/properties" "^5.7.0"
"@ethersproject/strings" "^5.7.0"
"@floating-ui/core@^1.0.5":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.1.0.tgz#0a1dee4bbce87ff71602625d33f711cafd8afc08"
integrity sha512-zbsLwtnHo84w1Kc8rScAo5GMk1GdecSlrflIbfnEBJwvTSj1SL6kkOYV+nHraMCPEy+RNZZUaZyL8JosDGCtGQ==
"@floating-ui/dom@^1.0.1":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.1.0.tgz#29fea1344fdef15b6ba270a733d20b7134fee5c2"
integrity sha512-TSogMPVxbRe77QCj1dt8NmRiJasPvuc+eT5jnJ6YpLqgOD2zXc5UA3S1qwybN+GVCDNdKfpKy1oj8RpzLJvh6A==
dependencies:
"@floating-ui/core" "^1.0.5"
"@humanwhocodes/config-array@^0.11.8":
version "0.11.8"
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.8.tgz#03595ac2075a4dc0f191cc2131de14fbd7d410b9"
......@@ -4030,6 +4049,13 @@
dependencies:
"@types/react" "*"
"@types/react-transition-group@^4.4.0":
version "4.4.5"
resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.5.tgz#aae20dcf773c5aa275d5b9f7cdbca638abc5e416"
integrity sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==
dependencies:
"@types/react" "*"
"@types/react@*":
version "18.0.21"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.21.tgz#b8209e9626bb00a34c76f55482697edd2b43cc67"
......@@ -5352,6 +5378,13 @@ caniuse-lite@^1.0.30001332, caniuse-lite@^1.0.30001400:
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001418.tgz#5f459215192a024c99e3e3a53aac310fc7cf24e6"
integrity sha512-oIs7+JL3K9JRQ3jPZjlH6qyYDp+nBTCais7hjh0s+fuBwufc7uZ7hPYMXrDOJhV360KGMTcczMRObk0/iMqZRg==
chakra-react-select@^4.4.3:
version "4.4.3"
resolved "https://registry.yarnpkg.com/chakra-react-select/-/chakra-react-select-4.4.3.tgz#678fcb25b90b9f977628694d1a9d49d072e01128"
integrity sha512-anDgJyYUpIapTmUbgXB+Iw5hJ90hOPvgoUPUaYdO5q9zY2VBFhQ1L0gBMqWAQxiKUmuHpwQypf8sPoVtd0b3KA==
dependencies:
react-select "5.7.0"
chalk@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4"
......@@ -6175,6 +6208,14 @@ dom-accessibility-api@^0.5.9:
resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.14.tgz#56082f71b1dc7aac69d83c4285eef39c15d93f56"
integrity sha512-NMt+m9zFMPZe0JcY9gN224Qvk6qLIdqex29clBvc/y75ZBX9YA9wNK3frsYvu2DI1xcCIwxwnX+TlsJ2DSOADg==
dom-helpers@^5.0.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
dependencies:
"@babel/runtime" "^7.8.7"
csstype "^3.0.2"
dom-serializer@^1.0.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30"
......@@ -8830,6 +8871,11 @@ mdn-data@2.0.14:
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50"
integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==
memoize-one@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045"
integrity sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==
merge-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
......@@ -9584,7 +9630,7 @@ prompts@^2.0.1:
kleur "^3.0.3"
sisteransi "^1.0.5"
prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
......@@ -9804,6 +9850,21 @@ react-scroll@^1.8.7:
lodash.throttle "^4.1.1"
prop-types "^15.7.2"
react-select@5.7.0:
version "5.7.0"
resolved "https://registry.yarnpkg.com/react-select/-/react-select-5.7.0.tgz#82921b38f1fcf1471a0b62304da01f2896cd8ce6"
integrity sha512-lJGiMxCa3cqnUr2Jjtg9YHsaytiZqeNOKeibv6WF5zbK/fPegZ1hg3y/9P1RZVLhqBTs0PfqQLKuAACednYGhQ==
dependencies:
"@babel/runtime" "^7.12.0"
"@emotion/cache" "^11.4.0"
"@emotion/react" "^11.8.1"
"@floating-ui/dom" "^1.0.1"
"@types/react-transition-group" "^4.4.0"
memoize-one "^6.0.0"
prop-types "^15.6.0"
react-transition-group "^4.3.0"
use-isomorphic-layout-effect "^1.1.2"
react-style-singleton@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.1.tgz#f99e420492b2d8f34d38308ff660b60d0b1205b4"
......@@ -9813,6 +9874,16 @@ react-style-singleton@^2.2.1:
invariant "^2.2.4"
tslib "^2.0.0"
react-transition-group@^4.3.0:
version "4.4.5"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1"
integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==
dependencies:
"@babel/runtime" "^7.5.5"
dom-helpers "^5.0.1"
loose-envify "^1.4.0"
prop-types "^15.6.2"
react@17.0.2:
version "17.0.2"
resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
......@@ -10965,6 +11036,11 @@ use-font-face-observer@^1.2.1:
fontfaceobserver "2.1.0"
react "17.0.2"
use-isomorphic-layout-effect@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz#497cefb13d863d687b08477d9e5a164ad8c1a6fb"
integrity sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==
use-sidecar@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.2.tgz#2f43126ba2d7d7e117aa5855e5d8f0276dfe73c2"
......
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