Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
5d7bda7
Move Selected Block Tools into the header toolbar in the DOM but pres…
jeryj Aug 9, 2023
c593e05
Render selected block toolbar as a fill within a slot in the header t…
jeryj Aug 17, 2023
4e0c909
Pass isFixed to ContextualToolbar for styling
jeryj Aug 9, 2023
53df7d3
Add block popover to edit site header slot
jeryj Aug 17, 2023
f0da0e8
poc: adjust styles for top toolbar in happy path on desktop and tablet
jeryj Aug 9, 2023
9fc803c
Use SCSS variables for calculating top toolbar height
jeryj Aug 10, 2023
5257349
Remove unnecessary z-index
jeryj Aug 10, 2023
9bd48f9
Show the toolbar as fixed when on tablet breakpoint even if using pop…
jeryj Aug 10, 2023
7fc9bb1
Add classname to selected block tools slot and use bubblesVirtually
jeryj Aug 17, 2023
96b184b
POC: Remove calculated width from toolbar
jeryj Aug 17, 2023
fd31f65
Move lastFocus into redux store
jeryj Aug 25, 2023
c3c76b9
Register global shortcut for moving focus back to the last focused bl…
jeryj Aug 25, 2023
e747b88
Start on escape to return to block selection
jeryj Aug 25, 2023
3b696bc
Add move focus to selected block global shortcut to site editor
jeryj Aug 25, 2023
732fabb
Rename editor focus-editor shortcut
jeryj Aug 25, 2023
9acb93d
Handle Escape on Toolbar Option 1: Add event listeners to all childre…
jeryj Sep 1, 2023
b5f5248
Handle Escape on Toolbar Option 2: Use addEventListener on the select…
jeryj Sep 1, 2023
401cf4c
Handle Escape on Toolbar Option 3: Remove bubblesVirtually from block…
jeryj Sep 1, 2023
25a79f2
POC: DON'T MERGE THIS. Allow tab keypress formatting in rich text fie…
jeryj Sep 6, 2023
384e717
Add inline rich tools to header popover
jeryj Sep 11, 2023
399afc6
Remove z-index hack for using editor block tools in header
jeryj Sep 11, 2023
051fd41
Add menubar role to toolbar group
jeryj Sep 11, 2023
44851dd
Fix accidental duplicate block iserter in site editor document toolbar
jeryj Sep 11, 2023
5fc387c
Make entire header bar menubar role
jeryj Sep 12, 2023
a9b0710
Add focusEditorOnEscape to NavigableToolbar to return focus to editor…
jeryj Sep 12, 2023
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
Next Next commit
Move Selected Block Tools into the header toolbar in the DOM but pres…
…erve all visual interactions

This is a big commit with a large potential for bugs. Think of this as a spike or POC for now. There'll be a lot to address. Some general TODOs:
- [ ] Refactor shared code between empty-block-inserter and selected-block-tools
- [ ] More explicitly pass the popover slot and content ref into the SelectedBlockTools
- [ ] Shortcut/keystrokes for returning from the toolbar to where the cursor was before moving into the toolbar
- [ ] Inline Tools either move to the top toolbar or get inserted into the main block toolbar (think image caption formatting tools)
- [ ] Visual styles for the top toolbar
  • Loading branch information
jeryj committed Sep 6, 2023
commit 5d7bda72ab6afe24e88018136e0aa856e74ce1bf
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
/**
* External dependencies
*/
import classnames from 'classnames';

/**
* WordPress dependencies
*/
import { isUnmodifiedDefaultBlock } from '@wordpress/blocks';
import { useSelect } from '@wordpress/data';

/**
* Internal dependencies
*/
import { store as blockEditorStore } from '../../store';
import BlockPopover from '../block-popover';
import useBlockToolbarPopoverProps from './use-block-toolbar-popover-props';
import Inserter from '../inserter';

function selector( select ) {
const {
__unstableGetEditorMode,
hasMultiSelection,
isTyping,
getLastMultiSelectedBlockClientId,
} = select( blockEditorStore );

return {
editorMode: __unstableGetEditorMode(),
hasMultiSelection: hasMultiSelection(),
isTyping: isTyping(),
lastClientId: hasMultiSelection()
? getLastMultiSelectedBlockClientId()
: null,
};
}

