superdoc 2.0.0-next.45 → 2.0.0-next.46

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 (34) hide show
  1. package/AGENTS.md +15 -8
  2. package/dist/chunks/{create-super-doc-ui-DDxbK_M7.cjs → create-super-doc-ui-6FUZ9d-y.cjs} +201 -122
  3. package/dist/chunks/{create-super-doc-ui-BTOlZen9.es.js → create-super-doc-ui-DCFTmVRK.es.js} +202 -123
  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/command-catalog.d.ts +1 -1
  7. package/dist/document-api/src/contract/operation-definitions.d.ts +1 -1
  8. package/dist/public/ui-react.cjs +17 -14
  9. package/dist/public/ui-react.es.js +17 -14
  10. package/dist/public/ui.cjs +1 -1
  11. package/dist/public/ui.es.js +1 -1
  12. package/dist/style.css +23 -23
  13. package/dist/style.layered.css +23 -23
  14. package/dist/superdoc/src/components/surfaces/FindReplaceSurface.vue.d.ts +2 -2
  15. package/dist/superdoc/src/components/surfaces/PasswordPromptSurface.vue.d.ts +2 -2
  16. package/dist/superdoc/src/components/surfaces/SurfaceExternalMount.vue.d.ts +2 -2
  17. package/dist/superdoc/src/composables/use-find-replace.d.ts +2 -2
  18. package/dist/superdoc/src/core/SuperDoc.d.ts +41 -0
  19. package/dist/superdoc/src/core/types/index.d.ts +2 -14
  20. package/dist/superdoc/src/internal/toolbar/built-in-toolbar.d.ts +5 -5
  21. package/dist/superdoc/src/public/browser-document-api.d.ts +53 -0
  22. package/dist/superdoc/src/public/index.d.cts +4 -0
  23. package/dist/superdoc/src/public/index.d.ts +2 -0
  24. package/dist/superdoc/src/public/ui/react.d.ts +18 -7
  25. package/dist/superdoc/src/public/ui/types.d.ts +81 -12
  26. package/dist/superdoc/src/public/ui-react.d.ts +4 -3
  27. package/dist/superdoc/src/public/ui.d.cts +8 -0
  28. package/dist/superdoc/src/public/ui.d.ts +1 -1
  29. package/dist/superdoc.cjs +53 -43
  30. package/dist/superdoc.es.js +53 -43
  31. package/dist-cdn/style.layered.css +1 -1
  32. package/dist-cdn/superdoc.min.css +1 -1
  33. package/dist-cdn/superdoc.min.js +35 -35
  34. package/package.json +1 -1
package/dist/style.css CHANGED
@@ -1727,11 +1727,11 @@ img[data-v-c95b2073] {
1727
1727
  pointer-events: auto;
1728
1728
  }
1729
1729
 
