@stll/folio-react 0.23.1 → 0.24.1

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.
@@ -1,27 +1,28 @@
1
- import { i as cn, n as FolioUIProvider, r as useFolioUI, t as DEFAULT_COMPONENTS } from "./folio-ui-BgDDRsUX.js";
1
+ import { i as cn, n as FolioUIProvider, r as useFolioUI, t as DEFAULT_COMPONENTS } from "./folio-ui-DO95voaI.js";
2
2
  import { t as messages_exports } from "./messages.js";
3
3
  import { c } from "react-compiler-runtime";
4
4
  import * as React$1 from "react";
5
5
  import React, { Component, Suspense, cloneElement, createContext, forwardRef, isValidElement, lazy, memo, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
6
- import { AlertCircleIcon, AlertTriangleIcon, AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon, BaselineIcon, BoldIcon, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ClipboardCopyIcon, EyeIcon, FileIcon, GlobeIcon, ImageIcon, IndentDecreaseIcon, IndentIncreaseIcon, InfoIcon, ItalicIcon, LinkIcon, ListIcon, ListOrderedIcon, MoreHorizontalIcon, OmegaIcon, PaintbrushIcon, PenLineIcon, PencilIcon, PilcrowIcon, Redo2Icon, RulerIcon, SeparatorHorizontalIcon, SquarePenIcon, StickyNoteIcon, TableIcon, TableOfContentsIcon, TypeIcon, UnderlineIcon, Undo2Icon, UnlinkIcon, XIcon } from "lucide-react";
6
+ import { AlertCircleIcon, AlertTriangleIcon, AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon, BaselineIcon, BoldIcon, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ClipboardCopyIcon, EyeIcon, FileIcon, GlobeIcon, ImageIcon, IndentDecreaseIcon, IndentIncreaseIcon, InfoIcon, ItalicIcon, LinkIcon, ListIcon, ListOrderedIcon, ListTreeIcon, MessageSquareTextIcon, MoreHorizontalIcon, OmegaIcon, PaintbrushIcon, PanelLeftOpenIcon, PenLineIcon, PencilIcon, PilcrowIcon, Redo2Icon, RulerIcon, SeparatorHorizontalIcon, SquarePenIcon, StickyNoteIcon, TableIcon, TableOfContentsIcon, TypeIcon, UnderlineIcon, Undo2Icon, UnlinkIcon, XIcon } from "lucide-react";
7
7
  import { closeHistory, redo, undo } from "prosemirror-history";
8
- import { IntlProvider, useTranslations } from "use-intl";
9
- import { FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, createFolioAIEditSnapshot, getCommentAnchorsFromDoc, getFolioDocumentOperationIssues, getTrackedChangesFromDoc } from "@stll/folio-core/ai-edits";
8
+ import { IntlProvider, useFormatter, useTranslations } from "use-intl";
9
+ import { FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FolioPendingSuggestionRegistry, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, createFolioAIEditSnapshot, createPendingSuggestionSourceSnapshot, getCommentAnchorsFromDoc, getFolioDocumentOperationIssues, getTrackedChangesFromDoc } from "@stll/folio-core/ai-edits";
10
10
  import { resolveActiveEditorStory } from "@stll/folio-core/controller/activeEditorStory";
11
11
  import { FOLIO_DOCX_SERIALIZATION_MODE, createFolioEditor } from "@stll/folio-core/controller/folioEditor";
12
+ import { createNoteReferenceFollower, withoutUnreferencedNotes } from "@stll/folio-core/prosemirror/noteReferenceReview";
12
13
  import { cloneDocumentWithParagraphPropertySources } from "@stll/folio-core/docx/document-clone";
13
14
  import { normalizeBaseDirection } from "@stll/folio-core/docx/normalizeBaseDirection";
14
15
  import { getCachedNumberingMap } from "@stll/folio-core/docx/numberingParser";
15
16
  import { classifyEditorKeydown, deleteSelectedTable, historyShortcutOwner, isFocusInInputLike, isKeydownInShortcutScope, isMacPlatform } from "@stll/folio-core/managers/editorShortcuts";
16
17
  import { computeScrollPageInfo, updateScrollPageTotal } from "@stll/folio-core/paged-layout/scrollPageInfo";
17
- import { NO_LIST_STATE, TextSelection, addColumnLeft, addColumnRight, addRowAbove, addRowBelow, applyFormatMarks, applyStyle, applyTableStyle, autoFitContents, captureFormatMarks, clearFormatting, clearTextColor, createStyleResolver, decreaseIndent, decreaseListLevel, deleteColumn, deleteRow, deleteTable, distributeColumns, extractSelectionState, getDocumentBuiltInStyles, getSelectedText, getTableContext, increaseIndent, increaseListLevel, listStateLevel, mergeCells, removeTabStop, removeTableBorders, sameListState, schema, selectColumn, selectRow, selectTable, setAlignment, setAllTableBorders, setCellBorder, setCellFillColor, setCellMargins, setCellTextDirection, setCellVerticalAlign, setFontFamily, setFontSize, setHighlight, setIndentFirstLine, setIndentLeft, setIndentRight, setInsideTableBorders, setLineSpacing, setLtr, setOutsideTableBorders, setRowHeight, setRtl, setTableBorderColor, setTableBorderPreset, setTableBorderWidth, setTableProperties, setTextColor, splitCell, toggleBidi, toggleBold, toggleBulletList, toggleHeaderRow, toggleItalic, toggleNoWrap, toggleNumberedList, toggleStrike, toggleSubscript, toggleSuperscript, toggleUnderline } from "@stll/folio-core/prosemirror";
18
+ import { NO_LIST_STATE, TextSelection, addColumnLeft, addColumnRight, addRowAbove, addRowBelow, applyFormatMarks, applyStyle, applyTableStyle, autoFitContents, captureFormatMarks, clearFormatting, clearTextColor, continueNumbering, createStyleResolver, decreaseIndent, decreaseListLevel, deleteColumn, deleteRow, deleteTable, distributeColumns, extractSelectionState, getDocumentBuiltInStyles, getSelectedText, getTableContext, increaseIndent, increaseListLevel, listStateLevel, mergeCells, removeTabStop, removeTableBorders, restartNumbering, sameListState, schema, selectColumn, selectRow, selectTable, setAlignment, setAllTableBorders, setCellBorder, setCellFillColor, setCellMargins, setCellTextDirection, setCellVerticalAlign, setFontFamily, setFontSize, setHighlight, setIndentFirstLine, setIndentLeft, setIndentRight, setInsideTableBorders, setLineSpacing, setLtr, setNumberingValue, setOutsideTableBorders, setRowHeight, setRtl, setTableBorderColor, setTableBorderPreset, setTableBorderWidth, setTableProperties, setTextColor, splitCell, toggleBidi, toggleBold, toggleBulletList, toggleHeaderRow, toggleItalic, toggleNoWrap, toggleNumberedList, toggleStrike, toggleSubscript, toggleSuperscript, toggleUnderline } from "@stll/folio-core/prosemirror";
18
19
  import { acceptAIEditRevision, acceptChange, acceptSuggestion, findAIEditRevisionRange, findChangeAtPosition, findNextChange, findParagraphBoundaryChangeAtPosition, findPreviousChange, findSuggestionRange, getSuggestions, rejectAIEditRevision, rejectChange, rejectSuggestion } from "@stll/folio-core/prosemirror/commands/comments";
19
20
  import { blockSdtAttrsToSdtProperties, findBlockSdtMatch, findBlockSdtMatches, removeContentControlTr, setContentControlContentTr, setContentControlValueTr } from "@stll/folio-core/prosemirror/commands/contentControls";
20
21
  import { setContentControlContentBlocksTr } from "@stll/folio-core/prosemirror/commands/contentControlsBlockFill";
21
22
  import { CLIPBOARD_READ_ERROR_EVENT, buildPlainTextSlice } from "@stll/folio-core/prosemirror/commands/pastePlainText";
22
23
  import { proseDocToBlocks } from "@stll/folio-core/prosemirror/conversion/fromProseDoc";
23
24
  import { ExtensionManager } from "@stll/folio-core/prosemirror/extensions/ExtensionManager";
24
- import { clearTrackedChanges, getChangedParagraphIds, hasStructuralChanges, hasUntrackedChanges } from "@stll/folio-core/prosemirror/extensions/features/ParagraphChangeTrackerExtension";
25
+ import { clearTrackedChanges, getChangedParagraphIds, hasStructuralChanges, hasUntrackedChanges, repackWithEditorSectionRemovals } from "@stll/folio-core/prosemirror/extensions/features/ParagraphChangeTrackerExtension";
25
26
  import { createStarterKit } from "@stll/folio-core/prosemirror/extensions/StarterKit";
26
27
  import { resolveFindMatchRange } from "@stll/folio-core/prosemirror/findReplaceSelection";
27
28
  import { createAICitationDecorationsPlugin } from "@stll/folio-core/prosemirror/plugins/aiCitationDecorations";
@@ -29,7 +30,7 @@ import { AI_SUGGESTION_SEVERITY_CLASS, aiSuggestionDecorationsKey, createAISugge
29
30
  import { anonymizationDecorationsKey, createAnonymizationDecorationsPlugin, slugAnonymizationLabel } from "@stll/folio-core/prosemirror/plugins/anonymizationDecorations";
30
31
  import { expectImageAttrs, expectTableAttrs, expectTableCellAttrs, mergeTableAttrs, mergeTableCellAttrs, mergeTableRowAttrs } from "@stll/folio-core/prosemirror/attrs";
31
32
  import { autocompleteSuggestionKey, autocompleteSuggestionPlugin } from "@stll/folio-core/prosemirror/plugins/autocompleteSuggestion";
32
- import { createSuggestionModePlugin, setSuggestionMode, suggestionModeKey } from "@stll/folio-core/prosemirror/plugins/suggestionMode";
33
+ import { createSuggestionModePlugin, deleteSelectionAsSuggestion, setSuggestionMode, suggestionModeKey } from "@stll/folio-core/prosemirror/plugins/suggestionMode";
33
34
  import { createTemplateDirectivesPlugin, templateDirectivesKey } from "@stll/folio-core/prosemirror/plugins/templateDirectives";
34
35
  import { createTemplatePreviewValuesPlugin, templatePreviewValuesKey } from "@stll/folio-core/prosemirror/plugins/templatePreviewValues";
35
36
  import { getTemplateSlashMenu, templateSlashMenuPlugin } from "@stll/folio-core/prosemirror/plugins/templateSlashMenu";
@@ -40,21 +41,23 @@ import { collectHeadings } from "@stll/folio-core/utils/headingCollector";
40
41
  import { formatPx, pixelsToTwips, pointsToHalfPoints, twipsToPixels } from "@stll/folio-core/utils/units";
41
42
  import { HistoryManager, classifyHistoryShortcut } from "@stll/folio-core/managers/HistoryManager";
42
43
  import { TableSelectionManager } from "@stll/folio-core/managers/TableSelectionManager";
44
+ import { DEFAULT_PAGE_HEIGHT_PX, getMargins, getPageSize, twipsToPixels as twipsToPixels$1 } from "@stll/folio-core/paged-layout/sectionGeometry";
43
45
  import { createPortal } from "react-dom";
44
46
  import { NodeSelection, Selection, TextSelection as TextSelection$1 } from "prosemirror-state";
45
47
  import { CellSelection } from "prosemirror-tables";
46
48
  import { createHeaderFooterEditorManager } from "@stll/folio-core/controller/headerFooterEditorManager";
47
49
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
48
50
  import { createNoteEditorManager } from "@stll/folio-core/controller/noteEditorManager";
51
+ import { projectMarkupView, visibleCaretPosition } from "@stll/folio-core/prosemirror/markupViewProjection";
49
52
  import { createFolioAIEditSnapshot as createFolioAIEditSnapshot$1 } from "@stll/folio-core/ai-edits/snapshot";
50
53
  import { createFolioEditorEmitter } from "@stll/folio-core/controller/folioEditorEvents";
51
54
  import { dispatchEditorTextInput } from "@stll/folio-core/prosemirror/textInput";
52
55
  import { createLatestRequestGate } from "@stll/folio-core/controller/latestRequestGate";
53
56
  import { runLayoutPipeline } from "@stll/folio-core/controller/layoutPipeline";
54
- import { browserClock, createLayoutScheduler } from "@stll/folio-core/controller/layoutScheduler";
57
+ import { TRANSACTION_LAYOUT_TIMING, browserClock, createLayoutScheduler } from "@stll/folio-core/controller/layoutScheduler";
55
58
  import { createLayoutSession } from "@stll/folio-core/controller/layoutSession";
56
59
  import { createHyphenationReadiness } from "@stll/folio-core/controller/hyphenationReadiness";
57
- import { documentFontsAreLoaded, getDocumentFontSet, waitForInitialLayoutFonts } from "@stll/folio-core/controller/fontReadiness";
60
+ import { readFontSetSignature, waitForInitialLayoutFonts, watchLayoutFontLoads } from "@stll/folio-core/controller/fontReadiness";
58
61
  import { getFootnoteText } from "@stll/folio-core/docx/footnoteParser";
59
62
  import { convertHeaderFooterPmDocToContent, convertHeaderFooterToContent } from "@stll/folio-core/layout-bridge/convert/headerFooterLayout";
60
63
  import { templatePreviewDirtyRange } from "@stll/folio-core/layout-bridge/convert/templatePreviewFlow";
@@ -80,10 +83,8 @@ import { isReadOnlyEditKey } from "@stll/folio-core/paged-layout/readOnlyEditAtt
80
83
  import { getPageScrollTarget, prefersReducedMotionBehavior } from "@stll/folio-core/paged-layout/scrollNavigation";
81
84
  import { PAGES_CONTAINER_CLASS, scrollPagesToPmPosition } from "@stll/folio-core/paged-layout/scrollToPmPosition";
82
85
  import { flashParagraphFragmentsByParaId } from "@stll/folio-core/paged-layout/paragraphFlash";
83
- import { DEFAULT_PAGE_HEIGHT_PX, getMargins, getPageSize, twipsToPixels as twipsToPixels$1 } from "@stll/folio-core/paged-layout/sectionGeometry";
84
86
  import { resizeColumnPair } from "@stll/folio-core/paged-layout/tableColumnResize";
85
87
  import { tableInsertButtonOffset } from "@stll/folio-core/paged-layout/tableInsertButtonGeometry";
86
- import { getTransactionsDirtyRange } from "@stll/folio-core/paged-layout/transactionDirtyRange";
87
88
  import { findStartPosForParaId } from "@stll/folio-core/prosemirror/utils/findParagraphByParaId";
88
89
  import { allowsDirectDrawingEdit } from "@stll/folio-core/docx/imageRawXml";
89
90
  import { commitImageFloatMove, commitImageInlineMove, commitImageResize, isFloatingImage } from "@stll/folio-core/prosemirror/imageCommit";
@@ -97,6 +98,7 @@ import { getFolioParaIdFromBlockId } from "@stll/folio-core/types/block-id";
97
98
  import { getPageTextFromLayout } from "@stll/folio-core/paged-layout/pageText";
98
99
  import { ContentControlWidgetController } from "@stll/folio-core/controller/contentControlWidgetController";
99
100
  import { createDefaultFindOptions, findInDocument } from "@stll/folio-core/utils/findReplace";
101
+ import { PANEL_METRICS, computePanelLayout } from "@stll/folio-core/panel-layout";
100
102
  import { ErrorManager } from "@stll/folio-core/managers/ErrorManager";
101
103
  import { ContextMenuManager } from "@stll/folio-core/managers/ContextMenuManager";
102
104
  import { DocumentLoaderManager } from "@stll/folio-core/managers/DocumentLoaderManager";
@@ -212,7 +214,7 @@ function useDocumentHistory(document, t0) {
212
214
  $[1] = t1;
213
215
  } else t1 = $[1];
214
216
  const options = t1;
215
- const isEqual = _temp$12;
217
+ const isEqual = _temp$14;
216
218
  let t2;
217
219
  if ($[2] !== options) {
218
220
  t2 = {
@@ -224,7 +226,7 @@ function useDocumentHistory(document, t0) {
224
226
  } else t2 = $[3];
225
227
  return useHistory(document, t2);
226
228
  }
227
- function _temp$12(a, b) {
229
+ function _temp$14(a, b) {
228
230
  if (a === b) return true;
229
231
  const aPackage = a?.package;
230
232
  const bPackage = b?.package;
@@ -745,7 +747,7 @@ const AISuggestionRectsOverlay = (t0) => {
745
747
  if (groups.length === 0) return null;
746
748
  let t1;
747
749
  if ($[0] !== groups) {
748
- t1 = groups.map(_temp$11);
750
+ t1 = groups.map(_temp$13);
749
751
  $[0] = groups;
750
752
  $[1] = t1;
751
753
  } else t1 = $[1];
@@ -761,7 +763,7 @@ const AISuggestionRectsOverlay = (t0) => {
761
763
  } else t2 = $[3];
762
764
  return t2;
763
765
  };
764
- function _temp$11(t0) {
766
+ function _temp$13(t0) {
765
767
  const { suggestion, rects, focused, font } = t0;
766
768
  const replacementAnchor = rects.at(-1);
767
769
  const showReplacement = focused && suggestion.suggestedText.length > 0 && replacementAnchor !== void 0;
@@ -996,7 +998,7 @@ const PassageHighlightOverlay = (t0) => {
996
998
  if (rects.length === 0) return null;
997
999
  let t1;
998
1000
  if ($[0] !== rects) {
999
- t1 = rects.map(_temp$10);
1001
+ t1 = rects.map(_temp$12);
1000
1002
  $[0] = rects;
1001
1003
  $[1] = t1;
1002
1004
  } else t1 = $[1];
@@ -1012,7 +1014,7 @@ const PassageHighlightOverlay = (t0) => {
1012
1014
  } else t2 = $[3];
1013
1015
  return t2;
1014
1016
  };
1015
- function _temp$10(rect, idx) {
1017
+ function _temp$12(rect, idx) {
1016
1018
  return /* @__PURE__ */ jsx("span", {
1017
1019
  className: "folio-passage-highlight",
1018
1020
  style: {
@@ -1039,7 +1041,7 @@ const EMPTY_LOADED_EMBEDDED_FONTS = {
1039
1041
  faces: [],
1040
1042
  familyMap: /* @__PURE__ */ new Map()
1041
1043
  };
1042
- function getDocumentFontSet$1() {
1044
+ function getDocumentFontSet() {
1043
1045
  if (typeof document === "undefined" || !("fonts" in document)) return null;
1044
1046
  return document.fonts;
1045
1047
  }
@@ -1070,7 +1072,7 @@ async function registerFontFace(fontSet, family, source, descriptors) {
1070
1072
  * run falls back to the CSS font stack.
1071
1073
  */
1072
1074
  async function loadEmbeddedFontFaces(buffer) {
1073
- const fontSet = getDocumentFontSet$1();
1075
+ const fontSet = getDocumentFontSet();
1074
1076
  if (!fontSet) return EMPTY_LOADED_EMBEDDED_FONTS;
1075
1077
  let fonts;
1076
1078
  try {
@@ -1094,7 +1096,7 @@ async function loadEmbeddedFontFaces(buffer) {
1094
1096
  }
1095
1097
  /** Remove previously registered faces from the document font set. */
1096
1098
  function removeFontFaces(faces) {
1097
- const fontSet = getDocumentFontSet$1();
1099
+ const fontSet = getDocumentFontSet();
1098
1100
  if (!fontSet) return;
1099
1101
  for (const face of faces) fontSet.delete(face);
1100
1102
  }
@@ -1153,7 +1155,7 @@ function toFontFaceInputs(fonts) {
1153
1155
  * thrown. Pair with {@link removeFontFaces} to unregister on change/unmount.
1154
1156
  */
1155
1157
  async function loadHostFontFaces(fonts) {
1156
- const fontSet = getDocumentFontSet$1();
1158
+ const fontSet = getDocumentFontSet();
1157
1159
  if (!fontSet) return [];
1158
1160
  const inputs = toFontFaceInputs(fonts);
1159
1161
  if (inputs.length === 0) return [];
@@ -2277,10 +2279,6 @@ const TABLE_INSERT_EDGE_PROXIMITY = 30;
2277
2279
  const TABLE_INSERT_HIDE_DELAY = 200;
2278
2280
  /** Delay before converting PM state back to the Folio document model. */
2279
2281
  const DOCUMENT_CHANGE_NOTIFY_DELAY = 250;
2280
- /** Quiet window for coalescing follow-up transactions after the leading frame. */
2281
- const TRANSACTION_LAYOUT_DEBOUNCE_MS = 32;
2282
- /** Upper bound for how long visible layout can trail the hidden editor. */
2283
- const TRANSACTION_LAYOUT_MAX_DELAY_MS = 96;
2284
2282
  /** Keep the visual caret hidden briefly while typed content relayouts. */
2285
2283
  const SELECTION_REVEAL_AFTER_INPUT_DELAY = 120;
2286
2284
  /**
@@ -2473,7 +2471,7 @@ function HfCaretOverlay(t0) {
2473
2471
  if (!pagesContainer) return null;
2474
2472
  let t4;
2475
2473
  if ($[17] !== rangeRects) {
2476
- t4 = rangeRects.map(_temp$9);
2474
+ t4 = rangeRects.map(_temp$11);
2477
2475
  $[17] = rangeRects;
2478
2476
  $[18] = t4;
2479
2477
  } else t4 = $[18];
@@ -2512,7 +2510,7 @@ function HfCaretOverlay(t0) {
2512
2510
  } else t7 = $[26];
2513
2511
  return t7;
2514
2512
  }
2515
- function _temp$9(r, i) {
2513
+ function _temp$11(r, i) {
2516
2514
  return /* @__PURE__ */ jsx("div", {
2517
2515
  "data-testid": "hf-selection-rect",
2518
2516
  style: {
@@ -2566,7 +2564,6 @@ function stableJsonStringify(value) {
2566
2564
  return nestedValue;
2567
2565
  });
2568
2566
  }
2569
- const INITIAL_FONT_READY_SUPPRESSION_MS = 250;
2570
2567
  function describeInvalidHighlightMarks(doc) {
2571
2568
  const invalidHighlights = [];
2572
2569
  const validHighlightColors = /* @__PURE__ */ new Set([
@@ -2842,7 +2839,7 @@ function buildFootnoteRenderItems(pageFootnoteMap, footnoteContentMap, doc) {
2842
2839
  * PagedEditor - Main paginated editing component.
2843
2840
  */
2844
2841
  const PagedEditor = forwardRef(function PagedEditor(props, ref) {
2845
- const { document, documentIO, documentIdentity, fonts: hostFonts, styles, theme: _theme, sectionProperties, headerContent, footerContent, firstPageHeaderContent, firstPageFooterContent, headerContentRId, footerContentRId, firstPageHeaderContentRId, firstPageFooterContentRId, readOnly = false, pageGap = 24, zoom = 1, pageRenderer, showMarginGuides = false, marginGuideColor, onDocumentChange, onReadOnlyEditAttempt, onCopy, onCut, onPaste, onSelectionChange, onSelectionTextChange, onEditorViewReady, externalPlugins = EMPTY_PLUGINS, showTemplateDirectives = true, collaboration, extensionManager, suggestionModeActive = false, suggestionAuthor, onActiveNoteStoryChange, onHeaderFooterDoubleClick, hfEditMode, activeHeaderFooterRId, onBodyClick, className, style, commentsSidebarOpen = false, sidebarOverlay, scrollContainerRef: scrollContainerRefProp, onHyperlinkClick, onContextMenu, onAnchorPositionsChange, onTotalPagesChange, onError, anchorPositionMode = "comments-and-revisions", onAnonymizationTermClick, selectedAnonymizationCanonical = null, anonymizationSelectionSeq } = props;
2842
+ const { document, documentIO, documentIdentity, fonts: hostFonts, styles, theme: _theme, sectionProperties, headerContent, footerContent, firstPageHeaderContent, firstPageFooterContent, headerContentRId, footerContentRId, firstPageHeaderContentRId, firstPageFooterContentRId, readOnly = false, pageGap = 24, zoom = 1, pageRenderer, markupView, showMarginGuides = false, marginGuideColor, onDocumentChange, onReadOnlyEditAttempt, onCopy, onCut, onPaste, onSelectionChange, onSelectionTextChange, onEditorViewReady, externalPlugins = EMPTY_PLUGINS, showTemplateDirectives = true, collaboration, extensionManager, suggestionModeActive = false, suggestionAuthor, onActiveNoteStoryChange, onHeaderFooterDoubleClick, hfEditMode, activeHeaderFooterRId, onBodyClick, className, style, pageEndGutter = 0, sidebarOverlay, scrollContainerRef: scrollContainerRefProp, onHyperlinkClick, onContextMenu, onAnchorPositionsChange, onTotalPagesChange, onError, anchorPositionMode = "comments-and-revisions", onAnonymizationTermClick, selectedAnonymizationCanonical = null, anonymizationSelectionSeq } = props;
2846
2843
  const getScrollContainer = useCallback(() => {
2847
2844
  if (scrollContainerRefProp && typeof scrollContainerRefProp === "object") return scrollContainerRefProp.current;
2848
2845
  return containerRef.current;
@@ -2897,7 +2894,6 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
2897
2894
  const pendingHiddenEditorSelectionRef = useRef(null);
2898
2895
  const queuedInputBeforeHiddenEditorRef = useRef([]);
2899
2896
  const pendingInitialFontReadyLayoutRef = useRef(false);
2900
- const suppressFontReadyUntilRef = useRef(0);
2901
2897
  const [isFocused, setIsFocused] = useState(false);
2902
2898
  const [selectionRects, setSelectionRects] = useState([]);
2903
2899
  const [caretPosition, setCaretPosition] = useState(null);
@@ -3063,6 +3059,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3063
3059
  const sectionHeaderFooterRefs = useMemo(() => resolveSectionHeaderFooterRefs(document), [document]);
3064
3060
  const layoutInputSignature = useMemo(() => buildLayoutInputSignature({
3065
3061
  columns,
3062
+ markupView,
3066
3063
  contentWidth,
3067
3064
  defaultTabStop,
3068
3065
  mirrorMargins,
@@ -3083,6 +3080,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3083
3080
  theme: _theme
3084
3081
  }), [
3085
3082
  columns,
3083
+ markupView,
3086
3084
  contentWidth,
3087
3085
  defaultTabStop,
3088
3086
  mirrorMargins,
@@ -3124,6 +3122,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3124
3122
  onError: (error) => onErrorRef.current?.(error)
3125
3123
  }));
3126
3124
  useEffect(() => hyphenationReadiness.cancel, [hyphenationReadiness]);
3125
+ const laidOutLayoutInputSignatureRef = useRef(null);
3127
3126
  const runLayoutPipeline$1 = useCallback((state_0, options = {}) => {
3128
3127
  const outcome = runLayoutPipeline({
3129
3128
  contentWidth,
@@ -3157,12 +3156,13 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3157
3156
  session: layoutSessionRef.current,
3158
3157
  renderHfFromContentOrPm,
3159
3158
  renderHeaderFooterContentByRId,
3160
- documentFontsAreLoaded,
3159
+ readFontSetSignature,
3161
3160
  buildFootnoteRenderItems,
3162
3161
  describeInvalidHighlightMarks,
3163
3162
  emptyTemplatePreviewEntries: EMPTY_TEMPLATE_PREVIEW_ENTRIES,
3164
3163
  emptyTemplatePreviewHidden: EMPTY_TEMPLATE_PREVIEW_HIDDEN,
3165
- hyphenationReadiness
3164
+ hyphenationReadiness,
3165
+ markupView
3166
3166
  }, state_0, options);
3167
3167
  if (outcome.blocks) setBlocks(outcome.blocks);
3168
3168
  if (outcome.measures !== void 0) setMeasures(outcome.measures);
@@ -3170,6 +3170,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3170
3170
  if (outcome.blockLookup) painterRef.current?.setBlockLookup(outcome.blockLookup);
3171
3171
  if (outcome.layout) {
3172
3172
  layoutRef.current = outcome.layout;
3173
+ laidOutLayoutInputSignatureRef.current = layoutInputSignature;
3173
3174
  folioEmitterRef.current.emit("layoutComplete", outcome.layout);
3174
3175
  }
3175
3176
  }, [
@@ -3197,7 +3198,9 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3197
3198
  document,
3198
3199
  defaultTabStop,
3199
3200
  mirrorMargins,
3200
- styles
3201
+ styles,
3202
+ markupView,
3203
+ layoutInputSignature
3201
3204
  ]);
3202
3205
  const runLayoutPipelineRef = useRef(runLayoutPipeline$1);
3203
3206
  runLayoutPipelineRef.current = runLayoutPipeline$1;
@@ -3236,24 +3239,29 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3236
3239
  ]);
3237
3240
  const layoutSchedulerRef = useRef(null);
3238
3241
  if (layoutSchedulerRef.current === null) layoutSchedulerRef.current = createLayoutScheduler({
3242
+ readState: () => hiddenPMRef.current?.getState() ?? precomputedInitialStateRef.current,
3239
3243
  runLayout: (state_2, options_1) => runLayoutPipelineRef.current(state_2, options_1),
3240
- debounceMs: TRANSACTION_LAYOUT_DEBOUNCE_MS,
3241
- leadingFrame: true,
3242
- maxDelayMs: TRANSACTION_LAYOUT_MAX_DELAY_MS,
3244
+ ...TRANSACTION_LAYOUT_TIMING,
3243
3245
  clock: browserClock
3244
3246
  });
3245
3247
  const documentChangeNotifyTimerRef = useRef(null);
3248
+ const [noteFollower] = useState(createNoteReferenceFollower);
3249
+ useEffect(() => {
3250
+ noteFollower.reset();
3251
+ }, [documentIdentity, noteFollower]);
3246
3252
  const flushDocumentChangeNotification = useCallback(() => {
3247
3253
  if (documentChangeNotifyTimerRef.current !== null) {
3248
3254
  window.clearTimeout(documentChangeNotifyTimerRef.current);
3249
3255
  documentChangeNotifyTimerRef.current = null;
3250
3256
  }
3251
- const newDoc = hiddenPMRef.current?.getDocument();
3257
+ let newDoc = hiddenPMRef.current?.getDocument();
3258
+ const body = hiddenPMRef.current?.getState()?.doc;
3259
+ if (newDoc && body) newDoc = noteFollower.reconcile(newDoc, body);
3252
3260
  if (newDoc) {
3253
3261
  onDocumentChangeRef.current?.(newDoc);
3254
3262
  folioEmitterRef.current.emit("docChange", newDoc);
3255
3263
  }
3256
- }, []);
3264
+ }, [noteFollower]);
3257
3265
  const scheduleDocumentChangeNotification = useCallback(() => {
3258
3266
  if (documentChangeNotifyTimerRef.current !== null) window.clearTimeout(documentChangeNotifyTimerRef.current);
3259
3267
  documentChangeNotifyTimerRef.current = window.setTimeout(() => {
@@ -3261,8 +3269,8 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3261
3269
  flushDocumentChangeNotification();
3262
3270
  }, DOCUMENT_CHANGE_NOTIFY_DELAY);
3263
3271
  }, [flushDocumentChangeNotification]);
3264
- const scheduleLayout = useCallback((state_3, dirtyRange) => {
3265
- layoutSchedulerRef.current?.schedule(state_3, dirtyRange);
3272
+ const scheduleLayout = useCallback(() => {
3273
+ layoutSchedulerRef.current?.schedule();
3266
3274
  }, []);
3267
3275
  useEffect(() => () => {
3268
3276
  layoutSchedulerRef.current?.dispose();
@@ -3292,7 +3300,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3292
3300
  const view_2 = hiddenPMRef.current?.getView();
3293
3301
  if (!view_2) return;
3294
3302
  const { selection: selection_1 } = view_2.state;
3295
- const domCaret = selection_1.empty ? getCaretFromDom(selection_1.head, zoom) : null;
3303
+ const domCaret = selection_1.empty ? getCaretFromDom(visibleCaretPosition(projectMarkupView(view_2.state, markupView), selection_1.head), zoom) : null;
3296
3304
  const overlayRect_0 = (pagesContainerRef.current?.parentElement?.querySelector("[data-testid=\"selection-overlay\"]"))?.getBoundingClientRect();
3297
3305
  syncImeCaretAnchor({
3298
3306
  hiddenHost: hiddenPMRef.current?.getHostElement(),
@@ -3302,21 +3310,25 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3302
3310
  top: overlayRect_0.top + domCaret.y * zoom
3303
3311
  } : null
3304
3312
  });
3305
- }, [getCaretFromDom, zoom]);
3313
+ }, [
3314
+ getCaretFromDom,
3315
+ zoom,
3316
+ markupView
3317
+ ]);
3306
3318
  /**
3307
3319
  * Update selection overlay from PM selection.
3308
3320
  */
3309
- const updateSelectionOverlay = useCallback((state_4) => {
3310
- const { from, to } = state_4.selection;
3321
+ const updateSelectionOverlay = useCallback((state_3) => {
3322
+ const { from, to } = state_3.selection;
3311
3323
  const isCurrentRequest = selectionOverlayRequestGate.begin();
3312
- if (directivesRef.current.length > 0) setDirectiveCaretPos(state_4.selection.head);
3324
+ if (directivesRef.current.length > 0) setDirectiveCaretPos(state_3.selection.head);
3313
3325
  onSelectionChangeRef.current?.(from, to);
3314
3326
  folioEmitterRef.current.emit("selectionChange", {
3315
3327
  from,
3316
3328
  to
3317
3329
  });
3318
3330
  if (onSelectionTextChangeRef.current) {
3319
- const text_0 = from === to ? "" : state_4.doc.textBetween(from, to, " ", " ");
3331
+ const text_0 = from === to ? "" : state_3.doc.textBetween(from, to, " ", " ");
3320
3332
  onSelectionTextChangeRef.current({
3321
3333
  from,
3322
3334
  to,
@@ -3336,7 +3348,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3336
3348
  if (pagesContainerRef.current) {
3337
3349
  const prevSelected = pagesContainerRef.current.querySelectorAll(".layout-table-cell-selected");
3338
3350
  for (const el_0 of Array.from(prevSelected)) el_0.classList.remove("layout-table-cell-selected");
3339
- const sel = state_4.selection;
3351
+ const sel = state_3.selection;
3340
3352
  if ("$anchorCell" in sel && typeof sel.forEachCell === "function") {
3341
3353
  const selectedRanges = [];
3342
3354
  sel.forEachCell((node_0, pos) => {
@@ -3364,7 +3376,8 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3364
3376
  return;
3365
3377
  }
3366
3378
  if (from === to) {
3367
- const domCaret_0 = getCaretFromDom(from, zoom);
3379
+ const caretPos = visibleCaretPosition(projectMarkupView(state_3, markupView), from);
3380
+ const domCaret_0 = getCaretFromDom(caretPos, zoom);
3368
3381
  if (domCaret_0) {
3369
3382
  setCaretPosition(domCaret_0);
3370
3383
  const overlayRect_1 = (pagesContainerRef.current?.parentElement?.querySelector("[data-testid=\"selection-overlay\"]"))?.getBoundingClientRect();
@@ -3385,7 +3398,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3385
3398
  setCaretPosition(null);
3386
3399
  loadSelectionGeometry().then(({ getCaretPosition }) => {
3387
3400
  if (!isCurrentRequest()) return;
3388
- const caret_0 = getCaretPosition(layout, blocks, measures, from);
3401
+ const caret_0 = getCaretPosition(layout, blocks, measures, caretPos);
3389
3402
  if (caret_0) {
3390
3403
  const fallbackCaret = {
3391
3404
  ...caret_0,
@@ -3477,7 +3490,8 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3477
3490
  measures,
3478
3491
  getCaretFromDom,
3479
3492
  selectionOverlayRequestGate,
3480
- zoom
3493
+ zoom,
3494
+ markupView
3481
3495
  ]);
3482
3496
  const updateSelectionOverlayRef = useRef(updateSelectionOverlay);
3483
3497
  updateSelectionOverlayRef.current = updateSelectionOverlay;
@@ -3489,8 +3503,8 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3489
3503
  if (animationFrame !== null) cancelAnimationFrame(animationFrame);
3490
3504
  animationFrame = requestAnimationFrame(() => {
3491
3505
  animationFrame = null;
3492
- const state_5 = hiddenPMRef.current?.getState();
3493
- if (state_5) updateSelectionOverlayRef.current(state_5);
3506
+ const state_4 = hiddenPMRef.current?.getState();
3507
+ if (state_4) updateSelectionOverlayRef.current(state_4);
3494
3508
  });
3495
3509
  };
3496
3510
  pagesContainer_0.addEventListener(PAINTER_PAINTED_EVENT, repaintSelection);
@@ -3731,7 +3745,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3731
3745
  }
3732
3746
  updatePassageHighlightOverlay();
3733
3747
  }, [passageHighlightOverlayRequestGate, updatePassageHighlightOverlay]);
3734
- const hideSelectionOverlayDuringInput = useCallback((state_6) => {
3748
+ const hideSelectionOverlayDuringInput = useCallback((state_5) => {
3735
3749
  selectionOverlayRequestGate.invalidate();
3736
3750
  suppressSelectionOverlayRef.current = true;
3737
3751
  setCaretPosition(null);
@@ -3740,7 +3754,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3740
3754
  revealSelectionOverlayTimerRef.current = window.setTimeout(() => {
3741
3755
  revealSelectionOverlayTimerRef.current = null;
3742
3756
  suppressSelectionOverlayRef.current = false;
3743
- updateSelectionOverlay(hiddenPMRef.current?.getState() ?? state_6);
3757
+ updateSelectionOverlay(hiddenPMRef.current?.getState() ?? state_5);
3744
3758
  }, SELECTION_REVEAL_AFTER_INPUT_DELAY);
3745
3759
  }, [selectionOverlayRequestGate, updateSelectionOverlay]);
3746
3760
  useEffect(() => () => {
@@ -3765,7 +3779,9 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3765
3779
  /**
3766
3780
  * Handle PM transaction - re-layout on content/selection change.
3767
3781
  */
3768
- const handleTransaction = useCallback(({ transactions, newState, docChanged }) => {
3782
+ const handleTransaction = useCallback(({ newState, docChanged, transactions }) => {
3783
+ const before = transactions[0]?.before;
3784
+ if (docChanged && before) noteFollower.noteBase(before);
3769
3785
  const nextMatches = anonymizationDecorationsKey.getState(newState)?.matches ?? [];
3770
3786
  const matchesChanged = nextMatches !== anonymizationMatchesRef.current;
3771
3787
  anonymizationMatchesRef.current = nextMatches;
@@ -3791,11 +3807,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3791
3807
  hidden: nextPreviewHidden,
3792
3808
  mode: nextPreviewMode
3793
3809
  };
3794
- if (!docChanged) if (nextPreviewMode !== previousPreview.mode) scheduleLayout(newState, null);
3795
- else {
3796
- const previewDirty = templatePreviewDirtyRange(previousPreview, templatePreviewRef.current);
3797
- if (previewDirty) scheduleLayout(newState, previewDirty);
3798
- }
3810
+ if (!docChanged && (nextPreviewMode !== previousPreview.mode || templatePreviewDirtyRange(previousPreview, templatePreviewRef.current) !== null)) scheduleLayout();
3799
3811
  }
3800
3812
  const nextAiState = aiSuggestionDecorationsKey.getState(newState);
3801
3813
  const nextAiSuggestions = nextAiState?.suggestions ?? EMPTY_AI_SUGGESTIONS;
@@ -3815,7 +3827,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3815
3827
  setPassageHighlightRects((prev_2) => prev_2.length === 0 ? prev_2 : []);
3816
3828
  }
3817
3829
  hideSelectionOverlayDuringInput(newState);
3818
- scheduleLayout(newState, getTransactionsDirtyRange(transactions));
3830
+ scheduleLayout();
3819
3831
  scheduleDocumentChangeNotification();
3820
3832
  }
3821
3833
  syncCoordinator.requestRender();
@@ -3830,7 +3842,8 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3830
3842
  updateDirectivesOverlay,
3831
3843
  updateAISuggestionsOverlay,
3832
3844
  passageHighlightOverlayRequestGate,
3833
- syncCoordinator
3845
+ syncCoordinator,
3846
+ noteFollower
3834
3847
  ]);
3835
3848
  /**
3836
3849
  * Handle a transaction on a persistent hidden HF EditorView.
@@ -3851,13 +3864,8 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3851
3864
  const activeHfPageNumberRef = useRef(null);
3852
3865
  const handleHfPmTransaction = useCallback((rId, kind, view_3, docChanged_0, selectionChanged) => {
3853
3866
  if (docChanged_0) {
3854
- let bodyState = hiddenPMRef.current?.getState();
3855
- if (!bodyState && precomputedInitialStateRef.current) bodyState = precomputedInitialStateRef.current;
3856
- if (!bodyState) {
3857
- ensureHiddenEditorView({ sync: true });
3858
- bodyState = hiddenPMRef.current?.getState();
3859
- }
3860
- if (bodyState) scheduleLayout(bodyState, null);
3867
+ if (!hiddenPMRef.current?.getState() && !precomputedInitialStateRef.current) ensureHiddenEditorView({ sync: true });
3868
+ scheduleLayout();
3861
3869
  }
3862
3870
  if (docChanged_0 || selectionChanged) {
3863
3871
  const { from: from_1, to: to_1 } = view_3.state.selection;
@@ -3877,10 +3885,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3877
3885
  }
3878
3886
  }, [scheduleLayout, ensureHiddenEditorView]);
3879
3887
  const handleNoteStoryTransaction = useCallback((view_4, docChanged_1, selectionChanged_0) => {
3880
- if (docChanged_1) {
3881
- const bodyState_0 = hiddenPMRef.current?.getState();
3882
- if (bodyState_0) scheduleLayout(bodyState_0, null);
3883
- }
3888
+ if (docChanged_1) scheduleLayout();
3884
3889
  if (docChanged_1 || selectionChanged_0) {
3885
3890
  const { from: from_2, to: to_2 } = view_4.state.selection;
3886
3891
  onSelectionChangeRef.current?.(from_2, to_2);
@@ -3903,12 +3908,12 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
3903
3908
  /**
3904
3909
  * Handle selection change from PM.
3905
3910
  */
3906
- const handleSelectionChange = useCallback((state_7) => {
3907
- const { selection: selection_2 } = state_7;
3911
+ const handleSelectionChange = useCallback((state_6) => {
3912
+ const { selection: selection_2 } = state_6;
3908
3913
  if (selection_2 instanceof NodeSelection && selection_2.node.type.name === "image") {
3909
3914
  setSelectionRects([]);
3910
3915
  setCaretPosition(null);
3911
- } else if (syncCoordinator.isSafeToRender()) updateSelectionOverlay(state_7);
3916
+ } else if (syncCoordinator.isSafeToRender()) updateSelectionOverlay(state_6);
3912
3917
  requestAnimationFrame(() => {
3913
3918
  const view_5 = hiddenPMRef.current?.getView();
3914
3919
  if (!view_5) {
@@ -4030,9 +4035,9 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4030
4035
  });
4031
4036
  }, [layout, scrollToPositionImpl]);
4032
4037
  const scrollToParaIdImpl = useCallback((paraId, options_2) => {
4033
- const state_8 = hiddenPMRef.current?.getState();
4034
- if (!state_8) return false;
4035
- const startPos = findStartPosForParaId(state_8.doc, paraId);
4038
+ const state_7 = hiddenPMRef.current?.getState();
4039
+ if (!state_7) return false;
4040
+ const startPos = findStartPosForParaId(state_7.doc, paraId);
4036
4041
  if (startPos == null || startPos < 0) return false;
4037
4042
  scrollToPositionImpl(startPos);
4038
4043
  requestAnimationFrame(() => {
@@ -4040,8 +4045,8 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
4040
4045
  const pages = pagesContainerRef.current;
4041
4046
  if (pages) flashParagraphFragmentsByParaId(pages, paraId, options_2.highlight);
4042
4047
  }
4043
- const targetNode = state_8.doc.nodeAt(startPos);
4044
- const inner = targetNode?.isTextblock === true ? Math.min(startPos + 1 + targetNode.content.size, state_8.doc.content.size) : Math.min(startPos + 1, state_8.doc.content.size);
4048
+ const targetNode = state_7.doc.nodeAt(startPos);
4049
+ const inner = targetNode?.isTextblock === true ? Math.min(startPos + 1 + targetNode.content.size, state_7.doc.content.size) : Math.min(startPos + 1, state_7.doc.content.size);
4045
4050
  hiddenPMRef.current?.setSelection(inner);
4046
4051
  hiddenPMRef.current?.focus();
4047
4052
  });
@@ -5146,7 +5151,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5146
5151
  let cancelled = false;
5147
5152
  pendingInitialFontReadyLayoutRef.current = true;
5148
5153
  const fontWaitStartedAt = performance.now();
5149
- const runAfterFontWait = (fontsLoaded) => {
5154
+ const runAfterFontWait = () => {
5150
5155
  if (cancelled) return;
5151
5156
  pendingInitialFontReadyLayoutRef.current = false;
5152
5157
  preHiddenInitialLayoutDoneRef.current = true;
@@ -5157,12 +5162,8 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5157
5162
  updateSelectionOverlay(initialState);
5158
5163
  updateAnonymizationOverlay();
5159
5164
  updateDirectivesOverlay();
5160
- if (fontsLoaded) {
5161
- layoutSessionRef.current.usedLoadedFonts = true;
5162
- suppressFontReadyUntilRef.current = performance.now() + INITIAL_FONT_READY_SUPPRESSION_MS;
5163
- }
5164
5165
  };
5165
- waitForInitialLayoutFonts(document, initialState.doc).then(runAfterFontWait, () => runAfterFontWait(false));
5166
+ waitForInitialLayoutFonts(document, initialState.doc).then(runAfterFontWait, runAfterFontWait);
5166
5167
  return () => {
5167
5168
  cancelled = true;
5168
5169
  pendingInitialFontReadyLayoutRef.current = false;
@@ -5211,7 +5212,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5211
5212
  setIsFocused(true);
5212
5213
  });
5213
5214
  };
5214
- if (layoutSessionRef.current.lastPmDoc?.eq(view_24.state.doc)) {
5215
+ if (layoutSessionRef.current.lastPmDoc?.eq(view_24.state.doc) && layoutSessionRef.current.lastMeasureInputs?.markupView === markupView) {
5215
5216
  const lastPreview = layoutSessionRef.current.lastTemplatePreview;
5216
5217
  if (templatePreviewRef.current.mode !== lastPreview.mode || templatePreviewDirtyRange(lastPreview, templatePreviewRef.current) !== null) runLayoutPipeline$1(view_24.state, { reason: "manual" });
5217
5218
  updateSelectionOverlay(view_24.state);
@@ -5230,7 +5231,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5230
5231
  };
5231
5232
  pendingInitialFontReadyLayoutRef.current = true;
5232
5233
  const fontWaitStartedAt_0 = performance.now();
5233
- const runAfterFontWait_0 = (fontsLoaded_0) => {
5234
+ const runAfterFontWait_0 = () => {
5234
5235
  pendingInitialFontReadyLayoutRef.current = false;
5235
5236
  const currentView_0 = hiddenPMRef.current?.getView();
5236
5237
  if (currentView_0 !== view_24) return;
@@ -5238,12 +5239,8 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5238
5239
  resetCanvasContext();
5239
5240
  clearAllCaches();
5240
5241
  runInitialLayout(currentView_0);
5241
- if (fontsLoaded_0) {
5242
- layoutSessionRef.current.usedLoadedFonts = true;
5243
- suppressFontReadyUntilRef.current = performance.now() + INITIAL_FONT_READY_SUPPRESSION_MS;
5244
- }
5245
5242
  };
5246
- waitForInitialLayoutFonts(document, view_24.state.doc).then(runAfterFontWait_0, () => runAfterFontWait_0(false));
5243
+ waitForInitialLayoutFonts(document, view_24.state.doc).then(runAfterFontWait_0, runAfterFontWait_0);
5247
5244
  focusReadyView();
5248
5245
  }, [
5249
5246
  applyPendingHiddenEditorInput,
@@ -5255,7 +5252,8 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5255
5252
  document,
5256
5253
  updateAutocompleteOverlay,
5257
5254
  readOnly,
5258
- refreshBodyImeCaretAnchor
5255
+ refreshBodyImeCaretAnchor,
5256
+ markupView
5259
5257
  ]);
5260
5258
  const handleEditorViewDestroy = useCallback(() => {
5261
5259
  onEditorViewReadyRef.current?.(null);
@@ -5296,32 +5294,17 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5296
5294
  useEffect(() => {
5297
5295
  updateAutocompleteOverlay();
5298
5296
  }, [updateAutocompleteOverlay]);
5299
- useEffect(() => {
5300
- const fontSet = getDocumentFontSet();
5301
- if (!fontSet) return;
5302
- const handleFontsLoading = () => {
5303
- if (performance.now() < suppressFontReadyUntilRef.current) return;
5304
- layoutSessionRef.current.usedLoadedFonts = false;
5305
- };
5306
- const handleFontsLoaded = () => {
5307
- if (pendingInitialFontReadyLayoutRef.current || performance.now() < suppressFontReadyUntilRef.current || layoutSessionRef.current.usedLoadedFonts) return;
5297
+ useEffect(() => watchLayoutFontLoads({
5298
+ measuredFontSet: () => layoutSessionRef.current.lastMeasureInputs?.fontSet ?? null,
5299
+ relayout: () => {
5300
+ if (pendingInitialFontReadyLayoutRef.current) return;
5308
5301
  const view_25 = hiddenPMRef.current?.getView();
5309
- if (view_25) {
5310
- resetCanvasContext();
5311
- clearAllCaches();
5312
- runLayoutPipelineRef.current(view_25.state, { reason: "font-ready" });
5313
- updateSelectionOverlayRef.current(view_25.state);
5314
- }
5315
- };
5316
- fontSet.addEventListener("loading", handleFontsLoading);
5317
- fontSet.addEventListener("loadingdone", handleFontsLoaded);
5318
- fontSet.addEventListener("loadingerror", handleFontsLoaded);
5319
- return () => {
5320
- fontSet.removeEventListener("loading", handleFontsLoading);
5321
- fontSet.removeEventListener("loadingdone", handleFontsLoaded);
5322
- fontSet.removeEventListener("loadingerror", handleFontsLoaded);
5323
- };
5324
- }, []);
5302
+ const state_8 = view_25?.state ?? layoutSessionRef.current.lastEditorState;
5303
+ if (!state_8) return;
5304
+ runLayoutPipelineRef.current(state_8, { reason: "font-ready" });
5305
+ if (view_25) updateSelectionOverlayRef.current(view_25.state);
5306
+ }
5307
+ }), []);
5325
5308
  const embeddedFontBuffer = document?.originalBuffer ?? null;
5326
5309
  useEffect(() => {
5327
5310
  if (!embeddedFontBuffer) return;
@@ -5377,27 +5360,23 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5377
5360
  };
5378
5361
  }, [hostFonts]);
5379
5362
  const layoutInputEpochRef = useRef(0);
5380
- const lastLayoutInputSignatureRef = useRef(null);
5381
5363
  useEffect(() => {
5382
5364
  if (layoutInputEpochRef.current === 0) {
5383
5365
  layoutInputEpochRef.current = 1;
5384
- lastLayoutInputSignatureRef.current = layoutInputSignature;
5385
5366
  return;
5386
5367
  }
5387
- const view_28 = hiddenPMRef.current?.getView();
5388
- if (view_28) {
5389
- const layoutInputsChanged = lastLayoutInputSignatureRef.current !== layoutInputSignature;
5390
- lastLayoutInputSignatureRef.current = layoutInputSignature;
5391
- if (!layoutInputsChanged && view_28.state.doc === layoutSessionRef.current.lastPmDoc) return;
5392
- runLayoutPipelineRef.current(view_28.state, { reason: "layout-input" });
5368
+ const state_9 = hiddenPMRef.current?.getView()?.state ?? (preHiddenInitialLayoutDoneRef.current && precomputedInitialDocumentRef.current === document ? layoutSessionRef.current.lastEditorState : null);
5369
+ if (state_9) {
5370
+ if (laidOutLayoutInputSignatureRef.current === layoutInputSignature && state_9.doc === layoutSessionRef.current.lastPmDoc) return;
5371
+ runLayoutPipelineRef.current(state_9, { reason: "layout-input" });
5393
5372
  }
5394
5373
  }, [document, layoutInputSignature]);
5395
5374
  useEffect(() => {
5396
5375
  const container = containerRef.current;
5397
5376
  if (!container) return;
5398
5377
  const observer = new ResizeObserver(() => {
5399
- const state_9 = hiddenPMRef.current?.getState();
5400
- if (state_9) updateSelectionOverlay(state_9);
5378
+ const state_10 = hiddenPMRef.current?.getState();
5379
+ if (state_10) updateSelectionOverlay(state_10);
5401
5380
  });
5402
5381
  observer.observe(container);
5403
5382
  return () => observer.disconnect();
@@ -5429,7 +5408,9 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5429
5408
  return folioEditor;
5430
5409
  },
5431
5410
  getDocument() {
5432
- const current_0 = folioEditor.getDocument();
5411
+ if (documentChangeNotifyTimerRef.current !== null) flushDocumentChangeNotification();
5412
+ const editorDocument = folioEditor.getDocument();
5413
+ const current_0 = editorDocument ? noteFollower.withPending(editorDocument) : null;
5433
5414
  return current_0 ? noteEditorRef.current?.snapshotDocument(current_0) ?? current_0 : null;
5434
5415
  },
5435
5416
  getState() {
@@ -5457,8 +5438,8 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5457
5438
  setIsFocused(true);
5458
5439
  },
5459
5440
  blur() {
5460
- const view_29 = getActiveEditorStory().view;
5461
- if (view_29?.hasFocus() && view_29.dom instanceof HTMLElement) view_29.dom.blur();
5441
+ const view_28 = getActiveEditorStory().view;
5442
+ if (view_28?.hasFocus() && view_28.dom instanceof HTMLElement) view_28.dom.blur();
5462
5443
  setIsFocused(false);
5463
5444
  },
5464
5445
  isFocused() {
@@ -5534,25 +5515,25 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5534
5515
  return bestNumber;
5535
5516
  },
5536
5517
  getBlockRect(blockId) {
5537
- const state_10 = folioEditor.getState();
5518
+ const state_11 = folioEditor.getState();
5538
5519
  const pagesContainer_6 = pagesContainerRef.current;
5539
5520
  const scrollRoot = getScrollContainer();
5540
- if (!state_10 || !pagesContainer_6 || !scrollRoot) return null;
5521
+ if (!state_11 || !pagesContainer_6 || !scrollRoot) return null;
5541
5522
  return readBlockRects({
5542
5523
  blockIds: [blockId],
5543
- snapshot: createFolioAIEditSnapshot$1(state_10.doc),
5524
+ snapshot: createFolioAIEditSnapshot$1(state_11.doc),
5544
5525
  pagesContainer: pagesContainer_6,
5545
5526
  scrollRoot
5546
5527
  }).get(blockId) ?? null;
5547
5528
  },
5548
5529
  getBlockRects(blockIds) {
5549
- const state_11 = folioEditor.getState();
5530
+ const state_12 = folioEditor.getState();
5550
5531
  const pagesContainer_7 = pagesContainerRef.current;
5551
5532
  const scrollRoot_0 = getScrollContainer();
5552
- if (!state_11 || !pagesContainer_7 || !scrollRoot_0) return /* @__PURE__ */ new Map();
5533
+ if (!state_12 || !pagesContainer_7 || !scrollRoot_0) return /* @__PURE__ */ new Map();
5553
5534
  return readBlockRects({
5554
5535
  blockIds,
5555
- snapshot: createFolioAIEditSnapshot$1(state_11.doc),
5536
+ snapshot: createFolioAIEditSnapshot$1(state_12.doc),
5556
5537
  pagesContainer: pagesContainer_7,
5557
5538
  scrollRoot: scrollRoot_0
5558
5539
  });
@@ -5564,8 +5545,10 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5564
5545
  }
5565
5546
  }), [
5566
5547
  ensureHiddenEditorView,
5548
+ flushDocumentChangeNotification,
5567
5549
  folioEditor,
5568
5550
  getActiveEditorStory,
5551
+ noteFollower,
5569
5552
  getScrollContainer,
5570
5553
  refreshBodyImeCaretAnchor,
5571
5554
  scrollToPageImpl,
@@ -5581,8 +5564,8 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5581
5564
  onTotalPagesChangeRef.current?.(totalPages);
5582
5565
  }, [layout]);
5583
5566
  useEffect(() => {
5584
- const state_12 = hiddenPMRef.current?.getState();
5585
- if (layout && state_12) updateSelectionOverlay(state_12);
5567
+ const state_13 = hiddenPMRef.current?.getState();
5568
+ if (layout && state_13) updateSelectionOverlay(state_13);
5586
5569
  }, [layout, updateSelectionOverlay]);
5587
5570
  const totalHeight = useMemo(() => {
5588
5571
  if (!layout) return DEFAULT_PAGE_HEIGHT_PX + 48;
@@ -5594,7 +5577,9 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5594
5577
  pageGap
5595
5578
  ]);
5596
5579
  const scaledViewportHeight = Math.max(1, totalHeight * zoom);
5597
- const scaledViewportWidth = Math.max(1, pageSize.w * zoom + (commentsSidebarOpen ? 304 : 0));
5580
+ let widestPageWidth = layout?.pages.length ? 0 : pageSize.w;
5581
+ for (const page_1 of layout?.pages ?? []) widestPageWidth = Math.max(widestPageWidth, page_1.size.w);
5582
+ const scaledViewportWidth = Math.max(1, widestPageWidth * zoom + pageEndGutter);
5598
5583
  const viewportExtentStyle = {
5599
5584
  position: "relative",
5600
5585
  width: `max(100%, ${String(scaledViewportWidth)}px)`,
@@ -5607,7 +5592,7 @@ const PagedEditor = forwardRef(function PagedEditor(props, ref) {
5607
5592
  position: "absolute",
5608
5593
  top: 0,
5609
5594
  left: `max(0px, calc((100% - ${String(scaledViewportWidth)}px) / 2))`,
5610
- width: pageSize.w,
5595
+ width: widestPageWidth,
5611
5596
  minHeight: totalHeight,
5612
5597
  transform: (() => {
5613
5598
  const parts = [];
@@ -6891,6 +6876,19 @@ function createComment(text, authorName, parentId, id) {
6891
6876
  function getCommentParentId(comment) {
6892
6877
  return comment.parentId;
6893
6878
  }
6879
+ /**
6880
+ * Threads the comments sidebar shows a card for: top-level comments not yet
6881
+ * resolved. Tracked changes are painted inline and have no card, so a
6882
+ * document with only tracked changes has none.
6883
+ */
6884
+ function countOpenCommentThreads(comments) {
6885
+ let count = 0;
6886
+ for (const comment of comments) {
6887
+ const parentId = getCommentParentId(comment);
6888
+ if ((parentId === null || parentId === void 0) && !comment.done) count += 1;
6889
+ }
6890
+ return count;
6891
+ }
6894
6892
  function applyCommentMarkRange(view, range, commentId, options) {
6895
6893
  const commentMark = view.state.schema.marks["comment"];
6896
6894
  const safeRange = clampCommentMarkRange(view.state.doc.content.size, range);
@@ -7124,7 +7122,7 @@ function ContentControlWidgetsOverlay(t0) {
7124
7122
  "aria-label": t11,
7125
7123
  style,
7126
7124
  className: "bg-popover text-popover-foreground min-w-[10rem] rounded-md border p-1 shadow-md",
7127
- onPointerDown: _temp$8,
7125
+ onPointerDown: _temp$10,
7128
7126
  children: [t12, t13]
7129
7127
  })
7130
7128
  }), document.body);
@@ -7136,7 +7134,7 @@ function ContentControlWidgetsOverlay(t0) {
7136
7134
  } else t14 = $[31];
7137
7135
  return t14;
7138
7136
  }
7139
- function _temp$8(event) {
7137
+ function _temp$10(event) {
7140
7138
  return event.stopPropagation();
7141
7139
  }
7142
7140
  function ContentControlDropdownItem(t0) {
@@ -7259,7 +7257,7 @@ function useFindReplace$1(hookOptions) {
7259
7257
  let t6;
7260
7258
  if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
7261
7259
  t6 = () => {
7262
- setState(_temp$7);
7260
+ setState(_temp$9);
7263
7261
  };
7264
7262
  $[8] = t6;
7265
7263
  } else t6 = $[8];
@@ -7423,7 +7421,7 @@ function _temp2$4(prev_2) {
7423
7421
  ...prev_2.dialog.status === "closed" ? openDialogState(prev_2.lastMode) : closedDialogState(prev_2.lastMode)
7424
7422
  };
7425
7423
  }
7426
- function _temp$7(prev_1) {
7424
+ function _temp$9(prev_1) {
7427
7425
  return {
7428
7426
  ...prev_1,
7429
7427
  ...closedDialogState(prev_1.lastMode)
@@ -7452,33 +7450,25 @@ function openDialogState(mode) {
7452
7450
  };
7453
7451
  }
7454
7452
  //#endregion
7455
- //#region src/components/DocumentOutline.tsx
7456
- const DocumentOutline = (t0) => {
7457
- const $ = c(21);
7458
- const { headings, scrollContainerRef, topOffset, docSize, onHeadingClick } = t0;
7459
- const OutlineRail = useFolioUI().OutlineRail;
7453
+ //#region src/components/hooks/useActiveHeading.ts
7454
+ /**
7455
+ * The heading the reader is in: the last heading whose paragraph starts above
7456
+ * the middle of the scroll viewport, tracked as the document scrolls. Shared
7457
+ * by every place the outline is drawn (column, rail, drawer), so a drawer
7458
+ * opens on the same heading the rail marks.
7459
+ */
7460
+ /** How long a jump holds the active heading before scrolling may move it. */
7461
+ const MANUAL_ACTIVE_LOCK_MS = 900;
7462
+ /** Outline item id for a heading: its ProseMirror position. */
7463
+ const headingId = (heading) => String(heading.pmPos);
7464
+ const useActiveHeading = (scrollContainerRef, headings) => {
7465
+ const $ = c(7);
7460
7466
  const [activeId, setActiveId] = useState(null);
7461
7467
  const manualLockUntil = useRef(0);
7468
+ let t0;
7462
7469
  let t1;
7463
- if ($[0] !== headings) {
7464
- t1 = headings.map(_temp$6);
7465
- $[0] = headings;
7466
- $[1] = t1;
7467
- } else t1 = $[1];
7468
- const items = t1;
7469
- let map;
7470
- if ($[2] !== docSize || $[3] !== headings) {
7471
- map = /* @__PURE__ */ new Map();
7472
- if (docSize > 0) for (const heading_0 of headings) map.set(String(heading_0.pmPos), Math.min(99, Math.max(1, heading_0.pmPos / docSize * 100)));
7473
- $[2] = docSize;
7474
- $[3] = headings;
7475
- $[4] = map;
7476
- } else map = $[4];
7477
- const pctByPmPos = map;
7478
- let t2;
7479
- let t3;
7480
- if ($[5] !== headings || $[6] !== scrollContainerRef) {
7481
- t2 = () => {
7470
+ if ($[0] !== headings || $[1] !== scrollContainerRef) {
7471
+ t0 = () => {
7482
7472
  const container = scrollContainerRef.current;
7483
7473
  if (!container || headings.length === 0) return;
7484
7474
  const compute = () => {
@@ -7496,15 +7486,11 @@ const DocumentOutline = (t0) => {
7496
7486
  top: el.getBoundingClientRect().top - containerTop + container.scrollTop
7497
7487
  });
7498
7488
  }
7499
- offsets.sort(_temp2$3);
7489
+ offsets.sort(_temp$8);
7500
7490
  let next = null;
7501
- for (const heading_1 of headings) {
7502
- let candidate;
7503
- for (const offset of offsets) if (offset.pm >= heading_1.pmPos) {
7504
- candidate = offset;
7505
- break;
7506
- }
7507
- if (candidate && candidate.top <= threshold) next = String(heading_1.pmPos);
7491
+ for (const heading of headings) {
7492
+ const candidate = offsets.find((offset) => offset.pm >= heading.pmPos);
7493
+ if (candidate && candidate.top <= threshold) next = headingId(heading);
7508
7494
  }
7509
7495
  setActiveId(next);
7510
7496
  };
@@ -7520,82 +7506,361 @@ const DocumentOutline = (t0) => {
7520
7506
  container.removeEventListener("scroll", onScroll);
7521
7507
  };
7522
7508
  };
7523
- t3 = [scrollContainerRef, headings];
7524
- $[5] = headings;
7525
- $[6] = scrollContainerRef;
7526
- $[7] = t2;
7527
- $[8] = t3;
7509
+ t1 = [scrollContainerRef, headings];
7510
+ $[0] = headings;
7511
+ $[1] = scrollContainerRef;
7512
+ $[2] = t0;
7513
+ $[3] = t1;
7528
7514
  } else {
7529
- t2 = $[7];
7530
- t3 = $[8];
7515
+ t0 = $[2];
7516
+ t1 = $[3];
7531
7517
  }
7532
- useEffect(t2, t3);
7533
- let t4;
7534
- if ($[9] !== onHeadingClick) {
7535
- t4 = (id) => {
7518
+ useEffect(t0, t1);
7519
+ let t2;
7520
+ if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
7521
+ t2 = (id) => {
7536
7522
  setActiveId(id);
7537
- manualLockUntil.current = Date.now() + 900;
7538
- onHeadingClick(Number(id));
7523
+ manualLockUntil.current = Date.now() + MANUAL_ACTIVE_LOCK_MS;
7539
7524
  };
7540
- $[9] = onHeadingClick;
7541
- $[10] = t4;
7542
- } else t4 = $[10];
7543
- const handleJump = t4;
7544
- let t5;
7545
- if ($[11] !== pctByPmPos) {
7546
- t5 = (id_0) => pctByPmPos.get(id_0) ?? null;
7547
- $[11] = pctByPmPos;
7548
- $[12] = t5;
7549
- } else t5 = $[12];
7550
- const resolvePct = t5;
7525
+ $[4] = t2;
7526
+ } else t2 = $[4];
7527
+ const markJumped = t2;
7528
+ let t3;
7529
+ if ($[5] !== activeId) {
7530
+ t3 = {
7531
+ activeId,
7532
+ markJumped
7533
+ };
7534
+ $[5] = activeId;
7535
+ $[6] = t3;
7536
+ } else t3 = $[6];
7537
+ return t3;
7538
+ };
7539
+ function _temp$8(a, b) {
7540
+ return a.pm - b.pm;
7541
+ }
7542
+ //#endregion
7543
+ //#region src/components/panelDrawer.tsx
7544
+ /**
7545
+ * The shared behaviour of a panel opened as a drawer over the page: a scrim
7546
+ * that closes it on an outside press, Escape that closes it, and focus that
7547
+ * moves into the drawer when it opens and back to where it came from when it
7548
+ * closes.
7549
+ */
7550
+ const FOCUSABLE = "button:not([disabled]), [href], input:not([disabled]), textarea:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])";
7551
+ const LIST_TAB_STOP = ":is(ol, ul) :is(button, [href], [tabindex]):not([tabindex=\"-1\"])";
7552
+ const initialFocusTarget = (container, initial) => {
7553
+ if (initial === "container") return container;
7554
+ return container.querySelector("[aria-current=\"true\"]") ?? container.querySelector(LIST_TAB_STOP) ?? container.querySelector(FOCUSABLE) ?? container;
7555
+ };
7556
+ /**
7557
+ * While `onClose` is set, `container` is an open drawer: focus moves into it,
7558
+ * Escape calls `onClose`, and once it closes focus returns to what had it
7559
+ * before, if that is still in the document.
7560
+ */
7561
+ const useDrawerFocus = (container, onClose, t0) => {
7562
+ const $ = c(8);
7563
+ const initial = t0 === void 0 ? "item" : t0;
7564
+ const onCloseRef = useRef(onClose);
7565
+ let t1;
7566
+ let t2;
7567
+ if ($[0] !== onClose) {
7568
+ t1 = () => {
7569
+ onCloseRef.current = onClose;
7570
+ };
7571
+ t2 = [onClose];
7572
+ $[0] = onClose;
7573
+ $[1] = t1;
7574
+ $[2] = t2;
7575
+ } else {
7576
+ t1 = $[1];
7577
+ t2 = $[2];
7578
+ }
7579
+ useEffect(t1, t2);
7580
+ const active = onClose !== null;
7581
+ let t3;
7582
+ let t4;
7583
+ if ($[3] !== active || $[4] !== container || $[5] !== initial) {
7584
+ t3 = () => {
7585
+ if (!active) return;
7586
+ const previous = document.activeElement instanceof HTMLElement ? document.activeElement : null;
7587
+ const element = container.current;
7588
+ if (element) initialFocusTarget(element, initial).focus({ preventScroll: true });
7589
+ const handleKeyDown = (event) => {
7590
+ if (event.key !== "Escape" || event.defaultPrevented) return;
7591
+ event.preventDefault();
7592
+ onCloseRef.current?.();
7593
+ };
7594
+ document.addEventListener("keydown", handleKeyDown);
7595
+ return () => {
7596
+ document.removeEventListener("keydown", handleKeyDown);
7597
+ if (previous?.isConnected) previous.focus({ preventScroll: true });
7598
+ };
7599
+ };
7600
+ t4 = [
7601
+ active,
7602
+ container,
7603
+ initial
7604
+ ];
7605
+ $[3] = active;
7606
+ $[4] = container;
7607
+ $[5] = initial;
7608
+ $[6] = t3;
7609
+ $[7] = t4;
7610
+ } else {
7611
+ t3 = $[6];
7612
+ t4 = $[7];
7613
+ }
7614
+ useEffect(t3, t4);
7615
+ };
7616
+ /** Dims the page under an open drawer; pressing it closes the drawer. */
7617
+ const PanelScrim = (t0) => {
7618
+ const $ = c(2);
7619
+ const { onDismiss } = t0;
7620
+ let t1;
7621
+ if ($[0] !== onDismiss) {
7622
+ t1 = /* @__PURE__ */ jsx("div", {
7623
+ "aria-hidden": "true",
7624
+ className: "folio-panel-scrim",
7625
+ "data-testid": "folio-panel-scrim",
7626
+ onMouseDown: (event) => {
7627
+ event.preventDefault();
7628
+ onDismiss();
7629
+ }
7630
+ });
7631
+ $[0] = onDismiss;
7632
+ $[1] = t1;
7633
+ } else t1 = $[1];
7634
+ return t1;
7635
+ };
7636
+ //#endregion
7637
+ //#region src/components/DocumentOutline.tsx
7638
+ const SURFACE_WIDTH = {
7639
+ column: PANEL_METRICS.outlineColumnWidth,
7640
+ rail: PANEL_METRICS.outlineRailWidth,
7641
+ drawer: PANEL_METRICS.drawerWidth
7642
+ };
7643
+ const DocumentOutline = (t0) => {
7644
+ const $ = c(55);
7645
+ const { headings, scrollContainerRef, docSize, activeId, onJump, surface, expanded, onExpand, onClose } = t0;
7646
+ const t = useTranslations("folio");
7647
+ const OutlineRail = useFolioUI().OutlineRail;
7648
+ const navRef = useRef(null);
7649
+ useDrawerFocus(navRef, surface === "drawer" && onClose ? onClose : null);
7650
+ let t1;
7651
+ if ($[0] !== headings) {
7652
+ t1 = headings.map(_temp$7);
7653
+ $[0] = headings;
7654
+ $[1] = t1;
7655
+ } else t1 = $[1];
7656
+ const items = t1;
7657
+ let map;
7658
+ if ($[2] !== docSize || $[3] !== headings) {
7659
+ map = /* @__PURE__ */ new Map();
7660
+ if (docSize > 0) for (const heading_0 of headings) map.set(headingId(heading_0), Math.min(99, Math.max(1, heading_0.pmPos / docSize * 100)));
7661
+ $[2] = docSize;
7662
+ $[3] = headings;
7663
+ $[4] = map;
7664
+ } else map = $[4];
7665
+ const pctById = map;
7666
+ let t2;
7667
+ if ($[5] !== onClose || $[6] !== onJump || $[7] !== surface) {
7668
+ t2 = (id) => {
7669
+ onJump(id);
7670
+ if (surface === "drawer") onClose?.();
7671
+ };
7672
+ $[5] = onClose;
7673
+ $[6] = onJump;
7674
+ $[7] = surface;
7675
+ $[8] = t2;
7676
+ } else t2 = $[8];
7677
+ const handleJump = t2;
7678
+ let t3;
7679
+ if ($[9] !== pctById) {
7680
+ t3 = (id_0) => pctById.get(id_0) ?? null;
7681
+ $[9] = pctById;
7682
+ $[10] = t3;
7683
+ } else t3 = $[10];
7684
+ const resolvePct = t3;
7551
7685
  if (headings.length < 2) return null;
7686
+ let t4;
7687
+ if ($[11] !== t) {
7688
+ t4 = t("editor.showDocumentOutline");
7689
+ $[11] = t;
7690
+ $[12] = t4;
7691
+ } else t4 = $[12];
7692
+ const outlineLabel = t4;
7693
+ const width = SURFACE_WIDTH[surface];
7694
+ const t5 = surface === "rail" ? "rail" : "panel";
7552
7695
  let t6;
7553
- if ($[13] !== OutlineRail || $[14] !== activeId || $[15] !== handleJump || $[16] !== items || $[17] !== resolvePct || $[18] !== scrollContainerRef || $[19] !== topOffset) {
7696
+ if ($[13] !== OutlineRail || $[14] !== activeId || $[15] !== handleJump || $[16] !== items || $[17] !== outlineLabel || $[18] !== resolvePct || $[19] !== scrollContainerRef || $[20] !== t5 || $[21] !== width) {
7554
7697
  t6 = /* @__PURE__ */ jsx(OutlineRail, {
7555
7698
  activeId,
7556
- ariaLabel: "Document outline",
7699
+ ariaLabel: outlineLabel,
7557
7700
  items,
7558
7701
  onJump: handleJump,
7559
- panelWidth: 320,
7702
+ panelWidth: width,
7703
+ presentation: t5,
7560
7704
  resolvePct,
7561
7705
  scrollContainerRef,
7562
- topOffset
7706
+ topOffset: 0
7563
7707
  });
7564
7708
  $[13] = OutlineRail;
7565
7709
  $[14] = activeId;
7566
7710
  $[15] = handleJump;
7567
7711
  $[16] = items;
7568
- $[17] = resolvePct;
7569
- $[18] = scrollContainerRef;
7570
- $[19] = topOffset;
7571
- $[20] = t6;
7572
- } else t6 = $[20];
7573
- return t6;
7712
+ $[17] = outlineLabel;
7713
+ $[18] = resolvePct;
7714
+ $[19] = scrollContainerRef;
7715
+ $[20] = t5;
7716
+ $[21] = width;
7717
+ $[22] = t6;
7718
+ } else t6 = $[22];
7719
+ const rail = t6;
7720
+ if (surface === "rail") {
7721
+ let t7;
7722
+ if ($[23] !== width) {
7723
+ t7 = { width };
7724
+ $[23] = width;
7725
+ $[24] = t7;
7726
+ } else t7 = $[24];
7727
+ const t8 = expanded ?? false;
7728
+ let t9;
7729
+ if ($[25] === Symbol.for("react.memo_cache_sentinel")) {
7730
+ t9 = /* @__PURE__ */ jsx(PanelLeftOpenIcon, {
7731
+ "aria-hidden": "true",
7732
+ size: 16
7733
+ });
7734
+ $[25] = t9;
7735
+ } else t9 = $[25];
7736
+ let t10;
7737
+ if ($[26] !== onExpand || $[27] !== outlineLabel || $[28] !== t8) {
7738
+ t10 = /* @__PURE__ */ jsx("button", {
7739
+ "aria-expanded": t8,
7740
+ "aria-label": outlineLabel,
7741
+ className: "folio-outline-icon-button",
7742
+ "data-testid": "folio-outline-expand",
7743
+ onClick: onExpand,
7744
+ title: outlineLabel,
7745
+ type: "button",
7746
+ children: t9
7747
+ });
7748
+ $[26] = onExpand;
7749
+ $[27] = outlineLabel;
7750
+ $[28] = t8;
7751
+ $[29] = t10;
7752
+ } else t10 = $[29];
7753
+ let t11;
7754
+ if ($[30] !== outlineLabel || $[31] !== rail || $[32] !== t10 || $[33] !== t7) {
7755
+ t11 = /* @__PURE__ */ jsxs("nav", {
7756
+ "aria-label": outlineLabel,
7757
+ className: "folio-outline folio-outline--rail",
7758
+ "data-testid": "folio-outline",
7759
+ "data-folio-outline-surface": "rail",
7760
+ style: t7,
7761
+ children: [t10, rail]
7762
+ });
7763
+ $[30] = outlineLabel;
7764
+ $[31] = rail;
7765
+ $[32] = t10;
7766
+ $[33] = t7;
7767
+ $[34] = t11;
7768
+ } else t11 = $[34];
7769
+ return t11;
7770
+ }
7771
+ const t7 = `folio-outline folio-outline--${surface}`;
7772
+ let t8;
7773
+ if ($[35] !== width) {
7774
+ t8 = { width };
7775
+ $[35] = width;
7776
+ $[36] = t8;
7777
+ } else t8 = $[36];
7778
+ let t9;
7779
+ if ($[37] !== t) {
7780
+ t9 = t("editor.outlineTitle");
7781
+ $[37] = t;
7782
+ $[38] = t9;
7783
+ } else t9 = $[38];
7784
+ let t10;
7785
+ if ($[39] !== t9) {
7786
+ t10 = /* @__PURE__ */ jsx("span", {
7787
+ className: "folio-outline-title",
7788
+ children: t9
7789
+ });
7790
+ $[39] = t9;
7791
+ $[40] = t10;
7792
+ } else t10 = $[40];
7793
+ let t11;
7794
+ if ($[41] !== onClose || $[42] !== surface || $[43] !== t) {
7795
+ t11 = surface === "drawer" && onClose && /* @__PURE__ */ jsx("button", {
7796
+ "aria-label": t("common.closeDialog"),
7797
+ className: "folio-outline-icon-button",
7798
+ onClick: onClose,
7799
+ title: t("common.closeDialog"),
7800
+ type: "button",
7801
+ children: /* @__PURE__ */ jsx(XIcon, {
7802
+ "aria-hidden": "true",
7803
+ size: 16
7804
+ })
7805
+ });
7806
+ $[41] = onClose;
7807
+ $[42] = surface;
7808
+ $[43] = t;
7809
+ $[44] = t11;
7810
+ } else t11 = $[44];
7811
+ let t12;
7812
+ if ($[45] !== t10 || $[46] !== t11) {
7813
+ t12 = /* @__PURE__ */ jsxs("div", {
7814
+ className: "folio-outline-header",
7815
+ children: [t10, t11]
7816
+ });
7817
+ $[45] = t10;
7818
+ $[46] = t11;
7819
+ $[47] = t12;
7820
+ } else t12 = $[47];
7821
+ let t13;
7822
+ if ($[48] !== outlineLabel || $[49] !== rail || $[50] !== surface || $[51] !== t12 || $[52] !== t7 || $[53] !== t8) {
7823
+ t13 = /* @__PURE__ */ jsxs("nav", {
7824
+ ref: navRef,
7825
+ "aria-label": outlineLabel,
7826
+ className: t7,
7827
+ "data-testid": "folio-outline",
7828
+ "data-folio-outline-surface": surface,
7829
+ style: t8,
7830
+ children: [t12, rail]
7831
+ });
7832
+ $[48] = outlineLabel;
7833
+ $[49] = rail;
7834
+ $[50] = surface;
7835
+ $[51] = t12;
7836
+ $[52] = t7;
7837
+ $[53] = t8;
7838
+ $[54] = t13;
7839
+ } else t13 = $[54];
7840
+ return t13;
7574
7841
  };
7575
- function _temp$6(heading) {
7842
+ function _temp$7(heading) {
7576
7843
  const item = {
7577
- id: String(heading.pmPos),
7844
+ id: headingId(heading),
7578
7845
  label: heading.text,
7579
7846
  level: heading.level
7580
7847
  };
7581
7848
  if (typeof heading.pageNumber === "number") item.meta = String(heading.pageNumber);
7582
7849
  return item;
7583
7850
  }
7584
- function _temp2$3(a, b) {
7585
- return a.pm - b.pm;
7586
- }
7587
7851
  //#endregion
7588
7852
  //#region src/components/DocxEditorDialogs.tsx
7589
- const FindReplaceDialog = lazy(() => import("./FindReplaceDialog-CqKK82nE.js").then((n) => n.n).then((m) => ({ default: m.FindReplaceDialog })));
7590
- const TablePropertiesDialog = lazy(() => import("./TablePropertiesDialog-DOUiX1KZ.js").then((n) => n.n).then((m) => ({ default: m.TablePropertiesDialog })));
7591
- const ImagePositionDialog = lazy(() => import("./ImagePositionDialog-DNodkoI2.js").then((n) => n.n).then((m) => ({ default: m.ImagePositionDialog })));
7592
- const ImagePropertiesDialog = lazy(() => import("./ImagePropertiesDialog-CLsDIUWb.js").then((n) => n.n).then((m) => ({ default: m.ImagePropertiesDialog })));
7593
- const FootnotePropertiesDialog = lazy(() => import("./FootnotePropertiesDialog-CixRdIiT.js").then((n) => n.n).then((m) => ({ default: m.FootnotePropertiesDialog })));
7594
- const PageSetupDialog = lazy(() => import("./PageSetupDialog-COkgeOQn.js").then((n) => n.n).then((m) => ({ default: m.PageSetupDialog })));
7595
- const InsertSymbolDialog = lazy(() => import("./InsertSymbolDialog-DCFLmfzn.js").then((n) => n.n).then((m) => ({ default: m.InsertSymbolDialog })));
7853
+ const FindReplaceDialog = lazy(() => import("./FindReplaceDialog-BUwFQWaq.js").then((n) => n.n).then((m) => ({ default: m.FindReplaceDialog })));
7854
+ const TablePropertiesDialog = lazy(() => import("./TablePropertiesDialog-DwPiUj4m.js").then((n) => n.n).then((m) => ({ default: m.TablePropertiesDialog })));
7855
+ const ImagePositionDialog = lazy(() => import("./ImagePositionDialog-9q71ka9N.js").then((n) => n.n).then((m) => ({ default: m.ImagePositionDialog })));
7856
+ const ImagePropertiesDialog = lazy(() => import("./ImagePropertiesDialog-o79NCGk7.js").then((n) => n.n).then((m) => ({ default: m.ImagePropertiesDialog })));
7857
+ const FootnotePropertiesDialog = lazy(() => import("./FootnotePropertiesDialog-6XdO0zBH.js").then((n) => n.n).then((m) => ({ default: m.FootnotePropertiesDialog })));
7858
+ const PageSetupDialog = lazy(() => import("./PageSetupDialog-CMdVXCZ-.js").then((n) => n.n).then((m) => ({ default: m.PageSetupDialog })));
7859
+ const SetNumberingValueDialog = lazy(() => import("./SetNumberingValueDialog-DOsaSq7e.js").then((m) => ({ default: m.SetNumberingValueDialog })));
7860
+ const InsertSymbolDialog = lazy(() => import("./InsertSymbolDialog-Cn_Nifhg.js").then((n) => n.n).then((m) => ({ default: m.InsertSymbolDialog })));
7596
7861
  function DocxEditorDialogs(t0) {
7597
- const $ = c(47);
7598
- const { findReplace, tableProperties, imagePosition, imageProperties, pageSetup, footnoteProperties, insertSymbol } = t0;
7862
+ const $ = c(52);
7863
+ const { findReplace, tableProperties, imagePosition, imageProperties, pageSetup, footnoteProperties, insertSymbol, setNumberingValue } = t0;
7599
7864
  let t1;
7600
7865
  if ($[0] !== findReplace.currentResult || $[1] !== findReplace.onClose || $[2] !== findReplace.onFind || $[3] !== findReplace.onFindNext || $[4] !== findReplace.onFindPrevious || $[5] !== findReplace.onReplace || $[6] !== findReplace.onReplaceAll || $[7] !== findReplace.state.dialog.status || $[8] !== findReplace.state.searchText) {
7601
7866
  t1 = findReplace.state.dialog.status === "open" && /* @__PURE__ */ jsx(FindReplaceDialog, {
@@ -7703,8 +7968,20 @@ function DocxEditorDialogs(t0) {
7703
7968
  $[38] = t7;
7704
7969
  } else t7 = $[38];
7705
7970
  let t8;
7706
- if ($[39] !== t1 || $[40] !== t2 || $[41] !== t3 || $[42] !== t4 || $[43] !== t5 || $[44] !== t6 || $[45] !== t7) {
7707
- t8 = /* @__PURE__ */ jsxs(Suspense, {
7971
+ if ($[39] !== setNumberingValue.isOpen || $[40] !== setNumberingValue.onApply || $[41] !== setNumberingValue.onClose) {
7972
+ t8 = setNumberingValue.isOpen && /* @__PURE__ */ jsx(SetNumberingValueDialog, {
7973
+ isOpen: setNumberingValue.isOpen,
7974
+ onClose: setNumberingValue.onClose,
7975
+ onApply: setNumberingValue.onApply
7976
+ });
7977
+ $[39] = setNumberingValue.isOpen;
7978
+ $[40] = setNumberingValue.onApply;
7979
+ $[41] = setNumberingValue.onClose;
7980
+ $[42] = t8;
7981
+ } else t8 = $[42];
7982
+ let t9;
7983
+ if ($[43] !== t1 || $[44] !== t2 || $[45] !== t3 || $[46] !== t4 || $[47] !== t5 || $[48] !== t6 || $[49] !== t7 || $[50] !== t8) {
7984
+ t9 = /* @__PURE__ */ jsxs(Suspense, {
7708
7985
  fallback: null,
7709
7986
  children: [
7710
7987
  t1,
@@ -7713,19 +7990,21 @@ function DocxEditorDialogs(t0) {
7713
7990
  t4,
7714
7991
  t5,
7715
7992
  t6,
7716
- t7
7993
+ t7,
7994
+ t8
7717
7995
  ]
7718
7996
  });
7719
- $[39] = t1;
7720
- $[40] = t2;
7721
- $[41] = t3;
7722
- $[42] = t4;
7723
- $[43] = t5;
7724
- $[44] = t6;
7725
- $[45] = t7;
7726
- $[46] = t8;
7727
- } else t8 = $[46];
7728
- return t8;
7997
+ $[43] = t1;
7998
+ $[44] = t2;
7999
+ $[45] = t3;
8000
+ $[46] = t4;
8001
+ $[47] = t5;
8002
+ $[48] = t6;
8003
+ $[49] = t7;
8004
+ $[50] = t8;
8005
+ $[51] = t9;
8006
+ } else t9 = $[51];
8007
+ return t9;
7729
8008
  }
7730
8009
  //#endregion
7731
8010
  //#region src/components/DocxEditorHelpers.tsx
@@ -7954,7 +8233,7 @@ function NotificationContainer(t0) {
7954
8233
  if ($[0] !== notifications || $[1] !== onDismiss) {
7955
8234
  t3 = Symbol.for("react.early_return_sentinel");
7956
8235
  bb0: {
7957
- const visibleNotifications = notifications.filter(_temp$5);
8236
+ const visibleNotifications = notifications.filter(_temp$6);
7958
8237
  if (visibleNotifications.length === 0) {
7959
8238
  t3 = null;
7960
8239
  break bb0;
@@ -7994,7 +8273,7 @@ function NotificationContainer(t0) {
7994
8273
  } else t4 = $[9];
7995
8274
  return t4;
7996
8275
  }
7997
- function _temp$5(n) {
8276
+ function _temp$6(n) {
7998
8277
  return !n.dismissed;
7999
8278
  }
8000
8279
  const SEVERITY_STYLES = {
@@ -8436,7 +8715,7 @@ function AlignmentButtons({ value = "left", onChange, disabled = false }) {
8436
8715
  function AlignmentOption(t0) {
8437
8716
  const $ = c(16);
8438
8717
  const { PopoverClose, option, selected, onChange } = t0;
8439
- const handleMouseDown = _temp$4;
8718
+ const handleMouseDown = _temp$5;
8440
8719
  let t1;
8441
8720
  if ($[0] !== onChange || $[1] !== option.value) {
8442
8721
  t1 = () => onChange?.(option.value);
@@ -8490,7 +8769,7 @@ function AlignmentOption(t0) {
8490
8769
  } else t8 = $[15];
8491
8770
  return t8;
8492
8771
  }
8493
- function _temp$4(event) {
8772
+ function _temp$5(event) {
8494
8773
  return event.preventDefault();
8495
8774
  }
8496
8775
  //#endregion
@@ -9082,7 +9361,7 @@ const DOCUMENT_COLOR_PRESETS = [
9082
9361
  }
9083
9362
  ];
9084
9363
  function FormattingBar(props) {
9085
- const { currentFormatting = {}, onFormat, onUndo, onRedo, canUndo = false, canRedo = false, disabled = false, className, style, enableShortcuts = true, editorRef, children, showStylePicker = true, showFormatPainter = true, formatPainterActive = false, onFormatPainter, showFontPicker = true, fontFamilies, showFontSizePicker = true, showTextColorPicker = true, showAlignmentButtons = true, showListButtons = true, showZoomControl, zoom, onZoomChange, rulerVisible = false, onToggleRuler, documentStyles, theme, onRefocusEditor, onInsertImage, onInsertTable, showTableInsert = true, onInsertPageBreak, onInsertTOC, onInsertSymbol, priorityExtra, inlineExtra, stylePickerLabel, stylePickerLabelStyle, inline = false } = props;
9364
+ const { currentFormatting = {}, onFormat, onUndo, onRedo, canUndo = false, canRedo = false, disabled = false, className, style, enableShortcuts = true, editorRef, children, showStylePicker = true, showFormatPainter = true, formatPainterActive = false, onFormatPainter, showFontPicker = true, fontFamilies, showFontSizePicker = true, showTextColorPicker = true, showAlignmentButtons = true, showListButtons = true, showZoomControl, zoom, onZoomChange, rulerVisible = false, onToggleRuler, documentStyles, theme, onRefocusEditor, onInsertImage, onInsertTable, showTableInsert = true, onInsertPageBreak, onInsertTOC, onInsertSymbol, priorityExtra, inlineExtra, panelToggles, stylePickerLabel, stylePickerLabelStyle, inline = false } = props;
9086
9365
  const folioUI = useFolioUI();
9087
9366
  const { Root: Menu, Trigger: MenuTrigger, Popup: MenuPopup } = folioUI.Menu;
9088
9367
  const ColorPicker = folioUI.ColorPicker;
@@ -9640,6 +9919,7 @@ function FormattingBar(props) {
9640
9919
  /* @__PURE__ */ jsxs("div", {
9641
9920
  className: "ms-auto flex shrink-0 items-center gap-1",
9642
9921
  children: [
9922
+ panelToggles,
9643
9923
  onToggleRuler && /* @__PURE__ */ jsx(ToolbarGroup, {
9644
9924
  label: t("viewGroup"),
9645
9925
  children: /* @__PURE__ */ jsx(ToolbarButton, {
@@ -10302,8 +10582,8 @@ const useHyperlinkHandlers = (t0) => {
10302
10582
  $[0] = t1;
10303
10583
  } else t1 = $[0];
10304
10584
  const handleHyperlinkClick = t1;
10305
- const handleHyperlinkPopupNavigate = _temp$3;
10306
- const handleHyperlinkPopupCopy = _temp2$2;
10585
+ const handleHyperlinkPopupNavigate = _temp$4;
10586
+ const handleHyperlinkPopupCopy = _temp2$3;
10307
10587
  let t2;
10308
10588
  if ($[1] !== focusActiveEditor || $[2] !== getActiveEditorView) {
10309
10589
  t2 = (displayText, href_1) => {
@@ -10364,14 +10644,14 @@ const useHyperlinkHandlers = (t0) => {
10364
10644
  } else t5 = $[12];
10365
10645
  return t5;
10366
10646
  };
10367
- function _temp$3(href) {
10647
+ function _temp$4(href) {
10368
10648
  const safeHref = sanitizeExternalUrl(href);
10369
10649
  if (safeHref) {
10370
10650
  const anchor = anchorTargetAttrs(void 0);
10371
10651
  window.open(safeHref, anchor.target, windowFeaturesFor(anchor));
10372
10652
  }
10373
10653
  }
10374
- function _temp2$2(href_0) {
10654
+ function _temp2$3(href_0) {
10375
10655
  navigator.clipboard.writeText(href_0);
10376
10656
  }
10377
10657
  //#endregion
@@ -10388,7 +10668,7 @@ const useImageHandlers = (t0) => {
10388
10668
  if (!file) return;
10389
10669
  const view = getActiveEditorView();
10390
10670
  if (!view) return;
10391
- insertImageFromFile(view, file, focusActiveEditor).catch(_temp$2);
10671
+ insertImageFromFile(view, file, focusActiveEditor).catch(_temp$3);
10392
10672
  e.target.value = "";
10393
10673
  };
10394
10674
  $[0] = focusActiveEditor;
@@ -10481,7 +10761,7 @@ const useImageHandlers = (t0) => {
10481
10761
  } else t7 = $[27];
10482
10762
  return t7;
10483
10763
  };
10484
- function _temp$2() {}
10764
+ function _temp$3() {}
10485
10765
  //#endregion
10486
10766
  //#region src/components/hooks/useKeyboardShortcuts.ts
10487
10767
  /**
@@ -10564,6 +10844,114 @@ function useKeyboardShortcuts({ pagedEditorRef, findReplace, tableSelection, onD
10564
10844
  }, [pagedEditorRef, scope]);
10565
10845
  }
10566
10846
  //#endregion
10847
+ //#region src/components/hooks/usePanelLayout.ts
10848
+ /**
10849
+ * Measures the width the editor's panels row has and decides, through
10850
+ * {@link computePanelLayout}, how the outline and the comments are shown.
10851
+ * One ResizeObserver feeds it; the scroll gutter, the ruler offset and the
10852
+ * page centring all read the result, so they agree with what is on screen.
10853
+ */
10854
+ const usePanelLayout = (t0) => {
10855
+ const $ = c(22);
10856
+ const { pageWidth, outline, comments, scrollContainerRef } = t0;
10857
+ const [row, setRow] = useState(null);
10858
+ const [availableWidth, setAvailableWidth] = useState(Number.POSITIVE_INFINITY);
10859
+ const [overlay, setOverlay] = useState("none");
10860
+ let t1;
10861
+ let t2;
10862
+ if ($[0] !== row || $[1] !== scrollContainerRef) {
10863
+ t1 = () => {
10864
+ if (!row) return;
10865
+ const measure = () => {
10866
+ const scroll = scrollContainerRef.current;
10867
+ const scrollbar = scroll ? scroll.offsetWidth - scroll.clientWidth : 0;
10868
+ setAvailableWidth(Math.max(0, row.clientWidth - scrollbar));
10869
+ };
10870
+ measure();
10871
+ const observer = new ResizeObserver(measure);
10872
+ observer.observe(row);
10873
+ if (scrollContainerRef.current) observer.observe(scrollContainerRef.current);
10874
+ return () => observer.disconnect();
10875
+ };
10876
+ t2 = [row, scrollContainerRef];
10877
+ $[0] = row;
10878
+ $[1] = scrollContainerRef;
10879
+ $[2] = t1;
10880
+ $[3] = t2;
10881
+ } else {
10882
+ t1 = $[2];
10883
+ t2 = $[3];
10884
+ }
10885
+ useLayoutEffect(t1, t2);
10886
+ let t3;
10887
+ if ($[4] !== availableWidth || $[5] !== comments || $[6] !== outline || $[7] !== pageWidth) {
10888
+ t3 = computePanelLayout({
10889
+ availableWidth,
10890
+ pageWidth,
10891
+ outline,
10892
+ comments
10893
+ });
10894
+ $[4] = availableWidth;
10895
+ $[5] = comments;
10896
+ $[6] = outline;
10897
+ $[7] = pageWidth;
10898
+ $[8] = t3;
10899
+ } else t3 = $[8];
10900
+ const layout = t3;
10901
+ const outlineDrawn = layout.outline === "rail" || layout.outline === "drawer";
10902
+ const commentsDrawn = layout.comments === "drawer";
10903
+ let t4;
10904
+ let t5;
10905
+ if ($[9] !== commentsDrawn || $[10] !== outlineDrawn || $[11] !== overlay) {
10906
+ t4 = () => {
10907
+ if (overlay === "outline" && !outlineDrawn || overlay === "comments" && !commentsDrawn) setOverlay("none");
10908
+ };
10909
+ t5 = [
10910
+ commentsDrawn,
10911
+ outlineDrawn,
10912
+ overlay
10913
+ ];
10914
+ $[9] = commentsDrawn;
10915
+ $[10] = outlineDrawn;
10916
+ $[11] = overlay;
10917
+ $[12] = t4;
10918
+ $[13] = t5;
10919
+ } else {
10920
+ t4 = $[12];
10921
+ t5 = $[13];
10922
+ }
10923
+ useEffect(t4, t5);
10924
+ let t6;
10925
+ if ($[14] !== availableWidth || $[15] !== outline || $[16] !== pageWidth) {
10926
+ t6 = () => computePanelLayout({
10927
+ availableWidth,
10928
+ pageWidth,
10929
+ outline,
10930
+ comments: "open"
10931
+ });
10932
+ $[14] = availableWidth;
10933
+ $[15] = outline;
10934
+ $[16] = pageWidth;
10935
+ $[17] = t6;
10936
+ } else t6 = $[17];
10937
+ const layoutWithCommentsOpen = t6;
10938
+ let t7;
10939
+ if ($[18] !== layout || $[19] !== layoutWithCommentsOpen || $[20] !== overlay) {
10940
+ t7 = {
10941
+ rowRef: setRow,
10942
+ layout,
10943
+ overlay,
10944
+ setOverlay,
10945
+ layoutWithCommentsOpen
10946
+ };
10947
+ $[18] = layout;
10948
+ $[19] = layoutWithCommentsOpen;
10949
+ $[20] = overlay;
10950
+ $[21] = t7;
10951
+ } else t7 = $[21];
10952
+ return t7;
10953
+ };
10954
+ //#endregion
10567
10955
  //#region src/components/hooks/useZoomAndPageInfo.ts
10568
10956
  const PAGE_INFO_FADE_MS = 600;
10569
10957
  const FIT_TO_WIDTH_PADDING_PX = 16;
@@ -11146,7 +11534,7 @@ function OptionsMenu(t0) {
11146
11534
  if ($[3] !== setShowOptions) {
11147
11535
  t3 = (e) => {
11148
11536
  e.stopPropagation();
11149
- setShowOptions(_temp$1);
11537
+ setShowOptions(_temp$2);
11150
11538
  };
11151
11539
  $[3] = setShowOptions;
11152
11540
  $[4] = t3;
@@ -11163,7 +11551,7 @@ function OptionsMenu(t0) {
11163
11551
  type: "button",
11164
11552
  className: "hf-options-button",
11165
11553
  onClick: t3,
11166
- onMouseDown: _temp2$1,
11554
+ onMouseDown: _temp2$2,
11167
11555
  children: [t4, " ▾"]
11168
11556
  });
11169
11557
  $[7] = t3;
@@ -11237,49 +11625,17 @@ function OptionsMenu(t0) {
11237
11625
  } else t7 = $[21];
11238
11626
  return t7;
11239
11627
  }
11240
- function _temp2$1(e_0) {
11628
+ function _temp2$2(e_0) {
11241
11629
  return e_0.stopPropagation();
11242
11630
  }
11243
- function _temp$1(prev) {
11631
+ function _temp$2(prev) {
11244
11632
  return !prev;
11245
11633
  }
11246
11634
  //#endregion
11247
- //#region src/components/selectionFormattingBuilder.ts
11635
+ //#region src/components/toolbarUtils.ts
11248
11636
  /**
11249
- * Assemble the `SelectionFormatting` object the toolbar consumes.
11250
- *
11251
- * Several fields are `?: T` (no `| undefined`) under
11252
- * `exactOptionalPropertyTypes`, so we only assign them when the source
11253
- * value is defined — assigning `undefined` would be a type error. Pure
11254
- * (no DOM, no PM state mutation).
11255
- */
11256
- function buildSelectionFormatting({ selectionState, fontFamily, fontSize, textColor, listState }) {
11257
- const { textFormatting, paragraphFormatting } = selectionState;
11258
- const formatting = {
11259
- underline: !!textFormatting.underline,
11260
- superscript: textFormatting.vertAlign === "superscript",
11261
- subscript: textFormatting.vertAlign === "subscript",
11262
- bidi: !!paragraphFormatting.bidi
11263
- };
11264
- if (textFormatting.bold !== void 0) formatting.bold = textFormatting.bold;
11265
- if (textFormatting.italic !== void 0) formatting.italic = textFormatting.italic;
11266
- if (textFormatting.strike !== void 0) formatting.strike = textFormatting.strike;
11267
- if (fontFamily !== void 0) formatting.fontFamily = fontFamily;
11268
- if (fontSize !== void 0) formatting.fontSize = fontSize;
11269
- if (textColor !== void 0) formatting.color = textColor;
11270
- if (textFormatting.highlight !== void 0) formatting.highlight = textFormatting.highlight;
11271
- if (paragraphFormatting.alignment !== void 0) formatting.alignment = paragraphFormatting.alignment;
11272
- if (paragraphFormatting.lineSpacing !== void 0) formatting.lineSpacing = paragraphFormatting.lineSpacing;
11273
- if (listState !== void 0) formatting.listState = listState;
11274
- if (selectionState.styleId !== null) formatting.styleId = selectionState.styleId;
11275
- if (paragraphFormatting.indentLeft !== void 0) formatting.indentLeft = paragraphFormatting.indentLeft;
11276
- return formatting;
11277
- }
11278
- //#endregion
11279
- //#region src/components/toolbarUtils.ts
11280
- /**
11281
- * Map hex color to OOXML highlight color name
11282
- * OOXML uses named colors for highlights (yellow, green, cyan, etc.)
11637
+ * Map hex color to OOXML highlight color name
11638
+ * OOXML uses named colors for highlights (yellow, green, cyan, etc.)
11283
11639
  */
11284
11640
  const HIGHLIGHT_HEX_TO_NAME = {
11285
11641
  FFFF00: "yellow",
@@ -11317,6 +11673,163 @@ function areSelectionFormattingEqual(a, b) {
11317
11673
  return a.bold === b.bold && a.italic === b.italic && a.underline === b.underline && a.strike === b.strike && a.superscript === b.superscript && a.subscript === b.subscript && a.fontFamily === b.fontFamily && a.fontSize === b.fontSize && a.color === b.color && a.highlight === b.highlight && a.alignment === b.alignment && a.lineSpacing === b.lineSpacing && sameListState(a.listState, b.listState) && a.styleId === b.styleId && a.indentLeft === b.indentLeft && a.bidi === b.bidi;
11318
11674
  }
11319
11675
  //#endregion
11676
+ //#region src/components/PanelToggles.tsx
11677
+ /**
11678
+ * Toolbar toggles for the editor's side panels, pinned at the end of the
11679
+ * toolbar so they never collapse into its overflow menu:
11680
+ *
11681
+ * - the outline, shown only while the outline is a drawer (in wider tiers it
11682
+ * has a column or a rail of its own);
11683
+ * - the comments, with the number of open threads as a badge.
11684
+ */
11685
+ /** Counts above this read as "99+". */
11686
+ const MAX_BADGE_COUNT = 99;
11687
+ function PanelToggles(t0) {
11688
+ const $ = c(27);
11689
+ const { outline, onToggleOutline, commentsShown, commentCount, onToggleComments } = t0;
11690
+ const t = useTranslations("folio");
11691
+ const format = useFormatter();
11692
+ let t1;
11693
+ if ($[0] !== t) {
11694
+ t1 = t("comments.visibility");
11695
+ $[0] = t;
11696
+ $[1] = t1;
11697
+ } else t1 = $[1];
11698
+ const commentsLabel = t1;
11699
+ let t2;
11700
+ if ($[2] !== commentCount || $[3] !== format) {
11701
+ t2 = commentCount > MAX_BADGE_COUNT ? `${format.number(MAX_BADGE_COUNT)}+` : format.number(commentCount);
11702
+ $[2] = commentCount;
11703
+ $[3] = format;
11704
+ $[4] = t2;
11705
+ } else t2 = $[4];
11706
+ const badge = t2;
11707
+ let t3;
11708
+ if ($[5] !== onToggleOutline || $[6] !== outline || $[7] !== t) {
11709
+ t3 = outline !== "absent" && /* @__PURE__ */ jsx(ToolbarButton, {
11710
+ active: outline === "open",
11711
+ ariaLabel: t("editor.showDocumentOutline"),
11712
+ onClick: onToggleOutline,
11713
+ testId: "toolbar-outline-toggle",
11714
+ title: t("editor.showDocumentOutline"),
11715
+ children: /* @__PURE__ */ jsx(ListTreeIcon, { size: 16 })
11716
+ });
11717
+ $[5] = onToggleOutline;
11718
+ $[6] = outline;
11719
+ $[7] = t;
11720
+ $[8] = t3;
11721
+ } else t3 = $[8];
11722
+ const t4 = commentsShown && "bg-[var(--doc-primary-light)] text-[var(--doc-text)]";
11723
+ let t5;
11724
+ if ($[9] !== t4) {
11725
+ t5 = cn("flex h-8 min-w-8 shrink-0 items-center justify-center gap-1 rounded-md px-1.5", "transition-colors duration-100", "text-[var(--doc-text-muted)] hover:bg-[var(--doc-primary-light)] hover:text-[var(--doc-text)]", t4);
11726
+ $[9] = t4;
11727
+ $[10] = t5;
11728
+ } else t5 = $[10];
11729
+ let t6;
11730
+ if ($[11] === Symbol.for("react.memo_cache_sentinel")) {
11731
+ t6 = /* @__PURE__ */ jsx(MessageSquareTextIcon, {
11732
+ "aria-hidden": "true",
11733
+ size: 16
11734
+ });
11735
+ $[11] = t6;
11736
+ } else t6 = $[11];
11737
+ let t7;
11738
+ if ($[12] !== commentsLabel) {
11739
+ t7 = /* @__PURE__ */ jsx("span", {
11740
+ className: "sr-only",
11741
+ children: commentsLabel
11742
+ });
11743
+ $[12] = commentsLabel;
11744
+ $[13] = t7;
11745
+ } else t7 = $[13];
11746
+ let t8;
11747
+ if ($[14] !== badge || $[15] !== commentCount) {
11748
+ t8 = commentCount > 0 && /* @__PURE__ */ jsx("span", {
11749
+ className: "min-w-4 rounded-full bg-[var(--doc-primary)] px-1 text-center text-[10px] leading-4 font-semibold text-[var(--primary-foreground,var(--doc-page))] tabular-nums",
11750
+ "data-testid": "toolbar-comments-count",
11751
+ children: badge
11752
+ });
11753
+ $[14] = badge;
11754
+ $[15] = commentCount;
11755
+ $[16] = t8;
11756
+ } else t8 = $[16];
11757
+ let t9;
11758
+ if ($[17] !== commentsLabel || $[18] !== commentsShown || $[19] !== onToggleComments || $[20] !== t5 || $[21] !== t7 || $[22] !== t8) {
11759
+ t9 = /* @__PURE__ */ jsxs("button", {
11760
+ "aria-pressed": commentsShown,
11761
+ className: t5,
11762
+ "data-testid": "toolbar-comments-toggle",
11763
+ onClick: onToggleComments,
11764
+ onMouseDown: _temp2$1,
11765
+ title: commentsLabel,
11766
+ type: "button",
11767
+ children: [
11768
+ t6,
11769
+ t7,
11770
+ t8
11771
+ ]
11772
+ });
11773
+ $[17] = commentsLabel;
11774
+ $[18] = commentsShown;
11775
+ $[19] = onToggleComments;
11776
+ $[20] = t5;
11777
+ $[21] = t7;
11778
+ $[22] = t8;
11779
+ $[23] = t9;
11780
+ } else t9 = $[23];
11781
+ let t10;
11782
+ if ($[24] !== t3 || $[25] !== t9) {
11783
+ t10 = /* @__PURE__ */ jsxs("div", {
11784
+ className: "flex shrink-0 items-center gap-0.5",
11785
+ onMouseUp: _temp$1,
11786
+ children: [t3, t9]
11787
+ });
11788
+ $[24] = t3;
11789
+ $[25] = t9;
11790
+ $[26] = t10;
11791
+ } else t10 = $[26];
11792
+ return t10;
11793
+ }
11794
+ function _temp2$1(event_0) {
11795
+ return event_0.preventDefault();
11796
+ }
11797
+ function _temp$1(event) {
11798
+ return event.stopPropagation();
11799
+ }
11800
+ //#endregion
11801
+ //#region src/components/selectionFormattingBuilder.ts
11802
+ /**
11803
+ * Assemble the `SelectionFormatting` object the toolbar consumes.
11804
+ *
11805
+ * Several fields are `?: T` (no `| undefined`) under
11806
+ * `exactOptionalPropertyTypes`, so we only assign them when the source
11807
+ * value is defined — assigning `undefined` would be a type error. Pure
11808
+ * (no DOM, no PM state mutation).
11809
+ */
11810
+ function buildSelectionFormatting({ selectionState, fontFamily, fontSize, textColor, listState }) {
11811
+ const { textFormatting, paragraphFormatting } = selectionState;
11812
+ const formatting = {
11813
+ underline: !!textFormatting.underline,
11814
+ superscript: textFormatting.vertAlign === "superscript",
11815
+ subscript: textFormatting.vertAlign === "subscript",
11816
+ bidi: !!paragraphFormatting.bidi
11817
+ };
11818
+ if (textFormatting.bold !== void 0) formatting.bold = textFormatting.bold;
11819
+ if (textFormatting.italic !== void 0) formatting.italic = textFormatting.italic;
11820
+ if (textFormatting.strike !== void 0) formatting.strike = textFormatting.strike;
11821
+ if (fontFamily !== void 0) formatting.fontFamily = fontFamily;
11822
+ if (fontSize !== void 0) formatting.fontSize = fontSize;
11823
+ if (textColor !== void 0) formatting.color = textColor;
11824
+ if (textFormatting.highlight !== void 0) formatting.highlight = textFormatting.highlight;
11825
+ if (paragraphFormatting.alignment !== void 0) formatting.alignment = paragraphFormatting.alignment;
11826
+ if (paragraphFormatting.lineSpacing !== void 0) formatting.lineSpacing = paragraphFormatting.lineSpacing;
11827
+ if (listState !== void 0) formatting.listState = listState;
11828
+ if (selectionState.styleId !== null) formatting.styleId = selectionState.styleId;
11829
+ if (paragraphFormatting.indentLeft !== void 0) formatting.indentLeft = paragraphFormatting.indentLeft;
11830
+ return formatting;
11831
+ }
11832
+ //#endregion
11320
11833
  //#region src/components/ui/HyperlinkPopup.tsx
11321
11834
  /**
11322
11835
  * HyperlinkPopup — floating popup for viewing/editing hyperlinks.
@@ -12150,7 +12663,7 @@ function useFolioComments({ doc, autoOpenReviewSidebar, anchorPositions, editorC
12150
12663
  setComments(bodyComments);
12151
12664
  setVisibleCommentAuthors(null);
12152
12665
  setActiveCommentId(null);
12153
- if (autoOpenReviewSidebar) setShowCommentsSidebar(true);
12666
+ if (autoOpenReviewSidebar && countOpenCommentThreads(bodyComments) > 0) setShowCommentsSidebar(true);
12154
12667
  commentsLoadedRef.current = true;
12155
12668
  }
12156
12669
  }, [
@@ -12279,8 +12792,10 @@ function useFolioComments({ doc, autoOpenReviewSidebar, anchorPositions, editorC
12279
12792
  * - Error boundary
12280
12793
  * - Loading states
12281
12794
  */
12282
- const CommentsSidebar = lazy(() => import("./CommentsSidebar-CGs9K70B.js").then((m) => ({ default: m.CommentsSidebar })));
12283
- const TextContextMenu = lazy(() => import("./TextContextMenu-Ci7-M4oU.js").then((m) => ({ default: m.TextContextMenu })));
12795
+ /** No headings to track while the outline is not shown. */
12796
+ const NO_HEADINGS = [];
12797
+ const CommentsSidebar = lazy(() => import("./CommentsSidebar-D0TBbrpB.js").then((m) => ({ default: m.CommentsSidebar })));
12798
+ const TextContextMenu = lazy(() => import("./TextContextMenu-Bqth8itn.js").then((m) => ({ default: m.TextContextMenu })));
12284
12799
  const loadAttemptSelectiveSave = async () => {
12285
12800
  const { attemptSelectiveSave } = await import("@stll/folio-core/docx/selectiveSave");
12286
12801
  return attemptSelectiveSave;
@@ -12298,6 +12813,15 @@ const DISPLAY_MODE_LABEL_KEYS = {
12298
12813
  };
12299
12814
  const preventMouseDownDefault = (event) => event.preventDefault();
12300
12815
  let documentOperationUndoHandleCursor = Date.now();
12816
+ /**
12817
+ * The comments a batch's applied operations own. A run whose result the
12818
+ * save-time check refused allocated comments nothing in the document names;
12819
+ * they stay out of the comment list.
12820
+ */
12821
+ const appliedOperationComments = (created, applied) => {
12822
+ const appliedIds = new Set(applied.map(({ commentId }) => commentId));
12823
+ return created.filter((comment) => appliedIds.has(comment.id));
12824
+ };
12301
12825
  function isDisplayMode(value) {
12302
12826
  return typeof value === "string" && DISPLAY_MODES.some((mode) => mode === value);
12303
12827
  }
@@ -12370,6 +12894,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
12370
12894
  const [tablePropsOpen, setTablePropsOpen] = useState(false);
12371
12895
  const [footnotePropsOpen, setFootnotePropsOpen] = useState(false);
12372
12896
  const [showInsertSymbol, setShowInsertSymbol] = useState(false);
12897
+ const [numberingValueDialogOpen, setNumberingValueDialogOpen] = useState(false);
12373
12898
  const [rulerVisible, setRulerVisible] = useState(showRulerProp);
12374
12899
  const toggleRuler = useCallback(() => setRulerVisible((visible) => !visible), []);
12375
12900
  const [showOutline, setShowOutline] = useState(showOutlineProp);
@@ -12509,11 +13034,16 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
12509
13034
  reportEditorViewReady(null);
12510
13035
  };
12511
13036
  }, [onEditorViewReady, reportEditorViewReady]);
13037
+ const [bodyViewEpoch, setBodyViewEpoch] = useState(0);
13038
+ const handleBodyViewReady = useCallback((view_2) => {
13039
+ reportEditorViewReady(view_2);
13040
+ setBodyViewEpoch((epoch) => epoch + 1);
13041
+ }, [reportEditorViewReady]);
12512
13042
  useEffect(() => {
12513
13043
  if (!showOutline) return;
12514
- const view_2 = pagedEditorRef.current?.getView();
12515
- if (!view_2) return;
12516
- const headings = collectHeadings(view_2.state.doc, getDocumentBuiltInStyles(view_2.state));
13044
+ const view_3 = pagedEditorRef.current?.getView();
13045
+ if (!view_3) return;
13046
+ const headings = collectHeadings(view_3.state.doc, getDocumentBuiltInStyles(view_3.state));
12517
13047
  setHeadingInfos(headings);
12518
13048
  let attempts = 0;
12519
13049
  let timer = null;
@@ -12534,7 +13064,11 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
12534
13064
  return () => {
12535
13065
  if (timer) clearTimeout(timer);
12536
13066
  };
12537
- }, [showOutline, history.state]);
13067
+ }, [
13068
+ showOutline,
13069
+ history.state,
13070
+ bodyViewEpoch
13071
+ ]);
12538
13072
  const pagedEditorRef = useRef(null);
12539
13073
  const hfEditorRef = useRef(null);
12540
13074
  const containerRef = useRef(null);
@@ -12544,6 +13078,31 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
12544
13078
  const editorContentRef = useRef(null);
12545
13079
  const scrollContainerRef = useRef(null);
12546
13080
  const initialScrollAppliedRef = useRef(false);
13081
+ const [widestLaidOutPageWidth, setWidestLaidOutPageWidth] = useState(null);
13082
+ const hasDocument = history.state !== null;
13083
+ useEffect(() => {
13084
+ const pagedEditor = pagedEditorRef.current;
13085
+ if (!pagedEditor) {
13086
+ setWidestLaidOutPageWidth(null);
13087
+ return;
13088
+ }
13089
+ const updatePageWidth = () => {
13090
+ const pages = pagedEditor.getLayout()?.pages;
13091
+ if (!pages) {
13092
+ setWidestLaidOutPageWidth(null);
13093
+ return;
13094
+ }
13095
+ let width = 0;
13096
+ for (const page_0 of pages) width = Math.max(width, page_0.size.w);
13097
+ setWidestLaidOutPageWidth(width);
13098
+ };
13099
+ updatePageWidth();
13100
+ return pagedEditor.getEditor().on("layoutComplete", updatePageWidth);
13101
+ }, [
13102
+ state.documentLoad.status,
13103
+ hasDocument,
13104
+ preserveDocumentWhileLoading
13105
+ ]);
12547
13106
  const [formatPainterMode, setFormatPainterModeState] = useState("off");
12548
13107
  const formatPainterModeRef = useRef("off");
12549
13108
  const capturedFormatMarksRef = useRef(null);
@@ -12552,9 +13111,6 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
12552
13111
  setFormatPainterModeState(next);
12553
13112
  }, []);
12554
13113
  const { contextMenu, openMenu: openContextMenu, closeMenu: closeContextMenu } = useContextMenu({ pagedEditorRef });
12555
- const toolbarWrapperRef = useRef(null);
12556
- const toolbarRoRef = useRef(null);
12557
- const [toolbarHeight, setToolbarHeight] = useState(0);
12558
13114
  const historyStateRef = useRef(history.state);
12559
13115
  historyStateRef.current = history.state;
12560
13116
  const borderSpecRef = useRef({
@@ -12571,6 +13127,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
12571
13127
  onCommentsChange
12572
13128
  });
12573
13129
  const documentOperationUndoEntriesRef = useRef([]);
13130
+ const pendingSuggestionRegistryRef = useRef(new FolioPendingSuggestionRegistry());
12574
13131
  const styleResolverCacheRef = useRef(null);
12575
13132
  const getCachedStyleResolver = useCallback((styles) => {
12576
13133
  const cached = styleResolverCacheRef.current;
@@ -12599,26 +13156,6 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
12599
13156
  canUndo: false
12600
13157
  });
12601
13158
  const [activeNoteStory, setActiveNoteStory] = useState(null);
12602
- const toolbarRefCallback = useCallback((el) => {
12603
- toolbarWrapperRef.current = el;
12604
- if (toolbarRoRef.current) {
12605
- toolbarRoRef.current.disconnect();
12606
- toolbarRoRef.current = null;
12607
- }
12608
- if (!el) {
12609
- setToolbarHeight(0);
12610
- return;
12611
- }
12612
- setToolbarHeight(el.offsetHeight);
12613
- const ro = new ResizeObserver(() => {
12614
- setToolbarHeight(el.offsetHeight);
12615
- });
12616
- ro.observe(el);
12617
- toolbarRoRef.current = ro;
12618
- }, []);
12619
- useEffect(() => () => {
12620
- toolbarRoRef.current?.disconnect();
12621
- }, []);
12622
13159
  const pushDocument = useCallback((document) => {
12623
13160
  history.push(document);
12624
13161
  return document;
@@ -12638,6 +13175,21 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
12638
13175
  });
12639
13176
  let activeHfRId = hfEditIsFirstPage ? activeFirstFooterRId : activeFooterRId;
12640
13177
  if (hfEditPosition === "header") activeHfRId = hfEditIsFirstPage ? activeFirstHeaderRId : activeHeaderRId;
13178
+ const panels = usePanelLayout({
13179
+ pageWidth: (widestLaidOutPageWidth ?? getPageSize(effectiveSectionProperties).w) * zoom,
13180
+ outline: showOutline && outlineHeadings.length > 1 ? "available" : "absent",
13181
+ comments: showCommentsSidebar ? "open" : "closed",
13182
+ scrollContainerRef
13183
+ });
13184
+ const { overlay: panelOverlay, setOverlay: setPanelOverlay, layoutWithCommentsOpen } = panels;
13185
+ const commentsSurface = (() => {
13186
+ if (panels.layout.comments === "column") return "column";
13187
+ if (panels.layout.comments === "drawer" && panelOverlay === "comments") return "drawer";
13188
+ return null;
13189
+ })();
13190
+ const { activeId: activeHeadingId, markJumped: markHeadingJumped } = useActiveHeading(scrollContainerRef, panels.layout.outline === "none" ? NO_HEADINGS : outlineHeadings);
13191
+ const closePanelOverlay = useCallback(() => setPanelOverlay("none"), [setPanelOverlay]);
13192
+ const toggleOutlineOverlay = useCallback(() => setPanelOverlay(panelOverlay === "outline" ? "none" : "outline"), [panelOverlay, setPanelOverlay]);
12641
13193
  const getActiveEditorStory = useCallback(() => {
12642
13194
  return resolveActiveEditorStory({
12643
13195
  bodyView: pagedEditorRef.current?.getView() ?? null,
@@ -12698,7 +13250,6 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
12698
13250
  }
12699
13251
  commentsDirtyRef.current = false;
12700
13252
  commentsLoadedRef.current = false;
12701
- trackedChangesLoadedRef.current = false;
12702
13253
  setComments([]);
12703
13254
  setTrackedChanges([]);
12704
13255
  setVisibleCommentAuthors(null);
@@ -12741,27 +13292,15 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
12741
13292
  }));
12742
13293
  }, [])
12743
13294
  });
12744
- const trackedChangesLoadedRef = useRef(false);
12745
13295
  useEffect(() => {
12746
13296
  if (state.documentLoad.status === "ready" && history.state) {
12747
- const timer_0 = setTimeout(() => {
12748
- extractTrackedChanges();
12749
- if (!trackedChangesLoadedRef.current) {
12750
- trackedChangesLoadedRef.current = true;
12751
- setTrackedChanges((prev_1) => {
12752
- if (autoOpenReviewSidebar && prev_1.length > 0) setShowCommentsSidebar(true);
12753
- return prev_1;
12754
- });
12755
- }
12756
- }, 200);
13297
+ const timer_0 = setTimeout(extractTrackedChanges, 200);
12757
13298
  return () => clearTimeout(timer_0);
12758
13299
  }
12759
13300
  }, [
12760
13301
  state.documentLoad.status,
12761
13302
  history.state,
12762
- extractTrackedChanges,
12763
- autoOpenReviewSidebar,
12764
- setShowCommentsSidebar
13303
+ extractTrackedChanges
12765
13304
  ]);
12766
13305
  useEffect(() => {
12767
13306
  if (initialScrollTop === void 0 || state.documentLoad.status !== "ready" || initialScrollAppliedRef.current) return;
@@ -12783,8 +13322,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
12783
13322
  });
12784
13323
  }, [onFontsLoadedCallback]);
12785
13324
  useEffect(() => {
12786
- const view_3 = pagedEditorRef.current?.getView();
12787
- if (view_3) setSuggestionMode(editingMode === "suggesting", view_3.state, view_3.dispatch, author);
13325
+ const view_4 = pagedEditorRef.current?.getView();
13326
+ if (view_4) setSuggestionMode(editingMode === "suggesting", view_4.state, view_4.dispatch, author);
12788
13327
  }, [editingMode, author]);
12789
13328
  const handleDocumentChange = useCallback((newDocument) => {
12790
13329
  const currentComments = commentsRef.current;
@@ -12803,9 +13342,9 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
12803
13342
  if (showOutlineRef.current) {
12804
13343
  if (collectHeadingsTimerRef.current) clearTimeout(collectHeadingsTimerRef.current);
12805
13344
  collectHeadingsTimerRef.current = setTimeout(() => {
12806
- const view_4 = pagedEditorRef.current?.getView();
12807
- if (view_4) {
12808
- const headings_0 = collectHeadings(view_4.state.doc, getDocumentBuiltInStyles(view_4.state));
13345
+ const view_5 = pagedEditorRef.current?.getView();
13346
+ if (view_5) {
13347
+ const headings_0 = collectHeadings(view_5.state.doc, getDocumentBuiltInStyles(view_5.state));
12809
13348
  const pagedRef_0 = pagedEditorRef.current;
12810
13349
  for (const heading_0 of headings_0) heading_0.pageNumber = pagedRef_0?.getPageNumberForPmPos(heading_0.pmPos) ?? null;
12811
13350
  setHeadingInfos(headings_0);
@@ -12828,6 +13367,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
12828
13367
  const pmDoc = pagedEditorRef.current?.getDocument();
12829
13368
  if (pmDoc) {
12830
13369
  doc_0.package.document.content = pmDoc.package.document.content;
13370
+ if (pmDoc.package.numbering) doc_0.package.numbering = pmDoc.package.numbering;
13371
+ else delete doc_0.package.numbering;
12831
13372
  if (pmDoc.package.footnotes !== void 0) doc_0.package.footnotes = pmDoc.package.footnotes;
12832
13373
  if (pmDoc.package.endnotes !== void 0) doc_0.package.endnotes = pmDoc.package.endnotes;
12833
13374
  } else doc_0 = normalizeBaseDirection(doc_0);
@@ -12836,8 +13377,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
12836
13377
  const flushBag = (bag) => {
12837
13378
  if (!bag) return;
12838
13379
  for (const [rId_0, hf] of bag) {
12839
- const view_5 = editor.getHfView(rId_0);
12840
- if (view_5) hf.content = proseDocToBlocks(view_5.state.doc, hf.content);
13380
+ const view_6 = editor.getHfView(rId_0);
13381
+ if (view_6) hf.content = proseDocToBlocks(view_6.state.doc, hf.content);
12841
13382
  }
12842
13383
  };
12843
13384
  flushBag(doc_0.package.headers);
@@ -12869,9 +13410,9 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
12869
13410
  findReplace,
12870
13411
  selectMatch: useCallback((match) => {
12871
13412
  const editor_0 = pagedEditorRef.current;
12872
- const view_6 = editor_0?.getView();
12873
- if (!editor_0 || !view_6) return false;
12874
- const range = resolveFindMatchRange(view_6.state.doc, match);
13413
+ const view_7 = editor_0?.getView();
13414
+ if (!editor_0 || !view_7) return false;
13415
+ const range = resolveFindMatchRange(view_7.state.doc, match);
12875
13416
  if (!range) return false;
12876
13417
  editor_0.setSelection(range.from, range.to);
12877
13418
  requestAnimationFrame(() => {
@@ -12881,17 +13422,17 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
12881
13422
  }, [])
12882
13423
  });
12883
13424
  const handleSelectionChange = useCallback((selectionState) => {
12884
- const view_7 = getActiveEditorView();
12885
- if (view_7) {
12886
- const { from, to } = view_7.state.selection;
13425
+ const view_8 = getActiveEditorView();
13426
+ if (view_8) {
13427
+ const { from, to } = view_8.state.selection;
12887
13428
  lastSelectionRef.current = {
12888
13429
  from,
12889
13430
  to
12890
13431
  };
12891
13432
  }
12892
13433
  let pmTableCtx = null;
12893
- if (view_7) {
12894
- pmTableCtx = getTableContext(view_7.state);
13434
+ if (view_8) {
13435
+ pmTableCtx = getTableContext(view_8.state);
12895
13436
  if (!pmTableCtx.isInTable) pmTableCtx = null;
12896
13437
  }
12897
13438
  if (pmTableCtx?.cellBorderColor) {
@@ -12903,18 +13444,18 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
12903
13444
  color: { rgb }
12904
13445
  };
12905
13446
  }
12906
- const pmImageCtx = view_7 ? detectImageContext(view_7.state) : null;
12907
- const trackedChange = view_7 ? detectActiveTrackedChange(view_7.state) : null;
13447
+ const pmImageCtx = view_8 ? detectImageContext(view_8.state) : null;
13448
+ const trackedChange = view_8 ? detectActiveTrackedChange(view_8.state) : null;
12908
13449
  if (!selectionState) {
12909
13450
  setFloatingCommentBtn(null);
12910
- setState((prev_2) => {
12911
- const selectionFormatting = areSelectionFormattingEqual(prev_2.selectionFormatting, EMPTY_SELECTION_FORMATTING) ? prev_2.selectionFormatting : EMPTY_SELECTION_FORMATTING;
12912
- const pmTableContext = areTableContextsEqual(prev_2.pmTableContext, pmTableCtx) ? prev_2.pmTableContext : pmTableCtx;
12913
- const pmImageContext = areImageContextsEqual(prev_2.pmImageContext, pmImageCtx) ? prev_2.pmImageContext : pmImageCtx;
12914
- const activeTrackedChange = areActiveTrackedChangesEqual(prev_2.activeTrackedChange, trackedChange) ? prev_2.activeTrackedChange : trackedChange;
12915
- if (selectionFormatting === prev_2.selectionFormatting && pmTableContext === prev_2.pmTableContext && pmImageContext === prev_2.pmImageContext && activeTrackedChange === prev_2.activeTrackedChange) return prev_2;
13451
+ setState((prev_1) => {
13452
+ const selectionFormatting = areSelectionFormattingEqual(prev_1.selectionFormatting, EMPTY_SELECTION_FORMATTING) ? prev_1.selectionFormatting : EMPTY_SELECTION_FORMATTING;
13453
+ const pmTableContext = areTableContextsEqual(prev_1.pmTableContext, pmTableCtx) ? prev_1.pmTableContext : pmTableCtx;
13454
+ const pmImageContext = areImageContextsEqual(prev_1.pmImageContext, pmImageCtx) ? prev_1.pmImageContext : pmImageCtx;
13455
+ const activeTrackedChange = areActiveTrackedChangesEqual(prev_1.activeTrackedChange, trackedChange) ? prev_1.activeTrackedChange : trackedChange;
13456
+ if (selectionFormatting === prev_1.selectionFormatting && pmTableContext === prev_1.pmTableContext && pmImageContext === prev_1.pmImageContext && activeTrackedChange === prev_1.activeTrackedChange) return prev_1;
12916
13457
  return {
12917
- ...prev_2,
13458
+ ...prev_1,
12918
13459
  selectionFormatting,
12919
13460
  pmTableContext,
12920
13461
  pmImageContext,
@@ -12943,19 +13484,19 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
12943
13484
  textColor,
12944
13485
  listState: selectionState.listState
12945
13486
  });
12946
- setState((prev_3) => {
12947
- const selectionFormatting_0 = areSelectionFormattingEqual(prev_3.selectionFormatting, formatting) ? prev_3.selectionFormatting : formatting;
12948
- const pmTableContext_0 = areTableContextsEqual(prev_3.pmTableContext, pmTableCtx) ? prev_3.pmTableContext : pmTableCtx;
12949
- const pmImageContext_0 = areImageContextsEqual(prev_3.pmImageContext, pmImageCtx) ? prev_3.pmImageContext : pmImageCtx;
12950
- const activeTrackedChange_0 = areActiveTrackedChangesEqual(prev_3.activeTrackedChange, trackedChange) ? prev_3.activeTrackedChange : trackedChange;
13487
+ setState((prev_2) => {
13488
+ const selectionFormatting_0 = areSelectionFormattingEqual(prev_2.selectionFormatting, formatting) ? prev_2.selectionFormatting : formatting;
13489
+ const pmTableContext_0 = areTableContextsEqual(prev_2.pmTableContext, pmTableCtx) ? prev_2.pmTableContext : pmTableCtx;
13490
+ const pmImageContext_0 = areImageContextsEqual(prev_2.pmImageContext, pmImageCtx) ? prev_2.pmImageContext : pmImageCtx;
13491
+ const activeTrackedChange_0 = areActiveTrackedChangesEqual(prev_2.activeTrackedChange, trackedChange) ? prev_2.activeTrackedChange : trackedChange;
12951
13492
  const paragraphIndentLeft = paragraphFormatting.indentLeft ?? 0;
12952
13493
  const paragraphIndentRight = paragraphFormatting.indentRight ?? 0;
12953
13494
  const paragraphFirstLineIndent = paragraphFormatting.indentFirstLine ?? 0;
12954
13495
  const paragraphHangingIndent = paragraphFormatting.hangingIndent ?? false;
12955
13496
  const paragraphTabs = paragraphFormatting.tabs ?? null;
12956
- if (selectionFormatting_0 === prev_3.selectionFormatting && pmTableContext_0 === prev_3.pmTableContext && pmImageContext_0 === prev_3.pmImageContext && activeTrackedChange_0 === prev_3.activeTrackedChange && paragraphIndentLeft === prev_3.paragraphIndentLeft && paragraphIndentRight === prev_3.paragraphIndentRight && paragraphFirstLineIndent === prev_3.paragraphFirstLineIndent && paragraphHangingIndent === prev_3.paragraphHangingIndent && paragraphTabs === prev_3.paragraphTabs) return prev_3;
13497
+ if (selectionFormatting_0 === prev_2.selectionFormatting && pmTableContext_0 === prev_2.pmTableContext && pmImageContext_0 === prev_2.pmImageContext && activeTrackedChange_0 === prev_2.activeTrackedChange && paragraphIndentLeft === prev_2.paragraphIndentLeft && paragraphIndentRight === prev_2.paragraphIndentRight && paragraphFirstLineIndent === prev_2.paragraphFirstLineIndent && paragraphHangingIndent === prev_2.paragraphHangingIndent && paragraphTabs === prev_2.paragraphTabs) return prev_2;
12957
13498
  return {
12958
- ...prev_3,
13499
+ ...prev_2,
12959
13500
  selectionFormatting: selectionFormatting_0,
12960
13501
  paragraphIndentLeft,
12961
13502
  paragraphIndentRight,
@@ -12967,10 +13508,10 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
12967
13508
  activeTrackedChange: activeTrackedChange_0
12968
13509
  };
12969
13510
  });
12970
- if (view_7 && selectionState.hasSelection && !isAddingComment && !readOnly) {
13511
+ if (view_8 && selectionState.hasSelection && !isAddingComment && !readOnly) {
12971
13512
  const container = scrollContainerRef.current;
12972
13513
  const parentEl = editorContentRef.current;
12973
- const { from: selFrom } = view_7.state.selection;
13514
+ const { from: selFrom } = view_8.state.selection;
12974
13515
  const top = findSelectionYPosition(container, parentEl, selFrom);
12975
13516
  if (top !== null && container && parentEl) {
12976
13517
  const pagesEl = container.querySelector(".paged-editor__pages");
@@ -12978,7 +13519,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
12978
13519
  const parentRect = parentEl.getBoundingClientRect();
12979
13520
  const rawLeft = pageEl ? pageEl.getBoundingClientRect().right - parentRect.left + 12 : parentRect.width / 2 + 408;
12980
13521
  const left = Math.max(16, Math.min(rawLeft, parentRect.width - 16));
12981
- const { from: from_0, to: to_0 } = view_7.state.selection;
13522
+ const { from: from_0, to: to_0 } = view_8.state.selection;
12982
13523
  if (from_0 !== to_0) setFloatingCommentBtn({
12983
13524
  top,
12984
13525
  left,
@@ -13008,8 +13549,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13008
13549
  onPrint();
13009
13550
  return;
13010
13551
  }
13011
- const pages = containerRef.current?.querySelector(".paged-editor__pages");
13012
- if (!pages) {
13552
+ const pages_0 = containerRef.current?.querySelector(".paged-editor__pages");
13553
+ if (!pages_0) {
13013
13554
  toast(t("printRedirect"));
13014
13555
  return;
13015
13556
  }
@@ -13029,7 +13570,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13029
13570
  return;
13030
13571
  }
13031
13572
  const styles_0 = [...document.querySelectorAll("style, link[rel=\"stylesheet\"]")].map((node_0) => node_0.outerHTML).join("\n");
13032
- const pagesCloneRaw = pages.cloneNode(true);
13573
+ const pagesCloneRaw = pages_0.cloneNode(true);
13033
13574
  if (!(pagesCloneRaw instanceof HTMLElement)) return;
13034
13575
  const pagesClone = pagesCloneRaw;
13035
13576
  const overlays = pagesClone.querySelectorAll(".selection-overlay, .layout-selection-overlay, .image-selection-overlay");
@@ -13127,98 +13668,98 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13127
13668
  });
13128
13669
  }, [history, pushDocument]);
13129
13670
  const handleTableAction = useCallback((action_0) => {
13130
- const view_8 = getActiveEditorView();
13131
- if (!view_8) return;
13671
+ const view_9 = getActiveEditorView();
13672
+ if (!view_9) return;
13132
13673
  switch (action_0) {
13133
13674
  case "addRowAbove":
13134
- addRowAbove(view_8.state, view_8.dispatch);
13675
+ addRowAbove(view_9.state, view_9.dispatch);
13135
13676
  break;
13136
13677
  case "addRowBelow":
13137
- addRowBelow(view_8.state, view_8.dispatch);
13678
+ addRowBelow(view_9.state, view_9.dispatch);
13138
13679
  break;
13139
13680
  case "addColumnLeft":
13140
- addColumnLeft(view_8.state, view_8.dispatch);
13681
+ addColumnLeft(view_9.state, view_9.dispatch);
13141
13682
  break;
13142
13683
  case "addColumnRight":
13143
- addColumnRight(view_8.state, view_8.dispatch);
13684
+ addColumnRight(view_9.state, view_9.dispatch);
13144
13685
  break;
13145
13686
  case "deleteRow":
13146
- deleteRow(view_8.state, view_8.dispatch);
13687
+ deleteRow(view_9.state, view_9.dispatch);
13147
13688
  break;
13148
13689
  case "deleteColumn":
13149
- deleteColumn(view_8.state, view_8.dispatch);
13690
+ deleteColumn(view_9.state, view_9.dispatch);
13150
13691
  break;
13151
13692
  case "deleteTable":
13152
- deleteTable(view_8.state, view_8.dispatch);
13693
+ deleteTable(view_9.state, view_9.dispatch);
13153
13694
  break;
13154
13695
  case "selectTable":
13155
- selectTable(view_8.state, view_8.dispatch);
13696
+ selectTable(view_9.state, view_9.dispatch);
13156
13697
  break;
13157
13698
  case "selectRow":
13158
- selectRow(view_8.state, view_8.dispatch);
13699
+ selectRow(view_9.state, view_9.dispatch);
13159
13700
  break;
13160
13701
  case "selectColumn":
13161
- selectColumn(view_8.state, view_8.dispatch);
13702
+ selectColumn(view_9.state, view_9.dispatch);
13162
13703
  break;
13163
13704
  case "mergeCells":
13164
- mergeCells(view_8.state, view_8.dispatch);
13705
+ mergeCells(view_9.state, view_9.dispatch);
13165
13706
  break;
13166
13707
  case "splitCell":
13167
- splitCell(view_8.state, view_8.dispatch);
13708
+ splitCell(view_9.state, view_9.dispatch);
13168
13709
  break;
13169
13710
  case "borderAll":
13170
- setAllTableBorders(view_8.state, view_8.dispatch, borderSpecRef.current);
13711
+ setAllTableBorders(view_9.state, view_9.dispatch, borderSpecRef.current);
13171
13712
  break;
13172
13713
  case "borderOutside":
13173
- setOutsideTableBorders(view_8.state, view_8.dispatch, borderSpecRef.current);
13714
+ setOutsideTableBorders(view_9.state, view_9.dispatch, borderSpecRef.current);
13174
13715
  break;
13175
13716
  case "borderInside":
13176
- setInsideTableBorders(view_8.state, view_8.dispatch, borderSpecRef.current);
13717
+ setInsideTableBorders(view_9.state, view_9.dispatch, borderSpecRef.current);
13177
13718
  break;
13178
13719
  case "borderNone":
13179
- removeTableBorders(view_8.state, view_8.dispatch);
13720
+ removeTableBorders(view_9.state, view_9.dispatch);
13180
13721
  break;
13181
13722
  case "borderTop":
13182
- setCellBorder("top", borderSpecRef.current, true)(view_8.state, view_8.dispatch);
13723
+ setCellBorder("top", borderSpecRef.current, true)(view_9.state, view_9.dispatch);
13183
13724
  break;
13184
13725
  case "borderBottom":
13185
- setCellBorder("bottom", borderSpecRef.current, true)(view_8.state, view_8.dispatch);
13726
+ setCellBorder("bottom", borderSpecRef.current, true)(view_9.state, view_9.dispatch);
13186
13727
  break;
13187
13728
  case "borderLeft":
13188
- setCellBorder("left", borderSpecRef.current, true)(view_8.state, view_8.dispatch);
13729
+ setCellBorder("left", borderSpecRef.current, true)(view_9.state, view_9.dispatch);
13189
13730
  break;
13190
13731
  case "borderRight":
13191
- setCellBorder("right", borderSpecRef.current, true)(view_8.state, view_8.dispatch);
13732
+ setCellBorder("right", borderSpecRef.current, true)(view_9.state, view_9.dispatch);
13192
13733
  break;
13193
- default: if (typeof action_0 === "object") if (action_0.type === "cellFillColor") setCellFillColor(action_0.color)(view_8.state, view_8.dispatch);
13734
+ default: if (typeof action_0 === "object") if (action_0.type === "cellFillColor") setCellFillColor(action_0.color)(view_9.state, view_9.dispatch);
13194
13735
  else if (action_0.type === "borderColor") {
13195
13736
  const rgb_0 = action_0.color.replace(/^#/u, "");
13196
13737
  borderSpecRef.current = {
13197
13738
  ...borderSpecRef.current,
13198
13739
  color: { rgb: rgb_0 }
13199
13740
  };
13200
- setTableBorderColor(action_0.color)(view_8.state, view_8.dispatch);
13741
+ setTableBorderColor(action_0.color)(view_9.state, view_9.dispatch);
13201
13742
  } else if (action_0.type === "borderWidth") {
13202
13743
  borderSpecRef.current = {
13203
13744
  ...borderSpecRef.current,
13204
13745
  size: action_0.size
13205
13746
  };
13206
- setTableBorderWidth(action_0.size)(view_8.state, view_8.dispatch);
13747
+ setTableBorderWidth(action_0.size)(view_9.state, view_9.dispatch);
13207
13748
  } else if (action_0.type === "cellBorder") setCellBorder(action_0.side, {
13208
13749
  style: action_0.style,
13209
13750
  size: action_0.size,
13210
13751
  color: { rgb: action_0.color.replace(/^#/u, "") }
13211
- })(view_8.state, view_8.dispatch);
13212
- else if (action_0.type === "cellVerticalAlign") setCellVerticalAlign(action_0.align)(view_8.state, view_8.dispatch);
13213
- else if (action_0.type === "cellMargins") setCellMargins(action_0.margins)(view_8.state, view_8.dispatch);
13214
- else if (action_0.type === "cellTextDirection") setCellTextDirection(action_0.direction)(view_8.state, view_8.dispatch);
13215
- else if (action_0.type === "toggleNoWrap") toggleNoWrap()(view_8.state, view_8.dispatch);
13216
- else if (action_0.type === "rowHeight") setRowHeight(action_0.height, action_0.rule)(view_8.state, view_8.dispatch);
13217
- else if (action_0.type === "toggleHeaderRow") toggleHeaderRow()(view_8.state, view_8.dispatch);
13218
- else if (action_0.type === "distributeColumns") distributeColumns()(view_8.state, view_8.dispatch);
13219
- else if (action_0.type === "autoFitContents") autoFitContents()(view_8.state, view_8.dispatch);
13752
+ })(view_9.state, view_9.dispatch);
13753
+ else if (action_0.type === "cellVerticalAlign") setCellVerticalAlign(action_0.align)(view_9.state, view_9.dispatch);
13754
+ else if (action_0.type === "cellMargins") setCellMargins(action_0.margins)(view_9.state, view_9.dispatch);
13755
+ else if (action_0.type === "cellTextDirection") setCellTextDirection(action_0.direction)(view_9.state, view_9.dispatch);
13756
+ else if (action_0.type === "toggleNoWrap") toggleNoWrap()(view_9.state, view_9.dispatch);
13757
+ else if (action_0.type === "rowHeight") setRowHeight(action_0.height, action_0.rule)(view_9.state, view_9.dispatch);
13758
+ else if (action_0.type === "toggleHeaderRow") toggleHeaderRow()(view_9.state, view_9.dispatch);
13759
+ else if (action_0.type === "distributeColumns") distributeColumns()(view_9.state, view_9.dispatch);
13760
+ else if (action_0.type === "autoFitContents") autoFitContents()(view_9.state, view_9.dispatch);
13220
13761
  else if (action_0.type === "openTableProperties") setTablePropsOpen(true);
13221
- else if (action_0.type === "tableProperties") setTableProperties(action_0.props)(view_8.state, view_8.dispatch);
13762
+ else if (action_0.type === "tableProperties") setTableProperties(action_0.props)(view_9.state, view_9.dispatch);
13222
13763
  else {
13223
13764
  let preset = getBuiltinTableStyle(action_0.styleId);
13224
13765
  const currentDocForTable = historyStateRef.current;
@@ -13289,7 +13830,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13289
13830
  if (preset.tableBorders) styleArg.tableBorders = preset.tableBorders;
13290
13831
  if (preset.conditionals) styleArg.conditionals = preset.conditionals;
13291
13832
  if (preset.look) styleArg.look = preset.look;
13292
- applyTableStyle(styleArg)(view_8.state, view_8.dispatch);
13833
+ applyTableStyle(styleArg)(view_9.state, view_9.dispatch);
13293
13834
  }
13294
13835
  }
13295
13836
  else tableSelection.handleAction(action_0);
@@ -13310,80 +13851,80 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13310
13851
  });
13311
13852
  }, [openContextMenu]);
13312
13853
  const handleFormat = useCallback((action_1) => {
13313
- const view_9 = getActiveEditorView();
13314
- if (!view_9) return;
13315
- view_9.focus();
13316
- const isBodyEditor = view_9 === pagedEditorRef.current?.getView();
13317
- const { from: from_1, to: to_1 } = view_9.state.selection;
13854
+ const view_10 = getActiveEditorView();
13855
+ if (!view_10) return;
13856
+ view_10.focus();
13857
+ const isBodyEditor = view_10 === pagedEditorRef.current?.getView();
13858
+ const { from: from_1, to: to_1 } = view_10.state.selection;
13318
13859
  const savedSelection = lastSelectionRef.current;
13319
13860
  if (isBodyEditor && savedSelection && (from_1 !== savedSelection.from || to_1 !== savedSelection.to)) try {
13320
- const tr = view_9.state.tr.setSelection(TextSelection.create(view_9.state.doc, savedSelection.from, savedSelection.to));
13321
- view_9.dispatch(tr);
13861
+ const tr = view_10.state.tr.setSelection(TextSelection.create(view_10.state.doc, savedSelection.from, savedSelection.to));
13862
+ view_10.dispatch(tr);
13322
13863
  } catch {}
13323
- const commandState = view_9.state;
13864
+ const commandState = view_10.state;
13324
13865
  if (action_1 === "bold") {
13325
- toggleBold(commandState, view_9.dispatch);
13866
+ toggleBold(commandState, view_10.dispatch);
13326
13867
  return;
13327
13868
  }
13328
13869
  if (action_1 === "italic") {
13329
- toggleItalic(commandState, view_9.dispatch);
13870
+ toggleItalic(commandState, view_10.dispatch);
13330
13871
  return;
13331
13872
  }
13332
13873
  if (action_1 === "underline") {
13333
- toggleUnderline(commandState, view_9.dispatch);
13874
+ toggleUnderline(commandState, view_10.dispatch);
13334
13875
  return;
13335
13876
  }
13336
13877
  if (action_1 === "strikethrough") {
13337
- toggleStrike(commandState, view_9.dispatch);
13878
+ toggleStrike(commandState, view_10.dispatch);
13338
13879
  return;
13339
13880
  }
13340
13881
  if (action_1 === "superscript") {
13341
- toggleSuperscript(commandState, view_9.dispatch);
13882
+ toggleSuperscript(commandState, view_10.dispatch);
13342
13883
  return;
13343
13884
  }
13344
13885
  if (action_1 === "subscript") {
13345
- toggleSubscript(commandState, view_9.dispatch);
13886
+ toggleSubscript(commandState, view_10.dispatch);
13346
13887
  return;
13347
13888
  }
13348
13889
  if (action_1 === "bulletList") {
13349
- toggleBulletList(commandState, view_9.dispatch);
13890
+ toggleBulletList(commandState, view_10.dispatch);
13350
13891
  return;
13351
13892
  }
13352
13893
  if (action_1 === "numberedList") {
13353
- toggleNumberedList(commandState, view_9.dispatch);
13894
+ toggleNumberedList(commandState, view_10.dispatch);
13354
13895
  return;
13355
13896
  }
13356
13897
  if (action_1 === "indent") {
13357
- if (!increaseListLevel(commandState, view_9.dispatch)) increaseIndent()(commandState, view_9.dispatch);
13898
+ if (!increaseListLevel(commandState, view_10.dispatch)) increaseIndent()(commandState, view_10.dispatch);
13358
13899
  return;
13359
13900
  }
13360
13901
  if (action_1 === "outdent") {
13361
- if (!decreaseListLevel(commandState, view_9.dispatch)) decreaseIndent()(commandState, view_9.dispatch);
13902
+ if (!decreaseListLevel(commandState, view_10.dispatch)) decreaseIndent()(commandState, view_10.dispatch);
13362
13903
  return;
13363
13904
  }
13364
13905
  if (action_1 === "clearFormatting") {
13365
- clearFormatting(commandState, view_9.dispatch);
13906
+ clearFormatting(commandState, view_10.dispatch);
13366
13907
  return;
13367
13908
  }
13368
13909
  if (action_1 === "setRtl") {
13369
- setRtl(commandState, view_9.dispatch);
13910
+ setRtl(commandState, view_10.dispatch);
13370
13911
  return;
13371
13912
  }
13372
13913
  if (action_1 === "setLtr") {
13373
- setLtr(commandState, view_9.dispatch);
13914
+ setLtr(commandState, view_10.dispatch);
13374
13915
  return;
13375
13916
  }
13376
13917
  if (typeof action_1 === "object") switch (action_1.type) {
13377
13918
  case "alignment":
13378
- setAlignment(action_1.value)(commandState, view_9.dispatch);
13919
+ setAlignment(action_1.value)(commandState, view_10.dispatch);
13379
13920
  break;
13380
13921
  case "toggleDirection":
13381
- toggleBidi(commandState, view_9.dispatch);
13922
+ toggleBidi(commandState, view_10.dispatch);
13382
13923
  break;
13383
13924
  case "textColor": {
13384
13925
  const colorVal_0 = action_1.value;
13385
- if (typeof colorVal_0 === "string") setTextColor({ rgb: colorVal_0.replace("#", "") })(commandState, view_9.dispatch);
13386
- else if (colorVal_0.auto) clearTextColor(commandState, view_9.dispatch);
13926
+ if (typeof colorVal_0 === "string") setTextColor({ rgb: colorVal_0.replace("#", "") })(commandState, view_10.dispatch);
13927
+ else if (colorVal_0.auto) clearTextColor(commandState, view_10.dispatch);
13387
13928
  else {
13388
13929
  const themeColor = typeof colorVal_0.themeColor === "string" ? colorVal_0.themeColor : void 0;
13389
13930
  setTextColor({
@@ -13391,21 +13932,21 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13391
13932
  ...themeColor ? { themeColor } : {},
13392
13933
  ...colorVal_0.themeTint === void 0 ? {} : { themeTint: colorVal_0.themeTint },
13393
13934
  ...colorVal_0.themeShade === void 0 ? {} : { themeShade: colorVal_0.themeShade }
13394
- })(commandState, view_9.dispatch);
13935
+ })(commandState, view_10.dispatch);
13395
13936
  }
13396
13937
  break;
13397
13938
  }
13398
13939
  case "highlightColor":
13399
- setHighlight((action_1.value ? mapHexToHighlightName(action_1.value) : "") || action_1.value)(commandState, view_9.dispatch);
13940
+ setHighlight((action_1.value ? mapHexToHighlightName(action_1.value) : "") || action_1.value)(commandState, view_10.dispatch);
13400
13941
  break;
13401
13942
  case "fontSize":
13402
- setFontSize(pointsToHalfPoints(action_1.value))(commandState, view_9.dispatch);
13943
+ setFontSize(pointsToHalfPoints(action_1.value))(commandState, view_10.dispatch);
13403
13944
  break;
13404
13945
  case "fontFamily":
13405
- setFontFamily(action_1.value)(commandState, view_9.dispatch);
13946
+ setFontFamily(action_1.value)(commandState, view_10.dispatch);
13406
13947
  break;
13407
13948
  case "lineSpacing":
13408
- setLineSpacing(action_1.value)(commandState, view_9.dispatch);
13949
+ setLineSpacing(action_1.value)(commandState, view_10.dispatch);
13409
13950
  break;
13410
13951
  case "applyStyle": {
13411
13952
  const currentDoc_0 = historyStateRef.current;
@@ -13418,22 +13959,22 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13418
13959
  const styleName = styleResolver_0.getStyle(action_1.value)?.name;
13419
13960
  if (styleName) styleAttrs.styleName = styleName;
13420
13961
  styleAttrs.numbering = currentDoc_0?.package.numbering ? getCachedNumberingMap(currentDoc_0.package.numbering) : null;
13421
- applyStyle(action_1.value, styleAttrs)(commandState, view_9.dispatch);
13422
- } else applyStyle(action_1.value)(commandState, view_9.dispatch);
13962
+ applyStyle(action_1.value, styleAttrs)(commandState, view_10.dispatch);
13963
+ } else applyStyle(action_1.value)(commandState, view_10.dispatch);
13423
13964
  break;
13424
13965
  }
13425
13966
  default: break;
13426
13967
  }
13427
13968
  }, [getActiveEditorView, getCachedStyleResolver]);
13428
13969
  const captureFormatPainter = useCallback(() => {
13429
- const view_10 = getActiveEditorView();
13430
- capturedFormatMarksRef.current = view_10 ? captureFormatMarks(view_10.state) : null;
13970
+ const view_11 = getActiveEditorView();
13971
+ capturedFormatMarksRef.current = view_11 ? captureFormatMarks(view_11.state) : null;
13431
13972
  }, [getActiveEditorView]);
13432
13973
  const paintFormatToSelection = useCallback(() => {
13433
- const view_11 = getActiveEditorView();
13434
- if (!view_11) return false;
13435
- const applied = applyFormatMarks(capturedFormatMarksRef.current)(view_11.state, view_11.dispatch);
13436
- if (applied) requestAnimationFrame(() => view_11.focus());
13974
+ const view_12 = getActiveEditorView();
13975
+ if (!view_12) return false;
13976
+ const applied = applyFormatMarks(capturedFormatMarksRef.current)(view_12.state, view_12.dispatch);
13977
+ if (applied) requestAnimationFrame(() => view_12.focus());
13437
13978
  return applied;
13438
13979
  }, [getActiveEditorView]);
13439
13980
  const handleFormatPainter = useCallback((sticky) => {
@@ -13583,6 +14124,18 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13583
14124
  label: t("rejectChange"),
13584
14125
  dividerAfter: true
13585
14126
  });
14127
+ if (contextMenu.listNumbering.type === "listItem") items.push({
14128
+ action: "restartNumbering",
14129
+ label: t("contextMenu.restartNumbering")
14130
+ }, {
14131
+ action: "continueNumbering",
14132
+ label: t("contextMenu.continueNumbering"),
14133
+ disabled: !contextMenu.listNumbering.canContinue
14134
+ }, {
14135
+ action: "setNumberingValue",
14136
+ label: t("contextMenu.setNumberingValue"),
14137
+ dividerAfter: true
14138
+ });
13586
14139
  items.push({
13587
14140
  action: "selectAll",
13588
14141
  label: t("selectAll"),
@@ -13593,17 +14146,18 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13593
14146
  contextMenu.hasSelection,
13594
14147
  contextMenu.cursorInTable,
13595
14148
  contextMenu.cursorInTrackedChange,
14149
+ contextMenu.listNumbering,
13596
14150
  customContextMenuItems,
13597
14151
  readOnly,
13598
14152
  t
13599
14153
  ]);
13600
14154
  const handleContextMenuAction = useCallback(async (action_2) => {
13601
- const view_12 = getActiveEditorView();
13602
- if (!view_12) return;
14155
+ const view_13 = getActiveEditorView();
14156
+ if (!view_13) return;
13603
14157
  focusActiveEditor();
13604
14158
  if (readOnly && action_2 !== "copy" && action_2 !== "selectAll") return;
13605
14159
  if (action_2.startsWith("custom:")) {
13606
- const { from: from_2, to: to_2 } = contextMenu.selectionRange.from !== contextMenu.selectionRange.to ? contextMenu.selectionRange : view_12.state.selection;
14160
+ const { from: from_2, to: to_2 } = contextMenu.selectionRange.from !== contextMenu.selectionRange.to ? contextMenu.selectionRange : view_13.state.selection;
13607
14161
  onCustomContextAction?.(action_2.slice(7), {
13608
14162
  from: from_2,
13609
14163
  to: to_2
@@ -13613,16 +14167,16 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13613
14167
  switch (action_2) {
13614
14168
  case "cut": {
13615
14169
  if (readOnly) return;
13616
- const { from: from_7, to: to_7 } = view_12.state.selection;
13617
- const text_2 = view_12.state.doc.textBetween(from_7, to_7, "\n");
14170
+ const { from: from_7, to: to_7 } = view_13.state.selection;
14171
+ const text_2 = view_13.state.doc.textBetween(from_7, to_7, "\n");
13618
14172
  navigator.clipboard.writeText(text_2).catch(() => void 0);
13619
- view_12.dispatch(view_12.state.tr.deleteSelection());
14173
+ if (!deleteSelectionAsSuggestion(view_13.state, view_13.dispatch)) view_13.dispatch(view_13.state.tr.deleteSelection());
13620
14174
  onCut?.();
13621
14175
  break;
13622
14176
  }
13623
14177
  case "copy": {
13624
- const { from: cf, to: ct } = view_12.state.selection;
13625
- const copied = view_12.state.doc.textBetween(cf, ct, "\n");
14178
+ const { from: cf, to: ct } = view_13.state.selection;
14179
+ const copied = view_13.state.doc.textBetween(cf, ct, "\n");
13626
14180
  navigator.clipboard.writeText(copied).catch(() => void 0);
13627
14181
  onCopy?.();
13628
14182
  break;
@@ -13645,12 +14199,12 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13645
14199
  bubbles: true,
13646
14200
  cancelable: true
13647
14201
  });
13648
- view_12.dom.dispatchEvent(pasteEvent);
14202
+ view_13.dom.dispatchEvent(pasteEvent);
13649
14203
  } catch {
13650
14204
  try {
13651
14205
  const text_0 = await navigator.clipboard.readText();
13652
14206
  if (text_0) {
13653
- view_12.dispatch(view_12.state.tr.insertText(text_0));
14207
+ view_13.dispatch(view_13.state.tr.insertText(text_0));
13654
14208
  onPaste?.();
13655
14209
  }
13656
14210
  } catch {}
@@ -13659,9 +14213,9 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13659
14213
  case "pasteAsPlainText":
13660
14214
  try {
13661
14215
  const text = await navigator.clipboard.readText();
13662
- if (text && !view_12.isDestroyed) {
13663
- const slice = buildPlainTextSlice(text, view_12.state.schema);
13664
- view_12.dispatch(view_12.state.tr.replaceSelection(slice).scrollIntoView());
14216
+ if (text && !view_13.isDestroyed) {
14217
+ const slice = buildPlainTextSlice(text, view_13.state.schema);
14218
+ view_13.dispatch(view_13.state.tr.replaceSelection(slice).scrollIntoView());
13665
14219
  onPaste?.();
13666
14220
  }
13667
14221
  } catch {
@@ -13669,46 +14223,46 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13669
14223
  }
13670
14224
  break;
13671
14225
  case "delete": {
13672
- const { from: from_6, to: to_6 } = view_12.state.selection;
13673
- if (from_6 !== to_6) view_12.dispatch(view_12.state.tr.deleteRange(from_6, to_6));
14226
+ const { from: from_6, to: to_6 } = view_13.state.selection;
14227
+ if (from_6 !== to_6) view_13.dispatch(view_13.state.tr.deleteRange(from_6, to_6));
13674
14228
  break;
13675
14229
  }
13676
14230
  case "selectAll":
13677
- view_12.dispatch(view_12.state.tr.setSelection(TextSelection.create(view_12.state.doc, 0, view_12.state.doc.content.size)));
14231
+ view_13.dispatch(view_13.state.tr.setSelection(TextSelection.create(view_13.state.doc, 0, view_13.state.doc.content.size)));
13678
14232
  break;
13679
14233
  case "addRowAbove":
13680
- addRowAbove(view_12.state, view_12.dispatch);
14234
+ addRowAbove(view_13.state, view_13.dispatch);
13681
14235
  break;
13682
14236
  case "addRowBelow":
13683
- addRowBelow(view_12.state, view_12.dispatch);
14237
+ addRowBelow(view_13.state, view_13.dispatch);
13684
14238
  break;
13685
14239
  case "deleteRow":
13686
- deleteRow(view_12.state, view_12.dispatch);
14240
+ deleteRow(view_13.state, view_13.dispatch);
13687
14241
  break;
13688
14242
  case "addColumnLeft":
13689
- addColumnLeft(view_12.state, view_12.dispatch);
14243
+ addColumnLeft(view_13.state, view_13.dispatch);
13690
14244
  break;
13691
14245
  case "addColumnRight":
13692
- addColumnRight(view_12.state, view_12.dispatch);
14246
+ addColumnRight(view_13.state, view_13.dispatch);
13693
14247
  break;
13694
14248
  case "deleteColumn":
13695
- deleteColumn(view_12.state, view_12.dispatch);
14249
+ deleteColumn(view_13.state, view_13.dispatch);
13696
14250
  break;
13697
14251
  case "tableBordersAll":
13698
- setTableBorderPreset("all")(view_12.state, view_12.dispatch);
14252
+ setTableBorderPreset("all")(view_13.state, view_13.dispatch);
13699
14253
  break;
13700
14254
  case "tableBordersNone":
13701
- setTableBorderPreset("none")(view_12.state, view_12.dispatch);
14255
+ setTableBorderPreset("none")(view_13.state, view_13.dispatch);
13702
14256
  break;
13703
14257
  case "addComment": {
13704
- const { from: from_5, to: to_5 } = contextMenu.selectionRange.from !== contextMenu.selectionRange.to ? contextMenu.selectionRange : view_12.state.selection;
14258
+ const { from: from_5, to: to_5 } = contextMenu.selectionRange.from !== contextMenu.selectionRange.to ? contextMenu.selectionRange : view_13.state.selection;
13705
14259
  if (from_5 === to_5) break;
13706
14260
  const commentY = findSelectionYPosition(scrollContainerRef.current, editorContentRef.current, from_5) ?? getFallbackCommentYPosition(scrollContainerRef.current);
13707
14261
  setCommentSelectionRange({
13708
14262
  from: from_5,
13709
14263
  to: to_5
13710
14264
  });
13711
- if (!applyCommentMarkRange(view_12, {
14265
+ if (!applyCommentMarkRange(view_13, {
13712
14266
  from: from_5,
13713
14267
  to: to_5
13714
14268
  }, -1, { selectEnd: true })) break;
@@ -13719,17 +14273,26 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13719
14273
  break;
13720
14274
  }
13721
14275
  case "acceptChange": {
13722
- const { from: from_4, to: to_4 } = view_12.state.selection;
13723
- const range_1 = findChangeAtPosition(view_12.state, from_4, to_4);
13724
- acceptChange(range_1.from, range_1.to)(view_12.state, view_12.dispatch);
14276
+ const { from: from_4, to: to_4 } = view_13.state.selection;
14277
+ const range_1 = findChangeAtPosition(view_13.state, from_4, to_4);
14278
+ acceptChange(range_1.from, range_1.to)(view_13.state, view_13.dispatch);
13725
14279
  break;
13726
14280
  }
13727
14281
  case "rejectChange": {
13728
- const { from: from_3, to: to_3 } = view_12.state.selection;
13729
- const range_0 = findChangeAtPosition(view_12.state, from_3, to_3);
13730
- rejectChange(range_0.from, range_0.to)(view_12.state, view_12.dispatch);
14282
+ const { from: from_3, to: to_3 } = view_13.state.selection;
14283
+ const range_0 = findChangeAtPosition(view_13.state, from_3, to_3);
14284
+ rejectChange(range_0.from, range_0.to)(view_13.state, view_13.dispatch);
13731
14285
  break;
13732
14286
  }
14287
+ case "restartNumbering":
14288
+ restartNumbering(view_13.state, view_13.dispatch);
14289
+ break;
14290
+ case "continueNumbering":
14291
+ continueNumbering(view_13.state, view_13.dispatch);
14292
+ break;
14293
+ case "setNumberingValue":
14294
+ setNumberingValueDialogOpen(true);
14295
+ break;
13733
14296
  case "separator": break;
13734
14297
  }
13735
14298
  }, [
@@ -13775,41 +14338,42 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13775
14338
  const handleTopMarginChange = useCallback((twips_1) => handlePageSetupApply({ marginTop: twips_1 }), [handlePageSetupApply]);
13776
14339
  const handleBottomMarginChange = useCallback((twips_2) => handlePageSetupApply({ marginBottom: twips_2 }), [handlePageSetupApply]);
13777
14340
  const handleIndentLeftChange = useCallback((twips_3) => {
13778
- const view_13 = getActiveEditorView();
13779
- if (!view_13) return;
13780
- setIndentLeft(twips_3)(view_13.state, view_13.dispatch);
13781
- }, [getActiveEditorView]);
13782
- const handleIndentRightChange = useCallback((twips_4) => {
13783
14341
  const view_14 = getActiveEditorView();
13784
14342
  if (!view_14) return;
13785
- setIndentRight(twips_4)(view_14.state, view_14.dispatch);
14343
+ setIndentLeft(twips_3)(view_14.state, view_14.dispatch);
13786
14344
  }, [getActiveEditorView]);
13787
- const handleFirstLineIndentChange = useCallback((twips_5) => {
14345
+ const handleIndentRightChange = useCallback((twips_4) => {
13788
14346
  const view_15 = getActiveEditorView();
13789
14347
  if (!view_15) return;
13790
- if (twips_5 < 0) setIndentFirstLine(-twips_5, true)(view_15.state, view_15.dispatch);
13791
- else setIndentFirstLine(twips_5, false)(view_15.state, view_15.dispatch);
14348
+ setIndentRight(twips_4)(view_15.state, view_15.dispatch);
13792
14349
  }, [getActiveEditorView]);
13793
- const handleTabStopRemove = useCallback((positionTwips) => {
14350
+ const handleFirstLineIndentChange = useCallback((twips_5) => {
13794
14351
  const view_16 = getActiveEditorView();
13795
14352
  if (!view_16) return;
13796
- removeTabStop(positionTwips)(view_16.state, view_16.dispatch);
14353
+ if (twips_5 < 0) setIndentFirstLine(-twips_5, true)(view_16.state, view_16.dispatch);
14354
+ else setIndentFirstLine(twips_5, false)(view_16.state, view_16.dispatch);
14355
+ }, [getActiveEditorView]);
14356
+ const handleTabStopRemove = useCallback((positionTwips) => {
14357
+ const view_17 = getActiveEditorView();
14358
+ if (!view_17) return;
14359
+ removeTabStop(positionTwips)(view_17.state, view_17.dispatch);
13797
14360
  }, [getActiveEditorView]);
13798
14361
  const serializeCurrentDocx = useCallback(async (options) => {
13799
14362
  let tripwireResult = null;
13800
14363
  let savedBuffer = null;
13801
14364
  try {
13802
- const doc_1 = buildCurrentDocument();
14365
+ const current = buildCurrentDocument();
14366
+ const doc_1 = current ? withoutUnreferencedNotes(current) : null;
13803
14367
  if (!doc_1) return null;
13804
14368
  const { resolveSelectiveSaveFlags } = await import("@stll/folio-core/docx/selectiveSaveFlags");
13805
14369
  const flags = resolveSelectiveSaveFlags(featureFlags);
13806
14370
  const useSelectiveForSave = flags.selectiveSave && options?.mode !== FOLIO_DOCX_SERIALIZATION_MODE.full;
13807
14371
  const shouldAttemptSelective = useSelectiveForSave || flags.selectiveSaveTripwire;
13808
- const view_17 = pagedEditorRef.current?.getView();
14372
+ const view_18 = pagedEditorRef.current?.getView();
13809
14373
  const baselineBuffer = originalBufferRef.current;
13810
14374
  let selectiveBuffer = null;
13811
- if (shouldAttemptSelective && view_17 && baselineBuffer) {
13812
- const editorState = view_17.state;
14375
+ if (shouldAttemptSelective && view_18 && baselineBuffer) {
14376
+ const editorState = view_18.state;
13813
14377
  selectiveBuffer = await (await loadAttemptSelectiveSave())(doc_1, baselineBuffer, {
13814
14378
  changedParaIds: getChangedParagraphIds(editorState),
13815
14379
  structuralChange: hasStructuralChanges(editorState),
@@ -13823,19 +14387,28 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13823
14387
  ...doc_1,
13824
14388
  originalBuffer: baselineBuffer
13825
14389
  } : doc_1;
14390
+ const repackFull = async () => {
14391
+ const repackDocx = await loadRepackDocx();
14392
+ const repack = () => repackDocx(repackSourceDoc);
14393
+ return view_18 ? repackWithEditorSectionRemovals({
14394
+ state: view_18.state,
14395
+ document: repackSourceDoc,
14396
+ repack
14397
+ }) : repack();
14398
+ };
13826
14399
  if (!buffer) {
13827
- fullBuffer = await (await loadRepackDocx())(repackSourceDoc);
14400
+ fullBuffer = await repackFull();
13828
14401
  buffer = fullBuffer;
13829
14402
  } else if (flags.selectiveSaveTripwire) try {
13830
- fullBuffer = await (await loadRepackDocx())(repackSourceDoc);
14403
+ fullBuffer = await repackFull();
13831
14404
  } catch {}
13832
14405
  if (flags.selectiveSaveTripwire && fullBuffer && onSelectiveSaveTripwire) try {
13833
14406
  const { compareSelectiveVsFull } = await import("@stll/folio-core/docx/selectiveSaveTripwire");
13834
14407
  tripwireResult = await compareSelectiveVsFull(selectiveBuffer, fullBuffer);
13835
14408
  } catch {}
13836
- if (view_17) {
14409
+ if (view_18) {
13837
14410
  originalBufferRef.current = buffer;
13838
- view_17.dispatch(clearTrackedChanges(view_17.state));
14411
+ view_18.dispatch(clearTrackedChanges(view_18.state));
13839
14412
  }
13840
14413
  savedBuffer = buffer;
13841
14414
  } catch (error) {
@@ -13879,9 +14452,9 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13879
14452
  useImperativeHandle(ref, () => ({
13880
14453
  getDocument: () => buildCurrentDocument(),
13881
14454
  hasPendingChanges: () => {
13882
- const view_18 = pagedEditorRef.current?.getView();
13883
- if (!view_18) return false;
13884
- return commentsDirtyRef.current || getChangedParagraphIds(view_18.state).size > 0 || hasStructuralChanges(view_18.state) || hasUntrackedChanges(view_18.state);
14455
+ const view_19 = pagedEditorRef.current?.getView();
14456
+ if (!view_19) return false;
14457
+ return commentsDirtyRef.current || getChangedParagraphIds(view_19.state).size > 0 || hasStructuralChanges(view_19.state) || hasUntrackedChanges(view_19.state);
13885
14458
  },
13886
14459
  getEditorRef: () => pagedEditorRef.current,
13887
14460
  getEditor: () => pagedEditorRef.current?.getEditor() ?? null,
@@ -13906,6 +14479,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13906
14479
  findReplace.openReplace(readFindSelectionSeed());
13907
14480
  },
13908
14481
  loadDocument: (document_0) => {
14482
+ pendingSuggestionRegistryRef.current.clear();
13909
14483
  const editor_2 = pagedEditorRef.current?.getEditor();
13910
14484
  if (editor_2) {
13911
14485
  editor_2.loadDocument(document_0);
@@ -13913,18 +14487,21 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13913
14487
  }
13914
14488
  loadParsedDocument(document_0);
13915
14489
  },
13916
- loadDocumentBuffer: (buffer_1) => pagedEditorRef.current?.getEditor().loadDocx(buffer_1) ?? loadBuffer(buffer_1),
14490
+ loadDocumentBuffer: (buffer_1) => {
14491
+ pendingSuggestionRegistryRef.current.clear();
14492
+ return pagedEditorRef.current?.getEditor().loadDocx(buffer_1) ?? loadBuffer(buffer_1);
14493
+ },
13917
14494
  ensureEditorView: (options_2) => {
13918
14495
  pagedEditorRef.current?.ensureView(options_2);
13919
14496
  },
13920
14497
  createAIEditSnapshot: () => {
13921
- const view_19 = pagedEditorRef.current?.getView();
13922
- return view_19 ? createFolioAIEditSnapshot(view_19.state.doc) : null;
14498
+ const view_20 = pagedEditorRef.current?.getView();
14499
+ return view_20 ? createFolioAIEditSnapshot(view_20.state.doc) : null;
13923
14500
  },
13924
14501
  applyDocumentOperations: ({ snapshot, batch, author: operationAuthor = author }) => {
13925
14502
  assertSupportedFolioDocumentOperationVersion(batch.version);
13926
- const view_20 = pagedEditorRef.current?.getView();
13927
- if (!view_20) {
14503
+ const view_21 = pagedEditorRef.current?.getView();
14504
+ if (!view_21) {
13928
14505
  let status = "committed";
13929
14506
  if (batch.dryRun === true) status = "previewed";
13930
14507
  else if (batch.atomic === true) status = "rejected";
@@ -13943,16 +14520,17 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13943
14520
  };
13944
14521
  }
13945
14522
  const existingUndoEntry = documentOperationUndoEntriesRef.current.at(-1);
13946
- if (existingUndoEntry && (!view_20.state.doc.eq(existingUndoEntry.afterState.doc) || commentsRef.current !== existingUndoEntry.commentsAfter)) documentOperationUndoEntriesRef.current.length = 0;
14523
+ if (existingUndoEntry && (!view_21.state.doc.eq(existingUndoEntry.afterState.doc) || commentsRef.current !== existingUndoEntry.commentsAfter)) documentOperationUndoEntriesRef.current.length = 0;
13947
14524
  const commentsBefore = commentsRef.current;
13948
14525
  const createdComments = [];
13949
14526
  const operationView = {
13950
- state: view_20.state,
14527
+ state: view_21.state,
13951
14528
  dispatch: (transaction) => {
13952
- view_20.dispatch(closeHistory(transaction));
13953
- operationView.state = view_20.state;
14529
+ view_21.dispatch(closeHistory(transaction));
14530
+ operationView.state = view_21.state;
13954
14531
  }
13955
14532
  };
14533
+ const activeSuggestionIds = new Set(getSuggestions(view_21.state).map((s_0) => s_0.suggestionId));
13956
14534
  const result = applyFolioDocumentOperations({
13957
14535
  view: operationView,
13958
14536
  snapshot,
@@ -13968,10 +14546,19 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13968
14546
  id: `react-${String(documentOperationUndoHandleCursor++)}`
13969
14547
  })
13970
14548
  });
13971
- if (createdComments.length > 0) updateComments((currentComments_0) => [...currentComments_0, ...createdComments]);
14549
+ if (batch.mode === "suggested" && result.status === "committed") pendingSuggestionRegistryRef.current.recordApplied({
14550
+ snapshot,
14551
+ story: { type: "main" },
14552
+ operations: batch.operations,
14553
+ applied: result.applied,
14554
+ author: operationAuthor,
14555
+ activeSuggestionIds
14556
+ });
14557
+ const batchComments = appliedOperationComments(createdComments, result.applied);
14558
+ if (batchComments.length > 0) updateComments((currentComments_0) => [...currentComments_0, ...batchComments]);
13972
14559
  if (result.undoHandle !== null) documentOperationUndoEntriesRef.current.push({
13973
14560
  undoHandle: result.undoHandle,
13974
- afterState: view_20.state,
14561
+ afterState: view_21.state,
13975
14562
  commentsBefore,
13976
14563
  commentsAfter: commentsRef.current
13977
14564
  });
@@ -13991,18 +14578,18 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
13991
14578
  reason: "notLatest"
13992
14579
  };
13993
14580
  const entry_3 = entries.at(-1);
13994
- const view_21 = pagedEditorRef.current?.getView();
13995
- if (!entry_3 || !view_21) return {
14581
+ const view_22 = pagedEditorRef.current?.getView();
14582
+ if (!entry_3 || !view_22) return {
13996
14583
  status: "rejected",
13997
14584
  undoHandle,
13998
14585
  reason: "unknownHandle"
13999
14586
  };
14000
- if (!view_21.state.doc.eq(entry_3.afterState.doc) || commentsRef.current !== entry_3.commentsAfter) return {
14587
+ if (!view_22.state.doc.eq(entry_3.afterState.doc) || commentsRef.current !== entry_3.commentsAfter) return {
14001
14588
  status: "rejected",
14002
14589
  undoHandle,
14003
14590
  reason: "documentChanged"
14004
14591
  };
14005
- if (!undo(view_21.state, view_21.dispatch)) return {
14592
+ if (!undo(view_22.state, view_22.dispatch)) return {
14006
14593
  status: "rejected",
14007
14594
  undoHandle,
14008
14595
  reason: "documentChanged"
@@ -14016,8 +14603,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14016
14603
  };
14017
14604
  },
14018
14605
  applyAIEditOperations: ({ snapshot: snapshot_0, operations, mode = "tracked-changes", author: operationAuthor_0 = author }) => {
14019
- const view_22 = pagedEditorRef.current?.getView();
14020
- if (!view_22) return {
14606
+ const view_23 = pagedEditorRef.current?.getView();
14607
+ if (!view_23) return {
14021
14608
  applied: [],
14022
14609
  skipped: operations.map((operation_0) => ({
14023
14610
  id: operation_0.id,
@@ -14025,8 +14612,9 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14025
14612
  }))
14026
14613
  };
14027
14614
  const createdComments_0 = [];
14615
+ const activeSuggestionIds_0 = new Set(getSuggestions(view_23.state).map((s_1) => s_1.suggestionId));
14028
14616
  const { applied: applied_0, skipped: skipped_0 } = applyFolioDocumentOperations({
14029
- view: view_22,
14617
+ view: view_23,
14030
14618
  snapshot: snapshot_0,
14031
14619
  batch: {
14032
14620
  version: FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION,
@@ -14040,21 +14628,30 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14040
14628
  return comment_0.id;
14041
14629
  }
14042
14630
  });
14043
- if (createdComments_0.length > 0) updateComments((currentComments_1) => [...currentComments_1, ...createdComments_0]);
14631
+ const batchComments_0 = appliedOperationComments(createdComments_0, applied_0);
14632
+ if (batchComments_0.length > 0) updateComments((currentComments_1) => [...currentComments_1, ...batchComments_0]);
14633
+ if (mode === "suggested") pendingSuggestionRegistryRef.current.recordApplied({
14634
+ snapshot: snapshot_0,
14635
+ story: { type: "main" },
14636
+ operations,
14637
+ applied: applied_0,
14638
+ author: operationAuthor_0,
14639
+ activeSuggestionIds: activeSuggestionIds_0
14640
+ });
14044
14641
  return {
14045
14642
  applied: applied_0,
14046
14643
  skipped: skipped_0
14047
14644
  };
14048
14645
  },
14049
14646
  acceptAIEditOperation: (revisionId) => {
14050
- const view_23 = pagedEditorRef.current?.getView();
14051
- if (!view_23) return false;
14052
- return acceptAIEditRevision(revisionId)(view_23.state, view_23.dispatch);
14053
- },
14054
- rejectAIEditOperation: (revisionId_0) => {
14055
14647
  const view_24 = pagedEditorRef.current?.getView();
14056
14648
  if (!view_24) return false;
14057
- return rejectAIEditRevision(revisionId_0)(view_24.state, view_24.dispatch);
14649
+ return acceptAIEditRevision(revisionId)(view_24.state, view_24.dispatch);
14650
+ },
14651
+ rejectAIEditOperation: (revisionId_0) => {
14652
+ const view_25 = pagedEditorRef.current?.getView();
14653
+ if (!view_25) return false;
14654
+ return rejectAIEditRevision(revisionId_0)(view_25.state, view_25.dispatch);
14058
14655
  },
14059
14656
  undo: () => {
14060
14657
  if (getActiveEditorStory().type === "headerFooter" && hfEditorRef.current) return hfEditorRef.current.undo();
@@ -14069,44 +14666,44 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14069
14666
  return redone;
14070
14667
  },
14071
14668
  scrollToAIEditOperation: (revisionId_1) => {
14072
- const view_25 = pagedEditorRef.current?.getView();
14073
- if (!view_25) return false;
14074
- const range_2 = findAIEditRevisionRange(view_25.state, revisionId_1);
14669
+ const view_26 = pagedEditorRef.current?.getView();
14670
+ if (!view_26) return false;
14671
+ const range_2 = findAIEditRevisionRange(view_26.state, revisionId_1);
14075
14672
  if (!range_2) return false;
14076
- const { from: from_8, to: to_8 } = clampRangeToDocSize(view_25.state.doc.content.size, range_2);
14077
- const $from = view_25.state.doc.resolve(from_8);
14078
- const $to = view_25.state.doc.resolve(to_8);
14079
- view_25.dispatch(view_25.state.tr.setSelection(TextSelection.between($from, $to)));
14673
+ const { from: from_8, to: to_8 } = clampRangeToDocSize(view_26.state.doc.content.size, range_2);
14674
+ const $from = view_26.state.doc.resolve(from_8);
14675
+ const $to = view_26.state.doc.resolve(to_8);
14676
+ view_26.dispatch(view_26.state.tr.setSelection(TextSelection.between($from, $to)));
14080
14677
  requestAnimationFrame(() => {
14081
14678
  pagedEditorRef.current?.scrollToPosition(from_8);
14082
14679
  });
14083
14680
  return true;
14084
14681
  },
14085
14682
  scrollToBlock: (blockId, snapshot_1) => {
14086
- const view_26 = pagedEditorRef.current?.getView();
14087
- if (!view_26) return false;
14683
+ const view_27 = pagedEditorRef.current?.getView();
14684
+ if (!view_27) return false;
14088
14685
  const range_3 = resolveFolioAIBlockRange({
14089
14686
  blockId,
14090
- doc: view_26.state.doc,
14687
+ doc: view_27.state.doc,
14091
14688
  snapshot: snapshot_1
14092
14689
  });
14093
14690
  if (range_3 === null) return false;
14094
14691
  const { from: from_9, to: to_9 } = range_3;
14095
- const $from_0 = view_26.state.doc.resolve(from_9);
14096
- const $to_0 = view_26.state.doc.resolve(to_9);
14097
- view_26.dispatch(view_26.state.tr.setSelection(TextSelection.between($from_0, $to_0)));
14692
+ const $from_0 = view_27.state.doc.resolve(from_9);
14693
+ const $to_0 = view_27.state.doc.resolve(to_9);
14694
+ view_27.dispatch(view_27.state.tr.setSelection(TextSelection.between($from_0, $to_0)));
14098
14695
  requestAnimationFrame(() => {
14099
14696
  pagedEditorRef.current?.scrollToPosition(from_9);
14100
14697
  });
14101
14698
  return true;
14102
14699
  },
14103
14700
  highlightPassage: ({ blockId: blockId_0, text: text_5, snapshot: snapshot_2 }) => {
14104
- const view_27 = pagedEditorRef.current?.getView();
14105
- if (!view_27) return "none";
14701
+ const view_28 = pagedEditorRef.current?.getView();
14702
+ if (!view_28) return "none";
14106
14703
  const passageRange = resolvePassageRange({
14107
14704
  blockId: blockId_0,
14108
14705
  text: text_5,
14109
- doc: view_27.state.doc,
14706
+ doc: view_28.state.doc,
14110
14707
  snapshot: snapshot_2
14111
14708
  });
14112
14709
  if (passageRange !== null) {
@@ -14119,16 +14716,16 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14119
14716
  pagedEditorRef.current?.setPassageHighlight(null);
14120
14717
  const blockRange = resolveFolioAIBlockRange({
14121
14718
  blockId: blockId_0,
14122
- doc: view_27.state.doc,
14719
+ doc: view_28.state.doc,
14123
14720
  snapshot: snapshot_2
14124
14721
  });
14125
14722
  if (blockRange === null) return "none";
14126
14723
  const paraId_0 = getFolioParaIdFromBlockId(blockId_0);
14127
14724
  if (paraId_0 !== null && pagedEditorRef.current?.scrollToParaId(paraId_0, { highlight: {} })) return "block";
14128
14725
  const { from: from_10, to: to_10 } = blockRange;
14129
- const $from_1 = view_27.state.doc.resolve(from_10);
14130
- const $to_1 = view_27.state.doc.resolve(to_10);
14131
- view_27.dispatch(view_27.state.tr.setSelection(TextSelection.between($from_1, $to_1)));
14726
+ const $from_1 = view_28.state.doc.resolve(from_10);
14727
+ const $to_1 = view_28.state.doc.resolve(to_10);
14728
+ view_28.dispatch(view_28.state.tr.setSelection(TextSelection.between($from_1, $to_1)));
14132
14729
  requestAnimationFrame(() => {
14133
14730
  pagedEditorRef.current?.scrollToPosition(from_10);
14134
14731
  });
@@ -14138,91 +14735,143 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14138
14735
  pagedEditorRef.current?.setPassageHighlight(null);
14139
14736
  },
14140
14737
  showInDocument: (target_1, snapshot_3) => {
14141
- const view_28 = pagedEditorRef.current?.getView();
14142
- if (!view_28) return false;
14738
+ const view_29 = pagedEditorRef.current?.getView();
14739
+ if (!view_29) return false;
14143
14740
  const range_4 = target_1.type === "textRange" ? resolveFolioAITextRange({
14144
14741
  range: target_1,
14145
- doc: view_28.state.doc,
14742
+ doc: view_29.state.doc,
14146
14743
  snapshot: snapshot_3
14147
14744
  }) : resolveFolioAIBlockRange({
14148
14745
  blockId: target_1.blockId,
14149
- doc: view_28.state.doc,
14746
+ doc: view_29.state.doc,
14150
14747
  snapshot: snapshot_3
14151
14748
  });
14152
14749
  if (range_4 === null) return false;
14153
14750
  const { from: from_11, to: to_11 } = range_4;
14154
- const $from_2 = view_28.state.doc.resolve(from_11);
14155
- const $to_2 = view_28.state.doc.resolve(to_11);
14156
- view_28.dispatch(view_28.state.tr.setSelection(TextSelection.between($from_2, $to_2)));
14751
+ const $from_2 = view_29.state.doc.resolve(from_11);
14752
+ const $to_2 = view_29.state.doc.resolve(to_11);
14753
+ view_29.dispatch(view_29.state.tr.setSelection(TextSelection.between($from_2, $to_2)));
14157
14754
  requestAnimationFrame(() => {
14158
14755
  pagedEditorRef.current?.scrollToPosition(from_11);
14159
14756
  });
14160
14757
  return true;
14161
14758
  },
14162
14759
  getSuggestions: () => {
14163
- const view_29 = pagedEditorRef.current?.getView();
14164
- return view_29 ? getSuggestions(view_29.state) : [];
14760
+ const view_30 = pagedEditorRef.current?.getView();
14761
+ return view_30 ? getSuggestions(view_30.state) : [];
14165
14762
  },
14763
+ exportPendingSuggestions: () => {
14764
+ const view_31 = pagedEditorRef.current?.getView();
14765
+ const activeIds = new Set(view_31 ? getSuggestions(view_31.state).map((s_2) => s_2.suggestionId) : []);
14766
+ return pendingSuggestionRegistryRef.current.exportPendingSuggestions({
14767
+ activeSuggestionIds: activeIds,
14768
+ snapshotForStory: (story_0, commentIds) => story_0.type === "main" && view_31 ? createPendingSuggestionSourceSnapshot(view_31.state, commentIds) : null
14769
+ });
14770
+ },
14771
+ loadPendingSuggestions: (records) => pendingSuggestionRegistryRef.current.loadPendingSuggestions({
14772
+ records,
14773
+ snapshotForStory: (story_1) => {
14774
+ const view_32 = pagedEditorRef.current?.getView();
14775
+ return story_1.type === "main" && view_32 ? createFolioAIEditSnapshot(view_32.state.doc) : null;
14776
+ },
14777
+ sourceSnapshotForStory: (story_2, commentIds_0) => {
14778
+ const view_33 = pagedEditorRef.current?.getView();
14779
+ return story_2.type === "main" && view_33 ? createPendingSuggestionSourceSnapshot(view_33.state, commentIds_0) : null;
14780
+ },
14781
+ apply: (record, snapshot_4) => {
14782
+ const view_34 = pagedEditorRef.current?.getView();
14783
+ if (!view_34) return {
14784
+ applied: [],
14785
+ skipped: []
14786
+ };
14787
+ const createdComments_1 = [];
14788
+ const result_0 = applyFolioDocumentOperations({
14789
+ view: view_34,
14790
+ snapshot: snapshot_4,
14791
+ batch: {
14792
+ version: FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION,
14793
+ operations: [record.operation],
14794
+ mode: "suggested"
14795
+ },
14796
+ author: record.author,
14797
+ createCommentId: (commentText) => {
14798
+ const comment_1 = createComment(commentText, record.author);
14799
+ createdComments_1.push(comment_1);
14800
+ return comment_1.id;
14801
+ }
14802
+ });
14803
+ const appliedComments = appliedOperationComments(createdComments_1, result_0.applied);
14804
+ if (appliedComments.length > 0) updateComments((currentComments_2) => [...currentComments_2, ...appliedComments]);
14805
+ return {
14806
+ applied: result_0.applied,
14807
+ skipped: result_0.skipped
14808
+ };
14809
+ },
14810
+ activeSuggestionIds: () => {
14811
+ const view_35 = pagedEditorRef.current?.getView();
14812
+ return new Set(view_35 ? getSuggestions(view_35.state).map((s_3) => s_3.suggestionId) : []);
14813
+ }
14814
+ }),
14166
14815
  acceptSuggestion: (suggestionId, options_3) => {
14167
- const view_30 = pagedEditorRef.current?.getView();
14168
- if (!view_30) return {
14816
+ const view_36 = pagedEditorRef.current?.getView();
14817
+ if (!view_36) return {
14169
14818
  accepted: false,
14170
14819
  appliedAs: null
14171
14820
  };
14172
- const appliedAs = getSuggestions(view_30.state).find((s_0) => s_0.suggestionId === suggestionId)?.appliedAs ?? null;
14173
- const accepted = acceptSuggestion(suggestionId, { author: options_3?.author ?? author })(view_30.state, view_30.dispatch);
14821
+ const appliedAs = getSuggestions(view_36.state).find((s_4) => s_4.suggestionId === suggestionId)?.appliedAs ?? null;
14822
+ const accepted = acceptSuggestion(suggestionId, { author: options_3?.author ?? author })(view_36.state, view_36.dispatch);
14174
14823
  return {
14175
14824
  accepted,
14176
14825
  appliedAs: accepted ? appliedAs : null
14177
14826
  };
14178
14827
  },
14179
14828
  rejectSuggestion: (suggestionId_0) => {
14180
- const view_31 = pagedEditorRef.current?.getView();
14181
- if (!view_31) return false;
14182
- return rejectSuggestion(suggestionId_0)(view_31.state, view_31.dispatch);
14829
+ const view_37 = pagedEditorRef.current?.getView();
14830
+ if (!view_37) return false;
14831
+ return rejectSuggestion(suggestionId_0)(view_37.state, view_37.dispatch);
14183
14832
  },
14184
14833
  scrollToSuggestion: (suggestionId_1) => {
14185
- const view_32 = pagedEditorRef.current?.getView();
14186
- if (!view_32) return false;
14187
- const range_5 = findSuggestionRange(view_32.state, suggestionId_1);
14834
+ const view_38 = pagedEditorRef.current?.getView();
14835
+ if (!view_38) return false;
14836
+ const range_5 = findSuggestionRange(view_38.state, suggestionId_1);
14188
14837
  if (!range_5) return false;
14189
- const { from: from_12, to: to_12 } = clampRangeToDocSize(view_32.state.doc.content.size, range_5);
14190
- const $from_3 = view_32.state.doc.resolve(from_12);
14191
- const $to_3 = view_32.state.doc.resolve(to_12);
14192
- view_32.dispatch(view_32.state.tr.setSelection(TextSelection.between($from_3, $to_3)));
14838
+ const { from: from_12, to: to_12 } = clampRangeToDocSize(view_38.state.doc.content.size, range_5);
14839
+ const $from_3 = view_38.state.doc.resolve(from_12);
14840
+ const $to_3 = view_38.state.doc.resolve(to_12);
14841
+ view_38.dispatch(view_38.state.tr.setSelection(TextSelection.between($from_3, $to_3)));
14193
14842
  requestAnimationFrame(() => {
14194
14843
  pagedEditorRef.current?.scrollToPosition(from_12);
14195
14844
  });
14196
14845
  return true;
14197
14846
  },
14198
14847
  getTrackedChanges: () => {
14199
- const view_33 = pagedEditorRef.current?.getView();
14200
- return view_33 ? getTrackedChangesFromDoc(view_33.state.doc) : [];
14848
+ const view_39 = pagedEditorRef.current?.getView();
14849
+ return view_39 ? getTrackedChangesFromDoc(view_39.state.doc) : [];
14201
14850
  },
14202
14851
  getCommentAnchors: () => {
14203
- const view_34 = pagedEditorRef.current?.getView();
14204
- return view_34 ? getCommentAnchorsFromDoc(view_34.state.doc) : [];
14852
+ const view_40 = pagedEditorRef.current?.getView();
14853
+ return view_40 ? getCommentAnchorsFromDoc(view_40.state.doc) : [];
14205
14854
  },
14206
14855
  getSelectionText: () => {
14207
- const view_35 = pagedEditorRef.current?.getView();
14208
- return view_35 ? getSelectedText(view_35.state) : "";
14856
+ const view_41 = pagedEditorRef.current?.getView();
14857
+ return view_41 ? getSelectedText(view_41.state) : "";
14209
14858
  },
14210
- getPageText: (page_0) => {
14211
- const view_36 = pagedEditorRef.current?.getView();
14212
- if (!view_36) return null;
14213
- return getPageTextFromLayout(pagedEditorRef.current?.getEditor()?.getLayout() ?? null, view_36.state.doc, page_0);
14859
+ getPageText: (page_1) => {
14860
+ const view_42 = pagedEditorRef.current?.getView();
14861
+ if (!view_42) return null;
14862
+ return getPageTextFromLayout(pagedEditorRef.current?.getEditor()?.getLayout() ?? null, view_42.state.doc, page_1);
14214
14863
  },
14215
- getTargetPage: (target_2, snapshot_4) => {
14216
- const view_37 = pagedEditorRef.current?.getView();
14217
- if (!view_37) return null;
14864
+ getTargetPage: (target_2, snapshot_5) => {
14865
+ const view_43 = pagedEditorRef.current?.getView();
14866
+ if (!view_43) return null;
14218
14867
  const range_6 = target_2.type === "textRange" ? resolveFolioAITextRange({
14219
14868
  range: target_2,
14220
- doc: view_37.state.doc,
14221
- snapshot: snapshot_4
14869
+ doc: view_43.state.doc,
14870
+ snapshot: snapshot_5
14222
14871
  }) : resolveFolioAIBlockRange({
14223
14872
  blockId: target_2.blockId,
14224
- doc: view_37.state.doc,
14225
- snapshot: snapshot_4
14873
+ doc: view_43.state.doc,
14874
+ snapshot: snapshot_5
14226
14875
  });
14227
14876
  if (range_6 === null) return null;
14228
14877
  return pagedEditorRef.current?.getPageNumberForPmPos(range_6.from) ?? null;
@@ -14232,49 +14881,49 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14232
14881
  getScrollRoot: () => pagedEditorRef.current?.getScrollRoot() ?? null,
14233
14882
  onLayoutChange: (listener) => pagedEditorRef.current?.onLayoutChange(listener) ?? (() => {}),
14234
14883
  getContentControls: (filter = {}) => {
14235
- const view_38 = pagedEditorRef.current?.getView();
14236
- if (!view_38) return [];
14237
- return findBlockSdtMatches(view_38.state.doc, filter).map((match_0) => ({
14884
+ const view_44 = pagedEditorRef.current?.getView();
14885
+ if (!view_44) return [];
14886
+ return findBlockSdtMatches(view_44.state.doc, filter).map((match_0) => ({
14238
14887
  properties: blockSdtAttrsToSdtProperties(match_0.node),
14239
14888
  path: match_0.path,
14240
14889
  pmPos: match_0.pos
14241
14890
  }));
14242
14891
  },
14243
14892
  scrollToContentControl: (filter_0) => {
14244
- const view_39 = pagedEditorRef.current?.getView();
14245
- if (!view_39) return false;
14246
- const match_1 = findBlockSdtMatch(view_39.state.doc, filter_0);
14893
+ const view_45 = pagedEditorRef.current?.getView();
14894
+ if (!view_45) return false;
14895
+ const match_1 = findBlockSdtMatch(view_45.state.doc, filter_0);
14247
14896
  if (!match_1) return false;
14248
14897
  const inside = match_1.pos + 1;
14249
- const $pos = view_39.state.doc.resolve(inside);
14250
- view_39.dispatch(view_39.state.tr.setSelection(TextSelection.near($pos)));
14898
+ const $pos = view_45.state.doc.resolve(inside);
14899
+ view_45.dispatch(view_45.state.tr.setSelection(TextSelection.near($pos)));
14251
14900
  requestAnimationFrame(() => {
14252
14901
  pagedEditorRef.current?.scrollToPosition(inside);
14253
14902
  });
14254
14903
  return true;
14255
14904
  },
14256
14905
  setContentControlContent: (filter_1, input, options_4 = {}) => {
14257
- const view_40 = pagedEditorRef.current?.getView();
14258
- if (!view_40) return false;
14259
- const tr_0 = typeof input === "string" ? setContentControlContentTr(view_40.state, filter_1, input, options_4) : setContentControlContentBlocksTr(view_40.state, filter_1, input, options_4);
14906
+ const view_46 = pagedEditorRef.current?.getView();
14907
+ if (!view_46) return false;
14908
+ const tr_0 = typeof input === "string" ? setContentControlContentTr(view_46.state, filter_1, input, options_4) : setContentControlContentBlocksTr(view_46.state, filter_1, input, options_4);
14260
14909
  if (!tr_0) return false;
14261
- view_40.dispatch(tr_0);
14910
+ view_46.dispatch(tr_0);
14262
14911
  return true;
14263
14912
  },
14264
14913
  setContentControlValue: (filter_2, input_0, options_5 = {}) => {
14265
- const view_41 = pagedEditorRef.current?.getView();
14266
- if (!view_41) return false;
14267
- const tr_1 = setContentControlValueTr(view_41.state, filter_2, input_0, options_5);
14914
+ const view_47 = pagedEditorRef.current?.getView();
14915
+ if (!view_47) return false;
14916
+ const tr_1 = setContentControlValueTr(view_47.state, filter_2, input_0, options_5);
14268
14917
  if (!tr_1) return false;
14269
- view_41.dispatch(tr_1);
14918
+ view_47.dispatch(tr_1);
14270
14919
  return true;
14271
14920
  },
14272
14921
  removeContentControl: (filter_3, options_6 = {}) => {
14273
- const view_42 = pagedEditorRef.current?.getView();
14274
- if (!view_42) return false;
14275
- const tr_2 = removeContentControlTr(view_42.state, filter_3, options_6);
14922
+ const view_48 = pagedEditorRef.current?.getView();
14923
+ if (!view_48) return false;
14924
+ const tr_2 = removeContentControlTr(view_48.state, filter_3, options_6);
14276
14925
  if (!tr_2) return false;
14277
- view_42.dispatch(tr_2);
14926
+ view_48.dispatch(tr_2);
14278
14927
  return true;
14279
14928
  }
14280
14929
  }), [
@@ -14358,39 +15007,39 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14358
15007
  if (isDisplayMode(value)) setDisplayMode(value);
14359
15008
  }, [setDisplayMode]);
14360
15009
  const handleAcceptActiveChange = useCallback(() => {
14361
- const view_43 = pagedEditorRef.current?.getView();
14362
- if (!view_43) return;
14363
- const { from: from_13, to: to_13 } = view_43.state.selection;
14364
- const range_7 = findChangeAtPosition(view_43.state, from_13, to_13);
14365
- acceptChange(range_7.from, range_7.to)(view_43.state, view_43.dispatch);
15010
+ const view_49 = pagedEditorRef.current?.getView();
15011
+ if (!view_49) return;
15012
+ const { from: from_13, to: to_13 } = view_49.state.selection;
15013
+ const range_7 = findChangeAtPosition(view_49.state, from_13, to_13);
15014
+ acceptChange(range_7.from, range_7.to)(view_49.state, view_49.dispatch);
14366
15015
  }, []);
14367
15016
  const handleRejectActiveChange = useCallback(() => {
14368
- const view_44 = pagedEditorRef.current?.getView();
14369
- if (!view_44) return;
14370
- const { from: from_14, to: to_14 } = view_44.state.selection;
14371
- const range_8 = findChangeAtPosition(view_44.state, from_14, to_14);
14372
- rejectChange(range_8.from, range_8.to)(view_44.state, view_44.dispatch);
15017
+ const view_50 = pagedEditorRef.current?.getView();
15018
+ if (!view_50) return;
15019
+ const { from: from_14, to: to_14 } = view_50.state.selection;
15020
+ const range_8 = findChangeAtPosition(view_50.state, from_14, to_14);
15021
+ rejectChange(range_8.from, range_8.to)(view_50.state, view_50.dispatch);
14373
15022
  }, []);
14374
15023
  const handlePreviousChange = useCallback(() => {
14375
- const view_45 = pagedEditorRef.current?.getView();
14376
- if (!view_45) return;
14377
- const { from: from_15 } = view_45.state.selection;
14378
- const change = findPreviousChange(view_45.state, from_15);
15024
+ const view_51 = pagedEditorRef.current?.getView();
15025
+ if (!view_51) return;
15026
+ const { from: from_15 } = view_51.state.selection;
15027
+ const change = findPreviousChange(view_51.state, from_15);
14379
15028
  if (!change) return;
14380
- view_45.dispatch(view_45.state.tr.setSelection(TextSelection.create(view_45.state.doc, change.from, change.to)));
14381
- view_45.focus();
15029
+ view_51.dispatch(view_51.state.tr.setSelection(TextSelection.create(view_51.state.doc, change.from, change.to)));
15030
+ view_51.focus();
14382
15031
  requestAnimationFrame(() => {
14383
15032
  pagedEditorRef.current?.scrollToPosition(change.from);
14384
15033
  });
14385
15034
  }, []);
14386
15035
  const handleNextChange = useCallback(() => {
14387
- const view_46 = pagedEditorRef.current?.getView();
14388
- if (!view_46) return;
14389
- const { to: to_15 } = view_46.state.selection;
14390
- const change_0 = findNextChange(view_46.state, to_15);
15036
+ const view_52 = pagedEditorRef.current?.getView();
15037
+ if (!view_52) return;
15038
+ const { to: to_15 } = view_52.state.selection;
15039
+ const change_0 = findNextChange(view_52.state, to_15);
14391
15040
  if (!change_0) return;
14392
- view_46.dispatch(view_46.state.tr.setSelection(TextSelection.create(view_46.state.doc, change_0.from, change_0.to)));
14393
- view_46.focus();
15041
+ view_52.dispatch(view_52.state.tr.setSelection(TextSelection.create(view_52.state.doc, change_0.from, change_0.to)));
15042
+ view_52.focus();
14394
15043
  requestAnimationFrame(() => {
14395
15044
  pagedEditorRef.current?.scrollToPosition(change_0.from);
14396
15045
  });
@@ -14560,21 +15209,21 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14560
15209
  requestAnimationFrame(syncCommentHighlightStyles);
14561
15210
  }, [onScrollTopChange, syncCommentHighlightStyles]);
14562
15211
  const handlePagedSelectionChange = useCallback((_from, _to) => {
14563
- const view_47 = getActiveEditorView() ?? pagedEditorRef.current?.getView() ?? null;
14564
- handleSelectionChange(view_47 ? extractSelectionState(view_47.state) : null);
15212
+ const view_53 = getActiveEditorView() ?? pagedEditorRef.current?.getView() ?? null;
15213
+ handleSelectionChange(view_53 ? extractSelectionState(view_53.state) : null);
14565
15214
  }, [getActiveEditorView, handleSelectionChange]);
14566
15215
  const handleTotalPagesChange = useCallback((totalPages) => {
14567
15216
  setScrollPageInfo((previous) => updateScrollPageTotal(previous, totalPages));
14568
15217
  }, [setScrollPageInfo]);
14569
15218
  const handleCommentClick = useCallback((id) => setActiveCommentId(id), [setActiveCommentId]);
14570
15219
  const handleCommentResolve = useCallback((id_0) => {
14571
- updateComments((previous_0) => previous_0.map((comment_1) => comment_1.id === id_0 ? {
14572
- ...comment_1,
15220
+ updateComments((previous_0) => previous_0.map((comment_2) => comment_2.id === id_0 ? {
15221
+ ...comment_2,
14573
15222
  done: true
14574
- } : comment_1));
15223
+ } : comment_2));
14575
15224
  }, [updateComments]);
14576
15225
  const handleCommentDelete = useCallback((id_1) => {
14577
- updateComments((previous_1) => previous_1.filter((comment_2) => comment_2.id !== id_1 && comment_2.parentId !== id_1));
15226
+ updateComments((previous_1) => previous_1.filter((comment_3) => comment_3.id !== id_1 && comment_3.parentId !== id_1));
14578
15227
  if (activeCommentId === id_1) setActiveCommentId(null);
14579
15228
  }, [
14580
15229
  activeCommentId,
@@ -14585,19 +15234,19 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14585
15234
  updateComments((previous_2) => [...previous_2, createComment(text_6, author, id_2)]);
14586
15235
  }, [author, updateComments]);
14587
15236
  const handleAddComment = useCallback((addText) => {
14588
- const comment_3 = createComment(addText, author);
14589
- const view_48 = pagedEditorRef.current?.getView();
14590
- if (!view_48 || !commentSelectionRange) return false;
14591
- if (!applyCommentMarkRange(view_48, commentSelectionRange, comment_3.id, { replacePending: true })) return false;
14592
- const commentAuthor_2 = getCommentAuthorKey(comment_3.author);
14593
- setVisibleCommentAuthors((current) => {
14594
- if (current === null) return null;
14595
- const next_1 = new Set(current);
15237
+ const comment_4 = createComment(addText, author);
15238
+ const view_54 = pagedEditorRef.current?.getView();
15239
+ if (!view_54 || !commentSelectionRange) return false;
15240
+ if (!applyCommentMarkRange(view_54, commentSelectionRange, comment_4.id, { replacePending: true })) return false;
15241
+ const commentAuthor_2 = getCommentAuthorKey(comment_4.author);
15242
+ setVisibleCommentAuthors((current_0) => {
15243
+ if (current_0 === null) return null;
15244
+ const next_1 = new Set(current_0);
14596
15245
  next_1.add(commentAuthor_2);
14597
15246
  return next_1;
14598
15247
  });
14599
- setActiveCommentId(comment_3.id);
14600
- updateComments((previous_3) => [...previous_3, comment_3]);
15248
+ setActiveCommentId(comment_4.id);
15249
+ updateComments((previous_3) => [...previous_3, comment_4]);
14601
15250
  pagedEditorRef.current?.relayout();
14602
15251
  requestAnimationFrame(() => {
14603
15252
  syncCommentHighlightStyles();
@@ -14622,8 +15271,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14622
15271
  updateComments((previous_4) => [...previous_4, createComment(text_7, author, revisionId_2)]);
14623
15272
  }, [author, updateComments]);
14624
15273
  const handleCancelAddComment = useCallback(() => {
14625
- const view_49 = pagedEditorRef.current?.getView();
14626
- if (view_49 && commentSelectionRange) removePendingCommentMarkRange(view_49, commentSelectionRange);
15274
+ const view_55 = pagedEditorRef.current?.getView();
15275
+ if (view_55 && commentSelectionRange) removePendingCommentMarkRange(view_55, commentSelectionRange);
14627
15276
  setIsAddingComment(false);
14628
15277
  setCommentSelectionRange(null);
14629
15278
  setAddCommentYPosition(null);
@@ -14639,27 +15288,89 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14639
15288
  })?.revisionId ?? null;
14640
15289
  }, []);
14641
15290
  const handleSidebarAcceptChange = useCallback((from_17, to_17) => {
14642
- const view_50 = pagedEditorRef.current?.getView();
14643
- if (!view_50) return;
15291
+ const view_56 = pagedEditorRef.current?.getView();
15292
+ if (!view_56) return;
14644
15293
  const revisionId_3 = resolveSidebarChangeRevisionId(from_17, to_17);
14645
15294
  if (revisionId_3 === null) return;
14646
- acceptAIEditRevision(revisionId_3)(view_50.state, view_50.dispatch);
15295
+ acceptAIEditRevision(revisionId_3)(view_56.state, view_56.dispatch);
14647
15296
  extractTrackedChanges();
14648
15297
  }, [extractTrackedChanges, resolveSidebarChangeRevisionId]);
14649
15298
  const handleSidebarRejectChange = useCallback((from_18, to_18) => {
14650
- const view_51 = pagedEditorRef.current?.getView();
14651
- if (!view_51) return;
15299
+ const view_57 = pagedEditorRef.current?.getView();
15300
+ if (!view_57) return;
14652
15301
  const revisionId_4 = resolveSidebarChangeRevisionId(from_18, to_18);
14653
15302
  if (revisionId_4 === null) return;
14654
- rejectAIEditRevision(revisionId_4)(view_51.state, view_51.dispatch);
15303
+ rejectAIEditRevision(revisionId_4)(view_57.state, view_57.dispatch);
14655
15304
  extractTrackedChanges();
14656
15305
  }, [extractTrackedChanges, resolveSidebarChangeRevisionId]);
14657
15306
  const commentsPageWidth = history.state?.package.document.finalSectionProperties?.pageWidth;
15307
+ const dismissCommentsDrawer = useCallback(() => {
15308
+ if (isAddingComment) handleCancelAddComment();
15309
+ setPanelOverlay("none");
15310
+ setShowCommentsSidebar(false);
15311
+ setActiveCommentId(null);
15312
+ }, [
15313
+ handleCancelAddComment,
15314
+ isAddingComment,
15315
+ setActiveCommentId,
15316
+ setPanelOverlay,
15317
+ setShowCommentsSidebar
15318
+ ]);
15319
+ useEffect(() => {
15320
+ if (isAddingComment && panels.layout.comments === "drawer") setPanelOverlay("comments");
15321
+ }, [
15322
+ isAddingComment,
15323
+ panels.layout.comments,
15324
+ setPanelOverlay
15325
+ ]);
15326
+ const toggleComments = useCallback(() => {
15327
+ if (commentsSurface === "drawer") {
15328
+ dismissCommentsDrawer();
15329
+ return;
15330
+ }
15331
+ if (commentsSurface === "column") {
15332
+ setShowCommentsSidebar(false);
15333
+ setActiveCommentId(null);
15334
+ return;
15335
+ }
15336
+ if (visibleCommentAuthorSet.size === 0) setVisibleCommentAuthors(null);
15337
+ setShowCommentsSidebar(true);
15338
+ if (layoutWithCommentsOpen().comments === "drawer") setPanelOverlay("comments");
15339
+ }, [
15340
+ commentsSurface,
15341
+ dismissCommentsDrawer,
15342
+ layoutWithCommentsOpen,
15343
+ setActiveCommentId,
15344
+ setPanelOverlay,
15345
+ setShowCommentsSidebar,
15346
+ setVisibleCommentAuthors,
15347
+ visibleCommentAuthorSet.size
15348
+ ]);
15349
+ const openCommentThreadCount = useMemo(() => countOpenCommentThreads(comments), [comments]);
15350
+ const outlineToggle = (() => {
15351
+ if (panels.layout.outline !== "drawer") return "absent";
15352
+ return panelOverlay === "outline" ? "open" : "closed";
15353
+ })();
15354
+ const panelToggles = useMemo(() => /* @__PURE__ */ jsx(PanelToggles, {
15355
+ outline: outlineToggle,
15356
+ onToggleOutline: toggleOutlineOverlay,
15357
+ commentsShown: commentsSurface !== null,
15358
+ commentCount: openCommentThreadCount,
15359
+ onToggleComments: toggleComments
15360
+ }), [
15361
+ commentsSurface,
15362
+ openCommentThreadCount,
15363
+ outlineToggle,
15364
+ toggleComments,
15365
+ toggleOutlineOverlay
15366
+ ]);
14658
15367
  const commentsSidebarOverlay = useMemo(() => {
14659
- if (!showCommentsSidebar) return;
15368
+ if (commentsSurface === null) return;
14660
15369
  return /* @__PURE__ */ jsx(Suspense, {
14661
15370
  fallback: null,
14662
15371
  children: /* @__PURE__ */ jsx(CommentsSidebar, {
15372
+ surface: commentsSurface,
15373
+ onDismiss: dismissCommentsDrawer,
14663
15374
  activeCommentId,
14664
15375
  comments: visibleComments,
14665
15376
  anchorPositions,
@@ -14694,7 +15405,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14694
15405
  handleSidebarRejectChange,
14695
15406
  handleTrackedChangeReply,
14696
15407
  isAddingComment,
14697
- showCommentsSidebar,
15408
+ commentsSurface,
15409
+ dismissCommentsDrawer,
14698
15410
  visibleComments
14699
15411
  ]);
14700
15412
  const getActiveHfView = useCallback(() => activeHfRId ? pagedEditorRef.current?.getHfView(activeHfRId) ?? null : null, [activeHfRId]);
@@ -14716,6 +15428,10 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14716
15428
  };
14717
15429
  requestAnimationFrame(flash);
14718
15430
  }, []);
15431
+ const handleOutlineJump = useCallback((id_3) => {
15432
+ markHeadingJumped(id_3);
15433
+ handleOutlineHeadingClick(Number(id_3));
15434
+ }, [handleOutlineHeadingClick, markHeadingJumped]);
14719
15435
  const handleTextContextAction = useCallback((action_3) => {
14720
15436
  handleContextMenuAction(action_3);
14721
15437
  }, [handleContextMenuAction]);
@@ -14727,8 +15443,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14727
15443
  }, [readOnly]);
14728
15444
  const closeTableProperties = useCallback(() => setTablePropsOpen(false), []);
14729
15445
  const applyTableProperties = useCallback((props_0) => {
14730
- const view_52 = getActiveEditorView();
14731
- if (view_52) setTableProperties(props_0)(view_52.state, view_52.dispatch);
15446
+ const view_58 = getActiveEditorView();
15447
+ if (view_58) setTableProperties(props_0)(view_58.state, view_58.dispatch);
14732
15448
  }, [getActiveEditorView]);
14733
15449
  const closeImagePosition = useCallback(() => setImagePositionOpen(false), [setImagePositionOpen]);
14734
15450
  const closeImageProperties = useCallback(() => setImagePropsOpen(false), [setImagePropsOpen]);
@@ -14736,8 +15452,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14736
15452
  const closeFootnoteProperties = useCallback(() => setFootnotePropsOpen(false), []);
14737
15453
  const closeInsertSymbol = useCallback(() => setShowInsertSymbol(false), []);
14738
15454
  const insertSymbol = useCallback((symbol) => {
14739
- const view_53 = getActiveEditorView();
14740
- if (view_53) view_53.dispatch(view_53.state.tr.insertText(symbol).scrollIntoView());
15455
+ const view_59 = getActiveEditorView();
15456
+ if (view_59) view_59.dispatch(view_59.state.tr.insertText(symbol).scrollIntoView());
14741
15457
  }, [getActiveEditorView]);
14742
15458
  const imagePropertiesCurrentData = useMemo(() => buildImagePropertiesData(state.pmImageContext), [state.pmImageContext]);
14743
15459
  const currentFindResult = findResultRef.current;
@@ -14818,6 +15534,20 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14818
15534
  footnotePropsOpen,
14819
15535
  handleApplyFootnoteProperties
14820
15536
  ]);
15537
+ const closeNumberingValueDialog = useCallback(() => setNumberingValueDialogOpen(false), []);
15538
+ const applyNumberingValue = useCallback((value_0) => {
15539
+ const view_60 = getActiveEditorView();
15540
+ if (view_60) setNumberingValue(value_0)(view_60.state, view_60.dispatch);
15541
+ }, [getActiveEditorView]);
15542
+ const numberingValueDialog = useMemo(() => ({
15543
+ isOpen: numberingValueDialogOpen,
15544
+ onClose: closeNumberingValueDialog,
15545
+ onApply: applyNumberingValue
15546
+ }), [
15547
+ applyNumberingValue,
15548
+ closeNumberingValueDialog,
15549
+ numberingValueDialogOpen
15550
+ ]);
14821
15551
  const insertSymbolDialog = useMemo(() => ({
14822
15552
  isOpen: showInsertSymbol,
14823
15553
  onClose: closeInsertSymbol,
@@ -14842,6 +15572,13 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14842
15572
  minWidth: 0,
14843
15573
  flexDirection: "row"
14844
15574
  };
15575
+ const panelsRowStyle = {
15576
+ position: "relative",
15577
+ display: "flex",
15578
+ flex: 1,
15579
+ minHeight: 0,
15580
+ minWidth: 0
15581
+ };
14845
15582
  const editorContainerStyle = {
14846
15583
  flex: 1,
14847
15584
  minHeight: 0,
@@ -14900,7 +15637,6 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14900
15637
  },
14901
15638
  children: [
14902
15639
  showToolbar && !readOnlyProp && /* @__PURE__ */ jsx("div", {
14903
- ref: toolbarRefCallback,
14904
15640
  className: "z-50 flex flex-shrink-0 flex-col gap-0 bg-[var(--doc-page)]",
14905
15641
  children: /* @__PURE__ */ jsx(FormattingBar, {
14906
15642
  currentFormatting: state.selectionFormatting,
@@ -14933,6 +15669,7 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14933
15669
  onInsertSymbol: handleOpenInsertSymbol,
14934
15670
  priorityExtra: toolbarPriorityExtra,
14935
15671
  inlineExtra: toolbarInlineExtra,
15672
+ panelToggles,
14936
15673
  ...history.state.package.styles?.styles ? { documentStyles: history.state.package.styles.styles } : {},
14937
15674
  ...state.pmImageContext ? { imageContext: state.pmImageContext } : {},
14938
15675
  ...state.pmTableContext ? { tableContext: state.pmTableContext } : {},
@@ -14940,241 +15677,273 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
14940
15677
  })
14941
15678
  }),
14942
15679
  /* @__PURE__ */ jsxs("div", {
14943
- ref: scrollContainerRef,
14944
- style: editorContainerStyle,
14945
- "data-folio-scroll": "",
14946
- onScroll: handleEditorScroll,
14947
- children: [rulerVisible && !readOnly && /* @__PURE__ */ jsx("div", {
14948
- style: {
14949
- position: "sticky",
14950
- top: 0,
14951
- zIndex: 20,
14952
- display: "flex",
14953
- justifyContent: "center",
14954
- flexShrink: 0,
14955
- paddingBlock: 4,
14956
- paddingLeft: 20,
14957
- paddingRight: 20 + (showCommentsSidebar ? 304 : 0),
14958
- minWidth: twipsToPixels(effectiveSectionProperties?.pageWidth ?? 12240) * zoom + 40 + (showCommentsSidebar ? 304 : 0),
14959
- backgroundColor: "var(--muted)",
14960
- transition: "padding 0.2s ease"
14961
- },
14962
- children: /* @__PURE__ */ jsx(HorizontalRuler, {
14963
- sectionProps: effectiveSectionProperties ?? null,
14964
- zoom,
14965
- unit: rulerUnit,
14966
- editable: !readOnly,
14967
- onLeftMarginChange: handleLeftMarginChange,
14968
- onRightMarginChange: handleRightMarginChange,
14969
- indentLeft: state.paragraphIndentLeft,
14970
- indentRight: state.paragraphIndentRight,
14971
- onIndentLeftChange: handleIndentLeftChange,
14972
- onIndentRightChange: handleIndentRightChange,
14973
- firstLineIndent: state.paragraphFirstLineIndent,
14974
- hangingIndent: state.paragraphHangingIndent,
14975
- onFirstLineIndentChange: handleFirstLineIndentChange,
14976
- tabStops: state.paragraphTabs,
14977
- onTabStopRemove: handleTabStopRemove
14978
- })
14979
- }), /* @__PURE__ */ jsx("div", {
14980
- style: {
14981
- display: "flex",
14982
- flex: 1,
14983
- minHeight: 0,
14984
- position: "relative"
14985
- },
14986
- children: /* @__PURE__ */ jsxs("div", {
14987
- ref: editorContentRef,
14988
- style: {
14989
- position: "relative",
14990
- flex: 1,
14991
- minWidth: 0
14992
- },
14993
- onMouseDown: containedHandler((e_0) => {
14994
- if (e_0.target === e_0.currentTarget) {
14995
- e_0.preventDefault();
14996
- pagedEditorRef.current?.focus();
14997
- }
14998
- }),
14999
- onContextMenu: handleEditorContextMenu,
15000
- children: [
15001
- rulerVisible && !readOnly && /* @__PURE__ */ jsx("div", {
15680
+ ref: panels.rowRef,
15681
+ className: "folio-panels-row",
15682
+ style: panelsRowStyle,
15683
+ "data-folio-panel-tier": panels.layout.tier,
15684
+ "data-folio-outline": panels.layout.outline,
15685
+ "data-folio-comments": panels.layout.comments,
15686
+ children: [
15687
+ (panels.layout.outline === "column" || panels.layout.outline === "rail") && /* @__PURE__ */ jsx(DocumentOutline, {
15688
+ headings: outlineHeadings,
15689
+ scrollContainerRef,
15690
+ docSize: pagedEditorRef.current?.getView()?.state.doc.content.size ?? 0,
15691
+ activeId: activeHeadingId,
15692
+ onJump: handleOutlineJump,
15693
+ surface: panels.layout.outline,
15694
+ expanded: panelOverlay === "outline",
15695
+ onExpand: toggleOutlineOverlay
15696
+ }),
15697
+ /* @__PURE__ */ jsxs("div", {
15698
+ ref: scrollContainerRef,
15699
+ style: editorContainerStyle,
15700
+ "data-folio-scroll": "",
15701
+ onScroll: handleEditorScroll,
15702
+ children: [rulerVisible && !readOnly && /* @__PURE__ */ jsx("div", {
15703
+ "data-testid": "folio-horizontal-ruler",
15704
+ style: {
15705
+ position: "sticky",
15706
+ top: 0,
15707
+ zIndex: 20,
15708
+ display: "flex",
15709
+ justifyContent: "center",
15710
+ flexShrink: 0,
15711
+ paddingBlock: 4,
15712
+ paddingLeft: 20,
15713
+ paddingRight: 20 + panels.layout.commentsGutter,
15714
+ minWidth: twipsToPixels(effectiveSectionProperties?.pageWidth ?? 12240) * zoom + 40 + panels.layout.commentsGutter,
15715
+ background: "var(--doc-canvas-surface)",
15716
+ transition: "padding 0.2s ease"
15717
+ },
15718
+ children: /* @__PURE__ */ jsx(HorizontalRuler, {
15719
+ sectionProps: effectiveSectionProperties ?? null,
15720
+ zoom,
15721
+ unit: rulerUnit,
15722
+ editable: !readOnly,
15723
+ onLeftMarginChange: handleLeftMarginChange,
15724
+ onRightMarginChange: handleRightMarginChange,
15725
+ indentLeft: state.paragraphIndentLeft,
15726
+ indentRight: state.paragraphIndentRight,
15727
+ onIndentLeftChange: handleIndentLeftChange,
15728
+ onIndentRightChange: handleIndentRightChange,
15729
+ firstLineIndent: state.paragraphFirstLineIndent,
15730
+ hangingIndent: state.paragraphHangingIndent,
15731
+ onFirstLineIndentChange: handleFirstLineIndentChange,
15732
+ tabStops: state.paragraphTabs,
15733
+ onTabStopRemove: handleTabStopRemove
15734
+ })
15735
+ }), /* @__PURE__ */ jsx("div", {
15736
+ style: {
15737
+ display: "flex",
15738
+ flex: 1,
15739
+ minHeight: 0,
15740
+ position: "relative"
15741
+ },
15742
+ children: /* @__PURE__ */ jsxs("div", {
15743
+ ref: editorContentRef,
15002
15744
  style: {
15003
- position: "absolute",
15004
- left: 0,
15005
- top: 0,
15006
- zIndex: 20,
15007
- paddingTop: 24 * zoom
15745
+ position: "relative",
15746
+ flex: 1,
15747
+ minWidth: 0
15008
15748
  },
15009
- children: /* @__PURE__ */ jsx(VerticalRuler, {
15010
- sectionProps: effectiveSectionProperties ?? null,
15011
- zoom,
15012
- unit: rulerUnit,
15013
- editable: !readOnly,
15014
- onTopMarginChange: handleTopMarginChange,
15015
- onBottomMarginChange: handleBottomMarginChange
15016
- })
15017
- }),
15018
- /* @__PURE__ */ jsx(PagedEditor, {
15019
- ref: pagedEditorRef,
15020
- document: history.state,
15021
- documentIO,
15022
- documentIdentity: loadedDocumentIdentity,
15023
- ...fonts !== void 0 ? { fonts } : {},
15024
- theme: history.state.package.theme || theme || null,
15025
- sectionProperties: effectiveSectionProperties ?? null,
15026
- headerContent,
15027
- footerContent,
15028
- firstPageHeaderContent,
15029
- firstPageFooterContent,
15030
- headerContentRId: activeHeaderRId,
15031
- footerContentRId: activeFooterRId,
15032
- firstPageHeaderContentRId: activeFirstHeaderRId,
15033
- firstPageFooterContentRId: activeFirstFooterRId,
15034
- ...history.state.package.styles ? { styles: history.state.package.styles } : {},
15035
- onHeaderFooterDoubleClick: showHeaderFooterEditing ? handleHeaderFooterStoryOpen : void 0,
15036
- hfEditMode: hfEditPosition,
15037
- activeHeaderFooterRId: activeHfRId,
15038
- onBodyClick: handleBodyClick,
15039
- onActiveNoteStoryChange: handleActiveNoteStoryChange,
15040
- zoom,
15041
- ...pageRenderer === void 0 ? {} : { pageRenderer },
15042
- showMarginGuides,
15043
- ...marginGuideColor !== void 0 ? { marginGuideColor } : {},
15044
- readOnly,
15045
- onDocumentChange: handleDocumentChange,
15046
- extensionManager,
15047
- suggestionModeActive: editingMode === "suggesting",
15048
- suggestionAuthor: author,
15049
- ...onCopy !== void 0 ? { onCopy } : {},
15050
- ...onCut !== void 0 ? { onCut } : {},
15051
- ...onPaste !== void 0 ? { onPaste } : {},
15052
- ...onReadonlyEditAttempt !== void 0 ? { onReadOnlyEditAttempt: onReadonlyEditAttempt } : {},
15053
- onSelectionChange: handlePagedSelectionChange,
15054
- ...onSelectionTextChange !== void 0 ? { onSelectionTextChange } : {},
15055
- ...onEditorViewReady !== void 0 ? { onEditorViewReady: reportEditorViewReady } : {},
15056
- externalPlugins: editorPlugins,
15057
- showTemplateDirectives,
15058
- ...collaboration !== void 0 ? { collaboration } : {},
15059
- onHyperlinkClick: handleHyperlinkClick,
15060
- onContextMenu: handleContextMenu,
15061
- commentsSidebarOpen: showCommentsSidebar,
15062
- anchorPositionMode: "comments",
15063
- onAnonymizationTermClick,
15064
- selectedAnonymizationCanonical,
15065
- anonymizationSelectionSeq,
15066
- ...showCommentsSidebar ? { onAnchorPositionsChange: setAnchorPositions } : {},
15067
- onTotalPagesChange: handleTotalPagesChange,
15068
- onError: handleEditorError,
15069
- scrollContainerRef,
15070
- sidebarOverlay: commentsSidebarOverlay
15071
- }),
15072
- floatingCommentBtn !== null && !isAddingComment && !readOnly && /* @__PURE__ */ jsx(Tooltip, {
15073
- content: "Add comment",
15074
- side: "bottom",
15075
- delayMs: 300,
15076
- children: /* @__PURE__ */ jsx("button", {
15077
- type: "button",
15078
- onMouseDown: (e_1) => {
15079
- e_1.preventDefault();
15080
- e_1.stopPropagation();
15081
- const view_54 = pagedEditorRef.current?.getView();
15082
- if (!view_54) {
15083
- setFloatingCommentBtn(null);
15084
- return;
15085
- }
15086
- const capturedRange = {
15087
- from: floatingCommentBtn.from,
15088
- to: floatingCommentBtn.to
15089
- };
15090
- const currentSelection = view_54.state.selection;
15091
- const safeRange = resolveCommentCreationRange({
15092
- docSize: view_54.state.doc.content.size,
15093
- capturedRange,
15094
- currentRange: {
15095
- from: currentSelection.from,
15096
- to: currentSelection.to
15749
+ onMouseDown: containedHandler((e_0) => {
15750
+ if (e_0.target === e_0.currentTarget) {
15751
+ e_0.preventDefault();
15752
+ pagedEditorRef.current?.focus();
15753
+ }
15754
+ }),
15755
+ onContextMenu: handleEditorContextMenu,
15756
+ children: [
15757
+ rulerVisible && !readOnly && /* @__PURE__ */ jsx("div", {
15758
+ style: {
15759
+ position: "absolute",
15760
+ left: 0,
15761
+ top: 0,
15762
+ zIndex: 20,
15763
+ paddingTop: 24 * zoom
15764
+ },
15765
+ children: /* @__PURE__ */ jsx(VerticalRuler, {
15766
+ sectionProps: effectiveSectionProperties ?? null,
15767
+ zoom,
15768
+ unit: rulerUnit,
15769
+ editable: !readOnly,
15770
+ onTopMarginChange: handleTopMarginChange,
15771
+ onBottomMarginChange: handleBottomMarginChange
15772
+ })
15773
+ }),
15774
+ /* @__PURE__ */ jsx(PagedEditor, {
15775
+ ref: pagedEditorRef,
15776
+ document: history.state,
15777
+ documentIO,
15778
+ documentIdentity: loadedDocumentIdentity,
15779
+ markupView: displayMode,
15780
+ ...fonts !== void 0 ? { fonts } : {},
15781
+ theme: history.state.package.theme || theme || null,
15782
+ sectionProperties: effectiveSectionProperties ?? null,
15783
+ headerContent,
15784
+ footerContent,
15785
+ firstPageHeaderContent,
15786
+ firstPageFooterContent,
15787
+ headerContentRId: activeHeaderRId,
15788
+ footerContentRId: activeFooterRId,
15789
+ firstPageHeaderContentRId: activeFirstHeaderRId,
15790
+ firstPageFooterContentRId: activeFirstFooterRId,
15791
+ ...history.state.package.styles ? { styles: history.state.package.styles } : {},
15792
+ onHeaderFooterDoubleClick: showHeaderFooterEditing ? handleHeaderFooterStoryOpen : void 0,
15793
+ hfEditMode: hfEditPosition,
15794
+ activeHeaderFooterRId: activeHfRId,
15795
+ onBodyClick: handleBodyClick,
15796
+ onActiveNoteStoryChange: handleActiveNoteStoryChange,
15797
+ zoom,
15798
+ ...pageRenderer === void 0 ? {} : { pageRenderer },
15799
+ showMarginGuides,
15800
+ ...marginGuideColor !== void 0 ? { marginGuideColor } : {},
15801
+ readOnly,
15802
+ onDocumentChange: handleDocumentChange,
15803
+ extensionManager,
15804
+ suggestionModeActive: editingMode === "suggesting",
15805
+ suggestionAuthor: author,
15806
+ ...onCopy !== void 0 ? { onCopy } : {},
15807
+ ...onCut !== void 0 ? { onCut } : {},
15808
+ ...onPaste !== void 0 ? { onPaste } : {},
15809
+ ...onReadonlyEditAttempt !== void 0 ? { onReadOnlyEditAttempt: onReadonlyEditAttempt } : {},
15810
+ onSelectionChange: handlePagedSelectionChange,
15811
+ ...onSelectionTextChange !== void 0 ? { onSelectionTextChange } : {},
15812
+ onEditorViewReady: handleBodyViewReady,
15813
+ externalPlugins: editorPlugins,
15814
+ showTemplateDirectives,
15815
+ ...collaboration !== void 0 ? { collaboration } : {},
15816
+ onHyperlinkClick: handleHyperlinkClick,
15817
+ onContextMenu: handleContextMenu,
15818
+ pageEndGutter: panels.layout.commentsGutter,
15819
+ anchorPositionMode: "comments",
15820
+ onAnonymizationTermClick,
15821
+ selectedAnonymizationCanonical,
15822
+ anonymizationSelectionSeq,
15823
+ ...showCommentsSidebar ? { onAnchorPositionsChange: setAnchorPositions } : {},
15824
+ onTotalPagesChange: handleTotalPagesChange,
15825
+ onError: handleEditorError,
15826
+ scrollContainerRef,
15827
+ sidebarOverlay: commentsSidebarOverlay
15828
+ }),
15829
+ floatingCommentBtn !== null && !isAddingComment && !readOnly && /* @__PURE__ */ jsx(Tooltip, {
15830
+ content: "Add comment",
15831
+ side: "bottom",
15832
+ delayMs: 300,
15833
+ children: /* @__PURE__ */ jsx("button", {
15834
+ type: "button",
15835
+ onMouseDown: (e_1) => {
15836
+ e_1.preventDefault();
15837
+ e_1.stopPropagation();
15838
+ const view_61 = pagedEditorRef.current?.getView();
15839
+ if (!view_61) {
15840
+ setFloatingCommentBtn(null);
15841
+ return;
15842
+ }
15843
+ const capturedRange = {
15844
+ from: floatingCommentBtn.from,
15845
+ to: floatingCommentBtn.to
15846
+ };
15847
+ const currentSelection = view_61.state.selection;
15848
+ const safeRange = resolveCommentCreationRange({
15849
+ docSize: view_61.state.doc.content.size,
15850
+ capturedRange,
15851
+ currentRange: {
15852
+ from: currentSelection.from,
15853
+ to: currentSelection.to
15854
+ },
15855
+ savedRange: lastSelectionRef.current
15856
+ });
15857
+ if (!safeRange) {
15858
+ setCommentSelectionRange(null);
15859
+ setFloatingCommentBtn(null);
15860
+ return;
15861
+ }
15862
+ setCommentSelectionRange(safeRange);
15863
+ if (!applyCommentMarkRange(view_61, safeRange, -1, { selectEnd: true })) {
15864
+ setCommentSelectionRange(null);
15865
+ setFloatingCommentBtn(null);
15866
+ return;
15867
+ }
15868
+ const yPos_0 = findSelectionYPosition(scrollContainerRef.current, editorContentRef.current, safeRange.from);
15869
+ setAddCommentYPosition(yPos_0 ?? floatingCommentBtn.top);
15870
+ setShowCommentsSidebar(true);
15871
+ setIsAddingComment(true);
15872
+ setFloatingCommentBtn(null);
15873
+ },
15874
+ style: {
15875
+ position: "absolute",
15876
+ top: floatingCommentBtn.top,
15877
+ left: floatingCommentBtn.left,
15878
+ transform: "translate(-50%, -50%)",
15879
+ zIndex: 50,
15880
+ width: 28,
15881
+ height: 28,
15882
+ borderRadius: 6,
15883
+ border: "1px solid var(--doc-border)",
15884
+ backgroundColor: "var(--doc-page)",
15885
+ color: "var(--doc-text-muted)",
15886
+ cursor: "pointer",
15887
+ display: "flex",
15888
+ alignItems: "center",
15889
+ justifyContent: "center",
15890
+ boxShadow: "0 2px 8px var(--doc-border)",
15891
+ transition: "background-color 0.15s, box-shadow 0.15s"
15892
+ },
15893
+ onMouseOver: (e_2) => {
15894
+ e_2.currentTarget.style.backgroundColor = "rgba(26, 115, 232, 0.08)";
15895
+ e_2.currentTarget.style.boxShadow = "0 1px 4px rgba(26, 115, 232, 0.3)";
15097
15896
  },
15098
- savedRange: lastSelectionRef.current
15897
+ onFocus: (e_3) => {
15898
+ e_3.currentTarget.style.backgroundColor = "rgba(26, 115, 232, 0.08)";
15899
+ },
15900
+ onMouseOut: (e_4) => {
15901
+ e_4.currentTarget.style.backgroundColor = "var(--doc-canvas, #fff)";
15902
+ e_4.currentTarget.style.boxShadow = "0 1px 3px rgba(60,64,67,0.2)";
15903
+ },
15904
+ onBlur: (e_5) => {
15905
+ e_5.currentTarget.style.backgroundColor = "var(--doc-canvas, #fff)";
15906
+ },
15907
+ children: /* @__PURE__ */ jsx(SquarePenIcon, { size: 16 })
15908
+ })
15909
+ }),
15910
+ hfEditPosition && (() => {
15911
+ if (!(() => {
15912
+ if (hfEditIsFirstPage) return (() => {
15913
+ if (hfEditPosition === "header") return firstPageHeaderContent;
15914
+ return firstPageFooterContent;
15915
+ })();
15916
+ if (hfEditPosition === "header") return headerContent;
15917
+ return footerContent;
15918
+ })()) return null;
15919
+ const targetEl = getHfTargetElement(hfEditPosition);
15920
+ const parentEl_0 = editorContentRef.current;
15921
+ if (!targetEl || !parentEl_0) return null;
15922
+ return /* @__PURE__ */ jsx(InlineHeaderFooterEditor, {
15923
+ ref: hfEditorRef,
15924
+ position: hfEditPosition,
15925
+ targetElement: targetEl,
15926
+ parentElement: parentEl_0,
15927
+ getActiveView: getActiveHfView,
15928
+ onClose: handleBodyClick,
15929
+ onRemove: handleRemoveHeaderFooter
15099
15930
  });
15100
- if (!safeRange) {
15101
- setCommentSelectionRange(null);
15102
- setFloatingCommentBtn(null);
15103
- return;
15104
- }
15105
- setCommentSelectionRange(safeRange);
15106
- if (!applyCommentMarkRange(view_54, safeRange, -1, { selectEnd: true })) {
15107
- setCommentSelectionRange(null);
15108
- setFloatingCommentBtn(null);
15109
- return;
15110
- }
15111
- const yPos_0 = findSelectionYPosition(scrollContainerRef.current, editorContentRef.current, safeRange.from);
15112
- setAddCommentYPosition(yPos_0 ?? floatingCommentBtn.top);
15113
- setShowCommentsSidebar(true);
15114
- setIsAddingComment(true);
15115
- setFloatingCommentBtn(null);
15116
- },
15117
- style: {
15118
- position: "absolute",
15119
- top: floatingCommentBtn.top,
15120
- left: floatingCommentBtn.left,
15121
- transform: "translate(-50%, -50%)",
15122
- zIndex: 50,
15123
- width: 28,
15124
- height: 28,
15125
- borderRadius: 6,
15126
- border: "1px solid var(--doc-border)",
15127
- backgroundColor: "var(--doc-page)",
15128
- color: "var(--doc-text-muted)",
15129
- cursor: "pointer",
15130
- display: "flex",
15131
- alignItems: "center",
15132
- justifyContent: "center",
15133
- boxShadow: "0 2px 8px var(--doc-border)",
15134
- transition: "background-color 0.15s, box-shadow 0.15s"
15135
- },
15136
- onMouseOver: (e_2) => {
15137
- e_2.currentTarget.style.backgroundColor = "rgba(26, 115, 232, 0.08)";
15138
- e_2.currentTarget.style.boxShadow = "0 1px 4px rgba(26, 115, 232, 0.3)";
15139
- },
15140
- onFocus: (e_3) => {
15141
- e_3.currentTarget.style.backgroundColor = "rgba(26, 115, 232, 0.08)";
15142
- },
15143
- onMouseOut: (e_4) => {
15144
- e_4.currentTarget.style.backgroundColor = "var(--doc-canvas, #fff)";
15145
- e_4.currentTarget.style.boxShadow = "0 1px 3px rgba(60,64,67,0.2)";
15146
- },
15147
- onBlur: (e_5) => {
15148
- e_5.currentTarget.style.backgroundColor = "var(--doc-canvas, #fff)";
15149
- },
15150
- children: /* @__PURE__ */ jsx(SquarePenIcon, { size: 16 })
15151
- })
15152
- }),
15153
- hfEditPosition && (() => {
15154
- if (!(() => {
15155
- if (hfEditIsFirstPage) return (() => {
15156
- if (hfEditPosition === "header") return firstPageHeaderContent;
15157
- return firstPageFooterContent;
15158
- })();
15159
- if (hfEditPosition === "header") return headerContent;
15160
- return footerContent;
15161
- })()) return null;
15162
- const targetEl = getHfTargetElement(hfEditPosition);
15163
- const parentEl_0 = editorContentRef.current;
15164
- if (!targetEl || !parentEl_0) return null;
15165
- return /* @__PURE__ */ jsx(InlineHeaderFooterEditor, {
15166
- ref: hfEditorRef,
15167
- position: hfEditPosition,
15168
- targetElement: targetEl,
15169
- parentElement: parentEl_0,
15170
- getActiveView: getActiveHfView,
15171
- onClose: handleBodyClick,
15172
- onRemove: handleRemoveHeaderFooter
15173
- });
15174
- })()
15175
- ]
15176
- })
15177
- })]
15931
+ })()
15932
+ ]
15933
+ })
15934
+ })]
15935
+ }),
15936
+ panelOverlay === "outline" && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(PanelScrim, { onDismiss: closePanelOverlay }), /* @__PURE__ */ jsx(DocumentOutline, {
15937
+ headings: outlineHeadings,
15938
+ scrollContainerRef,
15939
+ docSize: pagedEditorRef.current?.getView()?.state.doc.content.size ?? 0,
15940
+ activeId: activeHeadingId,
15941
+ onJump: handleOutlineJump,
15942
+ surface: "drawer",
15943
+ onClose: closePanelOverlay
15944
+ })] }),
15945
+ commentsSurface === "drawer" && /* @__PURE__ */ jsx(PanelScrim, { onDismiss: dismissCommentsDrawer })
15946
+ ]
15178
15947
  }),
15179
15948
  scrollPageInfo.totalPages > 1 && /* @__PURE__ */ jsx("div", {
15180
15949
  style: {
@@ -15201,13 +15970,6 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15201
15970
  current: String(scrollPageInfo.currentPage),
15202
15971
  total: String(scrollPageInfo.totalPages)
15203
15972
  })
15204
- }),
15205
- showOutline && outlineHeadings.length > 1 && /* @__PURE__ */ jsx(DocumentOutline, {
15206
- headings: outlineHeadings,
15207
- scrollContainerRef,
15208
- topOffset: toolbarHeight,
15209
- docSize: pagedEditorRef.current?.getView()?.state.doc.content.size ?? 0,
15210
- onHeadingClick: handleOutlineHeadingClick
15211
15973
  })
15212
15974
  ]
15213
15975
  })
@@ -15244,7 +16006,8 @@ const DocxEditor = forwardRef(function DocxEditor({ documentBuffer, password, do
15244
16006
  imageProperties: imagePropertiesDialog,
15245
16007
  pageSetup: pageSetupDialog,
15246
16008
  footnoteProperties: footnotePropertiesDialog,
15247
- insertSymbol: insertSymbolDialog
16009
+ insertSymbol: insertSymbolDialog,
16010
+ setNumberingValue: numberingValueDialog
15248
16011
  }),
15249
16012
  /* @__PURE__ */ jsx("input", {
15250
16013
  ref: imageInputRef,
@@ -15385,4 +16148,4 @@ const renderAsync = (input, container, options = {}) => {
15385
16148
  });
15386
16149
  };
15387
16150
  //#endregion
15388
- export { formatZoom as a, FormattingBar as c, containedHandler as d, clampZoom as i, ZoomControl as l, DocxEditor as n, parseZoom as o, ZOOM_PRESETS as r, useWheelZoom as s, renderAsync as t, AutocompleteCaretOverlay as u };
16151
+ export { formatZoom as a, FormattingBar as c, AutocompleteCaretOverlay as d, containedHandler as f, clampZoom as i, ZoomControl as l, DocxEditor as n, parseZoom as o, ZOOM_PRESETS as r, useWheelZoom as s, renderAsync as t, useDrawerFocus as u };