tiptapify 0.2.6 → 0.3.0

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 (69) hide show
  1. package/README.md +1 -1
  2. package/dist/tiptapify.css +1 -1
  3. package/dist/tiptapify.mjs +23435 -25368
  4. package/dist/tiptapify.umd.js +70 -73
  5. package/package.json +1 -1
  6. package/src/components/Footer.vue +1 -1
  7. package/src/components/Tiptapify.vue +6 -2
  8. package/src/components/Toolbar/Index.vue +3 -4
  9. package/src/components/Toolbar/Items.vue +3 -3
  10. package/src/components/UI/HotkeyTooltip.test.ts +65 -0
  11. package/src/components/UI/HotkeyTooltip.vue +54 -0
  12. package/src/components/UI/Tooltip.vue +20 -0
  13. package/src/composables/useTiptapifyConfig.test.ts +66 -0
  14. package/src/composables/useTiptapifyConfig.ts +17 -0
  15. package/src/constants/defaults.ts +4 -2
  16. package/src/extensions/components/actions/redo/Button.vue +5 -9
  17. package/src/extensions/components/actions/undo/Button.vue +5 -9
  18. package/src/extensions/components/ai/Button.vue +7 -10
  19. package/src/extensions/components/ai/Dialog.vue +4 -9
  20. package/src/extensions/components/alignment/center/Button.vue +5 -9
  21. package/src/extensions/components/alignment/justify/Button.vue +5 -9
  22. package/src/extensions/components/alignment/left/Button.vue +5 -9
  23. package/src/extensions/components/alignment/right/Button.vue +5 -9
  24. package/src/extensions/components/format/bold/Button.vue +5 -9
  25. package/src/extensions/components/format/italic/Button.vue +5 -9
  26. package/src/extensions/components/format/strike/Button.vue +5 -9
  27. package/src/extensions/components/format/underline/Button.vue +5 -9
  28. package/src/extensions/components/formatExtra/code/Button.vue +5 -9
  29. package/src/extensions/components/formatExtra/codeBlock/Button.vue +5 -9
  30. package/src/extensions/components/formatExtra/quote/Button.vue +5 -9
  31. package/src/extensions/components/formatExtra/sub/Button.vue +5 -9
  32. package/src/extensions/components/formatExtra/sup/Button.vue +5 -9
  33. package/src/extensions/components/list/bullet/Button.vue +8 -13
  34. package/src/extensions/components/list/indent/Button.vue +5 -9
  35. package/src/extensions/components/list/numbered/Button.vue +5 -9
  36. package/src/extensions/components/list/outdent/Button.vue +5 -9
  37. package/src/extensions/components/list/task/Button.vue +5 -9
  38. package/src/extensions/components/media/charmap/Button.vue +5 -8
  39. package/src/extensions/components/media/charmap/Picker.vue +2 -3
  40. package/src/extensions/components/media/emoji/Button.vue +6 -9
  41. package/src/extensions/components/media/emoji/Picker.vue +2 -3
  42. package/src/extensions/components/media/iframe/Button.vue +6 -10
  43. package/src/extensions/components/media/iframe/IframeDialog.vue +3 -7
  44. package/src/extensions/components/media/image/Button.vue +6 -10
  45. package/src/extensions/components/media/image/ImageDialog.vue +5 -10
  46. package/src/extensions/components/media/link/Button.vue +7 -10
  47. package/src/extensions/components/media/link/LinkDialog.vue +3 -7
  48. package/src/extensions/components/media/table/Button.vue +10 -24
  49. package/src/extensions/components/media/table/ColumnActions.vue +4 -9
  50. package/src/extensions/components/media/table/RowActions.vue +4 -9
  51. package/src/extensions/components/media/video/Button.vue +6 -10
  52. package/src/extensions/components/media/video/VideoDialog.vue +3 -7
  53. package/src/extensions/components/misc/break/Button.vue +5 -9
  54. package/src/extensions/components/misc/formatClear/Button.vue +5 -9
  55. package/src/extensions/components/misc/fullscreen/Button.vue +5 -9
  56. package/src/extensions/components/misc/invisibleChar/Button.vue +5 -9
  57. package/src/extensions/components/misc/line/Button.vue +5 -9
  58. package/src/extensions/components/misc/preview/Button.vue +5 -9
  59. package/src/extensions/components/misc/source/Button.vue +6 -10
  60. package/src/extensions/components/misc/source/ShowSourceDialog.vue +4 -5
  61. package/src/extensions/components/style/color/Button.vue +5 -9
  62. package/src/extensions/components/style/fontFamily/Button.vue +5 -9
  63. package/src/extensions/components/style/fontSize/Button.vue +6 -7
  64. package/src/extensions/components/style/heading/Button.vue +6 -8
  65. package/src/extensions/components/style/highlight/Button.vue +5 -9
  66. package/src/extensions/components/style/lineHeight/Button.vue +5 -9
  67. package/src/index.ts +3 -0
  68. package/src/utils/hotkeys.test.ts +146 -0
  69. package/src/utils/hotkeys.ts +65 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tiptapify",
