tiptapify 0.0.10 → 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 (46) hide show
  1. package/README.md +1 -1
  2. package/dist/tiptapify.css +1 -1
  3. package/dist/tiptapify.mjs +17514 -17174
  4. package/dist/tiptapify.umd.js +37 -38
  5. package/package.json +40 -40
  6. package/src/components/Tiptapify.vue +2 -2
  7. package/src/components/Toolbar/GroupBtn.vue +2 -2
  8. package/src/components/Toolbar/GroupDropdown.vue +4 -4
  9. package/src/components/Toolbar/Index.vue +3 -2
  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/editorExtensions.ts +1 -1
  14. package/src/{components/Toolbar/items/actions.ts → composables/Toolbar/useActionsItems.ts} +6 -3
  15. package/src/{components/Toolbar/items/alignment.ts → composables/Toolbar/useAlignmentItems.ts} +12 -9
  16. package/src/{components/Toolbar/items/formatExtra.ts → composables/Toolbar/useFormatExtraItems.ts} +9 -6
  17. package/src/{components/Toolbar/items/format.ts → composables/Toolbar/useFormatItems.ts} +8 -5
  18. package/src/{components/Toolbar/items/list.ts → composables/Toolbar/useListItems.ts} +14 -11
  19. package/src/{components/Toolbar/items/media.ts → composables/Toolbar/useMediaItems.ts} +22 -20
  20. package/src/{components/Toolbar/items/misc.ts → composables/Toolbar/useMiscItems.ts} +9 -6
  21. package/src/{components/Toolbar/items/style.ts → composables/Toolbar/useStyleItems.ts} +106 -79
  22. package/src/{components/Toolbar/fonts.ts → constants/style.ts} +21 -0
  23. package/src/extensions/components/FontFamily.vue +82 -0
  24. package/src/extensions/components/FontSize.vue +83 -0
  25. package/src/extensions/components/LineHeight.vue +82 -0
  26. package/src/extensions/components/LinkDialog.vue +20 -4
  27. package/src/extensions/components/ShowSourceDialog.vue +3 -2
  28. package/src/extensions/link.ts +8 -0
  29. package/src/extensions/slash-commands.ts +1 -1
  30. package/src/i18n/index.ts +0 -1
  31. package/src/i18n/locales/ch.json +83 -82
  32. package/src/i18n/locales/cz.json +30 -29
  33. package/src/i18n/locales/de.json +26 -25
  34. package/src/i18n/locales/en.json +1 -0
  35. package/src/i18n/locales/es.json +28 -27
  36. package/src/i18n/locales/fr.json +28 -27
  37. package/src/i18n/locales/it.json +30 -29
  38. package/src/i18n/locales/la.json +60 -59
  39. package/src/i18n/locales/lt.json +36 -35
  40. package/src/i18n/locales/nl.json +29 -28
  41. package/src/i18n/locales/pl.json +30 -29
  42. package/src/i18n/locales/pt.json +28 -27
  43. package/src/i18n/locales/ru.json +1 -0
  44. package/src/i18n/locales/se.json +29 -28
  45. package/src/i18n/locales/ua.json +1 -0
  46. /package/src/{components → extensions/components}/CodeBlockComponent.vue +0 -0