function EmptyBlockInserter( {
clientId,
rootClientId,
isEmptyDefaultBlock,
capturingClientId,
__unstablePopoverSlot,
__unstableContentRef,
} ) {
const { editorMode, isTyping, lastClientId } = useSelect( selector, [] );

const isInsertionPointVisible = useSelect(
( select ) => {
const {
isBlockInsertionPointVisible,
getBlockInsertionPoint,
getBlockOrder,
} = select( blockEditorStore );

if ( ! isBlockInsertionPointVisible() ) {
return false;
}

const insertionPoint = getBlockInsertionPoint();
const order = getBlockOrder( insertionPoint.rootClientId );
return order[ insertionPoint.index ] === clientId;
},
[ clientId ]
);

const showEmptyBlockSideInserter =
! isTyping && editorMode === 'edit' && isEmptyDefaultBlock;

const popoverProps = useBlockToolbarPopoverProps( {
contentElement: __unstableContentRef?.current,
clientId,
} );

if ( showEmptyBlockSideInserter ) {
return (
<BlockPopover
clientId={ capturingClientId || clientId }
__unstableCoverTarget
bottomClientId={ lastClientId }
className={ classnames(
'block-editor-block-list__block-side-inserter-popover',
{
'is-insertion-point-visible': isInsertionPointVisible,
}
) }
__unstablePopoverSlot={ __unstablePopoverSlot }
__unstableContentRef={ __unstableContentRef }
resize={ false }
shift={ false }
{ ...popoverProps }
>
<div className="block-editor-block-list__empty-block-inserter">
<Inserter
position="bottom right"
rootClientId={ rootClientId }
clientId={ clientId }
__experimentalIsQuick
/>
</div>
</BlockPopover>
);
}

return null;
}

function wrapperSelector( select ) {
const {
getSelectedBlockClientId,
getFirstMultiSelectedBlockClientId,
getBlockRootClientId,
getBlock,
getBlockParents,
__experimentalGetBlockListSettingsForBlocks,
} = select( blockEditorStore );

const clientId =
getSelectedBlockClientId() || getFirstMultiSelectedBlockClientId();

if ( ! clientId ) {
return;
}

const { name, attributes = {} } = getBlock( clientId ) || {};
const blockParentsClientIds = getBlockParents( clientId );

// Get Block List Settings for all ancestors of the current Block clientId.
const parentBlockListSettings = __experimentalGetBlockListSettingsForBlocks(
blockParentsClientIds
);

// Get the clientId of the topmost parent with the capture toolbars setting.
const capturingClientId = blockParentsClientIds.find(
( parentClientId ) =>
parentBlockListSettings[ parentClientId ]
?.__experimentalCaptureToolbars
);

return {
clientId,
rootClientId: getBlockRootClientId( clientId ),
name,
isEmptyDefaultBlock:
name && isUnmodifiedDefaultBlock( { name, attributes } ),
capturingClientId,
};
}

export default function WrappedEmptyBlockInserter( {
__unstablePopoverSlot,
__unstableContentRef,
} ) {
const selected = useSelect( wrapperSelector, [] );

if ( ! selected ) {
return null;
}

const {
clientId,
rootClientId,
name,
isEmptyDefaultBlock,
capturingClientId,
} = selected;

if ( ! name ) {
return null;
}

return (
<EmptyBlockInserter
clientId={ clientId }
rootClientId={ rootClientId }
isEmptyDefaultBlock={ isEmptyDefaultBlock }
capturingClientId={ capturingClientId }
__unstablePopoverSlot={ __unstablePopoverSlot }
__unstableContentRef={ __unstableContentRef }
/>
);
}
18 changes: 3 additions & 15 deletions packages/block-editor/src/components/block-tools/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
* WordPress dependencies
*/
import { useSelect, useDispatch } from '@wordpress/data';
import { useViewportMatch } from '@wordpress/compose';
import { Popover } from '@wordpress/components';
import { __unstableUseShortcutEventMatch as useShortcutEventMatch } from '@wordpress/keyboard-shortcuts';
import { useRef } from '@wordpress/element';
Expand All @@ -14,9 +13,8 @@ import {
InsertionPointOpenRef,
default as InsertionPoint,
} from './insertion-point';
import SelectedBlockPopover from './selected-block-popover';
import EmptyBlockInserter from './empty-block-inserter';
import { store as blockEditorStore } from '../../store';
import BlockContextualToolbar from './block-contextual-toolbar';
import usePopoverScroll from '../block-popover/use-popover-scroll';
import ZoomOutModeInserters from './zoom-out-mode-inserters';

Expand Down Expand Up @@ -45,11 +43,7 @@ export default function BlockTools( {
__unstableContentRef,
...props
} ) {
const isLargeViewport = useViewportMatch( 'medium' );
const { hasFixedToolbar, isZoomOutMode, isTyping } = useSelect(
selector,
[]
);
const { isZoomOutMode, isTyping } = useSelect( selector, [] );
const isMatch = useShortcutEventMatch();
const { getSelectedBlockClientIds, getBlockRootClientId } =
useSelect( blockEditorStore );
Expand Down Expand Up @@ -138,13 +132,7 @@ export default function BlockTools( {
__unstableContentRef={ __unstableContentRef }
/>
) }
{ ! isZoomOutMode &&
( hasFixedToolbar || ! isLargeViewport ) && (
<BlockContextualToolbar isFixed />
) }
{ /* Even if the toolbar is fixed, the block popover is still
needed for navigation and zoom-out mode. */ }
<SelectedBlockPopover
<EmptyBlockInserter
__unstableContentRef={ __unstableContentRef }
/>
{ /* Used for the inline rich text toolbar. */ }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useRef, useEffect } from '@wordpress/element';
import { isUnmodifiedDefaultBlock } from '@wordpress/blocks';
import { useDispatch, useSelect } from '@wordpress/data';
import { useShortcut } from '@wordpress/keyboard-shortcuts';
import { getScrollContainer } from '@wordpress/dom';