1730
- .superdoc[data-v-91c4cd11] {
1730
+ .superdoc[data-v-41f40a40] {
1731
1731
  display: flex;
1732
1732
  position: relative;
1733
1733
  }
1734
- .sd-visually-hidden[data-v-91c4cd11] {
1734
+ .sd-visually-hidden[data-v-41f40a40] {
1735
1735
  position: absolute;
1736
1736
  width: 1px;
1737
1737
  height: 1px;
@@ -1742,30 +1742,30 @@ img[data-v-c95b2073] {
1742
1742
  white-space: nowrap;
1743
1743
  border: 0;
1744
1744
  }
1745
- .right-sidebar[data-v-91c4cd11] {
1745
+ .right-sidebar[data-v-41f40a40] {
1746
1746
  min-width: 320px;
1747
1747
  height: 100%;
1748
1748
  }
1749
- .floating-comments[data-v-91c4cd11] {
1749
+ .floating-comments[data-v-41f40a40] {
1750
1750
  min-width: 300px;
1751
1751
  width: 300px;
1752
1752
  height: 100%;
1753
1753
  overflow: visible;
1754
1754
  }
1755
- .superdoc__layers[data-v-91c4cd11] {
1755
+ .superdoc__layers[data-v-41f40a40] {
1756
1756
  height: 100%;
1757
1757
  position: relative;
1758
1758
  box-sizing: border-box;
1759
1759
  }
1760
- .superdoc__document[data-v-91c4cd11] {
1760
+ .superdoc__document[data-v-41f40a40] {
1761
1761
  width: 100%;
1762
1762
  position: relative;
1763
1763
  }
1764
- .superdoc__sub-document[data-v-91c4cd11] {
1764
+ .superdoc__sub-document[data-v-41f40a40] {
1765
1765
  width: 100%;
1766
1766
  position: relative;
1767
1767
  }
1768
- .superdoc__selection-layer[data-v-91c4cd11] {
1768
+ .superdoc__selection-layer[data-v-41f40a40] {
1769
1769
  position: absolute;
1770
1770
  min-width: 100%;
1771
1771
  min-height: 100%;
@@ -1776,13 +1776,13 @@ img[data-v-c95b2073] {
1776
1776
  /* SD-3497: PDF whiteboard overlay sits above the rendered PDF canvas but below
1777
1777
  the PDF comment anchors (z-index 6 in PdfCommentsLayer) so anchors stay
1778
1778
  clickable, and below the selection layer (z-index 10). */
1779
- .superdoc__whiteboard-layer[data-v-91c4cd11] {
1779
+ .superdoc__whiteboard-layer[data-v-41f40a40] {
1780
1780
  z-index: 4;
1781
1781
  }
1782
- .superdoc__temp-selection[data-v-91c4cd11] {
1782
+ .superdoc__temp-selection[data-v-41f40a40] {
1783
1783
  position: absolute;
1784
1784
  }
1785
- .superdoc__right-sidebar[data-v-91c4cd11] {
1785
+ .superdoc__right-sidebar[data-v-41f40a40] {
1786
1786
  width: 320px;
1787
1787
  min-width: 320px;
1788
1788
  padding: 0 10px;
@@ -1790,7 +1790,7 @@ img[data-v-c95b2073] {
1790
1790
  position: relative;
1791
1791
  z-index: 2;
1792
1792
  }
1793
- .superdoc__compact-comment-popover[data-v-91c4cd11] {
1793
+ .superdoc__compact-comment-popover[data-v-41f40a40] {
1794
1794
  position: absolute;
1795
1795
  top: 12px;
1796
1796
  right: 12px;
@@ -1799,14 +1799,14 @@ img[data-v-c95b2073] {
1799
1799
  }
1800
1800
 
1801
1801
  /* Tools styles */
1802
- .tools[data-v-91c4cd11] {
1802
+ .tools[data-v-41f40a40] {
1803
1803
  position: absolute;
1804
1804
  z-index: 3;
1805
1805
  display: flex;
1806
1806
  flex-direction: column;
1807
1807
  gap: var(--sd-ui-tools-gap, 6px);
1808
1808
  }
1809
- .tools-item[data-v-91c4cd11] {
1809
+ .tools-item[data-v-41f40a40] {
1810
1810
  display: flex;
1811
1811
  align-items: center;
1812
1812
  justify-content: center;
@@ -1817,10 +1817,10 @@ img[data-v-c95b2073] {
1817
1817
  cursor: pointer;
1818
1818
  position: relative;
1819
1819
  }
1820
- .tools-item i[data-v-91c4cd11] {
1820
+ .tools-item i[data-v-41f40a40] {
1821
1821
  cursor: pointer;
1822
1822
  }
1823
- .superdoc__tools-icon[data-v-91c4cd11] {
1823
+ .superdoc__tools-icon[data-v-41f40a40] {
1824
1824
  width: var(--sd-ui-tools-icon-size, 20px);
1825
1825
  height: var(--sd-ui-tools-icon-size, 20px);
1826
1826
  flex-shrink: 0;
@@ -1835,22 +1835,22 @@ img[data-v-c95b2073] {
1835
1835
 
1836
1836
  /* 834px is iPad screen size in portrait orientation */
1837
1837
  @media (max-width: 834px) {
1838
- .superdoc .superdoc__layers[data-v-91c4cd11] {
1838
+ .superdoc .superdoc__layers[data-v-41f40a40] {
1839
1839
  margin: 0;
1840
1840
  border: 0 !important;
1841
1841
  box-shadow: none;
1842
1842
  }
1843
- .superdoc__sub-document[data-v-91c4cd11] {
1843
+ .superdoc__sub-document[data-v-41f40a40] {
1844
1844
  max-width: 100%;
1845
1845
  }
1846
- .superdoc__right-sidebar[data-v-91c4cd11] {
1846
+ .superdoc__right-sidebar[data-v-41f40a40] {
1847
1847
  padding: 10px;
1848
1848
  position: relative;
1849
1849
  }
1850
1850
  }
1851
1851
 
1852
1852
  /* AI Writer styles */
1853
- .ai-writer-container[data-v-91c4cd11] {
1853
+ .ai-writer-container[data-v-41f40a40] {
1854
1854
  position: fixed;
1855
1855
  z-index: 1000;
1856
1856
  background: white;
@@ -1866,10 +1866,10 @@ img[data-v-c95b2073] {
1866
1866
  transform: translateY(-50%);
1867
1867
  z-index: 50;
1868
1868
  } */
1869
- .ai-tool > svg[data-v-91c4cd11] {
1869
+ .ai-tool > svg[data-v-41f40a40] {
1870
1870
  fill: transparent;
1871
1871
  }
1872
- .ai-tool[data-v-91c4cd11]::before {
1872
+ .ai-tool[data-v-41f40a40]::before {
1873
1873
  content: '';
1874
1874
  position: absolute;
1875
1875
  width: 20px;
@@ -1890,7 +1890,7 @@ img[data-v-c95b2073] {
1890
1890
  filter: brightness(1.2);
1891
1891
  transition: filter 0.2s ease;
1892
1892
  }
1893
- .ai-tool[data-v-91c4cd11]:hover::before {
1893
+ .ai-tool[data-v-41f40a40]:hover::before {
1894
1894
  filter: brightness(1.3);
1895
1895
  }
1896
1896
 
@@ -1727,11 +1727,11 @@ img[data-v-c95b2073] {
1727
1727
  pointer-events: auto;
1728
1728
  }
1729
1729
 
1730
- .superdoc[data-v-91c4cd11] {
1730
+ .superdoc[data-v-41f40a40] {
1731
1731
  display: flex;
1732
1732
  position: relative;
1733
1733
  }
1734
- .sd-visually-hidden[data-v-91c4cd11] {
1734
+ .sd-visually-hidden[data-v-41f40a40] {
1735
1735
  position: absolute;
1736
1736
  width: 1px;
1737
1737
  height: 1px;
@@ -1742,30 +1742,30 @@ img[data-v-c95b2073] {
1742
1742
  white-space: nowrap;
1743
1743
  border: 0;
1744
1744
  }
1745
- .right-sidebar[data-v-91c4cd11] {
1745
+ .right-sidebar[data-v-41f40a40] {
1746
1746
  min-width: 320px;
1747
1747
  height: 100%;
1748
1748
  }
1749
- .floating-comments[data-v-91c4cd11] {
1749
+ .floating-comments[data-v-41f40a40] {
1750
1750
  min-width: 300px;
1751
1751
  width: 300px;
1752
1752
  height: 100%;
1753
1753
  overflow: visible;
1754
1754
  }
1755
- .superdoc__layers[data-v-91c4cd11] {
1755
+ .superdoc__layers[data-v-41f40a40] {
1756
1756
  height: 100%;
1757
1757
  position: relative;
1758
1758
  box-sizing: border-box;
1759
1759
  }
1760
- .superdoc__document[data-v-91c4cd11] {
1760
+ .superdoc__document[data-v-41f40a40] {
1761
1761
  width: 100%;
1762
1762
  position: relative;
1763
1763
  }
1764
- .superdoc__sub-document[data-v-91c4cd11] {
1764
+ .superdoc__sub-document[data-v-41f40a40] {
1765
1765
  width: 100%;
1766
1766
  position: relative;
1767
1767
  }
1768
- .superdoc__selection-layer[data-v-91c4cd11] {
1768
+ .superdoc__selection-layer[data-v-41f40a40] {
1769
1769
  position: absolute;
1770
1770
  min-width: 100%;
1771
1771
  min-height: 100%;
@@ -1776,13 +1776,13 @@ img[data-v-c95b2073] {
1776
1776
  /* SD-3497: PDF whiteboard overlay sits above the rendered PDF canvas but below
1777
1777
  the PDF comment anchors (z-index 6 in PdfCommentsLayer) so anchors stay
1778
1778
  clickable, and below the selection layer (z-index 10). */
1779
- .superdoc__whiteboard-layer[data-v-91c4cd11] {
1779
+ .superdoc__whiteboard-layer[data-v-41f40a40] {
1780
1780
  z-index: 4;
1781
1781
  }
1782
- .superdoc__temp-selection[data-v-91c4cd11] {
1782
+ .superdoc__temp-selection[data-v-41f40a40] {
1783
1783
  position: absolute;
1784
1784
  }
1785
- .superdoc__right-sidebar[data-v-91c4cd11] {
1785
+ .superdoc__right-sidebar[data-v-41f40a40] {
1786
1786
  width: 320px;
1787
1787
  min-width: 320px;
1788
1788
  padding: 0 10px;
@@ -1790,7 +1790,7 @@ img[data-v-c95b2073] {
1790
1790
  position: relative;
1791
1791
  z-index: 2;
1792
1792
  }
1793
- .superdoc__compact-comment-popover[data-v-91c4cd11] {
1793
+ .superdoc__compact-comment-popover[data-v-41f40a40] {
1794
1794
  position: absolute;
1795
1795
  top: 12px;
1796
1796
  right: 12px;
@@ -1799,14 +1799,14 @@ img[data-v-c95b2073] {
1799
1799
  }
1800
1800
 
1801
1801
  /* Tools styles */
1802
- .tools[data-v-91c4cd11] {
1802
+ .tools[data-v-41f40a40] {
1803
1803
  position: absolute;
1804
1804
  z-index: 3;
1805
1805
  display: flex;
1806
1806
  flex-direction: column;
1807
1807
  gap: var(--sd-ui-tools-gap, 6px);
1808
1808
  }
1809
- .tools-item[data-v-91c4cd11] {
1809
+ .tools-item[data-v-41f40a40] {
1810
1810
  display: flex;
1811
1811
  align-items: center;
1812
1812
  justify-content: center;
@@ -1817,10 +1817,10 @@ img[data-v-c95b2073] {
1817
1817
  cursor: pointer;
1818
1818
  position: relative;
1819
1819
  }
1820
- .tools-item i[data-v-91c4cd11] {
1820
+ .tools-item i[data-v-41f40a40] {
1821
1821
  cursor: pointer;
1822
1822
  }
1823
- .superdoc__tools-icon[data-v-91c4cd11] {
1823
+ .superdoc__tools-icon[data-v-41f40a40] {
1824
1824
  width: var(--sd-ui-tools-icon-size, 20px);
1825
1825
  height: var(--sd-ui-tools-icon-size, 20px);
1826
1826
  flex-shrink: 0;
@@ -1835,22 +1835,22 @@ img[data-v-c95b2073] {
1835
1835
 
1836
1836
  /* 834px is iPad screen size in portrait orientation */
1837
1837
  @media (max-width: 834px) {
1838
- .superdoc .superdoc__layers[data-v-91c4cd11] {
1838
+ .superdoc .superdoc__layers[data-v-41f40a40] {
1839
1839
  margin: 0;
1840
1840
  border: 0 !important;
1841
1841
  box-shadow: none;
1842
1842
  }
1843
- .superdoc__sub-document[data-v-91c4cd11] {
1843
+ .superdoc__sub-document[data-v-41f40a40] {
1844
1844
  max-width: 100%;
1845
1845
  }
1846
- .superdoc__right-sidebar[data-v-91c4cd11] {
1846
+ .superdoc__right-sidebar[data-v-41f40a40] {
1847
1847
  padding: 10px;
1848
1848
  position: relative;
1849
1849
  }
1850
1850
  }
1851
1851
 
1852
1852
  /* AI Writer styles */
1853
- .ai-writer-container[data-v-91c4cd11] {
1853
+ .ai-writer-container[data-v-41f40a40] {
1854
1854
  position: fixed;
1855
1855
  z-index: 1000;
1856
1856
  background: white;
@@ -1866,10 +1866,10 @@ img[data-v-c95b2073] {
1866
1866
  transform: translateY(-50%);
1867
1867
  z-index: 50;
1868
1868
  } */
1869
- .ai-tool > svg[data-v-91c4cd11] {
1869
+ .ai-tool > svg[data-v-41f40a40] {
1870
1870
  fill: transparent;
1871
1871
  }
1872
- .ai-tool[data-v-91c4cd11]::before {
1872
+ .ai-tool[data-v-41f40a40]::before {
1873
1873
  content: '';
1874
1874
  position: absolute;
1875
1875
  width: 20px;
@@ -1890,7 +1890,7 @@ img[data-v-c95b2073] {
1890
1890
  filter: brightness(1.2);
1891
1891
  transition: filter 0.2s ease;
1892
1892
  }
1893
- .ai-tool[data-v-91c4cd11]:hover::before {
1893
+ .ai-tool[data-v-41f40a40]:hover::before {
1894
1894
  filter: brightness(1.3);
1895
1895
  }
1896
1896
 
@@ -1,15 +1,15 @@
1
1
  declare const _default: import('vue').DefineComponent<{}, {
2
2
  close: Function;
3
3
  resolve: Function;
4
- mode: string;
5
4
  request: Record<string, any>;
5
+ mode: string;
6
6
  surfaceId: string;
7
7
  findReplace: Record<string, any>;
8
8
  $props: {
9
9
  readonly close?: Function | undefined;
10
10
  readonly resolve?: Function | undefined;
11
- readonly mode?: string | undefined;
12
11
  readonly request?: Record<string, any> | undefined;
12
+ readonly mode?: string | undefined;
13
13
  readonly surfaceId?: string | undefined;
14
14
  readonly findReplace?: Record<string, any> | undefined;
15
15
  };
@@ -1,15 +1,15 @@
1
1
  declare const _default: import('vue').DefineComponent<{}, {
2
2
  close: Function;
3
3
  resolve: Function;
4
- mode: string;
5
4
  request: Record<string, any>;
5
+ mode: string;
6
6
  surfaceId: string;
7
7
  passwordPrompt: Record<string, any>;
8
8
  $props: {
9
9
  readonly close?: Function | undefined;
10
10
  readonly resolve?: Function | undefined;
11
- readonly mode?: string | undefined;
12
11
  readonly request?: Record<string, any> | undefined;
12
+ readonly mode?: string | undefined;
13
13
  readonly surfaceId?: string | undefined;
14
14
  readonly passwordPrompt?: Record<string, any> | undefined;
15
15
  };
@@ -1,15 +1,15 @@
1
1
  declare const _default: import('vue').DefineComponent<{}, {
2
2
  close: Function;
3
3
  resolve: Function;
4
- mode: string;
5
4
  request: Record<string, any>;
5
+ mode: string;
6
6
  render: Function;
7
7
  surfaceId: string;
8
8
  $props: {
9
9
  readonly close?: Function | undefined;
10
10
  readonly resolve?: Function | undefined;
11
- readonly mode?: string | undefined;
12
11
  readonly request?: Record<string, any> | undefined;
12
+ readonly mode?: string | undefined;
13
13
  readonly render?: Function | undefined;
14
14
  readonly surfaceId?: string | undefined;
15
15
  };
@@ -10,8 +10,8 @@
10
10
  * @param {() => SearchEditor | null} options.getActiveEditor
11
11
  * @param {import('vue').Ref} [options.activeEditorRef] - Reactive ref to the active editor (for watching switches)
12
12
  * @param {() => boolean | FindReplaceConfig | undefined} [options.getFindReplaceConfig] - Config getter
13
- * @param {() => { search?: any } | null | undefined} [options.getSuperDocUI] - V2 UI controller getter
14
- * (`createSuperDocUI({ superdoc })`). Its `.search` slice is the single V2
13
+ * @param {() => { search?: any } | null | undefined} [options.getSuperDocUI] - Getter for the
14
+ * SuperDoc-owned UI controller (`superdoc.ui`). Its `.search` slice is the single V2
15
15
  * find/replace session authority; the V2 driver never touches `editor.commands`.
16
16
  */
17
17
  export function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, getFindReplaceConfig, getSuperDocUI, }: {
@@ -3,6 +3,7 @@ import { HocuspocusProviderWebsocket } from '@hocuspocus/provider';
3
3
  import { createSuperdocVueApp } from './create-app.js';
4
4
  import { Whiteboard } from './whiteboard/Whiteboard.js';
5
5
  import { EditorRuntimeFocusOptions } from './editor-runtime/types.js';
6
+ import { BorrowedSuperDocUI } from '../public/ui/types.js';
6
7
  import { AwarenessUser, CanPerformPermissionParams, CollaborationProvider, Config, ContentControlActiveChangePayload, ContentControlClickPayload, DocumentMode, Editor, EditorUpdateEvent, ExportParams, FontsChangedPayload, FontsResolvedPayload, InternalConfig, ListDefinitionsPayload, NavigableAddress, DocumentRendererRuntime, SearchMatch, SuperDocAwarenessUpdatePayload, SuperDocCommentsUpdatePayload, SuperDocEditorPayload, SuperDocExceptionPayload, SuperDocFontsApi, SuperDocLockedPayload, SuperDocMeasurementUnit, SuperDocMeasurementUnitChangePayload, SuperDocReadyPayload, SuperDocState, SuperDocViewportChangePayload, SuperDocViewportMetrics, SuperDocZoomMode, SuperDocZoomPayload, SuperDocZoomState, SurfaceHandle, SurfaceRequest, UpgradeToCollaborationOptions, User } from './types/index.js';
7
8
  import { WhiteboardData } from './whiteboard/Whiteboard.js';
8
9
  type ToolbarLike = {
@@ -53,6 +54,13 @@ interface SuperDocEventMap {
53
54
  'measurement-unit-change': [SuperDocMeasurementUnitChangePayload];
54
55
  'formatting-marks-change': [SuperDocFormattingMarksPayload];
55
56
  'document-mode-change': [SuperDocDocumentModeChangePayload];
57
+ /**
58
+ * The active editor was assigned or cleared. Internal: the UI controller
59
+ * listens so its snapshot follows the live editor. `editorCreate` only
60
+ * covers assignment, and it is emitted after `broadcastReady()`, so
61
+ * neither a pre-ready read nor a clear would refresh without this.
62
+ */
63
+ 'active-editor-change': [];
56
64
  'editor-update': [EditorUpdateEvent];
57
65
  'content-error': [SuperDocContentErrorPayload];
58
66
  'fonts-resolved': [FontsResolvedPayload];
@@ -231,6 +239,39 @@ export declare class SuperDoc extends EventEmitter<SuperDocEventMap> {
231
239
  * @returns The number of required editors
232
240
  */
233
241
  get requiredNumberOfEditors(): number;
242
+ /**
243
+ * The UI controller for this instance: the single place to read command
244
+ * state and drive comments, track changes, selection, zoom, and the other
245
+ * UI surfaces from application code.
246
+ *
247
+ * SuperDoc owns exactly one controller per instance. Every internal
248
+ * consumer — the built-in toolbar, the link popover, keyboard command
249
+ * routing, and the React bindings — reads this same object, so command
250
+ * state never diverges between built-in and custom UI. The controller is
251
+ * created by the first read and its identity never changes afterwards:
252
+ * replacing the document, remounting an editor, or switching the active
253
+ * editor in a multi-document instance all keep the same controller.
254
+ *
255
+ * Reading it is safe before the document is ready. Slices report a `pending`
256
+ * status and commands report themselves disabled instead of throwing, so a
257
+ * custom UI can subscribe in the same tick as the constructor and will start
258
+ * receiving real values once an editor mounts.
259
+ *
260
+ * `SuperDoc.destroy()` destroys the controller. The returned type is
261
+ * {@link BorrowedSuperDocUI}, which omits `destroy()`, so a consumer tearing
262
+ * down state that other readers of this instance still observe is a compile
263
+ * error rather than a rule in a comment. The instance keeps the owning
264
+ * reference privately.
265
+ *
266
+ * This is an observation and command surface, not a permission boundary.
267
+ * Anything it exposes is reachable by the page that hosts SuperDoc.
268
+ *
269
+ * @example
270
+ * const superdoc = new SuperDoc({ selector: '#editor', document: file });
271
+ * const stop = superdoc.ui.comments.observe((comments) => render(comments));
272
+ * superdoc.ui.commands.get('bold').getState(); // { enabled, active, ... }
273
+ */
274
+ get ui(): BorrowedSuperDocUI;
234
275
  /**
235
276
  * Snapshot of the current SuperDoc state. Always reflects the most
236
277
  * recent values from the Pinia store; consumers must re-read on
@@ -1,25 +1,13 @@
1
1
  import { Doc as YDoc } from 'yjs';
2
2
  import { HocuspocusProviderWebsocket } from '@hocuspocus/provider';
3
3
  import { Ref, ComputedRef } from 'vue';
4
- import { DocumentApi } from '../../../../document-api/src/index.js';
5
4
  import { DocumentFontOption, FontAssetUrlResolver, FontFamilyOption, FontLoadSummary, FontResolutionRecord } from '../../../../shared/font-system/src/index.js';
6
5
  import { SuperDoc as SuperDocClass } from '../SuperDoc.js';
7
6
  import { SuperDocActiveEditorExtensions, SuperDocExtension } from '../extensions/index.js';
7
+ import { BrowserDocumentApi } from '../../public/browser-document-api.js';
8
8
  export type { DocumentFontOption, FontAssetUrlContext, FontAssetUrlResolver, FontFaceSlot, FontFamilyOption, FontLoadResult, FontLoadStatus, FontLoadSummary, FontResolutionReason, FontResolutionRecord, GlyphException, ResolvedFontEvidence, SubstitutePolicyAction, SubstituteVerdict, } from '../../../../shared/font-system/src/index.js';
9
9
  export type SuperDoc = SuperDocClass;
10
- type MaybePromise<T> = T | Promise<T>;
11
- type BrowserDocumentApiObject<T> = {
12
- [K in keyof T]: BrowserDocumentApiValue<T[K]>;
13
- };
14
- type BrowserDocumentApiValue<T> = T extends (...args: infer Args) => infer Return ? ((...args: Args) => MaybePromise<Awaited<Return>>) & BrowserDocumentApiObject<T> : T extends object ? BrowserDocumentApiObject<T> : T;
15
- /**
16
- * Browser V2 active-editor Document API facade (`superdoc.activeEditor.doc`).
17
- * In the browser this surface is intentionally async-capable: callers must
18
- * tolerate promise-returning reads/writes, including the default
19
- * worker-backed runtime. SDK/headless callers should continue using the
20
- * synchronous `@superdoc/document-api` surface directly.
21
- */
22
- export type BrowserDocumentApi = BrowserDocumentApiObject<DocumentApi>;
10
+ export type { BrowserDocumentApi } from '../../public/browser-document-api.js';
23
11
  export type V2AuthoringSelectionCollapse = 'start' | 'end' | null;
24
12
  export type V2AuthoringResult = {
25
13
  ok: true;
@@ -177,14 +177,14 @@ export class BuiltInToolbar extends EventEmitter<string | symbol, any> {
177
177
  _detachFontsChanged: null;
178
178
  /** Active editor compatibility reference (set by `SuperDoc.setActiveEditor`). */
179
179
  activeEditor: any;
180
- /** Live shared command controller (single command-state truth). */
181
- ui: import('../../public/ui.js').SuperDocUI | null;
180
+ /** SuperDoc-owned command controller (single command-state truth). */
181
+ ui: any;
182
182
  /** Latest controller toolbar snapshot. */
183
- snapshot: import('../../public/ui.js').ToolbarSnapshotSlice | null;
183
+ snapshot: any;
184
184
  /** Controller subscription unsubscribe handle. */
185
- _unsubscribeController: (() => void) | null;
185
+ _unsubscribeController: any;
186
186
  /** Format-painter mode subscription unsubscribe handle. */
187
- _detachFormatPainterModeChange: (() => void) | null;
187
+ _detachFormatPainterModeChange: any;
188
188
  /** Registered custom-button command unregister handles. */
189
189
  _customCommandRegs: Map<any, any>;
190
190
  /** Signature of the last-built font options, to skip redundant rebuilds. */
@@ -0,0 +1,53 @@
1
+ import { DocumentApi } from '../../../document-api/src/index.js';
2
+ type MaybePromise<T> = T | Promise<T>;
3
+ type BrowserDocumentApiObject<T> = {
4
+ [K in keyof T]: BrowserDocumentApiValue<T[K]>;
5
+ };
6
+ type BrowserDocumentApiValue<T> = T extends (...args: infer Args) => infer Return ? ((...args: Args) => MaybePromise<Awaited<Return>>) & BrowserDocumentApiObject<T> : T extends object ? BrowserDocumentApiObject<T> : T;
7
+ /**
8
+ * Browser V2 active-editor Document API facade (`superdoc.activeEditor.doc`).
9
+ * In the browser this surface is intentionally async-capable: callers must
10
+ * tolerate promise-returning reads/writes, including the default
11
+ * worker-backed runtime. SDK/headless callers should continue using the
12
+ * synchronous `@superdoc/document-api` surface directly.
13
+ */
14
+ export type BrowserDocumentApi = BrowserDocumentApiObject<DocumentApi>;
15
+ /**
16
+ * Every operation optional, at any depth.
17
+ *
18
+ * A callable member keeps its call signature *and* its properties, mirroring
19
+ * what {@link BrowserDocumentApiValue} does. Parts of the Document API are both:
20
+ * `capabilities` is callable and carries `get()`, so reconstructing only the call
21
+ * signature would make `doc.capabilities.get()` a type error on a value that
22
+ * supports it at runtime.
23
+ *
24
+ * Intersected rather than unioned with the property bag. A union would let a
25
+ * non-callable object stand in for a callable member, which also makes the
26
+ * member type unenforceable: `{ comments: { list: 42 } }` satisfies a
27
+ * props-only alternative and the type stops catching wrong operations at all.
28
+ */
29
+ type DeepPartial<T> = T extends (...args: infer Args) => infer Return ? ((...args: Args) => Return) & {
30
+ [K in keyof T]?: DeepPartial<T[K]>;
31
+ } : T extends object ? {
32
+ [K in keyof T]?: DeepPartial<T[K]>;
33
+ } : T;
34
+ /**
35
+ * What a *host* may supply as `activeEditor.doc`.
36
+ *
37
+ * A host is duck-typed: a custom adapter or a test stub is expected to carry
38
+ * only the operations it actually implements, and the controller resolves
39
+ * operations defensively at runtime rather than assuming any of them exist.
40
+ * Requiring the whole surface here would reject exactly the partial hosts the
41
+ * contract is documented to accept.
42
+ *
43
+ * `CustomCommandContext.doc` uses this same partial type, because that value is
44
+ * the host's own object passed straight through. It can promise no more than the
45
+ * host contract does. {@link BrowserDocumentApi}, the complete facade, is the
46
+ * type of `activeEditor.doc` on a real `Editor`.
47
+ *
48
+ * Partial, not permissive: the operations a host does declare are still
49
+ * checked, so a typo or a wrong member type fails instead of passing as
50
+ * `any`.
51
+ */
52
+ export type PartialBrowserDocumentApi = DeepPartial<BrowserDocumentApi>;
53
+ export {};
@@ -5,6 +5,7 @@ import type { BlockNavigationAddress as __Cjs_BlockNavigationAddress } from './i
5
5
  import type { BlocksListResult as __Cjs_BlocksListResult } from './index.js' with { "resolution-mode": "import" };
6
6
  import type { BookmarkAddress as __Cjs_BookmarkAddress } from './index.js' with { "resolution-mode": "import" };
7
7
  import type { BookmarkInfo as __Cjs_BookmarkInfo } from './index.js' with { "resolution-mode": "import" };
8
+ import type { BorrowedSuperDocUI as __Cjs_BorrowedSuperDocUI } from './index.js' with { "resolution-mode": "import" };
8
9
  import type { CanPerformPermissionParams as __Cjs_CanPerformPermissionParams } from './index.js' with { "resolution-mode": "import" };
9
10
  import type { CollaborationConfig as __Cjs_CollaborationConfig } from './index.js' with { "resolution-mode": "import" };
10
11
  import type { CommentAddress as __Cjs_CommentAddress } from './index.js' with { "resolution-mode": "import" };
@@ -133,6 +134,7 @@ import type { SuperDocStoryLocator as __Cjs_SuperDocStoryLocator } from './index
133
134
  import type { SuperDocTelemetryConfig as __Cjs_SuperDocTelemetryConfig } from './index.js' with { "resolution-mode": "import" };
134
135
  import type { SuperDocTextAddress as __Cjs_SuperDocTextAddress } from './index.js' with { "resolution-mode": "import" };
135
136
  import type { SuperDocTextTarget as __Cjs_SuperDocTextTarget } from './index.js' with { "resolution-mode": "import" };
137
+ import type { SuperDocUI as __Cjs_SuperDocUI } from './index.js' with { "resolution-mode": "import" };
136
138
  import type { SuperDocViewportChangePayload as __Cjs_SuperDocViewportChangePayload } from './index.js' with { "resolution-mode": "import" };
137
139
  import type { SuperDocViewportMetrics as __Cjs_SuperDocViewportMetrics } from './index.js' with { "resolution-mode": "import" };
138
140
  import type { SuperDocVisibleRange as __Cjs_SuperDocVisibleRange } from './index.js' with { "resolution-mode": "import" };
@@ -175,6 +177,7 @@ export type { __Cjs_BlockNavigationAddress as BlockNavigationAddress };
175
177
  export type { __Cjs_BlocksListResult as BlocksListResult };
176
178
  export type { __Cjs_BookmarkAddress as BookmarkAddress };
177
179
  export type { __Cjs_BookmarkInfo as BookmarkInfo };
180
+ export type { __Cjs_BorrowedSuperDocUI as BorrowedSuperDocUI };
178
181
  export declare const buildTheme: typeof import('./index.js', { with: { "resolution-mode": "import" } }).buildTheme;
179
182
  export type { __Cjs_CanPerformPermissionParams as CanPerformPermissionParams };
180
183
  export type { __Cjs_CollaborationConfig as CollaborationConfig };
@@ -312,6 +315,7 @@ export type { __Cjs_SuperDocStoryLocator as SuperDocStoryLocator };
312
315
  export type { __Cjs_SuperDocTelemetryConfig as SuperDocTelemetryConfig };
313
316
  export type { __Cjs_SuperDocTextAddress as SuperDocTextAddress };
314
317
  export type { __Cjs_SuperDocTextTarget as SuperDocTextTarget };
318
+ export type { __Cjs_SuperDocUI as SuperDocUI };
315
319
  export type { __Cjs_SuperDocViewportChangePayload as SuperDocViewportChangePayload };
316
320
  export type { __Cjs_SuperDocViewportMetrics as SuperDocViewportMetrics };
317
321
  export type { __Cjs_SuperDocVisibleRange as SuperDocVisibleRange };
@@ -81,6 +81,8 @@ export type { SuperDocMeasurementUnitChangePayload } from '../core/types/index.j
81
81
  export type { SuperDocReadyPayload } from '../core/types/index.js';
82
82
  export type { SuperDocState } from '../core/types/index.js';
83
83
  export type { SuperDocTelemetryConfig } from '../core/types/index.js';
84
+ export type { BorrowedSuperDocUI } from './ui/types.js';
85
+ export type { SuperDocUI } from './ui/types.js';
84
86
  export type { SuperDocViewportChangePayload } from '../core/types/index.js';
85
87
  export type { SuperDocViewportMetrics } from '../core/types/index.js';
86
88
  export type { SuperDocZoomConfig } from '../core/types/index.js';
@@ -1,5 +1,5 @@
1
1
  import { ReactNode } from 'react';
2
- import { CommandState, CommentsSlice, ContentControlsSlice, DocumentSlice, FontFamilyOption, FontSizeOption, SelectionSlice, Subscribable, SuperDocLike, SuperDocUI, ToolbarSnapshotSlice, TrackChangesSlice, ZoomSlice } from './types.js';
2
+ import { BorrowedSuperDocUI, CommandState, CommentsSlice, ContentControlsSlice, DocumentSlice, FontFamilyOption, FontSizeOption, SelectionSlice, Subscribable, SuperDocLike, ToolbarSnapshotSlice, TrackChangesSlice, ZoomSlice } from './types.js';
3
3
  /** The raw SuperDoc instance (or host stub) handed to the provider. */
4
4
  export type SuperDocHost = SuperDocLike;
5
5
  /** Props accepted by {@link SuperDocUIProvider}. */
@@ -8,13 +8,24 @@ export interface SuperDocUIProviderProps {
8
8
  children?: ReactNode;
9
9
  }
10
10
  /**
11
- * Root provider. Owns the controller lifecycle: call {@link useSetSuperDoc}
12
- * from your editor-mount component's ready callback to bind a running SuperDoc
13
- * instance; the controller is created then and destroyed on unmount / rebind.
11
+ * Root provider. Call {@link useSetSuperDoc} from your editor-mount
12
+ * component's ready callback to bind a running SuperDoc instance; the hooks
13
+ * below then read that instance's own controller (`superdoc.ui`).
14
+ *
15
+ * The provider is a consumer, not an owner. SuperDoc creates the controller
16
+ * and destroys it in `superdoc.destroy()`, so unmounting or rebinding the
17
+ * provider leaves it running for the built-in toolbar and any other consumer
18
+ * of the same instance. Every React hook therefore observes the same command
19
+ * state the rest of the application sees.
14
20
  */
15
21
  export declare function SuperDocUIProvider(props: SuperDocUIProviderProps): import('react').ReactElement;
16
- /** Read the controller, or `null` until a SuperDoc instance is bound. */
17
- export declare function useSuperDocUI(): SuperDocUI | null;
22
+ /**
23
+ * Read the controller, or `null` until a SuperDoc instance is bound.
24
+ *
25
+ * Borrowed: the bound instance owns teardown, so the returned type omits
26
+ * `destroy()`. A provider-built fallback controller is disposed by the provider.
27
+ */
28
+ export declare function useSuperDocUI(): BorrowedSuperDocUI | null;
18
29
  /** Read the raw bound SuperDoc host, or `null` until one is bound. */
19
30
  export declare function useSuperDocHost(): SuperDocHost | null;
20
31
  /** Get the stable callback used to bind a running SuperDoc instance. */
@@ -46,7 +57,7 @@ export declare function toSliceSource<T>(source: SliceSource<T> | Subscribable<T
46
57
  * normalized via {@link toSliceSource}. `initial` is returned until the
47
58
  * controller is bound.
48
59
  */
49
- export declare function useSuperDocSlice<T>(pick: (ui: SuperDocUI) => SliceSource<T> | Subscribable<T>, initial: T): T;
60
+ export declare function useSuperDocSlice<T>(pick: (ui: BorrowedSuperDocUI) => SliceSource<T> | Subscribable<T>, initial: T): T;
50
61
  /** Subscribe to the selection slice. */
51
62
  export declare function useSuperDocSelection(): SelectionSlice;
52
63
  /** Subscribe to the comments slice. */