@ctzhian/tiptap 1.13.9 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dist/Editor/demo.js +133 -123
  2. package/dist/Editor/index.js +17 -0
  3. package/dist/EditorToolbar/index.js +11 -9
  4. package/dist/asset/css/index.css +5 -7
  5. package/dist/component/ActionDropdown/index.d.ts +5 -0
  6. package/dist/component/ActionDropdown/index.js +8 -3
  7. package/dist/component/CustomBubbleMenu/index.js +1 -1
  8. package/dist/component/CustomDragHandle/index.js +3 -59
  9. package/dist/component/FloatingPopover/index.d.ts +2 -2
  10. package/dist/component/HoverPopover/index.d.ts +2 -0
  11. package/dist/component/HoverPopover/index.js +22 -3
  12. package/dist/component/Icons/delete-back-2-line-icon.d.ts +6 -0
  13. package/dist/component/Icons/delete-back-2-line-icon.js +13 -0
  14. package/dist/component/Icons/{expand-horizontal-line.js → expand-horizontal-line-icon.js} +1 -1
  15. package/dist/component/Icons/index.d.ts +3 -2
  16. package/dist/component/Icons/index.js +4 -3
  17. package/dist/component/Menu/index.js +5 -1
  18. package/dist/contants/enums.d.ts +9 -0
  19. package/dist/contants/enums.js +61 -1
  20. package/dist/extension/component/Alert/index.js +141 -137
  21. package/dist/extension/component/Flow/Edit.d.ts +1 -1
  22. package/dist/extension/component/Flow/Edit.js +3 -31
  23. package/dist/extension/component/Flow/index.js +20 -19
  24. package/dist/extension/component/Image/index.d.ts +1 -0
  25. package/dist/extension/component/Image/index.js +16 -2
  26. package/dist/extension/component/Link/index.js +1 -1
  27. package/dist/extension/component/TableCellHandleMenu/index.d.ts +9 -0
  28. package/dist/extension/component/TableCellHandleMenu/index.js +500 -0
  29. package/dist/extension/component/TableExtendButton/TableExtendButton.css +30 -0
  30. package/dist/extension/component/TableExtendButton/index.d.ts +23 -0
  31. package/dist/extension/component/TableExtendButton/index.js +201 -0
  32. package/dist/extension/component/TableExtendButton/use-table-extend-row-column.d.ts +15 -0
  33. package/dist/extension/component/TableExtendButton/use-table-extend-row-column.js +87 -0
  34. package/dist/extension/component/TableHandle/TableHandleMenu.css +36 -0
  35. package/dist/extension/component/TableHandle/TableHandleMenu.d.ts +17 -0
  36. package/dist/extension/component/TableHandle/TableHandleMenu.js +685 -0
  37. package/dist/extension/component/TableHandle/index.d.ts +28 -0
  38. package/dist/extension/component/TableHandle/index.js +93 -0
  39. package/dist/extension/component/TableHandle/use-table-handle-positioning.d.ts +40 -0
  40. package/dist/extension/component/TableHandle/use-table-handle-positioning.js +193 -0
  41. package/dist/extension/component/TableHandle/use-table-handle-state.d.ts +22 -0
  42. package/dist/extension/component/TableHandle/use-table-handle-state.js +45 -0
  43. package/dist/extension/component/TableSelectionOverlay/index.d.ts +16 -0
  44. package/dist/extension/component/TableSelectionOverlay/index.js +452 -0
  45. package/dist/extension/component/Video/Insert.js +4 -2
  46. package/dist/extension/component/Video/Readonly.js +4 -11
  47. package/dist/extension/component/Video/index.d.ts +2 -1
  48. package/dist/extension/component/Video/index.js +447 -65
  49. package/dist/extension/extension/ImeComposition.d.ts +2 -0
  50. package/dist/extension/extension/ImeComposition.js +145 -0
  51. package/dist/extension/extension/index.d.ts +1 -0
  52. package/dist/extension/extension/index.js +1 -0
  53. package/dist/extension/index.js +2 -2
  54. package/dist/extension/node/FileHandler.d.ts +1 -1
  55. package/dist/extension/node/Flow/index.d.ts +0 -3
  56. package/dist/extension/node/Flow/index.js +7 -4
  57. package/dist/extension/node/Link/index.js +4 -3
  58. package/dist/extension/node/Table.js +236 -117
  59. package/dist/extension/node/TableHandler/create-image.d.ts +9 -0
  60. package/dist/extension/node/TableHandler/create-image.js +235 -0
  61. package/dist/extension/node/TableHandler/index.d.ts +15 -0
  62. package/dist/extension/node/TableHandler/index.js +33 -0
  63. package/dist/extension/node/TableHandler/plugin.d.ts +49 -0
  64. package/dist/extension/node/TableHandler/plugin.js +1030 -0
  65. package/dist/extension/node/TableOfContents/index.d.ts +5 -3
  66. package/dist/extension/node/TableOfContents/index.js +22 -2
  67. package/dist/extension/node/Video.d.ts +1 -0
  68. package/dist/extension/node/Video.js +38 -6
  69. package/dist/hook/index.js +1 -1
  70. package/dist/index.css +45 -29
  71. package/dist/type/index.d.ts +2 -0
  72. package/dist/util/index.d.ts +9 -0
  73. package/dist/util/index.js +26 -0
  74. package/dist/util/table-utils.d.ts +161 -0
  75. package/dist/util/table-utils.js +605 -0
  76. package/package.json +2 -1
  77. package/dist/extension/component/Table/ContextMenu.d.ts +0 -11
  78. package/dist/extension/component/Table/ContextMenu.js +0 -186
  79. package/dist/extension/component/Table/TableContextMenuPlugin.d.ts +0 -9
  80. package/dist/extension/component/Table/TableContextMenuPlugin.js +0 -336
  81. package/dist/extension/component/Table/index.d.ts +0 -2
  82. package/dist/extension/component/Table/index.js +0 -2
  83. /package/dist/component/Icons/{expand-horizontal-line.d.ts → expand-horizontal-line-icon.d.ts} +0 -0
