suneditor 2.47.5 → 2.47.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/LICENSE.txt +20 -20
  2. package/README.md +1625 -1613
  3. package/dist/css/suneditor.min.css +1 -1
  4. package/dist/suneditor.min.js +2 -2
  5. package/example.md +586 -586
  6. package/package.json +71 -71
  7. package/src/assets/css/suneditor-contents.css +561 -561
  8. package/src/assets/css/suneditor.css +2 -2
  9. package/src/assets/defaultIcons.js +103 -103
  10. package/src/lang/Lang.d.ts +143 -143
  11. package/src/lang/ckb.d.ts +4 -4
  12. package/src/lang/ckb.js +187 -187
  13. package/src/lang/cs.d.ts +4 -4
  14. package/src/lang/cs.js +187 -187
  15. package/src/lang/da.d.ts +4 -4
  16. package/src/lang/da.js +191 -191
  17. package/src/lang/de.d.ts +4 -4
  18. package/src/lang/de.js +188 -188
  19. package/src/lang/en.d.ts +4 -4
  20. package/src/lang/en.js +187 -187
  21. package/src/lang/es.d.ts +4 -4
  22. package/src/lang/es.js +187 -187
  23. package/src/lang/fa.d.ts +4 -4
  24. package/src/lang/fa.js +187 -187
  25. package/src/lang/fr.d.ts +4 -4
  26. package/src/lang/fr.js +188 -188
  27. package/src/lang/he.d.ts +4 -4
  28. package/src/lang/he.js +188 -188
  29. package/src/lang/hu.d.ts +5 -5
  30. package/src/lang/hu.js +188 -188
  31. package/src/lang/index.d.ts +25 -24
  32. package/src/lang/index.js +30 -27
  33. package/src/lang/it.d.ts +4 -4
  34. package/src/lang/it.js +188 -188
  35. package/src/lang/ja.d.ts +4 -4
  36. package/src/lang/ja.js +187 -187
  37. package/src/lang/km.d.ts +5 -0
  38. package/src/lang/km.js +188 -0
  39. package/src/lang/ko.d.ts +4 -4
  40. package/src/lang/ko.js +187 -187
  41. package/src/lang/lv.d.ts +4 -4
  42. package/src/lang/lv.js +187 -187
  43. package/src/lang/nl.d.ts +4 -4
  44. package/src/lang/nl.js +187 -187
  45. package/src/lang/pl.d.ts +4 -4
  46. package/src/lang/pl.js +187 -187
  47. package/src/lang/pt_br.d.ts +4 -4
  48. package/src/lang/pt_br.js +189 -189
  49. package/src/lang/ro.d.ts +4 -4
  50. package/src/lang/ro.js +187 -187
  51. package/src/lang/ru.d.ts +4 -4
  52. package/src/lang/ru.js +187 -187
  53. package/src/lang/se.d.ts +4 -4
  54. package/src/lang/se.js +191 -191
  55. package/src/lang/tr.d.ts +5 -5
  56. package/src/lang/tr.js +191 -191
  57. package/src/lang/ua.d.ts +5 -5
  58. package/src/lang/ua.js +188 -188
  59. package/src/lang/ur.d.ts +4 -4
  60. package/src/lang/ur.js +187 -187
  61. package/src/lang/zh_cn.d.ts +4 -4
  62. package/src/lang/zh_cn.js +187 -187
  63. package/src/lib/constructor.js +0 -0
  64. package/src/lib/context.d.ts +42 -42
  65. package/src/lib/context.js +0 -0
  66. package/src/lib/core.d.ts +1135 -1135
  67. package/src/lib/core.js +9 -3
  68. package/src/lib/history.d.ts +48 -48
  69. package/src/lib/history.js +218 -218
  70. package/src/lib/util.d.ts +677 -677
  71. package/src/lib/util.js +1 -1
  72. package/src/options.d.ts +621 -620
  73. package/src/plugins/CommandPlugin.d.ts +7 -7
  74. package/src/plugins/DialogPlugin.d.ts +19 -19
  75. package/src/plugins/FileBrowserPlugin.d.ts +29 -29
  76. package/src/plugins/Module.d.ts +14 -14
  77. package/src/plugins/Plugin.d.ts +41 -41
  78. package/src/plugins/SubmenuPlugin.d.ts +7 -7
  79. package/src/plugins/command/blockquote.d.ts +4 -4
  80. package/src/plugins/command/blockquote.js +46 -46
  81. package/src/plugins/dialog/audio.d.ts +4 -4
  82. package/src/plugins/dialog/audio.js +557 -558
  83. package/src/plugins/dialog/image.d.ts +4 -4
  84. package/src/plugins/dialog/image.js +1126 -1127
  85. package/src/plugins/dialog/link.d.ts +4 -4
  86. package/src/plugins/dialog/link.js +223 -223
  87. package/src/plugins/dialog/math.d.ts +4 -4
  88. package/src/plugins/dialog/math.js +300 -300
  89. package/src/plugins/dialog/video.d.ts +4 -4
  90. package/src/plugins/dialog/video.js +989 -989
  91. package/src/plugins/fileBrowser/imageGallery.d.ts +4 -4
  92. package/src/plugins/fileBrowser/imageGallery.js +64 -64
  93. package/src/plugins/index.d.ts +79 -79
  94. package/src/plugins/index.js +32 -32
  95. package/src/plugins/modules/_anchor.js +461 -461
  96. package/src/plugins/modules/_colorPicker.d.ts +59 -59
  97. package/src/plugins/modules/_colorPicker.js +0 -0
  98. package/src/plugins/modules/_notice.d.ts +20 -20
  99. package/src/plugins/modules/_notice.js +72 -72
  100. package/src/plugins/modules/_selectMenu.js +118 -118
  101. package/src/plugins/modules/component.d.ts +24 -24
  102. package/src/plugins/modules/component.js +80 -80
  103. package/src/plugins/modules/dialog.d.ts +27 -27
  104. package/src/plugins/modules/dialog.js +174 -174
  105. package/src/plugins/modules/fileBrowser.d.ts +41 -41
  106. package/src/plugins/modules/fileBrowser.js +377 -377
  107. package/src/plugins/modules/fileManager.d.ts +66 -66
  108. package/src/plugins/modules/fileManager.js +325 -325
  109. package/src/plugins/modules/index.d.ts +10 -10
  110. package/src/plugins/modules/index.js +8 -8
  111. package/src/plugins/modules/resizing.d.ts +153 -153
  112. package/src/plugins/modules/resizing.js +902 -902
  113. package/src/plugins/submenu/align.d.ts +4 -4
  114. package/src/plugins/submenu/align.js +160 -160
  115. package/src/plugins/submenu/font.d.ts +4 -4
  116. package/src/plugins/submenu/font.js +123 -123
  117. package/src/plugins/submenu/fontColor.d.ts +4 -4
  118. package/src/plugins/submenu/fontColor.js +0 -0
  119. package/src/plugins/submenu/fontSize.d.ts +4 -4
  120. package/src/plugins/submenu/fontSize.js +112 -112
  121. package/src/plugins/submenu/formatBlock.d.ts +4 -4
  122. package/src/plugins/submenu/formatBlock.js +273 -273
  123. package/src/plugins/submenu/hiliteColor.d.ts +4 -4
  124. package/src/plugins/submenu/hiliteColor.js +0 -0
  125. package/src/plugins/submenu/horizontalRule.d.ts +4 -4
  126. package/src/plugins/submenu/horizontalRule.js +98 -98
  127. package/src/plugins/submenu/lineHeight.d.ts +4 -4
  128. package/src/plugins/submenu/lineHeight.js +104 -104
  129. package/src/plugins/submenu/list.d.ts +4 -4
  130. package/src/plugins/submenu/list.js +456 -456
  131. package/src/plugins/submenu/paragraphStyle.d.ts +4 -4
  132. package/src/plugins/submenu/paragraphStyle.js +135 -135
  133. package/src/plugins/submenu/table.d.ts +4 -4
  134. package/src/plugins/submenu/template.d.ts +4 -4
  135. package/src/plugins/submenu/template.js +71 -71
  136. package/src/plugins/submenu/textStyle.d.ts +4 -4
  137. package/src/plugins/submenu/textStyle.js +167 -167
  138. package/src/suneditor.d.ts +9 -9
  139. package/src/suneditor.js +75 -75
  140. package/src/suneditor_build.js +20 -17
  141. package/README_V3_TEMP.md +0 -630
