tiptapify 0.0.5 → 0.0.6

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.
@@ -1,11 +1,12 @@
1
- import { computed, ComputedRef, Ref, ref } from "vue";
2
- import * as mdi from '@mdi/js'
3
- import { fonts } from './fonts'
4
-
5
- interface MDIIcons {
6
- [key: string]: string
7
- }
8
- const mdiIcons = mdi as MDIIcons
1
+ import { getActionsItems } from "@tiptapify/components/Toolbar/items/actions";
2
+ import { getAlignmentItems } from "@tiptapify/components/Toolbar/items/alignment";
3
+ import { getFormatExtraItems } from "@tiptapify/components/Toolbar/items/formatExtra";
4
+ import { getFormatItems } from "@tiptapify/components/Toolbar/items/format";
5
+ import { getListItems } from "@tiptapify/components/Toolbar/items/list";
6
+ import { getMediaItems } from "@tiptapify/components/Toolbar/items/media";
7
+ import { getMiscItems } from "@tiptapify/components/Toolbar/items/misc";
8
+ import { getStyleItems } from "@tiptapify/components/Toolbar/items/style";
9
+ import { ComputedRef, Ref, ref } from "vue";
9
10
 
10
11
  interface ToolbarItemAttrs {
11
12
  [key: string]: Function | any
@@ -15,26 +16,32 @@ interface ToolbarItemProps {
15
16
  [key: string]: any
16
17
  }
17
18
 
18
- interface ToolbarItem {
19
+ export interface ToolbarItem {
19
20
  name: string|number,
20
21
  tooltip: string,
21
22
  icon: string|ComputedRef<string>,
22
23
  noI18n?: boolean,
23
24
  enabled: boolean,
24
25
  modelValue?: any,
25
- section?: string,
26
26
  group?: boolean,
27
+ toggle?: boolean,
27
28
  props?: ToolbarItemProps,
28
29
  attrs?: ToolbarItemAttrs,
29
- children?: ToolbarItem[],
30
+ children?: ToolbarItems|ToolbarItem[],
30
31
  }
31
32
 
32
33
  export interface ToolbarItems {
33
34
  [key: string]: ToolbarItem
34
35
  }
35
36
 
37
+ export interface ToolbarItemSection {
38
+ group?: boolean,
39
+ toggle?: boolean,
40
+ items: ToolbarItems,
41
+ }
42
+
36
43
  export interface ToolbarItemSections {
37
- [key: string]: ToolbarItems
44
+ [key: string]: ToolbarItemSection
38
45
  }
39
46
 
40
47
  export function toolbarItems(
@@ -44,22 +51,16 @@ export function toolbarItems(
44
51
  customHeadingLevels: Array<number>,
45
52
  toolbarLinkButton: Ref,
46
53
  ): ToolbarItemSections {
47
- const headingLevels = ref([1, 2, 3, 4, 5, 6])
48
- if (customHeadingLevels.length) {
49
- customHeadingLevels.forEach(level => {
50
- if (level <= 0 || level > 6) {
51
- throw new Error('customHeadingLevels must be between 1 and 6')
52
- }
53
- })
54
-
55
- headingLevels.value = customHeadingLevels
56
- }
57
-
58
- const fontSizes = [6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 32, 48, 64, 96]
59
-
60
- const lineHeights = [1, 1.5, 2, 3, 4]
61
-
62
- const allMenuItems: ToolbarItems = {
54
+ const styleItems = ref(getStyleItems(editor.value, fontMeasure, customHeadingLevels))
55
+ const formatItems = ref(getFormatItems(editor.value))
56
+ const formatExtraItems = ref(getFormatExtraItems(editor.value))
57
+ const alignmentItems = ref(getAlignmentItems(editor.value))
58
+ const listItems = ref(getListItems(editor.value))
59
+ const actionsItems = ref(getActionsItems(editor.value))
60
+ const miscItems = ref(getMiscItems(editor.value))
61
+ const mediaItems = ref(getMediaItems(editor.value, toolbarLinkButton))
62
+
63
+ const allMenuItems: ToolbarItemSections = {
63
64
  /**
64
65
  * todo
65
66
  *
@@ -67,505 +68,20 @@ export function toolbarItems(
67
68
  * tables
68
69
  * media (image, video)
69
70
  */
70
- heading: {
71
- name: 'heading',
72
- tooltip: 'style.heading',
73
- icon: mdi.mdiFormatHeaderPound,
74
- section: 'style',
75
- modelValue: null,
76
- enabled: true,
77
- attrs: {
78
- click: () => editor.value.chain().focus().setParagraph().run()
79
- },
80
- props: {
81
- color: computed(() => editor.value.isActive('heading') ? 'primary' : ''),
82
- },
83
- children: [
84
- {
85
- name: `paragraph`,
86
- tooltip: `style.paragraph`,
87
- icon: mdiIcons[`mdiFormatParagraph`],
88
- noI18n: true,
89
- enabled: true,
90
- props: {
91
- color: computed(() => {
92
- return editor.value.isActive('paragraph') ? 'primary' : ''
93
- }),
94
- },
95
- attrs: {
96
- click: () => editor.value.chain().focus().setParagraph().run()
97
- }
98
- }
99
- ].concat(
100
- headingLevels.value.map(level => {
101
- return {
102
- name: `H${level}`,
103
- tooltip: `style.headings.h${level}`,
104
- icon: mdiIcons[`mdiFormatHeader${level}`],
105
- noI18n: true,
106
- enabled: true,
107
- props: {
108
- color: computed(() => {
109
- return editor.value.isActive('heading', { level }) ? 'primary' : ''
110
- }),
111
- },
112
- attrs: {
113
- click: () => editor.value.chain().focus().toggleHeading({ level }).run()
114
- }
115
- }
116
- })
117
- )
118
- },
119
- fontFamily: {
120
- name: 'font-family',
121
- tooltip: 'style.fontFamily',
122
- icon: mdi.mdiFormatFont,
123
- section: 'style',
124
- modelValue: null,
125
- enabled: true,
126
- attrs: {
127
- click: () => editor.value.chain().focus().unsetFontFamily().run()
128
- },
129
- children: fonts.map((font) => {
130
- return {
131
- name: font.name,
132
- tooltip: '',
133
- icon: '',
134
- enabled: true,
135
- noI18n: true,
136
- props: {
137
- color: computed(() => editor.value.isActive('textStyle', { fontFamily: font.fontFamily }) ? 'primary' : ''),
138
- style: `font-family: ${font.fontFamily};`
139
- },
140
- attrs: {
141
- click: () => editor.value.chain().focus().setFontFamily(font.fontFamily).run()
142
- }
143
- }
144
- })
145
- },
146
- fontSize: {
147
- name: 'font-size',
148
- tooltip: 'style.fontSize',
149
- icon: mdi.mdiFormatSize,
150
- section: 'style',
151
- modelValue: computed(() => editor.value.getAttributes('textStyle').fontSize || null),
152
- enabled: true,
153
- attrs: {
154
- click: () => editor.value.chain().focus().unsetFontSize().run()
155
- },
156
- children: fontSizes.map((fontSize) => {
157
- return {
158
- name: `${fontSize}${fontMeasure}`,
159
- tooltip: '',
160
- icon: '',
161
- enabled: true,
162
- noI18n: true,
163
- props: {
164
- color: computed(() => editor.value.isActive('textStyle', { fontSizes: fontSize }) ? 'primary' : ''),
165
- },
166
- attrs: {
167
- click: () => editor.value.chain().focus().setFontSize(`${fontSize}${fontMeasure}`).run()
168
- }
169
- }
170
- })
171
- },
172
- lineHeight: {
173
- name: 'line-height',
174
- tooltip: 'style.lineHeight',
175
- icon: mdi.mdiFormatLineHeight,
176
- section: 'style',
177
- modelValue: null,
178
- enabled: true,
179
- attrs: {
180
- click: () => editor.value.chain().focus().unsetLineHeight().run()
181
- },
182
- children: lineHeights.map((lineHeight) => {
183
- return {
184
- name: lineHeight,
185
- tooltip: '',
186
- icon: '',
187
- enabled: true,
188
- noI18n: true,
189
- props: {
190
- color: computed(() => editor.value.isActive('textStyle', { lineHeights: lineHeight }) ? 'primary' : ''),
191
- },
192
- attrs: {
193
- click: () => editor.value.chain().focus().setLineHeight(lineHeight).run()
194
- }
195
- }
196
- })
197
- },
198
-
199
- bold: {
200
- name: 'bold',
201
- tooltip: 'format.bold',
202
- icon: mdi.mdiFormatBold,
203
- section: 'format',
204
- enabled: true,
205
- props: {
206
- disabled: computed(() => !editor.value.can().chain().focus().toggleBold().run()),
207
- color: computed(() => editor.value.isActive('bold') ? 'primary' : ''),
208
- },
209
- attrs: {
210
- click: () => editor.value.chain().focus().toggleBold().run()
211
- }
212
- },
213
- italic: {
214
- name: 'italic',
215
- tooltip: 'format.italic',
216
- icon: mdi.mdiFormatItalic,
217
- section: 'format',
218
- enabled: true,
219
- props: {
220
- disabled: computed(() => !editor.value.can().chain().focus().toggleItalic().run()),
221
- color: computed(() => editor.value.isActive('italic') ? 'primary' : ''),
222
- },
223
- attrs: {
224
- click: () => editor.value.chain().focus().toggleItalic().run()
225
- }
226
- },
227
- strike: {
228
- name: 'strike',
229
- tooltip: 'format.strike',
230
- icon: mdi.mdiFormatStrikethroughVariant,
231
- section: 'format',
232
- enabled: true,
233
- props: {
234
- disabled: computed(() => !editor.value.can().chain().focus().toggleStrike().run()),
235
- color: computed(() => editor.value.isActive('strike') ? 'primary' : ''),
236
- },
237
- attrs: {
238
- click: () => editor.value.chain().focus().toggleStrike().run()
239
- }
240
- },
241
- underline: {
242
- name: 'underline',
243
- tooltip: 'format.underline',
244
- icon: mdi.mdiFormatUnderline,
245
- section: 'format',
246
- enabled: true,
247
- props: {
248
- disabled: computed(() => !editor.value.can().chain().focus().toggleUnderline().run()),
249
- color: computed(() => editor.value.isActive('underline') ? 'primary' : ''),
250
- },
251
- attrs: {
252
- click: () => editor.value.chain().focus().toggleUnderline().run()
253
- }
254
- },
255
- highlight: {
256
- name: 'highlight',
257
- tooltip: 'format.highlight',
258
- icon: mdi.mdiMarker,
259
- section: 'format',
260
- enabled: true,
261
- props: {
262
- disabled: computed(() => !editor.value.can().chain().focus().toggleHighlight().run()),
263
- color: computed(() => editor.value.isActive('highlight') ? 'primary' : ''),
264
- },
265
- attrs: {
266
- click: () => editor.value.chain().focus().toggleHighlight().run()
267
- }
268
- },
269
- formatClear: {
270
- name: 'format clear',
271
- tooltip: 'format.formatClear',
272
- icon: mdi.mdiFormatClear,
273
- section: 'format',
274
- enabled: true,
275
- props: {
276
- disabled: computed(() => !editor.value.can().chain().focus().unsetAllMarks().run()),
277
- },
278
- attrs: {
279
- click: () => editor.value.chain().focus().unsetAllMarks().clearNodes().run()
280
- }
281
- },
282
-
283
- code: {
284
- name: 'code',
285
- tooltip: 'format.code',
286
- icon: mdi.mdiXml,
287
- section: 'format_extra',
288
- enabled: true,
289
- props: {
290
- disabled: computed(() => !editor.value.can().chain().focus().toggleCode().run()),
291
- color: computed(() => editor.value.isActive('code') ? 'primary' : ''),
292
- },
293
- attrs: {
294
- click: () => editor.value.chain().focus().toggleCode().run()
295
- }
296
- },
297
- codeBlock: {
298
- name: 'codeblock',
299
- tooltip: 'format.codeblock',
300
- icon: mdi.mdiCodeBlockTags,
301
- section: 'format_extra',
302
- enabled: true,
303
- props: {
304
- disabled: computed(() => !editor.value.can().chain().focus().toggleCodeBlock().run()),
305
- color: computed(() => editor.value.isActive('codeBlock') ? 'primary' : ''),
306
- },
307
- attrs: {
308
- click: () => editor.value.chain().focus().toggleCodeBlock().run()
309
- }
310
- },
311
- blockquote: {
312
- name: 'blockquote',
313
- tooltip: 'format.blockquote',
314
- icon: mdi.mdiCommentQuote,
315
- section: 'format_extra',
316
- enabled: true,
317
- props: {
318
- disabled: computed(() => !editor.value.can().chain().focus().toggleBlockquote().run()),
319
- color: computed(() => editor.value.isActive('blockquote') ? 'primary' : ''),
320
- },
321
- attrs: {
322
- click: () => editor.value.chain().focus().toggleBlockquote().run()
323
- }
324
- },
325
-
326
- sup: {
327
- name: 'sup',
328
- tooltip: 'format.sup',
329
- icon: mdi.mdiFormatSuperscript,
330
- enabled: true,
331
- props: {
332
- disabled: computed(() => !editor.value.can().chain().focus().toggleSuperscript().run()),
333
- color: computed(() => editor.value.isActive('superscript') ? 'primary' : ''),
334
- },
335
- attrs: {
336
- click: () => editor.value.chain().focus().toggleSuperscript().run()
337
- }
338
- },
339
- sub: {
340
- name: 'sub',
341
- tooltip: 'format.sub',
342
- icon: mdi.mdiFormatSubscript,
343
- enabled: true,
344
- props: {
345
- disabled: computed(() => !editor.value.can().chain().focus().toggleSubscript().run()),
346
- color: computed(() => editor.value.isActive('subscript') ? 'primary' : ''),
347
- },
348
- attrs: {
349
- click: () => editor.value.chain().focus().toggleSubscript().run()
350
- }
351
- },
352
-
353
- alignment: {
354
- name: 'alignment',
355
- tooltip: 'alignment',
356
- icon: '',
357
- section: 'alignment',
358
- enabled: true,
359
- group: true,
360
- children: [
361
- {
362
- name: 'alignments.left',
363
- tooltip: 'alignments.left',
364
- icon: mdi.mdiFormatAlignLeft,
365
- enabled: true,
366
- props: {
367
- color: computed(() => editor.value.isActive('text-align', { align: 'left' }) ? 'primary' : ''),
368
- },
369
- attrs: {
370
- click: () => editor.value.chain().focus().toggleTextAlign('left').run()
371
- }
372
- },
373
- {
374
- name: 'alignments.center',
375
- tooltip: 'alignments.center',
376
- icon: mdi.mdiFormatAlignCenter,
377
- enabled: true,
378
- props: {
379
- color: computed(() => editor.value.isActive('text-align', { align: 'center' }) ? 'primary' : ''),
380
- },
381
- attrs: {
382
- click: () => editor.value.chain().focus().toggleTextAlign('center').run()
383
- }
384
- },
385
- {
386
- name: 'alignments.right',
387
- tooltip: 'alignments.right',
388
- icon: mdi.mdiFormatAlignRight,
389
- enabled: true,
390
- props: {
391
- color: computed(() => editor.value.isActive('text-align', { align: 'right' }) ? 'primary' : ''),
392
- },
393
- attrs: {
394
- click: () => editor.value.chain().focus().toggleTextAlign('right').run()
395
- }
396
- },
397
- {
398
- name: 'alignments.justify',
399
- tooltip: 'alignments.justify',
400
- icon: mdi.mdiFormatAlignJustify,
401
- enabled: true,
402
- props: {
403
- color: computed(() => editor.value.isActive('text-align', { align: 'justify' }) ? 'primary' : ''),
404
- },
405
- attrs: {
406
- click: () => editor.value.chain().focus().toggleTextAlign('justify').run()
407
- }
408
- },
409
- ]
410
- },
411
-
412
- list: {
413
- name: 'list',
414
- tooltip: 'list',
415
- icon: mdi.mdiFormatListGroup,
416
- section: 'list',
417
- enabled: true,
418
- group: true,
419
- children: [
420
- {
421
- name: 'lists.bullet',
422
- tooltip: 'lists.bullet',
423
- icon: mdi.mdiFormatListBulleted,
424
- enabled: true,
425
- props: {
426
- color: computed(() => editor.value.isActive('bulletList') ? 'primary' : ''),
427
- },
428
- attrs: {
429
- click: () => editor.value.chain().focus().toggleBulletList().run()
430
- }
431
- },
432
- {
433
- name: 'lists.numbered',
434
- tooltip: 'lists.numbered',
435
- icon: mdi.mdiFormatListNumbered,
436
- enabled: true,
437
- props: {
438
- color: computed(() => editor.value.isActive('orderedList') ? 'primary' : ''),
439
- },
440
- attrs: {
441
- click: () => editor.value.chain().focus().toggleOrderedList().run()
442
- }
443
- },
444
- {
445
- name: 'lists.task',
446
- tooltip: 'lists.task',
447
- icon: mdi.mdiFormatListChecks,
448
- enabled: true,
449
- props: {
450
- color: computed(() => editor.value.isActive('taskList') ? 'primary' : ''),
451
- },
452
- attrs: {
453
- click: () => editor.value.chain().focus().toggleTaskList().run()
454
- }
455
- },
456
- {
457
- name: 'lists.indent',
458
- tooltip: 'lists.indent',
459
- icon: mdi.mdiFormatIndentIncrease,
460
- enabled: true,
461
- props: {
462
- disabled: computed(() => !editor.value.can().sinkListItem('listItem')),
463
- active: false,
464
- },
465
- attrs: {
466
- click: () => editor.value.chain().focus().sinkListItem('listItem').run()
467
- }
468
- },
469
- {
470
- name: 'lists.outdent',
471
- tooltip: 'lists.outdent',
472
- icon: mdi.mdiFormatIndentDecrease,
473
- enabled: true,
474
- props: {
475
- disabled: computed(() => !editor.value.can().liftListItem('listItem')),
476
- active: false,
477
- },
478
- attrs: {
479
- click: () => editor.value.chain().focus().liftListItem('listItem').run()
480
- }
481
- },
482
- ]
483
- },
484
-
485
- link: {
486
- name: 'format.link',
487
- tooltip: 'format.link',
488
- icon: computed(() => editor.value.isActive('link') ? mdi.mdiLinkOff : mdi.mdiLink),
489
- section: 'media',
490
- enabled: true,
491
- props: {
492
- color: computed(() => editor.value.isActive('link') ? 'primary' : ''),
493
- disabled: computed(() => editor.value.isActive('code') || editor.value.isActive('codeBlock')),
494
- },
495
- attrs: {
496
- click: computed(() => {
497
- return editor.value.isActive('link')
498
- ? editor.value.chain().focus().unsetLink().run
499
- : toolbarLinkButton.value?.open
500
- })
501
- }
502
- },
503
-
504
- undo: {
505
- name: 'undo',
506
- tooltip: 'action.undo',
507
- icon: mdi.mdiUndo,
508
- section: 'actions',
509
- enabled: true,
510
- props: {
511
- disabled: computed(() => !editor.value.can().chain().focus().undo().run()),
512
- },
513
- attrs: {
514
- click: () => editor.value.chain().focus().undo().run()
515
- }
516
- },
517
- redo: {
518
- name: 'redo',
519
- tooltip: 'action.redo',
520
- icon: mdi.mdiRedo,
521
- section: 'actions',
522
- enabled: true,
523
- props: {
524
- disabled: computed(() => !editor.value.can().chain().focus().redo().run()),
525
- },
526
- attrs: {
527
- click: () => editor.value.chain().focus().redo().run()
528
- }
529
- },
530
-
531
- line: {
532
- name: 'line',
533
- tooltip: 'format.line',
534
- icon: mdi.mdiMinus,
535
- section: 'misc',
536
- enabled: true,
537
- props: {},
538
- attrs: {
539
- click: () => editor.value.chain().focus().setHorizontalRule().run()
540
- }
541
- },
542
- break: {
543
- name: 'break',
544
- tooltip: 'format.break',
545
- icon: mdi.mdiFormatPageBreak,
546
- section: 'misc',
547
- enabled: true,
548
- props: {},
549
- attrs: {
550
- click: () => editor.value.chain().focus().setHardBreak().run()
551
- }
552
- },
553
- source: {
554
- name: 'source',
555
- tooltip: 'misc.source',
556
- icon: mdi.mdiCodeTags,
557
- section: 'misc',
558
- enabled: true,
559
- props: {},
560
- attrs: {
561
- click: () => editor.value.commands.showSource()
562
- }
563
- },
71
+ style: { group: true, items: styleItems.value },
72
+ format: { group: true, items: formatItems.value },
73
+ format_extra: { group: true, items: formatExtraItems.value },
74
+ media: { group: true, items: mediaItems.value },
75
+ alignment: { toggle: true, items: alignmentItems.value },
76
+ list: { group: true, items: listItems.value },
77
+ actions: { group: true, items: actionsItems.value },
78
+ misc: { group: true, items: miscItems.value },
564
79
  }
565
80
 
566
-
567
-
568
- const pluginsList = Object.keys(allMenuItems)
81
+ const pluginsList: Array<string> = []
82
+ Object.keys(allMenuItems).forEach(section => {
83
+ Object.keys(allMenuItems[section]).forEach(item => pluginsList.push(item))
84
+ })
569
85
 
570
86
  if (items.list.length) {
571
87
  items.list.forEach(item => {
@@ -575,31 +91,42 @@ export function toolbarItems(
575
91
  })
576
92
  }
577
93
 
94
+ const toolbarItems: ToolbarItemSections = {}
95
+
578
96
  const sections = {}
579
- const toolbarItems: { [key: string]: ToolbarItems } = {}
580
- pluginsList.forEach(key => {
581
- const item = allMenuItems[key]
582
97
 
583
- if (items.list.length) {
584
- item.enabled = items.list.includes(key)
585
- if (items.exclude) {
586
- item.enabled = !item.enabled
98
+ Object.keys(allMenuItems).forEach(sectionName => {
99
+ const section = allMenuItems[sectionName]
100
+ Object.keys(section.items).forEach(plugin => {
101
+ const item = section.items[plugin]
102
+
103
+ if (items.list.length) {
104
+ item.enabled = items.list.includes(plugin)
105
+ if (items.exclude) {
106
+ item.enabled = !item.enabled
107
+ }
587
108
  }
588
- }
589
- const section = item.section ?? 'misc'
590
- if (typeof toolbarItems[section] === 'undefined') {
591
- sections[section] = 0
592
- toolbarItems[section] = {}
593
- }
594
- toolbarItems[section][key] = allMenuItems[key]
595
- if (allMenuItems[key].enabled) {
596
- sections[section]++
597
- }
109
+
110
+ if (typeof toolbarItems[sectionName] === 'undefined') {
111
+ sections[sectionName] = 0
112
+ toolbarItems[sectionName] = {
113
+ group: section.group ?? false,
114
+ toggle: section.toggle ?? false,
115
+ items: {},
116
+ }
117
+ }
118
+
119
+ toolbarItems[sectionName].items[plugin] = item
120
+
121
+ if (item.enabled) {
122
+ sections[sectionName]++
123
+ }
124
+ })
598
125
  })
599
126
 
600
- Object.keys(sections).forEach(key => {
601
- if (sections[key] === 0) {
602
- delete toolbarItems[key]
127
+ Object.keys(sections).forEach(sectionName => {
128
+ if (sections[sectionName] === 0) {
129
+ delete toolbarItems[sectionName]
603
130
  }
604
131
  })
605
132