/** * External dependencies */ import { Button, CheckboxControl } from '@wordpress/components'; import { Component } from '@wordpress/element'; import { compose } from '@wordpress/compose'; import PropTypes from 'prop-types'; import { uniqueId } from 'lodash'; import { withDispatch } from '@wordpress/data'; /** * Internal dependencies */ import './setting.scss'; class Setting extends Component { constructor( props ) { super( props ); this.state = { disabled: false, }; } renderInput = () => { const { handleChange, name, inputText, inputType, options, value, component, } = this.props; const { disabled } = this.state; switch ( inputType ) { case 'checkboxGroup': return options.map( ( optionGroup ) => optionGroup.options.length > 0 && (
{ optionGroup.label && ( { optionGroup.label } ) } { this.renderCheckboxOptions( optionGroup.options ) }
) ); case 'checkbox': return this.renderCheckboxOptions( options ); case 'button': return ( ); case 'component': const SettingComponent = component; return ( ); case 'text': default: const id = uniqueId( name ); return ( ); } }; handleInputCallback = () => { const { createNotice, callback } = this.props; if ( typeof callback !== 'function' ) { return; } return new Promise( ( resolve, reject ) => { this.setState( { disabled: true } ); callback( resolve, reject, createNotice ); } ) .then( () => { this.setState( { disabled: false } ); } ) .catch( () => { this.setState( { disabled: false } ); } ); }; renderCheckboxOptions( options ) { const { handleChange, name, value } = this.props; const { disabled } = this.state; return options.map( ( option ) => { return ( handleChange( { target: { checked, name, type: 'checkbox', value: option.value, }, } ) } disabled={ disabled } /> ); } ); } render() { const { helpText, label, name } = this.props; return (
{ label }
{ this.renderInput() } { helpText && ( { helpText } ) }
); } } Setting.propTypes = { /** * A callback that is fired after actionable items, such as buttons. */ callback: PropTypes.func, /** * Function assigned to the onChange of all inputs. */ handleChange: PropTypes.func.isRequired, /** * Optional help text displayed underneath the setting. */ helpText: PropTypes.oneOfType( [ PropTypes.string, PropTypes.array ] ), /** * Text used as placeholder or button text in the input area. */ inputText: PropTypes.string, /** * Type of input to use; defaults to a text input. */ inputType: PropTypes.oneOf( [ 'button', 'checkbox', 'checkboxGroup', 'text', 'component', ] ), /** * Label used for describing the setting. */ label: PropTypes.string.isRequired, /** * Setting slug applied to input names. */ name: PropTypes.string.isRequired, /** * Array of options used for when the `inputType` allows multiple selections. */ options: PropTypes.arrayOf( PropTypes.shape( { /** * Input value for this option. */ value: PropTypes.string, /** * Label for this option or above a group for a group `inputType`. */ label: PropTypes.string, /** * Description used for screen readers. */ description: PropTypes.string, /** * Key used for a group `inputType`. */ key: PropTypes.string, /** * Nested options for a group `inputType`. */ options: PropTypes.array, } ) ), /** * The string value used for the input or array of items if the input allows multiselection. */ value: PropTypes.oneOfType( [ PropTypes.string, PropTypes.array ] ), }; export default compose( withDispatch( ( dispatch ) => { const { createNotice } = dispatch( 'core/notices' ); return { createNotice }; } ) )( Setting );