diff --git a/.github/workflows/ci-react.yml b/.github/workflows/ci-react.yml new file mode 100644 index 0000000000..d4f6f23fb0 --- /dev/null +++ b/.github/workflows/ci-react.yml @@ -0,0 +1,45 @@ +name: CI React + +permissions: + contents: read + +on: + pull_request: + paths: + - 'packages/react/**' + workflow_dispatch: + +concurrency: + group: ci-react-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + + - uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + cache: pnpm + + - name: Install dependencies + run: pnpm install + + - name: Build superdoc (dependency) + run: pnpm run build:superdoc + + - name: Lint + run: pnpm --filter @superdoc-dev/react lint + + - name: Type check + run: pnpm --filter @superdoc-dev/react type-check + + - name: Build + run: pnpm --filter @superdoc-dev/react build + + - name: Test + run: pnpm --filter @superdoc-dev/react test diff --git a/.github/workflows/release-react.yml b/.github/workflows/release-react.yml new file mode 100644 index 0000000000..6d9b87e100 --- /dev/null +++ b/.github/workflows/release-react.yml @@ -0,0 +1,67 @@ +# Auto-releases on push to main (@next channel) +# For stable (@latest): cherry-pick commits to stable branch, then manually dispatch this workflow +name: 📦 Release react + +on: + push: + branches: + - main + paths: + - 'packages/react/**' + - 'packages/superdoc/**' + - 'packages/layout-engine/**' + - 'packages/super-editor/**' + - 'packages/ai/**' + - 'packages/word-layout/**' + - 'packages/preset-geometry/**' + - '!**/*.md' + workflow_dispatch: + +permissions: + contents: write + packages: write + +concurrency: + group: release-react-${{ github.ref }} + cancel-in-progress: true + +jobs: + release: + runs-on: ubuntu-24.04 + steps: + - name: Generate token + id: generate_token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} + + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + token: ${{ steps.generate_token.outputs.token }} + + - uses: pnpm/action-setup@v4 + + - uses: actions/setup-node@v6 + with: + node-version-file: .nvmrc + cache: pnpm + registry-url: 'https://registry.npmjs.org' + + - uses: oven-sh/setup-bun@v2 + + - name: Install dependencies + run: pnpm install + + - name: Build packages + run: pnpm run build + + - name: Release + env: + GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + LINEAR_TOKEN: ${{ secrets.LINEAR_TOKEN }} + working-directory: packages/react + run: pnpx semantic-release diff --git a/CLAUDE.md b/CLAUDE.md index a1a50d7c2a..cdb6ba29a5 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -25,6 +25,7 @@ State flows from super-editor → Layout Engine via: ``` packages/ superdoc/ Main entry point (npm: superdoc) + react/ React wrapper (@superdoc-dev/react) super-editor/ ProseMirror editor (@superdoc/super-editor) layout-engine/ Layout & pagination pipeline contracts/ - Shared type definitions @@ -43,11 +44,12 @@ e2e-tests/ Playwright tests | Task | Location | |------|----------| +| React integration | `packages/react/src/SuperDocEditor.tsx` | | Editing features | `super-editor/src/extensions/` | | Presentation mode visuals | `layout-engine/painters/dom/src/renderer.ts` | | DOCX import/export | `super-editor/src/core/super-converter/` | | Style resolution | `layout-engine/style-engine/` | -| Main entry point | `superdoc/src/SuperDoc.vue` | +| Main entry point (Vue) | `superdoc/src/SuperDoc.vue` | ## When to Modify Which System diff --git a/README.md b/README.md index d72d449c58..74c23b0943 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,30 @@ Or install with CDN ``` -### Basic usage +### React + +```bash +npm install @superdoc-dev/react +``` + +```tsx +import { SuperDocEditor } from '@superdoc-dev/react'; +import '@superdoc-dev/react/style.css'; + +function App() { + return ( + console.log('Ready!')} + /> + ); +} +``` + +See the [@superdoc-dev/react README](packages/react/README.md) for full documentation. + +### Vanilla JavaScript ```javascript import 'superdoc/style.css'; diff --git a/apps/docs/getting-started/frameworks/nextjs.mdx b/apps/docs/getting-started/frameworks/nextjs.mdx index 0a244afdc0..eef78f0e0e 100644 --- a/apps/docs/getting-started/frameworks/nextjs.mdx +++ b/apps/docs/getting-started/frameworks/nextjs.mdx @@ -3,124 +3,96 @@ title: Next.js keywords: "nextjs docx editor, next word editor, superdoc nextjs, ssr document editor, dynamic import docx" --- -SuperDoc works with Next.js using dynamic imports to avoid SSR issues. +SuperDoc works seamlessly with Next.js. The recommended approach is using `@superdoc-dev/react`, which handles SSR automatically. -## Installation +## Recommended: Using @superdoc-dev/react -```bash -npm install @harbour-enterprises/superdoc -``` - -## Basic component - -```jsx -// components/DocumentEditor.jsx -import { useEffect, useRef } from 'react'; -import dynamic from 'next/dynamic'; - -// Prevent SSR issues -const DocumentEditor = dynamic( - () => Promise.resolve(DocumentEditorComponent), - { ssr: false } -); - -function DocumentEditorComponent({ document }) { - const containerRef = useRef(null); - const superdocRef = useRef(null); - - useEffect(() => { - const initEditor = async () => { - const { SuperDoc } = await import('@harbour-enterprises/superdoc'); - - if (containerRef.current) { - superdocRef.current = new SuperDoc({ - selector: containerRef.current, - document - }); - } - }; - - initEditor(); - - return () => { - superdocRef.current = null; - }; - }, [document]); - - return
; -} +The React wrapper is the simplest way to integrate SuperDoc with Next.js: -export default DocumentEditor; +```bash +npm install @superdoc-dev/react ``` -## App Router (Next.js 13+) +### App Router (Next.js 13+) ```jsx // app/editor/page.jsx 'use client'; -import dynamic from 'next/dynamic'; - -const DocumentEditor = dynamic( - () => import('@/components/DocumentEditor'), - { - ssr: false, - loading: () =>
Loading editor...
- } -); +import { SuperDocEditor } from '@superdoc-dev/react'; +import '@superdoc-dev/react/style.css'; export default function EditorPage() { return ( -
- -
+ console.log('Editor ready!')} + style={{ height: '100vh' }} + /> ); } ``` -## API route for document handling - -```javascript -// pages/api/documents/[id].js (Pages Router) -// app/api/documents/[id]/route.js (App Router) - -export async function GET(request, { params }) { - const docId = params.id; - - // Fetch document from storage - const document = await fetchDocumentFromStorage(docId); - - return new Response(document, { - headers: { - 'Content-Type': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' - } - }); +### Pages Router + +```jsx +// pages/editor.jsx +import { SuperDocEditor } from '@superdoc-dev/react'; +import '@superdoc-dev/react/style.css'; + +export default function EditorPage() { + return ( + + ); } ``` -## With authentication + +The React wrapper is client-only (returns null on server, renders after hydration). For custom loading UI during SSR, use Next.js dynamic imports with a `loading` component. + -```jsx -// components/SecureEditor.jsx -import { useSession } from 'next-auth/react'; -import dynamic from 'next/dynamic'; +--- -const DocumentEditor = dynamic(() => import('./DocumentEditor'), { ssr: false }); +## CSS Import -export default function SecureEditor() { - const { data: session, status } = useSession(); +Import styles in your layout or page: - if (status === 'loading') return
Loading...
; - if (!session) return
Please sign in
; +```jsx +// app/layout.jsx +import '@superdoc-dev/react/style.css'; +export default function RootLayout({ children }) { return ( - + + {children} + ); } -``` \ No newline at end of file +``` + +--- + +## Next Steps + + + + Full React wrapper documentation + + + Configuration options + + + Real-time collaboration + + + React + TypeScript example + + + Next.js SSR integration + + diff --git a/apps/docs/getting-started/frameworks/react.mdx b/apps/docs/getting-started/frameworks/react.mdx index a23c1e324f..0dadd0bc5d 100644 --- a/apps/docs/getting-started/frameworks/react.mdx +++ b/apps/docs/getting-started/frameworks/react.mdx @@ -1,268 +1,584 @@ --- title: React Integration sidebarTitle: React -keywords: "react docx editor, react word component, superdoc react, microsoft word react, document editor react hooks" +keywords: "react docx editor, react word component, superdoc react, microsoft word react, document editor react hooks, @superdoc-dev/react" --- -SuperDoc works with React 16.8+ (hooks) and React 18+ (concurrent features). -## Install +SuperDoc provides `@superdoc-dev/react` - a first-party wrapper with proper lifecycle management, SSR safety, and React Strict Mode compatibility. + +## Installation ```bash -npm install @harbour-enterprises/superdoc +npm install @superdoc-dev/react ``` -## Basic Setup + +`superdoc` is included as a dependency - you don't need to install it separately. + -```jsx -import { useEffect, useRef } from 'react'; -import { SuperDoc } from '@harbour-enterprises/superdoc'; -import '@harbour-enterprises/superdoc/style.css'; - -function DocEditor({ document }) { - const containerRef = useRef(null); - const superdocRef = useRef(null); - - useEffect(() => { - if (!containerRef.current) return; - - superdocRef.current = new SuperDoc({ - selector: containerRef.current, - document - }); +## Quick Start - return () => { - superdocRef.current = null; - }; - }, [document]); +```jsx +import { SuperDocEditor } from '@superdoc-dev/react'; +import '@superdoc-dev/react/style.css'; - return
; +function App() { + return ( + console.log('Editor ready!')} + /> + ); } ``` -## Full Component +That's it! You now have a fully functional DOCX editor in your React app. + +--- + +## Core Concepts + +### The Component + +`` handles everything for you: -Build a reusable editor with controls: +- **Mounting** - Creates a SuperDoc instance when the component mounts +- **Updates** - Rebuilds automatically when the `document` prop changes +- **Cleanup** - Properly destroys the instance on unmount +- **Client-Only** - Returns null on server, renders only after hydration + +### Document Modes + +SuperDoc supports three editing modes: + +| Mode | Description | Use Case | +|------|-------------|----------| +| `editing` | Full editing capabilities | Default editing experience | +| `viewing` | Read-only presentation | Document preview | +| `suggesting` | Track changes mode | Collaborative review | ```jsx -import { useEffect, useRef, forwardRef, useImperativeHandle } from 'react'; -import { SuperDoc } from '@harbour-enterprises/superdoc'; -import '@harbour-enterprises/superdoc/style.css'; - -const DocEditor = forwardRef(({ document, user, onReady }, ref) => { - const containerRef = useRef(null); - const superdocRef = useRef(null); - - useImperativeHandle(ref, () => ({ - export: (options) => superdocRef.current?.export(options), - setMode: (mode) => superdocRef.current?.setDocumentMode(mode), - getHTML: () => superdocRef.current?.getHTML() - })); - - useEffect(() => { - if (!containerRef.current) return; - - superdocRef.current = new SuperDoc({ - selector: containerRef.current, - document, - user, - onReady: () => onReady?.(superdocRef.current) - }); + +``` + + +Changing `documentMode` via props is efficient - the component calls `setDocumentMode()` internally without rebuilding. You can also use `getInstance()?.setDocumentMode()` directly if preferred. + - return () => { - superdocRef.current = null; - }; - }, [document, user, onReady]); +### User Roles - return
; -}); +Roles control what actions a user can perform: + +| Role | Can Edit | Can Suggest | Can View | +|------|----------|-------------|----------| +| `editor` | Yes | Yes | Yes | +| `suggester` | No | Yes | Yes | +| `viewer` | No | No | Yes | + +```jsx + +``` + +--- + +## Working with Refs + +For programmatic control, use a ref to access the SuperDoc instance: + +```jsx +import { useRef } from 'react'; +import { SuperDocEditor } from '@superdoc-dev/react'; +import '@superdoc-dev/react/style.css'; -// Usage function App() { - const editorRef = useRef(); - + const editorRef = useRef(null); + const handleExport = async () => { - await editorRef.current.export({ isFinalDoc: true }); + // Export as DOCX and trigger download + await editorRef.current?.getInstance()?.export({ triggerDownload: true }); }; - + + const handleModeSwitch = () => { + // Switch mode without rebuilding + editorRef.current?.getInstance()?.setDocumentMode('suggesting'); + }; + return ( <> - - - Download DOCX + + console.log('Ready', editor)} + onReady={({ superdoc }) => console.log('Ready', superdoc)} /> ); } ``` -## File Upload +### Ref API + +The ref exposes a single method: + +| Method | Returns | Description | +|--------|---------|-------------| +| `getInstance()` | `SuperDoc \| null` | Access the underlying SuperDoc instance | + + +`getInstance()` returns `null` before the editor is ready. Use optional chaining (`?.`) for safe access. + + +### Available Instance Methods + +Once you have the SuperDoc instance via `getInstance()`, you can call any SuperDoc method: + +| Method | Returns | Description | +|--------|---------|-------------| +| `setDocumentMode(mode)` | `void` | Change mode without rebuild | +| `export(options?)` | `Promise` | Export document as DOCX | +| `getHTML(options?)` | `string[]` | Get document as HTML | +| `focus()` | `void` | Focus the editor | +| `search(text)` | `SearchResult[]` | Search document content | +| `goToSearchResult(match)` | `void` | Navigate to a search result | +| `setLocked(locked)` | `void` | Lock/unlock editing | +| `toggleRuler()` | `void` | Toggle ruler visibility | +| `save()` | `Promise` | Save (in collaboration mode) | + +--- + +## Common Patterns + +### File Upload ```jsx +import { useState, useRef } from 'react'; +import { SuperDocEditor } from '@superdoc-dev/react'; +import '@superdoc-dev/react/style.css'; + function FileEditor() { const [file, setFile] = useState(null); - const editorRef = useRef(); + const editorRef = useRef(null); - const handleFile = (e) => { - setFile(e.target.files[0]); + const handleFileChange = (e) => { + const selected = e.target.files?.[0]; + if (selected) setFile(selected); }; const handleExport = async () => { - const blob = await editorRef.current?.export({ - isFinalDoc: true - }); - // Download blob... + const blob = await editorRef.current?.getInstance()?.export({ triggerDownload: false }); + // Use blob for custom handling... }; return ( - <> - +
+ {file && ( <> - )} - +
+ ); +} +``` + +### Loading State + +Show a custom loading indicator while SuperDoc initializes: + +```jsx + ( +
+ Loading document... +
+ )} + onReady={() => console.log('Ready!')} +/> +``` + +### Document Switching + +The editor automatically rebuilds when the `document` prop changes: + +```jsx +function MultiDocEditor() { + const [currentDoc, setCurrentDoc] = useState(doc1); + + return ( +
+ + + +
); } ``` -## TypeScript +### View-Only Mode + +```jsx + +``` + +### With User Information + +```jsx + +``` + +--- + +## TypeScript Support + +The wrapper includes full TypeScript support: ```tsx -import { useEffect, useRef, forwardRef } from 'react'; -import { SuperDoc } from '@harbour-enterprises/superdoc'; -import type { SuperDocConfig } from '@harbour-enterprises/superdoc'; +import { useRef } from 'react'; +import { SuperDocEditor } from '@superdoc-dev/react'; +import type { SuperDocRef } from '@superdoc-dev/react'; +import '@superdoc-dev/react/style.css'; interface EditorProps { document: string | File | Blob; userId: string; - onReady?: (editor: SuperDoc) => void; } -interface EditorRef { - export: (options?: ExportOptions) => Promise; - setMode: (mode: 'editing' | 'viewing' | 'suggesting') => void; - getHTML: () => string[]; +function DocEditor({ document, userId }: EditorProps) { + const editorRef = useRef(null); + + const handleReady = ({ superdoc }: { superdoc: any }) => { + console.log('SuperDoc ready'); + }; + + const handleExport = async () => { + const blob = await editorRef.current?.getInstance()?.export({ + triggerDownload: true + }); + return blob; + }; + + return ( + + ); } +``` -const DocEditor = forwardRef( - ({ document, userId, onReady }, ref) => { - const containerRef = useRef(null); - const superdocRef = useRef(null); - - useImperativeHandle(ref, () => ({ - export: async (options) => { - if (!superdocRef.current) throw new Error('Editor not ready'); - return await superdocRef.current.export(options); - }, - setMode: (mode) => { - superdocRef.current?.setDocumentMode(mode); - }, - getHTML: () => { - return superdocRef.current?.getHTML() || []; - } - })); - - useEffect(() => { - if (!containerRef.current) return; - - const config: SuperDocConfig = { - selector: containerRef.current, - document, - user: { - name: userId, - email: `${userId}@company.com` - }, - onReady: () => onReady?.(superdocRef.current!) - }; - - superdocRef.current = new SuperDoc(config); - - return () => { - superdocRef.current = null; - }; - }, [document, userId, onReady]); - - return
; - } -); +### Exported Types + +```tsx +import type { + SuperDocEditorProps, + SuperDocRef, + DocumentMode, + UserRole, + SuperDocUser, + SuperDocModules, + SuperDocConfig, + SuperDocInstance, +} from '@superdoc-dev/react'; ``` -## SSR Support +--- + +## Framework Integration + +### Next.js (App Router) -For Next.js or other SSR frameworks: +The wrapper handles SSR automatically. For additional control: ```jsx +'use client'; + import dynamic from 'next/dynamic'; -const DocEditor = dynamic( - () => import('./DocEditor'), - { +const SuperDocEditor = dynamic( + () => import('@superdoc-dev/react').then(mod => mod.SuperDocEditor), + { ssr: false, loading: () =>
Loading editor...
} ); -// Or manually check for client-side -function SafeEditor(props) { - const [mounted, setMounted] = useState(false); - - useEffect(() => { - setMounted(true); - }, []); - - if (!mounted) return
Loading...
; - - return ; +export default function EditorPage() { + return ; } ``` -## Custom Hook +### Next.js (Pages Router) ```jsx -function useSuperDoc(config) { - const [ready, setReady] = useState(false); - const superdocRef = useRef(null); - - useEffect(() => { - if (!config.selector) return; - - superdocRef.current = new SuperDoc({ - ...config, - onReady: () => { - setReady(true); - config.onReady?.(); - } - }); - - return () => { - superdocRef.current = null; - setReady(false); - }; - }, [config.selector, config.document]); - - return { - editor: superdocRef.current, - ready, - export: (options) => superdocRef.current?.export(options), - setMode: (mode) => superdocRef.current?.setDocumentMode(mode) - }; +import dynamic from 'next/dynamic'; + +const SuperDocEditor = dynamic( + () => import('@superdoc-dev/react').then(mod => mod.SuperDocEditor), + { ssr: false } +); + +export default function EditorPage() { + return ; } ``` +### Vite / Create React App + +Works out of the box - just import and use: + +```jsx +import { SuperDocEditor } from '@superdoc-dev/react'; +import '@superdoc-dev/react/style.css'; + +function App() { + return ; +} +``` + +--- + +## Advanced Features + +### Real-time Collaboration + +```jsx +import * as Y from 'yjs'; +import { WebsocketProvider } from 'y-websocket'; + +function CollaborativeEditor() { + const ydoc = useMemo(() => new Y.Doc(), []); + const provider = useMemo( + () => new WebsocketProvider('wss://your-server.com', 'doc-id', ydoc), + [ydoc] + ); + + return ( + + ); +} +``` + + + + Learn more about setting up real-time collaboration + + + +### AI Features + +```jsx + +``` + +### Search and Navigate + +```jsx +const editorRef = useRef(null); + +const handleSearch = (query) => { + const instance = editorRef.current?.getInstance(); + const results = instance?.search(query); + if (results?.length) { + instance?.goToSearchResult(results[0]); + } +}; +``` + +### Export to HTML + +```jsx +const editorRef = useRef(null); + +const getHtmlContent = () => { + const htmlArray = editorRef.current?.getInstance()?.getHTML(); + console.log(htmlArray); // Array of HTML strings per section +}; +``` + +--- + +## Props Reference + +### Document Props + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `document` | `File \| Blob \| string \| object` | required | Document to load | +| `documentMode` | `'editing' \| 'viewing' \| 'suggesting'` | `'editing'` | Initial editing mode | +| `role` | `'editor' \| 'viewer' \| 'suggester'` | `'editor'` | User's permission level | + +### User Props + +| Prop | Type | Description | +|------|------|-------------| +| `user` | `{ name, email?, image? }` | Current user info | +| `users` | `Array<{ name, email, image? }>` | All users (for @-mentions) | + +### UI Props + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `id` | `string` | auto-generated | Custom container ID | +| `hideToolbar` | `boolean` | `false` | Hide the toolbar | +| `rulers` | `boolean` | - | Show/hide rulers (SuperDoc default) | +| `className` | `string` | - | CSS class for wrapper | +| `style` | `CSSProperties` | - | Inline styles | +| `renderLoading` | `() => ReactNode` | - | Custom loading UI | + +### Event Callbacks + +| Prop | Type | Description | +|------|------|-------------| +| `onReady` | `({ superdoc }) => void` | Editor initialized | +| `onEditorCreate` | `({ editor }) => void` | ProseMirror editor created | +| `onEditorDestroy` | `() => void` | Editor destroyed | +| `onEditorUpdate` | `({ editor }) => void` | Content changed | +| `onContentError` | `(event) => void` | Document parsing error | +| `onException` | `({ error }) => void` | Runtime error | + +### Advanced Props + +| Prop | Type | Description | +|------|------|-------------| +| `modules` | `object` | Configure collaboration, AI, comments | + + +All SuperDoc config options are available as props. The component extends `SuperDocConfig`, so any option from the core package can be passed directly. + + +### Props That Trigger Rebuild + +These props trigger a full instance rebuild when changed: + +| Prop | Reason | +|------|--------| +| `document` | New document to load | +| `user` | User identity changed | +| `users` | Users list changed | +| `modules` | Module configuration changed | +| `role` | Permission level changed | +| `hideToolbar` | Toolbar visibility changed | + +Other props like `documentMode` and callbacks are handled efficiently without rebuild. + +--- + +## Troubleshooting + +### "document is not defined" (SSR) + +The component handles SSR internally, but if you still see errors: + +```jsx +// Use dynamic import in Next.js +const SuperDocEditor = dynamic( + () => import('@superdoc-dev/react').then(mod => mod.SuperDocEditor), + { ssr: false } +); +``` + +### React Strict Mode Double-Mount + +The component handles React 18 Strict Mode correctly. The internal cleanup flag prevents issues from double-invocation during development. + +### Document Not Loading + +1. Verify the file is a valid `.docx` document +2. Check that `document` prop is a `File`, `Blob`, URL string, or config object +3. Listen for `onContentError` events for parsing errors + +### Changing Document Mode + +The component handles `documentMode` prop changes efficiently without rebuilding: + +```jsx +const [mode, setMode] = useState('editing'); + +// Just update state - no rebuild, no flicker + + +``` + +You can also use the imperative API if preferred: + +```jsx +editorRef.current?.getInstance()?.setDocumentMode('viewing'); +``` + +--- + +## Requirements + +| Requirement | Version | +|-------------|---------| +| React | 16.8.0+ | +| Node.js | 16+ | + ## Next Steps -- [Vue Integration](/getting-started/frameworks/vue) - Vue setup -- [API Reference](/core/superdoc/configuration) - Configuration options -- [Examples](https://github.com/Harbour-Enterprises/SuperDoc/tree/main/examples/react-example) - Working examples + + + Full configuration options + + + All available methods + + + Real-time collaboration setup + + + React + TypeScript example + + + Next.js SSR integration + + diff --git a/examples/getting-started/nextjs/.gitignore b/examples/getting-started/nextjs/.gitignore new file mode 100644 index 0000000000..ce6281ea81 --- /dev/null +++ b/examples/getting-started/nextjs/.gitignore @@ -0,0 +1,6 @@ +node_modules +/.next/ +/out/ +next-env.d.ts +*.tsbuildinfo +.DS_Store diff --git a/examples/getting-started/nextjs/eslint.config.mjs b/examples/getting-started/nextjs/eslint.config.mjs new file mode 100644 index 0000000000..05e726d1b4 --- /dev/null +++ b/examples/getting-started/nextjs/eslint.config.mjs @@ -0,0 +1,18 @@ +import { defineConfig, globalIgnores } from "eslint/config"; +import nextVitals from "eslint-config-next/core-web-vitals"; +import nextTs from "eslint-config-next/typescript"; + +const eslintConfig = defineConfig([ + ...nextVitals, + ...nextTs, + // Override default ignores of eslint-config-next. + globalIgnores([ + // Default ignores of eslint-config-next: + ".next/**", + "out/**", + "build/**", + "next-env.d.ts", + ]), +]); + +export default eslintConfig; diff --git a/examples/getting-started/nextjs/next.config.ts b/examples/getting-started/nextjs/next.config.ts new file mode 100644 index 0000000000..e9ffa3083a --- /dev/null +++ b/examples/getting-started/nextjs/next.config.ts @@ -0,0 +1,7 @@ +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = { + /* config options here */ +}; + +export default nextConfig; diff --git a/examples/getting-started/nextjs/package.json b/examples/getting-started/nextjs/package.json new file mode 100644 index 0000000000..7e0b71029d --- /dev/null +++ b/examples/getting-started/nextjs/package.json @@ -0,0 +1,27 @@ +{ + "name": "nextjs-superdoc", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "eslint" + }, + "dependencies": { + "@superdoc-dev/react": "workspace:*", + "next": "16.1.6", + "react": "^19.2.0", + "react-dom": "^19.2.0" + }, + "devDependencies": { + "@tailwindcss/postcss": "^4", + "@types/node": "^20", + "@types/react": "^19", + "@types/react-dom": "^19", + "eslint": "^9", + "eslint-config-next": "16.1.6", + "tailwindcss": "^4", + "typescript": "^5" + } +} diff --git a/examples/getting-started/nextjs/postcss.config.mjs b/examples/getting-started/nextjs/postcss.config.mjs new file mode 100644 index 0000000000..61e36849cf --- /dev/null +++ b/examples/getting-started/nextjs/postcss.config.mjs @@ -0,0 +1,7 @@ +const config = { + plugins: { + "@tailwindcss/postcss": {}, + }, +}; + +export default config; diff --git a/examples/getting-started/nextjs/public/file.svg b/examples/getting-started/nextjs/public/file.svg new file mode 100644 index 0000000000..004145cddf --- /dev/null +++ b/examples/getting-started/nextjs/public/file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/getting-started/nextjs/public/globe.svg b/examples/getting-started/nextjs/public/globe.svg new file mode 100644 index 0000000000..567f17b0d7 --- /dev/null +++ b/examples/getting-started/nextjs/public/globe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/getting-started/nextjs/public/next.svg b/examples/getting-started/nextjs/public/next.svg new file mode 100644 index 0000000000..5174b28c56 --- /dev/null +++ b/examples/getting-started/nextjs/public/next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/getting-started/nextjs/public/vercel.svg b/examples/getting-started/nextjs/public/vercel.svg new file mode 100644 index 0000000000..7705396033 --- /dev/null +++ b/examples/getting-started/nextjs/public/vercel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/getting-started/nextjs/public/window.svg b/examples/getting-started/nextjs/public/window.svg new file mode 100644 index 0000000000..b2b2a44f6e --- /dev/null +++ b/examples/getting-started/nextjs/public/window.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/getting-started/nextjs/src/app/favicon.ico b/examples/getting-started/nextjs/src/app/favicon.ico new file mode 100644 index 0000000000..718d6fea48 Binary files /dev/null and b/examples/getting-started/nextjs/src/app/favicon.ico differ diff --git a/examples/getting-started/nextjs/src/app/globals.css b/examples/getting-started/nextjs/src/app/globals.css new file mode 100644 index 0000000000..a2dc41ecee --- /dev/null +++ b/examples/getting-started/nextjs/src/app/globals.css @@ -0,0 +1,26 @@ +@import "tailwindcss"; + +:root { + --background: #ffffff; + --foreground: #171717; +} + +@theme inline { + --color-background: var(--background); + --color-foreground: var(--foreground); + --font-sans: var(--font-geist-sans); + --font-mono: var(--font-geist-mono); +} + +@media (prefers-color-scheme: dark) { + :root { + --background: #0a0a0a; + --foreground: #ededed; + } +} + +body { + background: var(--background); + color: var(--foreground); + font-family: Arial, Helvetica, sans-serif; +} diff --git a/examples/getting-started/nextjs/src/app/layout.tsx b/examples/getting-started/nextjs/src/app/layout.tsx new file mode 100644 index 0000000000..eab146199b --- /dev/null +++ b/examples/getting-started/nextjs/src/app/layout.tsx @@ -0,0 +1,34 @@ +import type { Metadata } from "next"; +import { Geist, Geist_Mono } from "next/font/google"; +import "./globals.css"; + +const geistSans = Geist({ + variable: "--font-geist-sans", + subsets: ["latin"], +}); + +const geistMono = Geist_Mono({ + variable: "--font-geist-mono", + subsets: ["latin"], +}); + +export const metadata: Metadata = { + title: "SuperDoc + Next.js", + description: "Document editor powered by SuperDoc", +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + + {children} + + + ); +} diff --git a/examples/getting-started/nextjs/src/app/page.tsx b/examples/getting-started/nextjs/src/app/page.tsx new file mode 100644 index 0000000000..f0a972148b --- /dev/null +++ b/examples/getting-started/nextjs/src/app/page.tsx @@ -0,0 +1,127 @@ +'use client'; + +import { useState, useRef } from 'react'; +import { SuperDocEditor, SuperDocRef, DocumentMode } from '@superdoc-dev/react'; +import '@superdoc-dev/react/style.css'; + +export default function Home() { + const [file, setFile] = useState(null); + const [mode, setMode] = useState('editing'); + const editorRef = useRef(null); + + const handleFileChange = (e: React.ChangeEvent) => { + const selectedFile = e.target.files?.[0]; + if (selectedFile) { + setFile(selectedFile); + } + }; + + const handleExport = async () => { + await editorRef.current?.getInstance()?.export({ triggerDownload: true }); + }; + + return ( +
+ {/* Header */} +
+

+ SuperDoc + Next.js +

+ +
+ {/* Mode Toggle */} + {file && ( + <> +
+ + +
+ + + + )} +
+
+ + {/* Main Content */} +
+ {!file ? ( + /* File Upload UI */ +
+ +
+ ) : ( + /* SuperDoc Editor */ +
+ console.log('SuperDoc is ready!')} + onEditorUpdate={() => console.log('Document updated')} + renderLoading={() => ( +
+
Loading document...
+
+ )} + style={{ height: 'calc(100vh - 73px)' }} + /> +
+ )} +
+
+ ); +} diff --git a/examples/getting-started/nextjs/tsconfig.json b/examples/getting-started/nextjs/tsconfig.json new file mode 100644 index 0000000000..cf9c65d3e0 --- /dev/null +++ b/examples/getting-started/nextjs/tsconfig.json @@ -0,0 +1,34 @@ +{ + "compilerOptions": { + "target": "ES2017", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "react-jsx", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./src/*"] + } + }, + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts", + ".next/dev/types/**/*.ts", + "**/*.mts" + ], + "exclude": ["node_modules"] +} diff --git a/examples/getting-started/typescript/.gitignore b/examples/getting-started/react/.gitignore similarity index 100% rename from examples/getting-started/typescript/.gitignore rename to examples/getting-started/react/.gitignore diff --git a/examples/getting-started/react/README.md b/examples/getting-started/react/README.md new file mode 100644 index 0000000000..5f0de5b164 --- /dev/null +++ b/examples/getting-started/react/README.md @@ -0,0 +1,47 @@ +# SuperDoc React + TypeScript Example + +A TypeScript example demonstrating `@superdoc-dev/react` integration with full type safety. + +## Features Demonstrated + +- **File Upload** - Load `.docx` files with type-safe event handlers +- **Mode Switching** - Toggle between editing, suggesting, and viewing modes +- **Ref API** - Access SuperDoc instance methods with proper typing +- **Export** - Download documents as DOCX +- **User Info** - Pass typed user information to the editor +- **Loading States** - Custom loading UI with `renderLoading` +- **Event Callbacks** - Typed callbacks for editor events + +## Run + +```bash +# From repo root +pnpm install +pnpm -C examples/getting-started/react dev +``` + +## Key Types Used + +```typescript +import type { SuperDocRef, DocumentMode } from '@superdoc-dev/react'; + +// Ref for accessing instance methods +const editorRef = useRef(null); + +// Typed document mode state +const [mode, setMode] = useState('editing'); + +// Access instance with proper types +const instance = editorRef.current?.getInstance(); +await instance?.export({ triggerDownload: true }); +``` + +## Project Structure + +``` +src/ +├── App.tsx # Main component with SuperDoc integration +├── App.css # Styles +├── main.tsx # Entry point +└── index.css # Global styles +``` diff --git a/examples/getting-started/react/demo-config.json b/examples/getting-started/react/demo-config.json deleted file mode 100644 index 787ff342c8..0000000000 --- a/examples/getting-started/react/demo-config.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "dirname": "react-example", - "tags": [ - "editing", - "viewing", - "react" - ], - "title": "React" -} \ No newline at end of file diff --git a/examples/getting-started/react/demo-thumbnail.png b/examples/getting-started/react/demo-thumbnail.png deleted file mode 100644 index 8425d2ff17..0000000000 Binary files a/examples/getting-started/react/demo-thumbnail.png and /dev/null differ diff --git a/examples/getting-started/react/demo-video.mp4 b/examples/getting-started/react/demo-video.mp4 deleted file mode 100644 index 77bbd8c622..0000000000 Binary files a/examples/getting-started/react/demo-video.mp4 and /dev/null differ diff --git a/examples/getting-started/react/index.html b/examples/getting-started/react/index.html index 5a4e3e6da2..fa31e5e69d 100644 --- a/examples/getting-started/react/index.html +++ b/examples/getting-started/react/index.html @@ -1,12 +1,12 @@ - + - SuperDoc React Example + SuperDoc React + TypeScript Example
- + - \ No newline at end of file + diff --git a/examples/getting-started/react/package.json b/examples/getting-started/react/package.json index 698373a5db..a96ee7c543 100644 --- a/examples/getting-started/react/package.json +++ b/examples/getting-started/react/package.json @@ -1,19 +1,23 @@ { - "name": "react-superdoc-example", + "name": "react-with-typescript-example", "private": true, "version": "0.0.1", "type": "module", "scripts": { - "dev": "vite" + "dev": "vite", + "build": "tsc -b && vite build", + "preview": "vite preview" }, "dependencies": { - "react": "^19.0.0", - "react-dom": "^19.0.0", - "styled-jsx": "^5.1.7", - "superdoc": "0.20.0-next.13" + "@superdoc-dev/react": "workspace:*", + "react": "^19.2.0", + "react-dom": "^19.2.0" }, "devDependencies": { - "@vitejs/plugin-react": "^4.0.4", - "vite": "^6.2.0" + "@types/react": "^18.3.0", + "@types/react-dom": "^18.3.0", + "@vitejs/plugin-react": "^4.3.0", + "typescript": "~5.5.0", + "vite": "^5.4.0" } } diff --git a/examples/getting-started/react/src/App.css b/examples/getting-started/react/src/App.css new file mode 100644 index 0000000000..c9fb3dbd23 --- /dev/null +++ b/examples/getting-started/react/src/App.css @@ -0,0 +1,218 @@ +/* Layout */ +.app { + height: 100vh; + display: flex; + flex-direction: column; + background: #f5f5f5; +} + +/* Header */ +.header { + padding: 1rem 1.5rem; + background: #1a1a2e; + color: white; + display: flex; + align-items: center; + gap: 1.5rem; + flex-wrap: wrap; +} + +.header h1 { + font-size: 1.25rem; + font-weight: 600; + margin-right: auto; +} + +/* Controls */ +.controls { + display: flex; + align-items: center; + gap: 1rem; + flex-wrap: wrap; +} + +/* Buttons */ +.btn { + padding: 0.5rem 1rem; + font-size: 0.875rem; + font-weight: 500; + border: 1px solid rgba(255, 255, 255, 0.2); + border-radius: 6px; + background: transparent; + color: white; + cursor: pointer; + transition: all 0.15s; +} + +.btn:hover { + background: rgba(255, 255, 255, 0.1); +} + +.btn.primary { + background: #3b82f6; + border-color: #3b82f6; +} + +.btn.primary:hover { + background: #2563eb; + border-color: #2563eb; +} + +.btn.large { + padding: 0.75rem 1.5rem; + font-size: 1rem; +} + +.btn:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +/* Mode Switcher */ +.mode-switcher { + display: flex; + background: rgba(255, 255, 255, 0.1); + border-radius: 6px; + padding: 2px; +} + +.mode-btn { + padding: 0.4rem 0.75rem; + font-size: 0.8rem; + font-weight: 500; + border: none; + border-radius: 4px; + background: transparent; + color: rgba(255, 255, 255, 0.7); + cursor: pointer; + transition: all 0.15s; +} + +.mode-btn:hover:not(:disabled) { + color: white; +} + +.mode-btn.active { + background: white; + color: #1a1a2e; +} + +.mode-btn:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +/* Actions */ +.actions { + display: flex; + gap: 0.5rem; +} + +/* Status */ +.status { + display: flex; + align-items: center; + gap: 0.5rem; + font-size: 0.8rem; + color: rgba(255, 255, 255, 0.7); +} + +.status-dot { + width: 8px; + height: 8px; + border-radius: 50%; + background: #fbbf24; +} + +.status-dot.ready { + background: #22c55e; +} + +.status-dot.loading { + animation: pulse 1s infinite; +} + +@keyframes pulse { + 0%, + 100% { + opacity: 1; + } + 50% { + opacity: 0.5; + } +} + +/* Editor Area */ +.editor-area { + flex: 1; + min-height: 0; + background: white; +} + +/* Empty State */ +.empty-state { + height: 100%; + display: flex; + align-items: center; + justify-content: center; + background: #fafafa; +} + +.empty-content { + text-align: center; + color: #666; +} + +.empty-content h2 { + font-size: 1.5rem; + font-weight: 600; + color: #333; + margin-bottom: 0.5rem; +} + +.empty-content p { + margin-bottom: 1.5rem; +} + +/* Loading State */ +.loading-state { + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 1rem; + color: #666; +} + +.spinner { + width: 32px; + height: 32px; + border: 3px solid #e5e7eb; + border-top-color: #3b82f6; + border-radius: 50%; + animation: spin 0.8s linear infinite; +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} + +/* Responsive */ +@media (max-width: 768px) { + .header { + padding: 1rem; + } + + .header h1 { + width: 100%; + margin-bottom: 0.5rem; + } + + .controls { + width: 100%; + justify-content: flex-start; + } +} diff --git a/examples/getting-started/react/src/App.jsx b/examples/getting-started/react/src/App.jsx deleted file mode 100644 index 95bb007893..0000000000 --- a/examples/getting-started/react/src/App.jsx +++ /dev/null @@ -1,75 +0,0 @@ -import { useRef, useState } from 'react'; -import DocumentEditor from './components/DocumentEditor'; - -function App() { - const [documentFile, setDocumentFile] = useState(null); - const fileInputRef = useRef(null); - - const handleFileChange = (event) => { - const file = event.target.files?.[0]; - if (file) { - setDocumentFile(file); - } - }; - - const handleEditorReady = (editor) => { - console.log('SuperDoc editor is ready', editor); - }; - - return ( -
-
-

SuperDoc Example

- - -
- -
- -
- - -
- ); -} - -export default App; diff --git a/examples/getting-started/react/src/App.tsx b/examples/getting-started/react/src/App.tsx new file mode 100644 index 0000000000..2f1ce76b59 --- /dev/null +++ b/examples/getting-started/react/src/App.tsx @@ -0,0 +1,181 @@ +import { useRef, useState } from 'react'; +import { SuperDocEditor } from '@superdoc-dev/react'; +import type { SuperDocRef, DocumentMode } from '@superdoc-dev/react'; +import '@superdoc-dev/react/style.css'; +import './App.css'; + +/** + * SuperDoc React + TypeScript Example + * + * Demonstrates: + * - File upload with type safety + * - Document mode switching (editing/viewing/suggesting) + * - Export functionality via ref API + * - User information + * - Loading states + * - Event callbacks + */ +function App() { + // Document state + const [document, setDocument] = useState(null); + const [mode, setMode] = useState('editing'); + const [isReady, setIsReady] = useState(false); + + // Ref for accessing SuperDoc instance methods + const editorRef = useRef(null); + const fileInputRef = useRef(null); + + // Current user (typed) + const currentUser = { + name: 'John Doe', + email: 'john@example.com', + }; + + // Handle file selection + const handleFileSelect = (event: React.ChangeEvent) => { + const file = event.target.files?.[0]; + if (file && file.name.endsWith('.docx')) { + setDocument(file); + setIsReady(false); + } + }; + + // Export document as DOCX + const handleExport = async () => { + const instance = editorRef.current?.getInstance(); + if (instance) { + await instance.export({ triggerDownload: true }); + } + }; + + // Get document as HTML + const handleGetHTML = () => { + const instance = editorRef.current?.getInstance(); + if (instance) { + const html = instance.getHTML(); + console.log('Document HTML:', html); + alert(`Document has ${html.length} section(s). Check console for HTML.`); + } + }; + + // Mode button component for cleaner JSX + const ModeButton = ({ + targetMode, + label, + }: { + targetMode: DocumentMode; + label: string; + }) => ( + + ); + + return ( +
+ {/* Header with controls */} +
+

SuperDoc React + TypeScript

+ +
+ {/* File upload */} + + + + {/* Mode switcher */} + {document && ( +
+ + + +
+ )} + + {/* Actions */} + {document && isReady && ( +
+ + +
+ )} +
+ + {/* Status indicator */} + {document && ( +
+ + {isReady ? `Ready - ${mode} mode` : 'Loading...'} +
+ )} +
+ + {/* Editor area */} +
+ {document ? ( + { + console.log('SuperDoc ready:', superdoc); + setIsReady(true); + }} + onEditorCreate={({ editor }) => { + console.log('ProseMirror editor created:', editor); + }} + onEditorUpdate={() => { + console.log('Document updated'); + }} + onContentError={(event) => { + console.error('Content error:', event); + }} + renderLoading={() => ( +
+
+

Loading document...

+
+ )} + style={{ height: '100%' }} + /> + ) : ( +
+
+

No Document Loaded

+

Click "Open Document" to load a .docx file

+ +
+
+ )} +
+
+ ); +} + +export default App; diff --git a/examples/getting-started/react/src/components/DocumentEditor.jsx b/examples/getting-started/react/src/components/DocumentEditor.jsx deleted file mode 100644 index 8b34e45318..0000000000 --- a/examples/getting-started/react/src/components/DocumentEditor.jsx +++ /dev/null @@ -1,74 +0,0 @@ -import { SuperDoc } from 'superdoc'; -import 'superdoc/style.css'; -import { useEffect, useRef } from 'react'; - -const DocumentEditor = ({ - initialData = null, - readOnly = false, - onEditorReady -}) => { - const editorRef = useRef(null); - - useEffect(() => { - const config = { - selector: '#superdoc', - toolbar: '#superdoc-toolbar', - documentMode: readOnly ? 'viewing' : 'editing', - pagination: true, - rulers: true, - onReady: () => { - if (onEditorReady) { - onEditorReady(editor); - } - }, - onEditorCreate: (event) => { - console.log('Editor is created', event); - }, - onEditorDestroy: () => { - console.log('Editor is destroyed'); - } - } - - if (initialData) config.document = initialData; - // config.document = './sample.docx'; // or use path to file - - const editor = new SuperDoc(config); - - editorRef.current = editor; - - // Cleanup on unmount - return () => { - if (editorRef.current) { - editorRef.current.destroy(); - editorRef.current = null; - } - }; - }, [initialData, readOnly, onEditorReady]); - - return ( -
-
-
- -
- ); -}; - -export default DocumentEditor; diff --git a/examples/getting-started/react/src/index.css b/examples/getting-started/react/src/index.css new file mode 100644 index 0000000000..558e2a6f6f --- /dev/null +++ b/examples/getting-started/react/src/index.css @@ -0,0 +1,20 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +html, +body, +#root { + height: 100%; +} + +body { + font-family: + -apple-system, + BlinkMacSystemFont, + 'Segoe UI', + Roboto, + sans-serif; +} diff --git a/examples/getting-started/react/src/main.jsx b/examples/getting-started/react/src/main.jsx deleted file mode 100644 index d76b758740..0000000000 --- a/examples/getting-started/react/src/main.jsx +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react'; -import ReactDOM from 'react-dom/client'; -import App from './App'; - -ReactDOM.createRoot(document.getElementById('root')).render( - - - -); diff --git a/examples/getting-started/react/src/main.tsx b/examples/getting-started/react/src/main.tsx new file mode 100644 index 0000000000..a46835a4fc --- /dev/null +++ b/examples/getting-started/react/src/main.tsx @@ -0,0 +1,10 @@ +import { StrictMode } from 'react'; +import { createRoot } from 'react-dom/client'; +import App from './App'; +import './index.css'; + +createRoot(document.getElementById('root')!).render( + + + +); diff --git a/examples/getting-started/typescript/src/vite-env.d.ts b/examples/getting-started/react/src/vite-env.d.ts similarity index 100% rename from examples/getting-started/typescript/src/vite-env.d.ts rename to examples/getting-started/react/src/vite-env.d.ts diff --git a/examples/getting-started/typescript/tsconfig.app.json b/examples/getting-started/react/tsconfig.json similarity index 70% rename from examples/getting-started/typescript/tsconfig.app.json rename to examples/getting-started/react/tsconfig.json index 358ca9ba93..109f0ac280 100644 --- a/examples/getting-started/typescript/tsconfig.app.json +++ b/examples/getting-started/react/tsconfig.json @@ -1,26 +1,20 @@ { "compilerOptions": { - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, - - /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "isolatedModules": true, "moduleDetection": "force", "noEmit": true, "jsx": "react-jsx", - - /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true, - "noUncheckedSideEffectImports": true + "noFallthroughCasesInSwitch": true }, "include": ["src"] } diff --git a/examples/getting-started/react/vite.config.js b/examples/getting-started/react/vite.config.js deleted file mode 100644 index 3e238c019c..0000000000 --- a/examples/getting-started/react/vite.config.js +++ /dev/null @@ -1,17 +0,0 @@ -import { defineConfig } from 'vite'; -import react from '@vitejs/plugin-react'; - -export default defineConfig({ - plugins: [ - react({ - babel: { - plugins: [ -"styled-jsx/babel" - ], - }, - }), - ], - optimizeDeps: { - include: ['superdoc'] - } -}); diff --git a/examples/getting-started/typescript/vite.config.ts b/examples/getting-started/react/vite.config.ts similarity index 55% rename from examples/getting-started/typescript/vite.config.ts rename to examples/getting-started/react/vite.config.ts index 7fcf49f040..8b0f57b91a 100644 --- a/examples/getting-started/typescript/vite.config.ts +++ b/examples/getting-started/react/vite.config.ts @@ -3,13 +3,5 @@ import react from '@vitejs/plugin-react' // https://vite.dev/config/ export default defineConfig({ - plugins: [ - react({ - babel: { - plugins: [ -"styled-jsx/babel" - ], - }, - }), - ], + plugins: [react()], }) diff --git a/examples/getting-started/typescript/demo-config.json b/examples/getting-started/typescript/demo-config.json deleted file mode 100644 index e02cc7fc21..0000000000 --- a/examples/getting-started/typescript/demo-config.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "dirname": "typescript-example", - "tags": [ - "editing", - "viewing", - "typescript", - "vanilla-js", - "react" - ], - "title": "Typescript" -} \ No newline at end of file diff --git a/examples/getting-started/typescript/demo-thumbnail.png b/examples/getting-started/typescript/demo-thumbnail.png deleted file mode 100644 index 94f386a039..0000000000 Binary files a/examples/getting-started/typescript/demo-thumbnail.png and /dev/null differ diff --git a/examples/getting-started/typescript/demo-video.mp4 b/examples/getting-started/typescript/demo-video.mp4 deleted file mode 100644 index c4780447b4..0000000000 Binary files a/examples/getting-started/typescript/demo-video.mp4 and /dev/null differ diff --git a/examples/getting-started/typescript/eslint.config.js b/examples/getting-started/typescript/eslint.config.js deleted file mode 100644 index 092408a9f0..0000000000 --- a/examples/getting-started/typescript/eslint.config.js +++ /dev/null @@ -1,28 +0,0 @@ -import js from '@eslint/js' -import globals from 'globals' -import reactHooks from 'eslint-plugin-react-hooks' -import reactRefresh from 'eslint-plugin-react-refresh' -import tseslint from 'typescript-eslint' - -export default tseslint.config( - { ignores: ['dist'] }, - { - extends: [js.configs.recommended, ...tseslint.configs.recommended], - files: ['**/*.{ts,tsx}'], - languageOptions: { - ecmaVersion: 2020, - globals: globals.browser, - }, - plugins: { - 'react-hooks': reactHooks, - 'react-refresh': reactRefresh, - }, - rules: { - ...reactHooks.configs.recommended.rules, - 'react-refresh/only-export-components': [ - 'warn', - { allowConstantExport: true }, - ], - }, - }, -) diff --git a/examples/getting-started/typescript/index.html b/examples/getting-started/typescript/index.html deleted file mode 100644 index e4b78eae12..0000000000 --- a/examples/getting-started/typescript/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - Vite + React + TS - - -
- - - diff --git a/examples/getting-started/typescript/package.json b/examples/getting-started/typescript/package.json deleted file mode 100644 index c446024c6b..0000000000 --- a/examples/getting-started/typescript/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "typescript-example", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "dev": "vite", - "build": "tsc -b && vite build", - "lint": "eslint .", - "preview": "vite preview" - }, - "dependencies": { - "react": "^19.0.0", - "react-dom": "^19.0.0", - "styled-jsx": "^5.1.7", - "superdoc": "0.20.0-next.13" - }, - "devDependencies": { - "@eslint/js": "^9.19.0", - "@types/react": "^19.0.8", - "@types/react-dom": "^19.0.3", - "@vitejs/plugin-react": "^4.3.4", - "eslint": "^9.19.0", - "eslint-plugin-react-hooks": "^5.0.0", - "eslint-plugin-react-refresh": "^0.4.18", - "globals": "^15.14.0", - "typescript": "~5.7.2", - "typescript-eslint": "^8.22.0", - "vite": "^6.2.0" - } -} diff --git a/examples/getting-started/typescript/src/App.tsx b/examples/getting-started/typescript/src/App.tsx deleted file mode 100644 index da4adaf0fe..0000000000 --- a/examples/getting-started/typescript/src/App.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import { useRef, useState, ChangeEvent } from 'react'; -import DocumentEditor from './components/DocumentEditor'; - -function App() { - const [documentFile, setDocumentFile] = useState(null); - const fileInputRef = useRef(null); - - const handleFileChange = (event: ChangeEvent) => { - const file = event.target.files?.[0]; - if (file) { - setDocumentFile(file); - } - }; - - return ( -
-
-

SuperDoc Example

- - -
- -
- -
- - -
- ); -} - -export default App; \ No newline at end of file diff --git a/examples/getting-started/typescript/src/components/DocumentEditor.tsx b/examples/getting-started/typescript/src/components/DocumentEditor.tsx deleted file mode 100644 index bd5e792ac8..0000000000 --- a/examples/getting-started/typescript/src/components/DocumentEditor.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import { SuperDoc, Config } from 'superdoc'; - -import 'superdoc/style.css'; -import { useEffect, useRef } from 'react'; - -interface Props { - initialData: File | null, - readOnly?: boolean, -} - -const DocumentEditor = ({ - initialData = null, - readOnly = false, -}: Props) => { - const editorRef = useRef(null); - useEffect(() => { - const config: Config = { - selector: '#superdoc', - toolbar: '#superdoc-toolbar', - document: initialData, // URL, File or document config - documentMode: readOnly ? 'viewing' : 'editing', - pagination: true, - rulers: true, - onReady: (event) => { - console.log('SuperDoc is ready', event); - }, - onEditorCreate: (event) => { - console.log('Editor is created', event); - }, - }; - - const editor = new SuperDoc(config); - editorRef.current = editor; - - // Cleanup on unmount - return () => { - if (editorRef.current) { - editorRef.current.destroy(); - editorRef.current = null; - } - }; - }, [initialData, readOnly]); - - return ( -
-
-
- -
- ); -}; - -export default DocumentEditor; diff --git a/examples/getting-started/typescript/src/main.tsx b/examples/getting-started/typescript/src/main.tsx deleted file mode 100644 index a996c1e074..0000000000 --- a/examples/getting-started/typescript/src/main.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import { createRoot } from 'react-dom/client' -import App from './App.tsx' - -createRoot(document.getElementById('root')!).render( - -) diff --git a/examples/getting-started/typescript/tsconfig.json b/examples/getting-started/typescript/tsconfig.json deleted file mode 100644 index 1e45f34b23..0000000000 --- a/examples/getting-started/typescript/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "files": [], - "references": [ - { "path": "./tsconfig.app.json" }, - { "path": "./tsconfig.node.json" } - ], - "compilerOptions": { - "checkJs": true, - "allowJs": true - } -} diff --git a/examples/getting-started/typescript/tsconfig.node.json b/examples/getting-started/typescript/tsconfig.node.json deleted file mode 100644 index db0becc8b0..0000000000 --- a/examples/getting-started/typescript/tsconfig.node.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compilerOptions": { - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", - "target": "ES2022", - "lib": ["ES2023"], - "module": "ESNext", - "skipLibCheck": true, - - /* Bundler mode */ - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "isolatedModules": true, - "moduleDetection": "force", - "noEmit": true, - - /* Linting */ - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true, - "noUncheckedSideEffectImports": true - }, - "include": ["vite.config.ts"] -} diff --git a/examples/pnpm-workspace.yaml b/examples/pnpm-workspace.yaml index 1736a0e370..c20f156108 100644 --- a/examples/pnpm-workspace.yaml +++ b/examples/pnpm-workspace.yaml @@ -15,3 +15,4 @@ onlyBuiltDependencies: overrides: superdoc: file:../packages/superdoc/superdoc.tgz + '@superdoc-dev/react': file:../packages/react/react.tgz diff --git a/examples/tests/test-config.js b/examples/tests/test-config.js index ea7986aa6f..385893ac4a 100644 --- a/examples/tests/test-config.js +++ b/examples/tests/test-config.js @@ -2,7 +2,6 @@ export default { packages: [ "getting-started/cdn", "getting-started/react", - "getting-started/typescript", "getting-started/vanilla", "getting-started/vue", // Customization diff --git a/packages/react/.releaserc.cjs b/packages/react/.releaserc.cjs new file mode 100644 index 0000000000..ce3571a882 --- /dev/null +++ b/packages/react/.releaserc.cjs @@ -0,0 +1,42 @@ +/* eslint-env node */ +const branch = process.env.GITHUB_REF_NAME || process.env.CI_COMMIT_BRANCH; + +const config = { + branches: [ + { name: 'stable', channel: 'latest' }, + { name: 'main', prerelease: 'next', channel: 'next' }, + ], + tagFormat: 'react-v${version}', + plugins: [ + '@semantic-release/commit-analyzer', + '@semantic-release/release-notes-generator', + ['@semantic-release/npm', { npmPublish: true }], + ], +}; + +const isPrerelease = config.branches.some( + (b) => typeof b === 'object' && b.name === branch && b.prerelease +); + +if (!isPrerelease) { + config.plugins.push([ + '@semantic-release/git', + { + assets: ['package.json'], + message: + 'chore(react): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}', + }, + ]); +} + +// Linear integration - labels issues with version on release +config.plugins.push(['semantic-release-linear-app', { teamKeys: ['SD'], addComment: true, packageName: 'react' }]); + +config.plugins.push([ + '@semantic-release/github', + { + successComment: ':tada: This ${issue.pull_request ? "PR" : "issue"} is included in **@superdoc-dev/react** v${nextRelease.version}\n\nThe release is available on [GitHub release]()', + } +]); + +module.exports = config; diff --git a/packages/react/CLAUDE.md b/packages/react/CLAUDE.md new file mode 100644 index 0000000000..1a53c37ca6 --- /dev/null +++ b/packages/react/CLAUDE.md @@ -0,0 +1,85 @@ +# @superdoc-dev/react + +React wrapper for SuperDoc. + +## Files + +| File | Purpose | +|------|---------| +| `src/SuperDocEditor.tsx` | Main component | +| `src/types.ts` | TypeScript types (extracted from superdoc) | +| `src/utils.ts` | ID generation | +| `src/index.ts` | Public exports | + +## Type System + +Types are extracted from `superdoc` constructor to avoid duplication: + +```typescript +type SuperDocConstructorConfig = ConstructorParameters[0]; + +export type DocumentMode = NonNullable; +export type UserRole = NonNullable; +export type SuperDocUser = NonNullable; +export type SuperDocModules = NonNullable; +export type SuperDocConfig = SuperDocConstructorConfig; +export type SuperDocInstance = InstanceType; + +// Props = SuperDocConfig (minus internal) + React-specific +type InternalProps = 'selector'; // managed by component +type OptionalInReact = 'documentMode'; // defaults to 'editing' + +export interface SuperDocEditorProps + extends Omit, + Partial>, + ReactProps {} +``` + +## React-Specific Props + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `id` | `string` | auto-generated | Custom container ID | +| `renderLoading` | `() => ReactNode` | - | Loading UI during init | +| `hideToolbar` | `boolean` | `false` | Hide the toolbar | +| `className` | `string` | - | Wrapper CSS class | +| `style` | `CSSProperties` | - | Wrapper inline styles | + +## SSR Behavior + +- Returns `renderLoading()` on server if provided, otherwise `null` +- Initializes SuperDoc only after client-side hydration +- Container div must exist before SuperDoc mounts + +## Ref API + +```typescript +const editorRef = useRef(null); + +// Access SuperDoc instance +const instance = editorRef.current?.getInstance(); + +// Call methods +instance?.setDocumentMode('viewing'); +instance?.export({ triggerDownload: true }); +instance?.getHTML(); +``` + +## Props That Trigger Rebuild + +These props cause the SuperDoc instance to be destroyed and recreated: +- `document` - new document to load +- `user` - user identity changed +- `users` - users list changed +- `modules` - module config changed +- `role` - permission level changed +- `hideToolbar` - toolbar visibility changed + +Other props like `documentMode` and callbacks are handled without rebuild. + +## Commands + +```bash +pnpm --filter @superdoc-dev/react build +pnpm --filter @superdoc-dev/react test +``` diff --git a/packages/react/README.md b/packages/react/README.md new file mode 100644 index 0000000000..4ef78e63d1 --- /dev/null +++ b/packages/react/README.md @@ -0,0 +1,184 @@ +# @superdoc-dev/react + +Official React wrapper for [SuperDoc](https://www.superdoc.dev). + +## Installation + +```bash +npm install @superdoc-dev/react +``` + +> `superdoc` is included as a dependency - no need to install it separately. + +## Quick Start + +```tsx +import { SuperDocEditor } from '@superdoc-dev/react'; +import '@superdoc-dev/react/style.css'; + +function App() { + return ; +} +``` + +## Changing Mode + +Just update the `documentMode` prop - the component handles it efficiently (no rebuild): + +```tsx +function App() { + const [mode, setMode] = useState('editing'); + + return ( + <> + + + + + ); +} +``` + +## Using the Ref + +Access SuperDoc methods via `getInstance()`: + +```tsx +import { useRef } from 'react'; +import { SuperDocEditor, SuperDocRef } from '@superdoc-dev/react'; + +function App() { + const ref = useRef(null); + + const handleExport = async () => { + await ref.current?.getInstance()?.export({ triggerDownload: true }); + }; + + return ( + <> + + + + ); +} +``` + +## Props + +All [SuperDoc config options](https://docs.superdoc.dev) are available as props, plus: + +| Prop | Type | Description | +|------|------|-------------| +| `id` | `string` | Custom container ID (auto-generated if not provided) | +| `renderLoading` | `() => ReactNode` | Loading UI | +| `hideToolbar` | `boolean` | Hide toolbar (default: false) | +| `className` | `string` | Wrapper CSS class | +| `style` | `CSSProperties` | Wrapper inline styles | + +### Props That Trigger Rebuilds + +These props cause the SuperDoc instance to be destroyed and recreated when changed: + +- `document` - The document to load +- `user` - Current user identity +- `users` - List of users +- `modules` - Module configuration (collaboration, comments, etc.) +- `role` - User permission level +- `hideToolbar` - Toolbar visibility + +### Props Handled Efficiently + +These props are applied without rebuilding: + +- `documentMode` - Calls `setDocumentMode()` internally + +### Initial-Only Props + +Other SuperDoc options (`rulers`, `pagination`, etc.) are applied only on initialization. To change them at runtime, use `getInstance()`: + +```tsx +ref.current?.getInstance()?.toggleRuler(); +``` + +### Common Props + +```tsx + console.log('Ready!')} + onEditorCreate={({ editor }) => console.log('Editor created')} +/> +``` + +## Examples + +### View-Only Mode + +```tsx + +``` + +### File Upload + +```tsx +function Editor() { + const [file, setFile] = useState(null); + + return ( + <> + setFile(e.target.files?.[0] || null)} /> + {file && } + + ); +} +``` + +### With Collaboration + +```tsx + +``` + +## Next.js + +```tsx +'use client'; + +import dynamic from 'next/dynamic'; + +const SuperDocEditor = dynamic( + () => import('@superdoc-dev/react').then((m) => m.SuperDocEditor), + { ssr: false } +); +``` + +## TypeScript + +```tsx +import type { + SuperDocEditorProps, + SuperDocRef, + DocumentMode, + UserRole, + SuperDocUser, +} from '@superdoc-dev/react'; +``` + +Types are extracted from the `superdoc` package, ensuring they stay in sync. + +## License + +AGPL-3.0 + diff --git a/packages/react/package.json b/packages/react/package.json new file mode 100644 index 0000000000..a58c418f5a --- /dev/null +++ b/packages/react/package.json @@ -0,0 +1,78 @@ +{ + "name": "@superdoc-dev/react", + "version": "0.1.0", + "description": "Official React wrapper for SuperDoc document editor", + "type": "module", + "main": "./dist/index.cjs", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "require": "./dist/index.cjs", + "import": "./dist/index.js" + }, + "./style.css": { + "import": "./style.css", + "require": "./style.css" + } + }, + "scripts": { + "build": "vite build", + "dev": "vite build --watch", + "test": "vitest run", + "type-check": "tsc --noEmit", + "lint": "eslint src --ext .ts,.tsx", + "prepublishOnly": "pnpm run build" + }, + "keywords": [ + "superdoc", + "react", + "document", + "editor", + "docx", + "word" + ], + "license": "AGPL-3.0", + "dependencies": { + "superdoc": ">=1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + }, + "devDependencies": { + "@testing-library/react": "catalog:", + "@types/node": "catalog:", + "@types/react": "catalog:", + "@types/react-dom": "catalog:", + "@typescript-eslint/eslint-plugin": "catalog:", + "@typescript-eslint/parser": "catalog:", + "eslint": "catalog:", + "happy-dom": "catalog:", + "react": "catalog:", + "react-dom": "catalog:", + "typescript": "catalog:", + "vite": "catalog:", + "vite-plugin-dts": "catalog:", + "@vitejs/plugin-react": "catalog:", + "vitest": "catalog:" + }, + "files": [ + "dist", + "style.css", + "README.md" + ], + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/superdoc-dev/superdoc.git", + "directory": "packages/react" + }, + "bugs": { + "url": "https://github.com/superdoc-dev/superdoc/issues" + }, + "homepage": "https://github.com/superdoc-dev/superdoc/tree/main/packages/react#readme" +} diff --git a/packages/react/src/SuperDocEditor.test.tsx b/packages/react/src/SuperDocEditor.test.tsx new file mode 100644 index 0000000000..6c469273ea --- /dev/null +++ b/packages/react/src/SuperDocEditor.test.tsx @@ -0,0 +1,227 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import { render, cleanup, waitFor } from '@testing-library/react'; +import { createRef, StrictMode } from 'react'; +import { SuperDocEditor } from './SuperDocEditor'; +import type { SuperDocRef } from './types'; + +describe('SuperDocEditor', () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + afterEach(() => { + cleanup(); + }); + + describe('mounting and unmounting', () => { + it('should render container elements', () => { + const { container } = render(); + + expect(container.querySelector('.superdoc-wrapper')).toBeTruthy(); + expect(container.querySelector('.superdoc-editor-container')).toBeTruthy(); + expect(container.querySelector('.superdoc-toolbar-container')).toBeTruthy(); + }); + + it('should hide toolbar when hideToolbar={true}', () => { + const { container } = render(); + + expect(container.querySelector('.superdoc-toolbar-container')).toBeFalsy(); + }); + + it('should apply className and style props', () => { + const { container } = render(); + + const wrapper = container.querySelector('.superdoc-wrapper'); + expect(wrapper?.classList.contains('custom-class')).toBe(true); + expect((wrapper as HTMLElement)?.style.backgroundColor).toBe('red'); + }); + + it('should handle unmount without throwing', async () => { + const onReady = vi.fn(); + const { unmount } = render(); + + // Wait for initialization to complete + await waitFor( + () => { + expect(onReady).toHaveBeenCalled(); + }, + { timeout: 5000 }, + ); + + // Unmount should not throw + expect(() => unmount()).not.toThrow(); + }); + }); + + describe('ref methods', () => { + it('should expose getInstance method only', () => { + const ref = createRef(); + render(); + + // Ref should be available immediately with getInstance + expect(ref.current).not.toBeNull(); + expect(typeof ref.current?.getInstance).toBe('function'); + }); + + it('should return null from getInstance before ready', () => { + const ref = createRef(); + render(); + + // Before async init completes, getInstance returns null + const instance = ref.current?.getInstance(); + expect(instance).toBeNull(); + }); + + it('should safely handle calls through getInstance before ready', () => { + const ref = createRef(); + render(); + + // Using optional chaining through getInstance is safe + expect(() => ref.current?.getInstance()?.focus()).not.toThrow(); + expect(() => ref.current?.getInstance()?.setDocumentMode('viewing')).not.toThrow(); + expect(() => ref.current?.getInstance()?.toggleRuler()).not.toThrow(); + }); + }); + + describe('loading state', () => { + it('should show loading content initially', () => { + const { container } = render( +
Loading...
} />, + ); + + expect(container.querySelector('[data-testid="loading"]')).toBeTruthy(); + }); + }); + + describe('callbacks', () => { + it('should call onReady when SuperDoc is ready', async () => { + const onReady = vi.fn(); + render(); + + await waitFor( + () => { + expect(onReady).toHaveBeenCalled(); + }, + { timeout: 5000 }, + ); + }); + + it('should call onEditorCreate when editor is created', async () => { + const onEditorCreate = vi.fn(); + render(); + + await waitFor( + () => { + expect(onEditorCreate).toHaveBeenCalled(); + }, + { timeout: 5000 }, + ); + }); + }); + + describe('onEditorDestroy', () => { + it('should call onEditorDestroy when component unmounts', async () => { + const onReady = vi.fn(); + const onEditorDestroy = vi.fn(); + const { unmount } = render(); + + await waitFor( + () => { + expect(onReady).toHaveBeenCalled(); + }, + { timeout: 5000 }, + ); + + unmount(); + + await waitFor( + () => { + expect(onEditorDestroy).toHaveBeenCalled(); + }, + { timeout: 5000 }, + ); + }); + }); + + describe('error states', () => { + it('should show error container when initialization fails', async () => { + // Force an error by providing an invalid document + const onException = vi.fn(); + const { container } = render( + , + ); + + await waitFor( + () => { + const errorContainer = container.querySelector('.superdoc-error-container'); + // If SuperDoc throws on invalid input, error UI shows + // If SuperDoc handles it gracefully, onException may be called instead + expect(errorContainer || onException.mock.calls.length > 0).toBeTruthy(); + }, + { timeout: 5000 }, + ); + }); + }); + + describe('Strict Mode compatibility', () => { + it('should not throw in Strict Mode', () => { + expect(() => { + render( + + + , + ); + }).not.toThrow(); + }); + }); + + describe('unique IDs', () => { + it('should generate unique container IDs for multiple instances', () => { + const { container: container1 } = render(); + const { container: container2 } = render(); + + const id1 = container1.querySelector('.superdoc-editor-container')?.id; + const id2 = container2.querySelector('.superdoc-editor-container')?.id; + + expect(id1).toBeTruthy(); + expect(id2).toBeTruthy(); + expect(id1).not.toBe(id2); + }); + }); + + describe('with real superdoc', () => { + it('should initialize superdoc instance', async () => { + const ref = createRef(); + const onReady = vi.fn(); + + render(); + + await waitFor( + () => { + expect(onReady).toHaveBeenCalled(); + expect(ref.current?.getInstance()).not.toBeNull(); + }, + { timeout: 5000 }, + ); + }); + + it('should provide access to superdoc methods after ready', async () => { + const ref = createRef(); + const onReady = vi.fn(); + + render(); + + await waitFor( + () => { + expect(onReady).toHaveBeenCalled(); + }, + { timeout: 5000 }, + ); + + const instance = ref.current?.getInstance(); + expect(instance).toBeTruthy(); + expect(typeof instance?.destroy).toBe('function'); + expect(typeof instance?.setDocumentMode).toBe('function'); + }); + }); +}); diff --git a/packages/react/src/SuperDocEditor.tsx b/packages/react/src/SuperDocEditor.tsx new file mode 100644 index 0000000000..e2b1d96b90 --- /dev/null +++ b/packages/react/src/SuperDocEditor.tsx @@ -0,0 +1,270 @@ +import { forwardRef, useEffect, useImperativeHandle, useRef, useState, type ForwardedRef } from 'react'; +import { generateId } from './utils'; +import type { + DocumentMode, + SuperDocEditorProps, + SuperDocInstance, + SuperDocRef, + SuperDocReadyEvent, + SuperDocEditorCreateEvent, + SuperDocEditorUpdateEvent, + SuperDocContentErrorEvent, + SuperDocExceptionEvent, +} from './types'; + +/** Callback props type for the ref */ +type CallbacksType = { + onReady?: (event: SuperDocReadyEvent) => void; + onEditorCreate?: (event: SuperDocEditorCreateEvent) => void; + onEditorDestroy?: () => void; + onEditorUpdate?: (event: SuperDocEditorUpdateEvent) => void; + onContentError?: (event: SuperDocContentErrorEvent) => void; + onException?: (event: SuperDocExceptionEvent) => void; +}; + +/** + * SuperDocEditor - React wrapper component for SuperDoc + * + * Provides a component-based API with proper lifecycle management + * and React Strict Mode compatibility. + * + * NOTE: This is a client-only component. During SSR, it renders the + * `renderLoading` placeholder if provided, otherwise returns null. + * For Next.js, use dynamic import with { ssr: false }. + */ +function SuperDocEditorInner(props: SuperDocEditorProps, ref: ForwardedRef) { + const [isClient, setIsClient] = useState(false); + const [hasError, setHasError] = useState(false); + + useEffect(() => { + setIsClient(true); + }, []); + + // Destructure React-specific props and key rebuild triggers + const { + // React-specific + id, + renderLoading, + hideToolbar = false, + className, + style, + // Callbacks (stored in ref to avoid triggering rebuilds) + onReady, + onEditorCreate, + onEditorDestroy, + onEditorUpdate, + onContentError, + onException, + // Key props that trigger rebuild when changed + document: documentProp, + user, + users, + modules, + // All other props passed through + ...restProps + } = props; + + // Apply defaults + const documentMode = props.documentMode ?? 'editing'; + const role = props.role ?? 'editor'; + + const instanceRef = useRef(null); + const toolbarContainerRef = useRef(null); + + // Generate stable IDs once per component instance (use provided id if available) + const idsRef = useRef<{ containerId: string; toolbarId: string } | null>(null); + if (idsRef.current === null) { + const baseId = id ?? generateId(); + idsRef.current = { containerId: baseId, toolbarId: `${baseId}-toolbar` }; + } + const { containerId, toolbarId } = idsRef.current; + + const [isLoading, setIsLoading] = useState(true); + + // Store callbacks in refs to avoid triggering effect on callback changes + const callbacksRef = useRef({ + onReady, + onEditorCreate, + onEditorDestroy, + onEditorUpdate, + onContentError, + onException, + }); + + // Update callback refs when props change + useEffect(() => { + callbacksRef.current = { + onReady, + onEditorCreate, + onEditorDestroy, + onEditorUpdate, + onContentError, + onException, + }; + }, [onReady, onEditorCreate, onEditorDestroy, onEditorUpdate, onContentError, onException]); + + // Queue mode changes that happen during init + const pendingModeRef = useRef(null); + const isInitializingRef = useRef(false); + + // Track documentMode changes and apply imperatively + const prevDocumentModeRef = useRef(documentMode); + useEffect(() => { + if (prevDocumentModeRef.current !== documentMode) { + if (instanceRef.current) { + // Instance exists, apply immediately + instanceRef.current.setDocumentMode(documentMode); + } else if (isInitializingRef.current) { + // Instance is initializing, queue the mode change + pendingModeRef.current = documentMode; + } + } + prevDocumentModeRef.current = documentMode; + }, [documentMode]); + + // Expose ref methods - simplified API with just getInstance() + useImperativeHandle( + ref, + () => ({ + getInstance: () => instanceRef.current, + }), + [], + ); + + // Main effect: create and destroy SuperDoc instance + useEffect(() => { + // Wait for client-side render so the container div exists in DOM + if (!isClient) return; + + // Reset states when document changes + setIsLoading(true); + setHasError(false); + isInitializingRef.current = true; + + let destroyed = false; + let instance: SuperDocInstance | null = null; + + const initSuperDoc = async () => { + try { + // Dynamic import for SSR safety + const modulePath = 'superdoc'; + const superdocModule = await import(/* @vite-ignore */ modulePath); + const SuperDoc = superdocModule.SuperDoc as new (config: Record) => SuperDocInstance; + + // Check if we were destroyed while loading + if (destroyed) return; + + // Build configuration - pass through all props + const superdocConfig = { + ...restProps, + selector: `#${CSS.escape(containerId)}`, + // Use internal toolbar container unless hideToolbar is true + ...(!hideToolbar && toolbarContainerRef.current ? { toolbar: `#${CSS.escape(toolbarId)}` } : {}), + documentMode, + role, + ...(documentProp != null ? { document: documentProp } : {}), + ...(user ? { user } : {}), + ...(users ? { users } : {}), + ...(modules ? { modules } : {}), + // Wire up callbacks with lifecycle guards + onReady: (event: SuperDocReadyEvent) => { + if (!destroyed) { + setIsLoading(false); + isInitializingRef.current = false; + + // Apply any pending mode changes + if (pendingModeRef.current && pendingModeRef.current !== documentMode) { + event.superdoc.setDocumentMode(pendingModeRef.current); + pendingModeRef.current = null; + } + + callbacksRef.current.onReady?.(event); + } + }, + onEditorCreate: (event: SuperDocEditorCreateEvent) => { + if (!destroyed) { + callbacksRef.current.onEditorCreate?.(event); + } + }, + onEditorDestroy: () => { + if (!destroyed) { + callbacksRef.current.onEditorDestroy?.(); + } + }, + onEditorUpdate: (event: SuperDocEditorUpdateEvent) => { + if (!destroyed) { + callbacksRef.current.onEditorUpdate?.(event); + } + }, + onContentError: (event: SuperDocContentErrorEvent) => { + if (!destroyed) { + callbacksRef.current.onContentError?.(event); + } + }, + onException: (event: SuperDocExceptionEvent) => { + if (!destroyed) { + callbacksRef.current.onException?.(event); + } + }, + }; + + instance = new SuperDoc(superdocConfig) as SuperDocInstance; + instanceRef.current = instance; + } catch (error) { + if (!destroyed) { + isInitializingRef.current = false; + setIsLoading(false); + setHasError(true); + console.error('[SuperDocEditor] Failed to initialize SuperDoc:', error); + callbacksRef.current.onException?.({ error: error as Error }); + } + } + }; + + initSuperDoc(); + + // Cleanup function + return () => { + isInitializingRef.current = false; + pendingModeRef.current = null; + if (instance) { + instance.destroy(); + instanceRef.current = null; + } + destroyed = true; + }; + // Only these props trigger a full rebuild. Other props (rulers, etc.) are + // initial values - use getInstance() methods to change them at runtime. + // Note: restProps is intentionally excluded to avoid rebuilds on every render. + // documentMode is handled separately via setDocumentMode() for efficiency. + }, [isClient, documentProp, user, users, modules, role, hideToolbar, containerId, toolbarId]); + + const wrapperClassName = ['superdoc-wrapper', className].filter(Boolean).join(' '); + + // Client-only: show renderLoading placeholder on server if provided, otherwise null + if (!isClient) { + return renderLoading ? ( +
+ {renderLoading()} +
+ ) : null; + } + + return ( +
+ {!hideToolbar &&
} +
+ {isLoading && !hasError && renderLoading &&
{renderLoading()}
} + {hasError &&
Failed to load editor. Check console for details.
} +
+ ); +} + +/** + * SuperDocEditor component with forwardRef - Initializes SuperDoc instance and handles cleanup. + */ +export const SuperDocEditor = forwardRef(SuperDocEditorInner); + +SuperDocEditor.displayName = 'SuperDocEditor'; + +export default SuperDocEditor; diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts new file mode 100644 index 0000000000..7790c0bef7 --- /dev/null +++ b/packages/react/src/index.ts @@ -0,0 +1,25 @@ +// Main component +export { SuperDocEditor, default } from './SuperDocEditor'; + +// Types - extracted from superdoc package for convenience +export type { + // Component props and ref + SuperDocEditorProps, + SuperDocRef, + + // Core types (extracted from superdoc constructor) + DocumentMode, + UserRole, + SuperDocUser, + SuperDocModules, + SuperDocConfig, + SuperDocInstance, + + // Callback event types + Editor, + SuperDocReadyEvent, + SuperDocEditorCreateEvent, + SuperDocEditorUpdateEvent, + SuperDocContentErrorEvent, + SuperDocExceptionEvent, +} from './types'; diff --git a/packages/react/src/types.ts b/packages/react/src/types.ts new file mode 100644 index 0000000000..5eca6211de --- /dev/null +++ b/packages/react/src/types.ts @@ -0,0 +1,163 @@ +import type { CSSProperties, ReactNode } from 'react'; +import type { SuperDoc, Editor } from 'superdoc'; + +/** + * Types for @superdoc-dev/react + * + * Core types are extracted from the SuperDoc constructor parameter type, + * ensuring they stay in sync with the superdoc package. + */ + +// ============================================================================= +// Extract types from SuperDoc constructor (single source of truth) +// ============================================================================= + +/** SuperDoc constructor config - extracted from superdoc package */ +type SuperDocConstructorConfig = ConstructorParameters[0]; + +/** SuperDoc instance type - from superdoc package */ +export type SuperDocInstance = InstanceType; + +/** Document mode - extracted from Config.documentMode */ +export type DocumentMode = NonNullable; + +/** User role - extracted from Config.role */ +export type UserRole = NonNullable; + +/** User object - extracted from Config.user */ +export type SuperDocUser = NonNullable; + +/** Modules configuration - extracted from Config.modules */ +export type SuperDocModules = NonNullable; + +/** Full SuperDoc config - extracted from constructor */ +export type SuperDocConfig = SuperDocConstructorConfig; + +// ============================================================================= +// Callback Event Types +// ============================================================================= + +// Re-export Editor type from superdoc +export type { Editor } from 'superdoc'; + +/** Event passed to onReady callback */ +export interface SuperDocReadyEvent { + superdoc: SuperDocInstance; +} + +/** Event passed to onEditorCreate callback */ +export interface SuperDocEditorCreateEvent { + editor: Editor; +} + +/** Event passed to onEditorUpdate callback */ +export interface SuperDocEditorUpdateEvent { + editor: Editor; +} + +/** Event passed to onContentError callback */ +export interface SuperDocContentErrorEvent { + error: Error; + editor: Editor; + documentId: string; + file: File; +} + +/** Event passed to onException callback */ +export interface SuperDocExceptionEvent { + error: Error; +} + +// ============================================================================= +// React Component Types +// ============================================================================= + +/** + * Props managed internally by the React component (not exposed to users). + * - selector: managed by component (creates internal container) + */ +type InternalProps = 'selector'; + +/** + * Props that are required in core but should be optional in React. + * - documentMode: defaults to 'editing' if not provided + */ +type OptionalInReact = 'documentMode'; + +/** + * Callback props that are explicitly typed in CallbackProps. + * These are excluded from SuperDocConfig to avoid type conflicts. + */ +type ExplicitCallbackProps = + | 'onReady' + | 'onEditorCreate' + | 'onEditorDestroy' + | 'onEditorUpdate' + | 'onContentError' + | 'onException'; + +/** + * Explicitly typed callback props to ensure proper TypeScript inference. + * These override any loosely-typed callbacks from SuperDocConfig. + */ +interface CallbackProps { + /** Callback when SuperDoc is ready */ + onReady?: (event: SuperDocReadyEvent) => void; + + /** Callback after an editor is created */ + onEditorCreate?: (event: SuperDocEditorCreateEvent) => void; + + /** Callback when editor is destroyed */ + onEditorDestroy?: () => void; + + /** Callback when document content is updated */ + onEditorUpdate?: (event: SuperDocEditorUpdateEvent) => void; + + /** Callback when there is a content parsing error */ + onContentError?: (event: SuperDocContentErrorEvent) => void; + + /** Callback when an exception is thrown */ + onException?: (event: SuperDocExceptionEvent) => void; +} + +/** + * React-specific props added on top of SuperDocConfig. + */ +interface ReactProps { + /** Optional ID for the editor container. Auto-generated if not provided. */ + id?: string; + + /** Render function for loading state */ + renderLoading?: () => ReactNode; + + /** Hide the toolbar container. When true, no toolbar is rendered. @default false */ + hideToolbar?: boolean; + + /** Additional CSS class name for the wrapper element */ + className?: string; + + /** Additional inline styles for the wrapper element */ + style?: CSSProperties; +} + +/** + * Props for SuperDocEditor component. + * + * Extends SuperDocConfig (minus internal props) with React-specific additions. + * When new props are added to SuperDoc core, they're automatically available here. + * + * Callback props are explicitly typed to ensure proper TypeScript inference. + */ +export interface SuperDocEditorProps + extends Omit, + Partial>, + CallbackProps, + ReactProps {} + +/** + * Ref interface for SuperDocEditor component + */ +export interface SuperDocRef { + /** Get the underlying SuperDoc instance. Returns null if not yet initialized. */ + getInstance(): SuperDocInstance | null; +} diff --git a/packages/react/src/utils.ts b/packages/react/src/utils.ts new file mode 100644 index 0000000000..97277bba59 --- /dev/null +++ b/packages/react/src/utils.ts @@ -0,0 +1,16 @@ +/** @module utils */ + +/** + * Generate a unique ID for SuperDoc container elements. + * + * Uses a combination of timestamp and random string to ensure uniqueness + * across multiple instances without relying on a global counter. + * + * Note: This function only runs on the client after hydration since + * IDs are generated in a ref initializer (not during SSR render). + * + * @returns A unique identifier string + */ +export function generateId(): string { + return `superdoc-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`; +} diff --git a/packages/react/style.css b/packages/react/style.css new file mode 100644 index 0000000000..7242c28bd0 --- /dev/null +++ b/packages/react/style.css @@ -0,0 +1,2 @@ +/* @superdoc-dev/react styles - re-exports superdoc styles */ +@import 'superdoc/style.css'; diff --git a/packages/react/tsconfig.json b/packages/react/tsconfig.json new file mode 100644 index 0000000000..309d389c06 --- /dev/null +++ b/packages/react/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "outDir": "./dist", + "rootDir": "./src", + "jsx": "react-jsx", + "forceConsistentCasingInFileNames": true, + "allowSyntheticDefaultImports": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.test.tsx"] +} diff --git a/packages/react/vite.config.ts b/packages/react/vite.config.ts new file mode 100644 index 0000000000..bd48e2cb0e --- /dev/null +++ b/packages/react/vite.config.ts @@ -0,0 +1,38 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; +import dts from 'vite-plugin-dts'; + +export default defineConfig({ + plugins: [ + react(), + dts({ + include: ['src/**/*'], + exclude: ['src/**/*.test.ts', 'src/**/*.test.tsx'], + outDir: 'dist', + rollupTypes: true, + }), + ], + build: { + target: 'es2020', + lib: { + entry: 'src/index.ts', + name: 'SuperDocReact', + formats: ['es', 'cjs'], + fileName: (format) => (format === 'es' ? 'index.js' : 'index.cjs'), + }, + minify: true, + sourcemap: false, + rollupOptions: { + external: ['react', 'react-dom', 'react/jsx-runtime', 'superdoc'], + output: { + exports: 'named', + globals: { + react: 'React', + 'react-dom': 'ReactDOM', + 'react/jsx-runtime': 'jsxRuntime', + superdoc: 'SuperDoc', + }, + }, + }, + }, +}); diff --git a/packages/react/vitest.config.ts b/packages/react/vitest.config.ts new file mode 100644 index 0000000000..e223796487 --- /dev/null +++ b/packages/react/vitest.config.ts @@ -0,0 +1,18 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + globals: true, + environment: 'happy-dom', + include: ['src/**/*.test.{ts,tsx}'], + coverage: { + provider: 'v8', + reporter: ['text', 'json', 'html'], + include: ['src/**/*.{ts,tsx}'], + exclude: ['src/**/*.d.ts', 'src/**/*.test.{ts,tsx}'], + }, + }, + esbuild: { + jsx: 'automatic', + }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index de8e483eb2..be88d83b1e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -208,11 +208,11 @@ catalogs: specifier: ^1.33.8 version: 1.41.5 react: - specifier: 19.2.0 - version: 19.2.0 + specifier: 19.2.4 + version: 19.2.4 react-dom: - specifier: 19.2.0 - version: 19.2.0 + specifier: 19.2.4 + version: 19.2.4 rehype-parse: specifier: ^9.0.1 version: 9.0.1 @@ -422,7 +422,7 @@ importers: 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) + 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.4(react@19.2.3))(react@19.2.3))(@types/node@22.19.8)(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(typescript@5.9.3) apps/vscode-ext: dependencies: @@ -511,6 +511,19 @@ importers: specifier: 'catalog:' version: 7.3.1(@types/node@22.19.8)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + examples/tests: + dependencies: + patch-package: + specifier: ^8.0.1 + version: 8.0.1 + devDependencies: + '@playwright/test': + specifier: ^1.55.0 + version: 1.58.1 + playwright: + specifier: ^1.55.0 + version: 1.58.1 + packages/ai: devDependencies: '@types/node': @@ -606,7 +619,7 @@ importers: version: 6.9.1 '@testing-library/react': specifier: 'catalog:' - version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@testing-library/user-event': specifier: 'catalog:' version: 14.6.1(@testing-library/dom@10.4.1) @@ -630,10 +643,10 @@ importers: version: 27.3.0(canvas@3.2.0) react: specifier: 'catalog:' - version: 19.2.0 + version: 19.2.4 react-dom: specifier: 'catalog:' - version: 19.2.0(react@19.2.0) + version: 19.2.4(react@19.2.4) superdoc: specifier: workspace:* version: link:../superdoc @@ -657,10 +670,10 @@ importers: version: link:.. react: specifier: 'catalog:' - version: 19.2.0 + version: 19.2.4 react-dom: specifier: 'catalog:' - version: 19.2.0(react@19.2.0) + version: 19.2.4(react@19.2.4) signature_pad: specifier: ^5.1.1 version: 5.1.3 @@ -884,6 +897,58 @@ importers: packages/preset-geometry: {} + packages/react: + dependencies: + superdoc: + specifier: '>=1.0.0' + version: 1.10.0(@hocuspocus/provider@2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(canvas@3.2.0)(pdfjs-dist@4.3.136)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19) + devDependencies: + '@testing-library/react': + specifier: 'catalog:' + version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@types/node': + specifier: 'catalog:' + version: 22.19.2 + '@types/react': + specifier: 'catalog:' + version: 19.2.11 + '@types/react-dom': + specifier: 'catalog:' + version: 19.2.3(@types/react@19.2.11) + '@typescript-eslint/eslint-plugin': + specifier: 'catalog:' + version: 8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': + specifier: 'catalog:' + version: 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@vitejs/plugin-react': + specifier: 'catalog:' + version: 5.1.3(vite@7.3.1(@types/node@22.19.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) + eslint: + specifier: 'catalog:' + version: 9.39.2(jiti@2.6.1) + happy-dom: + specifier: 20.4.0 + version: 20.4.0 + react: + specifier: 'catalog:' + version: 19.2.4 + react-dom: + specifier: 'catalog:' + version: 19.2.4(react@19.2.4) + typescript: + specifier: 'catalog:' + version: 5.9.3 + vite: + specifier: 'catalog:' + version: 7.3.1(@types/node@22.19.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vite-plugin-dts: + specifier: 'catalog:' + version: 4.5.4(@types/node@22.19.2)(rollup@4.57.1)(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) + vitest: + specifier: 'catalog:' + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0))(tsx@4.21.0)(yaml@2.8.2) + packages/super-editor: dependencies: buffer-crc32: @@ -1157,7 +1222,7 @@ importers: version: 6.9.1 '@testing-library/react': specifier: 'catalog:' - version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@testing-library/user-event': specifier: 'catalog:' version: 14.6.1(@testing-library/dom@10.4.1) @@ -1181,10 +1246,10 @@ importers: version: 27.3.0(canvas@3.2.0) react: specifier: 'catalog:' - version: 19.2.0 + version: 19.2.4 react-dom: specifier: 'catalog:' - version: 19.2.0(react@19.2.0) + version: 19.2.4(react@19.2.4) superdoc: specifier: workspace:* version: link:../superdoc @@ -1208,10 +1273,10 @@ importers: version: link:.. react: specifier: 'catalog:' - version: 19.2.0 + version: 19.2.4 react-dom: specifier: 'catalog:' - version: 19.2.0(react@19.2.0) + version: 19.2.4(react@19.2.4) superdoc: specifier: workspace:* version: link:../../superdoc @@ -1587,12 +1652,6 @@ packages: cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.25.12': - resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - '@esbuild/aix-ppc64@0.27.2': resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} engines: {node: '>=18'} @@ -1605,12 +1664,6 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.25.12': - resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - '@esbuild/android-arm64@0.27.2': resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==} engines: {node: '>=18'} @@ -1623,12 +1676,6 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-arm@0.25.12': - resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - '@esbuild/android-arm@0.27.2': resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==} engines: {node: '>=18'} @@ -1641,12 +1688,6 @@ packages: cpu: [x64] os: [android] - '@esbuild/android-x64@0.25.12': - resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - '@esbuild/android-x64@0.27.2': resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==} engines: {node: '>=18'} @@ -1659,12 +1700,6 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.25.12': - resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - '@esbuild/darwin-arm64@0.27.2': resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==} engines: {node: '>=18'} @@ -1677,12 +1712,6 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.25.12': - resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - '@esbuild/darwin-x64@0.27.2': resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==} engines: {node: '>=18'} @@ -1695,12 +1724,6 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.25.12': - resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - '@esbuild/freebsd-arm64@0.27.2': resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==} engines: {node: '>=18'} @@ -1713,12 +1736,6 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.12': - resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - '@esbuild/freebsd-x64@0.27.2': resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==} engines: {node: '>=18'} @@ -1731,12 +1748,6 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.25.12': - resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - '@esbuild/linux-arm64@0.27.2': resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==} engines: {node: '>=18'} @@ -1749,12 +1760,6 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.25.12': - resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - '@esbuild/linux-arm@0.27.2': resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==} engines: {node: '>=18'} @@ -1767,12 +1772,6 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.25.12': - resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - '@esbuild/linux-ia32@0.27.2': resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==} engines: {node: '>=18'} @@ -1785,12 +1784,6 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.25.12': - resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - '@esbuild/linux-loong64@0.27.2': resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==} engines: {node: '>=18'} @@ -1803,12 +1796,6 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.25.12': - resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - '@esbuild/linux-mips64el@0.27.2': resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==} engines: {node: '>=18'} @@ -1821,12 +1808,6 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.25.12': - resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - '@esbuild/linux-ppc64@0.27.2': resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==} engines: {node: '>=18'} @@ -1839,12 +1820,6 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.25.12': - resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - '@esbuild/linux-riscv64@0.27.2': resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==} engines: {node: '>=18'} @@ -1857,12 +1832,6 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.25.12': - resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - '@esbuild/linux-s390x@0.27.2': resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==} engines: {node: '>=18'} @@ -1875,24 +1844,12 @@ packages: cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.25.12': - resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - '@esbuild/linux-x64@0.27.2': resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.12': - resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - '@esbuild/netbsd-arm64@0.27.2': resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==} engines: {node: '>=18'} @@ -1905,24 +1862,12 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.12': - resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - '@esbuild/netbsd-x64@0.27.2': resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.12': - resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - '@esbuild/openbsd-arm64@0.27.2': resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==} engines: {node: '>=18'} @@ -1935,24 +1880,12 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.12': - resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - '@esbuild/openbsd-x64@0.27.2': resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.25.12': - resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - '@esbuild/openharmony-arm64@0.27.2': resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==} engines: {node: '>=18'} @@ -1965,12 +1898,6 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.25.12': - resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - '@esbuild/sunos-x64@0.27.2': resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==} engines: {node: '>=18'} @@ -1983,12 +1910,6 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.25.12': - resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - '@esbuild/win32-arm64@0.27.2': resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==} engines: {node: '>=18'} @@ -2001,12 +1922,6 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.25.12': - resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - '@esbuild/win32-ia32@0.27.2': resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==} engines: {node: '>=18'} @@ -2019,12 +1934,6 @@ packages: cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.25.12': - resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - '@esbuild/win32-x64@0.27.2': resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==} engines: {node: '>=18'} @@ -5288,11 +5197,6 @@ packages: engines: {node: '>=12'} hasBin: true - esbuild@0.25.12: - resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} - engines: {node: '>=18'} - hasBin: true - esbuild@0.27.2: resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} engines: {node: '>=18'} @@ -8616,10 +8520,10 @@ packages: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true - react-dom@19.2.0: - resolution: {integrity: sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==} + react-dom@19.2.4: + resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} peerDependencies: - react: ^19.2.0 + react: ^19.2.4 react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} @@ -8667,14 +8571,14 @@ packages: '@types/react': optional: true - react@19.2.0: - resolution: {integrity: sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==} - engines: {node: '>=0.10.0'} - react@19.2.3: resolution: {integrity: sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==} engines: {node: '>=0.10.0'} + react@19.2.4: + resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} + engines: {node: '>=0.10.0'} + read-cache@1.0.0: resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} @@ -9423,6 +9327,14 @@ packages: resolution: {integrity: sha512-WHkws2ZflZe41zj6AolvvmaTrWds/VuyeYr9iPVv/oQeaIoVxMKaushfFWpOGDT+GuBrM/sVqF8KUCYQlSSTdQ==} engines: {node: '>=18'} + superdoc@1.10.0: + resolution: {integrity: sha512-3I3c5B2ja5HXEpgSesXMiRadJXoWezeYlwpwAvGr8Uh47gCT773LXbL7GrH49xTZCR0lzPvTNyrZRj0Uz+SCUw==} + peerDependencies: + '@hocuspocus/provider': ^2.13.6 + pdfjs-dist: '>=4.3.136 <=4.6.82' + y-prosemirror: ^1.3.7 + yjs: 13.6.19 + supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -10076,46 +9988,6 @@ packages: peerDependencies: vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 - vite@6.4.1: - resolution: {integrity: sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - jiti: '>=1.21.0' - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - jiti: - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - vite@7.3.1: resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -10984,225 +10856,147 @@ snapshots: '@esbuild/aix-ppc64@0.19.12': optional: true - '@esbuild/aix-ppc64@0.25.12': - optional: true - '@esbuild/aix-ppc64@0.27.2': optional: true '@esbuild/android-arm64@0.19.12': optional: true - '@esbuild/android-arm64@0.25.12': - optional: true - '@esbuild/android-arm64@0.27.2': optional: true '@esbuild/android-arm@0.19.12': optional: true - '@esbuild/android-arm@0.25.12': - optional: true - '@esbuild/android-arm@0.27.2': optional: true '@esbuild/android-x64@0.19.12': optional: true - '@esbuild/android-x64@0.25.12': - optional: true - '@esbuild/android-x64@0.27.2': optional: true '@esbuild/darwin-arm64@0.19.12': optional: true - '@esbuild/darwin-arm64@0.25.12': - optional: true - '@esbuild/darwin-arm64@0.27.2': optional: true '@esbuild/darwin-x64@0.19.12': optional: true - '@esbuild/darwin-x64@0.25.12': - optional: true - '@esbuild/darwin-x64@0.27.2': optional: true '@esbuild/freebsd-arm64@0.19.12': optional: true - '@esbuild/freebsd-arm64@0.25.12': - optional: true - '@esbuild/freebsd-arm64@0.27.2': optional: true '@esbuild/freebsd-x64@0.19.12': optional: true - '@esbuild/freebsd-x64@0.25.12': - optional: true - '@esbuild/freebsd-x64@0.27.2': optional: true '@esbuild/linux-arm64@0.19.12': optional: true - '@esbuild/linux-arm64@0.25.12': - optional: true - '@esbuild/linux-arm64@0.27.2': optional: true '@esbuild/linux-arm@0.19.12': optional: true - '@esbuild/linux-arm@0.25.12': - optional: true - '@esbuild/linux-arm@0.27.2': optional: true '@esbuild/linux-ia32@0.19.12': optional: true - '@esbuild/linux-ia32@0.25.12': - optional: true - '@esbuild/linux-ia32@0.27.2': optional: true '@esbuild/linux-loong64@0.19.12': optional: true - '@esbuild/linux-loong64@0.25.12': - optional: true - '@esbuild/linux-loong64@0.27.2': optional: true '@esbuild/linux-mips64el@0.19.12': optional: true - '@esbuild/linux-mips64el@0.25.12': - optional: true - '@esbuild/linux-mips64el@0.27.2': optional: true '@esbuild/linux-ppc64@0.19.12': optional: true - '@esbuild/linux-ppc64@0.25.12': - optional: true - '@esbuild/linux-ppc64@0.27.2': optional: true '@esbuild/linux-riscv64@0.19.12': optional: true - '@esbuild/linux-riscv64@0.25.12': - optional: true - '@esbuild/linux-riscv64@0.27.2': optional: true '@esbuild/linux-s390x@0.19.12': optional: true - '@esbuild/linux-s390x@0.25.12': - optional: true - '@esbuild/linux-s390x@0.27.2': optional: true '@esbuild/linux-x64@0.19.12': optional: true - '@esbuild/linux-x64@0.25.12': - optional: true - '@esbuild/linux-x64@0.27.2': optional: true - '@esbuild/netbsd-arm64@0.25.12': - optional: true - '@esbuild/netbsd-arm64@0.27.2': optional: true '@esbuild/netbsd-x64@0.19.12': optional: true - '@esbuild/netbsd-x64@0.25.12': - optional: true - '@esbuild/netbsd-x64@0.27.2': optional: true - '@esbuild/openbsd-arm64@0.25.12': - optional: true - '@esbuild/openbsd-arm64@0.27.2': optional: true '@esbuild/openbsd-x64@0.19.12': optional: true - '@esbuild/openbsd-x64@0.25.12': - optional: true - '@esbuild/openbsd-x64@0.27.2': optional: true - '@esbuild/openharmony-arm64@0.25.12': - optional: true - '@esbuild/openharmony-arm64@0.27.2': optional: true '@esbuild/sunos-x64@0.19.12': optional: true - '@esbuild/sunos-x64@0.25.12': - optional: true - '@esbuild/sunos-x64@0.27.2': optional: true '@esbuild/win32-arm64@0.19.12': optional: true - '@esbuild/win32-arm64@0.25.12': - optional: true - '@esbuild/win32-arm64@0.27.2': optional: true '@esbuild/win32-ia32@0.19.12': optional: true - '@esbuild/win32-ia32@0.25.12': - optional: true - '@esbuild/win32-ia32@0.27.2': optional: true '@esbuild/win32-x64@0.19.12': optional: true - '@esbuild/win32-x64@0.25.12': - optional: true - '@esbuild/win32-x64@0.27.2': optional: true @@ -11261,11 +11055,11 @@ snapshots: '@floating-ui/core': 1.7.4 '@floating-ui/utils': 0.2.10 - '@floating-ui/react-dom@2.1.7(react-dom@19.2.0(react@19.2.3))(react@19.2.3)': + '@floating-ui/react-dom@2.1.7(react-dom@19.2.4(react@19.2.3))(react@19.2.3)': dependencies: '@floating-ui/dom': 1.7.5 react: 19.2.3 - react-dom: 19.2.0(react@19.2.3) + react-dom: 19.2.4(react@19.2.3) '@floating-ui/utils@0.2.10': {} @@ -11810,7 +11604,6 @@ snapshots: '@rushstack/node-core-library': 5.19.1(@types/node@22.19.2) transitivePeerDependencies: - '@types/node' - optional: true '@microsoft/api-extractor-model@7.32.2(@types/node@22.19.8)': dependencies: @@ -11838,7 +11631,6 @@ snapshots: typescript: 5.8.2 transitivePeerDependencies: - '@types/node' - optional: true '@microsoft/api-extractor@7.56.1(@types/node@22.19.8)': dependencies: @@ -11868,15 +11660,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.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.4(react@19.2.3))(react@19.2.3))(@types/node@22.19.8)(@types/react@19.2.11)(react-dom@19.2.4(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/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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(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/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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(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 @@ -11908,13 +11700,13 @@ snapshots: - typescript - utf-8-validate - '@mintlify/common@1.0.661(@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.661(@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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': dependencies: '@asyncapi/parser': 3.4.0 - '@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/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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) '@mintlify/models': 0.0.255 '@mintlify/openapi-parser': 0.0.8 - '@mintlify/validation': 0.1.555(@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.555(@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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(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 @@ -11968,13 +11760,13 @@ 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.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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': dependencies: '@asyncapi/parser': 3.4.0 - '@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/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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) '@mintlify/models': 0.0.263 '@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.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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(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 +11820,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.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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(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/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/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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) fs-extra: 11.1.0 unist-util-visit: 4.1.2 transitivePeerDependencies: @@ -12054,9 +11846,9 @@ snapshots: - typescript - utf-8-validate - '@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/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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': dependencies: - '@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) + '@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.4(react@19.2.3))(react@19.2.3) '@shikijs/transformers': 3.22.0 '@shikijs/twoslash': 3.22.0(typescript@5.9.3) arktype: 2.1.29 @@ -12065,9 +11857,9 @@ snapshots: mdast-util-gfm: 3.1.0 mdast-util-mdx-jsx: 3.2.0 mdast-util-to-hast: 13.2.1 - next-mdx-remote-client: 1.1.4(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(unified@11.0.5) + next-mdx-remote-client: 1.1.4(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(unified@11.0.5) react: 19.2.3 - react-dom: 19.2.0(react@19.2.3) + react-dom: 19.2.4(react@19.2.3) rehype-katex: 7.0.1 remark-gfm: 4.0.1 remark-math: 6.0.0 @@ -12103,12 +11895,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.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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(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.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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(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.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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(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 +11927,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.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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(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.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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(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 @@ -12173,9 +11965,9 @@ snapshots: - typescript - utf-8-validate - '@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/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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': dependencies: - '@mintlify/common': 1.0.661(@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.661(@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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(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 @@ -12208,9 +12000,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.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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(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.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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(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 @@ -12243,9 +12035,9 @@ snapshots: - typescript - utf-8-validate - '@mintlify/validation@0.1.555(@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.555(@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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(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/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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) '@mintlify/models': 0.0.255 arktype: 2.1.27 js-yaml: 4.1.0 @@ -12265,9 +12057,9 @@ 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.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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(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/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.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) '@mintlify/models': 0.0.263 arktype: 2.1.27 js-yaml: 4.1.0 @@ -12418,11 +12210,11 @@ snapshots: '@radix-ui/primitive@1.1.3': {} - '@radix-ui/react-arrow@1.1.7(@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)': + '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@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) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3) react: 19.2.3 - react-dom: 19.2.0(react@19.2.3) + react-dom: 19.2.4(react@19.2.3) optionalDependencies: '@types/react': 19.2.11 '@types/react-dom': 19.2.3(@types/react@19.2.11) @@ -12439,15 +12231,15 @@ snapshots: optionalDependencies: '@types/react': 19.2.11 - '@radix-ui/react-dismissable-layer@1.1.11(@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)': + '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)': dependencies: '@radix-ui/primitive': 1.1.3 '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.11)(react@19.2.3) - '@radix-ui/react-primitive': 2.1.3(@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) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3) '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.11)(react@19.2.3) '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.11)(react@19.2.3) react: 19.2.3 - react-dom: 19.2.0(react@19.2.3) + react-dom: 19.2.4(react@19.2.3) optionalDependencies: '@types/react': 19.2.11 '@types/react-dom': 19.2.3(@types/react@19.2.11) @@ -12458,13 +12250,13 @@ snapshots: optionalDependencies: '@types/react': 19.2.11 - '@radix-ui/react-focus-scope@1.1.7(@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)': + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)': dependencies: '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.11)(react@19.2.3) - '@radix-ui/react-primitive': 2.1.3(@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) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3) '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.11)(react@19.2.3) react: 19.2.3 - react-dom: 19.2.0(react@19.2.3) + react-dom: 19.2.4(react@19.2.3) optionalDependencies: '@types/react': 19.2.11 '@types/react-dom': 19.2.3(@types/react@19.2.11) @@ -12476,72 +12268,72 @@ snapshots: optionalDependencies: '@types/react': 19.2.11 - '@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)': + '@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.4(react@19.2.3))(react@19.2.3)': dependencies: '@radix-ui/primitive': 1.1.3 '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.11)(react@19.2.3) '@radix-ui/react-context': 1.1.2(@types/react@19.2.11)(react@19.2.3) - '@radix-ui/react-dismissable-layer': 1.1.11(@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) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3) '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.11)(react@19.2.3) - '@radix-ui/react-focus-scope': 1.1.7(@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) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3) '@radix-ui/react-id': 1.1.1(@types/react@19.2.11)(react@19.2.3) - '@radix-ui/react-popper': 1.2.8(@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) - '@radix-ui/react-portal': 1.1.9(@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) - '@radix-ui/react-presence': 1.1.5(@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) - '@radix-ui/react-primitive': 2.1.3(@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) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3) '@radix-ui/react-slot': 1.2.3(@types/react@19.2.11)(react@19.2.3) '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.11)(react@19.2.3) aria-hidden: 1.2.6 react: 19.2.3 - react-dom: 19.2.0(react@19.2.3) + react-dom: 19.2.4(react@19.2.3) react-remove-scroll: 2.7.2(@types/react@19.2.11)(react@19.2.3) optionalDependencies: '@types/react': 19.2.11 '@types/react-dom': 19.2.3(@types/react@19.2.11) - '@radix-ui/react-popper@1.2.8(@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)': + '@radix-ui/react-popper@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)': dependencies: - '@floating-ui/react-dom': 2.1.7(react-dom@19.2.0(react@19.2.3))(react@19.2.3) - '@radix-ui/react-arrow': 1.1.7(@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) + '@floating-ui/react-dom': 2.1.7(react-dom@19.2.4(react@19.2.3))(react@19.2.3) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3) '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.11)(react@19.2.3) '@radix-ui/react-context': 1.1.2(@types/react@19.2.11)(react@19.2.3) - '@radix-ui/react-primitive': 2.1.3(@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) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3) '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.11)(react@19.2.3) '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.11)(react@19.2.3) '@radix-ui/react-use-rect': 1.1.1(@types/react@19.2.11)(react@19.2.3) '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.11)(react@19.2.3) '@radix-ui/rect': 1.1.1 react: 19.2.3 - react-dom: 19.2.0(react@19.2.3) + react-dom: 19.2.4(react@19.2.3) optionalDependencies: '@types/react': 19.2.11 '@types/react-dom': 19.2.3(@types/react@19.2.11) - '@radix-ui/react-portal@1.1.9(@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)': + '@radix-ui/react-portal@1.1.9(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@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) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3) '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.11)(react@19.2.3) react: 19.2.3 - react-dom: 19.2.0(react@19.2.3) + react-dom: 19.2.4(react@19.2.3) optionalDependencies: '@types/react': 19.2.11 '@types/react-dom': 19.2.3(@types/react@19.2.11) - '@radix-ui/react-presence@1.1.5(@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)': + '@radix-ui/react-presence@1.1.5(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)': dependencies: '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.11)(react@19.2.3) '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.11)(react@19.2.3) react: 19.2.3 - react-dom: 19.2.0(react@19.2.3) + react-dom: 19.2.4(react@19.2.3) optionalDependencies: '@types/react': 19.2.11 '@types/react-dom': 19.2.3(@types/react@19.2.11) - '@radix-ui/react-primitive@2.1.3(@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)': + '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)': dependencies: '@radix-ui/react-slot': 1.2.3(@types/react@19.2.11)(react@19.2.3) react: 19.2.3 - react-dom: 19.2.0(react@19.2.3) + react-dom: 19.2.4(react@19.2.3) optionalDependencies: '@types/react': 19.2.11 '@types/react-dom': 19.2.3(@types/react@19.2.11) @@ -12710,7 +12502,6 @@ snapshots: semver: 7.5.4 optionalDependencies: '@types/node': 22.19.2 - optional: true '@rushstack/node-core-library@5.19.1(@types/node@22.19.8)': dependencies: @@ -12728,7 +12519,6 @@ snapshots: '@rushstack/problem-matcher@0.1.1(@types/node@22.19.2)': optionalDependencies: '@types/node': 22.19.2 - optional: true '@rushstack/problem-matcher@0.1.1(@types/node@22.19.8)': optionalDependencies: @@ -12746,7 +12536,6 @@ snapshots: supports-color: 8.1.1 optionalDependencies: '@types/node': 22.19.2 - optional: true '@rushstack/terminal@0.21.0(@types/node@22.19.8)': dependencies: @@ -12764,7 +12553,6 @@ snapshots: string-argv: 0.3.2 transitivePeerDependencies: - '@types/node' - optional: true '@rushstack/ts-command-line@5.2.0(@types/node@22.19.8)': dependencies: @@ -13119,12 +12907,12 @@ snapshots: picocolors: 1.1.1 redent: 3.0.0 - '@testing-library/react@16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@testing-library/react@16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@babel/runtime': 7.28.6 '@testing-library/dom': 10.4.1 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: '@types/react': 19.2.11 '@types/react-dom': 19.2.3(@types/react@19.2.11) @@ -13182,7 +12970,7 @@ snapshots: '@types/conventional-commits-parser@5.0.2': dependencies: - '@types/node': 22.19.2 + '@types/node': 22.19.8 '@types/cookie@0.4.1': {} @@ -13281,7 +13069,7 @@ snapshots: '@types/responselike@1.0.0': dependencies: - '@types/node': 22.19.2 + '@types/node': 22.19.8 '@types/supports-color@8.1.3': {} @@ -13628,6 +13416,18 @@ snapshots: lodash: 4.17.21 minimatch: 7.4.6 + '@vitejs/plugin-react@5.1.3(vite@7.3.1(@types/node@22.19.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0) + '@rolldown/pluginutils': 1.0.0-rc.2 + '@types/babel__core': 7.20.5 + react-refresh: 0.18.0 + vite: 7.3.1(@types/node@22.19.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - supports-color + '@vitejs/plugin-react@5.1.3(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@babel/core': 7.29.0 @@ -13679,21 +13479,21 @@ snapshots: chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@6.4.1(@types/node@22.19.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/mocker@3.2.4(vite@7.3.1(@types/node@22.19.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 6.4.1(@types/node@22.19.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@22.19.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) - '@vitest/mocker@3.2.4(vite@6.4.1(@types/node@22.19.8)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/mocker@3.2.4(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 6.4.1(@types/node@22.19.8)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@22.19.8)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) '@vitest/pretty-format@3.2.4': dependencies: @@ -14434,7 +14234,7 @@ snapshots: bun-types@1.3.8: dependencies: - '@types/node': 22.19.2 + '@types/node': 22.19.8 bundle-name@4.1.0: dependencies: @@ -15488,35 +15288,6 @@ snapshots: '@esbuild/win32-ia32': 0.19.12 '@esbuild/win32-x64': 0.19.12 - esbuild@0.25.12: - optionalDependencies: - '@esbuild/aix-ppc64': 0.25.12 - '@esbuild/android-arm': 0.25.12 - '@esbuild/android-arm64': 0.25.12 - '@esbuild/android-x64': 0.25.12 - '@esbuild/darwin-arm64': 0.25.12 - '@esbuild/darwin-x64': 0.25.12 - '@esbuild/freebsd-arm64': 0.25.12 - '@esbuild/freebsd-x64': 0.25.12 - '@esbuild/linux-arm': 0.25.12 - '@esbuild/linux-arm64': 0.25.12 - '@esbuild/linux-ia32': 0.25.12 - '@esbuild/linux-loong64': 0.25.12 - '@esbuild/linux-mips64el': 0.25.12 - '@esbuild/linux-ppc64': 0.25.12 - '@esbuild/linux-riscv64': 0.25.12 - '@esbuild/linux-s390x': 0.25.12 - '@esbuild/linux-x64': 0.25.12 - '@esbuild/netbsd-arm64': 0.25.12 - '@esbuild/netbsd-x64': 0.25.12 - '@esbuild/openbsd-arm64': 0.25.12 - '@esbuild/openbsd-x64': 0.25.12 - '@esbuild/openharmony-arm64': 0.25.12 - '@esbuild/sunos-x64': 0.25.12 - '@esbuild/win32-arm64': 0.25.12 - '@esbuild/win32-ia32': 0.25.12 - '@esbuild/win32-x64': 0.25.12 - esbuild@0.27.2: optionalDependencies: '@esbuild/aix-ppc64': 0.27.2 @@ -18650,9 +18421,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.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.4(react@19.2.3))(react@19.2.3))(@types/node@22.19.8)(@types/react@19.2.11)(react-dom@19.2.4(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.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.4(react@19.2.3))(react@19.2.3))(@types/node@22.19.8)(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(typescript@5.9.3) transitivePeerDependencies: - '@radix-ui/react-popover' - '@types/node' @@ -18744,13 +18515,13 @@ snapshots: netmask@2.0.2: {} - next-mdx-remote-client@1.1.4(@types/react@19.2.11)(react-dom@19.2.0(react@19.2.3))(react@19.2.3)(unified@11.0.5): + next-mdx-remote-client@1.1.4(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(unified@11.0.5): dependencies: '@babel/code-frame': 7.29.0 '@mdx-js/mdx': 3.1.1 '@mdx-js/react': 3.1.1(@types/react@19.2.11)(react@19.2.3) react: 19.2.3 - react-dom: 19.2.0(react@19.2.3) + react-dom: 19.2.4(react@19.2.3) remark-mdx-remove-esm: 1.2.2(unified@11.0.5) serialize-error: 12.0.0 vfile: 6.0.3 @@ -19725,14 +19496,14 @@ snapshots: minimist: 1.2.8 strip-json-comments: 2.0.1 - react-dom@19.2.0(react@19.2.0): + react-dom@19.2.4(react@19.2.3): dependencies: - react: 19.2.0 + react: 19.2.3 scheduler: 0.27.0 - react-dom@19.2.0(react@19.2.3): + react-dom@19.2.4(react@19.2.4): dependencies: - react: 19.2.3 + react: 19.2.4 scheduler: 0.27.0 react-is@16.13.1: {} @@ -19773,10 +19544,10 @@ snapshots: optionalDependencies: '@types/react': 19.2.11 - react@19.2.0: {} - react@19.2.3: {} + react@19.2.4: {} + read-cache@1.0.0: dependencies: pify: 2.3.0 @@ -20894,6 +20665,29 @@ snapshots: make-asynchronous: 1.0.1 time-span: 5.1.0 + superdoc@1.10.0(@hocuspocus/provider@2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(canvas@3.2.0)(pdfjs-dist@4.3.136)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19): + dependencies: + '@hocuspocus/provider': 2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19) + buffer-crc32: 1.0.0 + eventemitter3: 5.0.4 + jsdom: 27.3.0(canvas@3.2.0) + naive-ui: 2.43.2(vue@3.5.25(typescript@5.9.3)) + pdfjs-dist: 4.3.136 + pinia: 2.3.1(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3)) + rollup-plugin-copy: 3.5.0 + uuid: 9.0.1 + vue: 3.5.25(typescript@5.9.3) + y-prosemirror: 1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19) + y-websocket: 3.0.0(yjs@13.6.19) + yjs: 13.6.19 + transitivePeerDependencies: + - '@vue/composition-api' + - bufferutil + - canvas + - supports-color + - typescript + - utf-8-validate + supports-color@5.5.0: dependencies: has-flag: 3.0.0 @@ -21690,7 +21484,7 @@ snapshots: debug: 4.4.3(supports-color@5.5.0) es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.4.1(@types/node@22.19.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@22.19.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - '@types/node' - jiti @@ -21711,7 +21505,7 @@ snapshots: debug: 4.4.3(supports-color@5.5.0) es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.4.1(@types/node@22.19.8)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@22.19.8)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - '@types/node' - jiti @@ -21726,6 +21520,25 @@ snapshots: - tsx - yaml + vite-plugin-dts@4.5.4(@types/node@22.19.2)(rollup@4.57.1)(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)): + dependencies: + '@microsoft/api-extractor': 7.56.1(@types/node@22.19.2) + '@rollup/pluginutils': 5.3.0(rollup@4.57.1) + '@volar/typescript': 2.4.28 + '@vue/language-core': 2.2.0(typescript@5.9.3) + compare-versions: 6.1.1 + debug: 4.4.3(supports-color@5.5.0) + kolorist: 1.8.0 + local-pkg: 1.1.2 + magic-string: 0.30.21 + typescript: 5.9.3 + optionalDependencies: + vite: 7.3.1(@types/node@22.19.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - '@types/node' + - rollup + - supports-color + vite-plugin-dts@4.5.4(@types/node@22.19.8)(rollup@4.57.1)(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)): dependencies: '@microsoft/api-extractor': 7.56.1(@types/node@22.19.8) @@ -21761,36 +21574,6 @@ snapshots: transitivePeerDependencies: - rollup - vite@6.4.1(@types/node@22.19.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2): - dependencies: - esbuild: 0.25.12 - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 - postcss: 8.5.6 - rollup: 4.57.1 - tinyglobby: 0.2.15 - optionalDependencies: - '@types/node': 22.19.2 - fsevents: 2.3.3 - jiti: 2.6.1 - tsx: 4.21.0 - yaml: 2.8.2 - - vite@6.4.1(@types/node@22.19.8)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2): - dependencies: - esbuild: 0.25.12 - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 - postcss: 8.5.6 - rollup: 4.57.1 - tinyglobby: 0.2.15 - optionalDependencies: - '@types/node': 22.19.8 - fsevents: 2.3.3 - jiti: 2.6.1 - tsx: 4.21.0 - yaml: 2.8.2 - vite@7.3.1(@types/node@22.19.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2): dependencies: esbuild: 0.27.2 @@ -21825,7 +21608,7 @@ snapshots: dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@6.4.1(@types/node@22.19.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/mocker': 3.2.4(vite@7.3.1(@types/node@22.19.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -21843,7 +21626,7 @@ snapshots: tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 6.4.1(@types/node@22.19.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@22.19.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) vite-node: 3.2.4(@types/node@22.19.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) why-is-node-running: 2.3.0 optionalDependencies: @@ -21869,7 +21652,7 @@ snapshots: dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@6.4.1(@types/node@22.19.8)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/mocker': 3.2.4(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -21887,7 +21670,7 @@ snapshots: tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 6.4.1(@types/node@22.19.8)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@22.19.8)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) vite-node: 3.2.4(@types/node@22.19.8)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) why-is-node-running: 2.3.0 optionalDependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index e0eedf053b..e4174d3e12 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -4,6 +4,7 @@ packages: - apps/* - packages/**/* - shared/* + - examples/* catalog: '@commitlint/cli': ^19.8.1 @@ -76,8 +77,8 @@ catalog: prosemirror-test-builder: ^1.1.1 prosemirror-transform: ^1.9.0 prosemirror-view: ^1.33.8 - react: 19.2.0 - react-dom: 19.2.0 + react: 19.2.4 + react-dom: 19.2.4 rehype-parse: ^9.0.1 rehype-remark: ^10.0.1 remark-gfm: ^4.0.1