goodteditor-ui 1.0.50 → 1.0.52

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 (29) hide show
  1. package/index.d.ts +60 -0
  2. package/index.js +3 -3
  3. package/package.json +1 -1
  4. package/src/App.vue +3 -1
  5. package/src/components/ui/Popup.vue +27 -4
  6. package/src/components/ui/Tooltip.vue +26 -7
  7. package/src/components/ui/WysiwygEditor/WysiwygEditor.md +74 -0
  8. package/src/components/ui/{WysiwygEditor.vue → WysiwygEditor/WysiwygEditor.vue} +13 -16
  9. package/src/components/ui/WysiwygEditor/{WysiwygEditor.d.ts → constants.d.ts} +14 -5
  10. package/src/components/ui/WysiwygEditor/constants.js +29 -99
  11. package/src/components/ui/WysiwygEditor/index.d.ts +3 -4
  12. package/src/components/ui/WysiwygEditor/index.js +3 -4
  13. package/src/components/ui/WysiwygEditor/renders/Button.vue +4 -3
  14. package/src/components/ui/WysiwygEditor/renders/ColorPicker.vue +4 -3
  15. package/src/components/ui/WysiwygEditor/renders/Image.vue +5 -4
  16. package/src/components/ui/WysiwygEditor/renders/InputAuto.vue +2 -1
  17. package/src/components/ui/WysiwygEditor/renders/InputUnits.vue +2 -1
  18. package/src/components/ui/WysiwygEditor/renders/Link.vue +4 -3
  19. package/src/components/ui/WysiwygEditor/renders/Select.vue +2 -1
  20. package/src/components/ui/WysiwygEditor/renders/ToolbarPopover.vue +4 -3
  21. package/src/components/ui/WysiwygEditor/renders/mixins/RenderMixin.d.ts +20 -0
  22. package/src/components/ui/WysiwygEditor/renders/mixins/RenderMixin.js +8 -1
  23. package/src/components/ui/WysiwygEditor/renders/mixins/index.d.ts +1 -0
  24. package/src/components/ui/WysiwygEditor/renders/mixins/index.js +1 -1
  25. package/src/components/ui/WysiwygEditor/tools-and-commands.js +50 -49
  26. package/src/components/ui/WysiwygEditor/utils.js +20 -6
  27. package/src/components/ui/utils/Helpers.js +6 -0
  28. package/styleguide.config.js +7 -1
  29. package/src/components/ui/WysiwygEditor.md +0 -18
@@ -3,8 +3,8 @@
3
3
  <template #button="{ togglePopover }">
4
4
  <button
5
5
  :title="title"
6
- :class="{ 'btn-outline': !isPopoverShown, 'btn-primary': isPopoverShown }"
7
- class="btn btn-small btn-icon"
6
+ :class="{ 'btn-outline': !isPopoverShown }"
7
+ class="btn btn-small btn-icon btn-primary"
8
8
  @click="togglePopover">
9
9
  <div class="icon">
10
10
  <i class="mdi" :class="icon"></i>
@@ -106,9 +106,9 @@ import InputAutocomplete from '../../InputAutocomplete.vue';
106
106
  import InputUnits from '../../InputUnits.vue';
107
107
  import UiSelect from '../../Select.vue';
108
108
  import WithPopover from './components/WithPopover.vue';
109
- import { useRender } from './mixins';
109
+ import { useRender, RenderMixinTypes } from './mixins';
110
110
 
