diff --git a/.github/workflows/docs-validation.yml b/.github/workflows/ci-docs.yml similarity index 64% rename from .github/workflows/docs-validation.yml rename to .github/workflows/ci-docs.yml index c8ba7a2d73..9c865512ea 100644 --- a/.github/workflows/docs-validation.yml +++ b/.github/workflows/ci-docs.yml @@ -1,4 +1,4 @@ -name: Documentation Validation +name: CI Docs on: pull_request: @@ -8,7 +8,6 @@ on: jobs: validate: - name: Validate Documentation runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -22,6 +21,9 @@ jobs: node-version: '20' cache: 'pnpm' + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + - name: Install Dependencies run: pnpm install --frozen-lockfile @@ -30,3 +32,12 @@ jobs: - name: Check Broken Links run: pnpm --filter @superdoc/docs check:links + + - name: Check Code Imports + run: pnpm --filter @superdoc/docs check:imports + + - name: Build Packages + run: pnpm --prefix packages/superdoc run build + + - name: Test Code Examples + run: pnpm --filter @superdoc/docs test:examples diff --git a/apps/docs/CLAUDE.md b/apps/docs/CLAUDE.md index e96b6fea25..97deaf8683 100644 --- a/apps/docs/CLAUDE.md +++ b/apps/docs/CLAUDE.md @@ -99,7 +99,58 @@ Always verify API names against the source code before documenting. Key source f Common components: `ParamField`, `Note`, `Warning`, `Tip`, `CardGroup`, `Card`, `Tabs`, `Tab`, `Info`. +## Code examples pattern + +Every code snippet in API/reference pages must be copy-pasteable. Use `` with two tabs when a snippet is a fragment (assumes prior setup): + +- **Usage** tab — the focused snippet (what the method does) +- **Full Example** tab — complete, runnable code with imports and initialization + +```mdx + + +‍```javascript Usage +const blob = await superdoc.export({ isFinalDoc: true }); +‍``` + +‍```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: async (superdoc) => { + const blob = await superdoc.export({ isFinalDoc: true }); + }, +}); +‍``` + + +``` + +**Boilerplate by context:** + +| Context | Initialization | +|---|---| +| SuperDoc methods | `new SuperDoc({ selector, document, onReady })` | +| SuperEditor methods | `const editor = await Editor.open(file, { element })` | +| Extension commands | `editor.commands.X()` inside SuperDoc onReady or Editor.open | + +**When NOT to use CodeGroup:** Snippets that are already complete (have imports + initialization), config-only blocks, bash commands, XML/HTML examples. + +## Testing + +Code examples are tested automatically via pre-commit hooks and CI. Two checks run when `.mdx` files change: + +- `pnpm run check:imports` — validates import paths in all code blocks against an allowlist +- `pnpm run test:examples` — extracts "Full Example" blocks, executes them headlessly against a real Editor instance, and fails if any documented API doesn't exist + +The doctest suite lives in `__tests__/` and uses remark to parse MDX. When adding or modifying a Full Example, run `pnpm run test:examples` to verify it works. + ## Commands - `npx mintlify dev` — Start local dev server - `npx mintlify broken-links` — Check for broken links +- `pnpm run check:imports` — Validate code block import paths +- `pnpm run test:examples` — Run doctest suite (277 examples) diff --git a/apps/docs/__tests__/doctest.test.ts b/apps/docs/__tests__/doctest.test.ts new file mode 100644 index 0000000000..92ef2ff9bb --- /dev/null +++ b/apps/docs/__tests__/doctest.test.ts @@ -0,0 +1,92 @@ +import { test, describe, beforeAll, expect } from 'bun:test'; +import { resolve } from 'node:path'; +import { Editor, getStarterExtensions } from '../../../packages/superdoc/dist/super-editor.es.js'; +import { extractExamples } from './lib/extract.ts'; +import { transformCode, applyStubs } from './lib/transform.ts'; + +const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor; + +const docsRoot = resolve(import.meta.dir, '..'); +const fixturePath = resolve(import.meta.dir, '../../../packages/super-editor/src/tests/data/complex2.docx'); + +let fixtureBuffer: Buffer; + +beforeAll(async () => { + const bytes = await Bun.file(fixturePath).arrayBuffer(); + fixtureBuffer = Buffer.from(bytes); +}); + +/** + * Returns true if the error indicates a real API breakage in the user's code + * (method removed, renamed, or signature changed). Internal library errors + * (where the broken reference doesn't appear in the transformed code) are + * not considered API errors. + */ +function isApiError(err: unknown, code: string): boolean { + if (!(err instanceof Error)) return false; + const msg = err.message; + + if (msg.includes('is not a function')) { + const match = msg.match(/^(.+?)\s+is not a function/); + if (match) return code.includes(match[1].trim()); + return true; + } + + if (msg.includes('Cannot read properties of undefined')) { + const match = msg.match(/reading '([^']+)'/); + if (match) return code.includes(match[1]); + return true; + } + + if (msg.includes('Cannot read property')) return true; + if (msg.includes('Expected') && msg.includes('argument')) return true; + + return false; +} + +const examples = extractExamples(docsRoot); + +const byFile = new Map(); +for (const ex of examples) { + const list = byFile.get(ex.file) ?? []; + list.push(ex); + byFile.set(ex.file, list); +} + +for (const [file, fileExamples] of byFile) { + describe(file, () => { + for (const example of fileExamples) { + test(example.section, async () => { + const transformed = transformCode(example); + if (transformed === null) return; + + const code = applyStubs(transformed); + + const editor = await Editor.open(Buffer.from(fixtureBuffer), { + extensions: getStarterExtensions(), + suppressDefaultDocxStyles: true, + }); + + try { + editor.commands.selectAll(); + const fn = new AsyncFunction('editor', code); + await fn(editor); + } catch (err) { + if (isApiError(err, code)) { + throw new Error( + `API error in ${file} → ${example.section}:\n` + + ` ${(err as Error).message}\n\n` + + `Transformed code:\n${code}`, + ); + } + } finally { + editor.destroy(); + } + }); + } + }); +} + +test('extracted examples count', () => { + expect(examples.length).toBeGreaterThan(50); +}); diff --git a/apps/docs/__tests__/lib/extract.ts b/apps/docs/__tests__/lib/extract.ts new file mode 100644 index 0000000000..a64eb84b12 --- /dev/null +++ b/apps/docs/__tests__/lib/extract.ts @@ -0,0 +1,133 @@ +import { readdirSync, readFileSync } from 'node:fs'; +import { join, relative } from 'node:path'; +import { unified } from 'unified'; +import remarkParse from 'remark-parse'; +import remarkMdx from 'remark-mdx'; +import { visit } from 'unist-util-visit'; +import type { Code, Heading } from 'mdast'; + +export interface CodeExample { + file: string; + section: string; + code: string; + pattern: 'superdoc' | 'editor' | 'unknown'; + line: number; +} + +const SKIP_FILE_PATTERNS = [ + /guides\/migration\//, + /guides\/collaboration\//, + /document-api\//, + /solutions\/esign\//, + /solutions\/template-builder\//, + /ai\/ai-actions\//, + /ai\/ai-builder\//, + /getting-started\/frameworks\//, + /snippets\//, +]; + +const SKIP_IMPORTS = [ + 'openai', + '@liveblocks/', + '@hocuspocus/', + '@tiptap/', + '@y-sweet/', + 'hocuspocus', + 'fastify', + 'express', + '@superdoc-dev/ai', + '@superdoc-dev/esign', + '@superdoc-dev/template-builder', + '@superdoc-dev/superdoc-yjs-collaboration', + 'react', + 'react-dom', + 'vue', + '@angular/', +]; + +const parser = unified().use(remarkParse).use(remarkMdx); + +function globMdx(dir: string): string[] { + const results: string[] = []; + for (const entry of readdirSync(dir, { withFileTypes: true })) { + const full = join(dir, entry.name); + if (entry.isDirectory()) { + if (entry.name === 'node_modules' || entry.name.startsWith('.') || entry.name === '__tests__') continue; + results.push(...globMdx(full)); + } else if (entry.isFile() && entry.name.endsWith('.mdx')) { + results.push(full); + } + } + return results; +} + +function detectPattern(code: string): 'superdoc' | 'editor' | 'unknown' { + if (code.includes("from 'superdoc/super-editor'") || code.includes('Editor.open')) { + return 'editor'; + } + if (code.includes("from 'superdoc'") || code.includes('new SuperDoc')) { + return 'superdoc'; + } + return 'unknown'; +} + +function hasSkipImport(code: string): boolean { + for (const skipImport of SKIP_IMPORTS) { + if (code.includes(`'${skipImport}'`) || code.includes(`"${skipImport}"`)) return true; + if (skipImport.endsWith('/') && code.includes(skipImport)) return true; + } + return false; +} + +function headingText(node: Heading): string { + return node.children + .map((child) => { + if (child.type === 'text') return child.value; + if (child.type === 'inlineCode') return child.value; + return ''; + }) + .join('') + .trim(); +} + +export function extractExamples(docsRoot: string): CodeExample[] { + const files = globMdx(docsRoot); + const examples: CodeExample[] = []; + + for (const filePath of files) { + const relPath = relative(docsRoot, filePath); + if (SKIP_FILE_PATTERNS.some((p) => p.test(relPath))) continue; + + const tree = parser.parse(readFileSync(filePath, 'utf-8')); + + const headings: Array<{ line: number; text: string }> = []; + visit(tree, 'heading', (node: Heading) => { + if (node.depth <= 3 && node.position) { + headings.push({ line: node.position.start.line, text: headingText(node) }); + } + }); + + visit(tree, 'code', (node: Code) => { + if (!node.meta?.includes('Full Example')) return; + + const code = node.value; + if (hasSkipImport(code)) return; + + const pattern = detectPattern(code); + if (pattern === 'unknown') return; + + const codeLine = node.position?.start.line ?? 0; + let section = 'unknown'; + for (let i = headings.length - 1; i >= 0; i--) { + if (headings[i].line < codeLine) { + section = headings[i].text; + break; + } + } + + examples.push({ file: relPath, section, code, pattern, line: codeLine }); + }); + } + + return examples; +} diff --git a/apps/docs/__tests__/lib/transform.ts b/apps/docs/__tests__/lib/transform.ts new file mode 100644 index 0000000000..b77b2d83e1 --- /dev/null +++ b/apps/docs/__tests__/lib/transform.ts @@ -0,0 +1,170 @@ +import type { CodeExample } from './extract'; + +/** + * Transform a Full Example code block into executable code that + * receives an `editor` argument. Returns null if the code can't + * be meaningfully transformed. + */ +export function transformCode(example: CodeExample): string | null { + if (example.pattern === 'superdoc') return transformSuperdocPattern(example.code); + if (example.pattern === 'editor') return transformEditorPattern(example.code); + return null; +} + +function transformSuperdocPattern(code: string): string | null { + const lines = code.split('\n'); + + let onReadyStart = -1; + for (let i = 0; i < lines.length; i++) { + if (/onReady:\s*(async\s*)?\(/.test(lines[i])) { + onReadyStart = i; + break; + } + } + + if (onReadyStart === -1) { + return extractEventBody(code) ?? extractFallback(code); + } + + let braceDepth = 0; + let onReadyEnd = -1; + let bodyStart = -1; + + for (let i = onReadyStart; i < lines.length; i++) { + for (const ch of lines[i]) { + if (ch === '{') { + if (braceDepth === 0) bodyStart = i; + braceDepth++; + } + if (ch === '}') { + braceDepth--; + if (braceDepth === 0) { + onReadyEnd = i; + break; + } + } + } + if (onReadyEnd !== -1) break; + } + + if (bodyStart === -1 || onReadyEnd === -1) return null; + + const bodyLines = lines.slice(bodyStart + 1, onReadyEnd); + const filtered = bodyLines.filter( + (line) => + !line.trim().startsWith('const editor = superdoc') && + !line.trim().startsWith('let editor = superdoc') && + !line.trim().startsWith('const editor = instance') && + !line.trim().startsWith('let editor = instance'), + ); + + const result = filtered.join('\n').trim(); + return result || null; +} + +function transformEditorPattern(code: string): string | null { + const lines = code.split('\n'); + + const filtered = lines.filter((line) => { + const trimmed = line.trim(); + if (trimmed.startsWith('import ')) return false; + if (/(?:const|let)\s+editor\s*=\s*await\s+Editor\.open/.test(trimmed)) return false; + if (/^await\s+Editor\.open/.test(trimmed)) return false; + return true; + }); + + const result = filtered.join('\n').trim(); + return result || null; +} + +/** Extract handler body from superdoc.on() patterns that contain editor calls. */ +function extractEventBody(code: string): string | null { + const lines = code.split('\n'); + + let eventStart = -1; + for (let i = 0; i < lines.length; i++) { + if (/superdoc\.on\(/.test(lines[i])) { + eventStart = i; + break; + } + } + + if (eventStart === -1) return null; + if (!code.includes('editor.commands.') && !code.includes('editor.helpers.')) return null; + + let braceDepth = 0; + let bodyStart = -1; + let bodyEnd = -1; + + for (let i = eventStart; i < lines.length; i++) { + for (const ch of lines[i]) { + if (ch === '{') { + if (braceDepth === 0) bodyStart = i; + braceDepth++; + } + if (ch === '}') { + braceDepth--; + if (braceDepth === 0) { + bodyEnd = i; + break; + } + } + } + if (bodyEnd !== -1) break; + } + + if (bodyStart === -1 || bodyEnd === -1) return null; + + const bodyLines = lines.slice(bodyStart + 1, bodyEnd); + const filtered = bodyLines.filter( + (line) => !line.trim().startsWith('const editor = superdoc') && !line.trim().startsWith('let editor = superdoc'), + ); + + const result = filtered.join('\n').trim(); + return result || null; +} + +/** Last resort: extract any editor.commands/helpers lines from unrecognized patterns. */ +function extractFallback(code: string): string | null { + const commandLines = code.split('\n').filter((line) => { + const trimmed = line.trim(); + return ( + trimmed.includes('editor.commands.') || trimmed.includes('editor.helpers.') || trimmed.includes('editor.can().') + ); + }); + + if (commandLines.length === 0) return null; + return commandLines.join('\n').trim(); +} + +const PLACEHOLDER_REPLACEMENTS: [RegExp, string][] = [ + [/\bautoSave\b/g, '(() => {})'], + [/\bcleanup\b/g, '(() => {})'], + [/\bshowOnlineUsers\b/g, '(() => {})'], + [/\bshowFormattingToolbar\b/g, '(() => {})'], + [/\bsaveCurrentState\b/g, '(() => {})'], + [/\bupdateCommentsSidebar\b/g, '(() => {})'], + [/\bupdateReviewPanel\b/g, '(() => {})'], + [/\bshowCollaboratorsCursors\b/g, '(() => {})'], + [/\bhideLoadingSpinner\b/g, '(() => {})'], + [/\bupdateUserCursors\b/g, '(() => {})'], + [/\bshowLockBanner\b/g, '(() => {})'], + [/\badjustLayout\b/g, '(() => {})'], + [/\bupdateConnectionIndicator\b/g, '(() => {})'], + [/\brefreshToken\b/g, '(() => {})'], + [/\bclearInterval\b/g, '(() => {})'], + [/\bsaveToBackend\b/g, '(() => {})'], +]; + +export function applyStubs(code: string): string { + let result = code; + + // Prefix with ; to avoid ASI hazards when previous line lacks semicolons + result = result.replace(/console\.(log|warn|error|info|debug)\b/g, ';(() => {})'); + + for (const [pattern, replacement] of PLACEHOLDER_REPLACEMENTS) { + result = result.replace(pattern, replacement); + } + + return result; +} diff --git a/apps/docs/__tests__/tsconfig.json b/apps/docs/__tests__/tsconfig.json new file mode 100644 index 0000000000..ae2152afb5 --- /dev/null +++ b/apps/docs/__tests__/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "ESNext", + "module": "ESNext", + "moduleResolution": "bundler", + "allowJs": true, + "checkJs": false, + "noEmit": true, + "baseUrl": "../../..", + "paths": { + "@core/*": ["packages/super-editor/src/core/*"], + "@extensions/*": ["packages/super-editor/src/extensions/*"], + "@features/*": ["packages/super-editor/src/features/*"], + "@components/*": ["packages/super-editor/src/components/*"], + "@helpers/*": ["packages/super-editor/src/core/helpers/*"], + "@converter/*": ["packages/super-editor/src/core/super-converter/*"], + "@tests/*": ["packages/super-editor/src/tests/*"], + "@translator": ["packages/super-editor/src/core/super-converter/v3/node-translator/index.js"], + "@utils/*": ["packages/super-editor/src/utils/*"], + "@shared/*": ["shared/*"] + } + }, + "include": ["./**/*.ts"] +} diff --git a/apps/docs/core/superdoc/events.mdx b/apps/docs/core/superdoc/events.mdx index 47ef05628b..6ac4d4ed4a 100644 --- a/apps/docs/core/superdoc/events.mdx +++ b/apps/docs/core/superdoc/events.mdx @@ -7,53 +7,137 @@ SuperDoc uses an event system for lifecycle hooks and change notifications. ## Subscribing to events -```javascript + +```javascript Usage superdoc.on('ready', handler); // Subscribe superdoc.once('ready', handler); // One-time listener superdoc.off('ready', handler); // Unsubscribe ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, +}); + +const handler = ({ superdoc }) => { + console.log('Handler called'); +}; + +superdoc.on('ready', handler); // Subscribe +superdoc.once('ready', handler); // One-time listener +superdoc.off('ready', handler); // Unsubscribe +``` + + ## Lifecycle events ### `ready` Fired when SuperDoc is fully initialized. -```javascript + +```javascript Usage superdoc.on('ready', ({ superdoc }) => { // Safe to use all features }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, +}); + +superdoc.on('ready', ({ superdoc }) => { + // Safe to use all features +}); +``` + + ### `editorBeforeCreate` Fired before an editor is created. Use this to configure extensions or set up services. -```javascript + +```javascript Usage +superdoc.on('editorBeforeCreate', ({ editor }) => { + // Configure before editor mounts +}); +``` + +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, +}); + superdoc.on('editorBeforeCreate', ({ editor }) => { // Configure before editor mounts }); ``` + ### `editorCreate` When an editor is created. -```javascript + +```javascript Usage superdoc.on('editorCreate', ({ editor }) => { editor.focus(); }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, +}); + +superdoc.on('editorCreate', ({ editor }) => { + editor.focus(); +}); +``` + + ### `editorDestroy` When an editor is destroyed. -```javascript + +```javascript Usage +superdoc.on('editorDestroy', () => { + cleanup(); +}); +``` + +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, +}); + superdoc.on('editorDestroy', () => { cleanup(); }); ``` + ## Content events @@ -61,33 +145,83 @@ superdoc.on('editorDestroy', () => { When editor content changes. -```javascript + +```javascript Usage +superdoc.on('editor-update', ({ editor }) => { + autoSave(editor.getJSON()); +}); +``` + +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, +}); + superdoc.on('editor-update', ({ editor }) => { autoSave(editor.getJSON()); }); ``` + ### `content-error` When content processing fails. -```javascript + +```javascript Usage +superdoc.on('content-error', ({ error, editor, documentId }) => { + console.error('Content error:', error); +}); +``` + +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, +}); + superdoc.on('content-error', ({ error, editor, documentId }) => { console.error('Content error:', error); }); ``` + ### `fonts-resolved` When document fonts are resolved. -```javascript + +```javascript Usage +superdoc.on('fonts-resolved', ({ documentFonts, unsupportedFonts }) => { + if (unsupportedFonts.length > 0) { + console.warn('Unsupported fonts:', unsupportedFonts.join(', ')); + } +}); +``` + +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, +}); + superdoc.on('fonts-resolved', ({ documentFonts, unsupportedFonts }) => { if (unsupportedFonts.length > 0) { console.warn('Unsupported fonts:', unsupportedFonts.join(', ')); } }); ``` + ## Comments events @@ -95,46 +229,113 @@ superdoc.on('fonts-resolved', ({ documentFonts, unsupportedFonts }) => { When comments are modified. -```javascript + +```javascript Usage superdoc.on('comments-update', ({ type, data }) => { // type: 'add', 'update', 'deleted', 'resolved' }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, +}); + +superdoc.on('comments-update', ({ type, data }) => { + // type: 'add', 'update', 'deleted', 'resolved' +}); +``` + + ## Collaboration events ### `collaboration-ready` When collaboration is initialized. -```javascript + +```javascript Usage +superdoc.on('collaboration-ready', ({ editor }) => { + showOnlineUsers(); +}); +``` + +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, +}); + superdoc.on('collaboration-ready', ({ editor }) => { showOnlineUsers(); }); ``` + ### `awareness-update` When user presence changes. -```javascript + +```javascript Usage superdoc.on('awareness-update', ({ context, states }) => { const users = Array.from(states.values()); updateUserCursors(users); }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, +}); + +superdoc.on('awareness-update', ({ context, states }) => { + const users = Array.from(states.values()); + updateUserCursors(users); +}); +``` + + ### `locked` When document lock state changes. -```javascript + +```javascript Usage +superdoc.on('locked', ({ isLocked, lockedBy }) => { + if (isLocked) { + showLockBanner(`Locked by ${lockedBy.name}`); + } +}); +``` + +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, +}); + superdoc.on('locked', ({ isLocked, lockedBy }) => { if (isLocked) { showLockBanner(`Locked by ${lockedBy.name}`); } }); ``` + ## UI events @@ -142,11 +343,27 @@ superdoc.on('locked', ({ isLocked, lockedBy }) => { When the comments sidebar is toggled. -```javascript + +```javascript Usage +superdoc.on('sidebar-toggle', (isOpened) => { + adjustLayout(isOpened); +}); +``` + +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, +}); + superdoc.on('sidebar-toggle', (isOpened) => { adjustLayout(isOpened); }); ``` + ## Error events @@ -154,11 +371,27 @@ superdoc.on('sidebar-toggle', (isOpened) => { When an error occurs during document processing or runtime. -```javascript + +```javascript Usage +superdoc.on('exception', ({ error, document, editor }) => { + console.error('SuperDoc error:', error); +}); +``` + +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, +}); + superdoc.on('exception', ({ error, document, editor }) => { console.error('SuperDoc error:', error); }); ``` + ## Configuration-based events diff --git a/apps/docs/core/superdoc/methods.mdx b/apps/docs/core/superdoc/methods.mdx index a1ffe8a3a6..6d3589dde4 100644 --- a/apps/docs/core/superdoc/methods.mdx +++ b/apps/docs/core/superdoc/methods.mdx @@ -38,23 +38,60 @@ Export the document with various options. **Returns:** `Promise` - Document blob -```javascript + + +```javascript Usage const blob = await superdoc.export({ isFinalDoc: true, - commentsType: 'clean' + commentsType: 'clean', +}); +``` + +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: async (superdoc) => { + const blob = await superdoc.export({ + isFinalDoc: true, + commentsType: 'clean', + }); + }, }); ``` + + ### `save` Save document if in collaboration mode. **Returns:** `Promise` -```javascript + + +```javascript Usage await superdoc.save(); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: async (superdoc) => { + await superdoc.save(); + }, +}); +``` + + + ### `getHTML` Get HTML content of all editors. @@ -71,10 +108,28 @@ Get HTML content of all editors. **Returns:** `string[]` - Array of HTML strings, one per editor -```javascript + + +```javascript Usage const htmlArray = superdoc.getHTML(); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const htmlArray = superdoc.getHTML(); + console.log(htmlArray); + }, +}); +``` + + + ## Mode control ### `setDocumentMode` @@ -91,10 +146,27 @@ Change the document mode. -```javascript + + +```javascript Usage superdoc.setDocumentMode('suggesting'); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + superdoc.setDocumentMode('suggesting'); + }, +}); +``` + + + ### `lockSuperdoc` Lock or unlock the document. @@ -107,10 +179,30 @@ Lock or unlock the document. User who locked the document -```javascript + + +```javascript Usage superdoc.lockSuperdoc(true, currentUser); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + superdoc.lockSuperdoc(true, { + name: 'Jane Smith', + email: 'jane@example.com', + }); + }, +}); +``` + + + ### `setHighContrastMode` Enable/disable high contrast mode. @@ -119,10 +211,27 @@ Enable/disable high contrast mode. High contrast state -```javascript + + +```javascript Usage superdoc.setHighContrastMode(true); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + superdoc.setHighContrastMode(true); + }, +}); +``` + + + ## UI methods ### `setActiveEditor` @@ -133,10 +242,29 @@ Set which editor is currently active. Useful when working with multiple document Editor instance to set as active -```javascript + + +```javascript Usage superdoc.setActiveEditor(editor); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + documents: [doc1, doc2], + onReady: (superdoc) => { + // Switch to the second editor + const editors = superdoc.state.documents; + superdoc.setActiveEditor(editors[1].editor); + }, +}); +``` + + + ### `setDisableContextMenu` Toggle the custom context menu at runtime. @@ -145,10 +273,27 @@ Toggle the custom context menu at runtime. Whether to disable the context menu -```javascript + + +```javascript Usage superdoc.setDisableContextMenu(true); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + superdoc.setDisableContextMenu(true); + }, +}); +``` + + + ### `setTrackedChangesPreferences` Override how tracked changes are rendered in the layout engine. @@ -164,18 +309,52 @@ Override how tracked changes are rendered in the layout engine. -```javascript + + +```javascript Usage superdoc.setTrackedChangesPreferences({ mode: 'final' }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + superdoc.setTrackedChangesPreferences({ mode: 'final' }); + }, +}); +``` + + + ### `toggleRuler` Toggle ruler visibility. -```javascript + + +```javascript Usage superdoc.toggleRuler(); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + superdoc.toggleRuler(); + }, +}); +``` + + + **Removed in v1.0** — Pagination is now handled by the layout engine. Use `viewOptions.layout` in [configuration](/core/superdoc/configuration) instead. @@ -186,10 +365,27 @@ superdoc.toggleRuler(); Focus the active editor or first available. -```javascript + + +```javascript Usage superdoc.focus(); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + superdoc.focus(); + }, +}); +``` + + + ## Search methods ### `search` @@ -202,11 +398,31 @@ Search for text or regex in active editor. **Returns:** `Array` - Search matches -```javascript + + +```javascript Usage const results = superdoc.search('contract'); -const results = superdoc.search(/section \d+/gi); +const regexResults = superdoc.search(/section \d+/gi); +``` + +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const results = superdoc.search('contract'); + console.log(`Found ${results.length} matches`); + + const regexResults = superdoc.search(/section \d+/gi); + }, +}); ``` + + ### `goToSearchResult` Navigate to a search result. @@ -215,10 +431,30 @@ Navigate to a search result. Search result to navigate to -```javascript + + +```javascript Usage superdoc.goToSearchResult(results[0]); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const results = superdoc.search('contract'); + if (results.length) { + superdoc.goToSearchResult(results[0]); + } + }, +}); +``` + + + ## Comments methods ### `addCommentsList` @@ -229,18 +465,52 @@ Add a comments list to the specified element. Container for comments list -```javascript + + +```javascript Usage superdoc.addCommentsList('#comments-sidebar'); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + superdoc.addCommentsList('#comments-sidebar'); + }, +}); +``` + + + ### `removeCommentsList` Remove the comments list. -```javascript + + +```javascript Usage superdoc.removeCommentsList(); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + superdoc.removeCommentsList(); + }, +}); +``` + + + ## User management ### `addSharedUser` @@ -260,13 +530,33 @@ Add a user to the shared users list. -```javascript + + +```javascript Usage superdoc.addSharedUser({ name: 'Jane Smith', - email: 'jane@example.com' + email: 'jane@example.com', }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + superdoc.addSharedUser({ + name: 'Jane Smith', + email: 'jane@example.com', + }); + }, +}); +``` + + + ### `removeSharedUser` Remove a user from shared users. @@ -275,10 +565,27 @@ Remove a user from shared users. Email of user to remove -```javascript + + +```javascript Usage superdoc.removeSharedUser('jane@example.com'); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + superdoc.removeSharedUser('jane@example.com'); + }, +}); +``` + + + ## Lifecycle ### `destroy` @@ -287,40 +594,116 @@ Completely destroy the SuperDoc instance. This is irreversible. Cleans up all resources, events, and DOM. -```javascript + + +```javascript Usage +superdoc.destroy(); +``` + +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, +}); + +// Later, when you're done with the editor: superdoc.destroy(); ``` + + ## Event methods ### `on` Subscribe to an event. -```javascript + + +```javascript Usage +superdoc.on('ready', ({ superdoc }) => { + console.log('SuperDoc ready'); +}); +``` + +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, +}); + superdoc.on('ready', ({ superdoc }) => { console.log('SuperDoc ready'); }); ``` + + ### `once` Subscribe to an event once. -```javascript + + +```javascript Usage superdoc.once('ready', () => { // Only called once }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, +}); + +superdoc.once('ready', () => { + console.log('SuperDoc ready (one-time)'); +}); +``` + + + ### `off` Unsubscribe from an event. -```javascript + + +```javascript Usage +superdoc.off('ready', handler); +``` + +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, +}); + +const handler = ({ superdoc }) => { + console.log('SuperDoc ready'); +}; + +superdoc.on('ready', handler); + +// Later, unsubscribe: superdoc.off('ready', handler); ``` + + ## Schema introspection ### `getSchemaIntrospection` @@ -367,12 +750,31 @@ Available types: `NodeName`, `NodeAttrs`, `MarkName`, `MarkAttrs`, and spe Currently active editor instance. Returns `null` before the `ready` event. -```javascript + + +```javascript Usage if (superdoc.activeEditor) { superdoc.activeEditor.commands.toggleBold(); } ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + if (superdoc.activeEditor) { + superdoc.activeEditor.commands.toggleBold(); + } + }, +}); +``` + + + Always check for `null` before accessing. | Property | Type | Description | diff --git a/apps/docs/core/supereditor/events.mdx b/apps/docs/core/supereditor/events.mdx index 18e2615f21..22da078e2a 100644 --- a/apps/docs/core/supereditor/events.mdx +++ b/apps/docs/core/supereditor/events.mdx @@ -11,49 +11,102 @@ Events let you respond to editor lifecycle and content changes. Called before the editor view is created. -```javascript + +```javascript Usage onBeforeCreate: ({ editor }) => { // Set up external services } ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; + +const editor = await Editor.open(yourFile, { + element: document.querySelector('#editor'), + onBeforeCreate: ({ editor }) => { + // Set up external services + }, +}); +``` + + ### `onCreate` Called when editor is fully initialized and ready. -```javascript + +```javascript Usage onCreate: ({ editor }) => { editor.focus(); } ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; + +const editor = await Editor.open(yourFile, { + element: document.querySelector('#editor'), + onCreate: ({ editor }) => { + editor.focus(); + }, +}); +``` + + ### `onDestroy` Called when editor is being destroyed. Clean up resources here. -```javascript + +```javascript Usage onDestroy: () => { clearInterval(autoSaveTimer); } ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; + +const editor = await Editor.open(yourFile, { + element: document.querySelector('#editor'), + onDestroy: () => { + clearInterval(autoSaveTimer); + }, +}); +``` + + ### `onFirstRender` Called after the first render completes. -```javascript + +```javascript Usage onFirstRender: () => { hideLoadingSpinner(); } ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; + +const editor = await Editor.open(yourFile, { + element: document.querySelector('#editor'), + onFirstRender: () => { + hideLoadingSpinner(); + }, +}); +``` + + ## Content ### `onUpdate` Called when document content changes. -```javascript + +```javascript Usage onUpdate: ({ editor, transaction }) => { if (transaction.docChanged) { saveToBackend(editor.getJSON()); @@ -61,78 +114,196 @@ onUpdate: ({ editor, transaction }) => { } ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; + +const editor = await Editor.open(yourFile, { + element: document.querySelector('#editor'), + onUpdate: ({ editor, transaction }) => { + if (transaction.docChanged) { + saveToBackend(editor.getJSON()); + } + }, +}); +``` + + ### `onContentError` Called when content processing fails. -```javascript + +```javascript Usage onContentError: ({ error, editor, documentId }) => { console.error('Document error:', error); } ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; + +const editor = await Editor.open(yourFile, { + element: document.querySelector('#editor'), + onContentError: ({ error, editor, documentId }) => { + console.error('Document error:', error); + }, +}); +``` + + ## Selection ### `onSelectionUpdate` Called when selection changes (cursor movement). -```javascript + +```javascript Usage onSelectionUpdate: ({ editor }) => { toolbar.bold = editor.isActive('bold'); } ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; + +const editor = await Editor.open(yourFile, { + element: document.querySelector('#editor'), + onSelectionUpdate: ({ editor }) => { + toolbar.bold = editor.isActive('bold'); + }, +}); +``` + + ### `onFocus` Called when editor gains focus. -```javascript + +```javascript Usage onFocus: ({ editor, event }) => { showFormattingToolbar(); } ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; + +const editor = await Editor.open(yourFile, { + element: document.querySelector('#editor'), + onFocus: ({ editor, event }) => { + showFormattingToolbar(); + }, +}); +``` + + ### `onBlur` Called when editor loses focus. -```javascript + +```javascript Usage onBlur: ({ editor, event }) => { saveCurrentState(); } ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; + +const editor = await Editor.open(yourFile, { + element: document.querySelector('#editor'), + onBlur: ({ editor, event }) => { + saveCurrentState(); + }, +}); +``` + + ## Features ### `onCommentsUpdate` -```javascript + +```javascript Usage onCommentsUpdate: ({ editor }) => { updateCommentsSidebar(); } ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; + +const editor = await Editor.open(yourFile, { + element: document.querySelector('#editor'), + onCommentsUpdate: ({ editor }) => { + updateCommentsSidebar(); + }, +}); +``` + + ### `onCommentsLoaded` -```javascript + +```javascript Usage onCommentsLoaded: ({ editor, comments }) => { console.log(`Loaded ${comments.length} comments`); } ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; + +const editor = await Editor.open(yourFile, { + element: document.querySelector('#editor'), + onCommentsLoaded: ({ editor, comments }) => { + console.log(`Loaded ${comments.length} comments`); + }, +}); +``` + + ### `onTrackedChangesUpdate` -```javascript + +```javascript Usage onTrackedChangesUpdate: ({ editor }) => { updateReviewPanel(); } ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; + +const editor = await Editor.open(yourFile, { + element: document.querySelector('#editor'), + onTrackedChangesUpdate: ({ editor }) => { + updateReviewPanel(); + }, +}); +``` + + ### `onCollaborationReady` -```javascript + +```javascript Usage onCollaborationReady: ({ editor, ydoc }) => { showCollaboratorsCursors(); } ``` + +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; + +const editor = await Editor.open(yourFile, { + element: document.querySelector('#editor'), + onCollaborationReady: ({ editor, ydoc }) => { + showCollaboratorsCursors(); + }, +}); +``` + diff --git a/apps/docs/core/supereditor/methods.mdx b/apps/docs/core/supereditor/methods.mdx index e897045315..084eb87795 100644 --- a/apps/docs/core/supereditor/methods.mdx +++ b/apps/docs/core/supereditor/methods.mdx @@ -30,11 +30,27 @@ Open a document from a file, URL, or buffer. -```javascript + + +```javascript Usage await editor.open(docxFile); await editor.open(null, { mode: 'html', html: '