3
3
  "types": "./index.d.ts",
4
- "version": "0.2.6",
4
+ "version": "0.3.0",
5
5
  "description": "Tiptap3 editor with Vuetify3 menu implementation",
6
6
  "exports": {
7
7
  ".": {
@@ -57,7 +57,7 @@ function showFooter() {
57
57
  <VRow>
58
58
  <VCol class="d-flex align-center" :class="`justify-${alignment}`">
59
59
  <template v-if="limit > 0">
60
- <VTooltip>
60
+ <VTooltip :open-delay="1500">
61
61
  <template #default>
62
62
  <span v-html="limitText" />
63
63
  </template>
@@ -3,7 +3,7 @@
3
3
  import defaults from '@tiptapify/constants/defaults'
4
4
  import { itemsPropType, toolbarSections } from '@tiptapify/types/toolbarTypes'
5
5
  import { SlashCommandsConfig } from '@tiptapify/types/slashCommandsTypes'
6
- import { computed, onBeforeUnmount, PropType, provide, ref, ShallowRef } from 'vue'
6
+ import { computed, onBeforeUnmount, PropType, provide, ref, ShallowRef, toRef } from 'vue'
7
7
  import { default as Toolbar } from '@tiptapify/components/Toolbar/Index.vue'
8
8
  import { Editor, EditorContent } from '@tiptap/vue-3'
9
9
  import { TiptapifyAiOptions, TiptapifyAiResolvedOptions, TiptapifyEditor, TiptapifyFooterAlignment, variantBtnTypes, variantFieldTypes } from '@tiptapify/types/editor'
@@ -13,6 +13,7 @@ import MenuFloating from '@tiptapify/components/MenuFloating.vue'
13
13
  import { useI18n } from 'vue-i18n'
14
14
 
15
15
  import { getTiptapEditor } from '@tiptapify/components/index'
16
+ import { TIPTAPIFY_CONFIG_KEY } from '@tiptapify/composables/useTiptapifyConfig'
16
17
  import { createAiBackendProvider } from '@tiptapify/extensions/components/ai/backend'
17
18
 
18
19
  import Footer from '@tiptapify/components/Footer.vue'
@@ -139,6 +140,10 @@ const editor: ShallowRef<Editor | undefined> = getTiptapEditor(
139
140
  provide('tiptapifyEditor', editor)
140
141
  provide('tiptapifyI18n', { t })
141
142
  provide('tiptapifyAi', tiptapifyAi)
143
+ provide(TIPTAPIFY_CONFIG_KEY, {
144
+ variantBtn: toRef(props, 'variantBtn'),
145
+ variantField: toRef(props, 'variantField'),
146
+ })
142
147
 
143
148
  editor.value?.chain().setFontFamily(props.defaultFontFamily).run()
144
149
 
@@ -162,7 +167,6 @@ onBeforeUnmount(() => {
162
167
  <template v-if="toolbar">
163
168
  <Toolbar
164
169
  v-if="editor"
165
- :variant-btn="variantBtn"
166
170
  :variant-field="variantField"
167
171
  :font-measure="fontMeasure"
168
172
  :items="items"
@@ -2,14 +2,13 @@
2
2
  import { Editor } from '@tiptap/vue-3'
3
3
  import Items from '@tiptapify/components/Toolbar/Items.vue'
4
4
  import defaults from '@tiptapify/constants/defaults'
5
- import { variantBtnTypes, variantFieldTypes } from '@tiptapify/types/editor'
5
+ import { variantFieldTypes } from '@tiptapify/types/editor'
6
6
  import { computed, inject, PropType, Ref } from 'vue'
7
7
  import { itemsPropType, toolbarSections } from '@tiptapify/types/toolbarTypes'
8
8
 
9
9
  import { default as toolbarItemsGroups, availableItems } from '@tiptapify/components/Toolbar/items'
10
10
 
11
11
  const props = defineProps({
12
- variantBtn: { type: String as PropType<variantBtnTypes>, default() { return defaults.variantBtn } },
13
12
  variantField: { type: String as PropType<variantFieldTypes>, default() { return defaults.variantField } },
14
13
  items: { type: [Array, Object] as PropType<itemsPropType>, default() { return [] } },
15
14
  itemsExclude: { type: Boolean, default() { return false } },
@@ -178,10 +177,10 @@ Object.keys(props.customExtensions).forEach((key: any) => {
178
177
  <div v-if="editor" class="tiptapify-toolbar">
179
178
  <VToolbar elevation="1" :theme="theme" height="auto" :class="`ps-1 pr-1 rounded-t-${rounded}`">
180
179
  <VSlideGroup v-if="toolbarScrollable">
181
- <Items :items="toolbarItems" :variant-btn="variantBtn" />
180
+ <Items :items="toolbarItems" />
182
181
  </VSlideGroup>
183
182
 
184
- <Items v-else :items="toolbarItems" :variant-btn="variantBtn" />
183
+ <Items v-else :items="toolbarItems" />
185
184
  </VToolbar>
186
185
  </div>
187
186
  </template>
@@ -1,16 +1,16 @@
1
1
  <script setup lang="ts">
2
2
 
3
- import defaults from '@tiptapify/constants/defaults'
4
- import { variantBtnTypes } from '@tiptapify/types/editor'
3
+ import { useTiptapifyConfig } from '@tiptapify/composables/useTiptapifyConfig'
5
4
  import { PropType } from 'vue'
6
5
 
7
6
  import { toolbarSections } from '@tiptapify/types/toolbarTypes'
8
7
 
9
8
  defineProps({
10
- variantBtn: { type: String as PropType<variantBtnTypes>, default() { return defaults.variantBtn } },
11
9
  items: { type: Array as PropType<toolbarSections>, default() { return {} } },
12
10
  })
13
11
 
12
+ const { variantBtn } = useTiptapifyConfig()
13
+
14
14
  </script>
15
15
 
16
16
  <template>
@@ -0,0 +1,65 @@
1
+ import { afterEach, describe, expect, it, vi } from 'vitest'
2
+ import { createSSRApp, h } from 'vue'
3
+ import { renderToString } from 'vue/server-renderer'
4
+ import { createVuetify } from 'vuetify'
5
+ import HotkeyTooltip from './HotkeyTooltip.vue'
6
+
7
+ const MAC_UA = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36'
8
+ const WIN_UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36'
9
+
10
+ function mockUserAgent (userAgent: string) {
11
+ Object.defineProperty(window.navigator, 'userAgent', {
12
+ value: userAgent,
13
+ configurable: true,
14
+ })
15
+ }
16
+
17
+ function renderTooltip (label: string, hotkey: string): Promise<string> {
18
+ const app = createSSRApp({
19
+ render: () => h(HotkeyTooltip, { label, hotkey })
20
+ })
21
+ app.use(createVuetify())
22
+
23
+ return renderToString(app)
24
+ }
25
+
26
+ describe('HotkeyTooltip', () => {
27
+ afterEach(() => {
28
+ vi.unstubAllGlobals()
29
+ })
30
+
31
+ it('renders label and spelled-out hotkey on two lines on Windows', async () => {
32
+ mockUserAgent(WIN_UA)
33
+ const html = await renderTooltip('Bold', 'Mod-Shift-b')
34
+
35
+ expect(html).toContain('t-hotkey-tooltip__label')
36
+ expect(html).toContain('t-hotkey-tooltip__hotkey')
37
+ expect(html).toContain('Bold')
38
+ expect(html).toContain('Ctrl')
39
+ expect(html).toContain('Shift')
40
+ expect(html).toContain('>B</span>')
41
+ expect(html).not.toContain('mdiSvg:')
42
+ })
43
+
44
+ it('renders the hotkey with icons on macOS without spelled-out names', async () => {
45
+ mockUserAgent(MAC_UA)
46
+ const html = await renderTooltip('Heading', 'Mod-Alt-1..6')
47
+
48
+ expect(html).toContain('t-hotkey-tooltip__label')
49
+ expect(html).toContain('t-hotkey-tooltip__hotkey')
50
+ expect(html).toContain('Heading')
51
+ expect(html).toContain('mdiSvg:')
52
+ expect(html).toContain('1–6')
53
+ expect(html).not.toContain('Ctrl')
54
+ expect(html).not.toContain('>Command<')
55
+ expect(html).not.toContain('>Option<')
56
+ })
57
+
58
+ it('renders Enter as an icon on macOS', async () => {
59
+ mockUserAgent(MAC_UA)
60
+ const html = await renderTooltip('Hard break', 'Mod-Enter')
61
+
62
+ expect(html).toContain('mdiSvg:')
63
+ expect(html).not.toContain('>Enter<')
64
+ })
65
+ })
@@ -0,0 +1,54 @@
1
+ <script setup lang="ts">
2
+
3
+ import { computed } from 'vue'
4
+ import { hotkeyParts } from '@tiptapify/utils/hotkeys'
5
+
6
+ const props = defineProps({
7
+ label: { type: String, required: true },
8
+ hotkey: { type: String, required: true },
9
+ })
10
+
11
+ const parts = computed(() => hotkeyParts(props.hotkey))
12
+
13
+ </script>
14
+
15
+ <template>
16
+ <span class="t-hotkey-tooltip">
17
+ <span class="t-hotkey-tooltip__label">{{ label }}</span>
18
+ <span class="t-hotkey-tooltip__hotkey">
19
+ <template v-for="(part, index) in parts" :key="index">
20
+ <span v-if="index" class="t-hotkey-sep">+</span>
21
+ <VIcon v-if="part.icon" :icon="part.icon" size="12" class="t-hotkey-icon" />
22
+ <span v-else>{{ part.label }}</span>
23
+ </template>
24
+ </span>
25
+ </span>
26
+ </template>
27
+
28
+ <style scoped lang="scss">
29
+ .t-hotkey-tooltip {
30
+ align-items: center;
31
+ display: flex;
32
+ flex-direction: column;
33
+ gap: 3px;
34
+ padding: 4px 0;
35
+ white-space: nowrap;
36
+ }
37
+
38
+ .t-hotkey-tooltip__hotkey {
39
+ align-items: center;
40
+ background: rgba(127, 127, 127, .2);
41
+ background: color-mix(in srgb, currentColor 14%, transparent);
42
+ border-radius: 4px;
43
+ display: inline-flex;
44
+ font-family: 'JetBrainsMono', ui-monospace, Menlo, Consolas, monospace;
45
+ font-size: 11px;
46
+ gap: 4px;
47
+ letter-spacing: .03em;
48
+ padding: 3px 6px;
49
+
50
+ .t-hotkey-icon {
51
+ font-size: 12px;
52
+ }
53
+ }
54
+ </style>
@@ -0,0 +1,20 @@
1
+ <script setup lang="ts">
2
+
3
+ import HotkeyTooltip from '@tiptapify/components/UI/HotkeyTooltip.vue'
4
+
5
+ defineProps({
6
+ label: { type: String, default: '' },
7
+ hotkey: { type: String, default: '' },
8
+ openDelay: { type: Number, default: 500 },
9
+ })
10
+
11
+ </script>
12
+
13
+ <template>
14
+ <VTooltip activator="parent" :open-delay="openDelay">
15
+ <HotkeyTooltip v-if="hotkey" :label="label" :hotkey="hotkey" />
16
+ <slot v-else>
17
+ {{ label }}
18
+ </slot>
19
+ </VTooltip>
20
+ </template>
@@ -0,0 +1,66 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import { createSSRApp, h, provide, ref } from 'vue'
3
+ import { renderToString } from 'vue/server-renderer'
4
+ import { createVuetify } from 'vuetify'
5
+ import BoldButton from '@tiptapify/extensions/components/format/bold/Button.vue'
6
+ import { TIPTAPIFY_CONFIG_KEY, useTiptapifyConfig } from '@tiptapify/composables/useTiptapifyConfig'
7
+
8
+ const editor = {
9
+ isActive: () => false,
10
+ can: () => ({ chain: () => ({ focus: () => ({ toggleBold: () => ({ run: () => false }) }) }) }),
11
+ commands: { toggleBold: () => {} },
12
+ }
13
+
14
+ const Consumer = {
15
+ setup () {
16
+ const { variantBtn, variantField } = useTiptapifyConfig()
17
+ return () => h('span', [
18
+ h('span', { id: 'variant-btn' }, variantBtn.value),
19
+ h('span', { id: 'variant-field' }, variantField.value),
20
+ ])
21
+ },
22
+ }
23
+
24
+ function render (root: () => any, withConfig: boolean) {
25
+ const app = createSSRApp({
26
+ setup () {
27
+ if (withConfig) {
28
+ provide(TIPTAPIFY_CONFIG_KEY, {
29
+ variantBtn: ref('tonal'),
30
+ variantField: ref('outlined'),
31
+ })
32
+ }
33
+ provide('tiptapifyEditor', ref(editor))
34
+ provide('tiptapifyI18n', { t: (key: string) => key })
35
+ return root
36
+ },
37
+ })
38
+ app.use(createVuetify())
39
+
40
+ return renderToString(app)
41
+ }
42
+
43
+ describe('useTiptapifyConfig', () => {
44
+ it('exposes provided config values', async () => {
45
+ const html = await render(() => h(Consumer), true)
46
+
47
+ expect(html).toContain('<span id="variant-btn">tonal</span>')
48
+ expect(html).toContain('<span id="variant-field">outlined</span>')
49
+ })
50
+
51
+ it('falls back to defaults when no provider is present', async () => {
52
+ const html = await render(() => h(Consumer), false)
53
+
54
+ expect(html).toContain('<span id="variant-btn">flat</span>')
55
+ expect(html).toContain('<span id="variant-field">solo</span>')
56
+ })
57
+
58
+ it('is consumed by toolbar extension buttons', async () => {
59
+ const custom = await render(() => h(BoldButton), true)
60
+ const fallback = await render(() => h(BoldButton), false)
61
+
62
+ expect(custom).toContain('tonal')
63
+ expect(fallback).toContain('flat')
64
+ expect(custom).not.toEqual(fallback)
65
+ })
66
+ })
@@ -0,0 +1,17 @@
1
+ import { computed, inject, InjectionKey, Ref } from 'vue'
2
+ import defaults from '@tiptapify/constants/defaults'
3
+ import { variantBtnTypes, variantFieldTypes } from '@tiptapify/types/editor'
4
+
5
+ export interface TiptapifyConfig {
6
+ variantBtn: Ref<variantBtnTypes>
7
+ variantField: Ref<variantFieldTypes>
8
+ }
9
+
10
+ export const TIPTAPIFY_CONFIG_KEY: InjectionKey<TiptapifyConfig> = Symbol('tiptapifyConfig')
11
+
12
+ export function useTiptapifyConfig(): TiptapifyConfig {
13
+ return inject(TIPTAPIFY_CONFIG_KEY, {
14
+ variantBtn: computed(() => defaults.variantBtn),
15
+ variantField: computed(() => defaults.variantField),
16
+ })
17
+ }
@@ -1,4 +1,6 @@
1
+ import { variantBtnTypes, variantFieldTypes } from '@tiptapify/types/editor'
2
+
1
3
  export default {
2
- variantBtn: 'flat',
3
- variantField: 'solo',
4
+ variantBtn: 'flat' as variantBtnTypes,
5
+ variantField: 'solo' as variantFieldTypes,
4
6
  }
@@ -3,15 +3,13 @@
3
3
  import * as mdi from '@mdi/js'
4
4
  import { Editor } from '@tiptap/vue-3'
5
5
  import BtnIcon from '@tiptapify/components/UI/BtnIcon.vue'
6
- import { variantBtnTypes } from '@tiptapify/types/editor'
7
- import { inject, PropType, Ref } from 'vue'
6
+ import Tooltip from '@tiptapify/components/UI/Tooltip.vue'
7
+ import { useTiptapifyConfig } from '@tiptapify/composables/useTiptapifyConfig'
8
+ import { inject, Ref } from 'vue'
8
9
 
9
- import defaults from '@tiptapify/constants/defaults'
10
10
  import { ComposerTranslation } from 'vue-i18n'
11
11
 
12
- defineProps({
13
- variantBtn: { type: String as PropType<variantBtnTypes>, default() { return defaults.variantBtn } },
14
- })
12
+ const { variantBtn } = useTiptapifyConfig()
15
13
 
16
14
  const editor = inject('tiptapifyEditor') as Ref<Editor>
17
15
 
@@ -27,9 +25,7 @@ const { t } = inject('tiptapifyI18n') as { t: ComposerTranslation }
27
25
  :variant="variantBtn"
28
26
  @click="editor.chain().focus().redo().run()"
29
27
  >
30
- <VTooltip activator="parent">
31
- {{ t('action.redo') }}
32
- </VTooltip>
28
+ <Tooltip :label="t('action.redo')" hotkey="Mod-Shift-z" />
33
29
  <BtnIcon :icon="`mdiSvg:${mdi.mdiRedo}`" />
34
30
  </VBtn>
35
31
  </template>
@@ -3,15 +3,13 @@
3
3
  import * as mdi from '@mdi/js'
4
4
  import { Editor } from '@tiptap/vue-3'
5
5
  import BtnIcon from '@tiptapify/components/UI/BtnIcon.vue'
6
- import { variantBtnTypes } from '@tiptapify/types/editor'
7
- import { inject, PropType, Ref } from 'vue'
6
+ import Tooltip from '@tiptapify/components/UI/Tooltip.vue'
7
+ import { useTiptapifyConfig } from '@tiptapify/composables/useTiptapifyConfig'
8
+ import { inject, Ref } from 'vue'
8
9
 
9
- import defaults from '@tiptapify/constants/defaults'
10
10
  import { ComposerTranslation } from 'vue-i18n'
11
11
 
12
- defineProps({
13
- variantBtn: { type: String as PropType<variantBtnTypes>, default() { return defaults.variantBtn } },
14
- })
12
+ const { variantBtn } = useTiptapifyConfig()
15
13
 
16
14
  const editor = inject('tiptapifyEditor') as Ref<Editor>
17
15
 
@@ -27,9 +25,7 @@ const { t } = inject('tiptapifyI18n') as { t: ComposerTranslation }
27
25
  :variant="variantBtn"
28
26
  @click="editor.chain().focus().undo().run()"
29
27
  >
30
- <VTooltip activator="parent">
31
- {{ t('action.undo') }}
32
- </VTooltip>
28
+ <Tooltip :label="t('action.undo')" hotkey="Mod-z" />
33
29
  <BtnIcon :icon="`mdiSvg:${mdi.mdiUndo}`" />
34
30
  </VBtn>
35
31
  </template>
@@ -2,15 +2,14 @@
2
2
 
3
3
  import * as mdi from '@mdi/js'
4
4
  import BtnIcon from '@tiptapify/components/UI/BtnIcon.vue'
5
+ import Tooltip from '@tiptapify/components/UI/Tooltip.vue'
5
6
  import AiDialog from '@tiptapify/extensions/components/ai/Dialog.vue'
6
- import defaults from '@tiptapify/constants/defaults'
7
- import { TiptapifyAiResolvedOptions, variantBtnTypes } from '@tiptapify/types/editor'
8
- import { computed, ComputedRef, inject, PropType, useTemplateRef } from 'vue'
7
+ import { useTiptapifyConfig } from '@tiptapify/composables/useTiptapifyConfig'
8
+ import { TiptapifyAiResolvedOptions } from '@tiptapify/types/editor'
9
+ import { computed, ComputedRef, inject, useTemplateRef } from 'vue'
9
10
  import { ComposerTranslation } from 'vue-i18n'
10
11
 
11
- defineProps({
12
- variantBtn: { type: String as PropType<variantBtnTypes>, default() { return defaults.variantBtn } },
13
- })
12
+ const { variantBtn } = useTiptapifyConfig()
14
13
 
15
14
  const { t } = inject('tiptapifyI18n') as { t: ComposerTranslation }
16
15
  const ai = inject('tiptapifyAi') as ComputedRef<TiptapifyAiResolvedOptions | false>
@@ -32,11 +31,9 @@ function showDialog() {
32
31
 
33
32
  <template>
34
33
  <VBtn color="" :variant="variantBtn" size="32" :disabled="!isAvailable" @click="showDialog">
35
- <VTooltip activator="parent">
36
- {{ isAvailable ? t('ai.title') : t('ai.unavailable') }}
37
- </VTooltip>
34
+ <Tooltip :label="isAvailable ? t('ai.title') : t('ai.unavailable')" />
38
35
  <BtnIcon :icon="icon" />
39
36
  </VBtn>
40
37
 
41
- <AiDialog ref="dialog" :variant-btn="variantBtn" />
38
+ <AiDialog ref="dialog" />
42
39
  </template>
@@ -1,7 +1,7 @@
1
1
  <script lang="ts" setup>
2
2
 
3
3
  import TiptapifyDialog from '@tiptapify/components/UI/TiptapifyDialog.vue'
4
- import defaults from '@tiptapify/constants/defaults'
4
+ import { useTiptapifyConfig } from '@tiptapify/composables/useTiptapifyConfig'
5
5
  import {
6
6
  TiptapifyAiEditorContext,
7
7
  TiptapifyAiMode,
@@ -11,20 +11,15 @@ import {
11
11
  TiptapifyAiResponse,
12
12
  TiptapifyAiResolvedOptions,
13
13
  TiptapifyAiStream,
14
- TiptapifyEditor,
15
- variantBtnTypes,
16
- variantFieldTypes
14
+ TiptapifyEditor
17
15
  } from '@tiptapify/types/editor'
18
- import { computed, ComputedRef, inject, nextTick, PropType, Ref, ref, useTemplateRef, watch } from 'vue'
16
+ import { computed, ComputedRef, inject, nextTick, Ref, ref, useTemplateRef, watch } from 'vue'
19
17
  import * as mdi from '@mdi/js'
20
18
  import { ComposerTranslation } from 'vue-i18n'
21
19
  import { exceedsLimit } from './charLimit'
22
20
  import { DEFAULT_AI_INSTRUCTION } from './backend'
23
21
 
24
- defineProps({
25
- variantBtn: { type: String as PropType<variantBtnTypes>, default() { return defaults.variantBtn } },
26
- variantField: { type: String as PropType<variantFieldTypes>, default() { return defaults.variantField } },
27
- })
22
+ const { variantBtn, variantField } = useTiptapifyConfig()
28
23
 
29
24
  const editor = inject('tiptapifyEditor') as Ref<TiptapifyEditor>
30
25
  const ai = inject('tiptapifyAi') as ComputedRef<TiptapifyAiResolvedOptions | false>
@@ -3,15 +3,13 @@
3
3
  import * as mdi from '@mdi/js'
4
4
  import { Editor } from '@tiptap/vue-3'
5
5
  import BtnIcon from '@tiptapify/components/UI/BtnIcon.vue'
6
- import { variantBtnTypes } from '@tiptapify/types/editor'
7
- import { inject, PropType, Ref } from 'vue'
6
+ import Tooltip from '@tiptapify/components/UI/Tooltip.vue'
7
+ import { useTiptapifyConfig } from '@tiptapify/composables/useTiptapifyConfig'
8
+ import { inject, Ref } from 'vue'
8
9
 
9
- import defaults from '@tiptapify/constants/defaults'
10
10
  import { ComposerTranslation } from 'vue-i18n'
11
11
 
12
- defineProps({
13
- variantBtn: { type: String as PropType<variantBtnTypes>, default() { return defaults.variantBtn } },
14
- })
12
+ const { variantBtn } = useTiptapifyConfig()
15
13
 
16
14
  const editor = inject('tiptapifyEditor') as Ref<Editor>
17
15
 
@@ -26,9 +24,7 @@ const { t } = inject('tiptapifyI18n') as { t: ComposerTranslation }
26
24
  size="32"
27
25
  @click="editor.chain().focus().toggleTextAlign('center').run()"
28
26
  >
29
- <VTooltip activator="parent">
30
- {{ t('alignments.center') }}
31
- </VTooltip>
27
+ <Tooltip :label="t('alignments.center')" hotkey="Mod-Shift-e" />
32
28
  <BtnIcon :icon="`mdiSvg:${mdi.mdiFormatAlignCenter}`" />
33
29
  </VBtn>
34
30
  </template>
@@ -3,15 +3,13 @@
3
3
  import * as mdi from '@mdi/js'
4
4
  import { Editor } from '@tiptap/vue-3'
5
5
  import BtnIcon from '@tiptapify/components/UI/BtnIcon.vue'
6
- import { variantBtnTypes } from '@tiptapify/types/editor'
7
- import { inject, PropType, Ref } from 'vue'
6
+ import Tooltip from '@tiptapify/components/UI/Tooltip.vue'
7
+ import { useTiptapifyConfig } from '@tiptapify/composables/useTiptapifyConfig'
8
+ import { inject, Ref } from 'vue'
8
9
 
9
- import defaults from '@tiptapify/constants/defaults'
10
10
  import { ComposerTranslation } from 'vue-i18n'
11
11
 
12
- defineProps({
13
- variantBtn: { type: String as PropType<variantBtnTypes>, default() { return defaults.variantBtn } },
14
- })
12
+ const { variantBtn } = useTiptapifyConfig()
15
13
 
16
14
  const editor = inject('tiptapifyEditor') as Ref<Editor>
17
15
 
@@ -26,9 +24,7 @@ const { t } = inject('tiptapifyI18n') as { t: ComposerTranslation }
26
24
  size="32"
27
25
  @click="editor.chain().focus().toggleTextAlign('justify').run()"
28
26
  >
29
- <VTooltip activator="parent">
30
- {{ t('alignments.justify') }}
31
- </VTooltip>
27
+ <Tooltip :label="t('alignments.justify')" hotkey="Mod-Shift-j" />
32
28
  <BtnIcon :icon="`mdiSvg:${mdi.mdiFormatAlignJustify}`" />
33
29
  </VBtn>
34
30
  </template>
@@ -3,15 +3,13 @@
3
3
  import * as mdi from '@mdi/js'
4
4
  import { Editor } from '@tiptap/vue-3'
5
5
  import BtnIcon from '@tiptapify/components/UI/BtnIcon.vue'
6
- import { variantBtnTypes } from '@tiptapify/types/editor'
7
- import { inject, PropType, Ref } from 'vue'
6
+ import Tooltip from '@tiptapify/components/UI/Tooltip.vue'
7
+ import { useTiptapifyConfig } from '@tiptapify/composables/useTiptapifyConfig'
8
+ import { inject, Ref } from 'vue'
8
9
 
9
- import defaults from '@tiptapify/constants/defaults'
10
10
  import { ComposerTranslation } from 'vue-i18n'
11
11
 
12
- defineProps({
13
- variantBtn: { type: String as PropType<variantBtnTypes>, default() { return defaults.variantBtn } },
14
- })
12
+ const { variantBtn } = useTiptapifyConfig()
15
13
 
16
14
  const editor = inject('tiptapifyEditor') as Ref<Editor>
17
15
 
@@ -26,9 +24,7 @@ const { t } = inject('tiptapifyI18n') as { t: ComposerTranslation }
26
24
  size="32"
27
25
  @click="editor.chain().focus().toggleTextAlign('left').run()"
28
26
  >
29
- <VTooltip activator="parent">
30
- {{ t('alignments.left') }}
31
- </VTooltip>
27
+ <Tooltip :label="t('alignments.left')" hotkey="Mod-Shift-l" />
32
28
  <BtnIcon :icon="`mdiSvg:${mdi.mdiFormatAlignLeft}`" />
33
29
  </VBtn>
34
30
  </template>
@@ -3,15 +3,13 @@
3
3
  import * as mdi from '@mdi/js'
4
4
  import { Editor } from '@tiptap/vue-3'
5
5
  import BtnIcon from '@tiptapify/components/UI/BtnIcon.vue'
6
- import { variantBtnTypes } from '@tiptapify/types/editor'
7
- import { inject, PropType, Ref } from 'vue'
6
+ import Tooltip from '@tiptapify/components/UI/Tooltip.vue'
7
+ import { useTiptapifyConfig } from '@tiptapify/composables/useTiptapifyConfig'
8
+ import { inject, Ref } from 'vue'
8
9
 
9
- import defaults from '@tiptapify/constants/defaults'
10
10
  import { ComposerTranslation } from 'vue-i18n'
11
11
 
12
- defineProps({
13
- variantBtn: { type: String as PropType<variantBtnTypes>, default() { return defaults.variantBtn } },
14
- })
12
+ const { variantBtn } = useTiptapifyConfig()
15
13
 
16
14
  const editor = inject('tiptapifyEditor') as Ref<Editor>
17
15
 
@@ -26,9 +24,7 @@ const { t } = inject('tiptapifyI18n') as { t: ComposerTranslation }
26
24
  size="32"
27
25
  @click="editor.chain().focus().toggleTextAlign('right').run()"
28
26
  >
29
- <VTooltip activator="parent">
30
- {{ t('alignments.right') }}
31
- </VTooltip>
27
+ <Tooltip :label="t('alignments.right')" hotkey="Mod-Shift-r" />
32
28
  <BtnIcon :icon="`mdiSvg:${mdi.mdiFormatAlignRight}`" />
33
29
  </VBtn>
34
30
  </template>
@@ -3,15 +3,13 @@
3
3
  import * as mdi from '@mdi/js'
4
4
  import { Editor } from '@tiptap/vue-3'
5
5
  import BtnIcon from '@tiptapify/components/UI/BtnIcon.vue'
6
- import { variantBtnTypes } from '@tiptapify/types/editor'
7
- import { inject, PropType, Ref } from 'vue'
6
+ import Tooltip from '@tiptapify/components/UI/Tooltip.vue'
7
+ import { useTiptapifyConfig } from '@tiptapify/composables/useTiptapifyConfig'
8
+ import { inject, Ref } from 'vue'
8
9
 
9
- import defaults from '@tiptapify/constants/defaults'
10
10
  import { ComposerTranslation } from 'vue-i18n'
11
11
 
12
- defineProps({
13
- variantBtn: { type: String as PropType<variantBtnTypes>, default() { return defaults.variantBtn } },
14
- })
12
+ const { variantBtn } = useTiptapifyConfig()
15
13
 
16
14
  const editor = inject('tiptapifyEditor') as Ref<Editor>
17
15
 
@@ -27,9 +25,7 @@ const { t } = inject('tiptapifyI18n') as { t: ComposerTranslation }
27
25
  size="32"
28
26
  @click="editor.commands.toggleBold()"
29
27
  >
30
- <VTooltip activator="parent">
31
- {{ t('format.bold') }}
32
- </VTooltip>
28
+ <Tooltip :label="t('format.bold')" hotkey="Mod-b" />
33
29
  <BtnIcon :icon="`mdiSvg:${mdi.mdiFormatBold}`" />
34
30
  </VBtn>
35
31
  </template>