@lingxiteam/lcdp-ueditor-react 1.0.3-alpha.13 → 1.0.3-alpha.14
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/es/LcdpUeditor.d.ts +15 -4
- package/es/LcdpUeditor.js +59 -10
- package/es/ToolBottomBar/FormatModal/index.d.ts +9 -0
- package/es/ToolBottomBar/FormatModal/index.js +543 -0
- package/es/ToolBottomBar/FormatModal/index.less +300 -0
- package/es/ToolBottomBar/ProgressModal/index.d.ts +10 -0
- package/es/ToolBottomBar/ProgressModal/index.js +53 -0
- package/es/ToolBottomBar/ProgressModal/index.less +16 -0
- package/es/ToolBottomBar/index.d.ts +14 -0
- package/es/ToolBottomBar/index.js +290 -0
- package/es/ToolBottomBar/index.less +70 -0
- package/es/icon/ExportPDF.d.ts +3 -0
- package/es/icon/ExportPDF.js +24 -0
- package/es/icon/TextCopy.d.ts +3 -0
- package/es/icon/TextCopy.js +25 -0
- package/es/icon/TextFileIcon.d.ts +3 -0
- package/es/icon/TextFileIcon.js +26 -0
- package/es/icon/TextIcon.d.ts +3 -0
- package/es/icon/TextIcon.js +28 -0
- package/es/tools/exportPDF.d.ts +27 -0
- package/es/tools/exportPDF.js +146 -0
- package/es/tools/generateStylesFromSettings.d.ts +38 -0
- package/es/tools/generateStylesFromSettings.js +24 -0
- package/es/type.d.ts +17 -0
- package/lib/LcdpUeditor.d.ts +15 -4
- package/lib/LcdpUeditor.js +45 -8
- package/lib/ToolBottomBar/FormatModal/index.d.ts +9 -0
- package/lib/ToolBottomBar/FormatModal/index.js +261 -0
- package/lib/ToolBottomBar/FormatModal/index.less +300 -0
- package/lib/ToolBottomBar/ProgressModal/index.d.ts +10 -0
- package/lib/ToolBottomBar/ProgressModal/index.js +73 -0
- package/lib/ToolBottomBar/ProgressModal/index.less +16 -0
- package/lib/ToolBottomBar/index.d.ts +14 -0
- package/lib/ToolBottomBar/index.js +232 -0
- package/lib/ToolBottomBar/index.less +70 -0
- package/lib/icon/ExportPDF.d.ts +3 -0
- package/lib/icon/ExportPDF.js +57 -0
- package/lib/icon/TextCopy.d.ts +3 -0
- package/lib/icon/TextCopy.js +39 -0
- package/lib/icon/TextFileIcon.d.ts +3 -0
- package/lib/icon/TextFileIcon.js +39 -0
- package/lib/icon/TextIcon.d.ts +3 -0
- package/lib/icon/TextIcon.js +39 -0
- package/lib/tools/exportPDF.d.ts +27 -0
- package/lib/tools/exportPDF.js +95 -0
- package/lib/tools/generateStylesFromSettings.d.ts +38 -0
- package/lib/tools/generateStylesFromSettings.js +77 -0
- package/lib/type.d.ts +17 -0
- package/package.json +12 -3
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
.ueditor-rich-status-bar {
|
|
2
|
+
display: flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
justify-content: space-between;
|
|
5
|
+
padding: 4px 12px;
|
|
6
|
+
background-color: #f0f0f0;
|
|
7
|
+
border-top: 1px solid #e0e0e0;
|
|
8
|
+
min-height: 32px;
|
|
9
|
+
.ueditor-rich-status-bar-box {
|
|
10
|
+
display: flex;
|
|
11
|
+
gap: 16px;
|
|
12
|
+
color: #666;
|
|
13
|
+
.ueditor-rich-status-bar-item:not(.ueditor-rich-status-bar-text) {
|
|
14
|
+
display: flex;
|
|
15
|
+
align-items: center;
|
|
16
|
+
cursor: pointer;
|
|
17
|
+
border-radius: 4px;
|
|
18
|
+
padding: 4px 10px;
|
|
19
|
+
&:hover {
|
|
20
|
+
background-color: rgba(0, 0, 0, 0.05);
|
|
21
|
+
color: #1a73e8;
|
|
22
|
+
}
|
|
23
|
+
&.isActive {
|
|
24
|
+
color: #52c41a;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
.ueditor-rich-status-bar-text {
|
|
28
|
+
display: flex;
|
|
29
|
+
align-items: center;
|
|
30
|
+
}
|
|
31
|
+
.ueditor-rich-status-bar-icon {
|
|
32
|
+
margin-right: 4px;
|
|
33
|
+
font-size: 14px;
|
|
34
|
+
display: flex;
|
|
35
|
+
align-items: center;
|
|
36
|
+
}
|
|
37
|
+
.ueditor-rich-status-bar-extra {
|
|
38
|
+
margin-left: 12px;
|
|
39
|
+
color: rgba(0, 0, 0, 0.25);
|
|
40
|
+
font-size: 12px;
|
|
41
|
+
display: flex;
|
|
42
|
+
align-items: center;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.edui-default .edui-editor {
|
|
48
|
+
&.ueditor-rich-status-not-full {
|
|
49
|
+
background-color: #fafbfc;
|
|
50
|
+
.edui-editor-iframeholder {
|
|
51
|
+
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
|
52
|
+
margin: 20px auto;
|
|
53
|
+
background-color: #fff;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.edui-default .edui-editor-iframeholder {
|
|
59
|
+
&.ueditor-rich-status-content {
|
|
60
|
+
&-a3 {
|
|
61
|
+
width: 80% !important;
|
|
62
|
+
}
|
|
63
|
+
&-a4 {
|
|
64
|
+
width: 60% !important;
|
|
65
|
+
}
|
|
66
|
+
&-a5 {
|
|
67
|
+
width: 40% !important;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
var ExportFile = function ExportFile() {
|
|
3
|
+
return /*#__PURE__*/React.createElement("svg", {
|
|
4
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
5
|
+
width: "14",
|
|
6
|
+
height: "14",
|
|
7
|
+
viewBox: "0 0 24 24",
|
|
8
|
+
fill: "none",
|
|
9
|
+
stroke: "currentColor",
|
|
10
|
+
strokeWidth: "2",
|
|
11
|
+
strokeLinecap: "round",
|
|
12
|
+
strokeLinejoin: "round",
|
|
13
|
+
className: "lucide lucide-file-down"
|
|
14
|
+
}, /*#__PURE__*/React.createElement("path", {
|
|
15
|
+
d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"
|
|
16
|
+
}), /*#__PURE__*/React.createElement("path", {
|
|
17
|
+
d: "M14 2v4a2 2 0 0 0 2 2h4"
|
|
18
|
+
}), /*#__PURE__*/React.createElement("path", {
|
|
19
|
+
d: "M12 18v-6"
|
|
20
|
+
}), /*#__PURE__*/React.createElement("path", {
|
|
21
|
+
d: "m9 15 3 3 3-3"
|
|
22
|
+
}));
|
|
23
|
+
};
|
|
24
|
+
export default ExportFile;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
var TextIcon = function TextIcon() {
|
|
3
|
+
return /*#__PURE__*/React.createElement("svg", {
|
|
4
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
5
|
+
width: "14",
|
|
6
|
+
height: "14",
|
|
7
|
+
viewBox: "0 0 24 24",
|
|
8
|
+
fill: "none",
|
|
9
|
+
stroke: "currentColor",
|
|
10
|
+
strokeWidth: "2",
|
|
11
|
+
strokeLinecap: "round",
|
|
12
|
+
strokeLinejoin: "round",
|
|
13
|
+
className: "lucide lucide-copy"
|
|
14
|
+
}, /*#__PURE__*/React.createElement("rect", {
|
|
15
|
+
width: "14",
|
|
16
|
+
height: "14",
|
|
17
|
+
x: "8",
|
|
18
|
+
y: "8",
|
|
19
|
+
rx: "2",
|
|
20
|
+
ry: "2"
|
|
21
|
+
}), /*#__PURE__*/React.createElement("path", {
|
|
22
|
+
d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"
|
|
23
|
+
}));
|
|
24
|
+
};
|
|
25
|
+
export default TextIcon;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
var TextIcon = function TextIcon() {
|
|
3
|
+
return /*#__PURE__*/React.createElement("svg", {
|
|
4
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
5
|
+
width: "14",
|
|
6
|
+
height: "14",
|
|
7
|
+
viewBox: "0 0 24 24",
|
|
8
|
+
fill: "none",
|
|
9
|
+
stroke: "currentColor",
|
|
10
|
+
strokeWidth: "2",
|
|
11
|
+
strokeLinecap: "round",
|
|
12
|
+
strokeLinejoin: "round",
|
|
13
|
+
className: "lucide lucide-file-text"
|
|
14
|
+
}, /*#__PURE__*/React.createElement("path", {
|
|
15
|
+
d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"
|
|
16
|
+
}), /*#__PURE__*/React.createElement("path", {
|
|
17
|
+
d: "M14 2v4a2 2 0 0 0 2 2h4"
|
|
18
|
+
}), /*#__PURE__*/React.createElement("path", {
|
|
19
|
+
d: "M10 9H8"
|
|
20
|
+
}), /*#__PURE__*/React.createElement("path", {
|
|
21
|
+
d: "M16 13H8"
|
|
22
|
+
}), /*#__PURE__*/React.createElement("path", {
|
|
23
|
+
d: "M16 17H8"
|
|
24
|
+
}));
|
|
25
|
+
};
|
|
26
|
+
export default TextIcon;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
var TextIcon = function TextIcon() {
|
|
3
|
+
return /*#__PURE__*/React.createElement("svg", {
|
|
4
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
5
|
+
width: "14",
|
|
6
|
+
height: "14",
|
|
7
|
+
viewBox: "0 0 24 24",
|
|
8
|
+
fill: "none",
|
|
9
|
+
stroke: "currentColor",
|
|
10
|
+
strokeWidth: "2",
|
|
11
|
+
strokeLinecap: "round",
|
|
12
|
+
strokeLinejoin: "round",
|
|
13
|
+
className: "lucide lucide-type"
|
|
14
|
+
}, /*#__PURE__*/React.createElement("polyline", {
|
|
15
|
+
points: "4 7 4 4 20 4 20 7"
|
|
16
|
+
}), /*#__PURE__*/React.createElement("line", {
|
|
17
|
+
x1: "9",
|
|
18
|
+
x2: "15",
|
|
19
|
+
y1: "20",
|
|
20
|
+
y2: "20"
|
|
21
|
+
}), /*#__PURE__*/React.createElement("line", {
|
|
22
|
+
x1: "12",
|
|
23
|
+
x2: "12",
|
|
24
|
+
y1: "4",
|
|
25
|
+
y2: "20"
|
|
26
|
+
}));
|
|
27
|
+
};
|
|
28
|
+
export default TextIcon;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 将HTML内容转换为PDF文档流
|
|
3
|
+
* @param htmlElement HTML元素
|
|
4
|
+
* @param options 配置选项
|
|
5
|
+
* @returns PDF文档的Blob对象
|
|
6
|
+
*/
|
|
7
|
+
export declare const html2pdf: (htmlElement: HTMLElement, options?: {
|
|
8
|
+
filename?: string;
|
|
9
|
+
margin?: number;
|
|
10
|
+
image?: {
|
|
11
|
+
type?: 'jpeg' | 'png';
|
|
12
|
+
quality?: number;
|
|
13
|
+
};
|
|
14
|
+
jsPDF?: {
|
|
15
|
+
orientation?: 'portrait' | 'landscape';
|
|
16
|
+
unit?: 'pt' | 'mm' | 'cm' | 'in';
|
|
17
|
+
format?: 'a4' | 'a3' | 'a5' | 'a0';
|
|
18
|
+
};
|
|
19
|
+
}, onProgress?: ((progress: number, title: string) => void) | undefined) => Promise<Blob>;
|
|
20
|
+
/**
|
|
21
|
+
* 将HTML元素转换为PDF文档流并下载
|
|
22
|
+
* @param dom HTML元素
|
|
23
|
+
* @param pageWidth 页面宽度
|
|
24
|
+
* @param fileName 文件名
|
|
25
|
+
* @returns 下载的PDF文件
|
|
26
|
+
*/
|
|
27
|
+
export declare const domloadPdf: (dom: HTMLElement, pageWidth: 'a4' | 'a3' | 'a5' | 'a0', fileName?: string, onProgress?: ((progress: number, title: string) => void) | undefined) => Promise<void>;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
|
|
2
|
+
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
3
|
+
/**
|
|
4
|
+
* 将HTML内容转换为PDF文档流
|
|
5
|
+
* @param htmlElement HTML元素
|
|
6
|
+
* @param options 配置选项
|
|
7
|
+
* @returns PDF文档的Blob对象
|
|
8
|
+
*/
|
|
9
|
+
export var html2pdf = /*#__PURE__*/function () {
|
|
10
|
+
var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(htmlElement) {
|
|
11
|
+
var _options$jsPDF, _options$jsPDF2, _options$jsPDF3, _options$image, _options$image2;
|
|
12
|
+
var options,
|
|
13
|
+
onProgress,
|
|
14
|
+
_yield$import,
|
|
15
|
+
JS_PDF,
|
|
16
|
+
pdf,
|
|
17
|
+
_yield$import2,
|
|
18
|
+
html2canvas,
|
|
19
|
+
canvas,
|
|
20
|
+
imageType,
|
|
21
|
+
imageQuality,
|
|
22
|
+
imgData,
|
|
23
|
+
margin,
|
|
24
|
+
pdfWidth,
|
|
25
|
+
pdfHeight,
|
|
26
|
+
imgWidth,
|
|
27
|
+
imgHeight,
|
|
28
|
+
heightLeft,
|
|
29
|
+
position,
|
|
30
|
+
pageHeight,
|
|
31
|
+
_args = arguments;
|
|
32
|
+
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
33
|
+
while (1) switch (_context.prev = _context.next) {
|
|
34
|
+
case 0:
|
|
35
|
+
options = _args.length > 1 && _args[1] !== undefined ? _args[1] : {};
|
|
36
|
+
onProgress = _args.length > 2 ? _args[2] : undefined;
|
|
37
|
+
_context.next = 4;
|
|
38
|
+
return import( /* webpackChunkName: "jspdf" */'jspdf');
|
|
39
|
+
case 4:
|
|
40
|
+
_yield$import = _context.sent;
|
|
41
|
+
JS_PDF = _yield$import.jsPDF;
|
|
42
|
+
// 创建jsPDF实例
|
|
43
|
+
pdf = new JS_PDF({
|
|
44
|
+
orientation: ((_options$jsPDF = options.jsPDF) === null || _options$jsPDF === void 0 ? void 0 : _options$jsPDF.orientation) || 'portrait',
|
|
45
|
+
unit: ((_options$jsPDF2 = options.jsPDF) === null || _options$jsPDF2 === void 0 ? void 0 : _options$jsPDF2.unit) || 'pt',
|
|
46
|
+
format: ((_options$jsPDF3 = options.jsPDF) === null || _options$jsPDF3 === void 0 ? void 0 : _options$jsPDF3.format) || 'a4'
|
|
47
|
+
});
|
|
48
|
+
_context.next = 9;
|
|
49
|
+
return import /* webpackChunkName: "html2canvas" */('html2canvas');
|
|
50
|
+
case 9:
|
|
51
|
+
_yield$import2 = _context.sent;
|
|
52
|
+
html2canvas = _yield$import2.default;
|
|
53
|
+
onProgress === null || onProgress === void 0 || onProgress(20, '渲染页面内容...');
|
|
54
|
+
// 将HTML元素转换为Canvas
|
|
55
|
+
_context.next = 14;
|
|
56
|
+
return html2canvas(htmlElement, {
|
|
57
|
+
scale: 2,
|
|
58
|
+
// 提高清晰度
|
|
59
|
+
useCORS: true,
|
|
60
|
+
// 允许跨域图片
|
|
61
|
+
logging: false
|
|
62
|
+
});
|
|
63
|
+
case 14:
|
|
64
|
+
canvas = _context.sent;
|
|
65
|
+
// 获取Canvas数据URL
|
|
66
|
+
imageType = ((_options$image = options.image) === null || _options$image === void 0 ? void 0 : _options$image.type) || 'jpeg';
|
|
67
|
+
imageQuality = ((_options$image2 = options.image) === null || _options$image2 === void 0 ? void 0 : _options$image2.quality) || 1.0;
|
|
68
|
+
imgData = canvas.toDataURL("image/".concat(imageType), imageQuality); // 设置页面边距
|
|
69
|
+
margin = options.margin || 20;
|
|
70
|
+
pdfWidth = pdf.internal.pageSize.getWidth();
|
|
71
|
+
pdfHeight = pdf.internal.pageSize.getHeight();
|
|
72
|
+
imgWidth = pdfWidth - margin * 2;
|
|
73
|
+
imgHeight = canvas.height * imgWidth / canvas.width; // 添加图片到PDF
|
|
74
|
+
heightLeft = imgHeight;
|
|
75
|
+
position = margin;
|
|
76
|
+
pageHeight = pdfHeight - margin * 2; // 处理多页情况
|
|
77
|
+
pdf.addImage(imgData, imageType.toUpperCase(), margin, position, imgWidth, imgHeight);
|
|
78
|
+
heightLeft -= pageHeight;
|
|
79
|
+
while (heightLeft >= 0) {
|
|
80
|
+
position = heightLeft - imgHeight;
|
|
81
|
+
pdf.addPage();
|
|
82
|
+
pdf.addImage(imgData, imageType.toUpperCase(), margin, position, imgWidth, imgHeight);
|
|
83
|
+
heightLeft -= pageHeight;
|
|
84
|
+
}
|
|
85
|
+
onProgress === null || onProgress === void 0 || onProgress(50, '转换HTML内容...');
|
|
86
|
+
// 返回PDF文档流
|
|
87
|
+
return _context.abrupt("return", pdf.output('blob'));
|
|
88
|
+
case 31:
|
|
89
|
+
case "end":
|
|
90
|
+
return _context.stop();
|
|
91
|
+
}
|
|
92
|
+
}, _callee);
|
|
93
|
+
}));
|
|
94
|
+
return function html2pdf(_x) {
|
|
95
|
+
return _ref.apply(this, arguments);
|
|
96
|
+
};
|
|
97
|
+
}();
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* 将HTML元素转换为PDF文档流并下载
|
|
101
|
+
* @param dom HTML元素
|
|
102
|
+
* @param pageWidth 页面宽度
|
|
103
|
+
* @param fileName 文件名
|
|
104
|
+
* @returns 下载的PDF文件
|
|
105
|
+
*/
|
|
106
|
+
export var domloadPdf = /*#__PURE__*/function () {
|
|
107
|
+
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(dom, pageWidth) {
|
|
108
|
+
var fileName,
|
|
109
|
+
onProgress,
|
|
110
|
+
_yield$import3,
|
|
111
|
+
saveAs,
|
|
112
|
+
blob,
|
|
113
|
+
_args2 = arguments;
|
|
114
|
+
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
|
115
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
116
|
+
case 0:
|
|
117
|
+
fileName = _args2.length > 2 && _args2[2] !== undefined ? _args2[2] : '未命名';
|
|
118
|
+
onProgress = _args2.length > 3 ? _args2[3] : undefined;
|
|
119
|
+
_context2.next = 4;
|
|
120
|
+
return import /* webpackChunkName: "saveAs" */('file-saver');
|
|
121
|
+
case 4:
|
|
122
|
+
_yield$import3 = _context2.sent;
|
|
123
|
+
saveAs = _yield$import3.saveAs;
|
|
124
|
+
onProgress === null || onProgress === void 0 || onProgress(5, '初始化...');
|
|
125
|
+
_context2.next = 9;
|
|
126
|
+
return html2pdf(dom, {
|
|
127
|
+
jsPDF: {
|
|
128
|
+
orientation: 'portrait',
|
|
129
|
+
unit: 'pt',
|
|
130
|
+
format: pageWidth
|
|
131
|
+
}
|
|
132
|
+
}, onProgress);
|
|
133
|
+
case 9:
|
|
134
|
+
blob = _context2.sent;
|
|
135
|
+
onProgress === null || onProgress === void 0 || onProgress(80, '生成PDF...');
|
|
136
|
+
return _context2.abrupt("return", saveAs(blob, "".concat(fileName, ".pdf")));
|
|
137
|
+
case 12:
|
|
138
|
+
case "end":
|
|
139
|
+
return _context2.stop();
|
|
140
|
+
}
|
|
141
|
+
}, _callee2);
|
|
142
|
+
}));
|
|
143
|
+
return function domloadPdf(_x2, _x3) {
|
|
144
|
+
return _ref2.apply(this, arguments);
|
|
145
|
+
};
|
|
146
|
+
}();
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
interface HeadingStyle extends TextStyle {
|
|
2
|
+
marginTop: string;
|
|
3
|
+
marginBottom: string;
|
|
4
|
+
}
|
|
5
|
+
export interface TextStyle {
|
|
6
|
+
fontSize: string;
|
|
7
|
+
fontFamily: string;
|
|
8
|
+
fontWeight: string;
|
|
9
|
+
lineHeight: string;
|
|
10
|
+
color: string;
|
|
11
|
+
}
|
|
12
|
+
interface ListStyle extends TextStyle {
|
|
13
|
+
paddingLeft: string;
|
|
14
|
+
marginTop: string;
|
|
15
|
+
marginBottom: string;
|
|
16
|
+
}
|
|
17
|
+
export interface FormatSettings {
|
|
18
|
+
headings: {
|
|
19
|
+
h1: HeadingStyle;
|
|
20
|
+
h2: HeadingStyle;
|
|
21
|
+
h3: HeadingStyle;
|
|
22
|
+
h4: HeadingStyle;
|
|
23
|
+
h5: HeadingStyle;
|
|
24
|
+
h6: HeadingStyle;
|
|
25
|
+
};
|
|
26
|
+
paragraph: TextStyle;
|
|
27
|
+
lists: {
|
|
28
|
+
ul: ListStyle;
|
|
29
|
+
ol: ListStyle;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* 生成CSS样式内容
|
|
34
|
+
* @param settings 格式设置
|
|
35
|
+
* @returns CSS样式字符串
|
|
36
|
+
*/
|
|
37
|
+
export declare const generateStylesFromSettings: (settings: FormatSettings) => string;
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
2
|
+
/**
|
|
3
|
+
* 生成CSS样式内容
|
|
4
|
+
* @param settings 格式设置
|
|
5
|
+
* @returns CSS样式字符串
|
|
6
|
+
*/
|
|
7
|
+
export var generateStylesFromSettings = function generateStylesFromSettings(settings) {
|
|
8
|
+
var css = '';
|
|
9
|
+
|
|
10
|
+
// 处理标题样式
|
|
11
|
+
Object.entries(settings.headings).forEach(function (_ref) {
|
|
12
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
|
13
|
+
heading = _ref2[0],
|
|
14
|
+
style = _ref2[1];
|
|
15
|
+
css += "\n".concat(heading, " {\n font-family: ").concat(style.fontFamily, ";\n font-size: ").concat(style.fontSize, ";\n font-weight: ").concat(style.fontWeight, ";\n line-height: ").concat(style.lineHeight, ";\n color: ").concat(style.color, ";\n margin-top: ").concat(style.marginTop, ";\n margin-bottom: ").concat(style.marginBottom, ";\n}\n");
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
// 处理段落样式
|
|
19
|
+
css += "\np {\n font-family: ".concat(settings.paragraph.fontFamily, ";\n font-size: ").concat(settings.paragraph.fontSize, ";\n font-weight: ").concat(settings.paragraph.fontWeight, ";\n line-height: ").concat(settings.paragraph.lineHeight, ";\n color: ").concat(settings.paragraph.color, ";\n}\n");
|
|
20
|
+
|
|
21
|
+
// 处理列表样式
|
|
22
|
+
css += "\nul {\n font-family: ".concat(settings.lists.ul.fontFamily, ";\n font-size: ").concat(settings.lists.ul.fontSize, ";\n font-weight: ").concat(settings.lists.ul.fontWeight, ";\n line-height: ").concat(settings.lists.ul.lineHeight, ";\n color: ").concat(settings.lists.ul.color, ";\n padding-left: ").concat(settings.lists.ul.paddingLeft, ";\n margin-top: ").concat(settings.lists.ul.marginTop, ";\n margin-bottom: ").concat(settings.lists.ul.marginBottom, ";\n}\n\nol {\n font-family: ").concat(settings.lists.ol.fontFamily, ";\n font-size: ").concat(settings.lists.ol.fontSize, ";\n font-weight: ").concat(settings.lists.ol.fontWeight, ";\n line-height: ").concat(settings.lists.ol.lineHeight, ";\n color: ").concat(settings.lists.ol.color, ";\n padding-left: ").concat(settings.lists.ol.paddingLeft, ";\n margin-top: ").concat(settings.lists.ol.marginTop, ";\n margin-bottom: ").concat(settings.lists.ol.marginBottom, ";\n}\n");
|
|
23
|
+
return css;
|
|
24
|
+
};
|
package/es/type.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { FormatSettings } from './tools/generateStylesFromSettings';
|
|
2
3
|
interface IUeditorStype extends React.CSSProperties {
|
|
3
4
|
toolbarColor?: string;
|
|
4
5
|
}
|
|
@@ -100,6 +101,22 @@ export interface ILcdpUeditorProps {
|
|
|
100
101
|
* @param val 编辑器内容
|
|
101
102
|
*/
|
|
102
103
|
onChange?(val: string): void;
|
|
104
|
+
/**
|
|
105
|
+
* 样式前缀
|
|
106
|
+
*/
|
|
107
|
+
prefixCls?: string;
|
|
108
|
+
/**
|
|
109
|
+
* 格式设置变化
|
|
110
|
+
*/
|
|
111
|
+
onFormatChange?(val: FormatSettings): void;
|
|
112
|
+
/**
|
|
113
|
+
* 默认格式设置
|
|
114
|
+
*/
|
|
115
|
+
defaultFormatSetting?: FormatSettings;
|
|
116
|
+
/**
|
|
117
|
+
* 底部功能类型
|
|
118
|
+
*/
|
|
119
|
+
bottomTypes?: Array<'chineseCount' | 'charCount' | 'pageWidth' | 'formatSetting' | 'exportPdf' | 'fullScreen' | 'copy'>;
|
|
103
120
|
}
|
|
104
121
|
export interface ILcdpUeditorInst {
|
|
105
122
|
/**
|
package/lib/LcdpUeditor.d.ts
CHANGED
|
@@ -37,19 +37,20 @@ declare class LcdpUeditor extends React.Component<ILcdpUeditorProps, {}> {
|
|
|
37
37
|
* 上传文件函数
|
|
38
38
|
*/
|
|
39
39
|
private uploadFunction;
|
|
40
|
-
/**
|
|
41
|
-
* 是否加载完成
|
|
42
|
-
*/
|
|
43
|
-
private isReady;
|
|
44
40
|
/**
|
|
45
41
|
* 保存 compositionend 事件处理器引用
|
|
46
42
|
*/
|
|
47
43
|
private compositionEndHandler?;
|
|
44
|
+
/**
|
|
45
|
+
* 是否全屏
|
|
46
|
+
*/
|
|
47
|
+
private prefixCls;
|
|
48
48
|
/**
|
|
49
49
|
* 初始加载失败
|
|
50
50
|
*/
|
|
51
51
|
state: Readonly<{
|
|
52
52
|
initError: boolean;
|
|
53
|
+
isReady: boolean;
|
|
53
54
|
}>;
|
|
54
55
|
/**
|
|
55
56
|
* 编辑器配置项
|
|
@@ -80,6 +81,16 @@ declare class LcdpUeditor extends React.Component<ILcdpUeditorProps, {}> {
|
|
|
80
81
|
* 初始化编辑器实例
|
|
81
82
|
*/
|
|
82
83
|
initUeditor(): Promise<void>;
|
|
84
|
+
getStatusBarItem: (params: {
|
|
85
|
+
icon: React.ReactNode;
|
|
86
|
+
content: React.ReactNode;
|
|
87
|
+
onClick?: () => void;
|
|
88
|
+
extraNode?: React.ReactNode;
|
|
89
|
+
}) => JSX.Element;
|
|
90
|
+
/**
|
|
91
|
+
* 渲染状态栏
|
|
92
|
+
*/
|
|
93
|
+
renderStatusBar(): void;
|
|
83
94
|
render(): React.ReactNode;
|
|
84
95
|
}
|
|
85
96
|
export default LcdpUeditor;
|
package/lib/LcdpUeditor.js
CHANGED
|
@@ -33,11 +33,13 @@ __export(LcdpUeditor_exports, {
|
|
|
33
33
|
});
|
|
34
34
|
module.exports = __toCommonJS(LcdpUeditor_exports);
|
|
35
35
|
var import_react = __toESM(require("react"));
|
|
36
|
+
var import_react_dom = __toESM(require("react-dom"));
|
|
36
37
|
var import_const = require("./const");
|
|
37
38
|
var import_defaultConfig = __toESM(require("./defaultConfig.json"));
|
|
38
39
|
var import_UeditorResourceLoader = __toESM(require("./tools/UeditorResourceLoader"));
|
|
39
40
|
var import_debounce = __toESM(require("lodash/debounce"));
|
|
40
41
|
var import_filterHtmlNode = require("./tools/filterHtmlNode");
|
|
42
|
+
var import_ToolBottomBar = __toESM(require("./ToolBottomBar"));
|
|
41
43
|
var LcdpUeditor = class extends import_react.default.Component {
|
|
42
44
|
constructor(props) {
|
|
43
45
|
super(props);
|
|
@@ -66,20 +68,28 @@ var LcdpUeditor = class extends import_react.default.Component {
|
|
|
66
68
|
*/
|
|
67
69
|
this.currentContent = "";
|
|
68
70
|
/**
|
|
69
|
-
*
|
|
71
|
+
* 是否全屏
|
|
70
72
|
*/
|
|
71
|
-
this.
|
|
73
|
+
this.prefixCls = "pcfactory";
|
|
72
74
|
/**
|
|
73
75
|
* 初始加载失败
|
|
74
76
|
*/
|
|
75
77
|
this.state = {
|
|
76
|
-
initError: false
|
|
78
|
+
initError: false,
|
|
79
|
+
/**
|
|
80
|
+
* 是否加载完成
|
|
81
|
+
*/
|
|
82
|
+
isReady: false
|
|
77
83
|
};
|
|
78
84
|
/**
|
|
79
85
|
* 编辑器配置项
|
|
80
86
|
*/
|
|
81
87
|
this.editorConfig = {};
|
|
82
|
-
|
|
88
|
+
this.getStatusBarItem = (params) => {
|
|
89
|
+
const { icon, content, onClick, extraNode } = params;
|
|
90
|
+
return /* @__PURE__ */ import_react.default.createElement("span", { className: "ueditor-rich-status-bar-item", onClick }, /* @__PURE__ */ import_react.default.createElement("span", { className: "ueditor-rich-status-bar-icon" }, icon), /* @__PURE__ */ import_react.default.createElement("span", { className: "ueditor-rich-status-bar-content" }, content), extraNode);
|
|
91
|
+
};
|
|
92
|
+
const { config, prefixCls, onFormatChange } = props;
|
|
83
93
|
this.containerId = `ueditor_${Date.now()}_${String(Math.random()).slice(2, 6)}`;
|
|
84
94
|
if (this.props.ueditorPath) {
|
|
85
95
|
this.ueditorPath = this.props.ueditorPath;
|
|
@@ -103,6 +113,7 @@ var LcdpUeditor = class extends import_react.default.Component {
|
|
|
103
113
|
}
|
|
104
114
|
return null;
|
|
105
115
|
};
|
|
116
|
+
this.prefixCls = prefixCls || "pcfactory";
|
|
106
117
|
this.editorConfig = {
|
|
107
118
|
...import_defaultConfig.default,
|
|
108
119
|
maximumWords: (config == null ? void 0 : config.maximumWords) || 1e4,
|
|
@@ -113,7 +124,8 @@ var LcdpUeditor = class extends import_react.default.Component {
|
|
|
113
124
|
},
|
|
114
125
|
uploadFunction: this.uploadFunction,
|
|
115
126
|
initialContent: "",
|
|
116
|
-
pasteplain: (config == null ? void 0 : config.pasteplain) === true
|
|
127
|
+
pasteplain: (config == null ? void 0 : config.pasteplain) === true,
|
|
128
|
+
onFormatChange
|
|
117
129
|
};
|
|
118
130
|
this.debounceContentChange = (0, import_debounce.default)(this.onContentChange.bind(this), 300);
|
|
119
131
|
}
|
|
@@ -121,7 +133,7 @@ var LcdpUeditor = class extends import_react.default.Component {
|
|
|
121
133
|
this.initUeditor();
|
|
122
134
|
}
|
|
123
135
|
componentWillReceiveProps(nextProps) {
|
|
124
|
-
if (this.isReady) {
|
|
136
|
+
if (this.state.isReady) {
|
|
125
137
|
if ("value" in nextProps && this.currentContent !== nextProps.value) {
|
|
126
138
|
this.isReportFlag = false;
|
|
127
139
|
this.ueditorInst.setContent((0, import_filterHtmlNode.filterHtmlNode)(nextProps.value || "").str);
|
|
@@ -137,7 +149,7 @@ var LcdpUeditor = class extends import_react.default.Component {
|
|
|
137
149
|
}
|
|
138
150
|
componentWillUnmount() {
|
|
139
151
|
var _a, _b, _c;
|
|
140
|
-
if (this.isReady) {
|
|
152
|
+
if (this.state.isReady) {
|
|
141
153
|
const editorBody = (_a = this.ueditorInst) == null ? void 0 : _a.body;
|
|
142
154
|
if (editorBody && this.compositionEndHandler) {
|
|
143
155
|
editorBody.removeEventListener("compositionend", this.compositionEndHandler);
|
|
@@ -259,7 +271,9 @@ var LcdpUeditor = class extends import_react.default.Component {
|
|
|
259
271
|
if (nextValue) {
|
|
260
272
|
this.ueditorInst.setContent(nextValue);
|
|
261
273
|
}
|
|
262
|
-
this.
|
|
274
|
+
this.setState({
|
|
275
|
+
isReady: true
|
|
276
|
+
});
|
|
263
277
|
if (this.props.disabled) {
|
|
264
278
|
this.ueditorInst.setDisabled();
|
|
265
279
|
} else {
|
|
@@ -277,6 +291,7 @@ var LcdpUeditor = class extends import_react.default.Component {
|
|
|
277
291
|
}
|
|
278
292
|
this.initStyle();
|
|
279
293
|
this.mountRef();
|
|
294
|
+
this.renderStatusBar();
|
|
280
295
|
});
|
|
281
296
|
};
|
|
282
297
|
import_UeditorResourceLoader.default.onReady(readyFunc);
|
|
@@ -288,6 +303,28 @@ var LcdpUeditor = class extends import_react.default.Component {
|
|
|
288
303
|
});
|
|
289
304
|
import_UeditorResourceLoader.default.startLoad(jsList);
|
|
290
305
|
}
|
|
306
|
+
/**
|
|
307
|
+
* 渲染状态栏
|
|
308
|
+
*/
|
|
309
|
+
renderStatusBar() {
|
|
310
|
+
var _a, _b;
|
|
311
|
+
const bottomBarContainer = (_a = this.containerRef.current) == null ? void 0 : _a.querySelector("#edui1_bottombar");
|
|
312
|
+
const comp = /* @__PURE__ */ import_react.default.createElement(
|
|
313
|
+
import_ToolBottomBar.default,
|
|
314
|
+
{
|
|
315
|
+
ueditorInst: this.ueditorInst,
|
|
316
|
+
prefixCls: this.prefixCls,
|
|
317
|
+
containerRef: this.containerRef,
|
|
318
|
+
defaultFormatSetting: this.props.defaultFormatSetting,
|
|
319
|
+
onFormatChange: this.editorConfig.onFormatChange,
|
|
320
|
+
isReady: this.state.isReady,
|
|
321
|
+
bottomTypes: this.props.bottomTypes
|
|
322
|
+
}
|
|
323
|
+
);
|
|
324
|
+
if (bottomBarContainer && ((_b = this.props.bottomTypes) == null ? void 0 : _b.length)) {
|
|
325
|
+
import_react_dom.default.render(comp, bottomBarContainer);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
291
328
|
render() {
|
|
292
329
|
const { initError } = this.state;
|
|
293
330
|
if (initError) {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import './index.less';
|
|
3
|
+
import { FormatSettings } from '../../tools/generateStylesFromSettings';
|
|
4
|
+
interface FormatSettingsPanelProps {
|
|
5
|
+
onApply: (settings: FormatSettings) => void;
|
|
6
|
+
initialSettings?: Partial<FormatSettings>;
|
|
7
|
+
}
|
|
8
|
+
declare const FormatSettingsPanel: React.FC<React.PropsWithChildren<FormatSettingsPanelProps>>;
|
|
9
|
+
export default FormatSettingsPanel;
|