Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Block Library - Audio]: Add toolbar button to add/remove caption #45112

Merged
merged 3 commits into from
Oct 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 79 additions & 24 deletions packages/block-library/src/audio/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
SelectControl,
Spinner,
ToggleControl,
ToolbarButton,
} from '@wordpress/components';
import {
BlockControls,
Expand All @@ -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
Expand All @@ -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 );
Expand All @@ -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 } );
Expand Down Expand Up @@ -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, {
Expand Down Expand Up @@ -140,6 +176,23 @@ function AudioEdit( {

return (
<>
<BlockControls group="block">
<ToolbarButton
onClick={ () => {
setShowCaption( ! showCaption );
if ( showCaption && caption ) {
setAttributes( { caption: undefined } );
ntsekouras marked this conversation as resolved.
Show resolved Hide resolved
}
} }
icon={ captionIcon }
isPressed={ showCaption }
label={
showCaption
? __( 'Remove caption' )
: __( 'Add caption' )
}
/>
</BlockControls>
<BlockControls group="other">
<MediaReplaceFlow
mediaId={ id }
Expand Down Expand Up @@ -195,26 +248,28 @@ function AudioEdit( {
<audio controls="controls" src={ src } />
</Disabled>
{ isTemporaryAudio && <Spinner /> }
{ ( ! RichText.isEmpty( caption ) || isSelected ) && (
<RichText
tagName="figcaption"
className={ __experimentalGetElementClassName(
'caption'
) }
aria-label={ __( 'Audio caption text' ) }
placeholder={ __( 'Add caption' ) }
value={ caption }
onChange={ ( value ) =>
setAttributes( { caption: value } )
}
inlineToolbar
__unstableOnSplitAtEnd={ () =>
insertBlocksAfter(
createBlock( getDefaultBlockName() )
)
}
/>
) }
{ showCaption &&
( ! RichText.isEmpty( caption ) || isSelected ) && (
<RichText
tagName="figcaption"
className={ __experimentalGetElementClassName(
'caption'
) }
ref={ captionRef }
aria-label={ __( 'Audio caption text' ) }
placeholder={ __( 'Add caption' ) }
value={ caption }
onChange={ ( value ) =>
setAttributes( { caption: value } )
}
inlineToolbar
__unstableOnSplitAtEnd={ () =>
insertBlocksAfter(
createBlock( getDefaultBlockName() )
)
}
/>
) }
</figure>
</>
);
Expand Down
28 changes: 20 additions & 8 deletions packages/block-library/src/image/image.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -343,7 +351,11 @@ export default function Image( {
} }
icon={ captionIcon }
isPressed={ showCaption }
label={ __( 'Caption' ) }
label={
showCaption
? __( 'Remove caption' )
: __( 'Add caption' )
}
/>
) }
{ ! multiImageSelection && ! isEditingImage && (
Expand Down
6 changes: 5 additions & 1 deletion packages/block-library/src/video/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,11 @@ function VideoEdit( {
} }
icon={ captionIcon }
isPressed={ showCaption }
label={ __( 'Caption' ) }
label={
showCaption
? __( 'Remove caption' )
: __( 'Add caption' )
}
/>
<TracksEditor
tracks={ tracks }
Expand Down
2 changes: 1 addition & 1 deletion packages/e2e-tests/specs/editor/blocks/gallery.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ describe( 'Gallery', () => {

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'
);
Expand Down
6 changes: 3 additions & 3 deletions test/e2e/specs/editor/blocks/image.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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' );
Expand Down Expand Up @@ -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' );
Expand Down Expand Up @@ -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( () =>
Expand Down