Commit 4d0d415c authored by tom's avatar tom

addresses field

parent 8cc20100
......@@ -8,6 +8,7 @@ import type { PublicTagTypesResponse } from 'types/api/addressMetadata';
import Hint from 'ui/shared/Hint';
import PublicTagsSubmitFieldAddresses from './fields/PublicTagsSubmitFieldAddresses';
import PublicTagsSubmitFieldRequesterEmail from './fields/PublicTagsSubmitFieldRequesterEmail';
import PublicTagsSubmitFieldRequesterName from './fields/PublicTagsSubmitFieldRequesterName';
......@@ -18,6 +19,9 @@ interface Props {
const PublicTagsSubmitForm = ({ config }: Props) => {
const formApi = useForm<FormFields>({
mode: 'onBlur',
defaultValues: {
addresses: [ { hash: '' } ],
},
});
const onFormSubmit: SubmitHandler<FormFields> = React.useCallback((data) => {
......@@ -34,7 +38,7 @@ const PublicTagsSubmitForm = ({ config }: Props) => {
<Grid
columnGap={ 5 }
rowGap={{ base: 5, lg: 4 }}
templateColumns={{ base: '1fr', lg: '1fr 1fr minmax(0, 200px)' }}
templateColumns={{ base: '1fr', lg: '1fr 1fr minmax(0, 200px)', xl: '1fr 1fr minmax(0, 250px)' }}
>
<GridItem colSpan={ 3 } as="h2" textStyle="h4">
Company info
......@@ -48,8 +52,9 @@ const PublicTagsSubmitForm = ({ config }: Props) => {
<GridItem colSpan={ 3 } as="h2" textStyle="h4" mt={ 3 }>
Public tags/labels
<Hint label="Submit a public tag proposal for our moderation team to review" ml={ 1 }/>
<Hint label="Submit a public tag proposal for our moderation team to review" ml={ 1 } color="link"/>
</GridItem>
<PublicTagsSubmitFieldAddresses/>
<chakra.div bgColor="blue.100" h={ 20 }/>
<chakra.div bgColor="blue.100" h={ 20 }/>
<chakra.div bgColor="yellow.100" h={ 20 }/>
......
import { FormControl, GridItem, IconButton, Input } from '@chakra-ui/react';
import React from 'react';
import type { ControllerFieldState, ControllerRenderProps, UseFormStateReturn } from 'react-hook-form';
import { Controller, useFieldArray, useFormContext } from 'react-hook-form';
import type { FormFields } from '../types';
import { ADDRESS_REGEXP } from 'lib/validations/address';
import IconSvg from 'ui/shared/IconSvg';
import InputPlaceholder from 'ui/shared/InputPlaceholder';
const LIMIT = 10;
const PublicTagsSubmitFieldAddresses = () => {
const { control, formState } = useFormContext<FormFields>();
const { fields, insert, remove } = useFieldArray<FormFields, 'addresses'>({
name: 'addresses',
control,
});
const isDisabled = formState.isSubmitting;
const handleAddFieldClick = React.useCallback((event: React.MouseEvent) => {
const index = Number(event.currentTarget.getAttribute('data-index'));
if (!Object.is(index, NaN)) {
insert(index + 1, { hash: '' });
}
}, [ insert ]);
const handleRemoveFieldClick = React.useCallback((event: React.MouseEvent) => {
const index = Number(event.currentTarget.getAttribute('data-index'));
if (!Object.is(index, NaN)) {
remove(index);
}
}, [ remove ]);
const renderControl = React.useCallback(({ field, formState, fieldState }: {
field: ControllerRenderProps<FormFields, `addresses.${ number }.hash`>;
fieldState: ControllerFieldState;
formState: UseFormStateReturn<FormFields>;
}) => {
return (
<FormControl variant="floating" id={ field.name } isRequired size={{ base: 'md', lg: 'lg' }}>
<Input
{ ...field }
isInvalid={ Boolean(fieldState.error) }
isDisabled={ formState.isSubmitting }
required
autoComplete="off"
/>
<InputPlaceholder text="Smart contract / Address (0x...)" error={ fieldState.error }/>
</FormControl>
);
}, []);
return (
<>
{ fields.map((field, index) => {
return (
<React.Fragment key={ field.id }>
<GridItem colSpan={ 2 }>
<Controller
name={ `addresses.${ index }.hash` }
control={ control }
render={ renderControl }
rules={{ required: true, pattern: ADDRESS_REGEXP }}
/>
</GridItem>
<GridItem display="flex" alignItems="center" columnGap={ 5 }>
{ fields.length < LIMIT && !(fields.length > 1 && index === 0) && (
<IconButton
aria-label="add"
data-index={ index }
variant="outline"
w="30px"
h="30px"
onClick={ handleAddFieldClick }
icon={ <IconSvg name="plus" boxSize={ 5 }/> }
isDisabled={ isDisabled }
/>
) }
{ fields.length > 1 && (
<IconButton
aria-label="delete"
data-index={ index }
variant="outline"
w="30px"
h="30px"
onClick={ handleRemoveFieldClick }
icon={ <IconSvg name="minus" boxSize={ 5 }/> }
isDisabled={ isDisabled }
/>
) }
</GridItem>
</React.Fragment>
);
}) }
</>
);
};
export default React.memo(PublicTagsSubmitFieldAddresses);
......@@ -9,7 +9,11 @@ import InputPlaceholder from 'ui/shared/InputPlaceholder';
const PublicTagsSubmitFieldRequesterEmail = () => {
const { control } = useFormContext<FormFields>();
const { field, fieldState, formState } = useController<FormFields>({ control, name: 'requesterEmail', rules: { required: true, pattern: EMAIL_REGEXP } });
const { field, fieldState, formState } = useController<FormFields, 'requesterEmail'>({
control,
name: 'requesterEmail',
rules: { required: true, pattern: EMAIL_REGEXP },
});
const isDisabled = formState.isSubmitting;
......
......@@ -8,7 +8,7 @@ import InputPlaceholder from 'ui/shared/InputPlaceholder';
const PublicTagsSubmitFieldRequesterName = () => {
const { control } = useFormContext<FormFields>();
const { field, fieldState, formState } = useController<FormFields>({ control, name: 'requesterName', rules: { required: true } });
const { field, fieldState, formState } = useController<FormFields, 'requesterName'>({ control, name: 'requesterName', rules: { required: true } });
const isDisabled = formState.isSubmitting;
......
export interface FormFields {
requesterName: string;
requesterEmail: string;
addresses: Array<{ hash: string }>;
}
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