@mdaemon/html-editor-react 1.8.4 → 1.9.1

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 +75 -4
  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.1`,
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,75 @@ 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 within one paragraph still becomes a link
526
+ either way; over a larger selection (such as Ctrl+A) it replaces the selection.
527
+ - **Pasted Markdown cannot run script.** Raw HTML inside the Markdown is escaped to visible
528
+ text, the converted HTML is sanitized in an inert document before it reaches ProseMirror,
529
+ and links are limited to the schemes TipTap allows.
530
+ - Conversion runs on a budget so a crafted paste cannot freeze the tab: input over 256 KB, any
531
+ single paragraph, heading, list item or table cell over 5,000 characters, or a parse that
532
+ takes longer than 750 ms is abandoned and the text goes in as an ordinary paste instead.
533
+
464
534
  ## Templates
465
535
 
466
536
  Enable the template dropdown and provide a `templates` array:
@@ -612,7 +682,8 @@ Buttons after `||` begin collapsed behind a toggle (`...`) button.
612
682
  | `removeformat` | Strip all formatting |
613
683
  | `copy` | Copy selection |
614
684
  | `cut` | Cut selection |
615
- | `paste` | Paste from clipboard |
685
+ | `paste` | Paste from clipboard (follows the paste-as-Markdown mode) |
686
+ | `pastemarkdown` | Toggle paste-as-Markdown mode &mdash; not in any default toolbar (see [Pasting Markdown](#pasting-markdown)) |
616
687
  | `undo` | Undo |
617
688
  | `redo` | Redo |
618
689
  | `image` | Insert image (upload or URL) |
@@ -621,12 +692,12 @@ Buttons after `||` begin collapsed behind a toggle (`...`) button.
621
692
  | `charmap` | Special character picker |
622
693
  | `emoticons` | Emoji picker with search |
623
694
  | `code` | Open HTML source code editor dialog |
624
- | `link` | Insert/edit hyperlink |
695
+ | `link` | Insert/edit hyperlink (with the caret on a link, edits that link in place) |
625
696
  | `unlink` | Remove the link at the cursor |
626
697
  | `anchor` | Insert a named anchor (`<a id>` target) |
627
698
  | `codesample` | Toggle code sample |
628
699
  | `fullscreen` | Toggle fullscreen |
629
- | `preview` | Preview in new window |
700
+ | `preview` | Preview in new window (the window carries a Content Security Policy that blocks script) |
630
701
  | `searchreplace` | Find & Replace dialog |
631
702
  | `speechtotext` | Open Speech to Text dialog (requires `speech_to_text` + browser support) |
632
703
  | `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.1",
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.1",
60
60
  "@tiptap/react": "^3.31.3"
61
61
  },
62
62
  "devDependencies": {