@bitrix24/b24ui-nuxt 2.1.11 → 2.1.15

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 (78) hide show
  1. package/.nuxt/b24ui.css +2 -0
  2. package/README-AI.md +1 -1
  3. package/dist/meta.d.mts +98705 -785
  4. package/dist/meta.mjs +98705 -785
  5. package/dist/module.json +1 -1
  6. package/dist/module.mjs +1 -1
  7. package/dist/runtime/air-design-tokens/003_b24_context_light.css +1 -1
  8. package/dist/runtime/air-design-tokens/004_b24_context_dark.css +1 -1
  9. package/dist/runtime/air-design-tokens/components/popup.css +1 -1
  10. package/dist/runtime/air-design-tokens/tw-style/font-size.css +1 -1
  11. package/dist/runtime/components/ContextMenu.d.vue.ts +6 -2
  12. package/dist/runtime/components/ContextMenu.vue.d.ts +6 -2
  13. package/dist/runtime/components/ContextMenuContent.vue +3 -2
  14. package/dist/runtime/components/DropdownMenu.d.vue.ts +6 -2
  15. package/dist/runtime/components/DropdownMenu.vue +2 -2
  16. package/dist/runtime/components/DropdownMenu.vue.d.ts +6 -2
  17. package/dist/runtime/components/DropdownMenuContent.vue +5 -4
  18. package/dist/runtime/components/Editor.d.vue.ts +87 -0
  19. package/dist/runtime/components/Editor.vue +185 -0
  20. package/dist/runtime/components/Editor.vue.d.ts +87 -0
  21. package/dist/runtime/components/EditorDragHandle.d.vue.ts +60 -0
  22. package/dist/runtime/components/EditorDragHandle.vue +128 -0
  23. package/dist/runtime/components/EditorDragHandle.vue.d.ts +60 -0
  24. package/dist/runtime/components/EditorEmojiMenu.d.vue.ts +35 -0
  25. package/dist/runtime/components/EditorEmojiMenu.vue +70 -0
  26. package/dist/runtime/components/EditorEmojiMenu.vue.d.ts +35 -0
  27. package/dist/runtime/components/EditorMentionMenu.d.vue.ts +39 -0
  28. package/dist/runtime/components/EditorMentionMenu.vue +74 -0
  29. package/dist/runtime/components/EditorMentionMenu.vue.d.ts +39 -0
  30. package/dist/runtime/components/EditorSuggestionMenu.d.vue.ts +52 -0
  31. package/dist/runtime/components/EditorSuggestionMenu.vue +79 -0
  32. package/dist/runtime/components/EditorSuggestionMenu.vue.d.ts +52 -0
  33. package/dist/runtime/components/EditorToolbar.d.vue.ts +80 -0
  34. package/dist/runtime/components/EditorToolbar.vue +241 -0
  35. package/dist/runtime/components/EditorToolbar.vue.d.ts +80 -0
  36. package/dist/runtime/components/FormField.vue +2 -2
  37. package/dist/runtime/components/InputMenu.d.vue.ts +2 -0
  38. package/dist/runtime/components/InputMenu.vue +14 -1
  39. package/dist/runtime/components/InputMenu.vue.d.ts +2 -0
  40. package/dist/runtime/components/PageCard.vue +2 -1
  41. package/dist/runtime/components/Pagination.d.vue.ts +0 -1
  42. package/dist/runtime/components/Pagination.vue.d.ts +0 -1
  43. package/dist/runtime/components/Select.d.vue.ts +2 -0
  44. package/dist/runtime/components/Select.vue +14 -1
  45. package/dist/runtime/components/Select.vue.d.ts +2 -0
  46. package/dist/runtime/components/SelectMenu.d.vue.ts +2 -0
  47. package/dist/runtime/components/SelectMenu.vue +14 -1
  48. package/dist/runtime/components/SelectMenu.vue.d.ts +2 -0
  49. package/dist/runtime/components/User.vue +0 -1
  50. package/dist/runtime/components/color-mode/ColorModeSelect.vue +1 -0
  51. package/dist/runtime/components/locale/LocaleSelect.vue +6 -3
  52. package/dist/runtime/components/prose/Accordion.vue +1 -1
  53. package/dist/runtime/components/prose/Callout.vue +0 -1
  54. package/dist/runtime/components/prose/Card.vue +0 -1
  55. package/dist/runtime/composables/defineShortcuts.d.ts +2 -1
  56. package/dist/runtime/composables/defineShortcuts.js +62 -15
  57. package/dist/runtime/composables/useEditorMenu.d.ts +64 -0
  58. package/dist/runtime/composables/useEditorMenu.js +448 -0
  59. package/dist/runtime/dictionary/icons.d.ts +1 -0
  60. package/dist/runtime/dictionary/icons.js +5 -3
  61. package/dist/runtime/locale/in.d.ts +3 -0
  62. package/dist/runtime/locale/in.js +136 -0
  63. package/dist/runtime/locale/index.d.ts +25 -23
  64. package/dist/runtime/locale/index.js +11 -10
  65. package/dist/runtime/types/editor.d.ts +69 -0
  66. package/dist/runtime/types/editor.js +0 -0
  67. package/dist/runtime/types/index.d.ts +7 -0
  68. package/dist/runtime/types/index.js +7 -0
  69. package/dist/runtime/types/prose.d.ts +2 -0
  70. package/dist/runtime/types/prose.js +2 -0
  71. package/dist/runtime/utils/editor.d.ts +69 -0
  72. package/dist/runtime/utils/editor.js +364 -0
  73. package/dist/runtime/utils/tv.js +2 -1
  74. package/dist/runtime/vue/components/color-mode/ColorModeSelect.vue +1 -0
  75. package/dist/shared/{b24ui-nuxt.Dh5A-7HA.mjs → b24ui-nuxt.BYDi-4ID.mjs} +323 -132
  76. package/dist/unplugin.mjs +1 -1
  77. package/dist/vite.mjs +1 -1
  78. package/package.json +22 -8