@@ -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: {
@@ -1,34 +1,36 @@
1
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";
2
6
  import { Editor } from "@tiptap/vue-3";
3
- import { fonts } from "@tiptapify/components/Toolbar/fonts";
4
7
  import StyleColor from "@tiptapify/extensions/components/StyleColor.vue";
5
- import { computed, markRaw, ref } from "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";
6
19
 
7
20
  interface MDIIcons {
8
21
  [key: string]: string
9
22
  }
10
23
  const mdiIcons = mdi as MDIIcons
11
24
 
12
- export function getStyleItems(editor: Editor, theme: any, fontMeasure: string, customHeadingLevels: Array<number> = []) {
13
- const headingLevels = ref([1, 2, 3, 4, 5, 6])
14
- if (customHeadingLevels.length) {
15
- customHeadingLevels.forEach(level => {
16
- if (level <= 0 || level > 6) {
17
- throw new Error('customHeadingLevels must be between 1 and 6')
18
- }
19
- })
20
-
21
- headingLevels.value = customHeadingLevels
22
- }
23
-
24
- const fontSizes = [6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 32, 48, 64, 96]
25
+ export function useStyleItems(editor: Editor, theme: any, fontMeasure: string, customHeadingLevels: Array<number> = []) {
26
+ const { t } = useI18n();
25
27
 
26
- const lineHeights = [1, 1.5, 2, 3, 4]
28
+ setHeadingLevels(customHeadingLevels)
27
29
 
28
30
  return {
29
31
  heading: {
30
32
  name: 'heading',
31
- tooltip: 'style.heading',
33
+ tooltip: computed(() => t('style.heading')),
32
34
  icon: mdi.mdiFormatHeaderPound,
33
35
  modelValue: null,
34
36
  enabled: true,
@@ -37,9 +39,9 @@ export function getStyleItems(editor: Editor, theme: any, fontMeasure: string, c
37
39
  },
38
40
  children: [
39
41
  {
40
- name: `paragraph`,
41
- tooltip: `style.paragraph`,
42
- icon: mdiIcons[`mdiFormatParagraph`],
42
+ name: 'paragraph',
43
+ tooltip: computed(() => t('style.paragraph')),
44
+ icon: mdiIcons['mdiFormatParagraph'],
43
45
  noI18n: true,
44
46
  enabled: true,
45
47
  props: {
@@ -51,9 +53,10 @@ export function getStyleItems(editor: Editor, theme: any, fontMeasure: string, c
51
53
  }
52
54
  ].concat(
53
55
  headingLevels.value.map(level => {
56
+ const headingLevel: Level = level as Level
54
57
  return {
55
58
  name: `H${level}`,
56
- tooltip: `style.headings.h${level}`,
59
+ tooltip: computed(() => t(`style.headings.h${level}`)),
57
60
  icon: mdiIcons[`mdiFormatHeader${level}`],
58
61
  noI18n: true,
59
62
  enabled: true,
@@ -61,7 +64,7 @@ export function getStyleItems(editor: Editor, theme: any, fontMeasure: string, c
61
64
  color: computed(() => editor.isActive('heading', { level: level }) ? 'primary' : ''),
62
65
  },
63
66
  attrs: {
64
- click: () => editor.chain().focus().toggleHeading({ level }).run()
67
+ click: () => editor.chain().focus().toggleHeading({ level: headingLevel }).run()
65
68
  }
66
69
  }
67
70
  })
@@ -69,92 +72,116 @@ export function getStyleItems(editor: Editor, theme: any, fontMeasure: string, c
69
72
  },
70
73
  fontFamily: {
71
74
  name: 'font-family',
72
- tooltip: 'style.fontFamily',
75
+ tooltip: computed(() => t('style.fontFamily')),
73
76
  icon: mdi.mdiFormatFont,
74
77
  modelValue: false,
75
78
  enabled: true,
76
79
  props: {
77
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
+ }),
78
92
  },
79
- attrs: {
80
- click: () => editor.chain().focus().unsetFontFamily().run()
81
- },
82
- children: fonts.map((font) => {
83
- return {
84
- name: font.name,
85
- tooltip: '',
86
- icon: '',
87
- enabled: true,
88
- noI18n: true,
89
- props: {
90
- color: computed(() => editor.isActive('textStyle', {fontFamily: font.fontFamily}) ? 'primary' : ''),
91
- style: `font-family: ${font.fontFamily};`
92
- },
93
- attrs: {
94
- click: () => editor.chain().focus().setFontFamily(font.fontFamily).run()
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
+ }
95
103
  }
96
- }
97
- })
104
+
105
+ return fontFamily
106
+ }),
107
+ }
98
108
  },
99
109
  fontSize: {
100
110
  name: 'font-size',
101
- tooltip: 'style.fontSize',
111
+ tooltip: computed(() => t('style.fontSize')),
102
112
  icon: mdi.mdiFormatSize,
103
113
  modelValue: false,
104
114
  enabled: true,
105
115
  props: {
106
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
+ }),
107
128
  },
108
- attrs: {
109
- click: () => editor.chain().focus().unsetFontSize().run()
110
- },
111
- children: fontSizes.map((fontSize) => {
112
- return {
113
- name: `${fontSize}${fontMeasure}`,
114
- tooltip: '',
115
- icon: '',
116
- enabled: true,
117
- noI18n: true,
118
- props: {
119
- color: computed(() => editor.isActive('textStyle', {fontSizes: fontSize}) ? 'primary' : ''),
120
- },
121
- attrs: {
122
- click: () => editor.chain().focus().setFontSize(`${fontSize}${fontMeasure}`).run()
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
+ }
123
140
  }
124
- }
125
- })
141
+
142
+ return fontSize
143
+ }),
144
+ }
126
145
  },
