Skip to content

Commit e6b36ca

Browse files
authored
docs(byo-ui): Bring Your Own UI section + cross-links from built-in modules (SD-2669) (#3034)
* docs(byo-ui): add Build Your Own UI section nav and stub pages (SD-2669) Adds a new top-level "Build Your Own UI" group between Modules and Solutions in docs.json, plus 10 stub pages mapping one-to-one to controller domains: overview, react-setup, toolbar-and-commands, custom-commands, comments, review, selection-and-viewport, document-control, reference-demo, api-reference. The stub pages include frontmatter, a one-line value statement, and a Note callout pointing at SD-2669 for status. Stubs land first so cross-doc callouts on the existing Modules pages can link to stable URLs while the content is being written. Overview is filled in to anchor the layer model (Document API / superdoc/ui / built-in modules) and link to every page in the section. * docs(byo-ui): align overview and stubs with brand voice (SD-2669) Rewrites the overview to lead with one sentence, the layer model table, and a 15-line code snippet showing useSuperDocCommand bound to a button. Adds icons to the CardGroup so the section index reads at a glance. Sweeps em dashes from every stub. Brand voice rules ban them in favor of hyphens, periods, or split sentences. Adds superdoc/ui and superdoc/ui/react to the docs import allowlist so future pages in this section pass the import validator. Mintlify validate passes. * docs(byo-ui): write 8 BYO-UI section pages (SD-2669) Fills in: - React setup: provider, onReady, hooks table, common pitfalls - Toolbar and commands: per-button binding, payloads, built-in id table - Custom commands: register, getState, execute, override, namespacing - Comments: list, add from selection, capture-based composer, threads - Selection and viewport: selection slice, capture, scrollIntoView, getRect - Document control: setMode (Edit/Suggest), export, replaceFile - Reference demo: what it covers, how to read it, what it deliberately doesn't do - API reference: handwritten skeleton mirroring page order review.mdx and api-reference.mdx will be revisited after the ui.review → ui.trackChanges rename lands as a separate PR. All pages follow brand voice rules: code-first, short sentences, no em dashes, public APIs only. Trade-offs called out per page. Mintlify validate passes; import validator green. * docs(byo-ui): rename Review page to Track changes, drop merged-feed surface Mirrors the controller-side rename in #3029 / superdoc 1.30.1: 'ui.review' is gone and 'ui.trackChanges' takes its place. - Rename review.mdx → track-changes.mdx and rewrite for the tracked-changes-only surface (items, total, activeId). - Document the merged comments + changes feed as a consumer-side composition pattern with useSuperDocComments + useSuperDocTrackChanges. - Update docs.json nav, overview card grid, react-setup hook table, api-reference handle + types, and reference-demo coverage table. * docs: cross-link built-in modules to Build Your Own UI Adds <Tip> callouts on the four pages a consumer hits before they realize there's a custom-UI path: modules/comments, modules/track-changes, modules/toolbar/headless, and core/react/overview. Each one routes them to the relevant Build Your Own UI page so they don't fight the built-in module before discovering useSuperDocComments / useSuperDocTrackChanges / useSuperDocCommand. * docs(byo-ui): address review feedback on canonical pages - Custom commands: rewrite execute example to use the public ui.selection.getSnapshot().selectionTarget shape (was passing the wrong target type to editor.doc.insert). Lead with a pure-additive pattern; mark the activeEditor reach as a known escape hatch. - Custom commands: split override into two patterns. Pattern A (sibling + dispatch both) is the default. Pattern B (true override) now actually toggles the mark instead of silently discarding it. - Comments: de-emphasize the reply pattern. Group-by-parent shape is public; posting a reply is filed as a follow-up and points to the reference demo as a temporary workaround. - Track changes: move the merged-feed pattern out of the canonical page and into reference-demo as 'one app-level composition'. Keeps the controller surface tight. - Drop SSO-gated linear.app URLs from public-facing docs; keep ticket IDs as plain text. * docs(byo-ui): replace ticket references with copy-safe workarounds Public docs shouldn't promise specific follow-up tickets readers can't see. Each former 'tracked under SD-XXXX' note now describes either how the surface actually works today or a workaround that ships. - comments: post replies via useSuperDocHost() + editor.doc.comments.create (full snippet, not just a pointer to the demo). - custom-commands: drop the 'when SD-2844 lands' framing; the scoped structural cast is the pattern. - selection-and-viewport / track-changes: explain that non-body entities snap because story activation mounts the surface synchronously, and show how to layer your own smooth scroll if needed. - reference-demo: show window.getSelection() rect lookup as the path for floating menus today. - document-control: full transaction-listener snippet for a dirty indicator. * docs(byo-ui): use the typed controller APIs that landed in #3035, #3039, #3040 Three workarounds drop now that the controller surface covers them: - comments.mdx: post a reply via ui.comments.reply(parentId, { text }) instead of useSuperDocHost() + editor.doc.comments.create. - custom-commands.mdx: drop the structural cast on superdoc.activeEditor; use the typed editor argument that execute({ payload, superdoc, editor }) now provides. Pattern B's chain-command cast narrowed and called out. - document-control.mdx: drop the transaction-listener snippet; use useSuperDocDocument().dirty directly. Includes the export-button example pattern. Trade-offs trimmed accordingly. API reference updated: useSuperDocDocument now returns dirty; ui.commands.register() execute receives editor; ui.comments.reply listed in the comments handle block. * docs(byo-ui): address codex review on PR #3034 - api-reference.mdx: ui.toolbar.execute(id, payload?) was signature syntax, not valid TS. Split into two valid call forms with prose. - core/react/overview.mdx: drop the <Tip> block per AGENTS.md rule ('Don't add Tips, Warnings, or deep explanations in overview pages'). Cross-link kept as plain inline paragraph. * docs(byo-ui): drop em dashes per brand style * docs(byo-ui): correct toolbar ids and comment scrollTo scope Two factual fixes flagged in PR #3034 review: - toolbar-and-commands.mdx: the built-in command id table listed several ids that aren't on PublicToolbarItemId. strike → strikethrough, color → text-color, highlight → highlight-color, and the entire 'Block' row (heading-1/-2/-3, paragraph) is dropped because no block-level commands exist on this surface today. Replaced the table with the actual id set grouped by domain. - comments.mdx: the trade-off note claimed ui.comments.scrollTo is story-aware. CommentAddress is body-scoped in the contract — only TrackedChangeAddress carries a story field — so the call doesn't navigate to header/footer/note comments. Replaced with an honest description and pointer to ui.viewport.scrollIntoView for non-body cases. * refactor: rename build-your-own-ui to bring-your-own-ui (SD-2669) The BYO acronym is conventional for 'Bring Your Own X' (BYOK, BYOC, BYOD). It also reads more accurately to what consumers actually do: they bring their existing React app + design system and slot SuperDoc behind it, rather than building a UI from scratch. - Section title in docs.json: 'Build Your Own UI' becomes 'Bring Your Own UI'. - URL slugs: /build-your-own-ui/* becomes /bring-your-own-ui/*. - apps/docs/build-your-own-ui/ renamed to apps/docs/bring-your-own-ui/ (10 mdx pages, all internal links updated). - demos/build-your-own-ui/ renamed to demos/bring-your-own-ui/. Demo's package.json name, README heading, the docs reference-demo links, the playwright port-map key, and the ci-demos.yml matrix entry all follow. - Cross-link callouts on /modules/comments, /modules/track-changes, /modules/toolbar/headless, /core/react/overview reworded. * docs: integrate Bring Your Own UI into the broader docs (SD-2669) Fixes stale correctness issues and lays out the layer model so existing docs route customers to the right path. Stage 1 — correctness fixes on BYO pages - bring-your-own-ui/reference-demo: drop the 'demo reaches through useSuperDocHost()' prose; replies and custom commands now use the typed surface after #3035 and #3039 shipped. - bring-your-own-ui/custom-commands: Pattern B (override) reframed as an advanced escape hatch with a Warning, since override truly replaces and consumers shouldn't trust the built-in to still run. - modules/track-changes: drop 'merged comments + changes feed' from the BYO callout; the merged-feed pattern moved to reference-demo as an app-level composition. Stage 2 — toolbar IA cleanup - modules/toolbar/overview: replace the two-path table with a three-path decision: Built-in / Bring Your Own UI / Headless toolbar. Recommendation: new React apps reach for BYO first; headless stays supported for non-React and existing integrations. - modules/toolbar/headless: promote the BYO redirect from a Tip to a 'Using React?' section with the supported-vs-recommended framing. - modules/toolbar/examples: drop the React + shadcn and React + MUI examples; redirect React readers to BYO. Vue / Svelte / vanilla examples stay. Stage 3 — onboarding links - getting-started/frameworks/react: add BYO card to Next steps. - getting-started/quickstart: add BYO link inline under the React scenario plus a card in 'What's next'. Stage 4 — authoring guidance + LLM context - AGENTS.md: new 'Layer model' section with explicit recommendation order (Document API > superdoc/ui > Modules > Core). API naming marks superdoc.activeEditor.commands.* as legacy/compat. Source file table extended with the doc-api contract and superdoc/ui. - llms.txt: add Bring Your Own UI link plus a Layer Model section so agents recommend the right surface. Stage 5 — disambiguate track-changes pages without URL renames - modules/track-changes: title 'Track changes module', sidebarTitle 'Track changes module'. - bring-your-own-ui/track-changes: title 'Custom track changes UI', sidebarTitle stays 'Track changes' for nav consistency. * docs: route live-state events to BYO UI; expand llms-full layer model - core/superdoc/events.mdx: leading Note tells React consumers to prefer superdoc/ui subscriptions over manual superdoc.on(...) loops for live UI state. Lifecycle / integration / analytics events stay the documented use case. - llms-full.txt: new Layer Model section after Architecture so agents recommend Document API for mutations, superdoc/ui for custom React UI, and modules for built-in UI. Lists the four common anti-patterns to steer clear of in customer code. * docs: route legacy paths to typed surfaces (SD-2669) - modules/comments: lead the 'API methods' section with a Note that steers new code to editor.doc.comments.* (mutations) or ui.comments.* (React UI). The activeEditor.commands.* docs stay for backwards compatibility but no longer present as the recommended path. - core/supereditor/overview: was framing SuperEditor as 'Custom UI implementation' and claimed Document API was 'coming soon'. Both outdated. Rewrote 'When to use' as a layer-picker that points custom React UI at Bring Your Own UI, document mutations at the Document API, and SuperEditor at the genuine low-level cases (engine internals, custom extensions, server-side headless). * docs: add BYO UI pointers in core methods + doc-api migration guide - core/superdoc/methods: lead the Comments-methods section and the activeEditor property docs with a Note steering new code to ui.comments.* / editor.doc.* / ui.commands.*. addCommentsList / removeCommentsList stay supported for built-in sidebar users; activeEditor.commands stays for backwards compat. - guides/migration/document-api: append a 'Driving custom React UI' section. Migrators dropping editor.commands/state/view from doc mutations also benefit from migrating the UI side to typed hooks in the same pass. Points at the BYO UI overview and the demo. * docs: route remaining built-in callouts to typed surfaces - getting-started/import-export: post-init insertContent example steers new code to editor.doc.insert; chain command stays for apps already wired to activeEditor.commands.* - modules/toolbar/built-in: top-of-page Tip routes React readers to Bring Your Own UI first; headless stays as the non-React alternative. * docs: add four Mermaid diagrams to anchor BYO UI conceptually - bring-your-own-ui/overview: layer-model diagram showing how Your UI → superdoc/ui/react → superdoc/ui → Document API → engine, with built-in modules as a sibling path also routed through Document API. - bring-your-own-ui/react-setup: provider-tree diagram showing one provider, one controller, many components subscribing per slice. - bring-your-own-ui/comments: capture-sequence diagram for the textarea- composer flow (select, click Comment, capture, focus moves, submit posts via createFromCapture). - getting-started/quickstart: pick-your-surface decision flow at the top of the page so visitors route to AI agents / backend / built-in editor / Bring Your Own UI without reading the section headings. * docs(byo-ui): drop the three BYO Mermaid diagrams Felt too much for the BYO surface. Removing the layer-model, provider-tree, and capture-sequence diagrams. Visual story for BYO will land via media assets and embedded demos in a follow-up, not diagrams. Quickstart 'pick your surface' diagram stays — it's site-wide orientation, not BYO-specific. * docs(byo-ui): add embedded BYO UI demo on overview page New snippet at apps/docs/snippets/components/byo-ui-demo.jsx renders a compact 'workspace slice' driven by superdoc/ui: - Custom toolbar (B / I / Comment / Edit-Suggest / Export) wired to ui.commands observables, ui.document.setMode, ui.document.export. - Activity sidebar shows live ui.comments and ui.trackChanges with Resolve / Accept / Reject actions. Empty state with hints when no comments or changes exist. - Selection-capture composer for new comments via ui.selection.capture() + ui.comments.createFromCapture(). - Try-it checklist above the workspace. Loading: lazy behind a 'Launch interactive demo' button so the 5 MB SuperDoc UMD only loads on user gesture. Editor comes from the existing UMD pattern (window.SuperDoc); controller comes from a dynamic import() of superdoc/ui's ESM entry. The embed bridges controller observables into local React state instead of using superdoc/ui/react — that bundle imports React as a bare ESM specifier, which is fragile in Mintlify's runtime. Caption text points React app users at the typed hooks. Pinned to superdoc@1.30.1 (deterministic; floats forward only when we update the snippet). v1 ships overview only; per-domain variants (comments, track-changes, custom-command) come in follow-ups. * docs(byo-ui): revert embed from overview, hits Mintlify runtime issues Two failures on the deployed preview: 1. MDX runtime can't resolve capital-letter JSX references inside a snippet ('Expected component Workspace to be defined'). The helper functions inside byo-ui-demo.jsx need to be inlined into one big component, no nested <Workspace />, <ToolButton />, etc. 2. The SuperDoc UMD throws 'Identifier fs has already been declared' on injection, suggesting it's being loaded twice. Likely a baseUrl mismatch with the existing SuperDocEditor snippet on extension pages — different URL strings dodge the dedup querySelector. Per the agreed fallback plan, don't block #3034 on the embed. The snippet file stays at apps/docs/snippets/components/byo-ui-demo.jsx for the follow-up PR where we can debug Mintlify's runtime quirks without delaying the docs launch. * docs(byo-ui): tighten sidebar — group toolbar, drop reference-demo, drop embed snippet Sidebar IA cleanup. Customer-facing surface goes from 10 entries to 8 (one of which expands to 2 sub-pages): - Group 'Toolbar and commands' + 'Custom commands' under a 'Toolbar and commands' parent. URLs unchanged; sidebarTitle on each page set to 'Built-in' / 'Custom' so the sub-entries don't collide with the group label. Page titles ('Toolbar and commands', 'Custom commands') stay verbose at the top of each page. - Drop the 'Reference demo' page. Most of it duplicated content that belongs in the demo's own README. The merged-feed pattern, the 'deliberately doesn't do' list, and the three takeaways for your own UI all moved to demos/bring-your-own-ui/README.md. Overview gets a one-line callout pointing at the demo on GitHub. - 'Document control' page sidebarTitle becomes 'Document' — matches the one-word pattern of Comments / Track changes (each named after its ui.* slice). - Drop apps/docs/snippets/components/byo-ui-demo.jsx. The embed work is captured in SD-2871 and isn't blocking the docs launch. Final sidebar: Overview / React setup / Toolbar and commands (Built-in, Custom) / Comments / Track changes / Selection and viewport / Document / API reference * docs(quickstart): hide mermaid pan/zoom controls on the surface picker actions={false} disables the Mintlify-injected zoom/pan widget on the 'Pick your surface' diagram. The diagram is small and one-glance readable; the controls add visual noise without buying anything.
1 parent 340e55a commit e6b36ca

46 files changed

Lines changed: 1622 additions & 149 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci-demos.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
run: pnpm build:superdoc
3434

3535
- name: Build @superdoc-dev/react
36-
# build-your-own-ui imports the React wrapper from its dist/.
36+
# bring-your-own-ui imports the React wrapper from its dist/.
3737
# Other demos don't need this; cheap enough to run unconditionally.
3838
run: pnpm --filter @superdoc-dev/react run build
3939

@@ -56,7 +56,7 @@ jobs:
5656
fail-fast: false
5757
matrix:
5858
demo:
59-
- build-your-own-ui
59+
- bring-your-own-ui
6060
- cdn
6161
- custom-mark
6262
- custom-node

apps/docs/AGENTS.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,22 @@ Example:
9696

9797
Don't add Tips, Warnings, or deep explanations in overview pages. Keep examples concise.
9898

99+
## Layer model
100+
101+
When documenting a customer-facing operation, name the right layer:
102+
103+
- **Document API** (`editor.doc.*`) — request/response document operations: comments, tracked changes, format apply, insert/replace/delete, mark up. Same shape on server, client, and AI agents. **Use this for any document mutation.**
104+
- **`superdoc/ui` and `superdoc/ui/react`** — browser UI controller for custom toolbar, comments sidebar, review panel, selection capture, viewport, document controls (export / mode toggle / dirty indicator). **Use this for new custom React UI.**
105+
- **Modules** (`modules/*`) — built-in SuperDoc-rendered UI. Use this when the customer is happy with the built-in look and just wants config.
106+
- **Core** (`core/*`) — low-level instance/reference surface. Lifecycle, refs, host events. Reach for it when the higher layers don't cover the case (rare).
107+
108+
Recommend the highest layer that solves the problem. Mutate documents through the Document API. Build custom React UI through `superdoc/ui/react`. Reach `superdoc.activeEditor.*` only when documenting legacy compat or a known escape hatch (and call it out as such).
109+
99110
## API naming
100111

101112
- `superdoc.export()` for SuperDoc-level methods
102-
- `superdoc.activeEditor.commands.X()` for editor commands
113+
- `editor.doc.*` for document operations (the recommended path)
114+
- `superdoc.activeEditor.commands.X()` for editor chain commands. **Legacy/compat only — prefer `editor.doc.*` for mutations and `ui.commands.*` for UI dispatch.**
103115
- `superdoc.activeEditor.getHTML()` for editor-level methods
104116
- `superdoc.getHTML()` returns `Array<string>` (one per document section)
105117

@@ -111,6 +123,9 @@ Always verify API names against the source code before documenting. Key source f
111123
| SuperDoc config | `packages/superdoc/src/core/types/index.js` |
112124
| Editor methods | `packages/super-editor/src/editors/v1/core/Editor.ts` |
113125
| Extensions | `packages/super-editor/src/editors/v1/extensions/` |
126+
| Document API contract | `packages/document-api/src/contract/operation-definitions.ts` |
127+
| `superdoc/ui` controller | `packages/super-editor/src/ui/types.ts`, `create-super-doc-ui.ts` |
128+
| `superdoc/ui/react` hooks | `packages/super-editor/src/ui/react/` |
114129

115130
## Mintlify components
116131

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
---
2+
title: 'API reference'
3+
description: 'Every hook and handle on the superdoc/ui surface.'
4+
---
5+
6+
Handwritten reference for the controller surface. Mirrors the page order above.
7+
8+
## Provider and hooks
9+
10+
Imported from `superdoc/ui/react`.
11+
12+
### `<SuperDocUIProvider>`
13+
14+
Holds one controller per editor mount. Wrap your app once.
15+
16+
```tsx
17+
<SuperDocUIProvider>{children}</SuperDocUIProvider>
18+
```
19+
20+
### `useSetSuperDoc()`
21+
22+
Returns the setter the editor mount component calls in `onReady`. Most components don't use this directly.
23+
24+
```tsx
25+
const setSuperDoc = useSetSuperDoc();
26+
<SuperDocEditor onReady={({ superdoc }) => setSuperDoc(superdoc)} />
27+
```
28+
29+
### `useSuperDocUI()`
30+
31+
Returns the controller, or `null` until ready.
32+
33+
```tsx
34+
const ui = useSuperDocUI();
35+
ui?.commands.get('bold')?.execute();
36+
```
37+
38+
### `useSuperDocCommand(id)`
39+
40+
Subscribes to one command's state. See [Toolbar and commands](/bring-your-own-ui/toolbar-and-commands).
41+
42+
```ts
43+
const bold = useSuperDocCommand('bold');
44+
// { active: boolean; disabled: boolean; value: unknown; source: 'built-in' | 'custom' }
45+
```
46+
47+
### `useSuperDocSelection()`
48+
49+
Returns the live selection slice. See [Selection and viewport](/bring-your-own-ui/selection-and-viewport).
50+
51+
```ts
52+
const selection = useSuperDocSelection();
53+
// { empty, target, selectionTarget, activeMarks, activeCommentIds, activeChangeIds, quotedText }
54+
```
55+
56+
### `useSuperDocComments()`
57+
58+
Returns the comments slice. See [Comments](/bring-your-own-ui/comments).
59+
60+
```ts
61+
const { items, total, activeIds } = useSuperDocComments();
62+
```
63+
64+
### `useSuperDocTrackChanges()`
65+
66+
Returns the tracked-changes slice. See [Track changes](/bring-your-own-ui/track-changes).
67+
68+
```ts
69+
const { items, total, activeId } = useSuperDocTrackChanges();
70+
```
71+
72+
### `useSuperDocDocument()`
73+
74+
Returns the document slice. See [Document control](/bring-your-own-ui/document-control).
75+
76+
```ts
77+
const { ready, mode, dirty } = useSuperDocDocument();
78+
```
79+
80+
### `useSuperDocToolbar()`
81+
82+
Returns the full toolbar snapshot. Re-renders on any command change. Prefer `useSuperDocCommand` per button when possible.
83+
84+
```ts
85+
const toolbar = useSuperDocToolbar();
86+
// { context, commands: Record<string, UIToolbarCommandState> }
87+
```
88+
89+
### `useSuperDocSlice(picker, initial)`
90+
91+
Subscribe to any slice from `ui.select(...)`. Use when the typed hooks above don't cover what you need.
92+
93+
```ts
94+
const documentMode = useSuperDocSlice(
95+
(ui) => ui.select((state) => state.documentMode, Object.is),
96+
null,
97+
);
98+
```
99+
100+
### `useSuperDocHost()`
101+
102+
Returns the host SuperDoc instance. Reserved for operations the controller doesn't bridge yet.
103+
104+
```ts
105+
const host = useSuperDocHost();
106+
```
107+
108+
## Controller handles
109+
110+
Imported from `superdoc/ui`. The provider handles construction; you typically reach these through `useSuperDocUI()` + the typed hooks.
111+
112+
### `ui.commands`
113+
114+
Built-in dispatch and custom-command registration.
115+
116+
```ts
117+
ui.commands.get('bold')?.execute(); // dynamic dispatch
118+
ui.commands.bold.execute(); // typed per-built-in handle
119+
ui.commands.bold.observe(({ active, disabled }) => { ... });
120+
121+
const reg = ui.commands.register({ // custom command
122+
id: 'company.insertClause',
123+
execute: ({ payload, superdoc, editor }) => true,
124+
getState: ({ state }) => ({ disabled: state.selection.empty }),
125+
});
126+
reg.invalidate();
127+
reg.unregister();
128+
```
129+
130+
### `ui.comments`
131+
132+
Live snapshot, mutations, navigation.
133+
134+
```ts
135+
ui.comments.getSnapshot(); // sync read
136+
ui.comments.subscribe(({ snapshot }) => {});
137+
ui.comments.createFromSelection({ text });
138+
ui.comments.createFromCapture(capture, { text });
139+
ui.comments.reply(parentCommentId, { text });
140+
ui.comments.resolve(commentId);
141+
ui.comments.reopen(commentId);
142+
ui.comments.delete(commentId);
143+
ui.comments.scrollTo(commentId);
144+
```
145+
146+
### `ui.trackChanges`
147+
148+
Live list, accept / reject, navigation.
149+
150+
```ts
151+
ui.trackChanges.getSnapshot();
152+
ui.trackChanges.subscribe(({ snapshot }) => {});
153+
ui.trackChanges.accept(changeId);
154+
ui.trackChanges.reject(changeId);
155+
ui.trackChanges.acceptAll();
156+
ui.trackChanges.rejectAll();
157+
ui.trackChanges.next();
158+
ui.trackChanges.previous();
159+
ui.trackChanges.scrollTo(changeId);
160+
```
161+
162+
### `ui.document`
163+
164+
Mode, export, replace.
165+
166+
```ts
167+
ui.document.getSnapshot(); // { ready, mode, dirty }
168+
ui.document.subscribe(({ snapshot }) => {});
169+
ui.document.setMode('suggesting');
170+
await ui.document.export({ exportType: ['docx'], commentsType: 'external', triggerDownload: true });
171+
await ui.document.replaceFile(file);
172+
```
173+
174+
### `ui.selection`
175+
176+
Live slice and capture.
177+
178+
```ts
179+
ui.selection.getSnapshot();
180+
ui.selection.subscribe(({ snapshot }) => {});
181+
const captured = ui.selection.capture(); // frozen, holds across focus changes
182+
```
183+
184+
### `ui.viewport`
185+
186+
Geometry. Browser-only.
187+
188+
```ts
189+
ui.viewport.getRect({ target: { kind: 'entity', entityType: 'comment', entityId } });
190+
await ui.viewport.scrollIntoView({ target, block: 'center', behavior: 'smooth' });
191+
```
192+
193+
### `ui.toolbar`
194+
195+
Aggregate toolbar surface. Mirrors the headless-toolbar shape.
196+
197+
```ts
198+
ui.toolbar.getSnapshot();
199+
ui.toolbar.subscribe(({ snapshot }) => {});
200+
ui.toolbar.execute(id); // built-ins that take no payload
201+
ui.toolbar.execute(id, payload); // built-ins that take a payload
202+
```
203+
204+
`payload` is optional. Pass it for built-ins like `font-size`, `font-family`, and `link` that accept a value; omit it for togglable built-ins like `bold` or `italic`.
205+
206+
### `ui.select(selector, equality?)`
207+
208+
Raw selector substrate underlying every domain handle.
209+
210+
```ts
211+
const sub = ui.select((state) => state.selection, shallowEqual);
212+
sub.subscribe((selection) => { ... });
213+
```
214+
215+
### `ui.destroy()`
216+
217+
Tears down every subscription. The provider calls this on unmount.
218+
219+
## Types
220+
221+
Imported from `superdoc/ui`.
222+
223+
| Type | Shape |
224+
|---|---|
225+
| `SuperDocUI` | The controller. |
226+
| `SuperDocUIState` | The unified state model. |
227+
| `SelectionSlice` | `useSuperDocSelection()` return shape. |
228+
| `SelectionCapture` | Output of `ui.selection.capture()`. |
229+
| `CommentsSlice` | `useSuperDocComments()` return shape. |
230+
| `TrackChangesSlice` | `useSuperDocTrackChanges()` return shape. |
231+
| `TrackChangesItem` | `{ id, change }`. |
232+
| `DocumentSlice` | `useSuperDocDocument()` return shape. |
233+
| `ToolbarSnapshotSlice` | `useSuperDocToolbar()` return shape. |
234+
| `UIToolbarCommandState` | Per-command state shape. |
235+
| `CustomCommandRegistration` | Input to `ui.commands.register`. |
236+
| `CustomCommandRegistrationResult` | Return from `ui.commands.register`. |
237+
| `ScrollIntoViewInput` | Input to `ui.viewport.scrollIntoView`. |
238+
| `ViewportRect` | Plain value rectangle returned by `ui.viewport.getRect`. |
239+
240+
For the source of truth, the types ship with the `superdoc` package and are exported alongside the runtime values.

0 commit comments

Comments
 (0)