diff --git a/packages/block-library/src/audio/edit.js b/packages/block-library/src/audio/edit.js
index 68e9cc88117afe..47b2f36b2fb342 100644
--- a/packages/block-library/src/audio/edit.js
+++ b/packages/block-library/src/audio/edit.js
@@ -13,6 +13,7 @@ import {
SelectControl,
Spinner,
ToggleControl,
+ ToolbarButton,
} from '@wordpress/components';
import {
BlockControls,
@@ -25,12 +26,13 @@ import {
store as blockEditorStore,
__experimentalGetElementClassName,
} from '@wordpress/block-editor';
-import { useEffect } from '@wordpress/element';
+import { useEffect, useState, useCallback } from '@wordpress/element';
import { __, _x } from '@wordpress/i18n';
import { useDispatch, useSelect } from '@wordpress/data';
-import { audio as icon } from '@wordpress/icons';
+import { audio as icon, caption as captionIcon } from '@wordpress/icons';
import { createBlock, getDefaultBlockName } from '@wordpress/blocks';
import { store as noticesStore } from '@wordpress/notices';
+import { usePrevious } from '@wordpress/compose';
/**
* Internal dependencies
@@ -48,6 +50,8 @@ function AudioEdit( {
insertBlocksAfter,
} ) {
const { id, autoplay, caption, loop, preload, src } = attributes;
+ const prevCaption = usePrevious( caption );
+ const [ showCaption, setShowCaption ] = useState( !! caption );
const isTemporaryAudio = ! id && isBlobURL( src );
const mediaUpload = useSelect( ( select ) => {
const { getSettings } = select( blockEditorStore );
@@ -69,6 +73,30 @@ function AudioEdit( {
}
}, [] );
+ // We need to show the caption when changes come from
+ // history navigation(undo/redo).
+ useEffect( () => {
+ if ( caption && ! prevCaption ) {
+ setShowCaption( true );
+ }
+ }, [ caption, prevCaption ] );
+
+ // Focus the caption when we click to add one.
+ const captionRef = useCallback(
+ ( node ) => {
+ if ( node && ! caption ) {
+ node.focus();
+ }
+ },
+ [ caption ]
+ );
+
+ useEffect( () => {
+ if ( ! isSelected && ! caption ) {
+ setShowCaption( false );
+ }
+ }, [ isSelected, caption ] );
+
function toggleAttribute( attribute ) {
return ( newValue ) => {
setAttributes( { [ attribute ]: newValue } );
@@ -106,12 +134,20 @@ function AudioEdit( {
if ( ! media || ! media.url ) {
// In this case there was an error and we should continue in the editing state
// previous attributes should be removed because they may be temporary blob urls.
- setAttributes( { src: undefined, id: undefined } );
+ setAttributes( {
+ src: undefined,
+ id: undefined,
+ caption: undefined,
+ } );
return;
}
// Sets the block's attribute and updates the edit component from the
// selected media, then switches off the editing UI.
- setAttributes( { src: media.url, id: media.id } );
+ setAttributes( {
+ src: media.url,
+ id: media.id,
+ caption: media.caption,
+ } );
}
const classes = classnames( className, {
@@ -140,6 +176,23 @@ function AudioEdit( {
return (
<>
+
+ {
+ setShowCaption( ! showCaption );
+ if ( showCaption && caption ) {
+ setAttributes( { caption: undefined } );
+ }
+ } }
+ icon={ captionIcon }
+ isPressed={ showCaption }
+ label={
+ showCaption
+ ? __( 'Remove caption' )
+ : __( 'Add caption' )
+ }
+ />
+
{ isTemporaryAudio && }
- { ( ! RichText.isEmpty( caption ) || isSelected ) && (
-
- setAttributes( { caption: value } )
- }
- inlineToolbar
- __unstableOnSplitAtEnd={ () =>
- insertBlocksAfter(
- createBlock( getDefaultBlockName() )
- )
- }
- />
- ) }
+ { showCaption &&
+ ( ! RichText.isEmpty( caption ) || isSelected ) && (
+
+ setAttributes( { caption: value } )
+ }
+ inlineToolbar
+ __unstableOnSplitAtEnd={ () =>
+ insertBlocksAfter(
+ createBlock( getDefaultBlockName() )
+ )
+ }
+ />
+ ) }
>
);
diff --git a/packages/block-library/src/image/image.js b/packages/block-library/src/image/image.js
index 12e7f6dd96d2f1..244b26cbf3e7ce 100644
--- a/packages/block-library/src/image/image.js
+++ b/packages/block-library/src/image/image.js
@@ -32,7 +32,13 @@ import {
__experimentalGetElementClassName,
__experimentalUseBorderProps as useBorderProps,
} from '@wordpress/block-editor';
-import { useEffect, useMemo, useState, useRef } from '@wordpress/element';
+import {
+ useEffect,
+ useMemo,
+ useState,
+ useRef,
+ useCallback,
+} from '@wordpress/element';
import { __, sprintf, isRTL } from '@wordpress/i18n';
import { getFilename } from '@wordpress/url';
import {
@@ -93,7 +99,6 @@ export default function Image( {
sizeSlug,
} = attributes;
const imageRef = useRef();
- const captionRef = useRef();
const prevCaption = usePrevious( caption );
const [ showCaption, setShowCaption ] = useState( !! caption );
const { allowResize = true } = context;
@@ -195,11 +200,14 @@ export default function Image( {
}, [ caption, prevCaption ] );
// Focus the caption when we click to add one.
- useEffect( () => {
- if ( showCaption && ! caption ) {
- captionRef.current?.focus();
- }
- }, [ caption, showCaption ] );
+ const captionRef = useCallback(
+ ( node ) => {
+ if ( node && ! caption ) {
+ node.focus();
+ }
+ },
+ [ caption ]
+ );
// Get naturalWidth and naturalHeight from image ref, and fall back to loaded natural
// width and height. This resolves an issue in Safari where the loaded natural
@@ -343,7 +351,11 @@ export default function Image( {
} }
icon={ captionIcon }
isPressed={ showCaption }
- label={ __( 'Caption' ) }
+ label={
+ showCaption
+ ? __( 'Remove caption' )
+ : __( 'Add caption' )
+ }
/>
) }
{ ! multiImageSelection && ! isEditingImage && (
diff --git a/packages/block-library/src/video/edit.js b/packages/block-library/src/video/edit.js
index f3c1e620955729..ac7970a20d2704 100644
--- a/packages/block-library/src/video/edit.js
+++ b/packages/block-library/src/video/edit.js
@@ -224,7 +224,11 @@ function VideoEdit( {
} }
icon={ captionIcon }
isPressed={ showCaption }
- label={ __( 'Caption' ) }
+ label={
+ showCaption
+ ? __( 'Remove caption' )
+ : __( 'Add caption' )
+ }
/>
{
const imageListLink = ( await getListViewBlocks( 'Image' ) )[ 0 ];
await imageListLink.click();
- await clickBlockToolbarButton( 'Caption' );
+ await clickBlockToolbarButton( 'Add caption' );
const captionElement = await figureElement.$(
'.block-editor-rich-text__editable'
);
diff --git a/test/e2e/specs/editor/blocks/image.spec.js b/test/e2e/specs/editor/blocks/image.spec.js
index 0413aa3e33e012..209511d2d1cfa5 100644
--- a/test/e2e/specs/editor/blocks/image.spec.js
+++ b/test/e2e/specs/editor/blocks/image.spec.js
@@ -157,7 +157,7 @@ test.describe( 'Image', () => {
imageBlock.locator( 'data-testid=form-file-upload-input' )
);
await expect( image ).toHaveAttribute( 'src', new RegExp( filename ) );
- await editor.clickBlockToolbarButton( 'Caption' );
+ await editor.clickBlockToolbarButton( 'Add caption' );
await page.keyboard.type( '1' );
await page.keyboard.press( 'Enter' );
await page.keyboard.press( 'Backspace' );
@@ -186,7 +186,7 @@ test.describe( 'Image', () => {
await expect( image ).toBeVisible();
await expect( image ).toHaveAttribute( 'src', new RegExp( fileName ) );
- await editor.clickBlockToolbarButton( 'Caption' );
+ await editor.clickBlockToolbarButton( 'Add caption' );
await page.keyboard.type( '12' );
await page.keyboard.press( 'ArrowLeft' );
await page.keyboard.press( 'Enter' );
@@ -217,7 +217,7 @@ test.describe( 'Image', () => {
await expect( image ).toHaveAttribute( 'src', new RegExp( fileName ) );
// Add caption and navigate to inline toolbar.
- await editor.clickBlockToolbarButton( 'Caption' );
+ await editor.clickBlockToolbarButton( 'Add caption' );
await pageUtils.pressKeyWithModifier( 'shift', 'Tab' );
await expect(
await page.evaluate( () =>