@@ -6,93 +6,146 @@ import { Editor, EditorThemeProvider, EditorToolbar, useTiptap } from "./..";
6
6
  import { Box } from '@mui/material';
7
7
  import React from 'react';
8
8
  import "../index.css";
9
- var defaultContent = "#### tiptap \n[tiptap notion patch](https://tiptap.dev/docs/ui-components/templates/notion-like-editor)";
9
+ var EDITABLE = true;
10
+ var DEFAULT_CONTENT_TYPE = 'html';
11
+ var DEFAULT_HTML_CONTENT = "<p></p>\n<h6 id=\"a025f782-910f-4f17-9d0b-8f31f9cde175\" data-toc-id=\"a025f782-910f-4f17-9d0b-8f31f9cde175\"><span data-name=\"page_facing_up\" data-type=\"emoji\">\uD83D\uDCC4</span> \u6587\u672C\u5904\u7406</h6>\n<p>PandaWiki \u662F\u4E00\u6B3E AI \u5927\u6A21<code>\u578B\u9A71\u52A8\u7684\u5F00\u6E90\u77E5\u8BC6\u5E93\u642D</code>\u5EFA\u7CFB\u7EDF\uFF0CF<strong>AQ \u3001 \u535A\u5BA2\u7CFB\u7EDF \uFF0C\u501F\u52A9\u5927\u6A21\u578B\u7684\u529B\u91CF\u4E3A\u4F60\u63D0\u4F9B AI </strong>\u521B\u4F5C \u3001 AI \u95EE\u7B54 \u3001 AI \u641C\u7D22 \u7B49\u80FD\u529B\u3002\u501F<span style=\"color: rgb(90, 141, 218);\">\u52A9\u5927\u6A21\u578B\u7684</span><span style=\"background-color: rgb(255, 204, 188); color: rgb(90, 141, 218);\">\u529B\u91CF\u4E3A\u4F60\u63D0</span><span style=\"color: rgb(90, 141, 218);\">\u4F9B AI \u521B</span>\u4F5C\u80FD\u529B\u3002PandaWiki \u662F<u>\u4E00\u6B3E AI \u5927\u6A21\u578B\u9A71\u52A8\u7684\u5F00\u6E90\u77E5\u8BC6\u5E93\u642D\u5EFA\u7CFB\u7EDF\uFF0C\u5E2E</u>\u52A9\u4F60\u5FEB\u901F\u6784\u5EFA\u667A\u80FD\u5316\u7684 <s><u>\u4EA7\u54C1\u6587\u6863\u3001\u6280\u672F</u></s>\u6587\u6863\u3001FAQ \u3001<s> \u535A\u5BA2\u7CFB\u7EDF \uFF0C\u501F\u52A9\u5927\u6A21\u578B\u7684</s>\u529B\u91CF\u7CFB\u7EDF \uFF0C<span style=\"background-color: rgb(172, 84, 84);\">\u501F\u52A9\u5927\u6A21\u578B\u7684\u529B\u91CF\u4E3A\u4F60\u63D0\u4F9B AI \u521B\u4F5C \u3001 AI \u95EE</span>\u7B54 \u3001 AI \u641C\u7D22 \u7B49\u80FD\u529B\u3002\u7684\u529B\u91CF\u4E3A<mark>\u4F60\u63D0\u4F9B AI \u521B\u4F5C \u3001 AI \u95EE\u7B54 \u3001</mark> AI \u641C\u7D22\u3002</p>\n<h6 id=\"1739ed5e-f03c-4c2f-b763-37505601c935\" data-toc-id=\"1739ed5e-f03c-4c2f-b763-37505601c935\"><span data-name=\"video_camera\" data-type=\"emoji\">\uD83D\uDCF9</span> \u89C6\u9891</h6>\n<video src=\"https://media.w3.org/2010/05/sintel/trailer.mp4\" controls=\"true\" width=\"400\" data-align=\"center\"></video>\n<h6 id=\"746ea233-0e30-44a6-849a-090202217299\" data-toc-id=\"746ea233-0e30-44a6-849a-090202217299\">\u26A0\uFE0F \u8B66\u544A\u5757</h6>\n<div data-id=\"alert_5ysakwbhvqv\" data-variant=\"warning\" data-type=\"icon\" data-node=\"alert\"><p>\u6B64\u65F6\u8FD9\u662F\u4E00\u4E2A\u8B66\u544A\u5757\u3002</p></div>\n<h6 id=\"ebb64062-9efb-4de8-887f-7f8b7f9e54ca\" data-toc-id=\"ebb64062-9efb-4de8-887f-7f8b7f9e54ca\"><span data-name=\"bar_chart\" data-type=\"emoji\">\uD83D\uDCCA</span> \u6D41\u7A0B\u56FE\u64CD\u4F5C</h6>\n<div data-type=\"flow\" data-code=\"mindmap\n root((mindmap))\n Origins\n Long history\n ::icon(fa fa-book)\n Popularisation\n British popular psychology author Tony Buzan\n Research\n On effectiveness&lt;br/&gt;and features\n On Automatic creation\n Uses\n Creative techniques\n Strategic planning\n Argument mapping\n Tools\n Pen and paper\n Mermaid\" data-width=\"246px\"></div>\n<h6 id=\"4b8d8c4e-29dc-4674-928b-b9ded0e363ae\" data-toc-id=\"4b8d8c4e-29dc-4674-928b-b9ded0e363ae\"><span data-name=\"watch\" data-type=\"emoji\">\u231A</span> \u8868\u683C\u64CD\u4F5C</h6>\n<div class=\"tableWrapper\"><div class=\"table-container\"><table style=\"min-width: 661px;\"><colgroup><col style=\"width: 361px;\"><col style=\"min-width: 100px;\"><col style=\"min-width: 100px;\"><col style=\"min-width: 100px;\"></colgroup><tbody><tr class=\"table-row\"><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" colwidth=\"361\" data-background-color=\"\" data-text-align=\"center\" style=\"text-align: center;\"><p>\u94FE\u63A5</p></th><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" style=\"text-align: center;\"><p>\u590D\u6742\u6587\u672C</p></th><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" style=\"text-align: center;\"><p>\u56FE\u7247</p></th><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" style=\"text-align: center;\"><p>\u9644\u4EF6</p></th></tr><tr class=\"table-row\"><td colspan=\"1\" rowspan=\"1\" colwidth=\"361\" data-background-color=\"\" data-text-align=\"center\" data-vertical-align=\"middle\" style=\"text-align: center; vertical-align: middle;\"><p><a target=\"_blank\" class=\"MuiBox-root css-1ivg9gg\" type=\"icon\" rel=\"noopener noreferrer\" title=\"\u70B9\u51FB\u6B64\u5904\u8DF3\u8F6C\" href=\"http://localhost:8000/components/editor\">\u70B9\u51FB\u6B64\u5904\u8DF3\u8F6C</a></p></td><td colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" data-vertical-align=\"middle\" style=\"text-align: center; vertical-align: middle;\"><p><code>\u77E5</code><span style=\"background-color: rgb(255, 204, 188); color: rgb(90, 141, 218);\">\u529B</span><span style=\"color: rgb(90, 141, 218);\">\u4F9B</span><sup>\u5386</sup><sub>\u53F2</sub><u>\u52A8</u><s>\u5927</s><span style=\"background-color: rgb(172, 84, 84);\">\u501F</span><mark>\u7B54</mark></p></td><td colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" data-vertical-align=\"middle\" style=\"text-align: center; vertical-align: middle;\"><p><img src=\"https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg\" width=\"100\"></p></td><td colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" data-vertical-align=\"middle\" style=\"text-align: center; vertical-align: middle;\"><p><span data-tag=\"attachment\" url=\"\" title=\"\" size=\"0\" data-url=\"https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg\" data-title=\"\u8C01\u662F\u6211\u4EEC\u7684\u654C\u4EBA.txt\" data-size=\"18.27 KB\"></span></p></td></tr><tr class=\"table-row\"><td colspan=\"1\" rowspan=\"1\" colwidth=\"361\" data-background-color=\"\" data-text-align=\"center\" style=\"text-align: center;\"><video src=\"https://media.w3.org/2010/05/sintel/trailer.mp4\" controls=\"true\" width=\"75%\"></video></td><td colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" style=\"text-align: center;\"><p></p><p></p></td><td colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" style=\"text-align: center;\"><p></p></td><td colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" style=\"text-align: center;\"><p></p></td></tr></tbody></table></div><div class=\"table-controls\"></div><div class=\"table-selection-overlay-container\"></div></div>\n<p></p>\n";
12
+ var DEFAULT_MARKDOWN_CONTENT = "###### :page_facing_up: \u6587\u672C\u5904\u7406\n\nPandaWiki \u662F\u4E00\u6B3E AI \u5927\u6A21`\u578B\u9A71\u52A8\u7684\u5F00\u6E90\u77E5\u8BC6\u5E93\u642D`\u5EFA\u7CFB\u7EDF\uFF0CF**AQ \u3001 \u535A\u5BA2\u7CFB\u7EDF \uFF0C\u501F\u52A9\u5927\u6A21\u578B\u7684\u529B\u91CF\u4E3A\u4F60\u63D0\u4F9B AI **\u521B\u4F5C \u3001 AI \u95EE\u7B54 \u3001 AI \u641C\u7D22 \u7B49\u80FD\u529B\u3002\u501F\u52A9\u5927\u6A21\u578B\u7684\u529B\u91CF\u4E3A\u4F60\u63D0\u4F9B AI \u521B\u4F5C\u80FD\u529B\u3002PandaWiki \u662F++\u4E00\u6B3E AI \u5927\u6A21\u578B\u9A71\u52A8\u7684\u5F00\u6E90\u77E5\u8BC6\u5E93\u642D\u5EFA\u7CFB\u7EDF\uFF0C\u5E2E++\u52A9\u4F60\u5FEB\u901F\u6784\u5EFA\u667A\u80FD\u5316\u7684 ++~~\u4EA7\u54C1\u6587\u6863\u3001\u6280\u672F~~++\u6587\u6863\u3001FAQ \u3001~~ \u535A\u5BA2\u7CFB\u7EDF \uFF0C\u501F\u52A9\u5927\u6A21\u578B\u7684~~\u529B\u91CF\u7CFB\u7EDF \uFF0C\u501F\u52A9\u5927\u6A21\u578B\u7684\u529B\u91CF\u4E3A\u4F60\u63D0\u4F9B AI \u521B\u4F5C \u3001 AI \u95EE\u7B54 \u3001 AI \u641C\u7D22 \u7B49\u80FD\u529B\u3002\u7684\u529B\u91CF\u4E3A==\u4F60\u63D0\u4F9B AI \u521B\u4F5C \u3001 AI \u95EE\u7B54 \u3001== AI \u641C\u7D22\u3002\n\n###### :video_camera: \u89C6\u9891\n\n<video src=\"https://media.w3.org/2010/05/sintel/trailer.mp4\" width=\"400\" controls ></video>\n\n###### \u26A0\uFE0F \u8B66\u544A\u5757\n\n:::alert {#alert_5ysakwbhvqv indent=\"0\" variant=\"warning\" type=\"icon\"}\n\n\u6B64\u65F6\u8FD9\u662F\u4E00\u4E2A\u8B66\u544A\u5757\u3002\n\n:::\n\n###### :bar_chart: \u6D41\u7A0B\u56FE\u64CD\u4F5C\n\n```mermaid\nmindmap\n root((mindmap))\n Origins\n Long history\n ::icon(fa fa-book)\n Popularisation\n British popular psychology author Tony Buzan\n Research\n On effectiveness<br/>and features\n On Automatic creation\n Uses\n Creative techniques\n Strategic planning\n Argument mapping\n Tools\n Pen and paper\n Mermaid\n```\n\n###### :watch: \u8868\u683C\u64CD\u4F5C\n\n\n| \u94FE\u63A5 | \u590D\u6742\u6587\u672C | \u56FE\u7247 | \u9644\u4EF6 |\n| ------------------------------------------------------------------------------------------- | --------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |\n| [\u70B9\u51FB\u6B64\u5904\u8DF3\u8F6C](http://localhost:8000/components/editor) | `\u77E5`\u529B\u4F9B^\u5386^~\u53F2~++\u52A8++~~\u5927~~\u501F==\u7B54== | ![](https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg) | <a href=\"https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg\" target=\"_blank\" download=\"\u8C01\u662F\u6211\u4EEC\u7684\u654C\u4EBA.txt\">\u8C01\u662F\u6211\u4EEC\u7684\u654C\u4EBA.txt</a> |\n| <video src=\"https://media.w3.org/2010/05/sintel/trailer.mp4\" width=\"75%\" controls ></video> | \x1F | | |\n\n\n";
10
13
  var Reader = function Reader() {
11
- var handleTocUpdate = function handleTocUpdate(toc) {
12
- console.log('toc', toc);
14
+ // @ts-ignore
15
+ var isHtmlMode = DEFAULT_CONTENT_TYPE === 'html';
16
+ var content = isHtmlMode ? DEFAULT_HTML_CONTENT : DEFAULT_MARKDOWN_CONTENT;
17
+ var handleSave = function handleSave(editor) {
18
+ var value = isHtmlMode ? editor.getHTML() : editor.getMarkdown();
19
+ console.log("\u2B07\uFE0F ========= ".concat(DEFAULT_CONTENT_TYPE, " mode ========= \u2B07\uFE0F"));
20
+ console.log("%c".concat(JSON.stringify(value)), 'color: #42b983;');
21
+ console.log("\u2B06\uFE0F ========= end ========= \u2B06\uFE0F");
13
22
  };
14
- var _useTiptap = useTiptap({
15
- editable: true,
16
- exclude: ['invisibleCharacters'],
17
- contentType: 'markdown',
18
- onError: function onError(error) {
19
- alert(error.message);
20
- },
21
- onValidateUrl: function () {
22
- var _onValidateUrl = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(url, type) {
23
- return _regeneratorRuntime().wrap(function _callee$(_context) {
24
- while (1) switch (_context.prev = _context.next) {
25
- case 0:
26
- if (!url.startsWith('data:')) {
27
- _context.next = 2;
28
- break;
29
- }
30
- throw new Error("\u4E0D\u652F\u6301 base64 \u94FE\u63A5\uFF0C\u8BF7\u4F7F\u7528\u53EF\u8BBF\u95EE\u7684 ".concat(type, " URL"));
31
- case 2:
32
- _context.t0 = type;
33
- _context.next = _context.t0 === 'image' ? 5 : _context.t0 === 'video' ? 7 : _context.t0 === 'audio' ? 9 : _context.t0 === 'iframe' ? 11 : 13;
34
- break;
35
- case 5:
36
- if (!url.match(/\.(jpg|jpeg|png|gif|webp|svg)(\?.*)?$/i)) {
37
- console.warn('图片链接可能不是有效的图片格式');
38
- }
39
- return _context.abrupt("break", 13);
40
- case 7:
41
- if (!url.match(/\.(mp4|webm|ogg|mov|avi|wmv|flv|mkv)(\?.*)?$/i)) {
42
- console.warn('视频链接可能不是有效的视频格式');
43
- }
44
- return _context.abrupt("break", 13);
45
- case 9:
46
- if (!url.match(/\.(mp3|wav|ogg|m4a|flac|aac|wma)(\?.*)?$/i)) {
47
- console.warn('音频链接可能不是有效的音频格式');
48
- }
49
- return _context.abrupt("break", 13);
50
- case 11:
51
- // iframe 可以嵌入任何 URL,但可以检查是否是 HTTPS
52
- if (url.startsWith('http://') && !url.includes('localhost')) {
53
- console.warn('建议使用 HTTPS 链接以确保安全性');
23
+ var handleError = function handleError(error) {
24
+ alert(error.message);
25
+ };
26
+ var handleAiWritingGetSuggestion = /*#__PURE__*/function () {
27
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(_ref) {
28
+ var prefix, suffix;
29
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
30
+ while (1) switch (_context.prev = _context.next) {
31
+ case 0:
32
+ prefix = _ref.prefix, suffix = _ref.suffix;
33
+ console.log('onAiWritingGetSuggestion', prefix, suffix);
34
+ return _context.abrupt("return", new Promise(function (resolve) {
35
+ resolve(['this is a default suggestion.', 'we are good.', 'what is your name?', 'how are you?', 'what is your favorite color?', 'what is your favorite food?', 'what is your favorite animal?', 'what is your favorite book?', 'what is your favorite movie?', 'what is your favorite song?', 'what is your favorite artist?', 'what is your favorite band?', 'what is your favorite city?', 'what is your favorite country?', 'what is your favorite sport?'][Math.floor(Math.random() * 10)]);
36
+ }));
37
+ case 3:
38
+ case "end":
39
+ return _context.stop();
40
+ }
41
+ }, _callee);
42
+ }));
43
+ return function handleAiWritingGetSuggestion(_x) {
44
+ return _ref2.apply(this, arguments);
45
+ };
46
+ }();
47
+ var handleUpload = /*#__PURE__*/function () {
48
+ var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(file, onProgress) {
49
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
50
+ while (1) switch (_context2.prev = _context2.next) {
51
+ case 0:
52
+ return _context2.abrupt("return", new Promise(function (resolve) {
53
+ var progress = 0;
54
+ var interval = setInterval(function () {
55
+ progress += Math.random() * 20;
56
+ if (progress >= 100) {
57
+ progress = 100;
58
+ onProgress === null || onProgress === void 0 || onProgress({
59
+ progress: progress / 100
60
+ });
61
+ clearInterval(interval);
62
+ setTimeout(function () {
63
+ if (file.type.startsWith('image/')) {
64
+ resolve('https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg');
65
+ } else if (file.type.startsWith('video/')) {
66
+ resolve('http://vjs.zencdn.net/v/oceans.mp4');
67
+ } else {
68
+ resolve('https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg');
69
+ }
70
+ }, 200);
71
+ } else {
72
+ onProgress === null || onProgress === void 0 || onProgress({
73
+ progress: progress / 100
74
+ });
54
75
  }
55
- return _context.abrupt("break", 13);
56
- case 13:
57
- return _context.abrupt("return", url);
58
- case 14:
59
- case "end":
60
- return _context.stop();
61
- }
62
- }, _callee);
63
- }));
64
- function onValidateUrl(_x, _x2) {
65
- return _onValidateUrl.apply(this, arguments);
76
+ }, 100);
77
+ }));
78
+ case 1:
79
+ case "end":
80
+ return _context2.stop();
66
81
  }
67
- return onValidateUrl;
68
- }(),
69
- onSave: function onSave(editor) {
70
- var value = editor.getMarkdown();
71
- console.log(value);
72
- },
73
- onAiWritingGetSuggestion: function () {
74
- var _onAiWritingGetSuggestion = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(_ref) {
75
- var prefix, suffix;
76
- return _regeneratorRuntime().wrap(function _callee2$(_context2) {
77
- while (1) switch (_context2.prev = _context2.next) {
78
- case 0:
79
- prefix = _ref.prefix, suffix = _ref.suffix;
80
- console.log('onAiWritingGetSuggestion', prefix, suffix);
81
- return _context2.abrupt("return", new Promise(function (resolve) {
82
- resolve(['this is a default suggestion.', 'we are good.', 'what is your name?', 'how are you?', 'what is your favorite color?', 'what is your favorite food?', 'what is your favorite animal?', 'what is your favorite book?', 'what is your favorite movie?', 'what is your favorite song?', 'what is your favorite artist?', 'what is your favorite band?', 'what is your favorite city?', 'what is your favorite country?', 'what is your favorite sport?'][Math.floor(Math.random() * 10)]);
83
- }));
84
- case 3:
85
- case "end":
86
- return _context2.stop();
82
+ }, _callee2);
83
+ }));
84
+ return function handleUpload(_x2, _x3) {
85
+ return _ref3.apply(this, arguments);
86
+ };
87
+ }();
88
+ var handleTocUpdate = function handleTocUpdate(toc) {
89
+ // console.log('toc', toc)
90
+ };
91
+ var handleValidateUrl = /*#__PURE__*/function () {
92
+ var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(url, type) {
93
+ return _regeneratorRuntime().wrap(function _callee3$(_context3) {
94
+ while (1) switch (_context3.prev = _context3.next) {
95
+ case 0:
96
+ if (!url.startsWith('data:')) {
97
+ _context3.next = 2;
98
+ break;
99
+ }
100
+ throw new Error("\u4E0D\u652F\u6301 base64 \u94FE\u63A5\uFF0C\u8BF7\u4F7F\u7528\u53EF\u8BBF\u95EE\u7684 ".concat(type, " URL"));
101
+ case 2:
102
+ _context3.t0 = type;
103
+ _context3.next = _context3.t0 === 'image' ? 5 : _context3.t0 === 'video' ? 7 : _context3.t0 === 'audio' ? 9 : _context3.t0 === 'iframe' ? 11 : 13;
104
+ break;
105
+ case 5:
106
+ if (!url.match(/\.(jpg|jpeg|png|gif|webp|svg)(\?.*)?$/i)) {
107
+ console.warn('图片链接可能不是有效的图片格式');
108
+ }
109
+ return _context3.abrupt("break", 13);
110
+ case 7:
111
+ if (!url.match(/\.(mp4|webm|ogg|mov|avi|wmv|flv|mkv)(\?.*)?$/i)) {
112
+ console.warn('视频链接可能不是有效的视频格式');
113
+ }
114
+ return _context3.abrupt("break", 13);
115
+ case 9:
116
+ if (!url.match(/\.(mp3|wav|ogg|m4a|flac|aac|wma)(\?.*)?$/i)) {
117
+ console.warn('音频链接可能不是有效的音频格式');
118
+ }
119
+ return _context3.abrupt("break", 13);
120
+ case 11:
121
+ // iframe 可以嵌入任何 URL,但可以检查是否是 HTTPS
122
+ if (url.startsWith('http://') && !url.includes('localhost')) {
123
+ console.warn('建议使用 HTTPS 链接以确保安全性');
87
124
  }
88
- }, _callee2);
89
- }));
90
- function onAiWritingGetSuggestion(_x3) {
91
- return _onAiWritingGetSuggestion.apply(this, arguments);
125
+ return _context3.abrupt("break", 13);
126
+ case 13:
127
+ return _context3.abrupt("return", url);
128
+ case 14:
129
+ case "end":
130
+ return _context3.stop();
92
131
  }
93
- return onAiWritingGetSuggestion;
94
- }(),
132
+ }, _callee3);
133
+ }));
134
+ return function handleValidateUrl(_x4, _x5) {
135
+ return _ref4.apply(this, arguments);
136
+ };
137
+ }();
138
+ var _useTiptap = useTiptap({
139
+ editable: EDITABLE,
140
+ content: content,
141
+ contentType: DEFAULT_CONTENT_TYPE,
142
+ exclude: ['invisibleCharacters'],
143
+ onError: handleError,
144
+ onValidateUrl: handleValidateUrl,
145
+ onSave: handleSave,
146
+ onAiWritingGetSuggestion: handleAiWritingGetSuggestion,
95
147
  onTocUpdate: handleTocUpdate,
148
+ onUpload: handleUpload
96
149
  // onMentionFilter: async ({ query }: { query: string }) => {
97
150
  // return new Promise((resolve) => {
98
151
  // resolve([
@@ -112,49 +165,6 @@ var Reader = function Reader() {
112
165
  // .slice(0, 5))
113
166
  // })
114
167
  // },
115
- onUpload: function () {
116
- var _onUpload = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(file, onProgress) {
117
- return _regeneratorRuntime().wrap(function _callee3$(_context3) {
118
- while (1) switch (_context3.prev = _context3.next) {
119
- case 0:
120
- return _context3.abrupt("return", new Promise(function (resolve) {
121
- var progress = 0;
122
- var interval = setInterval(function () {
123
- progress += Math.random() * 20;
124
- if (progress >= 100) {
125
- progress = 100;
126
- onProgress === null || onProgress === void 0 || onProgress({
127
- progress: progress / 100
128
- });
129
- clearInterval(interval);
130
- setTimeout(function () {
131
- if (file.type.startsWith('image/')) {
132
- resolve('https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg');
133
- } else if (file.type.startsWith('video/')) {
134
- resolve('http://vjs.zencdn.net/v/oceans.mp4');
135
- } else {
136
- resolve('https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg');
137
- }
138
- }, 200);
139
- } else {
140
- onProgress === null || onProgress === void 0 || onProgress({
141
- progress: progress / 100
142
- });
143
- }
144
- }, 100);
145
- }));
146
- case 1:
147
- case "end":
148
- return _context3.stop();
149
- }
150
- }, _callee3);
151
- }));
152
- function onUpload(_x4, _x5) {
153
- return _onUpload.apply(this, arguments);
154
- }
155
- return onUpload;
156
- }(),
157
- content: defaultContent
158
168
  }),