/**
* Internal dependencies
Expand All @@ -19,7 +20,6 @@ import BlockContextualToolbar from './block-contextual-toolbar';
import { store as blockEditorStore } from '../../store';
import BlockPopover from '../block-popover';
import useBlockToolbarPopoverProps from './use-block-toolbar-popover-props';
import Inserter from '../inserter';
import { useShouldContextualToolbarShow } from '../../utils/use-should-contextual-toolbar-show';

function selector( select ) {
Expand All @@ -40,13 +40,12 @@ function selector( select ) {
};
}

function SelectedBlockPopover( {
function SelectedBlockTools( {
clientId,
rootClientId,
isEmptyDefaultBlock,
isFixed,
capturingClientId,
__unstablePopoverSlot,
__unstableContentRef,
} ) {
const { editorMode, hasMultiSelection, isTyping, lastClientId } = useSelect(
selector,
Expand Down Expand Up @@ -109,40 +108,30 @@ function SelectedBlockPopover( {
}, [ clientId ] );

const popoverProps = useBlockToolbarPopoverProps( {
contentElement: __unstableContentRef?.current,
contentElement: getScrollContainer(), // This is what useBlockToolbarPopoverProps does when the contentRef is undefined. This likely works by accident. It was being passed in via the BlockTools
clientId,
} );

if ( showEmptyBlockSideInserter ) {
if ( isFixed ) {
return (
<BlockPopover
clientId={ capturingClientId || clientId }
__unstableCoverTarget
bottomClientId={ lastClientId }
className={ classnames(
'block-editor-block-list__block-side-inserter-popover',
{
'is-insertion-point-visible': isInsertionPointVisible,
}
) }
__unstablePopoverSlot={ __unstablePopoverSlot }
__unstableContentRef={ __unstableContentRef }
resize={ false }
shift={ false }
{ ...popoverProps }
>
<div className="block-editor-block-list__empty-block-inserter">
<Inserter
position="bottom right"
rootClientId={ rootClientId }
clientId={ clientId }
__experimentalIsQuick
/>
</div>
</BlockPopover>
<BlockContextualToolbar
__experimentalInitialIndex={
initialToolbarItemIndexRef.current
}
__experimentalOnIndexChange={ ( index ) => {
initialToolbarItemIndexRef.current = index;
} }
// Resets the index whenever the active block changes so
// this is not persisted. See https://github.com/WordPress/gutenberg/pull/25760#issuecomment-717906169
key={ clientId }
/>
);
}

if ( showEmptyBlockSideInserter ) {
return null;
}

if ( shouldShowBreadcrumb || shouldShowContextualToolbar ) {
return (
<BlockPopover
Expand All @@ -154,8 +143,6 @@ function SelectedBlockPopover( {
'is-insertion-point-visible': isInsertionPointVisible,
}
) }
__unstablePopoverSlot={ __unstablePopoverSlot }
__unstableContentRef={ __unstableContentRef }
resize={ false }
{ ...popoverProps }
>
Expand Down Expand Up @@ -230,10 +217,7 @@ function wrapperSelector( select ) {
};
}

export default function WrappedBlockPopover( {
__unstablePopoverSlot,
__unstableContentRef,
} ) {
export default function WrappedSelectedBlockTools( { isFixed } ) {
const selected = useSelect( wrapperSelector, [] );

if ( ! selected ) {
Expand All @@ -253,13 +237,12 @@ export default function WrappedBlockPopover( {
}

return (
<SelectedBlockPopover
<SelectedBlockTools
clientId={ clientId }
rootClientId={ rootClientId }
isEmptyDefaultBlock={ isEmptyDefaultBlock }
isFixed={ isFixed }
capturingClientId={ capturingClientId }
__unstablePopoverSlot={ __unstablePopoverSlot }
__unstableContentRef={ __unstableContentRef }
/>
);
}
1 change: 1 addition & 0 deletions packages/block-editor/src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ export { default as BlockSettingsMenuControls } from './block-settings-menu-cont
export { default as BlockTitle } from './block-title';
export { default as BlockToolbar } from './block-toolbar';
export { default as BlockTools } from './block-tools';
export { default as _experimentalSelectedBlockTools } from './block-tools/selected-block-tools';
export {
default as CopyHandler,
useClipboardHandler as __unstableUseClipboardHandler,
Expand Down
Loading