@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.
Files changed (65) hide show
  1. package/README-AI.md +1 -1
  2. package/dist/meta.d.mts +98220 -780
  3. package/dist/meta.mjs +98220 -780
  4. package/dist/module.json +1 -1
  5. package/dist/module.mjs +1 -1
  6. package/dist/runtime/components/ContextMenu.d.vue.ts +6 -2
  7. package/dist/runtime/components/ContextMenu.vue.d.ts +6 -2
  8. package/dist/runtime/components/ContextMenuContent.vue +2 -2
  9. package/dist/runtime/components/DropdownMenu.d.vue.ts +6 -2
  10. package/dist/runtime/components/DropdownMenu.vue.d.ts +6 -2
  11. package/dist/runtime/components/DropdownMenuContent.vue +2 -2
  12. package/dist/runtime/components/Editor.d.vue.ts +87 -0
  13. package/dist/runtime/components/Editor.vue +185 -0
  14. package/dist/runtime/components/Editor.vue.d.ts +87 -0
  15. package/dist/runtime/components/EditorDragHandle.d.vue.ts +60 -0
  16. package/dist/runtime/components/EditorDragHandle.vue +128 -0
  17. package/dist/runtime/components/EditorDragHandle.vue.d.ts +60 -0
  18. package/dist/runtime/components/EditorEmojiMenu.d.vue.ts +35 -0
  19. package/dist/runtime/components/EditorEmojiMenu.vue +70 -0
  20. package/dist/runtime/components/EditorEmojiMenu.vue.d.ts +35 -0
  21. package/dist/runtime/components/EditorMentionMenu.d.vue.ts +39 -0
  22. package/dist/runtime/components/EditorMentionMenu.vue +74 -0
  23. package/dist/runtime/components/EditorMentionMenu.vue.d.ts +39 -0
  24. package/dist/runtime/components/EditorSuggestionMenu.d.vue.ts +52 -0
  25. package/dist/runtime/components/EditorSuggestionMenu.vue +79 -0
  26. package/dist/runtime/components/EditorSuggestionMenu.vue.d.ts +52 -0
  27. package/dist/runtime/components/EditorToolbar.d.vue.ts +80 -0
  28. package/dist/runtime/components/EditorToolbar.vue +239 -0
  29. package/dist/runtime/components/EditorToolbar.vue.d.ts +80 -0
  30. package/dist/runtime/components/FormField.vue +2 -2
  31. package/dist/runtime/components/InputMenu.d.vue.ts +2 -0
  32. package/dist/runtime/components/InputMenu.vue +14 -1
  33. package/dist/runtime/components/InputMenu.vue.d.ts +2 -0
  34. package/dist/runtime/components/Pagination.d.vue.ts +0 -1
  35. package/dist/runtime/components/Pagination.vue.d.ts +0 -1
  36. package/dist/runtime/components/Select.d.vue.ts +2 -0
  37. package/dist/runtime/components/Select.vue +14 -1
  38. package/dist/runtime/components/Select.vue.d.ts +2 -0
  39. package/dist/runtime/components/SelectMenu.d.vue.ts +2 -0
  40. package/dist/runtime/components/SelectMenu.vue +14 -1
  41. package/dist/runtime/components/SelectMenu.vue.d.ts +2 -0
  42. package/dist/runtime/components/color-mode/ColorModeSelect.vue +1 -0
  43. package/dist/runtime/components/locale/LocaleSelect.vue +1 -0
  44. package/dist/runtime/components/prose/Accordion.vue +1 -1
  45. package/dist/runtime/composables/defineShortcuts.d.ts +1 -0
  46. package/dist/runtime/composables/defineShortcuts.js +60 -13
  47. package/dist/runtime/composables/index.d.ts +1 -0
  48. package/dist/runtime/composables/index.js +1 -0
  49. package/dist/runtime/composables/useEditorMenu.d.ts +64 -0
  50. package/dist/runtime/composables/useEditorMenu.js +448 -0
  51. package/dist/runtime/composables/useSpeechRecognition.d.ts +122 -0
  52. package/dist/runtime/composables/useSpeechRecognition.js +166 -0
  53. package/dist/runtime/dictionary/icons.d.ts +1 -0
  54. package/dist/runtime/dictionary/icons.js +5 -3
  55. package/dist/runtime/types/editor.d.ts +69 -0
  56. package/dist/runtime/types/editor.js +0 -0
  57. package/dist/runtime/types/index.d.ts +7 -0
  58. package/dist/runtime/types/index.js +7 -0
  59. package/dist/runtime/utils/editor.d.ts +69 -0
  60. package/dist/runtime/utils/editor.js +364 -0
  61. package/dist/runtime/vue/components/color-mode/ColorModeSelect.vue +1 -0
  62. package/dist/shared/{b24ui-nuxt.BCphUjPy.mjs → b24ui-nuxt.C8MyFqPm.mjs} +185 -1
  63. package/dist/unplugin.mjs +1 -1
  64. package/dist/vite.mjs +1 -1
  65. package/package.json +16 -3
