diff --git a/packages/editor/src/components/suggestion-mode/style.scss b/packages/editor/src/components/suggestion-mode/style.scss index cb0f82704ce3ec..f4f7707bf059f8 100644 --- a/packages/editor/src/components/suggestion-mode/style.scss +++ b/packages/editor/src/components/suggestion-mode/style.scss @@ -57,6 +57,20 @@ $suggestion-color: #007017; } } +// Pending-insert: the block was inserted in Suggest mode but isn't yet +// "real" — the marker indicates it's proposed but not committed. A +// dashed green outline distinguishes it from the solid bracket used by +// pending attribute edits, and reduced opacity de-emphasizes the +// content without hiding it. Apply clears the marker; Reject runs +// removeBlock to undo the insert. +.block-editor-block-list__block.is-suggestion-pending-insert { + position: relative; + opacity: 0.7; + outline: 2px dashed $suggestion-color; + outline-offset: 2px; + border-radius: $radius-small; +} + .editor-collab-sidebar-panel__suggestion-summary { em { font-style: italic; diff --git a/packages/editor/src/components/suggestion-mode/suggestion-diff.js b/packages/editor/src/components/suggestion-mode/suggestion-diff.js index fdccd3f7f1a45b..00527ba6fa94c1 100644 --- a/packages/editor/src/components/suggestion-mode/suggestion-diff.js +++ b/packages/editor/src/components/suggestion-mode/suggestion-diff.js @@ -166,6 +166,9 @@ function DiffForOperation( { operation } ) { if ( operation.type === 'block-remove' ) { return ; } + if ( operation.type === 'block-insert-after' ) { + return ; + } if ( operation.type === 'attribute-set' && isTextValue( operation.before ) && @@ -262,6 +265,37 @@ function BlockRemoveDiff( { operation } ) { ); } +/** + * Render a `block-insert-after` op as an underlined inserted-block preview. + * The captured snapshot (`op.block`) carries the proposed block as it was + * at insertion time; `collectBlockText` walks its content and innerBlocks + * to produce a textual preview. + * + * Falls back to "Insert block: " when the op carries no usable text + * (an inserted block with no content yet, e.g. an empty paragraph). + * + * @param {{ operation: { blockName?: string, block?: Object } }} props + */ +function BlockInsertDiff( { operation } ) { + const blockName = operation.blockName ?? operation.block?.name ?? ''; + const innerText = collectBlockText( operation.block ); + const fallbackLabel = blockName + ? // translators: %s: block name (e.g. "core/paragraph"). + __( 'New block: %s' ).replace( '%s', blockName ) + : __( 'New block proposed.' ); + return ( + + + { __( 'Inserted:' ) } + { innerText || fallbackLabel } + + + ); +} + /** * Concatenate the text content of a serialized block snapshot for use in * the sidebar diff preview. Walks `attributes.content` (RichText-backed diff --git a/packages/editor/src/components/suggestion-mode/suggestion-summary.js b/packages/editor/src/components/suggestion-mode/suggestion-summary.js index 336a7b1e0c8cdb..87d07a8c578694 100644 --- a/packages/editor/src/components/suggestion-mode/suggestion-summary.js +++ b/packages/editor/src/components/suggestion-mode/suggestion-summary.js @@ -250,6 +250,13 @@ export function summarizeOperations( operations ) { } ); continue; } + if ( op.type === 'block-insert-after' ) { + lines.push( { + label: __( 'Insert block:' ), + value: friendlyBlockName( op.blockName ), + } ); + continue; + } if ( op.type !== 'attribute-set' ) { attributeLabels.push( op.attribute ); continue; diff --git a/packages/editor/src/components/suggestion-mode/test/suggestion-summary.js b/packages/editor/src/components/suggestion-mode/test/suggestion-summary.js index 5ff7eb2262fbef..458a08824212eb 100644 --- a/packages/editor/src/components/suggestion-mode/test/suggestion-summary.js +++ b/packages/editor/src/components/suggestion-mode/test/suggestion-summary.js @@ -234,4 +234,19 @@ describe( 'summarizeOperations', () => { { label: 'Remove block:', value: 'custom-block' }, ] ); } ); + + it( 'summarizes a block-insert-after op as "Insert block: "', () => { + const lines = summarizeOperations( [ + { + type: 'block-insert-after', + clientId: 'abc', + blockName: 'core/paragraph', + anchorClientId: null, + parentClientId: null, + }, + ] ); + expect( lines ).toEqual( [ + { label: 'Insert block:', value: 'paragraph' }, + ] ); + } ); } );