@arbidocs/blocks 0.4.95 → 0.4.96

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/agents/index.cjs +281 -281
  2. package/dist/agents/index.js +5 -5
  3. package/dist/chat/index.cjs +127 -127
  4. package/dist/chat/index.js +4 -4
  5. package/dist/{chunk-DCZGYCN2.cjs → chunk-3WW32OUU.cjs} +4 -4
  6. package/dist/{chunk-DCZGYCN2.cjs.map → chunk-3WW32OUU.cjs.map} +1 -1
  7. package/dist/{chunk-E2AAIMXO.cjs → chunk-7RI3G5BO.cjs} +538 -168
  8. package/dist/chunk-7RI3G5BO.cjs.map +1 -0
  9. package/dist/{chunk-KBPHLW2R.cjs → chunk-B4SRYJLM.cjs} +3 -3
  10. package/dist/{chunk-KBPHLW2R.cjs.map → chunk-B4SRYJLM.cjs.map} +1 -1
  11. package/dist/{chunk-RZGVMV6B.cjs → chunk-CK6TU76J.cjs} +5 -5
  12. package/dist/{chunk-RZGVMV6B.cjs.map → chunk-CK6TU76J.cjs.map} +1 -1
  13. package/dist/{chunk-EJAYB7PP.js → chunk-EWSEQEPL.js} +4 -4
  14. package/dist/{chunk-EJAYB7PP.js.map → chunk-EWSEQEPL.js.map} +1 -1
  15. package/dist/{chunk-ZNDAXSDP.js → chunk-H4SVY5FH.js} +3 -3
  16. package/dist/{chunk-ZNDAXSDP.js.map → chunk-H4SVY5FH.js.map} +1 -1
  17. package/dist/{chunk-CKYA2IG5.cjs → chunk-HBF4BDRU.cjs} +3 -3
  18. package/dist/{chunk-CKYA2IG5.cjs.map → chunk-HBF4BDRU.cjs.map} +1 -1
  19. package/dist/{chunk-24CS7JWU.js → chunk-HOXKR26S.js} +3 -3
  20. package/dist/{chunk-24CS7JWU.js.map → chunk-HOXKR26S.js.map} +1 -1
  21. package/dist/{chunk-PDEHIGJ5.js → chunk-ICBAFX5B.js} +3 -3
  22. package/dist/{chunk-PDEHIGJ5.js.map → chunk-ICBAFX5B.js.map} +1 -1
  23. package/dist/{chunk-OYMYNYFV.cjs → chunk-IF6VAYIA.cjs} +5 -5
  24. package/dist/{chunk-OYMYNYFV.cjs.map → chunk-IF6VAYIA.cjs.map} +1 -1
  25. package/dist/{chunk-EOEDGJ75.js → chunk-JID3CZSY.js} +3 -3
  26. package/dist/{chunk-EOEDGJ75.js.map → chunk-JID3CZSY.js.map} +1 -1
  27. package/dist/{chunk-WXLKMEMB.js → chunk-K27SDLLN.js} +538 -168
  28. package/dist/chunk-K27SDLLN.js.map +1 -0
  29. package/dist/{chunk-VYKMBLDX.cjs → chunk-MP6FK43E.cjs} +8 -8
  30. package/dist/{chunk-VYKMBLDX.cjs.map → chunk-MP6FK43E.cjs.map} +1 -1
  31. package/dist/{chunk-VQ65UHTV.cjs → chunk-MROSCSPW.cjs} +45 -45
  32. package/dist/{chunk-VQ65UHTV.cjs.map → chunk-MROSCSPW.cjs.map} +1 -1
  33. package/dist/{chunk-TOVSTC2M.cjs → chunk-PSN4VWI7.cjs} +5 -5
  34. package/dist/{chunk-TOVSTC2M.cjs.map → chunk-PSN4VWI7.cjs.map} +1 -1
  35. package/dist/{chunk-3OXWJ3CZ.cjs → chunk-SC33PQTQ.cjs} +5 -5
  36. package/dist/{chunk-3OXWJ3CZ.cjs.map → chunk-SC33PQTQ.cjs.map} +1 -1
  37. package/dist/{chunk-HUFLBZWI.js → chunk-SF4BDUZS.js} +3 -3
  38. package/dist/{chunk-HUFLBZWI.js.map → chunk-SF4BDUZS.js.map} +1 -1
  39. package/dist/{chunk-QQH2NI5U.js → chunk-SJVUKXS6.js} +6 -6
  40. package/dist/{chunk-QQH2NI5U.js.map → chunk-SJVUKXS6.js.map} +1 -1
  41. package/dist/{chunk-UMY6Y6BM.js → chunk-VLOPZHFH.js} +3 -3
  42. package/dist/{chunk-UMY6Y6BM.js.map → chunk-VLOPZHFH.js.map} +1 -1
  43. package/dist/{chunk-GNHOB2ZB.cjs → chunk-XMBYDLZQ.cjs} +4 -4
  44. package/dist/{chunk-GNHOB2ZB.cjs.map → chunk-XMBYDLZQ.cjs.map} +1 -1
  45. package/dist/{chunk-YG7DGGCA.js → chunk-XQDM6T6C.js} +3 -3
  46. package/dist/{chunk-YG7DGGCA.js.map → chunk-XQDM6T6C.js.map} +1 -1
  47. package/dist/{chunk-YPKSLTL5.js → chunk-Y52CEKVD.js} +3 -3
  48. package/dist/{chunk-YPKSLTL5.js.map → chunk-Y52CEKVD.js.map} +1 -1
  49. package/dist/connect/docx.cjs +6 -6
  50. package/dist/connect/docx.js +4 -4
  51. package/dist/connect/index.cjs +46 -46
  52. package/dist/connect/index.js +16 -16
  53. package/dist/docx/NativeDocxEditor.d.ts +3 -1
  54. package/dist/docx/index.cjs +24 -24
  55. package/dist/docx/index.js +3 -3
  56. package/dist/docx/review/DocxEditorReview.d.ts +4 -2
  57. package/dist/docx/review/commentText.d.ts +7 -0
  58. package/dist/facts/index.cjs +5 -5
  59. package/dist/facts/index.js +2 -2
  60. package/dist/index.cjs +1117 -1117
  61. package/dist/index.js +17 -17
  62. package/dist/settings/index.cjs +1 -1
  63. package/dist/settings/index.js +1 -1
  64. package/dist/shell/index.cjs +67 -67
  65. package/dist/shell/index.js +3 -3
  66. package/dist/studio/index.cjs +7 -7
  67. package/dist/studio/index.js +6 -6
  68. package/dist/workflow-canvas/index.cjs +49 -49
  69. package/dist/workflow-canvas/index.js +6 -6
  70. package/package.json +4 -4
  71. package/src/docx/styles.css +473 -91
  72. package/dist/chunk-E2AAIMXO.cjs.map +0 -1
  73. package/dist/chunk-WXLKMEMB.js.map +0 -1
