Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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/add-forms-name-variations
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Forms: add first and last name variations.
3 changes: 3 additions & 0 deletions projects/packages/forms/src/blocks/field-name/edit.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { __ } from '@wordpress/i18n';
import JetpackField from '../shared/components/jetpack-field';
import useFormWrapper from '../shared/hooks/use-form-wrapper';
import useNameLabelSync from './hooks/use-name-label-sync';

export default function NameFieldEdit( props ) {
useFormWrapper( props );

useNameLabelSync( { clientId: props.clientId, id: props.attributes?.id } );

return (
<JetpackField
clientId={ props.clientId }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { store as blockEditorStore } from '@wordpress/block-editor';
import { useSelect, useDispatch } from '@wordpress/data';
import { useEffect, useRef } from '@wordpress/element';
import {
FIRST_NAME_ID,
LAST_NAME_ID,
DEFAULT_FIRST_NAME_LABEL,
DEFAULT_LAST_NAME_LABEL,
DEFAULT_NAME_LABEL,
} from '../variations';

const isKnownId = id => id === FIRST_NAME_ID || id === LAST_NAME_ID;

const getDefaultLabelForId = id => {
if ( id === FIRST_NAME_ID ) return DEFAULT_FIRST_NAME_LABEL;
if ( id === LAST_NAME_ID ) return DEFAULT_LAST_NAME_LABEL;
return DEFAULT_NAME_LABEL;
};

/**
* Sync the nested label text with the Name field's variation id when users transform
* between known variations (first-name/last-name).
*
* @param {object} params - Parameters.
* @param {string} params.clientId - Block clientId for the Name field
* @param {string} params.id - Current variation id (e.g., 'first-name' | 'last-name')
*/
export default function useNameLabelSync( { clientId, id } ) {
const prevIdRef = useRef( id );
const { updateBlockAttributes } = useDispatch( blockEditorStore );

const labelClientId = useSelect(
select => {
const block = select( blockEditorStore ).getBlock( clientId );
const labelBlock = block?.innerBlocks?.find( b => b.name === 'jetpack/label' );
return labelBlock?.clientId;
},
[ clientId ]
);

const currentLabel = useSelect(
select => {
return labelClientId
? select( blockEditorStore ).getBlockAttributes( labelClientId )?.label
: undefined;
},
[ labelClientId ]
);

useEffect( () => {
const newId = id;
const prevId = prevIdRef.current;

if ( ! labelClientId ) {
prevIdRef.current = newId;
return;
}

// Handle transforms between known variations.
if ( isKnownId( newId ) && newId !== prevId ) {
const nextDefault = getDefaultLabelForId( newId );
// Ensure the parent block id matches the variation id.
if ( newId ) {
updateBlockAttributes( clientId, { id: newId } );
}
// Always set the label to the default for the selected variation.
updateBlockAttributes( labelClientId, { label: nextDefault } );
}

// Handle transforms from a known variation back to the base Name (no id).
const becameBase = isKnownId( prevId ) && ( newId === undefined || newId === '' );
if ( becameBase ) {
// Clear the parent block id when returning to base.
updateBlockAttributes( clientId, { id: '' } );
// Always set the label back to the base default.
updateBlockAttributes( labelClientId, { label: DEFAULT_NAME_LABEL } );
}

prevIdRef.current = newId;
}, [ id, clientId, labelClientId, currentLabel, updateBlockAttributes ] );
}
2 changes: 2 additions & 0 deletions projects/packages/forms/src/blocks/field-name/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { getIconColor } from '../shared/util/block-icons';
import deprecated from './deprecated';
import edit from './edit';
import save from './save';
import variations from './variations';

const name = 'field-name';
const settings = {
Expand All @@ -18,6 +19,7 @@ const settings = {
<Path d="M8.25 11.5C9.63071 11.5 10.75 10.3807 10.75 9C10.75 7.61929 9.63071 6.5 8.25 6.5C6.86929 6.5 5.75 7.61929 5.75 9C5.75 10.3807 6.86929 11.5 8.25 11.5ZM8.25 10C8.80228 10 9.25 9.55228 9.25 9C9.25 8.44772 8.80228 8 8.25 8C7.69772 8 7.25 8.44772 7.25 9C7.25 9.55228 7.69772 10 8.25 10ZM13 15.5V17.5H11.5V15.5C11.5 14.8096 10.9404 14.25 10.25 14.25H6.25C5.55964 14.25 5 14.8096 5 15.5V17.5H3.5V15.5C3.5 13.9812 4.73122 12.75 6.25 12.75H10.25C11.7688 12.75 13 13.9812 13 15.5ZM20.5 11H14.5V9.5H20.5V11ZM20.5 14.5H14.5V13H20.5V14.5Z" />
),
},
variations,
edit,
deprecated,
save,
Expand Down
67 changes: 67 additions & 0 deletions projects/packages/forms/src/blocks/field-name/variations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { Path } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import renderMaterialIcon from '../shared/components/render-material-icon';
import { getIconColor } from '../shared/util/block-icons';

const icon = {
foreground: getIconColor(),
src: renderMaterialIcon(
<Path d="M8.25 11.5C9.63071 11.5 10.75 10.3807 10.75 9C10.75 7.61929 9.63071 6.5 8.25 6.5C6.86929 6.5 5.75 7.61929 5.75 9C5.75 10.3807 6.86929 11.5 8.25 11.5ZM8.25 10C8.80228 10 9.25 9.55228 9.25 9C9.25 8.44772 8.80228 8 8.25 8C7.69772 8 7.25 8.44772 7.25 9C7.25 9.55228 7.69772 10 8.25 10ZM13 15.5V17.5H11.5V15.5C11.5 14.8096 10.9404 14.25 10.25 14.25H6.25C5.55964 14.25 5 14.8096 5 15.5V17.5H3.5V15.5C3.5 13.9812 4.73122 12.75 6.25 12.75H10.25C11.7688 12.75 13 13.9812 13 15.5ZM20.5 11H14.5V9.5H20.5V11ZM20.5 14.5H14.5V13H20.5V14.5Z" />
),
};

export const FIRST_NAME_ID = 'first-name';
export const LAST_NAME_ID = 'last-name';

export const DEFAULT_FIRST_NAME_LABEL = __( 'First name', 'jetpack-forms' );
export const DEFAULT_LAST_NAME_LABEL = __( 'Last name', 'jetpack-forms' );
export const DEFAULT_NAME_LABEL = __( 'Name', 'jetpack-forms' );

const variations = [
{
name: 'name',
title: DEFAULT_NAME_LABEL,
description: __( 'Collect the visitor’s name.', 'jetpack-forms' ),
icon,
scope: [ 'transform' ],
attributes: {
id: '',
},
innerBlocks: [
[ 'jetpack/label', { label: DEFAULT_NAME_LABEL } ],
[ 'jetpack/input', { type: 'text' } ],
],
},
{
name: FIRST_NAME_ID,
title: DEFAULT_FIRST_NAME_LABEL,
description: __( 'Collect the visitor’s first name.', 'jetpack-forms' ),
icon,
scope: [ 'inserter', 'transform' ],
isActive: [ 'id' ],
attributes: {
id: FIRST_NAME_ID,
},
innerBlocks: [
[ 'jetpack/label', { label: DEFAULT_FIRST_NAME_LABEL } ],
[ 'jetpack/input', { type: 'text' } ],
],
},
{
name: LAST_NAME_ID,
title: DEFAULT_LAST_NAME_LABEL,
description: __( 'Collect the visitor’s last name.', 'jetpack-forms' ),
icon,
scope: [ 'inserter', 'transform' ],
isActive: [ 'id' ],
attributes: {
id: LAST_NAME_ID,
},
innerBlocks: [
[ 'jetpack/label', { label: DEFAULT_LAST_NAME_LABEL } ],
[ 'jetpack/input', { type: 'text' } ],
],
},
];

export default variations;
4 changes: 4 additions & 0 deletions projects/plugins/jetpack/changelog/add-forms-name-variations
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: enhancement

Forms: add first and last name variations.
Loading