@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.
@@ -5,3 +5,4 @@ export * from './base-table';
5
5
  export * from './data-cell';
6
6
  export * from './icons';
7
7
  export * from './media-viewer';
8
+ export * from './tiptap-editor';
@@ -4,4 +4,5 @@ export * from "./base-list-table";
4
4
  export * from "./base-table";
5
5
  export * from "./data-cell";
6
6
  export * from "./icons";
7
- export * from "./media-viewer";
7
+ export * from "./media-viewer";
8
+ export * from "./tiptap-editor";
@@ -0,0 +1,2 @@
1
+ declare const _default: () => import("react/jsx-runtime").JSX.Element;
2
+ export default _default;
@@ -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,2 @@
1
+ export { matchTiptapVariables } from './modules/plugin-variable-node';
2
+ export * from './tiptap-editor';
@@ -0,0 +1,2 @@
1
+ export { matchTiptapVariables } from "./modules/plugin-variable-node";
2
+ export * from "./tiptap-editor";
@@ -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,3 @@
1
+ import { NodeViewProps } from '@tiptap/react';
2
+ import { FC } from 'react';
3
+ export declare const Component: FC<NodeViewProps>;
@@ -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;
@@ -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"
@@ -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.8",
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.6",
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",