159
169
  editor = _useTiptap.editor;
160
170
  return /*#__PURE__*/React.createElement(EditorThemeProvider, {
@@ -4,6 +4,10 @@ import React from 'react';
4
4
  import { PhotoProvider } from 'react-photo-view';
5
5
  import CustomBubbleMenu from "../component/CustomBubbleMenu";
6
6
  import CustomDragHandle from "../component/CustomDragHandle";
7
+ import { TableCellHandleMenu } from "../extension/component/TableCellHandleMenu";
8
+ import { TableExtendRowColumnButtons } from "../extension/component/TableExtendButton";
9
+ import { TableHandle } from "../extension/component/TableHandle";
10
+ import { TableSelectionOverlay } from "../extension/component/TableSelectionOverlay";
7
11
 
8
12
  // fix: https://github.com/ueberdosis/tiptap/issues/6785
9
13
 
@@ -63,6 +67,19 @@ var Editor = function Editor(_ref) {
63
67
  onTip: onTip
64
68
  }), /*#__PURE__*/React.createElement(EditorContent, {
65
69
  editor: editor
70
+ }), /*#__PURE__*/React.createElement(TableHandle, {
71
+ editor: editor
72
+ }), /*#__PURE__*/React.createElement(TableExtendRowColumnButtons, {
73
+ editor: editor
74
+ }), /*#__PURE__*/React.createElement(TableSelectionOverlay, {
75
+ editor: editor,
76
+ showResizeHandles: true,
77
+ cellMenu: function cellMenu(props) {
78
+ return /*#__PURE__*/React.createElement(TableCellHandleMenu, {
79
+ editor: props.editor,
80
+ onResizeStart: props.onResizeStart
81
+ });
82
+ }
66
83
  }));
