-
Notifications
You must be signed in to change notification settings - Fork 63
feat(react): add @superdoc-dev/react wrapper package #1912
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
af17227 to
9eec016
Compare
caio-pizzol
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good start!
the whole point of the React package is to provide the best DX as possible to (react) developers starting with SuperDoc - so let's make sure we nail the basics and keep it simple.
Add first-party React wrapper for SuperDoc with component-based API, proper lifecycle management, SSR safety, and React Strict Mode compatibility. Package features: - SuperDocEditor component with TypeScript support - Full ref API exposing all SuperDoc methods - Dynamic import for SSR safety - Loading state via renderLoading prop - Auto-rebuild on document prop change - Imperative mode switching via setDocumentMode() Key decisions: - superdoc as dependency (not peer) for simpler imports - CSS re-exported via @superdoc/react/style.css - React 16.8+ compatible (useRef for ID generation) - Tests use real superdoc (no mocks)
- Replace manual SuperDoc setup with SuperDocEditor component - Simplify imports to only use @superdoc/react - Add props reference table - Add ref methods reference table - Update SSR section with automatic handling - Remove custom hook section (no longer needed) - Update example links to new repo
This commit addresses layout issues in the React wrapper example where
the Events and HTML Export sidebars would overlap with the editor
content on smaller screen sizes.
Changes:
1. Split-view layout improvements:
- Changed editor-side from `flex: 1` to `flex: 1 1 400px` with
min-width: 300px for proper flex basis
- Changed sidebars from fixed width (280px) to flexible sizing:
`flex: 0 0 240px` with min-width: 200px and max-width: 300px
- Added flex-wrap: wrap to allow stacking on narrow screens
2. Mobile/narrow screen support (< 700px):
- Sidebar stacks below the editor instead of side-by-side
- Editor gets border-bottom instead of border-right
- Sidebar gets full width with border-top separator
3. Panel header/controls improvements:
- Added flex-wrap: wrap to panel-header for wrapping controls
- Added min-height: fit-content to prevent content clipping
- Added flex-wrap: wrap to panel-controls for button wrapping
4. Toolbar responsiveness:
- Made toolbar container horizontally scrollable
5. General responsive adjustments:
- At 900px: Reduced tab padding, font sizes, and control sizes
- At 600px: Further reductions for very small screens including
stacked event items and smaller badges
Documentation improvements following MDXEditor/Remotion patterns: README.md (root): - Added React quick start section with code example - Restructured Basic Usage into React and Vanilla JS sections packages/react/README.md: - Complete rewrite with concept-first methodology - Added Core Concepts section (modes, roles, component lifecycle) - Expanded Props Reference with categorized tables - Added Common Patterns section with real-world examples - Added Framework Integration (Next.js App/Pages Router) - Added Troubleshooting section packages/react/CLAUDE.md (new): - Architecture overview with ASCII diagram - Quick navigation table for key files - Implementation details (SSR safety, stable IDs, etc.) - Props → SuperDoc config mapping - Common tasks guide .claude/rules/ (new): - git-commits.md: Commit message format, no AI attribution rule - react-wrapper.md: React package development patterns - documentation.md: README vs CLAUDE.md standards - coding-standards.md: TypeScript, React, CSS conventions CLAUDE.md (root): - Added react package to project structure - Added React to "Where to Look" table - Added Framework Wrappers section - Reference to detailed git rules
React documentation (react.mdx): - Added Core Concepts section (component lifecycle, modes, roles) - Added Working with Refs section with method reference table - Added Common Patterns section (file upload, document switching, etc.) - Added TypeScript Support section with exported types - Added Framework Integration section (Next.js App/Pages Router, Vite) - Added Advanced Features section (collaboration, AI, search) - Added Troubleshooting section - Added Requirements table - Used MDXEditor/Remotion-style structure with Tips, Notes, CardGroups Next.js documentation (nextjs.mdx): - Updated to recommend @superdoc/react as primary approach - Added App Router and Pages Router examples - Added Complete Example with file upload and export - Added API Route examples for both routers - Added Authentication example with next-auth - Added CSS import guidance - Moved vanilla JS approach to Alternative section - Added CardGroup navigation to related docs
- Extract types from superdoc constructor (no duplication)
- Simplify ref API to just getInstance()
- Replace tsup with Vite for building
- Add hideToolbar prop (replaces boolean toolbar)
- Clean up unused code and simplify docs
- Fix React version mismatch (19.2.4)
- Add examples/* to pnpm workspace
BREAKING CHANGE: toolbar={false} replaced with hideToolbar prop
- Fix ref API in nextjs.mdx (add missing getInstance() calls) - Fix installation instructions in README (superdoc is a dependency) - Remove dead .claude/rules reference from CLAUDE.md - Fix example to use imperative mode switching (not prop-based) - Remove undocumented generateId export from public API - Add clarifying comment about dependency array behavior
The component handles documentMode prop changes efficiently by calling setDocumentMode() internally - no full rebuild occurs. Updated docs and example to show the simpler prop-based pattern.
The component now returns null (or renderLoading) on server and only renders after client-side hydration. This is the correct approach since SuperDoc requires browser APIs. - Added isClient state with useEffect to detect client - Return loading/null on server, full component on client - Fixed misleading comment in utils.ts about SSR
- Document optional `id` prop in README and react.mdx - Clarify component is client-only, not SSR-compatible - Update Tip to explain prop-based documentMode changes work without rebuild - Change nextjs.mdx example to use prop-based mode switching - Add "Props That Trigger Rebuild" section - Fix "bundled" wording to "included"
- Update react example to use SuperDocEditor component - Remove manual lifecycle management (DocumentEditor.jsx) - Rename typescript example to react-typescript - Move react-wrapper example to getting-started/react-typescript
809d288 to
7c333a6
Compare
# Conflicts: # pnpm-lock.yaml
… main These files were accidentally modified during the react-wrapper work.
New TypeScript example demonstrating @superdoc/react integration: - Proper .tsx files with full type safety - SuperDocRef and DocumentMode types usage - Typed event handlers and callbacks - Mode switching (editing/suggesting/viewing) - Export and getHTML via ref API - Loading states with renderLoading - User information
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cba407d124
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
🎉 This PR is included in @superdoc-dev/react v1.0.0-canary.5 The release is available on GitHub release |
…examples - Update CI workflow filters to use @superdoc-dev/react - Update style.css comment to reflect new package name - Consolidate react-with-typescript example into react example - Convert react example from JSX to TypeScript
|
🎉 This PR is included in @superdoc-dev/react v1.0.0-canary.6 The release is available on GitHub release |
- Replace fixed 100ms delay with waitFor predicate in test for more reliable CI - Document which props trigger rebuilds vs initial-only in README - Note: StrictMode is already enabled in the example (main.tsx)
|
🎉 This PR is included in @superdoc-dev/react v1.0.0-canary.7 The release is available on GitHub release |
90d7b76 to
3b9891b
Compare
…ards" This reverts commit 3b9891b.
- Remove temporary feat/react-wrapper branch from release config - Fix example links to point to correct directories (react, nextjs-ssr) - Add Next.js example link to documentation - Document hideToolbar as rebuild trigger - Fix README path in example - Use proper TypeScript event types instead of any - Add error state UI when initialization fails - Add containerId/toolbarId to effect dependencies - Define CallbacksType to reduce code duplication
Demonstrates @superdoc-dev/react integration with Next.js App Router: - Client-side dynamic import with ssr: false - TypeScript support - Basic editor setup
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 55 out of 68 changed files in this pull request and generated 5 comments.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Capture the current documentMode for this effect run | ||
| const effectDocumentMode = initialDocumentModeRef.current; | ||
| initialDocumentModeRef.current = documentMode; | ||
|
|
Copilot
AI
Feb 4, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
effectDocumentMode is taken from initialDocumentModeRef.current, but that ref is only updated inside this rebuild effect (which does not depend on documentMode). If documentMode changes without a rebuild and later a rebuild is triggered (e.g., document changes), the new SuperDoc instance can be initialized with a stale mode. Use the current documentMode value for this effect run (or update the ref in a separate useEffect that depends on documentMode).
| // 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: effectDocumentMode, |
Copilot
AI
Feb 4, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The wrapper always injects its own toolbar selector when hideToolbar is false, which will override a user-provided toolbar prop even though SuperDocConfig supports custom toolbars. Either (1) only set toolbar when the caller did not provide one, or (2) omit toolbar from the exposed props / document that toolbar is managed internally.
| /** | ||
| * @superdoc-dev/react - Official React wrapper for SuperDoc | ||
| * @packageDocumentation | ||
| * @version 1.0.0 | ||
| */ |
Copilot
AI
Feb 4, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The @version 1.0.0 tag in the package documentation header doesn’t match package.json version (0.1.0). This can confuse users and tooling that surfaces TSDoc headers; update the tag to match the package version or remove it.
| "react": "19.2.3", | ||
| "react-dom": "19.2.3" |
Copilot
AI
Feb 4, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This example pins react/react-dom to 19.2.3 while the workspace catalog was bumped to 19.2.4, which can lead to multiple React copies in the monorepo install and confusing hook/type issues. Prefer aligning to the workspace version (e.g., catalog: or the same 19.2.4 range) unless there’s a specific reason to stay on 19.2.3.
| "react": "19.2.3", | |
| "react-dom": "19.2.3" | |
| "react": "workspace:*", | |
| "react-dom": "workspace:*" |
| const handleReady = ({ superdoc }: { superdoc: any }) => { | ||
| console.log('SuperDoc ready'); | ||
| }; |
Copilot
AI
Feb 4, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the TypeScript example, handleReady uses { superdoc: any }, which undermines the “full TypeScript support” claim. Consider using the exported SuperDocReadyEvent (or SuperDocInstance) type for the callback parameter instead of any.
Summary
Adds
@superdoc-dev/react- a first-party React wrapper for SuperDoc with proper lifecycle management, SSR safety, and React Strict Mode compatibility.Closes SD-1716
Key Design Decisions
superdoc(no duplication)getInstance()method@superdoc-dev/react/style.cssuseReffor ID generation)renderLoadingif provided, otherwise null)Package Structure
Usage
Props
All props from
SuperDocConfigare supported, plus React-specific props:documentFile | Blob | string | objectdocumentMode'editing' | 'viewing' | 'suggesting''editing'role'editor' | 'viewer' | 'suggester''editor'idstringuser{ name, email?, image? }usersArray<{ name, email, image? }>modulesobjecthideToolbarbooleanfalserenderLoading() => ReactNodeclassNamestringstyleCSSPropertiesProps That Trigger Rebuild
documentuserusersmodulesrolehideToolbarOther props like
documentModeand callbacks are handled efficiently without rebuild.Ref API
Examples
examples/getting-started/reactexamples/integrations/nextjs-ssrRun examples from repo root:
Documentation Updated
apps/docs/getting-started/frameworks/react.mdx- Full React integration guideapps/docs/getting-started/frameworks/nextjs.mdx- Next.js integration guidepackages/react/README.md- Package READMEpackages/react/CLAUDE.md- Implementation details for AI assistantsTest Plan
pnpm --filter @superdoc-dev/react buildsucceedspnpm --filter @superdoc-dev/react testpasses (14 tests)