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,88 @@
/**
* External dependencies.
*/
import { addFilter } from '@wordpress/hooks';
import { select } from '@wordpress/data';
import { get, find } from 'lodash';
/**
* Carbon Fields dependencies.
*/
import { withProps } from '@carbon-fields/core';
/**
* Internal dependencies.
*/
import stripCompactInputPrefix from '../../utils/strip-compact-input-prefix';
/**
* Returns a field with the given name.
*
* @param {Object[]} fields
* @param {string} name
* @return {?Object}
*/
function findFieldByName( fields, name ) {
return find( fields, ( field ) => {
return field.name === name;
} );
}
addFilter( 'carbon-fields.association.metabox', 'carbon-fields/metaboxes', withProps( ( props ) => {
return {
hierarchyResolver() {
// Get all fields.
const container = select( 'carbon-fields/metaboxes' ).getContainerById( props.containerId );
const fields = select( 'carbon-fields/metaboxes' ).getFieldsByContainerId( props.containerId );
// Get a clean version of field's name.
const fieldName = stripCompactInputPrefix( props.name );
// Get the path.
let path = fieldName.split( /\[|\]/g );
// Remove chunks that are empty.
path = path.filter( ( chunk ) => chunk !== '' );
if ( container.type === 'widget' ) {
return props.field.base_name;
}
// Get the root field.
const rootFieldName = path.shift();
const rootField = findFieldByName( fields, rootFieldName );
// Get the hierarchy.
let accessor = fields.indexOf( rootField );
let hierarchy = rootField.base_name;
// Visit every branch in the tree so we can get the full hierarchy.
while ( path.length > 0 ) {
const chunk = path.shift();
const isGroup = ! isNaN( chunk );
const isSameField = chunk === props.field.base_name;
const isNestedComplex = ! isGroup && ! isSameField;
if ( isGroup ) {
accessor = `${ accessor }.value.${ chunk }.name`;
hierarchy = `${ hierarchy }[${ chunk }]:${ get( fields, accessor ) }/`;
}
if ( isNestedComplex ) {
const fieldReferences = get( fields, accessor.replace( /\.name$/, '.fields' ) );
const fieldReference = findFieldByName( fieldReferences, chunk );
const field = find( fields, [ 'id', fieldReference.id ] );
accessor = fields.indexOf( field );
hierarchy = `${ hierarchy }${ field.base_name }`;
}
if ( isSameField ) {
hierarchy = `${ hierarchy }${ chunk }`;
}
}
return hierarchy;
}
};
} ) );

View file

