Skip to content

Commit

Permalink
Account for block selection with no block toolbar
Browse files Browse the repository at this point in the history
There are some instances where a block can be selected but no block toolbar shows. This is a messy approach but duplicates the return null check from BlockToolbar into useCanBlockToolbarBeFocused. I think it would be better to combine the null check from BlockToolbar into its own hook so that hook can be used within useCanBlockToolbarBeFocused.
  • Loading branch information
jeryj committed Dec 20, 2023
1 parent 4173b30 commit dcf58ec
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 31 deletions.
85 changes: 57 additions & 28 deletions packages/block-editor/src/utils/use-can-block-toolbar-be-focused.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,76 @@
* WordPress dependencies
*/
import { useSelect } from '@wordpress/data';
import { isUnmodifiedDefaultBlock } from '@wordpress/blocks';
import {
getBlockType,
hasBlockSupport,
isUnmodifiedDefaultBlock,
} from '@wordpress/blocks';

/**
* Internal dependencies
*/
import { store as blockEditorStore } from '../store';
import { unlock } from '../lock-unlock';
import { useHasAnyBlockControls } from '../components/block-controls/use-has-block-controls';

/**
* Returns true if the block toolbar should be able to receive focus.
*
* @return {boolean} Whether the block toolbar should be able to receive focus
*/
export function useCanBlockToolbarBeFocused() {
return useSelect( ( select ) => {
const {
__unstableGetEditorMode,
getBlock,
getSettings,
getSelectedBlockClientId,
getFirstMultiSelectedBlockClientId,
} = unlock( select( blockEditorStore ) );
const hasAnyBlockControls = useHasAnyBlockControls();

const selectedBlockId =
getFirstMultiSelectedBlockClientId() || getSelectedBlockClientId();
const isEmptyDefaultBlock = isUnmodifiedDefaultBlock(
getBlock( selectedBlockId ) || {}
);
const { isToolbarEnabled, isDefaultEditingMode, maybeShowBlockToolbar } =
useSelect( ( select ) => {
const {
__unstableGetEditorMode,
getBlock,
getBlockName,
getBlockEditingMode,
getSettings,
getSelectedBlockClientId,
getFirstMultiSelectedBlockClientId,
} = unlock( select( blockEditorStore ) );

// Fixed Toolbar can be focused when:
// - a block is selected
// - fixed toolbar is on
// Block Toolbar Popover can be focused when:
// - a block is selected
// - we are in edit mode
// - it is not an empty default block
return (
!! selectedBlockId &&
( getSettings().hasFixedToolbar ||
( __unstableGetEditorMode() === 'edit' &&
! isEmptyDefaultBlock ) )
);
}, [] );
const selectedBlockId =
getFirstMultiSelectedBlockClientId() ||
getSelectedBlockClientId();
const isEmptyDefaultBlock = isUnmodifiedDefaultBlock(
getBlock( selectedBlockId ) || {}
);
const blockType =
selectedBlockId &&
getBlockType( getBlockName( selectedBlockId ) );

// Fixed Toolbar can be focused when:
// - a block is selected
// - the block has tools
// - fixed toolbar is on
// Block Toolbar Popover can be focused when:
// - a block is selected
// - the block has tools
// - we are in edit mode
// - it is not an empty default block
return {
isToolbarEnabled:
blockType &&
hasBlockSupport( blockType, '__experimentalToolbar', true ),
isDefaultEditingMode:
getBlockEditingMode( selectedBlockId ) === 'default',
maybeShowBlockToolbar:
getSettings().hasFixedToolbar ||
( __unstableGetEditorMode() === 'edit' &&
! isEmptyDefaultBlock ),
};
}, [] );

// The same check used in <BlockToolbar /> to see if it should return null.
// Should we combine these into their own hook so they stay consistent?
const noBlockToolbar =
! isToolbarEnabled ||
( ! isDefaultEditingMode && ! hasAnyBlockControls );

return ! noBlockToolbar && maybeShowBlockToolbar;
}
10 changes: 7 additions & 3 deletions packages/edit-site/src/components/header-edit-mode/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import classnames from 'classnames';
import { useViewportMatch, useReducedMotion } from '@wordpress/compose';
import {
BlockToolbar,
privateApis as blockEditorPrivateApis,
store as blockEditorStore,
} from '@wordpress/block-editor';
import { useSelect } from '@wordpress/data';
Expand Down Expand Up @@ -43,6 +44,7 @@ import { unlock } from '../../lock-unlock';
import { FOCUSABLE_ENTITIES } from '../../utils/constants';

const { PostViewLink, PreviewDropdown } = unlock( editorPrivateApis );
const { useCanBlockToolbarBeFocused } = unlock( blockEditorPrivateApis );

export default function HeaderEditMode() {
const {
Expand Down Expand Up @@ -99,7 +101,7 @@ export default function HeaderEditMode() {
const [ isBlockToolsCollapsed, setIsBlockToolsCollapsed ] =
useState( true );

const hasBlockSelected = !! blockSelectionStart;
const hasBlockToolbar = useCanBlockToolbarBeFocused();

useEffect( () => {
// If we have a new block selection, show the block tools
Expand Down Expand Up @@ -154,7 +156,7 @@ export default function HeaderEditMode() {
ref={ blockToolbarRef }
name="block-toolbar"
/>
{ hasBlockSelected && (
{ hasBlockToolbar && (
<Button
className="edit-site-header-edit-mode__block-tools-toggle"
icon={
Expand Down Expand Up @@ -183,7 +185,9 @@ export default function HeaderEditMode() {
'edit-site-header-edit-mode__center',
{
'is-collapsed':
! isBlockToolsCollapsed && isLargeViewport,
! isBlockToolsCollapsed &&
isLargeViewport &&
hasBlockToolbar,
}
) }
>
Expand Down

0 comments on commit dcf58ec

Please sign in to comment.