UNPKG

@gravityforms/components

Version:

UI components for use in Gravity Forms development. Both React and vanilla js flavors.

127 lines (118 loc) 3.65 kB
import { React, PropTypes } from '@gravityforms/libraries'; import Alert from '../modules/Alert'; import Box from '../elements/Box'; import Checkbox from '../elements/Checkbox'; import Heading from '../elements/Heading'; import Icon from '../elements/Icon'; import Input from '../elements/Input'; import InputGroup from '../modules/InputGroup'; import Label from '../elements/Label'; import BasicLink from '../elements/Link'; import Radio from '../elements/Radio'; import Select from '../elements/Select'; import Text from '../elements/Text'; import Textarea from '../elements/Textarea'; import Toggle from '../elements/Toggle'; const { Fragment, memo, useCallback } = React; /** * @module FormField * @description Renders a form field based on passed field data from the server. * * @since 3.1.0 * * @param {object} props Component props. * @param {string} props.id Field ID. * @param {object} props.field Field data. * @param {Function} props.setFieldData Passed handler for field changes if the field type supports it. * * @return {JSX.Element} The FormField component. */ const FormField = memo( ( { id, field, setFieldData } ) => { const handleChange = useCallback( ( value, e ) => { if ( e && e.target.type === 'radio' ) { setFieldData( e.target.name, e.target.value ); } else if ( field.props && field.props.name ) { setFieldData( field.props.name, value ); } }, [ field.props, setFieldData ] ); const renderNestedFields = ( fields ) => { if ( ! fields ) { return null; } return fields.map( ( nestedField, index ) => { const fieldId = `${ id }-${ index }`; return <FormField key={ fieldId } id={ fieldId } field={ nestedField } setFieldData={ setFieldData } />; } ); }; let component = null; if ( field.external ) { const External = field.component; const fieldProps = { ...field.props, onChange: field?.handle_change ? handleChange : undefined, }; component = <External { ...fieldProps } />; } else { const fieldProps = { id, ...field.props, }; switch ( field.component ) { case 'Alert': component = <Alert { ...fieldProps }>{ renderNestedFields( field.fields ) }</Alert>; break; case 'Box': component = <Box { ...fieldProps }>{ renderNestedFields( field.fields ) }</Box>; break; case 'Checkbox': component = <Checkbox { ...fieldProps } onChange={ handleChange } />; break; case 'Heading': component = <Heading { ...fieldProps } />; break; case 'Icon': component = <Icon { ...fieldProps } />; break; case 'Input': component = <Input { ...fieldProps } onChange={ handleChange } />; break; case 'InputGroup': component = <InputGroup { ...fieldProps } onChange={ handleChange } />; break; case 'Label': component = <Label { ...fieldProps } />; break; case 'Link': component = <BasicLink { ...fieldProps } />; break; case 'Radio': component = <Radio { ...fieldProps } onChange={ handleChange } />; break; case 'Select': component = <Select { ...fieldProps } onChange={ handleChange } />; break; case 'Text': component = <Text { ...fieldProps } />; break; case 'Textarea': component = <Textarea { ...fieldProps } onChange={ handleChange } />; break; case 'Toggle': component = <Toggle { ...fieldProps } onChange={ handleChange } />; break; default: component = null; } } return ( <Fragment> { component } </Fragment> ); } ); FormField.propTypes = { id: PropTypes.string, field: PropTypes.object, setFieldData: PropTypes.func, }; export default FormField;