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.
- package/README.md +1 -1
- package/dist/tiptapify.css +1 -1
- package/dist/tiptapify.mjs +21133 -19765
- package/dist/tiptapify.umd.js +37 -38
- package/package.json +43 -43
- package/src/components/Tiptapify.vue +2 -2
- package/src/components/Toolbar/GroupBtn.vue +2 -6
- package/src/components/Toolbar/GroupDropdown.vue +4 -8
- package/src/components/Toolbar/Index.vue +5 -4
- 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/UI/Dialog.vue +141 -0
- 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} +10 -7
- package/src/{components/Toolbar/items/format.ts → composables/Toolbar/useFormatItems.ts} +20 -17
- 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/composables/Toolbar/useStyleItems.ts +231 -0
- 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/ImageDialog.vue +17 -29
- package/src/extensions/components/LineHeight.vue +82 -0
- package/src/extensions/components/LinkDialog.vue +75 -44
- package/src/extensions/components/PreviewDialog.vue +8 -16
- package/src/extensions/components/ShowSourceDialog.vue +17 -18
- package/src/extensions/components/StyleColor.vue +68 -15
- package/src/extensions/components/TableBuilder.vue +3 -6
- 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 +119 -0
- package/src/i18n/locales/cz.json +119 -0
- package/src/i18n/locales/de.json +83 -76
- package/src/i18n/locales/en.json +82 -75
- package/src/i18n/locales/es.json +80 -73
- package/src/i18n/locales/fr.json +81 -73
- package/src/i18n/locales/it.json +80 -73
- package/src/i18n/locales/la.json +119 -0
- package/src/i18n/locales/lt.json +119 -0
- package/src/i18n/locales/nl.json +119 -0
- package/src/i18n/locales/pl.json +80 -74
- package/src/i18n/locales/pt.json +119 -0
- package/src/i18n/locales/ru.json +78 -71
- package/src/i18n/locales/se.json +119 -0
- package/src/i18n/locales/ua.json +79 -72
- package/src/components/Toolbar/items/style.ts +0 -187
- /package/src/{components → extensions/components}/CodeBlockComponent.vue +0 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tiptapify",
|
|
3
3
|
"types": "./index.d.ts",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.11",
|
|
5
5
|
"description": "Tiptap3 editor with Vuetify3 menu implementation",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|
|
@@ -53,48 +53,48 @@
|
|
|
53
53
|
"repository": "https://github.com/IVoyt/tiptapify",
|
|
54
54
|
"packageManager": "pnpm@10.12.1",
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@tiptap/core": "
|
|
57
|
-
"@tiptap/extension-blockquote": "
|
|
58
|
-
"@tiptap/extension-bold": "
|
|
59
|
-
"@tiptap/extension-bubble-menu": "
|
|
60
|
-
"@tiptap/extension-code": "
|
|
61
|
-
"@tiptap/extension-code-block": "
|
|
62
|
-
"@tiptap/extension-code-block-lowlight": "
|
|
63
|
-
"@tiptap/extension-color": "
|
|
64
|
-
"@tiptap/extension-document": "
|
|
65
|
-
"@tiptap/extension-floating-menu": "
|
|
66
|
-
"@tiptap/extension-font-family": "
|
|
67
|
-
"@tiptap/extension-hard-break": "
|
|
68
|
-
"@tiptap/extension-heading": "
|
|
69
|
-
"@tiptap/extension-highlight": "
|
|
70
|
-
"@tiptap/extension-horizontal-rule": "
|
|
71
|
-
"@tiptap/extension-image": "
|
|
72
|
-
"@tiptap/extension-italic": "
|
|
73
|
-
"@tiptap/extension-link": "
|
|
74
|
-
"@tiptap/extension-list": "
|
|
75
|
-
"@tiptap/extension-list-item": "
|
|
76
|
-
"@tiptap/extension-paragraph": "
|
|
77
|
-
"@tiptap/extension-placeholder": "
|
|
78
|
-
"@tiptap/extension-strike": "
|
|
79
|
-
"@tiptap/extension-subscript": "
|
|
80
|
-
"@tiptap/extension-superscript": "
|
|
81
|
-
"@tiptap/extension-table": "
|
|
82
|
-
"@tiptap/extension-task-item": "
|
|
83
|
-
"@tiptap/extension-task-list": "
|
|
84
|
-
"@tiptap/extension-text": "
|
|
85
|
-
"@tiptap/extension-text-align": "
|
|
86
|
-
"@tiptap/extension-text-style": "
|
|
87
|
-
"@tiptap/extension-typography": "
|
|
88
|
-
"@tiptap/extension-underline": "
|
|
89
|
-
"@tiptap/extensions": "
|
|
90
|
-
"@tiptap/pm": "
|
|
91
|
-
"@tiptap/starter-kit": "
|
|
92
|
-
"@tiptap/suggestion": "
|
|
93
|
-
"@tiptap/vue-3": "
|
|
56
|
+
"@tiptap/core": "^3.0.7",
|
|
57
|
+
"@tiptap/extension-blockquote": "^3.0.7",
|
|
58
|
+
"@tiptap/extension-bold": "^3.0.7",
|
|
59
|
+
"@tiptap/extension-bubble-menu": "^3.0.7",
|
|
60
|
+
"@tiptap/extension-code": "^3.0.7",
|
|
61
|
+
"@tiptap/extension-code-block": "^3.0.7",
|
|
62
|
+
"@tiptap/extension-code-block-lowlight": "^3.0.7",
|
|
63
|
+
"@tiptap/extension-color": "^3.0.7",
|
|
64
|
+
"@tiptap/extension-document": "^3.0.7",
|
|
65
|
+
"@tiptap/extension-floating-menu": "^3.0.7",
|
|
66
|
+
"@tiptap/extension-font-family": "^3.0.7",
|
|
67
|
+
"@tiptap/extension-hard-break": "^3.0.7",
|
|
68
|
+
"@tiptap/extension-heading": "^3.0.7",
|
|
69
|
+
"@tiptap/extension-highlight": "^3.0.7",
|
|
70
|
+
"@tiptap/extension-horizontal-rule": "^3.0.7",
|
|
71
|
+
"@tiptap/extension-image": "^3.0.7",
|
|
72
|
+
"@tiptap/extension-italic": "^3.0.7",
|
|
73
|
+
"@tiptap/extension-link": "^3.0.7",
|
|
74
|
+
"@tiptap/extension-list": "^3.0.7",
|
|
75
|
+
"@tiptap/extension-list-item": "^3.0.7",
|
|
76
|
+
"@tiptap/extension-paragraph": "^3.0.7",
|
|
77
|
+
"@tiptap/extension-placeholder": "^3.0.7",
|
|
78
|
+
"@tiptap/extension-strike": "^3.0.7",
|
|
79
|
+
"@tiptap/extension-subscript": "^3.0.7",
|
|
80
|
+
"@tiptap/extension-superscript": "^3.0.7",
|
|
81
|
+
"@tiptap/extension-table": "^3.0.7",
|
|
82
|
+
"@tiptap/extension-task-item": "^3.0.7",
|
|
83
|
+
"@tiptap/extension-task-list": "^3.0.7",
|
|
84
|
+
"@tiptap/extension-text": "^3.0.7",
|
|
85
|
+
"@tiptap/extension-text-align": "^3.0.7",
|
|
86
|
+
"@tiptap/extension-text-style": "^3.0.7",
|
|
87
|
+
"@tiptap/extension-typography": "^3.0.7",
|
|
88
|
+
"@tiptap/extension-underline": "^3.0.7",
|
|
89
|
+
"@tiptap/extensions": "^3.0.7",
|
|
90
|
+
"@tiptap/pm": "^3.0.7",
|
|
91
|
+
"@tiptap/starter-kit": "^3.0.7",
|
|
92
|
+
"@tiptap/suggestion": "^3.0.7",
|
|
93
|
+
"@tiptap/vue-3": "^3.0.7",
|
|
94
94
|
"highlight.js": "^11.11.1",
|
|
95
95
|
"linkifyjs": "^4.3.1",
|
|
96
96
|
"lowlight": "^3.3.0",
|
|
97
|
-
"vue-i18n": "^11.1.
|
|
97
|
+
"vue-i18n": "^11.1.10"
|
|
98
98
|
},
|
|
99
99
|
"peerDependencies": {
|
|
100
100
|
"@mdi/js": "^7.4.47",
|
|
@@ -104,17 +104,17 @@
|
|
|
104
104
|
"devDependencies": {
|
|
105
105
|
"@intlify/unplugin-vue-i18n": "^6.0.8",
|
|
106
106
|
"@rollup/plugin-alias": "^5.1.1",
|
|
107
|
-
"@types/node": "^22.
|
|
107
|
+
"@types/node": "^22.16.4",
|
|
108
108
|
"@vitejs/plugin-vue": "^5.2.4",
|
|
109
109
|
"@vitejs/plugin-vue-jsx": "^4.2.0",
|
|
110
110
|
"rollup-plugin-tsconfig-paths": "^1.5.2",
|
|
111
111
|
"sass-embedded": "^1.89.2",
|
|
112
112
|
"typescript": "^5.8.3",
|
|
113
|
-
"unplugin-vue-components": "^28.
|
|
113
|
+
"unplugin-vue-components": "^28.8.0",
|
|
114
114
|
"vite": "^6.3.5",
|
|
115
115
|
"vite-plugin-vuetify": "^2.1.1",
|
|
116
116
|
"vite-svg-loader": "^5.1.0",
|
|
117
117
|
"vite-tsconfig-paths": "^5.1.4",
|
|
118
|
-
"vue-tsc": "^2.2.
|
|
118
|
+
"vue-tsc": "^2.2.12"
|
|
119
119
|
}
|
|
120
120
|
}
|
|
@@ -32,7 +32,7 @@ const props = defineProps({
|
|
|
32
32
|
defaultFontFamily: { type: String, default () { return 'Inter' } },
|
|
33
33
|
fontMeasure: { type: String, default () { return 'px' } },
|
|
34
34
|
rounded: { type: String, default () { return '0' } },
|
|
35
|
-
|
|
35
|
+
customExtensions: { type: Object as PropType<extensionsComponents>, default() { return {} } },
|
|
36
36
|
})
|
|
37
37
|
|
|
38
38
|
// console.log('override extension components', computed(() => props.overrideExtensionsComponents).value)
|
|
@@ -80,7 +80,7 @@ onBeforeUnmount(() => {
|
|
|
80
80
|
:items="items"
|
|
81
81
|
:items-exclude="itemsExclude"
|
|
82
82
|
:rounded="rounded"
|
|
83
|
-
:
|
|
83
|
+
:custom-extensions="customExtensions"
|
|
84
84
|
:theme="currentTheme"
|
|
85
85
|
/>
|
|
86
86
|
</template>
|
|
@@ -4,25 +4,21 @@ import { useI18n } from "vue-i18n";
|
|
|
4
4
|
|
|
5
5
|
import { ToolbarItem } from "@tiptapify/components/Toolbar/items";
|
|
6
6
|
|
|
7
|
-
import helpers from "@tiptapify/utils/helpers";
|
|
8
|
-
|
|
9
7
|
defineProps({
|
|
10
8
|
variant: { type: String, default () { return 'flat' }},
|
|
11
9
|
toolbarItem: { type: Object as PropType<ToolbarItem>, default() { return {} }}
|
|
12
10
|
})
|
|
13
11
|
|
|
14
12
|
const { t } = useI18n();
|
|
15
|
-
|
|
16
|
-
const { ucFirst } = helpers;
|
|
17
13
|
</script>
|
|
18
14
|
|
|
19
15
|
<template>
|
|
20
16
|
<VBtn v-bind="toolbarItem?.props ?? {}" v-on="toolbarItem?.attrs ?? {}" size="32">
|
|
21
|
-
<VTooltip :text="
|
|
17
|
+
<VTooltip :text="toolbarItem.tooltip" location="top" activator="parent" />
|
|
22
18
|
|
|
23
19
|
<VIcon v-if="toolbarItem.icon" :icon="toolbarItem.icon" size="small" />
|
|
24
20
|
<span v-else class="menu-item-title">
|
|
25
|
-
{{
|
|
21
|
+
{{ toolbarItem.name }}
|
|
26
22
|
</span>
|
|
27
23
|
|
|
28
24
|
<VIcon v-if="toolbarItem.icon2" v-bind="toolbarItem?.icon2Props ?? {}" :icon="toolbarItem.icon2" size="small" style="position: absolute;" />
|
|
@@ -2,12 +2,8 @@
|
|
|
2
2
|
import { defineProps, PropType } from 'vue'
|
|
3
3
|
import { useI18n } from "vue-i18n";
|
|
4
4
|
|
|
5
|
-
import helpers from "@tiptapify/utils/helpers";
|
|
6
|
-
|
|
7
5
|
import { ToolbarItem } from "@tiptapify/components/Toolbar/items";
|
|
8
6
|
|
|
9
|
-
const { ucFirst } = helpers;
|
|
10
|
-
|
|
11
7
|
defineProps({
|
|
12
8
|
variant: { type: String, default () { return 'flat' }},
|
|
13
9
|
nested: { type: Boolean, default () { return false }},
|
|
@@ -22,11 +18,11 @@ const { t } = useI18n();
|
|
|
22
18
|
<VMenu v-model="toolbarItem.modelValue" v-bind="toolbarItem.props">
|
|
23
19
|
<template v-if="!nested" #activator="{ props: menuProps }">
|
|
24
20
|
<VBtn v-bind="{ ...menuProps, ...toolbarItem.props }" size="32">
|
|
25
|
-
<VTooltip :text="
|
|
21
|
+
<VTooltip :text="toolbarItem.tooltip" location="top" activator="parent" />
|
|
26
22
|
|
|
27
23
|
<VIcon v-if="toolbarItem.icon" :icon="toolbarItem.icon" size="small" />
|
|
28
24
|
<span v-else class="menu-item-title">
|
|
29
|
-
{{
|
|
25
|
+
{{ toolbarItem.name }}
|
|
30
26
|
</span>
|
|
31
27
|
</VBtn>
|
|
32
28
|
</template>
|
|
@@ -47,7 +43,7 @@ const { t } = useI18n();
|
|
|
47
43
|
v-bind="item.props ?? {}"
|
|
48
44
|
v-on="item?.attrs ?? {}"
|
|
49
45
|
>
|
|
50
|
-
<VTooltip v-if="item.tooltip" :text="
|
|
46
|
+
<VTooltip v-if="item.tooltip" :text="item.tooltip" location="top" activator="parent" />
|
|
51
47
|
|
|
52
48
|
<VIcon v-if="item.icon" :icon="item.icon" size="small" />
|
|
53
49
|
|
|
@@ -56,7 +52,7 @@ const { t } = useI18n();
|
|
|
56
52
|
{{ item.name }}
|
|
57
53
|
</template>
|
|
58
54
|
<template v-else>
|
|
59
|
-
{{
|
|
55
|
+
{{ item.toggle }}
|
|
60
56
|
</template>
|
|
61
57
|
</span>
|
|
62
58
|
|
|
@@ -20,16 +20,16 @@ const props = defineProps({
|
|
|
20
20
|
theme: { type: String, default() { return 'light' } },
|
|
21
21
|
rounded: { type: String, default() { return '0' } },
|
|
22
22
|
toolbarScrollable: { type: Boolean, default() { return false } },
|
|
23
|
-
|
|
23
|
+
customExtensions: { type: Object as PropType<extensionsComponents>, default() { return {} } },
|
|
24
24
|
})
|
|
25
25
|
|
|
26
26
|
const editor = inject('tiptapifyEditor') as Ref<Editor>
|
|
27
27
|
|
|
28
|
-
const
|
|
28
|
+
const appTheme = useTheme()
|
|
29
29
|
|
|
30
30
|
const items = toolbarItems(
|
|
31
31
|
editor,
|
|
32
|
-
|
|
32
|
+
appTheme,
|
|
33
33
|
computed(() => props.fontMeasure).value,
|
|
34
34
|
{ list: computed(() => props.items).value, exclude: computed(() => props.itemsExclude).value },
|
|
35
35
|
computed(() => props.headingLevels).value
|
|
@@ -39,7 +39,7 @@ const defaultComponents: extensionsComponents = getDefaultComponents(props.varia
|
|
|
39
39
|
|
|
40
40
|
const extensions: ShallowRef<extensionsComponents> = shallowRef({})
|
|
41
41
|
Object.keys(defaultComponents).forEach(extension => {
|
|
42
|
-
extensions.value[extension] = props.
|
|
42
|
+
extensions.value[extension] = props.customExtensions[extension] ?? defaultComponents[extension]
|
|
43
43
|
})
|
|
44
44
|
|
|
45
45
|
</script>
|
|
@@ -54,6 +54,7 @@ Object.keys(defaultComponents).forEach(extension => {
|
|
|
54
54
|
<Items v-else :items="items" />
|
|
55
55
|
</VToolbar>
|
|
56
56
|
|
|
57
|
+
<!-- mount components mentioned in "items" -->
|
|
57
58
|
<template v-for="extension in extensions">
|
|
58
59
|
<component :is="extension.component" v-bind="extension?.props ?? {}" />
|
|
59
60
|
</template>
|
|
@@ -36,11 +36,11 @@ const toolbarItemsRef: Ref<ToolbarItemSections> = ref(computed(() => props.items
|
|
|
36
36
|
elevation="4"
|
|
37
37
|
rounded="sm"
|
|
38
38
|
>
|
|
39
|
-
<VTooltip :text="
|
|
39
|
+
<VTooltip :text="toolbarItem.tooltip" location="top" activator="parent" />
|
|
40
40
|
|
|
41
41
|
<VIcon v-if="toolbarItem.icon" :icon="toolbarItem.icon" size="16" />
|
|
42
42
|
<span v-else class="menu-item-title">
|
|
43
|
-
{{
|
|
43
|
+
{{ toolbarItem.name }}
|
|
44
44
|
</span>
|
|
45
45
|
</VBtn>
|
|
46
46
|
|
|
@@ -17,11 +17,11 @@ const { t } = useI18n();
|
|
|
17
17
|
<VBtnToggle :variant="variant" elevation="4">
|
|
18
18
|
<template v-for="(item, key) in toolbarSection.items" :key="key">
|
|
19
19
|
<VBtn v-bind="item.props" v-on="item.attrs" size="32">
|
|
20
|
-
<VTooltip :text="
|
|
20
|
+
<VTooltip :text="item.name" location="top" activator="parent" />
|
|
21
21
|
|
|
22
22
|
<VIcon v-if="item.icon" :icon="item.icon" size="small" />
|
|
23
23
|
<span v-else class="menu-item-title">
|
|
24
|
-
{{
|
|
24
|
+
{{ item.name }}
|
|
25
25
|
</span>
|
|
26
26
|
</VBtn>
|
|
27
27
|
</template>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
1
|
+
import { useActionsItems } from "@tiptapify/composables/Toolbar/useActionsItems";
|
|
2
|
+
import { useAlignmentItems } from "@tiptapify/composables/Toolbar/useAlignmentItems";
|
|
3
|
+
import { useFormatExtraItems } from "@tiptapify/composables/Toolbar/useFormatExtraItems";
|
|
4
|
+
import { useFormatItems } from "@tiptapify/composables/Toolbar/useFormatItems";
|
|
5
|
+
import { useListItems } from "@tiptapify/composables/Toolbar/useListItems";
|
|
6
|
+
import { useMediaItems } from "@tiptapify/composables/Toolbar/useMediaItems";
|
|
7
|
+
import { useMiscItems } from "@tiptapify/composables/Toolbar/useMiscItems";
|
|
8
|
+
import { useStyleItems } from "@tiptapify/composables/Toolbar/useStyleItems";
|
|
9
9
|
import { ComputedRef, ref } from "vue";
|
|
10
10
|
|
|
11
11
|
interface ToolbarItemAttrs {
|
|
@@ -17,8 +17,8 @@ interface ToolbarItemProps {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export interface ToolbarItem {
|
|
20
|
-
name: string|number
|
|
21
|
-
tooltip: string
|
|
20
|
+
name: string|number|ComputedRef<string>,
|
|
21
|
+
tooltip: string|ComputedRef<string>,
|
|
22
22
|
icon: string|ComputedRef<string>,
|
|
23
23
|
icon2?: string|ComputedRef<string>,
|
|
24
24
|
noI18n?: boolean,
|
|
@@ -55,20 +55,20 @@ export function toolbarItems(
|
|
|
55
55
|
items: { list: Array<string>, exclude: boolean },
|
|
56
56
|
customHeadingLevels: Array<number>
|
|
57
57
|
): ToolbarItemSections {
|
|
58
|
-
const styleItems = ref(
|
|
59
|
-
const formatItems = ref(
|
|
60
|
-
const formatExtraItems = ref(
|
|
61
|
-
const alignmentItems = ref(
|
|
62
|
-
const listItems = ref(
|
|
63
|
-
const actionsItems = ref(
|
|
64
|
-
const miscItems = ref(
|
|
65
|
-
const mediaItems = ref(
|
|
58
|
+
const styleItems = ref(useStyleItems(editor.value, theme, fontMeasure, customHeadingLevels))
|
|
59
|
+
const formatItems = ref(useFormatItems(editor.value))
|
|
60
|
+
const formatExtraItems = ref(useFormatExtraItems(editor.value))
|
|
61
|
+
const alignmentItems = ref(useAlignmentItems(editor.value))
|
|
62
|
+
const listItems = ref(useListItems(editor.value))
|
|
63
|
+
const actionsItems = ref(useActionsItems(editor.value))
|
|
64
|
+
const miscItems = ref(useMiscItems(editor.value))
|
|
65
|
+
const mediaItems = ref(useMediaItems(editor.value))
|
|
66
66
|
|
|
67
67
|
const allMenuItems: ToolbarItemSections = {
|
|
68
68
|
/**
|
|
69
69
|
* todo
|
|
70
70
|
*
|
|
71
|
-
* media (
|
|
71
|
+
* media (video)
|
|
72
72
|
*/
|
|
73
73
|
style: { group: true, items: styleItems.value },
|
|
74
74
|
format: { group: true, items: formatItems.value },
|
|
@@ -95,7 +95,7 @@ export function toolbarItems(
|
|
|
95
95
|
|
|
96
96
|
const toolbarItems: ToolbarItemSections = {}
|
|
97
97
|
|
|
98
|
-
const sections = {}
|
|
98
|
+
const sections: { [key: string]: number } = {}
|
|
99
99
|
|
|
100
100
|
Object.keys(allMenuItems).forEach(sectionName => {
|
|
101
101
|
const section = allMenuItems[sectionName]
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
|
|
3
|
+
import * as mdi from "@mdi/js";
|
|
4
|
+
import { nextTick, ref, watch } from "vue";
|
|
5
|
+
import { useI18n } from "vue-i18n";
|
|
6
|
+
|
|
7
|
+
const props = defineProps({
|
|
8
|
+
module: String,
|
|
9
|
+
fullscreen: { type: Boolean, default () { return false } },
|
|
10
|
+
maxWidth: { type: Number, default () { return 800 } },
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
const { t } = useI18n();
|
|
14
|
+
|
|
15
|
+
defineExpose({ open, close })
|
|
16
|
+
const emits = defineEmits(['closeDialog'])
|
|
17
|
+
|
|
18
|
+
const dialog = ref<boolean>(false)
|
|
19
|
+
const movableHandler = ref(null)
|
|
20
|
+
|
|
21
|
+
function open() {
|
|
22
|
+
dialog.value = true
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function close() {
|
|
26
|
+
dialog.value = false
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function emitClose() {
|
|
30
|
+
emits('closeDialog')
|
|
31
|
+
|
|
32
|
+
close()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function dragElement(trigger: HTMLElement, container: HTMLElement) {
|
|
36
|
+
const coordinates = {
|
|
37
|
+
moveX: 0,
|
|
38
|
+
moveY: 0,
|
|
39
|
+
cursorX: 0,
|
|
40
|
+
cursorY: 0,
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
trigger.onmousedown = dragMouseDown
|
|
44
|
+
|
|
45
|
+
function dragMouseDown(e: MouseEvent) {
|
|
46
|
+
e.preventDefault()
|
|
47
|
+
|
|
48
|
+
coordinates.cursorX = e.clientX
|
|
49
|
+
coordinates.cursorY = e.clientY
|
|
50
|
+
|
|
51
|
+
document.onmouseup = closeDragElement
|
|
52
|
+
document.onmousemove = elementDrag
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function elementDrag(e: MouseEvent) {
|
|
56
|
+
e.preventDefault();
|
|
57
|
+
|
|
58
|
+
coordinates.moveX = coordinates.cursorX - e.clientX
|
|
59
|
+
coordinates.moveY = coordinates.cursorY - e.clientY
|
|
60
|
+
coordinates.cursorX = e.clientX
|
|
61
|
+
coordinates.cursorY = e.clientY
|
|
62
|
+
|
|
63
|
+
const parentOffsetLeft = container.parentNode.offsetLeft
|
|
64
|
+
const parentOffsetTop = container.parentNode.offsetTop
|
|
65
|
+
|
|
66
|
+
let left = container.offsetLeft - coordinates.moveX
|
|
67
|
+
if (left < (parentOffsetLeft * -1)) {
|
|
68
|
+
left = (parentOffsetLeft * -1)
|
|
69
|
+
}
|
|
70
|
+
if (left >= parentOffsetLeft) {
|
|
71
|
+
left = parentOffsetLeft
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
let top = container.offsetTop - coordinates.moveY
|
|
75
|
+
if (top < (parentOffsetTop * -1)) {
|
|
76
|
+
top = (parentOffsetTop * -1)
|
|
77
|
+
}
|
|
78
|
+
if (top >= parentOffsetTop) {
|
|
79
|
+
top = parentOffsetTop
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
container.style.left = `${left}px`
|
|
83
|
+
container.style.top = `${top}px`
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function closeDragElement() {
|
|
87
|
+
document.onmouseup = null
|
|
88
|
+
document.onmousemove = null
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
watch(() => dialog.value, async () => {
|
|
93
|
+
await nextTick()
|
|
94
|
+
|
|
95
|
+
if (!movableHandler.value) {
|
|
96
|
+
return
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (dialog.value && !props.fullscreen) {
|
|
100
|
+
dragElement(movableHandler.value.$el as HTMLElement, movableHandler.value.$el.parentNode as HTMLElement)
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
</script>
|
|
104
|
+
|
|
105
|
+
<template>
|
|
106
|
+
<VDialog v-model="dialog" :max-width="maxWidth" :fullscreen="fullscreen" absolute @click:outside="emitClose">
|
|
107
|
+
<VCard>
|
|
108
|
+
<VCardTitle ref="movableHandler" :class="`d-flex ${!fullscreen ? 'tiptapify-movable-handler' : ''}`" style="user-select: none;">
|
|
109
|
+
<VLabel>
|
|
110
|
+
{{ t(`dialog.${module}.title`) }}
|
|
111
|
+
</VLabel>
|
|
112
|
+
|
|
113
|
+
<VSpacer />
|
|
114
|
+
|
|
115
|
+
<VBtn density="compact" class="tiptapify-dialog-close" variant="elevated" elevation="4" icon @click="emitClose">
|
|
116
|
+
<VIcon size="x-small" :icon="mdi.mdiClose" />
|
|
117
|
+
</VBtn>
|
|
118
|
+
</VCardTitle>
|
|
119
|
+
|
|
120
|
+
<VDivider />
|
|
121
|
+
|
|
122
|
+
<slot name="content" />
|
|
123
|
+
|
|
124
|
+
<slot name="actions" />
|
|
125
|
+
</VCard>
|
|
126
|
+
</VDialog>
|
|
127
|
+
</template>
|
|
128
|
+
|
|
129
|
+
<style lang="scss" scoped>
|
|
130
|
+
:deep(.v-overlay__content) {
|
|
131
|
+
position: fixed;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.tiptapify-movable-handler, :deep(.tiptapify-movable-handler > *) {
|
|
135
|
+
cursor: move;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.tiptapify-dialog-close:hover {
|
|
139
|
+
cursor: pointer;
|
|
140
|
+
}
|
|
141
|
+
</style>
|
|
@@ -25,7 +25,7 @@ import { CodeBlockLowlight } from '@tiptap/extension-code-block-lowlight'
|
|
|
25
25
|
|
|
26
26
|
import { TiptapifyLink } from '@tiptapify/extensions/link'
|
|
27
27
|
import { TiptapifyImage } from '@tiptapify/extensions/image'
|
|
28
|
-
import CodeBlockComponent from '@tiptapify/components/CodeBlockComponent.vue'
|
|
28
|
+
import CodeBlockComponent from '@tiptapify/extensions/components/CodeBlockComponent.vue'
|
|
29
29
|
import { ViewSource } from '@tiptapify/extensions/view-source'
|
|
30
30
|
import { Preview } from '@tiptapify/extensions/preview'
|
|
31
31
|
import SlashCommands from '@tiptapify/extensions/slash-commands'
|
|
@@ -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 useActionsItems(editor: Editor) {
|
|
7
|
+
const { t } = useI18n();
|
|
4
8
|
|
|
5
|
-
export function getActionsItems(editor: Editor) {
|
|
6
9
|
return {
|
|
7
10
|
undo: {
|
|
8
11
|
name: 'undo',
|
|
9
|
-
tooltip: 'action.undo',
|
|
12
|
+
tooltip: computed(() => t('action.undo')),
|
|
10
13
|
icon: mdi.mdiUndo,
|
|
11
14
|
enabled: true,
|
|
12
15
|
props: {
|
|
@@ -18,7 +21,7 @@ export function getActionsItems(editor: Editor) {
|
|
|
18
21
|
},
|
|
19
22
|
redo: {
|
|
20
23
|
name: 'redo',
|
|
21
|
-
tooltip: 'action.redo',
|
|
24
|
+
tooltip: computed(() => t('action.redo')),
|
|
22
25
|
icon: mdi.mdiRedo,
|
|
23
26
|
enabled: true,
|
|
24
27
|
props: {
|
package/src/{components/Toolbar/items/alignment.ts → composables/Toolbar/useAlignmentItems.ts}
RENAMED
|
@@ -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 useAlignmentItems(editor: Editor) {
|
|
7
|
+
const { t } = useI18n();
|
|
4
8
|
|
|
5
|
-
export function getAlignmentItems(editor: Editor) {
|
|
6
9
|
return {
|
|
7
10
|
alignmentLeft: {
|
|
8
|
-
name: 'alignments.left',
|
|
9
|
-
tooltip: 'alignments.left',
|
|
11
|
+
name: computed(() => t('alignments.left')),
|
|
12
|
+
tooltip: computed(() => t('alignments.left')),
|
|
10
13
|
icon: mdi.mdiFormatAlignLeft,
|
|
11
14
|
enabled: true,
|
|
12
15
|
props: {
|
|
@@ -18,8 +21,8 @@ export function getAlignmentItems(editor: Editor) {
|
|
|
18
21
|
}
|
|
19
22
|
},
|
|
20
23
|
alignmentCenter: {
|
|
21
|
-
name: 'alignments.center',
|
|
22
|
-
tooltip: 'alignments.center',
|
|
24
|
+
name: computed(() => t('alignments.center')),
|
|
25
|
+
tooltip: computed(() => t('alignments.center')),
|
|
23
26
|
icon: mdi.mdiFormatAlignCenter,
|
|
24
27
|
enabled: true,
|
|
25
28
|
props: {
|
|
@@ -31,8 +34,8 @@ export function getAlignmentItems(editor: Editor) {
|
|
|
31
34
|
}
|
|
32
35
|
},
|
|
33
36
|
alignmentRight: {
|
|
34
|
-
name: 'alignments.right',
|
|
35
|
-
tooltip: 'alignments.right',
|
|
37
|
+
name: computed(() => t('alignments.right')),
|
|
38
|
+
tooltip: computed(() => t('alignments.right')),
|
|
36
39
|
icon: mdi.mdiFormatAlignRight,
|
|
37
40
|
enabled: true,
|
|
38
41
|
props: {
|
|
@@ -44,8 +47,8 @@ export function getAlignmentItems(editor: Editor) {
|
|
|
44
47
|
}
|
|
45
48
|
},
|
|
46
49
|
alignmentJustify: {
|
|
47
|
-
name: 'alignments.justify',
|
|
48
|
-
tooltip: 'alignments.justify',
|
|
50
|
+
name: computed(() => t('alignments.justify')),
|
|
51
|
+
tooltip: computed(() => t('alignments.justify')),
|
|
49
52
|
icon: mdi.mdiFormatAlignJustify,
|
|
50
53
|
enabled: true,
|
|
51
54
|
props: {
|
package/src/{components/Toolbar/items/formatExtra.ts → composables/Toolbar/useFormatExtraItems.ts}
RENAMED
|
@@ -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 useFormatExtraItems(editor: Editor) {
|
|
7
|
+
const { t } = useI18n();
|
|
4
8
|
|
|
5
|
-
export function getFormatExtraItems(editor: Editor) {
|
|
6
9
|
return {
|
|
7
10
|
sup: {
|
|
8
11
|
name: 'sup',
|
|
9
|
-
tooltip: 'format.sup',
|
|
12
|
+
tooltip: computed(() => t('format.sup')),
|
|
10
13
|
icon: mdi.mdiFormatSuperscript,
|
|
11
14
|
enabled: true,
|
|
12
15
|
props: {
|
|
@@ -19,7 +22,7 @@ export function getFormatExtraItems(editor: Editor) {
|
|
|
19
22
|
},
|
|
20
23
|
sub: {
|
|
21
24
|
name: 'sub',
|
|
22
|
-
tooltip: 'format.sub',
|
|
25
|
+
tooltip: computed(() => t('format.sub')),
|
|
23
26
|
icon: mdi.mdiFormatSubscript,
|
|
24
27
|
enabled: true,
|
|
25
28
|
props: {
|
|
@@ -32,7 +35,7 @@ export function getFormatExtraItems(editor: Editor) {
|
|
|
32
35
|
},
|
|
33
36
|
code: {
|
|
34
37
|
name: 'code',
|
|
35
|
-
tooltip: 'format.code',
|
|
38
|
+
tooltip: computed(() => t('format.code')),
|
|
36
39
|
icon: mdi.mdiXml,
|
|
37
40
|
enabled: true,
|
|
38
41
|
props: {
|
|
@@ -45,7 +48,7 @@ export function getFormatExtraItems(editor: Editor) {
|
|
|
45
48
|
},
|
|
46
49
|
codeBlock: {
|
|
47
50
|
name: 'codeblock',
|
|
48
|
-
tooltip: 'format.codeblock',
|
|
51
|
+
tooltip: computed(() => t('format.codeblock')),
|
|
49
52
|
icon: mdi.mdiCodeBlockTags,
|
|
50
53
|
enabled: true,
|
|
51
54
|
props: {
|
|
@@ -58,11 +61,11 @@ export function getFormatExtraItems(editor: Editor) {
|
|
|
58
61
|
},
|
|
59
62
|
blockquote: {
|
|
60
63
|
name: 'blockquote',
|
|
61
|
-
tooltip: 'format.blockquote',
|
|
64
|
+
tooltip: computed(() => t('format.blockquote')),
|
|
62
65
|
icon: mdi.mdiCommentQuote,
|
|
63
66
|
enabled: true,
|
|
64
67
|
props: {
|
|
65
|
-
disabled: computed(() => !editor.can().chain().focus().toggleBlockquote().run()),
|
|
68
|
+
disabled: computed(() => !editor.can().chain().focus().toggleBlockquote().run() || editor.isActive('codeBlock') || editor.isActive('code')),
|
|
66
69
|
color: computed(() => editor.isActive('blockquote') ? 'primary' : ''),
|
|
67
70
|
},
|
|
68
71
|
attrs: {
|