@regal-text-editor/plugin-table 0.1.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/README.md ADDED
@@ -0,0 +1,883 @@
1
+ # 👑 Regal Text Editor
2
+
3
+ ### A rich text editing engine built from scratch for the modern web.
4
+
5
+ <p align="center">
6
+ <strong>Headless</strong> ·
7
+ <strong>Extensible</strong> ·
8
+ <strong>Framework-Independent</strong> ·
9
+ <strong>React-Ready</strong> ·
10
+ <strong>RTL-Aware</strong> ·
11
+ <strong>Security-Conscious</strong>
12
+ </p>
13
+
14
+ <p align="center">
15
+ <a href="https://regal-text-editor.vercel.app/">Live Demo</a>
16
+ ·
17
+ <a href="https://www.npmjs.com/">NPM</a>
18
+ ·
19
+ <a href="https://github.com/mohammad-mirzaie-gh/regal-text-editor">GitHub</a>
20
+ </p>
21
+
22
+ ---
23
+
24
+ ## ⚡ What is Regal?
25
+
26
+ **Regal Text Editor** is a modular rich text editing engine and toolkit for the web, built completely from scratch.
27
+
28
+ It provides a framework-independent editing core, browser DOM adapter, React bindings, customizable UI components, and a real plugin architecture — distributed as **11 independently installable npm packages**.
29
+
30
+ Regal is **not a wrapper around ProseMirror, Slate, Lexical, TipTap, or CKEditor**.
31
+
32
+ The document model, schema system, transactions, selections, commands, history, serialization, parsing, and browser adapter are all implemented inside this project.
33
+
34
+ > **Rich text, without the black box.**
35
+
36
+ ### 🚀 Try it live
37
+
38
+ **[Open the Regal Text Editor Demo →](https://regal-text-editor.vercel.app/)**
39
+
40
+ The live demo runs the actual published-style React/UI stack in the browser, including the full plugin set.
41
+
42
+ ---
43
+
44
+ ## ✨ Why Regal?
45
+
46
+ Rich text editors often become tightly coupled systems where the editor engine, UI, framework, and features are difficult to separate.
47
+
48
+ Regal takes a different approach.
49
+
50
+ ### 🧠 Built from scratch
51
+
52
+ No dependency on an existing rich-text editing engine.
53
+
54
+ Regal owns its:
55
+
56
+ * Document model
57
+ * Schema system
58
+ * Transactions & operations
59
+ * Selection model
60
+ * Position tracking
61
+ * Command system
62
+ * Normalization
63
+ * Undo / redo history
64
+ * HTML parsing
65
+ * HTML serialization
66
+ * Markdown serialization
67
+ * JSON serialization
68
+ * Plain-text serialization
69
+ * Browser DOM adapter
70
+
71
+ ---
72
+
73
+ ### 🎛️ Headless by default
74
+
75
+ The core engine does not depend on React or the DOM.
76
+
77
+ ```ts
78
+ import { Editor, createBaseSchema } from "@regal-text-editor/core";
79
+
80
+ const editor = new Editor({
81
+ schema: createBaseSchema(),
82
+ plugins: [],
83
+ });
84
+ ```
85
+
86
+ This makes the core suitable for:
87
+
88
+ * Server-side document processing
89
+ * Document validation
90
+ * Format conversion
91
+ * Custom editors
92
+ * Custom rendering environments
93
+ * Framework-independent applications
94
+
95
+ You can use the engine without rendering an editor at all.
96
+
97
+ ---
98
+
99
+ ### 🧩 A real plugin architecture
100
+
101
+ Regal does not treat extensibility as a giant configuration object.
102
+
103
+ Plugins can register:
104
+
105
+ * Nodes
106
+ * Marks
107
+ * Commands
108
+ * Keyboard shortcuts
109
+ * HTML parsers
110
+ * HTML serializers
111
+ * Markdown serializers
112
+ * Editor behavior
113
+
114
+ More importantly, **the built-in features use the same plugin architecture available to consumers**.
115
+
116
+ Bold, headings, lists, links, images, code blocks and history are not privileged features hidden inside the engine.
117
+
118
+ They're plugins.
119
+
120
+ ---
121
+
122
+ ### 🎨 Theme it without CSS-in-JS
123
+
124
+ The UI is built around CSS custom properties.
125
+
126
+ Every major visual token — including colors, spacing, radii and shadows — can be overridden by the host application.
127
+
128
+ No CSS-in-JS.
129
+
130
+ No build-time theme generator.
131
+
132
+ No need to modify package source.
133
+
134
+ Two built-in themes are included:
135
+
136
+ ```html
137
+ <div data-rte-theme="notion">
138
+ ...
139
+ </div>
140
+ ```
141
+
142
+ ```html
143
+ <div data-rte-theme="midnight">
144
+ ...
145
+ </div>
146
+ ```
147
+
148
+ Or create your own theme by overriding the same CSS variables.
149
+
150
+ ---
151
+
152
+ ### ↔️ RTL-aware by construction
153
+
154
+ RTL is not implemented as a separate visual mode.
155
+
156
+ Regal uses logical CSS properties and logical alignment values:
157
+
158
+ ```ts
159
+ setTextAlign("start");
160
+ setTextAlign("center");
161
+ setTextAlign("end");
162
+ setTextAlign("justify");
163
+ ```
164
+
165
+ rather than hard-coded physical directions such as `left` and `right`.
166
+
167
+ This allows the editor UI and text alignment to behave naturally under:
168
+
169
+ ```html
170
+ <div dir="rtl">
171
+ ```
172
+
173
+ > Dedicated bidi-cursor testing is still planned.
174
+
175
+ ---
176
+
177
+ ### 🔐 Security-conscious by default
178
+
179
+ Rich text editors process untrusted HTML and URLs.
180
+
181
+ Regal treats sanitization as an editing boundary concern.
182
+
183
+ URLs are validated through an allow-list that accepts:
184
+
185
+ ```text
186
+ http:
187
+ https:
188
+ mailto:
189
+ tel:
190
+ relative URLs
191
+ ```
192
+
193
+ while rejecting dangerous schemes such as:
194
+
195
+ ```text
196
+ javascript:
197
+ data:
198
+ vbscript:
199
+ ```
200
+
201
+ Sanitization happens both when importing HTML **and when URLs enter through programmatic commands**.
202
+
203
+ HTML parsing also removes dangerous elements and event-handler attributes.
204
+
205
+ Text content is escaped during HTML serialization.
206
+
207
+ The editor never directly injects arbitrary external HTML into the DOM.
208
+
209
+ ---
210
+
211
+ ## 🏗️ Architecture
212
+
213
+ Regal is organized into five conceptual layers.
214
+
215
+ ```text
216
+ ┌──────────────────────────┐
217
+ │ Application │
218
+ └────────────┬─────────────┘
219
+
220
+ ┌────────────▼─────────────┐
221
+ │ @regal-text-editor │
222
+ │ /ui │
223
+ │ Toolbar · Popovers · UI │
224
+ └────────────┬─────────────┘
225
+
226
+ ┌────────────▼─────────────┐
227
+ │ @regal-text-editor │
228
+ │ /react │
229
+ │ Hooks · Components │
230
+ └────────────┬─────────────┘
231
+
232
+ ┌────────────────────┴────────────────────┐
233
+ │ │
234
+ ┌────────▼─────────┐ ┌─────────▼────────┐
235
+ │ Plugins │ │ Browser │
236
+ │ │ │ Adapter │
237
+ │ Marks · Lists │ │ DOM · Selection │
238
+ │ Links · Images │ │ Keyboard · IME │
239
+ │ Code · History │ │ Clipboard · DnD │
240
+ └────────┬─────────┘ └─────────┬────────┘
241
+ │ │
242
+ └──────────────────┬──────────────────────┘
243
+
244
+ ┌──────────▼───────────┐
245
+ │ @regal- │
246
+ │ text-editor/core │
247
+ │ │
248
+ │ Document Model │
249
+ │ Schema │
250
+ │ Transactions │
251
+ │ Selection │
252
+ │ Commands │
253
+ │ History │
254
+ │ Serialization │
255
+ │ Parsing │
256
+ │ Plugin System │
257
+ └──────────────────────┘
258
+ ```
259
+
260
+ ### Dependency philosophy
261
+
262
+ ```text
263
+ core
264
+
265
+ browser
266
+
267
+ react
268
+
269
+ ui
270
+
271
+ plugins → core
272
+ ```
273
+
274
+ The core never imports React.
275
+
276
+ The browser adapter never imports React.
277
+
278
+ The UI communicates with the editor through the public React API rather than reaching into engine internals.
279
+
280
+ This means you can replace individual layers without rewriting the entire editor.
281
+
282
+ ---
283
+
284
+ # 📦 Package Ecosystem
285
+
286
+ Regal is currently distributed as **11 independent packages** under the `@regal-text-editor/*` scope.
287
+
288
+ | Package | Description |
289
+ | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
290
+ | `@regal-text-editor/core` | Document model, schema, transactions, selection, commands, history, plugins, serialization, parsing & sanitization |
291
+ | `@regal-text-editor/browser` | DOM rendering, selection mapping, keyboard, IME, clipboard & drag/drop |
292
+ | `@regal-text-editor/react` | React bindings, `<RichTextEditor />` and editor hooks |
293
+ | `@regal-text-editor/ui` | Toolbar, bubble toolbar, popovers, icons & theming |
294
+ | `@regal-text-editor/plugin-basic-marks` | Bold, italic, underline, strikethrough & inline code |
295
+ | `@regal-text-editor/plugin-basic-blocks` | Paragraphs, headings, blockquotes, HR & alignment |
296
+ | `@regal-text-editor/plugin-lists` | Bullet, ordered & task lists, nesting and indentation |
297
+ | `@regal-text-editor/plugin-link` | Link marks and URL sanitization |
298
+ | `@regal-text-editor/plugin-image` | Block-level images |
299
+ | `@regal-text-editor/plugin-code-block` | Preformatted code blocks |
300
+ | `@regal-text-editor/plugin-history` | Undo / redo |
301
+
302
+ All packages are currently published as **ESM**, include TypeScript declarations and source maps, and are designed for tree-shaking.
303
+
304
+ ---
305
+
306
+ # 🧰 Features
307
+
308
+ ## ✍️ Text Formatting
309
+
310
+ * Bold
311
+ * Italic
312
+ * Underline
313
+ * Strikethrough
314
+ * Inline code
315
+ * Links
316
+ * Stored marks
317
+
318
+ ### Keyboard shortcuts
319
+
320
+ | Action | Shortcut |
321
+ | ------------- | ----------------- |
322
+ | Bold | `Mod + B` |
323
+ | Italic | `Mod + I` |
324
+ | Underline | `Mod + U` |
325
+ | Strikethrough | `Mod + Shift + X` |
326
+ | Inline Code | `Mod + E` |
327
+
328
+ `Mod` resolves to `⌘` on macOS and `Ctrl` elsewhere.
329
+
330
+ ---
331
+
332
+ ## 🧱 Block Content
333
+
334
+ * Paragraphs
335
+ * H1–H6
336
+ * Blockquotes
337
+ * Horizontal rules
338
+ * Logical text alignment
339
+
340
+ ```ts
341
+ setTextAlign("start");
342
+ setTextAlign("center");
343
+ setTextAlign("end");
344
+ setTextAlign("justify");
345
+ ```
346
+
347
+ ---
348
+
349
+ ## 📋 Lists
350
+
351
+ * Bullet lists
352
+ * Ordered lists
353
+ * Task lists
354
+ * Nested lists
355
+ * Indent / outdent
356
+ * Custom ordered-list start values
357
+
358
+ Keyboard behavior:
359
+
360
+ ```text
361
+ Enter → Split list item
362
+ Enter + empty → Exit list
363
+ Tab → Indent
364
+ Shift + Tab → Outdent
365
+ ```
366
+
367
+ ---
368
+
369
+ ## 🔗 Links
370
+
371
+ ```ts
372
+ setLink(href);
373
+ unsetLink();
374
+ getActiveLinkHref(editor);
375
+ ```
376
+
377
+ Links are sanitized at the command boundary and during HTML parsing.
378
+
379
+ Exported links include:
380
+
381
+ ```html
382
+ rel="noopener noreferrer"
383
+ ```
384
+
385
+ ---
386
+
387
+ ## 🖼️ Images
388
+
389
+ Images are currently represented as **block-level nodes**.
390
+
391
+ ```ts
392
+ insertImage(src, alt?);
393
+ ```
394
+
395
+ Images are URL-based and use the same URL sanitization rules as links.
396
+
397
+ Export formats:
398
+
399
+ * HTML
400
+ * Markdown
401
+
402
+ A built-in upload service is intentionally not included. Applications can connect their own upload infrastructure.
403
+
404
+ ---
405
+
406
+ ## 💻 Code Blocks
407
+
408
+ ```ts
409
+ toggleCodeBlock();
410
+ ```
411
+
412
+ Shortcut:
413
+
414
+ ```text
415
+ Mod + Alt + C
416
+ ```
417
+
418
+ Code blocks:
419
+
420
+ * Preserve whitespace
421
+ * Preserve line breaks
422
+ * Disable text marks
423
+ * Support a `language` attribute
424
+ * Import `<pre>` / `<pre><code>`
425
+ * Treat `Enter` as a literal line break
426
+
427
+ Syntax highlighting is not currently included.
428
+
429
+ ---
430
+
431
+ ## ↩️ Undo / Redo
432
+
433
+ ```text
434
+ Mod + Z
435
+ Mod + Shift + Z
436
+ Mod + Y
437
+ ```
438
+
439
+ History currently uses snapshots backed by Regal's persistent, structurally-shared document tree.
440
+
441
+ Rapid typing can be coalesced into a single undo step.
442
+
443
+ ---
444
+
445
+ ## 🔎 Find & Replace
446
+
447
+ Find & Replace is implemented directly in the core:
448
+
449
+ ```ts
450
+ findMatches();
451
+ replaceMatch();
452
+ replaceAllMatches();
453
+ ```
454
+
455
+ The UI is available through:
456
+
457
+ ```tsx
458
+ <FindReplacePanel />
459
+ ```
460
+
461
+ Search is case-insensitive by default and does not cross block boundaries.
462
+
463
+ ---
464
+
465
+ # ⚛️ React
466
+
467
+ Regal provides first-class React bindings without coupling the engine itself to React.
468
+
469
+ ```tsx
470
+ import {
471
+ EditorProvider,
472
+ RichTextEditor,
473
+ useEditor,
474
+ } from "@regal-text-editor/react";
475
+ ```
476
+
477
+ Available APIs include:
478
+
479
+ ```text
480
+ <RichTextEditor />
481
+ <EditorProvider />
482
+ useEditor()
483
+ useEditorSelector()
484
+ useCommand()
485
+ ```
486
+
487
+ Subscriptions are built around React's `useSyncExternalStore` model.
488
+
489
+ Both controlled and uncontrolled usage are supported.
490
+
491
+ ---
492
+
493
+ # 🎛️ UI
494
+
495
+ The optional UI package provides:
496
+
497
+ ```tsx
498
+ <Toolbar />
499
+ <BubbleToolbar />
500
+ <LinkButton />
501
+ <ImageButton />
502
+ <FindReplacePanel />
503
+ <ToolbarButton />
504
+ <ToolbarSeparator />
505
+ <ToolbarDropdown />
506
+ ```
507
+
508
+ The toolbar is data-driven:
509
+
510
+ ```tsx
511
+ <Toolbar items={defaultToolbarItems} />
512
+ ```
513
+
514
+ You can also completely replace it with your own UI.
515
+
516
+ ---
517
+
518
+ # 🧪 Quality
519
+
520
+ Regal currently has:
521
+
522
+ * **462 automated tests**
523
+ * **35 test files**
524
+ * **~93% statement coverage**
525
+ * Dedicated tests for every package
526
+ * Browser adapter tests
527
+ * React hook tests
528
+ * UI component tests
529
+ * Keyboard interaction tests
530
+ * IME composition tests
531
+ * Clipboard tests
532
+ * DOM selection mapping tests
533
+ * Full-stack jsdom integration tests
534
+
535
+ The published packages have also been verified outside the pnpm workspace using a normal `npm install` flow.
536
+
537
+ ---
538
+
539
+ # 📊 Current Status
540
+
541
+ Regal is a **working, tested foundation**, not a claim of feature parity with mature editors.
542
+
543
+ The project intentionally documents its current limitations.
544
+
545
+ ### ✅ Implemented
546
+
547
+ * Document model
548
+ * Schema
549
+ * Transactions
550
+ * Operations
551
+ * Selection & position tracking
552
+ * Commands
553
+ * Plugin architecture
554
+ * Bold / italic / underline / strike / inline code
555
+ * Links
556
+ * Paragraphs
557
+ * Headings
558
+ * Blockquotes
559
+ * Horizontal rules
560
+ * Logical text alignment
561
+ * Bullet / ordered / task lists
562
+ * List nesting
563
+ * Indent / outdent
564
+ * Block-level images
565
+ * Code blocks
566
+ * Undo / redo
567
+ * Find & replace
568
+ * HTML import/export
569
+ * JSON serialization
570
+ * Markdown export
571
+ * Plain-text serialization
572
+ * Read-only mode
573
+ * Placeholder / empty state
574
+ * Toolbar
575
+ * Bubble toolbar
576
+ * CSS-variable theming
577
+ * React integration
578
+
579
+ ### 🟡 Partial
580
+
581
+ * Schema content matching
582
+ * Snapshot-based history
583
+ * Clipboard compatibility
584
+ * Drag & drop
585
+ * Markdown import
586
+ * Accessibility auditing
587
+ * Dedicated RTL / bidi cursor testing
588
+
589
+ ### 🚧 Planned
590
+
591
+ * Tables
592
+ * Mentions / bookmarks
593
+ * Raw HTML editing
594
+ * Autosave helpers
595
+ * Slash commands
596
+ * Command palette
597
+ * Table of contents
598
+ * Auto-linking
599
+ * Smart typography
600
+ * Advanced spellcheck integration
601
+ * UI localization
602
+ * Syntax highlighting
603
+ * Block drag & drop
604
+
605
+ ---
606
+
607
+ # 📥 Installation
608
+
609
+ ## React
610
+
611
+ Install the packages you need:
612
+
613
+ ```bash
614
+ npm install \
615
+ @regal-text-editor/core \
616
+ @regal-text-editor/browser \
617
+ @regal-text-editor/react \
618
+ @regal-text-editor/ui \
619
+ @regal-text-editor/plugin-basic-blocks \
620
+ @regal-text-editor/plugin-basic-marks \
621
+ @regal-text-editor/plugin-lists \
622
+ @regal-text-editor/plugin-history
623
+ ```
624
+
625
+ ---
626
+
627
+ # ⚡ Quick Start
628
+
629
+ ```tsx
630
+ import { createBaseSchema } from "@regal-text-editor/core";
631
+
632
+ import {
633
+ EditorProvider,
634
+ RichTextEditor,
635
+ useEditor,
636
+ } from "@regal-text-editor/react";
637
+
638
+ import {
639
+ Toolbar,
640
+ defaultToolbarItems,
641
+ } from "@regal-text-editor/ui";
642
+
643
+ import "@regal-text-editor/ui/styles.css";
644
+
645
+ import { BasicBlocksPlugin } from "@regal-text-editor/plugin-basic-blocks";
646
+ import { BasicMarksPlugin } from "@regal-text-editor/plugin-basic-marks";
647
+ import { ListsPlugin } from "@regal-text-editor/plugin-lists";
648
+ import { HistoryPlugin } from "@regal-text-editor/plugin-history";
649
+
650
+ function Editor() {
651
+ const editor = useEditor({
652
+ schema: createBaseSchema(),
653
+
654
+ plugins: [
655
+ BasicBlocksPlugin(),
656
+ BasicMarksPlugin(),
657
+ ListsPlugin(),
658
+ HistoryPlugin(),
659
+ ],
660
+ });
661
+
662
+ return (
663
+ <EditorProvider editor={editor}>
664
+ <Toolbar items={defaultToolbarItems} />
665
+
666
+ <RichTextEditor
667
+ editor={editor}
668
+ placeholder="Start writing..."
669
+ onChange={(doc) => {
670
+ console.log(doc);
671
+ }}
672
+ />
673
+ </EditorProvider>
674
+ );
675
+ }
676
+ ```
677
+
678
+ ---
679
+
680
+ # 🧠 Headless Usage
681
+
682
+ You don't need React or the UI package.
683
+
684
+ ```ts
685
+ import {
686
+ Editor,
687
+ createBaseSchema,
688
+ } from "@regal-text-editor/core";
689
+
690
+ import {
691
+ BasicMarksPlugin,
692
+ } from "@regal-text-editor/plugin-basic-marks";
693
+
694
+ const editor = new Editor({
695
+ schema: createBaseSchema(),
696
+
697
+ plugins: [
698
+ BasicMarksPlugin(),
699
+ ],
700
+ });
701
+
702
+ editor.commands.execute(
703
+ editor,
704
+ "toggleBold"
705
+ );
706
+
707
+ console.log(editor.getHTML());
708
+ console.log(editor.getMarkdown());
709
+ console.log(editor.getJSON());
710
+ ```
711
+
712
+ This is useful for server-side processing, document manipulation, validation, conversion, or custom editor implementations.
713
+
714
+ ---
715
+
716
+ # 🔐 Security Model
717
+
718
+ Regal treats rich-text security as a first-class design concern.
719
+
720
+ ### URL allow-list
721
+
722
+ Allowed:
723
+
724
+ ```text
725
+ http:
726
+ https:
727
+ mailto:
728
+ tel:
729
+ relative URLs
730
+ ```
731
+
732
+ Rejected:
733
+
734
+ ```text
735
+ javascript:
736
+ data:
737
+ vbscript:
738
+ ```
739
+
740
+ ### Dangerous HTML
741
+
742
+ The parser removes dangerous elements such as:
743
+
744
+ ```html
745
+ <script>
746
+ <style>
747
+ <iframe>
748
+ <object>
749
+ <embed>
750
+ <link>
751
+ <meta>
752
+ <base>
753
+ <form>
754
+ ```
755
+
756
+ Event-handler attributes such as:
757
+
758
+ ```html
759
+ onclick
760
+ onload
761
+ onerror
762
+ ```
763
+
764
+ are removed as well.
765
+
766
+ ### Safe serialization
767
+
768
+ Text content is escaped during HTML serialization.
769
+
770
+ The browser adapter only renders HTML produced by Regal's own serializer from its validated document model.
771
+
772
+ ---
773
+
774
+ # 🌍 Compatibility
775
+
776
+ ### Node.js
777
+
778
+ Node.js `18.18+` is required for developing and building the monorepo.
779
+
780
+ ### React
781
+
782
+ React `18+` is required for:
783
+
784
+ ```text
785
+ @regal-text-editor/react
786
+ @regal-text-editor/ui
787
+ ```
788
+
789
+ React is a peer dependency and is not bundled.
790
+
791
+ ### Browser
792
+
793
+ Regal targets modern evergreen browsers supporting:
794
+
795
+ * `contentEditable`
796
+ * Selection API
797
+ * Range API
798
+ * `beforeinput`
799
+ * Clipboard APIs
800
+ * IME composition
801
+
802
+ HTML parsing requires a `DOMParser`-compatible environment.
803
+
804
+ ---
805
+
806
+ # 📦 Module Format
807
+
808
+ Regal is currently:
809
+
810
+ * ESM-only
811
+ * TypeScript typed
812
+ * Tree-shaking friendly
813
+ * `.d.ts` included
814
+ * Source maps included
815
+
816
+ There is currently **no CommonJS build**.
817
+
818
+ ---
819
+
820
+ # 🗺️ Roadmap
821
+
822
+ Regal is being developed around a simple principle:
823
+
824
+ > **The editor should be extensible without becoming tightly coupled.**
825
+
826
+ Future development will focus on:
827
+
828
+ * More document primitives
829
+ * More powerful plugins
830
+ * Better browser behavior
831
+ * Accessibility
832
+ * Advanced collaboration primitives
833
+ * Better serialization
834
+ * Developer tooling
835
+ * More framework integrations
836
+ * Richer UI primitives
837
+
838
+ The roadmap will evolve alongside the architecture.
839
+
840
+ ---
841
+
842
+ # 🤝 Contributing
843
+
844
+ Contributions are welcome.
845
+
846
+ Before opening a pull request:
847
+
848
+ 1. Keep changes focused.
849
+ 2. Add or update tests.
850
+ 3. Preserve the package boundaries.
851
+ 4. Keep public APIs strongly typed.
852
+ 5. Avoid unnecessary dependencies.
853
+ 6. Document user-facing behavior.
854
+ 7. Run the complete test suite before submitting.
855
+
856
+ ```bash
857
+ pnpm install
858
+ pnpm test
859
+ pnpm lint
860
+ pnpm typecheck
861
+ pnpm build
862
+ ```
863
+
864
+ ---
865
+
866
+ # 📄 License
867
+
868
+ Regal Text Editor is released under the **MIT License**.
869
+
870
+ ---
871
+
872
+ <div align="center">
873
+
874
+ # 👑 Regal Text Editor
875
+
876
+ ### Rich text, without the black box.
877
+
878
+ Built from scratch.
879
+ Designed to be extended.
880
+
881
+ [Live Demo](https://regal-text-editor.vercel.app/)
882
+
883
+ </div>