package/example.md CHANGED
@@ -1,587 +1,587 @@
1
- # Example usage in the framework
2
- This is just a simple example and is not a complete answer.
3
- If there are any examples or errors in other frameworks, please participate and correct them.
4
- - [React](#react-component)
5
- - [React class](#react-class)
6
- - [Vue](#vue-component)
7
-
8
-
9
- ## React Component
10
-
11
- ### React class
12
-
13
- ### 1. Editor.tsx
14
- ```typescript
15
- import React, { Component, createRef } from "react";
16
- import suneditor from "suneditor";
17
- import { en } from "suneditor/src/lang";
18
- import plugins from "suneditor/src/plugins";
19
- import CodeMirror from "codemirror";
20
- import katex from "katex";
21
- import "suneditor/dist/css/suneditor.min.css";
22
- import "codemirror/mode/htmlmixed/htmlmixed";
23
- import "codemirror/lib/codemirror.css";
24
- import "katex/dist/katex.min.css";
25
- import "./Editor.scss"
26
-
27
-
28
- interface Props {
29
- contents?: string;
30
- onBlur?: Function;
31
- onSave: Function;
32
- }
33
-
34
- interface State {
35
- imageList: any[];
36
- selectedImages: any[];
37
- imageSize: string;
38
- }
39
-
40
- class Editor extends Component<Props, State> {
41
- txtArea: any;
42
- editor: any;
43
-
44
- constructor(props: any) {
45
- super(props);
46
- this.txtArea = createRef();
47
- this.state = {
48
- imageList: [],
49
- selectedImages: [],
50
- imageSize: "0KB",
51
- };
52
- }
53
-
54
- componentDidMount() {
55
- const editor: any = this.editor = suneditor.create(this.txtArea.current, {
56
- plugins: plugins,
57
- lang: en,
58
- callBackSave: (contents: string) => this.props.onSave(contents),
59
- codeMirror: CodeMirror,
60
- stickyToolbar: 0,
61
- katex: katex,
62
- width: '100%',
63
- height: 'auto',
64
- minHeight: '400px',
65
- value: this.props.contents,
66
- // imageUploadUrl: `url`,
67
- imageMultipleFile: true,
68
- previewTemplate: `
69
- <div style="width:auto; max-width:1136px; min-height:400px; margin:auto;">
70
- {{contents}}
71
- </div>
72
- `,
73
- buttonList: [
74
- // default
75
- ['undo', 'redo'],
76
- ['font', 'fontSize', 'formatBlock'],
77
- ['paragraphStyle', 'blockquote'],
78
- ['bold', 'underline', 'italic', 'strike', 'subscript', 'superscript'],
79
- ['fontColor', 'hiliteColor', 'textStyle'],
80
- ['removeFormat'],
81
- ['outdent', 'indent'],
82
- ['align', 'horizontalRule', 'list', 'lineHeight'],
83
- ['table', 'link', 'image', 'video'],
84
- ['fullScreen', 'showBlocks', 'codeView'],
85
- ['preview'],
86
- ['save'],
87
- // responsive
88
- ['%1161', [
89
- ['undo', 'redo'],
90
- [':p-Formats-default.more_paragraph', 'font', 'fontSize', 'formatBlock', 'paragraphStyle', 'blockquote'],
91
- ['bold', 'underline', 'italic', 'strike', 'subscript', 'superscript'],
92
- ['fontColor', 'hiliteColor', 'textStyle'],
93
- ['removeFormat'],
94
- ['outdent', 'indent'],
95
- ['align', 'horizontalRule', 'list', 'lineHeight'],
96
- ['-right', 'save'],
97
- ['-right', ':i-Etc-default.more_vertical', 'fullScreen', 'showBlocks', 'codeView', 'preview'],
98
- ['-right', ':r-Table&Media-default.more_plus', 'table', 'link', 'image', 'video'],
99
- ]],
100
- ['%893', [
101
- ['undo', 'redo'],
102
- [':p-Formats-default.more_paragraph', 'font', 'fontSize', 'formatBlock', 'paragraphStyle', 'blockquote'],
103
- ['bold', 'underline', 'italic', 'strike'],
104
- [':t-Fonts-default.more_text', 'subscript', 'superscript', 'fontColor', 'hiliteColor', 'textStyle'],
105
- ['removeFormat'],
106
- ['outdent', 'indent'],
107
- ['align', 'horizontalRule', 'list', 'lineHeight'],
108
- ['-right', 'save'],
109
- ['-right', ':i-Etc-default.more_vertical', 'fullScreen', 'showBlocks', 'codeView', 'preview'],
110
- ['-right', ':r-Table&Media-default.more_plus', 'table', 'link', 'image', 'video'],
111
- ]],
112
- ['%855', [
113
- ['undo', 'redo'],
114
- [':p-Formats-default.more_paragraph', 'font', 'fontSize', 'formatBlock', 'paragraphStyle', 'blockquote'],
115
- [':t-Fonts-default.more_text', 'bold', 'underline', 'italic', 'strike', 'subscript', 'superscript', 'fontColor', 'hiliteColor', 'textStyle'],
116
- ['removeFormat'],
117
- ['outdent', 'indent'],
118
- ['align', 'horizontalRule', 'list', 'lineHeight'],
119
- [':r-Table&Media-default.more_plus', 'table', 'link', 'image', 'video'],
120
- ['-right', 'save'],
121
- ['-right', ':i-Etc-default.more_vertical', 'fullScreen', 'showBlocks', 'codeView', 'preview'],
122
- ]],
123
- ['%563', [
124
- ['undo', 'redo'],
125
- [':p-Formats-default.more_paragraph', 'font', 'fontSize', 'formatBlock', 'paragraphStyle', 'blockquote'],
126
- [':t-Fonts-default.more_text', 'bold', 'underline', 'italic', 'strike', 'subscript', 'superscript', 'fontColor', 'hiliteColor', 'textStyle'],
127
- ['removeFormat'],
128
- ['outdent', 'indent'],
129
- [':e-List&Line-default.more_horizontal', 'align', 'horizontalRule', 'list', 'lineHeight'],
130
- [':r-Table&Media-default.more_plus', 'table', 'link', 'image', 'video'],
131
- ['-right', 'save'],
132
- ['-right', ':i-Etc-default.more_vertical', 'fullScreen', 'showBlocks', 'codeView', 'preview'],
133
- ]],
134
- ['%458', [
135
- ['undo', 'redo'],
136
- [':p-Formats-default.more_paragraph', 'font', 'fontSize', 'formatBlock', 'paragraphStyle', 'blockquote'],
137
- [':t-Fonts-default.more_text', 'bold', 'underline', 'italic', 'strike', 'subscript', 'superscript', 'fontColor', 'hiliteColor', 'textStyle', 'removeFormat'],
138
- [':e-List&Line-default.more_horizontal', 'outdent', 'indent', 'align', 'horizontalRule', 'list', 'lineHeight'],
139
- [':r-Table&Media-default.more_plus', 'table', 'link', 'image', 'video'],
140
- ['-right', 'save'],
141
- ['-right', ':i-Etc-default.more_vertical', 'fullScreen', 'showBlocks', 'codeView', 'preview'],
142
- ]]
143
- ]
144
- });
145
-
146
- editor.onBlur = () => {
147
- if (typeof this.props.onBlur === 'function') this.props.onBlur()
148
- }
149
-
150
- editor.onImageUpload = this.imageUpload.bind(this);
151
- // editor.onVideoUpload = videoUpload;
152
- }
153
-
154
- componentDidUpdate(prevProps: any) {
155
- if (this.props.contents !== prevProps.contents) {
156
- this.editor.setContents(this.props.contents);
157
- this.editor.core.history.reset(true);
158
- }
159
- }
160
-
161
- componentWillUnmount() {
162
- if (this.editor) this.editor.destroy();
163
- }
164
-
165
- // image, video
166
- findIndex(arr: any[], index: number) {
167
- let idx = -1;
168
-
169
- arr.some(function (a, i) {
170
- if ((typeof a === 'number' ? a : a.index) === index) {
171
- idx = i;
172
- return true;
173
- }
174
- return false;
175
- })
176
-
177
- return idx;
178
- }
179
-
180
- imageUpload(targetElement: Element, index: number, state: string, imageInfo: Record<string, string>, remainingFilesCount: number) {
181
- if (state === 'delete') {
182
- this.state.imageList.splice(this.findIndex(this.state.imageList, index), 1)
183
- this.setState({
184
- imageList: this.state.imageList
185
- })
186
- } else {
187
- if (state === 'create') {
188
- const imageList = this.state.imageList;
189
- imageList.push(imageInfo)
190
- this.setState({
191
- imageList: imageList
192
- })
193
- } else { // update
194
- //
195
- }
196
- }
197
-
198
- if (remainingFilesCount === 0) {
199
- this.setImageList()
200
- }
201
- }
202
-
203
- setImageList() {
204
- const imageList = this.state.imageList;
205
- let size = 0;
206
-
207
- for (let i = 0; i < imageList.length; i++) {
208
- size += Number((imageList[i].size / 1000).toFixed(1));
209
- }
210
-
211
- this.setState({
212
- imageSize: size.toFixed(1) + 'KB'
213
- })
214
- }
215
-
216
- selectImage(evt: any, type: string, index: number) {
217
- evt.preventDefault();
218
- evt.stopPropagation();
219
- this.state.imageList[this.findIndex(this.state.imageList, index)][type]();
220
- }
221
-
222
- checkImage(index: number) {
223
- const selectedImages = this.state.selectedImages;
224
- const currentImageIdx = this.findIndex(selectedImages, index)
225
-
226
- if (currentImageIdx > -1) {
227
- selectedImages.splice(currentImageIdx, 1)
228
- } else {
229
- selectedImages.push(index)
230
- }
231
-
232
- this.setState({
233
- selectedImages: selectedImages
234
- })
235
- }
236
-
237
- deleteCheckedImages() {
238
- const iamgesInfo = this.editor.getImagesInfo();
239
-
240
- for (let i = 0; i < iamgesInfo.length; i++) {
241
- if (this.state.selectedImages.indexOf(iamgesInfo[i].index as number) > -1) {
242
- iamgesInfo[i].delete();
243
- i--;
244
- }
245
- }
246
-
247
- this.setState({
248
- selectedImages: [],
249
- })
250
- }
251
-
252
- fileUploadToEditor(e: any) {
253
- if (e.target.files) {
254
- this.editor.insertImage(e.target.files)
255
- e.target.value = ''
256
- }
257
- }
258
-
259
- render() {
260
- return <div>
261
- <textarea ref={this.txtArea} />
262
- <div className="component-list">
263
- <div className="file-list-info">
264
- <span>Attach files</span>
265
- <span className="xefu-btn">
266
- <span className="files-text">Images</span>
267
- </span>
268
- <input type="file" id="files_upload" accept=".jpg, .jpeg, .png, .ico, .tif, .tiff, .gif, .bmp, .raw" multiple className="files-text files-input" onChange={(e: any) => this.fileUploadToEditor(e)} />
269
- <span id="image_size" className="total-size text-small-2">{this.state.imageSize}</span>
270
- <button className="btn btn-md btn-danger" id="image_remove" disabled={this.state.selectedImages.length === 0} onClick={() => this.deleteCheckedImages()}>삭제</button>
271
- </div>
272
- <div className="file-list">
273
- <ul id="image_list">
274
- {
275
- this.state.imageList.map((v, i) => {
276
- return <li key={i} onClick={() => this.checkImage(v.index)} className={this.state.selectedImages.includes(v.index) ? "checked" : ""}>
277
- <div>
278
- <div className="image-wrapper"><img src={v.src} /></div>
279
- </div>
280
- <a onClick={(evt: any) => this.selectImage(evt, "select", v.index)} className="image-size">{(v.size / 1000).toFixed(1)}KB</a>
281
- <div className="image-check"><svg aria-hidden="true" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" data-fa-i2svg=""><path fill="currentColor" d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"></path></svg></div>
282
- </li>
283
- })
284
- }
285
- </ul>
286
- </div>
287
- </div>
288
- </div>;
289
- }
290
- }
291
-
292
- export default Editor;
293
- ```
294
-
295
- ### 2 PostEdit.tsx
296
- ```typescript
297
- import React, { Component, createRef } from "react";
298
- import Editor from "./Editor";
299
-
300
- interface Props {}
301
-
302
- interface State {
303
- content: string;
304
- }
305
-
306
- class PostEdit extends Component<Props, State> {
307
- editorRef: any = createRef();
308
-
309
- constructor(props: Props) {
310
- super(props);
311
- this.state = {
312
- content: "Test",
313
- };
314
- }
315
-
316
- save() {
317
- const contents = this.editorRef.current.editor.getContents();
318
- console.log("save", contents);
319
- }
320
-
321
- render() {
322
- return (
323
- <div>
324
- <Editor ref={this.editorRef} contents={this.state.content} onSave={this.save.bind(this)}></Editor>
325
-
326
- <button onClick={() => this.save()}>
327
- <span>Save</span>
328
- </button>
329
- </div>
330
- );
331
- }
332
- }
333
-
334
- export default PostEdit;
335
-
336
- ```
337
-
338
- ### 3. Editor file component Scss
339
- ```scss
340
- .sun-editor .se-dialog .se-dialog-inner .se-dialog-content {
341
- margin: 100px auto !important;
342
- }
343
- .sun-editor .se-wrapper .se-wrapper-wysiwyg {
344
- padding-bottom: 200px !important;
345
- }
346
-
347
- .sun-editor-editable .se-component.__se__float-left {
348
- margin: 0 0 10px 0;
349
- }
350
- .sun-editor-editable .se-component.__se__float-right {
351
- margin: 0 0 10px 0;
352
- }
353
-
354
- .sun-editor-editable a {
355
- color: #004cff !important;
356
- text-decoration: none !important;
357
- }
358
-
359
- // image list
360
- /** image list */
361
- .component-list {
362
- display: flex;
363
- box-sizing: border-box;
364
- position: relative;
365
- width: 100%;
366
- margin: 10px 0 10px 0;
367
- padding: 4px;
368
- background: #fff;
369
- }
370
-
371
- .xefu-btn {
372
- display: inline-block;
373
- *display: inline;
374
- margin: 0;
375
- padding: 0 12px !important;
376
- height: 24px !important;
377
- overflow: visible;
378
- border: 1px solid #bbb;
379
- border-radius: 2px;
380
- text-decoration: none !important;
381
- text-align: center;
382
- vertical-align: top;
383
- line-height: 24px !important;
384
- font-family: inherit;
385
- font-size: 12px;
386
- color: #333;
387
- *zoom: 1;
388
- cursor: pointer;
389
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
390
- background-color: #f5f5f5;
391
- *background-color: #e6e6e6;
392
- background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);
393
- background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);
394
- background-image: -webkit-gradient(top, #ffffff, #e6e6e6);
395
- background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);
396
- background-image: linear-gradient(top, #ffffff, #e6e6e6);
397
- background-repeat: repeat-x;
398
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff',endColorstr='#e6e6e6',GradientType=0);
399
- filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
400
- }
401
-
402
- .component-list .files-text {
403
- display: inline-block;
404
- margin: 0 -12px !important;
405
- padding: 0 12px !important;
406
- overflow: visible;
407
- width: auto;
408
- height: 24px;
409
- border: 0;
410
- vertical-align: top;
411
- text-decoration: none !important;
412
- line-height: 24px;
413
- font-family: inherit;
414
- font-size: 12px;
415
- color: #333;
416
- cursor: pointer;
417
- background: 0 0;
418
- }
419
-
420
- .component-list .files-input {
421
- position: absolute;
422
- width: 86px;
423
- left: 26px;
424
- top: 27px;
425
- opacity: 0;
426
- -ms-filter: "alpha(opacity=0)";
427
- font-size: 8px !important;
428
- direction: ltr;
429
- cursor: pointer;
430
- }
431
-
432
- .component-list * {
433
- box-sizing: border-box;
434
- }
435
-
436
- .component-list button {
437
- margin: 0 !important;
438
- }
439
-
440
- .component-list .file-list-info {
441
- float: left;
442
- white-space: nowrap;
443
- padding: 10px;
444
- background: #f5f5f5;
445
- border: 1px solid #ccc;
446
- }
447
-
448
- .component-list .file-list-info span {
449
- display: block;
450
- width: 100%;
451
- margin: 12px 0;
452
- }
453
-
454
- .component-list .file-list-info .total-size {
455
- color: #333;
456
- }
457
-
458
- .component-list .file-list {
459
- padding: 0 0 0 0;
460
- margin: 0 0 0 10px;
461
- border: none;
462
- }
463
-
464
- .component-list .file-list ul {
465
- margin: 0;
466
- padding: 0;
467
- height: auto;
468
- width: 100%;
469
- background-color: #f5f5f5;
470
- border: 1px solid #ccc;
471
- }
472
-
473
- .component-list .file-list ul li {
474
- position: relative;
475
- display: inline-block;
476
- margin: 3px;
477
- width: auto;
478
- height: auto;
479
- border: 3px solid #fff;
480
- }
481
-
482
- .component-list .file-list ul li .image-wrapper {
483
- width: 54px;
484
- height: auto;
485
- }
486
-
487
- .component-list .file-list ul li .file-wrapper {
488
- cursor: default;
489
- width: 70px;
490
- height: 21px;
491
- font-size: 11px;
492
- overflow: hidden;
493
- text-overflow: ellipsis;
494
- white-space: pre;
495
- word-break: break-all;
496
- padding-top: 4px;
497
- }
498
- .component-list .file-list ul li .file-wrapper svg {
499
- vertical-align: sub;
500
- }
501
-
502
- .component-list .file-list ul li.checked {
503
- border: 3px solid #dc3545;
504
- }
505
-
506
- .component-list .file-list ul li img {
507
- width: 100%;
508
- height: auto;
509
- }
510
-
511
- .component-list .file-list ul li .image-size {
512
- color: #666;
513
- font-size: 10px;
514
- }
515
-
516
- .component-list .file-list ul li .image-check {
517
- position: absolute;
518
- height: 12px;
519
- width: 12px;
520
- top: 0;
521
- left: auto;
522
- right: 0;
523
- margin: 0;
524
- padding: 1px 0 1px 2px;
525
- border: 0;
526
- border-radius: 0 0 0 5px;
527
- outline: none;
528
- background-color: #dc3545;
529
- }
530
-
531
- .component-list .file-list ul li.checked .image-check {
532
- display: block;
533
- }
534
-
535
- .component-list .file-list ul li:not(.checked) .image-check {
536
- display: none;
537
- }
538
-
539
- .component-list .file-list ul li .image-check svg {
540
- display: inline-block;
541
- font-size: 10px;
542
- height: 1em;
543
- width: 1em;
544
- overflow: visible;
545
- vertical-align: 0.875em;
546
- margin: 0;
547
- padding: 0;
548
- color: #fff;
549
- }
550
-
551
- /** video */
552
- .component-list .component-file-list {
553
- width: 100%;
554
- padding: 0 0 0 0;
555
- margin: 0 0 0 10px;
556
- border: none;
557
- }
558
- .component-list .component-file-list ul {
559
- margin: 0;
560
- padding: 0;
561
- height: auto;
562
- width: 100%;
563
- background-color: #f5f5f5;
564
- border: 1px solid #ccc;
565
- }
566
- .component-list .component-file-list ul li {
567
- position: relative;
568
- display: inline-block;
569
- width: 100%;
570
- height: 24px;
571
- margin: 0;
572
- border: 0;
573
- overflow: hidden;
574
- }
575
- .component-list .component-file-list ul li button {
576
- width: 30px;
577
- height: 24px;
578
- padding: 0;
579
- }
580
- .component-list .component-file-list ul li a {
581
- color: #333;
582
- }
583
-
584
- ```
585
-
586
-
1
+ # Example usage in the framework
2
+ This is just a simple example and is not a complete answer.
3
+ If there are any examples or errors in other frameworks, please participate and correct them.
4
+ - [React](#react-component)
5
+ - [React class](#react-class)
6
+ - [Vue](#vue-component)
7
+
8
+
9
+ ## React Component
10
+
11
+ ### React class
12
+
13
+ ### 1. Editor.tsx
14
+ ```typescript
15
+ import React, { Component, createRef } from "react";
16
+ import suneditor from "suneditor";
17
+ import { en } from "suneditor/src/lang";
18
+ import plugins from "suneditor/src/plugins";
19
+ import CodeMirror from "codemirror";
20
+ import katex from "katex";
21
+ import "suneditor/dist/css/suneditor.min.css";
22
+ import "codemirror/mode/htmlmixed/htmlmixed";
23
+ import "codemirror/lib/codemirror.css";
24
+ import "katex/dist/katex.min.css";
25
+ import "./Editor.scss"
26
+
27
+
28
+ interface Props {
29
+ contents?: string;
30
+ onBlur?: Function;
31
+ onSave: Function;
32
+ }
33
+
34
+ interface State {
35
+ imageList: any[];
36
+ selectedImages: any[];
37
+ imageSize: string;
38
+ }
39
+
40
+ class Editor extends Component<Props, State> {
41
+ txtArea: any;
42
+ editor: any;
43
+
44
+ constructor(props: any) {
45
+ super(props);
46
+ this.txtArea = createRef();
47
+ this.state = {
48
+ imageList: [],
49
+ selectedImages: [],
50
+ imageSize: "0KB",
51
+ };
52
+ }
53
+
54
+ componentDidMount() {
55
+ const editor: any = this.editor = suneditor.create(this.txtArea.current, {
56
+ plugins: plugins,
57
+ lang: en,
58
+ callBackSave: (contents: string) => this.props.onSave(contents),
59
+ codeMirror: CodeMirror,
60
+ stickyToolbar: 0,
61
+ katex: katex,
62
+ width: '100%',
63
+ height: 'auto',
64
+ minHeight: '400px',
65
+ value: this.props.contents,
66
+ // imageUploadUrl: `url`,
67
+ imageMultipleFile: true,
68
+ previewTemplate: `
69
+ <div style="width:auto; max-width:1136px; min-height:400px; margin:auto;">
70
+ {{contents}}
71
+ </div>
72
+ `,
73
+ buttonList: [
74
+ // default
75
+ ['undo', 'redo'],
76
+ ['font', 'fontSize', 'formatBlock'],
77
+ ['paragraphStyle', 'blockquote'],
78
+ ['bold', 'underline', 'italic', 'strike', 'subscript', 'superscript'],
79
+ ['fontColor', 'hiliteColor', 'textStyle'],
80
+ ['removeFormat'],
81
+ ['outdent', 'indent'],
82
+ ['align', 'horizontalRule', 'list', 'lineHeight'],
83
+ ['table', 'link', 'image', 'video'],
84
+ ['fullScreen', 'showBlocks', 'codeView'],
85
+ ['preview'],
86
+ ['save'],
87
+ // responsive
88
+ ['%1161', [
89
+ ['undo', 'redo'],
90
+ [':p-Formats-default.more_paragraph', 'font', 'fontSize', 'formatBlock', 'paragraphStyle', 'blockquote'],
91
+ ['bold', 'underline', 'italic', 'strike', 'subscript', 'superscript'],
92
+ ['fontColor', 'hiliteColor', 'textStyle'],
93
+ ['removeFormat'],
94
+ ['outdent', 'indent'],
95
+ ['align', 'horizontalRule', 'list', 'lineHeight'],
96
+ ['-right', 'save'],
97
+ ['-right', ':i-Etc-default.more_vertical', 'fullScreen', 'showBlocks', 'codeView', 'preview'],
98
+ ['-right', ':r-Table&Media-default.more_plus', 'table', 'link', 'image', 'video'],
99
+ ]],
100
+ ['%893', [
101
+ ['undo', 'redo'],
102
+ [':p-Formats-default.more_paragraph', 'font', 'fontSize', 'formatBlock', 'paragraphStyle', 'blockquote'],
103
+ ['bold', 'underline', 'italic', 'strike'],
104
+ [':t-Fonts-default.more_text', 'subscript', 'superscript', 'fontColor', 'hiliteColor', 'textStyle'],
105
+ ['removeFormat'],
106
+ ['outdent', 'indent'],
107
+ ['align', 'horizontalRule', 'list', 'lineHeight'],
108
+ ['-right', 'save'],
109
+ ['-right', ':i-Etc-default.more_vertical', 'fullScreen', 'showBlocks', 'codeView', 'preview'],
110
+ ['-right', ':r-Table&Media-default.more_plus', 'table', 'link', 'image', 'video'],
111
+ ]],
112
+ ['%855', [
113
+ ['undo', 'redo'],
114
+ [':p-Formats-default.more_paragraph', 'font', 'fontSize', 'formatBlock', 'paragraphStyle', 'blockquote'],
115
+ [':t-Fonts-default.more_text', 'bold', 'underline', 'italic', 'strike', 'subscript', 'superscript', 'fontColor', 'hiliteColor', 'textStyle'],
116
+ ['removeFormat'],
117
+ ['outdent', 'indent'],
118
+ ['align', 'horizontalRule', 'list', 'lineHeight'],
119
+ [':r-Table&Media-default.more_plus', 'table', 'link', 'image', 'video'],
120
+ ['-right', 'save'],
121
+ ['-right', ':i-Etc-default.more_vertical', 'fullScreen', 'showBlocks', 'codeView', 'preview'],
122
+ ]],
123
+ ['%563', [
124
+ ['undo', 'redo'],
125
+ [':p-Formats-default.more_paragraph', 'font', 'fontSize', 'formatBlock', 'paragraphStyle', 'blockquote'],
126
+ [':t-Fonts-default.more_text', 'bold', 'underline', 'italic', 'strike', 'subscript', 'superscript', 'fontColor', 'hiliteColor', 'textStyle'],
127
+ ['removeFormat'],
128
+ ['outdent', 'indent'],
129
+ [':e-List&Line-default.more_horizontal', 'align', 'horizontalRule', 'list', 'lineHeight'],
130
+ [':r-Table&Media-default.more_plus', 'table', 'link', 'image', 'video'],
131
+ ['-right', 'save'],
132
+ ['-right', ':i-Etc-default.more_vertical', 'fullScreen', 'showBlocks', 'codeView', 'preview'],
133
+ ]],
134
+ ['%458', [
135
+ ['undo', 'redo'],
136
+ [':p-Formats-default.more_paragraph', 'font', 'fontSize', 'formatBlock', 'paragraphStyle', 'blockquote'],
137
+ [':t-Fonts-default.more_text', 'bold', 'underline', 'italic', 'strike', 'subscript', 'superscript', 'fontColor', 'hiliteColor', 'textStyle', 'removeFormat'],
138
+ [':e-List&Line-default.more_horizontal', 'outdent', 'indent', 'align', 'horizontalRule', 'list', 'lineHeight'],
139
+ [':r-Table&Media-default.more_plus', 'table', 'link', 'image', 'video'],
140
+ ['-right', 'save'],
141
+ ['-right', ':i-Etc-default.more_vertical', 'fullScreen', 'showBlocks', 'codeView', 'preview'],
142
+ ]]
143
+ ]
144
+ });
145
+
146
+ editor.onBlur = () => {
147
+ if (typeof this.props.onBlur === 'function') this.props.onBlur()
148
+ }
149
+
150
+ editor.onImageUpload = this.imageUpload.bind(this);
151
+ // editor.onVideoUpload = videoUpload;
152
+ }
153
+
154
+ componentDidUpdate(prevProps: any) {
155
+ if (this.props.contents !== prevProps.contents) {
156
+ this.editor.setContents(this.props.contents);
157
+ this.editor.core.history.reset(true);
158
+ }
159
+ }
160
+
161
+ componentWillUnmount() {
162
+ if (this.editor) this.editor.destroy();
163
+ }
164
+
165
+ // image, video
166
+ findIndex(arr: any[], index: number) {
167
+ let idx = -1;
168
+
169
+ arr.some(function (a, i) {
170
+ if ((typeof a === 'number' ? a : a.index) === index) {
171
+ idx = i;
172
+ return true;
173
+ }
174
+ return false;
175
+ })
176
+
177
+ return idx;
178
+ }
179
+
180
+ imageUpload(targetElement: Element, index: number, state: string, imageInfo: Record<string, string>, remainingFilesCount: number) {
181
+ if (state === 'delete') {
182
+ this.state.imageList.splice(this.findIndex(this.state.imageList, index), 1)
183
+ this.setState({
184
+ imageList: this.state.imageList
185
+ })
186
+ } else {
187
+ if (state === 'create') {
188
+ const imageList = this.state.imageList;
189
+ imageList.push(imageInfo)
190
+ this.setState({
191
+ imageList: imageList
192
+ })
193
+ } else { // update
194
+ //
195
+ }
196
+ }
197
+
198
+ if (remainingFilesCount === 0) {
199
+ this.setImageList()
200
+ }
201
+ }
202
+
203
+ setImageList() {
204
+ const imageList = this.state.imageList;
205
+ let size = 0;
206
+
207
+ for (let i = 0; i < imageList.length; i++) {
208
+ size += Number((imageList[i].size / 1000).toFixed(1));
209
+ }
210
+
211
+ this.setState({
212
+ imageSize: size.toFixed(1) + 'KB'
213
+ })
214
+ }
215
+
216
+ selectImage(evt: any, type: string, index: number) {
217
+ evt.preventDefault();
218
+ evt.stopPropagation();
219
+ this.state.imageList[this.findIndex(this.state.imageList, index)][type]();
220
+ }
221
+
222
+ checkImage(index: number) {
223
+ const selectedImages = this.state.selectedImages;
224
+ const currentImageIdx = this.findIndex(selectedImages, index)
225
+
226
+ if (currentImageIdx > -1) {
227
+ selectedImages.splice(currentImageIdx, 1)
228
+ } else {
229
+ selectedImages.push(index)
230
+ }
231
+
232
+ this.setState({
233
+ selectedImages: selectedImages
234
+ })
235
+ }
236
+
237
+ deleteCheckedImages() {
238
+ const iamgesInfo = this.editor.getImagesInfo();
239
+
240
+ for (let i = 0; i < iamgesInfo.length; i++) {
241
+ if (this.state.selectedImages.indexOf(iamgesInfo[i].index as number) > -1) {
242
+ iamgesInfo[i].delete();
243
+ i--;
244
+ }
245
+ }
246
+
247
+ this.setState({
248
+ selectedImages: [],
249
+ })
250
+ }
251
+
252
+ fileUploadToEditor(e: any) {
253
+ if (e.target.files) {
254
+ this.editor.insertImage(e.target.files)
255
+ e.target.value = ''
256
+ }
257
+ }
258
+
259
+ render() {
260
+ return <div>
261
+ <textarea ref={this.txtArea} />
262
+ <div className="component-list">
263
+ <div className="file-list-info">
264
+ <span>Attach files</span>
265
+ <span className="xefu-btn">
266
+ <span className="files-text">Images</span>
267
+ </span>
268
+ <input type="file" id="files_upload" accept=".jpg, .jpeg, .png, .ico, .tif, .tiff, .gif, .bmp, .raw" multiple className="files-text files-input" onChange={(e: any) => this.fileUploadToEditor(e)} />
269
+ <span id="image_size" className="total-size text-small-2">{this.state.imageSize}</span>
270
+ <button className="btn btn-md btn-danger" id="image_remove" disabled={this.state.selectedImages.length === 0} onClick={() => this.deleteCheckedImages()}>삭제</button>
271
+ </div>
272
+ <div className="file-list">
273
+ <ul id="image_list">
274
+ {
275
+ this.state.imageList.map((v, i) => {
276
+ return <li key={i} onClick={() => this.checkImage(v.index)} className={this.state.selectedImages.includes(v.index) ? "checked" : ""}>
277
+ <div>
278
+ <div className="image-wrapper"><img src={v.src} /></div>
279
+ </div>
280
+ <a onClick={(evt: any) => this.selectImage(evt, "select", v.index)} className="image-size">{(v.size / 1000).toFixed(1)}KB</a>
281
+ <div className="image-check"><svg aria-hidden="true" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" data-fa-i2svg=""><path fill="currentColor" d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"></path></svg></div>
282
+ </li>
283
+ })
284
+ }
285
+ </ul>
286
+ </div>
287
+ </div>
288
+ </div>;
289
+ }
290
+ }
291
+
292
+ export default Editor;
293
+ ```
294
+
295
+ ### 2 PostEdit.tsx
296
+ ```typescript
297
+ import React, { Component, createRef } from "react";
298
+ import Editor from "./Editor";
299
+
300
+ interface Props {}
301
+
302
+ interface State {
303
+ content: string;
304
+ }
305
+
306
+ class PostEdit extends Component<Props, State> {
307
+ editorRef: any = createRef();
308
+
309
+ constructor(props: Props) {
310
+ super(props);
311
+ this.state = {
312
+ content: "Test",
313
+ };
314
+ }
315
+
316
+ save() {
317
+ const contents = this.editorRef.current.editor.getContents();
318
+ console.log("save", contents);
319
+ }
320
+
321
+ render() {
322
+ return (
323
+ <div>
324
+ <Editor ref={this.editorRef} contents={this.state.content} onSave={this.save.bind(this)}></Editor>
325
+
326
+ <button onClick={() => this.save()}>
327
+ <span>Save</span>
328
+ </button>
329
+ </div>
330
+ );
331
+ }
332
+ }
333
+
334
+ export default PostEdit;
335
+
336
+ ```
337
+
338
+ ### 3. Editor file component Scss
339
+ ```scss
340
+ .sun-editor .se-dialog .se-dialog-inner .se-dialog-content {
341
+ margin: 100px auto !important;
342
+ }
343
+ .sun-editor .se-wrapper .se-wrapper-wysiwyg {
344
+ padding-bottom: 200px !important;
345
+ }
346
+
347
+ .sun-editor-editable .se-component.__se__float-left {
348
+ margin: 0 0 10px 0;
349
+ }
350
+ .sun-editor-editable .se-component.__se__float-right {
351
+ margin: 0 0 10px 0;
352
+ }
353
+
354
+ .sun-editor-editable a {
355
+ color: #004cff !important;
356
+ text-decoration: none !important;
357
+ }
358
+
359
+ // image list
360
+ /** image list */
361
+ .component-list {
362
+ display: flex;
363
+ box-sizing: border-box;
364
+ position: relative;
365
+ width: 100%;
366
+ margin: 10px 0 10px 0;
367
+ padding: 4px;
368
+ background: #fff;
369
+ }
370
+
371
+ .xefu-btn {
372
+ display: inline-block;
373
+ *display: inline;
374
+ margin: 0;
375
+ padding: 0 12px !important;
376
+ height: 24px !important;
377
+ overflow: visible;
378
+ border: 1px solid #bbb;
379
+ border-radius: 2px;
380
+ text-decoration: none !important;
381
+ text-align: center;
382
+ vertical-align: top;
383
+ line-height: 24px !important;
384
+ font-family: inherit;
385
+ font-size: 12px;
386
+ color: #333;
387
+ *zoom: 1;
388
+ cursor: pointer;
389
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
390
+ background-color: #f5f5f5;
391
+ *background-color: #e6e6e6;
392
+ background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);
393
+ background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);
394
+ background-image: -webkit-gradient(top, #ffffff, #e6e6e6);
395
+ background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);
396
+ background-image: linear-gradient(top, #ffffff, #e6e6e6);
397
+ background-repeat: repeat-x;
398
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff',endColorstr='#e6e6e6',GradientType=0);
399
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
400
+ }
401
+
402
+ .component-list .files-text {
403
+ display: inline-block;
404
+ margin: 0 -12px !important;
405
+ padding: 0 12px !important;
406
+ overflow: visible;
407
+ width: auto;
408
+ height: 24px;
409
+ border: 0;
410
+ vertical-align: top;
411
+ text-decoration: none !important;
412
+ line-height: 24px;
413
+ font-family: inherit;
414
+ font-size: 12px;
415
+ color: #333;
416
+ cursor: pointer;
417
+ background: 0 0;
418
+ }
419
+
420
+ .component-list .files-input {
421
+ position: absolute;
422
+ width: 86px;
423
+ left: 26px;
424
+ top: 27px;
425
+ opacity: 0;
426
+ -ms-filter: "alpha(opacity=0)";
427
+ font-size: 8px !important;
428
+ direction: ltr;
429
+ cursor: pointer;
430
+ }
431
+
432
+ .component-list * {
433
+ box-sizing: border-box;
434
+ }
435
+
436
+ .component-list button {
437
+ margin: 0 !important;
438
+ }
439
+
440
+ .component-list .file-list-info {
441
+ float: left;
442
+ white-space: nowrap;
443
+ padding: 10px;
444
+ background: #f5f5f5;
445
+ border: 1px solid #ccc;
446
+ }
447
+
448
+ .component-list .file-list-info span {
449
+ display: block;
450
+ width: 100%;
451
+ margin: 12px 0;
452
+ }
453
+
454
+ .component-list .file-list-info .total-size {
455
+ color: #333;
456
+ }
457
+
458
+ .component-list .file-list {
459
+ padding: 0 0 0 0;
460
+ margin: 0 0 0 10px;
461
+ border: none;
462
+ }
463
+
464
+ .component-list .file-list ul {
465
+ margin: 0;
466
+ padding: 0;
467
+ height: auto;
468
+ width: 100%;
469
+ background-color: #f5f5f5;
470
+ border: 1px solid #ccc;
471
+ }
472
+
473
+ .component-list .file-list ul li {
474
+ position: relative;
475
+ display: inline-block;
476
+ margin: 3px;
477
+ width: auto;
478
+ height: auto;
479
+ border: 3px solid #fff;
480
+ }
481
+
482
+ .component-list .file-list ul li .image-wrapper {
483
+ width: 54px;
484
+ height: auto;
485
+ }
486
+
487
+ .component-list .file-list ul li .file-wrapper {
488
+ cursor: default;
489
+ width: 70px;
490
+ height: 21px;
491
+ font-size: 11px;
492
+ overflow: hidden;
493
+ text-overflow: ellipsis;
494
+ white-space: pre;
495
+ word-break: break-all;
496
+ padding-top: 4px;
497
+ }
498
+ .component-list .file-list ul li .file-wrapper svg {
499
+ vertical-align: sub;
500
+ }
501
+
502
+ .component-list .file-list ul li.checked {
503
+ border: 3px solid #dc3545;
504
+ }
505
+
506
+ .component-list .file-list ul li img {
507
+ width: 100%;
508
+ height: auto;
509
+ }
510
+
511
+ .component-list .file-list ul li .image-size {
512
+ color: #666;
513
+ font-size: 10px;
514
+ }
515
+
516
+ .component-list .file-list ul li .image-check {
517
+ position: absolute;
518
+ height: 12px;
519
+ width: 12px;
520
+ top: 0;
521
+ left: auto;
522
+ right: 0;
523
+ margin: 0;
524
+ padding: 1px 0 1px 2px;
525
+ border: 0;
526
+ border-radius: 0 0 0 5px;
527
+ outline: none;
528
+ background-color: #dc3545;
529
+ }
530
+
531
+ .component-list .file-list ul li.checked .image-check {
532
+ display: block;
533
+ }
534
+
535
+ .component-list .file-list ul li:not(.checked) .image-check {
536
+ display: none;
537
+ }
538
+
539
+ .component-list .file-list ul li .image-check svg {
540
+ display: inline-block;
541
+ font-size: 10px;
542
+ height: 1em;
543
+ width: 1em;
544
+ overflow: visible;
545
+ vertical-align: 0.875em;
546
+ margin: 0;
547
+ padding: 0;
548
+ color: #fff;
549
+ }
550
+
551
+ /** video */
552
+ .component-list .component-file-list {
553
+ width: 100%;
554
+ padding: 0 0 0 0;
555
+ margin: 0 0 0 10px;
556
+ border: none;
557
+ }
558
+ .component-list .component-file-list ul {
559
+ margin: 0;
560
+ padding: 0;
561
+ height: auto;
562
+ width: 100%;
563
+ background-color: #f5f5f5;
564
+ border: 1px solid #ccc;
565
+ }
566
+ .component-list .component-file-list ul li {
567
+ position: relative;
568
+ display: inline-block;
569
+ width: 100%;
570
+ height: 24px;
571
+ margin: 0;
572
+ border: 0;
573
+ overflow: hidden;
574
+ }
575
+ .component-list .component-file-list ul li button {
576
+ width: 30px;
577
+ height: 24px;
578
+ padding: 0;
579
+ }
580
+ .component-list .component-file-list ul li a {
581
+ color: #333;
582
+ }
583
+
584
+ ```
585
+
586
+
587
587
  ## Vue Component