127
146
  lineHeight: {
128
147
  name: 'line-height',
129
- tooltip: 'style.lineHeight',
148
+ tooltip: computed(() => t('style.lineHeight')),
130
149
  icon: mdi.mdiFormatLineHeight,
131
150
  modelValue: null,
132
151
  enabled: true,
133
152
  props: {
134
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
+ }),
135
165
  },
136
- attrs: {
137
- click: () => editor.chain().focus().unsetLineHeight().run()
138
- },
139
- children: lineHeights.map((lineHeight) => {
140
- return {
141
- name: lineHeight,
142
- tooltip: '',
143
- icon: '',
144
- enabled: true,
145
- noI18n: true,
146
- props: {
147
- color: computed(() => editor.isActive('textStyle', {lineHeights: lineHeight}) ? 'primary' : ''),
148
- },
149
- attrs: {
150
- click: () => editor.chain().focus().setLineHeight(lineHeight.toString()).run()
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
+ }
151
176
  }
152
- }
153
- })
177
+
178
+ return lineHeight
179
+ }),
180
+ }
154
181
  },
155
182
  highlight: {
156
183
  name: 'highlight',
157
- tooltip: 'style.color.highlight',
184
+ tooltip: computed(() => t('style.color.highlight')),
158
185
  icon: mdi.mdiFormatColorFill,
159
186
  icon2: mdi.mdiColorHelper,
160
187
  enabled: true,
@@ -178,7 +205,7 @@ export function getStyleItems(editor: Editor, theme: any, fontMeasure: string, c
178
205
  },
179
206
  color: {
180
207
  name: 'color',
181
- tooltip: 'style.color.text',
208
+ tooltip: computed(() => t('style.color.text')),
182
209
  icon: mdi.mdiFormatColorText,
183
210
  icon2: mdi.mdiColorHelper,
184
211
  enabled: true,
@@ -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>
@@ -0,0 +1,83 @@
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
+ sizes: { type: Array<number>, default: [] },
10
+ measure: { type: String, default: 'px' },
11
+ fontSize: { type: Number, default () { return null } },
12
+ })
13
+
14
+ const { t } = useI18n();
15
+
16
+ const emit = defineEmits(['close'])
17
+
18
+ const editor = inject('tiptapifyEditor') as Ref<Editor>
19
+
20
+ const initialFontSize = ref(computed(() => props.fontSize).value)
21
+
22
+ const fontSizeSelected = ref<boolean>(false)
23
+
24
+ function hoverFontSize(fontSize: number) {
25
+ fontSizeSelected.value = false
26
+
27
+ editor.value.chain().focus().setFontSize(`${fontSize}${props.measure}`).run()
28
+ }
29
+
30
+ function resetFontSize() {
31
+ if (fontSizeSelected.value) {
32
+ return
33
+ }
34
+
35
+ initialFontSize.value
36
+ ? editor.value.chain().focus().setFontSize(`${initialFontSize.value}${props.measure}`).run()
37
+ : editor.value.chain().focus().unsetFontSize().run()
38
+ }
39
+
40
+ function clearFontSize() {
41
+ editor.value.chain().focus().unsetFontSize().run()
42
+ emit('close')
43
+ }
44
+
45
+ function setFontSize() {
46
+ fontSizeSelected.value = true
47
+
48
+ emit('close')
49
+ }
50
+
51
+ function isFontSizeActive(fontSize: number): boolean {
52
+ return editor.value.isActive('textStyle', { fontSize: `${fontSize}${props.measure}` }) || fontSize === initialFontSize.value
53
+ }
54
+ </script>
55
+
56
+ <template>
57
+ <VList class="tiptapify-font-size-list">
58
+ <VListItem :disabled="fontSize === null" density="compact" @click="clearFontSize">
59
+ <VListItemTitle class="font-italic text-grey-darken-1">
60
+ {{ t('defaultValue') }}
61
+ </VListItemTitle>
62
+ </VListItem>
63
+ <VListItem
64
+ v-for="size in sizes"
65
+ :active="isFontSizeActive(size)"
66
+ :color="size === initialFontSize ? 'primary' : ''"
67
+ density="compact"
68
+ @click="setFontSize"
69
+ @mouseover="hoverFontSize(size)"
70
+ @mouseleave="resetFontSize"
71
+ >
72
+ <VListItemTitle>
73
+ {{ size }}{{ measure}}
74
+ </VListItemTitle>
75
+ </VListItem>
76
+ </VList>
77
+ </template>
78
+
79
+ <style lang="scss" scoped>
80
+ .tiptapify-font-size-list {
81
+ max-height: 390px;
82
+ }
83
+ </style>