goodteditor-ui 1.0.21 → 1.0.23

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 (114) hide show
  1. package/.eslintrc.js +7 -7
  2. package/.prettierrc +14 -14
  3. package/README.md +35 -35
  4. package/babel.config.js +5 -5
  5. package/index.js +53 -53
  6. package/jsconfig.json +13 -13
  7. package/package.json +66 -70
  8. package/src/App.vue +36 -36
  9. package/src/components/ui/Avatar.md +68 -68
  10. package/src/components/ui/Avatar.vue +180 -177
  11. package/src/components/ui/Badge.md +20 -20
  12. package/src/components/ui/Badge.vue +75 -75
  13. package/src/components/ui/Collapse.md +90 -90
  14. package/src/components/ui/Collapse.vue +86 -86
  15. package/src/components/ui/ColorPicker/Alpha.vue +114 -114
  16. package/src/components/ui/ColorPicker/Colors.vue +117 -117
  17. package/src/components/ui/ColorPicker/Hue.vue +113 -113
  18. package/src/components/ui/ColorPicker/Preview.vue +55 -55
  19. package/src/components/ui/ColorPicker/Saturation.vue +123 -123
  20. package/src/components/ui/ColorPicker/mixin.js +105 -105
  21. package/src/components/ui/ColorPicker.md +17 -17
  22. package/src/components/ui/ColorPicker.vue +314 -314
  23. package/src/components/ui/Datalist.md +41 -41
  24. package/src/components/ui/Datalist.vue +157 -157
  25. package/src/components/ui/DatePicker.md +168 -168
  26. package/src/components/ui/DatePicker.vue +527 -527
  27. package/src/components/ui/FileSelector.md +105 -105
  28. package/src/components/ui/FileSelector.vue +82 -82
  29. package/src/components/ui/Grid.md +130 -130
  30. package/src/components/ui/Grid.vue +92 -92
  31. package/src/components/ui/Image.md +59 -59
  32. package/src/components/ui/Image.vue +57 -57
  33. package/src/components/ui/InputAutocomplete.md +115 -115
  34. package/src/components/ui/InputAutocomplete.vue +341 -341
  35. package/src/components/ui/InputColorPicker.md +51 -51
  36. package/src/components/ui/InputColorPicker.vue +151 -151
  37. package/src/components/ui/InputDatePicker.md +121 -121
  38. package/src/components/ui/InputDatePicker.vue +326 -326
  39. package/src/components/ui/InputTags.md +51 -51
  40. package/src/components/ui/InputTags.vue +184 -184
  41. package/src/components/ui/InputTimePicker.md +25 -25
  42. package/src/components/ui/InputTimePicker.vue +253 -253
  43. package/src/components/ui/InputUnits.md +20 -20
  44. package/src/components/ui/InputUnits.vue +257 -257
  45. package/src/components/ui/Lazy.md +37 -37
  46. package/src/components/ui/Lazy.vue +92 -92
  47. package/src/components/ui/Pagination.md +74 -74
  48. package/src/components/ui/Pagination.vue +138 -138
  49. package/src/components/ui/Paginator.md +34 -34
  50. package/src/components/ui/Paginator.vue +83 -83
  51. package/src/components/ui/Popover.md +34 -34
  52. package/src/components/ui/Popover.vue +274 -274
  53. package/src/components/ui/Popup.md +59 -59
  54. package/src/components/ui/Popup.vue +150 -150
  55. package/src/components/ui/ResponsiveContainer.md +58 -58
  56. package/src/components/ui/ResponsiveContainer.vue +99 -99
  57. package/src/components/ui/Select.md +187 -187
  58. package/src/components/ui/Select.vue +421 -421
  59. package/src/components/ui/TimePicker.md +50 -50
  60. package/src/components/ui/TimePicker.vue +252 -252
  61. package/src/components/ui/Tooltip.md +54 -114
  62. package/src/components/ui/Tooltip.vue +113 -113
  63. package/src/components/ui/WysiwygEditor/WysiwygEditor.d.ts +119 -119
  64. package/src/components/ui/WysiwygEditor/constants.js +264 -264
  65. package/src/components/ui/WysiwygEditor/extensions/blockquote.js +15 -15
  66. package/src/components/ui/WysiwygEditor/extensions/bold.js +15 -15
  67. package/src/components/ui/WysiwygEditor/extensions/bullet-list.js +15 -15
  68. package/src/components/ui/WysiwygEditor/extensions/code-block.js +13 -13
  69. package/src/components/ui/WysiwygEditor/extensions/code.js +13 -13
  70. package/src/components/ui/WysiwygEditor/extensions/font-size.js +34 -34
  71. package/src/components/ui/WysiwygEditor/extensions/formatting.js +14 -14
  72. package/src/components/ui/WysiwygEditor/extensions/heading.js +13 -13
  73. package/src/components/ui/WysiwygEditor/extensions/horizontal-rule.js +15 -15
  74. package/src/components/ui/WysiwygEditor/extensions/image.js +19 -19
  75. package/src/components/ui/WysiwygEditor/extensions/index.d.ts +32 -32
  76. package/src/components/ui/WysiwygEditor/extensions/index.js +32 -32
  77. package/src/components/ui/WysiwygEditor/extensions/italic.js +15 -15
  78. package/src/components/ui/WysiwygEditor/extensions/link.js +16 -16
  79. package/src/components/ui/WysiwygEditor/extensions/list-item.js +15 -15
  80. package/src/components/ui/WysiwygEditor/extensions/ordered-list.js +15 -15
  81. package/src/components/ui/WysiwygEditor/extensions/paragraph.js +23 -23
  82. package/src/components/ui/WysiwygEditor/extensions/strike.js +15 -15
  83. package/src/components/ui/WysiwygEditor/extensions/table-cell.js +13 -13
  84. package/src/components/ui/WysiwygEditor/extensions/table-header.js +15 -15
  85. package/src/components/ui/WysiwygEditor/extensions/table-row.js +15 -15
  86. package/src/components/ui/WysiwygEditor/extensions/table.js +29 -29
  87. package/src/components/ui/WysiwygEditor/extensions/text-align.js +6 -6
  88. package/src/components/ui/WysiwygEditor/extensions/text-style.js +15 -15
  89. package/src/components/ui/WysiwygEditor/extensions/underline.js +15 -15
  90. package/src/components/ui/WysiwygEditor/index.d.ts +4 -4
  91. package/src/components/ui/WysiwygEditor/index.js +4 -4
  92. package/src/components/ui/WysiwygEditor/renders/Button.vue +28 -28
  93. package/src/components/ui/WysiwygEditor/renders/ColorPicker.vue +41 -41
  94. package/src/components/ui/WysiwygEditor/renders/InputAuto.vue +34 -34
  95. package/src/components/ui/WysiwygEditor/renders/InputBrowse.vue +35 -35
  96. package/src/components/ui/WysiwygEditor/renders/InputUnits.vue +38 -38
  97. package/src/components/ui/WysiwygEditor/renders/Link.vue +87 -87
  98. package/src/components/ui/WysiwygEditor/renders/Select.vue +47 -47
  99. package/src/components/ui/WysiwygEditor/renders/ToolbarPopover.vue +49 -49
  100. package/src/components/ui/WysiwygEditor/renders/index.d.ts +8 -8
  101. package/src/components/ui/WysiwygEditor/renders/index.js +8 -8
  102. package/src/components/ui/WysiwygEditor/renders/mixins/RenderMixin.js +39 -39
  103. package/src/components/ui/WysiwygEditor/renders/mixins/index.js +1 -1
  104. package/src/components/ui/WysiwygEditor/tools-and-commands.js +704 -704
  105. package/src/components/ui/WysiwygEditor/utils.js +72 -72
  106. package/src/components/ui/WysiwygEditor.md +18 -18
  107. package/src/components/ui/WysiwygEditor.vue +271 -271
  108. package/src/components/ui/utils/FormComponent.js +107 -107
  109. package/src/components/ui/utils/Helpers.js +84 -84
  110. package/src/components/ui/utils/WithPopover.js +81 -99
  111. package/src/main.js +8 -8
  112. package/styleguide.config.js +37 -37
  113. package/vue.config.js +8 -8
  114. package/dist/js.png +0 -0