@ -0,0 +1,295 @@
/**
* External dependencies.
*/
import produce from 'immer';
import { Component } from '@wordpress/element';
import { addFilter } from '@wordpress/hooks';
import { compose } from '@wordpress/compose';
import { withDispatch, withSelect } from '@wordpress/data';
import {
find,
assign,
without,
cloneDeep
} from 'lodash';
/**
* Carbon Fields dependencies.
*/
import { uniqueId } from '@carbon-fields/core';
/**
* Internal dependencies.
*/
import './style.scss';
import Field from '../../components/field';
import flattenField from '../../utils/flatten-field';
class ComplexField extends Component {
/**
* Handles adding of group.
*
* @param {Object} group
* @param {Function} callback
* @return {Object}
*/
handleAddGroup = ( group, callback ) => {
const {
id,
field,
value,
addFields,
onChange
} = this.props;
// Create a copy of the group to prevent
// incidentally modifications.
group = cloneDeep( group );
// Get a flat list of all fields for this group.
const fields = [];
group.id = uniqueId();
group.container_id = field.container_id;
group.fields = group.fields.map( ( groupField ) => flattenField( groupField, field.container_id, fields ) );
// Make sure that the group is expanded even
// `set_collapsed(true)` is used.
group.collapsed = false;
// Push the group to the field.
addFields( fields );
onChange( id, value.concat( group ) );
callback( group );
}
/**
* Handles cloning of group.
*
* @param {Object} group
* @param {Function} callback
* @return {void}
*/
handleCloneGroup = ( group, callback ) => {
const {
id,
value,
cloneFields,
onChange
} = this.props;
const originFieldIds = group.fields.map( ( groupField ) => groupField.id );
const cloneFieldIds = originFieldIds.map( () => uniqueId() );
const clonedGroup = cloneDeep( group );
clonedGroup.id = uniqueId();
clonedGroup.fields.forEach( ( groupField, index ) => {
groupField.id = cloneFieldIds[ index ];
} );
cloneFields( originFieldIds, cloneFieldIds );
onChange( id, produce( value, ( draft ) => {
draft.splice( value.indexOf( group ) + 1, 0, clonedGroup );
} ) );
callback( clonedGroup );
}
/**
* Handles removing of group.
*
* @param {Object} group
* @return {void}
*/
handleRemoveGroup = ( group ) => {
const {
id,
value,
onChange
} = this.props;
onChange(
id,
without( value, group ),
group.fields.map( ( groupField ) => groupField.id )
);
}
/**
* Handles expanding/collapsing of group.
*
* @param {string} groupId
* @return {void}
*/
handleToggleGroup = ( groupId ) => {
const {
field,
value,
onChange
} = this.props;
onChange( field.id, produce( value, ( draft ) => {
const group = find( draft, [ 'id', groupId ] );
group.collapsed = ! group.collapsed;
} ) );
}
/**
* Handles expanding/collapsing of all groups.
*
* @param {boolean} collapsed
* @return {void}
*/
handleToggleAllGroups = ( collapsed ) => {
const {
field,
value,
onChange
} = this.props;
onChange( field.id, produce( value, ( draft ) => {
draft.forEach( ( group ) => {
group.collapsed = collapsed;
} );
} ) );
}
/**
* Handles setuping of group.
*
* @param {Object} group
* @param {Object} props
* @return {Object}
*/
handleGroupSetup = ( group, props ) => {
return assign( {}, props, {
id: group.id,
name: group.name,
prefix: `${ this.props.name }[${ props.index }]`,
fields: group.fields,
collapsed: group.collapsed,
context: 'metabox'
} );
}
/**
* Handles setuping of group's field.
*
* @param {Object} field
* @param {Object} props
* @param {Object} groupProps
* @return {Array}
*/
handleGroupFieldSetup = ( field, props, groupProps ) => {
return [ Field, assign( {}, props, {
key: field.id,
id: field.id,
containerId: this.props.containerId,
name: `${ groupProps.prefix }[${ field.name }]`
} ) ];
}
/**
* Renders the component.
*
* @return {Object}
*/
render() {
const {
handleGroupSetup,
handleGroupFieldSetup,
handleAddGroup,
handleCloneGroup,
handleRemoveGroup,
handleToggleGroup,
handleToggleAllGroups
} = this;
const { value, children } = this.props;
const allGroupsAreCollapsed = value.every( ( { collapsed } ) => collapsed );
return children( {
allGroupsAreCollapsed,
handleGroupSetup,
handleGroupFieldSetup,
handleAddGroup,
handleCloneGroup,
handleRemoveGroup,
handleToggleGroup,
handleToggleAllGroups
} );
}
}
const applyWithSelect = withSelect( ( select, props ) => {
const { getComplexGroupValues } = select( 'carbon-fields/metaboxes' );
const groupValues = props.value.map( ( group ) => {
const fieldIds = group.fields.map( ( field ) => field.id );
return [ group.name, getComplexGroupValues( fieldIds ) ];
} );
return {
groupValues
};
} );
const applyWithDispatch = withDispatch( ( dispatch ) => {
const { addFields, cloneFields } = dispatch( 'carbon-fields/metaboxes' );
return {
addFields,
cloneFields
};
} );
addFilter( 'carbon-fields.complex.metabox', 'carbon-fields/metaboxes', ( OriginalComplexField ) => compose(
applyWithSelect,
applyWithDispatch
)( ( props ) => {
const {
id,
field,
name,
value,
groupValues
} = props;
return (
<ComplexField { ...props }>
{ ( {
allGroupsAreCollapsed,
handleGroupSetup,
handleGroupFieldSetup,
handleAddGroup,
handleCloneGroup,
handleRemoveGroup,
handleToggleGroup,
handleToggleAllGroups
} ) => (
<OriginalComplexField
groupIdKey="id"
groupFilterKey="name"
id={ id }
field={ field }
name={ name }
value={ value }
groupValues={ groupValues }
allGroupsAreCollapsed={ allGroupsAreCollapsed }
onGroupSetup={ handleGroupSetup }
onGroupFieldSetup={ handleGroupFieldSetup }
onAddGroup={ handleAddGroup }
onCloneGroup={ handleCloneGroup }
onRemoveGroup={ handleRemoveGroup }
onToggleGroup={ handleToggleGroup }
onToggleAllGroups={ handleToggleAllGroups }
onChange={ props.onChange }
/>
) }
</ComplexField>
);
} ) );

