UNPKG

@wordpress/editor

Version:
322 lines (320 loc) 11.6 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // packages/editor/src/components/collab-sidebar/note-thread.js var note_thread_exports = {}; __export(note_thread_exports, { NoteThread: () => NoteThread }); module.exports = __toCommonJS(note_thread_exports); var import_clsx = __toESM(require("clsx")); var import_element = require("@wordpress/element"); var import_components = require("@wordpress/components"); var import_ui = require("@wordpress/ui"); var import_compose = require("@wordpress/compose"); var import_i18n = require("@wordpress/i18n"); var import_data = require("@wordpress/data"); var import_dom = require("@wordpress/dom"); var import_block_editor = require("@wordpress/block-editor"); var import_add_note = require("./add-note.cjs"); var import_note = require("./note.cjs"); var import_note_card = require("./note-card.cjs"); var import_note_form = require("./note-form.cjs"); var import_floating_container = require("./floating-container.cjs"); var import_utils = require("./utils.cjs"); var import_store = require("../../store/index.cjs"); var import_lock_unlock = require("../../lock-unlock.cjs"); var import_jsx_runtime = require("react/jsx-runtime"); var { useBlockElement } = (0, import_lock_unlock.unlock)(import_block_editor.privateApis); function NoteThread({ note, onEditNote, onAddReply, onDeleteNote, isSelected, sidebarRef, floating, onKeyDown }) { const isFloating = !!floating; const { toggleBlockHighlight, selectBlock, toggleBlockSpotlight } = (0, import_lock_unlock.unlock)( (0, import_data.useDispatch)(import_block_editor.store) ); const { selectNote } = (0, import_lock_unlock.unlock)((0, import_data.useDispatch)(import_store.store)); const relatedBlockElement = useBlockElement(note.blockClientId); const debouncedToggleBlockHighlight = (0, import_compose.useDebounce)( toggleBlockHighlight, 50 ); const floatingRef = (0, import_element.useRef)(null); const isKeyboardTabbingRef = (0, import_element.useRef)(false); const registerThread = floating?.registerThread; const unregisterThread = floating?.unregisterThread; (0, import_element.useEffect)(() => { const floatingEl = floatingRef.current; if (floatingEl && registerThread) { registerThread(note.id, relatedBlockElement, floatingEl); } return () => unregisterThread?.(note.id); }, [relatedBlockElement, note.id, registerThread, unregisterThread]); const onMouseEnter = () => { debouncedToggleBlockHighlight(note.blockClientId, true); }; const onMouseLeave = () => { debouncedToggleBlockHighlight(note.blockClientId, false); }; const onFocus = () => { toggleBlockHighlight(note.blockClientId, true); }; const onBlur = (event) => { if (!document.hasFocus()) { return; } const isNoteFocused = event.relatedTarget?.closest( ".editor-collab-sidebar-panel__thread" ); const isDialogFocused = event.relatedTarget?.closest('[role="dialog"]'); const isTabbing = isKeyboardTabbingRef.current; if (isNoteFocused && !isTabbing) { return; } if (isDialogFocused) { return; } if (isTabbing && event.currentTarget.contains(event.relatedTarget)) { return; } toggleBlockHighlight(note.blockClientId, false); unselectNote(); }; const handleNoteSelect = () => { selectNote(note.id); toggleBlockSpotlight(note.blockClientId, true); if (!!note.blockClientId) { selectBlock(note.blockClientId, null); } }; const unselectNote = () => { selectNote(void 0); toggleBlockSpotlight(note.blockClientId, false); }; const handleResolve = () => { onEditNote({ id: note.id, status: "approved" }); unselectNote(); if (isFloating) { relatedBlockElement?.focus(); } else { (0, import_utils.focusNoteThread)(note.id, sidebarRef.current); } }; const allReplies = note?.reply || []; const lastReply = allReplies.length > 0 ? allReplies[allReplies.length - 1] : void 0; const restReplies = allReplies.length > 0 ? allReplies.slice(0, -1) : []; const noteExcerpt = (0, import_utils.getNoteExcerpt)( (0, import_dom.__unstableStripHTML)(note.content?.rendered), 10 ); const ariaLabel = !!note.blockClientId ? (0, import_i18n.sprintf)( // translators: %s: note excerpt (0, import_i18n.__)("Note: %s"), noteExcerpt ) : (0, import_i18n.sprintf)( // translators: %s: note excerpt (0, import_i18n.__)("Original block deleted. Note: %s"), noteExcerpt ); if (isFloating && note.id === "new") { return /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_add_note.AddNote, { onSubmit: onAddReply, sidebarRef, floating: { y: floating.y, ref: floatingRef } } ); } return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( import_floating_container.FloatingContainer, { floating: isFloating ? { y: floating.y, ref: floatingRef } : void 0, className: (0, import_clsx.default)("editor-collab-sidebar-panel__thread", { "is-selected": isSelected }), id: `note-thread-${note.id}`, gap: "md", onClick: handleNoteSelect, onMouseEnter, onMouseLeave, onFocus, onBlur, onKeyUp: (event) => { if (event.key === "Tab") { isKeyboardTabbingRef.current = false; } }, onKeyDown: (event) => { if (event.key === "Tab") { isKeyboardTabbingRef.current = true; } else { onKeyDown(event); } }, tabIndex: 0, role: "treeitem", "aria-label": ariaLabel, "aria-expanded": isSelected, children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_components.Button, { className: "editor-collab-sidebar-panel__skip-to-note", variant: "secondary", size: "compact", onClick: () => { (0, import_utils.focusNoteThread)(note.id, sidebarRef.current, "textarea"); }, children: (0, import_i18n.__)("Add new reply") } ), !note.blockClientId && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "editor-collab-sidebar-panel__deleted-block-notice", children: (0, import_i18n.__)("Original block deleted.") }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_note.Note, { note, isSelected, onEditNote, onDeleteNote, onResolve: handleResolve } ), isSelected && allReplies.map((reply) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_note.Note, { note: reply, parentNote: note, isSelected, onEditNote, onDeleteNote }, reply.id )), !isSelected && restReplies.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_ui.Stack, { direction: "row", align: "center", justify: "space-between", className: "editor-collab-sidebar-panel__more-reply-separator", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_components.Button, { size: "compact", variant: "tertiary", className: "editor-collab-sidebar-panel__more-reply-button", onClick: () => { selectNote(note.id); (0, import_utils.focusNoteThread)(note.id, sidebarRef.current); }, children: (0, import_i18n.sprintf)( // translators: %s: number of replies. (0, import_i18n._n)( "%s more reply", "%s more replies", restReplies.length ), restReplies.length ) } ) } ), !isSelected && lastReply && /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_note.Note, { note: lastReply, parentNote: note, isSelected: false, onEditNote, onDeleteNote } ), isSelected && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_note_card.NoteCard, { role: "treeitem", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_note_form.NoteForm, { onSubmit: (inputComment) => { if ("approved" === note.status) { onEditNote({ id: note.id, status: "hold", content: inputComment }); } else { onAddReply({ content: inputComment, parent: note.id }); } }, onCancel: (event) => { event.stopPropagation(); unselectNote(); (0, import_utils.focusNoteThread)(note.id, sidebarRef.current); }, labels: { submit: "approved" === note.status ? (0, import_i18n.__)("Reopen & Reply") : (0, import_i18n.__)("Reply"), input: (0, import_i18n.sprintf)( // translators: %1$s: note identifier, %2$s: author name (0, import_i18n.__)("Reply to note %1$s by %2$s"), note.id, note.author_name ) } } ) }), !!note.blockClientId && /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_components.Button, { className: "editor-collab-sidebar-panel__skip-to-block", variant: "secondary", size: "compact", onClick: (event) => { event.stopPropagation(); relatedBlockElement?.focus(); }, children: (0, import_i18n.__)("Back to block") } ) ] } ); } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { NoteThread }); //# sourceMappingURL=note-thread.cjs.map