/** * External dependencies */ import { createElement, useMemo } from '@wordpress/element'; import { Button } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ import { Form } from '../index'; import { TextField, PasswordField, CheckboxField, SelectField, } from './field-types'; import { Field, FormInputProps } from './types'; type DynamicFormProps = { fields: Field[] | { [ key: string ]: Field }; validate: ( values: Record< string, string > ) => Record< string, string >; isBusy?: boolean; onSubmit?: ( values: Record< string, string > ) => void; onChange?: ( value: Record< string, string >, values: Record< string, string >[], result: boolean ) => void; submitLabel?: string; }; const fieldTypeMap = { text: TextField, password: PasswordField, checkbox: CheckboxField, select: SelectField, default: TextField, }; const getInitialConfigValues = ( fields: Field[] ) => fields.reduce( ( data, field ) => ( { ...data, [ field.id ]: field.type === 'checkbox' ? field.value === 'yes' : field.value, } ), {} ); export const DynamicForm: React.FC< DynamicFormProps > = ( { fields: baseFields = [], isBusy = false, onSubmit = () => {}, onChange = () => {}, validate = () => ( {} ), submitLabel = __( 'Proceed', 'woocommerce-admin' ), } ) => { // Support accepting fields in the format provided by the API (object), but transform to Array const fields = baseFields instanceof Array ? baseFields : Object.values( baseFields ); const initialValues = useMemo( () => getInitialConfigValues( fields ), [ fields, ] ); return (
{ ( { getInputProps, handleSubmit, }: { getInputProps: ( name: string ) => FormInputProps; handleSubmit: () => void; } ) => { return (
{ fields.map( ( field ) => { if ( field.type && ! ( field.type in fieldTypeMap ) ) { /* eslint-disable no-console */ console.warn( `Field type of ${ field.type } not current supported in DynamicForm component` ); /* eslint-enable no-console */ return null; } const Control = fieldTypeMap[ field.type || 'default' ]; return ( ); } ) }
); } }
); };