Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Forms: refactor Multiple and Single Choice fields #39141

Merged
merged 7 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading