Skip to content

Commit

Permalink
Avoid focusing blocks when inserting them into the canvas (#28191)
Browse files Browse the repository at this point in the history
  • Loading branch information
youknowriad authored Feb 11, 2021
1 parent 89ee6ee commit db8da15
Show file tree
Hide file tree
Showing 37 changed files with 325 additions and 228 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -657,14 +657,15 @@ _Returns_

Returns the initial caret position for the selected block.
This position is to used to position the caret properly when the selected block changes.
If the current block is not a RichText, having initial position set to 0 means "focus block"

_Parameters_

- _state_ `Object`: Global application state.

_Returns_

- `?Object`: Selected block.
- `(||null)`: Initial position.

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

Expand Down Expand Up @@ -1138,6 +1139,7 @@ _Parameters_
- _index_ `?number`: Index at which block should be inserted.
- _rootClientId_ `?string`: Optional root client ID of block list on which to insert.
- _updateSelection_ `?boolean`: If true block selection will be updated. If false, block selection will not change. Defaults to true.
- _initialPosition_ `(||null)`: Initial focus position. Setting it to null prevent focusing the inserted block.
- _meta_ `?Object`: Optional Meta values to be passed to the action object.

_Returns_
Expand Down Expand Up @@ -1271,7 +1273,7 @@ _Parameters_
- _clientIds_ `(string|Array<string>)`: Block client ID(s) to replace.
- _blocks_ `(Object|Array<Object>)`: Replacement block(s).
- _indexToSelect_ `number`: Index of replacement block to select.
- _initialPosition_ `number`: Index of caret after in the selected block after the operation.
- _initialPosition_ `(||null)`: Index of caret after in the selected block after the operation.
- _meta_ `?Object`: Optional Meta values to be passed to the action object.

<a name="replaceInnerBlocks" href="#replaceInnerBlocks">#</a> **replaceInnerBlocks**
Expand All @@ -1284,6 +1286,7 @@ _Parameters_
- _rootClientId_ `string`: Client ID of the block whose InnerBlocks will re replaced.
- _blocks_ `Array<Object>`: Block objects to insert as new InnerBlocks
- _updateSelection_ `?boolean`: If true block selection will be updated. If false, block selection will not change. Defaults to false.
- _initialPosition_ `(||null)`: Initial block position.

_Returns_

Expand All @@ -1308,6 +1311,7 @@ _Parameters_

- _selectionStart_ `WPBlockSelection`: The selection start.
- _selectionEnd_ `WPBlockSelection`: The selection end.
- _initialPosition_ `(||null)`: Initial block position.

_Returns_

Expand All @@ -1323,7 +1327,7 @@ reflects a reverse selection.
_Parameters_

- _clientId_ `string`: Block client ID.
- _initialPosition_ `?number`: Optional initial position. Pass as -1 to reflect reverse selection.
- _initialPosition_ `(||null)`: Optional initial position. Pass as -1 to reflect reverse selection.

_Returns_

Expand Down
16 changes: 16 additions & 0 deletions docs/designers-developers/developers/data/data-core-editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -373,8 +373,22 @@ _Returns_

- `Array`: Block list.

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

Returns the current selection.

_Parameters_

- _state_ `Object`:

_Returns_

- `WPBlockSelection`: The selection end.

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

> **Deprecated** since Gutenberg 10.0.0.
Returns the current selection end.

_Parameters_
Expand All @@ -387,6 +401,8 @@ _Returns_

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

> **Deprecated** since Gutenberg 10.0.0.
Returns the current selection start.

_Parameters_
Expand Down
2 changes: 2 additions & 0 deletions packages/block-editor/src/components/block-list/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import useBlockDropZone from '../use-block-drop-zone';
import useInsertionPoint from './insertion-point';
import BlockPopover from './block-popover';
import { store as blockEditorStore } from '../../store';
import { useScrollSelectionIntoView } from '../selection-scroll-into-view';

/**
* If the block count exceeds the threshold, we disable the reordering animation
Expand All @@ -32,6 +33,7 @@ export default function BlockList( { className } ) {
const ref = useRef();
const [ blockNodes, setBlockNodes ] = useState( {} );
const insertionPoint = useInsertionPoint( ref );
useScrollSelectionIntoView( ref );

return (
<BlockNodes.Provider value={ blockNodes }>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,15 @@ function useInitialPosition( clientId ) {
}

// If there's no initial position, return 0 to focus the start.
return getSelectedBlocksInitialCaretPosition() || 0;
return getSelectedBlocksInitialCaretPosition();
},
[ clientId ]
);
}

/**
* Transitions focus to the block or inner tabbable when the block becomes
* selected.
* selected and an initial position is set.
*
* @param {RefObject} ref React ref with the block element.
* @param {string} clientId Block client ID.
Expand All @@ -62,7 +62,7 @@ export function useFocusFirstElement( ref, clientId ) {
const initialPosition = useInitialPosition( clientId );

useEffect( () => {
if ( initialPosition === undefined ) {
if ( initialPosition === undefined || initialPosition === null ) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ export default function BlockNavigationAppender( {
<Inserter
rootClientId={ parentBlockClientId }
__experimentalIsQuick
__experimentalSelectBlockOnInsert={ false }
aria-describedby={ descriptionId }
toggleProps={ { ref, tabIndex, onFocus } }
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,13 @@ import { Icon, plus } from '@wordpress/icons';
import Inserter from '../inserter';

function ButtonBlockAppender(
{
rootClientId,
className,
__experimentalSelectBlockOnInsert: selectBlockOnInsert,
onFocus,
tabIndex,
},
{ rootClientId, className, onFocus, tabIndex },
ref
) {
return (
<Inserter
position="bottom center"
rootClientId={ rootClientId }
__experimentalSelectBlockOnInsert={ selectBlockOnInsert }
__experimentalIsQuick
renderToggle={ ( {
onToggle,
Expand Down
5 changes: 1 addition & 4 deletions packages/block-editor/src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,7 @@ export { default as Inserter } from './inserter';
export { default as __experimentalLibrary } from './inserter/library';
export { default as __experimentalSearchForm } from './inserter/search-form';
export { default as BlockEditorKeyboardShortcuts } from './keyboard-shortcuts';
export {
default as MultiSelectScrollIntoView,
useScrollMultiSelectionIntoView as __unstableUseScrollMultiSelectionIntoView,
} from './multi-select-scroll-into-view';
export { MultiSelectScrollIntoView } from './selection-scroll-into-view';
export { default as NavigableToolbar } from './navigable-toolbar';
export {
default as ObserveTyping,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,12 @@ export default function useInnerBlockTemplateSync(
templateLock,
templateInsertUpdatesSelection
) {
const getSelectedBlocksInitialCaretPosition = useSelect(
( select ) =>
select( blockEditorStore ).getSelectedBlocksInitialCaretPosition,
[]
);
const { replaceInnerBlocks } = useDispatch( blockEditorStore );

const innerBlocks = useSelect(
( select ) => select( blockEditorStore ).getBlocks( clientId ),
[ clientId ]
Expand Down Expand Up @@ -69,7 +73,12 @@ export default function useInnerBlockTemplateSync(
nextBlocks,
innerBlocks.length === 0 &&
templateInsertUpdatesSelection &&
nextBlocks.length !== 0
nextBlocks.length !== 0,
// This ensures the "initialPosition" doesn't change when applying the template
// If we're supposed to focus the block, we'll focus the first inner block
// otherwise, we won't apply any auto-focus.
// This ensures for instance that the focus stays in the inserter when inserting the "buttons" block.
getSelectedBlocksInitialCaretPosition()
);
}
}
Expand Down
33 changes: 32 additions & 1 deletion packages/block-editor/src/components/inserter-list-item/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,30 @@ import {
createBlock,
createBlocksFromInnerBlocksTemplate,
} from '@wordpress/blocks';
import { ENTER } from '@wordpress/keycodes';

/**
* Internal dependencies
*/
import BlockIcon from '../block-icon';
import InserterDraggableBlocks from '../inserter-draggable-blocks';

/**
* Return true if platform is MacOS.
*
* @param {Object} _window window object by default; used for DI testing.
*
* @return {boolean} True if MacOS; false otherwise.
*/
function isAppleOS( _window = window ) {
const { platform } = _window.navigator;

return (
platform.indexOf( 'Mac' ) !== -1 ||
[ 'iPad', 'iPhone' ].includes( platform )
);
}

function InserterListItem( {
className,
composite,
Expand Down Expand Up @@ -83,9 +100,23 @@ function InserterListItem( {
disabled={ item.isDisabled }
onClick={ ( event ) => {
event.preventDefault();
onSelect( item );
onSelect(
item,
isAppleOS() ? event.metaKey : event.ctrlKey
);
onHover( null );
} }
onKeyDown={ ( event ) => {
const { keyCode } = event;
if ( keyCode === ENTER ) {
event.preventDefault();
onSelect(
item,
isAppleOS() ? event.metaKey : event.ctrlKey
);
onHover( null );
}
} }
onFocus={ () => {
if ( isDragging.current ) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ const useBlockTypesState = ( rootClientId, onInsert ) => {
);

const onSelectItem = useCallback(
( { name, initialAttributes, innerBlocks } ) => {
( { name, initialAttributes, innerBlocks }, shouldFocusBlock ) => {
const insertedBlock = createBlock(
name,
initialAttributes,
createBlocksFromInnerBlocksTemplate( innerBlocks )
);

onInsert( insertedBlock );
onInsert( insertedBlock, undefined, shouldFocusBlock );
},
[ onInsert ]
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ import { store as blockEditorStore } from '../../../store';
* block with this ID.
* @property {boolean=} isAppender Whether the inserter is an appender
* or not.
* @property {boolean=} selectBlockOnInsert Whether the block should be
* selected on insert.
* @property {Function=} onSelect Called after insertion.
*/

Expand All @@ -44,17 +42,17 @@ function useInsertionPoint( {
insertionIndex,
clientId,
isAppender,
selectBlockOnInsert,
onSelect,
shouldFocusBlock = true,
} ) {
const {
selectedBlock,
destinationRootClientId,
destinationIndex,
getSelectedBlock,
} = useSelect(
( select ) => {
const {
getSelectedBlock,
getSelectedBlock: _getSelectedBlock,
getBlockIndex,
getBlockOrder,
getBlockInsertionPoint,
Expand Down Expand Up @@ -92,7 +90,7 @@ function useInsertionPoint( {
}

return {
selectedBlock: getSelectedBlock(),
getSelectedBlock: _getSelectedBlock,
destinationRootClientId: _destinationRootClientId,
destinationIndex: _destinationIndex,
};
Expand All @@ -108,7 +106,9 @@ function useInsertionPoint( {
} = useDispatch( blockEditorStore );

const onInsertBlocks = useCallback(
( blocks, meta ) => {
( blocks, meta, shouldForceFocusBlock = false ) => {
const selectedBlock = getSelectedBlock();

if (
! isAppender &&
selectedBlock &&
Expand All @@ -118,45 +118,43 @@ function useInsertionPoint( {
selectedBlock.clientId,
blocks,
null,
null,
shouldFocusBlock || shouldForceFocusBlock ? 0 : null,
meta
);
} else {
insertBlocks(
blocks,
destinationIndex,
destinationRootClientId,
selectBlockOnInsert,
true,
shouldFocusBlock || shouldForceFocusBlock ? 0 : null,
meta
);
}

if ( ! selectBlockOnInsert ) {
const message = sprintf(
// translators: %d: the name of the block that has been added
_n(
'%d block added.',
'%d blocks added.',
castArray( blocks ).length
),
const message = sprintf(
// translators: %d: the name of the block that has been added
_n(
'%d block added.',
'%d blocks added.',
castArray( blocks ).length
);
speak( message );
}
),
castArray( blocks ).length
);
speak( message );

if ( onSelect ) {
onSelect();
}
},
[
isAppender,
selectedBlock,
getSelectedBlock,
replaceBlocks,
insertBlocks,
destinationRootClientId,
destinationIndex,
selectBlockOnInsert,
onSelect,
shouldFocusBlock,
]
);

Expand Down
Loading

0 comments on commit db8da15

Please sign in to comment.