@@ -1,704 +1,704 @@
1
- import {
2
- NodeType,
3
- MarkType,
4
- CommandType,
5
- ToolType,
6
- createButtonTool,
7
- createColorPickerTool,
8
- createCommand,
9
- createInputUnitsTool,
10
- createSelectTool,
11
- createToolbarPopoverTool,
12
- createInputAutoTool,
13
- createInputBrowseTool,
14
- createLinkTool
15
- } from './constants';
16
-
17
- export const CommandMap = {
18
- [CommandType.PARAGRAPH]: createCommand({
19
- name: CommandType.PARAGRAPH,
20
- title: 'Абзац',
21
- exec() {
22
- this.editor
23
- .chain()
24
- .focus()
25
- .setParagraph()
26
- .setParagraphClass('p')
27
- .resetAttributes(MarkType.TEXT_STYLE, 'fontSize')
28
- .run();
29
- },
30
- isActive() {
31
- return this.editor.isActive(NodeType.PARAGRAPH, { class: 'p' });
32
- }
33
- }),
34
- [CommandType.HEADING_1]: createCommand({
35
- name: CommandType.HEADING_1,
36
- title: 'Заголовок 1 (h1)',
37
- exec() {
38
- this.editor
39
- .chain()
40
- .focus()
41
- .setHeading({ level: 1 })
42
- .resetAttributes(MarkType.TEXT_STYLE, 'fontSize')
43
- .run();
44
- },
45
- isActive() {
46
- return this.editor.isActive(NodeType.HEADING, { level: 1 });
47
- }
48
- }),
49
- [CommandType.HEADING_2]: createCommand({
50
- name: CommandType.HEADING_2,
51
- title: 'Заголовок 2 (h2)',
52
- exec() {
53
- this.editor
54
- .chain()
55
- .focus()
56
- .setHeading({ level: 2 })
57
- .resetAttributes(MarkType.TEXT_STYLE, 'fontSize')
58
- .run();
59
- },
60
- isActive() {
61
- return this.editor.isActive(NodeType.HEADING, { level: 2 });
62
- }
63
- }),
64
- [CommandType.HEADING_3]: createCommand({
65
- name: CommandType.HEADING_3,
66
- title: 'Заголовок 3 (h3)',
67
- exec() {
68
- this.editor
69
- .chain()
70
- .focus()
71
- .setHeading({ level: 3 })
72
- .resetAttributes(MarkType.TEXT_STYLE, 'fontSize')
73
- .run();
74
- },
75
- isActive() {
76
- return this.editor.isActive(NodeType.HEADING, { level: 3 });
77
- }
78
- }),
79
- [CommandType.HEADING_4]: createCommand({
80
- name: CommandType.HEADING_4,
81
- title: 'Заголовок 4 (h4)',
82
- exec() {
83
- this.editor
84
- .chain()
85
- .focus()
86
- .setHeading({ level: 4 })
87
- .resetAttributes(MarkType.TEXT_STYLE, 'fontSize')
88
- .run();
89
- },
90
- isActive() {
91
- return this.editor.isActive(NodeType.HEADING, { level: 4 });
92
- }
93
- }),
94
- [CommandType.TEXT_SMALL]: createCommand({
95
- name: CommandType.TEXT_SMALL,
96
- title: 'Small',
97
- exec() {
98
- this.editor
99
- .chain()
100
- .focus()
101
- .setParagraph()
102
- .setParagraphClass('text-small')
103
- .resetAttributes(MarkType.TEXT_STYLE, 'fontSize')
104
- .run();
105
- },
106
- isActive() {
107
- return this.editor.isActive(NodeType.PARAGRAPH, { class: 'text-small' });
108
- }
109
- }),
110
- [CommandType.TEXT_XSMALL]: createCommand({
111
- name: CommandType.TEXT_XSMALL,
112
- title: 'Xsmall',
113
- exec() {
114
- this.editor
115
- .chain()
116
- .focus()
117
- .setParagraph()
118
- .setParagraphClass('text-xsmall')
119
- .resetAttributes(MarkType.TEXT_STYLE, 'fontSize')
120
- .run();
121
- },
122
- isActive() {
123
- return this.editor.isActive(NodeType.PARAGRAPH, { class: 'text-xsmall' });
124
- }
125
- }),
126
- [CommandType.CODE_BLOCK]: createCommand({
127
- name: CommandType.CODE_BLOCK,
128
- title: 'Код',
129
- exec() {
130
- this.editor
131
- .chain()
132
- .focus()
133
- .setCodeBlock()
134
- .run();
135
- },
136
- isActive() {
137
- return this.editor.isActive(NodeType.CODE_BLOCK);
138
- }
139
- }),
140
- [CommandType.SINK_LIST_ITEM]: createCommand({
141
- name: CommandType.SINK_LIST_ITEM,
142
- title: 'Опустить элемент списка',
143
- exec() {
144
- this.editor
145
- .chain()
146
- .focus()
147
- .sinkListItem(NodeType.LIST_ITEM)
148
- .run();
149
- },
150
- isEnabled() {
151
- return this.editor.can().sinkListItem(NodeType.LIST_ITEM);
152
- }
153
- }),
154
- [CommandType.LIFT_LIST_ITEM]: createCommand({
155
- name: CommandType.LIFT_LIST_ITEM,
156
- title: 'Поднять элемент списка',
157
- exec() {
158
- this.editor.chain().focus().liftListItem(NodeType.LIST_ITEM).run();
159
- },
160
- isEnabled() {
161
- return this.editor.can().liftListItem(NodeType.LIST_ITEM);
162
- }
163
- })
164
- };
165
-
166
- export const TableOptionsMap = {
167
- [ToolType.INSERT_TABLE]: createButtonTool({
168
- name: ToolType.INSERT_TABLE,
169
- icon: 'table',
170
- title: 'Вставить таблицу',
171
- exec() {
172
- this.editor
173
- .chain()
174
- .focus()
175
- .insertTable({ rows: 3, cols: 3, withHeaderRow: true })
176
- .run();
177
- },
178
- isEnabled() {
179
- return this.editor.can().insertTable();
180
- }
181
- }),
182
- [ToolType.DELETE_TABLE]: createButtonTool({
183
- name: ToolType.DELETE_TABLE,
184
- icon: 'table-remove',
185
- title: 'Удалить таблицу',
186
- exec() {
187
- this.editor.chain().focus().deleteTable().run();
188
- },
189
- isEnabled() {
190
- return this.editor.can().deleteTable();
191
- }
192
- }),
193
- [ToolType.ADD_COLUMN_BEFORE]: createButtonTool({
194
- name: ToolType.ADD_COLUMN_BEFORE,
195
- icon: 'table-column-plus-before',
196
- title: 'Добавить колонку перед',
197
- exec() {
198
- this.editor.chain().focus().addColumnBefore().run();
199
- },
200
- isEnabled() {
201
- return this.editor.can().addColumnBefore();
202
- }
203
- }),
204
- [ToolType.ADD_COLUMN_AFTER]: createButtonTool({
205
- name: ToolType.ADD_COLUMN_AFTER,
206
- icon: 'table-column-plus-after',
207
- title: 'Добавить колонку после',
208
- exec() {
209
- this.editor.chain().focus().addColumnAfter().run();
210
- },
211
- isEnabled() {
212
- return this.editor.can().addColumnAfter();
213
- }
214
- }),
215
- [ToolType.DELETE_COLUMN]: createButtonTool({
216
- name: ToolType.DELETE_COLUMN,
217
- icon: 'table-column-remove',
218
- title: 'Удалить колонку',
219
- exec() {
220
- this.editor.chain().focus().deleteColumn().run();
221
- },
222
- isEnabled() {
223
- return this.editor.can().deleteColumn();
224
- }
225
- }),
226
- [ToolType.ADD_ROW_BEFORE]: createButtonTool({
227
- name: ToolType.ADD_ROW_BEFORE,
228
- icon: 'table-row-plus-before',
229
- title: 'Добавить строку перед',
230
- exec() {
231
- this.editor.chain().focus().addRowBefore().run();
232
- },
233
- isEnabled() {
234
- return this.editor.can().addRowBefore();
235
- }
236
- }),
237
- [ToolType.ADD_ROW_AFTER]: createButtonTool({
238
- name: ToolType.ADD_ROW_AFTER,
239
- icon: 'table-row-plus-after',
240
- title: 'Добавить строку после',
241
- exec() {
242
- this.editor.chain().focus().addRowAfter().run();
243
- },
244
- isEnabled() {
245
- return this.editor.can().addRowAfter();
246
- }
247
- }),
248
- [ToolType.DELETE_ROW]: createButtonTool({
249
- name: ToolType.DELETE_ROW,
250
- icon: 'table-row-remove',
251
- title: 'Удалить строку',
252
- exec() {
253
- this.editor.chain().focus().deleteRow().run();
254
- },
255
- isEnabled() {
256
- return this.editor.can().deleteRow();
257
- }
258
- }),
259
- [ToolType.MERGE_CELLS]: createButtonTool({
260
- name: ToolType.MERGE_CELLS,
261
- icon: 'table-merge-cells',
262
- title: 'Объединить ячейки',
263
- exec() {
264
- this.editor.chain().focus().mergeCells().run();
265
- },
266
- isEnabled() {
267
- return this.editor.can().mergeCells();
268
- }
269
- }),
270
- [ToolType.SPLIT_CELL]: createButtonTool({
271
- name: ToolType.SPLIT_CELL,
272
- icon: 'table-split-cell',
273
- title: 'Разделить ячейки',
274
- exec() {
275
- this.editor.chain().focus().splitCell().run();
276
- },
277
- isEnabled() {
278
- return this.editor.can().splitCell();
279
- }
280
- }),
281
- [ToolType.TOGGLE_HEADER_ROW]: createButtonTool({
282
- name: ToolType.TOGGLE_HEADER_ROW,
283
- icon: 'table-row-height',
284
- title: 'Переключить строку заголовка',
285
- exec() {
286
- this.editor.chain().focus().toggleHeaderRow().run();
287
- },
288
- isEnabled() {
289
- return this.editor.can().toggleHeaderRow();
290
- }
291
- }),
292
- [ToolType.TOGGLE_HEADER_COLUMN]: createButtonTool({
293
- name: ToolType.TOGGLE_HEADER_COLUMN,
294
- icon: 'table-column-width',
295
- title: 'Переключить колонку заголовка',
296
- exec() {
297
- this.editor.chain().focus().toggleHeaderColumn().run();
298
- },
299
- isEnabled() {
300
- return this.editor.can().toggleHeaderColumn();
301
- }
302
- }),
303
- [ToolType.ALIGN_V_TOP]: createButtonTool({
304
- name: ToolType.ALIGN_V_TOP,
305
- icon: 'align-vertical-top',
306
- title: 'Выровнять по верхнему краю',
307
- exec() {
308
- const classNames = this.editor.getAttributes(NodeType.TABLE).class;
309
- this.editor.chain().focus().toggleTableAlignment('table-vtop', classNames).run();
310
- },
311
- isEnabled() {
312
- return this.editor.isActive(NodeType.TABLE);
313
- },
314
- isActive() {
315
- const classNames = this.editor.getAttributes(NodeType.TABLE).class;
316
- return classNames?.includes('table-vtop') ?? false;
317
- }
318
- }),
319
- [ToolType.ALIGN_V_MID]: createButtonTool({
320
- name: ToolType.ALIGN_V_MID,
321
- icon: 'align-vertical-center',
322
- title: 'Выровнять по центру',
323
- exec() {
324
- const classNames = this.editor.getAttributes(NodeType.TABLE).class;
325
- this.editor.chain().focus().toggleTableAlignment('table-vmid', classNames).run();
326
- },
327
- isEnabled() {
328
- return this.editor.isActive(NodeType.TABLE);
329
- },
330
- isActive() {
331
- const classNames = this.editor.getAttributes(NodeType.TABLE).class;
332
- return classNames?.includes('table-vmid') ?? false;
333
- }
334
- }),
335
- [ToolType.ALIGN_V_BOT]: createButtonTool({
336
- name: ToolType.ALIGN_V_BOT,
337
- icon: 'align-vertical-bottom',
338
- title: 'Выровнять по нижнему краю',
339
- exec() {
340
- const classNames = this.editor.getAttributes(NodeType.TABLE).class;
341
- this.editor.chain().focus().toggleTableAlignment('table-vbot', classNames).run();
342
- },
343
- isEnabled() {
344
- return this.editor.isActive(NodeType.TABLE);
345
- },
346
- isActive() {
347
- const classNames = this.editor.getAttributes(NodeType.TABLE).class;
348
- return classNames?.includes('table-vbot') ?? false;
349
- }
350
- }),
351
- [ToolType.TOGGLE_BORDERS]: createButtonTool({
352
- name: ToolType.TOGGLE_BORDERS,
353
- icon: 'border-all',
354
- title: 'Границы',
355
- exec() {
356
- const classNames = this.editor.getAttributes(NodeType.TABLE).class;
357
- this.editor.chain().focus().toggleTableClass('table-borders', classNames).run();
358
- },
359
- isEnabled() {
360
- return this.editor.isActive(NodeType.TABLE);
361
- },
362
- isActive() {
363
- const classNames = this.editor.getAttributes(NodeType.TABLE).class;
364
- return classNames?.includes('table-borders') ?? false;
365
- }
366
- }),
367
- [ToolType.TOGGLE_ZEBRA]: createButtonTool({
368
- name: ToolType.TOGGLE_ZEBRA,
369
- icon: 'view-stream',
370
- title: 'Стиль "зебра"',
371
- exec() {
372
- const classNames = this.editor.getAttributes(NodeType.TABLE).class;
373
- this.editor.chain().focus().toggleTableClass('table-zebra', classNames).run();
374
- },
375
- isEnabled() {
376
- return this.editor.isActive(NodeType.TABLE);
377
- },
378
- isActive() {
379
- const classNames = this.editor.getAttributes(NodeType.TABLE).class;
380
- return classNames?.includes('table-zebra') ?? false;
381
- }
382
- })
383
- };
384
-
385
- export const ImageOptionsMap = {
386
- [ToolType.INSERT_IMAGE]: createInputBrowseTool({
387
- name: ToolType.INSERT_IMAGE,
388
- title: 'Вставить изображение',
389
- async exec(fromInputUrl) {
390
- const setImage = (url) => {
391
- this.editor.chain().focus().setImage({ src: url }).run();
392
- };
393
-
394
- if (fromInputUrl != null) {
395
- setImage(fromInputUrl);
396
- return;
397
- }
398
-
399
- const imageUrl = await this.getImageUrl();
400
-
401
- if (imageUrl != null) {
402
- setImage(imageUrl);
403
- }
404
- },
405
- getValue() {
406
- return this.editor.getAttributes(NodeType.IMAGE).src;
407
- }
408
- })
409
- };
410
-
411
- export const ToolsMap = {
412
- [ToolType.UNDO]: createButtonTool({
413
- name: ToolType.UNDO,
414
- icon: 'undo-variant',
415
- title: 'Назад',
416
- exec() {
417
- this.editor.commands.undo();
418
- },
419
- isEnabled() {
420
- return this.editor.can().undo();
421
- }
422
- }),
423
- [ToolType.REDO]: createButtonTool({
424
- name: ToolType.REDO,
425
- icon: 'redo-variant',
426
- title: 'Вперед',
427
- exec() {
428
- this.editor.commands.redo();
429
- },
430
- isEnabled() {
431
- return this.editor.can().redo();
432
- }
433
- }),
434
- [ToolType.SAVE]: createButtonTool({
435
- name: ToolType.SAVE,
436
- icon: 'content-save',
437
- title: 'Сохранить',
438
- exec() {
439
- this.onChange();
440
- }
441
- }),
442
- [ToolType.PARAGRAPH_STYLE]: createSelectTool({
443
- name: ToolType.PARAGRAPH_STYLE,
444
- title: 'Стиль параграфа',
445
- exec(command) {
446
- if (command.name in CommandMap && command.isEnabled()) {
447
- command.exec();
448
- }
449
- },
450
- getValue(options) {
451
- return options.find(({ value }) => value.isActive()) ?? null;
452
- },
453
- options: [
454
- CommandMap[CommandType.PARAGRAPH],
455
- CommandMap[CommandType.HEADING_1],
456
- CommandMap[CommandType.HEADING_2],
457
- CommandMap[CommandType.HEADING_3],
458
- CommandMap[CommandType.HEADING_4],
459
- CommandMap[CommandType.TEXT_SMALL],
460
- CommandMap[CommandType.TEXT_XSMALL],
461
- CommandMap[CommandType.CODE_BLOCK]
462
- ]
463
- }),
464
- [ToolType.FONT_SIZE]: createInputUnitsTool({
465
- name: ToolType.FONT_SIZE,
466
- title: 'Размер шрифта',
467
- exec(value) {
468
- this.editor.commands.setFontSize(value);
469
- },
470
- isEnabled() {
471
- const { editor } = this;
472
-
473
- return (
474
- editor.isActive(NodeType.HEADING) ||
475
- editor.isActive(NodeType.PARAGRAPH, { class: 'text-small' }) ||
476
- editor.isActive(NodeType.PARAGRAPH, { class: 'text-xsmall' })
477
- ) === false;
478
- },
479
- getValue() {
480
- return this.editor.getAttributes(MarkType.TEXT_STYLE).fontSize;
481
- },
482
- units: ["rem", "em", "%", "px", "vh", "vw"]
483
- }),
484
- [ToolType.TEXT_COLOR]: createColorPickerTool({
485
- name: ToolType.TEXT_COLOR,
486
- icon: 'format-color-fill',
487
- title: 'Цвет',
488
- exec(value) {
489
- this.editor.chain().focus().setColor(value).run();
490
- },
491
- getValue() {
492
- return this.editor.getAttributes(MarkType.TEXT_STYLE).color;
493
- }
494
- }),
495
- [ToolType.FONT_FAMILY]: createInputAutoTool({
496
- name: ToolType.FONT_FAMILY,
497
- title: 'Семейство шрифта',
498
- exec(value) {
499
- this.editor.commands.setFontFamily(value);
500
- },
501
- getValue() {
502
- return this.editor.getAttributes(MarkType.TEXT_STYLE).fontFamily;
503
- },
504
- options: ['serif', 'sans-serif']
505
- }),
506
- [ToolType.BLOCKQUOTE]: createButtonTool({
507
- name: ToolType.BLOCKQUOTE,
508
- icon: 'format-quote-close-outline',
509
- title: 'Цитата',
510
- exec() {
511
- this.editor
512
- .chain()
513
- .focus()
514
- .toggleBlockquote()
515
- .run();
516
- },
517
- isActive() {
518
- return this.editor.isActive(NodeType.BLOCKQUOTE);
519
- }
520
- }),
521
- [ToolType.HARD_BREAK]: createButtonTool({
522
- name: ToolType.HARD_BREAK,
523
- title: 'Перевод строки',
524
- icon: 'keyboard-return',
525
- exec() {
526
- this.editor.chain().focus().setHardBreak().run();
527
- }
528
- }),
529
- [ToolType.CODE]: createButtonTool({
530
- name: ToolType.CODE,
531
- icon: 'code-not-equal-variant',
532
- title: 'Код',
533
- exec() {
534
- this.editor.chain().focus().toggleCode().run();
535
- },
536
- isActive() {
537
- return this.editor.isActive(MarkType.CODE);
538
- }
539
- }),
540
- [ToolType.IMAGE]: createToolbarPopoverTool({
541
- name: ToolType.IMAGE,
542
- icon: 'image-plus',
543
- title: 'Изображение',
544
- options: Object.values(ImageOptionsMap)
545
- }),
546
- [ToolType.ORDERED_LIST]: createButtonTool({
547
- name: ToolType.ORDERED_LIST,
548
- icon: 'format-list-numbered',
549
- title: 'Нумерованный список',
550
- exec() {
551
- this.editor.chain().focus().toggleOrderedList().run();
552
- },
553
- isActive() {
554
- return this.editor.isActive(NodeType.ORDERED_LIST);
555
- }
556
- }),
557
- [ToolType.BULLET_LIST]: createButtonTool({
558
- name: ToolType.BULLET_LIST,
559
- icon: 'format-list-bulleted',
560
- title: 'Маркированный список',
561
- exec() {
562
- this.editor.chain().focus().toggleBulletList().run();
563
- },
564
- isActive() {
565
- return this.editor.isActive(NodeType.BULLET_LIST);
566
- }
567
- }),
568
- [ToolType.TEXT_ALIGN_LEFT]: createButtonTool({
569
- name: ToolType.TEXT_ALIGN_LEFT,
570
- icon: 'format-align-left',
571
- title: 'По левому краю',
572
- exec() {
573
- this.editor.chain().focus().setTextAlign('left').run();
574
- },
575
- isActive() {
576
- return this.editor.isActive({ textAlign: 'left' });
577
- }
578
- }),
579
- [ToolType.TEXT_ALIGN_CENTER]: createButtonTool({
580
- name: ToolType.TEXT_ALIGN_CENTER,
581
- icon: 'format-align-center',
582
- title: 'По центру',
583
- exec() {
584
- this.editor.chain().focus().setTextAlign('center').run();
585
- },
586
- isActive() {
587
- return this.editor.isActive({ textAlign: 'center' });
588
- }
589
- }),
590
- [ToolType.TEXT_ALIGN_RIGHT]: createButtonTool({
591
- name: ToolType.TEXT_ALIGN_RIGHT,
592
- icon: 'format-align-right',
593
- title: 'По правому краю',
594
- exec() {
595
- this.editor.chain().focus().setTextAlign('right').run();
596
- },
597
- isActive() {
598
- return this.editor.isActive({ textAlign: 'right' });
599
- }
600
- }),
601
- [ToolType.HORIZONTAL_RULE]: createButtonTool({
602
- name: ToolType.HORIZONTAL_RULE,
603
- icon: 'minus',
604
- title: 'Вертикальный разделитель',
605
- exec() {
606
- this.editor.chain().focus().setHorizontalRule().run();
607
- },
608
- isEnabled() {
609
- return this.editor.can().setHorizontalRule();
610
- }
611
- }),
612
- [ToolType.LINK]: createLinkTool({
613
- name: ToolType.LINK,
614
- icon: 'link-plus',
615
- title: 'Ссылка',
616
- getValue() {
617
- const linkAttrs = this.editor.getAttributes(MarkType.LINK);
618
- const { href: url, target } = linkAttrs;
619
- return { url, target };
620
- },
621
- isEnabled() {
622
- return this.editor.can().setLink();
623
- },
624
- exec({ url, target }) {
625
- const { editor } = this;
626
-
627
- if (url === '') {
628
- editor
629
- .chain()
630
- .focus()
631
- .extendMarkRange(MarkType.LINK)
632
- .unsetLink()
633
- .run();
634
-
635
- return;
636
- }
637
-
638
- editor
639
- .chain()
640
- .focus()
641
- .extendMarkRange(MarkType.LINK)
642
- .setLink({ href: url, ...(target && { target }) })
643
- .run();
644
- }
645
- }),
646
- [ToolType.BOLD]: createButtonTool({
647
- name: ToolType.BOLD,
648
- icon: 'format-bold',
649
- title: 'Жирный',
650
- exec() {
651
- this.editor.chain().focus().toggleBold().run();
652
- },
653
- isActive() {
654
- return this.editor.isActive(MarkType.BOLD);
655
- }
656
- }),
657
- [ToolType.ITALIC]: createButtonTool({
658
- name: ToolType.ITALIC,
659
- icon: 'format-italic',
660
- title: 'Курсив',
661
- exec() {
662
- this.editor.chain().focus().toggleItalic().run();
663
- },
664
- isActive() {
665
- return this.editor.isActive(MarkType.ITALIC);
666
- }
667
- }),
668
- [ToolType.STRIKE]: createButtonTool({
669
- name: ToolType.STRIKE,
670
- icon: 'format-strikethrough-variant',
671
- title: 'Зачеркивание',
672
- exec() {
673
- this.editor.chain().focus().toggleStrike().run();
674
- },
675
- isActive() {
676
- return this.editor.isActive(MarkType.STRIKE);
677
- }
678
- }),
679
- [ToolType.UNDERLINE]: createButtonTool({
680
- name: ToolType.UNDERLINE,
681
- icon: 'format-underline',
682
- title: 'Подчеркивание',
683
- exec() {
684
- this.editor.chain().focus().toggleUnderline().run();
685
- },
686
- isActive() {
687
- return this.editor.isActive(MarkType.UNDERLINE);
688
- }
689
- }),
690
- [ToolType.TABLE]: createToolbarPopoverTool({
691
- name: ToolType.TABLE,
692
- icon: 'table-plus',
693
- title: 'таблица',
694
- options: Object.values(TableOptionsMap)
695
- }),
696
- [ToolType.CLEAR_FORMATTING]: createButtonTool({
697
- name: ToolType.CLEAR_FORMATTING,
698
- icon: 'eraser',
699
- title: 'Очистить форматирование',
700
- exec() {
701
- this.editor.chain().focus().clearFormatting().run();
702
- }
703
- })
704
- };
1
+ import {
2
+ NodeType,
3
+ MarkType,
4
+ CommandType,
5
+ ToolType,
6
+ createButtonTool,
7
+ createColorPickerTool,
8
+ createCommand,
9
+ createInputUnitsTool,
10
+ createSelectTool,
11
+ createToolbarPopoverTool,
12
+ createInputAutoTool,
13
+ createInputBrowseTool,
14
+ createLinkTool
15
+ } from './constants';
16
+
17
+ export const CommandMap = {
18
+ [CommandType.PARAGRAPH]: createCommand({
19
+ name: CommandType.PARAGRAPH,
20
+ title: 'Абзац',
21
+ exec() {
22
+ this.editor
23
+ .chain()
24
+ .focus()
25
+ .setParagraph()
26
+ .setParagraphClass('p')
27
+ .resetAttributes(MarkType.TEXT_STYLE, 'fontSize')
28
+ .run();
29
+ },
30
+ isActive() {
31
+ return this.editor.isActive(NodeType.PARAGRAPH, { class: 'p' });
32
+ }
33
+ }),
34
+ [CommandType.HEADING_1]: createCommand({
35
+ name: CommandType.HEADING_1,
36
+ title: 'Заголовок 1 (h1)',
37
+ exec() {
38
+ this.editor
39
+ .chain()
40
+ .focus()
41
+ .setHeading({ level: 1 })
42
+ .resetAttributes(MarkType.TEXT_STYLE, 'fontSize')
43
+ .run();
44
+ },
45
+ isActive() {
46
+ return this.editor.isActive(NodeType.HEADING, { level: 1 });
47
+ }
48
+ }),
49
+ [CommandType.HEADING_2]: createCommand({
50
+ name: CommandType.HEADING_2,
51
+ title: 'Заголовок 2 (h2)',
52
+ exec() {
53
+ this.editor
54
+ .chain()
55
+ .focus()
56
+ .setHeading({ level: 2 })
57
+ .resetAttributes(MarkType.TEXT_STYLE, 'fontSize')
58
+ .run();
59
+ },
60
+ isActive() {
61
+ return this.editor.isActive(NodeType.HEADING, { level: 2 });
62
+ }
63
+ }),
64
+ [CommandType.HEADING_3]: createCommand({
65
+ name: CommandType.HEADING_3,
66
+ title: 'Заголовок 3 (h3)',
67
+ exec() {
68
+ this.editor
69
+ .chain()
70
+ .focus()
71
+ .setHeading({ level: 3 })
72
+ .resetAttributes(MarkType.TEXT_STYLE, 'fontSize')
73
+ .run();
74
+ },
75
+ isActive() {
76
+ return this.editor.isActive(NodeType.HEADING, { level: 3 });
77
+ }
78
+ }),
79
+ [CommandType.HEADING_4]: createCommand({
80
+ name: CommandType.HEADING_4,
81
+ title: 'Заголовок 4 (h4)',
82
+ exec() {
83
+ this.editor
84
+ .chain()
85
+ .focus()
86
+ .setHeading({ level: 4 })
87
+ .resetAttributes(MarkType.TEXT_STYLE, 'fontSize')
88
+ .run();
89
+ },
90
+ isActive() {
91
+ return this.editor.isActive(NodeType.HEADING, { level: 4 });
92
+ }
93
+ }),
94
+ [CommandType.TEXT_SMALL]: createCommand({
95
+ name: CommandType.TEXT_SMALL,
96
+ title: 'Small',
97
+ exec() {
98
+ this.editor
99
+ .chain()
100
+ .focus()
101
+ .setParagraph()
102
+ .setParagraphClass('text-small')
103
+ .resetAttributes(MarkType.TEXT_STYLE, 'fontSize')
104
+ .run();
105
+ },
106
+ isActive() {
107
+ return this.editor.isActive(NodeType.PARAGRAPH, { class: 'text-small' });
108
+ }
109
+ }),
110
+ [CommandType.TEXT_XSMALL]: createCommand({
111
+ name: CommandType.TEXT_XSMALL,
112
+ title: 'Xsmall',
113
+ exec() {
114
+ this.editor
115
+ .chain()
116
+ .focus()
117
+ .setParagraph()
118
+ .setParagraphClass('text-xsmall')
119
+ .resetAttributes(MarkType.TEXT_STYLE, 'fontSize')
120
+ .run();
121
+ },
122
+ isActive() {
123
+ return this.editor.isActive(NodeType.PARAGRAPH, { class: 'text-xsmall' });
124
+ }
125
+ }),
126
+ [CommandType.CODE_BLOCK]: createCommand({
127
+ name: CommandType.CODE_BLOCK,
128
+ title: 'Код',
129
+ exec() {
130
+ this.editor
131
+ .chain()
132
+ .focus()
133
+ .setCodeBlock()
134
+ .run();
135
+ },
136
+ isActive() {
137
+ return this.editor.isActive(NodeType.CODE_BLOCK);
138
+ }
139
+ }),
140
+ [CommandType.SINK_LIST_ITEM]: createCommand({
141
+ name: CommandType.SINK_LIST_ITEM,
142
+ title: 'Опустить элемент списка',
143
+ exec() {
144
+ this.editor
145
+ .chain()
146
+ .focus()
147
+ .sinkListItem(NodeType.LIST_ITEM)
148
+ .run();
149
+ },
150
+ isEnabled() {
151
+ return this.editor.can().sinkListItem(NodeType.LIST_ITEM);
152
+ }
153
+ }),
154
+ [CommandType.LIFT_LIST_ITEM]: createCommand({
155
+ name: CommandType.LIFT_LIST_ITEM,
156
+ title: 'Поднять элемент списка',
157
+ exec() {
158
+ this.editor.chain().focus().liftListItem(NodeType.LIST_ITEM).run();
159
+ },
160
+ isEnabled() {
161
+ return this.editor.can().liftListItem(NodeType.LIST_ITEM);
162
+ }
163
+ })
164
+ };
165
+
166
+ export const TableOptionsMap = {
167
+ [ToolType.INSERT_TABLE]: createButtonTool({
168
+ name: ToolType.INSERT_TABLE,
169
+ icon: 'table',
170
+ title: 'Вставить таблицу',
171
+ exec() {
172
+ this.editor
173
+ .chain()
174
+ .focus()
175
+ .insertTable({ rows: 3, cols: 3, withHeaderRow: true })
176
+ .run();
177
+ },
178
+ isEnabled() {
179
+ return this.editor.can().insertTable();
180
+ }
181
+ }),
182
+ [ToolType.DELETE_TABLE]: createButtonTool({
183
+ name: ToolType.DELETE_TABLE,
184
+ icon: 'table-remove',
185
+ title: 'Удалить таблицу',
186
+ exec() {
187
+ this.editor.chain().focus().deleteTable().run();
188
+ },
189
+ isEnabled() {
190
+ return this.editor.can().deleteTable();
191
+ }
192
+ }),
193
+ [ToolType.ADD_COLUMN_BEFORE]: createButtonTool({
194
+ name: ToolType.ADD_COLUMN_BEFORE,
195
+ icon: 'table-column-plus-before',
196
+ title: 'Добавить колонку перед',
197
+ exec() {
198
+ this.editor.chain().focus().addColumnBefore().run();
199
+ },
200
+ isEnabled() {
201
+ return this.editor.can().addColumnBefore();
202
+ }
203
+ }),
204
+ [ToolType.ADD_COLUMN_AFTER]: createButtonTool({
205
+ name: ToolType.ADD_COLUMN_AFTER,
206
+ icon: 'table-column-plus-after',
207
+ title: 'Добавить колонку после',
208
+ exec() {
209
+ this.editor.chain().focus().addColumnAfter().run();
210
+ },
211
+ isEnabled() {
212
+ return this.editor.can().addColumnAfter();
213
+ }
214
+ }),
215
+ [ToolType.DELETE_COLUMN]: createButtonTool({
216
+ name: ToolType.DELETE_COLUMN,
217
+ icon: 'table-column-remove',
218
+ title: 'Удалить колонку',
219
+ exec() {
220
+ this.editor.chain().focus().deleteColumn().run();
221
+ },
222
+ isEnabled() {
223
+ return this.editor.can().deleteColumn();
224
+ }
225
+ }),
226
+ [ToolType.ADD_ROW_BEFORE]: createButtonTool({
227
+ name: ToolType.ADD_ROW_BEFORE,
228
+ icon: 'table-row-plus-before',
229
+ title: 'Добавить строку перед',
230
+ exec() {
231
+ this.editor.chain().focus().addRowBefore().run();
232
+ },
233
+ isEnabled() {
234
+ return this.editor.can().addRowBefore();
235
+ }
236
+ }),
237
+ [ToolType.ADD_ROW_AFTER]: createButtonTool({
238
+ name: ToolType.ADD_ROW_AFTER,
239
+ icon: 'table-row-plus-after',
240
+ title: 'Добавить строку после',
241
+ exec() {
242
+ this.editor.chain().focus().addRowAfter().run();
243
+ },
244
+ isEnabled() {
245
+ return this.editor.can().addRowAfter();
246
+ }
247
+ }),
248
+ [ToolType.DELETE_ROW]: createButtonTool({
249
+ name: ToolType.DELETE_ROW,
250
+ icon: 'table-row-remove',
251
+ title: 'Удалить строку',
252
+ exec() {
253
+ this.editor.chain().focus().deleteRow().run();
254
+ },
255
+ isEnabled() {
256
+ return this.editor.can().deleteRow();
257
+ }
258
+ }),
259
+ [ToolType.MERGE_CELLS]: createButtonTool({
260
+ name: ToolType.MERGE_CELLS,
261
+ icon: 'table-merge-cells',
262
+ title: 'Объединить ячейки',
263
+ exec() {
264
+ this.editor.chain().focus().mergeCells().run();
265
+ },
266
+ isEnabled() {
267
+ return this.editor.can().mergeCells();
268
+ }
269
+ }),
270
+ [ToolType.SPLIT_CELL]: createButtonTool({
271
+ name: ToolType.SPLIT_CELL,
272
+ icon: 'table-split-cell',
273
+ title: 'Разделить ячейки',
274
+ exec() {
275
+ this.editor.chain().focus().splitCell().run();
276
+ },
277
+ isEnabled() {
278
+ return this.editor.can().splitCell();
279
+ }
280
+ }),
281
+ [ToolType.TOGGLE_HEADER_ROW]: createButtonTool({
282
+ name: ToolType.TOGGLE_HEADER_ROW,
283
+ icon: 'table-row-height',
284
+ title: 'Переключить строку заголовка',
285
+ exec() {
286
+ this.editor.chain().focus().toggleHeaderRow().run();
287
+ },
288
+ isEnabled() {
289
+ return this.editor.can().toggleHeaderRow();
290
+ }
291
+ }),
292
+ [ToolType.TOGGLE_HEADER_COLUMN]: createButtonTool({
293
+ name: ToolType.TOGGLE_HEADER_COLUMN,
294
+ icon: 'table-column-width',
295
+ title: 'Переключить колонку заголовка',
296
+ exec() {
297
+ this.editor.chain().focus().toggleHeaderColumn().run();
298
+ },
299
+ isEnabled() {
300
+ return this.editor.can().toggleHeaderColumn();
301
+ }
302
+ }),
303
+ [ToolType.ALIGN_V_TOP]: createButtonTool({
304
+ name: ToolType.ALIGN_V_TOP,
305
+ icon: 'align-vertical-top',
306
+ title: 'Выровнять по верхнему краю',
307
+ exec() {
308
+ const classNames = this.editor.getAttributes(NodeType.TABLE).class;
309
+ this.editor.chain().focus().toggleTableAlignment('table-vtop', classNames).run();
310
+ },
311
+ isEnabled() {
312
+ return this.editor.isActive(NodeType.TABLE);
313
+ },
314
+ isActive() {
315
+ const classNames = this.editor.getAttributes(NodeType.TABLE).class;
316
+ return classNames?.includes('table-vtop') ?? false;
317
+ }
318
+ }),
319
+ [ToolType.ALIGN_V_MID]: createButtonTool({
320
+ name: ToolType.ALIGN_V_MID,
321
+ icon: 'align-vertical-center',
322
+ title: 'Выровнять по центру',
323
+ exec() {
324
+ const classNames = this.editor.getAttributes(NodeType.TABLE).class;
325
+ this.editor.chain().focus().toggleTableAlignment('table-vmid', classNames).run();
326
+ },
327
+ isEnabled() {
328
+ return this.editor.isActive(NodeType.TABLE);
329
+ },
330
+ isActive() {
331
+ const classNames = this.editor.getAttributes(NodeType.TABLE).class;
332
+ return classNames?.includes('table-vmid') ?? false;
333
+ }
334
+ }),
335
+ [ToolType.ALIGN_V_BOT]: createButtonTool({
336
+ name: ToolType.ALIGN_V_BOT,
337
+ icon: 'align-vertical-bottom',
338
+ title: 'Выровнять по нижнему краю',
339
+ exec() {
340
+ const classNames = this.editor.getAttributes(NodeType.TABLE).class;
341
+ this.editor.chain().focus().toggleTableAlignment('table-vbot', classNames).run();
342
+ },
343
+ isEnabled() {
344
+ return this.editor.isActive(NodeType.TABLE);
345
+ },
346
+ isActive() {
347
+ const classNames = this.editor.getAttributes(NodeType.TABLE).class;
348
+ return classNames?.includes('table-vbot') ?? false;
349
+ }
350
+ }),
351
+ [ToolType.TOGGLE_BORDERS]: createButtonTool({
352
+ name: ToolType.TOGGLE_BORDERS,
353
+ icon: 'border-all',
354
+ title: 'Границы',
355
+ exec() {
356
+ const classNames = this.editor.getAttributes(NodeType.TABLE).class;
357
+ this.editor.chain().focus().toggleTableClass('table-borders', classNames).run();
358
+ },
359
+ isEnabled() {
360
+ return this.editor.isActive(NodeType.TABLE);
361
+ },
362
+ isActive() {
363
+ const classNames = this.editor.getAttributes(NodeType.TABLE).class;
364
+ return classNames?.includes('table-borders') ?? false;
365
+ }
366
+ }),
367
+ [ToolType.TOGGLE_ZEBRA]: createButtonTool({
368
+ name: ToolType.TOGGLE_ZEBRA,
369
+ icon: 'view-stream',
370
+ title: 'Стиль "зебра"',
371
+ exec() {
372
+ const classNames = this.editor.getAttributes(NodeType.TABLE).class;
373
+ this.editor.chain().focus().toggleTableClass('table-zebra', classNames).run();
374
+ },
375
+ isEnabled() {
376
+ return this.editor.isActive(NodeType.TABLE);
377
+ },
378
+ isActive() {
379
+ const classNames = this.editor.getAttributes(NodeType.TABLE).class;
380
+ return classNames?.includes('table-zebra') ?? false;
381
+ }
382
+ })
383
+ };
384
+
385
+ export const ImageOptionsMap = {
386
+ [ToolType.INSERT_IMAGE]: createInputBrowseTool({
387
+ name: ToolType.INSERT_IMAGE,
388
+ title: 'Вставить изображение',
389
+ async exec(fromInputUrl) {
390
+ const setImage = (url) => {
391
+ this.editor.chain().focus().setImage({ src: url }).run();
392
+ };
393
+
394
+ if (fromInputUrl != null) {
395
+ setImage(fromInputUrl);
396
+ return;
397
+ }
398
+
399
+ const imageUrl = await this.getImageUrl();
400
+
401
+ if (imageUrl != null) {
402
+ setImage(imageUrl);
403
+ }
404
+ },
405
+ getValue() {
406
+ return this.editor.getAttributes(NodeType.IMAGE).src;
407
+ }
408
+ })
409
+ };
410
+
411
+ export const ToolsMap = {
412
+ [ToolType.UNDO]: createButtonTool({
413
+ name: ToolType.UNDO,
414
+ icon: 'undo-variant',
415
+ title: 'Назад',
416
+ exec() {
417
+ this.editor.commands.undo();
418
+ },
419
+ isEnabled() {
420
+ return this.editor.can().undo();
421
+ }
422
+ }),
423
+ [ToolType.REDO]: createButtonTool({
424
+ name: ToolType.REDO,
425
+ icon: 'redo-variant',
426
+ title: 'Вперед',
427
+ exec() {
428
+ this.editor.commands.redo();
429
+ },
430
+ isEnabled() {
431
+ return this.editor.can().redo();
432
+ }
433
+ }),
434
+ [ToolType.SAVE]: createButtonTool({
435
+ name: ToolType.SAVE,
436
+ icon: 'content-save',
437
+ title: 'Сохранить',
438
+ exec() {
439
+ this.onChange();
440
+ }
441
+ }),
442
+ [ToolType.PARAGRAPH_STYLE]: createSelectTool({
443
+ name: ToolType.PARAGRAPH_STYLE,
444
+ title: 'Стиль параграфа',
445
+ exec(command) {
446
+ if (command.name in CommandMap && command.isEnabled()) {
447
+ command.exec();
448
+ }
449
+ },
450
+ getValue(options) {
451
+ return options.find(({ value }) => value.isActive()) ?? null;
452
+ },
453
+ options: [
454
+ CommandMap[CommandType.PARAGRAPH],
455
+ CommandMap[CommandType.HEADING_1],
456
+ CommandMap[CommandType.HEADING_2],
457
+ CommandMap[CommandType.HEADING_3],
458
+ CommandMap[CommandType.HEADING_4],
459
+ CommandMap[CommandType.TEXT_SMALL],
460
+ CommandMap[CommandType.TEXT_XSMALL],
461
+ CommandMap[CommandType.CODE_BLOCK]
462
+ ]
463
+ }),
464
+ [ToolType.FONT_SIZE]: createInputUnitsTool({
465
+ name: ToolType.FONT_SIZE,
466
+ title: 'Размер шрифта',
467
+ exec(value) {
468
+ this.editor.commands.setFontSize(value);
469
+ },
470
+ isEnabled() {
471
+ const { editor } = this;
472
+
473
+ return (
474
+ editor.isActive(NodeType.HEADING) ||
475
+ editor.isActive(NodeType.PARAGRAPH, { class: 'text-small' }) ||
476
+ editor.isActive(NodeType.PARAGRAPH, { class: 'text-xsmall' })
477
+ ) === false;
478
+ },
479
+ getValue() {
480
+ return this.editor.getAttributes(MarkType.TEXT_STYLE).fontSize;
481
+ },
482
+ units: ["rem", "em", "%", "px", "vh", "vw"]
483
+ }),
484
+ [ToolType.TEXT_COLOR]: createColorPickerTool({
485
+ name: ToolType.TEXT_COLOR,
486
+ icon: 'format-color-fill',
487
+ title: 'Цвет',
488
+ exec(value) {
489
+ this.editor.chain().focus().setColor(value).run();
490
+ },
491
+ getValue() {
492
+ return this.editor.getAttributes(MarkType.TEXT_STYLE).color;
493
+ }
494
+ }),
495
+ [ToolType.FONT_FAMILY]: createInputAutoTool({
496
+ name: ToolType.FONT_FAMILY,
497
+ title: 'Семейство шрифта',
498
+ exec(value) {
499
+ this.editor.commands.setFontFamily(value);
500
+ },
501
+ getValue() {
502
+ return this.editor.getAttributes(MarkType.TEXT_STYLE).fontFamily;
503
+ },
504
+ options: ['serif', 'sans-serif']
505
+ }),
506
+ [ToolType.BLOCKQUOTE]: createButtonTool({
507
+ name: ToolType.BLOCKQUOTE,
508
+ icon: 'format-quote-close-outline',
509
+ title: 'Цитата',
510
+ exec() {
511
+ this.editor
512
+ .chain()
513
+ .focus()
514
+ .toggleBlockquote()
515
+ .run();
516
+ },
517
+ isActive() {
518
+ return this.editor.isActive(NodeType.BLOCKQUOTE);
519
+ }
520
+ }),
521
+ [ToolType.HARD_BREAK]: createButtonTool({
522
+ name: ToolType.HARD_BREAK,
523
+ title: 'Перевод строки',
524
+ icon: 'keyboard-return',
525
+ exec() {
526
+ this.editor.chain().focus().setHardBreak().run();
527
+ }
528
+ }),
529
+ [ToolType.CODE]: createButtonTool({
530
+ name: ToolType.CODE,
531
+ icon: 'code-not-equal-variant',
532
+ title: 'Код',
533
+ exec() {
534
+ this.editor.chain().focus().toggleCode().run();
535
+ },
536
+ isActive() {
537
+ return this.editor.isActive(MarkType.CODE);
538
+ }
539
+ }),
540
+ [ToolType.IMAGE]: createToolbarPopoverTool({
541
+ name: ToolType.IMAGE,
542
+ icon: 'image-plus',
543
+ title: 'Изображение',
544
+ options: Object.values(ImageOptionsMap)
545
+ }),
546
+ [ToolType.ORDERED_LIST]: createButtonTool({
547
+ name: ToolType.ORDERED_LIST,
548
+ icon: 'format-list-numbered',
549
+ title: 'Нумерованный список',
550
+ exec() {
551
+ this.editor.chain().focus().toggleOrderedList().run();
552
+ },
553
+ isActive() {
554
+ return this.editor.isActive(NodeType.ORDERED_LIST);
555
+ }
556
+ }),
557
+ [ToolType.BULLET_LIST]: createButtonTool({
558
+ name: ToolType.BULLET_LIST,
559
+ icon: 'format-list-bulleted',
560
+ title: 'Маркированный список',
561
+ exec() {
562
+ this.editor.chain().focus().toggleBulletList().run();
563
+ },
564
+ isActive() {
565
+ return this.editor.isActive(NodeType.BULLET_LIST);
566
+ }
567
+ }),
568
+ [ToolType.TEXT_ALIGN_LEFT]: createButtonTool({
569
+ name: ToolType.TEXT_ALIGN_LEFT,
570
+ icon: 'format-align-left',
571
+ title: 'По левому краю',
572
+ exec() {
573
+ this.editor.chain().focus().setTextAlign('left').run();
574
+ },
575
+ isActive() {
576
+ return this.editor.isActive({ textAlign: 'left' });
577
+ }
578
+ }),
579
+ [ToolType.TEXT_ALIGN_CENTER]: createButtonTool({
580
+ name: ToolType.TEXT_ALIGN_CENTER,
581
+ icon: 'format-align-center',
582
+ title: 'По центру',
583
+ exec() {
584
+ this.editor.chain().focus().setTextAlign('center').run();
585
+ },
586
+ isActive() {
587
+ return this.editor.isActive({ textAlign: 'center' });
588
+ }
589
+ }),
590
+ [ToolType.TEXT_ALIGN_RIGHT]: createButtonTool({
591
+ name: ToolType.TEXT_ALIGN_RIGHT,
592
+ icon: 'format-align-right',
593
+ title: 'По правому краю',
594
+ exec() {
595
+ this.editor.chain().focus().setTextAlign('right').run();
596
+ },
597
+ isActive() {
598
+ return this.editor.isActive({ textAlign: 'right' });
599
+ }
600
+ }),
601
+ [ToolType.HORIZONTAL_RULE]: createButtonTool({
602
+ name: ToolType.HORIZONTAL_RULE,
603
+ icon: 'minus',
604
+ title: 'Вертикальный разделитель',
605
+ exec() {
606
+ this.editor.chain().focus().setHorizontalRule().run();
607
+ },
608
+ isEnabled() {
609
+ return this.editor.can().setHorizontalRule();
610
+ }
611
+ }),
612
+ [ToolType.LINK]: createLinkTool({
613
+ name: ToolType.LINK,
614
+ icon: 'link-plus',
615
+ title: 'Ссылка',
616
+ getValue() {
617
+ const linkAttrs = this.editor.getAttributes(MarkType.LINK);
618
+ const { href: url, target } = linkAttrs;
619
+ return { url, target };
620
+ },
621
+ isEnabled() {
622
+ return this.editor.can().setLink();
623
+ },
624
+ exec({ url, target }) {
625
+ const { editor } = this;
626
+
627
+ if (url === '') {
628
+ editor
629
+ .chain()
630
+ .focus()
631
+ .extendMarkRange(MarkType.LINK)
632
+ .unsetLink()
633
+ .run();
634
+
635
+ return;
636
+ }
637
+
638
+ editor
639
+ .chain()
640
+ .focus()
641
+ .extendMarkRange(MarkType.LINK)
642
+ .setLink({ href: url, ...(target && { target }) })
643
+ .run();
644
+ }
645
+ }),
646
+ [ToolType.BOLD]: createButtonTool({
647
+ name: ToolType.BOLD,
648
+ icon: 'format-bold',
649
+ title: 'Жирный',
650
+ exec() {
651
+ this.editor.chain().focus().toggleBold().run();
652
+ },
653
+ isActive() {
654
+ return this.editor.isActive(MarkType.BOLD);
655
+ }
656
+ }),
657
+ [ToolType.ITALIC]: createButtonTool({
658
+ name: ToolType.ITALIC,
659
+ icon: 'format-italic',
660
+ title: 'Курсив',
661
+ exec() {
662
+ this.editor.chain().focus().toggleItalic().run();
663
+ },
664
+ isActive() {
665
+ return this.editor.isActive(MarkType.ITALIC);
666
+ }
667
+ }),
668
+ [ToolType.STRIKE]: createButtonTool({
669
+ name: ToolType.STRIKE,
670
+ icon: 'format-strikethrough-variant',
671
+ title: 'Зачеркивание',
672
+ exec() {
673
+ this.editor.chain().focus().toggleStrike().run();
674
+ },
675
+ isActive() {
676
+ return this.editor.isActive(MarkType.STRIKE);
677
+ }
678
+ }),
679
+ [ToolType.UNDERLINE]: createButtonTool({
680
+ name: ToolType.UNDERLINE,
681
+ icon: 'format-underline',
682
+ title: 'Подчеркивание',
683
+ exec() {
684
+ this.editor.chain().focus().toggleUnderline().run();
685
+ },
686
+ isActive() {
687
+ return this.editor.isActive(MarkType.UNDERLINE);
688
+ }
689
+ }),
690
+ [ToolType.TABLE]: createToolbarPopoverTool({
691
+ name: ToolType.TABLE,
692
+ icon: 'table-plus',
693
+ title: 'таблица',
694
+ options: Object.values(TableOptionsMap)
695
+ }),
696
+ [ToolType.CLEAR_FORMATTING]: createButtonTool({
697
+ name: ToolType.CLEAR_FORMATTING,
698
+ icon: 'eraser',
699
+ title: 'Очистить форматирование',
700
+ exec() {
701
+ this.editor.chain().focus().clearFormatting().run();
702
+ }
703
+ })
704
+ };