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

WIP: Try new api for in toolbar editing (and fix image block toolbar focus loss issue). #25890

Closed
wants to merge 15 commits into from
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -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.

<a name="getIsEditingInToolbar" href="#getIsEditingInToolbar">#</a> **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.

<a name="getLastMultiSelectedBlockClientId" href="#getLastMultiSelectedBlockClientId">#</a> **getLastMultiSelectedBlockClientId**

Returns the client ID of the last block in the multi-selection set, or null
Expand Down Expand Up @@ -1349,6 +1361,18 @@ _Parameters_
- _clientId_ `string`: The block's clientId.
- _hasControlledInnerBlocks_ `boolean`: True if the block's inner blocks are controlled.

<a name="setIsEditingInToolbar" href="#setIsEditingInToolbar">#</a> **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.

<a name="setNavigationMode" href="#setNavigationMode">#</a> **setNavigationMode**

Generators that triggers an action used to enable or disable the navigation mode.
Expand Down
46 changes: 20 additions & 26 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions packages/block-editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down
17 changes: 4 additions & 13 deletions packages/block-editor/src/components/block-controls/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<Slot
name={ buildSlotName( __experimentalIsExpanded ) }
{ ...props }
fillProps={ accessibleToolbarState }
/>
);
return <Slot { ...props } fillProps={ accessibleToolbarState } />;
}

function BlockControlsFill( { controls, __experimentalIsExpanded, children } ) {
function BlockControlsFill( { controls, children } ) {
if ( ! useDisplayBlockControls() ) {
return null;
}

return (
<Fill name={ buildSlotName( __experimentalIsExpanded ) }>
<Fill>
{ ( fillProps ) => {
// Children passed to BlockControlsFill will not have access to any
// React Context whose Provider is part of the BlockControlsSlot tree.
Expand All @@ -54,9 +48,6 @@ function BlockControlsFill( { controls, __experimentalIsExpanded, children } ) {
);
}

const buildSlotName = ( isExpanded ) =>
`BlockControls${ isExpanded ? '-expanded' : '' }`;

const BlockControls = BlockControlsFill;

BlockControls.Slot = BlockControlsSlot;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* External dependencies
*/
import classnames from 'classnames';

/**
* WordPress dependencies
*/
Expand All @@ -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 ) ),
Expand All @@ -31,7 +39,14 @@ function BlockContextualToolbar( { focusOnMount, ...props } ) {
}
}
return (
<div className="block-editor-block-contextual-toolbar-wrapper">
<div
className={ classnames(
'block-editor-block-contextual-toolbar-wrapper',
{
'is-editing-in-toolbar': isEditingInToolbar,
}
) }
>
<NavigableToolbar
focusOnMount={ focusOnMount }
className="block-editor-block-contextual-toolbar"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { useViewportMatch } from '@wordpress/compose';
/**
* Internal dependencies
*/
import BlockToolbarInlineEdit from '../block-toolbar-inline-edit';
import BlockSelectionButton from './block-selection-button';
import BlockContextualToolbar from './block-contextual-toolbar';
import Inserter from '../inserter';
Expand Down Expand Up @@ -184,11 +185,14 @@ function BlockPopover( {
</div>
) }
{ ( shouldShowContextualToolbar || isToolbarForced ) && (
<BlockContextualToolbar
// If the toolbar is being shown because of being forced
// it should focus the toolbar right after the mount.
focusOnMount={ isToolbarForced }
/>
<>
<BlockContextualToolbar
// If the toolbar is being shown because of being forced
// it should focus the toolbar right after the mount.
focusOnMount={ isToolbarForced }
/>
<BlockToolbarInlineEdit.Slot />
</>
) }
{ shouldShowBreadcrumb && (
<BlockSelectionButton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -514,11 +514,17 @@
}
}


/**
* Block Toolbar when contextual.
*/

.block-editor-block-contextual-toolbar-wrapper.is-editing-in-toolbar {
width: 0;
height: 0;
opacity: 0;
overflow: hidden;
}

.block-editor-block-contextual-toolbar {
// Block UI appearance.
border: $border-width solid $gray-900;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* External dependencies
*/
import { isEmpty } from 'lodash';

/**
* WordPress dependencies
*/
import { useDispatch } from '@wordpress/data';
import { useEffect } from '@wordpress/element';
import { createSlotFill } from '@wordpress/components';

/**
* Internal dependencies
*/
import PopoverWrapper from './popover-wrapper';

const { Fill, Slot } = createSlotFill( 'BlockToolbarInlineEdit' );

function BlockToolbarInlineEditStateHandler( { fills } ) {
const { setIsEditingInToolbar } = useDispatch( 'core/block-editor' );
useEffect( () => {
if ( isEmpty( fills ) ) {
setIsEditingInToolbar( false );
} else {
setIsEditingInToolbar( true );
}

return () => setIsEditingInToolbar( false );
}, [ fills ] );

return fills;
}

function BlockToolbarInlineEdit( { onClose, children } ) {
return (
<Fill>
<PopoverWrapper
className="block-editor-block-toolbar-inline-edit-popover"
onClose={ onClose }
>
<div className="block-editor-block-toolbar-inline-edit-popover__toolbar-wrapper">
{ children }
</div>
</PopoverWrapper>
</Fill>
);
}

function BlockToolbarInlineEditSlot() {
return (
<Slot>
{ ( fills ) => (
<BlockToolbarInlineEditStateHandler fills={ fills } />
) }
</Slot>
);
}

BlockToolbarInlineEdit.Slot = BlockToolbarInlineEditSlot;

export default BlockToolbarInlineEdit;
Loading