View file

@ -0,0 +1,54 @@
/* ==========================================================================
Complex
========================================================================== */
.cf-complex__inserter-menu {
.postbox &,
body[class*="taxonomy-"] & {
margin: 0;
border-radius: $wp-radius-round;
background-color: $wp-color-ultra-dark-gray;
&:before {
position: absolute;
top: 50%;
right: 100%;
width: 0;
height: 0;
border-width: 5px 5px 5px 0;
border-style: solid;
border-color: transparent $wp-color-ultra-dark-gray;
margin-top: -5px;
content: '';
}
}
}
.cf-complex__inserter-item {
.postbox &,
body[class*="taxonomy-"] & {
font-weight: 600;
color: $color-white;
transition: color $transition-base;
&:hover {
color: $wp-color-medium-blue;
}
}
}
.cf-complex__inserter-button {
.postbox .cf-complex__tabs &,
body[class*="taxonomy-"] .cf-complex__tabs & {
font-weight: 600;
color: $wp-color-dark-gray;
}
}
.cf-complex__tabs-item {
.postbox &,
body[class*="taxonomy"] & {
font-weight: 600;
color: $wp-color-dark-gray;
}
}

View file

@ -0,0 +1,12 @@
/**
* External dependencies.
*/
import { addFilter } from '@wordpress/hooks';
import { __ } from '@wordpress/i18n';
addFilter( 'carbon-fields.date_time.metabox', 'carbon-fields/metaboxes', ( OriginalDatetimeField ) => ( props ) => (
<OriginalDatetimeField
buttonText={ __( 'Select Date', 'carbon-fields-ui' ) }
{ ...props }
/>
) );

View file

@ -0,0 +1,16 @@
/**
* External dependencies.
*/
import { addFilter } from '@wordpress/hooks';
import { __ } from '@wordpress/i18n';
addFilter( 'carbon-fields.file.metabox', 'carbon-fields/metaboxes', ( OriginalFileField ) => ( props ) => {
return (
<OriginalFileField
buttonLabel={ __( 'Select File', 'carbon-fields-ui' ) }
mediaLibraryButtonLabel={ __( 'Use File', 'carbon-fields-ui' ) }
mediaLibraryTitle={ __( 'Select File', 'carbon-fields-ui' ) }
{ ...props }
/>
);
} );

View file

@ -0,0 +1,16 @@
/**
* External dependencies.
*/
import { addFilter } from '@wordpress/hooks';
import { __ } from '@wordpress/i18n';
addFilter( 'carbon-fields.image.metabox', 'carbon-fields/metaboxes', ( OriginalImageField ) => ( props ) => {
return (
<OriginalImageField
buttonLabel={ __( 'Select Image', 'carbon-fields-ui' ) }
mediaLibraryButtonLabel={ __( 'Use Image', 'carbon-fields-ui' ) }
mediaLibraryTitle={ __( 'Select Image', 'carbon-fields-ui' ) }
{ ...props }
/>
);
} );

View file

@ -0,0 +1,54 @@
/**
* External dependencies.
*/
import { compose } from '@wordpress/compose';
import { addFilter } from '@wordpress/hooks';
import { withDispatch } from '@wordpress/data';
/**
* Carbon Fields dependencies.
*/
import { withValidation } from '@carbon-fields/core';
/**
* Internal dependencies.
*/
import withField from '../hocs/with-field';
import withConditionalLogic from '../hocs/with-conditional-logic';
import isGutenberg from '../utils/is-gutenberg';
/**
* Connects every field to the store.
*/
addFilter( 'carbon-fields.field-edit.metabox', 'carbon-fields/metaboxes', compose(
withField,
withConditionalLogic,
withDispatch( ( dispatch ) => {
if ( isGutenberg() ) {
const { lockPostSaving, unlockPostSaving } = dispatch( 'core/editor' );
return {
lockSaving: lockPostSaving,
unlockSaving: unlockPostSaving
};
}
const { lockSaving, unlockSaving } = dispatch( 'carbon-fields/metaboxes' );
return {
lockSaving,
unlockSaving
};
} ),
withValidation
) );
import './association';
import './complex';
import './datetime';
import './file';
import './image';
import './multiselect';
import './media-gallery';
import './radio';
import './sidebar';

