From cb18edc35bd6e15806862877e66eadf3443aaa42 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Wed, 20 Oct 2021 15:42:53 +1100 Subject: [PATCH] Check element ref for active document so we can try to expand the list only when a block is selected outside the block list. Using an `useEffect` to loop through parent nodes, and expand them when necessary. --- .../src/components/list-view/index.js | 31 +++++++++++++++++-- .../list-view/use-list-view-client-ids.js | 7 +++++ .../src/components/list-view/utils.js | 11 +++++++ 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/packages/block-editor/src/components/list-view/index.js b/packages/block-editor/src/components/list-view/index.js index 8ce9f492b44ce..f79eaeb58cceb 100644 --- a/packages/block-editor/src/components/list-view/index.js +++ b/packages/block-editor/src/components/list-view/index.js @@ -24,6 +24,7 @@ import ListViewDropIndicator from './drop-indicator'; import useListViewClientIds from './use-list-view-client-ids'; import useListViewDropZone from './use-list-view-drop-zone'; import { store as blockEditorStore } from '../../store'; +import { hasFocusWithin } from './utils'; const noop = () => {}; const expanded = ( state, action ) => { @@ -65,7 +66,11 @@ function ListView( }, ref ) { - const { clientIdsTree, draggedClientIds } = useListViewClientIds( blocks ); + const { + clientIdsTree, + draggedClientIds, + selectedBlockParentIds, + } = useListViewClientIds( blocks ); const { selectBlock } = useDispatch( blockEditorStore ); const selectEditorBlock = useCallback( ( clientId ) => { @@ -75,12 +80,12 @@ function ListView( [ selectBlock, onSelect ] ); const [ expandedState, setExpandedState ] = useReducer( expanded, {} ); - const { ref: dropZoneRef, target: blockDropTarget } = useListViewDropZone(); const elementRef = useRef(); const treeGridRef = useMergeRefs( [ elementRef, dropZoneRef, ref ] ); - const isMounted = useRef( false ); + const hasFocus = hasFocusWithin( elementRef?.current ); + useEffect( () => { isMounted.current = true; }, [] ); @@ -139,6 +144,26 @@ function ListView( ] ); + // If a selection is made outside the block list, + // for example, in the Block Editor, + // try to expand the block list tree. + useEffect( () => { + if ( + ! hasFocus && + Array.isArray( selectedBlockParentIds ) && + selectedBlockParentIds.length + ) { + selectedBlockParentIds.forEach( ( clientId ) => { + if ( ! expandedState[ clientId ] ) { + setExpandedState( { + type: 'expand', + clientId, + } ); + } + } ); + } + }, [ hasFocus, selectedBlockParentIds ] ); + return ( isArray( selectedBlockClientIds ) && selectedBlockClientIds.length ? selectedBlockClientIds.indexOf( clientId ) !== -1 : selectedBlockClientIds === clientId; + +/** + * Returns true if the container contains the document active element. + * + * @param {HTMLElement} container An HTML element. + * + * @return {boolean} Whether the container contains the currently document active element. + */ +export const hasFocusWithin = ( container ) => { + return !! container?.contains( container?.ownerDocument?.activeElement ); +};