@@ -5,14 +5,14 @@ import { unzipSync, strFromU8, strToU8, zipSync } from 'fflate';
5
5
  import { collectReviewItems, revisionItemsOf } from '@docx-editor.dev/core/store';
6
6
  import React3, { createContext, useContext, useState, useRef, useCallback, useEffect, useLayoutEffect, useMemo } from 'react';
7
7
  import { useDocxEditor, ReviewRailContext, useEditorSnapshot, useChromeTranslate, DocxEditor, createFontSource } from '@docx-editor.dev/react';
8
+ import { AiMarkdown, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Button, DialogFooter, cn, splitMarkdownBlocks } from '@arbidocs/react/ui';
9
+ import { MessageSquarePlus, MessageSquare, PencilLine, ChevronLeft, ChevronRight, X, ChevronUp, ChevronDown, CheckCheck, RotateCcw, CircleCheck, Trash2, Check, SendHorizontal, Type, Ellipsis, RefreshCw, WifiOff, Download, Save, BookA, ListRestart } from 'lucide-react';
8
10
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
9
11
  import { createPortal } from 'react-dom';
10
- import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Button, DialogFooter, cn, splitMarkdownBlocks, AiMarkdown } from '@arbidocs/react/ui';
11
12
  import { renderToStaticMarkup } from 'react-dom/server';
12
13
  import * as Y from 'yjs';
13
14
  import { DOCUMENT_COLLABORATION_VERSIONS, collaborationModule } from '@arbidocs/coedit';
14
15
  import { createHocuspocusCollaboration } from '@arbidocs/coedit/hocuspocus';
15
- import { Type, Ellipsis, RefreshCw, WifiOff, Check, Download, Save, BookA, ListRestart } from 'lucide-react';
16
16
 
