Skip to content

Commit

Permalink
Forms: refactor Multiple and Single Choice fields (#39141)
Browse files Browse the repository at this point in the history
* Forms: Refactor Multiple Choice field

* changelog

* Add back deprecated version

* Refactor Single Choice field

* Fix wrong prop value for Multiple field

* Fix Button style

* Update projects/packages/forms/src/blocks/contact-form/util/merge-settings.js

Co-authored-by: Karen Attfield <[email protected]>

---------

Co-authored-by: Karen Attfield <[email protected]>
  • Loading branch information
monsieur-z and coder-karen authored Sep 16, 2024
1 parent 5d6173e commit ee3a5c5
Show file tree
Hide file tree
Showing 20 changed files with 381 additions and 308 deletions.
4 changes: 4 additions & 0 deletions projects/packages/forms/changelog/refactor-form-choice-fields
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: changed

Refactor Choice fields
180 changes: 19 additions & 161 deletions projects/packages/forms/src/blocks/contact-form/child-blocks.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { InnerBlocks, useBlockProps } from '@wordpress/block-editor';
import { createBlock, getBlockType } from '@wordpress/blocks';
import { createBlock } from '@wordpress/blocks';
import { Path } from '@wordpress/components';
import { Fragment } from '@wordpress/element';
import { __, _x } from '@wordpress/i18n';
Expand All @@ -9,11 +8,15 @@ import JetpackFieldCheckbox from './components/jetpack-field-checkbox';
import JetpackFieldConsent from './components/jetpack-field-consent';
import JetpackDatePicker from './components/jetpack-field-datepicker';
import JetpackDropdown from './components/jetpack-field-dropdown';
import JetpackFieldMultiple from './components/jetpack-field-multiple';
import { JetpackFieldOptionEdit } from './components/jetpack-field-option';
import JetpackFieldMultipleChoice from './components/jetpack-field-multiple-choice';
import JetpackFieldMultipleChoiceItem from './components/jetpack-field-multiple-choice/item';
import JetpackFieldSingleChoice from './components/jetpack-field-single-choice';
import JetpackFieldSingleChoiceItem from './components/jetpack-field-single-choice/item';
import JetpackFieldTextarea from './components/jetpack-field-textarea';
import { getIconColor } from './util/block-icons';
import { useFormWrapper } from './util/form';
import getFieldLabel from './util/get-field-label';
import mergeSettings from './util/merge-settings';
import renderMaterialIcon from './util/render-material-icon';

const FieldDefaults = {
Expand Down Expand Up @@ -229,26 +232,6 @@ const FieldDefaults = {
example: {},
};

const OptionFieldDefaults = {
apiVersion: 3,
category: 'contact-form',
edit: JetpackFieldOptionEdit,
attributes: {
label: {
type: 'string',
},
fieldType: {
enum: [ 'checkbox', 'radio' ],
default: 'checkbox',
},
},
supports: {
reusable: false,
html: false,
splitting: true,
},
};

const multiFieldV1 = fieldType => ( {
attributes: {
...FieldDefaults.attributes,
Expand All @@ -274,18 +257,14 @@ const multiFieldV1 = fieldType => ( {
save: () => null,
} );

const getFieldLabel = ( { attributes, name: blockName } ) => {
return null === attributes.label ? getBlockType( blockName ).title : attributes.label;
};

const editField = type => props => {
useFormWrapper( props );

return (
<JetpackField
clientId={ props.clientId }
type={ type }
label={ getFieldLabel( props ) }
label={ getFieldLabel( props.attributes, props.name ) }
required={ props.attributes.required }
requiredText={ props.attributes.requiredText }
setAttributes={ props.setAttributes }
Expand All @@ -299,27 +278,6 @@ const editField = type => props => {
);
};

const editMultiField = type => props => {
useFormWrapper( props );

return (
<JetpackFieldMultiple
className={ props.className }
clientId={ props.clientId }
label={ getFieldLabel( props ) }
required={ props.attributes.required }
requiredText={ props.attributes.requiredText }
options={ props.attributes.options }
setAttributes={ props.setAttributes }
type={ type }
isSelected={ props.isSelected }
id={ props.attributes.id }
width={ props.attributes.width }
attributes={ props.attributes }
/>
);
};

const EditTextarea = props => {
useFormWrapper( props );

Expand Down Expand Up @@ -631,121 +589,21 @@ export const childBlocks = [
},
},
{
name: 'field-option-checkbox',
settings: {
...OptionFieldDefaults,
parent: [ 'jetpack/field-checkbox-multiple' ],
title: __( 'Multiple Choice Option', 'jetpack-forms' ),
icon: renderMaterialIcon(
<>
<Path
d="M5.5 10.5H8.5V13.5H5.5V10.5ZM8.5 9H5.5C4.67157 9 4 9.67157 4 10.5V13.5C4 14.3284 4.67157 15 5.5 15H8.5C9.32843 15 10 14.3284 10 13.5V10.5C10 9.67157 9.32843 9 8.5 9ZM12 12.75H20V11.25H12V12.75Z"
fill={ getIconColor() }
/>
</>
),
},
},
{
name: 'field-option-radio',
settings: {
...OptionFieldDefaults,
parent: [ 'jetpack/field-radio' ],
title: __( 'Single Choice Option', 'jetpack-forms' ),
icon: renderMaterialIcon(
<Path
d="M7.5 13.5C6.67157 13.5 6 12.8284 6 12C6 11.1716 6.67157 10.5 7.5 10.5C8.32843 10.5 9 11.1716 9 12C9 12.8284 8.32843 13.5 7.5 13.5ZM4.5 12C4.5 13.6569 5.84315 15 7.5 15C9.15685 15 10.5 13.6569 10.5 12C10.5 10.3431 9.15685 9 7.5 9C5.84315 9 4.5 10.3431 4.5 12ZM12.5 12.75H20.5V11.25H12.5V12.75Z"
fill={ getIconColor() }
/>
),
},
name: JetpackFieldSingleChoice.name,
settings: mergeSettings( FieldDefaults, {
...JetpackFieldSingleChoice.settings,
deprecated: [ multiFieldV1( 'radio' ) ],
} ),
},
JetpackFieldSingleChoiceItem,
{
name: 'field-checkbox-multiple',
settings: {
...FieldDefaults,
title: __( 'Multiple Choice (Checkbox)', 'jetpack-forms' ),
keywords: [ __( 'Choose Multiple', 'jetpack-forms' ), __( 'Option', 'jetpack-forms' ) ],
description: __(
'Offer users a list of choices, and allow them to select multiple options.',
'jetpack-forms'
),
icon: renderMaterialIcon(
<Path
fill={ getIconColor() }
d="M7.0812 10.1419L10.6001 5.45005L9.40006 4.55005L6.91891 7.85824L5.53039 6.46972L4.46973 7.53038L7.0812 10.1419ZM12 8.5H20V7H12V8.5ZM12 17H20V15.5H12V17ZM8.5 14.5H5.5V17.5H8.5V14.5ZM5.5 13H8.5C9.32843 13 10 13.6716 10 14.5V17.5C10 18.3284 9.32843 19 8.5 19H5.5C4.67157 19 4 18.3284 4 17.5V14.5C4 13.6716 4.67157 13 5.5 13Z"
/>
),
edit: editMultiField( 'checkbox' ),
save: () => {
const blockProps = useBlockProps.save();

return (
<div { ...blockProps }>
<InnerBlocks.Content />
</div>
);
},
attributes: {
...FieldDefaults.attributes,
label: {
type: 'string',
default: 'Choose several options',
},
},
styles: [
{ name: 'list', label: 'List', isDefault: true },
{ name: 'button', label: 'Button' },
],
name: JetpackFieldMultipleChoice.name,
settings: mergeSettings( FieldDefaults, {
...JetpackFieldMultipleChoice.settings,
deprecated: [ multiFieldV1( 'checkbox' ) ],
},
},
{
name: 'field-radio',
settings: {
...FieldDefaults,
title: __( 'Single Choice (Radio)', 'jetpack-forms' ),
keywords: [
__( 'Choose', 'jetpack-forms' ),
__( 'Select', 'jetpack-forms' ),
__( 'Option', 'jetpack-forms' ),
],
description: __(
'Offer users a list of choices, and allow them to select a single option.',
'jetpack-forms'
),
icon: renderMaterialIcon(
<Fragment>
<Path
fill={ getIconColor() }
d="M4 7.75C4 9.40685 5.34315 10.75 7 10.75C8.65685 10.75 10 9.40685 10 7.75C10 6.09315 8.65685 4.75 7 4.75C5.34315 4.75 4 6.09315 4 7.75ZM20 8.5H12V7H20V8.5ZM20 17H12V15.5H20V17ZM7 17.75C6.17157 17.75 5.5 17.0784 5.5 16.25C5.5 15.4216 6.17157 14.75 7 14.75C7.82843 14.75 8.5 15.4216 8.5 16.25C8.5 17.0784 7.82843 17.75 7 17.75ZM4 16.25C4 17.9069 5.34315 19.25 7 19.25C8.65685 19.25 10 17.9069 10 16.25C10 14.5931 8.65685 13.25 7 13.25C5.34315 13.25 4 14.5931 4 16.25Z"
/>
</Fragment>
),
edit: editMultiField( 'radio' ),
save: () => {
const blockProps = useBlockProps.save();

return (
<div { ...blockProps }>
<InnerBlocks.Content />
</div>
);
},
attributes: {
...FieldDefaults.attributes,
label: {
type: 'string',
default: 'Choose one option',
},
},
styles: [
{ name: 'list', label: 'List', isDefault: true },
{ name: 'button', label: 'Button' },
],
deprecated: [ multiFieldV1( 'radio' ) ],
},
} ),
},
JetpackFieldMultipleChoiceItem,
{
name: 'field-select',
settings: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,50 +1,40 @@
import { InnerBlocks, useBlockProps } from '@wordpress/block-editor';
import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor';
import { compose, withInstanceId } from '@wordpress/compose';
import { useSelect } from '@wordpress/data';
import clsx from 'clsx';
import { useFormStyle } from '../util/form';
import { withSharedFieldAttributes } from '../util/with-shared-field-attributes';
import JetpackFieldControls from './jetpack-field-controls';
import JetpackFieldLabel from './jetpack-field-label';
import { useJetpackFieldStyles } from './use-jetpack-field-styles';
import { useFormStyle, useFormWrapper } from '../../util/form';
import getFieldLabel from '../../util/get-field-label';
import { withSharedFieldAttributes } from '../../util/with-shared-field-attributes';
import JetpackFieldControls from '../jetpack-field-controls';
import JetpackFieldLabel from '../jetpack-field-label';
import { useJetpackFieldStyles } from '../use-jetpack-field-styles';

const ALLOWED_BLOCKS = [ 'jetpack/field-option' ];
const JetpackFieldChoiceEdit = props => {
const { name, className, clientId, instanceId, setAttributes, isSelected, attributes, type } =
props;
const { required, requiredText, options, id, width } = attributes;

function JetpackFieldMultiple( props ) {
const {
className,
clientId,
id,
type,
instanceId,
required,
requiredText,
label,
setAttributes,
isSelected,
width,
options,
attributes,
} = props;
const formStyle = useFormStyle( clientId );
useFormWrapper( props );

const innerBlocks = useSelect(
select => {
return select( 'core/block-editor' ).getBlock( clientId ).innerBlocks;
},
select => select( 'core/block-editor' ).getBlock( clientId ).innerBlocks,
[ clientId ]
);

const classes = clsx( className, 'jetpack-field jetpack-field-multiple', {
'is-selected': isSelected,
'has-placeholder': ( options && options.length ) || innerBlocks.length,
} );

const formStyle = useFormStyle( clientId );
const { blockStyle } = useJetpackFieldStyles( attributes );
const blockProps = useBlockProps( {
id: `jetpack-field-multiple-${ instanceId }`,
className: classes,
style: blockStyle,
className: classes,
} );
const innerBlocksProps = useInnerBlocksProps( blockProps, {
defaultBlock: `jetpack/field-option-${ type }`,
template: [ [ `jetpack/field-option-${ type }` ] ],
templateInsertUpdatesSelection: true,
} );

return (
Expand All @@ -53,19 +43,13 @@ function JetpackFieldMultiple( props ) {
<JetpackFieldLabel
required={ required }
requiredText={ requiredText }
label={ label }
label={ getFieldLabel( attributes, name ) }
setAttributes={ setAttributes }
isSelected={ isSelected }
attributes={ attributes }
style={ formStyle }
/>
<div className="jetpack-field-multiple__list">
<InnerBlocks
allowedBlocks={ ALLOWED_BLOCKS }
template={ [ [ `jetpack/field-option-${ type }`, {} ] ] }
templateInsertUpdatesSelection={ true }
/>
</div>
<ul { ...innerBlocksProps } className="jetpack-field-multiple__list" />
</div>

<JetpackFieldControls
Expand All @@ -81,7 +65,7 @@ function JetpackFieldMultiple( props ) {
/>
</>
);
}
};

export default compose(
withSharedFieldAttributes( [
Expand All @@ -100,4 +84,4 @@ export default compose(
'borderColor',
] ),
withInstanceId
)( JetpackFieldMultiple );
)( JetpackFieldChoiceEdit );
Loading

0 comments on commit ee3a5c5

Please sign in to comment.