UNPKG

@wordpress/block-editor

Version:
120 lines (101 loc) 3.08 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.__unstableUseBlockElement = useBlockElement; exports.__unstableUseBlockRef = useBlockRef; exports.useBlockRefProvider = useBlockRefProvider; var _element = require("@wordpress/element"); var _compose = require("@wordpress/compose"); var _blockRefsProvider = require("../../provider/block-refs-provider"); /** * WordPress dependencies */ /** * Internal dependencies */ /** @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. */ function useBlockRefProvider(clientId) { const { refs, callbacks } = (0, _element.useContext)(_blockRefsProvider.BlockRefs); const ref = (0, _element.useRef)(); (0, _element.useLayoutEffect)(() => { refs.set(ref, clientId); return () => { refs.delete(ref); }; }, [clientId]); return (0, _compose.useRefEffect)(element => { // Update the ref in the provider. ref.current = element; // Call any update functions. callbacks.forEach((id, setElement) => { if (clientId === id) { setElement(element); } }); }, [clientId]); } /** * 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 } = (0, _element.useContext)(_blockRefsProvider.BlockRefs); const freshClientId = (0, _element.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 (0, _element.useMemo)(() => ({ get current() { let element = null; // Multiple refs may be created for a single block. Find the // first that has an element set. for (const [ref, id] of refs.entries()) { if (id === freshClientId.current && ref.current) { element = ref.current; } } return element; } }), []); } /** * 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 } = (0, _element.useContext)(_blockRefsProvider.BlockRefs); const ref = useBlockRef(clientId); const [element, setElement] = (0, _element.useState)(null); (0, _element.useLayoutEffect)(() => { if (!clientId) { return; } callbacks.set(setElement, clientId); return () => { callbacks.delete(setElement); }; }, [clientId]); return ref.current || element; } //# sourceMappingURL=use-block-refs.js.map