mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
[skip ci] special style for native coin value field
This commit is contained in:
@@ -89,6 +89,7 @@ export interface SmartContractMethodInput {
|
||||
name: string;
|
||||
type: SmartContractMethodArgType;
|
||||
components?: Array<SmartContractMethodInput>;
|
||||
fieldType?: 'native_coin';
|
||||
}
|
||||
|
||||
export interface SmartContractMethodOutput extends SmartContractMethodInput {
|
||||
|
||||
@@ -6,6 +6,7 @@ import { useForm, FormProvider } from 'react-hook-form';
|
||||
import type { MethodFormFields, ContractMethodCallResult } from './types';
|
||||
import type { SmartContractMethodInput, SmartContractMethod } from 'types/api/contract';
|
||||
|
||||
import config from 'configs/app';
|
||||
import arrowIcon from 'icons/arrows/down-right.svg';
|
||||
import * as mixpanel from 'lib/mixpanel/index';
|
||||
|
||||
@@ -38,9 +39,10 @@ const ContractMethodCallable = <T extends SmartContractMethod>({ data, onSubmit,
|
||||
return [
|
||||
...('inputs' in data ? data.inputs : []),
|
||||
...('stateMutability' in data && data.stateMutability === 'payable' ? [ {
|
||||
name: 'value',
|
||||
name: `Send native ${ config.chain.currency.symbol }`,
|
||||
type: 'uint256' as const,
|
||||
internalType: 'uint256' as const,
|
||||
fieldType: 'native_coin' as const,
|
||||
} ] : []),
|
||||
];
|
||||
}, [ data ]);
|
||||
@@ -139,9 +141,11 @@ const ContractMethodCallable = <T extends SmartContractMethod>({ data, onSubmit,
|
||||
<ContractMethodCallableRow
|
||||
key={ fieldName }
|
||||
fieldName={ fieldName }
|
||||
fieldType={ input.fieldType }
|
||||
argName={ input.name }
|
||||
argType={ input.type }
|
||||
isDisabled={ isLoading }
|
||||
isOptional={ input.fieldType === 'native_coin' && inputs.length > 1 }
|
||||
onChange={ handleFormChange }
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Box } from '@chakra-ui/react';
|
||||
import { Box, useColorModeValue } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
|
||||
import type { MethodFormFields } from './types';
|
||||
import type { SmartContractMethodArgType } from 'types/api/contract';
|
||||
import type { SmartContractMethodArgType, SmartContractMethodInput } from 'types/api/contract';
|
||||
|
||||
import ContractMethodField from './ContractMethodField';
|
||||
import ContractMethodFieldArray from './ContractMethodFieldArray';
|
||||
@@ -11,16 +11,19 @@ import { ARRAY_REGEXP } from './utils';
|
||||
|
||||
interface Props {
|
||||
fieldName: string;
|
||||
fieldType?: SmartContractMethodInput['fieldType'];
|
||||
argName: string;
|
||||
argType: SmartContractMethodArgType;
|
||||
onChange: () => void;
|
||||
isDisabled: boolean;
|
||||
isGrouped?: boolean;
|
||||
isOptional?: boolean;
|
||||
}
|
||||
|
||||
const ContractMethodCallableRow = ({ argName, fieldName, argType, onChange, isDisabled, isGrouped }: Props) => {
|
||||
const ContractMethodCallableRow = ({ argName, fieldName, fieldType, argType, onChange, isDisabled, isGrouped, isOptional }: Props) => {
|
||||
const { control, getValues, setValue } = useFormContext<MethodFormFields>();
|
||||
const arrayTypeMatch = argType.match(ARRAY_REGEXP);
|
||||
const nativeCoinFieldBgColor = useColorModeValue('blackAlpha.50', 'whiteAlpha.100');
|
||||
|
||||
const content = arrayTypeMatch ? (
|
||||
<ContractMethodFieldArray
|
||||
@@ -36,27 +39,47 @@ const ContractMethodCallableRow = ({ argName, fieldName, argType, onChange, isDi
|
||||
) : (
|
||||
<ContractMethodField
|
||||
name={ fieldName }
|
||||
type={ fieldType }
|
||||
argType={ argType }
|
||||
placeholder={ argType }
|
||||
control={ control }
|
||||
setValue={ setValue }
|
||||
getValues={ getValues }
|
||||
isDisabled={ isDisabled }
|
||||
isOptional={ isOptional }
|
||||
onChange={ onChange }
|
||||
/>
|
||||
);
|
||||
|
||||
const isNativeCoinField = fieldType === 'native_coin';
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box
|
||||
position="relative"
|
||||
fontWeight={ 500 }
|
||||
lineHeight="20px"
|
||||
py={{ lg: '6px' }}
|
||||
pt={{ base: isNativeCoinField ? '6px' : 0, lg: isNativeCoinField ? '10px' : '6px' }}
|
||||
pb={{ lg: isNativeCoinField ? '10px' : '6px' }}
|
||||
fontSize="sm"
|
||||
color={ isGrouped ? 'text_secondary' : 'initial' }
|
||||
wordBreak="break-word"
|
||||
_before={ isNativeCoinField ? {
|
||||
content: `" "`,
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: '-6px',
|
||||
width: { base: 'calc(100% + 12px)', lg: 'calc(100% + 18px)' },
|
||||
height: { base: 'calc(100% + 8px)', lg: '100%' },
|
||||
bgColor: nativeCoinFieldBgColor,
|
||||
borderTopLeftRadius: 'base',
|
||||
borderTopRightRadius: { base: 'base', lg: 'none' },
|
||||
borderBottomRightRadius: 'none',
|
||||
borderBottomLeftRadius: { base: 'none', lg: 'base' },
|
||||
zIndex: -1,
|
||||
} : undefined }
|
||||
>
|
||||
{ argName } ({ argType })
|
||||
{ argName }{ isOptional ? '' : '*' } ({ argType })
|
||||
</Box>
|
||||
{ content }
|
||||
</>
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
Input,
|
||||
InputGroup,
|
||||
InputRightElement,
|
||||
useColorModeValue,
|
||||
} from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
import type { Control, ControllerRenderProps, FieldError, UseFormGetValues, UseFormSetValue, UseFormStateReturn } from 'react-hook-form';
|
||||
@@ -12,7 +13,7 @@ import { NumericFormat } from 'react-number-format';
|
||||
import { isAddress, isHex, getAddress } from 'viem';
|
||||
|
||||
import type { MethodFormFields } from './types';
|
||||
import type { SmartContractMethodArgType } from 'types/api/contract';
|
||||
import type { SmartContractMethodArgType, SmartContractMethodInput } from 'types/api/contract';
|
||||
|
||||
import ClearButton from 'ui/shared/ClearButton';
|
||||
|
||||
@@ -21,6 +22,7 @@ import { INT_REGEXP, BYTES_REGEXP, getIntBoundaries, formatBooleanValue } from '
|
||||
|
||||
interface Props {
|
||||
name: string;
|
||||
type?: SmartContractMethodInput['fieldType'];
|
||||
index?: number;
|
||||
groupName?: string;
|
||||
placeholder: string;
|
||||
@@ -29,11 +31,14 @@ interface Props {
|
||||
setValue: UseFormSetValue<MethodFormFields>;
|
||||
getValues: UseFormGetValues<MethodFormFields>;
|
||||
isDisabled: boolean;
|
||||
isOptional?: boolean;
|
||||
onChange: () => void;
|
||||
}
|
||||
|
||||
const ContractMethodField = ({ control, name, groupName, index, argType, placeholder, setValue, getValues, isDisabled, onChange }: Props) => {
|
||||
const ContractMethodField = ({ control, name, type, groupName, index, argType, placeholder, setValue, getValues, isDisabled, isOptional, onChange }: Props) => {
|
||||
const ref = React.useRef<HTMLInputElement>(null);
|
||||
const nativeCoinFieldBgColor = useColorModeValue('blackAlpha.50', 'whiteAlpha.100');
|
||||
const bgColor = useColorModeValue('white', 'black');
|
||||
|
||||
const handleClear = React.useCallback(() => {
|
||||
setValue(name, '');
|
||||
@@ -76,10 +81,28 @@ const ContractMethodField = ({ control, name, groupName, index, argType, placeho
|
||||
const hasZerosControl = intMatch && Number(intMatch.power) >= 64;
|
||||
|
||||
return (
|
||||
<Box w="100%">
|
||||
<Box
|
||||
w="100%"
|
||||
pt={{ lg: type === 'native_coin' ? 1 : 0 }}
|
||||
pb={{ base: type === 'native_coin' ? '6px' : 0, lg: type === 'native_coin' ? 1 : 0 }}
|
||||
position="relative"
|
||||
_before={ type === 'native_coin' ? {
|
||||
content: `" "`,
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
right: '-6px',
|
||||
width: { base: 'calc(100% + 12px)', lg: 'calc(100% + 6px)' },
|
||||
height: '100%',
|
||||
bgColor: nativeCoinFieldBgColor,
|
||||
borderTopLeftRadius: 'none',
|
||||
borderTopRightRadius: { lg: 'base' },
|
||||
borderBottomRightRadius: 'base',
|
||||
borderBottomLeftRadius: { base: 'base', lg: 'none' },
|
||||
zIndex: -1,
|
||||
} : undefined }
|
||||
>
|
||||
<FormControl
|
||||
id={ name }
|
||||
mb={{ base: 1, lg: 0 }}
|
||||
isDisabled={ isDisabled }
|
||||
>
|
||||
<InputGroup size="xs">
|
||||
@@ -93,10 +116,11 @@ const ContractMethodField = ({ control, name, groupName, index, argType, placeho
|
||||
} : {}) }
|
||||
ref={ ref }
|
||||
isInvalid={ Boolean(error) }
|
||||
required
|
||||
required={ !isOptional }
|
||||
placeholder={ placeholder }
|
||||
paddingRight={ hasZerosControl ? '120px' : '40px' }
|
||||
autoComplete="off"
|
||||
bgColor={ bgColor }
|
||||
/>
|
||||
<InputRightElement w="auto" right={ 1 }>
|
||||
{ typeof field.value === 'string' && field.value.replace('\n', '') && <ClearButton onClick={ handleClear } isDisabled={ isDisabled }/> }
|
||||
@@ -107,7 +131,7 @@ const ContractMethodField = ({ control, name, groupName, index, argType, placeho
|
||||
{ error && <Box color="error" fontSize="sm" mt={ 1 }>{ error.message }</Box> }
|
||||
</Box>
|
||||
);
|
||||
}, [ index, groupName, name, intMatch, isDisabled, placeholder, handleClear, handleAddZeroesClick ]);
|
||||
}, [ index, groupName, name, intMatch, type, nativeCoinFieldBgColor, isDisabled, isOptional, placeholder, bgColor, handleClear, handleAddZeroesClick ]);
|
||||
|
||||
const validate = React.useCallback((_value: string | Array<string>) => {
|
||||
if (typeof _value === 'object') {
|
||||
@@ -116,7 +140,7 @@ const ContractMethodField = ({ control, name, groupName, index, argType, placeho
|
||||
|
||||
const value = _value.replace('\n', '');
|
||||
|
||||
if (!value) {
|
||||
if (!value && !isOptional) {
|
||||
return 'Field is required';
|
||||
}
|
||||
|
||||
@@ -174,14 +198,14 @@ const ContractMethodField = ({ control, name, groupName, index, argType, placeho
|
||||
}
|
||||
|
||||
return true;
|
||||
}, [ bytesMatch, intMatch, argType ]);
|
||||
}, [ isOptional, argType, intMatch, bytesMatch ]);
|
||||
|
||||
return (
|
||||
<Controller
|
||||
name={ name }
|
||||
control={ control }
|
||||
render={ renderInput }
|
||||
rules={{ required: 'Field is required', validate }}
|
||||
rules={{ required: isOptional ? false : 'Field is required', validate }}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -86,7 +86,7 @@ const ContractMethodsAccordionItem = <T extends SmartContractMethod>({ data, ind
|
||||
<AccordionIcon/>
|
||||
</AccordionButton>
|
||||
</Element>
|
||||
<AccordionPanel pb={ 4 } pr={ 0 } pl="28px">
|
||||
<AccordionPanel pb={ 4 } pr={ 0 } pl="28px" w="calc(100% - 6px)">
|
||||
{ renderContent(data, index, id) }
|
||||
</AccordionPanel>
|
||||
</AccordionItem>
|
||||
|
||||
Reference in New Issue
Block a user