UNPKG

@wordpress/compose

Version:
77 lines (76 loc) 2.21 kB
// packages/compose/src/hooks/use-copy-to-clipboard/index.ts import { useRef, useLayoutEffect } from "@wordpress/element"; import useRefEffect from "../use-ref-effect/index.mjs"; async function copyToClipboard(text, trigger) { if (!trigger) { return false; } const { ownerDocument } = trigger; if (!ownerDocument) { return false; } const { defaultView } = ownerDocument; try { if (defaultView?.navigator?.clipboard?.writeText) { await defaultView.navigator.clipboard.writeText(text); return true; } const textarea = ownerDocument.createElement("textarea"); textarea.value = text; textarea.setAttribute("readonly", ""); textarea.style.position = "fixed"; textarea.style.left = "-9999px"; textarea.style.top = "-9999px"; ownerDocument.body.appendChild(textarea); textarea.select(); const success = ownerDocument.execCommand("copy"); textarea.remove(); return success; } catch { return false; } } function clearSelection(trigger) { if ("focus" in trigger && typeof trigger.focus === "function") { trigger.focus(); } trigger.ownerDocument?.defaultView?.getSelection()?.removeAllRanges(); } function useUpdatedRef(value) { const ref = useRef(value); useLayoutEffect(() => { ref.current = value; }, [value]); return ref; } function useCopyToClipboard(text, onSuccess) { const textRef = useUpdatedRef(text); const onSuccessRef = useUpdatedRef(onSuccess); return useRefEffect((node) => { let isActive = true; const handleClick = async () => { const textToCopy = typeof textRef.current === "function" ? textRef.current() : textRef.current || ""; const success = await copyToClipboard(textToCopy, node); if (!isActive) { return; } if (success) { clearSelection(node); if (onSuccessRef.current) { onSuccessRef.current(); } } }; node.addEventListener("click", handleClick); return () => { isActive = false; node.removeEventListener("click", handleClick); }; }, []); } export { clearSelection, copyToClipboard, useCopyToClipboard as default }; //# sourceMappingURL=index.mjs.map