superdoc 2.0.0-next.49 → 2.0.0-next.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/AGENTS.md +31 -10
  2. package/dist/chunks/{create-super-doc-ui-BmtUtDDR.es.js → create-super-doc-ui-D4UDePxr.es.js} +126 -28
  3. package/dist/chunks/{create-super-doc-ui-BNo2DvD1.cjs → create-super-doc-ui-DlSN0ENQ.cjs} +126 -28
  4. package/dist/collaboration-upgrade-engine.cjs +1 -1
  5. package/dist/collaboration-upgrade-engine.es.js +1 -1
  6. package/dist/document-api/src/contract/operation-definitions.d.ts +1 -1
  7. package/dist/public/ui-react.cjs +1 -1
  8. package/dist/public/ui-react.es.js +1 -1
  9. package/dist/public/ui.cjs +1 -1
  10. package/dist/public/ui.es.js +1 -1
  11. package/dist/shared/font-system/src/font-offerings.d.ts +1 -1
  12. package/dist/style.css +28 -28
  13. package/dist/style.layered.css +28 -28
  14. package/dist/superdoc/src/core/SuperDoc.d.ts +43 -1
  15. package/dist/superdoc/src/core/config/merge-defined.d.ts +35 -0
  16. package/dist/superdoc/src/core/config/normalize-interaction-config.d.ts +15 -0
  17. package/dist/superdoc/src/core/config/normalize-surfaces-config.d.ts +23 -0
  18. package/dist/superdoc/src/core/config/normalize-ui-config.d.ts +62 -0
  19. package/dist/superdoc/src/core/types/index.d.ts +209 -2
  20. package/dist/superdoc/src/public/index.d.cts +6 -0
  21. package/dist/superdoc/src/public/index.d.ts +3 -0
  22. package/dist/superdoc/src/public/ui.d.cts +2 -0
  23. package/dist/superdoc/src/public/ui.d.ts +1 -1
  24. package/dist/superdoc.cjs +211 -37
  25. package/dist/superdoc.es.js +211 -37
  26. package/dist-cdn/style.layered.css +1 -1
  27. package/dist-cdn/superdoc.min.css +1 -1
  28. package/dist-cdn/superdoc.min.js +37 -37
  29. package/package.json +2 -2
@@ -39,6 +39,7 @@ import type { FindReplaceResolution as __Cjs_FindReplaceResolution } from './ind
39
39
  import type { FlowBlock as __Cjs_FlowBlock } from './index.js' with { "resolution-mode": "import" };
40
40
  import type { FlowMode as __Cjs_FlowMode } from './index.js' with { "resolution-mode": "import" };
41
41
  import type { IntentSurfaceRequest as __Cjs_IntentSurfaceRequest } from './index.js' with { "resolution-mode": "import" };
42
+ import type { InteractionConfig as __Cjs_InteractionConfig } from './index.js' with { "resolution-mode": "import" };
42
43
  import type { Layout as __Cjs_Layout } from './index.js' with { "resolution-mode": "import" };
43
44
  import type { LayoutEngineOptions as __Cjs_LayoutEngineOptions } from './index.js' with { "resolution-mode": "import" };
44
45
  import type { LayoutFragment as __Cjs_LayoutFragment } from './index.js' with { "resolution-mode": "import" };
