@lobehub/editor 1.4.7 → 1.5.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 (98) hide show
  1. package/es/editor-kernel/kernel.d.ts +4 -1
  2. package/es/editor-kernel/kernel.js +56 -1
  3. package/es/index.d.ts +2 -0
  4. package/es/index.js +2 -0
  5. package/es/locale/index.d.ts +7 -0
  6. package/es/locale/index.js +7 -0
  7. package/es/plugins/code/command/index.d.ts +3 -0
  8. package/es/plugins/code/command/index.js +48 -0
  9. package/es/plugins/code/index.d.ts +3 -0
  10. package/es/plugins/code/index.js +3 -0
  11. package/es/plugins/code/node/code.d.ts +19 -0
  12. package/es/plugins/{common/node/LexicalLineBreakNode.js → code/node/code.js} +93 -95
  13. package/es/plugins/code/plugin/index.d.ts +5 -0
  14. package/es/plugins/{common/node/ParagraphNode.js → code/plugin/index.js} +40 -33
  15. package/es/plugins/code/plugin/registry.d.ts +3 -0
  16. package/es/plugins/code/plugin/registry.js +48 -0
  17. package/es/plugins/code/react/CodeReactPlugin.d.ts +4 -0
  18. package/es/plugins/code/react/CodeReactPlugin.js +31 -0
  19. package/es/plugins/code/react/index.d.ts +1 -0
  20. package/es/plugins/code/react/index.js +1 -0
  21. package/es/plugins/code/react/style.d.ts +3 -0
  22. package/es/plugins/code/react/style.js +10 -0
  23. package/es/plugins/code/react/type.d.ts +3 -0
  24. package/es/plugins/code/react/type.js +1 -0
  25. package/es/plugins/common/data-source/json-data-source.js +42 -5
  26. package/es/plugins/common/data-source/text-data-source.js +2 -2
  27. package/es/plugins/common/index.d.ts +1 -0
  28. package/es/plugins/common/index.js +1 -0
  29. package/es/plugins/common/node/ElementDOMSlot.d.ts +3 -5
  30. package/es/plugins/common/node/ElementDOMSlot.js +29 -56
  31. package/es/plugins/common/node/cursor.d.ts +12 -0
  32. package/es/plugins/common/node/cursor.js +303 -0
  33. package/es/plugins/common/plugin/index.js +11 -9
  34. package/es/plugins/common/plugin/register.d.ts +3 -1
  35. package/es/plugins/common/plugin/register.js +46 -13
  36. package/es/plugins/link/command/index.d.ts +5 -1
  37. package/es/plugins/link/command/index.js +21 -3
  38. package/es/plugins/link/react/ReactLinkPlugin.js +6 -9
  39. package/es/plugins/link/react/components/LinkEdit.d.ts +2 -1
  40. package/es/plugins/link/react/components/LinkEdit.js +195 -51
  41. package/es/plugins/link/react/components/LinkToolbar.d.ts +10 -0
  42. package/es/plugins/link/react/components/LinkToolbar.js +73 -0
  43. package/es/plugins/link/react/style.d.ts +3 -2
  44. package/es/plugins/link/react/style.js +8 -5
  45. package/es/plugins/list/command/index.d.ts +1 -0
  46. package/es/plugins/list/command/index.js +1 -0
  47. package/es/plugins/list/plugin/checkList.d.ts +3 -0
  48. package/es/plugins/list/plugin/checkList.js +167 -0
  49. package/es/plugins/list/plugin/index.js +9 -2
  50. package/es/plugins/list/react/style.js +4 -2
  51. package/es/plugins/markdown/data-source/markdown-data-source.js +5 -1
  52. package/es/plugins/markdown/service/shortcut.d.ts +3 -3
  53. package/es/plugins/math/command/index.d.ts +13 -0
  54. package/es/plugins/math/command/index.js +47 -0
  55. package/es/plugins/math/index.d.ts +3 -0
  56. package/es/plugins/math/index.js +3 -0
  57. package/es/plugins/math/node/index.d.ts +45 -0
  58. package/es/plugins/math/node/index.js +259 -0
  59. package/es/plugins/math/plugin/index.d.ts +11 -0
  60. package/es/plugins/math/plugin/index.js +103 -0
  61. package/es/plugins/math/react/component/MathEditor.d.ts +10 -0
  62. package/es/plugins/math/react/component/MathEditor.js +253 -0
  63. package/es/plugins/math/react/component/MathEditorContainer.d.ts +14 -0
  64. package/es/plugins/math/react/component/MathEditorContainer.js +60 -0
  65. package/es/plugins/math/react/component/MathEditorContent.d.ts +26 -0
  66. package/es/plugins/math/react/component/MathEditorContent.js +163 -0
  67. package/es/plugins/math/react/component/MathInline.d.ts +10 -0
  68. package/es/plugins/math/react/component/MathInline.js +105 -0
  69. package/es/plugins/math/react/component/Placeholder.d.ts +3 -0
  70. package/es/plugins/math/react/component/Placeholder.js +19 -0
  71. package/es/plugins/math/react/index.d.ts +3 -0
  72. package/es/plugins/math/react/index.js +43 -0
  73. package/es/plugins/math/react/style.d.ts +6 -0
  74. package/es/plugins/math/react/style.js +16 -0
  75. package/es/plugins/math/react/type.d.ts +13 -0
  76. package/es/plugins/math/react/type.js +1 -0
  77. package/es/plugins/slash/react/ReactSlashPlugin.js +12 -10
  78. package/es/react/FloatMenu/FloatMenu.d.ts +4 -0
  79. package/es/react/FloatMenu/FloatMenu.js +49 -0
  80. package/es/react/FloatMenu/index.d.ts +2 -0
  81. package/es/react/FloatMenu/index.js +2 -0
  82. package/es/react/FloatMenu/type.d.ts +19 -0
  83. package/es/react/FloatMenu/type.js +1 -0
  84. package/es/react/SlashMenu/SlashMenu.js +32 -48
  85. package/es/react/SlashMenu/type.d.ts +5 -13
  86. package/es/react/hooks/useEditorState/index.d.ts +4 -0
  87. package/es/react/hooks/useEditorState/index.js +40 -4
  88. package/es/react/index.d.ts +1 -0
  89. package/es/react/index.js +1 -0
  90. package/es/types/global.d.ts +4 -0
  91. package/es/types/kernel.d.ts +26 -1
  92. package/package.json +2 -1
  93. package/es/plugins/common/node/LexicalLineBreakNode.d.ts +0 -31
  94. package/es/plugins/common/node/ParagraphNode.d.ts +0 -7
  95. package/es/plugins/link/react/components/Toolbar.d.ts +0 -7
  96. package/es/plugins/link/react/components/Toolbar.js +0 -63
  97. /package/es/react/{SlashMenu → FloatMenu}/style.d.ts +0 -0
  98. /package/es/react/{SlashMenu → FloatMenu}/style.js +0 -0
