diff --git a/packages/dataviews/src/components/dataform/stories/index.story.tsx b/packages/dataviews/src/components/dataform/stories/index.story.tsx index ecad2af43fb84b..a4717e79cf715b 100644 --- a/packages/dataviews/src/components/dataform/stories/index.story.tsx +++ b/packages/dataviews/src/components/dataform/stories/index.story.tsx @@ -8,7 +8,7 @@ import { ToggleControl } from '@wordpress/components'; * Internal dependencies */ import DataForm from '../index'; -import type { Field, Form } from '../../../types'; +import type { DataFormControlProps, Field, Form } from '../../../types'; type SamplePost = { title: string; @@ -19,6 +19,7 @@ type SamplePost = { date: string; birthdate: string; password?: string; + sticky?: boolean; }; const meta = { @@ -107,16 +108,19 @@ const fields = [ id: 'sticky', label: 'Sticky', type: 'integer', - Edit: ( { field, onChange, data, hideLabelFromVision } ) => { - const { id, getValue } = field; + Edit: ( { + field, + onChange, + value, + hideLabelFromVision, + }: DataFormControlProps< SamplePost > ) => { + const { id } = field; return ( - onChange( { [ id ]: ! getValue( { item: data } ) } ) - } + checked={ value } + onChange={ () => onChange( { [ id ]: ! value } ) } /> ); }, diff --git a/packages/dataviews/src/constants.ts b/packages/dataviews/src/constants.ts index 5ae94c7eb4a135..fa5a9cd179de93 100644 --- a/packages/dataviews/src/constants.ts +++ b/packages/dataviews/src/constants.ts @@ -68,3 +68,6 @@ export const sortIcons = { export const LAYOUT_TABLE = 'table'; export const LAYOUT_GRID = 'grid'; export const LAYOUT_LIST = 'list'; + +// Dataform mixed value. +export const MIXED_VALUE = Symbol.for( 'DATAFORM_MIXED_VALUE' ); diff --git a/packages/dataviews/src/dataform-controls/datetime.tsx b/packages/dataviews/src/dataform-controls/datetime.tsx index b31c5c60bb9c6e..4c777d5c4e2fc1 100644 --- a/packages/dataviews/src/dataform-controls/datetime.tsx +++ b/packages/dataviews/src/dataform-controls/datetime.tsx @@ -10,13 +10,12 @@ import { useCallback } from '@wordpress/element'; import type { DataFormControlProps } from '../types'; export default function DateTime< Item >( { - data, field, onChange, hideLabelFromVision, -}: DataFormControlProps< Item > ) { + value, +}: DataFormControlProps< Item, string > ) { const { id, label } = field; - const value = field.getValue( { item: data } ); const onChangeControl = useCallback( ( newValue: string | null ) => onChange( { [ id ]: newValue } ), @@ -34,7 +33,7 @@ export default function DateTime< Item >( { { label } ) } diff --git a/packages/dataviews/src/dataform-controls/integer.tsx b/packages/dataviews/src/dataform-controls/integer.tsx index f70a90ffe15239..d4c544d2d49695 100644 --- a/packages/dataviews/src/dataform-controls/integer.tsx +++ b/packages/dataviews/src/dataform-controls/integer.tsx @@ -10,13 +10,12 @@ import { useCallback } from '@wordpress/element'; import type { DataFormControlProps } from '../types'; export default function Integer< Item >( { - data, field, onChange, hideLabelFromVision, -}: DataFormControlProps< Item > ) { + value, +}: DataFormControlProps< Item, number > ) { const { id, label, description } = field; - const value = field.getValue( { item: data } ) ?? ''; const onChangeControl = useCallback( ( newValue: string | undefined ) => onChange( { @@ -29,7 +28,7 @@ export default function Integer< Item >( { ( { - data, field, onChange, hideLabelFromVision, -}: DataFormControlProps< Item > ) { + value, +}: DataFormControlProps< Item, string > ) { const { id, label } = field; - const value = field.getValue( { item: data } ); const onChangeControl = useCallback( ( newValue: string ) => @@ -32,7 +31,7 @@ export default function Radio< Item >( { label={ label } onChange={ onChangeControl } options={ field.elements } - selected={ value } + selected={ typeof value === 'symbol' ? '' : value } hideLabelFromVision={ hideLabelFromVision } /> ); diff --git a/packages/dataviews/src/dataform-controls/select.tsx b/packages/dataviews/src/dataform-controls/select.tsx index 2b3bd9373fc155..d50625116a810d 100644 --- a/packages/dataviews/src/dataform-controls/select.tsx +++ b/packages/dataviews/src/dataform-controls/select.tsx @@ -11,13 +11,12 @@ import { __ } from '@wordpress/i18n'; import type { DataFormControlProps } from '../types'; export default function Select< Item >( { - data, field, onChange, hideLabelFromVision, -}: DataFormControlProps< Item > ) { + value, +}: DataFormControlProps< Item, string | number > ) { const { id, label } = field; - const value = field.getValue( { item: data } ) ?? ''; const onChangeControl = useCallback( ( newValue: any ) => onChange( { @@ -41,7 +40,7 @@ export default function Select< Item >( { return ( ( { - data, field, onChange, hideLabelFromVision, -}: DataFormControlProps< Item > ) { + value, +}: DataFormControlProps< Item, string > ) { const { id, label, placeholder } = field; - const value = field.getValue( { item: data } ); const onChangeControl = useCallback( ( newValue: string ) => @@ -30,7 +29,7 @@ export default function Text< Item >( { ( + combinedField: CombinedFormField, + fieldDefinitions: NormalizedField< Item >[] +): boolean { + return combinedField.children.some( ( child ) => { + const fieldId = typeof child === 'string' ? child : child.id; + + return ! fieldDefinitions.find( + ( fieldDefinition ) => fieldDefinition.id === fieldId + )?.unique; + } ); +} + export function DataFormLayout< Item >( { data, form, onChange, children, }: { - data: Item; + data: Item | Item[]; form: Form; onChange: ( value: any ) => void; children?: ( FieldLayout: ( props: { - data: Item; + data: Item | Item[]; field: FormField; onChange: ( value: any ) => void; hideLabelFromVision?: boolean; @@ -69,6 +88,18 @@ export function DataFormLayout< Item >( { return null; } + if ( + Array.isArray( data ) && + ( ( isCombinedField( formField ) && + ! doesCombinedFieldSupportBulkEdits( + formField, + fieldDefinitions + ) ) || + ( fieldDefinition && fieldDefinition.unique ) ) + ) { + return null; + } + if ( children ) { return children( FieldLayout, formField ); } diff --git a/packages/dataviews/src/dataforms-layouts/panel/index.tsx b/packages/dataviews/src/dataforms-layouts/panel/index.tsx index 269b2bb418a856..72fcf6e0a03879 100644 --- a/packages/dataviews/src/dataforms-layouts/panel/index.tsx +++ b/packages/dataviews/src/dataforms-layouts/panel/index.tsx @@ -26,6 +26,8 @@ import type { import DataFormContext from '../../components/dataform-context'; import { DataFormLayout } from '../data-form-layout'; import { isCombinedField } from '../is-combined-field'; +import { MIXED_VALUE } from '../../constants'; +import useFieldValue from '../use-field-value'; function DropdownHeader( { title, @@ -70,7 +72,7 @@ function PanelDropdown< Item >( { fieldDefinition: NormalizedField< Item >; popoverAnchor: HTMLElement | null; labelPosition: 'side' | 'top' | 'none'; - data: Item; + data: Item | Item[]; onChange: ( value: any ) => void; field: FormField; } ) { @@ -98,6 +100,8 @@ function PanelDropdown< Item >( { }; }, [ field ] ); + const fieldValue = useFieldValue( data, field.id ); + // Memoize popoverProps to avoid returning a new object every time. const popoverProps = useMemo( () => ( { @@ -111,6 +115,8 @@ function PanelDropdown< Item >( { [ popoverAnchor ] ); + const showMixedValue = Array.isArray( data ) && fieldValue === MIXED_VALUE; + return ( ( { ) } onClick={ onToggle } > - + { showMixedValue ? ( + __( 'Mixed' ) + ) : ( + + ) } ) } renderContent={ ( { onClose } ) => ( diff --git a/packages/dataviews/src/dataforms-layouts/regular/index.tsx b/packages/dataviews/src/dataforms-layouts/regular/index.tsx index a3d90b807b5cd4..ef81f2fb15292e 100644 --- a/packages/dataviews/src/dataforms-layouts/regular/index.tsx +++ b/packages/dataviews/src/dataforms-layouts/regular/index.tsx @@ -16,6 +16,7 @@ import type { Form, FieldLayoutProps } from '../../types'; import DataFormContext from '../../components/dataform-context'; import { DataFormLayout } from '../data-form-layout'; import { isCombinedField } from '../is-combined-field'; +import useFieldValue from '../use-field-value'; function Header( { title }: { title: string } ) { return ( @@ -59,6 +60,8 @@ export default function FormRegularField< Item >( { }; }, [ field ] ); + const fieldValue = useFieldValue( data, field.id ); + if ( isCombinedField( field ) ) { return ( <> @@ -95,6 +98,7 @@ export default function FormRegularField< Item >( { field={ fieldDefinition } onChange={ onChange } hideLabelFromVision + value={ fieldValue } /> @@ -105,6 +109,7 @@ export default function FormRegularField< Item >( {
( + data: Item | Item[], + fieldId: string +) { + const { fields } = useContext( DataFormContext ); + return useMemo( () => { + const fieldDefinition = fields.find( + ( fieldDef ) => fieldDef.id === fieldId + ); + if ( ! fieldDefinition ) { + return undefined; + } + if ( Array.isArray( data ) ) { + const [ firstRecord, ...remainingRecords ] = data; + const firstValue = fieldDefinition.getValue( { + item: firstRecord, + } ); + const intersects = remainingRecords.every( ( item ) => { + return fieldDefinition.getValue( { item } ) === firstValue; + } ); + return intersects ? firstValue : MIXED_VALUE; + } + return fieldDefinition.getValue( { + item: data, + } ); + }, [ data, fields, fieldId ] ); +} diff --git a/packages/dataviews/src/normalize-fields.ts b/packages/dataviews/src/normalize-fields.ts index 2ed87cbe112229..c9f0f7ea8ba83c 100644 --- a/packages/dataviews/src/normalize-fields.ts +++ b/packages/dataviews/src/normalize-fields.ts @@ -76,6 +76,7 @@ export function normalizeFields< Item >( sort, isValid, Edit, + unique: field.unique ?? false, enableHiding: field.enableHiding ?? true, enableSorting: field.enableSorting ?? true, }; diff --git a/packages/dataviews/src/types.ts b/packages/dataviews/src/types.ts index 96fd4a8cd01afc..780fe71dc7c30d 100644 --- a/packages/dataviews/src/types.ts +++ b/packages/dataviews/src/types.ts @@ -111,7 +111,10 @@ export type Field< Item > = { /** * Callback used to render an edit control for the field. */ - Edit?: ComponentType< DataFormControlProps< Item > > | string; + Edit?: + | ComponentType< DataFormControlProps< Item > > + | ComponentType< DataFormUniqueControlProps< Item > > + | string; /** * Callback used to sort the field. @@ -158,6 +161,11 @@ export type Field< Item > = { * Defaults to `item[ field.id ]`. */ getValue?: ( args: { item: Item } ) => any; + + /** + * Whether the field supports editing multiple items. + */ + unique?: boolean; }; export type NormalizedField< Item > = Field< Item > & { @@ -165,11 +173,14 @@ export type NormalizedField< Item > = Field< Item > & { header: string | ReactElement; getValue: ( args: { item: Item } ) => any; render: ComponentType< DataViewRenderFieldProps< Item > >; - Edit: ComponentType< DataFormControlProps< Item > >; + Edit: + | ComponentType< DataFormControlProps< Item > > + | ComponentType< DataFormUniqueControlProps< Item > >; sort: ( a: Item, b: Item, direction: SortDirection ) => number; isValid: ( item: Item, context?: ValidationContext ) => boolean; enableHiding: boolean; enableSorting: boolean; + unique: boolean; }; /** @@ -179,11 +190,20 @@ export type Fields< Item > = Field< Item >[]; export type Data< Item > = Item[]; -export type DataFormControlProps< Item > = { - data: Item; +export type DataFormControlProps< Item, ValueType = any > = { + data: Item | Item[]; field: NormalizedField< Item >; onChange: ( value: Record< string, any > ) => void; hideLabelFromVision?: boolean; + value?: ValueType | symbol; +}; + +export type DataFormUniqueControlProps< Item, ValueType = any > = Omit< + DataFormControlProps< Item, ValueType >, + 'data' | 'value' +> & { + data: Item; + value?: ValueType; }; export type DataViewRenderFieldProps< Item > = { @@ -539,14 +559,14 @@ export type Form = { }; export interface DataFormProps< Item > { - data: Item; + data: Item | Item[]; fields: Field< Item >[]; form: Form; onChange: ( value: Record< string, any > ) => void; } export interface FieldLayoutProps< Item > { - data: Item; + data: Item | Item[]; field: FormField; onChange: ( value: any ) => void; hideLabelFromVision?: boolean; diff --git a/packages/edit-site/src/components/post-edit/index.js b/packages/edit-site/src/components/post-edit/index.js index 97484c89ed670b..c0c7d9a2306a6b 100644 --- a/packages/edit-site/src/components/post-edit/index.js +++ b/packages/edit-site/src/components/post-edit/index.js @@ -11,7 +11,7 @@ import { DataForm } from '@wordpress/dataviews'; import { useDispatch, useSelect } from '@wordpress/data'; import { store as coreDataStore } from '@wordpress/core-data'; import { __experimentalVStack as VStack } from '@wordpress/components'; -import { useState, useMemo, useEffect } from '@wordpress/element'; +import { useMemo } from '@wordpress/element'; import { privateApis as editorPrivateApis } from '@wordpress/editor'; /** @@ -24,17 +24,35 @@ import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor'; const { usePostFields, PostCardPanel } = unlock( editorPrivateApis ); -const fieldsWithBulkEditSupport = [ - 'title', - 'status', - 'date', - 'author', - 'comment_status', -]; +const DATAFORM_CONFIG = { + type: 'panel', + fields: [ + { + id: 'featured_media', + layout: 'regular', + }, + { + id: 'status', + label: __( 'Status & Visibility' ), + children: [ 'status', 'password' ], + }, + 'author', + 'date', + 'slug', + 'parent', + 'comment_status', + { + label: __( 'Template' ), + labelPosition: 'side', + id: 'template', + layout: 'regular', + }, + ], +}; function PostEditForm( { postType, postId } ) { const ids = useMemo( () => postId.split( ',' ), [ postId ] ); - const { record, hasFinishedResolution } = useSelect( + const { record, hasFinishedResolution, records } = useSelect( ( select ) => { const args = [ 'postType', postType, ids[ 0 ] ]; @@ -46,15 +64,27 @@ function PostEditForm( { postType, postId } ) { return { record: ids.length === 1 ? getEditedEntityRecord( ...args ) : null, - hasFinishedResolution: hasFinished( - 'getEditedEntityRecord', - args + hasFinishedResolution: ids.every( ( id ) => + hasFinished( 'getEditedEntityRecord', [ + 'postType', + postType, + id, + ] ) ), + records: + ids.length > 1 + ? ids.map( ( id ) => + select( coreDataStore ).getEditedEntityRecord( + 'postType', + postType, + id + ) + ) + : null, }; }, [ postType, ids ] ); - const [ multiEdits, setMultiEdits ] = useState( {} ); const { editEntityRecord } = useDispatch( coreDataStore ); const { fields: _fields } = usePostFields( { postType } ); const fields = useMemo( @@ -73,67 +103,28 @@ function PostEditForm( { postType, postId } ) { [ _fields ] ); - const form = useMemo( - () => ( { - type: 'panel', - fields: [ - { - id: 'featured_media', - layout: 'regular', - }, - { - id: 'status', - label: __( 'Status & Visibility' ), - children: [ 'status', 'password' ], - }, - 'author', - 'date', - 'slug', - 'parent', - 'comment_status', - { - label: __( 'Template' ), - labelPosition: 'side', - id: 'template', - layout: 'regular', - }, - ].filter( - ( field ) => - ids.length === 1 || - fieldsWithBulkEditSupport.includes( field ) - ), - } ), - [ ids ] - ); const onChange = ( edits ) => { for ( const id of ids ) { + const editedRecord = + ids.length > 1 ? records.find( ( r ) => r.id === +id ) : record; if ( edits.status && edits.status !== 'future' && - record?.status === 'future' && - new Date( record.date ) > new Date() + editedRecord?.status === 'future' && + new Date( editedRecord.date ) > new Date() ) { edits.date = null; } if ( edits.status && edits.status === 'private' && - record.password + editedRecord.password ) { edits.password = ''; } editEntityRecord( 'postType', postType, id, edits ); - if ( ids.length > 1 ) { - setMultiEdits( ( prev ) => ( { - ...prev, - ...edits, - } ) ); - } } }; - useEffect( () => { - setMultiEdits( {} ); - }, [ ids ] ); const { ExperimentalBlockEditorProvider } = unlock( blockEditorPrivateApis @@ -166,9 +157,9 @@ function PostEditForm( { postType, postId } ) { { hasFinishedResolution && ( ) } diff --git a/packages/fields/src/fields/featured-image/featured-image-edit.tsx b/packages/fields/src/fields/featured-image/featured-image-edit.tsx index ee51e5c60f13e0..1a99fab07741d3 100644 --- a/packages/fields/src/fields/featured-image/featured-image-edit.tsx +++ b/packages/fields/src/fields/featured-image/featured-image-edit.tsx @@ -17,18 +17,18 @@ import { __ } from '@wordpress/i18n'; import type { BasePost } from '../../types'; export const FeaturedImageEdit = ( { - data, field, onChange, -}: DataFormControlProps< BasePost > ) => { + value, +}: DataFormControlProps< BasePost, number > ) => { const { id } = field; - const value = field.getValue( { item: data } ); - const media = useSelect( ( select ) => { const { getEntityRecord } = select( coreStore ); - return getEntityRecord( 'root', 'media', value ); + return typeof value !== 'symbol' + ? getEntityRecord( 'root', 'media', value ) + : undefined; }, [ value ] ); diff --git a/packages/fields/src/fields/parent/parent-edit.tsx b/packages/fields/src/fields/parent/parent-edit.tsx index 21cdbee7a365a4..85a62657ee4e41 100644 --- a/packages/fields/src/fields/parent/parent-edit.tsx +++ b/packages/fields/src/fields/parent/parent-edit.tsx @@ -109,16 +109,18 @@ export const getItemPriority = ( name: string, searchValue: string ) => { export function PageAttributesParent( { data, + value, onChangeControl, }: { - data: BasePost; + data: BasePost | BasePost[]; + value?: number | symbol; onChangeControl: ( newValue: number ) => void; } ) { const [ fieldValue, setFieldValue ] = useState< null | string >( null ); - const pageId = data.parent; - const postId = data.id; - const postTypeSlug = data.type; + const pageId = typeof value === 'symbol' ? undefined : value; + const postId = Array.isArray( data ) ? undefined : data.id; + const postTypeSlug = Array.isArray( data ) ? data[ 0 ].type : data.type; const { parentPostTitle, pageItems, isHierarchical } = useSelect( ( select ) => { @@ -272,7 +274,7 @@ export function PageAttributesParent( { value={ pageId?.toString() } options={ parentOptions } onFilterValueChange={ debounce( - ( value: unknown ) => handleKeydown( value as string ), + ( newValue: unknown ) => handleKeydown( newValue as string ), 300 ) } onChange={ handleChange } @@ -285,7 +287,8 @@ export const ParentEdit = ( { data, field, onChange, -}: DataFormControlProps< BasePost > ) => { + value, +}: DataFormControlProps< BasePost, number > ) => { const { id } = field; const homeUrl = useSelect( ( select ) => { @@ -339,6 +342,7 @@ export const ParentEdit = ( { ) }

diff --git a/packages/fields/src/fields/password/edit.tsx b/packages/fields/src/fields/password/edit.tsx index 75226c1f93f15b..094d36a0d03620 100644 --- a/packages/fields/src/fields/password/edit.tsx +++ b/packages/fields/src/fields/password/edit.tsx @@ -16,17 +16,16 @@ import { __ } from '@wordpress/i18n'; import type { BasePost } from '../../types'; function PasswordEdit( { - data, onChange, - field, -}: DataFormControlProps< BasePost > ) { + value, +}: DataFormControlProps< BasePost, string > ) { const [ showPassword, setShowPassword ] = useState( - !! field.getValue( { item: data } ) + typeof value !== 'symbol' && !! value ); - const handleTogglePassword = ( value: boolean ) => { - setShowPassword( value ); - if ( ! value ) { + const handleTogglePassword = ( newValue: boolean ) => { + setShowPassword( newValue ); + if ( ! newValue ) { onChange( { password: '' } ); } }; @@ -48,12 +47,12 @@ function PasswordEdit( {
+ onChange={ ( newValue ) => onChange( { - password: value, + password: newValue, } ) } - value={ field.getValue( { item: data } ) || '' } + value={ typeof value === 'symbol' ? '' : value ?? '' } placeholder={ __( 'Use a secure password' ) } type="text" __next40pxDefaultSize diff --git a/packages/fields/src/fields/slug/index.ts b/packages/fields/src/fields/slug/index.ts index 7311b1d10a66f6..e457578971ef96 100644 --- a/packages/fields/src/fields/slug/index.ts +++ b/packages/fields/src/fields/slug/index.ts @@ -17,6 +17,7 @@ const slugField: Field< BasePost > = { label: __( 'Slug' ), Edit: SlugEdit, render: SlugView, + unique: true, }; /** diff --git a/packages/fields/src/fields/slug/slug-edit.tsx b/packages/fields/src/fields/slug/slug-edit.tsx index aad6610550069c..e206a83b49adf5 100644 --- a/packages/fields/src/fields/slug/slug-edit.tsx +++ b/packages/fields/src/fields/slug/slug-edit.tsx @@ -14,7 +14,7 @@ import { useDispatch } from '@wordpress/data'; import { useCallback, useEffect, useRef } from '@wordpress/element'; import { store as noticesStore } from '@wordpress/notices'; import { safeDecodeURIComponent } from '@wordpress/url'; -import type { DataFormControlProps } from '@wordpress/dataviews'; +import type { DataFormUniqueControlProps } from '@wordpress/dataviews'; import { __ } from '@wordpress/i18n'; /** @@ -27,7 +27,7 @@ const SlugEdit = ( { field, onChange, data, -}: DataFormControlProps< BasePost > ) => { +}: DataFormUniqueControlProps< BasePost, string > ) => { const { id } = field; const slug = field.getValue( { item: data } ) || getSlug( data ); diff --git a/packages/fields/src/fields/template/template-edit.tsx b/packages/fields/src/fields/template/template-edit.tsx index c17364568a4578..4df0ab62f4d42e 100644 --- a/packages/fields/src/fields/template/template-edit.tsx +++ b/packages/fields/src/fields/template/template-edit.tsx @@ -32,12 +32,11 @@ export const TemplateEdit = ( { data, field, onChange, -}: DataFormControlProps< BasePost > ) => { + value, +}: DataFormControlProps< BasePost, string > ) => { const { id } = field; - const postType = data.type; - const postId = - typeof data.id === 'number' ? data.id : parseInt( data.id, 10 ); - const slug = data.slug; + const postType = Array.isArray( data ) ? data[ 0 ].type : data.type; + const slug = Array.isArray( data ) ? '' : data.slug; const { availableTemplates, templates } = useSelect( ( select ) => { @@ -55,11 +54,18 @@ export const TemplateEdit = ( { select( coreStore ) ); - const isPostsPage = getPostsPageId() === +postId; - const isFrontPage = - postType === 'page' && getHomePage()?.postId === +postId; + const posts = Array.isArray( data ) ? data : [ data ]; - const allowSwitchingTemplate = ! isPostsPage && ! isFrontPage; + const allowSwitchingTemplate = posts.every( ( post ) => { + const postId = + typeof post.id === 'number' + ? post.id + : parseInt( post.id, 10 ); + const isPostsPage = +getPostsPageId() === postId; + const isFrontPage = + postType === 'page' && +getHomePage()?.postId === postId; + return ! isPostsPage && ! isFrontPage; + } ); return { templates: allTemplates, @@ -67,13 +73,13 @@ export const TemplateEdit = ( { ? allTemplates.filter( ( template ) => template.is_custom && - template.slug !== data.template && + template.slug !== value && !! template.content.raw // Skip empty templates. ) : [], }; }, - [ data.template, postId, postType ] + [ value, postType, data ] ); const templatesAsPatterns = useMemo( @@ -89,8 +95,6 @@ export const TemplateEdit = ( { const shownTemplates = useAsyncList( templatesAsPatterns ); - const value = field.getValue( { item: data } ); - const currentTemplate = useSelect( ( select ) => { const foundTemplate = templates?.find( @@ -141,6 +145,13 @@ export const TemplateEdit = ( { [ id, onChange ] ); + let buttonLabel = ''; + if ( typeof value === 'symbol' ) { + buttonLabel = __( 'Mixed' ); + } else if ( currentTemplate ) { + buttonLabel = getItemTitle( currentTemplate ); + } + return (
- { currentTemplate - ? getItemTitle( currentTemplate ) - : '' } + { buttonLabel } ) } renderContent={ ( { onToggle } ) => ( - { - setShowModal( true ); - onToggle(); - } } - > - { __( 'Swap template' ) } - + { availableTemplates.length > 0 && ( + { + setShowModal( true ); + onToggle(); + } } + > + { __( 'Swap template' ) } + + ) } { // The default template in a post is indicated by an empty string - value !== '' && ( + value !== '' && typeof value !== 'symbol' && ( { onChangeControl( '' );