UNPKG

@wordpress/block-editor

Version:
175 lines (174 loc) 5.25 kB
// packages/block-editor/src/hooks/fit-text.js import { addFilter } from "@wordpress/hooks"; import { hasBlockSupport } from "@wordpress/blocks"; import { useEffect, useCallback } from "@wordpress/element"; import { useSelect } from "@wordpress/data"; import { optimizeFitText } from "../utils/fit-text-utils"; import { store as blockEditorStore } from "../store"; import { useBlockElement } from "../components/block-list/use-block-props/use-block-refs"; var EMPTY_OBJECT = {}; var FIT_TEXT_SUPPORT_KEY = "typography.fitText"; function addAttributes(settings) { if (!hasBlockSupport(settings, FIT_TEXT_SUPPORT_KEY)) { return settings; } if (settings.attributes?.fitText) { return settings; } return { ...settings, attributes: { ...settings.attributes, fitText: { type: "boolean" } } }; } function useFitText({ fitText, name, clientId }) { const hasFitTextSupport2 = hasBlockSupport(name, FIT_TEXT_SUPPORT_KEY); const blockElement = useBlockElement(clientId); const { blockAttributes, parentId } = useSelect( (select) => { if (!clientId || !hasFitTextSupport2 || !fitText) { return EMPTY_OBJECT; } return { blockAttributes: select(blockEditorStore).getBlockAttributes(clientId), parentId: select(blockEditorStore).getBlockRootClientId(clientId) }; }, [clientId, hasFitTextSupport2, fitText] ); const applyFitText = useCallback(() => { if (!blockElement || !hasFitTextSupport2 || !fitText) { return; } const styleId = `fit-text-${clientId}`; let styleElement = blockElement.ownerDocument.getElementById(styleId); if (!styleElement) { styleElement = blockElement.ownerDocument.createElement("style"); styleElement.id = styleId; blockElement.ownerDocument.head.appendChild(styleElement); } const blockSelector = `#block-${clientId}`; const applyFontSize = (fontSize) => { if (fontSize === 0) { styleElement.textContent = ""; } else { styleElement.textContent = `${blockSelector} { font-size: ${fontSize}px !important; }`; } }; optimizeFitText(blockElement, applyFontSize); }, [blockElement, clientId, hasFitTextSupport2, fitText]); useEffect(() => { if (!fitText || !blockElement || !clientId || !hasFitTextSupport2) { return; } const currentElement = blockElement; const previousVisibility = currentElement.style.visibility; let hideFrameId = null; let calculateFrameId = null; let showTimeoutId = null; hideFrameId = window.requestAnimationFrame(() => { currentElement.style.visibility = "hidden"; calculateFrameId = window.requestAnimationFrame(() => { applyFitText(); showTimeoutId = setTimeout(() => { currentElement.style.visibility = previousVisibility; }, 10); }); }); let resizeObserver; if (window.ResizeObserver && currentElement.parentElement) { resizeObserver = new window.ResizeObserver(applyFitText); resizeObserver.observe(currentElement.parentElement); resizeObserver.observe(currentElement); } return () => { if (hideFrameId !== null) { window.cancelAnimationFrame(hideFrameId); } if (calculateFrameId !== null) { window.cancelAnimationFrame(calculateFrameId); } if (showTimeoutId !== null) { clearTimeout(showTimeoutId); } if (resizeObserver) { resizeObserver.disconnect(); } const styleId = `fit-text-${clientId}`; const styleElement = currentElement.ownerDocument.getElementById(styleId); if (styleElement) { styleElement.remove(); } }; }, [ fitText, clientId, parentId, applyFitText, blockElement, hasFitTextSupport2 ]); useEffect(() => { if (fitText && blockElement && hasFitTextSupport2) { const frameId = window.requestAnimationFrame(() => { if (blockElement) { applyFitText(); } }); return () => window.cancelAnimationFrame(frameId); } }, [ blockAttributes, fitText, applyFitText, blockElement, hasFitTextSupport2 ]); } function addSaveProps(props, blockType, attributes) { if (!hasBlockSupport(blockType, FIT_TEXT_SUPPORT_KEY)) { return props; } const { fitText } = attributes; if (!fitText) { return props; } const className = props.className ? `${props.className} has-fit-text` : "has-fit-text"; return { ...props, className }; } function useBlockProps({ name, fitText, clientId }) { useFitText({ fitText, name, clientId }); if (!fitText || !hasBlockSupport(name, FIT_TEXT_SUPPORT_KEY)) { return {}; } return { className: "has-fit-text" }; } addFilter( "blocks.registerBlockType", "core/fit-text/addAttribute", addAttributes ); var hasFitTextSupport = (blockNameOrType) => { return hasBlockSupport(blockNameOrType, FIT_TEXT_SUPPORT_KEY); }; var fit_text_default = { useBlockProps, addSaveProps, attributeKeys: ["fitText"], hasSupport: hasFitTextSupport, edit: () => null }; export { FIT_TEXT_SUPPORT_KEY, fit_text_default as default }; //# sourceMappingURL=fit-text.js.map