@@ -6,29 +6,39 @@ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" !=
6
6
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
7
  import { computePosition, flip, offset, shift } from '@floating-ui/dom';
8
8
  import { mergeRegister } from '@lexical/utils';
9
- import { Icon, Input } from '@lobehub/ui';
9
+ import { Block, Button, Hotkey, Icon, Input, Text } from '@lobehub/ui';
10
10
  import { COMMAND_PRIORITY_EDITOR, COMMAND_PRIORITY_NORMAL, KEY_ESCAPE_COMMAND, KEY_TAB_COMMAND, createCommand } from 'lexical';
11
- import { LinkIcon } from 'lucide-react';
11
+ import { BaselineIcon, LinkIcon } from 'lucide-react';
12
12
  import { useCallback, useEffect, useRef, useState } from 'react';
13
+ import { Flexbox } from 'react-layout-kit';
13
14
  import { useLexicalComposerContext, useLexicalEditor } from "../../../../editor-kernel/react";
15
+ import { useTranslation } from "../../../../editor-kernel/react/useTranslation";
16
+ import { UPDATE_LINK_TEXT_COMMAND } from "../../command";
14
17
  import { useStyles } from "../style";
15
18
  import { jsx as _jsx } from "react/jsx-runtime";
19
+ import { jsxs as _jsxs } from "react/jsx-runtime";
16
20
  export var EDIT_LINK_COMMAND = createCommand();
17
- export var LinkEdit = function LinkEdit() {
21
+ var LinkEdit = function LinkEdit() {
18
22
  var divRef = useRef(null);
19
23
  var linkNodeRef = useRef(null);
20
24
  var linkInputRef = useRef(null);
25
+ var linkTextInputRef = useRef(null);
21
26
  var _useState = useState(''),
22
27
  _useState2 = _slicedToArray(_useState, 2),
23
28
  linkUrl = _useState2[0],
24
29
  setLinkUrl = _useState2[1];
25
- var _useState3 = useState(null),
30
+ var _useState3 = useState(''),
26
31
  _useState4 = _slicedToArray(_useState3, 2),
27
- linkDom = _useState4[0],
28
- setLinkDom = _useState4[1];
32
+ linkText = _useState4[0],
33
+ setLinkText = _useState4[1];
34
+ var _useState5 = useState(null),
35
+ _useState6 = _slicedToArray(_useState5, 2),
36
+ linkDom = _useState6[0],
37
+ setLinkDom = _useState6[1];
29
38
  var _useLexicalComposerCo = useLexicalComposerContext(),
30
39
  _useLexicalComposerCo2 = _slicedToArray(_useLexicalComposerCo, 1),
31
40
  editor = _useLexicalComposerCo2[0];
41
+ var t = useTranslation();
32
42
  var _useStyles = useStyles(),
33
43
  styles = _useStyles.styles,
34
44
  theme = _useStyles.theme;
@@ -48,39 +58,132 @@ export var LinkEdit = function LinkEdit() {
48
58
  }
49
59
  });
