-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Block editor: create useBlockRef and useBlockElement for better access (
#29573) * Block nodes: create useBlockRef for access to block node via ref * Try layout effect * Adjust useMergeRef to not depend on ref order * wip * Rewrite * Fix multi select * Revert useMergeRefs * Fix roving toolbar reset * Add inline docs
- Loading branch information
Showing
12 changed files
with
165 additions
and
165 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 0 additions & 61 deletions
61
packages/block-editor/src/components/block-list/use-block-props/use-block-nodes.js
This file was deleted.
Oops, something went wrong.
101 changes: 101 additions & 0 deletions
101
packages/block-editor/src/components/block-list/use-block-props/use-block-refs.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { | ||
useCallback, | ||
useContext, | ||
useLayoutEffect, | ||
useMemo, | ||
useRef, | ||
useState, | ||
} from '@wordpress/element'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { BlockRefs } from '../../provider/block-refs-provider'; | ||
|
||
/** @typedef {import('@wordpress/element').RefCallback} RefCallback */ | ||
/** @typedef {import('@wordpress/element').RefObject} RefObject */ | ||
|
||
/** | ||
* Provides a ref to the BlockRefs context. | ||
* | ||
* @param {string} clientId The client ID of the element ref. | ||
* | ||
* @return {RefCallback} Ref callback. | ||
*/ | ||
export function useBlockRefProvider( clientId ) { | ||
const { refs, callbacks } = useContext( BlockRefs ); | ||
const ref = useRef(); | ||
useLayoutEffect( () => { | ||
refs.set( clientId, ref ); | ||
return () => { | ||
refs.delete( clientId ); | ||
}; | ||
}, [] ); | ||
return useCallback( ( element ) => { | ||
// Update the ref in the provider. | ||
ref.current = element; | ||
// Call any update functions. | ||
callbacks.forEach( ( id, setElement ) => { | ||
if ( clientId === id ) { | ||
setElement( element ); | ||
} | ||
} ); | ||
}, [] ); | ||
} | ||
|
||
/** | ||
* Gets a ref pointing to the current block element. Continues to return a | ||
* stable ref even if the block client ID changes. | ||
* | ||
* @param {string} clientId The client ID to get a ref for. | ||
* | ||
* @return {RefObject} A ref containing the element. | ||
*/ | ||
function useBlockRef( clientId ) { | ||
const { refs } = useContext( BlockRefs ); | ||
const freshClientId = useRef(); | ||
freshClientId.current = clientId; | ||
// Always return an object, even if no ref exists for a given client ID, so | ||
// that `current` works at a later point. | ||
return useMemo( | ||
() => ( { | ||
get current() { | ||
return refs.get( freshClientId.current )?.current || null; | ||
}, | ||
} ), | ||
[] | ||
); | ||
} | ||
|
||
/** | ||
* Return the element for a given client ID. Updates whenever the element | ||
* changes, becomes available, or disappears. | ||
* | ||
* @param {string} clientId The client ID to an element for. | ||
* | ||
* @return {Element|null} The block's wrapper element. | ||
*/ | ||
function useBlockElement( clientId ) { | ||
const { callbacks } = useContext( BlockRefs ); | ||
const ref = useBlockRef( clientId ); | ||
const [ element, setElement ] = useState( null ); | ||
|
||
useLayoutEffect( () => { | ||
if ( ! clientId ) { | ||
return; | ||
} | ||
|
||
callbacks.set( setElement, clientId ); | ||
return () => { | ||
callbacks.delete( setElement ); | ||
}; | ||
}, [ clientId ] ); | ||
|
||
return ref.current || element; | ||
} | ||
|
||
export { useBlockRef as __unstableUseBlockRef }; | ||
export { useBlockElement as __unstableUseBlockElement }; |
Oops, something went wrong.