Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | 1x 18x 12x 37x 12x 12x 12x 12x 1x 4x 4x 7x 10x 4x 10x 3x 4x 4x | import { childBlocks } from '../child-blocks.js';
type BlockLike = {
name?: string;
clientId?: string;
attributes?: Record< string, unknown >;
innerBlocks?: BlockLike[];
};
/**
* Determine whether a block is an input the visitor can be asked to fill in.
*
* Hidden fields and implicit consent checkboxes carry a `required` attribute but
* are never something a visitor answers, so they don't count.
*
* @param {string} fullName - Fully qualified block name, e.g. `jetpack/field-email`.
* @return {boolean} True when the block is a visitor-facing input.
*/
export const isInputWithRequiredField = ( fullName?: string ): boolean => {
if ( ! fullName || ! fullName.startsWith( 'jetpack/' ) ) return false;
const baseName = fullName.slice( 'jetpack/'.length );
const field = childBlocks.find( block => block.name === baseName );
// @ts-expect-error: childBlocks are defined in JS without explicit types.
// TS is inferring the type wrong. Fix is to update childBlocks to TS with types.
const hasRequired = !! field && field?.settings?.attributes?.required !== undefined;
const isHidden = field?.name === 'field-hidden';
const isImplicitConsent =
field?.name === 'field-consent' &&
// @ts-expect-error: childBlocks are defined in JS without explicit types.
// TS is inferring the type wrong. Fix is to update childBlocks to TS with types.
field?.settings?.attributes?.consentType !== 'explicit';
return hasRequired && ! isHidden && ! isImplicitConsent;
};
/**
* Collect the visitor-facing input fields anywhere inside a form.
*
* Recurses, because a multi-step form keeps its fields inside step blocks rather
* than directly under the form.
*
* @param {Array} blocks - Blocks to search, typically a form's inner blocks.
* @return {Array} Every input block found, in document order.
*/
export const getInputFields = ( blocks: BlockLike[] = [] ): BlockLike[] => {
const inputFields: BlockLike[] = [];
const findInputFields = ( blockList: BlockLike[] ) => {
blockList.forEach( block => {
if ( isInputWithRequiredField( block.name ) ) {
inputFields.push( block );
}
if ( block.innerBlocks && block.innerBlocks.length > 0 ) {
findInputFields( block.innerBlocks );
}
} );
};
findInputFields( blocks );
return inputFields;
};
export default getInputFields;
|