Commit 81c3dac7 authored by tom's avatar tom

async select for compiler version

parent 7c00d780
import { Code } from '@chakra-ui/react';
import { Checkbox, Code } from '@chakra-ui/react';
import { useQueryClient } from '@tanstack/react-query';
import React from 'react';
import type { ControllerRenderProps } from 'react-hook-form';
......@@ -13,44 +13,76 @@ import FancySelect from 'ui/shared/FancySelect/FancySelect';
import ContractVerificationFormRow from '../ContractVerificationFormRow';
const OPTIONS_LIMIT = 50;
interface Props {
isVyper?: boolean;
}
const ContractVerificationFieldCompiler = ({ isVyper }: Props) => {
const { formState, control } = useFormContext<FormFields>();
const [ isNightly, setIsNightly ] = React.useState(false);
const { formState, control, getValues, resetField } = useFormContext<FormFields>();
const isMobile = useIsMobile();
const queryClient = useQueryClient();
const config = queryClient.getQueryData<SmartContractVerificationConfig>(getResourceKey('contract_verification_config'));
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 options = React.useMemo(() => (
(isVyper ? config?.vyper_compiler_versions : config?.solidity_compiler_versions)?.map((option) => ({ label: option, value: option })) || []
), [ config?.solidity_compiler_versions, config?.vyper_compiler_versions, isVyper ]);
const loadOptions = React.useCallback(async(inputValue: string) => {
return options
.filter(({ label }) => !inputValue || label.toLowerCase().includes(inputValue.toLowerCase()))
.filter(({ label }) => isNightly ? true : !label.includes('nightly'))
.slice(0, OPTIONS_LIMIT);
}, [ isNightly, options ]);
const renderControl = React.useCallback(({ field }: {field: ControllerRenderProps<FormFields, 'compiler'>}) => {
const error = 'compiler' in formState.errors ? formState.errors.compiler : undefined;
return (
<FancySelect
{ ...field }
options={ options }
loadOptions={ loadOptions }
defaultOptions
size={ isMobile ? 'md' : 'lg' }
placeholder="Compiler"
isDisabled={ formState.isSubmitting }
error={ error }
isRequired
isAsync
/>
);
}, [ formState.errors, formState.isSubmitting, isMobile, options ]);
}, [ formState.errors, formState.isSubmitting, isMobile, loadOptions ]);
return (
<ContractVerificationFormRow>
<Controller
name="compiler"
control={ control }
render={ renderControl }
rules={{ required: true }}
/>
<>
<Controller
name="compiler"
control={ control }
render={ renderControl }
rules={{ required: true }}
/>
{ !isVyper && (
<Checkbox
size="lg"
mt={ 3 }
onChange={ handleCheckboxChange }
isDisabled={ formState.isSubmitting }
>
Include nightly builds
</Checkbox>
) }
</>
{ isVyper ? null : (
<>
<span>The compiler version is specified in </span>
......
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 type { CSSObjectWithLabel, GroupBase, SingleValue, MultiValue, AsyncProps, Props as SelectProps } from 'chakra-react-select';
import { Select, AsyncSelect } from 'chakra-react-select';
import React from 'react';
import type { FieldError, FieldErrorsImpl, Merge } from 'react-hook-form';
......@@ -9,20 +9,23 @@ 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;
interface CommonProps {
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) => {
interface RegularSelectProps extends SelectProps<Option, boolean, GroupBase<Option>>, CommonProps {
isAsync?: false;
onChange: (newValue: SingleValue<Option> | MultiValue<Option>) => void;
}
interface AsyncSelectProps extends AsyncProps<Option, boolean, GroupBase<Option>>, CommonProps {
isAsync: true;
onChange: (newValue: SingleValue<Option> | MultiValue<Option>) => void;
}
type Props = RegularSelectProps | AsyncSelectProps;
const FancySelect = (props: Props) => {
const menuZIndex = useToken('zIndices', 'dropdown');
const { colorMode } = useColorMode();
......@@ -32,34 +35,30 @@ const FancySelect = ({ size = 'md', options, placeholder, name, onChange, onBlur
const chakraStyles = React.useMemo(() => getChakraStyles(colorMode), [ colorMode ]);
const SelectComponent = props.isAsync ? AsyncSelect : Select;
return (
<FormControl
variant="floating"
size={ size }
isRequired={ isRequired }
{ ...(error ? { 'aria-invalid': true } : {}) }
{ ...(isDisabled ? { 'aria-disabled': true } : {}) }
{ ...(value ? { 'data-active': true } : {}) }
size={ props.size || 'md' }
isRequired={ props.isRequired }
{ ...(props.error ? { 'aria-invalid': true } : {}) }
{ ...(props.isDisabled ? { 'aria-disabled': true } : {}) }
{ ...(props.value ? { 'data-active': true } : {}) }
>
<Select
<SelectComponent
{ ...props }
size={ props.size || 'md' }
menuPortalTarget={ window.document.body }
placeholder=""
name={ name }
options={ options }
size={ size }
styles={ styles }
chakraStyles={ chakraStyles }
isInvalid={ Boolean(props.error) }
useBasicStyles
onChange={ onChange }
onBlur={ onBlur }
isDisabled={ isDisabled }
isRequired={ isRequired }
isInvalid={ Boolean(error) }
value={ value }
/>
<InputPlaceholder
text={ placeholder }
error={ error }
text={ typeof props.placeholder === 'string' ? props.placeholder : '' }
error={ props.error }
isFancy
/>
</FormControl>
......
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