UNPKG

@wordpress/server-side-render

Version:

The component used with WordPress to server-side render a preview of dynamic blocks to display in the editor.

105 lines (104 loc) 2.98 kB
// packages/server-side-render/src/hook.js import { debounce } from "@wordpress/compose"; import { useEffect, useState, useRef } from "@wordpress/element"; import apiFetch from "@wordpress/api-fetch"; import { addQueryArgs } from "@wordpress/url"; import { __experimentalSanitizeBlockAttributes } from "@wordpress/blocks"; function rendererPath(block, attributes = null, urlQueryArgs = {}) { return addQueryArgs(`/wp/v2/block-renderer/${block}`, { context: "edit", ...null !== attributes ? { attributes } : {}, ...urlQueryArgs }); } function removeBlockSupportAttributes(attributes) { const { backgroundColor, borderColor, fontFamily, fontSize, gradient, textColor, className, ...restAttributes } = attributes; const { border, color, elements, shadow, spacing, typography, ...restStyles } = attributes?.style || {}; return { ...restAttributes, style: restStyles }; } function useServerSideRender(args) { const [response, setResponse] = useState({ status: "idle" }); const shouldDebounceRef = useRef(false); const { attributes, block, skipBlockSupportAttributes = false, httpMethod = "GET", urlQueryArgs } = args; let sanitizedAttributes = attributes && __experimentalSanitizeBlockAttributes(block, attributes); if (skipBlockSupportAttributes) { sanitizedAttributes = removeBlockSupportAttributes(sanitizedAttributes); } const isPostRequest = "POST" === httpMethod; const urlAttributes = isPostRequest ? null : sanitizedAttributes; const path = rendererPath(block, urlAttributes, urlQueryArgs); const body = isPostRequest ? JSON.stringify({ attributes: sanitizedAttributes ?? null }) : void 0; useEffect(() => { const controller = new AbortController(); const debouncedFetch = debounce( function() { { setResponse({ status: "loading" }); apiFetch({ path, method: isPostRequest ? "POST" : "GET", body, headers: isPostRequest ? { "Content-Type": "application/json" } : {}, signal: controller.signal }).then((res) => { setResponse({ status: "success", content: res ? res.rendered : "" }); }).catch((error) => { if (error.name === "AbortError") { return; } setResponse({ status: "error", error: error.message }); }).finally(() => { shouldDebounceRef.current = true; }); } }, shouldDebounceRef.current ? 500 : 0 ); debouncedFetch(); return () => { controller.abort(); debouncedFetch.cancel(); }; }, [path, isPostRequest, body]); return response; } export { removeBlockSupportAttributes, rendererPath, useServerSideRender }; //# sourceMappingURL=hook.js.map