67
84
  };
68
85
  export default Editor;
@@ -1,3 +1,9 @@
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
+ 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; }
3
+ 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; }
4
+ 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; }
5
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
6
+ 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); }
1
7
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
8
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
9
  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); }
@@ -9,7 +15,7 @@ import { useEditorState } from '@tiptap/react';
9
15
  import React from 'react';
10
16
  import { AiGenerate2Icon, ArrowGoBackLineIcon, ArrowGoForwardLineIcon, BoldIcon, CodeBoxLineIcon, CollapseHorizontalLine, EraserLineIcon, ExpandHorizontalLineIcon, ItalicIcon, LinkIcon, MarkPenLineIcon, StrikethroughIcon, SubscriptIcon, SuperscriptIcon, UnderlineIcon } from "../component/Icons";
11
17
  import { EditorAlignSelect, EditorFontBgColor, EditorFontColor, EditorFontSize, EditorHeading, EditorInsert, EditorListSelect, EditorMore, EditorVerticalAlignSelect, ToolbarItem } from "../component/Toolbar";
12
- import { hasMarksInSelection } from "../util";
18
+ import { getLinkAttributesWithSelectedText, hasMarksInSelection } from "../util";
13
19
  var EditorToolbar = function EditorToolbar(_ref) {
14
20
  var editor = _ref.editor,
15
21
  menuInToolbarMore = _ref.menuInToolbarMore,
@@ -299,14 +305,10 @@ var EditorToolbar = function EditorToolbar(_ref) {
299
305
  }
300
306
  }),
