@wordpress/block-editor
Version:
128 lines (127 loc) • 3.53 kB
JavaScript
// packages/block-editor/src/components/block-toolbar/utils.js
import { useSelect, useDispatch } from "@wordpress/data";
import { useState, useRef, useEffect } from "@wordpress/element";
import { store as blockEditorStore } from "../../store/index.mjs";
var { clearTimeout, setTimeout } = window;
var DEBOUNCE_TIMEOUT = 200;
function useDebouncedShowGestures({
ref,
isFocused,
highlightParent,
debounceTimeout = DEBOUNCE_TIMEOUT
}) {
const { getSelectedBlockClientId, getBlockRootClientId } = useSelect(blockEditorStore);
const { toggleBlockHighlight } = useDispatch(blockEditorStore);
const timeoutRef = useRef();
const isDistractionFree = useSelect(
(select) => select(blockEditorStore).getSettings().isDistractionFree,
[]
);
const handleOnChange = (nextIsFocused) => {
if (nextIsFocused && isDistractionFree) {
return;
}
const selectedBlockClientId = getSelectedBlockClientId();
const clientId = highlightParent ? getBlockRootClientId(selectedBlockClientId) : selectedBlockClientId;
toggleBlockHighlight(clientId, nextIsFocused);
};
const getIsHovered = () => {
return ref?.current && ref.current.matches(":hover");
};
const shouldHideGestures = () => {
const isHovered = getIsHovered();
return !isFocused && !isHovered;
};
const clearTimeoutRef = () => {
const timeout = timeoutRef.current;
if (timeout && clearTimeout) {
clearTimeout(timeout);
}
};
const debouncedShowGestures = (event) => {
if (event) {
event.stopPropagation();
}
clearTimeoutRef();
handleOnChange(true);
};
const debouncedHideGestures = (event) => {
if (event) {
event.stopPropagation();
}
clearTimeoutRef();
timeoutRef.current = setTimeout(() => {
if (shouldHideGestures()) {
handleOnChange(false);
}
}, debounceTimeout);
};
useEffect(
() => () => {
handleOnChange(false);
clearTimeoutRef();
},
[]
);
return {
debouncedShowGestures,
debouncedHideGestures
};
}
function useShowHoveredOrFocusedGestures({
ref,
highlightParent = false,
debounceTimeout = DEBOUNCE_TIMEOUT
}) {
const [isFocused, setIsFocused] = useState(false);
const { debouncedShowGestures, debouncedHideGestures } = useDebouncedShowGestures({
ref,
debounceTimeout,
isFocused,
highlightParent
});
const registerRef = useRef(false);
const isFocusedWithin = () => {
return ref?.current && ref.current.contains(ref.current.ownerDocument.activeElement);
};
useEffect(() => {
const node = ref.current;
const handleOnFocus = () => {
if (isFocusedWithin()) {
setIsFocused(true);
debouncedShowGestures();
}
};
const handleOnBlur = () => {
if (!isFocusedWithin()) {
setIsFocused(false);
debouncedHideGestures();
}
};
if (node && !registerRef.current) {
node.addEventListener("focus", handleOnFocus, true);
node.addEventListener("blur", handleOnBlur, true);
registerRef.current = true;
}
return () => {
if (node) {
node.removeEventListener("focus", handleOnFocus);
node.removeEventListener("blur", handleOnBlur);
}
};
}, [
ref,
registerRef,
setIsFocused,
debouncedShowGestures,
debouncedHideGestures
]);
return {
onMouseMove: debouncedShowGestures,
onMouseLeave: debouncedHideGestures
};
}
export {
useShowHoveredOrFocusedGestures
};
//# sourceMappingURL=utils.mjs.map