corvée(dépendances) ajoute Carbon Fields

This commit is contained in:
gcch 2024-08-09 18:45:01 +02:00
commit 62368587e5
459 changed files with 72750 additions and 26 deletions

View file

@ -0,0 +1,175 @@
/**
* External dependencies.
*/
import of from 'callbag-of';
import takeUntil from 'callbag-take-until';
import distinctUntilChanged from 'callbag-distinct-until-changed';
import { pipe, merge } from 'callbag-basics';
import { select } from '@wordpress/data';
import {
get,
map,
find,
some,
pick,
keyBy,
repeat,
isEqual,
fromPairs,
difference,
startsWith
} from 'lodash';
/**
* Carbon Fields dependencies.
*/
import { fromSelector, withConditionalLogic } from '@carbon-fields/core';
/**
* Returns all root fields from the given holder
* while excluding some of them.
*
* @param {Object} fieldsHolder
* @param {Object} allFields
* @param {string[]} excludedIds
* @return {Object[]}
*/
function getFieldsFromFieldsHolder( fieldsHolder, allFields, excludedIds = [] ) {
if ( typeof fieldsHolder === 'undefined' ) {
return [];
}
return pick( allFields, difference( map( fieldsHolder.fields, 'id' ), excludedIds ) );
}
/**
* Adds the `parent.` parent prefix to field's name.
*
* @param {Object[]} fields
* @param {number} depth
* @return {Array[]}
*/
function mapParentPrefix( fields, depth = 0 ) {
return map( fields, ( field ) => ( [
field.id,
`${ repeat( 'parent.', depth ) }${ field.base_name }`
] ) );
}
/**
* The function used to track dependencies required
* by conditional logic.
*
* @param {Object} props
* @param {Object} component
* @return {Object}
*/
function input( props, component ) {
const { getFieldsByContainerId } = select( 'carbon-fields/metaboxes' );
return pipe(
merge(
of( getFieldsByContainerId( props.containerId ) ),
fromSelector( getFieldsByContainerId, props.containerId )
),
takeUntil( component.unmount ),
distinctUntilChanged( isEqual )
);
}
/**
* The function that provides the data that needs to be
* evaluated by conditional logic.
*
* @param {Object} props
* @param {Object} fields
* @return {Object}
*/
function output( props, fields ) {
fields = keyBy( fields, 'id' );
const container = select( 'carbon-fields/metaboxes' ).getContainerById( props.containerId );
const isTopLevelField = some( container.fields, [ 'id', props.id ] );
let siblingFields = [];
if ( isTopLevelField ) {
siblingFields = getFieldsFromFieldsHolder( container, fields, [ props.id ] );
siblingFields = mapParentPrefix( siblingFields );
} else {
const fieldName = props.name.replace( new RegExp( `^${ window.cf.config.compactInputKey }\\[(.+?)\\]` ), '$1' );
// Get the root field.
const rootField = find( fields, ( field ) => {
return field.container_id === props.containerId
&& startsWith( fieldName, field.name );
} );
// Get the hierarchy.
let path = fieldName.split( /\[|\]/g );
// Remove the chunk with name of root field
// because we already have it.
path.shift();
// Remove any chunks that don't have a value.
path = path.filter( ( chunk ) => chunk !== '' );
// Remove the chunk with name of field
// because we don't needed it.
path.pop();
// Keep reference to the depth
// so we can add the `parent.` prefix.
let depth = path.reduce( ( accumulator, chunk ) => {
return isNaN( chunk )
? accumulator + 1
: accumulator;
}, 0 );
// Collect fields that are siblings of root field.
siblingFields = getFieldsFromFieldsHolder( container, fields, [ rootField.id ] );
siblingFields = mapParentPrefix( siblingFields, depth + 1 );
// Keep reference to the full path of the field.
let pathPrefix = `${ rootField.id }.value`;
while ( path.length > 0 ) {
const chunk = path.shift();
const isGroup = ! isNaN( chunk );
const isNestedComplex = ! isGroup;
if ( isGroup ) {
pathPrefix = `${ pathPrefix }[${ chunk }]`;
const group = get( fields, pathPrefix );
const groupFields = getFieldsFromFieldsHolder( group, fields, [ props.id ] );
siblingFields = siblingFields.concat( mapParentPrefix( groupFields, depth ) );
pathPrefix = `${ pathPrefix }.fields`;
}
if ( isNestedComplex ) {
const groupField = find( get( fields, pathPrefix ), [ 'name', chunk ] );
if ( groupField ) {
pathPrefix = `${ groupField.id }.value`;
}
depth--;
}
}
}
siblingFields = siblingFields.map( ( [ id, name ] ) => ( [
name,
get( fields, `${ id }.value` )
] ) );
return fromPairs( siblingFields );
}
export default withConditionalLogic( input, output );

View file

@ -0,0 +1,24 @@
/**
* External dependencies.
*/
import { withSelect } from '@wordpress/data';
import { createHigherOrderComponent } from '@wordpress/compose';
/**
* Creates a high-order component which adds connection
* to the store.
*
* @param {Function} Component
* @return {Function}
*/
export default createHigherOrderComponent( ( Component ) => {
const applyWithSelect = withSelect( ( select, { id } ) => {
const container = select( 'carbon-fields/metaboxes' ).getContainerById( id );
return {
container
};
} );
return applyWithSelect( Component );
}, 'withContainer' );

View file

@ -0,0 +1,48 @@
/**
* External dependencies.
*/
import { withSelect, withDispatch } from '@wordpress/data';
import { compose, createHigherOrderComponent } from '@wordpress/compose';
/**
* Creates a high-order component which adds connection
* to the store.
*
* @param {Function} Component
* @return {Function}
*/
export default createHigherOrderComponent( ( Component ) => {
const applyWithSelect = withSelect( ( select, props ) => {
const { compactInput, compactInputKey } = window.cf.config;
const field = select( 'carbon-fields/metaboxes' ).getFieldById( props.id );
const value = field && field.value;
let name = props.name || field.name;
/**
* Wrap top-level field names in compact input key.
*
* The fields in widgets don't need this prefix because
* their input is already compacted by the `widget` namespace.
*/
if ( compactInput && ! props.name && name.indexOf( 'widget-carbon_fields' ) === -1 ) {
name = `${ compactInputKey }[${ name }]`;
}
return {
field,
name,
value
};
} );
const applyWithDispatch = withDispatch( ( dispatch ) => {
const { updateFieldValue } = dispatch( 'carbon-fields/metaboxes' );
return {
onChange: updateFieldValue
};
} );
return compose( applyWithSelect, applyWithDispatch )( Component );
}, 'withField' );