@bitrix24/b24ui-nuxt 2.1.10 → 2.1.12
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-AI.md +1 -1
- package/dist/meta.d.mts +98220 -780
- package/dist/meta.mjs +98220 -780
- package/dist/module.json +1 -1
- package/dist/module.mjs +1 -1
- package/dist/runtime/components/ContextMenu.d.vue.ts +6 -2
- package/dist/runtime/components/ContextMenu.vue.d.ts +6 -2
- package/dist/runtime/components/ContextMenuContent.vue +2 -2
- package/dist/runtime/components/DropdownMenu.d.vue.ts +6 -2
- package/dist/runtime/components/DropdownMenu.vue.d.ts +6 -2
- package/dist/runtime/components/DropdownMenuContent.vue +2 -2
- package/dist/runtime/components/Editor.d.vue.ts +87 -0
- package/dist/runtime/components/Editor.vue +185 -0
- package/dist/runtime/components/Editor.vue.d.ts +87 -0
- package/dist/runtime/components/EditorDragHandle.d.vue.ts +60 -0
- package/dist/runtime/components/EditorDragHandle.vue +128 -0
- package/dist/runtime/components/EditorDragHandle.vue.d.ts +60 -0
- package/dist/runtime/components/EditorEmojiMenu.d.vue.ts +35 -0
- package/dist/runtime/components/EditorEmojiMenu.vue +70 -0
- package/dist/runtime/components/EditorEmojiMenu.vue.d.ts +35 -0
- package/dist/runtime/components/EditorMentionMenu.d.vue.ts +39 -0
- package/dist/runtime/components/EditorMentionMenu.vue +74 -0
- package/dist/runtime/components/EditorMentionMenu.vue.d.ts +39 -0
- package/dist/runtime/components/EditorSuggestionMenu.d.vue.ts +52 -0
- package/dist/runtime/components/EditorSuggestionMenu.vue +79 -0
- package/dist/runtime/components/EditorSuggestionMenu.vue.d.ts +52 -0
- package/dist/runtime/components/EditorToolbar.d.vue.ts +80 -0
- package/dist/runtime/components/EditorToolbar.vue +239 -0
- package/dist/runtime/components/EditorToolbar.vue.d.ts +80 -0
- package/dist/runtime/components/FormField.vue +2 -2
- package/dist/runtime/components/InputMenu.d.vue.ts +2 -0
- package/dist/runtime/components/InputMenu.vue +14 -1
- package/dist/runtime/components/InputMenu.vue.d.ts +2 -0
- package/dist/runtime/components/Pagination.d.vue.ts +0 -1
- package/dist/runtime/components/Pagination.vue.d.ts +0 -1
- package/dist/runtime/components/Select.d.vue.ts +2 -0
- package/dist/runtime/components/Select.vue +14 -1
- package/dist/runtime/components/Select.vue.d.ts +2 -0
- package/dist/runtime/components/SelectMenu.d.vue.ts +2 -0
- package/dist/runtime/components/SelectMenu.vue +14 -1
- package/dist/runtime/components/SelectMenu.vue.d.ts +2 -0
- package/dist/runtime/components/color-mode/ColorModeSelect.vue +1 -0
- package/dist/runtime/components/locale/LocaleSelect.vue +1 -0
- package/dist/runtime/components/prose/Accordion.vue +1 -1
- package/dist/runtime/composables/defineShortcuts.d.ts +1 -0
- package/dist/runtime/composables/defineShortcuts.js +60 -13
- package/dist/runtime/composables/index.d.ts +1 -0
- package/dist/runtime/composables/index.js +1 -0
- package/dist/runtime/composables/useEditorMenu.d.ts +64 -0
- package/dist/runtime/composables/useEditorMenu.js +448 -0
- package/dist/runtime/composables/useSpeechRecognition.d.ts +122 -0
- package/dist/runtime/composables/useSpeechRecognition.js +166 -0
- package/dist/runtime/dictionary/icons.d.ts +1 -0
- package/dist/runtime/dictionary/icons.js +5 -3
- package/dist/runtime/types/editor.d.ts +69 -0
- package/dist/runtime/types/editor.js +0 -0
- package/dist/runtime/types/index.d.ts +7 -0
- package/dist/runtime/types/index.js +7 -0
- package/dist/runtime/utils/editor.d.ts +69 -0
- package/dist/runtime/utils/editor.js +364 -0
- package/dist/runtime/vue/components/color-mode/ColorModeSelect.vue +1 -0
- package/dist/shared/{b24ui-nuxt.BCphUjPy.mjs → b24ui-nuxt.C8MyFqPm.mjs} +185 -1
- package/dist/unplugin.mjs +1 -1
- package/dist/vite.mjs +1 -1
- package/package.json +16 -3
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { AppConfig } from '@nuxt/schema';
|
|
2
|
+
import type { Editor, JSONContent } from '@tiptap/vue-3';
|
|
3
|
+
import type { DragHandleProps } from '@tiptap/extension-drag-handle-vue-3';
|
|
4
|
+
import theme from '#build/b24ui/editor-drag-handle';
|
|
5
|
+
import type { ButtonProps, IconComponent, LinkPropsKeys } from '../types';
|
|
6
|
+
import type { FloatingUIOptions } from '../types/editor';
|
|
7
|
+
import type { ComponentConfig } from '../types/tv';
|
|
8
|
+
type EditorDragHandle = ComponentConfig<typeof theme, AppConfig, 'editorDragHandle'>;
|
|
9
|
+
export interface EditorDragHandleProps extends Omit<DragHandleProps, 'editor' | 'element' | 'onNodeChange' | 'computePositionConfig' | 'class'>, Omit<ButtonProps, LinkPropsKeys | 'icon' | 'color'> {
|
|
10
|
+
/**
|
|
11
|
+
* @defaultValue icons.drag
|
|
12
|
+
* @IconComponent
|
|
13
|
+
*/
|
|
14
|
+
icon?: IconComponent;
|
|
15
|
+
/**
|
|
16
|
+
* @defaultValue 'air-tertiary-no-accent'
|
|
17
|
+
*/
|
|
18
|
+
color?: ButtonProps['color'];
|
|
19
|
+
/**
|
|
20
|
+
* The options for positioning the drag handle. Those are passed to Floating UI and include options for the placement, offset, flip, shift, size, autoPlacement, hide, and inline middleware.
|
|
21
|
+
* @defaultValue { strategy: 'absolute', placement: 'left-start' }
|
|
22
|
+
* @see https://floating-ui.com/docs/computePosition#options
|
|
23
|
+
*/
|
|
24
|
+
options?: FloatingUIOptions;
|
|
25
|
+
editor: Editor;
|
|
26
|
+
b24ui?: EditorDragHandle['slots'] & ButtonProps['b24ui'];
|
|
27
|
+
}
|
|
28
|
+
export interface EditorDragHandleSlots {
|
|
29
|
+
default(props: {
|
|
30
|
+
b24ui: EditorDragHandle['b24ui'];
|
|
31
|
+
onClick: () => {
|
|
32
|
+
node: JSONContent;
|
|
33
|
+
pos: number;
|
|
34
|
+
} | undefined;
|
|
35
|
+
}): any;
|
|
36
|
+
}
|
|
37
|
+
export interface EditorDragHandleEmits {
|
|
38
|
+
nodeChange: [{
|
|
39
|
+
node: JSONContent;
|
|
40
|
+
pos: number;
|
|
41
|
+
}];
|
|
42
|
+
}
|
|
43
|
+
declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<EditorDragHandleProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
44
|
+
nodeChange: (args_0: {
|
|
45
|
+
node: JSONContent;
|
|
46
|
+
pos: number;
|
|
47
|
+
}) => any;
|
|
48
|
+
}, string, import("vue").PublicProps, Readonly<EditorDragHandleProps> & Readonly<{
|
|
49
|
+
onNodeChange?: ((args_0: {
|
|
50
|
+
node: JSONContent;
|
|
51
|
+
pos: number;
|
|
52
|
+
}) => any) | undefined;
|
|
53
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, EditorDragHandleSlots>;
|
|
54
|
+
declare const _default: typeof __VLS_export;
|
|
55
|
+
export default _default;
|
|
56
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
57
|
+
new (): {
|
|
58
|
+
$slots: S;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { AppConfig } from '@nuxt/schema';
|
|
2
|
+
import type { EditorMenuOptions } from '../composables/useEditorMenu';
|
|
3
|
+
import type { ComponentConfig } from '../types/tv';
|
|
4
|
+
import theme from '#build/b24ui/editor-emoji-menu';
|
|
5
|
+
type EditorEmojiMenu = ComponentConfig<typeof theme, AppConfig, 'editorEmojiMenu'>;
|
|
6
|
+
export interface EditorEmojiMenuItem {
|
|
7
|
+
name: string;
|
|
8
|
+
emoji?: string;
|
|
9
|
+
shortcodes: string[];
|
|
10
|
+
tags: string[];
|
|
11
|
+
group?: string;
|
|
12
|
+
fallbackImage?: string;
|
|
13
|
+
[key: string]: any;
|
|
14
|
+
}
|
|
15
|
+
export interface EditorEmojiMenuProps<T extends EditorEmojiMenuItem = EditorEmojiMenuItem> extends Partial<Pick<EditorMenuOptions<T>, 'editor' | 'char' | 'pluginKey' | 'filterFields' | 'limit' | 'options' | 'appendTo'>> {
|
|
16
|
+
items?: T[] | T[][];
|
|
17
|
+
class?: any;
|
|
18
|
+
b24ui?: EditorEmojiMenu['slots'];
|
|
19
|
+
}
|
|
20
|
+
declare const __VLS_export: <T extends EditorEmojiMenuItem>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
21
|
+
props: __VLS_PrettifyLocal<EditorEmojiMenuProps<T>> & import("vue").PublicProps & (typeof globalThis extends {
|
|
22
|
+
__VLS_PROPS_FALLBACK: infer P;
|
|
23
|
+
} ? P : {});
|
|
24
|
+
expose: (exposed: {}) => void;
|
|
25
|
+
attrs: any;
|
|
26
|
+
slots: {};
|
|
27
|
+
emit: {};
|
|
28
|
+
}>) => import("vue").VNode & {
|
|
29
|
+
__ctx?: Awaited<typeof __VLS_setup>;
|
|
30
|
+
};
|
|
31
|
+
declare const _default: typeof __VLS_export;
|
|
32
|
+
export default _default;
|
|
33
|
+
type __VLS_PrettifyLocal<T> = {
|
|
34
|
+
[K in keyof T as K]: T[K];
|
|
35
|
+
} & {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import theme from "#build/b24ui/editor-emoji-menu";
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<script setup>
|
|
6
|
+
import { computed, h, onMounted, onBeforeUnmount, nextTick, toRef } from "vue";
|
|
7
|
+
import { useAppConfig } from "#imports";
|
|
8
|
+
import { useEditorMenu } from "../composables/useEditorMenu";
|
|
9
|
+
import { tv } from "../utils/tv";
|
|
10
|
+
defineOptions({ inheritAttrs: false });
|
|
11
|
+
const props = defineProps({
|
|
12
|
+
items: { type: Array, required: false },
|
|
13
|
+
class: { type: null, required: false },
|
|
14
|
+
b24ui: { type: null, required: false },
|
|
15
|
+
editor: { type: Object, required: false },
|
|
16
|
+
char: { type: String, required: false, default: ":" },
|
|
17
|
+
pluginKey: { type: String, required: false, default: "emojiMenu" },
|
|
18
|
+
filterFields: { type: Array, required: false, default: () => ["name", "shortcodes", "tags"] },
|
|
19
|
+
limit: { type: Number, required: false },
|
|
20
|
+
options: { type: Object, required: false },
|
|
21
|
+
appendTo: { type: Function, required: false, skipCheck: true }
|
|
22
|
+
});
|
|
23
|
+
const appConfig = useAppConfig();
|
|
24
|
+
const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.editorEmojiMenu || {} })());
|
|
25
|
+
let menu = null;
|
|
26
|
+
onMounted(async () => {
|
|
27
|
+
await nextTick();
|
|
28
|
+
if (!props.editor || props.editor.isDestroyed) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
menu = useEditorMenu({
|
|
32
|
+
editor: props.editor,
|
|
33
|
+
char: props.char,
|
|
34
|
+
pluginKey: props.pluginKey,
|
|
35
|
+
items: toRef(() => props.items),
|
|
36
|
+
filterFields: props.filterFields,
|
|
37
|
+
limit: props.limit,
|
|
38
|
+
options: props.options,
|
|
39
|
+
appendTo: props.appendTo,
|
|
40
|
+
b24ui,
|
|
41
|
+
onSelect: (editor, range, item) => {
|
|
42
|
+
if (!item.emoji) return;
|
|
43
|
+
editor.chain().focus().deleteRange(range).insertContent(item.emoji).run();
|
|
44
|
+
},
|
|
45
|
+
renderItem: (item, styles) => {
|
|
46
|
+
const content = item.emoji || item.shortcodes[0] || item.name;
|
|
47
|
+
return [
|
|
48
|
+
h("span", { class: styles.value.itemLeadingIcon() }, content),
|
|
49
|
+
h("span", { class: styles.value.itemWrapper() }, [
|
|
50
|
+
h("span", { class: styles.value.itemLabel() }, item.name)
|
|
51
|
+
])
|
|
52
|
+
];
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
props.editor.registerPlugin(menu.plugin);
|
|
56
|
+
});
|
|
57
|
+
onBeforeUnmount(() => {
|
|
58
|
+
if (menu) {
|
|
59
|
+
menu.destroy();
|
|
60
|
+
menu = null;
|
|
61
|
+
}
|
|
62
|
+
if (props.editor && !props.editor.isDestroyed) {
|
|
63
|
+
props.editor.unregisterPlugin(props.pluginKey);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
</script>
|
|
67
|
+
|
|
68
|
+
<template>
|
|
69
|
+
<div />
|
|
70
|
+
</template>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { AppConfig } from '@nuxt/schema';
|
|
2
|
+
import type { EditorMenuOptions } from '../composables/useEditorMenu';
|
|
3
|
+
import type { ComponentConfig } from '../types/tv';
|
|
4
|
+
import theme from '#build/b24ui/editor-emoji-menu';
|
|
5
|
+
type EditorEmojiMenu = ComponentConfig<typeof theme, AppConfig, 'editorEmojiMenu'>;
|
|
6
|
+
export interface EditorEmojiMenuItem {
|
|
7
|
+
name: string;
|
|
8
|
+
emoji?: string;
|
|
9
|
+
shortcodes: string[];
|
|
10
|
+
tags: string[];
|
|
11
|
+
group?: string;
|
|
12
|
+
fallbackImage?: string;
|
|
13
|
+
[key: string]: any;
|
|
14
|
+
}
|
|
15
|
+
export interface EditorEmojiMenuProps<T extends EditorEmojiMenuItem = EditorEmojiMenuItem> extends Partial<Pick<EditorMenuOptions<T>, 'editor' | 'char' | 'pluginKey' | 'filterFields' | 'limit' | 'options' | 'appendTo'>> {
|
|
16
|
+
items?: T[] | T[][];
|
|
17
|
+
class?: any;
|
|
18
|
+
b24ui?: EditorEmojiMenu['slots'];
|
|
19
|
+
}
|
|
20
|
+
declare const __VLS_export: <T extends EditorEmojiMenuItem>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
21
|
+
props: __VLS_PrettifyLocal<EditorEmojiMenuProps<T>> & import("vue").PublicProps & (typeof globalThis extends {
|
|
22
|
+
__VLS_PROPS_FALLBACK: infer P;
|
|
23
|
+
} ? P : {});
|
|
24
|
+
expose: (exposed: {}) => void;
|
|
25
|
+
attrs: any;
|
|
26
|
+
slots: {};
|
|
27
|
+
emit: {};
|
|
28
|
+
}>) => import("vue").VNode & {
|
|
29
|
+
__ctx?: Awaited<typeof __VLS_setup>;
|
|
30
|
+
};
|
|
31
|
+
declare const _default: typeof __VLS_export;
|
|
32
|
+
export default _default;
|
|
33
|
+
type __VLS_PrettifyLocal<T> = {
|
|
34
|
+
[K in keyof T as K]: T[K];
|
|
35
|
+
} & {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { AppConfig } from '@nuxt/schema';
|
|
2
|
+
import theme from '#build/b24ui/editor-mention-menu';
|
|
3
|
+
import type { EditorMenuOptions } from '../composables/useEditorMenu';
|
|
4
|
+
import type { AvatarProps, IconComponent } from '../types';
|
|
5
|
+
import type { ComponentConfig } from '../types/tv';
|
|
6
|
+
type EditorMentionMenu = ComponentConfig<typeof theme, AppConfig, 'editorMentionMenu'>;
|
|
7
|
+
export interface EditorMentionMenuItem {
|
|
8
|
+
label: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
/**
|
|
11
|
+
* @IconComponent
|
|
12
|
+
*/
|
|
13
|
+
icon?: IconComponent;
|
|
14
|
+
avatar?: AvatarProps;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
class?: any;
|
|
17
|
+
[key: string]: any;
|
|
18
|
+
}
|
|
19
|
+
export interface EditorMentionMenuProps<T extends EditorMentionMenuItem = EditorMentionMenuItem> extends Partial<Pick<EditorMenuOptions<T>, 'editor' | 'char' | 'pluginKey' | 'filterFields' | 'limit' | 'options' | 'appendTo'>> {
|
|
20
|
+
items?: T[] | T[][];
|
|
21
|
+
class?: any;
|
|
22
|
+
b24ui?: EditorMentionMenu['slots'];
|
|
23
|
+
}
|
|
24
|
+
declare const __VLS_export: <T extends EditorMentionMenuItem>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
25
|
+
props: __VLS_PrettifyLocal<EditorMentionMenuProps<T>> & import("vue").PublicProps & (typeof globalThis extends {
|
|
26
|
+
__VLS_PROPS_FALLBACK: infer P;
|
|
27
|
+
} ? P : {});
|
|
28
|
+
expose: (exposed: {}) => void;
|
|
29
|
+
attrs: any;
|
|
30
|
+
slots: {};
|
|
31
|
+
emit: {};
|
|
32
|
+
}>) => import("vue").VNode & {
|
|
33
|
+
__ctx?: Awaited<typeof __VLS_setup>;
|
|
34
|
+
};
|
|
35
|
+
declare const _default: typeof __VLS_export;
|
|
36
|
+
export default _default;
|
|
37
|
+
type __VLS_PrettifyLocal<T> = {
|
|
38
|
+
[K in keyof T as K]: T[K];
|
|
39
|
+
} & {};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import theme from "#build/b24ui/editor-mention-menu";
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<script setup>
|
|
6
|
+
import { computed, h, onMounted, onBeforeUnmount, nextTick, toRef } from "vue";
|
|
7
|
+
import { useAppConfig } from "#imports";
|
|
8
|
+
import { useEditorMenu } from "../composables/useEditorMenu";
|
|
9
|
+
import { tv } from "../utils/tv";
|
|
10
|
+
import B24Avatar from "./Avatar.vue";
|
|
11
|
+
defineOptions({ inheritAttrs: false });
|
|
12
|
+
const props = defineProps({
|
|
13
|
+
items: { type: Array, required: false },
|
|
14
|
+
class: { type: null, required: false },
|
|
15
|
+
b24ui: { type: null, required: false },
|
|
16
|
+
editor: { type: Object, required: false },
|
|
17
|
+
char: { type: String, required: false, default: "@" },
|
|
18
|
+
pluginKey: { type: String, required: false, default: "mentionMenu" },
|
|
19
|
+
filterFields: { type: Array, required: false },
|
|
20
|
+
limit: { type: Number, required: false },
|
|
21
|
+
options: { type: Object, required: false },
|
|
22
|
+
appendTo: { type: Function, required: false, skipCheck: true }
|
|
23
|
+
});
|
|
24
|
+
const appConfig = useAppConfig();
|
|
25
|
+
const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.editorMentionMenu || {} })());
|
|
26
|
+
let menu = null;
|
|
27
|
+
onMounted(async () => {
|
|
28
|
+
await nextTick();
|
|
29
|
+
if (!props.editor || props.editor.isDestroyed) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
menu = useEditorMenu({
|
|
33
|
+
editor: props.editor,
|
|
34
|
+
char: props.char,
|
|
35
|
+
pluginKey: props.pluginKey,
|
|
36
|
+
items: toRef(() => props.items),
|
|
37
|
+
filterFields: props.filterFields,
|
|
38
|
+
limit: props.limit,
|
|
39
|
+
options: props.options,
|
|
40
|
+
appendTo: props.appendTo,
|
|
41
|
+
b24ui,
|
|
42
|
+
onSelect: (editor, range, item) => {
|
|
43
|
+
editor.chain().focus().deleteRange(range).insertContent({
|
|
44
|
+
type: "mention",
|
|
45
|
+
attrs: item
|
|
46
|
+
}).run();
|
|
47
|
+
},
|
|
48
|
+
renderItem: (item, styles) => [
|
|
49
|
+
/**
|
|
50
|
+
* @memo Icon - first, Avatar - second
|
|
51
|
+
*/
|
|
52
|
+
item.icon ? h(item.icon, { class: styles.value.itemLeadingIcon() }) : item.avatar ? h(B24Avatar, { ...item.avatar, size: styles.value.itemLeadingAvatarSize(), class: styles.value.itemLeadingAvatar() }) : null,
|
|
53
|
+
h("span", { class: styles.value.itemWrapper() }, [
|
|
54
|
+
h("span", { class: styles.value.itemLabel() }, item.label),
|
|
55
|
+
item.description ? h("span", { class: styles.value.itemDescription() }, item.description) : null
|
|
56
|
+
])
|
|
57
|
+
]
|
|
58
|
+
});
|
|
59
|
+
props.editor.registerPlugin(menu.plugin);
|
|
60
|
+
});
|
|
61
|
+
onBeforeUnmount(() => {
|
|
62
|
+
if (menu) {
|
|
63
|
+
menu.destroy();
|
|
64
|
+
menu = null;
|
|
65
|
+
}
|
|
66
|
+
if (props.editor && !props.editor.isDestroyed) {
|
|
67
|
+
props.editor.unregisterPlugin(props.pluginKey);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
</script>
|
|
71
|
+
|
|
72
|
+
<template>
|
|
73
|
+
<div />
|
|
74
|
+
</template>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { AppConfig } from '@nuxt/schema';
|
|
2
|
+
import theme from '#build/b24ui/editor-mention-menu';
|
|
3
|
+
import type { EditorMenuOptions } from '../composables/useEditorMenu';
|
|
4
|
+
import type { AvatarProps, IconComponent } from '../types';
|
|
5
|
+
import type { ComponentConfig } from '../types/tv';
|
|
6
|
+
type EditorMentionMenu = ComponentConfig<typeof theme, AppConfig, 'editorMentionMenu'>;
|
|
7
|
+
export interface EditorMentionMenuItem {
|
|
8
|
+
label: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
/**
|
|
11
|
+
* @IconComponent
|
|
12
|
+
*/
|
|
13
|
+
icon?: IconComponent;
|
|
14
|
+
avatar?: AvatarProps;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
class?: any;
|
|
17
|
+
[key: string]: any;
|
|
18
|
+
}
|
|
19
|
+
export interface EditorMentionMenuProps<T extends EditorMentionMenuItem = EditorMentionMenuItem> extends Partial<Pick<EditorMenuOptions<T>, 'editor' | 'char' | 'pluginKey' | 'filterFields' | 'limit' | 'options' | 'appendTo'>> {
|
|
20
|
+
items?: T[] | T[][];
|
|
21
|
+
class?: any;
|
|
22
|
+
b24ui?: EditorMentionMenu['slots'];
|
|
23
|
+
}
|
|
24
|
+
declare const __VLS_export: <T extends EditorMentionMenuItem>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
25
|
+
props: __VLS_PrettifyLocal<EditorMentionMenuProps<T>> & import("vue").PublicProps & (typeof globalThis extends {
|
|
26
|
+
__VLS_PROPS_FALLBACK: infer P;
|
|
27
|
+
} ? P : {});
|
|
28
|
+
expose: (exposed: {}) => void;
|
|
29
|
+
attrs: any;
|
|
30
|
+
slots: {};
|
|
31
|
+
emit: {};
|
|
32
|
+
}>) => import("vue").VNode & {
|
|
33
|
+
__ctx?: Awaited<typeof __VLS_setup>;
|
|
34
|
+
};
|
|
35
|
+
declare const _default: typeof __VLS_export;
|
|
36
|
+
export default _default;
|
|
37
|
+
type __VLS_PrettifyLocal<T> = {
|
|
38
|
+
[K in keyof T as K]: T[K];
|
|
39
|
+
} & {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { AppConfig } from '@nuxt/schema';
|
|
2
|
+
import theme from '#build/b24ui/editor-suggestion-menu';
|
|
3
|
+
import type { EditorMenuOptions } from '../composables/useEditorMenu';
|
|
4
|
+
import type { IconComponent } from '../types';
|
|
5
|
+
import type { EditorItem, EditorCustomHandlers } from '../types/editor';
|
|
6
|
+
import type { ComponentConfig } from '../types/tv';
|
|
7
|
+
type EditorSuggestionMenu = ComponentConfig<typeof theme, AppConfig, 'editorSuggestionMenu'>;
|
|
8
|
+
type EditorSuggestionMenuLabelItem = {
|
|
9
|
+
type: 'label';
|
|
10
|
+
label: string;
|
|
11
|
+
class?: any;
|
|
12
|
+
[key: string]: any;
|
|
13
|
+
};
|
|
14
|
+
type EditorSuggestionMenuSeparatorItem = {
|
|
15
|
+
type: 'separator';
|
|
16
|
+
class?: any;
|
|
17
|
+
[key: string]: any;
|
|
18
|
+
};
|
|
19
|
+
type EditorSuggestionMenuActionItem<H extends EditorCustomHandlers = EditorCustomHandlers> = {
|
|
20
|
+
type?: never;
|
|
21
|
+
label: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
/**
|
|
24
|
+
* @IconComponent
|
|
25
|
+
*/
|
|
26
|
+
icon?: IconComponent;
|
|
27
|
+
disabled?: boolean;
|
|
28
|
+
class?: any;
|
|
29
|
+
[key: string]: any;
|
|
30
|
+
} & EditorItem<H>;
|
|
31
|
+
export type EditorSuggestionMenuItem<H extends EditorCustomHandlers = EditorCustomHandlers> = EditorSuggestionMenuLabelItem | EditorSuggestionMenuSeparatorItem | EditorSuggestionMenuActionItem<H>;
|
|
32
|
+
export interface EditorSuggestionMenuProps<T extends EditorSuggestionMenuItem = EditorSuggestionMenuItem> extends Partial<Pick<EditorMenuOptions<T>, 'editor' | 'char' | 'pluginKey' | 'filterFields' | 'limit' | 'options' | 'appendTo'>> {
|
|
33
|
+
items?: T[] | T[][];
|
|
34
|
+
class?: any;
|
|
35
|
+
b24ui?: EditorSuggestionMenu['slots'];
|
|
36
|
+
}
|
|
37
|
+
declare const __VLS_export: <T extends EditorSuggestionMenuItem>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
38
|
+
props: __VLS_PrettifyLocal<EditorSuggestionMenuProps<T>> & import("vue").PublicProps & (typeof globalThis extends {
|
|
39
|
+
__VLS_PROPS_FALLBACK: infer P;
|
|
40
|
+
} ? P : {});
|
|
41
|
+
expose: (exposed: {}) => void;
|
|
42
|
+
attrs: any;
|
|
43
|
+
slots: {};
|
|
44
|
+
emit: {};
|
|
45
|
+
}>) => import("vue").VNode & {
|
|
46
|
+
__ctx?: Awaited<typeof __VLS_setup>;
|
|
47
|
+
};
|
|
48
|
+
declare const _default: typeof __VLS_export;
|
|
49
|
+
export default _default;
|
|
50
|
+
type __VLS_PrettifyLocal<T> = {
|
|
51
|
+
[K in keyof T as K]: T[K];
|
|
52
|
+
} & {};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import theme from "#build/b24ui/editor-suggestion-menu";
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<script setup>
|
|
6
|
+
import { computed, h, inject, onMounted, onBeforeUnmount, nextTick, toRef } from "vue";
|
|
7
|
+
import { useAppConfig } from "#imports";
|
|
8
|
+
import { useEditorMenu } from "../composables/useEditorMenu";
|
|
9
|
+
import { createHandlers } from "../utils/editor";
|
|
10
|
+
import { tv } from "../utils/tv";
|
|
11
|
+
defineOptions({ inheritAttrs: false });
|
|
12
|
+
const props = defineProps({
|
|
13
|
+
items: { type: Array, required: false },
|
|
14
|
+
class: { type: null, required: false },
|
|
15
|
+
b24ui: { type: null, required: false },
|
|
16
|
+
editor: { type: Object, required: false },
|
|
17
|
+
char: { type: String, required: false, default: "/" },
|
|
18
|
+
pluginKey: { type: String, required: false, default: "suggestionMenu" },
|
|
19
|
+
filterFields: { type: Array, required: false },
|
|
20
|
+
limit: { type: Number, required: false },
|
|
21
|
+
options: { type: Object, required: false },
|
|
22
|
+
appendTo: { type: Function, required: false, skipCheck: true }
|
|
23
|
+
});
|
|
24
|
+
const appConfig = useAppConfig();
|
|
25
|
+
const handlers = inject("editorHandlers", computed(() => createHandlers()));
|
|
26
|
+
const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.editorSuggestionMenu || {} })());
|
|
27
|
+
let menu = null;
|
|
28
|
+
onMounted(async () => {
|
|
29
|
+
await nextTick();
|
|
30
|
+
if (!props.editor || props.editor.isDestroyed) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
menu = useEditorMenu({
|
|
34
|
+
editor: props.editor,
|
|
35
|
+
char: props.char,
|
|
36
|
+
pluginKey: props.pluginKey,
|
|
37
|
+
items: toRef(() => props.items),
|
|
38
|
+
filterFields: props.filterFields,
|
|
39
|
+
limit: props.limit,
|
|
40
|
+
options: props.options,
|
|
41
|
+
appendTo: props.appendTo,
|
|
42
|
+
b24ui,
|
|
43
|
+
onSelect: (editor, range, item) => {
|
|
44
|
+
if (item.type === "label" || item.type === "separator") return;
|
|
45
|
+
editor.chain().focus().deleteRange(range).run();
|
|
46
|
+
const handler = handlers?.value?.[item.kind];
|
|
47
|
+
if (handler) {
|
|
48
|
+
handler.execute(editor, item).run();
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
renderItem: (item, styles) => {
|
|
52
|
+
if (item.type === "label") {
|
|
53
|
+
return [h("span", {}, item.label)];
|
|
54
|
+
}
|
|
55
|
+
return [
|
|
56
|
+
item.icon ? h(item.icon, { class: styles.value.itemLeadingIcon() }) : null,
|
|
57
|
+
h("span", { class: styles.value.itemWrapper() }, [
|
|
58
|
+
h("span", { class: styles.value.itemLabel() }, item.label),
|
|
59
|
+
item.description ? h("span", { class: styles.value.itemDescription() }, item.description) : null
|
|
60
|
+
])
|
|
61
|
+
];
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
props.editor.registerPlugin(menu.plugin);
|
|
65
|
+
});
|
|
66
|
+
onBeforeUnmount(() => {
|
|
67
|
+
if (menu) {
|
|
68
|
+
menu.destroy();
|
|
69
|
+
menu = null;
|
|
70
|
+
}
|
|
71
|
+
if (props.editor && !props.editor.isDestroyed) {
|
|
72
|
+
props.editor.unregisterPlugin(props.pluginKey);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
</script>
|
|
76
|
+
|
|
77
|
+
<template>
|
|
78
|
+
<div />
|
|
79
|
+
</template>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { AppConfig } from '@nuxt/schema';
|
|
2
|
+
import theme from '#build/b24ui/editor-suggestion-menu';
|
|
3
|
+
import type { EditorMenuOptions } from '../composables/useEditorMenu';
|
|
4
|
+
import type { IconComponent } from '../types';
|
|
5
|
+
import type { EditorItem, EditorCustomHandlers } from '../types/editor';
|
|
6
|
+
import type { ComponentConfig } from '../types/tv';
|
|
7
|
+
type EditorSuggestionMenu = ComponentConfig<typeof theme, AppConfig, 'editorSuggestionMenu'>;
|
|
8
|
+
type EditorSuggestionMenuLabelItem = {
|
|
9
|
+
type: 'label';
|
|
10
|
+
label: string;
|
|
11
|
+
class?: any;
|
|
12
|
+
[key: string]: any;
|
|
13
|
+
};
|
|
14
|
+
type EditorSuggestionMenuSeparatorItem = {
|
|
15
|
+
type: 'separator';
|
|
16
|
+
class?: any;
|
|
17
|
+
[key: string]: any;
|
|
18
|
+
};
|
|
19
|
+
type EditorSuggestionMenuActionItem<H extends EditorCustomHandlers = EditorCustomHandlers> = {
|
|
20
|
+
type?: never;
|
|
21
|
+
label: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
/**
|
|
24
|
+
* @IconComponent
|
|
25
|
+
*/
|
|
26
|
+
icon?: IconComponent;
|
|
27
|
+
disabled?: boolean;
|
|
28
|
+
class?: any;
|
|
29
|
+
[key: string]: any;
|
|
30
|
+
} & EditorItem<H>;
|
|
31
|
+
export type EditorSuggestionMenuItem<H extends EditorCustomHandlers = EditorCustomHandlers> = EditorSuggestionMenuLabelItem | EditorSuggestionMenuSeparatorItem | EditorSuggestionMenuActionItem<H>;
|
|
32
|
+
export interface EditorSuggestionMenuProps<T extends EditorSuggestionMenuItem = EditorSuggestionMenuItem> extends Partial<Pick<EditorMenuOptions<T>, 'editor' | 'char' | 'pluginKey' | 'filterFields' | 'limit' | 'options' | 'appendTo'>> {
|
|
33
|
+
items?: T[] | T[][];
|
|
34
|
+
class?: any;
|
|
35
|
+
b24ui?: EditorSuggestionMenu['slots'];
|
|
36
|
+
}
|
|
37
|
+
declare const __VLS_export: <T extends EditorSuggestionMenuItem>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
38
|
+
props: __VLS_PrettifyLocal<EditorSuggestionMenuProps<T>> & import("vue").PublicProps & (typeof globalThis extends {
|
|
39
|
+
__VLS_PROPS_FALLBACK: infer P;
|
|
40
|
+
} ? P : {});
|
|
41
|
+
expose: (exposed: {}) => void;
|
|
42
|
+
attrs: any;
|
|
43
|
+
slots: {};
|
|
44
|
+
emit: {};
|
|
45
|
+
}>) => import("vue").VNode & {
|
|
46
|
+
__ctx?: Awaited<typeof __VLS_setup>;
|
|
47
|
+
};
|
|
48
|
+
declare const _default: typeof __VLS_export;
|
|
49
|
+
export default _default;
|
|
50
|
+
type __VLS_PrettifyLocal<T> = {
|
|
51
|
+
[K in keyof T as K]: T[K];
|
|
52
|
+
} & {};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { AppConfig } from '@nuxt/schema';
|
|
2
|
+
import type { Editor } from '@tiptap/vue-3';
|
|
3
|
+
import type { BubbleMenuPluginProps } from '@tiptap/extension-bubble-menu';
|
|
4
|
+
import type { FloatingMenuPluginProps } from '@tiptap/extension-floating-menu';
|
|
5
|
+
import theme from '#build/b24ui/editor-toolbar';
|
|
6
|
+
import type { ButtonProps, DropdownMenuProps, DropdownMenuItem, TooltipProps, LinkPropsKeys } from '../types';
|
|
7
|
+
import type { EditorItem, EditorCustomHandlers } from '../types/editor';
|
|
8
|
+
import type { ArrayOrNested, DynamicSlots, MergeTypes, NestedItem } from '../types/utils';
|
|
9
|
+
import type { ComponentConfig } from '../types/tv';
|
|
10
|
+
type EditorToolbar = ComponentConfig<typeof theme, AppConfig, 'editorToolbar'>;
|
|
11
|
+
type ButtonItem = Omit<ButtonProps, 'type'> & {
|
|
12
|
+
'slot'?: string;
|
|
13
|
+
'tooltip'?: TooltipProps;
|
|
14
|
+
'aria-label'?: string;
|
|
15
|
+
};
|
|
16
|
+
type EditorToolbarButtonItem<H extends EditorCustomHandlers = EditorCustomHandlers> = Omit<ButtonItem, LinkPropsKeys> & EditorItem<H>;
|
|
17
|
+
type EditorToolbarDropdownChildItem<H extends EditorCustomHandlers = EditorCustomHandlers> = DropdownMenuItem | (Omit<DropdownMenuItem, 'type'> & EditorItem<H>);
|
|
18
|
+
type EditorToolbarDropdownItem<H extends EditorCustomHandlers = EditorCustomHandlers> = ButtonItem & DropdownMenuProps<ArrayOrNested<EditorToolbarDropdownChildItem<H>>>;
|
|
19
|
+
export type EditorToolbarItem<H extends EditorCustomHandlers = EditorCustomHandlers> = ButtonItem | EditorToolbarButtonItem<H> | EditorToolbarDropdownItem<H>;
|
|
20
|
+
type EditorToolbarBaseProps<T extends ArrayOrNested<EditorToolbarItem> = ArrayOrNested<EditorToolbarItem>> = {
|
|
21
|
+
/**
|
|
22
|
+
* The element or component this component should render as.
|
|
23
|
+
* @defaultValue 'div'
|
|
24
|
+
*/
|
|
25
|
+
as?: any;
|
|
26
|
+
/**
|
|
27
|
+
* The color of the toolbar controls.
|
|
28
|
+
* @defaultValue 'air-tertiary-no-accent'
|
|
29
|
+
*/
|
|
30
|
+
color?: ButtonProps['color'];
|
|
31
|
+
/**
|
|
32
|
+
* The color of the active toolbar control.
|
|
33
|
+
* @defaultValue 'air-primary'
|
|
34
|
+
*/
|
|
35
|
+
activeColor?: ButtonProps['color'];
|
|
36
|
+
/**
|
|
37
|
+
* The size of the toolbar controls.
|
|
38
|
+
* @defaultValue 'sm'
|
|
39
|
+
*/
|
|
40
|
+
size?: ButtonProps['size'];
|
|
41
|
+
items?: T;
|
|
42
|
+
editor: Editor;
|
|
43
|
+
class?: any;
|
|
44
|
+
b24ui?: EditorToolbar['slots'];
|
|
45
|
+
};
|
|
46
|
+
export type EditorToolbarProps<T extends ArrayOrNested<EditorToolbarItem> = ArrayOrNested<EditorToolbarItem>> = (EditorToolbarBaseProps<T> & {
|
|
47
|
+
layout?: 'fixed';
|
|
48
|
+
}) | (EditorToolbarBaseProps<T> & Partial<Omit<BubbleMenuPluginProps, 'editor' | 'element'>> & {
|
|
49
|
+
layout?: 'bubble';
|
|
50
|
+
}) | (EditorToolbarBaseProps<T> & Partial<Omit<FloatingMenuPluginProps, 'editor' | 'element'>> & {
|
|
51
|
+
layout?: 'floating';
|
|
52
|
+
});
|
|
53
|
+
type SlotPropsProps = {
|
|
54
|
+
index: number;
|
|
55
|
+
isActive: (item: EditorToolbarItem) => boolean;
|
|
56
|
+
isDisabled: (item: EditorToolbarItem) => boolean;
|
|
57
|
+
onClick: (e: MouseEvent, item: EditorToolbarItem) => void;
|
|
58
|
+
};
|
|
59
|
+
type SlotProps<T extends EditorToolbarItem> = (props: {
|
|
60
|
+
item: T;
|
|
61
|
+
} & SlotPropsProps) => any;
|
|
62
|
+
export type EditorToolbarSlots<A extends ArrayOrNested<EditorToolbarItem> = ArrayOrNested<EditorToolbarItem>, T extends NestedItem<A> = NestedItem<A>> = {
|
|
63
|
+
item: SlotProps<T>;
|
|
64
|
+
} & DynamicSlots<MergeTypes<T>, undefined, SlotPropsProps>;
|
|
65
|
+
declare const __VLS_export: <T extends ArrayOrNested<EditorToolbarItem>>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
66
|
+
props: __VLS_PrettifyLocal<EditorToolbarProps<T>> & import("vue").PublicProps & (typeof globalThis extends {
|
|
67
|
+
__VLS_PROPS_FALLBACK: infer P;
|
|
68
|
+
} ? P : {});
|
|
69
|
+
expose: (exposed: {}) => void;
|
|
70
|
+
attrs: any;
|
|
71
|
+
slots: EditorToolbarSlots<T, NestedItem<T>>;
|
|
72
|
+
emit: {};
|
|
73
|
+
}>) => import("vue").VNode & {
|
|
74
|
+
__ctx?: Awaited<typeof __VLS_setup>;
|
|
75
|
+
};
|
|
76
|
+
declare const _default: typeof __VLS_export;
|
|
77
|
+
export default _default;
|
|
78
|
+
type __VLS_PrettifyLocal<T> = {
|
|
79
|
+
[K in keyof T as K]: T[K];
|
|
80
|
+
} & {};
|