{"_id":"@cannyminds/rich-text-editor","_rev":"2-6c1d25ced16ed4b511b2920049c9cc21","name":"@cannyminds/rich-text-editor","dist-tags":{"latest":"0.3.0"},"versions":{"0.1.0":{"name":"@cannyminds/rich-text-editor","version":"0.1.0","keywords":["react","rich-text-editor","tiptap","wysiwyg","editor","track-changes","collaboration","multi-user","history","json-export","document-management","typescript"],"author":{"name":"CannyMinds Dev Team"},"license":"MIT","_id":"@cannyminds/rich-text-editor@0.1.0","maintainers":[{"name":"ganapathy-cm","email":"ganapathy@cannymindstech.com"}],"homepage":"https://github.com/CannyMinds/DMS-Rich-Text-Editor#readme","bugs":{"url":"https://github.com/CannyMinds/DMS-Rich-Text-Editor/issues"},"dist":{"shasum":"9cbe4858a04321742730a5ab4e13285c018741bd","tarball":"https://registry.npmjs.org/@cannyminds/rich-text-editor/-/rich-text-editor-0.1.0.tgz","fileCount":9,"integrity":"sha512-JG6Qi/z1C6OWY0RkC6P5x/2x/AzwmiAkteEbxGexsgJsFpCe4SP9k1unV0aBfOb1N7zim6nCj6+z70nglaendw==","signatures":[{"sig":"MEYCIQCuDBLRhvGHld4+SuXtCXiwjnvHw/nSwiSeWv89mVp5nQIhAK2NzWfNkQ1TUf5+8+2fxaA0K2uB6eZcKmyeNIuzIGsA","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":529692},"main":"./dist/index.cjs","type":"module","_from":"file:cannyminds-rich-text-editor-0.1.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./styles.css":"./dist/styles.css","./dist/styles.css":"./dist/styles.css"},"scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"tsup"},"_npmUser":{"name":"ganapathy-cm","email":"ganapathy@cannymindstech.com"},"_resolved":"C:\\Users\\CODETE~1\\AppData\\Local\\Temp\\afd57474d7a342dc9cc542f71c4f9968\\cannyminds-rich-text-editor-0.1.0.tgz","_integrity":"sha512-JG6Qi/z1C6OWY0RkC6P5x/2x/AzwmiAkteEbxGexsgJsFpCe4SP9k1unV0aBfOb1N7zim6nCj6+z70nglaendw==","repository":{"url":"git+https://github.com/CannyMinds/DMS-Rich-Text-Editor.git","type":"git","directory":"packages/rich-text-editor"},"_npmVersion":"10.2.2","description":"A React Rich Text Editor with multi-user track changes, complete JSON history export, and collaborative editing support. Built on Tiptap.","directories":{},"_nodeVersion":"22.14.0","dependencies":{"@tiptap/pm":"^2.27.1","@tiptap/core":"^2.10.4","@tiptap/react":"^2.10.4","@tiptap/starter-kit":"^2.10.4","@tiptap/extension-link":"^2.10.4","@tiptap/extension-color":"^2.10.4","@tiptap/extension-image":"^2.10.4","@tiptap/extension-table":"^2.10.4","@tiptap/extension-highlight":"^2.10.4","@tiptap/extension-table-row":"^2.10.4","@tiptap/extension-underline":"^2.10.4","@tiptap/extension-table-cell":"^2.10.4","@tiptap/extension-text-align":"^2.10.4","@tiptap/extension-text-style":"^2.10.4","@tiptap/extension-placeholder":"^2.10.4","@tiptap/extension-table-header":"^2.10.4"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.0","typescript":"^5.0.0","@types/node":"^22.0.0","@types/react":"^18.0.0","@types/react-dom":"^18.0.0"},"peerDependencies":{"react":">=16.8.0","react-dom":">=16.8.0"},"_npmOperationalInternal":{"tmp":"tmp/rich-text-editor_0.1.0_1769221070596_0.6139550005619077","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@cannyminds/rich-text-editor","version":"0.3.0","description":"A React Rich Text Editor with multi-user track changes, complete JSON history export, and collaborative editing support. Built on Tiptap.","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./styles.css":"./dist/styles.css","./dist/styles.css":"./dist/styles.css"},"type":"module","scripts":{"build":"tsup","prepublishOnly":"npm run build","test":"echo \"Error: no test specified\" && exit 1"},"keywords":["react","rich-text-editor","tiptap","wysiwyg","editor","track-changes","collaboration","multi-user","history","json-export","document-management","typescript"],"author":{"name":"CannyMinds Dev Team"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/CannyMinds/DMS-Rich-Text-Editor.git","directory":"packages/rich-text-editor"},"packageManager":"pnpm@10.10.0","peerDependencies":{"react":">=16.8.0","react-dom":">=16.8.0"},"dependencies":{"@tiptap/core":"^2.10.4","@tiptap/extension-color":"^2.10.4","@tiptap/extension-highlight":"^2.10.4","@tiptap/extension-image":"^2.10.4","@tiptap/extension-link":"^2.10.4","@tiptap/extension-placeholder":"^2.10.4","@tiptap/extension-table":"^2.10.4","@tiptap/extension-table-cell":"^2.10.4","@tiptap/extension-table-header":"^2.10.4","@tiptap/extension-table-row":"^2.10.4","@tiptap/extension-text-align":"^2.10.4","@tiptap/extension-text-style":"^2.10.4","@tiptap/extension-underline":"^2.10.4","@tiptap/pm":"^2.27.1","@tiptap/react":"^2.10.4","@tiptap/starter-kit":"^2.10.4"},"devDependencies":{"@types/node":"^22.0.0","@types/react":"^18.0.0","@types/react-dom":"^18.0.0","tsup":"^8.5.0","typescript":"^5.0.0"},"publishConfig":{"access":"public"},"_id":"@cannyminds/rich-text-editor@0.3.0","gitHead":"8bf0e62bf46bc62a6f88e2916b5c9a6d50ae8ea5","bugs":{"url":"https://github.com/CannyMinds/DMS-Rich-Text-Editor/issues"},"homepage":"https://github.com/CannyMinds/DMS-Rich-Text-Editor#readme","_nodeVersion":"22.14.0","_npmVersion":"10.2.2","dist":{"integrity":"sha512-5WCPZ2y9+hYYE5TRkGFL0MZmzOP+QxEzJbAOD9wtgtwSNicPRaKjE8ntKpY2Vw1aXiw55ddZdEntcMiPb8+Vmw==","shasum":"e4db6fecba1a4546aa045c2cf0c95096d28e61b4","tarball":"https://registry.npmjs.org/@cannyminds/rich-text-editor/-/rich-text-editor-0.3.0.tgz","fileCount":9,"unpackedSize":529734,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCXo4vkwW9KVPszkHncS5y9mp8151Yb51172XFQjRAkFAIhAOVJsot+3HFc0P+ZS/z6p/OyzHxfqKcDr3nnmg2eyWpe"}]},"_npmUser":{"name":"ganapathy-cm","email":"ganapathy@cannymindstech.com"},"directories":{},"maintainers":[{"name":"ganapathy-cm","email":"ganapathy@cannymindstech.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/rich-text-editor_0.3.0_1769676626086_0.013296366739325771"},"_hasShrinkwrap":false}},"time":{"created":"2026-01-24T02:17:50.536Z","modified":"2026-01-29T08:50:26.381Z","0.1.0":"2026-01-24T02:17:50.769Z","0.3.0":"2026-01-29T08:50:26.271Z"},"bugs":{"url":"https://github.com/CannyMinds/DMS-Rich-Text-Editor/issues"},"author":{"name":"CannyMinds Dev Team"},"license":"MIT","homepage":"https://github.com/CannyMinds/DMS-Rich-Text-Editor#readme","keywords":["react","rich-text-editor","tiptap","wysiwyg","editor","track-changes","collaboration","multi-user","history","json-export","document-management","typescript"],"repository":{"type":"git","url":"git+https://github.com/CannyMinds/DMS-Rich-Text-Editor.git","directory":"packages/rich-text-editor"},"description":"A React Rich Text Editor with multi-user track changes, complete JSON history export, and collaborative editing support. Built on Tiptap.","maintainers":[{"name":"ganapathy-cm","email":"ganapathy@cannymindstech.com"}],"readme":"# @cannyminds/rich-text-editor\r\n\r\nA powerful React Rich Text Editor component built with [Tiptap](https://tiptap.dev/), featuring **multi-user track changes** with complete JSON history export.\r\n\r\n[![npm version](https://badge.fury.io/js/@cannyminds%2Frich-text-editor.svg)](https://www.npmjs.com/package/@cannyminds/rich-text-editor)\r\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\r\n\r\n## ✨ Features\r\n\r\n- 🎨 **Multi-User Track Changes** - Real-time collaborative editing with user-specific highlights\r\n- 📋 **Complete History in JSON** - Export all changes with user attribution and timestamps\r\n- 🛠️ **Headless Architecture** - Full styling control, works with any design system\r\n- ⚛️ **React 16.8+** - Modern hooks-based API with TypeScript support\r\n- 🔌 **Extensible** - Built on Tiptap, use 100+ community extensions\r\n- 📝 **Rich Formatting** - Tables, images, links, code blocks, and more\r\n\r\n---\r\n\r\n## 📦 Installation\r\n\r\n### npm\r\n```bash\r\nnpm install @cannyminds/rich-text-editor\r\n```\r\n\r\n### pnpm\r\n```bash\r\npnpm add @cannyminds/rich-text-editor\r\n```\r\n\r\n### yarn\r\n```bash\r\nyarn add @cannyminds/rich-text-editor\r\n```\r\n\r\n### bun\r\n```bash\r\nbun add @cannyminds/rich-text-editor\r\n```\r\n\r\n### Local Development (Monorepo / Workspaces)\r\n\r\nIf you're developing locally within a monorepo or want to link the package during development:\r\n\r\n**pnpm workspaces:**\r\n```json\r\n// In your consuming package's package.json\r\n{\r\n  \"dependencies\": {\r\n    \"@cannyminds/rich-text-editor\": \"workspace:*\"\r\n  }\r\n}\r\n```\r\n\r\n**npm/yarn link:**\r\n```bash\r\n# In the rich-text-editor package directory\r\nnpm link\r\n\r\n# In your consuming project\r\nnpm link @cannyminds/rich-text-editor\r\n```\r\n\r\n**File reference:**\r\n```json\r\n// In your consuming package's package.json\r\n{\r\n  \"dependencies\": {\r\n    \"@cannyminds/rich-text-editor\": \"file:../packages/rich-text-editor\"\r\n  }\r\n}\r\n```\r\n\r\n---\r\n\r\n## 🚀 Quick Start\r\n\r\n### Basic Usage\r\n\r\n```tsx\r\nimport { RichTextEditor } from '@cannyminds/rich-text-editor';\r\nimport '@cannyminds/rich-text-editor/styles.css';\r\n\r\nfunction App() {\r\n  const [content, setContent] = useState('<p>Hello World!</p>');\r\n\r\n  return (\r\n    <RichTextEditor\r\n      content={content}\r\n      onUpdate={(html) => setContent(html)}\r\n      placeholder=\"Start writing...\"\r\n      showToolbar={true}\r\n      showCharacterCount={true}\r\n    />\r\n  );\r\n}\r\n```\r\n\r\n### With Track Changes\r\n\r\n```tsx\r\nimport { \r\n  RichTextEditor, \r\n  TrackChanges,\r\n  type TrackChangesUser \r\n} from '@cannyminds/rich-text-editor';\r\nimport '@cannyminds/rich-text-editor/styles.css';\r\n\r\nfunction CollaborativeEditor() {\r\n  const [changes, setChanges] = useState<TrackChange[]>([]);\r\n  \r\n  const currentUser: TrackChangesUser = {\r\n    id: 'user-1',\r\n    name: 'John Doe',\r\n    color: '#3B82F6'  // Blue highlights\r\n  };\r\n\r\n  const handleTrackChange = (change: TrackChange) => {\r\n    // Each change is delivered as JSON\r\n    setChanges(prev => [...prev, {\r\n      id: crypto.randomUUID(),\r\n      ...change,\r\n    }]);\r\n  };\r\n\r\n  return (\r\n    <RichTextEditor\r\n      content=\"\"\r\n      extensions={[\r\n        TrackChanges.configure({\r\n          enabled: true,\r\n          currentUser,\r\n          onTrackChange: handleTrackChange,\r\n        })\r\n      ]}\r\n    />\r\n  );\r\n}\r\n```\r\n\r\n---\r\n\r\n## 📊 Track Changes JSON Format\r\n\r\nEvery change is captured in a structured JSON format, perfect for auditing, version control, and collaborative workflows.\r\n\r\n### TrackChange Interface\r\n\r\n```typescript\r\ninterface TrackChange {\r\n  userId: string;                    // User identifier\r\n  userName: string;                  // Display name\r\n  userColor: string;                 // Hex color for highlighting\r\n  text: string;                      // Changed text content\r\n  from: number;                      // Start position in document\r\n  to: number;                        // End position in document\r\n  type: 'insert' | 'delete';         // Type of change\r\n}\r\n```\r\n\r\n### TextChange (Extended Format)\r\n\r\nFor complete history tracking with persistence:\r\n\r\n```typescript\r\ninterface TextChange {\r\n  id: string;                        // Unique change identifier\r\n  userId: string;                    // User ID\r\n  userName: string;                  // User display name\r\n  userColor: string;                 // Hex color (#3B82F6)\r\n  timestamp: number;                 // Unix timestamp (ms)\r\n  startOffset: number;               // Document start position\r\n  endOffset: number;                 // Document end position\r\n  oldText: string;                   // Text before change\r\n  newText: string;                   // Text after change\r\n  type: 'insert' | 'delete' | 'replace';\r\n}\r\n```\r\n\r\n### Example JSON Output\r\n\r\n```json\r\n[\r\n  {\r\n    \"id\": \"change-1705678901234\",\r\n    \"userId\": \"user-1\",\r\n    \"userName\": \"John Doe\",\r\n    \"userColor\": \"#3B82F6\",\r\n    \"timestamp\": 1705678901234,\r\n    \"startOffset\": 0,\r\n    \"endOffset\": 12,\r\n    \"oldText\": \"\",\r\n    \"newText\": \"Hello World!\",\r\n    \"type\": \"insert\"\r\n  },\r\n  {\r\n    \"id\": \"change-1705678905678\",\r\n    \"userId\": \"user-2\", \r\n    \"userName\": \"Jane Smith\",\r\n    \"userColor\": \"#10B981\",\r\n    \"timestamp\": 1705678905678,\r\n    \"startOffset\": 6,\r\n    \"endOffset\": 11,\r\n    \"oldText\": \"World\",\r\n    \"newText\": \"\",\r\n    \"type\": \"delete\"\r\n  }\r\n]\r\n```\r\n\r\n---\r\n\r\n## 🎨 Multi-User Highlighting\r\n\r\nEach user gets a unique color for their changes:\r\n\r\n```tsx\r\nconst users: TrackChangesUser[] = [\r\n  { id: 'user-1', name: 'John Doe', color: '#3B82F6' },     // Blue\r\n  { id: 'user-2', name: 'Jane Smith', color: '#10B981' },   // Green\r\n  { id: 'user-3', name: 'Bob Wilson', color: '#F59E0B' },   // Orange\r\n  { id: 'user-4', name: 'Alice Brown', color: '#8B5CF6' },  // Purple\r\n];\r\n```\r\n\r\n**Visual Indicators:**\r\n- **Insertions**: Background highlight + colored underline\r\n- **Deletions**: Red strikethrough with light red background\r\n- **Tooltips**: Hover to see \"Added by [User] • [Date/Time]\"\r\n\r\n---\r\n\r\n## 🔧 API Reference\r\n\r\n### RichTextEditor Props\r\n\r\n| Prop | Type | Default | Description |\r\n|------|------|---------|-------------|\r\n| `content` | `string` | `''` | Initial HTML content |\r\n| `onUpdate` | `(html: string) => void` | - | Callback on content change |\r\n| `onBlur` | `(html: string) => void` | - | Callback on blur |\r\n| `editable` | `boolean` | `true` | Enable/disable editing |\r\n| `placeholder` | `string` | `'Start writing...'` | Placeholder text |\r\n| `extensions` | `Extension[]` | `[]` | Additional Tiptap extensions |\r\n| `showToolbar` | `boolean` | `true` | Show/hide toolbar |\r\n| `showCharacterCount` | `boolean` | `false` | Show character count |\r\n| `minHeight` | `number \\| string` | `200` | Minimum editor height |\r\n| `maxHeight` | `number \\| string` | - | Maximum editor height |\r\n| `autoFocus` | `boolean` | `false` | Auto-focus on mount |\r\n| `className` | `string` | `''` | Custom container class |\r\n\r\n### TrackChanges Extension Options\r\n\r\n```typescript\r\nTrackChanges.configure({\r\n  enabled: boolean;              // Enable/disable tracking\r\n  currentUser: TrackChangesUser; // Current user info\r\n  onTrackChange: (change) => {}; // Change callback\r\n})\r\n```\r\n\r\n### Editor Commands\r\n\r\n```typescript\r\n// Enable/disable tracking\r\neditor.commands.enableTrackChanges();\r\neditor.commands.disableTrackChanges();\r\n\r\n// Set current user\r\neditor.commands.setTrackChangesUser({\r\n  id: 'user-1',\r\n  name: 'John Doe',\r\n  color: '#3B82F6'\r\n});\r\n```\r\n\r\n---\r\n\r\n## 🎯 Advanced Usage\r\n\r\n### Headless Mode (Custom UI)\r\n\r\n```tsx\r\nimport { useEditor, EditorContent, StarterKit } from '@cannyminds/rich-text-editor';\r\nimport '@cannyminds/rich-text-editor/styles.css';\r\n\r\nfunction CustomEditor() {\r\n  const editor = useEditor({\r\n    extensions: [StarterKit],\r\n    content: '<p>Custom UI</p>',\r\n  });\r\n\r\n  return (\r\n    <div>\r\n      <button onClick={() => editor?.chain().focus().toggleBold().run()}>\r\n        Bold\r\n      </button>\r\n      {/* \r\n        IMPORTANT: Wrap EditorContent in 'rte-content' to apply library styles \r\n        (tables, lists, blockquotes, etc.) \r\n      */}\r\n      <div className=\"rte-content\">\r\n        <EditorContent editor={editor} />\r\n      </div>\r\n    </div>\r\n  );\r\n}\r\n```\r\n\r\n### Export History as JSON\r\n\r\n```tsx\r\n// Get all changes from your state management\r\nconst exportHistory = () => {\r\n  const historyJson = JSON.stringify(changes, null, 2);\r\n  \r\n  // Download as file\r\n  const blob = new Blob([historyJson], { type: 'application/json' });\r\n  const url = URL.createObjectURL(blob);\r\n  const a = document.createElement('a');\r\n  a.href = url;\r\n  a.download = 'document-history.json';\r\n  a.click();\r\n};\r\n```\r\n\r\n### Toggle Highlight Visibility\r\n\r\nUse CSS to show/hide track change highlights:\r\n\r\n```css\r\n/* Hide all highlights */\r\n.hide-highlights .track-change-highlight {\r\n  background: transparent !important;\r\n  border-bottom: none !important;\r\n}\r\n\r\n/* Hide deletions */\r\n.hide-highlights .track-change-delete {\r\n  display: none;\r\n}\r\n```\r\n\r\n---\r\n\r\n## 📚 Exports\r\n\r\n```typescript\r\n// Components\r\nexport { RichTextEditor } from '@cannyminds/rich-text-editor';\r\n\r\n// Extensions\r\nexport { TrackChanges, trackChangesPluginKey } from '@cannyminds/rich-text-editor';\r\nexport { ResizableImage } from '@cannyminds/rich-text-editor';\r\n\r\n// Tiptap Re-exports\r\nexport { useEditor, EditorContent } from '@cannyminds/rich-text-editor';\r\nexport { StarterKit, Table, Link, Image, Highlight } from '@cannyminds/rich-text-editor';\r\n\r\n// Types\r\nexport type { \r\n  TrackChangesUser, \r\n  TrackChangesOptions,\r\n  RichTextEditorProps,\r\n  Editor \r\n} from '@cannyminds/rich-text-editor';\r\n```\r\n\r\n---\r\n\r\n## 🎨 Styling\r\n\r\nImport the default styles:\r\n\r\n```tsx\r\nimport '@cannyminds/rich-text-editor/styles.css';\r\n```\r\n\r\nOr use the dist path:\r\n\r\n```tsx\r\nimport '@cannyminds/rich-text-editor/dist/styles.css';\r\n```\r\n\r\n### CSS Variables (Customization)\r\n\r\n```css\r\n:root {\r\n  --rte-border-color: #e2e8f0;\r\n  --rte-toolbar-bg: #f8fafc;\r\n  --rte-content-bg: #ffffff;\r\n  --rte-focus-ring: #3b82f6;\r\n}\r\n```\r\n\r\n---\r\n\r\n## 📄 License\r\n\r\nMIT © [CannyMinds Dev Team](https://github.com/CannyMinds)\r\n\r\n---\r\n\r\n## 🔗 Links\r\n\r\n- [GitHub Repository](https://github.com/CannyMinds/DMS-Rich-Text-Editor)\r\n- [Demo Application](http://localhost:3007) (Run `pnpm dev` in the project)\r\n- [Tiptap Documentation](https://tiptap.dev/docs)\r\n","readmeFilename":"README.md"}