rte-builder 2.0.5 → 2.0.7

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/dist/index.mjs CHANGED
@@ -1,9 +1,7 @@
1
1
  "use client";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
9
7
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
@@ -14,9 +12,6 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
14
12
  var __esm = (fn, res) => function __init() {
15
13
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
16
14
  };
17
- var __commonJS = (cb, mod) => function __require2() {
18
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
19
- };
20
15
  var __export = (target, all) => {
21
16
  for (var name in all)
22
17
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -29,14 +24,6 @@ var __copyProps = (to, from, except, desc) => {
29
24
  }
30
25
  return to;
31
26
  };
32
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
33
- // If the importer is in node compatibility mode or this is not an ESM
34
- // file that has been converted to a CommonJS file using a Babel-
35
- // compatible transform (i.e. "__esModule" has not been set), then set
36
- // "default" to the CommonJS "module.exports" for node compatibility.
37
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
38
- mod
39
- ));
40
27
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
41
28
 
42
29
  // src/extensions/FontSize.ts
@@ -1585,8 +1572,18 @@ var init_Indent = __esm({
1585
1572
  },
1586
1573
  addKeyboardShortcuts() {
1587
1574
  return {
1588
- Tab: () => this.editor.commands.indent(),
1589
- "Shift-Tab": () => this.editor.commands.outdent()
1575
+ Tab: () => {
1576
+ if (this.editor.isActive("listItem")) {
1577
+ return false;
1578
+ }
1579
+ return this.editor.commands.indent();
1580
+ },
1581
+ "Shift-Tab": () => {
1582
+ if (this.editor.isActive("listItem")) {
1583
+ return false;
1584
+ }
1585
+ return this.editor.commands.outdent();
1586
+ }
1590
1587
  };
1591
1588
  }
1592
1589
  });
