@lobehub/editor 1.14.2 → 1.16.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.
@@ -1,6 +1,20 @@
1
1
  import type { IEditorPluginConstructor } from "../../../types";
2
2
  export interface CommonPluginOptions {
3
3
  enableHotkey?: boolean;
4
+ /**
5
+ * Enable/disable markdown shortcuts
6
+ * @default true - all formats enabled
7
+ */
8
+ markdownOption?: boolean | {
9
+ bold?: boolean;
10
+ code?: boolean;
11
+ header?: boolean;
12
+ italic?: boolean;
13
+ quote?: boolean;
14
+ strikethrough?: boolean;
15
+ underline?: boolean;
16
+ underlineStrikethrough?: boolean;
17
+ };
4
18
  theme?: {
5
19
  quote?: string;
6
20
  textBold?: string;
@@ -1,11 +1,11 @@
1
1
  var _class;
2
- function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
3
2
  function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
4
3
  function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
5
4
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
6
5
  function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
7
6
  function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
8
7
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
8
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
9
9
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
10
10
  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
11
11
  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
@@ -33,8 +33,8 @@ import TextDataSource from "../data-source/text-data-source";
33
33
  import { patchBreakLine, registerBreakLineClick } from "../node/ElementDOMSlot";
34
34
  import { CursorNode, registerCursorNode } from "../node/cursor";
35
35
  import { createBlockNode } from "../utils";
36
- import { registerHeaderBackspace, registerLastElement, registerRichKeydown } from "./register";
37
36
  import { registerMDReader } from "./mdReader";
37
+ import { registerHeaderBackspace, registerLastElement, registerRichKeydown } from "./register";
38
38
  patchBreakLine();
39
39
  export var CommonPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
40
40
  _inherits(CommonPlugin, _KernelPlugin);
@@ -73,64 +73,112 @@ export var CommonPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
73
73
  _createClass(CommonPlugin, [{
74
74
  key: "registerMarkdown",
75
75
  value: function registerMarkdown(kernel) {
76
+ var _this$config$markdown, _this$config;
76
77
  var markdownService = kernel.requireService(IMarkdownShortCutService);
77
78
  if (!markdownService) {
78
79
  return;
79
80
  }
80
- markdownService.registerMarkdownShortCut({
81
- regExp: /^>\s/,
82
- replace: function replace(parentNode, children, _match, isImport) {
83
- if (isImport) {
84
- var previousNode = parentNode.getPreviousSibling();
85
- if ($isQuoteNode(previousNode)) {
86
- previousNode.splice(previousNode.getChildrenSize(), 0, [$createLineBreakNode()].concat(_toConsumableArray(children)));
87
- parentNode.remove();
88
- return;
81
+
82
+ // Parse markdown options
83
+ var markdownOption = (_this$config$markdown = (_this$config = this.config) === null || _this$config === void 0 ? void 0 : _this$config.markdownOption) !== null && _this$config$markdown !== void 0 ? _this$config$markdown : true;
84
+ var isMarkdownEnabled = markdownOption !== false;
85
+
86
+ // Determine which formats are enabled
87
+ var formats = {
88
+ bold: true,
89
+ header: true,
90
+ italic: true,
91
+ quote: true,
92
+ strikethrough: true
93
+ // Note: code, underline, underlineStrikethrough are handled by other plugins/writers
94
+ };
95
+ if (_typeof(markdownOption) === 'object') {
96
+ var _markdownOption$bold, _markdownOption$heade, _markdownOption$itali, _markdownOption$quote, _markdownOption$strik;
97
+ formats.bold = (_markdownOption$bold = markdownOption.bold) !== null && _markdownOption$bold !== void 0 ? _markdownOption$bold : true;
98
+ formats.header = (_markdownOption$heade = markdownOption.header) !== null && _markdownOption$heade !== void 0 ? _markdownOption$heade : true;
99
+ formats.italic = (_markdownOption$itali = markdownOption.italic) !== null && _markdownOption$itali !== void 0 ? _markdownOption$itali : true;
100
+ formats.quote = (_markdownOption$quote = markdownOption.quote) !== null && _markdownOption$quote !== void 0 ? _markdownOption$quote : true;
101
+ formats.strikethrough = (_markdownOption$strik = markdownOption.strikethrough) !== null && _markdownOption$strik !== void 0 ? _markdownOption$strik : true;
102
+ }
103
+ if (!isMarkdownEnabled) {
104
+ return;
105
+ }
106
+
107
+ // Register quote shortcut if enabled
108
+ if (formats.quote) {
109
+ markdownService.registerMarkdownShortCut({
110
+ regExp: /^>\s/,
111
+ replace: function replace(parentNode, children, _match, isImport) {
112
+ if (isImport) {
113
+ var previousNode = parentNode.getPreviousSibling();
114
+ if ($isQuoteNode(previousNode)) {
115
+ previousNode.splice(previousNode.getChildrenSize(), 0, [$createLineBreakNode()].concat(_toConsumableArray(children)));
116
+ parentNode.remove();
117
+ return;
118
+ }
89
119
  }
90
- }
91
- var node = $createQuoteNode();
92
- node.append.apply(node, _toConsumableArray(children));
93
- parentNode.replace(node);
94
- if (!isImport) {
95
- node.select(0, 0);
96
- }
97
- },
98
- type: 'element'
99
- });
100
- markdownService.registerMarkdownShortCut({
101
- regExp: /^(#{1,6})\s/,
102
- replace: createBlockNode(function (match, parentNode) {
103
- var tag = 'h' + match[1].length;
104
- if ($isHeadingNode(parentNode) && parentNode.getTag() === tag) {
105
- return $createParagraphNode();
106
- }
107
- return $createHeadingNode(tag);
108
- }),
109
- type: 'element'
110
- });
111
- markdownService.registerMarkdownShortCuts([{
112
- format: ['bold'],
113
- tag: '**',
114
- type: 'text-format'
115
- }, {
116
- format: ['bold'],
117
- intraword: false,
118
- tag: '__',
119
- type: 'text-format'
120
- }, {
121
- format: ['strikethrough'],
122
- tag: '~~',
123
- type: 'text-format'
124
- }, {
125
- format: ['italic'],
126
- tag: '*',
127
- type: 'text-format'
128
- }, {
129
- format: ['italic'],
130
- intraword: false,
131
- tag: '_',
132
- type: 'text-format'
133
- }, {
120
+ var node = $createQuoteNode();
121
+ node.append.apply(node, _toConsumableArray(children));
122
+ parentNode.replace(node);
123
+ if (!isImport) {
124
+ node.select(0, 0);
125
+ }
126
+ },
127
+ type: 'element'
128
+ });
129
+ }
130
+
131
+ // Register header shortcut if enabled
132
+ if (formats.header) {
133
+ markdownService.registerMarkdownShortCut({
134
+ regExp: /^(#{1,6})\s/,
135
+ replace: createBlockNode(function (match, parentNode) {
136
+ var tag = 'h' + match[1].length;
137
+ if ($isHeadingNode(parentNode) && parentNode.getTag() === tag) {
138
+ return $createParagraphNode();
139
+ }
140
+ return $createHeadingNode(tag);
141
+ }),
142
+ type: 'element'
143
+ });
144
+ }
145
+
146
+ // Register text format shortcuts based on enabled formats
147
+ var textFormatShortcuts = [];
148
+ if (formats.bold) {
149
+ textFormatShortcuts.push({
150
+ format: ['bold'],
151
+ tag: '**',
152
+ type: 'text-format'
153
+ }, {
154
+ format: ['bold'],
155
+ intraword: false,
156
+ tag: '__',
157
+ type: 'text-format'
158
+ });
159
+ }
160
+ if (formats.strikethrough) {
161
+ textFormatShortcuts.push({
162
+ format: ['strikethrough'],
163
+ tag: '~~',
164
+ type: 'text-format'
165
+ });
166
+ }
167
+ if (formats.italic) {
168
+ textFormatShortcuts.push({
169
+ format: ['italic'],
170
+ tag: '*',
171
+ type: 'text-format'
172
+ }, {
173
+ format: ['italic'],
174
+ intraword: false,
175
+ tag: '_',
176
+ type: 'text-format'
177
+ });
178
+ }
179
+
180
+ // Always register superscript and subscript (not in options)
181
+ textFormatShortcuts.push({
134
182
  format: ['superscript'],
135
183
  tag: '^',
136
184
  type: 'text-format'
@@ -138,7 +186,10 @@ export var CommonPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
138
186
  format: ['subscript'],
139
187
  tag: '~',
140
188
  type: 'text-format'
141
- }]);
189
+ });
190
+ if (textFormatShortcuts.length > 0) {
191
+ markdownService.registerMarkdownShortCuts(textFormatShortcuts);
192
+ }
142
193
  markdownService.registerMarkdownWriter('paragraph', function (ctx) {
143
194
  ctx.wrap('', '\n\n');
144
195
  });
@@ -263,9 +314,9 @@ export var CommonPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
263
314
  }, {
264
315
  key: "onInit",
265
316
  value: function onInit(editor) {
266
- var _this$config;
317
+ var _this$config2;
267
318
  this.registerClears(registerRichText(editor), registerDragonSupport(editor), registerHistory(editor, createEmptyHistoryState(), 300), registerHeaderBackspace(editor), registerRichKeydown(editor, this.kernel, {
268
- enableHotkey: (_this$config = this.config) === null || _this$config === void 0 ? void 0 : _this$config.enableHotkey
319
+ enableHotkey: (_this$config2 = this.config) === null || _this$config2 === void 0 ? void 0 : _this$config2.enableHotkey
269
320
  }), registerCommands(editor), registerBreakLineClick(editor), registerCursorNode(editor), registerLastElement(editor));
270
321
  this.registerMarkdown(this.kernel);
271
322
  }
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
- function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4
3
  var _excluded = ["fontSize", "headerMultiple", "lineHeight", "marginMultiple"];
4
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
5
5
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
6
6
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
7
7
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
@@ -36,6 +36,10 @@ var ReactPlainText = /*#__PURE__*/memo(function (_ref) {
36
36
  variant = _ref.variant,
37
37
  _ref$enableHotkey = _ref.enableHotkey,
38
38
  enableHotkey = _ref$enableHotkey === void 0 ? true : _ref$enableHotkey,
39
+ _ref$enablePasteMarkd = _ref.enablePasteMarkdown,
40
+ enablePasteMarkdown = _ref$enablePasteMarkd === void 0 ? true : _ref$enablePasteMarkd,
41
+ _ref$markdownOption = _ref.markdownOption,
42
+ markdownOption = _ref$markdownOption === void 0 ? true : _ref$markdownOption,
39
43
  onKeyDown = _ref.onKeyDown,
40
44
  onFocus = _ref.onFocus,
41
45
  onBlur = _ref.onBlur,
@@ -59,7 +63,7 @@ var ReactPlainText = /*#__PURE__*/memo(function (_ref) {
59
63
  _useLexicalComposerCo2 = _slicedToArray(_useLexicalComposerCo, 1),
60
64
  editor = _useLexicalComposerCo2[0];
61
65
  var decorators = useDecorators(editor, LexicalErrorBoundary);
62
- var _useThemeStyles = useThemeStyles(),
66
+ var _useThemeStyles = useThemeStyles(markdownOption),
63
67
  themeStyles = _useThemeStyles.styles;
64
68
  var _useStyles = useStyles({
65
69
  fontSize: fontSize,
@@ -79,12 +83,15 @@ var ReactPlainText = /*#__PURE__*/memo(function (_ref) {
79
83
  content = _Children$only$props.content,
80
84
  placeholder = _Children$only$props.placeholder;
81
85
  useLayoutEffect(function () {
82
- editor.registerPlugin(MarkdownPlugin);
86
+ editor.registerPlugin(MarkdownPlugin, {
87
+ enablePasteMarkdown: enablePasteMarkdown
88
+ });
83
89
  editor.registerPlugin(CommonPlugin, {
84
90
  enableHotkey: enableHotkey,
91
+ markdownOption: markdownOption,
85
92
  theme: restTheme ? _objectSpread(_objectSpread({}, themeStyles), restTheme) : themeStyles
86
93
  });
87
- }, [editor, enableHotkey, restTheme, themeStyles]);
94
+ }, [editor, enableHotkey, enablePasteMarkdown, markdownOption, restTheme, themeStyles]);
88
95
  useEffect(function () {
89
96
  var _editor$getLexicalEdi;
90
97
  var container = editorContainerRef.current;
@@ -159,7 +166,7 @@ var ReactPlainText = /*#__PURE__*/memo(function (_ref) {
159
166
  });
160
167
  };
161
168
  return /*#__PURE__*/_jsxs("div", {
162
- className: cx(styles.root, styles.variant, className),
169
+ className: cx(styles.root, markdownOption === true && styles.variant, markdownOption === false && styles.noHeader, _typeof(markdownOption) === 'object' && markdownOption.header === true && styles.header, _typeof(markdownOption) === 'object' && markdownOption.header === false && styles.noHeader, _typeof(markdownOption) === 'object' && markdownOption.code === true && styles.code, _typeof(markdownOption) === 'object' && markdownOption.quote === true && styles.blockquote, className),
163
170
  style: style,
164
171
  children: [/*#__PURE__*/_jsx("div", {
165
172
  contentEditable: true,
@@ -1,4 +1,13 @@
1
- export declare const useThemeStyles: (props?: unknown) => import("antd-style").ReturnStyles<{
1
+ export declare const useThemeStyles: (props?: boolean | {
2
+ bold?: boolean | undefined;
3
+ code?: boolean | undefined;
4
+ header?: boolean | undefined;
5
+ italic?: boolean | undefined;
6
+ quote?: boolean | undefined;
7
+ strikethrough?: boolean | undefined;
8
+ underline?: boolean | undefined;
9
+ underlineStrikethrough?: boolean | undefined;
10
+ } | undefined) => import("antd-style").ReturnStyles<{
2
11
  quote: string;
3
12
  textBold: import("antd-style").SerializedStyles;
4
13
  textCode: string;
@@ -13,6 +22,11 @@ export declare const useStyles: (props?: {
13
22
  lineHeight?: number | undefined;
14
23
  marginMultiple?: number | undefined;
15
24
  } | undefined) => import("antd-style").ReturnStyles<{
25
+ blockquote: import("antd-style").SerializedStyles;
26
+ code: import("antd-style").SerializedStyles;
27
+ header: import("antd-style").SerializedStyles;
28
+ noHeader: import("antd-style").SerializedStyles;
29
+ p: import("antd-style").SerializedStyles;
16
30
  root: import("antd-style").SerializedStyles;
17
31
  variant: string;
18
32
  }>;
@@ -1,17 +1,19 @@
1
- var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9, _templateObject10;
1
+ var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9, _templateObject10, _templateObject11, _templateObject12, _templateObject13, _templateObject14, _templateObject15, _templateObject16;
2
2
  function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
3
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
3
4
  import { createStyles } from 'antd-style';
4
5
  export var useThemeStyles = createStyles(function (_ref) {
5
6
  var css = _ref.css,
6
7
  token = _ref.token;
8
+ var markdownOption = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
7
9
  return {
8
10
  quote: 'editor_quote',
9
- textBold: css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n font-weight: bold;\n "]))),
11
+ textBold: markdownOption === true || _typeof(markdownOption) === 'object' && markdownOption.bold === true ? css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n font-weight: bold;\n "]))) : css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n font-weight: unset;\n "]))),
10
12
  textCode: 'editor_code',
11
- textItalic: css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n font-style: italic;\n "]))),
12
- textStrikethrough: css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n color: ", ";\n text-decoration: line-through;\n "])), token.colorTextDescription),
13
- textUnderline: css(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n text-decoration: underline;\n "]))),
14
- textUnderlineStrikethrough: css(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n text-decoration: underline line-through;\n "])))
13
+ textItalic: markdownOption === true || _typeof(markdownOption) === 'object' && markdownOption.italic === true ? css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n font-style: italic;\n "]))) : css(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n font-style: unset;\n "]))),
14
+ textStrikethrough: markdownOption === true || _typeof(markdownOption) === 'object' && markdownOption.strikethrough === true ? css(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n color: ", ";\n text-decoration: line-through;\n "])), token.colorTextDescription) : css(_templateObject6 || (_templateObject6 = _taggedTemplateLiteral(["\n text-decoration: unset;\n "]))),
15
+ textUnderline: markdownOption === true || _typeof(markdownOption) === 'object' && markdownOption.strikethrough === true ? css(_templateObject7 || (_templateObject7 = _taggedTemplateLiteral(["\n text-decoration: underline;\n "]))) : css(_templateObject8 || (_templateObject8 = _taggedTemplateLiteral(["\n text-decoration: unset;\n "]))),
16
+ textUnderlineStrikethrough: markdownOption === true || _typeof(markdownOption) === 'object' && markdownOption.underlineStrikethrough === true ? css(_templateObject9 || (_templateObject9 = _taggedTemplateLiteral(["\n text-decoration: underline line-through;\n "]))) : css(_templateObject10 || (_templateObject10 = _taggedTemplateLiteral(["\n text-decoration: unset;\n "])))
15
17
  };
16
18
  });
17
19
  export var useStyles = createStyles(function (_ref2, _ref3) {
@@ -26,12 +28,17 @@ export var useStyles = createStyles(function (_ref2, _ref3) {
26
28
  marginMultiple = _ref3$marginMultiple === void 0 ? 2 : _ref3$marginMultiple,
27
29
  _ref3$lineHeight = _ref3.lineHeight,
28
30
  lineHeight = _ref3$lineHeight === void 0 ? 1.8 : _ref3$lineHeight;
29
- var __root = css(_templateObject6 || (_templateObject6 = _taggedTemplateLiteral(["\n --lobe-markdown-font-size: ", "px;\n --lobe-markdown-header-multiple: ", ";\n --lobe-markdown-margin-multiple: ", ";\n --lobe-markdown-line-height: ", ";\n --lobe-markdown-border-radius: ", ";\n --lobe-markdown-border-color: ", ";\n\n position: relative;\n\n display: flex;\n flex-direction: column;\n\n width: 100%;\n max-width: 100%;\n height: 100%;\n\n font-size: var(--lobe-markdown-font-size);\n line-height: var(--lobe-markdown-line-height);\n word-break: break-word;\n\n @keyframes cursor-blink {\n to {\n visibility: hidden;\n }\n }\n\n [data-lexical-cursor='true'] {\n pointer-events: none;\n position: absolute;\n display: block;\n\n &::after {\n content: '';\n\n position: absolute;\n inset-block-start: -2px;\n\n display: block;\n\n width: 20px;\n border-block-start: 1px solid ", ";\n\n animation: cursor-blink 1.1s steps(2, start) infinite;\n }\n }\n "])), fontSize, headerMultiple, marginMultiple, lineHeight, token.borderRadiusLG, token.colorFillQuaternary, token.colorText);
30
- var header = css(_templateObject7 || (_templateObject7 = _taggedTemplateLiteral(["\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n margin-block: max(\n calc(var(--lobe-markdown-header-multiple) * var(--lobe-markdown-margin-multiple) * 0.4em),\n var(--lobe-markdown-font-size)\n );\n font-weight: bold;\n line-height: 1.25;\n }\n\n h1 {\n font-size: calc(\n var(--lobe-markdown-font-size) * (1 + 1.5 * var(--lobe-markdown-header-multiple))\n );\n }\n\n h2 {\n font-size: calc(\n var(--lobe-markdown-font-size) * (1 + var(--lobe-markdown-header-multiple))\n );\n }\n\n h3 {\n font-size: calc(\n var(--lobe-markdown-font-size) * (1 + 0.5 * var(--lobe-markdown-header-multiple))\n );\n }\n\n h4 {\n font-size: calc(\n var(--lobe-markdown-font-size) * (1 + 0.25 * var(--lobe-markdown-header-multiple))\n );\n }\n\n h5,\n h6 {\n font-size: calc(var(--lobe-markdown-font-size) * 1);\n }\n "])));
31
- var p = css(_templateObject8 || (_templateObject8 = _taggedTemplateLiteral(["\n p {\n margin-block: 4px;\n line-height: var(--lobe-markdown-line-height);\n letter-spacing: 0.02em;\n\n &:not(:first-child) {\n margin-block-start: calc(var(--lobe-markdown-margin-multiple) * 0.5em);\n }\n\n &:not(:last-child) {\n margin-block-end: calc(var(--lobe-markdown-margin-multiple) * 0.5em);\n }\n }\n "])));
32
- var blockquote = css(_templateObject9 || (_templateObject9 = _taggedTemplateLiteral(["\n .editor_quote {\n margin-block: calc(var(--lobe-markdown-margin-multiple) * 0.5em);\n margin-inline: 0;\n padding-block: 0;\n padding-inline: 1em;\n border-inline-start: solid 4px ", ";\n\n color: ", ";\n }\n "])), token.colorBorder, token.colorTextSecondary);
33
- var code = css(_templateObject10 || (_templateObject10 = _taggedTemplateLiteral(["\n .editor_code {\n display: inline;\n\n margin-inline: 0.25em;\n padding-block: 0.2em;\n padding-inline: 0.4em;\n border: 1px solid var(--lobe-markdown-border-color);\n border-radius: 0.25em;\n\n font-family: ", ";\n font-size: 0.875em;\n line-height: 1;\n word-break: break-word;\n white-space: break-spaces;\n\n background: ", ";\n }\n "])), token.fontFamilyCode, token.colorFillSecondary);
31
+ var __root = css(_templateObject11 || (_templateObject11 = _taggedTemplateLiteral(["\n --lobe-markdown-font-size: ", "px;\n --lobe-markdown-header-multiple: ", ";\n --lobe-markdown-margin-multiple: ", ";\n --lobe-markdown-line-height: ", ";\n --lobe-markdown-border-radius: ", ";\n --lobe-markdown-border-color: ", ";\n\n position: relative;\n\n display: flex;\n flex-direction: column;\n\n width: 100%;\n max-width: 100%;\n height: 100%;\n\n font-size: var(--lobe-markdown-font-size);\n line-height: var(--lobe-markdown-line-height);\n word-break: break-word;\n\n @keyframes cursor-blink {\n to {\n visibility: hidden;\n }\n }\n\n [data-lexical-cursor='true'] {\n pointer-events: none;\n position: absolute;\n display: block;\n\n &::after {\n content: '';\n\n position: absolute;\n inset-block-start: -2px;\n\n display: block;\n\n width: 20px;\n border-block-start: 1px solid ", ";\n\n animation: cursor-blink 1.1s steps(2, start) infinite;\n }\n }\n "])), fontSize, headerMultiple, marginMultiple, lineHeight, token.borderRadiusLG, token.colorFillQuaternary, token.colorText);
32
+ var header = css(_templateObject12 || (_templateObject12 = _taggedTemplateLiteral(["\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n margin-block: max(\n calc(var(--lobe-markdown-header-multiple) * var(--lobe-markdown-margin-multiple) * 0.4em),\n var(--lobe-markdown-font-size)\n );\n font-weight: bold;\n line-height: 1.25;\n }\n\n h1 {\n font-size: calc(\n var(--lobe-markdown-font-size) * (1 + 1.5 * var(--lobe-markdown-header-multiple))\n );\n }\n\n h2 {\n font-size: calc(\n var(--lobe-markdown-font-size) * (1 + var(--lobe-markdown-header-multiple))\n );\n }\n\n h3 {\n font-size: calc(\n var(--lobe-markdown-font-size) * (1 + 0.5 * var(--lobe-markdown-header-multiple))\n );\n }\n\n h4 {\n font-size: calc(\n var(--lobe-markdown-font-size) * (1 + 0.25 * var(--lobe-markdown-header-multiple))\n );\n }\n\n h5,\n h6 {\n font-size: calc(var(--lobe-markdown-font-size) * 1);\n }\n "])));
33
+ var p = css(_templateObject13 || (_templateObject13 = _taggedTemplateLiteral(["\n p {\n margin-block: 4px;\n line-height: var(--lobe-markdown-line-height);\n letter-spacing: 0.02em;\n\n &:not(:first-child) {\n margin-block-start: calc(var(--lobe-markdown-margin-multiple) * 0.5em);\n }\n\n &:not(:last-child) {\n margin-block-end: calc(var(--lobe-markdown-margin-multiple) * 0.5em);\n }\n }\n "])));
34
+ var blockquote = css(_templateObject14 || (_templateObject14 = _taggedTemplateLiteral(["\n .editor_quote {\n margin-block: calc(var(--lobe-markdown-margin-multiple) * 0.5em);\n margin-inline: 0;\n padding-block: 0;\n padding-inline: 1em;\n border-inline-start: solid 4px ", ";\n\n color: ", ";\n }\n "])), token.colorBorder, token.colorTextSecondary);
35
+ var code = css(_templateObject15 || (_templateObject15 = _taggedTemplateLiteral(["\n .editor_code {\n display: inline;\n\n margin-inline: 0.25em;\n padding-block: 0.2em;\n padding-inline: 0.4em;\n border: 1px solid var(--lobe-markdown-border-color);\n border-radius: 0.25em;\n\n font-family: ", ";\n font-size: 0.875em;\n line-height: 1;\n word-break: break-word;\n white-space: break-spaces;\n\n background: ", ";\n }\n "])), token.fontFamilyCode, token.colorFillSecondary);
34
36
  return {
37
+ blockquote: blockquote,
38
+ code: code,
39
+ header: header,
40
+ noHeader: css(_templateObject16 || (_templateObject16 = _taggedTemplateLiteral(["\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n margin-block: 4px;\n font-size: var(--lobe-markdown-font-size);\n line-height: var(--lobe-markdown-line-height);\n letter-spacing: 0.02em;\n\n &:not(:first-child) {\n margin-block-start: calc(var(--lobe-markdown-margin-multiple) * 0.5em);\n }\n\n &:not(:last-child) {\n margin-block-end: calc(var(--lobe-markdown-margin-multiple) * 0.5em);\n }\n }\n "]))),
41
+ p: p,
35
42
  root: __root,
36
43
  variant: cx(header, p, blockquote, code)
37
44
  };
@@ -11,6 +11,16 @@ export interface ReactPlainTextProps {
11
11
  children: ReactElement<ReactEditorContentProps>;
12
12
  className?: string;
13
13
  enableHotkey?: boolean;
14
+ /**
15
+ * Enable automatic markdown formatting for pasted content
16
+ * @default true
17
+ */
18
+ enablePasteMarkdown?: boolean;
19
+ /**
20
+ * Enable/disable markdown shortcuts
21
+ * @default true - all formats enabled
22
+ */
23
+ markdownOption?: CommonPluginOptions['markdownOption'];
14
24
  onBlur?: (props: {
15
25
  editor: IEditor;
16
26
  event: FocusEvent<HTMLDivElement>;
@@ -63,104 +63,104 @@ function convertMdastToLexical(node, index, ctx) {
63
63
  }
64
64
  default:
65
65
  {
66
- if (markdownReaders[node.type]) {
67
- var _children = [];
68
- if ('children' in node && Array.isArray(node.children)) {
69
- var htmlStack = []; // 当前循环是否包含 HTML 标签
70
- _children = node.children.reduce(function (ret, child, index) {
71
- if (child.type === 'html') {
72
- var tag = child.value.replaceAll(/^<\/?|>$/g, '');
73
- var isEndTag = child.value.startsWith('</');
74
- if (selfClosingHtmlTags.has(tag)) {
75
- // Self-closing tag
76
- var _reader = markdownReaders['html'];
77
- if (Array.isArray(_reader)) {
78
- var _iterator = _createForOfIteratorHelper(_reader),
79
- _step;
80
- try {
81
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
82
- var element = _step.value;
83
- var inode = element(child, [], index);
84
- if (inode) {
85
- ret.push(inode);
86
- return ret;
87
- }
66
+ var _children = [];
67
+ if ('children' in node && Array.isArray(node.children)) {
68
+ var htmlStack = []; // 当前循环是否包含 HTML 标签
69
+ _children = node.children.reduce(function (ret, child, index) {
70
+ if (child.type === 'html') {
71
+ var tag = child.value.replaceAll(/^<\/?|>$/g, '');
72
+ var isEndTag = child.value.startsWith('</');
73
+ if (selfClosingHtmlTags.has(tag)) {
74
+ // Self-closing tag
75
+ var reader = markdownReaders['html'];
76
+ if (Array.isArray(reader)) {
77
+ var _iterator = _createForOfIteratorHelper(reader),
78
+ _step;
79
+ try {
80
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
81
+ var element = _step.value;
82
+ var inode = element(child, [], index);
83
+ if (inode) {
84
+ ret.push(inode);
85
+ return ret;
88
86
  }
89
- } catch (err) {
90
- _iterator.e(err);
91
- } finally {
92
- _iterator.f();
93
- }
94
- } else if (typeof _reader === 'function') {
95
- var _inode = _reader(child, [], index);
96
- if (_inode) {
97
- ret.push(_inode);
98
- return ret;
99
87
  }
88
+ } catch (err) {
89
+ _iterator.e(err);
90
+ } finally {
91
+ _iterator.f();
100
92
  }
101
- return ret;
102
- }
103
- if (isEndTag) {
104
- var top = ctx.pop();
105
- htmlStack.pop();
106
- if ((top === null || top === void 0 ? void 0 : top.tag) !== tag) {
107
- logger.warn('HTML tag mismatch:', tag);
108
- ret.push.apply(ret, _toConsumableArray((top === null || top === void 0 ? void 0 : top.children) || []));
93
+ } else if (typeof reader === 'function') {
94
+ var _inode = reader(child, [], index);
95
+ if (_inode) {
96
+ ret.push(_inode);
109
97
  return ret;
110
98
  }
111
- var _reader2 = markdownReaders['html'];
112
- var _children2 = top.children.flat().filter(Boolean) || [];
113
- if (Array.isArray(_reader2)) {
114
- var _iterator2 = _createForOfIteratorHelper(_reader2),
115
- _step2;
116
- try {
117
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
118
- var _element = _step2.value;
119
- var _inode2 = _element(top.node, _children2, index);
120
- if (_inode2) {
121
- ret.push(_inode2);
122
- return ret;
123
- }
99
+ }
100
+ return ret;
101
+ }
102
+ if (isEndTag) {
103
+ var top = ctx.pop();
104
+ htmlStack.pop();
105
+ if ((top === null || top === void 0 ? void 0 : top.tag) !== tag) {
106
+ logger.warn('HTML tag mismatch:', tag);
107
+ ret.push.apply(ret, _toConsumableArray((top === null || top === void 0 ? void 0 : top.children) || []));
108
+ return ret;
109
+ }
110
+ var _reader = markdownReaders['html'];
111
+ var _children2 = top.children.flat().filter(Boolean) || [];
112
+ if (Array.isArray(_reader)) {
113
+ var _iterator2 = _createForOfIteratorHelper(_reader),
114
+ _step2;
115
+ try {
116
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
117
+ var _element = _step2.value;
118
+ var _inode2 = _element(top.node, _children2, index);
119
+ if (_inode2) {
120
+ ret.push(_inode2);
121
+ return ret;
124
122
  }
125
- } catch (err) {
126
- _iterator2.e(err);
127
- } finally {
128
- _iterator2.f();
129
- }
130
- } else if (typeof _reader2 === 'function') {
131
- var _inode3 = _reader2(top.node, _children2, index);
132
- if (_inode3) {
133
- ret.push(_inode3);
134
- return ret;
135
123
  }
124
+ } catch (err) {
125
+ _iterator2.e(err);
126
+ } finally {
127
+ _iterator2.f();
136
128
  }
137
- if (top) {
138
- ret.push.apply(ret, _toConsumableArray(top.children));
129
+ } else if (typeof _reader === 'function') {
130
+ var _inode3 = _reader(top.node, _children2, index);
131
+ if (_inode3) {
132
+ ret.push(_inode3);
133
+ return ret;
139
134
  }
140
- return ret;
141
135
  }
142
- var htmlStackItem = {
143
- children: [],
144
- index: index,
145
- isEndTag: isEndTag,
146
- node: child,
147
- tag: tag
148
- };
149
- htmlStack.push(htmlStackItem);
150
- ctx.push(htmlStackItem);
151
- return ret;
152
- }
153
- if (htmlStack.length > 0) {
154
- var _top = ctx.last;
155
- if (_top) {
156
- _top.children.push(convertMdastToLexical(child, index, ctx, markdownReaders));
136
+ if (top) {
137
+ ret.push.apply(ret, _toConsumableArray(top.children));
157
138
  }
158
139
  return ret;
159
140
  }
160
- ret.push(convertMdastToLexical(child, index, ctx, markdownReaders));
141
+ var htmlStackItem = {
142
+ children: [],
143
+ index: index,
144
+ isEndTag: isEndTag,
145
+ node: child,
146
+ tag: tag
147
+ };
148
+ htmlStack.push(htmlStackItem);
149
+ ctx.push(htmlStackItem);
161
150
  return ret;
162
- }, []).filter(Boolean).flat();
163
- }
151
+ }
152
+ if (htmlStack.length > 0) {
153
+ var _top = ctx.last;
154
+ if (_top) {
155
+ _top.children.push(convertMdastToLexical(child, index, ctx, markdownReaders));
156
+ }
157
+ return ret;
158
+ }
159
+ ret.push(convertMdastToLexical(child, index, ctx, markdownReaders));
160
+ return ret;
161
+ }, []).filter(Boolean).flat();
162
+ }
163
+ if (markdownReaders[node.type]) {
164
164
  var reader = markdownReaders[node.type];
165
165
  if (Array.isArray(reader)) {
166
166
  var _iterator3 = _createForOfIteratorHelper(reader),
@@ -187,7 +187,7 @@ function convertMdastToLexical(node, index, ctx) {
187
187
  }
188
188
 
189
189
  // Fallback for unsupported nodes
190
- return null;
190
+ return _children || null;
191
191
  }
192
192
  }
193
193
  }
@@ -1,4 +1,9 @@
1
1
  import { IEditorPluginConstructor } from "../../../types";
2
2
  export interface MarkdownPluginOptions {
3
+ /**
4
+ * Enable automatic markdown formatting for pasted content
5
+ * @default true
6
+ */
7
+ enablePasteMarkdown?: boolean;
3
8
  }
4
9
  export declare const MarkdownPlugin: IEditorPluginConstructor<MarkdownPluginOptions>;
@@ -21,19 +21,17 @@ import MarkdownDataSource from "../data-source/markdown-data-source";
21
21
  import { parseMarkdownToLexical } from "../data-source/markdown/parse";
22
22
  import { IMarkdownShortCutService, MarkdownShortCutService } from "../service/shortcut";
23
23
  import { $generateNodesFromSerializedNodes, $insertGeneratedNodes, canContainTransformableMarkdown } from "../utils";
24
-
25
- // eslint-disable-next-line @typescript-eslint/no-empty-interface
26
-
27
24
  export var MarkdownPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
28
25
  _inherits(MarkdownPlugin, _KernelPlugin);
29
26
  var _super = _createSuper(MarkdownPlugin);
30
- function MarkdownPlugin(kernel) {
27
+ function MarkdownPlugin(kernel, config) {
31
28
  var _this;
32
29
  _classCallCheck(this, MarkdownPlugin);
33
30
  _this = _super.call(this);
34
31
  _defineProperty(_assertThisInitialized(_this), "logger", createDebugLogger('plugin', 'markdown'));
35
32
  _defineProperty(_assertThisInitialized(_this), "service", void 0);
36
33
  _this.kernel = kernel;
34
+ _this.config = config;
37
35
  _this.service = new MarkdownShortCutService(kernel);
38
36
  kernel.registerService(IMarkdownShortCutService, _this.service);
39
37
  // @todo To be implemented
@@ -121,6 +119,13 @@ export var MarkdownPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
121
119
  return false;
122
120
  }, COMMAND_PRIORITY_CRITICAL));
123
121
  this.register(editor.registerCommand(PASTE_COMMAND, function (event) {
122
+ var _this2$config$enableP, _this2$config;
123
+ // Check if markdown paste formatting is enabled (default: true)
124
+ var enablePasteMarkdown = (_this2$config$enableP = (_this2$config = _this2.config) === null || _this2$config === void 0 ? void 0 : _this2$config.enablePasteMarkdown) !== null && _this2$config$enableP !== void 0 ? _this2$config$enableP : true;
125
+ if (!enablePasteMarkdown) {
126
+ _this2.logger.debug('paste markdown formatting is disabled');
127
+ return false;
128
+ }
124
129
  if (!(event instanceof ClipboardEvent)) return false;
125
130
  var clipboardData = event.clipboardData;
126
131
  if (!clipboardData) return false;
@@ -40,6 +40,10 @@ var Editor = /*#__PURE__*/memo(function (_ref) {
40
40
  onFocus = _ref.onFocus,
41
41
  onBlur = _ref.onBlur,
42
42
  autoFocus = _ref.autoFocus,
43
+ _ref$enablePasteMarkd = _ref.enablePasteMarkdown,
44
+ enablePasteMarkdown = _ref$enablePasteMarkd === void 0 ? true : _ref$enablePasteMarkd,
45
+ _ref$markdownOption = _ref.markdownOption,
46
+ markdownOption = _ref$markdownOption === void 0 ? true : _ref$markdownOption,
43
47
  onCompositionStart = _ref.onCompositionStart,
44
48
  onCompositionEnd = _ref.onCompositionEnd,
45
49
  onContextMenu = _ref.onContextMenu;
@@ -86,6 +90,8 @@ var Editor = /*#__PURE__*/memo(function (_ref) {
86
90
  children: [memoPlugins, memoSlash, memoMention, /*#__PURE__*/_jsx(ReactPlainText, {
87
91
  autoFocus: autoFocus,
88
92
  className: className,
93
+ enablePasteMarkdown: enablePasteMarkdown,
94
+ markdownOption: markdownOption,
89
95
  onBlur: onBlur,
90
96
  onChange: onChange,
91
97
  onCompositionEnd: onCompositionEnd,
@@ -12,6 +12,21 @@ export interface EditorProps extends Partial<ReactEditorContentProps>, Omit<Reac
12
12
  children?: ReactNode;
13
13
  className?: string;
14
14
  editor?: IEditor;
15
+ /**
16
+ * Enable automatic markdown formatting for pasted content
17
+ * @default true
18
+ */
19
+ enablePasteMarkdown?: boolean;
20
+ markdownOption?: boolean | {
21
+ bold?: boolean;
22
+ code?: boolean;
23
+ header?: boolean;
24
+ italic?: boolean;
25
+ quote?: boolean;
26
+ strikethrough?: boolean;
27
+ underline?: boolean;
28
+ underlineStrikethrough?: boolean;
29
+ };
15
30
  mentionOption?: MentionOption;
16
31
  onInit?: (editor: IEditor) => void;
17
32
  plugins?: EditorPlugin[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/editor",
3
- "version": "1.14.2",
3
+ "version": "1.16.0",
4
4
  "description": "A powerful and extensible rich text editor built on Meta's Lexical framework, providing a modern editing experience with React integration.",
5
5
  "keywords": [
6
6
  "lobehub",