@fileverse-dev/ddoc 5.1.9 → 6.0.0-drop-in.0

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 (31) hide show
  1. package/README.md +89 -19
  2. package/dist/headless-editor-utils.es.js +3 -3
  3. package/dist/{index-DtE1zaH8.mjs → index-8MQH4TSF.mjs} +1 -1
  4. package/dist/index.d.ts +1 -1
  5. package/dist/index.es.js +10142 -9893
  6. package/dist/{markdown-source-pane-CA4cDQyu.mjs → markdown-source-pane-CXO7aIOp.mjs} +1 -1
  7. package/dist/package/components/editor-navbar.d.ts +12 -0
  8. package/dist/package/components/fullscreen-toolbar.d.ts +2 -2
  9. package/dist/package/components/tabs/document-mobile-tab-panel.d.ts +3 -1
  10. package/dist/package/components/tabs/document-tabs-sidebar.d.ts +2 -1
  11. package/dist/package/components/toc/document-outline.d.ts +1 -1
  12. package/dist/package/components/toc/toc.d.ts +1 -1
  13. package/dist/package/components/toc/types.d.ts +7 -0
  14. package/dist/package/hooks/use-canvas-metrics.d.ts +16 -0
  15. package/dist/package/hooks/use-controllable-state.d.ts +3 -0
  16. package/dist/package/hooks/use-editor-media-query.d.ts +4 -0
  17. package/dist/package/hooks/use-focus-mode.d.ts +1 -3
  18. package/dist/package/hooks/use-tab-editor.d.ts +4 -1
  19. package/dist/package/sync-local/socketClient.d.ts +2 -0
  20. package/dist/package/sync-local/types/index.d.ts +3 -0
  21. package/dist/package/types.d.ts +39 -5
  22. package/dist/package/use-ddoc-editor.d.ts +3 -1
  23. package/dist/package/utils/container-query-support.d.ts +1 -0
  24. package/dist/package/utils/editor-width-store.d.ts +6 -0
  25. package/dist/package/utils/responsive.d.ts +3 -1
  26. package/dist/package/utils/stats-publisher.d.ts +8 -0
  27. package/dist/{split-view-toolbar-8eYCwI8J.mjs → split-view-toolbar-BnfwwwTs.mjs} +1 -1
  28. package/dist/style.css +1 -1
  29. package/dist/{use-headless-editor-tZq6fxul.mjs → use-headless-editor-Buqsz3UI.mjs} +7628 -7612
  30. package/package.json +2 -2
  31. package/tailwind.preset.cjs +42 -0
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
  [ddocs.new](http://ddocs.new/) is your privacy-focused, open-source alternative to Google Docs. It is an end-to-end encrypted document editor that is optimized for multiplayer collaboration without compromising on speed or people's control over their data.
3
3
 
4
4
  ## 𓆏 Features include:
5
- - End-to-end encryption
5
+ - End-to-end encryption with post-quantum cryptography
6
6
  - Real-time and async collaboration
7
7
  - Suggestion mode (tracked changes) and commenting
8
8
  - Markdown and LaTeX support
@@ -46,6 +46,32 @@ import 'katex/dist/katex.min.css'; // math; fonts are served as files
46
46
  import '@fileverse-dev/ddoc/styles'; // editor CSS
47
47
  ```
48
48
 
49
+ ### Sizing
50
+
51
+ `DdocEditor` fills its parent: `width: 100%; height: 100%`. The parent must have a definite height. The editor never reads the viewport, so a navbar above it or a footer below it is ordinary layout:
52
+
53
+ ```tsx
54
+ <div style={{ height: '100dvh', display: 'flex', flexDirection: 'column' }}>
55
+ <div style={{ flex: 1, minHeight: 0 }}>
56
+ <DdocEditor renderNavbar={renderNavbar} />
57
+ </div>
58
+ <footer>…</footer>
59
+ </div>
60
+ ```
61
+
62
+ If the editor renders with no height, its parent has none.
63
+
64
+ `renderNavbar` output is the editor's first row by default. Without `renderNavbar` no navbar element is rendered. To place the navbar elsewhere, pass the element to render into. Hold it in state, not in a ref, so the editor re-renders when it attaches:
65
+
66
+ ```tsx
67
+ const [navbarEl, setNavbarEl] = useState<HTMLElement | null>(null);
68
+
69
+ <header ref={setNavbarEl} />
70
+ <DdocEditor navbarContainer={navbarEl} renderNavbar={renderNavbar} />
71
+ ```
72
+
73
+ The layout follows the editor's width, not the window's: in a narrow panel it uses its narrow layout. Known limits: one `DdocEditor` per page; in a narrow editor on a wide screen the comment sheet still covers the whole viewport.
74
+
49
75
  ### Peer Dependencies
50
76
 
51
77
  This package requires the following peer dependencies to be installed in your project:
@@ -120,6 +146,28 @@ The preset composes `@fileverse/ui/tailwind` (class-based dark mode, animate plu
120
146
 
121
147
  You should now be set to use dDocs!
122
148
 
149
+ ### Migrating from 5.x
150
+
151
+ 6.0 changes how the editor is sized. No prop was removed.
152
+
153
+ - Give the editor a parent with a definite height (see Sizing). It no longer sizes itself from `100dvh`.
154
+ - Put your footer after the editor in normal flow. `footerHeight` has no effect and can be removed.
155
+ - The navbar and toolbars are no longer inside `#editor-canvas`. CSS that used `#editor-canvas` as their ancestor should use `.ddoc-editor-root`.
156
+ - Without `renderNavbar` the editor renders no navbar element at all. The navbar's height now comes from its content; it was a fixed 64px, 46px below `lg`.
157
+ - `editorCanvasClassNames` should not set a height.
158
+ - `zoomLevel`, `isNavbarVisible` and `isPreviewMode` are optional. Every UI state can be left out, or controlled with a value and an `onXChange` callback. The `setX` props still work and are deprecated.
159
+ - Your Tailwind build needs no config change. The new `ddoc-*` variants (container-query breakpoints that follow the editor's width) come from the `@fileverse-dev/ddoc/tailwind` preset you already use.
160
+
161
+ Behaviour that changes without a code change on your side:
162
+
163
+ - UI features that did nothing without their `setX` prop now work on internal state. The Split View toggle shows whenever live collaboration is off (it needed `setIsSplitView` before), and the comment drawer, the outline and presentation mode open without a setter. To keep one fixed, pass its value with no callback, for example `isPresentationMode={false}`. For Split View, `isSplitView={false}` keeps the editor out of Split View, but the toolbar toggle is still shown and does nothing.
164
+ - `onFocusModeChange` and the deprecated `onFocusMode` also fire when `isFocusMode` is not passed.
165
+ - `#editor-canvas` is now the document scroller (it carries `data-editor-scroll-container`), and the root (`.ddoc-editor-root`) is `overflow: hidden`.
166
+ - A navbar portalled with `navbarContainer` is positioned and layered by you; the editor only renders into the element.
167
+ - The navbar and toolbars no longer slide or fade when hidden; their rows are removed and the canvas takes the space.
168
+ - The mobile tab panel sits at the editor's bottom edge. It no longer adds `24px + env(safe-area-inset-bottom)`, so your footer must carry the safe-area inset.
169
+ - The editor's responsive classes use `:where()` in their window fallback, so they need Chrome 88+, Safari 14+ or Firefox 78+.
170
+
123
171
  # dDocProps Interface
124
172
 
125
173
  The `DdocProps` interface is a TypeScript interface that defines the properties for a page-related component. It includes properties for handling preview mode, managing publishing data, and optionally storing metadata and content associated with the page.
@@ -131,7 +179,7 @@ The `DdocProps` interface is a TypeScript interface that defines the properties
131
179
  | `initialContent` | `JSONContent` | Initial content of the editor |
132
180
  | `onChange` | `(changes: JSONContent, chunk?: any) => void` | Callback triggered on editor content changes |
133
181
  | `ref` | `React.RefObject` | Reference to access editor instance |
134
- | `isPreviewMode` | `boolean` | Controls if editor is in preview/read-only mode |
182
+ | `isPreviewMode` | `boolean` | Controls if editor is in preview/read-only mode. Optional, defaults to `false` |
135
183
  | `editorCanvasClassNames` | `string` | Additional CSS classes for editor canvas |
136
184
  | `ignoreCorruptedData` | `boolean` | Whether to ignore corrupted data during loading |
137
185
  | `onInvalidContentError` | `(error: any) => void` | Callback for handling invalid content errors |
@@ -151,19 +199,40 @@ The `DdocProps` interface is a TypeScript interface that defines the properties
151
199
 
152
200
  ## UI/UX Props
153
201
 
154
- | Property | Type | Description |
155
- | ----------------------- | ----------------------------------------- | -------------------------------------- |
156
- | `zoomLevel` | `string` | Current zoom level of the editor |
157
- | `setZoomLevel` | `React.Dispatch<SetStateAction<string>>` | Function to update zoom level |
158
- | `isNavbarVisible` | `boolean` | Controls navbar visibility |
159
- | `setIsNavbarVisible` | `React.Dispatch<SetStateAction<boolean>>` | Function to toggle navbar visibility |
160
- | `renderNavbar` | `() => JSX.Element` | Custom navbar renderer |
161
- | `renderThemeToggle` | `() => JSX.Element` | Custom theme toggle renderer |
162
- | `isPresentationMode` | `boolean` | Controls presentation mode |
163
- | `setIsPresentationMode` | `React.Dispatch<SetStateAction<boolean>>` | Function to toggle presentation mode |
164
- | `sharedSlidesLink` | `string` | Link for shared presentation slides |
165
- | `documentStyling` | `DocumentStyling` | Custom styling for document appearance |
166
- | `fonts` | `FontDescriptor[]` | Consumer-provided font catalog (see Custom Fonts) |
202
+ Every UI state can be left out (the editor keeps it internally), or controlled with a value and an `onXChange` callback. The `setX` props still work and are deprecated.
203
+
204
+ | Property | Type | Description |
205
+ | --------------------------- | ----------------------------------------- | ----------------------------------------------------------------------------------- |
206
+ | `zoomLevel` | `string` | Current zoom level of the editor. Optional, defaults to `'1'` |
207
+ | `onZoomLevelChange` | `(zoomLevel: string) => void` | Zoom changed |
208
+ | `setZoomLevel` | `React.Dispatch<SetStateAction<string>>` | Deprecated, use `onZoomLevelChange` |
209
+ | `isNavbarVisible` | `boolean` | Controls navbar visibility. Optional, defaults to `true` |
210
+ | `onNavbarVisibleChange` | `(visible: boolean) => void` | Navbar shown or hidden |
211
+ | `setIsNavbarVisible` | `React.Dispatch<SetStateAction<boolean>>` | Deprecated, use `onNavbarVisibleChange` |
212
+ | `renderNavbar` | `() => JSX.Element` | Custom navbar renderer. Without it no navbar is rendered |
213
+ | `navbarContainer` | `HTMLElement \| null` | Element to render the navbar into. Omit for in-flow. `null` renders nothing until it attaches |
214
+ | `renderThemeToggle` | `() => JSX.Element` | Custom theme toggle renderer |
215
+ | `showTOC` | `boolean` | Controls the outline |
216
+ | `onShowTOCChange` | `(show: boolean) => void` | Outline shown or hidden |
217
+ | `setShowTOC` | `React.Dispatch<SetStateAction<boolean>>` | Deprecated, use `onShowTOCChange` |
218
+ | `commentDrawerOpen` | `boolean` | Controls the comment drawer |
219
+ | `onCommentDrawerOpenChange` | `(open: boolean) => void` | Comment drawer opened or closed |
220
+ | `setCommentDrawerOpen` | `React.Dispatch<SetStateAction<boolean>>` | Deprecated, use `onCommentDrawerOpenChange` |
221
+ | `isPresentationMode` | `boolean` | Controls presentation mode |
222
+ | `onPresentationModeChange` | `(active: boolean) => void` | Presentation mode entered or left |
223
+ | `setIsPresentationMode` | `React.Dispatch<SetStateAction<boolean>>` | Deprecated, use `onPresentationModeChange` |
224
+ | `isSplitView` | `boolean` | Controls Split View |
225
+ | `onSplitViewChange` | `(active: boolean) => void` | Split View entered or left |
226
+ | `setIsSplitView` | `React.Dispatch<SetStateAction<boolean>>` | Deprecated, use `onSplitViewChange` |
227
+ | `isFocusMode` | `boolean` | Controls focus mode |
228
+ | `onFocusModeChange` | `(isFocusMode: boolean) => void` | Focus mode changed |
229
+ | `onFocusMode` | `(isFocusMode: boolean) => void` | Deprecated, use `onFocusModeChange` |
230
+ | `onStatsChange` | `(stats: { words; characters; selectedWords; pages: number \| null }) => void` | Active-tab stats; fires when any field changes. `pages` is `null` until measured |
231
+ | `setWordCount`, `setCharacterCount`, `setSelectedWordCount`, `setPageCount` | `React.Dispatch<SetStateAction<number>>` | Deprecated, use `onStatsChange` |
232
+ | `footerHeight` | `string` | Deprecated, no effect. Put the footer after the editor in normal flow |
233
+ | `sharedSlidesLink` | `string` | Link for shared presentation slides |
234
+ | `documentStyling` | `DocumentStyling` | Custom styling for document appearance |
235
+ | `fonts` | `FontDescriptor[]` | Consumer-provided font catalog (see Custom Fonts) |
167
236
 
168
237
  ## Document Styling
169
238
 
@@ -283,7 +352,8 @@ const fonts: FontDescriptor[] = [
283
352
  | `onCommentReply` | `(id: string, reply: IComment) => void` | Callback for comment replies |
284
353
  | `onNewComment` | `(comment: IComment) => void` | Callback for new comments |
285
354
  | `commentDrawerOpen` | `boolean` | Controls comment drawer visibility |
286
- | `setCommentDrawerOpen` | `(isOpen: boolean) => void` | Function to toggle comment drawer |
355
+ | `onCommentDrawerOpenChange` | `(open: boolean) => void` | Comment drawer opened or closed |
356
+ | `setCommentDrawerOpen` | `(isOpen: boolean) => void` | Deprecated, use `onCommentDrawerOpenChange` |
287
357
  | `onResolveComment` | `(commentId: string) => void` | Callback when resolving comments |
288
358
  | `onUnresolveComment` | `(commentId: string) => void` | Callback when unresolving comments |
289
359
  | `onDeleteComment` | `(commentId: string) => void` | Callback when deleting comments |
@@ -303,9 +373,9 @@ const fonts: FontDescriptor[] = [
303
373
 
304
374
  | Property | Type | Description |
305
375
  | ------------------- | ------------------------------------------------------------------------ | ----------------------------------------- |
306
- | `setCharacterCount` | `React.Dispatch<SetStateAction<number>>` | Updates character count |
307
- | `setWordCount` | `React.Dispatch<SetStateAction<number>>` | Updates word count |
308
- | `setPageCount` | `React.Dispatch<SetStateAction<number>>` | Updates approx. export page count |
376
+ | `setCharacterCount` | `React.Dispatch<SetStateAction<number>>` | Deprecated, use `onStatsChange`. Updates character count |
377
+ | `setWordCount` | `React.Dispatch<SetStateAction<number>>` | Deprecated, use `onStatsChange`. Updates word count |
378
+ | `setPageCount` | `React.Dispatch<SetStateAction<number>>` | Deprecated, use `onStatsChange`. Updates approx. export page count |
309
379
  | `ensResolutionUrl` | `string` | URL for ENS name resolution |
310
380
  | `ipfsImageUploadFn` | ` (file: File) => Promise<IpfsImageUploadResponse>` | function for secure image uploads |
311
381
  | `ipfsImageFetchFn` | ` (_data: IpfsImageFetchPayload) => Promise<{ url: string;file: File;}>` | function for fetch secure image from IPFS |
@@ -1,8 +1,8 @@
1
- import { cc as s } from "./use-headless-editor-tZq6fxul.mjs";
2
- const c = (e) => {
1
+ import { ce as s } from "./use-headless-editor-Buqsz3UI.mjs";
2
+ const n = (e) => {
3
3
  const { getYjsConvertor: t, mergeYjsUpdates: r } = s(e);
4
4
  return { getYjsConvertor: t, mergeYjsUpdates: r };
5
5
  };
6
6
  export {
7
- c as createHeadlessSyncRuntime
7
+ n as createHeadlessSyncRuntime
8
8
  };
@@ -1,4 +1,4 @@
1
- import { cd as Ql, ce as Zl, cf as eh } from "./use-headless-editor-tZq6fxul.mjs";
1
+ import { cf as Ql, cg as Zl, ch as eh } from "./use-headless-editor-Buqsz3UI.mjs";
2
2
  let An = [], Xr = [];
3
3
  (() => {
4
4
  let s = "lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,3b,f,,w,1j,,,,4,8,4,,3,7,a,2,t,,1m,,,,2,4,8,,9,,a,2,q,,2,2,1l,,4,2,4,2,2,3,3,,u,2,3,,b,2,1l,,4,5,,2,4,,k,2,m,6,,,1m,,,2,,4,8,,7,3,a,2,u,,1n,,,,c,,9,,14,,3,,1l,3,5,3,,4,7,2,b,2,t,,1m,,2,,2,,3,,5,2,7,2,b,2,s,2,1l,2,,,2,4,8,,9,,a,2,t,,20,,4,,2,3,,,8,,29,,2,7,c,8,2q,,2,9,b,6,22,2,r,,,,,,1j,e,,5,,2,5,b,,10,9,,2u,4,,6,,2,2,2,p,2,4,3,g,4,d,,2,2,6,,f,,jj,3,qa,3,t,3,t,2,u,2,1s,2,,7,8,,2,b,9,,19,3,3b,2,y,,3a,3,4,2,9,,6,3,63,2,2,,1m,,,7,,,,,2,8,6,a,2,,1c,h,1r,4,1c,7,,,5,,14,9,c,2,w,4,2,2,,3,1k,,,2,3,,,3,1m,8,2,2,48,3,,d,,7,4,,6,,3,2,5i,1m,,5,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,p,2,5,,47,2,q,i,d,,12,8,p,b,1a,3,1c,,2,4,2,2,13,,1v,6,2,2,2,2,c,,8,,1b,,1f,,,3,2,2,5,2,,,16,2,8,,6m,,2,,4,,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,14,3,4,,4l,2,fx,4,ar,2,49,b,4w,,1i,f,1k,3,1d,4,2,2,1x,3,10,5,,8,1q,,c,2,1g,9,a,4,2,,2n,3,2,,,2,6,,4g,,3,8,l,2,1l,2,,,,,m,,e,7,3,5,5f,8,2,3,,,n,,29,,2,6,,,2,,,2,,2,6j,,2,4,6,2,,2,r,2,2d,8,2,,,2,2y,,,,2,6,,,2t,3,2,4,,5,77,9,,2,6t,,a,2,,,4,,40,4,2,2,4,,w,a,14,6,2,4,8,,9,6,2,3,1a,d,,2,ba,7,,6,,,2a,m,2,7,,2,,2,3e,6,3,,,2,,7,,,20,2,3,,,,9n,2,f0b,5,1n,7,t4,,1r,4,29,,f5k,2,43q,,,3,4,5,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,79,7,c5,4,15s,7,31,7,240,5,gx7k,2o,3k,6o".split(",").map((e) => e ? parseInt(e, 36) : 1);
package/dist/index.d.ts CHANGED
@@ -19,6 +19,6 @@ export type { CollaborationProps, CollabConnectionConfig, CollabSessionMeta, Col
19
19
  export { encryptForRoomKey, decryptForRoomKey, } from './package/sync-local/crypto/room-key';
20
20
  export { WIRE_TAG, isXChaChaCipher } from './package/sync-local/crypto';
21
21
  export { fetchSessionState, seedSession, } from './package/sync-local/session-tools';
22
- export type { CommentMutationMeta, SuggestionType } from './package/types';
22
+ export type { CommentMutationMeta, DdocStats, SuggestionType, } from './package/types';
23
23
  export type { IComment } from './package/extensions/comment/comment.ts';
24
24
  export type { FontDescriptor } from './package/types';