View file

@ -0,0 +1,21 @@
/**
* External dependencies.
*/
import { addFilter } from '@wordpress/hooks';
import { __ } from '@wordpress/i18n';
/**
* The internal dependencies.
*/
import './style.scss';
addFilter( 'carbon-fields.media_gallery.metabox', 'carbon-fields/metaboxes', ( OriginalMediaGalleryField ) => ( props ) => {
return (
<OriginalMediaGalleryField
buttonLabel={ __( 'Select Attachments', 'carbon-fields-ui' ) }
mediaLibraryButtonLabel={ __( 'Use Attachments', 'carbon-fields-ui' ) }
mediaLibraryTitle={ __( 'Select Attachments', 'carbon-fields-ui' ) }
{ ...props }
/>
);
} );

View file

@ -0,0 +1,54 @@
/* ==========================================================================
Media Gallery
========================================================================== */
.cf-media-gallery__inner {
.postbox & {
border: 1px solid $wp-color-gray-light-500;
}
}
.cf-media-gallery__actions {
.postbox & {
border-top: 1px solid $wp-color-gray-light-500;
}
.cf-container-term-meta & {
padding-left: 0;
}
}
.cf-media-gallery__list {
.cf-container-term-meta & {
margin: 0 -8px;
max-height: 285px;
}
}
.cf-media-gallery__item {
.cf-container-term-meta & {
flex-basis: 20%;
}
}
.cf-media-gallery__item-inner {
.postbox &,
.cf-container-term-meta & {
border: 1px solid $wp-color-gray-light-500;
}
}
.cf-media-gallery__item-preview {
.postbox &,
.cf-container-term-meta & {
background-color: $wp-color-gray-light-200;
}
}
.cf-media-gallery__item-name {
.postbox &,
.cf-container-term-meta & {
border-top: 1px solid $wp-color-gray-light-500;
background-color: $wp-color-gray-light-200;
}
}

View file

@ -0,0 +1,4 @@
/**
* Internal dependencies.
*/
import './style.scss';

View file

@ -0,0 +1,15 @@
/* ==========================================================================
Multiselect
========================================================================== */
.cf-multiselect__control {
.postbox & {
border-color: #ddd;
box-shadow: 0 1px 2px transparentize($color-black, 0.93) inset;
}
.postbox &--is-focused,
.postbox &--is-focused:hover {
box-shadow: 0 0 2px transparentize($wp-color-blue, 0.2);
}
}

View file

@ -0,0 +1,4 @@
/**
* The internal dependencies.
*/
import './style.scss';

View file

@ -0,0 +1,21 @@
/* ==========================================================================
Radio
========================================================================== */
.cf-radio__label {
.inside .cf-radio-image .cf-radio__input:focus ~ & {
box-shadow: 0 0 2px transparentize($wp-color-medium-blue, 0.2);
}
}
.cf-radio-image__image {
.inside & {
border: 1px solid $wp-color-gray-light-800;
}
.inside .cf-radio__input:focus ~ .cf-radio__label &,
.inside .cf-radio__input:checked ~ .cf-radio__label & {
outline: 4px solid $wp-color-medium-blue;
}
}

View file

@ -0,0 +1,13 @@
/**
* External dependencies.
*/
import { withDispatch } from '@wordpress/data';
import { addFilter } from '@wordpress/hooks';
addFilter( 'carbon-fields.sidebar.metabox', 'carbon-fields/metaboxes', withDispatch( ( dispatch ) => {
const { receiveSidebar } = dispatch( 'carbon-fields/metaboxes' );
return {
onAdded: receiveSidebar
};
} ) );