All files / app/ui/form DynamicFormField.tsx

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130    110x   110x   110x 110x 110x 110x 110x                                   110x 782x 782x 782x 782x 782x 782x 782x 782x 782x 782x 782x   782x 782x 782x 782x 782x 782x 782x   782x 782x   782x                                   782x 557x 96x 47x     49x         461x     1271x                                               782x                                       110x  
import { FormField as FormFieldType } from '@bigcommerce/checkout-sdk';
import { FieldProps } from 'formik';
import React, { memo, useCallback, useMemo, FunctionComponent, ReactNode } from 'react';
 
import { TranslatedString } from '../../locale';
 
import CheckboxGroupFormField from './CheckboxGroupFormField';
import DynamicFormFieldType from './DynamicFormFieldType';
import DynamicInput from './DynamicInput';
import FormField from './FormField';
import Label from './Label';
 
export interface DynamicFormFieldOption {
    code: string;
    name: string;
}
 
export interface DynamicFormFieldProps {
    field: FormFieldType;
    inputId?: string;
    extraClass?: string;
    autocomplete?: string;
    parentFieldName?: string;
    placeholder?: string;
    label?: ReactNode;
    onChange?(value: string | string[]): void;
}
 
const DynamicFormField: FunctionComponent<DynamicFormFieldProps>  = ({
    field: {
        fieldType,
        type,
        secret,
        name,
        label: fieldLabel,
        required,
        options,
        max,
        min,
        maxLength,
    },
    parentFieldName,
    onChange,
    placeholder,
    inputId,
    autocomplete,
    label,
    extraClass,
}) => {
    const fieldInputId = inputId || name;
    const fieldName = parentFieldName ? `${parentFieldName}.${name}` : name;
 
    const labelComponent = useMemo(() => (
        <Label htmlFor={ fieldInputId }>
            { label || fieldLabel }
            { !required &&
                <>
                    { ' ' }
                    <small className="optimizedCheckout-contentSecondary">
                        <TranslatedString id="common.optional_text" />
                    </small>
                </> }
        </Label>
    ), [
        fieldInputId,
        fieldLabel,
        required,
        label,
    ]);
 
    const dynamicFormFieldType = useMemo((): DynamicFormFieldType => {
        if (fieldType === 'text') {
            if (type === 'integer') {
                return DynamicFormFieldType.number;
            }
 
            return secret ?
                DynamicFormFieldType.password :
                DynamicFormFieldType.text;
        }
 
        return fieldType as DynamicFormFieldType;
    }, [fieldType, type, secret]);
 
    const renderInput = useCallback(({ field }: FieldProps<string>) => (
        <DynamicInput
            { ...field }
            autoComplete={ autocomplete }
            fieldType={ dynamicFormFieldType }
            id={ fieldInputId }
            max={ max }
            maxLength={ maxLength || undefined }
            min={ min }
            options={ options && options.items }
            placeholder={ placeholder || (options && options.helperLabel) }
            rows={ options && (options as any).rows }
        />
    ), [
        fieldInputId,
        max,
        maxLength,
        min,
        options,
        placeholder,
        dynamicFormFieldType,
        autocomplete,
    ]);
 
    return (
        <div className={ `dynamic-form-field ${extraClass}` }>
            { fieldType === DynamicFormFieldType.checkbox ?
                <CheckboxGroupFormField
                    id={ fieldInputId }
                    label={ labelComponent }
                    name={ fieldName }
                    onChange={ onChange }
                    options={ (options && options.items) || [] }
                /> :
                <FormField
                    input={ renderInput }
                    label={ labelComponent }
                    name={ fieldName }
                    onChange={ onChange }
                /> }
        </div>
    );
};
 
export default memo(DynamicFormField);