@@ -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-tertiary-accent'
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
+ } & {};
@@ -0,0 +1,241 @@
1
+ <script>
2
+ import theme from "#build/b24ui/editor-toolbar";
3
+ </script>
4
+
5
+ <script setup>
6
+ import { computed, inject } from "vue";
7
+ import { Primitive, Separator, useForwardProps } from "reka-ui";
8
+ import { defu } from "defu";
9
+ import { BubbleMenu, FloatingMenu } from "@tiptap/vue-3/menus";
10
+ import { reactiveOmit } from "@vueuse/core";
11
+ import { useAppConfig } from "#imports";
12
+ import { isArrayOfArray, pick, omit } from "../utils";
13
+ import { createHandlers } from "../utils/editor";
14
+ import { tv } from "../utils/tv";
15
+ import B24Button from "./Button.vue";
16
+ import B24DropdownMenu from "./DropdownMenu.vue";
17
+ import B24Tooltip from "./Tooltip.vue";
18
+ defineOptions({ inheritAttrs: false });
19
+ const props = defineProps({
20
+ as: { type: null, required: false },
21
+ color: { type: null, required: false, default: "air-tertiary-no-accent" },
22
+ activeColor: { type: null, required: false, default: "air-tertiary-accent" },
23
+ size: { type: null, required: false, default: "sm" },
24
+ items: { type: null, required: false },
25
+ editor: { type: Object, required: true },
26
+ class: { type: null, required: false },
27
+ b24ui: { type: null, required: false },
28
+ layout: { type: String, required: false, default: "fixed" },
29
+ pluginKey: { type: [Object, String], required: false },
30
+ updateDelay: { type: Number, required: false },
31
+ resizeDelay: { type: Number, required: false },
32
+ shouldShow: { type: [Function, null], required: false },
33
+ appendTo: { type: Function, required: false, skipCheck: true },
34
+ getReferencedVirtualElement: { type: Function, required: false },
35
+ options: { type: Object, required: false }
36
+ });
37
+ defineSlots();
38
+ const appConfig = useAppConfig();
39
+ const handlers = inject("editorHandlers", computed(() => createHandlers()));
40
+ const Component = computed(() => {
41
+ return {
42
+ bubble: BubbleMenu,
43
+ floating: FloatingMenu,
44
+ fixed: "template"
45
+ }[props.layout];
46
+ });
47
+ const rootProps = useForwardProps(reactiveOmit(props, "as", "color", "activeColor", "size", "items", "layout", "editor", "class", "b24ui"));
48
+ const options = computed(() => defu(props.options, {
49
+ offset: 8,
50
+ shift: { padding: 8 }
51
+ }));
52
+ const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.editorToolbar || {} })({
53
+ layout: props.layout
54
+ }));
55
+ const groups = computed(
56
+ () => props.items?.length ? isArrayOfArray(props.items) ? props.items : [props.items] : []
57
+ );
58
+ function isActive(item) {
59
+ if (!props.editor?.isEditable) {
60
+ return false;
61
+ }
62
+ if ("items" in item && item.items?.length) {
63
+ return item.items?.some((item2) => isActive(item2)) || false;
64
+ }
65
+ if (!("kind" in item)) {
66
+ return item.active ?? false;
67
+ }
68
+ const handler = handlers?.value?.[item.kind];
69
+ return handler?.isActive(props.editor, item) || false;
70
+ }
71
+ function isDisabled(item) {
72
+ if (!props.editor?.isEditable) {
73
+ return true;
74
+ }
75
+ if ("items" in item && item.items?.length) {
76
+ const items = isArrayOfArray(item.items) ? item.items.flat() : item.items;
77
+ const itemItems = items.filter((item2) => "kind" in item2);
78
+ if (itemItems.length === 0) {
79
+ return true;
80
+ }
81
+ return itemItems.every((item2) => isDisabled(item2));
82
+ }
83
+ if (!("kind" in item)) {
84
+ return item.disabled ?? false;
85
+ }
86
+ const handler = handlers?.value?.[item.kind];
87
+ if (!handler) {
88
+ return false;
89
+ }
90
+ if (handler.isDisabled?.(props.editor, item)) {
91
+ return true;
92
+ }
93
+ return !handler.canExecute(props.editor, item);
94
+ }
95
+ function onClick(e, item) {
96
+ if (!props.editor?.isEditable || isDisabled(item)) {
97
+ return;
98
+ }
99
+ if ("items" in item || !("kind" in item)) {
100
+ if ("onClick" in item) {
101
+ for (const onClick2 of Array.isArray(item.onClick) ? item.onClick : [item.onClick]) {
102
+ onClick2?.(e);
103
+ }
104
+ }
105
+ return;
106
+ }
107
+ const handler = handlers?.value?.[item.kind];
108
+ if (handler) {
109
+ handler.execute(props.editor, item).run();
110
+ }
111
+ }
112
+ function getActiveChildItem(item) {
113
+ if (!item.items) {
114
+ return void 0;
115
+ }
116
+ const items = isArrayOfArray(item.items) ? item.items.flat() : item.items;
117
+ return items.find((childItem) => {
118
+ if (!("kind" in childItem)) {
119
+ return false;
120
+ }
121
+ return isActive(childItem);
122
+ });
123
+ }
124
+ function getButtonProps(item) {
125
+ const baseProps = omit(item, ["kind", "mark", "align", "level", "href", "src", "pos", "items", "slot", "checkedIcon", "loadingIcon", "externalIcon", "content", "arrow", "portal", "modal", "tooltip"]);
126
+ if ("items" in item && item.items?.length) {
127
+ const activeChild = getActiveChildItem(item);
128
+ if (activeChild?.icon) {
129
+ baseProps.icon = activeChild.icon;
130
+ }
131
+ if (activeChild?.label && baseProps.label !== void 0) {
132
+ baseProps.label = activeChild.label;
133
+ }
134
+ }
135
+ return defu(baseProps, {
136
+ color: props.color,
137
+ activeColor: props.activeColor,
138
+ size: props.size
139
+ });
140
+ }
141
+ function getDropdownProps(item) {
142
+ const baseProps = pick(item, ["checkedIcon", "loadingIcon", "externalIcon", "content", "arrow", "portal", "modal", "b24ui"]);
143
+ return defu(baseProps, {
144
+ modal: false
145
+ });
146
+ }
147
+ function mapDropdownItem(item) {
148
+ const children = "children" in item && Array.isArray(item.children) ? item.children.map(mapDropdownItem) : void 0;
149
+ if (!("kind" in item)) {
150
+ return children ? { ...item, children } : item;
151
+ }
152
+ const editorToolbarItem = item;
153
+ return {
154
+ ...editorToolbarItem,
155
+ ...children && { children },
156
+ // @ts-expect-error: need test at nuxt.ui? but this work
157
+ active: isActive(editorToolbarItem),
158
+ // @ts-expect-error: need test at nuxt.ui? but this work
159
+ disabled: isDisabled(editorToolbarItem),
160
+ // @ts-expect-error: need test at nuxt.ui? but this work
161
+ onSelect: (e) => onClick(e, editorToolbarItem)
162
+ };
163
+ }
164
+ function getDropdownItems(item) {
165
+ if (!item.items) {
166
+ return [];
167
+ }
168
+ return isArrayOfArray(item.items) ? item.items.map((group) => group.map(mapDropdownItem)) : [item.items.map(mapDropdownItem)];
169
+ }
170
+ </script>
171
+
172
+ <template>
173
+ <Primitive
174
+ :as="Component"
175
+ v-bind="Component !== 'template' ? {
176
+ editor,
177
+ tabindex: -1,
178
+ class: b24ui.root({ class: props.b24ui?.root }),
179
+ ...rootProps,
180
+ options,
181
+ ...$attrs
182
+ } : {
183
+ ...$attrs
184
+ }"
185
+ >
186
+ <Primitive :as="as" role="toolbar" data-slot="base" :class="b24ui.base({ class: [props.b24ui?.base, props.class] })">
187
+ <template v-for="(group, groupIndex) in groups" :key="`group-${groupIndex}`">
188
+ <div role="group" data-slot="group" :class="b24ui.group({ class: props.b24ui?.group })">
189
+ <template v-for="(item, index) in group" :key="`group-${groupIndex}-${index}`">
190
+ <slot
191
+ :name="item.slot || 'item'"
192
+ :item="item"
193
+ :index="index"
194
+ :is-active="isActive"
195
+ :is-disabled="isDisabled"
196
+ :on-click="onClick"
197
+ >
198
+ <B24DropdownMenu
199
+ v-if="'items' in item && item.items?.length"
200
+ v-bind="getDropdownProps(item)"
201
+ :items="getDropdownItems(item)"
202
+ >
203
+ <B24Tooltip v-if="item.tooltip" :disabled="isDisabled(item)" v-bind="{ ...item.tooltip || {} }">
204
+ <B24Button :active="isActive(item)" :disabled="isDisabled(item)" v-bind="getButtonProps(item)" />
205
+ </B24Tooltip>
206
+
207
+ <B24Button v-else :active="isActive(item)" :disabled="isDisabled(item)" v-bind="getButtonProps(item)" />
208
+ </B24DropdownMenu>
209
+
210
+ <B24Tooltip v-else-if="item.tooltip" :disabled="isDisabled(item)" v-bind="{ ...item.tooltip || {} }">
211
+ <B24Button
212
+ :active="isActive(item)"
213
+ :disabled="isDisabled(item)"
214
+ v-bind="getButtonProps(item)"
215
+ :b24ui="item.b24ui"
216
+ @click="onClick($event, item)"
217
+ />
218
+ </B24Tooltip>
219
+
220
+ <B24Button
221
+ v-else
222
+ :active="isActive(item)"
223
+ :disabled="isDisabled(item)"
224
+ v-bind="getButtonProps(item)"
225
+ :b24ui="item.b24ui"
226
+ @click="onClick($event, item)"
227
+ />
228
+ </slot>
229
+ </template>
230
+ </div>
231
+
232
+ <Separator
233
+ v-if="groupIndex < groups.length - 1"
234
+ data-slot="separator"
235
+ :class="b24ui.separator({ class: props.b24ui?.separator })"
236
+ orientation="vertical"
237
+ />
238
+ </template>
239
+ </Primitive>
240
+ </Primitive>
241
+ </template>