301
307
  onClick: function onClick() {
302
- var selection = editor.state.selection;
303
- var start = selection.from;
304
- var end = selection.to;
305
- var text = editor.state.doc.textBetween(start, end, '');
306
- editor.chain().focus().setInlineLink({
307
- href: '',
308
- title: text
309
- }).run();
308
+ var linkAttributes = getLinkAttributesWithSelectedText(editor);
309
+ editor.chain().focus().setInlineLink(_objectSpread({
310
+ href: ''
311
+ }, linkAttributes)).run();
310
312
  },
311
313
  className: isLink ? 'tool-active' : ''
312
314
  }), !isSimpleMode && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(EditorAlignSelect, {
@@ -80,11 +80,6 @@
80
80
  border-color: var(--mui-palette-text-disabled);
81
81
  }
82
82
 
83
- .tiptap.ProseMirror .react-renderer {
84
- margin-bottom: 1rem;
85
- line-height: 1;
86
- }
87
-
88
83
  .tiptap.ProseMirror .react-renderer.node-image,
89
84
  .tiptap.ProseMirror .react-renderer.node-inlineLink,
90
85
  .tiptap.ProseMirror .react-renderer.node-inlineAttachment,
@@ -117,10 +112,13 @@
117
112
 
118
113
  .tiptap.ProseMirror .video-wrapper,
119
114
  .tiptap.ProseMirror .image-wrapper {
120
- display: inline-block;
121
115
  box-sizing: border-box;
122
- text-align: center;
123
116
  line-height: 1;
117
+
118
+ }
119
+
120
+ .tiptap.ProseMirror .image-wrapper {
121
+ display: inline-block;
124
122
  }
125
123
 
126
124
  .tiptap.ProseMirror .image-wrapper img {
@@ -20,6 +20,11 @@ export interface ActionDropdownProps {
20
20
  anchorOrigin?: PopoverOrigin;
21
21
  /** Popover 变换位置 */
22
22
  transformOrigin?: PopoverOrigin;
23
+ /** 当没有选中值时的默认显示内容 */
24
+ defaultDisplay?: {
25
+ icon?: React.ReactNode;
26
+ label?: string;
27
+ };
23
28
  }
24
29
  declare const ActionDropdown: React.FC<ActionDropdownProps>;
25
30
  export default ActionDropdown;
@@ -33,7 +33,8 @@ var ActionDropdown = function ActionDropdown(_ref) {
33
33
  transformOrigin = _ref$transformOrigin === void 0 ? {
34
34
  vertical: 'top',
35
35
  horizontal: 'left'
36
- } : _ref$transformOrigin;
36
+ } : _ref$transformOrigin,
37
+ defaultDisplay = _ref.defaultDisplay;
37
38
  var _React$useState = React.useState(null),
38
39
  _React$useState2 = _slicedToArray(_React$useState, 2),
39
40
  anchorEl = _React$useState2[0],
@@ -45,6 +46,10 @@ var ActionDropdown = function ActionDropdown(_ref) {
45
46
  return item.key === selected;
46
47
  });
47
48
  }, [list, selected]);
