tiptapify 0.0.9 → 0.0.11

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 (52) hide show
  1. package/README.md +1 -1
  2. package/dist/tiptapify.css +1 -1
  3. package/dist/tiptapify.mjs +21133 -19765
  4. package/dist/tiptapify.umd.js +37 -38
  5. package/package.json +43 -43
  6. package/src/components/Tiptapify.vue +2 -2
  7. package/src/components/Toolbar/GroupBtn.vue +2 -6
  8. package/src/components/Toolbar/GroupDropdown.vue +4 -8
  9. package/src/components/Toolbar/Index.vue +5 -4
  10. package/src/components/Toolbar/Items.vue +2 -2
  11. package/src/components/Toolbar/Toggle.vue +2 -2
  12. package/src/components/Toolbar/items.ts +20 -20
  13. package/src/components/UI/Dialog.vue +141 -0
  14. package/src/components/editorExtensions.ts +1 -1
  15. package/src/{components/Toolbar/items/actions.ts → composables/Toolbar/useActionsItems.ts} +6 -3
  16. package/src/{components/Toolbar/items/alignment.ts → composables/Toolbar/useAlignmentItems.ts} +12 -9
  17. package/src/{components/Toolbar/items/formatExtra.ts → composables/Toolbar/useFormatExtraItems.ts} +10 -7
  18. package/src/{components/Toolbar/items/format.ts → composables/Toolbar/useFormatItems.ts} +20 -17
  19. package/src/{components/Toolbar/items/list.ts → composables/Toolbar/useListItems.ts} +14 -11
  20. package/src/{components/Toolbar/items/media.ts → composables/Toolbar/useMediaItems.ts} +22 -20
  21. package/src/{components/Toolbar/items/misc.ts → composables/Toolbar/useMiscItems.ts} +9 -6
  22. package/src/composables/Toolbar/useStyleItems.ts +231 -0
  23. package/src/{components/Toolbar/fonts.ts → constants/style.ts} +21 -0
  24. package/src/extensions/components/FontFamily.vue +82 -0
  25. package/src/extensions/components/FontSize.vue +83 -0
  26. package/src/extensions/components/ImageDialog.vue +17 -29
  27. package/src/extensions/components/LineHeight.vue +82 -0
  28. package/src/extensions/components/LinkDialog.vue +75 -44
  29. package/src/extensions/components/PreviewDialog.vue +8 -16
  30. package/src/extensions/components/ShowSourceDialog.vue +17 -18
  31. package/src/extensions/components/StyleColor.vue +68 -15
  32. package/src/extensions/components/TableBuilder.vue +3 -6
  33. package/src/extensions/link.ts +8 -0
  34. package/src/extensions/slash-commands.ts +1 -1
  35. package/src/i18n/index.ts +0 -1
  36. package/src/i18n/locales/ch.json +119 -0
  37. package/src/i18n/locales/cz.json +119 -0
  38. package/src/i18n/locales/de.json +83 -76
  39. package/src/i18n/locales/en.json +82 -75
  40. package/src/i18n/locales/es.json +80 -73
  41. package/src/i18n/locales/fr.json +81 -73
  42. package/src/i18n/locales/it.json +80 -73
  43. package/src/i18n/locales/la.json +119 -0
  44. package/src/i18n/locales/lt.json +119 -0
  45. package/src/i18n/locales/nl.json +119 -0
  46. package/src/i18n/locales/pl.json +80 -74
  47. package/src/i18n/locales/pt.json +119 -0
  48. package/src/i18n/locales/ru.json +78 -71
  49. package/src/i18n/locales/se.json +119 -0
  50. package/src/i18n/locales/ua.json +79 -72
  51. package/src/components/Toolbar/items/style.ts +0 -187
  52. /package/src/{components → extensions/components}/CodeBlockComponent.vue +0 -0
@@ -1,12 +1,15 @@
1
1
  import * as mdi from "@mdi/js";
