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

Avoid focusing blocks when inserting them into the canvas #28191

Merged
merged 25 commits into from
Feb 11, 2021
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
7fe9baa
Avoid focusing blocks when inserting them into the canvas
youknowriad Jan 14, 2021
6f03043
Fix block patterns insertion
youknowriad Jan 15, 2021
76eb7e4
Fix the behavior of the quick inserter
youknowriad Jan 20, 2021
af7c4e8
Fix spoken inserter message
youknowriad Jan 21, 2021
25285b5
Stabilize some e2e tests
youknowriad Jan 25, 2021
b736b7c
Fix unit tests
youknowriad Jan 25, 2021
442d9e8
Fix more e2e tests
youknowriad Jan 25, 2021
032f60b
Implement ctrl+click in the inserter
youknowriad Feb 8, 2021
162247d
Add onKeyDown handler
youknowriad Feb 9, 2021
1afbc81
Replace the selectionStart and selectionEnd edits with a more generic…
youknowriad Feb 9, 2021
fae3bd6
Focus block on transform
youknowriad Feb 9, 2021
daaa98f
Fix non MacOS ctrl+Enter
youknowriad Feb 9, 2021
7e87f12
Fix inner blocks insertions
youknowriad Feb 9, 2021
e4c7b71
Consider initialPosition null or undefined similarly
youknowriad Feb 9, 2021
0ba720c
Fix allowed blocks test
youknowriad Feb 9, 2021
9f617c3
Chacnge selectBlock action default initialPosition value to retain ba…
youknowriad Feb 10, 2021
399d9fa
Try a less disruptive approach on the store APIs
youknowriad Feb 10, 2021
8128337
Fix unit tests
youknowriad Feb 10, 2021
9f511cc
Fix writing flow test
youknowriad Feb 10, 2021
1574695
Fix replacing default blocks
youknowriad Feb 11, 2021
0d0a6f5
Fix button block appender
youknowriad Feb 11, 2021
12cf64f
Fix Buttons block insertion
youknowriad Feb 11, 2021
228eef4
Fix unit tests
youknowriad Feb 11, 2021
70bb530
Simplify the initialPosition reducer
youknowriad Feb 11, 2021
8321b3a
Fix remaining e2e tests
youknowriad Feb 11, 2021
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 @@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we have logic for this in the keyboard package?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't seem exposed, but definitely something we should expose.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mmm, actually, it seems I could use isKeyboardEvent directly. Thanks Ella

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wasn't able to do on the "click" event, we'd need to expose isApple somehow.

);
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