@@ -0,0 +1,239 @@
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-primary" },
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
+ if (!("kind" in item)) {
149
+ return item;
150
+ }
151
+ const editorToolbarItem = item;
152
+ return {
153
+ ...editorToolbarItem,
154
+ // @ts-expect-error: need test at nuxt.ui? but this work
155
+ active: isActive(editorToolbarItem),
156
+ // @ts-expect-error: need test at nuxt.ui? but this work
157
+ disabled: isDisabled(editorToolbarItem),
158
+ // @ts-expect-error: need test at nuxt.ui? but this work
159
+ onClick: (e) => onClick(e, editorToolbarItem)
160
+ };
161
+ }
162
+ function getDropdownItems(item) {
163
+ if (!item.items) {
164
+ return [];
165
+ }
166
+ return isArrayOfArray(item.items) ? item.items.map((group) => group.map(mapDropdownItem)) : [item.items.map(mapDropdownItem)];
167
+ }
168
+ </script>
169
+
170
+ <template>
171
+ <Primitive
172
+ :as="Component"
173
+ v-bind="Component !== 'template' ? {
174
+ editor,
175
+ tabindex: -1,
176
+ class: b24ui.root({ class: props.b24ui?.root }),
177
+ ...rootProps,
178
+ options,
179
+ ...$attrs
180
+ } : {
181
+ ...$attrs
182
+ }"
183
+ >
184
+ <Primitive :as="as" role="toolbar" data-slot="base" :class="b24ui.base({ class: [props.b24ui?.base, props.class] })">
185
+ <template v-for="(group, groupIndex) in groups" :key="`group-${groupIndex}`">
186
+ <div role="group" data-slot="group" :class="b24ui.group({ class: props.b24ui?.group })">
187
+ <template v-for="(item, index) in group" :key="`group-${groupIndex}-${index}`">
188
+ <slot
189
+ :name="item.slot || 'item'"
190
+ :item="item"
191
+ :index="index"
192
+ :is-active="isActive"
193
+ :is-disabled="isDisabled"
194
+ :on-click="onClick"
195
+ >
196
+ <B24DropdownMenu
197
+ v-if="'items' in item && item.items?.length"
198
+ v-bind="getDropdownProps(item)"
199
+ :items="getDropdownItems(item)"
200
+ >
201
+ <B24Tooltip v-if="item.tooltip" :disabled="isDisabled(item)" v-bind="{ ...item.tooltip || {} }">
202
+ <B24Button :active="isActive(item)" :disabled="isDisabled(item)" v-bind="getButtonProps(item)" />
203
+ </B24Tooltip>
204
+
205
+ <B24Button v-else :active="isActive(item)" :disabled="isDisabled(item)" v-bind="getButtonProps(item)" />
206
+ </B24DropdownMenu>
207
+
208
+ <B24Tooltip v-else-if="item.tooltip" :disabled="isDisabled(item)" v-bind="{ ...item.tooltip || {} }">
209
+ <B24Button
210
+ :active="isActive(item)"
211
+ :disabled="isDisabled(item)"
212
+ v-bind="getButtonProps(item)"
213
+ :b24ui="item.b24ui"
214
+ @click="onClick($event, item)"
215
+ />
216
+ </B24Tooltip>
217
+
218
+ <B24Button
219
+ v-else
220
+ :active="isActive(item)"
221
+ :disabled="isDisabled(item)"
222
+ v-bind="getButtonProps(item)"
223
+ :b24ui="item.b24ui"
224
+ @click="onClick($event, item)"
225
+ />
226
+ </slot>
227
+ </template>
228
+ </div>
229
+
230
+ <Separator
231
+ v-if="groupIndex < groups.length - 1"
232
+ data-slot="separator"
233
+ :class="b24ui.separator({ class: props.b24ui?.separator })"
234
+ orientation="vertical"
235
+ />
236
+ </template>
237
+ </Primitive>
238
+ </Primitive>
239
+ </template>
@@ -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
+ } & {};
@@ -16,7 +16,7 @@ const props = defineProps({
16
16
  label: { type: String, required: false },
17
17
  description: { type: String, required: false },
18
18
  help: { type: String, required: false },
19
- error: { type: [Boolean, String], required: false },
19
+ error: { type: [Boolean, String], required: false, default: void 0 },
20
20
  hint: { type: String, required: false },
21
21
  size: { type: null, required: false },
22
22
  required: { type: Boolean, required: false },
@@ -83,7 +83,7 @@ provide(formFieldInjectionKey, computed(() => ({
83
83
  <div data-slot="container" :class="[(label || !!slots.label || description || !!slots.description) && b24ui.container({ class: props.b24ui?.container })]">
84
84
  <slot :error="error" />
85
85
 
86
- <div v-if="typeof error === 'string' && error || !!slots.error" :id="`${ariaId}-error`" data-slot="error" :class="b24ui.error({ class: props.b24ui?.error })">
86
+ <div v-if="props.error !== false && (typeof error === 'string' && error || !!slots.error)" :id="`${ariaId}-error`" data-slot="error" :class="b24ui.error({ class: props.b24ui?.error })">
87
87
  <slot name="error" :error="error">
88
88
  <div data-slot="errorWrapper" :class="b24ui.errorWrapper({ class: props.b24ui?.errorWrapper })">
89
89
  <WarningIcon data-slot="errorIcon" :class="b24ui.errorIcon()" />
@@ -3,6 +3,7 @@ import type { AppConfig } from '@nuxt/schema';
3
3
  import theme from '#build/b24ui/input-menu';
4
4
  import type { UseComponentIconsProps } from '../composables/useComponentIcons';
5
5
  import type { AvatarProps, ChipProps, BadgeProps, IconComponent } from '../types';
6
+ import type { ModelModifiers } from '../types/input';
6
7
  import type { InputHTMLAttributes } from '../types/html';
7
8
  import type { AcceptableValue, ArrayOrNested, GetItemKeys, GetModelValue, GetModelValueEmits, NestedItem, EmitsToProps } from '../types/utils';
8
9
  import type { ComponentConfig } from '../types/tv';
@@ -136,6 +137,7 @@ export interface InputMenuProps<T extends ArrayOrNested<InputMenuItem> = ArrayOr
136
137
  defaultValue?: GetModelValue<T, VK, M>;
137
138
  /** The controlled value of the InputMenu. Can be binded-with with `v-model`. */
138
139
  modelValue?: GetModelValue<T, VK, M>;
140
+ modelModifiers?: Omit<ModelModifiers<GetModelValue<T, VK, M>>, 'lazy'>;
139
141
  /** Whether multiple options can be selected or not. */
140
142
  multiple?: M & boolean;
141
143
  tag?: string;
@@ -14,7 +14,7 @@ import { useComponentIcons } from "../composables/useComponentIcons";
14
14
  import { useFormField } from "../composables/useFormField";
15
15
  import { useLocale } from "../composables/useLocale";
16
16
  import { usePortal } from "../composables/usePortal";
17
- import { compare, get, getDisplayValue, isArrayOfArray } from "../utils";
17
+ import { compare, get, getDisplayValue, isArrayOfArray, looseToNumber } from "../utils";
18
18
  import { getEstimateSize } from "../utils/virtualizer";
19
19
  import { tv } from "../utils/tv";
20
20
  import icons from "../dictionary/icons";
@@ -48,6 +48,7 @@ const props = defineProps({
48
48
  items: { type: null, required: false },
49
49
  defaultValue: { type: null, required: false },
50
50
  modelValue: { type: null, required: false },
51
+ modelModifiers: { type: Object, required: false },
51
52
  multiple: { type: Boolean, required: false },
52
53
  tag: { type: String, required: false },
53
54
  tagColor: { type: null, required: false },
@@ -184,6 +185,18 @@ function onUpdate(value) {
184
185
  if (toRaw(props.modelValue) === value) {
185
186
  return;
186
187
  }
188
+ if (props.modelModifiers?.trim) {
189
+ value = value?.trim() ?? null;
190
+ }
191
+ if (props.modelModifiers?.number) {
192
+ value = looseToNumber(value);
193
+ }
194
+ if (props.modelModifiers?.nullable) {
195
+ value ??= null;
196
+ }
197
+ if (props.modelModifiers?.optional) {
198
+ value ??= void 0;
199
+ }
187
200
  const event = new Event("change", { target: { value } });
188
201
  emits("change", event);
189
202
  emitFormChange();
@@ -3,6 +3,7 @@ import type { AppConfig } from '@nuxt/schema';
3
3
  import theme from '#build/b24ui/input-menu';
4
4
  import type { UseComponentIconsProps } from '../composables/useComponentIcons';
5
5
  import type { AvatarProps, ChipProps, BadgeProps, IconComponent } from '../types';
6
+ import type { ModelModifiers } from '../types/input';
6
7
  import type { InputHTMLAttributes } from '../types/html';
7
8
  import type { AcceptableValue, ArrayOrNested, GetItemKeys, GetModelValue, GetModelValueEmits, NestedItem, EmitsToProps } from '../types/utils';
8
9
  import type { ComponentConfig } from '../types/tv';
@@ -136,6 +137,7 @@ export interface InputMenuProps<T extends ArrayOrNested<InputMenuItem> = ArrayOr
136
137
  defaultValue?: GetModelValue<T, VK, M>;
137
138
  /** The controlled value of the InputMenu. Can be binded-with with `v-model`. */
138
139
  modelValue?: GetModelValue<T, VK, M>;
140
+ modelModifiers?: Omit<ModelModifiers<GetModelValue<T, VK, M>>, 'lazy'>;
139
141
  /** Whether multiple options can be selected or not. */
140
142
  multiple?: M & boolean;
141
143
  tag?: string;
@@ -43,7 +43,6 @@ export interface PaginationProps extends Partial<Pick<PaginationRootProps, 'defa
43
43
  /**
44
44
  * The color of the pagination controls.
45
45
  * @defaultValue 'air-secondary-no-accent'
46
- * @IconComponent
47
46
  */
48
47
  color?: ButtonProps['color'];
49
48
  /**
@@ -43,7 +43,6 @@ export interface PaginationProps extends Partial<Pick<PaginationRootProps, 'defa
43
43
  /**
44
44
  * The color of the pagination controls.
45
45
  * @defaultValue 'air-secondary-no-accent'
46
- * @IconComponent
47
46
  */
48
47
  color?: ButtonProps['color'];
49
48
  /**
@@ -3,6 +3,7 @@ import type { AppConfig } from '@nuxt/schema';
3
3
  import theme from '#build/b24ui/select';
4
4
  import type { UseComponentIconsProps } from '../composables/useComponentIcons';
5
5
  import type { AvatarProps, ChipProps, BadgeProps, IconComponent } from '../types';
6
+ import type { ModelModifiers } from '../types/input';
6
7
  import type { ButtonHTMLAttributes } from '../types/html';
7
8
  import type { AcceptableValue, ArrayOrNested, GetItemKeys, GetModelValue, GetModelValueEmits, NestedItem, EmitsToProps } from '../types/utils';
8
9
  import type { ComponentConfig } from '../types/tv';
@@ -115,6 +116,7 @@ export interface SelectProps<T extends ArrayOrNested<SelectItem> = ArrayOrNested
115
116
  defaultValue?: GetModelValue<T, VK, M>;
116
117
  /** The controlled value of the Select. Can be bind as `v-model`. */
117
118
  modelValue?: GetModelValue<T, VK, M>;
119
+ modelModifiers?: Omit<ModelModifiers<GetModelValue<T, VK, M>>, 'lazy'>;
118
120
  /** Whether multiple options can be selected or not. */
119
121
  multiple?: M & boolean;
120
122
  /** Highlight the ring color like a focus state. */
@@ -12,7 +12,7 @@ import { useFieldGroup } from "../composables/useFieldGroup";
12
12
  import { useComponentIcons } from "../composables/useComponentIcons";
13
13
  import { useFormField } from "../composables/useFormField";
14
14
  import { usePortal } from "../composables/usePortal";
15
- import { get, getDisplayValue, isArrayOfArray } from "../utils";
15
+ import { get, getDisplayValue, isArrayOfArray, looseToNumber } from "../utils";
16
16
  import { tv } from "../utils/tv";
17
17
  import icons from "../dictionary/icons";
18
18
  import B24Badge from "./Badge.vue";
@@ -41,6 +41,7 @@ const props = defineProps({
41
41
  items: { type: null, required: false },
42
42
  defaultValue: { type: null, required: false },
43
43
  modelValue: { type: null, required: false },
44
+ modelModifiers: { type: Object, required: false },
44
45
  multiple: { type: Boolean, required: false },
45
46
  highlight: { type: Boolean, required: false },
46
47
  autofocus: { type: Boolean, required: false },
@@ -119,6 +120,18 @@ onMounted(() => {
119
120
  }, props.autofocusDelay);
120
121
  });
121
122
  function onUpdate(value) {
123
+ if (props.modelModifiers?.trim) {
124
+ value = value?.trim() ?? null;
125
+ }
126
+ if (props.modelModifiers?.number) {
127
+ value = looseToNumber(value);
128
+ }
129
+ if (props.modelModifiers?.nullable) {
130
+ value ??= null;
131
+ }
132
+ if (props.modelModifiers?.optional) {
133
+ value ??= void 0;
134
+ }
122
135
  const event = new Event("change", { target: { value } });
123
136
  emits("change", event);
124
137
  emitFormChange();
@@ -3,6 +3,7 @@ import type { AppConfig } from '@nuxt/schema';
3
3
  import theme from '#build/b24ui/select';
4
4
  import type { UseComponentIconsProps } from '../composables/useComponentIcons';
5
5
  import type { AvatarProps, ChipProps, BadgeProps, IconComponent } from '../types';
6
+ import type { ModelModifiers } from '../types/input';
6
7
  import type { ButtonHTMLAttributes } from '../types/html';
7
8
  import type { AcceptableValue, ArrayOrNested, GetItemKeys, GetModelValue, GetModelValueEmits, NestedItem, EmitsToProps } from '../types/utils';
8
9
  import type { ComponentConfig } from '../types/tv';
@@ -115,6 +116,7 @@ export interface SelectProps<T extends ArrayOrNested<SelectItem> = ArrayOrNested
115
116
  defaultValue?: GetModelValue<T, VK, M>;
116
117
  /** The controlled value of the Select. Can be bind as `v-model`. */
117
118
  modelValue?: GetModelValue<T, VK, M>;
119
+ modelModifiers?: Omit<ModelModifiers<GetModelValue<T, VK, M>>, 'lazy'>;
118
120
  /** Whether multiple options can be selected or not. */
119
121
  multiple?: M & boolean;
120
122
  /** Highlight the ring color like a focus state. */
@@ -3,6 +3,7 @@ import type { AppConfig } from '@nuxt/schema';
3
3
  import theme from '#build/b24ui/select-menu';
4
4
  import type { UseComponentIconsProps } from '../composables/useComponentIcons';
5
5
  import type { AvatarProps, ChipProps, InputProps, BadgeProps, IconComponent } from '../types';
6
+ import type { ModelModifiers } from '../types/input';
6
7
  import type { ButtonHTMLAttributes } from '../types/html';
7
8
  import type { AcceptableValue, ArrayOrNested, GetItemKeys, GetModelValue, GetModelValueEmits, NestedItem, EmitsToProps } from '../types/utils';
8
9
  import type { ComponentConfig } from '../types/tv';
@@ -142,6 +143,7 @@ export interface SelectMenuProps<T extends ArrayOrNested<SelectMenuItem> = Array
142
143
  defaultValue?: GetModelValue<T, VK, M>;
143
144
  /** The controlled value of the SelectMenu. Can be binded-with with `v-model`. */
144
145
  modelValue?: GetModelValue<T, VK, M>;
146
+ modelModifiers?: Omit<ModelModifiers<GetModelValue<T, VK, M>>, 'lazy'>;
145
147
  /** Whether multiple options can be selected or not. */
146
148
  multiple?: M & boolean;
147
149
  /** Highlight the ring color like a focus state. */
@@ -13,7 +13,7 @@ import { useComponentIcons } from "../composables/useComponentIcons";
13
13
  import { useFormField } from "../composables/useFormField";
14
14
  import { useLocale } from "../composables/useLocale";
15
15
  import { usePortal } from "../composables/usePortal";
16
- import { compare, get, getDisplayValue, isArrayOfArray } from "../utils";
16
+ import { compare, get, getDisplayValue, isArrayOfArray, looseToNumber } from "../utils";
17
17
  import { getEstimateSize } from "../utils/virtualizer";
18
18
  import { tv } from "../utils/tv";
19
19
  import icons from "../dictionary/icons";
@@ -47,6 +47,7 @@ const props = defineProps({
47
47
  items: { type: null, required: false },
48
48
  defaultValue: { type: null, required: false },
49
49
  modelValue: { type: null, required: false },
50
+ modelModifiers: { type: Object, required: false },
50
51
  multiple: { type: Boolean, required: false },
51
52
  highlight: { type: Boolean, required: false },
52
53
  createItem: { type: [Boolean, String, Object], required: false },
@@ -188,6 +189,18 @@ function onUpdate(value) {
188
189
  if (toRaw(props.modelValue) === value) {
189
190
  return;
190
191
  }
192
+ if (props.modelModifiers?.trim) {
193
+ value = value?.trim() ?? null;
194
+ }
195
+ if (props.modelModifiers?.number) {
196
+ value = looseToNumber(value);
197
+ }
198
+ if (props.modelModifiers?.nullable) {
199
+ value ??= null;
200
+ }
201
+ if (props.modelModifiers?.optional) {
202
+ value ??= void 0;
203
+ }
191
204
  const event = new Event("change", { target: { value } });
192
205
  emits("change", event);
193
206
  emitFormChange();
@@ -3,6 +3,7 @@ import type { AppConfig } from '@nuxt/schema';
3
3
  import theme from '#build/b24ui/select-menu';
4
4
  import type { UseComponentIconsProps } from '../composables/useComponentIcons';
5
5
  import type { AvatarProps, ChipProps, InputProps, BadgeProps, IconComponent } from '../types';
6
+ import type { ModelModifiers } from '../types/input';
6
7
  import type { ButtonHTMLAttributes } from '../types/html';
7
8
  import type { AcceptableValue, ArrayOrNested, GetItemKeys, GetModelValue, GetModelValueEmits, NestedItem, EmitsToProps } from '../types/utils';
8
9
  import type { ComponentConfig } from '../types/tv';
@@ -142,6 +143,7 @@ export interface SelectMenuProps<T extends ArrayOrNested<SelectMenuItem> = Array
142
143
  defaultValue?: GetModelValue<T, VK, M>;
143
144
  /** The controlled value of the SelectMenu. Can be binded-with with `v-model`. */
144
145
  modelValue?: GetModelValue<T, VK, M>;
146
+ modelModifiers?: Omit<ModelModifiers<GetModelValue<T, VK, M>>, 'lazy'>;
145
147
  /** Whether multiple options can be selected or not. */
146
148
  multiple?: M & boolean;
147
149
  /** Highlight the ring color like a focus state. */
@@ -33,6 +33,7 @@ const props = defineProps({
33
33
  labelKey: { type: null, required: false },
34
34
  descriptionKey: { type: null, required: false },
35
35
  defaultValue: { type: null, required: false },
36
+ modelModifiers: { type: Object, required: false },
36
37
  multiple: { type: Boolean, required: false },
37
38
  highlight: { type: Boolean, required: false },
38
39
  createItem: { type: [Boolean, String, Object], required: false },
@@ -31,6 +31,7 @@ const props = defineProps({
31
31
  labelKey: { type: null, required: false, default: "name" },
32
32
  descriptionKey: { type: null, required: false },
33
33
  defaultValue: { type: null, required: false },
34
+ modelModifiers: { type: Object, required: false },
34
35
  multiple: { type: Boolean, required: false },
35
36
  highlight: { type: Boolean, required: false },
36
37
  createItem: { type: [Boolean, String, Object], required: false },
@@ -37,7 +37,7 @@ onBeforeUpdate(() => rerenderCount.value++);
37
37
  </script>
38
38
 
39
39
  <template>
40
- <B24Accordion :type="type" :items="items" :unmount-on-hide="false" :class="props.class" :ui="transformUI(b24ui(), props.b24ui)">
40
+ <B24Accordion :type="type" :items="items" :unmount-on-hide="false" :class="props.class" :b24ui="transformUI(b24ui(), props.b24ui)">
41
41
  <template #content="{ item }">
42
42
  <component :is="item.component" />
43
43
  </template>
@@ -9,6 +9,7 @@ export interface ShortcutsConfig {
9
9
  }
10
10
  export interface ShortcutsOptions {
11
11
  chainDelay?: number;
12
+ layoutIndependent?: boolean;
12
13
  }
13
14
  export declare function extractShortcuts(items: any[] | any[][]): Record<string, Handler>;
14
15
  export declare function defineShortcuts(config: MaybeRef<ShortcutsConfig>, options?: ShortcutsOptions): import("@vueuse/shared").Fn;