import { Flex } from '@chakra-ui/react'; import React from 'react'; import { useFormContext } from 'react-hook-form'; import type { ContractAbiItemInput } from '../types'; import ArrayButton from 'ui/shared/forms/ArrayButton'; import type { Props as AccordionProps } from './ContractMethodFieldAccordion'; import ContractMethodFieldAccordion from './ContractMethodFieldAccordion'; import ContractMethodFieldInput from './ContractMethodFieldInput'; import ContractMethodFieldInputTuple from './ContractMethodFieldInputTuple'; import ContractMethodFieldLabel from './ContractMethodFieldLabel'; import { getFieldLabel, matchArray, transformDataForArrayItem } from './utils'; interface Props extends Pick { data: ContractAbiItemInput; level: number; basePath: string; isDisabled: boolean; isArrayElement?: boolean; size?: number; } const ContractMethodFieldInputArray = ({ data, level, basePath, onAddClick, onRemoveClick, index: parentIndex, isDisabled, isArrayElement, }: Props) => { const { formState: { errors } } = useFormContext(); const fieldsWithErrors = Object.keys(errors); const isInvalid = fieldsWithErrors.some((field) => field.startsWith(basePath)); const arrayMatch = matchArray(data.type); const hasFixedSize = arrayMatch !== null && arrayMatch.size !== Infinity; const [ registeredIndices, setRegisteredIndices ] = React.useState(hasFixedSize ? Array(arrayMatch.size).fill(0).map((_, i) => i) : [ 0 ]); const handleAddButtonClick = React.useCallback((event: React.MouseEvent) => { event.preventDefault(); setRegisteredIndices((prev) => [ ...prev, prev[prev.length - 1] + 1 ]); }, []); const handleRemoveButtonClick = React.useCallback((event: React.MouseEvent) => { event.preventDefault(); const itemIndex = event.currentTarget.getAttribute('data-index'); if (itemIndex) { setRegisteredIndices((prev) => prev.filter((index) => index !== Number(itemIndex))); } }, [ ]); if (arrayMatch?.isNested) { return ( <> { registeredIndices.map((registeredIndex, index) => { const itemData = transformDataForArrayItem(data, index); const itemBasePath = `${ basePath }:${ registeredIndex }`; const itemIsInvalid = fieldsWithErrors.some((field) => field.startsWith(itemBasePath)); return ( 1 ? handleRemoveButtonClick : undefined } index={ registeredIndex } > ); }) } ); } const isTupleArray = arrayMatch?.itemType.includes('tuple'); if (isTupleArray) { const content = ( <> { registeredIndices.map((registeredIndex, index) => { const itemData = transformDataForArrayItem(data, index); return ( 1 ? handleRemoveButtonClick : undefined } index={ registeredIndex } isDisabled={ isDisabled } isOptional={ registeredIndices.length === 1 } /> ); }) } ); if (isArrayElement) { return content; } return ( { content } ); } // primitive value array return ( { !isArrayElement && } { registeredIndices.map((registeredIndex, index) => { const itemData = transformDataForArrayItem(data, index); return ( { !hasFixedSize && registeredIndices.length > 1 && } { !hasFixedSize && index === registeredIndices.length - 1 && } ); }) } ); }; export default React.memo(ContractMethodFieldInputArray);