Skip to content

Commit

Permalink
Check element ref for active document so we can try to expand the lis…
Browse files Browse the repository at this point in the history
…t only when a block is selected outside the block list.

Using an `useEffect` to loop through parent nodes, and expand them when necessary.
  • Loading branch information
ramonjd committed Oct 25, 2021
1 parent 2bb4e77 commit cb18edc
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 3 deletions.
31 changes: 28 additions & 3 deletions packages/block-editor/src/components/list-view/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) => {
Expand Down Expand Up @@ -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 ) => {
Expand All @@ -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;
}, [] );
Expand Down Expand Up @@ -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 (
<AsyncModeProvider value={ true }>
<ListViewDropIndicator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,18 @@ export default function useListViewClientIds( blocks ) {
const {
getDraggedBlockClientIds,
__unstableGetClientIdsTree,
getSelectedBlockClientIds,
getBlockParents,
} = select( blockEditorStore );
const selectedBlockClientIds = getSelectedBlockClientIds();

return {
draggedClientIds: getDraggedBlockClientIds(),
clientIdsTree: blocks ? blocks : __unstableGetClientIdsTree(),
selectedBlockParentIds: getBlockParents(
selectedBlockClientIds[ 0 ],
false
),
};
},
[ blocks ]
Expand Down
11 changes: 11 additions & 0 deletions packages/block-editor/src/components/list-view/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,14 @@ export const isClientIdSelected = ( clientId, selectedBlockClientIds ) =>
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 );
};

0 comments on commit cb18edc

Please sign in to comment.