2
2
  import { Editor } from "@tiptap/vue-3";
3
3
  import { computed } from "vue";
4
+ import { useI18n } from "vue-i18n";
5
+
6
+ export function useFormatItems(editor: Editor) {
7
+ const { t } = useI18n();
4
8
 
5
- export function getFormatItems(editor: Editor) {
6
9
  return {
7
10
  bold: {
8
11
  name: 'bold',
9
- tooltip: 'format.bold',
12
+ tooltip: computed(() => t('format.bold')),
10
13
  icon: mdi.mdiFormatBold,
11
14
  enabled: true,
12
15
  props: {
@@ -19,7 +22,7 @@ export function getFormatItems(editor: Editor) {
19
22
  },
20
23
  italic: {
21
24
  name: 'italic',
22
- tooltip: 'format.italic',
25
+ tooltip: computed(() => t('format.italic')),
23
26
  icon: mdi.mdiFormatItalic,
24
27
  enabled: true,
25
28
  props: {
@@ -30,22 +33,9 @@ export function getFormatItems(editor: Editor) {
30
33
  click: () => editor.chain().focus().toggleItalic().run()
31
34
  }
32
35
  },
33
- strike: {
34
- name: 'strike',
35
- tooltip: 'format.strike',
36
- icon: mdi.mdiFormatStrikethroughVariant,
37
- enabled: true,
38
- props: {
39
- disabled: computed(() => !editor.can().chain().focus().toggleStrike().run()),
40
- color: computed(() => editor.isActive('strike') ? 'primary' : ''),
41
- },
42
- attrs: {
43
- click: () => editor.chain().focus().toggleStrike().run()
44
- }
45
- },
46
36
  underline: {
47
37
  name: 'underline',
48
- tooltip: 'format.underline',
38
+ tooltip: computed(() => t('format.underline')),
49
39
  icon: mdi.mdiFormatUnderline,
50
40
  enabled: true,
51
41
  props: {
@@ -55,6 +45,19 @@ export function getFormatItems(editor: Editor) {
55
45
  attrs: {
56
46
  click: () => editor.chain().focus().toggleUnderline().run()
57
47
  }
48
+ },
49
+ strike: {
50
+ name: 'strike',
51
+ tooltip: computed(() => t('format.strike')),
52
+ icon: mdi.mdiFormatStrikethroughVariant,
53
+ enabled: true,
54
+ props: {
55
+ disabled: computed(() => !editor.can().chain().focus().toggleStrike().run()),
56
+ color: computed(() => editor.isActive('strike') ? 'primary' : ''),
57
+ },
58
+ attrs: {
59
+ click: () => editor.chain().focus().toggleStrike().run()
60
+ }
58
61
  }
59
62
  }
60
63
  }
@@ -1,12 +1,15 @@
1
1
  import * as mdi from "@mdi/js";
2
2
  import { Editor } from "@tiptap/vue-3";
3
3
  import { computed } from "vue";
4
+ import { useI18n } from "vue-i18n";
5
+
6
+ export function useListItems(editor: Editor) {
7
+ const { t } = useI18n();
4
8
 
5
- export function getListItems(editor: Editor) {
6
9
  return {
7
10
  listBullet: {
8
- name: 'lists.bullet',
9
- tooltip: 'lists.bullet',
11
+ name: computed(() => t('lists.bullet')),
12
+ tooltip: computed(() => t('lists.bullet')),
10
13
  icon: mdi.mdiFormatListBulleted,
11
14
  enabled: true,
12
15
  props: {
@@ -17,8 +20,8 @@ export function getListItems(editor: Editor) {
17
20
  }
18
21
  },
19
22
  listNumbered: {
20
- name: 'lists.numbered',
21
- tooltip: 'lists.numbered',
23
+ name: computed(() => t('lists.numbered')),
24
+ tooltip: computed(() => t('lists.numbered')),
22
25
  icon: mdi.mdiFormatListNumbered,
23
26
  enabled: true,
24
27
  props: {
@@ -29,8 +32,8 @@ export function getListItems(editor: Editor) {
29
32
  }
30
33
  },
31
34
  listTask: {
32
- name: 'lists.task',
33
- tooltip: 'lists.task',
35
+ name: computed(() => t('lists.task')),
36
+ tooltip: computed(() => t('lists.task')),
34
37
  icon: mdi.mdiFormatListChecks,
35
38
  enabled: true,
36
39
  props: {
@@ -41,8 +44,8 @@ export function getListItems(editor: Editor) {
41
44
  }
42
45
  },
43
46
  listIndent: {
44
- name: 'lists.indent',
45
- tooltip: 'lists.indent',
47
+ name: computed(() => t('lists.indent')),
48
+ tooltip: computed(() => t('lists.indent')),
46
49
  icon: mdi.mdiFormatIndentIncrease,
47
50
  enabled: true,
48
51
  props: {
@@ -54,8 +57,8 @@ export function getListItems(editor: Editor) {
54
57
  }
55
58
  },
56
59
  listOutdent: {
57
- name: 'lists.outdent',
58
- tooltip: 'lists.outdent',
60
+ name: computed(() => t('lists.outdent')),
61
+ tooltip: computed(() => t('lists.outdent')),
59
62
  icon: mdi.mdiFormatIndentDecrease,
60
63
  enabled: true,
61
64
  props: {
@@ -2,16 +2,18 @@ import * as mdi from "@mdi/js";
2
2
  import { Editor } from "@tiptap/vue-3";
3
3
  import TableBuilder from "@tiptapify/extensions/components/TableBuilder.vue";
4
4
  import { computed, markRaw } from "vue";
5
+ import { useI18n } from "vue-i18n";
5
6
 
6
- export function getMediaItems(editor: Editor) {
7
+ export function useMediaItems(editor: Editor) {
8
+ const { t } = useI18n();
7
9
  return {
8
10
  link: {
9
- name: 'media.link',
10
- tooltip: 'media.link',
11
- icon: computed(() => editor.isActive('link') ? mdi.mdiLinkOff : mdi.mdiLink),
11
+ name: computed(() => t('media.link')),
12
+ tooltip: computed(() => t('media.link')),
13
+ icon: computed(() => editor.isActive('tiptapifyLink') ? mdi.mdiLinkOff : mdi.mdiLink),
12
14
  enabled: true,
13
15
  props: {
14
- color: computed(() => editor.isActive('link') ? 'primary' : ''),
16
+ color: computed(() => editor.isActive('tiptapifyLink') ? 'primary' : ''),
15
17
  disabled: computed(() => editor.isActive('code') || editor.isActive('codeBlock')),
16
18
  },
17
19
  attrs: {
@@ -19,8 +21,8 @@ export function getMediaItems(editor: Editor) {
19
21
  }
20
22
  },
21
23
  image: {
22
- name: 'media.image',
23
- tooltip: 'media.image',
24
+ name: computed(() => t('media.image')),
25
+ tooltip: computed(() => t('media.image')),
24
26
  icon: mdi.mdiImage,
25
27
  enabled: true,
26
28
  props: {
@@ -33,7 +35,7 @@ export function getMediaItems(editor: Editor) {
33
35
  },
34
36
  table: {
35
37
  name: 'tables',
36
- tooltip: 'media.tables.table',
38
+ tooltip: computed(() => t('media.tables.table')),
37
39
  icon: mdi.mdiTable,
38
40
  modelValue: false,
39
41
  enabled: true,
@@ -44,7 +46,7 @@ export function getMediaItems(editor: Editor) {
44
46
  children: [
45
47
  {
46
48
  name: 'insert table',
47
- tooltip: 'media.tables.insertTable',
49
+ tooltip: computed(() => t('media.tables.insertTable')),
48
50
  icon: mdi.mdiTablePlus,
49
51
  enabled: true,
50
52
  props: {
@@ -59,7 +61,7 @@ export function getMediaItems(editor: Editor) {
59
61
  },
60
62
  {
61
63
  name: 'delete table',
62
- tooltip: 'media.tables.deleteTable',
64
+ tooltip: computed(() => t('media.tables.deleteTable')),
63
65
  icon: mdi.mdiTableMinus,
64
66
  enabled: true,
65
67
  props: {
@@ -71,7 +73,7 @@ export function getMediaItems(editor: Editor) {
71
73
  },
72
74
  {
73
75
  name: 'table row',
74
- tooltip: 'media.tables.row',
76
+ tooltip: computed(() => t('media.tables.row')),
75
77
  icon: mdi.mdiTableRow,
76
78
  enabled: true,
77
79
  props: {
@@ -89,7 +91,7 @@ export function getMediaItems(editor: Editor) {
89
91
  children: [
90
92
  {
91
93
  name: 'insert row before',
92
- tooltip: 'media.tables.insertRowBefore',
94
+ tooltip: computed(() => t('media.tables.insertRowBefore')),
93
95
  icon: mdi.mdiTableRowPlusBefore,
94
96
  enabled: true,
95
97
  props: {
@@ -101,7 +103,7 @@ export function getMediaItems(editor: Editor) {
101
103
  },
102
104
  {
103
105
  name: 'insert row after',
104
- tooltip: 'media.tables.insertRowAfter',
106
+ tooltip: computed(() => t('media.tables.insertRowAfter')),
105
107
  icon: mdi.mdiTableRowPlusAfter,
106
108
  enabled: true,
107
109
  props: {
@@ -113,7 +115,7 @@ export function getMediaItems(editor: Editor) {
113
115
  },
114
116
  {
115
117
  name: 'delete row',
116
- tooltip: 'media.tables.deleteRow',
118
+ tooltip: computed(() => t('media.tables.deleteRow')),
117
119
  icon: mdi.mdiTableRowRemove,
118
120
  enabled: true,
119
121
  props: {
@@ -127,7 +129,7 @@ export function getMediaItems(editor: Editor) {
127
129
  },
128
130
  {
129
131
  name: 'column',
130
- tooltip: 'media.tables.col',
132
+ tooltip: computed(() => t('media.tables.col')),
131
133
  icon: mdi.mdiTableColumn,
132
134
  enabled: true,
133
135
  props: {
@@ -145,7 +147,7 @@ export function getMediaItems(editor: Editor) {
145
147
  children: [
146
148
  {
147
149
  name: 'insert col before',
148
- tooltip: 'media.tables.insertColBefore',
150
+ tooltip: computed(() => t('media.tables.insertColBefore')),
149
151
  icon: mdi.mdiTableColumnPlusBefore,
150
152
  enabled: true,
151
153
  props: {
@@ -157,7 +159,7 @@ export function getMediaItems(editor: Editor) {
157
159
  },
158
160
  {
159
161
  name: 'insert column after',
160
- tooltip: 'media.tables.insertColAfter',
162
+ tooltip: computed(() => t('media.tables.insertColAfter')),
161
163
  icon: mdi.mdiTableColumnPlusAfter,
162
164
  enabled: true,
163
165
  props: {
@@ -169,7 +171,7 @@ export function getMediaItems(editor: Editor) {
169
171
  },
170
172
  {
171
173
  name: 'delete column',
172
- tooltip: 'media.tables.deleteCol',
174
+ tooltip: computed(() => t('media.tables.deleteCol')),
173
175
  icon: mdi.mdiTableColumnRemove,
174
176
  enabled: true,
175
177
  props: {
@@ -183,7 +185,7 @@ export function getMediaItems(editor: Editor) {
183
185
  },
184
186
  {
185
187
  name: 'merge cells',
186
- tooltip: 'media.tables.mergeCells',
188
+ tooltip: computed(() => t('media.tables.mergeCells')),
187
189
  icon: mdi.mdiTableMergeCells,
188
190
  enabled: true,
189
191
  props: {
@@ -195,7 +197,7 @@ export function getMediaItems(editor: Editor) {
195
197
  },
196
198
  {
197
199
  name: 'split cell',
198
- tooltip: 'media.tables.splitCell',
200
+ tooltip: computed(() => t('media.tables.splitCell')),
199
201
  icon: mdi.mdiTableSplitCell,
200
202
  enabled: true,
201
203
  props: {
@@ -1,12 +1,15 @@
1
1
  import * as mdi from "@mdi/js";
2
2
  import { Editor } from "@tiptap/vue-3";
3
3
  import { computed } from "vue";
4
+ import { useI18n } from "vue-i18n";
5
+
6
+ export function useMiscItems(editor: Editor) {
7
+ const { t } = useI18n();
4
8
 
5
- export function getMiscItems(editor: Editor) {
6
9
  return {
7
10
  line: {
8
11
  name: 'line',
9
- tooltip: 'format.line',
12
+ tooltip: computed(() => t('format.line')),
10
13
  icon: mdi.mdiMinus,
11
14
  enabled: true,
12
15
  props: {},
@@ -16,7 +19,7 @@ export function getMiscItems(editor: Editor) {
16
19
  },
17
20
  break: {
18
21
  name: 'break',
19
- tooltip: 'format.break',
22
+ tooltip: computed(() => t('format.break')),
20
23
  icon: mdi.mdiFormatPageBreak,
21
24
  enabled: true,
22
25
  props: {},
@@ -26,7 +29,7 @@ export function getMiscItems(editor: Editor) {
26
29
  },
27
30
  source: {
28
31
  name: 'source',
29
- tooltip: 'misc.source',
32
+ tooltip: computed(() => t('misc.source')),
30
33
  icon: mdi.mdiCodeTags,
31
34
  enabled: true,
32
35
  props: {},
@@ -36,7 +39,7 @@ export function getMiscItems(editor: Editor) {
36
39
  },
37
40
  preview: {
38
41
  name: 'preview',
39
- tooltip: 'misc.preview',
42
+ tooltip: computed(() => t('misc.preview')),
40
43
  icon: mdi.mdiFileEyeOutline,
41
44
  enabled: true,
42
45
  attrs: {
@@ -45,7 +48,7 @@ export function getMiscItems(editor: Editor) {
45
48
  },
46
49
  formatClear: {
47
50
  name: 'format clear',
48
- tooltip: 'format.formatClear',
51
+ tooltip: computed(() => t('format.formatClear')),
49
52
  icon: mdi.mdiFormatClear,
50
53
  enabled: true,
51
54
  props: {
@@ -0,0 +1,231 @@
1
+ import * as mdi from "@mdi/js";
2
+ import { Level } from "@tiptap/extension-heading";
3
+ import FontFamily from "@tiptapify/extensions/components/FontFamily.vue";
4
+ import FontSize from "@tiptapify/extensions/components/FontSize.vue";
5
+ import LineHeight from "@tiptapify/extensions/components/LineHeight.vue";
6
+ import { Editor } from "@tiptap/vue-3";
7
+ import StyleColor from "@tiptapify/extensions/components/StyleColor.vue";
8
+ import { computed, markRaw } from "vue";
9
+ import { useI18n } from "vue-i18n";
10
+ import {
11
+ fonts,
12
+ fontSizes,
13
+ lineHeights,
14
+ headingLevels,
15
+ setHeadingLevels,
16
+ defaultFontSize,
17
+ defaultLineHeight
18
+ } from "@tiptapify/constants/style";
19
+
20
+ interface MDIIcons {
21
+ [key: string]: string
22
+ }
23
+ const mdiIcons = mdi as MDIIcons
24
+
25
+ export function useStyleItems(editor: Editor, theme: any, fontMeasure: string, customHeadingLevels: Array<number> = []) {
26
+ const { t } = useI18n();
27
+
28
+ setHeadingLevels(customHeadingLevels)
29
+
30
+ return {
31
+ heading: {
32
+ name: 'heading',
33
+ tooltip: computed(() => t('style.heading')),
34
+ icon: mdi.mdiFormatHeaderPound,
35
+ modelValue: null,
36
+ enabled: true,
37
+ props: {
38
+ color: computed(() => editor.isActive('heading') || editor.isActive('paragraph') ? 'primary' : ''),
39
+ },
40
+ children: [
41
+ {
42
+ name: 'paragraph',
43
+ tooltip: computed(() => t('style.paragraph')),
44
+ icon: mdiIcons['mdiFormatParagraph'],
45
+ noI18n: true,
46
+ enabled: true,
47
+ props: {
48
+ color: computed(() => editor.isActive('paragraph') ? 'primary' : ''),
49
+ },
50
+ attrs: {
51
+ click: () => editor.chain().focus().setParagraph().run()
52
+ }
53
+ }
54
+ ].concat(
55
+ headingLevels.value.map(level => {
56
+ const headingLevel: Level = level as Level
57
+ return {
58
+ name: `H${level}`,
59
+ tooltip: computed(() => t(`style.headings.h${level}`)),
60
+ icon: mdiIcons[`mdiFormatHeader${level}`],
61
+ noI18n: true,
62
+ enabled: true,
63
+ props: {
64
+ color: computed(() => editor.isActive('heading', { level: level }) ? 'primary' : ''),
65
+ },
66
+ attrs: {
67
+ click: () => editor.chain().focus().toggleHeading({ level: headingLevel }).run()
68
+ }
69
+ }
70
+ })
71
+ )
72
+ },
73
+ fontFamily: {
74
+ name: 'font-family',
75
+ tooltip: computed(() => t('style.fontFamily')),
76
+ icon: mdi.mdiFormatFont,
77
+ modelValue: false,
78
+ enabled: true,
79
+ props: {
80
+ disabled: computed(() => !editor.can().chain().focus().unsetFontFamily().run()),
81
+ color: computed(() => {
82
+ let color = ''
83
+ for (const font in fonts) {
84
+ if (editor.isActive('textStyle', { fontFamily: fonts[font].fontFamily })) {
85
+ color = 'primary'
86
+ break;
87
+ }
88
+ }
89
+
90
+ return color
91
+ }),
92
+ },
93
+ component: markRaw(FontFamily),
94
+ componentProps: {
95
+ fonts: fonts,
96
+ fontFamily: computed(() => {
97
+ let fontFamily = ''
98
+ for (const font in fonts) {
99
+ if (editor.isActive('textStyle', { fontFamily: fonts[font].fontFamily })) {
100
+ fontFamily = fonts[font].fontFamily
101
+ break;
102
+ }
103
+ }
104
+
105
+ return fontFamily
106
+ }),
107
+ }
108
+ },
109
+ fontSize: {
110
+ name: 'font-size',
111
+ tooltip: computed(() => t('style.fontSize')),
112
+ icon: mdi.mdiFormatSize,
113
+ modelValue: false,
114
+ enabled: true,
115
+ props: {
116
+ disabled: computed(() => !editor.can().chain().focus().unsetFontSize().run()),
117
+ color: computed(() => {
118
+ let color = ''
119
+ for (const size of fontSizes) {
120
+ if (editor.isActive('textStyle', { fontSize: `${size}${fontMeasure}` })) {
121
+ color = 'primary'
122
+ break;
123
+ }
124
+ }
125
+
126
+ return color
127
+ }),
128
+ },
129
+ component: markRaw(FontSize),
130
+ componentProps: {
131
+ sizes: fontSizes,
132
+ measure: fontMeasure,
133
+ fontSize: computed(() => {
134
+ let fontSize = null
135
+ for (const size of fontSizes) {
136
+ if (editor.isActive('textStyle', { fontSize: `${size}${fontMeasure}` })) {
137
+ fontSize = size
138
+ break;
139
+ }
140
+ }
141
+
142
+ return fontSize
143
+ }),
144
+ }
145
+ },
146
+ lineHeight: {
147
+ name: 'line-height',
148
+ tooltip: computed(() => t('style.lineHeight')),
149
+ icon: mdi.mdiFormatLineHeight,
150
+ modelValue: null,
151
+ enabled: true,
152
+ props: {
153
+ disabled: computed(() => !editor.can().chain().focus().unsetLineHeight().run()),
154
+ color: computed(() => {
155
+ let color = ''
156
+ for (const height of lineHeights) {
157
+ if (editor.isActive('textStyle', { lineHeight: height.toString() })) {
158
+ color = 'primary'
159
+ break;
160
+ }
161
+ }
162
+
163
+ return color
164
+ }),
165
+ },
166
+ component: markRaw(LineHeight),
167
+ componentProps: {
168
+ lineHeights,
169
+ lineHeight: computed(() => {
170
+ let lineHeight = null
171
+ for (const height of lineHeights) {
172
+ if (editor.isActive('textStyle', { lineHeight: height.toString() })) {
173
+ lineHeight = height
174
+ break;
175
+ }
176
+ }
177
+
178
+ return lineHeight
179
+ }),
180
+ }
181
+ },
182
+ highlight: {
183
+ name: 'highlight',
184
+ tooltip: computed(() => t('style.color.highlight')),
185
+ icon: mdi.mdiFormatColorFill,
186
+ icon2: mdi.mdiColorHelper,
187
+ enabled: true,
188
+ props: {
189
+ disabled: computed(() => !editor.can().chain().focus().toggleHighlight().run()),
190
+ },
191
+ icon2Props: {
192
+ disabled: computed(() => !editor.can().chain().focus().toggleHighlight().run()),
193
+ color: computed(() => {
194
+ const defaultColor = theme.global.current.value.dark ? '#fff' : '#000'
195
+ return editor.getAttributes('highlight').color || defaultColor
196
+ }),
197
+ style: 'filter: drop-shadow(rgba(0, 0, 0, .75) 1px 1px 2px);'
198
+ },
199
+ component: markRaw(StyleColor),
200
+ componentProps: {
201
+ fontColor: false,
202
+ backgroundColor: true,
203
+ color: computed(() => editor.getAttributes('highlight').color || ''),
204
+ }
205
+ },
206
+ color: {
207
+ name: 'color',
208
+ tooltip: computed(() => t('style.color.text')),
209
+ icon: mdi.mdiFormatColorText,
210
+ icon2: mdi.mdiColorHelper,
211
+ enabled: true,
212
+ props: {
213
+ disabled: computed(() => !editor.can().chain().focus().toggleHighlight().run()),
214
+ },
215
+ icon2Props: {
216
+ disabled: computed(() => !editor.can().chain().focus().toggleHighlight().run()),
217
+ color: computed(() => {
218
+ const defaultColor = theme.global.current.value.dark ? '#fff' : '#000'
219
+ return editor.getAttributes('textStyle').color || defaultColor
220
+ }),
221
+ style: 'filter: drop-shadow(rgba(0, 0, 0, .75) 1px 1px 2px);'
222
+ },
223
+ component: markRaw(StyleColor),
224
+ componentProps: {
225
+ fontColor: true,
226
+ backgroundColor: false,
227
+ color: computed(() => editor.getAttributes('textStyle').color || ''),
228
+ }
229
+ }
230
+ }
231
+ }
@@ -1,3 +1,24 @@
1
+ import { ref } from "vue";
2
+
3
+ export const defaultFontSize = 12
4
+ export const fontSizes = [6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 32, 48, 64, 96]
5
+
6
+ export const defaultLineHeight = 1
7
+ export const lineHeights = [1, 1.5, 2, 3, 4]
8
+
9
+ export const headingLevels = ref([1, 2, 3, 4, 5, 6])
10
+ export function setHeadingLevels(customHeadingLevels: number[]) {
11
+ if (customHeadingLevels.length) {
12
+ customHeadingLevels.forEach(level => {
13
+ if (level < 1 || level > 6) {
14
+ throw new Error('customHeadingLevels must be between 1 and 6')
15
+ }
16
+ })
17
+
18
+ headingLevels.value = customHeadingLevels
19
+ }
20
+ }
21
+
1
22
  export const fonts = [
2
23
  {
3
24
  name: 'Arial',
@@ -0,0 +1,82 @@
1
+ <script setup lang="ts">
2
+
3
+ import { Editor } from "@tiptap/vue-3";
4
+
5
+ import { computed, inject, Ref, ref } from 'vue'
6
+ import { useI18n } from "vue-i18n";
7
+
8
+ const props = defineProps({
9
+ fonts: { type: Array<{ name: string, fontFamily: string }>, default: [] },
10
+ fontFamily: { type: String, default: '' },
11
+ })
12
+
13
+ const { t } = useI18n();
14
+
15
+ const emit = defineEmits(['close'])
16
+
17
+ const editor = inject('tiptapifyEditor') as Ref<Editor>
18
+
19
+ const initialFontFamily = ref(computed(() => props.fontFamily).value)
20
+
21
+ const fontSelected = ref<boolean>(false)
22
+
23
+ function hoverFontFamily(font: string) {
24
+ fontSelected.value = false
25
+
26
+ editor.value.chain().focus().setFontFamily(font).run()
27
+ }
28
+
29
+ function resetFontFamily() {
30
+ if (fontSelected.value) {
31
+ return
32
+ }
33
+
34
+ initialFontFamily.value
35
+ ? editor.value.chain().focus().setFontFamily(initialFontFamily.value).run()
36
+ : editor.value.chain().focus().unsetFontFamily().run()
37
+ }
38
+
39
+ function clearFontFamily() {
40
+ editor.value.chain().focus().unsetFontFamily().run()
41
+ emit('close')
42
+ }
43
+
44
+ function setFontFamily() {
45
+ fontSelected.value = true
46
+
47
+ emit('close')
48
+ }
49
+
50
+ function isFontFamilyActive(fontFamily: string): boolean {
51
+ return editor.value.isActive('textStyle', { fontFamily }) || fontFamily === initialFontFamily.value
52
+ }
53
+ </script>
54
+
55
+ <template>
56
+ <VList class="tiptapify-font-family-list">
57
+ <VListItem :disabled="fontFamily === ''" density="compact" @click="clearFontFamily">
58
+ <VListItemTitle class="font-italic text-grey-darken-1">
59
+ {{ t('defaultValue') }}
60
+ </VListItemTitle>
61
+ </VListItem>
62
+ <VListItem
63
+ v-for="font in fonts"
64
+ :active="isFontFamilyActive(font.fontFamily)"
65
+ :color="font.fontFamily === initialFontFamily ? 'primary' : ''"
66
+ density="compact"
67
+ @click="setFontFamily"
68
+ @mouseover="hoverFontFamily(font.fontFamily)"
69
+ @mouseleave="resetFontFamily"
70
+ >
71
+ <VListItemTitle>
72
+ {{ font.name }}
73
+ </VListItemTitle>
74
+ </VListItem>
75
+ </VList>
76
+ </template>
77
+
78
+ <style lang="scss" scoped>
79
+ .tiptapify-font-family-list {
80
+ max-height: 390px;
81
+ }
82
+ </style>