diff --git a/docs/designers-developers/developers/data/data-core-block-editor.md b/docs/designers-developers/developers/data/data-core-block-editor.md index 2fb6515f86a7fb..51816fcec993e2 100644 --- a/docs/designers-developers/developers/data/data-core-block-editor.md +++ b/docs/designers-developers/developers/data/data-core-block-editor.md @@ -442,6 +442,18 @@ _Properties_ - _isDisabled_ `boolean`: Whether or not the user should be prevented from inserting this item. - _frecency_ `number`: Heuristic that combines frequency and recency. +# **getIsEditingInToolbar** + +Returns whether inline toolbar editing UI is visible. + +_Parameters_ + +- _state_ `Object`: Global application state. + +_Returns_ + +- `boolean`: True if inline toolbar editing UI is visible. + # **getLastMultiSelectedBlockClientId** Returns the client ID of the last block in the multi-selection set, or null @@ -1349,6 +1361,18 @@ _Parameters_ - _clientId_ `string`: The block's clientId. - _hasControlledInnerBlocks_ `boolean`: True if the block's inner blocks are controlled. +# **setIsEditingInToolbar** + +Returns an action that updates the toolbar inline editing state. + +_Parameters_ + +- _isEditingInToolbar_ `boolean`: Whether to show or hide inline editing. + +_Returns_ + +- `Object`: Action object. + # **setNavigationMode** Generators that triggers an action used to enable or disable the navigation mode. diff --git a/package-lock.json b/package-lock.json index 8ca2bd93249c56..cf5f01728484a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15019,19 +15019,12 @@ } }, "@types/react": { - "version": "16.9.49", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.49.tgz", - "integrity": "sha512-DtLFjSj0OYAdVLBbyjhuV9CdGVHCkHn2R+xr3XkBvK2rS1Y1tkc14XSGjYgm5Fjjr90AxH9tiSzc1pCFMGO06g==", + "version": "16.9.18", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.18.tgz", + "integrity": "sha512-MvjiKX/kUE8o49ipppg49RDZ97p4XfW1WWksp/UlTUSJpisyhzd62pZAMXxAscFLoxfYOflkGANAnGkSeHTFQg==", "requires": { "@types/prop-types": "*", - "csstype": "^3.0.2" - }, - "dependencies": { - "csstype": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.3.tgz", - "integrity": "sha512-jPl+wbWPOWJ7SXsWyqGRk3lGecbar0Cb0OvZF/r/ZU011R4YqiRehgkQ9p4eQfo9DSDLqLL3wHwfxeJiuIsNag==" - } + "csstype": "^2.2.0" } }, "@types/react-color": { @@ -15044,9 +15037,9 @@ } }, "@types/react-dom": { - "version": "16.9.8", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.8.tgz", - "integrity": "sha512-ykkPQ+5nFknnlU6lDd947WbQ6TE3NNzbQAkInC2EKY1qeYdTKp7onFusmYZb+ityzx2YviqT6BXSu+LyWWJwcA==", + "version": "16.9.5", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.5.tgz", + "integrity": "sha512-BX6RQ8s9D+2/gDhxrj8OW+YD4R+8hj7FEM/OJHGNR0KipE1h1mSsf39YeyC81qafkq+N3rU3h3RFbLSwE5VqUg==", "requires": { "@types/react": "*" } @@ -16791,7 +16784,6 @@ "@wordpress/token-list": "file:packages/token-list", "@wordpress/url": "file:packages/url", "@wordpress/viewport": "file:packages/viewport", - "@wordpress/warning": "file:packages/warning", "@wordpress/wordcount": "file:packages/wordcount", "classnames": "^2.2.5", "css-mediaquery": "^0.1.2", @@ -16802,7 +16794,6 @@ "memize": "^1.1.0", "react-autosize-textarea": "^3.0.2", "react-spring": "^8.0.19", - "react-transition-group": "^2.9.0", "reakit": "1.1.0", "redux-multi": "^0.1.12", "refx": "^3.0.0", @@ -31656,6 +31647,7 @@ "version": "3.4.0", "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", + "dev": true, "requires": { "@babel/runtime": "^7.1.2" } @@ -53111,7 +53103,8 @@ "react-lifecycles-compat": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==", + "dev": true }, "react-merge-refs": { "version": "1.0.0", @@ -53874,6 +53867,15 @@ "symbol-observable": "1.0.1" } }, + "scheduler": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.15.0.tgz", + "integrity": "sha512-xAefmSfN6jqAa7Kuq7LIJY0bwAPG3xlCj0HMEBQk1lxYiDKZscY2xJ5U/61ZTrYbmNQbXa+gc7czPkVo11tnCg==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -54390,6 +54392,7 @@ "version": "2.9.0", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", + "dev": true, "requires": { "dom-helpers": "^3.4.0", "loose-envify": "^1.4.0", @@ -55971,15 +55974,6 @@ "xmlchars": "^2.1.1" } }, - "scheduler": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.15.0.tgz", - "integrity": "sha512-xAefmSfN6jqAa7Kuq7LIJY0bwAPG3xlCj0HMEBQk1lxYiDKZscY2xJ5U/61ZTrYbmNQbXa+gc7czPkVo11tnCg==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, "schema-utils": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", diff --git a/packages/block-editor/package.json b/packages/block-editor/package.json index dee14d5468e36a..fc1612ba904f00 100644 --- a/packages/block-editor/package.json +++ b/packages/block-editor/package.json @@ -50,7 +50,6 @@ "@wordpress/token-list": "file:../token-list", "@wordpress/url": "file:../url", "@wordpress/viewport": "file:../viewport", - "@wordpress/warning": "file:../warning", "@wordpress/wordcount": "file:../wordcount", "classnames": "^2.2.5", "css-mediaquery": "^0.1.2", @@ -61,7 +60,6 @@ "memize": "^1.1.0", "react-autosize-textarea": "^3.0.2", "react-spring": "^8.0.19", - "react-transition-group": "^2.9.0", "reakit": "1.1.0", "redux-multi": "^0.1.12", "refx": "^3.0.0", diff --git a/packages/block-editor/src/components/block-controls/index.js b/packages/block-editor/src/components/block-controls/index.js index f2b35e4b5301f8..297d3839df4aa9 100644 --- a/packages/block-editor/src/components/block-controls/index.js +++ b/packages/block-editor/src/components/block-controls/index.js @@ -20,24 +20,18 @@ import useDisplayBlockControls from '../use-display-block-controls'; const { Fill, Slot } = createSlotFill( 'BlockControls' ); -function BlockControlsSlot( { __experimentalIsExpanded = false, ...props } ) { +function BlockControlsSlot( props ) { const accessibleToolbarState = useContext( ToolbarContext ); - return ( - - ); + return ; } -function BlockControlsFill( { controls, __experimentalIsExpanded, children } ) { +function BlockControlsFill( { controls, children } ) { if ( ! useDisplayBlockControls() ) { return null; } return ( - + { ( fillProps ) => { // Children passed to BlockControlsFill will not have access to any // React Context whose Provider is part of the BlockControlsSlot tree. @@ -54,9 +48,6 @@ function BlockControlsFill( { controls, __experimentalIsExpanded, children } ) { ); } -const buildSlotName = ( isExpanded ) => - `BlockControls${ isExpanded ? '-expanded' : '' }`; - const BlockControls = BlockControlsFill; BlockControls.Slot = BlockControlsSlot; diff --git a/packages/block-editor/src/components/block-list/block-contextual-toolbar.js b/packages/block-editor/src/components/block-list/block-contextual-toolbar.js index 154a8f2e1f303c..f2c35796246bba 100644 --- a/packages/block-editor/src/components/block-list/block-contextual-toolbar.js +++ b/packages/block-editor/src/components/block-list/block-contextual-toolbar.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + /** * WordPress dependencies */ @@ -12,14 +17,17 @@ import NavigableToolbar from '../navigable-toolbar'; import { BlockToolbar } from '../'; function BlockContextualToolbar( { focusOnMount, ...props } ) { - const { blockType } = useSelect( ( select ) => { - const { getBlockName, getSelectedBlockClientIds } = select( - 'core/block-editor' - ); + const { blockType, isEditingInToolbar } = useSelect( ( select ) => { + const { + getBlockName, + getSelectedBlockClientIds, + getIsEditingInToolbar, + } = select( 'core/block-editor' ); const { getBlockType } = select( 'core/blocks' ); const selectedBlockClientIds = getSelectedBlockClientIds(); const selectedBlockClientId = selectedBlockClientIds[ 0 ]; return { + isEditingInToolbar: getIsEditingInToolbar(), blockType: selectedBlockClientId && getBlockType( getBlockName( selectedBlockClientId ) ), @@ -31,7 +39,14 @@ function BlockContextualToolbar( { focusOnMount, ...props } ) { } } return ( -
+
) } { ( shouldShowContextualToolbar || isToolbarForced ) && ( - + <> + + + ) } { shouldShowBreadcrumb && ( { + if ( isEmpty( fills ) ) { + setIsEditingInToolbar( false ); + } else { + setIsEditingInToolbar( true ); + } + + return () => setIsEditingInToolbar( false ); + }, [ fills ] ); + + return fills; +} + +function BlockToolbarInlineEdit( { onClose, children } ) { + return ( + + +
+ { children } +
+
+
+ ); +} + +function BlockToolbarInlineEditSlot() { + return ( + + { ( fills ) => ( + + ) } + + ); +} + +BlockToolbarInlineEdit.Slot = BlockToolbarInlineEditSlot; + +export default BlockToolbarInlineEdit; diff --git a/packages/block-editor/src/components/block-toolbar-inline-edit/popover-wrapper.js b/packages/block-editor/src/components/block-toolbar-inline-edit/popover-wrapper.js new file mode 100644 index 00000000000000..1e056996131547 --- /dev/null +++ b/packages/block-editor/src/components/block-toolbar-inline-edit/popover-wrapper.js @@ -0,0 +1,122 @@ +/** + * WordPress dependencies + */ +import { + withConstrainedTabbing, + withFocusReturn, + withFocusOutside, +} from '@wordpress/components'; +import { focus } from '@wordpress/dom'; +import { Component, useEffect, useRef } from '@wordpress/element'; +import { ESCAPE, UP, RIGHT, DOWN, LEFT } from '@wordpress/keycodes'; + +const ARROW_KEYCODES = [ UP, RIGHT, DOWN, LEFT ]; + +function stopPropagation( event ) { + event.stopPropagation(); +} + +const DetectOutside = withFocusOutside( + class extends Component { + handleFocusOutside( event ) { + this.props.onFocusOutside( event ); + } + + render() { + return this.props.children; + } + } +); + +const FocusManaged = withConstrainedTabbing( + withFocusReturn( ( { children } ) => children ) +); + +/** + * Hook used to focus the first tabbable element on mount. + * + * @param {boolean|string} focusOnMount Focus on mount mode. + * @param {Object} contentRef Reference to the popover content element. + */ +function useFocusContentOnMount( focusOnMount, contentRef ) { + // Focus handling + useEffect( () => { + /* + * Without the setTimeout, the dom node is not being focused. Related: + * https://stackoverflow.com/questions/35522220/react-ref-with-focus-doesnt-work-without-settimeout-my-example + * + * TODO: Treat the cause, not the symptom. + */ + const focusTimeout = setTimeout( () => { + if ( ! focusOnMount || ! contentRef.current ) { + return; + } + + if ( focusOnMount === 'firstElement' ) { + // Find first tabbable node within content and shift focus, falling + // back to the popover panel itself. + const firstTabbable = focus.tabbable.find( + contentRef.current + )[ 0 ]; + + if ( firstTabbable ) { + firstTabbable.focus(); + } else { + contentRef.current.focus(); + } + + return; + } + + if ( focusOnMount === 'container' ) { + // Focus the popover panel itself so items in the popover are easily + // accessed via keyboard navigation. + contentRef.current.focus(); + } + }, 0 ); + + return () => clearTimeout( focusTimeout ); + }, [] ); +} + +export default function PopoverWrapper( { + onClose, + focusOnMount = 'firstElement', + children, + className, +} ) { + // Event handlers + const onKeyDown = ( event ) => { + if ( ARROW_KEYCODES.includes( event.keyCode ) ) { + // Prevent WritingFlow from triggering a block focus change. + event.stopPropagation(); + } + + if ( event.keyCode === ESCAPE && onClose ) { + // Close on escape + event.stopPropagation(); + onClose(); + } + }; + + const contentRef = useRef(); + + useFocusContentOnMount( focusOnMount, contentRef ); + + // Disable reason: this stops certain events from propagating outside of the component. + // - onMouseDown is disabled as this can cause interactions with other DOM elements + /* eslint-disable jsx-a11y/no-static-element-interactions */ + return ( +
+ + { children } + +
+ ); + /* eslint-enable jsx-a11y/no-static-element-interactions */ +} diff --git a/packages/block-editor/src/components/block-toolbar-inline-edit/style.scss b/packages/block-editor/src/components/block-toolbar-inline-edit/style.scss new file mode 100644 index 00000000000000..0ba61112c6876f --- /dev/null +++ b/packages/block-editor/src/components/block-toolbar-inline-edit/style.scss @@ -0,0 +1,7 @@ +.block-editor-block-toolbar-inline-edit-popover { + margin-bottom: $grid-unit-15; +} + +.block-editor-block-toolbar-inline-edit-popover__toolbar-wrapper { + display: flex; +} diff --git a/packages/block-editor/src/components/block-toolbar/expanded-block-controls-container.js b/packages/block-editor/src/components/block-toolbar/expanded-block-controls-container.js deleted file mode 100644 index e1a475c286e88f..00000000000000 --- a/packages/block-editor/src/components/block-toolbar/expanded-block-controls-container.js +++ /dev/null @@ -1,131 +0,0 @@ -/** - * External dependencies - */ -import { TransitionGroup, CSSTransition } from 'react-transition-group'; -import { throttle } from 'lodash'; - -/** - * WordPress dependencies - */ -import { useRef, useState, useEffect, useCallback } from '@wordpress/element'; -import warning from '@wordpress/warning'; - -/** - * Internal dependencies - */ -import BlockControls from '../block-controls'; - -function getComputedStyle( node ) { - return node.ownerDocument.defaultView.getComputedStyle( node ); -} - -export default function ExpandedBlockControlsContainer( { - children, - className, -} ) { - return ( - - { ( fills ) => { - return ( - - { children } - - ); - } } - - ); -} - -function ExpandedBlockControlsHandler( { fills, className = '', children } ) { - const containerRef = useRef(); - const fillsRef = useRef(); - const toolbarRef = useRef(); - const [ dimensions, setDimensions ] = useState( {} ); - - const fillsPropRef = useRef(); - fillsPropRef.current = fills; - const resizeToolbar = useCallback( - throttle( () => { - const toolbarContentElement = fillsPropRef.current.length - ? fillsRef.current - : toolbarRef.current; - if ( ! toolbarContentElement ) { - return; - } - toolbarContentElement.style.position = 'absolute'; - toolbarContentElement.style.width = 'auto'; - const contentCSS = getComputedStyle( toolbarContentElement ); - setDimensions( { - width: contentCSS.getPropertyValue( 'width' ), - height: contentCSS.getPropertyValue( 'height' ), - } ); - toolbarContentElement.style.position = ''; - toolbarContentElement.style.width = ''; - }, 100 ), - [] - ); - - useEffect( () => { - const observer = new window.MutationObserver( function ( - mutationsList - ) { - const hasChildList = mutationsList.find( - ( { type } ) => type === 'childList' - ); - if ( hasChildList ) { - resizeToolbar(); - } - } ); - - observer.observe( containerRef.current, { - childList: true, - subtree: true, - } ); - - return () => observer.disconnect(); - }, [] ); - - useEffect( () => { - if ( fills.length > 1 ) { - warning( - `${ fills.length } slots were registered but only one may be displayed.` - ); - } - }, [ fills.length ] ); - - const displayFill = fills[ 0 ]; - return ( -
- - { displayFill ? ( - -
- { displayFill } -
-
- ) : ( - -
- { children } -
-
- ) } -
-
- ); -} diff --git a/packages/block-editor/src/components/block-toolbar/index.js b/packages/block-editor/src/components/block-toolbar/index.js index bed8b921a2fe91..87cfcad1cf9f1a 100644 --- a/packages/block-editor/src/components/block-toolbar/index.js +++ b/packages/block-editor/src/components/block-toolbar/index.js @@ -22,12 +22,8 @@ import BlockControls from '../block-controls'; import BlockFormatControls from '../block-format-controls'; import BlockSettingsMenu from '../block-settings-menu'; import { useShowMoversGestures } from './utils'; -import ExpandedBlockControlsContainer from './expanded-block-controls-container'; -export default function BlockToolbar( { - hideDragHandle, - __experimentalExpandedControl = false, -} ) { +export default function BlockToolbar( { hideDragHandle } ) { const { blockClientIds, blockClientId, @@ -106,12 +102,8 @@ export default function BlockToolbar( { shouldShowMovers && 'is-showing-movers' ); - const Wrapper = __experimentalExpandedControl - ? ExpandedBlockControlsContainer - : 'div'; - return ( - +
{ ! isMultiToolbar && (
@@ -141,6 +133,6 @@ export default function BlockToolbar( { ) } - +
); } diff --git a/packages/block-editor/src/components/block-toolbar/style.scss b/packages/block-editor/src/components/block-toolbar/style.scss index bffe229b714e04..c9499b4731dfd0 100644 --- a/packages/block-editor/src/components/block-toolbar/style.scss +++ b/packages/block-editor/src/components/block-toolbar/style.scss @@ -106,31 +106,3 @@ transform: translateY(-($block-toolbar-height + $grid-unit-15)); } } - -.block-editor-block-toolbar-animated-width-container { - position: relative; - overflow: hidden; - transition: width 300ms; -} - -.block-editor-block-toolbar-content-enter { - position: absolute; - top: 0; - left: 0; - width: auto; - opacity: 0; -} -.block-editor-block-toolbar-content-enter-active { - position: absolute; - opacity: 1; - transition: opacity 300ms; -} -.block-editor-block-toolbar-content-exit { - width: auto; - opacity: 1; - pointer-events: none; -} -.block-editor-block-toolbar-content-exit-active { - opacity: 0; - transition: opacity 300ms; -} diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index 7719bfff230e89..72306584cd3bef 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -17,6 +17,7 @@ export { default as BlockEdit, useBlockEditContext } from './block-edit'; export { default as BlockFormatControls } from './block-format-controls'; export { default as BlockIcon } from './block-icon'; export { default as BlockNavigationDropdown } from './block-navigation/dropdown'; +export { default as __experimentalBlockToolbarInlineEdit } from './block-toolbar-inline-edit'; export { BlockNavigationBlockFill as __experimentalBlockNavigationBlockFill } from './block-navigation/block-slot'; export { default as __experimentalBlockNavigationEditor } from './block-navigation/editor'; export { default as __experimentalBlockNavigationTree } from './block-navigation/tree'; diff --git a/packages/block-editor/src/store/actions.js b/packages/block-editor/src/store/actions.js index e506e3271028e8..bbaf9832b1f9cc 100644 --- a/packages/block-editor/src/store/actions.js +++ b/packages/block-editor/src/store/actions.js @@ -551,6 +551,20 @@ export function hideInsertionPoint() { }; } +/** + * Returns an action that updates the toolbar inline editing state. + * + * @param {boolean} isEditingInToolbar Whether to show or hide inline editing. + * + * @return {Object} Action object. + */ +export function setIsEditingInToolbar( isEditingInToolbar ) { + return { + type: 'SET_IS_EDITING_IN_TOOLBAR', + isEditingInToolbar, + }; +} + /** * Returns an action object resetting the template validity. * diff --git a/packages/block-editor/src/store/reducer.js b/packages/block-editor/src/store/reducer.js index 85898175da7dac..b4934c277622a7 100644 --- a/packages/block-editor/src/store/reducer.js +++ b/packages/block-editor/src/store/reducer.js @@ -1530,6 +1530,22 @@ export function isNavigationMode( state = false, action ) { return state; } +/** + * Reducer returning whether the toolbar is showing an inline editing UI. + * + * @param {boolean} state Whether inline editing UI is displayed. + * @param {Object} action Dispatched action. + * + * @return {boolean} Updated state denoting whether inline editing UI is shown. + */ +export function isEditingInToolbar( state = false, action ) { + if ( action.type === 'SET_IS_EDITING_IN_TOOLBAR' ) { + return action.isEditingInToolbar; + } + + return state; +} + /** * Reducer returning whether the block moving mode is enabled or not. * @@ -1663,6 +1679,7 @@ export default combineReducers( { preferences, lastBlockAttributesChange, isNavigationMode, + isEditingInToolbar, hasBlockMovingClientId, automaticChangeStatus, highlightedBlock, diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index b84a7ff24aed79..94d68040df91e9 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -1791,3 +1791,14 @@ export function isBlockHighlighted( state, clientId ) { export function areInnerBlocksControlled( state, clientId ) { return !! state.blocks.controlledInnerBlocks[ clientId ]; } + +/** + * Returns whether inline toolbar editing UI is visible. + * + * @param {Object} state Global application state. + * + * @return {boolean} True if inline toolbar editing UI is visible. + */ +export function getIsEditingInToolbar( state ) { + return state.isEditingInToolbar; +} diff --git a/packages/block-editor/src/style.scss b/packages/block-editor/src/style.scss index 096eb3bacb7969..84bfa247103e08 100644 --- a/packages/block-editor/src/style.scss +++ b/packages/block-editor/src/style.scss @@ -24,6 +24,7 @@ @import "./components/block-settings-menu/style.scss"; @import "./components/block-styles/style.scss"; @import "./components/block-switcher/style.scss"; +@import "./components/block-toolbar-inline-edit/style.scss"; @import "./components/block-types-list/style.scss"; @import "./components/block-variation-picker/style.scss"; @import "./components/button-block-appender/style.scss"; diff --git a/packages/block-library/src/image/image-editor.js b/packages/block-library/src/image/image-editor.js index a3401132390fb3..1abea058264850 100644 --- a/packages/block-library/src/image/image-editor.js +++ b/packages/block-library/src/image/image-editor.js @@ -9,7 +9,7 @@ import classnames from 'classnames'; * WordPress dependencies */ -import { BlockControls } from '@wordpress/block-editor'; +import { __experimentalBlockToolbarInlineEdit } from '@wordpress/block-editor'; import { useState } from '@wordpress/element'; import { search, @@ -20,7 +20,6 @@ import { import { ToolbarGroup, ToolbarButton, - ToolbarItem, Spinner, RangeControl, DropdownMenu, @@ -319,7 +318,9 @@ export default function ImageEditor( { /> { inProgress && }
- + <__experimentalBlockToolbarInlineEdit + onClose={ () => setIsEditingImage( false ) } + > ) } /> - - { ( toggleProps ) => ( - - ) } - + - + ); } diff --git a/packages/block-library/src/image/image.js b/packages/block-library/src/image/image.js index 3e32afd372524d..a484a4167229d4 100644 --- a/packages/block-library/src/image/image.js +++ b/packages/block-library/src/image/image.js @@ -248,26 +248,26 @@ export default function Image( { const controls = ( <> - { ! isEditingImage && ( - - - - ) } - { canEditImage && ! isEditingImage && ( + + + + { canEditImage && ( setIsEditingImage( true ) } icon={ crop } label={ __( 'Crop' ) } + aria-haspopup="dialog" + aria-expanded={ isEditingImage } /> ) } @@ -280,17 +280,15 @@ export default function Image( { /> ) } - { ! isEditingImage && ( - - ) } +