@wordpress/block-editor
Version:
107 lines (106 loc) • 3.49 kB
JavaScript
/**
* WordPress dependencies
*/
import { useState, useRef, useLayoutEffect, useEffect, useReducer } from '@wordpress/element';
import isShallowEqual from '@wordpress/is-shallow-equal';
/**
* Internal dependencies
*/
import BlockPopoverCover from '../components/block-popover/cover';
import { useBlockElement } from '../components/block-list/use-block-props/use-block-refs';
import { jsx as _jsx } from "react/jsx-runtime";
function SpacingVisualizer({
clientId,
value,
computeStyle,
forceShow
}) {
const blockElement = useBlockElement(clientId);
const [style, updateStyle] = useReducer(() => computeStyle(blockElement));
useLayoutEffect(() => {
if (!blockElement) {
return;
}
// It's not sufficient to read the computed spacing value when value.spacing changes as
// useEffect may run before the browser recomputes CSS. We therefore combine
// useLayoutEffect and two rAF calls to ensure that we read the spacing after the current
// paint but before the next paint.
// See https://github.com/WordPress/gutenberg/pull/59227.
window.requestAnimationFrame(() => window.requestAnimationFrame(updateStyle));
}, [blockElement, value]);
const previousValueRef = useRef(value);
const [isActive, setIsActive] = useState(false);
useEffect(() => {
if (isShallowEqual(value, previousValueRef.current) || forceShow) {
return;
}
setIsActive(true);
previousValueRef.current = value;
const timeout = setTimeout(() => {
setIsActive(false);
}, 400);
return () => {
setIsActive(false);
clearTimeout(timeout);
};
}, [value, forceShow]);
if (!isActive && !forceShow) {
return null;
}
return /*#__PURE__*/_jsx(BlockPopoverCover, {
clientId: clientId,
__unstablePopoverSlot: "block-toolbar",
children: /*#__PURE__*/_jsx("div", {
className: "block-editor__spacing-visualizer",
style: style
})
});
}
function getComputedCSS(element, property) {
return element.ownerDocument.defaultView.getComputedStyle(element).getPropertyValue(property);
}
export function MarginVisualizer({
clientId,
value,
forceShow
}) {
return /*#__PURE__*/_jsx(SpacingVisualizer, {
clientId: clientId,
value: value?.spacing?.margin,
computeStyle: blockElement => {
const top = getComputedCSS(blockElement, 'margin-top');
const right = getComputedCSS(blockElement, 'margin-right');
const bottom = getComputedCSS(blockElement, 'margin-bottom');
const left = getComputedCSS(blockElement, 'margin-left');
return {
borderTopWidth: top,
borderRightWidth: right,
borderBottomWidth: bottom,
borderLeftWidth: left,
top: top ? `-${top}` : 0,
right: right ? `-${right}` : 0,
bottom: bottom ? `-${bottom}` : 0,
left: left ? `-${left}` : 0
};
},
forceShow: forceShow
});
}
export function PaddingVisualizer({
clientId,
value,
forceShow
}) {
return /*#__PURE__*/_jsx(SpacingVisualizer, {
clientId: clientId,
value: value?.spacing?.padding,
computeStyle: blockElement => ({
borderTopWidth: getComputedCSS(blockElement, 'padding-top'),
borderRightWidth: getComputedCSS(blockElement, 'padding-right'),
borderBottomWidth: getComputedCSS(blockElement, 'padding-bottom'),
borderLeftWidth: getComputedCSS(blockElement, 'padding-left')
}),
forceShow: forceShow
});
}
//# sourceMappingURL=spacing-visualizer.js.map