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.
- package/README.md +1 -1
- package/dist/tiptapify.css +1 -1
- package/dist/tiptapify.mjs +17514 -17174
- package/dist/tiptapify.umd.js +37 -38
- package/package.json +40 -40
- package/src/components/Tiptapify.vue +2 -2
- package/src/components/Toolbar/GroupBtn.vue +2 -2
- package/src/components/Toolbar/GroupDropdown.vue +4 -4
- package/src/components/Toolbar/Index.vue +3 -2
- package/src/components/Toolbar/Items.vue +2 -2
- package/src/components/Toolbar/Toggle.vue +2 -2
- package/src/components/Toolbar/items.ts +20 -20
- package/src/components/editorExtensions.ts +1 -1
- package/src/{components/Toolbar/items/actions.ts → composables/Toolbar/useActionsItems.ts} +6 -3
- package/src/{components/Toolbar/items/alignment.ts → composables/Toolbar/useAlignmentItems.ts} +12 -9
- package/src/{components/Toolbar/items/formatExtra.ts → composables/Toolbar/useFormatExtraItems.ts} +9 -6
- package/src/{components/Toolbar/items/format.ts → composables/Toolbar/useFormatItems.ts} +8 -5
- package/src/{components/Toolbar/items/list.ts → composables/Toolbar/useListItems.ts} +14 -11
- package/src/{components/Toolbar/items/media.ts → composables/Toolbar/useMediaItems.ts} +22 -20
- package/src/{components/Toolbar/items/misc.ts → composables/Toolbar/useMiscItems.ts} +9 -6
- package/src/{components/Toolbar/items/style.ts → composables/Toolbar/useStyleItems.ts} +106 -79
- package/src/{components/Toolbar/fonts.ts → constants/style.ts} +21 -0
- package/src/extensions/components/FontFamily.vue +82 -0
- package/src/extensions/components/FontSize.vue +83 -0
- package/src/extensions/components/LineHeight.vue +82 -0
- package/src/extensions/components/LinkDialog.vue +20 -4
- package/src/extensions/components/ShowSourceDialog.vue +3 -2
- package/src/extensions/link.ts +8 -0
- package/src/extensions/slash-commands.ts +1 -1
- package/src/i18n/index.ts +0 -1
- package/src/i18n/locales/ch.json +83 -82
- package/src/i18n/locales/cz.json +30 -29
- package/src/i18n/locales/de.json +26 -25
- package/src/i18n/locales/en.json +1 -0
- package/src/i18n/locales/es.json +28 -27
- package/src/i18n/locales/fr.json +28 -27
- package/src/i18n/locales/it.json +30 -29
- package/src/i18n/locales/la.json +60 -59
- package/src/i18n/locales/lt.json +36 -35
- package/src/i18n/locales/nl.json +29 -28
- package/src/i18n/locales/pl.json +30 -29
- package/src/i18n/locales/pt.json +28 -27
- package/src/i18n/locales/ru.json +1 -0
- package/src/i18n/locales/se.json +29 -28
- package/src/i18n/locales/ua.json +1 -0
- /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
|
|
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('
|
|
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('
|
|
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
|
|
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
|
|
13
|
-
const
|
|
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
|
-
|
|
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:
|
|
41
|
-
tooltip:
|
|
42
|
-
icon: mdiIcons[
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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>
|