@@ -1698,7 +1695,10 @@ var init_TipTapToolbar = __esm({
1698
1695
  {
1699
1696
  ref: buttonRef,
1700
1697
  type: "button",
1701
- onClick,
1698
+ onMouseDown: (e) => {
1699
+ e.preventDefault();
1700
+ onClick();
1701
+ },
1702
1702
  disabled,
1703
1703
  title,
1704
1704
  className: `rte-builder-toolbar-btn ${active ? "active" : ""} ${disabled ? "disabled" : ""}`,
@@ -1782,9 +1782,42 @@ var init_TipTapToolbar = __esm({
1782
1782
  return /* @__PURE__ */ jsx(
1783
1783
  ToolbarButton3,
1784
1784
  {
1785
- onClick: () => editor.chain().focus().toggleCodeBlock().run(),
1785
+ onClick: () => {
1786
+ if (editor.isActive("codeBlock")) {
1787
+ let htmlSource = "";
1788
+ editor.state.doc.descendants((node) => {
1789
+ if (node.type.name === "codeBlock") {
1790
+ htmlSource = node.textContent;
1791
+ return false;
1792
+ }
1793
+ });
1794
+ htmlSource = htmlSource.trim();
1795
+ if (htmlSource) {
1796
+ editor.commands.setContent(htmlSource, true, {
1797
+ preserveWhitespace: false
1798
+ });
1799
+ } else {
1800
+ editor.commands.clearContent(true);
1801
+ }
1802
+ editor.commands.focus();
1803
+ } else {
1804
+ const currentHTML = editor.getHTML();
1805
+ const isEmptyContent = !currentHTML || currentHTML === "<p></p>" || currentHTML.trim() === "";
1806
+ const codeBlockContent = isEmptyContent ? { type: "doc", content: [{ type: "codeBlock" }] } : {
1807
+ type: "doc",
1808
+ content: [
1809
+ {
1810
+ type: "codeBlock",
1811
+ content: [{ type: "text", text: currentHTML }]
1812
+ }
1813
+ ]
1814
+ };
1815
+ editor.commands.setContent(codeBlockContent, false);
1816
+ editor.commands.focus();
1817
+ }
1818
+ },
1786
1819
  active: editor.isActive("codeBlock"),
1787
- title: "Code Block",
1820
+ title: "Code Block (HTML Source)",
1788
1821
  children: /* @__PURE__ */ jsx(CodeXml, { size: 18 })
1789
1822
  },
1790
1823
  "codeBlock"
@@ -1885,6 +1918,16 @@ var init_TipTapToolbar = __esm({
1885
1918
  case "textColor":
1886
1919
  const textPresetColors = ["#11a161", "#85144b", "#ff851b", "#b10dc9"];
1887
1920
  return /* @__PURE__ */ jsxs("span", { className: "rte-builder-toolbar-color-group", children: [
1921
+ /* @__PURE__ */ jsx(
1922
+ "button",
1923
+ {
1924
+ className: "rte-builder-color-preset rte-builder-color-preset-none",
1925
+ onClick: () => editor.chain().focus().unsetColor().run(),
1926
+ title: "Text Color: None (Reset)",
1927
+ type: "button"
1928
+ },
1929
+ "text-none"
1930
+ ),
1888
1931
  textPresetColors.map((color) => /* @__PURE__ */ jsx(
1889
1932
  "button",
1890
1933
  {
@@ -2266,7 +2309,8 @@ var init_TipTapToolbar = __esm({
2266
2309
  return null;
2267
2310
  }
2268
2311
  };
2269
- return /* @__PURE__ */ jsx("div", { className: "rte-builder-toolbar", children: buttons.map(renderButton) });
2312
+ const isSourceMode = editor.isActive("codeBlock");
2313
+ return /* @__PURE__ */ jsx("div", { className: `rte-builder-toolbar${isSourceMode ? " rte-builder-toolbar-source-mode" : ""}`, children: buttons.map(renderButton) });
2270
2314
  };
2271
2315
  }
2272
2316
  });
@@ -2434,6 +2478,12 @@ var init_TipTapEditorComponent = __esm({
2434
2478
  attributes: {
2435
2479
  class: "rte-builder-content",
2436
2480
  style: `min-height: ${minHeight}px; ${maxHeight ? `max-height: ${maxHeight}px;` : ""}`
2481
+ },
2482
+ transformPastedHTML(html) {
2483
+ return html.replace(/(<br\s*\/?>\s*){3,}/gi, "<br><br>").replace(/(<p>\s*<\/p>\s*){2,}/gi, "<p></p>").replace(/>\s{2,}</g, "> <").replace(/(&nbsp;\s*){2,}/g, "&nbsp;").replace(/[\u200B\u200C\u200D\uFEFF]/g, "").replace(
2484
+ /style="[^"]*"/gi,
2485
+ (match) => match.replace(/margin(-top|-bottom):\s*[\d.]+(px|em|rem|pt)\s*;?/gi, "").replace(/padding(-top|-bottom):\s*[\d.]+(px|em|rem|pt)\s*;?/gi, "").replace(/line-height:\s*[\d.]+(px|em|rem|pt|%)?\s*;?/gi, "").replace(/style="\s*"/gi, "")
2486
+ );
2437
2487
  }
2438
2488
  },
2439
2489
  ...editorConfig
@@ -2571,203 +2621,6 @@ var init_TipTapEditorComponent = __esm({
2571
2621
  }
2572
2622
  });
2573
2623
 
2574
- // node_modules/is-hotkey/lib/index.js
2575
- var require_lib = __commonJS({
2576
- "node_modules/is-hotkey/lib/index.js"(exports) {
2577
- "use strict";
2578
- Object.defineProperty(exports, "__esModule", {
2579
- value: true
2580
- });
2581
- var IS_MAC = typeof window != "undefined" && /Mac|iPod|iPhone|iPad/.test(window.navigator.platform);
2582
- var MODIFIERS = {
2583
- alt: "altKey",
2584
- control: "ctrlKey",
2585
- meta: "metaKey",
2586
- shift: "shiftKey"
2587
- };
2588
- var ALIASES = {
2589
- add: "+",
2590
- break: "pause",
2591
- cmd: "meta",
2592
- command: "meta",
2593
- ctl: "control",
2594
- ctrl: "control",
2595
- del: "delete",
2596
- down: "arrowdown",
2597
- esc: "escape",
2598
- ins: "insert",
2599
- left: "arrowleft",
2600
- mod: IS_MAC ? "meta" : "control",
2601
- opt: "alt",
2602
- option: "alt",
2603
- return: "enter",
2604
- right: "arrowright",
2605
- space: " ",
2606
- spacebar: " ",
2607
- up: "arrowup",
2608
- win: "meta",
2609
- windows: "meta"
2610
- };
2611
- var CODES = {
2612
- backspace: 8,
2613
- tab: 9,
2614
- enter: 13,
2615
- shift: 16,
2616
- control: 17,
2617
- alt: 18,
2618
- pause: 19,
2619
- capslock: 20,
2620
- escape: 27,
2621
- " ": 32,
2622
- pageup: 33,
2623
- pagedown: 34,
2624
- end: 35,
2625
- home: 36,
2626
- arrowleft: 37,
2627
- arrowup: 38,
2628
- arrowright: 39,
2629
- arrowdown: 40,
2630
- insert: 45,
2631
- delete: 46,
2632
- meta: 91,
2633
- numlock: 144,
2634
- scrolllock: 145,
2635
- ";": 186,
2636
- "=": 187,
2637
- ",": 188,
2638
- "-": 189,
2639
- ".": 190,
2640
- "/": 191,
2641
- "`": 192,
2642
- "[": 219,
2643
- "\\": 220,
2644
- "]": 221,
2645
- "'": 222
2646
- };
2647
- for (f = 1; f < 20; f++) {
2648
- CODES["f" + f] = 111 + f;
2649
- }
2650
- var f;
2651
- function isHotkey2(hotkey, options, event) {
2652
- if (options && !("byKey" in options)) {
2653
- event = options;
2654
- options = null;
2655
- }
2656
- if (!Array.isArray(hotkey)) {
2657
- hotkey = [hotkey];
2658
- }
2659
- var array = hotkey.map(function(string) {
2660
- return parseHotkey(string, options);
2661
- });
2662
- var check = function check2(e) {
2663
- return array.some(function(object) {
2664
- return compareHotkey(object, e);
2665
- });
2666
- };
2667
- var ret = event == null ? check : check(event);
2668
- return ret;
2669
- }
2670
- function isCodeHotkey(hotkey, event) {
2671
- return isHotkey2(hotkey, event);
2672
- }
2673
- function isKeyHotkey(hotkey, event) {
2674
- return isHotkey2(hotkey, { byKey: true }, event);
2675
- }
2676
- function parseHotkey(hotkey, options) {
2677
- var byKey = options && options.byKey;
2678
- var ret = {};
2679
- hotkey = hotkey.replace("++", "+add");
2680
- var values = hotkey.split("+");
2681
- var length = values.length;
2682
- for (var k in MODIFIERS) {
2683
- ret[MODIFIERS[k]] = false;
2684
- }
2685
- var _iteratorNormalCompletion = true;
2686
- var _didIteratorError = false;
2687
- var _iteratorError = void 0;
2688
- try {
2689
- for (var _iterator = values[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
2690
- var value = _step.value;
2691
- var optional = value.endsWith("?") && value.length > 1;
2692
- if (optional) {
2693
- value = value.slice(0, -1);
2694
- }
2695
- var name = toKeyName(value);
2696
- var modifier = MODIFIERS[name];
2697
- if (value.length > 1 && !modifier && !ALIASES[value] && !CODES[name]) {
2698
- throw new TypeError('Unknown modifier: "' + value + '"');
2699
- }
2700
- if (length === 1 || !modifier) {
2701
- if (byKey) {
2702
- ret.key = name;
2703
- } else {
2704
- ret.which = toKeyCode(value);
2705
- }
2706
- }
2707
- if (modifier) {
2708
- ret[modifier] = optional ? null : true;
2709
- }
2710
- }
2711
- } catch (err) {
2712
- _didIteratorError = true;
2713
- _iteratorError = err;
2714
- } finally {
2715
- try {
2716
- if (!_iteratorNormalCompletion && _iterator.return) {
2717
- _iterator.return();
2718
- }
2719
- } finally {
2720
- if (_didIteratorError) {
2721
- throw _iteratorError;
2722
- }
2723
- }
2724
- }
2725
- return ret;
2726
- }
2727
- function compareHotkey(object, event) {
2728
- for (var key in object) {
2729
- var expected = object[key];
2730
- var actual = void 0;
2731
- if (expected == null) {
2732
- continue;
2733
- }
2734
- if (key === "key" && event.key != null) {
2735
- actual = event.key.toLowerCase();
2736
- } else if (key === "which") {
2737
- actual = expected === 91 && event.which === 93 ? 91 : event.which;
2738
- } else {
2739
- actual = event[key];
2740
- }
2741
- if (actual == null && expected === false) {
2742
- continue;
2743
- }
2744
- if (actual !== expected) {
2745
- return false;
2746
- }
2747
- }
2748
- return true;
2749
- }
2750
- function toKeyCode(name) {
2751
- name = toKeyName(name);
2752
- var code = CODES[name] || name.toUpperCase().charCodeAt(0);
2753
- return code;
2754
- }
2755
- function toKeyName(name) {
2756
- name = name.toLowerCase();
2757
- name = ALIASES[name] || name;
2758
- return name;
2759
- }
2760
- exports.default = isHotkey2;
2761
- exports.isHotkey = isHotkey2;
2762
- exports.isCodeHotkey = isCodeHotkey;
2763
- exports.isKeyHotkey = isKeyHotkey;
2764
- exports.parseHotkey = parseHotkey;
2765
- exports.compareHotkey = compareHotkey;
2766
- exports.toKeyCode = toKeyCode;
2767
- exports.toKeyName = toKeyName;
2768
- }
2769
- });
2770
-
2771
2624
  // src/adapters/slate/SlateToolbar.tsx
2772
2625
  import { useCallback as useCallback2, useState as useState2, useRef as useRef2, useEffect as useEffect3 } from "react";
2773
2626
  import { Editor, Transforms, Element as SlateElement } from "slate";
@@ -3679,12 +3532,12 @@ import {
3679
3532
  import { createEditor, Editor as Editor2, Transforms as Transforms2, Text as Text2, Element as SlateElement2, Node as Node2 } from "slate";
3680
3533
  import { Slate, Editable, withReact, ReactEditor as ReactEditor2 } from "slate-react";
3681
3534
  import { withHistory, HistoryEditor } from "slate-history";
3535
+ import isHotkey from "is-hotkey";
3682
3536
  import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
3683
- var import_is_hotkey, HOTKEYS, LIST_TYPES, TEXT_ALIGN_TYPES, isMarkActive, isBlockActive, toggleMark, toggleBlock, serializeToHtml, serializeNode, escapeHtml, deserializeFromHtml, deserializeElement, renderElement, renderLeaf, withInlines, SlateEditorComponent, SlateEditorComponent_default;
3537
+ var HOTKEYS, LIST_TYPES, TEXT_ALIGN_TYPES, isMarkActive, isBlockActive, toggleMark, toggleBlock, serializeToHtml, serializeNode, escapeHtml, deserializeFromHtml, deserializeElement, renderElement, renderLeaf, withInlines, SlateEditorComponent, SlateEditorComponent_default;
3684
3538
  var init_SlateEditorComponent = __esm({
3685
3539
  "src/adapters/slate/SlateEditorComponent.tsx"() {
3686
3540
  "use strict";
3687
- import_is_hotkey = __toESM(require_lib());
3688
3541
  init_SlateToolbar();
3689
3542
  HOTKEYS = {
3690
3543
  "mod+b": "bold",
@@ -4024,7 +3877,7 @@ var init_SlateEditorComponent = __esm({
4024
3877
  const handleKeyDown = useCallback3(
4025
3878
  (event) => {
4026
3879
  for (const hotkey in HOTKEYS) {
4027
- if ((0, import_is_hotkey.default)(hotkey, event)) {
3880
+ if (isHotkey(hotkey, event)) {
4028
3881
  event.preventDefault();
4029
3882
  const mark = HOTKEYS[hotkey];
4030
3883
  toggleMark(editor, mark);
@@ -6300,7 +6153,10 @@ var Toolbar = ({
6300
6153
  {
6301
6154
  ref: buttonRef,
6302
6155
  type: "button",
6303
- onClick,
6156
+ onMouseDown: (e) => {
6157
+ e.preventDefault();
6158
+ onClick();
6159
+ },
6304
6160
  disabled,
6305
6161
  title,
6306
6162
  className: `rte-builder-toolbar-btn ${active ? "active" : ""} ${disabled ? "disabled" : ""}`,
@@ -6368,9 +6224,42 @@ var Toolbar = ({
6368
6224
  return /* @__PURE__ */ jsx8(
6369
6225
  ToolbarButton3,
6370
6226
  {
6371
- onClick: () => editor.chain().focus().toggleCodeBlock().run(),
6227
+ onClick: () => {
6228
+ if (editor.isActive("codeBlock")) {
6229
+ let htmlSource = "";
6230
+ editor.state.doc.descendants((node) => {
6231
+ if (node.type.name === "codeBlock") {
6232
+ htmlSource = node.textContent;
6233
+ return false;
6234
+ }
6235
+ });
6236
+ htmlSource = htmlSource.trim();
6237
+ if (htmlSource) {
6238
+ editor.commands.setContent(htmlSource, true, {
6239
+ preserveWhitespace: false
6240
+ });
6241
+ } else {
6242
+ editor.commands.clearContent(true);
6243
+ }
6244
+ editor.commands.focus();
6245
+ } else {
6246
+ const currentHTML = editor.getHTML();
6247
+ const isEmptyContent = !currentHTML || currentHTML === "<p></p>" || currentHTML.trim() === "";
6248
+ const codeBlockContent = isEmptyContent ? { type: "doc", content: [{ type: "codeBlock" }] } : {
6249
+ type: "doc",
6250
+ content: [
6251
+ {
6252
+ type: "codeBlock",
6253
+ content: [{ type: "text", text: currentHTML }]
6254
+ }
6255
+ ]
6256
+ };
6257
+ editor.commands.setContent(codeBlockContent, false);
6258
+ editor.commands.focus();
6259
+ }
6260
+ },
6372
6261
  active: editor.isActive("codeBlock"),
6373
- title: "Code Block",
6262
+ title: "Code Block (HTML Source)",
6374
6263
  children: /* @__PURE__ */ jsx8(CodeXml2, { size: 18 })
6375
6264
  },
6376
6265
  "codeBlock"
@@ -6469,17 +6358,29 @@ var Toolbar = ({
6469
6358
  "lineHeight"
6470
6359
  );
6471
6360
  case "textColor":
6472
- return /* @__PURE__ */ jsx8("span", { className: "rte-builder-toolbar-color", children: /* @__PURE__ */ jsxs8("label", { title: "Text Color", children: [
6473
- /* @__PURE__ */ jsx8(Type, { size: 18 }),
6361
+ return /* @__PURE__ */ jsxs8("span", { className: "rte-builder-toolbar-color-group", children: [
6474
6362
  /* @__PURE__ */ jsx8(
6475
- "input",
6363
+ "button",
6476
6364
  {
6477
- type: "color",
6478
- onChange: (e) => editor.chain().focus().setColor(e.target.value).run(),
6479
- value: editor.getAttributes("textStyle").color || "#000000"
6480
- }
6481
- )
6482
- ] }) }, "textColor");
6365
+ className: "rte-builder-color-preset rte-builder-color-preset-none",
6366
+ onClick: () => editor.chain().focus().unsetColor().run(),
6367
+ title: "Text Color: None (Reset)",
6368
+ type: "button"
6369
+ },
6370
+ "text-none"
6371
+ ),
6372
+ /* @__PURE__ */ jsx8("span", { className: "rte-builder-toolbar-color", children: /* @__PURE__ */ jsxs8("label", { title: "Text Color", children: [
6373
+ /* @__PURE__ */ jsx8(Type, { size: 18 }),
6374
+ /* @__PURE__ */ jsx8(
6375
+ "input",
6376
+ {
6377
+ type: "color",
6378
+ onChange: (e) => editor.chain().focus().setColor(e.target.value).run(),
6379
+ value: editor.getAttributes("textStyle").color || "#000000"
6380
+ }
6381
+ )
6382
+ ] }) })
6383
+ ] }, "textColor");
6483
6384
  case "backgroundColor":
6484
6385
  return /* @__PURE__ */ jsx8("span", { className: "rte-builder-toolbar-color", children: /* @__PURE__ */ jsxs8("label", { title: "Background Color", children: [
6485
6386
  /* @__PURE__ */ jsx8(Highlighter, { size: 18 }),
@@ -6764,7 +6665,8 @@ var Toolbar = ({
6764
6665
  return null;
6765
6666
  }
6766
6667
  };
6767
- return /* @__PURE__ */ jsx8("div", { className: "rte-builder-toolbar", children: buttons.map(renderButton) });
6668
+ const isSourceMode = editor.isActive("codeBlock");
6669
+ return /* @__PURE__ */ jsx8("div", { className: `rte-builder-toolbar${isSourceMode ? " rte-builder-toolbar-source-mode" : ""}`, children: buttons.map(renderButton) });
6768
6670
  };
6769
6671
 
6770
6672
  // src/components/RichTextEditor.tsx