@mdaemon/html-editor-react 1.8.4 → 1.9.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.
Files changed (2) hide show
  1. package/README.md +73 -3
  2. package/package.json +2 -2
package/README.md CHANGED
@@ -19,7 +19,7 @@ npm install @mdaemon/html-editor-react
19
19
  **Peer dependencies:** `react` and `react-dom` (v18 or v19).
20
20
 
21
21
  **TipTap:** the editor is built on TipTap 3, and this package tracks the same version the
22
- engine uses — currently **3.31.3** (`@mdaemon/html-editor` `^1.12.3`,
22
+ engine uses — currently **3.31.3** (`@mdaemon/html-editor` `^1.13.0`,
23
23
  `@tiptap/react` `^3.31.3`). If your app depends on any `@tiptap/*` package directly, keep
24
24
  it on that version too: ProseMirror throws at runtime if two copies of `@tiptap/core` /
25
25
  `@tiptap/pm` end up in the bundle. If you only use `<Editor>` or `useEditor`, there is
@@ -266,6 +266,7 @@ The `config` prop (or `useEditor`'s `config` option) accepts an `EditorConfig` o
266
266
  | `browser_spellcheck` | `boolean` | `true` | Enable browser spell check. |
267
267
  | `entity_encoding` | `'raw' \| 'named' \| 'numeric'` | `'raw'` | HTML entity encoding mode. |
268
268
  | `paste_from_office` | `boolean` | `true` | Clean and preserve formatting when pasting from Microsoft Word/Excel. Pasted list indentation is normalized either way &mdash; see [Lists & Indentation](#lists--indentation). |
269
+ | `paste_markdown` | `boolean` | `false` | Start with paste-as-Markdown on, so a paste is read as Markdown and inserted as real formatting. Toggle at runtime via `getEditor()?.setPasteMarkdown()` or the `pastemarkdown` toolbar button &mdash; see [Pasting Markdown](#pasting-markdown). |
269
270
  | `speech_to_text` | `boolean` | `true` | Enable the `speechtotext` and `dictate` toolbar buttons (requires the Web Speech API). |
270
271
  | `convert_unsafe_embeds` | `boolean` | `true` | Sanitize embedded content. |
271
272
  | `format_empty_lines` | `boolean` | `true` | Preserve blank lines outside the editor. On the way out (`getContent()`, the `onChange` payload, preview, and the source dialog) each empty block is filled with a `<br>` &mdash; bare empty blocks otherwise collapse to zero height in mail clients; on the way in (`setContent()`, `insertContent()`, templates) it is stripped back out, so `setContent(getContent(x))` is stable across round-trips. A block is only "empty" if it has no visible content &mdash; a `<div>&nbsp;</div>` spacer counts as content and is left alone. Set `false` to pass content through unchanged in both directions. |
@@ -461,6 +462,74 @@ Lists pasted from Word, Outlook, Google Docs, another editor, or a web page are
461
462
 
462
463
  Word/Excel cleaning as a whole can be turned off with [`paste_from_office: false`](#configuration); list indentation is normalized either way.
463
464
 
465
+ ## Pasting Markdown
466
+
467
+ Chat apps, AI assistants and README files hand out Markdown, which by default pastes in as
468
+ the raw `#`, `*` and `|` characters. The editor's **Paste Markdown** mode reads a paste
469
+ as Markdown and inserts it as real formatting: headings, bold, italic, strikethrough, inline
470
+ code, links, images, bullet/ordered/nested lists, blockquotes, horizontal rules, fenced code
471
+ blocks with their language, and GFM tables.
472
+
473
+ The mode is **off by default** and, like TinyMCE's *Paste as text*, stays on once turned on
474
+ until it is turned off again. It is per editor instance and the editor does not persist it.
475
+
476
+ Turn it on at init with the `paste_markdown` config option, or at runtime through the raw
477
+ editor instance:
478
+
479
+ ```tsx
480
+ <Editor config={{ paste_markdown: true }} />
481
+
482
+ // At runtime
483
+ editorRef.current?.getEditor()?.setPasteMarkdown(true);
484
+ const on = editorRef.current?.getEditor()?.isPasteMarkdownEnabled();
485
+
486
+ // Or toggle it the TinyMCE way
487
+ editorRef.current?.getEditor()?.execCommand('mceTogglePasteMarkdown');
488
+ ```
489
+
490
+ The `pastemarkdown` toolbar button lets the user toggle the mode. It is deliberately **not**
491
+ in any default toolbar, so no existing layout changes &mdash; add it to a `toolbar` string
492
+ to offer it:
493
+
494
+ ```tsx
495
+ <Editor config={{ toolbar: 'bold italic | copy cut paste pastemarkdown | undo redo' }} />
496
+ ```
497
+
498
+ While the mode is on the button shows the active background, a dot badge and
499
+ `aria-pressed="true"`, and the toolbar's `paste` button converts as well.
500
+
501
+ To remember the user's choice, listen for the `pastemarkdownchange` event &mdash; fired with
502
+ the new boolean, and only when it actually changes &mdash; and pass the saved value back as
503
+ `paste_markdown` next time:
504
+
505
+ ```tsx
506
+ <Editor
507
+ config={{ paste_markdown: savedPreference }}
508
+ onInit={(editor) => {
509
+ editor.on('pastemarkdownchange', (enabled) => savePreference(enabled));
510
+ }}
511
+ />
512
+ ```
513
+
514
+ A few things worth knowing:
515
+
516
+ - **A single newline is a line break**, not a continuation of the paragraph, because chat and
517
+ assistant output is written that way. A blank line still starts a new paragraph.
518
+ - **Task lists paste as plain bullets** (`- [ ] item` becomes a bullet reading `item`) &mdash;
519
+ the editor has no checkbox node.
520
+ - While the mode is on the clipboard's `text/plain` is used and its `text/html` ignored, so
521
+ syntax-highlighted HTML copied from a code editor does not paste as coloured code. Markdown
522
+ mode also takes precedence over the built-in code-block paste for clipboards that VS Code
523
+ (and editors that copy the way it does) mark as code.
524
+ - Pastes that carry files (images), Markdown pasted inside a code block, and drag-and-drop are
525
+ never converted. A URL pasted over a selection still becomes a link either way.
526
+ - **Pasted Markdown cannot run script.** Raw HTML inside the Markdown is escaped to visible
527
+ text, the converted HTML is sanitized in an inert document before it reaches ProseMirror,
528
+ and links are limited to the schemes TipTap allows.
529
+ - Conversion runs on a budget so a crafted paste cannot freeze the tab: input over 256 KB, any
530
+ single paragraph, heading, list item or table cell over 5,000 characters, or a parse that
531
+ takes longer than 750 ms is abandoned and the text goes in as an ordinary paste instead.
532
+
464
533
  ## Templates
465
534
 
466
535
  Enable the template dropdown and provide a `templates` array:
@@ -612,7 +681,8 @@ Buttons after `||` begin collapsed behind a toggle (`...`) button.
612
681
  | `removeformat` | Strip all formatting |
613
682
  | `copy` | Copy selection |
614
683
  | `cut` | Cut selection |
615
- | `paste` | Paste from clipboard |
684
+ | `paste` | Paste from clipboard (follows the paste-as-Markdown mode) |
685
+ | `pastemarkdown` | Toggle paste-as-Markdown mode &mdash; not in any default toolbar (see [Pasting Markdown](#pasting-markdown)) |
616
686
  | `undo` | Undo |
617
687
  | `redo` | Redo |
618
688
  | `image` | Insert image (upload or URL) |
@@ -626,7 +696,7 @@ Buttons after `||` begin collapsed behind a toggle (`...`) button.
626
696
  | `anchor` | Insert a named anchor (`<a id>` target) |
627
697
  | `codesample` | Toggle code sample |
628
698
  | `fullscreen` | Toggle fullscreen |
629
- | `preview` | Preview in new window |
699
+ | `preview` | Preview in new window (the window carries a Content Security Policy that blocks script) |
630
700
  | `searchreplace` | Find & Replace dialog |
631
701
  | `speechtotext` | Open Speech to Text dialog (requires `speech_to_text` + browser support) |
632
702
  | `dictate` | Toggle inline dictation &mdash; inserts speech at the cursor (requires `speech_to_text` + browser support) |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mdaemon/html-editor-react",
3
- "version": "1.8.4",
3
+ "version": "1.9.0",
4
4
  "description": "React wrapper for MDHTMLEditor",
5
5
  "homepage": "https://github.com/mdaemon-technologies/MDHTMLEditor-react",
6
6
  "repository": {
@@ -56,7 +56,7 @@
56
56
  "react-dom": "^19.0.0 || ^18.0.0"
57
57
  },
58
58
  "dependencies": {
59
- "@mdaemon/html-editor": "^1.12.3",
59
+ "@mdaemon/html-editor": "^1.13.0",
60
60
  "@tiptap/react": "^3.31.3"
61
61
  },
62
62
  "devDependencies": {