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
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tiptapify",
3
3
  "types": "./index.d.ts",
4
- "version": "0.0.9",
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": "next",
57
- "@tiptap/extension-blockquote": "next",
58
- "@tiptap/extension-bold": "next",
59
- "@tiptap/extension-bubble-menu": "next",
60
- "@tiptap/extension-code": "next",
61
- "@tiptap/extension-code-block": "next",
62
- "@tiptap/extension-code-block-lowlight": "next",
63
- "@tiptap/extension-color": "next",
64
- "@tiptap/extension-document": "next",
65
- "@tiptap/extension-floating-menu": "next",
66
- "@tiptap/extension-font-family": "next",
67
- "@tiptap/extension-hard-break": "next",
68
- "@tiptap/extension-heading": "next",
69
- "@tiptap/extension-highlight": "next",
70
- "@tiptap/extension-horizontal-rule": "next",
71
- "@tiptap/extension-image": "next",
72
- "@tiptap/extension-italic": "next",
73
- "@tiptap/extension-link": "next",
74
- "@tiptap/extension-list": "next",
75
- "@tiptap/extension-list-item": "next",
76
- "@tiptap/extension-paragraph": "next",
77
- "@tiptap/extension-placeholder": "next",
78
- "@tiptap/extension-strike": "next",
79
- "@tiptap/extension-subscript": "next",
80
- "@tiptap/extension-superscript": "next",
81
- "@tiptap/extension-table": "next",
82
- "@tiptap/extension-task-item": "next",
83
- "@tiptap/extension-task-list": "next",
84
- "@tiptap/extension-text": "next",
85
- "@tiptap/extension-text-align": "next",
86
- "@tiptap/extension-text-style": "next",
87
- "@tiptap/extension-typography": "next",
88
- "@tiptap/extension-underline": "next",
89
- "@tiptap/extensions": "next",
90
- "@tiptap/pm": "next",
91
- "@tiptap/starter-kit": "next",
92
- "@tiptap/suggestion": "next",
93
- "@tiptap/vue-3": "next",
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.6"
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.15.32",
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.7.0",
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.10"
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
- overrideExtensionsComponents: { type: Object as PropType<extensionsComponents>, default() { return {} } },
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
- :override-extensions-components="overrideExtensionsComponents"
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="ucFirst(t(toolbarItem.tooltip))" location="top" activator="parent" />
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
- {{ ucFirst(t(toolbarItem.name)) }}
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="ucFirst(t(toolbarItem.tooltip))" location="top" activator="parent" />
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
- {{ ucFirst(t(toolbarItem.name)) }}
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="ucFirst(t(item.tooltip))" location="top" activator="parent" />
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
- {{ ucFirst(t(item.toggle)) }}
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
- overrideExtensionsComponents: { type: Object as PropType<extensionsComponents>, default() { return {} } },
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 theme = useTheme()
28
+ const appTheme = useTheme()
29
29
 
30
30
  const items = toolbarItems(
31
31
  editor,
32
- theme,
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.overrideExtensionsComponents[extension] ?? defaultComponents[extension]
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="t(toolbarItem.tooltip)" location="top" activator="parent" />
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
- {{ t(toolbarItem.name) }}
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="t(item.name)" location="top" activator="parent" />
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
- {{ t(item.name) }}
24
+ {{ item.name }}
25
25
  </span>
26
26
  </VBtn>
27
27
  </template>
@@ -1,11 +1,11 @@
1
- import { getActionsItems } from "@tiptapify/components/Toolbar/items/actions";
2
- import { getAlignmentItems } from "@tiptapify/components/Toolbar/items/alignment";
3
- import { getFormatExtraItems } from "@tiptapify/components/Toolbar/items/formatExtra";
4
- import { getFormatItems } from "@tiptapify/components/Toolbar/items/format";
5
- import { getListItems } from "@tiptapify/components/Toolbar/items/list";
6
- import { getMediaItems } from "@tiptapify/components/Toolbar/items/media";
7
- import { getMiscItems } from "@tiptapify/components/Toolbar/items/misc";
8
- import { getStyleItems } from "@tiptapify/components/Toolbar/items/style";
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(getStyleItems(editor.value, theme, fontMeasure, customHeadingLevels))
59
- const formatItems = ref(getFormatItems(editor.value))
60
- const formatExtraItems = ref(getFormatExtraItems(editor.value))
61
- const alignmentItems = ref(getAlignmentItems(editor.value))
62
- const listItems = ref(getListItems(editor.value))
63
- const actionsItems = ref(getActionsItems(editor.value))
64
- const miscItems = ref(getMiscItems(editor.value))
65
- const mediaItems = ref(getMediaItems(editor.value))
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 (image, video)
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: {
@@ -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: {
@@ -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: {