From da36eac2f79794e849657d7b47b8319fc04c88ae Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Mon, 12 Jan 2026 14:34:35 +0800 Subject: [PATCH 01/12] Remove normalization functions --- .../src/hooks/block-fields/index.js | 192 ++---------------- 1 file changed, 20 insertions(+), 172 deletions(-) diff --git a/packages/block-editor/src/hooks/block-fields/index.js b/packages/block-editor/src/hooks/block-fields/index.js index 15e5451d338d1a..31d4bac7bf2e70 100644 --- a/packages/block-editor/src/hooks/block-fields/index.js +++ b/packages/block-editor/src/hooks/block-fields/index.js @@ -56,120 +56,6 @@ function createConfiguredControl( config ) { }; } -/** - * Normalize a media value to a canonical structure. - * Only includes properties that are present in the field's mapping (if provided). - * - * @param {Object} value - The mapped value from the block attributes (with canonical keys) - * @param {Object} fieldDef - Optional field definition containing the mapping - * @return {Object} Normalized media value with canonical properties - */ -function normalizeMediaValue( value, fieldDef ) { - const defaults = { - id: null, - url: '', - caption: '', - alt: '', - type: 'image', - poster: '', - featuredImage: false, - link: '', - }; - - const result = {}; - - // If there's a mapping, only include properties that are in it - if ( fieldDef?.mapping ) { - Object.keys( fieldDef.mapping ).forEach( ( key ) => { - result[ key ] = value?.[ key ] ?? defaults[ key ] ?? ''; - } ); - return result; - } - - // Without mapping, include all default properties - Object.keys( defaults ).forEach( ( key ) => { - result[ key ] = value?.[ key ] ?? defaults[ key ]; - } ); - return result; -} - -/** - * Denormalize a media value from canonical structure back to mapped keys. - * Only includes properties that are present in the field's mapping. - * - * @param {Object} value - The normalized media value - * @param {Object} fieldDef - The field definition containing the mapping - * @return {Object} Value with only mapped properties - */ -function denormalizeMediaValue( value, fieldDef ) { - if ( ! fieldDef.mapping ) { - return value; - } - - const result = {}; - Object.entries( fieldDef.mapping ).forEach( ( [ key ] ) => { - if ( key in value ) { - result[ key ] = value[ key ]; - } - } ); - return result; -} - -/** - * Normalize a link value to a canonical structure. - * Only includes properties that are present in the field's mapping (if provided). - * - * @param {Object} value - The mapped value from the block attributes (with canonical keys) - * @param {Object} fieldDef - Optional field definition containing the mapping - * @return {Object} Normalized link value with canonical properties - */ -function normalizeLinkValue( value, fieldDef ) { - const defaults = { - url: '', - rel: '', - linkTarget: '', - destination: '', - }; - - const result = {}; - - // If there's a mapping, only include properties that are in it - if ( fieldDef?.mapping ) { - Object.keys( fieldDef.mapping ).forEach( ( key ) => { - result[ key ] = value?.[ key ] ?? defaults[ key ] ?? ''; - } ); - return result; - } - - // Without mapping, include all default properties - Object.keys( defaults ).forEach( ( key ) => { - result[ key ] = value?.[ key ] ?? defaults[ key ]; - } ); - return result; -} - -/** - * Denormalize a link value from canonical structure back to mapped keys. - * Only includes properties that are present in the field's mapping. - * - * @param {Object} value - The normalized link value - * @param {Object} fieldDef - The field definition containing the mapping - * @return {Object} Value with only mapped properties - */ -function denormalizeLinkValue( value, fieldDef ) { - if ( ! fieldDef.mapping ) { - return value; - } - - const result = {}; - Object.entries( fieldDef.mapping ).forEach( ( [ key ] ) => { - if ( key in value ) { - result[ key ] = value[ key ]; - } - } ); - return result; -} - /** * Component that renders a DataForm for a single block's attributes * @param {Object} props @@ -237,67 +123,29 @@ function BlockFields( { type: fieldDef.type, // Use the field's type; DataForm will use built-in or custom Edit config: { ...fieldDef.args, defaultValues }, hideLabelFromVision: fieldDef.id === 'content', - // getValue and setValue handle the mapping to block attributes - getValue: ( { item } ) => { - if ( fieldDef.mapping ) { - // Extract mapped properties from the block attributes - const mappedValue = {}; - Object.entries( fieldDef.mapping ).forEach( - ( [ key, attrKey ] ) => { - mappedValue[ key ] = item[ attrKey ]; - } - ); + }; - // Normalize to canonical structure based on field type - if ( fieldDef.type === 'media' ) { - return normalizeMediaValue( mappedValue, fieldDef ); + if ( fieldDef.mapping ) { + field.getValue = ( { item } ) => { + // Extract mapped properties from the block attributes + const mappedValue = {}; + Object.entries( fieldDef.mapping ).forEach( + ( [ key, attrKey ] ) => { + mappedValue[ key ] = item[ attrKey ]; } - if ( fieldDef.type === 'link' ) { - return normalizeLinkValue( mappedValue, fieldDef ); - } - - // For other types, return as-is - return mappedValue; - } - // For simple id-based fields, use the id as the attribute key - return item[ fieldDef.id ]; - }, - setValue: ( { item, value } ) => { - if ( fieldDef.mapping ) { - // Denormalize from canonical structure back to mapped keys - let denormalizedValue = value; - if ( fieldDef.type === 'media' ) { - denormalizedValue = denormalizeMediaValue( - value, - fieldDef - ); - } else if ( fieldDef.type === 'link' ) { - denormalizedValue = denormalizeLinkValue( - value, - fieldDef - ); + ); + return mappedValue; + }; + field.setValue = ( { value } ) => { + const attributeUpdates = {}; + Object.entries( fieldDef.mapping ).forEach( + ( [ key, attrKey ] ) => { + attributeUpdates[ attrKey ] = value[ key ]; } - - // Build an object with all mapped attributes - const updates = {}; - Object.entries( fieldDef.mapping ).forEach( - ( [ key, attrKey ] ) => { - // If key is explicitly in value, use it (even if undefined to allow clearing) - // Otherwise, preserve the old value - if ( key in denormalizedValue ) { - updates[ attrKey ] = - denormalizedValue[ key ]; - } else { - updates[ attrKey ] = item[ attrKey ]; - } - } - ); - return updates; - } - // For simple id-based fields, use the id as the attribute key - return { [ fieldDef.id ]: value }; - }, - }; + ); + return attributeUpdates; + }; + } // Only add custom Edit component if one exists for this type if ( ControlComponent ) { From f61e8744ced46e89cd866672899c89f07e9dc924 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Mon, 12 Jan 2026 14:44:07 +0800 Subject: [PATCH 02/12] Update link field to remove mapping --- .../src/hooks/block-fields/link/index.js | 52 +++++-------------- 1 file changed, 13 insertions(+), 39 deletions(-) diff --git a/packages/block-editor/src/hooks/block-fields/link/index.js b/packages/block-editor/src/hooks/block-fields/link/index.js index df71e929b5634d..dffaeac09e9cac 100644 --- a/packages/block-editor/src/hooks/block-fields/link/index.js +++ b/packages/block-editor/src/hooks/block-fields/link/index.js @@ -73,11 +73,6 @@ export default function Link( { data, field, onChange, config = {} } ) { isControl: true, } ); const { fieldDef } = config; - const updateAttributes = ( newValue ) => { - const mappedChanges = field.setValue( { item: data, value: newValue } ); - onChange( mappedChanges ); - }; - const value = field.getValue( { item: data } ); const url = value?.url; const rel = value?.rel || ''; @@ -145,30 +140,12 @@ export default function Link( { data, field, onChange, config = {} } ) { ...newValues, } ); - // Build update object dynamically based on what's in the mapping - const updateValue = { ...value }; - - if ( fieldDef?.mapping ) { - Object.keys( fieldDef.mapping ).forEach( - ( key ) => { - if ( key === 'href' || key === 'url' ) { - updateValue[ key ] = - updatedAttrs.url; - } else if ( key === 'rel' ) { - updateValue[ key ] = - updatedAttrs.rel; - } else if ( - key === 'target' || - key === 'linkTarget' - ) { - updateValue[ key ] = - updatedAttrs.linkTarget; - } - } - ); - } - - updateAttributes( updateValue ); + onChange( + field.setValue( { + item: data, + value: updatedAttrs, + } ) + ); } } onRemove={ () => { // Remove all link-related properties based on what's in the mapping @@ -177,20 +154,17 @@ export default function Link( { data, field, onChange, config = {} } ) { if ( fieldDef?.mapping ) { Object.keys( fieldDef.mapping ).forEach( ( key ) => { - if ( - key === 'href' || - key === 'url' || - key === 'rel' || - key === 'target' || - key === 'linkTarget' - ) { - removeValue[ key ] = undefined; - } + removeValue[ key ] = undefined; } ); } - updateAttributes( removeValue ); + onChange( + field.setValue( { + item: data, + value: removeValue, + } ) + ); } } /> From b270364d879f95685028e3318b702f9e51e4dcf4 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Mon, 12 Jan 2026 14:52:08 +0800 Subject: [PATCH 03/12] Update media field --- .../src/hooks/block-fields/media/index.js | 102 +++++------------- packages/block-library/src/cover/index.js | 2 +- .../block-library/src/media-text/index.js | 2 +- 3 files changed, 29 insertions(+), 77 deletions(-) diff --git a/packages/block-editor/src/hooks/block-fields/media/index.js b/packages/block-editor/src/hooks/block-fields/media/index.js index c4e03966c7441c..3e4bdb475a354e 100644 --- a/packages/block-editor/src/hooks/block-fields/media/index.js +++ b/packages/block-editor/src/hooks/block-fields/media/index.js @@ -87,13 +87,6 @@ export default function Media( { data, field, onChange, config = {} } ) { const value = field.getValue( { item: data } ); const { allowedTypes = [], multiple = false } = field.config || {}; const { fieldDef } = config; - const updateAttributes = ( newFieldValue ) => { - const mappedChanges = field.setValue( { - item: data, - value: newFieldValue, - } ); - onChange( mappedChanges ); - }; // Check if featured image is supported by checking if it's in the mapping const hasFeaturedImageSupport = @@ -152,51 +145,32 @@ export default function Media( { data, field, onChange, config = {} } ) { if ( fieldDef?.mapping ) { Object.keys( fieldDef.mapping ).forEach( ( key ) => { - if ( - key === 'id' || - key === 'src' || - key === 'url' - ) { - resetValue[ key ] = undefined; - } else if ( key === 'caption' || key === 'alt' ) { - resetValue[ key ] = ''; - } + resetValue[ key ] = undefined; } ); } - // Turn off featured image when resetting (only if it's in the mapping) - if ( hasFeaturedImageSupport ) { - resetValue.featuredImage = false; - } - - // Merge with existing value to preserve other field properties - updateAttributes( { ...value, ...resetValue } ); + onChange( + field.setValue( { + item: data, + value: resetValue, + } ) + ); } } { ...( hasFeaturedImageSupport && { useFeaturedImage: !! value?.featuredImage, onToggleFeaturedImage: () => { - updateAttributes( { - ...value, - featuredImage: ! value?.featuredImage, - } ); + onChange( + field.setValue( { + item: data, + value: { + featuredImage: ! value?.featuredImage, + }, + } ) + ); }, } ) } onSelect={ ( selectedMedia ) => { if ( selectedMedia.id && selectedMedia.url ) { - // Determine mediaType from MIME type, not from object type - let mediaType = 'image'; // default - if ( selectedMedia.mime_type ) { - if ( - selectedMedia.mime_type.startsWith( 'video/' ) - ) { - mediaType = 'video'; - } else if ( - selectedMedia.mime_type.startsWith( 'audio/' ) - ) { - mediaType = 'audio'; - } - } - // Build new value dynamically based on what's in the mapping const newValue = {}; @@ -204,38 +178,13 @@ export default function Media( { data, field, onChange, config = {} } ) { if ( fieldDef?.mapping ) { Object.keys( fieldDef.mapping ).forEach( ( key ) => { - if ( key === 'id' ) { - newValue[ key ] = selectedMedia.id; - } else if ( - key === 'src' || - key === 'url' - ) { - newValue[ key ] = selectedMedia.url; - } else if ( key === 'type' ) { - newValue[ key ] = mediaType; - } else if ( - key === 'link' && - selectedMedia.link - ) { - newValue[ key ] = selectedMedia.link; - } else if ( - key === 'caption' && - ! value?.caption && - selectedMedia.caption - ) { - newValue[ key ] = selectedMedia.caption; - } else if ( - key === 'alt' && - ! value?.alt && - selectedMedia.alt - ) { - newValue[ key ] = selectedMedia.alt; - } else if ( - key === 'poster' && - selectedMedia.poster - ) { - newValue[ key ] = selectedMedia.poster; + // Handle weird camel-casing. + if ( key === 'mediaType' ) { + newValue[ key ] = + selectedMedia.media_type; + return; } + newValue[ key ] = selectedMedia[ key ]; } ); } @@ -245,9 +194,12 @@ export default function Media( { data, field, onChange, config = {} } ) { newValue.featuredImage = false; } - // Merge with existing value to preserve other field properties - const finalValue = { ...value, ...newValue }; - updateAttributes( finalValue ); + onChange( + field.setValue( { + item: data, + value: newValue, + } ) + ); } } } renderToggle={ ( buttonProps ) => ( diff --git a/packages/block-library/src/cover/index.js b/packages/block-library/src/cover/index.js index a3e2ffb093a70b..abde17fd0107f9 100644 --- a/packages/block-library/src/cover/index.js +++ b/packages/block-library/src/cover/index.js @@ -67,7 +67,7 @@ if ( window.__experimentalContentOnlyInspectorFields ) { label: __( 'Background' ), type: 'media', mapping: { - type: 'backgroundType', + mediaType: 'backgroundType', id: 'id', url: 'url', alt: 'alt', diff --git a/packages/block-library/src/media-text/index.js b/packages/block-library/src/media-text/index.js index d50e6eaaceb1e6..45e52a805d5a1f 100644 --- a/packages/block-library/src/media-text/index.js +++ b/packages/block-library/src/media-text/index.js @@ -62,7 +62,7 @@ if ( window.__experimentalContentOnlyInspectorFields ) { type: 'media', mapping: { id: 'mediaId', - type: 'mediaType', + mediaType: 'mediaType', url: 'mediaUrl', link: 'mediaLink', }, From c392621c14186cfb0ebacf4322bd45f354d6f385 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Mon, 12 Jan 2026 15:06:26 +0800 Subject: [PATCH 04/12] Update rich text --- .../block-editor/src/hooks/block-fields/rich-text/index.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/block-editor/src/hooks/block-fields/rich-text/index.js b/packages/block-editor/src/hooks/block-fields/rich-text/index.js index a190887108af67..b019909138963d 100644 --- a/packages/block-editor/src/hooks/block-fields/rich-text/index.js +++ b/packages/block-editor/src/hooks/block-fields/rich-text/index.js @@ -33,10 +33,6 @@ export default function RichTextControl( { const attrValue = field.getValue( { item: data } ); const fieldConfig = field.config || {}; const { clientId } = config; - const updateAttributes = ( html ) => { - const mappedChanges = field.setValue( { item: data, value: html } ); - onChange( mappedChanges ); - }; const [ selection, setSelection ] = useState( { start: undefined, end: undefined, @@ -107,7 +103,7 @@ export default function RichTextControl( { } = useRichText( { value: attrValue, onChange( html, { __unstableFormats, __unstableText } ) { - updateAttributes( html ); + onChange( field.setValue( { item: data, value: html } ) ); Object.values( changeHandlers ).forEach( ( changeHandler ) => { changeHandler( __unstableFormats, __unstableText ); } ); From 6092de7a2e8492700db06af3624bec590d99d31a Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Mon, 12 Jan 2026 15:06:59 +0800 Subject: [PATCH 05/12] Fix allowedTypes --- packages/block-editor/src/hooks/block-fields/media/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/hooks/block-fields/media/index.js b/packages/block-editor/src/hooks/block-fields/media/index.js index 3e4bdb475a354e..40e82f849461c0 100644 --- a/packages/block-editor/src/hooks/block-fields/media/index.js +++ b/packages/block-editor/src/hooks/block-fields/media/index.js @@ -85,8 +85,8 @@ export default function Media( { data, field, onChange, config = {} } ) { isControl: true, } ); const value = field.getValue( { item: data } ); - const { allowedTypes = [], multiple = false } = field.config || {}; const { fieldDef } = config; + const { allowedTypes = [], multiple = false } = fieldDef.args || {}; // Check if featured image is supported by checking if it's in the mapping const hasFeaturedImageSupport = From 8f36fdd1c246e9efb0f6f62e9c2bb5e61cc50582 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Mon, 12 Jan 2026 15:16:12 +0800 Subject: [PATCH 06/12] Remove defaultValues config and config prop that seems to not be working --- .../block-editor/src/hooks/block-fields/index.js | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/packages/block-editor/src/hooks/block-fields/index.js b/packages/block-editor/src/hooks/block-fields/index.js index 31d4bac7bf2e70..4c8fc9799c1899 100644 --- a/packages/block-editor/src/hooks/block-fields/index.js +++ b/packages/block-editor/src/hooks/block-fields/index.js @@ -106,22 +106,10 @@ function BlockFields( { return blockTypeFields.map( ( fieldDef ) => { const ControlComponent = CONTROLS[ fieldDef.type ]; - const defaultValues = {}; - if ( fieldDef.mapping && blockType?.attributes ) { - Object.entries( fieldDef.mapping ).forEach( - ( [ key, attrKey ] ) => { - defaultValues[ key ] = - blockType.attributes[ attrKey ]?.defaultValue ?? - undefined; - } - ); - } - const field = { id: fieldDef.id, label: fieldDef.label, type: fieldDef.type, // Use the field's type; DataForm will use built-in or custom Edit - config: { ...fieldDef.args, defaultValues }, hideLabelFromVision: fieldDef.id === 'content', }; @@ -159,7 +147,7 @@ function BlockFields( { return field; } ); - }, [ blockTypeFields, blockType?.attributes, clientId ] ); + }, [ blockTypeFields, clientId ] ); const handleToggleField = ( fieldId ) => { setForm( ( prev ) => { From 5f14aa30ceca6d53222cc3ddc2b7505e5dd2bee7 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Mon, 12 Jan 2026 15:17:43 +0800 Subject: [PATCH 07/12] Improve clarity of createConfiguredControl --- .../src/hooks/block-fields/index.js | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/packages/block-editor/src/hooks/block-fields/index.js b/packages/block-editor/src/hooks/block-fields/index.js index 4c8fc9799c1899..94e5690d925c3e 100644 --- a/packages/block-editor/src/hooks/block-fields/index.js +++ b/packages/block-editor/src/hooks/block-fields/index.js @@ -39,20 +39,19 @@ const CONTROLS = { * Creates a configured control component that wraps a custom control * and passes configuration as props. * - * @param {Object} config - The control configuration - * @param {string} config.control - The control type (key in CONTROLS map) + * @param {Component} ControlComponent The React component for the control. + * @param {string} type The type of control. + * @param {Object} config The control configuration passed as a prop. + * * @return {Function} A wrapped control component */ -function createConfiguredControl( config ) { - const { control, ...controlConfig } = config; - const ControlComponent = CONTROLS[ control ]; - +function createConfiguredControl( ControlComponent, type, config ) { if ( ! ControlComponent ) { - throw new Error( `Control type "${ control }" not found` ); + throw new Error( `Control type "${ type }" not found` ); } return function ConfiguredControl( props ) { - return ; + return ; }; } @@ -104,8 +103,6 @@ function BlockFields( { } return blockTypeFields.map( ( fieldDef ) => { - const ControlComponent = CONTROLS[ fieldDef.type ]; - const field = { id: fieldDef.id, label: fieldDef.label, @@ -136,13 +133,17 @@ function BlockFields( { } // Only add custom Edit component if one exists for this type + const ControlComponent = CONTROLS[ fieldDef.type ]; if ( ControlComponent ) { // Use EditConfig pattern: Edit is an object with control type and config props - field.Edit = createConfiguredControl( { - control: fieldDef.type, - clientId, - fieldDef, - } ); + field.Edit = createConfiguredControl( + ControlComponent, + fieldDef.type, + { + clientId, + fieldDef, + } + ); } return field; From 8c5f600a444135727282069daee9f9cd6c48cbe5 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Mon, 12 Jan 2026 15:21:41 +0800 Subject: [PATCH 08/12] Move event handler to after early return --- .../block-editor/src/hooks/block-fields/index.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/block-editor/src/hooks/block-fields/index.js b/packages/block-editor/src/hooks/block-fields/index.js index 94e5690d925c3e..53b655c8e6e469 100644 --- a/packages/block-editor/src/hooks/block-fields/index.js +++ b/packages/block-editor/src/hooks/block-fields/index.js @@ -150,6 +150,12 @@ function BlockFields( { } ); }, [ blockTypeFields, clientId ] ); + if ( ! blockTypeFields?.length ) { + // TODO - we might still want to show a placeholder for blocks with no fields. + // for example, a way to select the block. + return null; + } + const handleToggleField = ( fieldId ) => { setForm( ( prev ) => { if ( prev.fields?.includes( fieldId ) ) { @@ -166,12 +172,6 @@ function BlockFields( { } ); }; - if ( ! blockTypeFields?.length ) { - // TODO - we might still want to show a placeholder for blocks with no fields. - // for example, a way to select the block. - return null; - } - return (
From 6a839dba2f09c2e4c24975416fdbeaffff7848ac Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Mon, 12 Jan 2026 15:27:49 +0800 Subject: [PATCH 09/12] Remove hideLabelFromVision prop --- packages/block-editor/src/hooks/block-fields/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/block-editor/src/hooks/block-fields/index.js b/packages/block-editor/src/hooks/block-fields/index.js index 53b655c8e6e469..e7a33c47fa5067 100644 --- a/packages/block-editor/src/hooks/block-fields/index.js +++ b/packages/block-editor/src/hooks/block-fields/index.js @@ -107,7 +107,6 @@ function BlockFields( { id: fieldDef.id, label: fieldDef.label, type: fieldDef.type, // Use the field's type; DataForm will use built-in or custom Edit - hideLabelFromVision: fieldDef.id === 'content', }; if ( fieldDef.mapping ) { From 54157166760f2a613937794649a4f59a32c83591 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Mon, 12 Jan 2026 15:58:48 +0800 Subject: [PATCH 10/12] Remove use of mapping in media onChange --- .../src/hooks/block-fields/media/index.js | 20 ++++--------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/packages/block-editor/src/hooks/block-fields/media/index.js b/packages/block-editor/src/hooks/block-fields/media/index.js index 40e82f849461c0..0788ff639ef734 100644 --- a/packages/block-editor/src/hooks/block-fields/media/index.js +++ b/packages/block-editor/src/hooks/block-fields/media/index.js @@ -172,22 +172,10 @@ export default function Media( { data, field, onChange, config = {} } ) { onSelect={ ( selectedMedia ) => { if ( selectedMedia.id && selectedMedia.url ) { // Build new value dynamically based on what's in the mapping - const newValue = {}; - - // Iterate over mapping keys and set values for supported properties - if ( fieldDef?.mapping ) { - Object.keys( fieldDef.mapping ).forEach( - ( key ) => { - // Handle weird camel-casing. - if ( key === 'mediaType' ) { - newValue[ key ] = - selectedMedia.media_type; - return; - } - newValue[ key ] = selectedMedia[ key ]; - } - ); - } + const newValue = { + ...selectedMedia, + mediaType: selectedMedia.media_type, + }; // Turn off featured image when manually selecting media if ( hasFeaturedImageSupport ) { From 9b442f5dbef4feb647672f2f2a06df86e1ad1796 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Mon, 12 Jan 2026 16:30:39 +0800 Subject: [PATCH 11/12] Add getValue/setValue comment --- packages/block-editor/src/hooks/block-fields/index.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/block-editor/src/hooks/block-fields/index.js b/packages/block-editor/src/hooks/block-fields/index.js index e7a33c47fa5067..dc0c514440d770 100644 --- a/packages/block-editor/src/hooks/block-fields/index.js +++ b/packages/block-editor/src/hooks/block-fields/index.js @@ -109,6 +109,12 @@ function BlockFields( { type: fieldDef.type, // Use the field's type; DataForm will use built-in or custom Edit }; + // If the field defines a `mapping`, then custom `getValue` and `setValue` + // implementations are provided. + // These functions map from the inconsistent attribute keys found on blocks + // to consistent keys that the field can use internally (and back again). + // When `mapping` isn't provided, we can use the field API's default + // implementation of these functions. if ( fieldDef.mapping ) { field.getValue = ( { item } ) => { // Extract mapped properties from the block attributes From 8dcc153774c120676f60e95a37cf99d4a6b43a33 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Tue, 13 Jan 2026 09:59:25 +0800 Subject: [PATCH 12/12] Fix use of config in MediaThumbnail --- .../block-editor/src/hooks/block-fields/media/index.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/block-editor/src/hooks/block-fields/media/index.js b/packages/block-editor/src/hooks/block-fields/media/index.js index 0788ff639ef734..8b75cf84ab3dde 100644 --- a/packages/block-editor/src/hooks/block-fields/media/index.js +++ b/packages/block-editor/src/hooks/block-fields/media/index.js @@ -24,9 +24,9 @@ import { useInspectorPopoverPlacement } from '../use-inspector-popover-placement import { getMediaSelectKey } from '../../../store/private-keys'; import { store as blockEditorStore } from '../../../store'; -function MediaThumbnail( { data, field, attachment } ) { - const config = field.config || {}; - const { allowedTypes = [], multiple = false } = config; +function MediaThumbnail( { data, field, attachment, config } ) { + const { fieldDef } = config; + const { allowedTypes = [], multiple = false } = fieldDef.args || {}; if ( multiple ) { return 'todo multiple'; @@ -53,7 +53,7 @@ function MediaThumbnail( { data, field, attachment } ) { const value = field.getValue( { item: data } ); const url = value?.url; - if ( url ) { + if ( allowedTypes[ 0 ] === 'image' && url ) { return (
@@ -208,6 +208,7 @@ export default function Media( { data, field, onChange, config = {} } ) { attachment={ attachment } field={ field } data={ data } + config={ config } /> {