49
+
50
+ // 获取显示的图标和标签
51
+ var displayIcon = (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.icon) || (defaultDisplay === null || defaultDisplay === void 0 ? void 0 : defaultDisplay.icon);
52
+ var displayLabel = (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.label) || (defaultDisplay === null || defaultDisplay === void 0 ? void 0 : defaultDisplay.label) || '';
48
53
  var handleClick = function handleClick(event) {
49
54
  event.stopPropagation();
50
55
  setAnchorEl(event.currentTarget);
@@ -67,14 +72,14 @@ var ActionDropdown = function ActionDropdown(_ref) {
67
72
  var open = Boolean(anchorEl);
68
73
  var curId = open ? id : undefined;
69
74
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ToolbarItem, {
70
- icon: selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.icon,
75
+ icon: displayIcon,
71
76
  text: /*#__PURE__*/React.createElement(Stack, {
72
77
  direction: "row",
73
78
  alignItems: "center",
74
79
  gap: 0.5
75
80
  }, /*#__PURE__*/React.createElement(Box, {
76
81
  component: "span"
77
- }, selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.label), /*#__PURE__*/React.createElement(ArrowDownSLineIcon, {
82
+ }, displayLabel), /*#__PURE__*/React.createElement(ArrowDownSLineIcon, {
78
83
  sx: {
79
84
  fontSize: 16,
80
85
  transition: 'transform 0.2s ease-in-out',
@@ -84,7 +84,7 @@ var CustomBubbleMenu = function CustomBubbleMenu(_ref) {
84
84
  // return cellSelection.$anchorCell.pos !== cellSelection.$headCell.pos;
85
85
  // }
86
86
  // }
87
- if (editor.state.selection.empty || editor.isActive('image') || editor.isActive('video') || editor.isActive('audio') || editor.isActive('emoji') || editor.isActive('codeBlock') || editor.isActive('blockMath') || editor.isActive('inlineMath') || editor.isActive('blockLink') || editor.isActive('inlineLink') || editor.isActive('blockAttachment') || editor.isActive('inlineAttachment') || editor.isActive('horizontalRule') || editor.isActive('iframe') || editor.isActive('yamlFormat') || editor.isActive('flow')) {
87
+ if (editor.state.selection.empty || editor.isActive('image') || editor.isActive('video') || editor.isActive('audio') || editor.isActive('emoji') || editor.isActive('codeBlock') || editor.isActive('blockMath') || editor.isActive('inlineMath') || editor.isActive('blockLink') || editor.isActive('inlineLink') || editor.isActive('blockAttachment') || editor.isActive('inlineAttachment') || editor.isActive('horizontalRule') || editor.isActive('iframe') || editor.isActive('yamlFormat') || editor.isActive('flow') || editor.isActive('table')) {
88
88
  return false;
89
89
  }
90
90
  return true;
@@ -18,7 +18,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
18
18
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
19
19
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
20
20
  import { AddLineIcon, AlignBottomIcon, AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon, AlignTopIcon, ArrowDownSLineIcon, AttachmentLineIcon, BrushLineIcon, DeleteLineIcon, DownloadLineIcon, DraggableIcon, EraserLineIcon, FileCopyLineIcon, FontSizeIcon, H1Icon, H2Icon, H3Icon, ImageLineIcon, IndentDecreaseIcon, IndentIncreaseIcon, Information2LineIcon, ListCheck3Icon, ListOrdered2Icon, ListUnorderedIcon, MovieLineIcon, Music2LineIcon, QuoteTextIcon, Repeat2LineIcon, ScissorsCutLineIcon, TextIcon, TextWrapIcon } from "../Icons";
21
- import { NODE_TYPE_LABEL, NodeTypeEnum } from "../../contants/enums";
21
+ import { getThemeTextBgColor, getThemeTextColor, NODE_TYPE_LABEL, NodeTypeEnum } from "../../contants/enums";
22
22
  import { Box, Divider, Stack, Typography, useTheme } from '@mui/material';
23
23
  import DragHandle from '@tiptap/extension-drag-handle-react';
24
24
  import { Fragment, Slice } from '@tiptap/pm/model';
@@ -122,62 +122,6 @@ var CustomDragHandle = function CustomDragHandle(_ref3) {
122
122
  _useState8 = _slicedToArray(_useState7, 2),
123
123
  hasMarks = _useState8[0],
124
124
  setHasMarks = _useState8[1];
125
- var THEME_TEXT_COLOR = [{
126
- label: '默认色',
127
- value: theme.palette.text.primary
128
- }, {
129
- label: '主题色',
130
- value: theme.palette.primary.main
131
- }, {
132
- label: '成功色',
133
- value: theme.palette.success.main
134
- }, {
135
- label: '警告色',
136
- value: theme.palette.warning.main
137
- }, {
138
- label: '错误色',
139
- value: theme.palette.error.main
140
- }, {
141
- label: '黑色',
142
- value: theme.palette.common.black
143
- }, {
144
- label: '灰色',
145
- value: theme.palette.text.disabled
146
- }, {
147
- label: '白色',
148
- value: theme.palette.common.white
149
- }];
150
- var THEME_TEXT_BG_COLOR = [{
151
- label: '默认背景',
152
- value: theme.palette.background.paper
153
- }, {
154
- label: '灰色背景',
155
- value: '#f8f8f7'
156
- }, {
157
- label: '棕色背景',
158
- value: '#f4eeee'
159
- }, {
160
- label: '橙色背景',
161
- value: '#fbecdd'
162
- }, {
163
- label: '黄色背景',
164
- value: '#fef9c3'
165
- }, {
166
- label: '绿色背景',
167
- value: '#dcfce7'
168
- }, {
169
- label: '蓝色背景',
170
- value: '#e0f2fe'
171
- }, {
172
- label: '紫色背景',
173
- value: '#f3e8ff'
174
- }, {
175
- label: '粉色背景',
176
- value: '#fcf1f6'
177
- }, {
178
- label: '红色背景',
179
- value: '#ffe4e6'
180
- }];
181
125
  var cancelNodeType = function cancelNodeType() {
182
126
  var _current$node;
183
127
  var type = (_current$node = current.node) === null || _current$node === void 0 ? void 0 : _current$node.type.name;
@@ -557,7 +501,7 @@ var CustomDragHandle = function CustomDragHandle(_ref3) {
557
501
  }
558
502
  }, "\u6587\u5B57\u989C\u8272"),
559
503
  key: 'text-color'
560
- }].concat(_toConsumableArray(THEME_TEXT_COLOR.map(function (it) {
504
+ }].concat(_toConsumableArray(getThemeTextColor(theme).map(function (it) {
561
505
  return {
562
506
  label: it.label,
563
507
  key: it.value,
@@ -593,7 +537,7 @@ var CustomDragHandle = function CustomDragHandle(_ref3) {
593
537
  }
594
538
  }, "\u6587\u5B57\u80CC\u666F\u989C\u8272"),
595
539
  key: 'background-color'
596
- }], _toConsumableArray(THEME_TEXT_BG_COLOR.map(function (it) {
540
+ }], _toConsumableArray(getThemeTextBgColor(theme).map(function (it) {
597
541
  return {
598
542
  label: it.label,
599
543
  key: it.value,
@@ -1,4 +1,4 @@
1
- import { Strategy, VirtualElement } from '@floating-ui/dom';
1
+ import { Placement, Strategy, VirtualElement } from '@floating-ui/dom';
2
2
  import React from 'react';
3
3
  export interface FloatingPopoverProps {
4
4
  open: boolean;
@@ -6,7 +6,7 @@ export interface FloatingPopoverProps {
6
6
  onClose: () => void;
7
7
  children: React.ReactNode;
8
8
  strategy?: Strategy;
9
- placement?: 'top' | 'bottom' | 'left' | 'right';
9
+ placement?: Placement;
10
10
  offset?: number;
11
11
  className?: string;
12
12
  style?: React.CSSProperties;
@@ -18,6 +18,8 @@ export interface HoverPopoverProps {
18
18
  className?: string;
19
19
  /** 样式对象 */
20
20
  style?: React.CSSProperties;
21
+ /** 是否保持打开状态(用于点击 action 按钮触发弹框时保持打开) */
22
+ keepOpen?: boolean;
21
23
  }
22
24
  /**
23
25
  * HoverPopover 组件
@@ -26,7 +26,9 @@ export var HoverPopover = function HoverPopover(_ref) {
26
26
  _ref$disabled = _ref.disabled,
27
27
  disabled = _ref$disabled === void 0 ? false : _ref$disabled,
28
28
  className = _ref.className,
29
- style = _ref.style;
29
+ style = _ref.style,
30
+ _ref$keepOpen = _ref.keepOpen,
31
+ keepOpen = _ref$keepOpen === void 0 ? false : _ref$keepOpen;
30
32
  var _useState = useState(null),
31
33
  _useState2 = _slicedToArray(_useState, 2),
32
34
  anchorEl = _useState2[0],
@@ -35,6 +37,13 @@ export var HoverPopover = function HoverPopover(_ref) {
35
37
  var closeTimerRef = useRef(null);
36
38
  var childRef = useRef(null);
37
39
 
40
+ // 当 keepOpen 为 true 时,确保 anchorEl 不为 null
41
+ useEffect(function () {
42
+ if (keepOpen && !anchorEl && childRef.current) {
43
+ setAnchorEl(childRef.current);
44
+ }
45
+ }, [keepOpen, anchorEl]);
46
+
38
47
  // 清理定时器
39
48
  useEffect(function () {
40
49
  return function () {
@@ -71,7 +80,7 @@ export var HoverPopover = function HoverPopover(_ref) {
71
80
  hoverTimerRef.current = timer;
72
81
  };
73
82
  var handleMouseLeave = function handleMouseLeave() {
74
- if (disabled) {
83
+ if (disabled || keepOpen) {
75
84
  return;
76
85
  }
77
86
 
@@ -109,10 +118,20 @@ export var HoverPopover = function HoverPopover(_ref) {
109
118
  var handlePopoverMouseLeave = function handlePopoverMouseLeave(event) {
110
119
  event.stopPropagation();
111
120
 
121
+ // 如果 keepOpen 为 true,不关闭
122
+ if (keepOpen) {
123
+ return;
124
+ }
125
+
112
126
  // 鼠标离开 popover,延迟关闭
113
127
  handleMouseLeave();
114
128
  };
115
129
  var handleForceClose = function handleForceClose() {
130
+ // 如果 keepOpen 为 true,不关闭
131
+ if (keepOpen) {
132
+ return;
133
+ }
134
+
116
135
  // 强制关闭,清除所有定时器
117
136
  if (hoverTimerRef.current) {
118
137
  clearTimeout(hoverTimerRef.current);
@@ -128,7 +147,7 @@ export var HoverPopover = function HoverPopover(_ref) {
128
147
  ref: childRef,
129
148
  onMouseEnter: handleMouseEnter,
130
149
  onMouseLeave: handleMouseLeave,
131
- className: className,
150
+ className: "hover-popover-child ".concat(className || ''),
132
151
  style: style
133
152
  }, children), /*#__PURE__*/React.createElement(FloatingPopover, {
134
153
  open: Boolean(anchorEl),