@wordpress/block-editor
Version:
175 lines (174 loc) • 5.25 kB
JavaScript
// 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