Skip to content
Open
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/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