Hello

' }); ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + +await editor.open(docxFile); +await editor.open(null, { mode: 'html', html: '

Hello

' }); +``` + +
+ This is the instance method. For one-liner creation, use the static `Editor.open()` factory — see [Configuration](/core/supereditor/configuration). @@ -43,11 +59,27 @@ This is the instance method. For one-liner creation, use the static `Editor.open Close the current document. The editor instance stays alive for reuse. -```javascript + + +```javascript Usage editor.close(); await editor.open(anotherFile); ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + +editor.close(); +await editor.open(anotherFile); +``` + + + ### `save` Save back to the original source path (Node.js only). @@ -69,11 +101,27 @@ Save back to the original source path (Node.js only). -```javascript + + +```javascript Usage await editor.save(); await editor.save({ isFinalDoc: true }); ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + +await editor.save(); +await editor.save({ isFinalDoc: true }); +``` + + + Throws if the editor was opened from a Blob/Buffer instead of a file path. Use `saveTo()` or `exportDocument()` instead. ### `saveTo` @@ -84,19 +132,50 @@ Save to a specific path (Node.js only). File path -```javascript + + +```javascript Usage +await editor.saveTo('/path/to/output.docx'); +``` + +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + await editor.saveTo('/path/to/output.docx'); ``` + + ### `exportDocument` Export as a Blob (browser) or Buffer (Node.js). -```javascript + + +```javascript Usage const blob = await editor.exportDocument(); const blob = await editor.exportDocument({ isFinalDoc: true }); ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + +const blob = await editor.exportDocument(); +const blob = await editor.exportDocument({ isFinalDoc: true }); +``` + + + ### `exportDocx` Lower-level export with additional control. @@ -118,105 +197,297 @@ Lower-level export with additional control. -```javascript + + +```javascript Usage +const blob = await editor.exportDocx({ + isFinalDoc: true, + commentsType: 'clean' +}); +``` + +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + const blob = await editor.exportDocx({ isFinalDoc: true, commentsType: 'clean' }); ``` + + ### `replaceFile` Replace the current DOCX with a new file. -```javascript + + +```javascript Usage await editor.replaceFile(newDocxFile); ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + +await editor.replaceFile(newDocxFile); +``` + + + ## Content ### `getHTML` -```javascript + + +```javascript Usage +const html = editor.getHTML(); +const html = editor.getHTML({ unflattenLists: true }); +``` + +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + const html = editor.getHTML(); const html = editor.getHTML({ unflattenLists: true }); ``` + + ### `getJSON` -```javascript + + +```javascript Usage +const json = editor.getJSON(); +``` + +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + const json = editor.getJSON(); ``` + + ### `getMarkdown` -```javascript + + +```javascript Usage +const md = await editor.getMarkdown(); +``` + +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + const md = await editor.getMarkdown(); ``` + + ### `replaceContent` Replace the entire document content. -```javascript + + +```javascript Usage editor.replaceContent(proseMirrorJson); ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + +editor.replaceContent(proseMirrorJson); +``` + + + ### `replaceNodeWithHTML` Replace a specific node with HTML. -```javascript + + +```javascript Usage +const table = editor.getNodesOfType('table')[0]; +editor.replaceNodeWithHTML(table, '...
'); +``` + +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + const table = editor.getNodesOfType('table')[0]; editor.replaceNodeWithHTML(table, '...
'); ``` +
+ ## Editor control ### `mount` / `unmount` -```javascript + + +```javascript Usage +editor.mount(document.querySelector('#editor')); +editor.unmount(); // Keeps instance alive +``` + +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + editor.mount(document.querySelector('#editor')); editor.unmount(); // Keeps instance alive ``` + + ### `destroy` Permanently destroy the editor. Irreversible. The instance cannot be used after this. -```javascript + + +```javascript Usage +editor.destroy(); +``` + +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + editor.destroy(); ``` + + ### `focus` / `blur` -```javascript + + +```javascript Usage +editor.focus(); +editor.blur(); +``` + +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + editor.focus(); editor.blur(); ``` + + ### `setEditable` -```javascript + + +```javascript Usage +editor.setEditable(false); // Read-only +editor.setEditable(true); // Editable +``` + +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + editor.setEditable(false); // Read-only editor.setEditable(true); // Editable ``` + + ### `setDocumentMode` -```javascript + + +```javascript Usage +editor.setDocumentMode('editing'); // Full editing +editor.setDocumentMode('suggesting'); // Track changes +editor.setDocumentMode('viewing'); // Read-only +``` + +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + editor.setDocumentMode('editing'); // Full editing editor.setDocumentMode('suggesting'); // Track changes editor.setDocumentMode('viewing'); // Read-only ``` + + ## Commands All commands are accessed via `editor.commands`: -```javascript + + +```javascript Usage // Formatting editor.commands.toggleBold(); editor.commands.toggleItalic(); @@ -230,6 +501,29 @@ editor.commands.setTextSelection({ from: 10, to: 20 }); editor.commands.selectAll(); ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + +// Formatting +editor.commands.toggleBold(); +editor.commands.toggleItalic(); +editor.commands.toggleUnderline(); + +// Tables +editor.commands.insertTable({ rows: 3, cols: 3 }); + +// Selection +editor.commands.setTextSelection({ from: 10, to: 20 }); +editor.commands.selectAll(); +``` + + + ### `insertContent` Insert content with automatic format detection. @@ -249,48 +543,127 @@ Insert content with automatic format detection. -```javascript + + +```javascript Usage editor.commands.insertContent(htmlContent, { contentType: 'html' }); editor.commands.insertContent(markdownText, { contentType: 'markdown' }); editor.commands.insertContent('Plain text', { contentType: 'text' }); ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + +editor.commands.insertContent(htmlContent, { contentType: 'html' }); +editor.commands.insertContent(markdownText, { contentType: 'markdown' }); +editor.commands.insertContent('Plain text', { contentType: 'text' }); +``` + + + HTML and Markdown inline styles are stripped on import to ensure Word compatibility. ## Document metadata ### `getMetadata` -```javascript + + +```javascript Usage const { documentGuid, isModified, version } = editor.getMetadata(); ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + +const { documentGuid, isModified, version } = editor.getMetadata(); +``` + + + ### `getDocumentIdentifier` Get a stable identifier (GUID or content hash). -```javascript + + +```javascript Usage +const id = await editor.getDocumentIdentifier(); +``` + +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + const id = await editor.getDocumentIdentifier(); ``` + + ### `isDocumentModified` -```javascript + + +```javascript Usage if (editor.isDocumentModified()) { // Prompt user to save } ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + +if (editor.isDocumentModified()) { + // Prompt user to save +} +``` + + + ## Schema ### `getSchemaSummaryJSON` Generate a summary of the document schema. Useful for AI agents that need to understand the document structure. -```javascript + + +```javascript Usage +const summary = await editor.getSchemaSummaryJSON(); +``` + +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + const summary = await editor.getSchemaSummaryJSON(); ``` + + ## Position & coordinates ### `getElementAtPos` @@ -301,62 +674,175 @@ Get the DOM element at a document position. Document position -```javascript + + +```javascript Usage +const element = editor.getElementAtPos(42); +``` + +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + const element = editor.getElementAtPos(42); ``` + + ### `getNodesOfType` Get all nodes of a specific type. -```javascript + + +```javascript Usage const tables = editor.getNodesOfType('table'); const paragraphs = editor.getNodesOfType('paragraph'); ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + +const tables = editor.getNodesOfType('table'); +const paragraphs = editor.getNodesOfType('paragraph'); +``` + + + ### `isActive` Check if a node or mark is active. -```javascript + + +```javascript Usage editor.isActive('bold'); editor.isActive('heading', { level: 2 }); ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + +editor.isActive('bold'); +editor.isActive('heading', { level: 2 }); +``` + + + ### `getAttributes` Get attributes of the active node or mark. -```javascript + + +```javascript Usage const attrs = editor.getAttributes('link'); console.log(attrs.href); ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + +const attrs = editor.getAttributes('link'); +console.log(attrs.href); +``` + + + ## Page & layout ### `getPageStyles` -```javascript + + +```javascript Usage const styles = editor.getPageStyles(); ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + +const styles = editor.getPageStyles(); +``` + + + ### `updatePageStyle` -```javascript + + +```javascript Usage +editor.updatePageStyle({ + pageMargins: { top: '1in', bottom: '1in', left: '1in', right: '1in' } +}); +``` + +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + editor.updatePageStyle({ pageMargins: { top: '1in', bottom: '1in', left: '1in', right: '1in' } }); ``` + + ## Search -```javascript + + +```javascript Usage const results = editor.commands.search('hello'); const results = editor.commands.search(/\d{3}-\d{4}/gi); editor.commands.goToSearchResult(results[0]); ``` +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; +import 'superdoc/style.css'; + +const editor = await Editor.open(yourFile, { + element: document.getElementById('editor'), +}); + +const results = editor.commands.search('hello'); +const results = editor.commands.search(/\d{3}-\d{4}/gi); + +editor.commands.goToSearchResult(results[0]); +``` + + + ## Properties | Property | Type | Description | diff --git a/apps/docs/extensions/block-node.mdx b/apps/docs/extensions/block-node.mdx index 2da5a9475a..3d71f3dfee 100644 --- a/apps/docs/extensions/block-node.mdx +++ b/apps/docs/extensions/block-node.mdx @@ -20,11 +20,28 @@ The replacement node should have the same type as the original **Example:** -```javascript + +```javascript Usage const newParagraph = editor.schema.nodes.paragraph.create({}, editor.schema.text('New content')) editor.commands.replaceBlockNodeById('block-123', newParagraph) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + const newParagraph = editor.schema.nodes.paragraph.create({}, editor.schema.text('New content')) + editor.commands.replaceBlockNodeById('block-123', newParagraph) + }, +}); +``` + + **Parameters:** @@ -44,10 +61,26 @@ Completely removes the node from the document **Example:** -```javascript + +```javascript Usage editor.commands.deleteBlockNodeById('block-123') ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.deleteBlockNodeById('block-123') + }, +}); +``` + + **Parameters:** @@ -64,10 +97,26 @@ Merges new attributes with existing ones **Example:** -```javascript + +```javascript Usage editor.commands.updateBlockNodeAttributes('block-123', { textAlign: 'center' }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.updateBlockNodeAttributes('block-123', { textAlign: 'center' }) + }, +}); +``` + + **Parameters:** @@ -85,11 +134,28 @@ Get all block nodes in the document **Example:** -```javascript + +```javascript Usage const blocks = editor.helpers.blockNode.getBlockNodes() console.log(`Found ${blocks.length} block nodes`) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + const blocks = editor.helpers.blockNode.getBlockNodes() + console.log(`Found ${blocks.length} block nodes`) + }, +}); +``` + + **Returns:** @@ -102,11 +168,28 @@ Get a specific block node by its ID **Example:** -```javascript + +```javascript Usage const block = editor.helpers.blockNode.getBlockNodeById('block-123') if (block.length) console.log('Found:', block[0].node.type.name) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + const block = editor.helpers.blockNode.getBlockNodeById('block-123') + if (block.length) console.log('Found:', block[0].node.type.name) + }, +}); +``` + + **Parameters:** @@ -125,11 +208,28 @@ Get all block nodes of a specific type **Example:** -```javascript + +```javascript Usage const paragraphs = editor.helpers.blockNode.getBlockNodesByType('paragraph') const headings = editor.helpers.blockNode.getBlockNodesByType('heading') ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + const paragraphs = editor.helpers.blockNode.getBlockNodesByType('paragraph') + const headings = editor.helpers.blockNode.getBlockNodesByType('heading') + }, +}); +``` + + **Parameters:** @@ -148,7 +248,8 @@ Get all block nodes within a position range **Example:** -```javascript + +```javascript Usage const selection = editor.state.selection const blocksInSelection = editor.helpers.blockNode.getBlockNodesInRange( selection.from, @@ -156,6 +257,25 @@ const blocksInSelection = editor.helpers.blockNode.getBlockNodesInRange( ) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + const selection = editor.state.selection + const blocksInSelection = editor.helpers.blockNode.getBlockNodesInRange( + selection.from, + selection.to + ) + }, +}); +``` + + **Parameters:** diff --git a/apps/docs/extensions/bold.mdx b/apps/docs/extensions/bold.mdx index f60499821c..82dc80f641 100644 --- a/apps/docs/extensions/bold.mdx +++ b/apps/docs/extensions/bold.mdx @@ -14,26 +14,74 @@ import Description from '/snippets/extensions/bold.mdx' Apply bold formatting to the current selection. -```javascript + +```javascript Usage editor.commands.setBold() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.setBold(); + }, +}); +``` + + ### `unsetBold` Remove bold formatting from the current selection. -```javascript + +```javascript Usage editor.commands.unsetBold() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.unsetBold(); + }, +}); +``` + + ### `toggleBold` Toggle bold formatting on the current selection. -```javascript + +```javascript Usage editor.commands.toggleBold() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.toggleBold(); + }, +}); +``` + + ## Keyboard shortcuts | Command | Shortcut | Description | diff --git a/apps/docs/extensions/bookmarks.mdx b/apps/docs/extensions/bookmarks.mdx index 7fd120f68e..1a19161131 100644 --- a/apps/docs/extensions/bookmarks.mdx +++ b/apps/docs/extensions/bookmarks.mdx @@ -16,11 +16,28 @@ Insert a bookmark at the current cursor position. Bookmarks are invisible naviga **Example:** -```javascript + +```javascript Usage editor.commands.insertBookmark({ name: 'chapter1' }) editor.commands.insertBookmark({ name: 'introduction', id: 'intro-001' }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.insertBookmark({ name: 'chapter1' }) + editor.commands.insertBookmark({ name: 'introduction', id: 'intro-001' }) + }, +}); +``` + + **Parameters:** @@ -33,10 +50,26 @@ Navigate to a bookmark by name. Scrolls the document to the bookmark position. **Example:** -```javascript + +```javascript Usage editor.commands.goToBookmark('chapter1') ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.goToBookmark('chapter1') + }, +}); +``` + + **Parameters:** diff --git a/apps/docs/extensions/bullet-list.mdx b/apps/docs/extensions/bullet-list.mdx index 66b473337b..73ce6c3168 100644 --- a/apps/docs/extensions/bullet-list.mdx +++ b/apps/docs/extensions/bullet-list.mdx @@ -20,10 +20,26 @@ Toggle bullet list formatting on the current selection. Converts selected paragr **Example:** -```javascript + +```javascript Usage editor.commands.toggleBulletList() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.toggleBulletList() + }, +}); +``` + + ## Keyboard shortcuts | Command | Shortcut | Description | diff --git a/apps/docs/extensions/color.mdx b/apps/docs/extensions/color.mdx index 9fe416b684..f6b831351d 100644 --- a/apps/docs/extensions/color.mdx +++ b/apps/docs/extensions/color.mdx @@ -36,11 +36,28 @@ Preserves other text styling attributes **Example:** -```javascript + +```javascript Usage // Set to red using hex editor.commands.setColor('#ff0000') ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Set to red using hex + editor.commands.setColor('#ff0000'); + }, +}); +``` + + **Parameters:** @@ -57,10 +74,26 @@ Removes color while preserving other text styles **Example:** -```javascript + +```javascript Usage editor.commands.unsetColor() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.unsetColor(); + }, +}); +``` + + ## Types ### `ColorValue` diff --git a/apps/docs/extensions/comments.mdx b/apps/docs/extensions/comments.mdx index 4932c9efb5..fdb9a22752 100644 --- a/apps/docs/extensions/comments.mdx +++ b/apps/docs/extensions/comments.mdx @@ -24,7 +24,8 @@ modules: { Add a comment to the current text selection. Requires text to be selected. -```javascript + +```javascript Usage // Simple text comment editor.commands.addComment('Please review this section') @@ -37,6 +38,30 @@ editor.commands.addComment({ }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Simple text comment + editor.commands.addComment('Please review this section') + + // With options + editor.commands.addComment({ + content: 'Please review', + author: 'Jane Smith', + authorEmail: 'jane@example.com', + isInternal: false + }) + }, +}); +``` + + **Parameters:** @@ -47,13 +72,32 @@ editor.commands.addComment({ Add a reply to an existing comment thread. -```javascript + +```javascript Usage editor.commands.addCommentReply({ parentId: 'comment-123', content: 'Done, updated the wording.' }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.addCommentReply({ + parentId: 'comment-123', + content: 'Done, updated the wording.' + }) + }, +}); +``` + + **Parameters:** @@ -64,10 +108,26 @@ editor.commands.addCommentReply({ Remove a comment and its highlight marks from the document. -```javascript + +```javascript Usage editor.commands.removeComment({ commentId: 'abc-123' }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.removeComment({ commentId: 'abc-123' }) + }, +}); +``` + + **Parameters:** @@ -78,10 +138,26 @@ editor.commands.removeComment({ commentId: 'abc-123' }) Resolve a comment. Removes the highlight but preserves positional anchors for export. -```javascript + +```javascript Usage editor.commands.resolveComment({ commentId: 'abc-123' }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.resolveComment({ commentId: 'abc-123' }) + }, +}); +``` + + **Parameters:** @@ -92,29 +168,80 @@ editor.commands.resolveComment({ commentId: 'abc-123' }) Set the active/selected comment thread by ID. -```javascript + +```javascript Usage editor.commands.setActiveComment({ commentId: 'abc-123' }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.setActiveComment({ commentId: 'abc-123' }) + }, +}); +``` + + ### `setCommentInternal` Toggle whether a comment is internal (private) or external. -```javascript + +```javascript Usage editor.commands.setCommentInternal({ commentId: 'abc-123', isInternal: true }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.setCommentInternal({ + commentId: 'abc-123', + isInternal: true + }) + }, +}); +``` + + ### `setCursorById` Move the cursor to the start of a comment's range. Also works for tracked change IDs. -```javascript + +```javascript Usage editor.commands.setCursorById('abc-123') ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.setCursorById('abc-123') + }, +}); +``` + + ## Events ```javascript diff --git a/apps/docs/extensions/content-block.mdx b/apps/docs/extensions/content-block.mdx index 3d03b712fa..adc31c97cf 100644 --- a/apps/docs/extensions/content-block.mdx +++ b/apps/docs/extensions/content-block.mdx @@ -44,10 +44,26 @@ Creates a visual separator between content sections **Example:** -```javascript + +```javascript Usage editor.commands.insertHorizontalRule() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.insertHorizontalRule() + }, +}); +``` + + ### `insertContentBlock` Insert a content block @@ -58,11 +74,28 @@ Used for spacing, dividers, and special inline content **Example:** -```javascript + +```javascript Usage // Insert a spacer block editor.commands.insertContentBlock({ size: { height: 20 } }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Insert a spacer block + editor.commands.insertContentBlock({ size: { height: 20 } }) + }, +}); +``` + + **Parameters:** diff --git a/apps/docs/extensions/custom-selection.mdx b/apps/docs/extensions/custom-selection.mdx index b65016279d..49f557a353 100644 --- a/apps/docs/extensions/custom-selection.mdx +++ b/apps/docs/extensions/custom-selection.mdx @@ -20,11 +20,28 @@ Used internally to maintain selection when interacting with toolbar **Example:** -```javascript + +```javascript Usage // Restore selection after toolbar interaction editor.commands.restorePreservedSelection() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Restore selection after toolbar interaction + editor.commands.restorePreservedSelection() + }, +}); +``` + + **Returns:** `Function` Command function ## Types diff --git a/apps/docs/extensions/document-section.mdx b/apps/docs/extensions/document-section.mdx index 4386768b78..ed4d7b1496 100644 --- a/apps/docs/extensions/document-section.mdx +++ b/apps/docs/extensions/document-section.mdx @@ -10,7 +10,7 @@ Encapsulate and manage discrete parts of documents. Legal clauses stay locked wh Included by default in SuperDoc. ```javascript -import { DocumentSection } from 'superdoc/extensions'; +import { DocumentSection } from 'superdoc/super-editor'; ``` ## Commands @@ -19,7 +19,8 @@ import { DocumentSection } from 'superdoc/extensions'; Create a new document section. -```javascript + +```javascript Usage editor.commands.createDocumentSection({ id: 'legal-1', title: 'Terms & Conditions', @@ -29,35 +30,105 @@ editor.commands.createDocumentSection({ }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.createDocumentSection({ + id: 'legal-1', + title: 'Terms & Conditions', + description: 'Legal terms', + isLocked: true, + html: '

