Commit 138c1689 authored by tom's avatar tom

base implementation

parent 2e379ec9
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';
......@@ -67,6 +68,7 @@ function getFloatingVariantStylesForSize(size: 'md' | 'lg', props: StyleFunction
// input styles
input: Input.sizes?.[size].field,
'input[aria-autocomplete=list]': FancySelect.sizes[size].field,
textarea: Textarea.sizes?.[size],
'input, textarea': {
padding: inputPx,
......
......@@ -22,6 +22,14 @@ const variantFloating = defineStyle((props) => {
const { focusPlaceholderColor } = getDefaultFormColors(props);
const bc = backgroundColor || mode('white', 'black')(props);
const activeStyles = {
backgroundColor: bc,
color: getColor(theme, focusPlaceholderColor),
fontSize: 'xs',
lineHeight: '16px',
borderTopRightRadius: 'none',
};
return {
left: '2px',
top: '2px',
......@@ -38,13 +46,8 @@ const variantFloating = defineStyle((props) => {
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
_focusWithin: {
backgroundColor: bc,
color: getColor(theme, focusPlaceholderColor),
fontSize: 'xs',
lineHeight: '16px',
borderTopRightRadius: 'none',
},
_focusWithin: activeStyles,
'&[data-active=true]': activeStyles,
};
});
......@@ -55,13 +58,19 @@ const variants = {
const sizes = {
lg: defineStyle((props) => {
if (props.variant === 'floating') {
const activeStyles = {
padding: '16px 24px 2px 24px',
};
return {
fontSize: 'md',
lineHeight: '24px',
padding: '28px 24px',
right: '26px',
_focusWithin: {
padding: '16px 24px 2px 24px',
_focusWithin: activeStyles,
'&[data-active=true]': activeStyles,
'&[data-fancy=true]': {
right: '36px',
},
};
}
......@@ -70,13 +79,19 @@ const sizes = {
}),
md: defineStyle((props) => {
if (props.variant === 'floating') {
const activeStyles = {
padding: '10px 16px 2px 16px',
};
return {
fontSize: 'md',
lineHeight: '20px',
padding: '18px 16px',
right: '18px',
_focusWithin: {
padding: '10px 16px 2px 16px',
_focusWithin: activeStyles,
'&[data-active=true]': activeStyles,
'&[data-fancy=true]': {
right: '36px',
},
};
}
......
......@@ -26,7 +26,6 @@ const ContractVerificationFieldCode = ({ isVyper }: Props) => {
isInvalid={ Boolean(error) }
isDisabled={ formState.isSubmitting }
required
maxLength={ 255 }
/>
<InputPlaceholder text="Contract code" error={ error }/>
</FormControl>
......
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 = [
......@@ -26,6 +29,13 @@ interface Props {
const ContractVerificationFieldCompiler = ({ isVyper }: Props) => {
const [ isNightly, setIsNightly ] = React.useState(false);
const { formState, control } = useFormContext<FormFields>();
const isMobile = useIsMobile();
const options = React.useMemo(() => (
[
...COMPILERS, ...(isNightly ? COMPILERS_NIGHTLY : []),
].map((option) => ({ label: option, value: option }))
), [ isNightly ]);
const handleCheckboxChange = React.useCallback(() => {
setIsNightly(prev => !prev);
......@@ -35,17 +45,17 @@ const ContractVerificationFieldCompiler = ({ isVyper }: Props) => {
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>
......
import { FormControl, useBoolean, useToken } 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 } from 'react-hook-form';
import type { Option } from './types';
import { chakraStyles } from 'ui/shared/FancySelect/utils';
import InputPlaceholder from 'ui/shared/InputPlaceholder';
interface Props {
size?: Size;
options: OptionsOrGroups<Option, GroupBase<Option>>;
placeholder: string;
name: string;
onChange: (newValue: string) => void;
onBlur?: () => void;
isDisabled?: boolean;
isRequired?: boolean;
error?: FieldError;
}
const FancySelect = ({ size = 'md', options, placeholder, name, onChange, onBlur, isDisabled, isRequired, error }: Props) => {
const [ hasValue, setHasValue ] = useBoolean(false);
const menuZIndex = useToken('zIndices', 'dropdown');
const handleChange = React.useCallback((newValue: SingleValue<Option> | MultiValue<Option>) => {
if (Array.isArray(newValue)) {
return;
}
const _newValue = newValue as SingleValue<Option>;
if (!_newValue) {
return;
}
setHasValue.on();
onChange(_newValue.value);
}, [ setHasValue, onChange ]);
const handleBlur = React.useCallback(() => {
onBlur?.();
}, [ onBlur ]);
const styles = React.useMemo(() => ({
menuPortal: (provided: CSSObjectWithLabel) => ({ ...provided, zIndex: menuZIndex }),
}), [ menuZIndex ]);
return (
<FormControl variant="floating" size={ size } isRequired={ isRequired }>
<Select
menuPortalTarget={ window.document.body }
placeholder=""
name={ name }
options={ options }
size={ size }
styles={ styles }
chakraStyles={ chakraStyles }
useBasicStyles
onChange={ handleChange }
onBlur={ handleBlur }
isDisabled={ isDisabled }
isRequired={ isRequired }
isInvalid={ Boolean(error) }
/>
<InputPlaceholder
text={ placeholder }
isActive={ hasValue }
error={ error }
isFancy
/>
</FormControl>
);
};
export default React.memo(FancySelect);
export interface Option {
label: string;
value: string;
}
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 chakraStyles: ChakraStylesConfig<Option> = {
// control: (provided) => ({
// ...provided,
// }),
inputContainer: (provided) => ({
...provided,
py: 0,
mx: 0,
}),
valueContainer: (provided, state) => ({
...provided,
...getValueContainerStyles(state.selectProps.size),
}),
singleValue: (provided, state) => ({
...provided,
mx: 0,
transform: 'none',
...getSingleValueStyles(state.selectProps.size),
}),
};
export { chakraStyles };
......@@ -5,9 +5,12 @@ import type { FieldError } from 'react-hook-form';
interface Props {
text: string;
error?: Partial<FieldError>;
className?: string;
isActive?: boolean;
isFancy?: boolean;
}
const InputPlaceholder = ({ text, error }: Props) => {
const InputPlaceholder = ({ text, error, className, isActive, isFancy }: Props) => {
let errorMessage = error?.message;
if (!errorMessage && error?.type === 'pattern') {
......@@ -15,11 +18,15 @@ const InputPlaceholder = ({ text, error }: Props) => {
}
return (
<FormLabel>
<FormLabel
className={ className }
{ ...(isActive ? { 'data-active': true } : {}) }
{ ...(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);
......@@ -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.6":
version "0.11.7"
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.7.tgz#38aec044c6c828f6ed51d5d7ae3d9b9faf6dbb0f"
......@@ -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