111
- const SizeUnits = ["rem", "em", "%", "px", "vh", "vw"];
111
+ const SizeUnits = ['rem', 'em', '%', 'px', 'vh', 'vw'];
112
112
  const AlignOptions = [
113
113
  { value: null, label: 'По левому краю' },
114
114
  { value: 'mar-h-auto', label: 'По центру' },
@@ -163,6 +163,7 @@ export default {
163
163
  AlignOptions
164
164
  },
165
165
  methods: {
166
+ ...RenderMixinTypes,
166
167
  setImageSettings() {
167
168
  const attrs = this.tool.getValue();
168
169
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  <script>
10
10
  import InputAutocomplete from '../../InputAutocomplete.vue';
11
- import { useRender } from './mixins';
11
+ import { useRender, RenderMixinTypes } from './mixins';
12
12
 
13
13
  export default {
14
14
  components: { InputAutocomplete },
@@ -19,6 +19,7 @@ export default {
19
19
  }
20
20
  },
21
21
  methods: {
22
+ ...RenderMixinTypes,
22
23
  onInput(value) {
23
24
  this.tool.exec(value);
24
25
  this.emitExecuted();
@@ -8,7 +8,7 @@
8
8
 
9
9
  <script>
10
10
  import InputUnits from '../../InputUnits.vue';
11
- import { useRender } from './mixins';
11
+ import { useRender, RenderMixinTypes } from './mixins';
12
12
 
13
13
  export default {
14
14
  components: { InputUnits },
@@ -22,6 +22,7 @@ export default {
22
22
  }
23
23
  },
24
24
  methods: {
25
+ ...RenderMixinTypes,
25
26
  onChange(value) {
26
27
  this.tool.exec(value);
27
28
  this.emitExecuted();
@@ -3,8 +3,8 @@
3
3
  <template #button="{ togglePopover }">
4
4
  <button
5
5
  :title="title"
6
- :class="{ 'btn-outline': !isPopoverShown, 'btn-primary': isPopoverShown }"
7
- class="btn btn-small btn-icon"
6
+ :class="{ 'btn-outline': !isPopoverShown }"
7
+ class="btn btn-small btn-icon btn-primary"
8
8
  @click="togglePopover">
9
9
  <div class="icon">
10
10
  <i class="mdi" :class="icon"></i>
@@ -39,7 +39,7 @@
39
39
  import InputAutocomplete from '../../InputAutocomplete.vue';
40
40
  import UiSelect from '../../Select.vue';
41
41
  import WithPopover from './components/WithPopover.vue';
42
- import { useRender } from './mixins';
42
+ import { useRender, RenderMixinTypes } from './mixins';
43
43
 
44
44
  const TargetType = {
45
45
  BLANK: '_blank',
@@ -74,6 +74,7 @@ export default {
74
74
  }
75
75
  },
76
76
  methods: {
77
+ ...RenderMixinTypes,
77
78
  execute() {
78
79
  const { tool, url, target } = this;
79
80
  tool.exec({ url, target });
@@ -9,7 +9,7 @@
9
9
 
10
10
  <script>
11
11
  import UiSelect from '../../Select.vue';
12
- import { useRender } from './mixins';
12
+ import { useRender, RenderMixinTypes } from './mixins';
13
13
 
14
14
  export default {
15
15
  components: { UiSelect },
@@ -32,6 +32,7 @@ export default {
32
32
  }
33
33
  },
34
34
  methods: {
35
+ ...RenderMixinTypes,
35
36
  onChange(option) {
36
37
  this.tool.exec(this.valueObjects ? option.value : option);
37
38
  this.emitExecuted();
@@ -1,8 +1,8 @@
1
1
  <template>
2
2
  <div :data-popover="popoverTargetId" :title="title">
3
3
  <button
4
- :class="{ 'btn-outline': !popoverShow, 'btn-primary': popoverShow }"
5
- class="btn btn-small btn-icon"
4
+ :class="{ 'btn-outline': !popoverShow }"
5
+ class="btn btn-small btn-icon btn-primary"
6
6
  @click="togglePopover">
7
7
  <div class="icon">
8
8
  <i class="mdi" :class="icon"></i>
@@ -27,12 +27,13 @@
27
27
  import Popover from '../../Popover.vue';
28
28
  import UiDatalist from '../../Datalist.vue';
29
29
  import WithPopover from '../../utils/WithPopover';
30
- import { useRender } from './mixins';
30
+ import { useRender, RenderMixinTypes } from './mixins';
31
31
 
32
32
  export default {
33
33
  components: { Popover, UiDatalist },
34
34
  mixins: [useRender(), WithPopover],
35
35
  methods: {
36
+ ...RenderMixinTypes,
36
37
  onCommandExecuted() {
37
38
  this.popoverShow = false;
38
39
  this.emitExecuted();
@@ -0,0 +1,20 @@
1
+ import { ComponentOptions } from 'vue';
2
+ import { ITool } from '../../constants';
3
+
4
+ interface IRenderMixinInstance {
5
+ // props
6
+ tool: ITool;
7
+
8
+ // computed
9
+ readonly icon: string;
10
+ readonly title: string;
11
+ readonly isActive: boolean;
12
+ readonly isEnabled: boolean;
13
+
14
+ /** to notify the wysiwyg-editor that a command was executed */
15
+ emitExecuted(): void;
16
+ }
17
+
18
+ export const RenderMixinTypes: IRenderMixinInstance = undefined;
19
+
20
+ export function useRender(): ComponentOptions;
@@ -1,11 +1,14 @@
1
+ /** @return {import('vue').ComponentOptions} */
1
2
  export const useRender = () => ({
2
3
  props: {
4
+ /** @type {import('vue').PropOptions<import('../../constants').ITool>}*/
3
5
  tool: {
4
6
  type: Object,
5
7
  default: null
6
8
  }
7
9
  },
8
10
  computed: {
11
+ /** @return {string} */
9
12
  icon() {
10
13
  const { tool } = this;
11
14
 
@@ -15,6 +18,7 @@ export const useRender = () => ({
15
18
 
16
19
  return [null, undefined, ''].includes(tool.icon) ? 'mdi-help-box' : `mdi-${tool.icon}`;
17
20
  },
21
+ /** @return {string} */
18
22
  title() {
19
23
  const { tool } = this;
20
24
 
@@ -24,16 +28,19 @@ export const useRender = () => ({
24
28
 
25
29
  return tool.title ?? tool.name ?? 'Unknown tool';
26
30
  },
31
+ /** @return {boolean} */
27
32
  isActive() {
28
33
  return this.tool.isActive();
29
34
  },
35
+ /** @return {boolean} */
30
36
  isEnabled() {
31
37
  return this.tool.isEnabled();
32
38
  }
33
39
  },
34
40
  methods: {
41
+ /** to notify the wysiwyg-editor that a command was executed */
35
42
  emitExecuted() {
36
43
  this.$emit('command-executed');
37
44
  }
38
45
  }
39
- })
46
+ });
@@ -0,0 +1 @@
1
+ export * from './RenderMixin';
@@ -1 +1 @@
1
- export { useRender } from './RenderMixin';
1
+ export * from './RenderMixin';
@@ -3,15 +3,9 @@ import {
3
3
  MarkType,
4
4
  CommandType,
5
5
  ToolType,
6
- createButtonTool,
7
- createColorPickerTool,
6
+ Render,
7
+ createTool,
8
8
  createCommand,
9
- createInputUnitsTool,
10
- createSelectTool,
11
- createToolbarPopoverTool,
12
- createInputAutoTool,
13
- createLinkTool,
14
- createImageTool,
15
9
  } from './constants';
16
10
 
17
11
  export const CommandMap = {
@@ -164,7 +158,7 @@ export const CommandMap = {
164
158
  };
165
159
 
166
160
  export const TableOptionsMap = {
167
- [ToolType.INSERT_TABLE]: createButtonTool({
161
+ [ToolType.INSERT_TABLE]: createTool({
168
162
  name: ToolType.INSERT_TABLE,
169
163
  icon: 'table',
170
164
  title: 'Вставить таблицу',
@@ -179,7 +173,7 @@ export const TableOptionsMap = {
179
173
  return this.editor.can().insertTable();
180
174
  }
181
175
  }),
182
- [ToolType.DELETE_TABLE]: createButtonTool({
176
+ [ToolType.DELETE_TABLE]: createTool({
183
177
  name: ToolType.DELETE_TABLE,
184
178
  icon: 'table-remove',
185
179
  title: 'Удалить таблицу',
@@ -190,7 +184,7 @@ export const TableOptionsMap = {
190
184
  return this.editor.can().deleteTable();
191
185
  }
192
186
  }),
193
- [ToolType.ADD_COLUMN_BEFORE]: createButtonTool({
187
+ [ToolType.ADD_COLUMN_BEFORE]: createTool({
194
188
  name: ToolType.ADD_COLUMN_BEFORE,
195
189
  icon: 'table-column-plus-before',
196
190
  title: 'Добавить колонку перед',
@@ -201,7 +195,7 @@ export const TableOptionsMap = {
201
195
  return this.editor.can().addColumnBefore();
202
196
  }
203
197
  }),
204
- [ToolType.ADD_COLUMN_AFTER]: createButtonTool({
198
+ [ToolType.ADD_COLUMN_AFTER]: createTool({
205
199
  name: ToolType.ADD_COLUMN_AFTER,
206
200
  icon: 'table-column-plus-after',
207
201
  title: 'Добавить колонку после',
@@ -212,7 +206,7 @@ export const TableOptionsMap = {
212
206
  return this.editor.can().addColumnAfter();
213
207
  }
214
208
  }),
215
- [ToolType.DELETE_COLUMN]: createButtonTool({
209
+ [ToolType.DELETE_COLUMN]: createTool({
216
210
  name: ToolType.DELETE_COLUMN,
217
211
  icon: 'table-column-remove',
218
212
  title: 'Удалить колонку',
@@ -223,7 +217,7 @@ export const TableOptionsMap = {
223
217
  return this.editor.can().deleteColumn();
224
218
  }
225
219
  }),
226
- [ToolType.ADD_ROW_BEFORE]: createButtonTool({
220
+ [ToolType.ADD_ROW_BEFORE]: createTool({
227
221
  name: ToolType.ADD_ROW_BEFORE,
228
222
  icon: 'table-row-plus-before',
229
223
  title: 'Добавить строку перед',
@@ -234,7 +228,7 @@ export const TableOptionsMap = {
234
228
  return this.editor.can().addRowBefore();
235
229
  }
236
230
  }),
237
- [ToolType.ADD_ROW_AFTER]: createButtonTool({
231
+ [ToolType.ADD_ROW_AFTER]: createTool({
238
232
  name: ToolType.ADD_ROW_AFTER,
239
233
  icon: 'table-row-plus-after',
240
234
  title: 'Добавить строку после',
@@ -245,7 +239,7 @@ export const TableOptionsMap = {
245
239
  return this.editor.can().addRowAfter();
246
240
  }
247
241
  }),
248
- [ToolType.DELETE_ROW]: createButtonTool({
242
+ [ToolType.DELETE_ROW]: createTool({
249
243
  name: ToolType.DELETE_ROW,
250
244
  icon: 'table-row-remove',
251
245
  title: 'Удалить строку',
@@ -256,7 +250,7 @@ export const TableOptionsMap = {
256
250
  return this.editor.can().deleteRow();
257
251
  }
258
252
  }),
259
- [ToolType.MERGE_CELLS]: createButtonTool({
253
+ [ToolType.MERGE_CELLS]: createTool({
260
254
  name: ToolType.MERGE_CELLS,
261
255
  icon: 'table-merge-cells',
262
256
  title: 'Объединить ячейки',
@@ -267,7 +261,7 @@ export const TableOptionsMap = {
267
261
  return this.editor.can().mergeCells();
268
262
  }
269
263
  }),
270
- [ToolType.SPLIT_CELL]: createButtonTool({
264
+ [ToolType.SPLIT_CELL]: createTool({
271
265
  name: ToolType.SPLIT_CELL,
272
266
  icon: 'table-split-cell',
273
267
  title: 'Разделить ячейки',
@@ -278,7 +272,7 @@ export const TableOptionsMap = {
278
272
  return this.editor.can().splitCell();
279
273
  }
280
274
  }),
281
- [ToolType.TOGGLE_HEADER_ROW]: createButtonTool({
275
+ [ToolType.TOGGLE_HEADER_ROW]: createTool({
282
276
  name: ToolType.TOGGLE_HEADER_ROW,
283
277
  icon: 'table-row-height',
284
278
  title: 'Переключить строку заголовка',
@@ -289,7 +283,7 @@ export const TableOptionsMap = {
289
283
  return this.editor.can().toggleHeaderRow();
290
284
  }
291
285
  }),
292
- [ToolType.TOGGLE_HEADER_COLUMN]: createButtonTool({
286
+ [ToolType.TOGGLE_HEADER_COLUMN]: createTool({
293
287
  name: ToolType.TOGGLE_HEADER_COLUMN,
294
288
  icon: 'table-column-width',
295
289
  title: 'Переключить колонку заголовка',
@@ -300,7 +294,7 @@ export const TableOptionsMap = {
300
294
  return this.editor.can().toggleHeaderColumn();
301
295
  }
302
296
  }),
303
- [ToolType.ALIGN_V_TOP]: createButtonTool({
297
+ [ToolType.ALIGN_V_TOP]: createTool({
304
298
  name: ToolType.ALIGN_V_TOP,
305
299
  icon: 'align-vertical-top',
306
300
  title: 'Выровнять по верхнему краю',
@@ -316,7 +310,7 @@ export const TableOptionsMap = {
316
310
  return classNames?.includes('table-vtop') ?? false;
317
311
  }
318
312
  }),
319
- [ToolType.ALIGN_V_MID]: createButtonTool({
313
+ [ToolType.ALIGN_V_MID]: createTool({
320
314
  name: ToolType.ALIGN_V_MID,
321
315
  icon: 'align-vertical-center',
322
316
  title: 'Выровнять по центру',
@@ -332,7 +326,7 @@ export const TableOptionsMap = {
332
326
  return classNames?.includes('table-vmid') ?? false;
333
327
  }
334
328
  }),
335
- [ToolType.ALIGN_V_BOT]: createButtonTool({
329
+ [ToolType.ALIGN_V_BOT]: createTool({
336
330
  name: ToolType.ALIGN_V_BOT,
337
331
  icon: 'align-vertical-bottom',
338
332
  title: 'Выровнять по нижнему краю',
@@ -348,7 +342,7 @@ export const TableOptionsMap = {
348
342
  return classNames?.includes('table-vbot') ?? false;
349
343
  }
350
344
  }),
351
- [ToolType.TOGGLE_BORDERS]: createButtonTool({
345
+ [ToolType.TOGGLE_BORDERS]: createTool({
352
346
  name: ToolType.TOGGLE_BORDERS,
353
347
  icon: 'border-all',
354
348
  title: 'Границы',
@@ -364,7 +358,7 @@ export const TableOptionsMap = {
364
358
  return classNames?.includes('table-borders') ?? false;
365
359
  }
366
360
  }),
367
- [ToolType.TOGGLE_ZEBRA]: createButtonTool({
361
+ [ToolType.TOGGLE_ZEBRA]: createTool({
368
362
  name: ToolType.TOGGLE_ZEBRA,
369
363
  icon: 'view-stream',
370
364
  title: 'Стиль "зебра"',
@@ -383,7 +377,7 @@ export const TableOptionsMap = {
383
377
  };
384
378
 
385
379
  export const ToolsMap = {
386
- [ToolType.UNDO]: createButtonTool({
380
+ [ToolType.UNDO]: createTool({
387
381
  name: ToolType.UNDO,
388
382
  icon: 'undo-variant',
389
383
  title: 'Назад',
@@ -394,7 +388,7 @@ export const ToolsMap = {
394
388
  return this.editor.can().undo();
395
389
  }
396
390
  }),
397
- [ToolType.REDO]: createButtonTool({
391
+ [ToolType.REDO]: createTool({
398
392
  name: ToolType.REDO,
399
393
  icon: 'redo-variant',
400
394
  title: 'Вперед',
@@ -405,7 +399,7 @@ export const ToolsMap = {
405
399
  return this.editor.can().redo();
406
400
  }
407
401
  }),
408
- [ToolType.SAVE]: createButtonTool({
402
+ [ToolType.SAVE]: createTool({
409
403
  name: ToolType.SAVE,
410
404
  icon: 'content-save',
411
405
  title: 'Сохранить',
@@ -413,8 +407,9 @@ export const ToolsMap = {
413
407
  this.onChange();
414
408
  }
415
409
  }),
416
- [ToolType.PARAGRAPH_STYLE]: createSelectTool({
410
+ [ToolType.PARAGRAPH_STYLE]: createTool({
417
411
  name: ToolType.PARAGRAPH_STYLE,
412
+ render: Render.SELECT,
418
413
  title: 'Стиль параграфа',
419
414
  exec(command) {
420
415
  if (command.name in CommandMap && command.isEnabled()) {
@@ -435,8 +430,9 @@ export const ToolsMap = {
435
430
  CommandMap[CommandType.CODE_BLOCK]
436
431
  ]
437
432
  }),
438
- [ToolType.FONT_SIZE]: createInputUnitsTool({
433
+ [ToolType.FONT_SIZE]: createTool({
439
434
  name: ToolType.FONT_SIZE,
435
+ render: Render.INPUT_UNITS,
440
436
  title: 'Размер шрифта',
441
437
  exec(value) {
442
438
  this.editor.commands.setFontSize(value);
@@ -455,8 +451,9 @@ export const ToolsMap = {
455
451
  },
456
452
  units: ["rem", "em", "%", "px", "vh", "vw"]
457
453
  }),
458
- [ToolType.TEXT_COLOR]: createColorPickerTool({
454
+ [ToolType.TEXT_COLOR]: createTool({
459
455
  name: ToolType.TEXT_COLOR,
456
+ render: Render.COLOR_PICKER,
460
457
  icon: 'format-color-fill',
461
458
  title: 'Цвет',
462
459
  exec(value) {
@@ -466,8 +463,9 @@ export const ToolsMap = {
466
463
  return this.editor.getAttributes(MarkType.TEXT_STYLE).color;
467
464
  }
468
465
  }),
469
- [ToolType.FONT_FAMILY]: createInputAutoTool({
466
+ [ToolType.FONT_FAMILY]: createTool({
470
467
  name: ToolType.FONT_FAMILY,
468
+ render: Render.INPUT_AUTO,
471
469
  title: 'Семейство шрифта',
472
470
  exec(value) {
473
471
  this.editor.commands.setFontFamily(value);
@@ -477,7 +475,7 @@ export const ToolsMap = {
477
475
  },
478
476
  options: ['serif', 'sans-serif']
479
477
  }),
480
- [ToolType.BLOCKQUOTE]: createButtonTool({
478
+ [ToolType.BLOCKQUOTE]: createTool({
481
479
  name: ToolType.BLOCKQUOTE,
482
480
  icon: 'format-quote-close-outline',
483
481
  title: 'Цитата',
@@ -492,7 +490,7 @@ export const ToolsMap = {
492
490
  return this.editor.isActive(NodeType.BLOCKQUOTE);
493
491
  }
494
492
  }),
495
- [ToolType.HARD_BREAK]: createButtonTool({
493
+ [ToolType.HARD_BREAK]: createTool({
496
494
  name: ToolType.HARD_BREAK,
497
495
  title: 'Перевод строки',
498
496
  icon: 'keyboard-return',
@@ -500,7 +498,7 @@ export const ToolsMap = {
500
498
  this.editor.chain().focus().setHardBreak().run();
501
499
  }
502
500
  }),
503
- [ToolType.CODE]: createButtonTool({
501
+ [ToolType.CODE]: createTool({
504
502
  name: ToolType.CODE,
505
503
  icon: 'code-not-equal-variant',
506
504
  title: 'Код',
@@ -511,8 +509,9 @@ export const ToolsMap = {
511
509
  return this.editor.isActive(MarkType.CODE);
512
510
  }
513
511
  }),
514
- [ToolType.IMAGE]: createImageTool({
512
+ [ToolType.IMAGE]: createTool({
515
513
  name: ToolType.IMAGE,
514
+ render: Render.IMAGE,
516
515
  icon: 'image-plus',
517
516
  title: 'Изображение',
518
517
  async exec({ url = null, isResponsive, align, width, height }) {
@@ -548,7 +547,7 @@ export const ToolsMap = {
548
547
  return this.editor.getAttributes(NodeType.IMAGE);
549
548
  }
550
549
  }),
551
- [ToolType.ORDERED_LIST]: createButtonTool({
550
+ [ToolType.ORDERED_LIST]: createTool({
552
551
  name: ToolType.ORDERED_LIST,
553
552
  icon: 'format-list-numbered',
554
553
  title: 'Нумерованный список',
@@ -559,7 +558,7 @@ export const ToolsMap = {
559
558
  return this.editor.isActive(NodeType.ORDERED_LIST);
560
559
  }
561
560
  }),
562
- [ToolType.BULLET_LIST]: createButtonTool({
561
+ [ToolType.BULLET_LIST]: createTool({
563
562
  name: ToolType.BULLET_LIST,
564
563
  icon: 'format-list-bulleted',
565
564
  title: 'Маркированный список',
@@ -570,7 +569,7 @@ export const ToolsMap = {
570
569
  return this.editor.isActive(NodeType.BULLET_LIST);
571
570
  }
572
571
  }),
573
- [ToolType.TEXT_ALIGN_LEFT]: createButtonTool({
572
+ [ToolType.TEXT_ALIGN_LEFT]: createTool({
574
573
  name: ToolType.TEXT_ALIGN_LEFT,
575
574
  icon: 'format-align-left',
576
575
  title: 'По левому краю',
@@ -581,7 +580,7 @@ export const ToolsMap = {
581
580
  return this.editor.isActive({ textAlign: 'left' });
582
581
  }
583
582
  }),
584
- [ToolType.TEXT_ALIGN_CENTER]: createButtonTool({
583
+ [ToolType.TEXT_ALIGN_CENTER]: createTool({
585
584
  name: ToolType.TEXT_ALIGN_CENTER,
586
585
  icon: 'format-align-center',
587
586
  title: 'По центру',
@@ -592,7 +591,7 @@ export const ToolsMap = {
592
591
  return this.editor.isActive({ textAlign: 'center' });
593
592
  }
594
593
  }),
595
- [ToolType.TEXT_ALIGN_RIGHT]: createButtonTool({
594
+ [ToolType.TEXT_ALIGN_RIGHT]: createTool({
596
595
  name: ToolType.TEXT_ALIGN_RIGHT,
597
596
  icon: 'format-align-right',
598
597
  title: 'По правому краю',
@@ -603,7 +602,7 @@ export const ToolsMap = {
603
602
  return this.editor.isActive({ textAlign: 'right' });
604
603
  }
605
604
  }),
606
- [ToolType.HORIZONTAL_RULE]: createButtonTool({
605
+ [ToolType.HORIZONTAL_RULE]: createTool({
607
606
  name: ToolType.HORIZONTAL_RULE,
608
607
  icon: 'minus',
609
608
  title: 'Вертикальный разделитель',
@@ -614,8 +613,9 @@ export const ToolsMap = {
614
613
  return this.editor.can().setHorizontalRule();
615
614
  }
616
615
  }),
617
- [ToolType.LINK]: createLinkTool({
616
+ [ToolType.LINK]: createTool({
618
617
  name: ToolType.LINK,
618
+ render: Render.LINK,
619
619
  icon: 'link-plus',
620
620
  title: 'Ссылка',
621
621
  getValue() {
@@ -648,7 +648,7 @@ export const ToolsMap = {
648
648
  .run();
649
649
  }
650
650
  }),
651
- [ToolType.BOLD]: createButtonTool({
651
+ [ToolType.BOLD]: createTool({
652
652
  name: ToolType.BOLD,
653
653
  icon: 'format-bold',
654
654
  title: 'Жирный',
@@ -659,7 +659,7 @@ export const ToolsMap = {
659
659
  return this.editor.isActive(MarkType.BOLD);
660
660
  }
661
661
  }),
662
- [ToolType.ITALIC]: createButtonTool({
662
+ [ToolType.ITALIC]: createTool({
663
663
  name: ToolType.ITALIC,
664
664
  icon: 'format-italic',
665
665
  title: 'Курсив',
@@ -670,7 +670,7 @@ export const ToolsMap = {
670
670
  return this.editor.isActive(MarkType.ITALIC);
671
671
  }
672
672
  }),
673
- [ToolType.STRIKE]: createButtonTool({
673
+ [ToolType.STRIKE]: createTool({
674
674
  name: ToolType.STRIKE,
675
675
  icon: 'format-strikethrough-variant',
676
676
  title: 'Зачеркивание',
@@ -681,7 +681,7 @@ export const ToolsMap = {
681
681
  return this.editor.isActive(MarkType.STRIKE);
682
682
  }
683
683
  }),
684
- [ToolType.UNDERLINE]: createButtonTool({
684
+ [ToolType.UNDERLINE]: createTool({
685
685
  name: ToolType.UNDERLINE,
686
686
  icon: 'format-underline',
687
687
  title: 'Подчеркивание',
@@ -692,13 +692,14 @@ export const ToolsMap = {
692
692
  return this.editor.isActive(MarkType.UNDERLINE);
693
693
  }
694
694
  }),
695
- [ToolType.TABLE]: createToolbarPopoverTool({
695
+ [ToolType.TABLE]: createTool({
696
696
  name: ToolType.TABLE,
697
+ render: Render.TOOLBAR_POPOVER,
697
698
  icon: 'table-plus',
698
699
  title: 'таблица',
699
700
  options: Object.values(TableOptionsMap)
700
701
  }),
701
- [ToolType.CLEAR_FORMATTING]: createButtonTool({
702
+ [ToolType.CLEAR_FORMATTING]: createTool({
702
703
  name: ToolType.CLEAR_FORMATTING,
703
704
  icon: 'eraser',
704
705
  title: 'Очистить форматирование',
@@ -1,8 +1,8 @@
1
1
  import { ToolsMap } from './tools-and-commands';
2
2
 
3
3
  /**
4
- * @typedef {import('./WysiwygEditor').ToolDef} Tool
5
- * @typedef {import('./WysiwygEditor').CommandDef} Command
4
+ * @typedef {import('./constants').ToolDef} Tool
5
+ * @typedef {import('./constants').CommandDef} Command
6
6
  * @typedef {Object} ToolGroup
7
7
  * @property {string} title
8
8
  * @property {string[]} group
@@ -13,11 +13,25 @@ import { ToolsMap } from './tools-and-commands';
13
13
  * @return {{title:string, group: Tool[]}[]}
14
14
  */
15
15
  export const buildToolGroups = (toolGroups) => {
16
- const toolsFlattened = new Set(toolGroups.flatMap(({ group }) => group));
17
- const availableTools = Object.values(ToolsMap).filter(({ name }) => toolsFlattened.has(name));
18
- const populateToolsGroup = (tools)=> availableTools.filter(({ name }) => tools.has(name));
16
+ const toolsFlatted = toolGroups.flatMap(({ group }) => group);
17
+ const availableTools = Object
18
+ .values(ToolsMap)
19
+ .filter(({ name: toolName }) => toolsFlatted.some(
20
+ (tool) => typeof tool === 'string' ? toolName === tool : tool?.name === toolName)
21
+ );
19
22
 
20
- return toolGroups.reduce((acc, { title, group }) => [...acc, { title, group: populateToolsGroup(new Set(group)) }], []);
23
+ /**
24
+ * @param {Tool[]} toolsGroup
25
+ * @return Tool[]
26
+ */
27
+ const populateToolsGroup = (toolsGroup) =>
28
+ toolsGroup.reduce((acc, tool) => {
29
+ const { name = tool, ...rest } = typeof tool === 'string' ? {} : tool;
30
+ const foundTool = availableTools.find(({ name: toolName }) => toolName === name);
31
+
32
+ return [...acc, { ...foundTool, ...rest }];
33
+ }, []);
34
+ return toolGroups.reduce((acc, { group, title }) => [...acc, { title, group: populateToolsGroup(group) }], []);
21
35
  };
22
36
 
23
37
  /**
@@ -34,6 +34,11 @@ const Position = {
34
34
  END: 'end',
35
35
  };
36
36
 
37
+ const TriggerOn = {
38
+ MOUSE_MOVE: 'mousemove',
39
+ CLICK: 'click'
40
+ };
41
+
37
42
  const debounce = (func, delay) => {
38
43
  let timeout;
39
44
  return function executedFunction(...args) {
@@ -78,6 +83,7 @@ export {
78
83
  nextId,
79
84
  Key,
80
85
  Position,
86
+ TriggerOn,
81
87
  debounce,
82
88
  useIntersectionObserver,
83
89
  generateGetBoundingClientRect,
@@ -2,7 +2,7 @@ const path = require('path');
2
2
  const { version } = require('./package.json');
3
3
 
4
4
  module.exports = {
5
- components: 'src/components/ui/[A-Z]*.vue',
5
+ components: 'src/components/ui/**/[A-Z]*.vue',
6
6
  require: ['goodt-framework-css'],
7
7
  title: 'UI',
8
8
  version,
@@ -11,6 +11,12 @@ module.exports = {
11
11
  const name = path.basename(componentPath, '.vue');
12
12
  return `import { ${name} } from 'goodteditor-ui';`;
13
13
  },
14
+ ignore: [
15
+ 'src/components/ui/ColorPicker/**',
16
+ 'src/components/ui/utils/**',
17
+ 'src/components/ui/WysiwygEditor/extensions/**',
18
+ 'src/components/ui/WysiwygEditor/renders/**',
19
+ ],
14
20
  template: {
15
21
  head: {
16
22
  links: [