@teamias/rex-design 0.0.8 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +2 -1
- package/dist/components/tiptap-editor/demo/index.d.ts +2 -0
- package/dist/components/tiptap-editor/demo/index.js +22 -0
- package/dist/components/tiptap-editor/index.d.ts +2 -0
- package/dist/components/tiptap-editor/index.js +2 -0
- package/dist/components/tiptap-editor/modules/plugin-image-node/index.d.ts +1 -0
- package/dist/components/tiptap-editor/modules/plugin-image-node/index.js +25 -0
- package/dist/components/tiptap-editor/modules/plugin-link-node/index.d.ts +1 -0
- package/dist/components/tiptap-editor/modules/plugin-link-node/index.js +85 -0
- package/dist/components/tiptap-editor/modules/plugin-variable-node/component.d.ts +3 -0
- package/dist/components/tiptap-editor/modules/plugin-variable-node/component.js +133 -0
- package/dist/components/tiptap-editor/modules/plugin-variable-node/index.d.ts +14 -0
- package/dist/components/tiptap-editor/modules/plugin-variable-node/index.js +84 -0
- package/dist/components/tiptap-editor/styles.d.ts +4 -0
- package/dist/components/tiptap-editor/styles.js +11 -0
- package/dist/components/tiptap-editor/tiptap-editor.d.ts +40 -0
- package/dist/components/tiptap-editor/tiptap-editor.js +529 -0
- package/dist/index.d.ts +42 -0
- package/dist/locales/en-US.json +21 -0
- package/dist/locales/zh-CN.json +21 -0
- package/package.json +20 -4
package/dist/components/index.js
CHANGED
|
@@ -0,0 +1,22 @@
|
|
|
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); }
|
|
7
|
+
import enUS from "../../../locales/en-US.json";
|
|
8
|
+
import { RexProConfigProvider, TiptapEditor } from "../../..";
|
|
9
|
+
import { crush } from 'radash';
|
|
10
|
+
import { createIntl } from 'react-intl';
|
|
11
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
12
|
+
export default (function () {
|
|
13
|
+
return /*#__PURE__*/_jsx(RexProConfigProvider, {
|
|
14
|
+
value: {
|
|
15
|
+
intl: createIntl({
|
|
16
|
+
locale: 'en-us',
|
|
17
|
+
messages: _objectSpread({}, crush(enUS))
|
|
18
|
+
})
|
|
19
|
+
},
|
|
20
|
+
children: /*#__PURE__*/_jsx(TiptapEditor, {})
|
|
21
|
+
});
|
|
22
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const Image: import("@tiptap/core").Node<import("@tiptap/extension-image").ImageOptions, any>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Image as RawImage } from '@tiptap/extension-image';
|
|
2
|
+
|
|
3
|
+
// 自定义图片扩展,确保图片渲染为可调整大小的 DOM 结构
|
|
4
|
+
export var Image = RawImage.extend({
|
|
5
|
+
addNodeView: function addNodeView() {
|
|
6
|
+
return function (_ref) {
|
|
7
|
+
var node = _ref.node,
|
|
8
|
+
editor = _ref.editor,
|
|
9
|
+
getPos = _ref.getPos;
|
|
10
|
+
var img = document.createElement('img');
|
|
11
|
+
img.src = node.attrs.src;
|
|
12
|
+
|
|
13
|
+
// 用 div 包裹 img,以便添加 resize 句柄
|
|
14
|
+
var wrapper = document.createElement('div');
|
|
15
|
+
wrapper.className = 'resizable-image-wrapper';
|
|
16
|
+
wrapper.appendChild(img);
|
|
17
|
+
|
|
18
|
+
// 返回 NodeView 对象,包含 dom 属性
|
|
19
|
+
return {
|
|
20
|
+
dom: wrapper,
|
|
21
|
+
contentDOM: null
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const Link: import("@tiptap/core").Mark<import("@tiptap/extension-link").LinkOptions, any>;
|
|
@@ -0,0 +1,85 @@
|
|
|
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 _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
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."); }
|
|
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); }
|
|
5
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
6
|
+
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
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 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; }
|
|
9
|
+
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; }
|
|
10
|
+
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; }
|
|
11
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
12
|
+
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); }
|
|
13
|
+
import { default as RawLink } from '@tiptap/extension-link';
|
|
14
|
+
import { Plugin } from 'prosemirror-state';
|
|
15
|
+
|
|
16
|
+
// 自定义链接扩展
|
|
17
|
+
export var Link = RawLink.extend({
|
|
18
|
+
// 添加自定义属性
|
|
19
|
+
addAttributes: function addAttributes() {
|
|
20
|
+
var _this$parent;
|
|
21
|
+
return _objectSpread(_objectSpread({}, (_this$parent = this.parent) === null || _this$parent === void 0 ? void 0 : _this$parent.call(this)), {}, {
|
|
22
|
+
// 添加自定义属性,比如打开方式
|
|
23
|
+
target: {
|
|
24
|
+
default: null,
|
|
25
|
+
parseHTML: function parseHTML(element) {
|
|
26
|
+
return element.getAttribute('target');
|
|
27
|
+
},
|
|
28
|
+
renderHTML: function renderHTML(attributes) {
|
|
29
|
+
return attributes.target ? {
|
|
30
|
+
target: attributes.target
|
|
31
|
+
} : {};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
},
|
|
36
|
+
// 添加自定义事件处理
|
|
37
|
+
addProseMirrorPlugins: function addProseMirrorPlugins() {
|
|
38
|
+
var _this$parent2;
|
|
39
|
+
var plugins = ((_this$parent2 = this.parent) === null || _this$parent2 === void 0 ? void 0 : _this$parent2.call(this)) || [];
|
|
40
|
+
return [].concat(_toConsumableArray(plugins), [
|
|
41
|
+
// 添加自定义点击处理插件
|
|
42
|
+
new Plugin({
|
|
43
|
+
// spec: '',
|
|
44
|
+
// getState: () => {},
|
|
45
|
+
props: {
|
|
46
|
+
handleClick: function handleClick(view, pos, event) {
|
|
47
|
+
var _event$target;
|
|
48
|
+
// console.log(view, pos, event);
|
|
49
|
+
|
|
50
|
+
// 获取当前选区
|
|
51
|
+
var state = view.state;
|
|
52
|
+
var _state$selection = state.selection,
|
|
53
|
+
from = _state$selection.from,
|
|
54
|
+
to = _state$selection.to;
|
|
55
|
+
|
|
56
|
+
// 检查点击位置是否在链接节点内
|
|
57
|
+
var linkNode = ((_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.nodeName) === 'A' && event.target.classList.contains('tiptap-link') ? event.target : null;
|
|
58
|
+
|
|
59
|
+
// console.log(event, state.doc.nodeAt(pos));
|
|
60
|
+
if (linkNode) {
|
|
61
|
+
if (event.ctrlKey || event.metaKey) {
|
|
62
|
+
var href = linkNode.href;
|
|
63
|
+
window.open(href, '_blank');
|
|
64
|
+
return true;
|
|
65
|
+
} else {
|
|
66
|
+
event.preventDefault();
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
})]);
|
|
74
|
+
},
|
|
75
|
+
// 添加自定义样式类
|
|
76
|
+
addOptions: function addOptions() {
|
|
77
|
+
var _this$parent3;
|
|
78
|
+
return _objectSpread(_objectSpread({}, (_this$parent3 = this.parent) === null || _this$parent3 === void 0 ? void 0 : _this$parent3.call(this)), {}, {
|
|
79
|
+
HTMLAttributes: {
|
|
80
|
+
class: 'tiptap-link',
|
|
81
|
+
style: 'cursor: pointer;'
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
});
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
2
|
+
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."); }
|
|
3
|
+
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); }
|
|
4
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
5
|
+
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
6
|
+
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; }
|
|
7
|
+
import { VerticalAlignTopOutlined } from '@ant-design/icons';
|
|
8
|
+
import { useStateData } from "../../../..";
|
|
9
|
+
import { NodeViewWrapper } from '@tiptap/react';
|
|
10
|
+
import { Dropdown, Input } from 'antd';
|
|
11
|
+
import { useRef } from 'react';
|
|
12
|
+
import styled from 'styled-components';
|
|
13
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
14
|
+
export var Component = function Component(props) {
|
|
15
|
+
var opts = props.extension.options;
|
|
16
|
+
var nodeViewWrapperRef = useRef(null);
|
|
17
|
+
var ref = useRef(null);
|
|
18
|
+
var _useStateData = useStateData(function () {
|
|
19
|
+
return {
|
|
20
|
+
open: true,
|
|
21
|
+
inputFocus: false
|
|
22
|
+
// inlineOptions: [],
|
|
23
|
+
};
|
|
24
|
+
}),
|
|
25
|
+
state = _useStateData.state,
|
|
26
|
+
update = _useStateData.update;
|
|
27
|
+
var updateSelected = function updateSelected(val) {
|
|
28
|
+
props.updateAttributes({
|
|
29
|
+
selected: val
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// const getFocus = () => {
|
|
34
|
+
// if (state.open) {
|
|
35
|
+
// setTimeout(() => {
|
|
36
|
+
// ref.current?.focus();
|
|
37
|
+
// }, 0);
|
|
38
|
+
// }
|
|
39
|
+
// };
|
|
40
|
+
|
|
41
|
+
// console.log(props);
|
|
42
|
+
// useEffect(() => {
|
|
43
|
+
// getFocus();
|
|
44
|
+
// }, [state.open,]);
|
|
45
|
+
|
|
46
|
+
return /*#__PURE__*/_jsx(NodeViewWrapper, {
|
|
47
|
+
style: {
|
|
48
|
+
display: 'inline-block'
|
|
49
|
+
},
|
|
50
|
+
ref: nodeViewWrapperRef,
|
|
51
|
+
onClick: function onClick(e) {
|
|
52
|
+
if (state.inputFocus) {
|
|
53
|
+
e.stopPropagation();
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
children: /*#__PURE__*/_jsx("div", {
|
|
57
|
+
contentEditable: false,
|
|
58
|
+
children: /*#__PURE__*/_jsx(Dropdown, {
|
|
59
|
+
open: state.open
|
|
60
|
+
// getPopupContainer={triggerNode => {
|
|
61
|
+
// // triggerNode.parentNode as HTMLElement
|
|
62
|
+
// console.log(triggerNode);
|
|
63
|
+
// }}
|
|
64
|
+
,
|
|
65
|
+
trigger: ['click'],
|
|
66
|
+
menu: {
|
|
67
|
+
items: [{
|
|
68
|
+
label: /*#__PURE__*/_jsx("span", {
|
|
69
|
+
style: {
|
|
70
|
+
fontSize: 12
|
|
71
|
+
},
|
|
72
|
+
children: "\u6CE8\u5165\u53C2\u6570\u9009\u62E9"
|
|
73
|
+
}),
|
|
74
|
+
key: '__key-1',
|
|
75
|
+
disabled: true
|
|
76
|
+
}, {
|
|
77
|
+
type: 'divider'
|
|
78
|
+
}, {
|
|
79
|
+
label: /*#__PURE__*/_jsx("div", {
|
|
80
|
+
contentEditable: false,
|
|
81
|
+
children: /*#__PURE__*/_jsx(Input.Search, {
|
|
82
|
+
size: "small",
|
|
83
|
+
placeholder: "\u81EA\u5B9A\u4E49\u53D8\u91CF\u540D",
|
|
84
|
+
enterButton: /*#__PURE__*/_jsx(VerticalAlignTopOutlined, {}),
|
|
85
|
+
ref: ref,
|
|
86
|
+
onFocusCapture: function onFocusCapture() {
|
|
87
|
+
// 在获取焦点瞬间,阻止 NodeViewWrapper 的默认事件
|
|
88
|
+
// 100ms 后解开限制
|
|
89
|
+
// 这里来解决焦点不对问题
|
|
90
|
+
state.inputFocus = true;
|
|
91
|
+
setTimeout(function () {
|
|
92
|
+
state.inputFocus = false;
|
|
93
|
+
}, 200);
|
|
94
|
+
},
|
|
95
|
+
onSearch: function onSearch(e) {
|
|
96
|
+
if (e) {
|
|
97
|
+
var _nodeViewWrapperRef$c;
|
|
98
|
+
// console.log(nodeViewWrapperRef);
|
|
99
|
+
(_nodeViewWrapperRef$c = nodeViewWrapperRef.current) === null || _nodeViewWrapperRef$c === void 0 || _nodeViewWrapperRef$c.click();
|
|
100
|
+
state.open = false;
|
|
101
|
+
updateSelected(e);
|
|
102
|
+
update();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
})
|
|
106
|
+
}),
|
|
107
|
+
key: '__key-2',
|
|
108
|
+
disabled: true
|
|
109
|
+
}, {
|
|
110
|
+
type: 'divider'
|
|
111
|
+
}].concat(_toConsumableArray(opts.options)),
|
|
112
|
+
onClick: function onClick(e) {
|
|
113
|
+
if (!e.key.startsWith('__key-')) {
|
|
114
|
+
updateSelected(e.key);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
onOpenChange: function onOpenChange(val) {
|
|
119
|
+
state.open = val;
|
|
120
|
+
update();
|
|
121
|
+
},
|
|
122
|
+
children: props.node.attrs.selected && /*#__PURE__*/_jsx(SpanBox, {
|
|
123
|
+
className: props.selected ? 'selected' : '',
|
|
124
|
+
children: props.node.attrs.selected
|
|
125
|
+
})
|
|
126
|
+
})
|
|
127
|
+
})
|
|
128
|
+
});
|
|
129
|
+
};
|
|
130
|
+
var SpanBox = styled.span.withConfig({
|
|
131
|
+
displayName: "SpanBox",
|
|
132
|
+
componentId: "rex-design-aaf4__sc-1qkqodh-0"
|
|
133
|
+
})(["border:1px solid #ccc;font-size:12px;vertical-align:middle;padding:0 3px;border-radius:4px;cursor:pointer;color:#296dff;background:#fff;margin:0 4px;&.selected{border-color:#296dff;background:#eff4ff;}"]);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Node } from '@tiptap/core';
|
|
2
|
+
export declare const PluginVariableBNode: Node<PluginVariableBNodeOptions, any>;
|
|
3
|
+
/**
|
|
4
|
+
* 提取 tiptap 编辑器内容中的所有 <react-variable-node selected="label"></react-variable-node> 占位符
|
|
5
|
+
* @param text 编辑器内容字符串
|
|
6
|
+
* @param source 匹配对象
|
|
7
|
+
*/
|
|
8
|
+
export declare const matchTiptapVariables: (text: string, source?: Record<string, unknown>) => string;
|
|
9
|
+
export interface PluginVariableBNodeOptions {
|
|
10
|
+
options?: Array<{
|
|
11
|
+
label: string;
|
|
12
|
+
key: string;
|
|
13
|
+
}>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { Node, mergeAttributes } from '@tiptap/core';
|
|
2
|
+
import { ReactNodeViewRenderer } from '@tiptap/react';
|
|
3
|
+
import { get } from 'radash';
|
|
4
|
+
import { Component } from "./component";
|
|
5
|
+
|
|
6
|
+
/** 标签名称 */
|
|
7
|
+
var tagName = 'react-variable-node';
|
|
8
|
+
export var PluginVariableBNode = Node.create({
|
|
9
|
+
name: 'variable',
|
|
10
|
+
// 唯一名称
|
|
11
|
+
inline: true,
|
|
12
|
+
// 行内节点(非块级)
|
|
13
|
+
group: 'inline',
|
|
14
|
+
// 分组为行内
|
|
15
|
+
atom: true,
|
|
16
|
+
// 原子节点(不可分割)
|
|
17
|
+
// parseDOM: [{ tag: 'span.variable', },], // 解析 DOM 规则
|
|
18
|
+
addAttributes: function addAttributes() {
|
|
19
|
+
return {
|
|
20
|
+
// count: {
|
|
21
|
+
// default: 0,
|
|
22
|
+
// },
|
|
23
|
+
// options: {
|
|
24
|
+
// default: this.options.options,
|
|
25
|
+
// },
|
|
26
|
+
selected: {
|
|
27
|
+
default: ''
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
parseHTML: function parseHTML() {
|
|
32
|
+
return [{
|
|
33
|
+
tag: tagName
|
|
34
|
+
}];
|
|
35
|
+
},
|
|
36
|
+
renderHTML: function renderHTML(_ref) {
|
|
37
|
+
var HTMLAttributes = _ref.HTMLAttributes;
|
|
38
|
+
return [tagName, mergeAttributes(HTMLAttributes)];
|
|
39
|
+
},
|
|
40
|
+
addNodeView: function addNodeView() {
|
|
41
|
+
return ReactNodeViewRenderer(Component);
|
|
42
|
+
},
|
|
43
|
+
addInputRules: function addInputRules() {
|
|
44
|
+
var _this = this;
|
|
45
|
+
return [{
|
|
46
|
+
find: /\{/,
|
|
47
|
+
handler: function handler(_ref2) {
|
|
48
|
+
var state = _ref2.state,
|
|
49
|
+
range = _ref2.range,
|
|
50
|
+
match = _ref2.match;
|
|
51
|
+
state.tr.replaceRangeWith(range.from, range.to, _this.type.create({
|
|
52
|
+
name: match[1]
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
}];
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* 提取 tiptap 编辑器内容中的所有 <react-variable-node selected="label"></react-variable-node> 占位符
|
|
61
|
+
* @param text 编辑器内容字符串
|
|
62
|
+
* @param source 匹配对象
|
|
63
|
+
*/
|
|
64
|
+
export var matchTiptapVariables = function matchTiptapVariables(text) {
|
|
65
|
+
var source = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
66
|
+
var reg = new RegExp("<".concat(tagName, " selected=\"(.*?)\"></").concat(tagName, ">"), 'g');
|
|
67
|
+
return text.replace(reg, function (content, match1) {
|
|
68
|
+
// console.log(arg);
|
|
69
|
+
return "".concat(get(source, match1) || '');
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
// const parseValue = (pathKey: string, source: Record<string, unknown>) => {
|
|
74
|
+
// // 'ssss[0].ewe.we.qqw'
|
|
75
|
+
// const paths = pathKey.replace(/\[|\]/g, '.').replace(/\.\./g, '.').split('.');
|
|
76
|
+
// const val = paths.slice(1).reduce((mainVal, key) => {
|
|
77
|
+
// if (typeof mainVal === 'undefined') return mainVal;
|
|
78
|
+
// if (mainVal === null) return null;
|
|
79
|
+
|
|
80
|
+
// return (mainVal as Record<string, unknown>)[key];
|
|
81
|
+
// }, source[paths[0]]);
|
|
82
|
+
|
|
83
|
+
// return val;
|
|
84
|
+
// };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
export declare const Box: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
|
|
3
|
+
"data-max-height"?: string | number | undefined;
|
|
4
|
+
}>> & string;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import styled from 'styled-components';
|
|
2
|
+
export var Box = styled.div.withConfig({
|
|
3
|
+
displayName: "Box",
|
|
4
|
+
componentId: "rex-design-aaf4__sc-szanbo-0"
|
|
5
|
+
})(["margin:0;overflow:hidden;color:rgba(0,0,0,0.88);font-size:14px;list-style:none;position:relative;display:inline-block;width:100%;min-width:0;border-radius:6px;transition:all 0.2s;max-width:100%;height:auto;min-height:32px;line-height:1.5714285714285714;vertical-align:bottom;transition:all 0.3s;box-sizing:border-box;background:#ffffff;border-width:1px;border-style:solid;border-color:#d9d9d9;div.tiptap[contenteditable]{margin:0;outline:none;overflow:auto;padding:4px 11px;min-height:", ";", " .resizable-image-wrapper{display:inline-block;overflow:auto;resize:auto;min-width:10px;min-height:10px;img{width:100%;height:100%;}}.resizable-image-wrapper.ProseMirror-selectednode{outline:3px solid #1677ff;}}&:hover{border-color:#4096ff;background-color:#ffffff;}&:focus,&:focus-within{border-color:#1677ff;box-shadow:0 0 0 2px rgba(5,145,255,0.1);outline:0;background-color:#ffffff;}"], function (p) {
|
|
6
|
+
return parseFloat((p['data-max-height'] || 100) + '') <= 100 ? typeof p['data-max-height'] === 'number' ? "".concat(p['data-max-height'], "px") : p['data-max-height'] : '100px';
|
|
7
|
+
}, function (props) {
|
|
8
|
+
return {
|
|
9
|
+
maxHeight: typeof props['data-max-height'] === 'number' ? "".concat(props['data-max-height'], "px") : props['data-max-height']
|
|
10
|
+
};
|
|
11
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Extensions, useEditor } from '@tiptap/react';
|
|
2
|
+
import { FC, ReactNode } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* https://v2.tiptap.dev/docs/editor/extensions/nodes/task-item
|
|
5
|
+
*/
|
|
6
|
+
export declare const TiptapEditor: FC<TiptapEditorProps>;
|
|
7
|
+
export interface TiptapEditorProps {
|
|
8
|
+
value?: string;
|
|
9
|
+
defaultValue?: string;
|
|
10
|
+
onChange?: (value: string) => void;
|
|
11
|
+
maxHeight?: number | string;
|
|
12
|
+
/** 变量 */
|
|
13
|
+
variableObject?: Record<string, unknown>;
|
|
14
|
+
/**
|
|
15
|
+
* @desc 类型
|
|
16
|
+
* - html html文本
|
|
17
|
+
* - text 存文本
|
|
18
|
+
*/
|
|
19
|
+
type?: 'html' | 'text';
|
|
20
|
+
/** 隐藏工具栏 */
|
|
21
|
+
hiddenToolBar?: boolean;
|
|
22
|
+
/** 阻止换行 */
|
|
23
|
+
preventLineBreaks?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* @desc 自定义渲染工具栏
|
|
26
|
+
* - oldNode 默认的渲染模块
|
|
27
|
+
* - editor useEditor 的操作对象
|
|
28
|
+
* - config 默认的工具列表
|
|
29
|
+
*/
|
|
30
|
+
renderToolBar?: (oldNode: JSX.Element, editor: ReturnType<typeof useEditor>, config: IConfigItem[]) => ReactNode;
|
|
31
|
+
/** 插件注入 */
|
|
32
|
+
extensions?: Extensions;
|
|
33
|
+
}
|
|
34
|
+
interface IConfigItem {
|
|
35
|
+
title: string;
|
|
36
|
+
key: string;
|
|
37
|
+
icon?: JSX.Element;
|
|
38
|
+
onClick?: () => void;
|
|
39
|
+
}
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
2
|
+
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."); }
|
|
3
|
+
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); }
|
|
4
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
5
|
+
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
6
|
+
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; }
|
|
7
|
+
// src/Tiptap.tsx
|
|
8
|
+
import { Icons } from "../..";
|
|
9
|
+
import BulletList from '@tiptap/extension-bullet-list';
|
|
10
|
+
import { Color } from '@tiptap/extension-color';
|
|
11
|
+
import FileHandler from '@tiptap/extension-file-handler';
|
|
12
|
+
import Highlight from '@tiptap/extension-highlight';
|
|
13
|
+
import OrderedList from '@tiptap/extension-ordered-list';
|
|
14
|
+
import SubSub from '@tiptap/extension-subscript';
|
|
15
|
+
import SubSup from '@tiptap/extension-superscript';
|
|
16
|
+
import TextAlign from '@tiptap/extension-text-align';
|
|
17
|
+
import TextStyleKit from '@tiptap/extension-text-style';
|
|
18
|
+
import { EditorContent, useEditor } from '@tiptap/react';
|
|
19
|
+
import StarterKit from '@tiptap/starter-kit';
|
|
20
|
+
import { ColorPicker, Divider, Flex, Tooltip } from 'antd';
|
|
21
|
+
import { keys } from 'radash';
|
|
22
|
+
import { useEffect } from 'react';
|
|
23
|
+
import { useIntl } from 'react-intl';
|
|
24
|
+
import { Image } from "./modules/plugin-image-node";
|
|
25
|
+
import { Link } from "./modules/plugin-link-node";
|
|
26
|
+
import { PluginVariableBNode } from "./modules/plugin-variable-node";
|
|
27
|
+
import { Box } from "./styles";
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* https://v2.tiptap.dev/docs/editor/extensions/nodes/task-item
|
|
31
|
+
*/
|
|
32
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
33
|
+
import { Fragment as _Fragment } from "react/jsx-runtime";
|
|
34
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
35
|
+
export var TiptapEditor = function TiptapEditor(_ref) {
|
|
36
|
+
var _ref$type = _ref.type,
|
|
37
|
+
type = _ref$type === void 0 ? 'html' : _ref$type,
|
|
38
|
+
_ref$maxHeight = _ref.maxHeight,
|
|
39
|
+
maxHeight = _ref$maxHeight === void 0 ? 100 : _ref$maxHeight,
|
|
40
|
+
_ref$variableObject = _ref.variableObject,
|
|
41
|
+
variableObject = _ref$variableObject === void 0 ? {} : _ref$variableObject,
|
|
42
|
+
value = _ref.value,
|
|
43
|
+
defaultValue = _ref.defaultValue,
|
|
44
|
+
onChange = _ref.onChange,
|
|
45
|
+
hiddenToolBar = _ref.hiddenToolBar,
|
|
46
|
+
preventLineBreaks = _ref.preventLineBreaks,
|
|
47
|
+
renderToolBar = _ref.renderToolBar,
|
|
48
|
+
extensions = _ref.extensions;
|
|
49
|
+
var intl = useIntl();
|
|
50
|
+
var editor = useEditor({
|
|
51
|
+
extensions: [].concat(_toConsumableArray(extensions || []), [BulletList, OrderedList, StarterKit.configure({
|
|
52
|
+
paragraph: {
|
|
53
|
+
HTMLAttributes: {
|
|
54
|
+
style: 'margin: 0'
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}), TextStyleKit, Color, TextAlign.configure({
|
|
58
|
+
types: ['heading', 'paragraph']
|
|
59
|
+
}), SubSup, SubSub, Highlight.configure({
|
|
60
|
+
multicolor: true
|
|
61
|
+
}),
|
|
62
|
+
// Variable,
|
|
63
|
+
PluginVariableBNode.configure({
|
|
64
|
+
options: keys(variableObject).map(function (ii) {
|
|
65
|
+
return {
|
|
66
|
+
label: ii,
|
|
67
|
+
key: ii
|
|
68
|
+
};
|
|
69
|
+
})
|
|
70
|
+
}), Image.configure({
|
|
71
|
+
allowBase64: true,
|
|
72
|
+
inline: true
|
|
73
|
+
}), FileHandler.configure({
|
|
74
|
+
allowedMimeTypes: ['image/png', 'image/jpeg', 'image/gif', 'image/webp'],
|
|
75
|
+
onDrop: function onDrop(currentEditor, files, pos) {
|
|
76
|
+
files.forEach(function (file) {
|
|
77
|
+
var fileReader = new FileReader();
|
|
78
|
+
fileReader.readAsDataURL(file);
|
|
79
|
+
fileReader.onload = function () {
|
|
80
|
+
currentEditor.chain().insertContentAt(pos, {
|
|
81
|
+
type: 'image',
|
|
82
|
+
attrs: {
|
|
83
|
+
src: fileReader.result
|
|
84
|
+
}
|
|
85
|
+
}).focus().run();
|
|
86
|
+
};
|
|
87
|
+
});
|
|
88
|
+
},
|
|
89
|
+
onPaste: function onPaste(currentEditor, files, htmlContent) {
|
|
90
|
+
files.forEach(function (file) {
|
|
91
|
+
if (htmlContent) {
|
|
92
|
+
// if there is htmlContent, stop manual insertion & let other extensions handle insertion via inputRule
|
|
93
|
+
// you could extract the pasted file from this url string and upload it to a server for example
|
|
94
|
+
console.log(htmlContent);
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
var fileReader = new FileReader();
|
|
98
|
+
fileReader.readAsDataURL(file);
|
|
99
|
+
fileReader.onload = function () {
|
|
100
|
+
currentEditor.chain().insertContentAt(currentEditor.state.selection.anchor, {
|
|
101
|
+
type: 'image',
|
|
102
|
+
attrs: {
|
|
103
|
+
src: fileReader.result
|
|
104
|
+
}
|
|
105
|
+
}).focus().run();
|
|
106
|
+
};
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}), Link.configure({
|
|
110
|
+
defaultProtocol: 'https',
|
|
111
|
+
openOnClick: false,
|
|
112
|
+
protocols: ['http', 'https']
|
|
113
|
+
})
|
|
114
|
+
// ImageUploadNode.configure({
|
|
115
|
+
// accept: 'image/*',
|
|
116
|
+
// maxSize: MAX_FILE_SIZE,
|
|
117
|
+
// limit: 3,
|
|
118
|
+
// upload: handleImageUpload,
|
|
119
|
+
// onError: (error) => console.error('Upload failed:', error),
|
|
120
|
+
// }),
|
|
121
|
+
]),
|
|
122
|
+
content: defaultValue || '',
|
|
123
|
+
onUpdate: function onUpdate(_ref2) {
|
|
124
|
+
var editor = _ref2.editor;
|
|
125
|
+
if (type === 'text') {
|
|
126
|
+
// `<p style="margin: 0">/qwe/<react-variable-node selected="qwe"></react-variable-node></p>`.replace(/<p.*?>(.*?)<\/p>/, '$1');
|
|
127
|
+
var text = editor.getHTML();
|
|
128
|
+
onChange === null || onChange === void 0 || onChange(text.replace(/<p.*?>(.*?)<\/p>/, '$1'));
|
|
129
|
+
} else {
|
|
130
|
+
var html = editor.getHTML();
|
|
131
|
+
onChange === null || onChange === void 0 || onChange(html);
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
editorProps: {
|
|
135
|
+
handleKeyDown: function handleKeyDown(view, event) {
|
|
136
|
+
if (preventLineBreaks && event.key === 'Enter') {
|
|
137
|
+
event.preventDefault();
|
|
138
|
+
return true; // 阻止换行
|
|
139
|
+
}
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
var config = [{
|
|
145
|
+
title: intl.formatMessage({
|
|
146
|
+
id: 'rex.components.tiptap-editor.undo',
|
|
147
|
+
defaultMessage: '撤回'
|
|
148
|
+
}),
|
|
149
|
+
key: 'undo',
|
|
150
|
+
onClick: function onClick() {
|
|
151
|
+
return editor === null || editor === void 0 ? void 0 : editor.commands.undo();
|
|
152
|
+
},
|
|
153
|
+
icon: /*#__PURE__*/_jsx(Icons, {
|
|
154
|
+
type: "iconify",
|
|
155
|
+
name: "ic:round-undo",
|
|
156
|
+
color: "#666"
|
|
157
|
+
})
|
|
158
|
+
}, {
|
|
159
|
+
title: intl.formatMessage({
|
|
160
|
+
id: 'rex.components.tiptap-editor.redo',
|
|
161
|
+
defaultMessage: '恢复'
|
|
162
|
+
}),
|
|
163
|
+
key: 'redo',
|
|
164
|
+
onClick: function onClick() {
|
|
165
|
+
return editor === null || editor === void 0 ? void 0 : editor.commands.redo();
|
|
166
|
+
},
|
|
167
|
+
icon: /*#__PURE__*/_jsx(Icons, {
|
|
168
|
+
type: "iconify",
|
|
169
|
+
name: "ic:round-redo",
|
|
170
|
+
color: "#666"
|
|
171
|
+
})
|
|
172
|
+
}, {
|
|
173
|
+
title: intl.formatMessage({
|
|
174
|
+
id: 'rex.components.tiptap-editor.divider',
|
|
175
|
+
defaultMessage: '分割'
|
|
176
|
+
}),
|
|
177
|
+
key: 'divider'
|
|
178
|
+
}, {
|
|
179
|
+
title: intl.formatMessage({
|
|
180
|
+
id: 'rex.components.tiptap-editor.font-color',
|
|
181
|
+
defaultMessage: '字体颜色'
|
|
182
|
+
}),
|
|
183
|
+
key: 'color',
|
|
184
|
+
icon: /*#__PURE__*/_jsx(ColorPicker, {
|
|
185
|
+
defaultValue: "#333",
|
|
186
|
+
format: "hex",
|
|
187
|
+
allowClear: true,
|
|
188
|
+
onChangeComplete: function onChangeComplete(color) {
|
|
189
|
+
editor === null || editor === void 0 || editor.commands.setColor(color.toHexString());
|
|
190
|
+
},
|
|
191
|
+
children: /*#__PURE__*/_jsx(Icons, {
|
|
192
|
+
type: "iconify",
|
|
193
|
+
name: "ic:round-color-lens",
|
|
194
|
+
color: "#666"
|
|
195
|
+
})
|
|
196
|
+
})
|
|
197
|
+
}, {
|
|
198
|
+
title: intl.formatMessage({
|
|
199
|
+
id: 'rex.components.tiptap-editor.background-color',
|
|
200
|
+
defaultMessage: '背景颜色'
|
|
201
|
+
}),
|
|
202
|
+
key: 'backgroundColor',
|
|
203
|
+
icon: /*#__PURE__*/_jsx(ColorPicker, {
|
|
204
|
+
defaultValue: "#333",
|
|
205
|
+
format: "hex",
|
|
206
|
+
allowClear: true,
|
|
207
|
+
onChangeComplete: function onChangeComplete(color) {
|
|
208
|
+
editor === null || editor === void 0 || editor.commands.setHighlight({
|
|
209
|
+
color: color.toHexString()
|
|
210
|
+
});
|
|
211
|
+
},
|
|
212
|
+
children: /*#__PURE__*/_jsx(Icons, {
|
|
213
|
+
type: "iconify",
|
|
214
|
+
name: "ic:twotone-color-lens",
|
|
215
|
+
color: "#666"
|
|
216
|
+
})
|
|
217
|
+
})
|
|
218
|
+
}, {
|
|
219
|
+
title: intl.formatMessage({
|
|
220
|
+
id: 'rex.components.tiptap-editor.divider',
|
|
221
|
+
defaultMessage: '分割'
|
|
222
|
+
}),
|
|
223
|
+
key: 'divider'
|
|
224
|
+
}, {
|
|
225
|
+
title: intl.formatMessage({
|
|
226
|
+
id: 'rex.components.tiptap-editor.bullet-list',
|
|
227
|
+
defaultMessage: '有序列表'
|
|
228
|
+
}),
|
|
229
|
+
key: 'bulletList',
|
|
230
|
+
onClick: function onClick() {
|
|
231
|
+
return editor === null || editor === void 0 ? void 0 : editor.commands.toggleOrderedList();
|
|
232
|
+
},
|
|
233
|
+
icon: /*#__PURE__*/_jsx(Icons, {
|
|
234
|
+
type: "iconify",
|
|
235
|
+
name: "ic:round-format-list-numbered",
|
|
236
|
+
color: "#666"
|
|
237
|
+
})
|
|
238
|
+
}, {
|
|
239
|
+
title: intl.formatMessage({
|
|
240
|
+
id: 'rex.components.tiptap-editor.ordered-list',
|
|
241
|
+
defaultMessage: '无序列表'
|
|
242
|
+
}),
|
|
243
|
+
key: 'orderedList',
|
|
244
|
+
onClick: function onClick() {
|
|
245
|
+
return editor === null || editor === void 0 ? void 0 : editor.commands.toggleBulletList();
|
|
246
|
+
},
|
|
247
|
+
icon: /*#__PURE__*/_jsx(Icons, {
|
|
248
|
+
type: "iconify",
|
|
249
|
+
name: "ic:round-reorder",
|
|
250
|
+
color: "#666"
|
|
251
|
+
})
|
|
252
|
+
}, {
|
|
253
|
+
title: intl.formatMessage({
|
|
254
|
+
id: 'rex.components.tiptap-editor.divider',
|
|
255
|
+
defaultMessage: '分割'
|
|
256
|
+
}),
|
|
257
|
+
key: 'divider'
|
|
258
|
+
}, {
|
|
259
|
+
title: intl.formatMessage({
|
|
260
|
+
id: 'rex.components.tiptap-editor.bold',
|
|
261
|
+
defaultMessage: '加粗'
|
|
262
|
+
}),
|
|
263
|
+
key: 'toggleBold',
|
|
264
|
+
onClick: function onClick() {
|
|
265
|
+
return editor === null || editor === void 0 ? void 0 : editor.commands.toggleBold();
|
|
266
|
+
},
|
|
267
|
+
icon: /*#__PURE__*/_jsx(Icons, {
|
|
268
|
+
type: "iconify",
|
|
269
|
+
name: "ic:round-format-bold",
|
|
270
|
+
color: "#666"
|
|
271
|
+
})
|
|
272
|
+
}, {
|
|
273
|
+
title: intl.formatMessage({
|
|
274
|
+
id: 'rex.components.tiptap-editor.italic',
|
|
275
|
+
defaultMessage: '斜体'
|
|
276
|
+
}),
|
|
277
|
+
key: 'toggleItalic',
|
|
278
|
+
onClick: function onClick() {
|
|
279
|
+
return editor === null || editor === void 0 ? void 0 : editor.commands.toggleItalic();
|
|
280
|
+
},
|
|
281
|
+
icon: /*#__PURE__*/_jsx(Icons, {
|
|
282
|
+
type: "iconify",
|
|
283
|
+
name: "ic:round-format-italic",
|
|
284
|
+
color: "#666"
|
|
285
|
+
})
|
|
286
|
+
}, {
|
|
287
|
+
title: intl.formatMessage({
|
|
288
|
+
id: 'rex.components.tiptap-editor.strike',
|
|
289
|
+
defaultMessage: '划线'
|
|
290
|
+
}),
|
|
291
|
+
key: 'toggleStrike',
|
|
292
|
+
onClick: function onClick() {
|
|
293
|
+
return editor === null || editor === void 0 ? void 0 : editor.commands.toggleStrike();
|
|
294
|
+
},
|
|
295
|
+
icon: /*#__PURE__*/_jsx(Icons, {
|
|
296
|
+
type: "iconify",
|
|
297
|
+
name: "ic:round-strikethrough-s",
|
|
298
|
+
color: "#666"
|
|
299
|
+
})
|
|
300
|
+
}, {
|
|
301
|
+
title: intl.formatMessage({
|
|
302
|
+
id: 'rex.components.tiptap-editor.divider',
|
|
303
|
+
defaultMessage: '分割'
|
|
304
|
+
}),
|
|
305
|
+
key: 'divider'
|
|
306
|
+
}, {
|
|
307
|
+
title: intl.formatMessage({
|
|
308
|
+
id: 'rex.components.tiptap-editor.superscript',
|
|
309
|
+
defaultMessage: '上标'
|
|
310
|
+
}),
|
|
311
|
+
key: 'toggleSuperscript',
|
|
312
|
+
onClick: function onClick() {
|
|
313
|
+
return editor === null || editor === void 0 ? void 0 : editor.commands.toggleSuperscript();
|
|
314
|
+
},
|
|
315
|
+
icon: /*#__PURE__*/_jsx(Icons, {
|
|
316
|
+
type: "iconify",
|
|
317
|
+
name: "ic:round-superscript",
|
|
318
|
+
color: "#666"
|
|
319
|
+
})
|
|
320
|
+
}, {
|
|
321
|
+
title: intl.formatMessage({
|
|
322
|
+
id: 'rex.components.tiptap-editor.subscript',
|
|
323
|
+
defaultMessage: '下标'
|
|
324
|
+
}),
|
|
325
|
+
key: 'toggleSubscript',
|
|
326
|
+
onClick: function onClick() {
|
|
327
|
+
return editor === null || editor === void 0 ? void 0 : editor.commands.toggleSubscript();
|
|
328
|
+
},
|
|
329
|
+
icon: /*#__PURE__*/_jsx(Icons, {
|
|
330
|
+
type: "iconify",
|
|
331
|
+
name: "ic:round-subscript",
|
|
332
|
+
color: "#666"
|
|
333
|
+
})
|
|
334
|
+
}, {
|
|
335
|
+
title: intl.formatMessage({
|
|
336
|
+
id: 'rex.components.tiptap-editor.divider',
|
|
337
|
+
defaultMessage: '分割'
|
|
338
|
+
}),
|
|
339
|
+
key: 'divider'
|
|
340
|
+
}, {
|
|
341
|
+
title: intl.formatMessage({
|
|
342
|
+
id: 'rex.components.tiptap-editor.align-left',
|
|
343
|
+
defaultMessage: '左对齐'
|
|
344
|
+
}),
|
|
345
|
+
key: 'left',
|
|
346
|
+
onClick: function onClick() {
|
|
347
|
+
return editor === null || editor === void 0 ? void 0 : editor.commands.setTextAlign('left');
|
|
348
|
+
},
|
|
349
|
+
icon: /*#__PURE__*/_jsx(Icons, {
|
|
350
|
+
type: "iconify",
|
|
351
|
+
name: "ic:round-align-horizontal-left",
|
|
352
|
+
color: "#666"
|
|
353
|
+
})
|
|
354
|
+
}, {
|
|
355
|
+
title: intl.formatMessage({
|
|
356
|
+
id: 'rex.components.tiptap-editor.align-center',
|
|
357
|
+
defaultMessage: '居中'
|
|
358
|
+
}),
|
|
359
|
+
key: 'center',
|
|
360
|
+
onClick: function onClick() {
|
|
361
|
+
return editor === null || editor === void 0 ? void 0 : editor.commands.setTextAlign('center');
|
|
362
|
+
},
|
|
363
|
+
icon: /*#__PURE__*/_jsx(Icons, {
|
|
364
|
+
type: "iconify",
|
|
365
|
+
name: "ic:round-align-horizontal-center",
|
|
366
|
+
color: "#666"
|
|
367
|
+
})
|
|
368
|
+
}, {
|
|
369
|
+
title: intl.formatMessage({
|
|
370
|
+
id: 'rex.components.tiptap-editor.align-right',
|
|
371
|
+
defaultMessage: '右对齐'
|
|
372
|
+
}),
|
|
373
|
+
key: 'right',
|
|
374
|
+
onClick: function onClick() {
|
|
375
|
+
return editor === null || editor === void 0 ? void 0 : editor.commands.setTextAlign('right');
|
|
376
|
+
},
|
|
377
|
+
icon: /*#__PURE__*/_jsx(Icons, {
|
|
378
|
+
type: "iconify",
|
|
379
|
+
name: "ic:round-align-horizontal-right",
|
|
380
|
+
color: "#666"
|
|
381
|
+
})
|
|
382
|
+
}, {
|
|
383
|
+
title: intl.formatMessage({
|
|
384
|
+
id: 'rex.components.tiptap-editor.divider',
|
|
385
|
+
defaultMessage: '分割'
|
|
386
|
+
}),
|
|
387
|
+
key: 'divider'
|
|
388
|
+
}, {
|
|
389
|
+
title: intl.formatMessage({
|
|
390
|
+
id: 'rex.components.tiptap-editor.set-link',
|
|
391
|
+
defaultMessage: '设置链接'
|
|
392
|
+
}),
|
|
393
|
+
key: 'link',
|
|
394
|
+
icon: /*#__PURE__*/_jsx(Icons, {
|
|
395
|
+
type: "iconify",
|
|
396
|
+
name: "ic:baseline-link",
|
|
397
|
+
color: editor !== null && editor !== void 0 && editor.isActive('link') ? '#006cff' : '#666'
|
|
398
|
+
}),
|
|
399
|
+
onClick: function onClick() {
|
|
400
|
+
var previousUrl = editor === null || editor === void 0 ? void 0 : editor.getAttributes('link').href;
|
|
401
|
+
var url = prompt(intl.formatMessage({
|
|
402
|
+
id: 'rex.components.tiptap-editor.enter-link-url',
|
|
403
|
+
defaultMessage: '请输入链接地址:'
|
|
404
|
+
}), previousUrl);
|
|
405
|
+
if (url) {
|
|
406
|
+
editor === null || editor === void 0 || editor.chain().focus().setLink({
|
|
407
|
+
href: url
|
|
408
|
+
}).run();
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}, {
|
|
412
|
+
title: intl.formatMessage({
|
|
413
|
+
id: 'rex.components.tiptap-editor.unset-link',
|
|
414
|
+
defaultMessage: '取消链接'
|
|
415
|
+
}),
|
|
416
|
+
key: 'unsetLink',
|
|
417
|
+
icon: /*#__PURE__*/_jsx(Icons, {
|
|
418
|
+
type: "iconify",
|
|
419
|
+
name: "ic:baseline-link-off",
|
|
420
|
+
color: editor !== null && editor !== void 0 && editor.isActive('link') ? '#006cff' : '#666'
|
|
421
|
+
}),
|
|
422
|
+
onClick: function onClick() {
|
|
423
|
+
return editor !== null && editor !== void 0 && editor.isActive('link') ? editor === null || editor === void 0 ? void 0 : editor.chain().focus().unsetLink().run() : '';
|
|
424
|
+
}
|
|
425
|
+
}, {
|
|
426
|
+
title: intl.formatMessage({
|
|
427
|
+
id: 'rex.components.tiptap-editor.divider',
|
|
428
|
+
defaultMessage: '分割'
|
|
429
|
+
}),
|
|
430
|
+
key: 'divider'
|
|
431
|
+
}, {
|
|
432
|
+
title: intl.formatMessage({
|
|
433
|
+
id: 'rex.components.tiptap-editor.upload-image',
|
|
434
|
+
defaultMessage: '上传图片'
|
|
435
|
+
}),
|
|
436
|
+
key: 'image',
|
|
437
|
+
onClick: function onClick() {
|
|
438
|
+
// 创建隐藏的文件输入框
|
|
439
|
+
var input = document.createElement('input');
|
|
440
|
+
input.type = 'file';
|
|
441
|
+
input.accept = 'image/*';
|
|
442
|
+
input.onchange = function (event) {
|
|
443
|
+
var _files;
|
|
444
|
+
var file = (_files = event.target.files) === null || _files === void 0 ? void 0 : _files[0];
|
|
445
|
+
if (!file) return;
|
|
446
|
+
var fileReader = new FileReader();
|
|
447
|
+
fileReader.readAsDataURL(file);
|
|
448
|
+
fileReader.onload = function () {
|
|
449
|
+
editor === null || editor === void 0 || editor.chain().insertContentAt(editor.state.selection.anchor, {
|
|
450
|
+
type: 'image',
|
|
451
|
+
attrs: {
|
|
452
|
+
src: fileReader.result
|
|
453
|
+
}
|
|
454
|
+
}).focus().run();
|
|
455
|
+
};
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
// 触发文件选择
|
|
459
|
+
input.click();
|
|
460
|
+
},
|
|
461
|
+
icon: /*#__PURE__*/_jsx(Icons, {
|
|
462
|
+
type: "iconify",
|
|
463
|
+
name: "ic:outline-broken-image",
|
|
464
|
+
color: "#666"
|
|
465
|
+
})
|
|
466
|
+
}];
|
|
467
|
+
useEffect(function () {
|
|
468
|
+
return function () {
|
|
469
|
+
editor === null || editor === void 0 || editor.destroy();
|
|
470
|
+
};
|
|
471
|
+
}, []);
|
|
472
|
+
useEffect(function () {
|
|
473
|
+
if (type === 'text') {
|
|
474
|
+
if (value && value === (editor === null || editor === void 0 ? void 0 : editor.getText())) return;
|
|
475
|
+
editor === null || editor === void 0 || editor.commands.setContent(value || '');
|
|
476
|
+
} else {
|
|
477
|
+
if (value && value === (editor === null || editor === void 0 ? void 0 : editor.getHTML())) return;
|
|
478
|
+
editor === null || editor === void 0 || editor.commands.setContent(value || '');
|
|
479
|
+
}
|
|
480
|
+
}, [value]);
|
|
481
|
+
return /*#__PURE__*/_jsxs(Box, {
|
|
482
|
+
"data-max-height": maxHeight,
|
|
483
|
+
onClick: function onClick() {
|
|
484
|
+
setTimeout(function () {
|
|
485
|
+
editor === null || editor === void 0 || editor.chain().focus();
|
|
486
|
+
}, 0);
|
|
487
|
+
},
|
|
488
|
+
children: [function () {
|
|
489
|
+
if (hiddenToolBar) return /*#__PURE__*/_jsx(_Fragment, {});
|
|
490
|
+
var oldNode = /*#__PURE__*/_jsx(Flex, {
|
|
491
|
+
wrap: true,
|
|
492
|
+
gap: "small",
|
|
493
|
+
align: "center",
|
|
494
|
+
style: {
|
|
495
|
+
padding: '4px 10px',
|
|
496
|
+
borderBottom: '1px solid #ddd',
|
|
497
|
+
background: '#f8f8f8'
|
|
498
|
+
},
|
|
499
|
+
children: config.map(function (item, index) {
|
|
500
|
+
if (item.key === 'divider') {
|
|
501
|
+
return /*#__PURE__*/_jsx(Divider, {
|
|
502
|
+
type: "vertical"
|
|
503
|
+
}, "".concat(item.key, "-").concat(index));
|
|
504
|
+
}
|
|
505
|
+
return /*#__PURE__*/_jsx(Tooltip, {
|
|
506
|
+
title: item.title,
|
|
507
|
+
arrow: false,
|
|
508
|
+
children: /*#__PURE__*/_jsx("div", {
|
|
509
|
+
onClick: function onClick() {
|
|
510
|
+
var _item$onClick;
|
|
511
|
+
return (_item$onClick = item.onClick) === null || _item$onClick === void 0 ? void 0 : _item$onClick.call(item);
|
|
512
|
+
},
|
|
513
|
+
style: {
|
|
514
|
+
cursor: 'pointer'
|
|
515
|
+
},
|
|
516
|
+
children: item.icon
|
|
517
|
+
})
|
|
518
|
+
}, "".concat(item.key, "-").concat(index));
|
|
519
|
+
})
|
|
520
|
+
});
|
|
521
|
+
if (renderToolBar) {
|
|
522
|
+
return renderToolBar(oldNode, editor, config);
|
|
523
|
+
}
|
|
524
|
+
return oldNode;
|
|
525
|
+
}(), /*#__PURE__*/_jsx(EditorContent, {
|
|
526
|
+
editor: editor
|
|
527
|
+
})]
|
|
528
|
+
});
|
|
529
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,27 @@ export declare const designLocales: {
|
|
|
5
5
|
zhCN: {
|
|
6
6
|
rex: {
|
|
7
7
|
components: {
|
|
8
|
+
"tiptap-editor": {
|
|
9
|
+
undo: string;
|
|
10
|
+
redo: string;
|
|
11
|
+
divider: string;
|
|
12
|
+
"font-color": string;
|
|
13
|
+
"background-color": string;
|
|
14
|
+
bold: string;
|
|
15
|
+
italic: string;
|
|
16
|
+
strike: string;
|
|
17
|
+
superscript: string;
|
|
18
|
+
subscript: string;
|
|
19
|
+
"align-left": string;
|
|
20
|
+
"align-center": string;
|
|
21
|
+
"align-right": string;
|
|
22
|
+
"set-link": string;
|
|
23
|
+
"unset-link": string;
|
|
24
|
+
"upload-image": string;
|
|
25
|
+
"enter-link-url": string;
|
|
26
|
+
"bullet-list": string;
|
|
27
|
+
"ordered-list": string;
|
|
28
|
+
};
|
|
8
29
|
"base-list-table": {
|
|
9
30
|
"expand-more-data-hide": string;
|
|
10
31
|
"expand-more-data": string;
|
|
@@ -44,6 +65,27 @@ export declare const designLocales: {
|
|
|
44
65
|
enUS: {
|
|
45
66
|
rex: {
|
|
46
67
|
components: {
|
|
68
|
+
"tiptap-editor": {
|
|
69
|
+
undo: string;
|
|
70
|
+
redo: string;
|
|
71
|
+
divider: string;
|
|
72
|
+
"font-color": string;
|
|
73
|
+
"background-color": string;
|
|
74
|
+
bold: string;
|
|
75
|
+
italic: string;
|
|
76
|
+
strike: string;
|
|
77
|
+
superscript: string;
|
|
78
|
+
subscript: string;
|
|
79
|
+
"align-left": string;
|
|
80
|
+
"align-center": string;
|
|
81
|
+
"align-right": string;
|
|
82
|
+
"set-link": string;
|
|
83
|
+
"unset-link": string;
|
|
84
|
+
"upload-image": string;
|
|
85
|
+
"enter-link-url": string;
|
|
86
|
+
"bullet-list": string;
|
|
87
|
+
"ordered-list": string;
|
|
88
|
+
};
|
|
47
89
|
"base-list-table": {
|
|
48
90
|
"expand-more-data": string;
|
|
49
91
|
"expand-more-data-hide": string;
|
package/dist/locales/en-US.json
CHANGED
|
@@ -1,6 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"rex": {
|
|
3
3
|
"components": {
|
|
4
|
+
"tiptap-editor": {
|
|
5
|
+
"undo": "Undo",
|
|
6
|
+
"redo": "Redo",
|
|
7
|
+
"divider": "Divider",
|
|
8
|
+
"font-color": "Font Color",
|
|
9
|
+
"background-color": "Background Color",
|
|
10
|
+
"bold": "Bold",
|
|
11
|
+
"italic": "Italic",
|
|
12
|
+
"strike": "Strike",
|
|
13
|
+
"superscript": "Superscript",
|
|
14
|
+
"subscript": "Subscript",
|
|
15
|
+
"align-left": "Align Left",
|
|
16
|
+
"align-center": "Align Center",
|
|
17
|
+
"align-right": "Align Right",
|
|
18
|
+
"set-link": "Set Link",
|
|
19
|
+
"unset-link": "Unset Link",
|
|
20
|
+
"upload-image": "Upload Image",
|
|
21
|
+
"enter-link-url": "Please enter link URL:",
|
|
22
|
+
"bullet-list": "Ordered list",
|
|
23
|
+
"ordered-list": "Unordered list"
|
|
24
|
+
},
|
|
4
25
|
"base-list-table": {
|
|
5
26
|
"expand-more-data": "There are still {count} pieces of data not displayed",
|
|
6
27
|
"expand-more-data-hide": "Close"
|
package/dist/locales/zh-CN.json
CHANGED
|
@@ -1,6 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"rex": {
|
|
3
3
|
"components": {
|
|
4
|
+
"tiptap-editor": {
|
|
5
|
+
"undo": "撤回",
|
|
6
|
+
"redo": "恢复",
|
|
7
|
+
"divider": "分割",
|
|
8
|
+
"font-color": "字体颜色",
|
|
9
|
+
"background-color": "背景颜色",
|
|
10
|
+
"bold": "加粗",
|
|
11
|
+
"italic": "斜体",
|
|
12
|
+
"strike": "划线",
|
|
13
|
+
"superscript": "上标",
|
|
14
|
+
"subscript": "下标",
|
|
15
|
+
"align-left": "左对齐",
|
|
16
|
+
"align-center": "居中",
|
|
17
|
+
"align-right": "右对齐",
|
|
18
|
+
"set-link": "设置链接",
|
|
19
|
+
"unset-link": "取消链接",
|
|
20
|
+
"upload-image": "上传图片",
|
|
21
|
+
"enter-link-url": "请输入链接地址:",
|
|
22
|
+
"bullet-list": "有序列表",
|
|
23
|
+
"ordered-list": "无序列表"
|
|
24
|
+
},
|
|
4
25
|
"base-list-table": {
|
|
5
26
|
"expand-more-data-hide": "收起",
|
|
6
27
|
"expand-more-data": "还有{count}条数据未展示"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teamias/rex-design",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.10",
|
|
4
4
|
"description": "A react library developed with dumi",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -51,11 +51,27 @@
|
|
|
51
51
|
"@ant-design/icons": "^6.0.0",
|
|
52
52
|
"@ant-design/pro-components": "^2.8.10",
|
|
53
53
|
"@iconify/react": "^6.0.0",
|
|
54
|
+
"@tiptap/core": "^2.12.0",
|
|
55
|
+
"@tiptap/extension-bullet-list": "2.12.0",
|
|
56
|
+
"@tiptap/extension-color": "^2.12.0",
|
|
57
|
+
"@tiptap/extension-file-handler": "^3.0.7",
|
|
58
|
+
"@tiptap/extension-highlight": "^2.12.0",
|
|
59
|
+
"@tiptap/extension-image": "2.12.0",
|
|
60
|
+
"@tiptap/extension-link": "2.12.0",
|
|
61
|
+
"@tiptap/extension-ordered-list": "2.12.0",
|
|
62
|
+
"@tiptap/extension-subscript": "^2.12.0",
|
|
63
|
+
"@tiptap/extension-superscript": "^2.12.0",
|
|
64
|
+
"@tiptap/extension-text-align": "^2.12.0",
|
|
65
|
+
"@tiptap/extension-text-style": "^2.12.0",
|
|
66
|
+
"@tiptap/pm": "^2.12.0",
|
|
67
|
+
"@tiptap/react": "^2.12.0",
|
|
68
|
+
"@tiptap/starter-kit": "^2.12.0",
|
|
54
69
|
"ahooks": "^3.9.0",
|
|
55
70
|
"antd": "^5.26.7",
|
|
56
71
|
"classnames": "^2.5.1",
|
|
57
72
|
"dayjs": "^1.11.13",
|
|
58
73
|
"lodash": "^4.17.21",
|
|
74
|
+
"prosemirror-state": "^1.4.3",
|
|
59
75
|
"radash": "^12.1.1",
|
|
60
76
|
"rc-virtual-list": "^3.19.1",
|
|
61
77
|
"react-intl": "^7.1.11",
|
|
@@ -65,7 +81,8 @@
|
|
|
65
81
|
"@changesets/cli": "^2.29.5",
|
|
66
82
|
"@commitlint/cli": "^17.1.2",
|
|
67
83
|
"@commitlint/config-conventional": "^17.1.0",
|
|
68
|
-
"@teamias/umi-loader-source-plugin": "^0.0.
|
|
84
|
+
"@teamias/umi-loader-source-plugin": "^0.0.11",
|
|
85
|
+
"@teamias/umi-plugin-upload-build": "^0.0.2",
|
|
69
86
|
"@types/lodash": "^4.17.20",
|
|
70
87
|
"@types/react": "^18.0.0",
|
|
71
88
|
"@types/react-dom": "^18.0.0",
|
|
@@ -80,8 +97,7 @@
|
|
|
80
97
|
"prettier-plugin-packagejson": "^2.2.18",
|
|
81
98
|
"react": "^18.0.0",
|
|
82
99
|
"react-dom": "^18.0.0",
|
|
83
|
-
"stylelint": "^14.9.1"
|
|
84
|
-
"umi-plugin-upload-build": "^1.1.0"
|
|
100
|
+
"stylelint": "^14.9.1"
|
|
85
101
|
},
|
|
86
102
|
"peerDependencies": {
|
|
87
103
|
"@ant-design/icons": ">=5.0.0",
|