@editora/plugins 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ajay Kumar
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,559 @@
1
+ # @editora/plugins
2
+
3
+ Comprehensive plugin collection for Editora Rich Text Editor with 40+ plugins for text formatting, media management, accessibility, and more.
4
+
5
+ ## 📦 Installation
6
+
7
+ ```bash
8
+ npm install @editora/plugins @editora/core
9
+ ```
10
+
11
+ ## 🎯 Overview
12
+
13
+ This package provides a complete set of plugins for building feature-rich text editors. Each plugin is modular, tree-shakeable, and can be used independently.
14
+
15
+ ## ✨ Plugin Categories
16
+
17
+ ### Text Formatting (12 plugins)
18
+ - Bold, Italic, Underline, Strikethrough
19
+ - Font Family, Font Size, Text Color, Background Color
20
+ - Subscript, Superscript, Code Inline
21
+ - Clear Formatting
22
+
23
+ ### Block Elements (8 plugins)
24
+ - Headings (H1-H6)
25
+ - Paragraphs
26
+ - Blockquotes
27
+ - Code Blocks with syntax highlighting
28
+ - Horizontal Rules
29
+ - Page Breaks
30
+ - Preformatted Text
31
+ - Footnotes
32
+
33
+ ### Lists & Structure (5 plugins)
34
+ - Bullet Lists
35
+ - Numbered Lists
36
+ - Checklists
37
+ - Indent/Outdent
38
+ - Text Alignment (Left, Center, Right, Justify)
39
+
40
+ ### Media & Embeds (6 plugins)
41
+ - Images with upload
42
+ - Videos
43
+ - Audio
44
+ - Embed IFrames
45
+ - Media Manager
46
+ - Special Characters & Emojis
47
+
48
+ ### Advanced Features (10 plugins)
49
+ - Tables (full editing capabilities)
50
+ - Math Equations (LaTeX support)
51
+ - Merge Tags / Templates
52
+ - Comments & Annotations
53
+ - Document Manager (import/export)
54
+ - Spell Checker
55
+ - Accessibility Checker
56
+ - Link Management
57
+ - Anchor Links
58
+ - Print Preview
59
+
60
+ ### Utilities (4 plugins)
61
+ - History (Undo/Redo)
62
+ - Fullscreen Mode
63
+ - Line Height
64
+ - Text Direction (LTR/RTL)
65
+ - Capitalization (uppercase, lowercase, title case)
66
+
67
+ ## 🚀 Quick Start
68
+
69
+ ### Basic Formatting
70
+
71
+ ```typescript
72
+ import {
73
+ createBoldPlugin,
74
+ createItalicPlugin,
75
+ createUnderlinePlugin,
76
+ createStrikethroughPlugin
77
+ } from '@editora/plugins';
78
+
79
+ const plugins = [
80
+ createBoldPlugin(),
81
+ createItalicPlugin(),
82
+ createUnderlinePlugin(),
83
+ createStrikethroughPlugin()
84
+ ];
85
+ ```
86
+
87
+ ### Complete Editor Setup
88
+
89
+ ```typescript
90
+ import {
91
+ // Text formatting
92
+ createBoldPlugin,
93
+ createItalicPlugin,
94
+ createUnderlinePlugin,
95
+ createFontFamilyPlugin,
96
+ createFontSizePlugin,
97
+ createTextColorPlugin,
98
+ createBackgroundColorPlugin,
99
+
100
+ // Block elements
101
+ createHeadingPlugin,
102
+ createParagraphPlugin,
103
+ createBlockquotePlugin,
104
+ createCodeSamplePlugin,
105
+
106
+ // Lists
107
+ createListPlugin,
108
+ createChecklistPlugin,
109
+ createIndentPlugin,
110
+ createTextAlignmentPlugin,
111
+
112
+ // Media
113
+ createImagePlugin,
114
+ createLinkPlugin,
115
+ createTablePlugin,
116
+
117
+ // Advanced
118
+ createMathPlugin,
119
+ createCommentsPlugin,
120
+ createHistoryPlugin,
121
+ createFullscreenPlugin,
122
+ createDocumentManagerPlugin
123
+ } from '@editora/plugins';
124
+
125
+ const plugins = [
126
+ // ... initialize all plugins
127
+ ];
128
+ ```
129
+
130
+ ## 📖 Plugin API Reference
131
+
132
+ ### Text Formatting Plugins
133
+
134
+ #### Bold Plugin
135
+ ```typescript
136
+ createBoldPlugin(options?: {
137
+ keyboard?: string; // Default: 'Mod-b'
138
+ icon?: ReactNode;
139
+ className?: string;
140
+ })
141
+ ```
142
+
143
+ #### Font Family Plugin
144
+ ```typescript
145
+ createFontFamilyPlugin(options?: {
146
+ fonts?: Array<{
147
+ name: string;
148
+ value: string;
149
+ fallback?: string;
150
+ }>;
151
+ defaultFont?: string;
152
+ })
153
+
154
+ // Example
155
+ const fontFamilyPlugin = createFontFamilyPlugin({
156
+ fonts: [
157
+ { name: 'Arial', value: 'Arial, sans-serif' },
158
+ { name: 'Times New Roman', value: 'Times New Roman, serif' },
159
+ { name: 'Courier New', value: 'Courier New, monospace' }
160
+ ]
161
+ });
162
+ ```
163
+
164
+ #### Font Size Plugin
165
+ ```typescript
166
+ createFontSizePlugin(options?: {
167
+ sizes?: string[]; // Default: ['8pt', '10pt', '12pt', '14pt', '18pt', '24pt', '36pt']
168
+ defaultSize?: string;
169
+ })
170
+ ```
171
+
172
+ #### Text Color Plugin
173
+ ```typescript
174
+ createTextColorPlugin(options?: {
175
+ colors?: string[];
176
+ customColors?: boolean;
177
+ recentColors?: boolean;
178
+ })
179
+ ```
180
+
181
+ ### Block Element Plugins
182
+
183
+ #### Heading Plugin
184
+ ```typescript
185
+ createHeadingPlugin(options?: {
186
+ levels?: number[]; // Default: [1, 2, 3, 4, 5, 6]
187
+ defaultLevel?: number;
188
+ keyboard?: Record<number, string>;
189
+ })
190
+
191
+ // Example
192
+ const headingPlugin = createHeadingPlugin({
193
+ levels: [1, 2, 3],
194
+ keyboard: {
195
+ 1: 'Mod-Alt-1',
196
+ 2: 'Mod-Alt-2',
197
+ 3: 'Mod-Alt-3'
198
+ }
199
+ });
200
+ ```
201
+
202
+ #### Code Sample Plugin
203
+ ```typescript
204
+ createCodeSamplePlugin(options?: {
205
+ languages?: Array<{
206
+ name: string;
207
+ value: string;
208
+ }>;
209
+ theme?: 'light' | 'dark' | 'github' | 'monokai';
210
+ lineNumbers?: boolean;
211
+ highlightActiveLine?: boolean;
212
+ })
213
+
214
+ // Example
215
+ const codeSamplePlugin = createCodeSamplePlugin({
216
+ languages: [
217
+ { name: 'JavaScript', value: 'javascript' },
218
+ { name: 'TypeScript', value: 'typescript' },
219
+ { name: 'Python', value: 'python' },
220
+ { name: 'HTML', value: 'html' },
221
+ { name: 'CSS', value: 'css' }
222
+ ],
223
+ theme: 'github',
224
+ lineNumbers: true
225
+ });
226
+ ```
227
+
228
+ ### List Plugins
229
+
230
+ #### List Plugin
231
+ ```typescript
232
+ createListPlugin(options?: {
233
+ bulletList?: boolean;
234
+ orderedList?: boolean;
235
+ keyboard?: {
236
+ bullet?: string; // Default: 'Mod-Shift-8'
237
+ ordered?: string; // Default: 'Mod-Shift-7'
238
+ };
239
+ })
240
+ ```
241
+
242
+ #### Checklist Plugin
243
+ ```typescript
244
+ createChecklistPlugin(options?: {
245
+ nested?: boolean;
246
+ keyboard?: string;
247
+ })
248
+ ```
249
+
250
+ ### Media Plugins
251
+
252
+ #### Image Plugin
253
+ ```typescript
254
+ createImagePlugin(options: {
255
+ upload: (file: File) => Promise<string>;
256
+ validate?: (file: File) => boolean;
257
+ maxSize?: number; // bytes
258
+ allowedTypes?: string[];
259
+ resize?: boolean;
260
+ maxWidth?: number;
261
+ maxHeight?: number;
262
+ quality?: number; // 0-1
263
+ })
264
+
265
+ // Example
266
+ const imagePlugin = createImagePlugin({
267
+ upload: async (file) => {
268
+ const formData = new FormData();
269
+ formData.append('image', file);
270
+ const response = await fetch('/api/upload', {
271
+ method: 'POST',
272
+ body: formData
273
+ });
274
+ const data = await response.json();
275
+ return data.url;
276
+ },
277
+ maxSize: 5 * 1024 * 1024, // 5MB
278
+ allowedTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'],
279
+ resize: true,
280
+ maxWidth: 1200,
281
+ quality: 0.9
282
+ });
283
+ ```
284
+
285
+ #### Link Plugin
286
+ ```typescript
287
+ createLinkPlugin(options?: {
288
+ openOnClick?: boolean;
289
+ validate?: (url: string) => boolean;
290
+ onLinkClick?: (url: string) => void;
291
+ targetBlank?: boolean;
292
+ nofollow?: boolean;
293
+ })
294
+
295
+ // Example
296
+ const linkPlugin = createLinkPlugin({
297
+ openOnClick: false,
298
+ validate: (url) => {
299
+ return url.startsWith('http://') || url.startsWith('https://');
300
+ },
301
+ onLinkClick: (url) => {
302
+ window.open(url, '_blank', 'noopener,noreferrer');
303
+ },
304
+ targetBlank: true
305
+ });
306
+ ```
307
+
308
+ ### Advanced Plugins
309
+
310
+ #### Table Plugin
311
+ ```typescript
312
+ createTablePlugin(options?: {
313
+ allowResize?: boolean;
314
+ defaultRows?: number;
315
+ defaultCols?: number;
316
+ maxRows?: number;
317
+ maxCols?: number;
318
+ cellSelection?: boolean;
319
+ headerRow?: boolean;
320
+ })
321
+
322
+ // Example
323
+ const tablePlugin = createTablePlugin({
324
+ allowResize: true,
325
+ defaultRows: 3,
326
+ defaultCols: 3,
327
+ maxRows: 20,
328
+ maxCols: 10,
329
+ cellSelection: true,
330
+ headerRow: true
331
+ });
332
+ ```
333
+
334
+ #### Math Plugin
335
+ ```typescript
336
+ createMathPlugin(options?: {
337
+ engine?: 'katex' | 'mathjax';
338
+ inline?: boolean;
339
+ display?: boolean;
340
+ macros?: Record<string, string>;
341
+ })
342
+
343
+ // Example
344
+ const mathPlugin = createMathPlugin({
345
+ engine: 'katex',
346
+ inline: true,
347
+ display: true,
348
+ macros: {
349
+ '\\R': '\\mathbb{R}',
350
+ '\\N': '\\mathbb{N}'
351
+ }
352
+ });
353
+ ```
354
+
355
+ #### Comments Plugin
356
+ ```typescript
357
+ createCommentsPlugin(options?: {
358
+ onCommentAdd?: (comment: Comment) => void;
359
+ onCommentEdit?: (comment: Comment) => void;
360
+ onCommentDelete?: (commentId: string) => void;
361
+ onCommentResolve?: (commentId: string) => void;
362
+ showResolved?: boolean;
363
+ })
364
+ ```
365
+
366
+ #### Document Manager Plugin
367
+ ```typescript
368
+ createDocumentManagerPlugin(options?: {
369
+ export?: {
370
+ word?: boolean;
371
+ pdf?: boolean;
372
+ html?: boolean;
373
+ markdown?: boolean;
374
+ };
375
+ import?: {
376
+ word?: boolean;
377
+ html?: boolean;
378
+ markdown?: boolean;
379
+ };
380
+ fileName?: string;
381
+ })
382
+
383
+ // Example
384
+ const documentManagerPlugin = createDocumentManagerPlugin({
385
+ export: {
386
+ word: true,
387
+ pdf: true,
388
+ html: true
389
+ },
390
+ fileName: 'document'
391
+ });
392
+ ```
393
+
394
+ #### Spell Check Plugin
395
+ ```typescript
396
+ createSpellCheckPlugin(options?: {
397
+ language?: string; // Default: 'en-US'
398
+ customDictionary?: string[];
399
+ ignoreUppercase?: boolean;
400
+ ignoreNumbers?: boolean;
401
+ })
402
+ ```
403
+
404
+ #### Accessibility Checker Plugin
405
+ ```typescript
406
+ createA11yCheckerPlugin(options?: {
407
+ rules?: string[];
408
+ autoCheck?: boolean;
409
+ severity?: 'error' | 'warning' | 'info';
410
+ })
411
+ ```
412
+
413
+ ### Utility Plugins
414
+
415
+ #### History Plugin
416
+ ```typescript
417
+ createHistoryPlugin(options?: {
418
+ depth?: number; // Default: 100
419
+ keyboard?: {
420
+ undo?: string; // Default: 'Mod-z'
421
+ redo?: string; // Default: 'Mod-Shift-z'
422
+ };
423
+ })
424
+ ```
425
+
426
+ #### Fullscreen Plugin
427
+ ```typescript
428
+ createFullscreenPlugin(options?: {
429
+ keyboard?: string; // Default: 'F11'
430
+ onEnter?: () => void;
431
+ onExit?: () => void;
432
+ })
433
+ ```
434
+
435
+ ## 💡 Usage Examples
436
+
437
+ ### Blog Editor
438
+
439
+ ```typescript
440
+ import {
441
+ createBoldPlugin,
442
+ createItalicPlugin,
443
+ createHeadingPlugin,
444
+ createParagraphPlugin,
445
+ createLinkPlugin,
446
+ createImagePlugin,
447
+ createListPlugin,
448
+ createBlockquotePlugin,
449
+ createHistoryPlugin
450
+ } from '@editora/plugins';
451
+
452
+ const blogPlugins = [
453
+ createBoldPlugin(),
454
+ createItalicPlugin(),
455
+ createHeadingPlugin({ levels: [1, 2, 3] }),
456
+ createParagraphPlugin(),
457
+ createLinkPlugin({ targetBlank: true }),
458
+ createImagePlugin({
459
+ upload: uploadImage,
460
+ maxSize: 2 * 1024 * 1024
461
+ }),
462
+ createListPlugin(),
463
+ createBlockquotePlugin(),
464
+ createHistoryPlugin()
465
+ ];
466
+ ```
467
+
468
+ ### Technical Documentation Editor
469
+
470
+ ```typescript
471
+ import {
472
+ createBoldPlugin,
473
+ createItalicPlugin,
474
+ createCodePlugin,
475
+ createCodeSamplePlugin,
476
+ createHeadingPlugin,
477
+ createTablePlugin,
478
+ createLinkPlugin,
479
+ createAnchorPlugin,
480
+ createMathPlugin,
481
+ createHistoryPlugin
482
+ } from '@editora/plugins';
483
+
484
+ const docsPlugins = [
485
+ createBoldPlugin(),
486
+ createItalicPlugin(),
487
+ createCodePlugin(),
488
+ createCodeSamplePlugin({
489
+ languages: [
490
+ { name: 'JavaScript', value: 'javascript' },
491
+ { name: 'TypeScript', value: 'typescript' },
492
+ { name: 'Python', value: 'python' }
493
+ ],
494
+ lineNumbers: true
495
+ }),
496
+ createHeadingPlugin(),
497
+ createTablePlugin({ headerRow: true }),
498
+ createLinkPlugin(),
499
+ createAnchorPlugin(),
500
+ createMathPlugin({ engine: 'katex' }),
501
+ createHistoryPlugin()
502
+ ];
503
+ ```
504
+
505
+ ### Collaborative Editor
506
+
507
+ ```typescript
508
+ import {
509
+ createBoldPlugin,
510
+ createItalicPlugin,
511
+ createCommentsPlugin,
512
+ createHistoryPlugin,
513
+ createMergeTagPlugin
514
+ } from '@editora/plugins';
515
+
516
+ const collaborativePlugins = [
517
+ createBoldPlugin(),
518
+ createItalicPlugin(),
519
+ createCommentsPlugin({
520
+ onCommentAdd: async (comment) => {
521
+ await saveComment(comment);
522
+ },
523
+ onCommentResolve: async (commentId) => {
524
+ await resolveComment(commentId);
525
+ }
526
+ }),
527
+ createMergeTagPlugin({
528
+ tags: [
529
+ { label: 'First Name', value: '{{firstName}}' },
530
+ { label: 'Last Name', value: '{{lastName}}' },
531
+ { label: 'Email', value: '{{email}}' }
532
+ ]
533
+ }),
534
+ createHistoryPlugin()
535
+ ];
536
+ ```
537
+
538
+ ## 🔧 TypeScript Support
539
+
540
+ All plugins include full TypeScript definitions:
541
+
542
+ ```typescript
543
+ import type { Plugin, PluginConfig } from '@editora/plugins';
544
+
545
+ const customConfig: PluginConfig = {
546
+ // Full type safety
547
+ };
548
+ ```
549
+
550
+ ## 📄 License
551
+
552
+ MIT © [Ajay Kumar](https://github.com/ajaykr089)
553
+
554
+ ## 🔗 Links
555
+
556
+ - [Documentation](https://github.com/ajaykr089/Editora#readme)
557
+ - [GitHub Repository](https://github.com/ajaykr089/Editora)
558
+ - [Issue Tracker](https://github.com/ajaykr089/Editora/issues)
559
+ - [npm Package](https://www.npmjs.com/package/@editora/plugins)
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("./index-CGbrgpa_.js");async function l(i){return new Promise((o,r)=>{const t=new FileReader;t.onload=async e=>{try{const n=e.target?.result,a=await c.mammoth.convertToHtml({arrayBuffer:n});o(a.value)}catch(n){r(new Error(`Failed to import Word document: ${n}`))}},t.onerror=()=>r(new Error("Failed to read file")),t.readAsArrayBuffer(i)})}async function m(i,o="document.docx"){try{const r=c.getApiUrl("exportWord"),t=c.getApiHeaders(),e=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json",...t},body:JSON.stringify({htmlContent:i,filename:o})});if(!e.ok){const a=await e.json();throw new Error(a.error||"Failed to export document")}const n=await e.blob();h(n,o)}catch(r){throw new Error(`Failed to export to Word: ${r}`)}}async function p(i,o="document.pdf",r){try{const t=new c.E({orientation:"portrait",unit:"mm",format:"a4"}),e=20;if(r){const n=await c.html2canvas(r,{scale:2,useCORS:!0,allowTaint:!0}),a=n.toDataURL("image/png"),d=t.internal.pageSize.getWidth()-2*e,s=n.height*d/n.width;t.addImage(a,"PNG",e,e,d,s)}else{const n=u(i).split(`
2
+ `);let a=e;n.forEach(d=>{a>t.internal.pageSize.getHeight()-e&&(t.addPage(),a=e),t.text(d,e,a),a+=7})}t.save(o)}catch(t){throw new Error(`Failed to export to PDF: ${t}`)}}function u(i){const o=document.createElement("div");return o.innerHTML=i,o.textContent||o.innerText||""}function h(i,o){const r=URL.createObjectURL(i),t=document.createElement("a");t.href=r,t.download=o,document.body.appendChild(t),t.click(),document.body.removeChild(t),URL.revokeObjectURL(r)}exports.exportToPdf=p;exports.exportToWord=m;exports.importFromWord=l;
@@ -0,0 +1,77 @@
1
+ import { m as s, g as l, a as m, E as p, h } from "./index-560-K8WX.mjs";
2
+ async function w(i) {
3
+ return new Promise((o, r) => {
4
+ const t = new FileReader();
5
+ t.onload = async (e) => {
6
+ try {
7
+ const n = e.target?.result, a = await s.convertToHtml({ arrayBuffer: n });
8
+ o(a.value);
9
+ } catch (n) {
10
+ r(new Error(`Failed to import Word document: ${n}`));
11
+ }
12
+ }, t.onerror = () => r(new Error("Failed to read file")), t.readAsArrayBuffer(i);
13
+ });
14
+ }
15
+ async function y(i, o = "document.docx") {
16
+ try {
17
+ const r = l("exportWord"), t = m(), e = await fetch(r, {
18
+ method: "POST",
19
+ headers: {
20
+ "Content-Type": "application/json",
21
+ ...t
22
+ },
23
+ body: JSON.stringify({
24
+ htmlContent: i,
25
+ filename: o
26
+ })
27
+ });
28
+ if (!e.ok) {
29
+ const a = await e.json();
30
+ throw new Error(a.error || "Failed to export document");
31
+ }
32
+ const n = await e.blob();
33
+ f(n, o);
34
+ } catch (r) {
35
+ throw new Error(`Failed to export to Word: ${r}`);
36
+ }
37
+ }
38
+ async function x(i, o = "document.pdf", r) {
39
+ try {
40
+ const t = new p({
41
+ orientation: "portrait",
42
+ unit: "mm",
43
+ format: "a4"
44
+ }), e = 20;
45
+ if (r) {
46
+ const n = await h(r, {
47
+ scale: 2,
48
+ useCORS: !0,
49
+ allowTaint: !0
50
+ }), a = n.toDataURL("image/png"), c = t.internal.pageSize.getWidth() - 2 * e, d = n.height * c / n.width;
51
+ t.addImage(a, "PNG", e, e, c, d);
52
+ } else {
53
+ const n = u(i).split(`
54
+ `);
55
+ let a = e;
56
+ n.forEach((c) => {
57
+ a > t.internal.pageSize.getHeight() - e && (t.addPage(), a = e), t.text(c, e, a), a += 7;
58
+ });
59
+ }
60
+ t.save(o);
61
+ } catch (t) {
62
+ throw new Error(`Failed to export to PDF: ${t}`);
63
+ }
64
+ }
65
+ function u(i) {
66
+ const o = document.createElement("div");
67
+ return o.innerHTML = i, o.textContent || o.innerText || "";
68
+ }
69
+ function f(i, o) {
70
+ const r = URL.createObjectURL(i), t = document.createElement("a");
71
+ t.href = r, t.download = o, document.body.appendChild(t), t.click(), document.body.removeChild(t), URL.revokeObjectURL(r);
72
+ }
73
+ export {
74
+ x as exportToPdf,
75
+ y as exportToWord,
76
+ w as importFromWord
77
+ };