17
17
  function normalizeDocxExport(data) {
18
18
  const files = unzipSync(new Uint8Array(data));
@@ -136,7 +136,25 @@ var ReviewItemContext = createContext(null);
136
136
  function useReviewItem() {
137
137
  return useContext(ReviewItemContext);
138
138
  }
139
+
140
+ // src/docx/review/commentText.ts
141
+ var SKIP = /* @__PURE__ */ new Set(["delText", "instrText", "delInstrText", "pPr", "rPr"]);
142
+ function inline(node) {
143
+ if (node.kind === "textValue") return node.value ?? "";
144
+ if (node.localName && SKIP.has(node.localName)) return "";
145
+ if (node.localName === "br" || node.localName === "cr") return "\n";
146
+ if (node.localName === "tab") return " ";
147
+ return (node.children ?? []).map(inline).join("");
148
+ }
149
+ function commentText(entry) {
150
+ if (entry.kind !== "comment") return entry.text;
151
+ const blocks = entry.item?.comment?.blocks ?? [];
152
+ const text = blocks.map(inline).join("\n").trim();
153
+ return text || entry.text;
154
+ }
139
155
  var CARD_GAP = 8;
156
+ var CLUSTER_GAP = 24;
157
+ var REVIEW_MARGIN_MIN_WIDTH = 900;
140
158
  var REVISION_LABELS = {
141
159
  insert: "Inserted",
142
160
  delete: "Deleted",
@@ -152,33 +170,102 @@ function isTopLevel(entry) {
152
170
  if (entry.kind === "custom") return entry.item.carded;
153
171
  return true;
154
172
  }
155
- function formatDate(value) {
156
- if (!value) return "";
173
+ function kindLabel(entry) {
174
+ if (entry.kind === "revision") return REVISION_LABELS[entry.revisionKind] ?? "Change";
175
+ if (entry.kind === "comment") return entry.resolved ? "Resolved" : "Comment";
176
+ return "Note";
177
+ }
178
+ function parseDate(value) {
179
+ if (!value) return null;
157
180
  const date = new Date(value);
158
- return Number.isNaN(date.getTime()) ? "" : date.toLocaleString();
181
+ return Number.isNaN(date.getTime()) ? null : date;
182
+ }
183
+ function relativeDate(date) {
184
+ const seconds = (Date.now() - date.getTime()) / 1e3;
185
+ if (seconds < 45) return "just now";
186
+ if (seconds < 45 * 60) return `${Math.round(seconds / 60)}m ago`;
187
+ if (seconds < 22 * 3600) return `${Math.round(seconds / 3600)}h ago`;
188
+ if (seconds < 7 * 86400) return `${Math.round(seconds / 86400)}d ago`;
189
+ const sameYear = date.getFullYear() === (/* @__PURE__ */ new Date()).getFullYear();
190
+ return date.toLocaleDateString(void 0, {
191
+ day: "numeric",
192
+ month: "short",
193
+ year: sameYear ? void 0 : "numeric"
194
+ });
195
+ }
196
+ function authorHue(author) {
197
+ let hash = 0;
198
+ for (const char of author) hash = hash * 31 + char.charCodeAt(0) | 0;
199
+ return Math.abs(hash) % 360;
159
200
  }
160
201
  function Avatar({ entry }) {
161
- return /* @__PURE__ */ jsx("span", { className: "native-docx-review-avatar", "aria-hidden": "true", children: entry.initials });
202
+ return /* @__PURE__ */ jsx(
203
+ "span",
204
+ {
205
+ className: "native-docx-review-avatar",
206
+ "aria-hidden": "true",
207
+ style: { "--review-author-hue": authorHue(entry.author || "") },
208
+ children: entry.initials
209
+ }
210
+ );
162
211
  }
163
- function Message({ entry }) {
164
- return /* @__PURE__ */ jsxs("div", { className: "native-docx-review-message", children: [
165
- /* @__PURE__ */ jsxs("div", { className: "native-docx-review-byline", children: [
166
- /* @__PURE__ */ jsx(Avatar, { entry }),
212
+ function Byline({ entry, children }) {
213
+ const date = parseDate(entry.date);
214
+ return /* @__PURE__ */ jsxs("div", { className: "native-docx-review-byline", children: [
215
+ /* @__PURE__ */ jsx(Avatar, { entry }),
216
+ /* @__PURE__ */ jsxs("div", { className: "native-docx-review-who", children: [
167
217
  /* @__PURE__ */ jsx("span", { className: "native-docx-review-author", children: entry.author || "Reviewer" }),
168
- /* @__PURE__ */ jsx("time", { className: "native-docx-review-date", children: formatDate(entry.date) })
218
+ /* @__PURE__ */ jsxs("span", { className: "native-docx-review-meta", children: [
219
+ kindLabel(entry),
220
+ date && /* @__PURE__ */ jsxs(Fragment, { children: [
221
+ " \xB7 ",
222
+ /* @__PURE__ */ jsx(
223
+ "time",
224
+ {
225
+ className: "native-docx-review-date",
226
+ dateTime: date.toISOString(),
227
+ title: date.toLocaleString(),
228
+ children: relativeDate(date)
229
+ }
230
+ )
231
+ ] })
232
+ ] })
169
233
  ] }),
170
- /* @__PURE__ */ jsx("p", { className: "native-docx-review-text", "data-testid": "review-text", children: entry.text })
234
+ children
235
+ ] });
236
+ }
237
+ function ChangeText({ entry }) {
238
+ const removed = entry.revisionKind === "replace" ? entry.replacedText : void 0;
239
+ const struck = entry.revisionKind === "delete" || entry.revisionKind === "moveFrom";
240
+ const added = entry.revisionKind === "insert" || entry.revisionKind === "moveTo" || removed !== void 0;
241
+ return /* @__PURE__ */ jsxs("p", { className: "native-docx-review-change", "data-testid": "review-text", children: [
242
+ removed && /* @__PURE__ */ jsxs(Fragment, { children: [
243
+ /* @__PURE__ */ jsx("del", { children: removed }),
244
+ /* @__PURE__ */ jsx("span", { className: "native-docx-review-arrow", "aria-hidden": "true", children: "\u2192" })
245
+ ] }),
246
+ struck ? /* @__PURE__ */ jsx("del", { children: entry.text }) : added ? /* @__PURE__ */ jsx("ins", { children: entry.text }) : /* @__PURE__ */ jsx("span", { children: entry.text })
247
+ ] });
248
+ }
249
+ function CommentText({ text, testId }) {
250
+ return /* @__PURE__ */ jsx("div", { className: "native-docx-review-text", "data-testid": testId, children: /* @__PURE__ */ jsx(AiMarkdown, { className: "native-docx-review-markdown", allowHtml: false, children: text }) });
251
+ }
252
+ function Reply({ entry }) {
253
+ return /* @__PURE__ */ jsxs("div", { className: "native-docx-review-message", children: [
254
+ /* @__PURE__ */ jsx(Byline, { entry }),
255
+ /* @__PURE__ */ jsx(CommentText, { text: commentText(entry) })
171
256
  ] });
172
257
  }
173
258
  function ReplyForm({
174
259
  entry,
175
- review
260
+ review,
261
+ onDismiss
176
262
  }) {
177
263
  const [text, setText] = useState("");
178
264
  return /* @__PURE__ */ jsxs(
179
265
  "form",
180
266
  {
181
267
  className: "native-docx-review-reply",
268
+ onClick: (event) => event.stopPropagation(),
182
269
  onSubmit: (event) => {
183
270
  event.preventDefault();
184
271
  const value = text.trim();
@@ -190,25 +277,39 @@ function ReplyForm({
190
277
  {
191
278
  "data-testid": "review-reply-input",
192
279
  "aria-label": "Reply",
193
- placeholder: "Reply",
280
+ placeholder: "Reply\u2026",
194
281
  value: text,
195
282
  onChange: (event) => setText(event.target.value),
196
283
  onKeyDown: (event) => {
197
284
  if (event.key === "Escape") {
285
+ event.preventDefault();
198
286
  event.stopPropagation();
199
- review.setActive(null);
287
+ onDismiss();
200
288
  }
201
289
  }
202
290
  }
203
291
  ),
204
- /* @__PURE__ */ jsx("button", { type: "submit", disabled: !text.trim(), children: "Reply" }),
292
+ /* @__PURE__ */ jsx(
293
+ "button",
294
+ {
295
+ type: "submit",
296
+ className: "native-docx-review-icon native-docx-review-send",
297
+ "aria-label": "Reply",
298
+ title: "Reply",
299
+ disabled: !text.trim(),
300
+ children: /* @__PURE__ */ jsx(SendHorizontal, { size: 14 })
301
+ }
302
+ ),
205
303
  /* @__PURE__ */ jsx(
206
304
  "button",
207
305
  {
208
306
  type: "button",
307
+ className: "native-docx-review-icon",
209
308
  "data-testid": "review-reply-cancel",
210
- onClick: () => review.setActive(null),
211
- children: "Cancel"
309
+ "aria-label": "Cancel",
310
+ title: "Cancel",
311
+ onClick: onDismiss,
312
+ children: /* @__PURE__ */ jsx(X, { size: 14 })
212
313
  }
213
314
  )
214
315
  ]
@@ -221,7 +322,8 @@ function Card({
221
322
  review,
222
323
  extra,
223
324
  cardRef,
224
- top
325
+ top,
326
+ onDismiss
225
327
  }) {
226
328
  const resolved = entry.kind === "comment" && entry.resolved;
227
329
  return /* @__PURE__ */ jsx(ReviewItemContext.Provider, { value: entry, children: /* @__PURE__ */ jsxs(
@@ -240,60 +342,85 @@ function Card({
240
342
  },
241
343
  "data-testid": "review-card",
242
344
  "data-kind": entry.kind,
345
+ "data-change": entry.kind === "revision" ? entry.revisionKind : void 0,
243
346
  "data-active": entry.isActive || void 0,
244
347
  "data-resolved": resolved || void 0,
245
- style: { top },
348
+ "data-floating": top === void 0 || void 0,
349
+ style: top === void 0 ? void 0 : { top },
246
350
  onClick: () => {
247
351
  if (entry.activatable && !entry.isActive) review.setActive(entry.key);
248
352
  },
249
353
  children: [
250
- entry.kind === "revision" && /* @__PURE__ */ jsx("div", { className: "native-docx-review-kind", children: REVISION_LABELS[entry.revisionKind] ?? "Change" }),
251
- /* @__PURE__ */ jsx(Message, { entry }),
252
- replies.map((reply) => /* @__PURE__ */ jsx(Message, { entry: reply }, reply.key)),
354
+ /* @__PURE__ */ jsx(Byline, { entry, children: entry.kind === "comment" && /* @__PURE__ */ jsxs("div", { className: "native-docx-review-tools", children: [
355
+ /* @__PURE__ */ jsx(
356
+ "button",
357
+ {
358
+ type: "button",
359
+ className: "native-docx-review-icon",
360
+ "data-testid": "review-resolve",
361
+ "aria-label": entry.resolved ? "Reopen" : "Resolve",
362
+ title: entry.resolved ? "Reopen" : "Resolve",
363
+ onClick: (event) => {
364
+ event.stopPropagation();
365
+ review.resolve(entry, !entry.resolved);
366
+ },
367
+ children: entry.resolved ? /* @__PURE__ */ jsx(RotateCcw, { size: 14 }) : /* @__PURE__ */ jsx(CircleCheck, { size: 14 })
368
+ }
369
+ ),
370
+ /* @__PURE__ */ jsx(
371
+ "button",
372
+ {
373
+ type: "button",
374
+ className: "native-docx-review-icon",
375
+ "data-testid": "review-delete",
376
+ "aria-label": "Delete",
377
+ title: "Delete",
378
+ onClick: (event) => {
379
+ event.stopPropagation();
380
+ review.remove(entry);
381
+ },
382
+ children: /* @__PURE__ */ jsx(Trash2, { size: 14 })
383
+ }
384
+ )
385
+ ] }) }),
386
+ entry.kind === "revision" ? /* @__PURE__ */ jsx(ChangeText, { entry }) : /* @__PURE__ */ jsx(CommentText, { text: commentText(entry), testId: "review-text" }),
387
+ replies.length > 0 && /* @__PURE__ */ jsx("div", { className: "native-docx-review-thread", children: replies.map((reply) => /* @__PURE__ */ jsx(Reply, { entry: reply }, reply.key)) }),
253
388
  extra,
254
- /* @__PURE__ */ jsxs("div", { className: "native-docx-review-actions", children: [
255
- entry.kind === "revision" && !entry.readOnly && /* @__PURE__ */ jsxs(Fragment, { children: [
256
- /* @__PURE__ */ jsx(
257
- "button",
258
- {
259
- type: "button",
260
- "data-testid": "review-accept",
261
- onClick: () => review.accept(entry),
262
- children: "Accept"
263
- }
264
- ),
265
- /* @__PURE__ */ jsx(
266
- "button",
267
- {
268
- type: "button",
269
- "data-testid": "review-reject",
270
- onClick: () => review.reject(entry),
271
- children: "Reject"
272
- }
273
- )
274
- ] }),
275
- entry.kind === "comment" && /* @__PURE__ */ jsxs(Fragment, { children: [
276
- /* @__PURE__ */ jsx(
277
- "button",
278
- {
279
- type: "button",
280
- "data-testid": "review-resolve",
281
- onClick: () => review.resolve(entry, !entry.resolved),
282
- children: entry.resolved ? "Reopen" : "Resolve"
283
- }
284
- ),
285
- /* @__PURE__ */ jsx(
286
- "button",
287
- {
288
- type: "button",
289
- "data-testid": "review-delete",
290
- onClick: () => review.remove(entry),
291
- children: "Delete"
292
- }
293
- )
294
- ] })
389
+ entry.kind === "revision" && !entry.readOnly && /* @__PURE__ */ jsxs("div", { className: "native-docx-review-decide", children: [
390
+ /* @__PURE__ */ jsxs(
391
+ "button",
392
+ {
393
+ type: "button",
394
+ className: "native-docx-review-accept",
395
+ "data-testid": "review-accept",
396
+ onClick: (event) => {
397
+ event.stopPropagation();
398
+ review.accept(entry);
399
+ },
400
+ children: [
401
+ /* @__PURE__ */ jsx(Check, { size: 14 }),
402
+ "Accept"
403
+ ]
404
+ }
405
+ ),
406
+ /* @__PURE__ */ jsxs(
407
+ "button",
408
+ {
409
+ type: "button",
410
+ className: "native-docx-review-reject",
411
+ "data-testid": "review-reject",
412
+ onClick: (event) => {
413
+ event.stopPropagation();
414
+ review.reject(entry);
415
+ },
416
+ children: [
417
+ /* @__PURE__ */ jsx(X, { size: 14 }),
418
+ "Reject"
419
+ ]
420
+ }
421
+ )
295
422
  ] }),
296
- entry.isActive && entry.kind !== "custom" && /* @__PURE__ */ jsx(ReplyForm, { entry, review })
423
+ entry.isActive && entry.kind !== "custom" && /* @__PURE__ */ jsx(ReplyForm, { entry, review, onDismiss })
297
424
  ]
298
425
  }
299
426
  ) });
@@ -313,7 +440,8 @@ function Draft({
313
440
  ref: formRef,
314
441
  className: "native-docx-review-card native-docx-review-draft",
315
442
  "data-testid": "review-draft",
316
- style: { top },
443
+ "data-floating": top === void 0 || void 0,
444
+ style: top === void 0 ? void 0 : { top },
317
445
  onSubmit: (event) => {
318
446
  event.preventDefault();
319
447
  if (text.trim()) onSubmit(text.trim());
@@ -325,22 +453,53 @@ function Draft({
325
453
  ref: input,
326
454
  "data-testid": "review-draft-input",
327
455
  "aria-label": "Comment",
328
- placeholder: "Add a comment",
456
+ placeholder: "Add a comment\u2026",
329
457
  value: text,
330
458
  onChange: (event) => setText(event.target.value),
331
459
  onKeyDown: (event) => {
332
- if (event.key === "Escape") onCancel();
460
+ if (event.key === "Escape") {
461
+ event.preventDefault();
462
+ event.stopPropagation();
463
+ onCancel();
464
+ }
333
465
  }
334
466
  }
335
467
  ),
336
- /* @__PURE__ */ jsxs("div", { className: "native-docx-review-actions", children: [
337
- /* @__PURE__ */ jsx("button", { type: "submit", disabled: !text.trim(), children: "Comment" }),
338
- /* @__PURE__ */ jsx("button", { type: "button", "data-testid": "review-draft-cancel", onClick: onCancel, children: "Cancel" })
468
+ /* @__PURE__ */ jsxs("div", { className: "native-docx-review-decide", children: [
469
+ /* @__PURE__ */ jsx("button", { type: "submit", className: "native-docx-review-accept", disabled: !text.trim(), children: "Comment" }),
470
+ /* @__PURE__ */ jsx(
471
+ "button",
472
+ {
473
+ type: "button",
474
+ className: "native-docx-review-plain",
475
+ "data-testid": "review-draft-cancel",
476
+ onClick: onCancel,
477
+ children: "Cancel"
478
+ }
479
+ )
339
480
  ] })
340
481
  ]
341
482
  }
342
483
  );
343
484
  }
485
+ function useScrollArea(anchor, ready) {
486
+ const [area, setArea] = useState({
487
+ element: null,
488
+ width: 0
489
+ });
490
+ useLayoutEffect(() => {
491
+ const element = anchor.current?.closest(".docx-editor__scroll-container") ?? null;
492
+ const measure = () => setArea(
493
+ (previous) => previous.element === element && previous.width === (element?.clientWidth ?? 0) ? previous : { element, width: element?.clientWidth ?? 0 }
494
+ );
495
+ measure();
496
+ if (!element || typeof ResizeObserver === "undefined") return;
497
+ const observer = new ResizeObserver(measure);
498
+ observer.observe(element);
499
+ return () => observer.disconnect();
500
+ }, [anchor, ready]);
501
+ return area;
502
+ }
344
503
  function DocxEditorReviewRail({
345
504
  children
346
505
  }) {
@@ -351,6 +510,10 @@ function DocxEditorReviewRail({
351
510
  const [tops, setTops] = useState({});
352
511
  const [showResolved, setShowResolved] = useState(true);
353
512
  const elements = useRef(/* @__PURE__ */ new Map());
513
+ const anchor = useRef(null);
514
+ const toolbar = useRef(null);
515
+ const area = useScrollArea(anchor, review.ready);
516
+ const layout = area.width === 0 || area.width >= REVIEW_MARGIN_MIN_WIDTH ? "margin" : "compact";
354
517
  const openDraft = useCallback(() => {
355
518
  const placement = editor?.getSelectionPlacement();
356
519
  if (!placement) return;
@@ -359,9 +522,22 @@ function DocxEditorReviewRail({
359
522
  }, [editor, review.setPaneOpen]);
360
523
  useEffect(() => registry?.register(), [registry]);
361
524
  useEffect(() => registry?.registerCommentDraft(openDraft), [registry, openDraft]);
525
+ const shownLayout = useRef(null);
526
+ useEffect(() => {
527
+ if (!review.ready || area.width === 0 || shownLayout.current === layout) return;
528
+ editor?.setReviewPaneOptions({ opening: layout === "margin" ? "auto" : "manual" });
529
+ const deepLinked = shownLayout.current === null && review.activeKey !== null;
530
+ shownLayout.current = layout;
531
+ if (layout === "margin") review.setPaneOpen(true);
532
+ else if (!deepLinked) {
533
+ setDraft(null);
534
+ review.setPaneOpen(false);
535
+ }
536
+ }, [editor, layout, area.width, review.ready, review.setPaneOpen]);
362
537
  const scale = editor?.getRenderScale() ?? 1;
363
538
  const top = review.items.filter(isTopLevel).filter((entry) => entry.anchorY !== null).filter((entry) => showResolved || entry.kind !== "comment" || !entry.resolved);
364
- const hasChanges = review.items.some((entry) => entry.kind === "revision");
539
+ const changes = review.items.filter((entry) => entry.kind === "revision").length;
540
+ const comments = top.filter((entry) => entry.kind === "comment").length;
365
541
  const hasResolved = review.items.some((entry) => entry.kind === "comment" && entry.resolved);
366
542
  const repliesOf = useCallback(
367
543
  (entry) => review.items.filter(
@@ -369,10 +545,49 @@ function DocxEditorReviewRail({
369
545
  ),
370
546
  [review.items]
371
547
  );
548
+ const column = layout === "margin" && review.paneOpen && (top.length > 0 || draft !== null);
549
+ const bubbleOpen = layout === "compact" && (review.paneOpen || draft !== null);
550
+ useEffect(() => {
551
+ const element = area.element;
552
+ if (!element) return;
553
+ if (column) element.setAttribute("data-review-margin", "");
554
+ else element.removeAttribute("data-review-margin");
555
+ return () => element.removeAttribute("data-review-margin");
556
+ }, [area.element, column]);
557
+ const dismiss = useCallback(() => {
558
+ setDraft(null);
559
+ if (layout === "compact") review.setPaneOpen(false);
560
+ else review.setActive(null);
561
+ }, [layout, review.setPaneOpen, review.setActive]);
562
+ useEffect(() => {
563
+ const element = area.element;
564
+ if (!element || !bubbleOpen) return;
565
+ const close = (event) => {
566
+ const target = event.target;
567
+ if (target instanceof Element && target.closest(
568
+ ".native-docx-review-bubble, .native-docx-review-marker, .native-docx-review-add"
569
+ ))
570
+ return;
571
+ dismiss();
572
+ };
573
+ const escape = (event) => {
574
+ if (event.key !== "Escape" || event.defaultPrevented) return;
575
+ if (!(event.target instanceof Node) || !element.contains(event.target)) return;
576
+ event.preventDefault();
577
+ dismiss();
578
+ };
579
+ const document2 = element.ownerDocument;
580
+ element.addEventListener("pointerdown", close);
581
+ document2.addEventListener("keydown", escape);
582
+ return () => {
583
+ element.removeEventListener("pointerdown", close);
584
+ document2.removeEventListener("keydown", escape);
585
+ };
586
+ }, [area.element, bubbleOpen, dismiss]);
372
587
  useLayoutEffect(() => {
373
- if (!review.paneOpen) return;
588
+ if (!column) return;
374
589
  const next = {};
375
- let floor = 0;
590
+ let floor = (toolbar.current?.offsetHeight ?? 0) + CARD_GAP;
376
591
  const rows = top.map((entry) => ({
377
592
  key: entry.key,
378
593
  y: (entry.anchorY ?? 0) * scale
@@ -390,7 +605,7 @@ function DocxEditorReviewRail({
390
605
  return same ? previous : next;
391
606
  });
392
607
  });
393
- if (!review.ready) return null;
608
+ if (!review.ready) return /* @__PURE__ */ jsx("div", { ref: anchor, className: "native-docx-review" });
394
609
  const selection = editor?.getSelectionPlacement();
395
610
  const addComment = selection && /* @__PURE__ */ jsx(
396
611
  "button",
@@ -399,108 +614,254 @@ function DocxEditorReviewRail({
399
614
  className: "native-docx-review-add",
400
615
  "data-testid": "review-add-comment",
401
616
  "aria-label": "Add comment",
617
+ title: "Add comment",
402
618
  style: { top: selection.anchorY * scale },
403
619
  onMouseDown: (event) => event.preventDefault(),
404
620
  onClick: openDraft,
405
- children: "+"
621
+ children: /* @__PURE__ */ jsx(MessageSquarePlus, { size: 14 })
406
622
  }
407
623
  );
408
- if (!review.paneOpen) {
409
- return /* @__PURE__ */ jsxs("div", { className: "native-docx-review-markers", "data-testid": "review-markers", children: [
624
+ if (column) {
625
+ return /* @__PURE__ */ jsx("div", { ref: anchor, className: "native-docx-review", children: /* @__PURE__ */ jsxs("aside", { className: "native-docx-review-pane", "data-testid": "review-pane", "aria-label": "Review", children: [
410
626
  addComment,
627
+ /* @__PURE__ */ jsxs("div", { ref: toolbar, className: "native-docx-review-toolbar", "data-testid": "review-toolbar", children: [
628
+ /* @__PURE__ */ jsx("span", { className: "native-docx-review-summary", children: [
629
+ changes && `${changes} ${changes === 1 ? "change" : "changes"}`,
630
+ comments && `${comments} ${comments === 1 ? "comment" : "comments"}`
631
+ ].filter(Boolean).join(" \xB7 ") || "Review" }),
632
+ hasResolved && /* @__PURE__ */ jsxs("label", { className: "native-docx-review-switch", children: [
633
+ /* @__PURE__ */ jsx(
634
+ "input",
635
+ {
636
+ type: "checkbox",
637
+ "data-testid": "review-show-resolved",
638
+ checked: showResolved,
639
+ onChange: (event) => setShowResolved(event.target.checked)
640
+ }
641
+ ),
642
+ "Resolved"
643
+ ] }),
644
+ changes > 0 && /* @__PURE__ */ jsx(BulkActions, { review, navigate: true })
645
+ ] }),
646
+ draft && /* @__PURE__ */ jsx(
647
+ Draft,
648
+ {
649
+ top: tops.__draft ?? draft.anchorY * scale,
650
+ formRef: (element) => {
651
+ if (element) elements.current.set("__draft", element);
652
+ },
653
+ onCancel: () => setDraft(null),
654
+ onSubmit: (text) => {
655
+ if (review.addComment(text)) setDraft(null);
656
+ }
657
+ }
658
+ ),
411
659
  top.map((entry) => /* @__PURE__ */ jsx(
660
+ Card,
661
+ {
662
+ entry,
663
+ replies: repliesOf(entry),
664
+ review,
665
+ extra: children?.(entry),
666
+ top: tops[entry.key] ?? (entry.anchorY ?? 0) * scale,
667
+ onDismiss: dismiss,
668
+ cardRef: (element) => {
669
+ if (element) elements.current.set(entry.key, element);
670
+ else elements.current.delete(entry.key);
671
+ }
672
+ },
673
+ entry.key
674
+ ))
675
+ ] }) });
676
+ }
677
+ const clusters = [];
678
+ for (const entry of [...top].sort((a, b) => (a.anchorY ?? 0) - (b.anchorY ?? 0))) {
679
+ const y = (entry.anchorY ?? 0) * scale;
680
+ const last = clusters[clusters.length - 1];
681
+ if (last && y - last.y < CLUSTER_GAP) last.entries.push(entry);
682
+ else clusters.push({ y, entries: [entry] });
683
+ }
684
+ const shown = bubbleOpen ? draft ? null : clusters.find((cluster) => cluster.entries.some((entry) => entry.isActive)) ?? clusters[0] : void 0;
685
+ const focus = shown?.entries.find((entry) => entry.isActive) ?? shown?.entries[0];
686
+ const position = focus ? top.indexOf(focus) : -1;
687
+ const step = (offset) => {
688
+ const next = top[position + offset];
689
+ if (next) review.setActive(next.key);
690
+ };
691
+ return /* @__PURE__ */ jsx("div", { ref: anchor, className: "native-docx-review", children: /* @__PURE__ */ jsxs("div", { className: "native-docx-review-markers", "data-testid": "review-markers", children: [
692
+ addComment,
693
+ clusters.map((cluster) => {
694
+ const [first] = cluster.entries;
695
+ const comment = cluster.entries.some((entry) => entry.kind === "comment");
696
+ return /* @__PURE__ */ jsxs(
412
697
  "button",
413
698
  {
414
699
  type: "button",
415
700
  className: "native-docx-review-marker",
416
701
  "data-testid": "review-marker",
417
- "data-kind": entry.kind,
418
- "aria-label": `${entry.author}: ${entry.text.slice(0, 60)}`,
419
- style: { top: (entry.anchorY ?? 0) * scale },
702
+ "data-kind": comment ? "comment" : first.kind,
703
+ "data-active": cluster === shown || void 0,
704
+ "aria-label": cluster.entries.length === 1 ? `${first.author}: ${first.text.slice(0, 60)}` : `${cluster.entries.length} comments and changes`,
705
+ "aria-expanded": layout === "compact" ? cluster === shown : void 0,
706
+ style: { top: cluster.y },
420
707
  onClick: () => {
708
+ if (layout === "compact" && cluster === shown) return dismiss();
709
+ setDraft(null);
421
710
  review.setPaneOpen(true);
422
- review.setActive(entry.key);
423
- }
711
+ review.setActive(first.key);
712
+ },
713
+ children: [
714
+ comment ? /* @__PURE__ */ jsx(MessageSquare, { size: 13 }) : /* @__PURE__ */ jsx(PencilLine, { size: 13 }),
715
+ cluster.entries.length > 1 && /* @__PURE__ */ jsx("span", { className: "native-docx-review-count", children: cluster.entries.length })
716
+ ]
424
717
  },
425
- entry.key
426
- ))
427
- ] });
428
- }
429
- return /* @__PURE__ */ jsxs("aside", { className: "native-docx-review-pane", "data-testid": "review-pane", "aria-label": "Review", children: [
430
- addComment,
431
- /* @__PURE__ */ jsxs("div", { className: "native-docx-review-toolbar", "data-testid": "review-toolbar", children: [
432
- hasChanges && /* @__PURE__ */ jsxs(Fragment, { children: [
433
- /* @__PURE__ */ jsx(
434
- "button",
435
- {
436
- type: "button",
437
- "data-testid": "review-previous",
438
- onClick: () => review.navigate("previous"),
439
- children: "Previous change"
440
- }
441
- ),
442
- /* @__PURE__ */ jsx("button", { type: "button", "data-testid": "review-next", onClick: () => review.navigate("next"), children: "Next change" }),
443
- /* @__PURE__ */ jsx(
444
- "button",
445
- {
446
- type: "button",
447
- "data-testid": "review-accept-all",
448
- onClick: () => review.resolveAll("accept"),
449
- children: "Accept all"
450
- }
451
- ),
452
- /* @__PURE__ */ jsx(
453
- "button",
454
- {
455
- type: "button",
456
- "data-testid": "review-reject-all",
457
- onClick: () => review.resolveAll("reject"),
458
- children: "Reject all"
718
+ first.key
719
+ );
720
+ }),
721
+ bubbleOpen && (draft || shown || top.length === 0) && /* @__PURE__ */ jsx(
722
+ "div",
723
+ {
724
+ className: "native-docx-review-bubble",
725
+ "data-testid": "review-bubble",
726
+ role: "dialog",
727
+ "data-state": "open",
728
+ "aria-label": "Review",
729
+ style: {
730
+ top: draft ? draft.anchorY * scale : shown?.y ?? 0,
731
+ width: Math.max(220, Math.min(340, area.width - 56))
732
+ },
733
+ onKeyDown: (event) => {
734
+ if (event.key === "Escape") {
735
+ event.preventDefault();
736
+ event.stopPropagation();
737
+ dismiss();
459
738
  }
460
- )
461
- ] }),
462
- hasResolved && /* @__PURE__ */ jsxs("label", { children: [
463
- /* @__PURE__ */ jsx(
464
- "input",
739
+ },
740
+ children: draft ? /* @__PURE__ */ jsx(
741
+ Draft,
465
742
  {
466
- type: "checkbox",
467
- "data-testid": "review-show-resolved",
468
- checked: showResolved,
469
- onChange: (event) => setShowResolved(event.target.checked)
743
+ onCancel: dismiss,
744
+ onSubmit: (text) => {
745
+ if (review.addComment(text)) setDraft(null);
746
+ }
470
747
  }
471
- ),
472
- "Show resolved"
473
- ] })
748
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
749
+ /* @__PURE__ */ jsxs("div", { className: "native-docx-review-bubble-head", children: [
750
+ top.length > 1 && position >= 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
751
+ /* @__PURE__ */ jsx(
752
+ "button",
753
+ {
754
+ type: "button",
755
+ className: "native-docx-review-icon",
756
+ "data-testid": "review-bubble-previous",
757
+ "aria-label": "Previous",
758
+ disabled: position === 0,
759
+ onClick: () => step(-1),
760
+ children: /* @__PURE__ */ jsx(ChevronLeft, { size: 14 })
761
+ }
762
+ ),
763
+ /* @__PURE__ */ jsxs("span", { className: "native-docx-review-summary", children: [
764
+ position + 1,
765
+ " of ",
766
+ top.length
767
+ ] }),
768
+ /* @__PURE__ */ jsx(
769
+ "button",
770
+ {
771
+ type: "button",
772
+ className: "native-docx-review-icon",
773
+ "data-testid": "review-bubble-next",
774
+ "aria-label": "Next",
775
+ disabled: position === top.length - 1,
776
+ onClick: () => step(1),
777
+ children: /* @__PURE__ */ jsx(ChevronRight, { size: 14 })
778
+ }
779
+ )
780
+ ] }),
781
+ /* @__PURE__ */ jsx(
782
+ "button",
783
+ {
784
+ type: "button",
785
+ className: "native-docx-review-icon native-docx-review-close",
786
+ "data-testid": "review-bubble-close",
787
+ "aria-label": "Close",
788
+ onClick: dismiss,
789
+ children: /* @__PURE__ */ jsx(X, { size: 14 })
790
+ }
791
+ )
792
+ ] }),
793
+ shown?.entries.map((entry) => /* @__PURE__ */ jsx(
794
+ Card,
795
+ {
796
+ entry,
797
+ replies: repliesOf(entry),
798
+ review,
799
+ extra: children?.(entry),
800
+ onDismiss: dismiss
801
+ },
802
+ entry.key
803
+ )),
804
+ !shown && /* @__PURE__ */ jsx("p", { className: "native-docx-review-empty", "data-testid": "review-empty", children: "No comments or changes." }),
805
+ changes > 1 && /* @__PURE__ */ jsx("div", { className: "native-docx-review-bubble-foot", children: /* @__PURE__ */ jsx(BulkActions, { review }) })
806
+ ] })
807
+ }
808
+ )
809
+ ] }) });
810
+ }
811
+ function BulkActions({ review, navigate }) {
812
+ return /* @__PURE__ */ jsxs("div", { className: "native-docx-review-bulk", children: [
813
+ navigate && /* @__PURE__ */ jsxs("span", { className: "native-docx-review-segment", children: [
814
+ /* @__PURE__ */ jsx(
815
+ "button",
816
+ {
817
+ type: "button",
818
+ className: "native-docx-review-icon",
819
+ "data-testid": "review-previous",
820
+ "aria-label": "Previous change",
821
+ title: "Previous change",
822
+ onClick: () => review.navigate("previous"),
823
+ children: /* @__PURE__ */ jsx(ChevronUp, { size: 14 })
824
+ }
825
+ ),
826
+ /* @__PURE__ */ jsx(
827
+ "button",
828
+ {
829
+ type: "button",
830
+ className: "native-docx-review-icon",
831
+ "data-testid": "review-next",
832
+ "aria-label": "Next change",
833
+ title: "Next change",
834
+ onClick: () => review.navigate("next"),
835
+ children: /* @__PURE__ */ jsx(ChevronDown, { size: 14 })
836
+ }
837
+ )
474
838
  ] }),
475
- draft && /* @__PURE__ */ jsx(
476
- Draft,
839
+ /* @__PURE__ */ jsxs(
840
+ "button",
477
841
  {
478
- top: tops.__draft ?? draft.anchorY * scale,
479
- formRef: (element) => {
480
- if (element) elements.current.set("__draft", element);
481
- },
482
- onCancel: () => setDraft(null),
483
- onSubmit: (text) => {
484
- if (review.addComment(text)) setDraft(null);
485
- }
842
+ type: "button",
843
+ className: "native-docx-review-accept",
844
+ "data-testid": "review-accept-all",
845
+ onClick: () => review.resolveAll("accept"),
846
+ children: [
847
+ /* @__PURE__ */ jsx(CheckCheck, { size: 14 }),
848
+ "Accept all"
849
+ ]
486
850
  }
487
851
  ),
488
- top.map((entry) => /* @__PURE__ */ jsx(
489
- Card,
852
+ /* @__PURE__ */ jsxs(
853
+ "button",
490
854
  {
491
- entry,
492
- replies: repliesOf(entry),
493
- review,
494
- extra: children?.(entry),
495
- top: tops[entry.key] ?? (entry.anchorY ?? 0) * scale,
496
- cardRef: (element) => {
497
- if (element) elements.current.set(entry.key, element);
498
- else elements.current.delete(entry.key);
499
- }
500
- },
501
- entry.key
502
- )),
503
- top.length === 0 && !draft && /* @__PURE__ */ jsx("p", { className: "native-docx-review-empty", "data-testid": "review-empty", children: "No comments or changes." })
855
+ type: "button",
856
+ className: "native-docx-review-reject",
857
+ "data-testid": "review-reject-all",
858
+ onClick: () => review.resolveAll("reject"),
859
+ children: [
860
+ /* @__PURE__ */ jsx(X, { size: 14 }),
861
+ "Reject all"
862
+ ]
863
+ }
864
+ )
504
865
  ] });
505
866
  }
506
867
  function ReviewCardSlot({ children }) {
@@ -582,14 +943,7 @@ function DocxCommentActivity() {
582
943
  /* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { children: "Document comment" }) }),
583
944
  thread.map((entry) => /* @__PURE__ */ jsxs("div", { className: "space-y-1 border-b pb-4 last:border-0", children: [
584
945
  /* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: entry.author || "Reviewer" }),
585
- /* @__PURE__ */ jsx(
586
- "p",
587
- {
588
- className: "whitespace-pre-wrap break-words text-sm",
589
- "data-testid": "docx-full-comment-text",
590
- children: entry.text
591
- }
592
- )
946
+ /* @__PURE__ */ jsx("div", { "data-testid": "docx-full-comment-text", children: /* @__PURE__ */ jsx(AiMarkdown, { allowHtml: false, children: commentText(entry) }) })
593
947
  ] }, entry.key)),
594
948
  statuses.map(([id, run]) => /* @__PURE__ */ jsxs("p", { role: "status", className: "text-sm", children: [
595
949
  run.label,
@@ -1985,7 +2339,10 @@ function DefinedTermButtons() {
1985
2339
  )
1986
2340
  ] });
1987
2341
  }
1988
- function DocxRibbon({ onSave }) {
2342
+ function DocxRibbon({
2343
+ onSave,
2344
+ badge
2345
+ }) {
1989
2346
  const [tab, setTab] = useState("Home");
1990
2347
  const t = useChromeTranslate();
1991
2348
  return /* @__PURE__ */ jsxs("div", { className: "native-docx-ribbon", children: [
@@ -2031,7 +2388,8 @@ function DocxRibbon({ onSave }) {
2031
2388
  /* @__PURE__ */ jsx(DocxEditor.Toolbar.Comments, {}),
2032
2389
  /* @__PURE__ */ jsx(RibbonMenu, { label: "Review options", icon: /* @__PURE__ */ jsx(Ellipsis, { size: 16 }), children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.Reviewers, {}) })
2033
2390
  ] })
2034
- ] })
2391
+ ] }),
2392
+ badge && /* @__PURE__ */ jsx("span", { className: "native-docx-ribbon-badge", "data-testid": "docx-ribbon-badge", children: badge })
2035
2393
  ] });
2036
2394
  }
2037
2395
  var fixedZoomMode = { type: "fixed" };
@@ -2296,7 +2654,10 @@ function NativeDocxEditor({
2296
2654
  const resize = new ResizeObserver(fit);
2297
2655
  const chrome = new MutationObserver(fit);
2298
2656
  resize.observe(viewport);
2299
- chrome.observe(viewport, { attributes: true, attributeFilter: ["style", "data-review-pane"] });
2657
+ chrome.observe(viewport, {
2658
+ attributes: true,
2659
+ attributeFilter: ["style", "data-review-pane", "data-review-margin"]
2660
+ });
2300
2661
  fit();
2301
2662
  fitCleanup.current = () => {
2302
2663
  resize.disconnect();
@@ -2378,7 +2739,16 @@ function NativeDocxEditor({
2378
2739
  trackMoves: true
2379
2740
  }
2380
2741
  ),
2381
- !stream && /* @__PURE__ */ jsx(DocxRibbon, { onSave: () => void saveVersion() }),
2742
+ !stream && /* @__PURE__ */ jsx(
2743
+ DocxRibbon,
2744
+ {
2745
+ onSave: () => void saveVersion(),
2746
+ badge: (
2747
+ // Says the document is shared live, in place of a title row above the ribbon.
2748
+ ready.room && ready.canEdit && !snapshot ? /* @__PURE__ */ jsx("span", { title: "Edits sync live with everyone who has this document open", children: "Co-edit mode" }) : void 0
2749
+ )
2750
+ }
2751
+ ),
2382
2752
  /* @__PURE__ */ jsxs(
2383
2753
  "div",
2384
2754
  {
@@ -2510,5 +2880,5 @@ async function loadFonts(baseUrl) {
2510
2880
  }
2511
2881
 
2512
2882
  export { DEFAULT_DEFINED_TERMS_LABELS, DEFINED_TERM_TRIGGER, DefinedTermsProvider, DocxCommentActivity, DocxEditorReview, DocxMentions, DocxParticipants, DocxRibbon, NativeDocxEditor, editorPort, findDefinitionsSection, insertDefinedTerm, loadDocxFonts, normalizeDocxExport, reviewModule, updateDefinitions, useDefinedTerms, useReview, useReviewItem, withDirectEditing };
2513
- //# sourceMappingURL=chunk-WXLKMEMB.js.map
2514
- //# sourceMappingURL=chunk-WXLKMEMB.js.map
2883
+ //# sourceMappingURL=chunk-K27SDLLN.js.map
2884
+ //# sourceMappingURL=chunk-K27SDLLN.js.map