modules_InputGroup_index.js
import { React, PropTypes, classnames } from '@gravityforms/libraries';
import { ConditionalWrapper } from '@gravityforms/react-utils';
import { spacerClasses, uniqueId } from '@gravityforms/utils';
import Checkbox from '../../elements/Checkbox';
import Radio from '../../elements/Radio';
const { forwardRef, useState } = React;
/**
* @module InputGroup
* @description A inputgroup component that wraps checkboxes or radios and handles their state changes as one
* aggregate.
*
* @since 1.1.15
*
* @param {object} props Component props.
* @param {JSX.Element} props.children React element children.
* @param {boolean} props.childrenBelow Render children below or above group if found?
* @param {object} props.customAttributes Custom attributes for the component.
* @param {string|Array|object} props.customClasses Custom classes for the component.
* @param {Array} props.data The data for the inputs.
* @param {string} props.id The id of the input group.
* @param {string} props.initialValue The initial value of the input group if input type is radio.
* @param {string} props.inputType The input type, one of `radio` or `checkbox`.
* @param {Function} props.onChange On change function handler.
* @param {string|number|Array|object} props.spacing The spacing for the component, as a string, number, array, or object.
* @param {string} props.tagName Tagname for the container.
* @param {boolean} props.useWrapper Whether to use a wrapper around the inputs or not.
* @param {object} props.wrapperAttributes Custom attributes for the wrapper component.
* @param {string} props.wrapperTagName Tagname for the wrapper.
* @param {object|null} ref Ref to the component.
*
* @return {JSX.Element} The InputGroup component.
*
* @example
* import InputGroup from '@gravityforms/components/react/admin/modules/InputGroup';
*
* return (
* <InputGroup
* id="setup-wizard-form-types"
* data={ [ { ...input1Data }, { ...input2Data } ] }
* onChange={ () => { handleInputChange(); } }
* useWrapper={ true }
* />
* );
*
*/
const InputGroup = forwardRef( ( {
children = null,
childrenBelow = true,
customAttributes = {},
customClasses = [],
data = [],
id = '',
initialValue = '',
inputType = 'checkbox',
onChange = () => {},
spacing = '',
tagName = 'div',
useWrapper = false,
wrapperAttributes = {},
wrapperTagName = 'div',
}, ref ) => {
const [ value, setValue ] = useState( initialValue );
const componentProps = {
className: classnames( {
'gform-input-group': true,
...spacerClasses( spacing ),
}, customClasses ),
...customAttributes,
};
const inputId = id || uniqueId( 'input-group' );
const InputContainer = inputType === 'checkbox' ? Checkbox : Radio;
const handleOnChange = ( checked, e ) => {
if ( inputType === 'radio' ) {
setValue( e.target.value );
}
onChange( checked, e );
};
const getWrapper = ( ch ) => {
const Wrapper = wrapperTagName;
const {
customClasses: wrapperCustomClasses,
...restWrapperAttributes
} = wrapperAttributes;
const wrapperProps = {
...restWrapperAttributes,
className: classnames(
[ 'gform-input-group__wrapper' ],
wrapperCustomClasses || [],
),
};
return <Wrapper { ...wrapperProps }>{ ch }</Wrapper>;
};
const Container = tagName;
return (
<Container { ...componentProps } ref={ ref }>
{ ! childrenBelow && children }
{
data.map( ( props, index ) => {
const inputProps = {
...props,
onChange: handleOnChange,
};
if ( inputType === 'radio' ) {
inputProps.externalControl = true;
inputProps.externalChecked = props.value === value;
}
return (
<ConditionalWrapper
condition={ useWrapper }
key={ `${ inputId }-${ index }` }
wrapper={ getWrapper }
>
<InputContainer { ...inputProps } />
</ConditionalWrapper>
);
} )
}
{ childrenBelow && children }
</Container>
);
} );
InputGroup.propTypes = {
children: PropTypes.oneOfType( [
PropTypes.arrayOf( PropTypes.node ),
PropTypes.node,
] ),
childrenBelow: PropTypes.bool,
customAttributes: PropTypes.object,
customClasses: PropTypes.oneOfType( [
PropTypes.string,
PropTypes.array,
PropTypes.object,
] ),
data: PropTypes.array,
id: PropTypes.string,
inputType: PropTypes.string,
onChange: PropTypes.func,
spacing: PropTypes.oneOfType( [
PropTypes.string,
PropTypes.number,
PropTypes.array,
PropTypes.object,
] ),
tagName: PropTypes.string,
useWrapper: PropTypes.bool,
wrapperAttributes: PropTypes.object,
wrapperTagName: PropTypes.string,
};
InputGroup.displayName = 'InputGroup';
export default InputGroup;