UNPKG

@wordpress/editor

Version:
164 lines (163 loc) 5.16 kB
// packages/editor/src/components/collaborators-overlay/overlay.tsx import { useResizeObserver, useMergeRefs } from "@wordpress/compose"; import { useCallback, useEffect, useRef, useState } from "@wordpress/element"; import { __ } from "@wordpress/i18n"; import Avatar from "../collaborators-presence/avatar/index.mjs"; import { AVATAR_IFRAME_STYLES } from "./avatar-iframe-styles.mjs"; import { OVERLAY_IFRAME_STYLES } from "./overlay-iframe-styles.mjs"; import { setDelayedInterval } from "./timing-utils.mjs"; import { useBlockHighlighting } from "./use-block-highlighting.mjs"; import { useRenderCursors } from "./use-render-cursors.mjs"; import { jsx, jsxs } from "react/jsx-runtime"; var RERENDER_DELAY_MS = 500; var CURSOR_REDRAW_INTERVAL_MS = 1e4; function Overlay({ blockEditorDocument, postId, postType, cursorRegistry }) { const [overlayElement, setOverlayElement] = useState(null); const { cursors, rerenderCursorsAfterDelay } = useRenderCursors( overlayElement, blockEditorDocument ?? null, postId ?? null, postType ?? null, RERENDER_DELAY_MS ); const { highlights, rerenderHighlightsAfterDelay } = useBlockHighlighting( overlayElement, blockEditorDocument ?? null, postId ?? null, postType ?? null, RERENDER_DELAY_MS ); const onResize = useCallback(() => { rerenderCursorsAfterDelay(); rerenderHighlightsAfterDelay(); }, [rerenderCursorsAfterDelay, rerenderHighlightsAfterDelay]); const resizeObserverRef = useResizeObserver(onResize); useEffect(() => { const cleanupCursors = rerenderCursorsAfterDelay(); const cleanupHighlights = rerenderHighlightsAfterDelay(); return () => { cleanupCursors(); cleanupHighlights(); }; }, [rerenderCursorsAfterDelay, rerenderHighlightsAfterDelay]); useEffect(() => { if (cursors.length === 0) { return; } return setDelayedInterval( rerenderCursorsAfterDelay, CURSOR_REDRAW_INTERVAL_MS ); }, [cursors.length, rerenderCursorsAfterDelay]); const mergedRef = useMergeRefs([ setOverlayElement, resizeObserverRef ]); const cursorRefsMap = useRef(/* @__PURE__ */ new Map()); useEffect(() => { if (!cursorRegistry) { return; } const refs = cursorRefsMap.current; const currentIds = new Set(cursors.map((c) => c.clientId)); for (const id of refs.keys()) { if (!currentIds.has(id)) { cursorRegistry.unregisterCursor(id); refs.delete(id); } } for (const [id, el] of refs.entries()) { cursorRegistry.registerCursor(id, el); } return () => cursorRegistry.removeAll(); }, [cursors, cursorRegistry]); const setCursorRef = useCallback( (clientId) => (el) => { if (el) { cursorRefsMap.current.set(clientId, el); } else { cursorRefsMap.current.delete(clientId); } }, [] ); return /* @__PURE__ */ jsxs("div", { className: "collaborators-overlay-full", ref: mergedRef, children: [ /* @__PURE__ */ jsx("style", { children: AVATAR_IFRAME_STYLES + OVERLAY_IFRAME_STYLES }), cursors.map((cursor) => /* @__PURE__ */ jsxs("div", { children: [ !cursor.isMe && cursor.selectionRects?.map((rect, index) => /* @__PURE__ */ jsx( "div", { className: "collaborators-overlay-selection-rect", style: { left: `${rect.x}px`, top: `${rect.y}px`, width: `${rect.width}px`, height: `${rect.height}px`, backgroundColor: cursor.color } }, `${cursor.clientId}-sel-${index}` )), /* @__PURE__ */ jsxs( "div", { ref: setCursorRef(cursor.clientId), className: "collaborators-overlay-user", style: { left: `${cursor.x}px`, top: `${cursor.y}px` }, children: [ !cursor.isMe && /* @__PURE__ */ jsx( "div", { className: "collaborators-overlay-user-cursor", style: { backgroundColor: cursor.color, height: `${cursor.height}px` } } ), /* @__PURE__ */ jsx( Avatar, { className: "collaborators-overlay-user-label", variant: "badge", size: "small", src: cursor.avatarUrl, name: cursor.userName, label: cursor.isMe ? __("You") : void 0, borderColor: cursor.color } ) ] } ) ] }, cursor.clientId)), highlights.map((highlight) => /* @__PURE__ */ jsx( Avatar, { className: "collaborators-overlay-block-label", variant: "badge", size: "small", src: highlight.avatarUrl, name: highlight.userName, borderColor: highlight.color, style: { left: `${highlight.x}px`, top: `${highlight.y}px` } }, highlight.blockId )) ] }); } export { Overlay }; //# sourceMappingURL=overlay.mjs.map