Content...

' + }) + }, +}); +``` +
+ ### `removeSectionAtSelection` Remove the section at the current cursor position. -```javascript + +```javascript Usage editor.commands.removeSectionAtSelection() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.removeSectionAtSelection() + }, +}); +``` + + ### `removeSectionById` Remove a section by its ID. -```javascript + +```javascript Usage editor.commands.removeSectionById('legal-1') ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.removeSectionById('legal-1') + }, +}); +``` + + ### `lockSectionById` Lock a section to prevent editing. -```javascript + +```javascript Usage editor.commands.lockSectionById('legal-1') ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.lockSectionById('legal-1') + }, +}); +``` + + ### `updateSectionById` Update a section's content or attributes. -```javascript + +```javascript Usage editor.commands.updateSectionById({ id: 'legal-1', html: '

Updated...

', @@ -65,9 +136,29 @@ editor.commands.updateSectionById({ }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.updateSectionById({ + id: 'legal-1', + html: '

Updated...

', + attrs: { title: 'New Title' } + }) + }, +}); +``` +
+ ## Helpers -```javascript + +```javascript Usage // Get all sections const sections = editor.helpers.documentSection.getAllSections(editor); @@ -83,6 +174,33 @@ const childEditor = editor.helpers.documentSection.getLinkedSectionEditor( ); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Get all sections + const sections = editor.helpers.documentSection.getAllSections(editor); + + // Export sections + const html = editor.helpers.documentSection.exportSectionsToHTML(editor); + const json = editor.helpers.documentSection.exportSectionsToJSON(editor); + + // Create a linked editor for a section + const childEditor = editor.helpers.documentSection.getLinkedSectionEditor( + 'section-id', + { element: '#editor' }, + editor + ); + }, +}); +``` + + ## Attributes | Attribute | Type | Default | Description | @@ -114,7 +232,8 @@ Sections export as Word content controls: ### Contract structure -```javascript + +```javascript Usage const contractSections = [ { id: 'parties', title: '1. Parties', isLocked: false }, { id: 'terms', title: '2. Terms', isLocked: true }, @@ -130,9 +249,37 @@ contractSections.forEach(section => { }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + const contractSections = [ + { id: 'parties', title: '1. Parties', isLocked: false }, + { id: 'terms', title: '2. Terms', isLocked: true }, + { id: 'pricing', title: '3. Pricing', isLocked: false }, + { id: 'signatures', title: '4. Signatures', isLocked: true } + ]; + + contractSections.forEach(section => { + editor.commands.createDocumentSection({ + ...section, + html: loadTemplate(section.id) + }); + }); + }, +}); +``` + + ### Role-based locking -```javascript + +```javascript Usage function applyRolePermissions(userRole) { const sections = editor.helpers.documentSection.getAllSections(editor); @@ -146,6 +293,31 @@ function applyRolePermissions(userRole) { } ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + function applyRolePermissions(userRole) { + const sections = editor.helpers.documentSection.getAllSections(editor); + + sections.forEach(({ node }) => { + const { id, sectionType } = node.attrs; + + if (sectionType === 'legal' && userRole !== 'legal') { + editor.commands.lockSectionById(id); + } + }); + } + }, +}); +``` + + ## Related - [Field Annotation](/extensions/field-annotation) - Form fields diff --git a/apps/docs/extensions/document.mdx b/apps/docs/extensions/document.mdx index d34b074827..95e9752f40 100644 --- a/apps/docs/extensions/document.mdx +++ b/apps/docs/extensions/document.mdx @@ -20,12 +20,30 @@ Returns word count, character count, and paragraph count **Example:** -```javascript + +```javascript Usage // Get word and character count const stats = editor.commands.getDocumentStats() console.log(`${stats.words} words, ${stats.characters} characters`) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Get word and character count + const stats = editor.commands.getDocumentStats() + console.log(`${stats.words} words, ${stats.characters} characters`) + }, +}); +``` + + ### `clearDocument` Clear entire document @@ -36,17 +54,34 @@ Replaces all content with an empty paragraph **Example:** -```javascript + +```javascript Usage editor.commands.clearDocument() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.clearDocument() + }, +}); +``` + + ### `setSectionPageMarginsAtSelection` Set page margins for the section at the current cursor position. **Example:** -```javascript + +```javascript Usage editor.commands.setSectionPageMarginsAtSelection({ topInches: 1, rightInches: 1, @@ -55,6 +90,26 @@ editor.commands.setSectionPageMarginsAtSelection({ }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.setSectionPageMarginsAtSelection({ + topInches: 1, + rightInches: 1, + bottomInches: 1, + leftInches: 1 + }) + }, +}); +``` + + **Parameters:** diff --git a/apps/docs/extensions/field-annotation.mdx b/apps/docs/extensions/field-annotation.mdx index c64c56e48b..75fd63890f 100644 --- a/apps/docs/extensions/field-annotation.mdx +++ b/apps/docs/extensions/field-annotation.mdx @@ -28,17 +28,24 @@ description: "Interactive form fields for documents. It can be used when variabl **Basic Setup:** ```javascript -import { FieldAnnotationPlugin } from '@superdoc/field-annotation'; - -const plugin = FieldAnnotationPlugin({ - editor: myEditor, - handleDropOutside: true +import { SuperDoc } from 'superdoc'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + // Field annotations are included by default via getStarterExtensions(). + // Configure options here: + fieldAnnotation: { + handleDropOutside: true, + borderColor: '#b015b3', + }, }); ``` **Form Template Workflow:** -```javascript + +```javascript Usage // 1. Create form fields const fields = [ { id: 'name', label: 'Full Name', type: 'text' }, @@ -67,6 +74,46 @@ editor.annotate([ ]); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // 1. Create form fields + const fields = [ + { id: 'name', label: 'Full Name', type: 'text' }, + { id: 'date', label: 'Date', type: 'text' }, + { id: 'signature', label: 'Sign Here', type: 'signature' } + ]; + + // 2. Insert fields into document + fields.forEach((field, i) => { + editor.commands.addFieldAnnotation(i * 100, { + fieldId: field.id, + displayLabel: field.label, + type: field.type + }); + }); + + // 3. Handle user interactions + editor.on('fieldAnnotationClicked', ({ node }) => { + openFieldEditor(node.attrs.fieldId); + }); + + // 4. Fill and export + editor.annotate([ + { input_id: 'name', input_value: 'John Doe' }, + { input_id: 'date', input_value: '2024-01-15' } + ]); + }, +}); +``` + + ## Commands ### Find & Search @@ -77,7 +124,8 @@ Find field annotations matching a predicate function Added in v0.10.3 -```javascript + +```javascript Usage // Find all signature fields const signatureFields = findFieldAnnotations( node => node.attrs.type === 'signature', @@ -85,7 +133,27 @@ const signatureFields = findFieldAnnotations( ); ``` -```javascript +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Find all signature fields + const signatureFields = findFieldAnnotations( + node => node.attrs.type === 'signature', + editor.state + ); + }, +}); +``` + + + +```javascript Usage // Find fields with specific color const redFields = findFieldAnnotations( node => node.attrs.fieldColor === '#FF0000', @@ -93,6 +161,25 @@ const redFields = findFieldAnnotations( ); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Find fields with specific color + const redFields = findFieldAnnotations( + node => node.attrs.fieldColor === '#FF0000', + editor.state + ); + }, +}); +``` + + **Parameters:** @@ -123,18 +210,54 @@ const redFields = findFieldAnnotations( Find all field annotations between two positions -```javascript + +```javascript Usage // Find fields in selection const { from, to } = state.selection; const selectedFields = findFieldAnnotationsBetween(from, to, state.doc); ``` -```javascript +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Find fields in selection + const { from, to } = editor.state.selection; + const selectedFields = findFieldAnnotationsBetween(from, to, editor.state.doc); + }, +}); +``` + + + +```javascript Usage // Find fields in specific range const rangeFields = findFieldAnnotationsBetween(100, 500, state.doc); console.log(`Found ${rangeFields.length} fields in range`); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Find fields in specific range + const rangeFields = findFieldAnnotationsBetween(100, 500, editor.state.doc); + console.log(`Found ${rangeFields.length} fields in range`); + }, +}); +``` + + **Parameters:** @@ -169,12 +292,30 @@ console.log(`Found ${rangeFields.length} fields in range`); Find field annotations by field ID(s) -```javascript + +```javascript Usage // Find single field const fields = findFieldAnnotationsByFieldId('field-123', state); ``` -```javascript +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Find single field + const fields = findFieldAnnotationsByFieldId('field-123', editor.state); + }, +}); +``` + + + +```javascript Usage // Find multiple fields const fields = findFieldAnnotationsByFieldId(['field-1', 'field-2'], state); fields.forEach(({ pos, node }) => { @@ -182,6 +323,25 @@ fields.forEach(({ pos, node }) => { }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Find multiple fields + const fields = findFieldAnnotationsByFieldId(['field-1', 'field-2'], editor.state); + fields.forEach(({ pos, node }) => { + console.log(`Found ${node.attrs.fieldId} at position ${pos}`); + }); + }, +}); +``` + + **Parameters:** @@ -214,13 +374,32 @@ Find the first field annotation matching a field ID Added in v0.10.2 -```javascript + +```javascript Usage const firstField = findFirstFieldAnnotationByFieldId('field-123', state); if (firstField) { console.log(`First occurrence at position ${firstField.pos}`); } ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + const firstField = findFirstFieldAnnotationByFieldId('field-123', editor.state); + if (firstField) { + console.log(`First occurrence at position ${firstField.pos}`); + } + }, +}); +``` + + **Parameters:** @@ -245,13 +424,32 @@ Find field annotations in headers and footers by field ID or array of field IDs. Added in v0.11.2 -```javascript + +```javascript Usage const headerFooterAnnotations = findHeaderFooterAnnotationsByFieldId('field-123', editor, activeSectionEditor); headerFooterAnnotations.forEach(({ node, pos }) => { console.log(`Field ${node.attrs.fieldId} at position ${pos}`); }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + const headerFooterAnnotations = findHeaderFooterAnnotationsByFieldId('field-123', editor, activeSectionEditor); + headerFooterAnnotations.forEach(({ node, pos }) => { + console.log(`Field ${node.attrs.fieldId} at position ${pos}`); + }); + }, +}); +``` + + **Parameters:** @@ -326,13 +524,32 @@ Get all field annotations with their bounding rectangles Added in v0.11.0 -```javascript + +```javascript Usage const annotationsWithRects = getAllFieldAnnotationsWithRect(view, state); annotationsWithRects.forEach(({ node, rect }) => { console.log(`Field ${node.attrs.fieldId} at ${rect.left}, ${rect.top}`); }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + const annotationsWithRects = getAllFieldAnnotationsWithRect(editor.view, editor.state); + annotationsWithRects.forEach(({ node, rect }) => { + console.log(`Field ${node.attrs.fieldId} at ${rect.left}, ${rect.top}`); + }); + }, +}); +``` + + **Parameters:** @@ -370,13 +587,32 @@ Find field annotation nodes that were removed in a transaction Added in v0.11.2 -```javascript + +```javascript Usage const removedFields = findRemovedFieldAnnotations(transaction); removedFields.forEach(({ node, pos }) => { console.log(`Field ${node.attrs.fieldId} at position ${pos}`); }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + const removedFields = findRemovedFieldAnnotations(transaction); + removedFields.forEach(({ node, pos }) => { + console.log(`Field ${node.attrs.fieldId} at position ${pos}`); + }); + }, +}); +``` + + **Parameters:** @@ -403,16 +639,50 @@ removedFields.forEach(({ node, pos }) => { Delete field annotations by field ID -```javascript + +```javascript Usage // Delete single field annotation editor.commands.deleteFieldAnnotations('field-123') ``` -```javascript +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Delete single field annotation + editor.commands.deleteFieldAnnotations('field-123') + }, +}); +``` + + + +```javascript Usage // Delete multiple field annotations editor.commands.deleteFieldAnnotations(['field-1', 'field-2']) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Delete multiple field annotations + editor.commands.deleteFieldAnnotations(['field-1', 'field-2']) + }, +}); +``` + + **Parameters:** @@ -427,11 +697,28 @@ editor.commands.deleteFieldAnnotations(['field-1', 'field-2']) Delete field annotations by node references -```javascript + +```javascript Usage const annotations = editor.helpers.fieldAnnotation.getAllFieldAnnotations(); editor.commands.deleteFieldAnnotationsByNode(annotations.slice(0, 2)); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + const annotations = editor.helpers.fieldAnnotation.getAllFieldAnnotations(); + editor.commands.deleteFieldAnnotationsByNode(annotations.slice(0, 2)); + }, +}); +``` + + **Parameters:** @@ -446,11 +733,28 @@ editor.commands.deleteFieldAnnotationsByNode(annotations.slice(0, 2)); Delete a single field annotation -```javascript + +```javascript Usage const annotation = editor.helpers.fieldAnnotation.findFieldAnnotationsByFieldId('field-123')[0]; editor.commands.deleteFieldAnnotation(annotation); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + const annotation = editor.helpers.fieldAnnotation.findFieldAnnotationsByFieldId('field-123')[0]; + editor.commands.deleteFieldAnnotation(annotation); + }, +}); +``` + + **Parameters:** @@ -465,16 +769,50 @@ editor.commands.deleteFieldAnnotation(annotation); Delete a portion of annotations associated with a field -```javascript + +```javascript Usage // Remove annotations starting from index 6 editor.commands.sliceFieldAnnotations('field-123', 5) ``` -```javascript +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Remove annotations starting from index 6 + editor.commands.sliceFieldAnnotations('field-123', 5) + }, +}); +``` + + + +```javascript Usage // Remove from multiple fields editor.commands.sliceFieldAnnotations(['field-1', 'field-2'], 5) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Remove from multiple fields + editor.commands.sliceFieldAnnotations(['field-1', 'field-2'], 5) + }, +}); +``` + + **Parameters:** @@ -495,7 +833,8 @@ editor.commands.sliceFieldAnnotations(['field-1', 'field-2'], 5) Add field annotation at specified position -```javascript + +```javascript Usage editor.commands.addFieldAnnotation(10, { fieldId: 'field-123', displayLabel: 'Enter your name', @@ -504,6 +843,26 @@ editor.commands.addFieldAnnotation(10, { }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.addFieldAnnotation(10, { + fieldId: 'field-123', + displayLabel: 'Enter your name', + fieldType: 'TEXTINPUT', + fieldColor: '#980043' + }) + }, +}); +``` + + **Parameters:** @@ -543,13 +902,32 @@ editor.commands.addFieldAnnotation(10, { Add field annotation at current selection position -```javascript + +```javascript Usage editor.commands.addFieldAnnotationAtSelection({ fieldId: 'field-456', displayLabel: 'Signature here' }, true) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.addFieldAnnotationAtSelection({ + fieldId: 'field-456', + displayLabel: 'Signature here' + }, true) + }, +}); +``` + + **Parameters:** @@ -570,7 +948,8 @@ editor.commands.addFieldAnnotationAtSelection({ Replace text ranges with field annotations -```javascript + +```javascript Usage editor.commands.replaceWithFieldAnnotation([{ from: 20, to: 45, @@ -582,6 +961,29 @@ editor.commands.replaceWithFieldAnnotation([{ }]) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.replaceWithFieldAnnotation([{ + from: 20, + to: 45, + attrs: { + fieldId: 'field-789', + fieldType: 'TEXTINPUT', + fieldColor: '#980043' + } + }]) + }, +}); +``` + + **Parameters:** @@ -613,11 +1015,28 @@ Replace field annotations with text labels in current selection Added in v0.11.0 -```javascript + +```javascript Usage // Replace all annotations in selection with their labels editor.commands.replaceFieldAnnotationsWithLabelInSelection() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Replace all annotations in selection with their labels + editor.commands.replaceFieldAnnotationsWithLabelInSelection() + }, +}); +``` + + **Parameters:** @@ -634,12 +1053,30 @@ Replace field annotations with text labels Added in v0.11.0 -```javascript + +```javascript Usage // Replace specific fields with labels editor.commands.replaceFieldAnnotationsWithLabel(['field-1', 'field-2']) ``` -```javascript +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Replace specific fields with labels + editor.commands.replaceFieldAnnotationsWithLabel(['field-1', 'field-2']) + }, +}); +``` + + + +```javascript Usage // Replace only text annotations in selection editor.commands.replaceFieldAnnotationsWithLabel(null, { isInSelection: true, @@ -647,6 +1084,25 @@ editor.commands.replaceFieldAnnotationsWithLabel(null, { }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Replace only text annotations in selection + editor.commands.replaceFieldAnnotationsWithLabel(null, { + isInSelection: true, + types: ['text'] + }) + }, +}); +``` + + **Parameters:** @@ -676,18 +1132,36 @@ editor.commands.replaceFieldAnnotationsWithLabel(null, { Reset all field annotations to their default values -```javascript + +```javascript Usage // Reset all annotations in document editor.commands.resetFieldAnnotations() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Reset all annotations in document + editor.commands.resetFieldAnnotations() + }, +}); +``` + + **Returns:** `boolean` Command success status #### `updateFieldAnnotations` Update field annotations by field ID -```javascript + +```javascript Usage // Update single field editor.commands.updateFieldAnnotations('field-123', { displayLabel: 'Updated label', @@ -695,13 +1169,51 @@ editor.commands.updateFieldAnnotations('field-123', { }) ``` -```javascript +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Update single field + editor.commands.updateFieldAnnotations('field-123', { + displayLabel: 'Updated label', + fieldColor: '#FF0000' + }) + }, +}); +``` + + + +```javascript Usage // Update multiple fields editor.commands.updateFieldAnnotations(['field-1', 'field-2'], { hidden: true }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Update multiple fields + editor.commands.updateFieldAnnotations(['field-1', 'field-2'], { + hidden: true + }) + }, +}); +``` + + **Parameters:** @@ -731,7 +1243,8 @@ editor.commands.updateFieldAnnotations(['field-1', 'field-2'], { Update a specific field annotation instance -```javascript + +```javascript Usage // Update specific annotation instance const annotation = editor.helpers.fieldAnnotation.findFirstFieldAnnotationByFieldId('field-123', state); editor.commands.updateFieldAnnotation(annotation, { @@ -739,6 +1252,25 @@ editor.commands.updateFieldAnnotation(annotation, { }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Update specific annotation instance + const annotation = editor.helpers.fieldAnnotation.findFirstFieldAnnotationByFieldId('field-123', editor.state); + editor.commands.updateFieldAnnotation(annotation, { + displayLabel: 'New label' + }) + }, +}); +``` + + **Parameters:** @@ -757,7 +1289,8 @@ editor.commands.updateFieldAnnotation(annotation, { Update the attributes of annotations -```javascript + +```javascript Usage const annotations = editor.helpers.fieldAnnotation.getAllFieldAnnotations(); editor.commands.updateFieldAnnotationsAttributes(annotations, { fieldColor: '#FF0000', @@ -765,6 +1298,25 @@ editor.commands.updateFieldAnnotationsAttributes(annotations, { }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + const annotations = editor.helpers.fieldAnnotation.getAllFieldAnnotations(); + editor.commands.updateFieldAnnotationsAttributes(annotations, { + fieldColor: '#FF0000', + hidden: false + }); + }, +}); +``` + + **Parameters:** @@ -783,7 +1335,8 @@ editor.commands.updateFieldAnnotationsAttributes(annotations, { Hide field annotations based on a condition -```javascript + +```javascript Usage // Hide specific field IDs editor.commands.setFieldAnnotationsHiddenByCondition(node => { const targetIds = ['field-1', 'field-2', 'field-3']; @@ -791,7 +1344,27 @@ editor.commands.setFieldAnnotationsHiddenByCondition(node => { }) ``` -```javascript +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Hide specific field IDs + editor.commands.setFieldAnnotationsHiddenByCondition(node => { + const targetIds = ['field-1', 'field-2', 'field-3']; + return targetIds.includes(node.attrs.fieldId); + }) + }, +}); +``` + + + +```javascript Usage // Hide signature fields and show others editor.commands.setFieldAnnotationsHiddenByCondition( node => node.attrs.type === 'signature', @@ -799,6 +1372,25 @@ editor.commands.setFieldAnnotationsHiddenByCondition( ) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Hide signature fields and show others + editor.commands.setFieldAnnotationsHiddenByCondition( + node => node.attrs.type === 'signature', + true + ) + }, +}); +``` + + **Parameters:** @@ -817,27 +1409,78 @@ editor.commands.setFieldAnnotationsHiddenByCondition( Show all hidden field annotations -```javascript + +```javascript Usage // Make all annotations visible editor.commands.unsetFieldAnnotationsHidden() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Make all annotations visible + editor.commands.unsetFieldAnnotationsHidden() + }, +}); +``` + + **Returns:** `boolean` Command success status #### `setFieldAnnotationsVisibility` Set visibility for all field annotations -```javascript + +```javascript Usage // Make all annotations visible editor.commands.setFieldAnnotationsVisibility('visible') ``` -```javascript +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Make all annotations visible + editor.commands.setFieldAnnotationsVisibility('visible') + }, +}); +``` + + + +```javascript Usage // Hide all annotations (preserves layout) editor.commands.setFieldAnnotationsVisibility('hidden') ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Hide all annotations (preserves layout) + editor.commands.setFieldAnnotationsVisibility('hidden') + }, +}); +``` + + **Parameters:** @@ -852,7 +1495,8 @@ editor.commands.setFieldAnnotationsVisibility('hidden') Set highlighted status for annotations matching predicate -```javascript + +```javascript Usage // Highlight specific field IDs editor.commands.setFieldAnnotationsHighlighted((node) => { const targetIds = ['field-1', 'field-2', 'field-3']; @@ -860,11 +1504,47 @@ editor.commands.setFieldAnnotationsHighlighted((node) => { }, true) ``` -```javascript +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Highlight specific field IDs + editor.commands.setFieldAnnotationsHighlighted((node) => { + const targetIds = ['field-1', 'field-2', 'field-3']; + return targetIds.includes(node.attrs.fieldId); + }, true) + }, +}); +``` + + + +```javascript Usage // Remove highlighting from all annotations editor.commands.setFieldAnnotationsHighlighted(() => true, false) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Remove highlighting from all annotations + editor.commands.setFieldAnnotationsHighlighted(() => true, false) + }, +}); +``` + + **Parameters:** @@ -883,16 +1563,50 @@ editor.commands.setFieldAnnotationsHighlighted(() => true, false) Toggle formatting for field annotations in selection -```javascript + +```javascript Usage // Toggle bold formatting on selected annotations editor.commands.toggleFieldAnnotationsFormat('bold'); ``` -```javascript +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Toggle bold formatting on selected annotations + editor.commands.toggleFieldAnnotationsFormat('bold'); + }, +}); +``` + + + +```javascript Usage // Toggle italic and update selection editor.commands.toggleFieldAnnotationsFormat('italic', true); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Toggle italic and update selection + editor.commands.toggleFieldAnnotationsFormat('italic', true); + }, +}); +``` + + **Parameters:** @@ -911,10 +1625,26 @@ editor.commands.toggleFieldAnnotationsFormat('italic', true); Set font family for field annotations in current selection -```javascript + +```javascript Usage editor.commands.setFieldAnnotationsFontFamily('Arial', true) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.setFieldAnnotationsFontFamily('Arial', true) + }, +}); +``` + + **Parameters:** @@ -933,10 +1663,26 @@ editor.commands.setFieldAnnotationsFontFamily('Arial', true) Set font size for field annotations in current selection -```javascript + +```javascript Usage editor.commands.setFieldAnnotationsFontSize('14pt') ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.setFieldAnnotationsFontSize('14pt') + }, +}); +``` + + **Parameters:** @@ -955,10 +1701,26 @@ editor.commands.setFieldAnnotationsFontSize('14pt') Set text highlight color for field annotations in current selection -```javascript + +```javascript Usage editor.commands.setFieldAnnotationsTextHighlight('#ffff00') ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.setFieldAnnotationsTextHighlight('#ffff00') + }, +}); +``` + + **Parameters:** @@ -977,10 +1739,26 @@ editor.commands.setFieldAnnotationsTextHighlight('#ffff00') Set text color for field annotations in current selection -```javascript + +```javascript Usage editor.commands.setFieldAnnotationsTextColor('#0066cc') ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.setFieldAnnotationsTextColor('#0066cc') + }, +}); +``` + + **Parameters:** @@ -1017,7 +1795,8 @@ Track field annotation deletions in a transaction and emit events Added in v0.11.2 -```javascript + +```javascript Usage // Listen for field deletions editor.on('fieldAnnotationDeleted', ({ removedNodes }) => { removedNodes.forEach(({ node }) => { @@ -1028,6 +1807,28 @@ editor.on('fieldAnnotationDeleted', ({ removedNodes }) => { }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Listen for field deletions + editor.on('fieldAnnotationDeleted', ({ removedNodes }) => { + removedNodes.forEach(({ node }) => { + console.log(`Field ${node.attrs.fieldId} was deleted`); + // Clean up external references + removeFieldFromDatabase(node.attrs.fieldId); + }); + }); + }, +}); +``` + + **Parameters:** diff --git a/apps/docs/extensions/font-family.mdx b/apps/docs/extensions/font-family.mdx index 49cb73ee7b..4d0ebefb6e 100644 --- a/apps/docs/extensions/font-family.mdx +++ b/apps/docs/extensions/font-family.mdx @@ -36,11 +36,28 @@ Preserves other text styling attributes **Example:** -```javascript + +```javascript Usage // Set to Arial editor.commands.setFontFamily('Arial') ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Set to Arial + editor.commands.setFontFamily('Arial') + }, +}); +``` + + **Parameters:** @@ -57,10 +74,26 @@ Reverts to default document font **Example:** -```javascript + +```javascript Usage editor.commands.unsetFontFamily() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.unsetFontFamily() + }, +}); +``` + + ## Types ### `FontFamilyValue` diff --git a/apps/docs/extensions/font-size.mdx b/apps/docs/extensions/font-size.mdx index 44a0eead4b..df6fb859aa 100644 --- a/apps/docs/extensions/font-size.mdx +++ b/apps/docs/extensions/font-size.mdx @@ -40,12 +40,30 @@ Automatically clamps to min/max values **Example:** -```javascript + +```javascript Usage editor.commands.setFontSize('14pt') editor.commands.setFontSize('18px') editor.commands.setFontSize(16) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.setFontSize('14pt') + editor.commands.setFontSize('18px') + editor.commands.setFontSize(16) + }, +}); +``` + + **Parameters:** @@ -62,10 +80,26 @@ Reverts to default document size **Example:** -```javascript + +```javascript Usage editor.commands.unsetFontSize() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.unsetFontSize() + }, +}); +``` + + ## Types ### `FontSizeDefaults` diff --git a/apps/docs/extensions/format-commands.mdx b/apps/docs/extensions/format-commands.mdx index e55b3756fc..caf2a672a1 100644 --- a/apps/docs/extensions/format-commands.mdx +++ b/apps/docs/extensions/format-commands.mdx @@ -20,10 +20,26 @@ Removes all marks and resets nodes to default paragraph **Example:** -```javascript + +```javascript Usage editor.commands.clearFormat() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.clearFormat() + }, +}); +``` + + ### `clearMarksFormat` Clear only mark formatting @@ -34,10 +50,26 @@ Removes bold, italic, underline, colors, etc. but preserves block structure **Example:** -```javascript + +```javascript Usage editor.commands.clearMarksFormat() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.clearMarksFormat() + }, +}); +``` + + ### `clearNodesFormat` Clear only node formatting @@ -48,10 +80,26 @@ Converts headings, lists, etc. to paragraphs but preserves text marks **Example:** -```javascript + +```javascript Usage editor.commands.clearNodesFormat() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.clearNodesFormat() + }, +}); +``` + + ### `copyFormat` Copy format from selection or apply copied format @@ -62,21 +110,54 @@ Works like format painter - first click copies, second click applies **Example:** -```javascript + +```javascript Usage editor.commands.copyFormat() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.copyFormat() + }, +}); +``` + + ### `toggleMarkCascade` Toggle a mark type with cascade behavior, handling nested marks and negation attributes. Used internally by formatting extensions (bold, italic, etc.) but can be called directly for custom mark toggling. **Example:** -```javascript + +```javascript Usage editor.commands.toggleMarkCascade('bold') editor.commands.toggleMarkCascade('italic', { extendEmptyMarkRange: true }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.toggleMarkCascade('bold') + editor.commands.toggleMarkCascade('italic', { extendEmptyMarkRange: true }) + }, +}); +``` + + **Parameters:** diff --git a/apps/docs/extensions/heading.mdx b/apps/docs/extensions/heading.mdx index 1fdba0d804..7e848a6e87 100644 --- a/apps/docs/extensions/heading.mdx +++ b/apps/docs/extensions/heading.mdx @@ -36,10 +36,26 @@ Converts current block to heading **Example:** -```javascript + +```javascript Usage editor.commands.setHeading({ level: 2 }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.setHeading({ level: 2 }) + }, +}); +``` + + **Parameters:** @@ -56,11 +72,28 @@ Switches between heading and paragraph for the same level **Example:** -```javascript + +```javascript Usage editor.commands.toggleHeading({ level: 1 }) editor.commands.toggleHeading({ level: 3 }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.toggleHeading({ level: 1 }) + editor.commands.toggleHeading({ level: 3 }) + }, +}); +``` + + **Parameters:** diff --git a/apps/docs/extensions/highlight.mdx b/apps/docs/extensions/highlight.mdx index 4e9651650e..5dd927629f 100644 --- a/apps/docs/extensions/highlight.mdx +++ b/apps/docs/extensions/highlight.mdx @@ -32,11 +32,28 @@ Apply highlight with specified color **Example:** -```javascript + +```javascript Usage editor.commands.setHighlight('#FFEB3B') editor.commands.setHighlight('rgba(255, 235, 59, 0.5)') ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.setHighlight('#FFEB3B'); + editor.commands.setHighlight('rgba(255, 235, 59, 0.5)'); + }, +}); +``` + + **Parameters:** @@ -49,20 +66,52 @@ Remove highlight formatting **Example:** -```javascript + +```javascript Usage editor.commands.unsetHighlight() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.unsetHighlight(); + }, +}); +``` + + ### `toggleHighlight` Toggle highlight formatting **Example:** -```javascript + +```javascript Usage editor.commands.toggleHighlight() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.toggleHighlight(); + }, +}); +``` + + ## Keyboard shortcuts | Command | Shortcut | Description | diff --git a/apps/docs/extensions/history.mdx b/apps/docs/extensions/history.mdx index fa702d88dd..46e20a299e 100644 --- a/apps/docs/extensions/history.mdx +++ b/apps/docs/extensions/history.mdx @@ -32,10 +32,26 @@ Groups changes within the newGroupDelay window **Example:** -```javascript + +```javascript Usage editor.commands.undo() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.undo() + }, +}); +``` + + ### `redo` Redo the last undone action @@ -46,10 +62,26 @@ Only available after an undo action **Example:** -```javascript + +```javascript Usage editor.commands.redo() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.redo() + }, +}); +``` + + ## Keyboard shortcuts | Command | Shortcut | Description | diff --git a/apps/docs/extensions/image.mdx b/apps/docs/extensions/image.mdx index ad873e35f3..6e6850f067 100644 --- a/apps/docs/extensions/image.mdx +++ b/apps/docs/extensions/image.mdx @@ -104,7 +104,8 @@ Supports URLs, relative paths, and base64 data URIs **Example:** -```javascript + +```javascript Usage editor.commands.setImage({ src: 'https://example.com/image.jpg' }) editor.commands.setImage({ src: 'data:image/png;base64,...', @@ -113,6 +114,26 @@ editor.commands.setImage({ }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.setImage({ src: 'https://example.com/image.jpg' }) + editor.commands.setImage({ + src: 'data:image/png;base64,...', + alt: 'Company logo', + size: { width: 200 } + }) + }, +}); +``` + + **Parameters:** @@ -125,7 +146,8 @@ Set the wrapping mode and attributes for the selected image **Example:** -```javascript + +```javascript Usage // No wrapping, behind document editor.commands.setWrapping({ type: 'None', attrs: {behindDoc: true} }) @@ -159,6 +181,51 @@ editor.commands.setWrapping({ }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // No wrapping, behind document + editor.commands.setWrapping({ type: 'None', attrs: {behindDoc: true} }) + + // Square wrapping on both sides with distances + editor.commands.setWrapping({ + type: 'Square', + attrs: { + wrapText: 'bothSides', + distTop: 10, + distBottom: 10, + distLeft: 10, + distRight: 10 + } + }) + + // Tight wrapping with polygon + editor.commands.setWrapping({ + type: 'Tight', + attrs: { + polygon: [[0, 0], [100, 0], [100, 100], [0, 100]] + } + }) + + // Top and bottom wrapping + editor.commands.setWrapping({ + type: 'TopAndBottom', + attrs: { + distTop: 15, + distBottom: 15 + } + }) + }, +}); +``` + + **Parameters:** diff --git a/apps/docs/extensions/italic.mdx b/apps/docs/extensions/italic.mdx index 90ca736319..03875354a2 100644 --- a/apps/docs/extensions/italic.mdx +++ b/apps/docs/extensions/italic.mdx @@ -14,26 +14,74 @@ import Description from '/snippets/extensions/italic.mdx' Apply italic formatting to the current selection. -```javascript + +```javascript Usage editor.commands.setItalic() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.setItalic(); + }, +}); +``` + + ### `unsetItalic` Remove italic formatting from the current selection. -```javascript + +```javascript Usage editor.commands.unsetItalic() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.unsetItalic(); + }, +}); +``` + + ### `toggleItalic` Toggle italic formatting on the current selection. -```javascript + +```javascript Usage editor.commands.toggleItalic() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.toggleItalic(); + }, +}); +``` + + ## Keyboard shortcuts | Command | Shortcut | Description | diff --git a/apps/docs/extensions/line-break.mdx b/apps/docs/extensions/line-break.mdx index 0cd41cf5ed..0f820241ba 100644 --- a/apps/docs/extensions/line-break.mdx +++ b/apps/docs/extensions/line-break.mdx @@ -20,10 +20,26 @@ Creates a soft break within the same paragraph **Example:** -```javascript + +```javascript Usage editor.commands.insertLineBreak() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.insertLineBreak() + }, +}); +``` + + ### `insertPageBreak` Insert a page break @@ -34,10 +50,26 @@ Forces content to start on a new page when printed **Example:** -```javascript + +```javascript Usage editor.commands.insertPageBreak() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.insertPageBreak() + }, +}); +``` + + ## Source code diff --git a/apps/docs/extensions/line-height.mdx b/apps/docs/extensions/line-height.mdx index c64810199c..b0bd8128ee 100644 --- a/apps/docs/extensions/line-height.mdx +++ b/apps/docs/extensions/line-height.mdx @@ -16,11 +16,28 @@ Set line height as a multiplier (e.g., 1.5 for 1.5x line spacing). **Example:** -```javascript + +```javascript Usage editor.commands.setLineHeight(1.5) editor.commands.setLineHeight(2) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.setLineHeight(1.5) + editor.commands.setLineHeight(2) + }, +}); +``` + + **Parameters:** @@ -33,10 +50,26 @@ Remove line height and revert to default line spacing. **Example:** -```javascript + +```javascript Usage editor.commands.unsetLineHeight() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.unsetLineHeight() + }, +}); +``` + + ## Source code diff --git a/apps/docs/extensions/link.mdx b/apps/docs/extensions/link.mdx index bbc360ceef..d9b0a1f334 100644 --- a/apps/docs/extensions/link.mdx +++ b/apps/docs/extensions/link.mdx @@ -88,7 +88,8 @@ Automatically adds underline formatting and trims whitespace from link boundarie **Example:** -```javascript + +```javascript Usage editor.commands.setLink({ href: 'https://example.com' }) editor.commands.setLink({ href: 'https://example.com', @@ -96,6 +97,25 @@ editor.commands.setLink({ }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.setLink({ href: 'https://example.com' }) + editor.commands.setLink({ + href: 'https://example.com', + text: 'Visit Example' + }) + }, +}); +``` + + **Parameters:** @@ -112,21 +132,54 @@ Also removes underline and text color **Example:** -```javascript + +```javascript Usage editor.commands.unsetLink() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.unsetLink() + }, +}); +``` + + ### `toggleLink` Toggle link on selection **Example:** -```javascript + +```javascript Usage editor.commands.toggleLink({ href: 'https://example.com' }) editor.commands.toggleLink() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.toggleLink({ href: 'https://example.com' }) + editor.commands.toggleLink() + }, +}); +``` + + **Parameters:** diff --git a/apps/docs/extensions/linked-styles.mdx b/apps/docs/extensions/linked-styles.mdx index 151542acbf..2d2ed72102 100644 --- a/apps/docs/extensions/linked-styles.mdx +++ b/apps/docs/extensions/linked-styles.mdx @@ -16,11 +16,28 @@ Apply a linked style to the selected paragraphs. **Example:** -```javascript + +```javascript Usage const style = editor.helpers.linkedStyles.getStyleById('Heading1'); editor.commands.setLinkedStyle(style); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + const style = editor.helpers.linkedStyles.getStyleById('Heading1'); + editor.commands.setLinkedStyle(style); + }, +}); +``` + + **Parameters:** @@ -33,12 +50,30 @@ Toggle a linked style on the current selection. Removes the style if already app **Example:** -```javascript + +```javascript Usage const style = editor.helpers.linkedStyles.getStyleById('Heading1'); editor.commands.toggleLinkedStyle(style) editor.commands.toggleLinkedStyle(style, 'paragraph') ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + const style = editor.helpers.linkedStyles.getStyleById('Heading1'); + editor.commands.toggleLinkedStyle(style) + editor.commands.toggleLinkedStyle(style, 'paragraph') + }, +}); +``` + + **Parameters:** @@ -54,11 +89,28 @@ Apply a linked style by its ID. **Example:** -```javascript + +```javascript Usage editor.commands.setStyleById('Heading1') editor.commands.setStyleById('Normal') ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.setStyleById('Heading1') + editor.commands.setStyleById('Normal') + }, +}); +``` + + **Parameters:** @@ -73,10 +125,26 @@ Get all available linked styles from the document. **Example:** -```javascript + +```javascript Usage const styles = editor.helpers.linkedStyles.getStyles(); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + const styles = editor.helpers.linkedStyles.getStyles(); + }, +}); +``` + + **Returns:** @@ -89,10 +157,26 @@ Get a specific style by ID. **Example:** -```javascript + +```javascript Usage const headingStyle = editor.helpers.linkedStyles.getStyleById('Heading1'); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + const headingStyle = editor.helpers.linkedStyles.getStyleById('Heading1'); + }, +}); +``` + + **Parameters:** diff --git a/apps/docs/extensions/ordered-list.mdx b/apps/docs/extensions/ordered-list.mdx index 5ec2fcb761..27e7bbaafc 100644 --- a/apps/docs/extensions/ordered-list.mdx +++ b/apps/docs/extensions/ordered-list.mdx @@ -20,20 +20,52 @@ Toggle ordered list formatting on the current selection. Converts selected parag **Example:** -```javascript + +```javascript Usage editor.commands.toggleOrderedList() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.toggleOrderedList() + }, +}); +``` + + ### `restartNumbering` Restart list numbering from the current position. **Example:** -```javascript + +```javascript Usage editor.commands.restartNumbering() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.restartNumbering() + }, +}); +``` + + ## Keyboard shortcuts | Command | Shortcut | Description | diff --git a/apps/docs/extensions/overview.mdx b/apps/docs/extensions/overview.mdx index 428ae0f040..a8181b677f 100644 --- a/apps/docs/extensions/overview.mdx +++ b/apps/docs/extensions/overview.mdx @@ -16,13 +16,32 @@ Extensions provide: You don't typically configure extensions directly. SuperDoc handles it: -```javascript + +```javascript Usage // These commands come from extensions editor.commands.toggleBold(); // Bold extension -editor.commands.insertTable(); // Table extension -editor.commands.acceptAllChanges(); // TrackChanges extension +editor.commands.insertTable(); // Table extension +editor.commands.acceptAllTrackedChanges(); // TrackChanges extension ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // These commands come from extensions + editor.commands.toggleBold(); // Bold extension + editor.commands.insertTable(); // Table extension + editor.commands.acceptAllTrackedChanges(); // TrackChanges extension + }, +}); +``` + + ## Extension categories ### Core editing diff --git a/apps/docs/extensions/page-number.mdx b/apps/docs/extensions/page-number.mdx index 8848702b20..06dbb7089b 100644 --- a/apps/docs/extensions/page-number.mdx +++ b/apps/docs/extensions/page-number.mdx @@ -28,10 +28,26 @@ Only works in header/footer contexts **Example:** -```javascript + +```javascript Usage editor.commands.addAutoPageNumber() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.addAutoPageNumber() + }, +}); +``` + + **Returns:** `Function` Command function ### `addTotalPageCount` @@ -44,10 +60,26 @@ Only works in header/footer contexts **Example:** -```javascript + +```javascript Usage editor.commands.addTotalPageCount() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.addTotalPageCount() + }, +}); +``` + + **Returns:** `Function` Command function ## Keyboard shortcuts diff --git a/apps/docs/extensions/paragraph.mdx b/apps/docs/extensions/paragraph.mdx index 6abee0474c..8676b83f75 100644 --- a/apps/docs/extensions/paragraph.mdx +++ b/apps/docs/extensions/paragraph.mdx @@ -14,26 +14,74 @@ import Description from '/snippets/extensions/paragraph.mdx' Convert selected paragraphs to a bullet list, or remove list formatting if already a bullet list. -```javascript + +```javascript Usage editor.commands.toggleBulletList() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.toggleBulletList() + }, +}); +``` + + ### `toggleOrderedList` Convert selected paragraphs to an ordered list, or remove list formatting if already an ordered list. -```javascript + +```javascript Usage editor.commands.toggleOrderedList() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.toggleOrderedList() + }, +}); +``` + + ### `restartNumbering` Reset list numbering for the current list item and following items. -```javascript + +```javascript Usage editor.commands.restartNumbering() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.restartNumbering() + }, +}); +``` + + ## Keyboard shortcuts | Command | Shortcut | Description | diff --git a/apps/docs/extensions/search.mdx b/apps/docs/extensions/search.mdx index 7e3e96a700..065c43d3d5 100644 --- a/apps/docs/extensions/search.mdx +++ b/apps/docs/extensions/search.mdx @@ -20,10 +20,26 @@ Scrolls editor to the first match from previous search **Example:** -```javascript + +```javascript Usage editor.commands.goToFirstMatch() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.goToFirstMatch() + }, +}); +``` + + ### `search` Search for string matches in editor content @@ -34,11 +50,28 @@ Returns array of SearchMatch objects with positions and IDs **Example:** -```javascript + +```javascript Usage const matches = editor.commands.search('test string') const regexMatches = editor.commands.search(/test/i) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + const matches = editor.commands.search('test string') + const regexMatches = editor.commands.search(/test/i) + }, +}); +``` + + **Parameters:** @@ -64,11 +97,28 @@ Scrolls to match and selects it **Example:** -```javascript + +```javascript Usage const searchResults = editor.commands.search('test string') editor.commands.goToSearchResult(searchResults[3]) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + const searchResults = editor.commands.search('test string') + editor.commands.goToSearchResult(searchResults[3]) + }, +}); +``` + + **Parameters:** diff --git a/apps/docs/extensions/strike.mdx b/apps/docs/extensions/strike.mdx index e737dc6454..c73bdc8509 100644 --- a/apps/docs/extensions/strike.mdx +++ b/apps/docs/extensions/strike.mdx @@ -24,30 +24,78 @@ Apply strikethrough formatting **Example:** -```javascript + +```javascript Usage editor.commands.setStrike() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.setStrike(); + }, +}); +``` + + ### `unsetStrike` Remove strikethrough formatting **Example:** -```javascript + +```javascript Usage editor.commands.unsetStrike() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.unsetStrike(); + }, +}); +``` + + ### `toggleStrike` Toggle strikethrough formatting **Example:** -```javascript + +```javascript Usage editor.commands.toggleStrike() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.toggleStrike(); + }, +}); +``` + + ## Keyboard shortcuts | Command | Shortcut | Description | diff --git a/apps/docs/extensions/structured-content.mdx b/apps/docs/extensions/structured-content.mdx index 244a33d771..fe7dd0c19c 100644 --- a/apps/docs/extensions/structured-content.mdx +++ b/apps/docs/extensions/structured-content.mdx @@ -115,12 +115,30 @@ Update all structured content fields that share the same group identifier. **Example:** -```javascript + +```javascript Usage editor.commands.updateStructuredContentByGroup('pricing', { text: '$99.00' }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.updateStructuredContentByGroup('pricing', { + text: '$99.00' + }) + }, +}); +``` + + **Parameters:** @@ -136,11 +154,28 @@ Remove all structured content fields that share the same group identifier. **Example:** -```javascript + +```javascript Usage editor.commands.deleteStructuredContentByGroup('pricing') editor.commands.deleteStructuredContentByGroup(['pricing', 'deprecated']) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.deleteStructuredContentByGroup('pricing') + editor.commands.deleteStructuredContentByGroup(['pricing', 'deprecated']) + }, +}); +``` + + **Parameters:** @@ -154,7 +189,8 @@ Each inner array represents the cell values for one new row. **Example:** -```javascript + +```javascript Usage editor.commands.appendRowsToStructuredContentTable({ id: "block-123", tableIndex: 0, @@ -166,6 +202,29 @@ editor.commands.appendRowsToStructuredContentTable({ }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.appendRowsToStructuredContentTable({ + id: "block-123", + tableIndex: 0, + rows: [ + ["A", "B"], + ["C", "D"], + ], + copyRowStyle: true, + }); + }, +}); +``` + + **Parameters:** +```javascript Usage +const blocks = editor.helpers.structuredContentCommands.getStructuredContentBlockTags(editor.state); console.log(`Found ${blocks.length} structured content blocks`); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + const blocks = editor.helpers.structuredContentCommands.getStructuredContentBlockTags(editor.state); + console.log(`Found ${blocks.length} structured content blocks`); + }, +}); +``` +
+ **Parameters:** @@ -199,11 +275,28 @@ Get all inline structured content tags in the document **Example:** -```javascript -const inlines = editor.helpers.getStructuredContentInlineTags(editor.state); + +```javascript Usage +const inlines = editor.helpers.structuredContentCommands.getStructuredContentInlineTags(editor.state); console.log(`Found ${inlines.length} inline fields`); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + const inlines = editor.helpers.structuredContentCommands.getStructuredContentInlineTags(editor.state); + console.log(`Found ${inlines.length} inline fields`); + }, +}); +``` + + **Parameters:** @@ -214,14 +307,34 @@ Find all tables inside a structured content block by ID **Example:** -```javascript -const tables = editor.helpers.getStructuredContentTablesById( + +```javascript Usage +const tables = editor.helpers.structuredContentCommands.getStructuredContentTablesById( "block-123", editor.state ); console.log(`Block contains ${tables.length} table(s)`); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + const tables = editor.helpers.structuredContentCommands.getStructuredContentTablesById( + "block-123", + editor.state + ); + console.log(`Block contains ${tables.length} table(s)`); + }, +}); +``` + + **Parameters:** @@ -235,13 +348,32 @@ Find all structured content nodes that share the same group identifier. **Example:** -```javascript -const fields = editor.helpers.getStructuredContentByGroup('pricing', editor.state); + +```javascript Usage +const fields = editor.helpers.structuredContentCommands.getStructuredContentByGroup('pricing', editor.state); fields.forEach(({ node, pos }) => { console.log(node.attrs.tag, pos); }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + const fields = editor.helpers.structuredContentCommands.getStructuredContentByGroup('pricing', editor.state); + fields.forEach(({ node, pos }) => { + console.log(node.attrs.tag, pos); + }); + }, +}); +``` + + **Parameters:** @@ -255,11 +387,28 @@ Get all structured content tags (inline and block) in the document **Example:** -```javascript -const allTags = editor.helpers.getStructuredContentTags(editor.state); + +```javascript Usage +const allTags = editor.helpers.structuredContentCommands.getStructuredContentTags(editor.state); console.log(`Found ${allTags.length} structured content elements`); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + const allTags = editor.helpers.structuredContentCommands.getStructuredContentTags(editor.state); + console.log(`Found ${allTags.length} structured content elements`); + }, +}); +``` + + **Parameters:** @@ -270,14 +419,34 @@ Get structured content tag(s) by ID **Example:** -```javascript -const field = editor.helpers.getStructuredContentTagsById( + +```javascript Usage +const field = editor.helpers.structuredContentCommands.getStructuredContentTagsById( "field-123", editor.state ); if (field.length) console.log("Found field:", field[0].node.attrs); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + const field = editor.helpers.structuredContentCommands.getStructuredContentTagsById( + "field-123", + editor.state + ); + if (field.length) console.log("Found field:", field[0].node.attrs); + }, +}); +``` + + **Parameters:** diff --git a/apps/docs/extensions/table.mdx b/apps/docs/extensions/table.mdx index 2194bc6962..648595882d 100644 --- a/apps/docs/extensions/table.mdx +++ b/apps/docs/extensions/table.mdx @@ -68,11 +68,28 @@ Insert a new table into the document **Example:** -```javascript + +```javascript Usage editor.commands.insertTable() editor.commands.insertTable({ rows: 3, cols: 3, withHeaderRow: true }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.insertTable() + editor.commands.insertTable({ rows: 3, cols: 3, withHeaderRow: true }) + }, +}); +``` + + **Parameters:** @@ -85,10 +102,26 @@ Delete the entire table containing the cursor **Example:** -```javascript + +```javascript Usage editor.commands.deleteTable() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.deleteTable() + }, +}); +``` + + ### `addColumnBefore` Add a column before the current column @@ -99,10 +132,26 @@ Preserves cell attributes from current column **Example:** -```javascript + +```javascript Usage editor.commands.addColumnBefore() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.addColumnBefore() + }, +}); +``` + + ### `addColumnAfter` Add a column after the current column @@ -113,10 +162,26 @@ Preserves cell attributes from current column **Example:** -```javascript + +```javascript Usage editor.commands.addColumnAfter() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.addColumnAfter() + }, +}); +``` + + **Returns:** `Function` Command ### `deleteColumn` @@ -125,10 +190,26 @@ Delete the column containing the cursor **Example:** -```javascript + +```javascript Usage editor.commands.deleteColumn() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.deleteColumn() + }, +}); +``` + + **Returns:** `Function` Command ### `addRowBefore` @@ -141,10 +222,26 @@ Preserves cell attributes from current row **Example:** -```javascript + +```javascript Usage editor.commands.addRowBefore() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.addRowBefore() + }, +}); +``` + + **Returns:** `Function` Command ### `addRowAfter` @@ -157,10 +254,26 @@ Preserves cell attributes from current row **Example:** -```javascript + +```javascript Usage editor.commands.addRowAfter() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.addRowAfter() + }, +}); +``` + + **Returns:** `Function` Command ### `deleteRow` @@ -169,10 +282,26 @@ Delete the row containing the cursor **Example:** -```javascript + +```javascript Usage editor.commands.deleteRow() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.deleteRow() + }, +}); +``` + + **Returns:** `Function` Command ### `mergeCells` @@ -185,10 +314,26 @@ Content from all cells is preserved **Example:** -```javascript + +```javascript Usage editor.commands.mergeCells() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.mergeCells() + }, +}); +``` + + **Returns:** `Function` Command ### `splitCell` @@ -197,10 +342,26 @@ Split a merged cell back into individual cells **Example:** -```javascript + +```javascript Usage editor.commands.splitCell() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.splitCell() + }, +}); +``` + + **Returns:** `Function` Command - true if split, false if position invalid ### `splitSingleCell` @@ -213,10 +374,26 @@ Different from splitCell which splits merged cells back to original cells **Example:** -```javascript + +```javascript Usage editor.commands.splitSingleCell() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.splitSingleCell() + }, +}); +``` + + **Returns:** `Function` Command - true if split, false if position invalid ### `mergeOrSplit` @@ -229,10 +406,26 @@ Merges if multiple cells selected, splits if merged cell selected **Example:** -```javascript + +```javascript Usage editor.commands.mergeOrSplit() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.mergeOrSplit() + }, +}); +``` + + **Returns:** `Function` Command ### `toggleHeaderColumn` @@ -241,10 +434,26 @@ Toggle the first column as header column **Example:** -```javascript + +```javascript Usage editor.commands.toggleHeaderColumn() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.toggleHeaderColumn() + }, +}); +``` + + **Returns:** `Function` Command ### `toggleHeaderRow` @@ -253,10 +462,26 @@ Toggle the first row as header row **Example:** -```javascript + +```javascript Usage editor.commands.toggleHeaderRow() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.toggleHeaderRow() + }, +}); +``` + + **Returns:** `Function` Command ### `toggleHeaderCell` @@ -265,10 +490,26 @@ Toggle current cell as header cell **Example:** -```javascript + +```javascript Usage editor.commands.toggleHeaderCell() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.toggleHeaderCell() + }, +}); +``` + + **Returns:** `Function` Command ### `setCellAttr` @@ -277,11 +518,28 @@ Set an attribute on selected cells **Example:** -```javascript + +```javascript Usage editor.commands.setCellAttr('background', { color: 'ff0000' }) setCellAttr('verticalAlign', 'middle') ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.setCellAttr('background', { color: 'ff0000' }) + editor.commands.setCellAttr('verticalAlign', 'middle') + }, +}); +``` + + **Parameters:** @@ -299,10 +557,26 @@ Navigate to the next cell (Tab behavior) **Example:** -```javascript + +```javascript Usage editor.commands.goToNextCell() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.goToNextCell() + }, +}); +``` + + **Returns:** `Function` Command ### `goToPreviousCell` @@ -311,10 +585,26 @@ Navigate to the previous cell (Shift+Tab behavior) **Example:** -```javascript + +```javascript Usage editor.commands.goToPreviousCell() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.goToPreviousCell() + }, +}); +``` + + **Returns:** `Function` Command ### `fixTables` @@ -327,10 +617,26 @@ Repairs malformed tables and normalizes structure **Example:** -```javascript + +```javascript Usage editor.commands.fixTables() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.fixTables() + }, +}); +``` + + **Returns:** `Function` Command ### `setCellSelection` @@ -339,10 +645,26 @@ Set cell selection programmatically **Example:** -```javascript + +```javascript Usage editor.commands.setCellSelection({ anchorCell: 10, headCell: 15 }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.setCellSelection({ anchorCell: 10, headCell: 15 }) + }, +}); +``` + + **Parameters:** @@ -357,11 +679,28 @@ Set background color for selected cells **Example:** -```javascript + +```javascript Usage editor.commands.setCellBackground('#ff0000') editor.commands.setCellBackground('ff0000') ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.setCellBackground('#ff0000') + editor.commands.setCellBackground('ff0000') + }, +}); +``` + + **Parameters:** @@ -374,13 +713,32 @@ Append rows with content to an existing table. **Example:** -```javascript + +```javascript Usage editor.commands.appendRowsWithContent({ valueRows: [['Cell A', 'Cell B'], ['Cell C', 'Cell D']], copyRowStyle: true }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.appendRowsWithContent({ + valueRows: [['Cell A', 'Cell B'], ['Cell C', 'Cell D']], + copyRowStyle: true + }) + }, +}); +``` + + **Parameters:** @@ -397,10 +755,26 @@ Sets all border sizes to 0 **Example:** -```javascript + +```javascript Usage editor.commands.deleteCellAndTableBorders() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.deleteCellAndTableBorders() + }, +}); +``` + + **Returns:** `Function` Command ## Keyboard shortcuts diff --git a/apps/docs/extensions/text-align.mdx b/apps/docs/extensions/text-align.mdx index 1e50949968..26a2e432d4 100644 --- a/apps/docs/extensions/text-align.mdx +++ b/apps/docs/extensions/text-align.mdx @@ -24,11 +24,28 @@ Set text alignment on the current paragraph. **Example:** -```javascript + +```javascript Usage editor.commands.setTextAlign('center') editor.commands.setTextAlign('justify') ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.setTextAlign('center') + editor.commands.setTextAlign('justify') + }, +}); +``` + + **Parameters:** @@ -45,10 +62,26 @@ Resets alignment to the default value **Example:** -```javascript + +```javascript Usage editor.commands.unsetTextAlign() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.unsetTextAlign() + }, +}); +``` + + ## Keyboard shortcuts | Command | Shortcut | Description | diff --git a/apps/docs/extensions/text-indent.mdx b/apps/docs/extensions/text-indent.mdx index dde97c2c6b..00d2791c58 100644 --- a/apps/docs/extensions/text-indent.mdx +++ b/apps/docs/extensions/text-indent.mdx @@ -16,7 +16,8 @@ Set text indentation in points. **Example:** -```javascript + +```javascript Usage // Set to 72 points (1 inch) editor.commands.setTextIndentation(72) @@ -24,6 +25,25 @@ editor.commands.setTextIndentation(72) editor.commands.setTextIndentation(36) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Set to 72 points (1 inch) + editor.commands.setTextIndentation(72) + + // Set to 36 points (0.5 inch) + editor.commands.setTextIndentation(36) + }, +}); +``` + + **Parameters:** @@ -36,30 +56,78 @@ Remove text indentation from selected paragraphs. **Example:** -```javascript + +```javascript Usage editor.commands.unsetTextIndentation() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.unsetTextIndentation() + }, +}); +``` + + ### `increaseTextIndent` Increase text indentation by 36 points (0.5 inch). **Example:** -```javascript + +```javascript Usage editor.commands.increaseTextIndent() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.increaseTextIndent() + }, +}); +``` + + ### `decreaseTextIndent` Decrease text indentation by 36 points. Removes indentation completely if it reaches 0 or below. **Example:** -```javascript + +```javascript Usage editor.commands.decreaseTextIndent() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.decreaseTextIndent() + }, +}); +``` + + ## Source code diff --git a/apps/docs/extensions/text-style.mdx b/apps/docs/extensions/text-style.mdx index 8517fadc42..888736a443 100644 --- a/apps/docs/extensions/text-style.mdx +++ b/apps/docs/extensions/text-style.mdx @@ -40,10 +40,26 @@ Automatically checks if any style attributes exist before removal **Example:** -```javascript + +```javascript Usage editor.commands.removeEmptyTextStyle() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.removeEmptyTextStyle() + }, +}); +``` + + ## Source code import { SourceCodeLink } from '/snippets/components/source-code-link.jsx' diff --git a/apps/docs/extensions/track-changes.mdx b/apps/docs/extensions/track-changes.mdx index 2e31920171..c7a9c657cc 100644 --- a/apps/docs/extensions/track-changes.mdx +++ b/apps/docs/extensions/track-changes.mdx @@ -16,17 +16,36 @@ superdoc.setDocumentMode('editing'); // Disable tracking Or toggle programmatically: -```javascript + +```javascript Usage editor.commands.enableTrackChanges() editor.commands.disableTrackChanges() editor.commands.toggleTrackChanges() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.enableTrackChanges() + editor.commands.disableTrackChanges() + editor.commands.toggleTrackChanges() + }, +}); +``` + + ## Commands ### Accept changes -```javascript + +```javascript Usage // Accept at current selection editor.commands.acceptTrackedChangeBySelection() @@ -46,9 +65,41 @@ editor.commands.acceptAllTrackedChanges() editor.commands.acceptTrackedChangeFromToolbar() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Accept at current selection + editor.commands.acceptTrackedChangeBySelection() + + // Accept a specific change by ID + editor.commands.acceptTrackedChangeById('change-123') + + // Accept a change object (with start/end positions) + editor.commands.acceptTrackedChange({ trackedChange: { start: 10, end: 50 } }) + + // Accept changes in a range + editor.commands.acceptTrackedChangesBetween(10, 50) + + // Accept all changes in the document + editor.commands.acceptAllTrackedChanges() + + // Toolbar-aware accept (uses active thread or selection) + editor.commands.acceptTrackedChangeFromToolbar() + }, +}); +``` + + ### Reject changes -```javascript + +```javascript Usage // Reject at current selection editor.commands.rejectTrackedChangeOnSelection() @@ -68,11 +119,43 @@ editor.commands.rejectAllTrackedChanges() editor.commands.rejectTrackedChangeFromToolbar() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Reject at current selection + editor.commands.rejectTrackedChangeOnSelection() + + // Reject a specific change by ID + editor.commands.rejectTrackedChangeById('change-123') + + // Reject a change object + editor.commands.rejectTrackedChange({ trackedChange: { start: 10, end: 50 } }) + + // Reject changes in a range + editor.commands.rejectTrackedChangesBetween(10, 50) + + // Reject all changes in the document + editor.commands.rejectAllTrackedChanges() + + // Toolbar-aware reject + editor.commands.rejectTrackedChangeFromToolbar() + }, +}); +``` + + ### Insert tracked change programmatically Use `insertTrackedChange` to add tracked edits from external sources (e.g., AI suggestions): -```javascript + +```javascript Usage editor.commands.insertTrackedChange({ from: 10, to: 25, @@ -81,6 +164,26 @@ editor.commands.insertTrackedChange({ }) ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.insertTrackedChange({ + from: 10, + to: 25, + text: 'replacement text', + comment: 'AI suggestion: improved wording' + }) + }, +}); +``` + + **Parameters:** @@ -89,7 +192,8 @@ editor.commands.insertTrackedChange({ ### View modes -```javascript + +```javascript Usage // Show document as it was before changes editor.commands.toggleTrackChangesShowOriginal() editor.commands.enableTrackChangesShowOriginal() @@ -100,6 +204,28 @@ editor.commands.toggleTrackChangesShowFinal() editor.commands.enableTrackChangesShowFinal() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Show document as it was before changes + editor.commands.toggleTrackChangesShowOriginal() + editor.commands.enableTrackChangesShowOriginal() + editor.commands.disableTrackChangesShowOriginal() + + // Show document as if all changes were accepted + editor.commands.toggleTrackChangesShowFinal() + editor.commands.enableTrackChangesShowFinal() + }, +}); +``` + + ## Helpers ```javascript @@ -127,7 +253,8 @@ Each change includes author name, email, timestamp, and a unique ID. Changes export to DOCX as Word revisions: -```javascript + +```javascript Usage // Export with changes preserved await superdoc.export(); @@ -136,6 +263,26 @@ editor.commands.acceptAllTrackedChanges(); await superdoc.export(); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + // Export with changes preserved + await superdoc.export(); + + // Accept all first, then export clean + editor.commands.acceptAllTrackedChanges(); + await superdoc.export(); + }, +}); +``` + + ## Source code import { SourceCodeLink } from '/snippets/components/source-code-link.jsx' diff --git a/apps/docs/extensions/underline.mdx b/apps/docs/extensions/underline.mdx index 7481b82205..786c679b13 100644 --- a/apps/docs/extensions/underline.mdx +++ b/apps/docs/extensions/underline.mdx @@ -36,10 +36,26 @@ Apply underline formatting **Example:** -```javascript + +```javascript Usage editor.commands.setUnderline() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.setUnderline(); + }, +}); +``` + + **Returns:** `Function` Command ### `unsetUnderline` @@ -48,10 +64,26 @@ Remove underline formatting **Example:** -```javascript + +```javascript Usage editor.commands.unsetUnderline() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.unsetUnderline(); + }, +}); +``` + + **Returns:** `Function` Command ### `toggleUnderline` @@ -60,10 +92,26 @@ Toggle underline formatting **Example:** -```javascript + +```javascript Usage editor.commands.toggleUnderline() ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const editor = superdoc.activeEditor; + editor.commands.toggleUnderline(); + }, +}); +``` + + **Returns:** `Function` Command ## Keyboard shortcuts diff --git a/apps/docs/getting-started/ai-agents.mdx b/apps/docs/getting-started/ai-agents.mdx index ccc0fa9c5d..9404e9e455 100644 --- a/apps/docs/getting-started/ai-agents.mdx +++ b/apps/docs/getting-started/ai-agents.mdx @@ -27,12 +27,25 @@ const docx = await editor.exportDocx(); ## Content formats -```javascript + +```javascript Usage +editor.commands.insertContent(value, { contentType: 'html' }); // Recommended for LLMs +editor.commands.insertContent(value, { contentType: 'markdown' }); +editor.commands.insertContent(value, { contentType: 'text' }); +editor.commands.insertContent(value, { contentType: 'schema' }); // ProseMirror JSON +``` + +```javascript Full Example +import { Editor } from 'superdoc/super-editor'; + +const editor = await Editor.open(yourFile); + editor.commands.insertContent(value, { contentType: 'html' }); // Recommended for LLMs editor.commands.insertContent(value, { contentType: 'markdown' }); editor.commands.insertContent(value, { contentType: 'text' }); editor.commands.insertContent(value, { contentType: 'schema' }); // ProseMirror JSON ``` + See [Import/Export](/getting-started/import-export) for format details, limitations, and guidance on choosing a format. @@ -40,7 +53,22 @@ See [Import/Export](/getting-started/import-export) for format details, limitati Use `suggesting` mode so AI edits appear as tracked changes that users can accept or reject: -```javascript + +```javascript Usage +const contract = await readFile('./contract.docx'); +const editor = await Editor.open(contract, { + documentMode: 'suggesting', +}); + +// AI suggestions are tracked — users review them in Word +editor.commands.insertContent(aiRevisions, { contentType: 'html' }); +const redlined = await editor.exportDocx(); +``` + +```javascript Full Example +import { readFile } from 'node:fs/promises'; +import { Editor } from 'superdoc/super-editor'; + const contract = await readFile('./contract.docx'); const editor = await Editor.open(contract, { documentMode: 'suggesting', @@ -50,6 +78,7 @@ const editor = await Editor.open(contract, { editor.commands.insertContent(aiRevisions, { contentType: 'html' }); const redlined = await editor.exportDocx(); ``` + ## LLM quick reference diff --git a/apps/docs/getting-started/import-export.mdx b/apps/docs/getting-started/import-export.mdx index 41fd84bc28..efec519b29 100644 --- a/apps/docs/getting-started/import-export.mdx +++ b/apps/docs/getting-started/import-export.mdx @@ -75,12 +75,29 @@ new SuperDoc({ Insert content into an existing document using editor commands. -```javascript + +```javascript Usage superdoc.activeEditor.commands.insertContent(content, { contentType: 'html' // 'html' | 'markdown' | 'text' | 'schema' }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + superdoc.activeEditor.commands.insertContent(content, { + contentType: 'html' // 'html' | 'markdown' | 'text' | 'schema' + }); + }, +}); +``` + + The content to insert. String for `html`, `markdown`, and `text`. ProseMirror JSON object for `schema`. @@ -93,7 +110,8 @@ superdoc.activeEditor.commands.insertContent(content, { ### DOCX export -```javascript + +```javascript Usage // Download as .docx file await superdoc.export(); @@ -110,6 +128,33 @@ await superdoc.export({ isFinalDoc: true }); await superdoc.export({ exportedName: 'Final Contract' }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: async (superdoc) => { + // Download as .docx file + await superdoc.export(); + + // Get blob without triggering download + const blob = await superdoc.export({ triggerDownload: false }); + + // Export without comments + await superdoc.export({ commentsType: 'clean' }); + + // Export as final document (applies tracked changes) + await superdoc.export({ isFinalDoc: true }); + + // Custom filename + await superdoc.export({ exportedName: 'Final Contract' }); + }, +}); +``` + + Formats to export @@ -144,7 +189,8 @@ await superdoc.export({ exportedName: 'Final Contract' }); ### HTML export -```javascript + +```javascript Usage // Returns array of HTML strings (one per document) const htmlArray = superdoc.getHTML(); @@ -152,26 +198,74 @@ const htmlArray = superdoc.getHTML(); const html = superdoc.activeEditor.getHTML(); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + // Returns array of HTML strings (one per document) + const htmlArray = superdoc.getHTML(); + + // From the active editor (single string) + const html = superdoc.activeEditor.getHTML(); + }, +}); +``` + + HTML export is structure-only. Custom CSS styling and Word-specific formatting are not included. ### JSON export -```javascript + +```javascript Usage // From the active editor const json = superdoc.activeEditor.getJSON(); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: (superdoc) => { + const json = superdoc.activeEditor.getJSON(); + }, +}); +``` + + JSON export preserves the full document structure and can be re-imported with `jsonOverride`. ### Markdown export -```javascript + +```javascript Usage // From the active editor const markdown = await superdoc.activeEditor.getMarkdown(); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + onReady: async (superdoc) => { + const markdown = await superdoc.activeEditor.getMarkdown(); + }, +}); +``` + + ## HTML element mapping | HTML Element | Imported As | Notes | diff --git a/apps/docs/guides/migration/typescript-migration.mdx b/apps/docs/guides/migration/typescript-migration.mdx index 371b1c3300..da809a72a8 100644 --- a/apps/docs/guides/migration/typescript-migration.mdx +++ b/apps/docs/guides/migration/typescript-migration.mdx @@ -179,7 +179,7 @@ export function updateNodeAttrs(node: PMNode, attrs: Record): PMNod ### Extension pattern ```typescript -import { Extension } from '@core/Extension'; +import { Extension } from 'superdoc/super-editor'; export interface MyExtensionOptions { enabled?: boolean; diff --git a/apps/docs/modules/comments.mdx b/apps/docs/modules/comments.mdx index 733fc43099..6517eca9cc 100644 --- a/apps/docs/modules/comments.mdx +++ b/apps/docs/modules/comments.mdx @@ -168,12 +168,31 @@ modules: { After initialization: -```javascript + + +```javascript Usage superdoc.on("ready", () => { superdoc.addCommentsList("#comments-sidebar"); }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + user: { name: 'John Smith', email: 'john@company.com' }, + modules: { comments: { allowResolve: true } }, + onReady: (superdoc) => { + superdoc.addCommentsList("#comments-sidebar"); + }, +}); +``` + + + ## Permission resolver Customize who can resolve comments or accept tracked changes. The resolver receives the permission type, current user, and any tracked-change metadata. Return `false` to block the action. @@ -208,7 +227,9 @@ modules: { Word comments are automatically imported with the document and marked with `importedId`. When exporting, use the `commentsType` option: -```javascript + + +```javascript Usage // Include comments in export const blob = await superdoc.export({ commentsType: "external" }); @@ -216,6 +237,27 @@ const blob = await superdoc.export({ commentsType: "external" }); const cleanBlob = await superdoc.export({ commentsType: "clean" }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + user: { name: 'John Smith', email: 'john@company.com' }, + modules: { comments: { allowResolve: true } }, + onReady: async (superdoc) => { + // Include comments in export + const blob = await superdoc.export({ commentsType: "external" }); + + // Remove all comments + const cleanBlob = await superdoc.export({ commentsType: "clean" }); + }, +}); +``` + + + ## API methods These methods are available on the active editor's commands: @@ -224,7 +266,9 @@ These methods are available on the active editor's commands: Add a comment to the current text selection. Requires a text selection. -```javascript + + +```javascript Usage // Simple usage superdoc.activeEditor.commands.addComment("Review this section"); @@ -237,6 +281,32 @@ superdoc.activeEditor.commands.addComment({ }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + user: { name: 'John Smith', email: 'john@company.com' }, + modules: { comments: { allowResolve: true } }, + onReady: (superdoc) => { + // Simple usage + superdoc.activeEditor.commands.addComment("Review this section"); + + // With options + superdoc.activeEditor.commands.addComment({ + content: "Please clarify this section", + author: "John Smith", + authorEmail: "john@company.com", + isInternal: true, + }); + }, +}); +``` + + + Comment content as a string, or an options object with: @@ -263,13 +333,35 @@ superdoc.activeEditor.commands.addComment({ Add a reply to an existing comment or tracked change. -```javascript + + +```javascript Usage superdoc.activeEditor.commands.addCommentReply({ parentId: "comment-123", content: "I agree with this suggestion", }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + user: { name: 'John Smith', email: 'john@company.com' }, + modules: { comments: { allowResolve: true } }, + onReady: (superdoc) => { + superdoc.activeEditor.commands.addCommentReply({ + parentId: "comment-123", + content: "I agree with this suggestion", + }); + }, +}); +``` + + + @@ -292,49 +384,153 @@ superdoc.activeEditor.commands.addCommentReply({ ### `removeComment` -```javascript + + +```javascript Usage superdoc.activeEditor.commands.removeComment({ commentId: "comment-123", }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + user: { name: 'John Smith', email: 'john@company.com' }, + modules: { comments: { allowResolve: true } }, + onReady: (superdoc) => { + superdoc.activeEditor.commands.removeComment({ + commentId: "comment-123", + }); + }, +}); +``` + + + ### `setActiveComment` Highlight and focus a comment. -```javascript + + +```javascript Usage superdoc.activeEditor.commands.setActiveComment({ commentId: "comment-123", }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + user: { name: 'John Smith', email: 'john@company.com' }, + modules: { comments: { allowResolve: true } }, + onReady: (superdoc) => { + superdoc.activeEditor.commands.setActiveComment({ + commentId: "comment-123", + }); + }, +}); +``` + + + ### `resolveComment` -```javascript + + +```javascript Usage superdoc.activeEditor.commands.resolveComment({ commentId: "comment-123", }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + user: { name: 'John Smith', email: 'john@company.com' }, + modules: { comments: { allowResolve: true } }, + onReady: (superdoc) => { + superdoc.activeEditor.commands.resolveComment({ + commentId: "comment-123", + }); + }, +}); +``` + + + ### `setCommentInternal` Toggle a comment between internal and external visibility. -```javascript + + +```javascript Usage superdoc.activeEditor.commands.setCommentInternal({ commentId: "comment-123", isInternal: true, }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + user: { name: 'John Smith', email: 'john@company.com' }, + modules: { comments: { allowResolve: true } }, + onReady: (superdoc) => { + superdoc.activeEditor.commands.setCommentInternal({ + commentId: "comment-123", + isInternal: true, + }); + }, +}); +``` + + + ### `setCursorById` Navigate the cursor to a comment's position in the document. -```javascript + + +```javascript Usage superdoc.activeEditor.commands.setCursorById("comment-123"); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + user: { name: 'John Smith', email: 'john@company.com' }, + modules: { comments: { allowResolve: true } }, + onReady: (superdoc) => { + superdoc.activeEditor.commands.setCursorById("comment-123"); + }, +}); +``` + + + ## Events ### `onCommentsUpdate` diff --git a/apps/docs/modules/toolbar.mdx b/apps/docs/modules/toolbar.mdx index eb654af6f6..984175d081 100644 --- a/apps/docs/modules/toolbar.mdx +++ b/apps/docs/modules/toolbar.mdx @@ -370,70 +370,227 @@ The toolbar automatically adapts based on the user's role: ## API methods -```javascript + + +```javascript Usage const toolbar = superdoc.toolbar; ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + toolbar: '#toolbar', + onReady: (superdoc) => { + const toolbar = superdoc.toolbar; + }, +}); +``` + + + ### `getToolbarItemByName` Get a toolbar item by its name. -```javascript + + +```javascript Usage const boldBtn = toolbar.getToolbarItemByName('bold'); boldBtn.active.value; // boolean boldBtn.disabled.value; // boolean ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + toolbar: '#toolbar', + onReady: (superdoc) => { + const toolbar = superdoc.toolbar; + const boldBtn = toolbar.getToolbarItemByName('bold'); + boldBtn.active.value; // boolean + boldBtn.disabled.value; // boolean + }, +}); +``` + + + ### `getToolbarItemByGroup` Get all toolbar items in a layout group. -```javascript + + +```javascript Usage const leftItems = toolbar.getToolbarItemByGroup('left'); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + toolbar: '#toolbar', + onReady: (superdoc) => { + const toolbar = superdoc.toolbar; + const leftItems = toolbar.getToolbarItemByGroup('left'); + }, +}); +``` + + + ### `updateToolbarState` Refresh all button states based on the current editor state. -```javascript + + +```javascript Usage toolbar.updateToolbarState(); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + toolbar: '#toolbar', + onReady: (superdoc) => { + const toolbar = superdoc.toolbar; + toolbar.updateToolbarState(); + }, +}); +``` + + + ### `setZoom` Set the editor zoom level programmatically. -```javascript + + +```javascript Usage toolbar.setZoom(150); // 150% ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + toolbar: '#toolbar', + onReady: (superdoc) => { + const toolbar = superdoc.toolbar; + toolbar.setZoom(150); // 150% + }, +}); +``` + + + ### `destroy` Clean up toolbar resources and event listeners. -```javascript + + +```javascript Usage toolbar.destroy(); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + toolbar: '#toolbar', + onReady: (superdoc) => { + const toolbar = superdoc.toolbar; + toolbar.destroy(); + }, +}); +``` + + + ## Events ### `superdoc-command` Fired when a SuperDoc-level command is executed (zoom, document mode). -```javascript + + +```javascript Usage toolbar.on('superdoc-command', ({ item, argument }) => { console.log(`Command: ${item.command}, arg: ${argument}`); }); ``` +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + toolbar: '#toolbar', + onReady: (superdoc) => { + const toolbar = superdoc.toolbar; + toolbar.on('superdoc-command', ({ item, argument }) => { + console.log(`Command: ${item.command}, arg: ${argument}`); + }); + }, +}); +``` + + + ### `exception` Fired when an error occurs during a toolbar action. -```javascript + + +```javascript Usage toolbar.on('exception', ({ error, editor, originalError }) => { console.error('Toolbar error:', error); }); ``` + +```javascript Full Example +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + +const superdoc = new SuperDoc({ + selector: '#editor', + document: yourFile, + toolbar: '#toolbar', + onReady: (superdoc) => { + const toolbar = superdoc.toolbar; + toolbar.on('exception', ({ error, editor, originalError }) => { + console.error('Toolbar error:', error); + }); + }, +}); +``` + + diff --git a/apps/docs/package.json b/apps/docs/package.json index e596425ce1..707ca504f3 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -7,10 +7,16 @@ "gen:api": "node scripts/sync-api-docs.js", "gen:docs": "node scripts/sync-sdk-docs.js", "gen:all": "pnpm run gen:api && pnpm run gen:docs", - "check:links": "mintlify broken-links" + "check:links": "mintlify broken-links", + "check:imports": "bun scripts/validate-code-imports.ts", + "test:examples": "bun test __tests__/doctest.test.ts" }, "devDependencies": { "documentation": "^14.0.3", - "mintlify": "^4.2.295" + "mintlify": "^4.2.331", + "remark-mdx": "^3.1.1", + "remark-parse": "^11.0.0", + "unified": "catalog:", + "unist-util-visit": "^5.1.0" } } diff --git a/apps/docs/scripts/validate-code-imports.ts b/apps/docs/scripts/validate-code-imports.ts new file mode 100644 index 0000000000..3100ddb359 --- /dev/null +++ b/apps/docs/scripts/validate-code-imports.ts @@ -0,0 +1,173 @@ +#!/usr/bin/env bun + +/** + * Validates import statements in MDX code blocks. + * Scans all .mdx files for JS/TS code blocks and checks + * that every import path is on the allowlist. + */ + +import { readdirSync, readFileSync } from 'node:fs'; +import { join, relative, resolve } from 'node:path'; +import { unified } from 'unified'; +import remarkParse from 'remark-parse'; +import remarkMdx from 'remark-mdx'; +import { visit } from 'unist-util-visit'; +import type { Code } from 'mdast'; + +const EXACT_SUPERDOC_IMPORTS = new Set([ + 'superdoc', + 'superdoc/super-editor', + 'superdoc/types', + 'superdoc/converter', + 'superdoc/docx-zipper', + 'superdoc/file-zipper', + 'superdoc/style.css', + '@superdoc-dev/ai', + '@superdoc-dev/esign', + '@superdoc-dev/esign/styles.css', + '@superdoc-dev/template-builder', + '@superdoc-dev/template-builder/defaults', + '@superdoc-dev/superdoc-yjs-collaboration', +]); + +const EXACT_EXTERNAL_IMPORTS = new Set([ + 'react', + 'react-dom', + 'react-dom/client', + 'vue', + 'yjs', + 'y-prosemirror', + 'openai', + 'bun:test', + 'hocuspocus', + 'fastify', + 'express', + 'cors', + 'pg', + 'ioredis', +]); + +const PREFIX_EXTERNAL_IMPORTS = [ + '@angular/', + 'prosemirror-', + 'node:', + 'fs/', + '@hocuspocus/', + '@tiptap/', + '@tiptap-pro/', + '@liveblocks/', + '@y-sweet/', + '@fastify/', + '@aws-sdk/', + 'next/', +]; + +const IMPORT_REGEX = /import\s+(?:(?:[\s\S]*?)\s+from\s+)?['"]([^'"]+)['"]/g; + +const RESET = '\x1b[0m'; +const RED = '\x1b[31m'; +const GREEN = '\x1b[32m'; +const YELLOW = '\x1b[33m'; +const CYAN = '\x1b[36m'; +const BOLD = '\x1b[1m'; +const DIM = '\x1b[2m'; + +function isImportAllowed(importPath: string): boolean { + if (importPath.startsWith('./') || importPath.startsWith('../')) return true; + if (EXACT_SUPERDOC_IMPORTS.has(importPath)) return true; + if (EXACT_EXTERNAL_IMPORTS.has(importPath)) return true; + return PREFIX_EXTERNAL_IMPORTS.some((p) => importPath.startsWith(p)); +} + +function globMdx(dir: string): string[] { + const results: string[] = []; + for (const entry of readdirSync(dir, { withFileTypes: true })) { + const full = join(dir, entry.name); + if (entry.isDirectory()) { + if (entry.name === 'node_modules' || entry.name.startsWith('.')) continue; + results.push(...globMdx(full)); + } else if (entry.isFile() && entry.name.endsWith('.mdx')) { + results.push(full); + } + } + return results; +} + +interface ImportError { + file: string; + line: number; + importPath: string; + text: string; +} + +const parser = unified().use(remarkParse).use(remarkMdx); + +function validateFile(filePath: string): ImportError[] { + const content = readFileSync(filePath, 'utf-8'); + const tree = parser.parse(content); + const errors: ImportError[] = []; + + visit(tree, 'code', (node: Code) => { + const lang = node.lang ?? ''; + if (!['js', 'javascript', 'ts', 'typescript', 'jsx', 'tsx'].includes(lang)) return; + + const codeLine = node.position?.start.line ?? 0; + const lines = node.value.split('\n'); + + for (let i = 0; i < lines.length; i++) { + IMPORT_REGEX.lastIndex = 0; + let match; + while ((match = IMPORT_REGEX.exec(lines[i])) !== null) { + if (!isImportAllowed(match[1])) { + errors.push({ + file: filePath, + line: codeLine + i + 1, + importPath: match[1], + text: lines[i].trim(), + }); + } + } + } + }); + + return errors; +} + +const docsRoot = resolve(import.meta.dir, '..'); +const files = globMdx(docsRoot); + +console.log(`${CYAN}${BOLD}Validating imports in ${files.length} MDX files...${RESET}\n`); + +let totalErrors = 0; +const errorsByFile = new Map(); + +for (const file of files) { + const errors = validateFile(file); + if (errors.length > 0) { + errorsByFile.set(relative(docsRoot, file), errors); + totalErrors += errors.length; + } +} + +if (totalErrors === 0) { + console.log(`${GREEN}${BOLD}All imports are valid.${RESET}`); + process.exit(0); +} + +console.log(`${RED}${BOLD}Found ${totalErrors} invalid import${totalErrors === 1 ? '' : 's'}:${RESET}\n`); + +for (const [relFile, errors] of errorsByFile) { + console.log(`${YELLOW}${BOLD}${relFile}${RESET}`); + for (const err of errors) { + console.log(` ${DIM}${err.line}${RESET} ${RED}Invalid import: ${BOLD}${err.importPath}${RESET}`); + console.log(` ${DIM}${err.text}${RESET}`); + } + console.log(); +} + +console.log( + `${RED}${BOLD}${totalErrors} error${totalErrors === 1 ? '' : 's'} found. ` + + `Please use only allowed import paths in code examples.${RESET}`, +); + +process.exit(1); diff --git a/apps/docs/solutions/template-builder/introduction.mdx b/apps/docs/solutions/template-builder/introduction.mdx index 920bf61544..57b76e18fa 100644 --- a/apps/docs/solutions/template-builder/introduction.mdx +++ b/apps/docs/solutions/template-builder/introduction.mdx @@ -25,7 +25,7 @@ A React component for creating document templates with dynamic fields that can b ```jsx import SuperDocTemplateBuilder from "@superdoc-dev/template-builder"; -import "superdoc/dist/style.css"; +import "superdoc/style.css"; function TemplateEditor() { return ( diff --git a/apps/docs/solutions/template-builder/quickstart.mdx b/apps/docs/solutions/template-builder/quickstart.mdx index b23d15ec52..f0d222e3f2 100644 --- a/apps/docs/solutions/template-builder/quickstart.mdx +++ b/apps/docs/solutions/template-builder/quickstart.mdx @@ -17,7 +17,7 @@ Import the component and styles, then render with minimal props: ```jsx import SuperDocTemplateBuilder from "@superdoc-dev/template-builder"; -import "superdoc/dist/style.css"; +import "superdoc/style.css"; function App() { return ( diff --git a/lefthook.yml b/lefthook.yml index 5d5e0ef632..e4e0f18d1b 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -28,6 +28,14 @@ pre-commit: root: "apps/vscode-ext/" glob: "apps/vscode-ext/**/*.{ts,js}" run: pnpm run lint + docs-check-imports: + root: "apps/docs/" + glob: "apps/docs/**/*.mdx" + run: pnpm run check:imports + docs-test-examples: + root: "apps/docs/" + glob: "apps/docs/**/*.mdx" + run: pnpm run test:examples commit-msg: commands: diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index de8e483eb2..a8766f9dfd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,288 +6,9 @@ settings: catalogs: default: - '@commitlint/cli': - specifier: ^19.8.1 - version: 19.8.1 - '@commitlint/config-conventional': - specifier: ^19.8.1 - version: 19.8.1 - '@eslint/js': - specifier: ^9.31.0 - version: 9.39.2 - '@floating-ui/dom': - specifier: ^1.7.0 - version: 1.7.5 - '@fontsource/inter': - specifier: ^5.2.8 - version: 5.2.8 - '@hocuspocus/provider': - specifier: ^2.13.6 - version: 2.15.3 - '@hocuspocus/server': - specifier: ^2.13.6 - version: 2.15.3 - '@linear/sdk': - specifier: ^53.0.0 - version: 53.0.0 - '@playwright/test': - specifier: ^1.57.0 - version: 1.58.1 - '@semantic-release/changelog': - specifier: ^6.0.3 - version: 6.0.3 - '@semantic-release/git': - specifier: ^10.0.1 - version: 10.0.1 - '@testing-library/jest-dom': - specifier: ^6.9.1 - version: 6.9.1 - '@testing-library/react': - specifier: ^16.3.0 - version: 16.3.2 - '@testing-library/user-event': - specifier: ^14.6.1 - version: 14.6.1 - '@types/bun': - specifier: ^1.3.8 - version: 1.3.8 - '@types/node': - specifier: 22.19.2 - version: 22.19.2 - '@types/react': - specifier: ^19.2.6 - version: 19.2.11 - '@types/react-dom': - specifier: ^19.2.3 - version: 19.2.3 - '@typescript-eslint/eslint-plugin': - specifier: ^8.49.0 - version: 8.54.0 - '@typescript-eslint/parser': - specifier: ^8.49.0 - version: 8.54.0 - '@vitejs/plugin-react': - specifier: ^5.1.1 - version: 5.1.3 - '@vitejs/plugin-vue': - specifier: 6.0.2 - version: 6.0.2 - '@vitest/coverage-v8': - specifier: ^3.2.4 - version: 3.2.4 - '@vue/test-utils': - specifier: ^2.4.6 - version: 2.4.6 - buffer-crc32: - specifier: ^1.0.0 - version: 1.0.0 - color2k: - specifier: ^2.0.3 - version: 2.0.3 - concurrently: - specifier: ^9.1.2 - version: 9.2.1 - eslint: - specifier: ^9.39.1 - version: 9.39.2 - eslint-config-prettier: - specifier: ^9.1.0 - version: 9.1.2 - eslint-import-resolver-typescript: - specifier: ^4.4.4 - version: 4.4.4 - eslint-plugin-import-x: - specifier: ^4.16.1 - version: 4.16.1 - eslint-plugin-jsdoc: - specifier: ^54.1.0 - version: 54.7.0 - eslint-plugin-react: - specifier: ^7.37.5 - version: 7.37.5 - eslint-plugin-react-hooks: - specifier: ^7.0.1 - version: 7.0.1 - eventemitter3: - specifier: ^5.0.1 - version: 5.0.4 - fast-glob: - specifier: ^3.3.3 - version: 3.3.3 - he: - specifier: ^1.2.0 - version: 1.2.0 - jimp: - specifier: ^1.6.0 - version: 1.6.0 - jszip: - specifier: 3.10.1 - version: 3.10.1 - lefthook: - specifier: ^1.11.13 - version: 1.13.6 - lib0: - specifier: ^0.2.114 - version: 0.2.117 - marked: - specifier: ^16.2.0 - version: 16.4.2 - naive-ui: - specifier: ^2.43.1 - version: 2.43.2 - nodemon: - specifier: ^3.1.10 - version: 3.1.11 - patch-package: - specifier: ^8.0.1 - version: 8.0.1 - pdfjs-dist: - specifier: 4.3.136 - version: 4.3.136 - pinia: - specifier: ^2.1.7 - version: 2.3.1 - pixelmatch: - specifier: ^7.1.0 - version: 7.1.0 - playwright: - specifier: ^1.56.0 - version: 1.58.1 - postcss-nested: - specifier: ^6.0.1 - version: 6.2.0 - postcss-nested-import: - specifier: ^1.3.0 - version: 1.3.0 - postcss-prefixwrap: - specifier: ^1.56.2 - version: 1.57.2 - prettier: - specifier: 3.3.3 - version: 3.3.3 - prosemirror-commands: - specifier: ^1.5.2 - version: 1.7.1 - prosemirror-dropcursor: - specifier: ^1.8.1 - version: 1.8.2 - prosemirror-gapcursor: - specifier: ^1.3.2 - version: 1.4.0 - prosemirror-history: - specifier: ^1.4.0 - version: 1.5.0 - prosemirror-inputrules: - specifier: ^1.4.0 - version: 1.5.1 - prosemirror-keymap: - specifier: ^1.2.2 - version: 1.2.3 - prosemirror-model: - specifier: ^1.25.2 - version: 1.25.4 - prosemirror-schema-basic: - specifier: ^1.2.2 - version: 1.2.4 - prosemirror-schema-list: - specifier: ^1.3.0 - version: 1.5.1 - prosemirror-state: - specifier: ^1.4.3 - version: 1.4.4 - prosemirror-tables: - specifier: ^1.4.0 - version: 1.8.5 - prosemirror-test-builder: - specifier: ^1.1.1 - version: 1.1.1 - prosemirror-transform: - specifier: ^1.9.0 - version: 1.11.0 - prosemirror-view: - specifier: ^1.33.8 - version: 1.41.5 - react: - specifier: 19.2.0 - version: 19.2.0 - react-dom: - specifier: 19.2.0 - version: 19.2.0 - rehype-parse: - specifier: ^9.0.1 - version: 9.0.1 - rehype-remark: - specifier: ^10.0.1 - version: 10.0.1 - remark-gfm: - specifier: ^4.0.1 - version: 4.0.1 - remark-stringify: - specifier: ^11.0.0 - version: 11.0.0 - rollup-plugin-copy: - specifier: ^3.5.0 - version: 3.5.0 - rollup-plugin-visualizer: - specifier: ^5.12.0 - version: 5.14.0 - semantic-release: - specifier: ^24.2.7 - version: 24.2.9 - semantic-release-commit-filter: - specifier: ^1.0.2 - version: 1.0.2 - semantic-release-linear-app: - specifier: ^0.7.0 - version: 0.7.0 - tippy.js: - specifier: ^6.3.7 - version: 6.3.7 - tsx: - specifier: ^4.20.6 - version: 4.21.0 - typescript: - specifier: ^5.9.2 - version: 5.9.3 - typescript-eslint: - specifier: ^8.49.0 - version: 8.54.0 unified: - specifier: ^11.0.5 + specifier: 11.0.5 version: 11.0.5 - uuid: - specifier: ^9.0.1 - version: 9.0.1 - verdaccio: - specifier: ^6.1.6 - version: 6.2.5 - vite: - specifier: ^7.2.7 - version: 7.3.1 - vite-plugin-dts: - specifier: ~4.5.4 - version: 4.5.4 - vite-plugin-node-polyfills: - specifier: ^0.24.0 - version: 0.24.0 - vitest: - specifier: ^3.2.4 - version: 3.2.4 - xml-js: - specifier: 1.6.11 - version: 1.6.11 - y-prosemirror: - specifier: ^1.3.7 - version: 1.3.7 - y-protocols: - specifier: ^1.0.6 - version: 1.0.7 - y-websocket: - specifier: ^3.0.0 - version: 3.0.0 - yjs: - specifier: 13.6.19 - version: 13.6.19 overrides: canvas: 3.2.0 @@ -421,8 +142,20 @@ importers: specifier: ^14.0.3 version: 14.0.3 mintlify: - specifier: ^4.2.295 - version: 4.2.315(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/node@22.19.8)(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(typescript@5.9.3) + specifier: ^4.2.331 + version: 4.2.331(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/node@22.19.8)(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(typescript@5.9.3) + remark-mdx: + specifier: ^3.1.1 + version: 3.1.1 + remark-parse: + specifier: ^11.0.0 + version: 11.0.0 + unified: + specifier: 'catalog:' + version: 11.0.5 + unist-util-visit: + specifier: ^5.1.0 + version: 5.1.0 apps/vscode-ext: dependencies: @@ -1309,6 +1042,9 @@ packages: '@asyncapi/specs@6.11.1': resolution: {integrity: sha512-A3WBLqAKGoJ2+6FWFtpjBlCQ1oFCcs4GxF7zsIGvNqp/klGUHjlA3aAcZ9XMMpLGE8zPeYDz2x9FmO6DSuKraQ==} + '@asyncapi/specs@6.8.1': + resolution: {integrity: sha512-czHoAk3PeXTLR+X8IUaD+IpT+g+zUvkcgMDJVothBsan+oHN3jfcFcFUNdOPAAFoUCQN1hXF1dWuphWy05THlA==} + '@azure/abort-controller@2.1.2': resolution: {integrity: sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==} engines: {node: '>=18.0.0'} @@ -2559,19 +2295,19 @@ packages: '@microsoft/tsdoc@0.16.0': resolution: {integrity: sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA==} - '@mintlify/cli@4.0.919': - resolution: {integrity: sha512-7zVYxDV/KteLlphmy7zGLUIQek1jFM1Lt7DPo1LVAUR3S8gYp35MopJLkR/o7WrpVVZnyZAYdmkEs/cbiCBQBw==} + '@mintlify/cli@4.0.935': + resolution: {integrity: sha512-mY0T3QOdDNuZlb4qx6GEAq0nSkWQGCn0Ug5kjQH3GjZFeeROm0EDYzoXlwAgLL/DkFEU9GpWmO3kU8EvetXtBw==} engines: {node: '>=18.0.0'} hasBin: true '@mintlify/common@1.0.661': resolution: {integrity: sha512-/Hdiblzaomp+AWStQ4smhVMgesQhffzQjC9aYBnmLReNdh2Js+ccQFUaWL3TNIxwiS2esaZvsHSV/D+zyRS3hg==} - '@mintlify/common@1.0.698': - resolution: {integrity: sha512-CicjlATkONn6ARR55J6JY+tUmSof3zjZKb708RYv3yG3qQdMB2/g0+FvQXkk2dsPgq105J5dFb/n2+vYuiEsHA==} + '@mintlify/common@1.0.713': + resolution: {integrity: sha512-0Ir8BLMVfADPi04/O5jDDemL+dxpNqHgx/JDQALuCFS4ANqHk7C9ES7ifsnt/rjmiiX7kuXSFqoAZrt1WMTLaA==} - '@mintlify/link-rot@3.0.857': - resolution: {integrity: sha512-ThNzzt4qzs0G88l7VJ3GqTHRUGhtDftydWQrxvm2v/eTUO9mjFkJZ1UZcp0/NYZgEOi2eLLHSns5B+PVlow5LA==} + '@mintlify/link-rot@3.0.872': + resolution: {integrity: sha512-2KDAD+hTmRZZCq0XCvvG+p/xSn5gtHCkHYA8Zfd2mhHceHCofNikvjffpYKx96eqaNCLhbeUYVnLlquBs820oQ==} engines: {node: '>=18.0.0'} '@mintlify/mdx@3.0.4': @@ -2585,19 +2321,19 @@ packages: resolution: {integrity: sha512-LIUkfA7l7ypHAAuOW74ZJws/NwNRqlDRD/U466jarXvvSlGhJec/6J4/I+IEcBvWDnc9anLFKmnGO04jPKgAsg==} engines: {node: '>=18.0.0'} - '@mintlify/models@0.0.263': - resolution: {integrity: sha512-Hfu0CfCkZ0Rpsvc5CBX3JDA0bqDWJ16T7ukoj/y5KltWhrukEPOl9/QR1zG/ScdXDwdOm3Zn5QQDT3GLbL0tnQ==} + '@mintlify/models@0.0.268': + resolution: {integrity: sha512-8HDPI3luABg5p/VTVYAOqabqOtcK2jdBuRTYOJiV39QqjQY29Q7kWH697PUokN6CO9uP2CCkPG5O5Gi7QxflWA==} engines: {node: '>=18.0.0'} '@mintlify/openapi-parser@0.0.8': resolution: {integrity: sha512-9MBRq9lS4l4HITYCrqCL7T61MOb20q9IdU7HWhqYMNMM1jGO1nHjXasFy61yZ8V6gMZyyKQARGVoZ0ZrYN48Og==} engines: {node: '>=18'} - '@mintlify/prebuild@1.0.834': - resolution: {integrity: sha512-JEdLMiKp9AygNpyEP2OuBJi9dzH34o8o57E55vlUrhQ6I/Po3Ww0yNQYH5wQ6bZM+tVX2ugJjKMclFURBfYMaw==} + '@mintlify/prebuild@1.0.849': + resolution: {integrity: sha512-GlFRJYrS7sIByZXKLa91VeCGruMunbwoxGbWRF5gAiknkuhng9SuX7zB7yTa0J3ApmLO3oZG5baWfzflcQY01w==} - '@mintlify/previewing@4.0.890': - resolution: {integrity: sha512-A8QeRFQ9dCsZJQgr6GCzSSrI+zlNm4dSlYUBDjPDkYI92uKmZO95maAKiXaWPKGQfjeIf8YYbP3n+k4QE+gpgg==} + '@mintlify/previewing@4.0.905': + resolution: {integrity: sha512-3PjzszHkvswA742dofEDohINUnlbmi4gnKP9xWK7wA+dLszKJ56BYjm6VCWJjpG3PuO4oPFIS9vI1YRCEM8kRQ==} engines: {node: '>=18.0.0'} '@mintlify/scraping@4.0.522': @@ -2605,16 +2341,16 @@ packages: engines: {node: '>=18.0.0'} hasBin: true - '@mintlify/scraping@4.0.559': - resolution: {integrity: sha512-xowugtpLPQacXLqdSB+X85Ug1uxbJMkWa8IzO8CiyJN9kcx1EIG9Ydxn0JJhyENETR3jd1VLKzIMvLXFeGAzZA==} + '@mintlify/scraping@4.0.574': + resolution: {integrity: sha512-FN2MM8uxBi2Foxpua0UIDLYo4YvcJE/NMwOGfbQ/HWx73eWhsA0LI+uhqpq8ZYqgc4awVif1oKc7OcuEhtY7Kg==} engines: {node: '>=18.0.0'} hasBin: true '@mintlify/validation@0.1.555': resolution: {integrity: sha512-11QVUReL4N5u8wSCgZt4RN7PA0jYQoMEBZ5IrUp5pgb5ZJBOoGV/vPsQrxPPa1cxsUDAuToNhtGxRQtOav/w8w==} - '@mintlify/validation@0.1.577': - resolution: {integrity: sha512-tecysj9oeTc0SHz1ro/oaqMLwEpJw/K8oqoDWULgOfBcDPeG6uKNMe2NiLyVZLZUMxsywFKOJFRkF/8mTbJcHQ==} + '@mintlify/validation@0.1.585': + resolution: {integrity: sha512-32mezT7v1dmPQa2DyGDYf0t+HHUbmpShJVnMrxxhXyMHvKUqOu4ENoRCAxRbfc4OLPxAFRB4qEEq2toID+tOHw==} '@napi-rs/wasm-runtime@0.2.12': resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} @@ -7528,8 +7264,8 @@ packages: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} engines: {node: '>= 8'} - mintlify@4.2.315: - resolution: {integrity: sha512-G2P7C5TAjayZF2WqrF+2Ya/yfIQSswS605YaBlXMlMCL4lFmqt4POPCowkg4OnojgAIm44JaBohYjhsDJqlMZA==} + mintlify@4.2.331: + resolution: {integrity: sha512-57mLAnYuZ9EEpTT84NAgUOFK7SSEM0cuO1J+NxNfywJi/RL+JmDijd9Tv74QHOEUhPwHjKPzOkhYR82vMqIdvw==} engines: {node: '>=18.0.0'} hasBin: true @@ -8819,6 +8555,9 @@ packages: remark-mdx@3.1.0: resolution: {integrity: sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA==} + remark-mdx@3.1.1: + resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==} + remark-parse@10.0.2: resolution: {integrity: sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==} @@ -9471,7 +9210,7 @@ packages: tar@6.1.15: resolution: {integrity: sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==} engines: {node: '>=10'} - deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exhorbitant rates) by contacting i@izs.me temp-dir@2.0.0: resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} @@ -10590,6 +10329,10 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 + '@asyncapi/specs@6.8.1': + dependencies: + '@types/json-schema': 7.0.15 + '@azure/abort-controller@2.1.2': dependencies: tslib: 2.8.1 @@ -10694,7 +10437,7 @@ snapshots: '@babel/types': 7.29.0 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -10778,7 +10521,7 @@ snapshots: '@babel/parser': 7.29.0 '@babel/template': 7.28.6 '@babel/types': 7.29.0 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -11785,7 +11528,7 @@ snapshots: recma-jsx: 1.0.1(acorn@8.15.0) recma-stringify: 1.0.0 rehype-recma: 1.0.0 - remark-mdx: 3.1.0 + remark-mdx: 3.1.1 remark-parse: 11.0.0 remark-rehype: 11.1.1 source-map: 0.7.6 @@ -11868,15 +11611,15 @@ snapshots: '@microsoft/tsdoc@0.16.0': {} - '@mintlify/cli@4.0.919(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/node@22.19.8)(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(typescript@5.9.3)': + '@mintlify/cli@4.0.935(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/node@22.19.8)(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(typescript@5.9.3)': dependencies: '@inquirer/prompts': 7.9.0(@types/node@22.19.8) - '@mintlify/common': 1.0.698(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - '@mintlify/link-rot': 3.0.857(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - '@mintlify/models': 0.0.263 - '@mintlify/prebuild': 1.0.834(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - '@mintlify/previewing': 4.0.890(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(typescript@5.9.3) - '@mintlify/validation': 0.1.577(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/common': 1.0.713(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/link-rot': 3.0.872(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/models': 0.0.268 + '@mintlify/prebuild': 1.0.849(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/previewing': 4.0.905(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(typescript@5.9.3) + '@mintlify/validation': 0.1.585(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) adm-zip: 0.5.16 chalk: 5.2.0 color: 4.2.3 @@ -11968,13 +11711,14 @@ snapshots: - ts-node - typescript - '@mintlify/common@1.0.698(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': + '@mintlify/common@1.0.713(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': dependencies: '@asyncapi/parser': 3.4.0 + '@asyncapi/specs': 6.8.1 '@mintlify/mdx': 3.0.4(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - '@mintlify/models': 0.0.263 + '@mintlify/models': 0.0.268 '@mintlify/openapi-parser': 0.0.8 - '@mintlify/validation': 0.1.577(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/validation': 0.1.585(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) '@sindresorhus/slugify': 2.2.0 '@types/mdast': 4.0.4 acorn: 8.11.2 @@ -12028,13 +11772,13 @@ snapshots: - ts-node - typescript - '@mintlify/link-rot@3.0.857(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': + '@mintlify/link-rot@3.0.872(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': dependencies: - '@mintlify/common': 1.0.698(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - '@mintlify/prebuild': 1.0.834(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - '@mintlify/previewing': 4.0.890(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(typescript@5.9.3) + '@mintlify/common': 1.0.713(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/prebuild': 1.0.849(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/previewing': 4.0.905(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(typescript@5.9.3) '@mintlify/scraping': 4.0.522(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - '@mintlify/validation': 0.1.577(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/validation': 0.1.585(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) fs-extra: 11.1.0 unist-util-visit: 4.1.2 transitivePeerDependencies: @@ -12087,7 +11831,7 @@ snapshots: transitivePeerDependencies: - debug - '@mintlify/models@0.0.263': + '@mintlify/models@0.0.268': dependencies: axios: 1.13.2 openapi-types: 12.1.3 @@ -12103,12 +11847,12 @@ snapshots: leven: 4.1.0 yaml: 2.8.2 - '@mintlify/prebuild@1.0.834(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': + '@mintlify/prebuild@1.0.849(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': dependencies: - '@mintlify/common': 1.0.698(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/common': 1.0.713(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) '@mintlify/openapi-parser': 0.0.8 - '@mintlify/scraping': 4.0.559(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - '@mintlify/validation': 0.1.577(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/scraping': 4.0.574(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/validation': 0.1.585(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) chalk: 5.3.0 favicons: 7.2.0 front-matter: 4.0.2 @@ -12135,11 +11879,11 @@ snapshots: - typescript - utf-8-validate - '@mintlify/previewing@4.0.890(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(typescript@5.9.3)': + '@mintlify/previewing@4.0.905(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(typescript@5.9.3)': dependencies: - '@mintlify/common': 1.0.698(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - '@mintlify/prebuild': 1.0.834(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - '@mintlify/validation': 0.1.577(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/common': 1.0.713(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/prebuild': 1.0.849(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/validation': 0.1.585(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) better-opn: 3.0.2 chalk: 5.2.0 chokidar: 3.5.3 @@ -12208,9 +11952,9 @@ snapshots: - typescript - utf-8-validate - '@mintlify/scraping@4.0.559(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': + '@mintlify/scraping@4.0.574(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': dependencies: - '@mintlify/common': 1.0.698(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/common': 1.0.713(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) '@mintlify/openapi-parser': 0.0.8 fs-extra: 11.1.1 hast-util-to-mdast: 10.1.0 @@ -12265,10 +12009,10 @@ snapshots: - supports-color - typescript - '@mintlify/validation@0.1.577(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': + '@mintlify/validation@0.1.585(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': dependencies: '@mintlify/mdx': 3.0.4(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - '@mintlify/models': 0.0.263 + '@mintlify/models': 0.0.268 arktype: 2.1.27 js-yaml: 4.1.0 lcm: 0.0.3 @@ -12402,7 +12146,7 @@ snapshots: '@puppeteer/browsers@2.3.0': dependencies: - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 extract-zip: 2.0.1 progress: 2.0.3 proxy-agent: 6.5.0 @@ -13397,7 +13141,7 @@ snapshots: '@typescript/vfs@1.6.2(typescript@5.9.3)': dependencies: - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -15004,6 +14748,10 @@ snapshots: dependencies: ms: 2.1.3 + debug@4.4.3: + dependencies: + ms: 2.1.3 + debug@4.4.3(supports-color@5.5.0): dependencies: ms: 2.1.3 @@ -15101,7 +14849,7 @@ snapshots: detect-port@1.5.1: dependencies: address: 1.2.2 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -15909,7 +15657,7 @@ snapshots: extract-zip@2.0.1: dependencies: - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: @@ -16226,7 +15974,7 @@ snapshots: dependencies: basic-ftp: 5.1.0 data-uri-to-buffer: 6.0.2 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -16793,7 +16541,7 @@ snapshots: http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.4 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -16822,7 +16570,7 @@ snapshots: https-proxy-agent@7.0.6: dependencies: agent-base: 7.1.4 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -18526,7 +18274,7 @@ snapshots: micromark@3.2.0: dependencies: '@types/debug': 4.1.12 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 decode-named-character-reference: 1.3.0 micromark-core-commonmark: 1.1.0 micromark-factory-space: 1.1.0 @@ -18548,7 +18296,7 @@ snapshots: micromark@4.0.2: dependencies: '@types/debug': 4.1.12 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 decode-named-character-reference: 1.3.0 devlop: 1.1.0 micromark-core-commonmark: 2.0.3 @@ -18650,9 +18398,9 @@ snapshots: minipass: 3.3.6 yallist: 4.0.0 - mintlify@4.2.315(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/node@22.19.8)(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(typescript@5.9.3): + mintlify@4.2.331(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/node@22.19.8)(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(typescript@5.9.3): dependencies: - '@mintlify/cli': 4.0.919(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/node@22.19.8)(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(typescript@5.9.3) + '@mintlify/cli': 4.0.935(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3))(@types/node@22.19.8)(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(typescript@5.9.3) transitivePeerDependencies: - '@radix-ui/react-popover' - '@types/node' @@ -19084,7 +18832,7 @@ snapshots: dependencies: '@tootallnate/quickjs-emscripten': 0.23.0 agent-base: 7.1.4 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 get-uri: 6.0.5 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 @@ -19592,7 +19340,7 @@ snapshots: proxy-agent@6.5.0: dependencies: agent-base: 7.1.4 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 lru-cache: 7.18.3 @@ -19645,7 +19393,7 @@ snapshots: dependencies: '@puppeteer/browsers': 2.3.0 chromium-bidi: 0.6.2(devtools-protocol@0.0.1312386) - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 devtools-protocol: 0.0.1312386 ws: 8.19.0 transitivePeerDependencies: @@ -20050,6 +19798,13 @@ snapshots: transitivePeerDependencies: - supports-color + remark-mdx@3.1.1: + dependencies: + mdast-util-mdx: 3.0.0 + micromark-extension-mdxjs: 3.0.0 + transitivePeerDependencies: + - supports-color + remark-parse@10.0.2: dependencies: '@types/mdast': 3.0.15 @@ -20609,7 +20364,7 @@ snapshots: socket.io-adapter@2.5.6: dependencies: - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 ws: 8.18.3 transitivePeerDependencies: - bufferutil @@ -20619,7 +20374,7 @@ snapshots: socket.io-parser@4.2.5: dependencies: '@socket.io/component-emitter': 3.1.2 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -20640,7 +20395,7 @@ snapshots: socks-proxy-agent@8.0.5: dependencies: agent-base: 7.1.4 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3 socks: 2.8.7 transitivePeerDependencies: - supports-color diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index e0eedf053b..5a2783f74f 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -91,7 +91,7 @@ catalog: tsx: ^4.20.6 typescript: ^5.9.2 typescript-eslint: ^8.49.0 - unified: ^11.0.5 + unified: 11.0.5 uuid: ^9.0.1 verdaccio: ^6.1.6 vite: ^7.2.7