@@ -154,6 +155,7 @@ import type { SurfaceOutcome as __Cjs_SurfaceOutcome } from './index.js' with {
154
155
  import type { SurfaceRequest as __Cjs_SurfaceRequest } from './index.js' with { "resolution-mode": "import" };
155
156
  import type { SurfaceResolution as __Cjs_SurfaceResolution } from './index.js' with { "resolution-mode": "import" };
156
157
  import type { SurfaceResolver as __Cjs_SurfaceResolver } from './index.js' with { "resolution-mode": "import" };
158
+ import type { SurfacesConfig as __Cjs_SurfacesConfig } from './index.js' with { "resolution-mode": "import" };
157
159
  import type { SurfacesModuleConfig as __Cjs_SurfacesModuleConfig } from './index.js' with { "resolution-mode": "import" };
158
160
  import type { TextAddress as __Cjs_TextAddress } from './index.js' with { "resolution-mode": "import" };
159
161
  import type { TextSegment as __Cjs_TextSegment } from './index.js' with { "resolution-mode": "import" };
@@ -165,6 +167,7 @@ import type { TrackChangesSemanticColorsConfig as __Cjs_TrackChangesSemanticColo
165
167
  import type { TrackedChangeAddress as __Cjs_TrackedChangeAddress } from './index.js' with { "resolution-mode": "import" };
166
168
  import type { TrackedChangeSemanticColorKey as __Cjs_TrackedChangeSemanticColorKey } from './index.js' with { "resolution-mode": "import" };
167
169
  import type { TrackedChangeSemanticColorResolverInput as __Cjs_TrackedChangeSemanticColorResolverInput } from './index.js' with { "resolution-mode": "import" };
170
+ import type { UIConfig as __Cjs_UIConfig } from './index.js' with { "resolution-mode": "import" };
168
171
  import type { UpgradeToCollaborationOptions as __Cjs_UpgradeToCollaborationOptions } from './index.js' with { "resolution-mode": "import" };
169
172
  import type { User as __Cjs_User } from './index.js' with { "resolution-mode": "import" };
170
173
  import type { V2CollaborationConfig as __Cjs_V2CollaborationConfig } from './index.js' with { "resolution-mode": "import" };
@@ -218,6 +221,7 @@ export type { __Cjs_FlowMode as FlowMode };
218
221
  export declare const getFileObject: typeof import('./index.js', { with: { "resolution-mode": "import" } }).getFileObject;
219
222
  export declare const HTML: typeof import('./index.js', { with: { "resolution-mode": "import" } }).HTML;
220
223
  export type { __Cjs_IntentSurfaceRequest as IntentSurfaceRequest };
224
+ export type { __Cjs_InteractionConfig as InteractionConfig };
221
225
  export type { __Cjs_Layout as Layout };
222
226
  export type { __Cjs_LayoutEngineOptions as LayoutEngineOptions };
223
227
  export type { __Cjs_LayoutFragment as LayoutFragment };
@@ -335,6 +339,7 @@ export type { __Cjs_SurfaceOutcome as SurfaceOutcome };
335
339
  export type { __Cjs_SurfaceRequest as SurfaceRequest };
336
340
  export type { __Cjs_SurfaceResolution as SurfaceResolution };
337
341
  export type { __Cjs_SurfaceResolver as SurfaceResolver };
342
+ export type { __Cjs_SurfacesConfig as SurfacesConfig };
338
343
  export type { __Cjs_SurfacesModuleConfig as SurfacesModuleConfig };
339
344
  export type { __Cjs_TextAddress as TextAddress };
340
345
  export type { __Cjs_TextSegment as TextSegment };
@@ -346,6 +351,7 @@ export type { __Cjs_TrackChangesSemanticColorsConfig as TrackChangesSemanticColo
346
351
  export type { __Cjs_TrackedChangeAddress as TrackedChangeAddress };
347
352
  export type { __Cjs_TrackedChangeSemanticColorKey as TrackedChangeSemanticColorKey };
348
353
  export type { __Cjs_TrackedChangeSemanticColorResolverInput as TrackedChangeSemanticColorResolverInput };
354
+ export type { __Cjs_UIConfig as UIConfig };
349
355
  export type { __Cjs_UpgradeToCollaborationOptions as UpgradeToCollaborationOptions };
350
356
  export type { __Cjs_User as User };
351
357
  export type { __Cjs_V2CollaborationConfig as V2CollaborationConfig };
@@ -108,6 +108,9 @@ export type { TrackChangesSemanticColorsConfig } from '../core/types/index.js';
108
108
  export type { TrackedChangeSemanticColorKey } from '../core/types/index.js';
109
109
  export type { TrackedChangeSemanticColorResolverInput } from '../core/types/index.js';
110
110
  export type { TrackedChangeAddress } from '../core/types/index.js';
111
+ export type { InteractionConfig } from '../core/types/index.js';
112
+ export type { SurfacesConfig } from '../core/types/index.js';
113
+ export type { UIConfig } from '../core/types/index.js';
111
114
  export type { UpgradeToCollaborationOptions } from '../core/types/index.js';
112
115
  export type { V2CollaborationConfig } from '../core/types/index.js';
113
116
  export type { User } from '../core/types/index.js';
@@ -20,6 +20,7 @@ import type { ContentControlsListResult as __Cjs_ContentControlsListResult } fro
20
20
  import type { ContentControlsSlice as __Cjs_ContentControlsSlice } from './ui.js' with { "resolution-mode": "import" };
21
21
  import type { ContentControlViewportAddress as __Cjs_ContentControlViewportAddress } from './ui.js' with { "resolution-mode": "import" };
22
22
  import type { ContextMenuItem as __Cjs_ContextMenuItem } from './ui.js' with { "resolution-mode": "import" };
23
+ import type { CustomCommandContext as __Cjs_CustomCommandContext } from './ui.js' with { "resolution-mode": "import" };
23
24
  import type { CustomCommandHandle as __Cjs_CustomCommandHandle } from './ui.js' with { "resolution-mode": "import" };
24
25
  import type { CustomCommandHandleState as __Cjs_CustomCommandHandleState } from './ui.js' with { "resolution-mode": "import" };
25
26
  import type { CustomCommandRegistration as __Cjs_CustomCommandRegistration } from './ui.js' with { "resolution-mode": "import" };
@@ -116,6 +117,7 @@ export type { __Cjs_ContentControlsSlice as ContentControlsSlice };
116
117
  export type { __Cjs_ContentControlViewportAddress as ContentControlViewportAddress };
117
118
  export type { __Cjs_ContextMenuItem as ContextMenuItem };
118
119
  export declare const createSuperDocUI: typeof import('./ui.js', { with: { "resolution-mode": "import" } }).createSuperDocUI;
120
+ export type { __Cjs_CustomCommandContext as CustomCommandContext };
119
121
  export type { __Cjs_CustomCommandHandle as CustomCommandHandle };
120
122
  export type { __Cjs_CustomCommandHandleState as CustomCommandHandleState };
121
123
  export type { __Cjs_CustomCommandRegistration as CustomCommandRegistration };
@@ -26,4 +26,4 @@
26
26
  export { createSuperDocUI } from './ui/create-super-doc-ui.js';
27
27
  export { shallowEqual } from './ui/equality.js';
28
28
  export { BUILT_IN_COMMAND_IDS } from './ui/commands.js';
29
- export type { EqualityFn, SelectorFn, Subscribable, SuperDocUI, BorrowedSuperDocUI, SuperDocUIOptions, SuperDocUIState, SuperDocUIScope, SuperDocLike, SuperDocEditorLike, CommandHandle, CommandState, CommandExecutionResult, WorkflowReceipt, WorkflowActionResult, WorkflowScrollResult, SelectionRestoreResult, SuperDocUIReason, CommandsHandle, ContextMenuItem, CustomCommandHandle, CustomCommandHandleState, CustomCommandRegistration, CustomCommandRegistrationResult, MetadataHandle, SelectionHandle, ToolbarHandle, CommentsHandle, TrackChangesHandle, ContentControlsHandle, ContentControlFocusResult, FontsHandle, ZoomHandle, DocumentHandle, ViewportHandle, StylesHandle, ActiveParagraphStyle, SliceStatus, SelectionSlice, SelectionCapture, CommentAnchorCapture, ToolbarSnapshotSlice, CommentsSlice, TrackChangesSlice, ContentControlsSlice, FontsSlice, ZoomSlice, DocumentSlice, StylesSlice, StyleCatalogView, StyleCatalogItemType, StyleCatalogFilterType, StyleProvenance, StyleCatalogItemVisibility, StyleCatalogItemUsage, StyleCatalogItemPreview, StyleCatalogItem, StyleCatalogDefaults, StyleCatalogDiagnostic, StyleCatalogSourceStatus, StylesGetCatalogInput, StylesGetCatalogResult, CommentInfo, CommentsListQuery, TrackChangeInfo, TrackChangePointHit, TrackChangesItem, FontFamilyOption, FontSizeOption, CommentAddress, TrackedChangeAddress, ContentControlViewportAddress, ViewportEntityAddress, ViewportEntityHit, ViewportContext, ViewportRect, ViewportGetRectInput, ViewportRectResult, BrowserDocumentApi, PartialBrowserDocumentApi, DocumentApi, Receipt, SelectionInfo, SelectionTarget, SelectionPoint, TextTarget, TextAddress, ScrollIntoViewInput, ScrollIntoViewOutput, EntityAddress, CommentsListResult, TrackChangesListResult, ContentControlsListResult, ContentControlInfo, } from './ui/types.js';
29
+ export type { EqualityFn, SelectorFn, Subscribable, SuperDocUI, BorrowedSuperDocUI, SuperDocUIOptions, SuperDocUIState, SuperDocUIScope, SuperDocLike, SuperDocEditorLike, CommandHandle, CommandState, CommandExecutionResult, WorkflowReceipt, WorkflowActionResult, WorkflowScrollResult, SelectionRestoreResult, SuperDocUIReason, CommandsHandle, ContextMenuItem, CustomCommandContext, CustomCommandHandle, CustomCommandHandleState, CustomCommandRegistration, CustomCommandRegistrationResult, MetadataHandle, SelectionHandle, ToolbarHandle, CommentsHandle, TrackChangesHandle, ContentControlsHandle, ContentControlFocusResult, FontsHandle, ZoomHandle, DocumentHandle, ViewportHandle, StylesHandle, ActiveParagraphStyle, SliceStatus, SelectionSlice, SelectionCapture, CommentAnchorCapture, ToolbarSnapshotSlice, CommentsSlice, TrackChangesSlice, ContentControlsSlice, FontsSlice, ZoomSlice, DocumentSlice, StylesSlice, StyleCatalogView, StyleCatalogItemType, StyleCatalogFilterType, StyleProvenance, StyleCatalogItemVisibility, StyleCatalogItemUsage, StyleCatalogItemPreview, StyleCatalogItem, StyleCatalogDefaults, StyleCatalogDiagnostic, StyleCatalogSourceStatus, StylesGetCatalogInput, StylesGetCatalogResult, CommentInfo, CommentsListQuery, TrackChangeInfo, TrackChangePointHit, TrackChangesItem, FontFamilyOption, FontSizeOption, CommentAddress, TrackedChangeAddress, ContentControlViewportAddress, ViewportEntityAddress, ViewportEntityHit, ViewportContext, ViewportRect, ViewportGetRectInput, ViewportRectResult, BrowserDocumentApi, PartialBrowserDocumentApi, DocumentApi, Receipt, SelectionInfo, SelectionTarget, SelectionPoint, TextTarget, TextAddress, ScrollIntoViewInput, ScrollIntoViewOutput, EntityAddress, CommentsListResult, TrackChangesListResult, ContentControlsListResult, ContentControlInfo, } from './ui/types.js';
package/dist/superdoc.cjs CHANGED
@@ -6,7 +6,7 @@ const require_uuid = require("./chunks/uuid-CFp0WGVU.cjs");
6
6
  const require_jszip = require("./chunks/jszip-BdUBlUeG.cjs");
7
7
  const require__plugin_vue_export_helper = require("./chunks/_plugin-vue_export-helper-BTwbGDKw.cjs");
8
8
  const require_constants = require("./chunks/constants-sbCZ2O_A.cjs");
9
- const require_create_super_doc_ui = require("./chunks/create-super-doc-ui-BNo2DvD1.cjs");
9
+ const require_create_super_doc_ui = require("./chunks/create-super-doc-ui-DlSN0ENQ.cjs");
10
10
  let vue = require("vue");
11
11
  vue = require_rolldown_runtime.__toESM(vue);
12
12
  require("y-websocket");
@@ -378,7 +378,7 @@ function setupDevtoolsPlugin(pluginDescriptor, setupFn) {
378
378
  var activePinia;
379
379
  var setActivePinia = (pinia) => activePinia = pinia;
380
380
  var piniaSymbol = require_jszip.process$1.env.NODE_ENV !== "production" ? Symbol("pinia") : Symbol();
381
- function isPlainObject(o) {
381
+ function isPlainObject$3(o) {
382
382
  return o && typeof o === "object" && Object.prototype.toString.call(o) === "[object Object]" && typeof o.toJSON !== "function";
383
383
  }
384
384
  var MutationType;
@@ -1052,7 +1052,7 @@ function patchObject(newState, oldState) {
1052
1052
  const subPatch = oldState[key];
1053
1053
  if (!(key in newState)) continue;
1054
1054
  const targetValue = newState[key];
1055
- if (isPlainObject(targetValue) && isPlainObject(subPatch) && !(0, lib_exports.isRef)(subPatch) && !(0, lib_exports.isReactive)(subPatch)) newState[key] = patchObject(targetValue, subPatch);
1055
+ if (isPlainObject$3(targetValue) && isPlainObject$3(subPatch) && !(0, lib_exports.isRef)(subPatch) && !(0, lib_exports.isReactive)(subPatch)) newState[key] = patchObject(targetValue, subPatch);
1056
1056
  else newState[key] = subPatch;
1057
1057
  }
1058
1058
  return newState;
@@ -1085,14 +1085,14 @@ function mergeReactiveObjects(target, patchToApply) {
1085
1085
  if (!patchToApply.hasOwnProperty(key)) continue;
1086
1086
  const subPatch = patchToApply[key];
1087
1087
  const targetValue = target[key];
1088
- if (isPlainObject(targetValue) && isPlainObject(subPatch) && target.hasOwnProperty(key) && !(0, lib_exports.isRef)(subPatch) && !(0, lib_exports.isReactive)(subPatch)) target[key] = mergeReactiveObjects(targetValue, subPatch);
1088
+ if (isPlainObject$3(targetValue) && isPlainObject$3(subPatch) && target.hasOwnProperty(key) && !(0, lib_exports.isRef)(subPatch) && !(0, lib_exports.isReactive)(subPatch)) target[key] = mergeReactiveObjects(targetValue, subPatch);
1089
1089
  else target[key] = subPatch;
1090
1090
  }
1091
1091
  return target;
1092
1092
  }
1093
1093
  var skipHydrateSymbol = require_jszip.process$1.env.NODE_ENV !== "production" ? Symbol("pinia:skipHydration") : Symbol();
1094
1094
  function shouldHydrate(obj) {
1095
- return !isPlainObject(obj) || !obj.hasOwnProperty(skipHydrateSymbol);
1095
+ return !isPlainObject$3(obj) || !obj.hasOwnProperty(skipHydrateSymbol);
1096
1096
  }
1097
1097
  var { assign } = Object;
1098
1098
  function isComputed(o) {
@@ -1302,7 +1302,7 @@ function createSetupStore($id, setup, options = {}, pinia, hot, isOptionsStore)
1302
1302
  if (stateKey in store.$state) {
1303
1303
  const newStateTarget = newStore.$state[stateKey];
1304
1304
  const oldStateSource = store.$state[stateKey];
1305
- if (typeof newStateTarget === "object" && isPlainObject(newStateTarget) && isPlainObject(oldStateSource)) patchObject(newStateTarget, oldStateSource);
1305
+ if (typeof newStateTarget === "object" && isPlainObject$3(newStateTarget) && isPlainObject$3(oldStateSource)) patchObject(newStateTarget, oldStateSource);
1306
1306
  else newStore.$state[stateKey] = oldStateSource;
1307
1307
  }
1308
1308
  set(store, stateKey, (0, lib_exports.toRef)(newStore.$state, stateKey));
@@ -3010,6 +3010,11 @@ const useCommentsStore = defineStore("comments", () => {
3010
3010
  ok: false,
3011
3011
  reason: "read-only-document"
3012
3012
  });
3013
+ const resolveDisabledOutcome = () => ({
3014
+ ok: false,
3015
+ reason: "resolve-disabled"
3016
+ });
3017
+ const resolveIsDisabled = () => commentsConfig.allowResolve === false;
3013
3018
  const commentsAreReadOnly$1 = () => commentsConfig.readOnly === true;
3014
3019
  const viewingVisibility = (0, vue.reactive)({
3015
3020
  documentMode: "editing",
@@ -4318,6 +4323,7 @@ const useCommentsStore = defineStore("comments", () => {
4318
4323
  };
4319
4324
  const resolveCommentV2 = async ({ superdoc, commentId } = {}) => {
4320
4325
  if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
4326
+ if (resolveIsDisabled()) return resolveDisabledOutcome();
4321
4327
  const v2Adapter = getV2CommentsAdapter(superdoc);
4322
4328
  if (!v2Adapter) return {
4323
4329
  ok: false,
@@ -4365,6 +4371,7 @@ const useCommentsStore = defineStore("comments", () => {
4365
4371
  };
4366
4372
  const reopenCommentV2 = async ({ superdoc, commentId } = {}) => {
4367
4373
  if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
4374
+ if (resolveIsDisabled()) return resolveDisabledOutcome();
4368
4375
  const v2Adapter = getV2CommentsAdapter(superdoc);
4369
4376
  if (!v2Adapter) return {
4370
4377
  ok: false,
@@ -8789,19 +8796,20 @@ var _sfc_main$30 = {
8789
8796
  });
8790
8797
  }
8791
8798
  positions.sort((a, b) => a.anchorTop - b.anchorTop);
8792
- resolveCollisions(positions, activeKey ? positions.findIndex((p) => p.id === activeKey) : -1, 15);
8799
+ const collisionPositions = [];
8793
8800
  for (const position of positions) {
8794
- if (!position.hasAnchorGeometry) continue;
8795
- const offscreenTop = resolvePersistentReviewCardTop({
8801
+ const offscreenTop = position.hasAnchorGeometry ? resolvePersistentReviewCardTop({
8796
8802
  comment: position.commentRef,
8797
8803
  anchorTop: position.anchorTop,
8798
8804
  anchorBottom: position.anchorBottom,
8799
8805
  cardHeight: position.height,
8800
8806
  viewportTop: viewportRange.top,
8801
8807
  viewportBottom: viewportRange.bottom
8802
- });
8803
- if (offscreenTop != null) position.top = offscreenTop;
8808
+ }) : null;
8809
+ if (offscreenTop == null) collisionPositions.push(position);
8810
+ else position.top = offscreenTop;
8804
8811
  }
8812
+ resolveCollisions(collisionPositions, activeKey ? collisionPositions.findIndex((p) => p.id === activeKey) : -1, 15);
8805
8813
  return positions;
8806
8814
  });
8807
8815
  const wrapperMinHeight = (0, vue.computed)(() => {
@@ -9310,7 +9318,7 @@ var _sfc_main$30 = {
9310
9318
  };
9311
9319
  }
9312
9320
  };
9313
- var FloatingComments_default = /* @__PURE__ */ require__plugin_vue_export_helper.__plugin_vue_export_helper_default(_sfc_main$30, [["__scopeId", "data-v-a1bd2282"]]);
9321
+ var FloatingComments_default = /* @__PURE__ */ require__plugin_vue_export_helper.__plugin_vue_export_helper_default(_sfc_main$30, [["__scopeId", "data-v-b5be33eb"]]);
9314
9322
  var _hoisted_1$22 = {
9315
9323
  class: "superdoc__pdf-comments-layer pdf-comments-layer",
9316
9324
  "aria-hidden": "false"
@@ -13889,8 +13897,7 @@ var _sfc_main$20 = {
13889
13897
  const allowSelectionInViewMode = () => !!proxy?.$superdoc?.config?.allowSelectionInViewMode;
13890
13898
  const isViewingCommentsVisible = (0, vue.computed)(() => isViewingMode() && commentsStore.viewingVisibility.commentsVisible === true);
13891
13899
  const isFindReplaceEnabled = (0, vue.computed)(() => {
13892
- const val = proxy?.$superdoc?.config?.modules?.surfaces?.findReplace;
13893
- return val === true || typeof val === "object" && val !== null;
13900
+ return proxy?.$superdoc?.uiConfig?.search?.enabled === true;
13894
13901
  });
13895
13902
  (0, vue.computed)(() => isViewingMode() && commentsStore.viewingVisibility.trackChangesVisible === true);
13896
13903
  const shouldRenderCommentsInViewing = (0, vue.computed)(() => commentsStore.shouldRenderReviewInViewing);
@@ -13962,7 +13969,7 @@ var _sfc_main$20 = {
13962
13969
  getSurfaceManager: getLinkPopoverSurfaceManager,
13963
13970
  getActiveEditor: () => proxy.$superdoc?.activeEditor,
13964
13971
  getUi: getSuperDocUI,
13965
- getResolver: () => proxy.$superdoc?.config?.modules?.links?.popoverResolver,
13972
+ getResolver: () => proxy.$superdoc?.uiConfig?.linkPopover?.suppressed ? () => ({ type: "none" }) : proxy.$superdoc?.config?.modules?.links?.popoverResolver,
13966
13973
  getLayerElement: () => layers.value,
13967
13974
  emitException: (payload) => {
13968
13975
  proxy.$superdoc?.emit("exception", {
@@ -15176,11 +15183,11 @@ var _sfc_main$20 = {
15176
15183
  externalExtensions: proxy.$superdoc.config.editorExtensions || [],
15177
15184
  extensions: proxy.$superdoc.config.extensions || [],
15178
15185
  suppressDefaultDocxStyles: proxy.$superdoc.config.suppressDefaultDocxStyles,
15179
- disableContextMenu: proxy.$superdoc.config.disableContextMenu,
15186
+ disableContextMenu: !proxy.$superdoc.uiConfig.contextMenu.enabled || proxy.$superdoc.config.disableContextMenu === true,
15180
15187
  jsonOverride: proxy.$superdoc.config.jsonOverride,
15181
15188
  viewOptions: proxy.$superdoc.config.viewOptions,
15182
15189
  contained: proxy.$superdoc.config.contained,
15183
- linkPopoverResolver: proxy.$superdoc.config.modules?.links?.popoverResolver,
15190
+ linkPopoverResolver: proxy.$superdoc.uiConfig.linkPopover.enabled ? proxy.$superdoc.config.modules?.links?.popoverResolver : void 0,
15184
15191
  layoutEngineOptions: useLayoutEngine ? {
15185
15192
  ...proxy.$superdoc.config.layoutEngineOptions || {},
15186
15193
  proofing: resolvedProofingConfig.value,
@@ -15188,7 +15195,7 @@ var _sfc_main$20 = {
15188
15195
  zoom: (activeZoom.value ?? 100) / 100,
15189
15196
  emitCommentPositionsInViewing: isViewingMode() && shouldRenderCommentsInViewing.value,
15190
15197
  enableCommentsInViewing: isViewingCommentsVisible.value,
15191
- contentControlsChrome: proxy.$superdoc.config.modules?.contentControls?.chrome,
15198
+ contentControlsChrome: !proxy.$superdoc.uiConfig.contentControls.enabled ? "none" : proxy.$superdoc.uiConfig.contentControls.options.chrome ?? (proxy.$superdoc.config.modules?.contentControls?.chrome === "none" ? void 0 : proxy.$superdoc.config.modules?.contentControls?.chrome),
15192
15199
  resolveTrackedChangeColor: require_create_super_doc_ui.composeAuthorColorResolver(proxy.$superdoc.config.modules?.trackChanges?.authorColors)
15193
15200
  } : void 0,
15194
15201
  permissionResolver: (payload = {}) => proxy.$superdoc.canPerformPermission({
@@ -15783,6 +15790,7 @@ var _sfc_main$20 = {
15783
15790
  selectionLayer.value.style.pointerEvents = "none";
15784
15791
  };
15785
15792
  const shouldShowSelection = (0, vue.computed)(() => {
15793
+ if (!proxy.$superdoc.uiConfig.comments.enabled) return false;
15786
15794
  const config = proxy.$superdoc.config.modules?.comments;
15787
15795
  if (!config || config === false) return false;
15788
15796
  return !config.readOnly;
@@ -15796,6 +15804,7 @@ var _sfc_main$20 = {
15796
15804
  if (!isV2Mode.value) return false;
15797
15805
  if (!doc || doc.type !== "application/vnd.openxmlformats-officedocument.wordprocessingml.document") return false;
15798
15806
  if (proxy.$superdoc.config.viewOptions?.layout === "web") return false;
15807
+ if (proxy.$superdoc.uiConfig.ruler.suppressed) return false;
15799
15808
  if (!Boolean(unwrapDocField(doc.rulers))) return false;
15800
15809
  if (!v2RulerReady.value) return false;
15801
15810
  const editor = proxy.$superdoc?.activeEditor;
@@ -16127,7 +16136,7 @@ var _sfc_main$20 = {
16127
16136
  };
16128
16137
  }
16129
16138
  };
16130
- var SuperDoc_default = /* @__PURE__ */ require__plugin_vue_export_helper.__plugin_vue_export_helper_default(_sfc_main$20, [["__scopeId", "data-v-41f40a40"]]);
16139
+ var SuperDoc_default = /* @__PURE__ */ require__plugin_vue_export_helper.__plugin_vue_export_helper_default(_sfc_main$20, [["__scopeId", "data-v-2a7bfa95"]]);
16131
16140
  var PINIA_DEVTOOLS_SETUP_EVENT = "devtools-plugin:setup";
16132
16141
  var PINIA_DEVTOOLS_PLUGIN_ID = "dev.esm.pinia";
16133
16142
  var piniaDevtoolsSuppressionState = {
@@ -28382,7 +28391,7 @@ var SurfaceManager = class {
28382
28391
  if (resolution.type === "external") return { render: resolution.render };
28383
28392
  }
28384
28393
  }
28385
- throw new Error(`SurfaceManager: no renderer resolved for kind "${request.kind}". Provide a resolver via modules.surfaces.resolver, or use a direct-render request.`);
28394
+ throw new Error(`SurfaceManager: no renderer resolved for kind "${request.kind}". Provide a resolver via surfaces.resolver, or use a direct-render request.`);
28386
28395
  }
28387
28396
  #createDestroyedHandle(rawRequest) {
28388
28397
  return {
@@ -28514,6 +28523,129 @@ function normalizeSuperDocUser(user) {
28514
28523
  ...user
28515
28524
  };
28516
28525
  }
28526
+ function mergeDefined(...sources) {
28527
+ const merged = {};
28528
+ for (const source of sources) {
28529
+ if (typeof source !== "object" || source === null) continue;
28530
+ for (const [key, value] of Object.entries(source)) {
28531
+ if (value === void 0) continue;
28532
+ merged[key] = value;
28533
+ }
28534
+ }
28535
+ return merged;
28536
+ }
28537
+ function firstDefined(...values) {
28538
+ for (const value of values) if (value !== void 0) return value;
28539
+ }
28540
+ var HISTORICAL_DEFAULTS = Object.freeze({
28541
+ toolbar: true,
28542
+ comments: true,
28543
+ contextMenu: true,
28544
+ search: false,
28545
+ linkPopover: false,
28546
+ ruler: false,
28547
+ contentControls: true
28548
+ });
28549
+ var DEFAULT_TOOLBAR_GROUP_IDS = Object.freeze([
28550
+ "left",
28551
+ "center",
28552
+ "right"
28553
+ ]);
28554
+ var BUILT_IN_SURFACES = Object.freeze(Object.keys(HISTORICAL_DEFAULTS));
28555
+ var isPlainObject$2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
28556
+ function resolveSurface(ui, key) {
28557
+ const value = ui?.[key];
28558
+ if (value === false) return false;
28559
+ if (value === void 0) return HISTORICAL_DEFAULTS[key];
28560
+ return true;
28561
+ }
28562
+ function resolveOptions(ui, key) {
28563
+ const value = ui?.[key];
28564
+ return isPlainObject$2(value) ? value : {};
28565
+ }
28566
+ function normalizeUiConfig(config = {}) {
28567
+ const raw = config.ui;
28568
+ const allDisabled = raw === false;
28569
+ const ui = isPlainObject$2(raw) ? raw : void 0;
28570
+ const enabled = (key) => !allDisabled && resolveSurface(ui, key);
28571
+ const explicit = (key) => {
28572
+ if (allDisabled) return false;
28573
+ return ui?.[key] === void 0 ? void 0 : resolveSurface(ui, key);
28574
+ };
28575
+ const options = (key) => allDisabled ? {} : resolveOptions(ui, key);
28576
+ const rulerSuppressed = allDisabled || explicit("ruler") === false;
28577
+ const toolbarOptions = options("toolbar");
28578
+ const legacyToolbar = config.modules?.toolbar;
28579
+ const legacyToolbarOptions = isPlainObject$2(legacyToolbar) ? legacyToolbar : {};
28580
+ const groupCandidates = [toolbarOptions.groups, legacyToolbarOptions.groups];
28581
+ const composedGroups = groupCandidates.find(isPlainObject$2);
28582
+ const selectedGroups = firstDefined(groupCandidates.find(Array.isArray), legacyToolbarOptions.toolbarGroups, config.toolbarGroups);
28583
+ const selection = Array.isArray(selectedGroups) ? selectedGroups : null;
28584
+ const ownGroup = (map, group) => Object.prototype.hasOwnProperty.call(map, group);
28585
+ const projectedGroups = composedGroups && selection ? Object.fromEntries([...selection.filter((group) => ownGroup(composedGroups, group)), ...Object.keys(composedGroups).filter((group) => !DEFAULT_TOOLBAR_GROUP_IDS.includes(group))].map((group) => [group, composedGroups[group]])) : composedGroups;
28586
+ return {
28587
+ enabled: !allDisabled,
28588
+ toolbar: {
28589
+ enabled: enabled("toolbar"),
28590
+ container: allDisabled ? null : firstDefined(toolbarOptions.container, legacyToolbarOptions.selector, config.toolbar) ?? null,
28591
+ options: allDisabled ? {} : {
28592
+ ...mergeDefined(legacyToolbarOptions, toolbarOptions),
28593
+ groups: projectedGroups,
28594
+ toolbarGroups: selectedGroups,
28595
+ icons: mergeDefined(config.toolbarIcons, legacyToolbarOptions.icons, toolbarOptions.icons),
28596
+ texts: mergeDefined(config.toolbarTexts, legacyToolbarOptions.texts, toolbarOptions.texts)
28597
+ }
28598
+ },
28599
+ comments: {
28600
+ enabled: explicit("comments") ?? (!allDisabled && config.modules?.comments !== false),
28601
+ options: options("comments")
28602
+ },
28603
+ contextMenu: {
28604
+ enabled: explicit("contextMenu") ?? (!allDisabled && config.disableContextMenu !== true),
28605
+ suppressed: allDisabled || explicit("contextMenu") === false,
28606
+ options: options("contextMenu")
28607
+ },
28608
+ search: {
28609
+ enabled: explicit("search") ?? (!allDisabled && Boolean(config.modules?.surfaces?.findReplace)),
28610
+ options: options("search")
28611
+ },
28612
+ linkPopover: {
28613
+ enabled: explicit("linkPopover") ?? (!allDisabled && Boolean(config.modules?.links?.popoverResolver)),
28614
+ suppressed: allDisabled || explicit("linkPopover") === false,
28615
+ options: options("linkPopover")
28616
+ },
28617
+ ruler: {
28618
+ enabled: explicit("ruler") ?? (!allDisabled && Boolean(config.rulers)),
28619
+ suppressed: rulerSuppressed,
28620
+ container: rulerSuppressed ? null : options("ruler").container ?? config.rulerContainer ?? null
28621
+ },
28622
+ contentControls: {
28623
+ enabled: explicit("contentControls") ?? (!allDisabled && config.modules?.contentControls?.chrome !== "none"),
28624
+ options: options("contentControls")
28625
+ }
28626
+ };
28627
+ }
28628
+ var isPlainObject$1 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
28629
+ function normalizeInteractionConfig(config = {}) {
28630
+ const interaction = isPlainObject$1(config.interaction) ? config.interaction : {};
28631
+ const interactionComments = isPlainObject$1(interaction.comments) ? interaction.comments : {};
28632
+ const legacyComments = isPlainObject$1(config.modules?.comments) ? config.modules.comments : {};
28633
+ return { comments: {
28634
+ readOnly: (interactionComments.readOnly ?? legacyComments.readOnly ?? false) === true,
28635
+ allowResolve: (interactionComments.allowResolve ?? legacyComments.allowResolve ?? true) !== false
28636
+ } };
28637
+ }
28638
+ var isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
28639
+ function normalizeSurfacesConfig(config = {}) {
28640
+ const next = isPlainObject(config.surfaces) ? config.surfaces : {};
28641
+ const legacy = isPlainObject(config.modules?.surfaces) ? config.modules.surfaces : {};
28642
+ const resolver = next.resolver === void 0 ? legacy.resolver : next.resolver;
28643
+ return {
28644
+ resolver: typeof resolver === "function" ? resolver : null,
28645
+ dialog: mergeDefined(legacy.dialog, next.dialog),
28646
+ floating: mergeDefined(legacy.floating, next.floating)
28647
+ };
28648
+ }
28517
28649
  var EditorRuntimeRegistry = class {
28518
28650
  #runtimes = /* @__PURE__ */ new Map();
28519
28651
  #rootToId = /* @__PURE__ */ new Map();
@@ -34008,6 +34140,11 @@ var BuiltInToolbar = class extends require_eventemitter3.import_eventemitter3.de
34008
34140
  this._detachFontsChanged = null;
34009
34141
  }
34010
34142
  #initToolbarGroups() {
34143
+ if (Array.isArray(this.config.groups)) {
34144
+ this.config.toolbarGroups = this.config.groups;
34145
+ this.config.groups = null;
34146
+ return;
34147
+ }
34011
34148
  if (this.config.groups && !Array.isArray(this.config.groups) && Object.keys(this.config.groups).length) this.config.toolbarGroups = Object.keys(this.config.groups);
34012
34149
  }
34013
34150
  getAvailableWidth() {
@@ -34021,6 +34158,7 @@ var BuiltInToolbar = class extends require_eventemitter3.import_eventemitter3.de
34021
34158
  }
34022
34159
  #makeToolbarItems() {
34023
34160
  const availableWidth = this.getAvailableWidth();
34161
+ const hasExplicitGroupComposition = this.config.groups && !Array.isArray(this.config.groups) && Object.keys(this.config.groups).length > 0;
34024
34162
  const { defaultItems, overflowItems } = makeDefaultItems({
34025
34163
  superToolbar: this,
34026
34164
  toolbarIcons: this.config.icons,
@@ -34035,14 +34173,14 @@ var BuiltInToolbar = class extends require_eventemitter3.import_eventemitter3.de
34035
34173
  const customToolbarItems = customItems.map((item) => this.#prepareCustomButton(item));
34036
34174
  if (customItems.length) defaultItems.push(...customToolbarItems);
34037
34175
  let allConfigItems = [...defaultItems.map((item) => item.name.value), ...overflowItems.map((item) => item.name.value)];
34038
- if (this.config.groups) {
34176
+ if (hasExplicitGroupComposition) {
34039
34177
  const groupedItems = Object.values(this.config.groups).flatMap((item) => item);
34040
34178
  const configuredGroups = new Set(Object.keys(this.config.groups));
34041
34179
  const groupedCustomItems = customToolbarItems.filter((item) => configuredGroups.has(item.group?.value || "center")).map((item) => item.name.value);
34042
34180
  allConfigItems = [...new Set([...groupedItems, ...groupedCustomItems])];
34043
34181
  }
34044
34182
  const filteredItems = defaultItems.filter((item) => allConfigItems.includes(item.name.value)).filter((item) => !this.config.excludeItems.includes(item.name.value));
34045
- if (this.config.groups) {
34183
+ if (hasExplicitGroupComposition) {
34046
34184
  for (const [group, names] of Object.entries(this.config.groups)) for (const item of filteredItems) if (names.includes(item.name.value)) item.group.value = group;
34047
34185
  }
34048
34186
  this.toolbarItems = filteredItems;
@@ -34606,6 +34744,18 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
34606
34744
  #pendingV2LockSeed = null;
34607
34745
  #mountWrapper = null;
34608
34746
  #ui = null;
34747
+ #uiConfig = normalizeUiConfig({});
34748
+ get uiConfig() {
34749
+ return this.#uiConfig;
34750
+ }
34751
+ #interactionConfig = normalizeInteractionConfig({});
34752
+ get interactionConfig() {
34753
+ return this.#interactionConfig;
34754
+ }
34755
+ #surfacesConfig = normalizeSurfacesConfig({});
34756
+ get surfacesConfig() {
34757
+ return this.#surfacesConfig;
34758
+ }
34609
34759
  #surfaceManager;
34610
34760
  #editorRuntimeRegistry = new EditorRuntimeRegistry();
34611
34761
  #editorRuntimeRegistryUnsub = null;
@@ -34675,7 +34825,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
34675
34825
  if (!config.selector) throw new Error("SuperDoc: selector is required");
34676
34826
  const container = typeof config.selector === "string" ? document.querySelector(config.selector) : config.selector;
34677
34827
  if (!(container instanceof HTMLElement)) throw new Error("SuperDoc: selector must be a valid CSS selector string or DOM element");
34678
- this.#surfaceManager = new SurfaceManager({ getModuleConfig: () => this.config.modules?.surfaces });
34828
+ this.#surfaceManager = new SurfaceManager({ getModuleConfig: () => this.#surfacesConfig });
34679
34829
  this.#init(config, container);
34680
34830
  }
34681
34831
  async #init(config, container) {
@@ -34709,10 +34859,21 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
34709
34859
  this.config.modules = this.config.modules || {};
34710
34860
  if (!Object.prototype.hasOwnProperty.call(this.config.modules, "comments")) this.config.modules.comments = {};
34711
34861
  this.config.modules.comments = normalizeCommentsUiPolicy(this.config.modules.comments);
34862
+ this.#uiConfig = normalizeUiConfig(this.config);
34863
+ this.#interactionConfig = normalizeInteractionConfig(this.config);
34864
+ this.#surfacesConfig = normalizeSurfacesConfig(this.config);
34865
+ this.config.disableContextMenu = !this.#uiConfig.contextMenu.enabled;
34866
+ if (!this.#uiConfig.comments.enabled) this.config.modules.comments = false;
34867
+ else if (this.config.modules.comments === false) this.config.modules.comments = {};
34868
+ if (this.#uiConfig.comments.enabled) {
34869
+ if (this.config.modules.comments === true) this.config.modules.comments = {};
34870
+ const commentsBlock = this.config.modules.comments;
34871
+ if (commentsBlock) Object.assign(commentsBlock, this.#interactionConfig.comments);
34872
+ }
34712
34873
  this.config.colors = shuffleArray(this.config.colors);
34713
34874
  this.userColorMap = /* @__PURE__ */ new Map();
34714
34875
  this.colorIndex = 0;
34715
- this.version = "2.0.0-next.49";
34876
+ this.version = "2.0.0-next.50";
34716
34877
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
34717
34878
  this.superdocId = config.superdocId || require_uuid.v4_default();
34718
34879
  this.colors = this.config.colors ?? [];
@@ -35724,29 +35885,28 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
35724
35885
  #addToolbar() {
35725
35886
  const toolbarModuleConfig = this.config.modules?.toolbar;
35726
35887
  const toolbarModule = toolbarModuleConfig && typeof toolbarModuleConfig === "object" ? toolbarModuleConfig : {};
35727
- this.toolbarElement = toolbarModule.selector || this.config.toolbar;
35728
- if (!(Boolean(this.config.toolbar) || toolbarModuleConfig === true || toolbarModuleConfig != null && typeof toolbarModuleConfig === "object")) {
35888
+ const toolbarUi = this.#uiConfig.toolbar;
35889
+ this.toolbarElement = toolbarUi.container ?? void 0;
35890
+ const uiBlock = this.config.ui;
35891
+ const namedInUiBlock = typeof uiBlock === "object" && uiBlock !== null && uiBlock.toolbar !== void 0;
35892
+ if (!(toolbarUi.enabled && (Boolean(toolbarUi.container) || toolbarModuleConfig === true || toolbarModuleConfig != null && typeof toolbarModuleConfig === "object" || namedInUiBlock))) {
35729
35893
  this.toolbar = null;
35730
35894
  return;
35731
35895
  }
35732
35896
  try {
35733
35897
  this.toolbar = createBuiltInToolbar({
35734
35898
  ...toolbarModule,
35899
+ ...toolbarUi.options,
35735
35900
  selector: this.toolbarElement,
35736
35901
  superdoc: this,
35737
35902
  editor: this.activeEditor,
35738
35903
  role: this.config.role,
35739
35904
  isDev: this.isDev,
35740
35905
  documentMode: this.config.documentMode,
35741
- toolbarGroups: toolbarModule.toolbarGroups ?? this.config.toolbarGroups,
35742
- icons: {
35743
- ...this.config.toolbarIcons,
35744
- ...toolbarModule.icons
35745
- },
35746
- texts: {
35747
- ...this.config.toolbarTexts,
35748
- ...toolbarModule.texts
35749
- },
35906
+ groups: toolbarUi.options.groups,
35907
+ toolbarGroups: toolbarUi.options.toolbarGroups,
35908
+ icons: toolbarUi.options.icons,
35909
+ texts: toolbarUi.options.texts,
35750
35910
  uiDisplayFallbackFont: this.config.uiDisplayFallbackFont
35751
35911
  });
35752
35912
  } catch (error) {
@@ -35797,6 +35957,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
35797
35957
  return documentRuntime.scrollToElement(elementId);
35798
35958
  }
35799
35959
  setDisableContextMenu(disabled = true) {
35960
+ if (!disabled && this.#uiConfig.contextMenu.suppressed) return;
35800
35961
  const nextValue = Boolean(disabled);
35801
35962
  if (this.config.disableContextMenu === nextValue) return;
35802
35963
  this.config.disableContextMenu = nextValue;
@@ -36080,13 +36241,26 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
36080
36241
  if (isV2ActiveEditorFacade(activeEditor) && typeof activeEditor.replaceFile === "function") {
36081
36242
  const result = await activeEditor.replaceFile(source);
36082
36243
  const state = result && typeof result === "object" ? result.state : null;
36083
- if (state === null || state === "review-ready" || state === "editing-ready") this.#replaceActiveDocumentData(activeEditor, source);
36244
+ if (state === null || state === "review-ready" || state === "editing-ready") {
36245
+ this.#replaceActiveDocumentData(activeEditor, source);
36246
+ this.emit("document-replaced", {
36247
+ editor: activeEditor,
36248
+ host: activeEditor?.host
36249
+ });
36250
+ }
36084
36251
  return result;
36085
36252
  }
36086
36253
  const legacyReplaceFile = activeEditor && !isV2ActiveEditorFacade(activeEditor) ? activeEditor.replaceFile : null;
36087
36254
  if (typeof legacyReplaceFile === "function") {
36088
36255
  const result = await legacyReplaceFile.call(activeEditor, source);
36089
- this.#replaceActiveDocumentData(activeEditor, source);
36256
+ const legacyState = result && typeof result === "object" ? result.state : void 0;
36257
+ if (legacyState === void 0 || legacyState === null || legacyState === "review-ready" || legacyState === "editing-ready") {
36258
+ this.#replaceActiveDocumentData(activeEditor, source);
36259
+ this.emit("document-replaced", {
36260
+ editor: activeEditor,
36261
+ host: activeEditor?.host
36262
+ });
36263
+ }
36090
36264
  return result;
36091
36265
  }
36092
36266
  throw new Error("SuperDoc: replaceFile is unavailable for the active editor");