Skip to content

Commit d6ad7ae

Browse files
committed
Update label/id when transforming
1 parent 891a6ec commit d6ad7ae

File tree

3 files changed

+113
-8
lines changed

3 files changed

+113
-8
lines changed

projects/packages/forms/src/blocks/field-name/edit.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import { __ } from '@wordpress/i18n';
22
import JetpackField from '../shared/components/jetpack-field';
33
import useFormWrapper from '../shared/hooks/use-form-wrapper';
4+
import useNameLabelSync from './hooks/use-name-label-sync';
45

56
export default function NameFieldEdit( props ) {
67
useFormWrapper( props );
78

9+
useNameLabelSync( { clientId: props.clientId, id: props.attributes?.id } );
10+
811
return (
912
<JetpackField
1013
clientId={ props.clientId }
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { store as blockEditorStore } from '@wordpress/block-editor';
2+
import { useSelect, useDispatch } from '@wordpress/data';
3+
import { useEffect, useRef } from '@wordpress/element';
4+
import {
5+
FIRST_NAME_ID,
6+
LAST_NAME_ID,
7+
DEFAULT_FIRST_NAME_LABEL,
8+
DEFAULT_LAST_NAME_LABEL,
9+
DEFAULT_NAME_LABEL,
10+
} from '../variations';
11+
12+
const isKnownId = id => id === FIRST_NAME_ID || id === LAST_NAME_ID;
13+
14+
const getDefaultLabelForId = id => {
15+
if ( id === FIRST_NAME_ID ) return DEFAULT_FIRST_NAME_LABEL;
16+
if ( id === LAST_NAME_ID ) return DEFAULT_LAST_NAME_LABEL;
17+
return DEFAULT_NAME_LABEL;
18+
};
19+
20+
/**
21+
* Sync the nested label text with the Name field's variation id when users transform
22+
* between known variations (first-name/last-name).
23+
*
24+
* @param {object} params - Parameters.
25+
* @param {string} params.clientId - Block clientId for the Name field
26+
* @param {string} params.id - Current variation id (e.g., 'first-name' | 'last-name')
27+
*/
28+
export default function useNameLabelSync( { clientId, id } ) {
29+
const prevIdRef = useRef( id );
30+
const { updateBlockAttributes } = useDispatch( blockEditorStore );
31+
32+
const labelClientId = useSelect(
33+
select => {
34+
const block = select( blockEditorStore ).getBlock( clientId );
35+
const labelBlock = block?.innerBlocks?.find( b => b.name === 'jetpack/label' );
36+
return labelBlock?.clientId;
37+
},
38+
[ clientId ]
39+
);
40+
41+
const currentLabel = useSelect(
42+
select => {
43+
return labelClientId
44+
? select( blockEditorStore ).getBlockAttributes( labelClientId )?.label
45+
: undefined;
46+
},
47+
[ labelClientId ]
48+
);
49+
50+
useEffect( () => {
51+
const newId = id;
52+
const prevId = prevIdRef.current;
53+
54+
if ( ! labelClientId ) {
55+
prevIdRef.current = newId;
56+
return;
57+
}
58+
59+
// Handle transforms between known variations.
60+
if ( isKnownId( newId ) && newId !== prevId ) {
61+
const nextDefault = getDefaultLabelForId( newId );
62+
// Ensure the parent block id matches the variation id.
63+
if ( newId ) {
64+
updateBlockAttributes( clientId, { id: newId } );
65+
}
66+
// Always set the label to the default for the selected variation.
67+
updateBlockAttributes( labelClientId, { label: nextDefault } );
68+
}
69+
70+
// Handle transforms from a known variation back to the base Name (no id).
71+
const becameBase = isKnownId( prevId ) && ( newId === undefined || newId === '' );
72+
if ( becameBase ) {
73+
// Clear the parent block id when returning to base.
74+
updateBlockAttributes( clientId, { id: '' } );
75+
// Always set the label back to the base default.
76+
updateBlockAttributes( labelClientId, { label: DEFAULT_NAME_LABEL } );
77+
}
78+
79+
prevIdRef.current = newId;
80+
}, [ id, clientId, labelClientId, currentLabel, updateBlockAttributes ] );
81+
}

projects/packages/forms/src/blocks/field-name/variations.js

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,34 +10,55 @@ const icon = {
1010
),
1111
};
1212

13+
export const FIRST_NAME_ID = 'first-name';
14+
export const LAST_NAME_ID = 'last-name';
15+
16+
export const DEFAULT_FIRST_NAME_LABEL = __( 'First name', 'jetpack-forms' );
17+
export const DEFAULT_LAST_NAME_LABEL = __( 'Last name', 'jetpack-forms' );
18+
export const DEFAULT_NAME_LABEL = __( 'Name', 'jetpack-forms' );
19+
1320
const variations = [
1421
{
15-
name: 'first-name',
16-
title: __( 'First name', 'jetpack-forms' ),
22+
name: 'name',
23+
title: DEFAULT_NAME_LABEL,
24+
description: __( 'Collect the visitor’s name.', 'jetpack-forms' ),
25+
icon,
26+
scope: [ 'transform' ],
27+
attributes: {
28+
id: '',
29+
},
30+
innerBlocks: [
31+
[ 'jetpack/label', { label: DEFAULT_NAME_LABEL } ],
32+
[ 'jetpack/input', { type: 'text' } ],
33+
],
34+
},
35+
{
36+
name: FIRST_NAME_ID,
37+
title: DEFAULT_FIRST_NAME_LABEL,
1738
description: __( 'Collect the visitor’s first name.', 'jetpack-forms' ),
1839
icon,
1940
scope: [ 'inserter', 'transform' ],
2041
isActive: [ 'id' ],
2142
attributes: {
22-
id: 'first-name',
43+
id: FIRST_NAME_ID,
2344
},
2445
innerBlocks: [
25-
[ 'jetpack/label', { label: __( 'First name', 'jetpack-forms' ) } ],
46+
[ 'jetpack/label', { label: DEFAULT_FIRST_NAME_LABEL } ],
2647
[ 'jetpack/input', { type: 'text' } ],
2748
],
2849
},
2950
{
30-
name: 'last-name',
31-
title: __( 'Last name', 'jetpack-forms' ),
51+
name: LAST_NAME_ID,
52+
title: DEFAULT_LAST_NAME_LABEL,
3253
description: __( 'Collect the visitor’s last name.', 'jetpack-forms' ),
3354
icon,
3455
scope: [ 'inserter', 'transform' ],
3556
isActive: [ 'id' ],
3657
attributes: {
37-
id: 'last-name',
58+
id: LAST_NAME_ID,
3859
},
3960
innerBlocks: [
40-
[ 'jetpack/label', { label: __( 'Last name', 'jetpack-forms' ) } ],
61+
[ 'jetpack/label', { label: DEFAULT_LAST_NAME_LABEL } ],
4162
[ 'jetpack/input', { type: 'text' } ],
4263
],
4364
},

0 commit comments

Comments
 (0)