50
60
  }, [linkDom]);
51
- var handleKeyDown = useCallback(function (event) {
61
+
62
+ // 提取提交逻辑到独立函数
63
+ var handleSubmit = useCallback(function () {
52
64
  var lexicalEditor = editor.getLexicalEditor();
53
- if (!linkNodeRef.current || !linkInputRef.current || !lexicalEditor) {
65
+ if (!linkNodeRef.current || !linkInputRef.current || !linkTextInputRef.current || !lexicalEditor) {
54
66
  return;
55
67
  }
56
68
  var linkNode = linkNodeRef.current;
57
69
  var input = linkInputRef.current;
58
70
  var inputDOM = input.input;
59
- if (event.key === 'Enter') {
60
- event.preventDefault();
61
- var currentURL = lexicalEditor.read(function () {
62
- return linkNode.getURL();
71
+ var textInput = linkTextInputRef.current;
72
+ var textInputDOM = textInput.input;
73
+
74
+ // 更新链接URL
75
+ var currentURL = lexicalEditor.read(function () {
76
+ return linkNode.getURL();
77
+ });
78
+ if (currentURL !== inputDOM.value) {
79
+ lexicalEditor.update(function () {
80
+ linkNode.setURL(inputDOM.value);
63
81
  });
64
- if (currentURL !== inputDOM.value) {
65
- lexicalEditor.update(function () {
66
- linkNode.setURL(inputDOM.value);
67
- lexicalEditor.focus();
68
- });
69
- } else {
70
- lexicalEditor.focus();
71
- }
72
- return;
73
- } else if (event.key === 'Escape' || event.key === 'Tab') {
74
- event.preventDefault();
75
- lexicalEditor.focus();
82
+ }
83
+
84
+ // 更新链接文本
85
+ var currentText = lexicalEditor.read(function () {
86
+ return linkNode.getTextContent();
87
+ });
88
+ if (currentText !== textInputDOM.value) {
89
+ lexicalEditor.dispatchCommand(UPDATE_LINK_TEXT_COMMAND, {
90
+ key: linkNode.getKey(),
91
+ text: textInputDOM.value
92
+ });
93
+ }
94
+
95
+ // 关闭编辑器并聚焦到编辑器
96
+ lexicalEditor.focus();
97
+
98
+ // 隐藏编辑面板
99
+ if (divRef.current) {
100
+ divRef.current.style.left = '-9999px';
101
+ divRef.current.style.top = '-9999px';
102
+ }
103
+ linkNodeRef.current = null;
104
+ setLinkUrl('');
105
+ setLinkText('');
106
+ setLinkDom(null);
107
+ }, [editor, linkNodeRef, linkInputRef, linkTextInputRef]);
108
+
109
+ // 取消编辑,不保存更改
110
+ var handleCancel = useCallback(function () {
111
+ var lexicalEditor = editor.getLexicalEditor();
112
+ if (!lexicalEditor) return;
113
+
114
+ // 将焦点返回到编辑器
115
+ lexicalEditor.focus();
116
+
117
+ // 隐藏编辑面板
118
+ if (divRef.current) {
119
+ divRef.current.style.left = '-9999px';
120
+ divRef.current.style.top = '-9999px';
121
+ }
122
+ linkNodeRef.current = null;
123
+ setLinkUrl('');
124
+ setLinkText('');
125
+ setLinkDom(null);
126
+ }, [editor]);
127
+ var handleKeyDown = useCallback(function (event) {
128
+ var lexicalEditor = editor.getLexicalEditor();
129
+ if (!linkNodeRef.current || !linkInputRef.current || !linkTextInputRef.current || !lexicalEditor) {
76
130
  return;
77
131
  }
78
- }, [linkNodeRef, linkInputRef]);
132
+ var linkNode = linkNodeRef.current;
133
+ var input = linkInputRef.current;
134
+ var inputDOM = input.input;
135
+ var textInput = linkTextInputRef.current;
136
+ var textInputDOM = textInput.input;
137
+ switch (event.key) {
138
+ case 'Enter':
139
+ {
140
+ event.preventDefault();
141
+ if (event.currentTarget === textInputDOM) {
142
+ var currentText = lexicalEditor.read(function () {
143
+ return linkNode.getTextContent();
144
+ });
145
+ if (currentText !== textInputDOM.value) {
146
+ lexicalEditor.dispatchCommand(UPDATE_LINK_TEXT_COMMAND, {
147
+ key: linkNode.getKey(),
148
+ text: textInputDOM.value
149
+ });
150
+ // 更新文本后跳转到链接输入框
151
+ inputDOM.focus();
152
+ } else {
153
+ // 如果文本没有变化,直接跳转到链接输入框
154
+ inputDOM.focus();
155
+ }
156
+ } else if (event.currentTarget === inputDOM) {
157
+ // 在链接输入框按回车时提交所有更改
158
+ handleSubmit();
159
+ }
160
+ return;
161
+ }
162
+ case 'Tab':
163
+ {
164
+ event.preventDefault();
165
+ if (event.currentTarget === textInputDOM) {
166
+ inputDOM.focus();
167
+ } else {
168
+ lexicalEditor.focus();
169
+ }
170
+ return;
171
+ }
172
+ case 'Escape':
173
+ {
174
+ event.preventDefault();
175
+ handleCancel();
176
+ return;
177
+ }
178
+ // No default
179
+ }
180
+ }, [linkNodeRef, linkInputRef, handleSubmit, handleCancel]);
79
181
  useLexicalEditor(function (editor) {
80
182
  return mergeRegister(editor.registerCommand(EDIT_LINK_COMMAND, function (payload) {
81
183
  if (!payload.linkNode || !payload.linkNodeDOM) {
82
184
  setLinkDom(null);
83
185
  setLinkUrl('');
186
+ setLinkText('');
84
187
  if (divRef.current) {
85
188
  divRef.current.style.left = '-9999px';
86
189
  divRef.current.style.top = '-9999px';
@@ -89,6 +192,7 @@ export var LinkEdit = function LinkEdit() {
89
192
  }
90
193
  linkNodeRef.current = payload.linkNode;
91
194
  setLinkUrl(payload.linkNode.getURL());
195
+ setLinkText(payload.linkNode.getTextContent());
92
196
  setLinkDom(payload.linkNodeDOM);
93
197
  return true;
94
198
  }, COMMAND_PRIORITY_EDITOR), editor.registerCommand(KEY_ESCAPE_COMMAND, function () {
@@ -98,41 +202,81 @@ export var LinkEdit = function LinkEdit() {
98
202
  }
99
203
  linkNodeRef.current = null;
100
204
  setLinkUrl('');
205
+ setLinkText('');
101
206
  setLinkDom(null);
102
207
  return true;
103
208
  }, COMMAND_PRIORITY_EDITOR), editor.registerCommand(KEY_TAB_COMMAND, function (payload) {
104
- if (linkNodeRef.current && linkInputRef.current) {
209
+ if (linkNodeRef.current && linkTextInputRef.current) {
105
210
  payload.stopImmediatePropagation();
106
211
  payload.preventDefault();
107
- linkInputRef.current.focus();
212
+ linkTextInputRef.current.focus();
108
213
  return true;
109
214
  }
110
215
  return false;
111
216
  }, COMMAND_PRIORITY_NORMAL));
112
217
  }, []);
113
- return /*#__PURE__*/_jsx("div", {
114
- className: styles.editor_linkEdit,
218
+ return /*#__PURE__*/_jsxs(Block, {
219
+ className: styles.linkEdit,
115
220
  ref: divRef,
116
- children: /*#__PURE__*/_jsx(Input, {
117
- onChange: function onChange(e) {
118
- // Handle link URL change
119
- setLinkUrl(e.target.value);
120
- },
121
- onKeyDown: handleKeyDown,
122
- placeholder: "https://enter-link-url",
123
- prefix: /*#__PURE__*/_jsx(Icon, {
124
- color: theme.colorTextDescription,
125
- icon: LinkIcon
126
- }),
127
- ref: linkInputRef,
128
- shadow: true,
129
- style: {
130
- background: theme.colorBgElevated,
131
- maxWidth: '100%',
132
- minWidth: 240
133
- },
134
- value: linkUrl,
135
- variant: 'outlined'
136
- })
221
+ shadow: true,
222
+ variant: 'outlined',
223
+ children: [/*#__PURE__*/_jsxs(Flexbox, {
224
+ gap: 8,
225
+ padding: 12,
226
+ children: [/*#__PURE__*/_jsx(Text, {
227
+ weight: 500,
228
+ children: t('link.editTextTitle')
229
+ }), /*#__PURE__*/_jsx(Input, {
230
+ onChange: function onChange(e) {
231
+ // Handle link text change
232
+ setLinkText(e.target.value);
233
+ },
234
+ onKeyDown: handleKeyDown,
235
+ prefix: /*#__PURE__*/_jsx(Icon, {
236
+ color: theme.colorTextDescription,
237
+ icon: BaselineIcon
238
+ }),
239
+ ref: linkTextInputRef,
240
+ value: linkText
241
+ }), /*#__PURE__*/_jsx(Text, {
242
+ weight: 500,
243
+ children: t('link.editLinkTitle')
244
+ }), /*#__PURE__*/_jsx(Input, {
245
+ onChange: function onChange(e) {
246
+ // Handle link URL change
247
+ setLinkUrl(e.target.value);
248
+ },
249
+ onKeyDown: handleKeyDown,
250
+ placeholder: "https://enter-link-url",
251
+ prefix: /*#__PURE__*/_jsx(Icon, {
252
+ color: theme.colorTextDescription,
253
+ icon: LinkIcon
254
+ }),
255
+ ref: linkInputRef,
256
+ value: linkUrl,
257
+ variant: 'outlined'
258
+ })]
259
+ }), /*#__PURE__*/_jsx(Flexbox, {
260
+ className: styles.linkEditFooter,
261
+ horizontal: true,
262
+ justify: 'flex-end',
263
+ padding: 4,
264
+ width: '100%',
265
+ children: /*#__PURE__*/_jsxs(Button, {
266
+ onClick: function onClick(e) {
267
+ e.preventDefault();
268
+ handleSubmit();
269
+ },
270
+ size: 'small',
271
+ type: 'text',
272
+ variant: 'filled',
273
+ children: [t('confirm'), /*#__PURE__*/_jsx(Hotkey, {
274
+ compact: true,
275
+ keys: "enter",
276
+ variant: 'borderless'
277
+ })]
278
+ })
279
+ })]
137
280
  });
138
- };
281
+ };
282
+ export default LinkEdit;
@@ -0,0 +1,10 @@
1
+ /// <reference types="react" />
2
+ import { type ActionIconGroupProps } from '@lobehub/ui';
3
+ import { LexicalEditor } from 'lexical';
4
+ import { LinkNode } from '../../node/LinkNode';
5
+ interface LinkToolbarProps extends Omit<ActionIconGroupProps, 'items'> {
6
+ editor: LexicalEditor;
7
+ linkNode: LinkNode | null;
8
+ }
9
+ declare const LinkToolbar: import("react").NamedExoticComponent<LinkToolbarProps>;
10
+ export default LinkToolbar;
@@ -0,0 +1,73 @@
1
+ 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); }
2
+ var _excluded = ["linkNode", "editor"];
3
+ 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; }
4
+ 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; }
5
+ 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; }
6
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
7
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
8
+ function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
9
+ function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
10
+ import { ActionIconGroup } from '@lobehub/ui';
11
+ import { EditIcon, ExternalLinkIcon, UnlinkIcon } from 'lucide-react';
12
+ import { memo } from 'react';
13
+ import { useTranslation } from "../../../../editor-kernel/react/useTranslation";
14
+ import { TOGGLE_LINK_COMMAND } from "../../node/LinkNode";
15
+ import { useStyles } from "../style";
16
+ import { EDIT_LINK_COMMAND } from "./LinkEdit";
17
+ import { jsx as _jsx } from "react/jsx-runtime";
18
+ var LinkToolbar = /*#__PURE__*/memo(function (_ref) {
19
+ var linkNode = _ref.linkNode,
20
+ editor = _ref.editor,
21
+ rest = _objectWithoutProperties(_ref, _excluded);
22
+ var _useStyles = useStyles(),
23
+ styles = _useStyles.styles;
24
+ var t = useTranslation();
25
+ var handleEdit = function handleEdit() {
26
+ // Edit link
27
+ if (linkNode) {
28
+ editor.dispatchCommand(EDIT_LINK_COMMAND, {
29
+ linkNode: linkNode,
30
+ linkNodeDOM: editor.getElementByKey(linkNode.getKey())
31
+ });
32
+ }
33
+ };
34
+ var handleRemove = function handleRemove() {
35
+ // Remove link
36
+ editor.dispatchCommand(TOGGLE_LINK_COMMAND, null);
37
+ };
38
+ var handleOpenLink = function handleOpenLink() {
39
+ // Open link in new window
40
+ if (linkNode) {
41
+ var url = editor.read(function () {
42
+ return linkNode.getURL();
43
+ });
44
+ window.open(url, '_blank');
45
+ }
46
+ };
47
+ return /*#__PURE__*/_jsx(ActionIconGroup, _objectSpread({
48
+ className: styles.linkToolbar,
49
+ items: [{
50
+ icon: EditIcon,
51
+ key: 'edit',
52
+ label: t('link.edit'),
53
+ onClick: handleEdit
54
+ }, {
55
+ icon: ExternalLinkIcon,
56
+ key: 'openLink',
57
+ label: t('link.open'),
58
+ onClick: handleOpenLink
59
+ }, {
60
+ icon: UnlinkIcon,
61
+ key: 'unlink',
62
+ label: t('link.unlink'),
63
+ onClick: handleRemove
64
+ }],
65
+ shadow: true,
66
+ size: {
67
+ blockSize: 32,
68
+ size: 16
69
+ },
70
+ variant: 'outlined'
71
+ }, rest));
72
+ });
73
+ export default LinkToolbar;
@@ -1,5 +1,6 @@
1
1
  export declare const useStyles: (props?: unknown) => import("antd-style").ReturnStyles<{
2
- editor_linkEdit: import("antd-style").SerializedStyles;
3
- editor_linkPlugin: import("antd-style").SerializedStyles;
4
2
  link: import("antd-style").SerializedStyles;
3
+ linkEdit: string;
4
+ linkEditFooter: import("antd-style").SerializedStyles;
5
+ linkToolbar: string;
5
6
  }>;
@@ -1,12 +1,15 @@
1
- var _templateObject, _templateObject2;
1
+ var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5;
2
2
  function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
3
3
  import { createStyles } from 'antd-style';
4
4
  export var useStyles = createStyles(function (_ref) {
5
- var css = _ref.css;
5
+ var cx = _ref.cx,
6
+ css = _ref.css,
7
+ token = _ref.token;
6
8
  var position = css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n position: absolute;\n z-index: 999;\n inset-block-start: -9999px;\n inset-inline-start: -9999px;\n "])));
7
9
  return {
8
- editor_linkEdit: position,
9
- editor_linkPlugin: position,
10
- link: css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n cursor: pointer;\n\n margin-block: 1em;\n margin-inline: 0;\n padding: 2px;\n border: none;\n "])))
10
+ link: css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n cursor: pointer;\n\n margin-block: 1em;\n margin-inline: 0;\n padding: 2px;\n border: none;\n "]))),
11
+ linkEdit: cx(position, css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n min-width: 320px;\n max-width: 100%;\n background: ", ";\n "])), token.colorBgElevated)),
12
+ linkEditFooter: css(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n border-block-start: 1px solid ", ";\n background: ", ";\n "])), token.colorBorderSecondary, token.colorFillQuaternary),
13
+ linkToolbar: cx(position, css(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n background: ", ";\n "])), token.colorBgElevated))
11
14
  };
12
15
  });
@@ -1 +1,2 @@
1
+ export { INSERT_CHECK_LIST_COMMAND } from '../plugin/checkList';
1
2
  export { INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND, REMOVE_LIST_COMMAND, UPDATE_LIST_START_COMMAND, } from '@lexical/list';
@@ -1 +1,2 @@
1
+ export { INSERT_CHECK_LIST_COMMAND } from "../plugin/checkList";
1
2
  export { INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND, REMOVE_LIST_COMMAND, UPDATE_LIST_START_COMMAND } from '@lexical/list';
@@ -0,0 +1,3 @@
1
+ import type { LexicalCommand, LexicalEditor } from 'lexical';
2
+ export declare const INSERT_CHECK_LIST_COMMAND: LexicalCommand<void>;
3
+ export declare function registerCheckList(editor: LexicalEditor): () => void;
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ import { $insertList, $isListItemNode, $isListNode } from '@lexical/list';
9
+ import { $findMatchingParent, calculateZoomLevel, isHTMLElement, mergeRegister } from '@lexical/utils';
10
+ import { $getNearestNodeFromDOMNode, $getSelection, $isElementNode, $isRangeSelection, COMMAND_PRIORITY_LOW, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_LEFT_COMMAND, KEY_ARROW_UP_COMMAND, createCommand, getNearestEditorFromDOMNode } from 'lexical';
11
+ export var INSERT_CHECK_LIST_COMMAND = createCommand('INSERT_CHECK_LIST_COMMAND');
12
+ function handleCheckItemEvent(event, callback) {
13
+ var target = event.target;
14
+ if (!isHTMLElement(target)) {
15
+ return;
16
+ }
17
+
18
+ // Ignore clicks on LI that have nested lists
19
+ var firstChild = target.firstChild;
20
+ if (isHTMLElement(firstChild) && (firstChild.tagName === 'UL' || firstChild.tagName === 'OL')) {
21
+ return;
22
+ }
23
+ var parentNode = target.parentNode;
24
+
25
+ // @ts-ignore internal field
26
+ if (!parentNode || parentNode.__lexicalListType !== 'check') {
27
+ return;
28
+ }
29
+ var rect = target.getBoundingClientRect();
30
+ var zoom = calculateZoomLevel(target);
31
+ var clientX = event.clientX / zoom;
32
+
33
+ // Use getComputedStyle if available, otherwise fallback to 0px width
34
+ var beforeStyles = window.getComputedStyle ? window.getComputedStyle(target, '::before') : {
35
+ width: '0px'
36
+ };
37
+ var beforeWidthInPixels = parseFloat(beforeStyles.width);
38
+ var beforeMargin = parseFloat(beforeStyles.marginLeft);
39
+
40
+ // Make click area slightly larger for touch devices to improve accessibility
41
+ var isTouchEvent = event.pointerType === 'touch';
42
+ var clickAreaPadding = isTouchEvent ? 32 : 0; // Add 32px padding for touch events
43
+
44
+ if (target.dir === 'rtl' ? clientX < rect.right + clickAreaPadding && clientX > rect.right - beforeWidthInPixels - clickAreaPadding : clientX > rect.left + beforeMargin - clickAreaPadding && clientX < rect.left + beforeMargin + beforeWidthInPixels + clickAreaPadding) {
45
+ callback();
46
+ }
47
+ }
48
+ function handleClick(event) {
49
+ handleCheckItemEvent(event, function () {
50
+ if (isHTMLElement(event.target)) {
51
+ var domNode = event.target;
52
+ var editor = getNearestEditorFromDOMNode(domNode);
53
+ if (editor && editor.isEditable()) {
54
+ editor.update(function () {
55
+ var node = $getNearestNodeFromDOMNode(domNode);
56
+ if ($isListItemNode(node)) {
57
+ domNode.focus();
58
+ node.toggleChecked();
59
+ }
60
+ });
61
+ }
62
+ }
63
+ });
64
+ }
65
+ function handlePointerDown(event) {
66
+ handleCheckItemEvent(event, function () {
67
+ // Prevents caret moving when clicking on check mark
68
+ event.preventDefault();
69
+ });
70
+ }
71
+ function getActiveCheckListItem() {
72
+ var activeElement = document.activeElement;
73
+ return isHTMLElement(activeElement) && activeElement.tagName === 'LI' && activeElement.parentNode &&
74
+ // @ts-ignore internal field
75
+ activeElement.parentNode.__lexicalListType === 'check' ? activeElement : null;
76
+ }
77
+ function findCheckListItemSibling(node, backward) {
78
+ var sibling = backward ? node.getPreviousSibling() : node.getNextSibling();
79
+ var parent = node;
80
+
81
+ // Going up in a tree to get non-null sibling
82
+ while (!sibling && $isListItemNode(parent)) {
83
+ // Get li -> parent ul/ol -> parent li
84
+ parent = parent.getParentOrThrow().getParent();
85
+ if (parent) {
86
+ sibling = backward ? parent.getPreviousSibling() : parent.getNextSibling();
87
+ }
88
+ }
89
+
90
+ // Going down in a tree to get first non-nested list item
91
+ while ($isListItemNode(sibling)) {
92
+ var firstChild = backward ? sibling.getLastChild() : sibling.getFirstChild();
93
+ if (!$isListNode(firstChild)) {
94
+ return sibling;
95
+ }
96
+ sibling = backward ? firstChild.getLastChild() : firstChild.getFirstChild();
97
+ }
98
+ return null;
99
+ }
100
+ function handleArrowUpOrDown(event, editor, backward) {
101
+ var activeItem = getActiveCheckListItem();
102
+ if (activeItem) {
103
+ editor.update(function () {
104
+ var listItem = $getNearestNodeFromDOMNode(activeItem);
105
+ if (!$isListItemNode(listItem)) {
106
+ return;
107
+ }
108
+ var nextListItem = findCheckListItemSibling(listItem, backward);
109
+ if (nextListItem) {
110
+ nextListItem.selectStart();
111
+ var dom = editor.getElementByKey(nextListItem.__key);
112
+ if (dom) {
113
+ event.preventDefault();
114
+ setTimeout(function () {
115
+ dom.focus();
116
+ }, 0);
117
+ }
118
+ }
119
+ });
120
+ }
121
+ return false;
122
+ }
123
+ export function registerCheckList(editor) {
124
+ return mergeRegister(editor.registerCommand(INSERT_CHECK_LIST_COMMAND, function () {
125
+ $insertList('check');
126
+ return true;
127
+ }, COMMAND_PRIORITY_LOW), editor.registerCommand(KEY_ARROW_DOWN_COMMAND, function (event) {
128
+ return handleArrowUpOrDown(event, editor, false);
129
+ }, COMMAND_PRIORITY_LOW), editor.registerCommand(KEY_ARROW_UP_COMMAND, function (event) {
130
+ return handleArrowUpOrDown(event, editor, true);
131
+ }, COMMAND_PRIORITY_LOW), editor.registerCommand(KEY_ARROW_LEFT_COMMAND, function (event) {
132
+ return editor.getEditorState().read(function () {
133
+ var selection = $getSelection();
134
+ if ($isRangeSelection(selection) && selection.isCollapsed()) {
135
+ var anchor = selection.anchor;
136
+ var isElement = anchor.type === 'element';
137
+ if (isElement || anchor.offset === 0) {
138
+ var anchorNode = anchor.getNode();
139
+ var elementNode = $findMatchingParent(anchorNode, function (node) {
140
+ return $isElementNode(node) && !node.isInline();
141
+ });
142
+ if ($isListItemNode(elementNode)) {
143
+ var parent = elementNode.getParent();
144
+ if ($isListNode(parent) && parent.getListType() === 'check' && (isElement || elementNode.getFirstDescendant() === anchorNode)) {
145
+ var domNode = editor.getElementByKey(elementNode.__key);
146
+ if (domNode && document.activeElement !== domNode) {
147
+ domNode.focus();
148
+ event.preventDefault();
149
+ return true;
150
+ }
151
+ }
152
+ }
153
+ }
154
+ }
155
+ return false;
156
+ });
157
+ }, COMMAND_PRIORITY_LOW), editor.registerRootListener(function (rootElement, prevElement) {
158
+ if (rootElement !== null) {
159
+ rootElement.addEventListener('click', handleClick);
160
+ rootElement.addEventListener('pointerdown', handlePointerDown);
161
+ }
162
+ if (prevElement !== null) {
163
+ prevElement.removeEventListener('click', handleClick);
164
+ prevElement.removeEventListener('pointerdown', handlePointerDown);
165
+ }
166
+ }));
167
+ }
@@ -20,6 +20,7 @@ import { $createParagraphNode, $getSelection, $isRangeSelection, $isRootNode, $i
20
20
  import { KernelPlugin } from "../../../editor-kernel/plugin";
21
21
  import { IMarkdownShortCutService } from "../../markdown";
22
22
  import { $indentOverTab, listReplace } from "../utils";
23
+ import { registerCheckList } from "./checkList";
23
24
  var ORDERED_LIST_REGEX = /^(\s*)(\d+)\.\s/;
24
25
  var UNORDERED_LIST_REGEX = /^(\s*)[*+-]\s/;
25
26
  var CHECK_LIST_REGEX = /^(\s*)(?:-\s)?\s?(\[(\s|x)?])\s/i;
@@ -41,7 +42,10 @@ export var ListPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
41
42
  kernel.registerThemes({
42
43
  // Define themes for list nodes here
43
44
  list: {
45
+ checklist: 'editor_listItemCheck',
44
46
  listitem: 'editor_listItem',
47
+ listitemChecked: 'editor_listItemChecked',
48
+ listitemUnchecked: 'editor_listItemUnchecked',
45
49
  nested: {
46
50
  listitem: 'editor_listItemNested'
47
51
  },
@@ -102,7 +106,7 @@ export var ListPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
102
106
  }
103
107
  case 'check':
104
108
  {
105
- ctx.wrap("".concat(prefix, "[").concat(node.getChecked() ? 'x' : ' ', "] "), '\n');
109
+ ctx.wrap("".concat(prefix, "- [").concat(node.getChecked() ? 'x' : ' ', "] "), '\n');
106
110
  break;
107
111
  }
108
112
  default:
@@ -118,6 +122,7 @@ export var ListPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
118
122
  key: "onInit",
119
123
  value: function onInit(editor) {
120
124
  this.register(registerList(editor));
125
+ this.register(registerCheckList(editor));
121
126
  this.register(registerListStrictIndentTransform(editor));
122
127
  this.registerClears(editor.registerCommand(KEY_TAB_COMMAND, function (event) {
123
128
  var selection = $getSelection();
@@ -139,7 +144,9 @@ export var ListPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
139
144
  }
140
145
  var anchorNode = anchor.getNode();
141
146
  var listItemNode;
142
- if ($isTextNode(anchorNode)) {
147
+ if ($isListItemNode(anchorNode)) {
148
+ listItemNode = anchorNode;
149
+ } else if ($isTextNode(anchorNode)) {
143
150
  // Do not handle non-leading text nodes
144
151
  if (anchorNode.getPreviousSibling()) {
145
152
  return false;