@bitrix24/b24ui-nuxt 0.5.10 → 0.5.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/dist/meta.cjs +72112 -0
  2. package/dist/meta.d.cts +72110 -0
  3. package/dist/meta.d.mts +5060 -5060
  4. package/dist/meta.d.ts +72110 -0
  5. package/dist/meta.mjs +5060 -5060
  6. package/dist/module.cjs +63 -0
  7. package/dist/module.d.cts +15 -0
  8. package/dist/module.d.ts +15 -0
  9. package/dist/module.json +3 -3
  10. package/dist/module.mjs +1 -1
  11. package/dist/runtime/components/Advice.vue +54 -47
  12. package/dist/runtime/components/Alert.vue +96 -71
  13. package/dist/runtime/components/App.vue +34 -37
  14. package/dist/runtime/components/Avatar.vue +81 -69
  15. package/dist/runtime/components/AvatarGroup.vue +76 -53
  16. package/dist/runtime/components/Badge.vue +83 -83
  17. package/dist/runtime/components/Button.vue +157 -220
  18. package/dist/runtime/components/ButtonGroup.vue +51 -35
  19. package/dist/runtime/components/Calendar.vue +152 -186
  20. package/dist/runtime/components/Checkbox.vue +73 -84
  21. package/dist/runtime/components/Chip.vue +74 -59
  22. package/dist/runtime/components/Collapsible.vue +41 -44
  23. package/dist/runtime/components/Container.vue +27 -18
  24. package/dist/runtime/components/Countdown.vue +378 -198
  25. package/dist/runtime/components/DescriptionList.vue +149 -102
  26. package/dist/runtime/components/DropdownMenu.vue +139 -83
  27. package/dist/runtime/components/DropdownMenuContent.vue +84 -137
  28. package/dist/runtime/components/Form.vue +216 -162
  29. package/dist/runtime/components/FormField.vue +80 -76
  30. package/dist/runtime/components/Input.vue +179 -160
  31. package/dist/runtime/components/InputMenu.vue +380 -300
  32. package/dist/runtime/components/InputNumber.vue +175 -178
  33. package/dist/runtime/components/Kbd.vue +45 -33
  34. package/dist/runtime/components/Link.vue +173 -179
  35. package/dist/runtime/components/LinkBase.vue +42 -64
  36. package/dist/runtime/components/Modal.vue +127 -105
  37. package/dist/runtime/components/ModalDialogClose.vue +8 -4
  38. package/dist/runtime/components/Navbar.vue +33 -24
  39. package/dist/runtime/components/NavbarDivider.vue +33 -24
  40. package/dist/runtime/components/NavbarSection.vue +33 -24
  41. package/dist/runtime/components/NavbarSpacer.vue +33 -24
  42. package/dist/runtime/components/NavigationMenu.vue +210 -144
  43. package/dist/runtime/components/OverlayProvider.vue +17 -13
  44. package/dist/runtime/components/Popover.vue +81 -81
  45. package/dist/runtime/components/Progress.vue +136 -109
  46. package/dist/runtime/components/RadioGroup.vue +134 -120
  47. package/dist/runtime/components/Range.vue +85 -94
  48. package/dist/runtime/components/Select.vue +260 -212
  49. package/dist/runtime/components/SelectMenu.vue +365 -272
  50. package/dist/runtime/components/Separator.vue +71 -61
  51. package/dist/runtime/components/Sidebar.vue +33 -24
  52. package/dist/runtime/components/SidebarBody.vue +38 -30
  53. package/dist/runtime/components/SidebarFooter.vue +33 -24
  54. package/dist/runtime/components/SidebarHeader.vue +33 -24
  55. package/dist/runtime/components/SidebarHeading.vue +33 -24
  56. package/dist/runtime/components/SidebarLayout.vue +70 -40
  57. package/dist/runtime/components/SidebarSection.vue +33 -24
  58. package/dist/runtime/components/SidebarSpacer.vue +33 -24
  59. package/dist/runtime/components/Skeleton.vue +22 -17
  60. package/dist/runtime/components/Slideover.vue +131 -108
  61. package/dist/runtime/components/StackedLayout.vue +73 -40
  62. package/dist/runtime/components/Switch.vue +95 -100
  63. package/dist/runtime/components/Tabs.vue +107 -81
  64. package/dist/runtime/components/Textarea.vue +201 -177
  65. package/dist/runtime/components/Toast.vue +105 -94
  66. package/dist/runtime/components/Toaster.vue +116 -94
  67. package/dist/runtime/components/Tooltip.vue +64 -78
  68. package/dist/runtime/components/content/TableWrapper.vue +70 -58
  69. package/dist/runtime/composables/useAvatarGroup.d.ts +1 -1
  70. package/dist/runtime/composables/useButtonGroup.d.ts +2 -2
  71. package/dist/runtime/composables/useComponentIcons.d.ts +3 -3
  72. package/dist/runtime/composables/useFormField.d.ts +1 -1
  73. package/dist/runtime/prose/A.vue +23 -18
  74. package/dist/runtime/prose/Blockquote.vue +23 -18
  75. package/dist/runtime/prose/Code.vue +31 -23
  76. package/dist/runtime/prose/Em.vue +23 -18
  77. package/dist/runtime/prose/H1.vue +23 -18
  78. package/dist/runtime/prose/H2.vue +23 -18
  79. package/dist/runtime/prose/H3.vue +23 -18
  80. package/dist/runtime/prose/H4.vue +23 -18
  81. package/dist/runtime/prose/H5.vue +23 -18
  82. package/dist/runtime/prose/H6.vue +23 -18
  83. package/dist/runtime/prose/Hr.vue +19 -18
  84. package/dist/runtime/prose/Img.vue +23 -18
  85. package/dist/runtime/prose/Li.vue +23 -18
  86. package/dist/runtime/prose/Ol.vue +23 -18
  87. package/dist/runtime/prose/P.vue +23 -18
  88. package/dist/runtime/prose/Pre.vue +33 -28
  89. package/dist/runtime/prose/Strong.vue +23 -18
  90. package/dist/runtime/prose/Table.vue +54 -44
  91. package/dist/runtime/prose/Tbody.vue +23 -18
  92. package/dist/runtime/prose/Td.vue +23 -18
  93. package/dist/runtime/prose/Th.vue +23 -18
  94. package/dist/runtime/prose/Thead.vue +23 -18
  95. package/dist/runtime/prose/Tr.vue +23 -18
  96. package/dist/runtime/prose/Ul.vue +23 -18
  97. package/dist/runtime/vue/components/Link.vue +202 -201
  98. package/dist/shared/b24ui-nuxt.DrKwIWoc.cjs +7721 -0
  99. package/dist/types.d.mts +5 -3
  100. package/dist/types.d.ts +7 -0
  101. package/dist/unplugin.cjs +236 -0
  102. package/dist/unplugin.d.cts +33 -0
  103. package/dist/unplugin.d.ts +33 -0
  104. package/dist/vite.cjs +21 -0
  105. package/dist/vite.d.cts +14 -0
  106. package/dist/vite.d.ts +14 -0
  107. package/package.json +25 -13
  108. package/dist/runtime/components/Advice.vue.d.ts +0 -170
  109. package/dist/runtime/components/Alert.vue.d.ts +0 -464
  110. package/dist/runtime/components/App.vue.d.ts +0 -23
  111. package/dist/runtime/components/Avatar.vue.d.ts +0 -281
  112. package/dist/runtime/components/AvatarGroup.vue.d.ts +0 -204
  113. package/dist/runtime/components/Badge.vue.d.ts +0 -517
  114. package/dist/runtime/components/Button.vue.d.ts +0 -640
  115. package/dist/runtime/components/ButtonGroup.vue.d.ts +0 -116
  116. package/dist/runtime/components/Calendar.vue.d.ts +0 -437
  117. package/dist/runtime/components/Checkbox.vue.d.ts +0 -354
  118. package/dist/runtime/components/Chip.vue.d.ts +0 -271
  119. package/dist/runtime/components/Collapsible.vue.d.ts +0 -118
  120. package/dist/runtime/components/Container.vue.d.ts +0 -27
  121. package/dist/runtime/components/Countdown.vue.d.ts +0 -356
  122. package/dist/runtime/components/DescriptionList.vue.d.ts +0 -379
  123. package/dist/runtime/components/DropdownMenu.vue.d.ts +0 -533
  124. package/dist/runtime/components/DropdownMenuContent.vue.d.ts +0 -228
  125. package/dist/runtime/components/Form.vue.d.ts +0 -55
  126. package/dist/runtime/components/FormField.vue.d.ts +0 -282
  127. package/dist/runtime/components/Input.vue.d.ts +0 -755
  128. package/dist/runtime/components/InputMenu.vue.d.ts +0 -1504
  129. package/dist/runtime/components/InputNumber.vue.d.ts +0 -658
  130. package/dist/runtime/components/Kbd.vue.d.ts +0 -109
  131. package/dist/runtime/components/Link.vue.d.ts +0 -129
  132. package/dist/runtime/components/LinkBase.vue.d.ts +0 -48
  133. package/dist/runtime/components/Modal.vue.d.ts +0 -327
  134. package/dist/runtime/components/ModalDialogClose.vue.d.ts +0 -10
  135. package/dist/runtime/components/Navbar.vue.d.ts +0 -101
  136. package/dist/runtime/components/NavbarDivider.vue.d.ts +0 -101
  137. package/dist/runtime/components/NavbarSection.vue.d.ts +0 -101
  138. package/dist/runtime/components/NavbarSpacer.vue.d.ts +0 -101
  139. package/dist/runtime/components/NavigationMenu.vue.d.ts +0 -824
  140. package/dist/runtime/components/OverlayProvider.vue.d.ts +0 -2
  141. package/dist/runtime/components/Popover.vue.d.ts +0 -147
  142. package/dist/runtime/components/Progress.vue.d.ts +0 -592
  143. package/dist/runtime/components/RadioGroup.vue.d.ts +0 -723
  144. package/dist/runtime/components/Range.vue.d.ts +0 -417
  145. package/dist/runtime/components/Select.vue.d.ts +0 -1200
  146. package/dist/runtime/components/SelectMenu.vue.d.ts +0 -1298
  147. package/dist/runtime/components/Separator.vue.d.ts +0 -400
  148. package/dist/runtime/components/Sidebar.vue.d.ts +0 -101
  149. package/dist/runtime/components/SidebarBody.vue.d.ts +0 -90
  150. package/dist/runtime/components/SidebarFooter.vue.d.ts +0 -101
  151. package/dist/runtime/components/SidebarHeader.vue.d.ts +0 -101
  152. package/dist/runtime/components/SidebarHeading.vue.d.ts +0 -101
  153. package/dist/runtime/components/SidebarLayout.vue.d.ts +0 -222
  154. package/dist/runtime/components/SidebarSection.vue.d.ts +0 -101
  155. package/dist/runtime/components/SidebarSpacer.vue.d.ts +0 -101
  156. package/dist/runtime/components/Skeleton.vue.d.ts +0 -26
  157. package/dist/runtime/components/Slideover.vue.d.ts +0 -360
  158. package/dist/runtime/components/StackedLayout.vue.d.ts +0 -192
  159. package/dist/runtime/components/Switch.vue.d.ts +0 -587
  160. package/dist/runtime/components/Tabs.vue.d.ts +0 -453
  161. package/dist/runtime/components/Textarea.vue.d.ts +0 -601
  162. package/dist/runtime/components/Toast.vue.d.ts +0 -438
  163. package/dist/runtime/components/Toaster.vue.d.ts +0 -219
  164. package/dist/runtime/components/Tooltip.vue.d.ts +0 -186
  165. package/dist/runtime/components/content/TableWrapper.vue.d.ts +0 -237
  166. package/dist/runtime/prose/A.vue.d.ts +0 -84
  167. package/dist/runtime/prose/Blockquote.vue.d.ts +0 -84
  168. package/dist/runtime/prose/Code.vue.d.ts +0 -97
  169. package/dist/runtime/prose/Em.vue.d.ts +0 -84
  170. package/dist/runtime/prose/H1.vue.d.ts +0 -97
  171. package/dist/runtime/prose/H2.vue.d.ts +0 -123
  172. package/dist/runtime/prose/H3.vue.d.ts +0 -123
  173. package/dist/runtime/prose/H4.vue.d.ts +0 -123
  174. package/dist/runtime/prose/H5.vue.d.ts +0 -123
  175. package/dist/runtime/prose/H6.vue.d.ts +0 -123
  176. package/dist/runtime/prose/Hr.vue.d.ts +0 -74
  177. package/dist/runtime/prose/Img.vue.d.ts +0 -77
  178. package/dist/runtime/prose/Li.vue.d.ts +0 -84
  179. package/dist/runtime/prose/Ol.vue.d.ts +0 -84
  180. package/dist/runtime/prose/P.vue.d.ts +0 -84
  181. package/dist/runtime/prose/Pre.vue.d.ts +0 -117
  182. package/dist/runtime/prose/Strong.vue.d.ts +0 -84
  183. package/dist/runtime/prose/Table.vue.d.ts +0 -144
  184. package/dist/runtime/prose/Tbody.vue.d.ts +0 -84
  185. package/dist/runtime/prose/Td.vue.d.ts +0 -84
  186. package/dist/runtime/prose/Th.vue.d.ts +0 -84
  187. package/dist/runtime/prose/Thead.vue.d.ts +0 -84
  188. package/dist/runtime/prose/Tr.vue.d.ts +0 -84
  189. package/dist/runtime/prose/Ul.vue.d.ts +0 -84
  190. package/dist/runtime/vue/components/Link.vue.d.ts +0 -129
@@ -1,223 +1,273 @@
1
- <script>
2
- import _appConfig from "#build/app.config";
3
- import theme from "#build/b24ui/input-menu";
4
- import { tv } from "../utils/tv";
5
- const appConfigInputMenu = _appConfig;
6
- const inputMenu = tv({ extend: tv(theme), ...appConfigInputMenu.b24ui?.inputMenu || {} });
1
+ <script lang="ts">
2
+ import type { InputHTMLAttributes } from 'vue'
3
+ import type { VariantProps } from 'tailwind-variants'
4
+ import type { ComboboxRootProps, ComboboxRootEmits, ComboboxContentProps, ComboboxContentEmits, ComboboxArrowProps } from 'reka-ui'
5
+ import type { AppConfig } from '@nuxt/schema'
6
+ import _appConfig from '#build/app.config'
7
+ import theme from '#build/b24ui/input-menu'
8
+ import type { UseComponentIconsProps } from '../composables/useComponentIcons'
9
+ import { tv } from '../utils/tv'
10
+ import type { AvatarProps, ChipProps, InputProps, IconComponent } from '../types'
11
+ import type {
12
+ AcceptableValue,
13
+ ArrayOrNested,
14
+ GetItemKeys,
15
+ GetModelValue,
16
+ GetModelValueEmits,
17
+ NestedItem,
18
+ PartialString,
19
+ EmitsToProps
20
+ } from '../types/utils'
21
+
22
+ const appConfigInputMenu = _appConfig as AppConfig & { b24ui: { inputMenu: Partial<typeof theme> } }
23
+
24
+ const inputMenu = tv({ extend: tv(theme), ...(appConfigInputMenu.b24ui?.inputMenu || {}) })
25
+
26
+ type InputMenuVariants = VariantProps<typeof inputMenu>
27
+
28
+ interface _InputMenuItem {
29
+ label?: string
30
+ /**
31
+ * Display an icon on the left side.
32
+ * @IconComponent
33
+ */
34
+ icon?: IconComponent
35
+ avatar?: AvatarProps
36
+ color?: InputMenuVariants['color']
37
+ chip?: ChipProps
38
+ /**
39
+ * The item type.
40
+ * @defaultValue 'item'
41
+ */
42
+ type?: 'label' | 'separator' | 'item'
43
+ disabled?: boolean
44
+ onSelect?(e?: Event): void
45
+ [key: string]: any
46
+ }
47
+ export type InputMenuItem = _InputMenuItem | AcceptableValue | boolean
48
+
49
+ export interface InputMenuProps<T extends ArrayOrNested<InputMenuItem> = ArrayOrNested<InputMenuItem>, VK extends GetItemKeys<T> | undefined = undefined, M extends boolean = false> extends Pick<ComboboxRootProps<T>, 'open' | 'defaultOpen' | 'disabled' | 'name' | 'resetSearchTermOnBlur' | 'highlightOnHover'>, UseComponentIconsProps {
50
+ /**
51
+ * The element or component this component should render as.
52
+ * @defaultValue 'div'
53
+ */
54
+ as?: any
55
+ id?: string
56
+ /**
57
+ * @defaultValue 'text'
58
+ */
59
+ type?: InputHTMLAttributes['type']
60
+ /**
61
+ * The placeholder text when the input is empty
62
+ */
63
+ placeholder?: string
64
+ /**
65
+ * @defaultValue 'primary'
66
+ */
67
+ color?: InputMenuVariants['color']
68
+ /**
69
+ * @defaultValue 'md'
70
+ */
71
+ size?: InputMenuVariants['size']
72
+ /**
73
+ * Removes padding from input
74
+ * @defaultValue false
75
+ */
76
+ noPadding?: boolean
77
+ /**
78
+ * Removes all borders (rings)
79
+ * @defaultValue false
80
+ */
81
+ noBorder?: boolean
82
+ /**
83
+ * Removes all borders (rings) except the bottom one
84
+ * @defaultValue false
85
+ */
86
+ underline?: boolean
87
+ /**
88
+ * Rounds the corners of the button
89
+ * @defaultValue false
90
+ */
91
+ rounded?: boolean
92
+ /**
93
+ * @defaultValue false
94
+ */
95
+ required?: boolean
96
+ /**
97
+ * @defaultValue false
98
+ */
99
+ autofocus?: boolean
100
+ /**
101
+ * @defaultValue 0
102
+ */
103
+ autofocusDelay?: number
104
+ /**
105
+ * The icon displayed to open the menu.
106
+ * @defaultValue icons.chevronDown
107
+ * @IconComponent
108
+ */
109
+ trailingIcon?: IconComponent
110
+ /**
111
+ * The icon displayed when an item is selected.
112
+ * @defaultValue icons.check
113
+ * @IconComponent
114
+ */
115
+ selectedIcon?: IconComponent
116
+ /**
117
+ * The icon displayed to delete a tag.
118
+ * Works only when `multiple` is `true`.
119
+ * @defaultValue icons.close
120
+ * @IconComponent
121
+ */
122
+ deleteIcon?: IconComponent
123
+ /**
124
+ * The content of the menu.
125
+ * @defaultValue { side: 'bottom', sideOffset: 8, collisionPadding: 8, position: 'popper' }
126
+ */
127
+ content?: Omit<ComboboxContentProps, 'as' | 'asChild' | 'forceMount'> & Partial<EmitsToProps<ComboboxContentEmits>>
128
+ /**
129
+ * Display an arrow alongside the menu.
130
+ * @defaultValue false
131
+ */
132
+ arrow?: boolean | Omit<ComboboxArrowProps, 'as' | 'asChild'>
133
+ /**
134
+ * Render the menu in a portal.
135
+ * @defaultValue true
136
+ */
137
+ portal?: boolean
138
+ /**
139
+ * When `items` is an array of objects, select the field to use as the value instead of the object itself.
140
+ * @defaultValue undefined
141
+ */
142
+ valueKey?: VK
143
+ /**
144
+ * When `items` is an array of objects, select the field to use as the label.
145
+ * @defaultValue 'label'
146
+ */
147
+ labelKey?: keyof NestedItem<T>
148
+ items?: T
149
+ /**
150
+ * The value of the InputMenu when initially rendered. Use when you do not need to control the state of the InputMenu
151
+ */
152
+ defaultValue?: GetModelValue<T, VK, M>
153
+ /**
154
+ * The controlled value of the InputMenu. Can be binded-with with `v-model`
155
+ */
156
+ modelValue?: GetModelValue<T, VK, M>
157
+ /**
158
+ * Whether multiple options can be selected or not
159
+ * @defaultValue false
160
+ */
161
+ multiple?: M & boolean
162
+ tag?: string
163
+ /**
164
+ * @defaultValue 'primary'
165
+ */
166
+ tagColor?: InputMenuVariants['tagColor']
167
+ /**
168
+ * Highlight the ring color like a focus state
169
+ * @defaultValue false
170
+ */
171
+ highlight?: boolean
172
+ /**
173
+ * Determines if custom user input that does not exist in options can be added.
174
+ * @defaultValue false
175
+ */
176
+ createItem?: boolean | 'always' | { position?: 'top' | 'bottom', when?: 'empty' | 'always' }
177
+ /**
178
+ * Fields to filter items by.
179
+ * @defaultValue [labelKey]
180
+ */
181
+ filterFields?: string[]
182
+ /**
183
+ * When `true`, disable the default filters, useful for custom filtering (useAsyncData, useFetch, etc.).
184
+ * @defaultValue false
185
+ */
186
+ ignoreFilter?: boolean
187
+ class?: any
188
+ b24ui?: PartialString<typeof inputMenu.slots>
189
+ }
190
+
191
+ export type InputMenuEmits<A extends ArrayOrNested<InputMenuItem>, VK extends GetItemKeys<A> | undefined, M extends boolean> = Pick<ComboboxRootEmits, 'update:open'> & {
192
+ change: [payload: Event]
193
+ blur: [payload: FocusEvent]
194
+ focus: [payload: FocusEvent]
195
+ create: [item: string]
196
+ /** Event handler when highlighted element changes. */
197
+ highlight: [payload: {
198
+ ref: HTMLElement
199
+ value: GetModelValue<A, VK, M>
200
+ } | undefined]
201
+ } & GetModelValueEmits<A, VK, M>
202
+
203
+ type SlotProps<T extends InputMenuItem> = (props: { item: T, index: number }) => any
204
+
205
+ export interface InputMenuSlots<
206
+ A extends ArrayOrNested<InputMenuItem> = ArrayOrNested<InputMenuItem>,
207
+ VK extends GetItemKeys<A> | undefined = undefined,
208
+ M extends boolean = false,
209
+ T extends NestedItem<A> = NestedItem<A>
210
+ > {
211
+ 'leading'(props: { modelValue?: GetModelValue<A, VK, M>, open: boolean, b24ui: ReturnType<typeof inputMenu> }): any
212
+ 'trailing'(props: { modelValue?: GetModelValue<A, VK, M>, open: boolean, b24ui: ReturnType<typeof inputMenu> }): any
213
+ 'empty'(props: { searchTerm?: string }): any
214
+ 'item': SlotProps<T>
215
+ 'item-leading': SlotProps<T>
216
+ 'item-label': SlotProps<T>
217
+ 'item-trailing': SlotProps<T>
218
+ 'tags-item-text': SlotProps<T>
219
+ 'tags-item-delete': SlotProps<T>
220
+ 'create-item-label'(props: { item: string }): any
221
+ }
7
222
  </script>
8
223
 
9
- <script setup>
10
- import { computed, ref, toRef, onMounted, toRaw, nextTick } from "vue";
11
- import { useForwardPropsEmits, useFilter } from "reka-ui";
12
- import { defu } from "defu";
13
- import { isEqual } from "ohash/utils";
14
- import { reactivePick, createReusableTemplate } from "@vueuse/core";
15
- import { useButtonGroup } from "../composables/useButtonGroup";
16
- import { useComponentIcons } from "../composables/useComponentIcons";
17
- import { useFormField } from "../composables/useFormField";
18
- import { useLocale } from "../composables/useLocale";
19
- import { compare, get, isArrayOfArray } from "../utils";
20
- import icons from "../dictionary/icons";
21
- defineOptions({ inheritAttrs: false });
22
- const props = defineProps({
23
- as: {
24
- type: null,
25
- required: false
26
- },
27
- id: {
28
- type: String,
29
- required: false
30
- },
31
- type: {
32
- type: null,
33
- required: false,
34
- default: "text"
35
- },
36
- placeholder: {
37
- type: String,
38
- required: false
39
- },
40
- color: {
41
- type: null,
42
- required: false
43
- },
44
- size: {
45
- type: null,
46
- required: false
47
- },
48
- noPadding: {
49
- type: Boolean,
50
- required: false
51
- },
52
- noBorder: {
53
- type: Boolean,
54
- required: false
55
- },
56
- underline: {
57
- type: Boolean,
58
- required: false
59
- },
60
- rounded: {
61
- type: Boolean,
62
- required: false
63
- },
64
- required: {
65
- type: Boolean,
66
- required: false
67
- },
68
- autofocus: {
69
- type: Boolean,
70
- required: false
71
- },
72
- autofocusDelay: {
73
- type: Number,
74
- required: false,
75
- default: 0
76
- },
77
- trailingIcon: {
78
- type: [Function, Object],
79
- required: false
80
- },
81
- selectedIcon: {
82
- type: [Function, Object],
83
- required: false
84
- },
85
- deleteIcon: {
86
- type: [Function, Object],
87
- required: false
88
- },
89
- content: {
90
- type: Object,
91
- required: false
92
- },
93
- arrow: {
94
- type: [Boolean, Object],
95
- required: false
96
- },
97
- portal: {
98
- type: Boolean,
99
- required: false,
100
- default: true
101
- },
102
- valueKey: {
103
- type: null,
104
- required: false
105
- },
106
- labelKey: {
107
- type: null,
108
- required: false,
109
- default: "label"
110
- },
111
- items: {
112
- type: null,
113
- required: false
114
- },
115
- defaultValue: {
116
- type: null,
117
- required: false
118
- },
119
- modelValue: {
120
- type: null,
121
- required: false
122
- },
123
- multiple: {
124
- type: Boolean,
125
- required: false
126
- },
127
- tag: {
128
- type: String,
129
- required: false
130
- },
131
- tagColor: {
132
- type: null,
133
- required: false
134
- },
135
- highlight: {
136
- type: Boolean,
137
- required: false
138
- },
139
- createItem: {
140
- type: [Boolean, String, Object],
141
- required: false
142
- },
143
- filterFields: {
144
- type: Array,
145
- required: false
146
- },
147
- ignoreFilter: {
148
- type: Boolean,
149
- required: false
150
- },
151
- class: {
152
- type: null,
153
- required: false
154
- },
155
- b24ui: {
156
- type: null,
157
- required: false
158
- },
159
- open: {
160
- type: Boolean,
161
- required: false
162
- },
163
- defaultOpen: {
164
- type: Boolean,
165
- required: false
166
- },
167
- disabled: {
168
- type: Boolean,
169
- required: false
170
- },
171
- name: {
172
- type: String,
173
- required: false
174
- },
175
- resetSearchTermOnBlur: {
176
- type: Boolean,
177
- required: false
178
- },
179
- highlightOnHover: {
180
- type: Boolean,
181
- required: false
182
- },
183
- icon: {
184
- type: [Function, Object],
185
- required: false
186
- },
187
- avatar: {
188
- type: Object,
189
- required: false
190
- },
191
- loading: {
192
- type: Boolean,
193
- required: false
194
- },
195
- trailing: {
196
- type: Boolean,
197
- required: false
198
- }
199
- });
200
- const emits = defineEmits(["update:open", "change", "blur", "focus", "create", "highlight", "update:modelValue"]);
201
- const slots = defineSlots();
202
- const searchTerm = defineModel("searchTerm", {
203
- "type": String,
204
- ...{
205
- default: ""
206
- }
207
- });
208
- const { t } = useLocale();
209
- const { contains } = useFilter({ sensitivity: "base" });
210
- const rootProps = useForwardPropsEmits(reactivePick(props, "as", "modelValue", "defaultValue", "open", "defaultOpen", "required", "multiple", "resetSearchTermOnBlur", "highlightOnHover", "ignoreFilter"), emits);
211
- const contentProps = toRef(() => defu(props.content, { side: "bottom", sideOffset: 8, collisionPadding: 8, position: "popper" }));
212
- const arrowProps = toRef(() => props.arrow);
213
- const { emitFormBlur, emitFormFocus, emitFormChange, emitFormInput, size: formGroupSize, color, id, name, highlight, disabled, ariaAttrs } = useFormField(props);
214
- const { orientation, size: buttonGroupSize } = useButtonGroup(props);
215
- const { isLeading, isTrailing, leadingIconName, trailingIconName } = useComponentIcons(toRef(() => defu(props, { trailingIcon: icons.chevronDown })));
216
- const inputSize = computed(() => buttonGroupSize.value || formGroupSize.value);
224
+ <script setup lang="ts" generic="T extends ArrayOrNested<InputMenuItem>, VK extends GetItemKeys<T> | undefined = undefined, M extends boolean = false">
225
+ import { computed, ref, toRef, onMounted, toRaw, nextTick } from 'vue'
226
+ import { ComboboxRoot, ComboboxArrow, ComboboxAnchor, ComboboxInput, ComboboxTrigger, ComboboxPortal, ComboboxContent, ComboboxViewport, ComboboxEmpty, ComboboxGroup, ComboboxLabel, ComboboxSeparator, ComboboxItem, ComboboxItemIndicator, TagsInputRoot, TagsInputItem, TagsInputItemText, TagsInputItemDelete, TagsInputInput, useForwardPropsEmits, useFilter } from 'reka-ui'
227
+ import { defu } from 'defu'
228
+ import { isEqual } from 'ohash/utils'
229
+ import { reactivePick, createReusableTemplate } from '@vueuse/core'
230
+ import { useButtonGroup } from '../composables/useButtonGroup'
231
+ import { useComponentIcons } from '../composables/useComponentIcons'
232
+ import { useFormField } from '../composables/useFormField'
233
+ import { useLocale } from '../composables/useLocale'
234
+ import { compare, get, isArrayOfArray } from '../utils'
235
+ import icons from '../dictionary/icons'
236
+ import B24Avatar from './Avatar.vue'
237
+ import B24Chip from './Chip.vue'
238
+
239
+ defineOptions({ inheritAttrs: false })
240
+
241
+ const props = withDefaults(defineProps<InputMenuProps<T, VK, M>>(), {
242
+ type: 'text',
243
+ autofocusDelay: 0,
244
+ portal: true,
245
+ labelKey: 'label' as never
246
+ })
247
+ const emits = defineEmits<InputMenuEmits<T, VK, M>>()
248
+ const slots = defineSlots<InputMenuSlots<T, VK, M>>()
249
+
250
+ const searchTerm = defineModel<string>('searchTerm', { default: '' })
251
+
252
+ const { t } = useLocale()
253
+ const { contains } = useFilter({ sensitivity: 'base' })
254
+
255
+ const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'modelValue', 'defaultValue', 'open', 'defaultOpen', 'required', 'multiple', 'resetSearchTermOnBlur', 'highlightOnHover', 'ignoreFilter'), emits)
256
+ const contentProps = toRef(() => defu(props.content, { side: 'bottom', sideOffset: 8, collisionPadding: 8, position: 'popper' }) as ComboboxContentProps)
257
+ const arrowProps = toRef(() => props.arrow as ComboboxArrowProps)
258
+
259
+ const { emitFormBlur, emitFormFocus, emitFormChange, emitFormInput, size: formGroupSize, color, id, name, highlight, disabled, ariaAttrs } = useFormField<InputProps>(props)
260
+ const { orientation, size: buttonGroupSize } = useButtonGroup<InputProps>(props)
261
+ const { isLeading, isTrailing, leadingIconName, trailingIconName } = useComponentIcons(toRef(() => defu(props, { trailingIcon: icons.chevronDown })))
262
+
263
+ const inputSize = computed(() => buttonGroupSize.value || formGroupSize.value)
264
+
217
265
  const isTag = computed(() => {
218
- return props.tag;
219
- });
220
- const [DefineCreateItemTemplate, ReuseCreateItemTemplate] = createReusableTemplate();
266
+ return props.tag
267
+ })
268
+
269
+ const [DefineCreateItemTemplate, ReuseCreateItemTemplate] = createReusableTemplate()
270
+
221
271
  const b24ui = computed(() => inputMenu({
222
272
  color: color.value,
223
273
  size: inputSize?.value,
@@ -232,104 +282,134 @@ const b24ui = computed(() => inputMenu({
232
282
  trailing: Boolean(isTrailing.value || !!slots.trailing),
233
283
  multiple: props.multiple,
234
284
  buttonGroup: orientation.value
235
- }));
236
- function displayValue(value) {
285
+ }))
286
+
287
+ function displayValue(value: T): string {
237
288
  if (!props.valueKey) {
238
- return value && (typeof value === "object" ? get(value, props.labelKey) : value);
289
+ return value && (typeof value === 'object' ? get(value, props.labelKey as string) : value)
239
290
  }
240
- const item = items.value.find((item2) => compare(typeof item2 === "object" ? get(item2, props.valueKey) : item2, value));
241
- return item && (typeof item === "object" ? get(item, props.labelKey) : item);
291
+
292
+ const item = items.value.find(item => compare(typeof item === 'object' ? get(item as Record<string, any>, props.valueKey as string) : item, value))
293
+ return item && (typeof item === 'object' ? get(item, props.labelKey as string) : item)
242
294
  }
243
- const groups = computed(
244
- () => props.items?.length ? isArrayOfArray(props.items) ? props.items : [props.items] : []
245
- );
246
- const items = computed(() => groups.value.flatMap((group) => group));
295
+
296
+ const groups = computed<InputMenuItem[][]>(() =>
297
+ props.items?.length
298
+ ? isArrayOfArray(props.items)
299
+ ? props.items
300
+ : [props.items]
301
+ : []
302
+ )
303
+ // eslint-disable-next-line vue/no-dupe-keys
304
+ const items = computed(() => groups.value.flatMap(group => group))
305
+
247
306
  const filteredGroups = computed(() => {
248
307
  if (props.ignoreFilter || !searchTerm.value) {
249
- return groups.value;
308
+ return groups.value
250
309
  }
251
- const fields = Array.isArray(props.filterFields) ? props.filterFields : [props.labelKey];
252
- return groups.value.map((group) => group.filter((item) => {
253
- if (typeof item !== "object" || item === null) {
254
- return contains(String(item), searchTerm.value);
310
+
311
+ const fields = Array.isArray(props.filterFields) ? props.filterFields : [props.labelKey] as string[]
312
+
313
+ return groups.value.map(group => group.filter((item) => {
314
+ if (typeof item !== 'object' || item === null) {
315
+ return contains(String(item), searchTerm.value)
255
316
  }
256
- if (item.type && ["label", "separator"].includes(item.type)) {
257
- return true;
317
+
318
+ if (item.type && ['label', 'separator'].includes(item.type)) {
319
+ return true
258
320
  }
259
- return fields.some((field) => contains(get(item, field), searchTerm.value));
260
- })).filter((group) => group.filter(
261
- (item) => !isInputItem(item) || isInputItem(item) && (!item.type || !["label", "separator"].includes(item.type))
262
- ).length > 0);
263
- });
264
- const filteredItems = computed(() => filteredGroups.value.flatMap((group) => group));
321
+
322
+ return fields.some(field => contains(get(item, field), searchTerm.value))
323
+ })).filter(group => group.filter(item =>
324
+ !isInputItem(item) || (isInputItem(item) && (!item.type || !['label', 'separator'].includes(item.type)))
325
+ ).length > 0)
326
+ })
327
+ const filteredItems = computed(() => filteredGroups.value.flatMap(group => group))
328
+
265
329
  const createItem = computed(() => {
266
330
  if (!props.createItem || !searchTerm.value) {
267
- return false;
331
+ return false
268
332
  }
269
- const newItem = props.valueKey ? { [props.valueKey]: searchTerm.value } : searchTerm.value;
270
- if (typeof props.createItem === "object" && props.createItem.when === "always" || props.createItem === "always") {
271
- return !filteredItems.value.find((item) => compare(item, newItem, String(props.valueKey)));
333
+
334
+ const newItem = props.valueKey ? { [props.valueKey]: searchTerm.value } as NestedItem<T> : searchTerm.value
335
+
336
+ if ((typeof props.createItem === 'object' && props.createItem.when === 'always') || props.createItem === 'always') {
337
+ return !filteredItems.value.find(item => compare(item, newItem, String(props.valueKey)))
272
338
  }
273
- return !filteredItems.value.length;
274
- });
275
- const createItemPosition = computed(() => typeof props.createItem === "object" ? props.createItem.position : "bottom");
276
- const inputRef = ref(null);
339
+
340
+ return !filteredItems.value.length
341
+ })
342
+ const createItemPosition = computed(() => typeof props.createItem === 'object' ? props.createItem.position : 'bottom')
343
+
344
+ const inputRef = ref<InstanceType<typeof ComboboxInput> | null>(null)
345
+
277
346
  function autoFocus() {
278
347
  if (props.autofocus) {
279
- inputRef.value?.$el?.focus();
348
+ inputRef.value?.$el?.focus()
280
349
  }
281
350
  }
351
+
282
352
  onMounted(() => {
283
353
  setTimeout(() => {
284
- autoFocus();
285
- }, props.autofocusDelay);
286
- });
287
- function onUpdate(value) {
354
+ autoFocus()
355
+ }, props.autofocusDelay)
356
+ })
357
+
358
+ function onUpdate(value: any) {
288
359
  if (toRaw(props.modelValue) === value) {
289
- return;
360
+ return
290
361
  }
291
- const event = new Event("change", { target: { value } });
292
- emits("change", event);
293
- emitFormChange();
294
- emitFormInput();
362
+ // @ts-expect-error - 'target' does not exist in type 'EventInit'
363
+ const event = new Event('change', { target: { value } })
364
+ emits('change', event)
365
+ emitFormChange()
366
+ emitFormInput()
295
367
  }
296
- function onBlur(event) {
297
- emits("blur", event);
298
- emitFormBlur();
368
+
369
+ function onBlur(event: FocusEvent) {
370
+ emits('blur', event)
371
+ emitFormBlur()
299
372
  }
300
- function onFocus(event) {
301
- emits("focus", event);
302
- emitFormFocus();
373
+
374
+ function onFocus(event: FocusEvent) {
375
+ emits('focus', event)
376
+ emitFormFocus()
303
377
  }
304
- function onUpdateOpen(value) {
378
+
379
+ function onUpdateOpen(value: boolean) {
305
380
  if (!value) {
306
- const event = new FocusEvent("blur");
307
- emits("blur", event);
308
- emitFormBlur();
381
+ const event = new FocusEvent('blur')
382
+ emits('blur', event)
383
+ emitFormBlur()
309
384
  } else {
310
- const event = new FocusEvent("focus");
311
- emits("focus", event);
385
+ const event = new FocusEvent('focus')
386
+ emits('focus', event)
312
387
  }
388
+
313
389
  nextTick(() => {
314
- searchTerm.value = "";
315
- });
390
+ searchTerm.value = ''
391
+ })
316
392
  }
317
- function onRemoveTag(event) {
393
+
394
+ function onRemoveTag(event: any) {
318
395
  if (props.multiple) {
319
- const modelValue = props.modelValue;
320
- const filteredValue = modelValue.filter((value) => !isEqual(value, event));
321
- emits("update:modelValue", filteredValue);
322
- onUpdate(filteredValue);
396
+ const modelValue = props.modelValue as GetModelValue<T, VK, true>
397
+ const filteredValue = modelValue.filter(value => !isEqual(value, event))
398
+ emits('update:modelValue', filteredValue as GetModelValue<T, VK, M>)
399
+ onUpdate(filteredValue)
323
400
  }
324
401
  }
325
- function isInputItem(item) {
326
- return typeof item === "object" && item !== null;
402
+
403
+ function isInputItem(item: InputMenuItem): item is _InputMenuItem {
404
+ return typeof item === 'object' && item !== null
327
405
  }
406
+
328
407
  defineExpose({
329
408
  inputRef
330
- });
409
+ })
331
410
  </script>
332
411
 
412
+ <!-- eslint-disable vue/no-template-shadow -->
333
413
  <template>
334
414
  <DefineCreateItemTemplate>
335
415
  <ComboboxGroup :class="b24ui.group({ addNew: true, class: props.b24ui?.group })">
@@ -344,7 +424,7 @@ defineExpose({
344
424
  :is="icons.plus"
345
425
  :class="b24ui.itemLeadingIcon({ addNew: true, class: props.b24ui?.itemLeadingIcon })"
346
426
  />
347
- {{ t("inputMenu.create", { label: searchTerm }) }}
427
+ {{ t('inputMenu.create', { label: searchTerm }) }}
348
428
  </slot>
349
429
  </span>
350
430
  </ComboboxItem>
@@ -371,7 +451,7 @@ defineExpose({
371
451
  <TagsInputRoot
372
452
  v-if="multiple"
373
453
  v-slot="{ modelValue: tags }"
374
- :model-value="modelValue"
454
+ :model-value="(modelValue as string[])"
375
455
  :disabled="disabled"
376
456
  :required="required"
377
457
  delimiter=""
@@ -380,15 +460,15 @@ defineExpose({
380
460
  @focus="onFocus"
381
461
  @remove-tag="onRemoveTag"
382
462
  >
383
- <TagsInputItem v-for="(item, index) in tags" :key="index" :value="item" :class="b24ui.tagsItem({ class: props.b24ui?.tagsItem })">
463
+ <TagsInputItem v-for="(item, index) in tags" :key="index" :value="(item as string)" :class="b24ui.tagsItem({ class: props.b24ui?.tagsItem })">
384
464
  <TagsInputItemText :class="b24ui.tagsItemText({ class: props.b24ui?.tagsItemText })">
385
- <slot name="tags-item-text" :item="item" :index="index">
386
- {{ displayValue(item) }}
465
+ <slot name="tags-item-text" :item="(item as NestedItem<T>)" :index="index">
466
+ {{ displayValue(item as T) }}
387
467
  </slot>
388
468
  </TagsInputItemText>
389
469
 
390
470
  <TagsInputItemDelete :class="b24ui.tagsItemDelete({ class: props.b24ui?.tagsItemDelete })" :disabled="disabled">
391
- <slot name="tags-item-delete" :item="item" :index="index">
471
+ <slot name="tags-item-delete" :item="(item as NestedItem<T>)" :index="index">
392
472
  <Component
393
473
  :is="deleteIcon || icons.close"
394
474
  :class="b24ui.tagsItemDeleteIcon({ class: props.b24ui?.tagsItemDeleteIcon })"
@@ -422,18 +502,18 @@ defineExpose({
422
502
  />
423
503
 
424
504
  <span v-if="isLeading || !!avatar || !!slots.leading" :class="b24ui.leading({ class: props.b24ui?.leading })">
425
- <slot name="leading" :model-value="modelValue" :open="open" :b24ui="b24ui">
505
+ <slot name="leading" :model-value="(modelValue as GetModelValue<T, VK, M>)" :open="open" :b24ui="b24ui">
426
506
  <Component
427
507
  :is="leadingIconName"
428
508
  v-if="isLeading && leadingIconName"
429
509
  :class="b24ui.leadingIcon({ class: props.b24ui?.leadingIcon })"
430
510
  />
431
- <B24Avatar v-else-if="!!avatar" :size="props.b24ui?.itemLeadingAvatarSize || b24ui.itemLeadingAvatarSize()" v-bind="avatar" :class="b24ui.itemLeadingAvatar({ class: props.b24ui?.itemLeadingAvatar })" />
511
+ <B24Avatar v-else-if="!!avatar" :size="((props.b24ui?.itemLeadingAvatarSize || b24ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="avatar" :class="b24ui.itemLeadingAvatar({ class: props.b24ui?.itemLeadingAvatar })" />
432
512
  </slot>
433
513
  </span>
434
514
 
435
515
  <ComboboxTrigger v-if="isTrailing || !!slots.trailing" :class="b24ui.trailing({ class: props.b24ui?.trailing })">
436
- <slot name="trailing" :model-value="modelValue" :open="open" :b24ui="b24ui">
516
+ <slot name="trailing" :model-value="(modelValue as GetModelValue<T, VK, M>)" :open="open" :b24ui="b24ui">
437
517
  <Component
438
518
  :is="trailingIconName"
439
519
  v-if="trailingIconName"
@@ -447,7 +527,7 @@ defineExpose({
447
527
  <ComboboxContent :class="b24ui.content({ class: props.b24ui?.content })" v-bind="contentProps">
448
528
  <ComboboxEmpty :class="b24ui.empty({ class: props.b24ui?.empty })">
449
529
  <slot name="empty" :search-term="searchTerm">
450
- {{ searchTerm ? t("inputMenu.noMatch", { searchTerm }) : t("inputMenu.noData") }}
530
+ {{ searchTerm ? t('inputMenu.noMatch', { searchTerm }) : t('inputMenu.noData') }}
451
531
  </slot>
452
532
  </ComboboxEmpty>
453
533
 
@@ -457,29 +537,29 @@ defineExpose({
457
537
  <ComboboxGroup v-for="(group, groupIndex) in filteredGroups" :key="`group-${groupIndex}`" :class="b24ui.group({ class: props.b24ui?.group })">
458
538
  <template v-for="(item, index) in group" :key="`group-${groupIndex}-${index}`">
459
539
  <ComboboxLabel v-if="isInputItem(item) && item.type === 'label'" :class="b24ui.label({ class: props.b24ui?.label })">
460
- {{ get(item, props.labelKey) }}
540
+ {{ get(item, props.labelKey as string) }}
461
541
  </ComboboxLabel>
462
542
 
463
543
  <ComboboxSeparator v-else-if="isInputItem(item) && item.type === 'separator'" :class="b24ui.separator({ class: props.b24ui?.separator })" />
464
544
 
465
545
  <ComboboxItem
466
546
  v-else
467
- :class="b24ui.item({ class: props.b24ui?.item, colorItem: isInputItem(item) ? item?.color : void 0 })"
547
+ :class="b24ui.item({ class: props.b24ui?.item, colorItem: isInputItem(item) ? item?.color : undefined })"
468
548
  :disabled="isInputItem(item) && item.disabled"
469
549
  :value="props.valueKey && isInputItem(item) ? get(item, String(props.valueKey)) : item"
470
550
  @select="isInputItem(item) && item.onSelect?.($event)"
471
551
  >
472
- <slot name="item" :item="item" :index="index">
473
- <slot name="item-leading" :item="item" :index="index">
552
+ <slot name="item" :item="(item as NestedItem<T>)" :index="index">
553
+ <slot name="item-leading" :item="(item as NestedItem<T>)" :index="index">
474
554
  <Component
475
555
  :is="item.icon"
476
556
  v-if="isInputItem(item) && item.icon"
477
557
  :class="b24ui.itemLeadingIcon({ class: props.b24ui?.itemLeadingIcon, colorItem: item?.color })"
478
558
  />
479
- <B24Avatar v-else-if="isInputItem(item) && item.avatar" :size="props.b24ui?.itemLeadingAvatarSize || b24ui.itemLeadingAvatarSize()" v-bind="item.avatar" :class="b24ui.itemLeadingAvatar({ class: props.b24ui?.itemLeadingAvatar, colorItem: item?.color })" />
559
+ <B24Avatar v-else-if="isInputItem(item) && item.avatar" :size="((props.b24ui?.itemLeadingAvatarSize || b24ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="item.avatar" :class="b24ui.itemLeadingAvatar({ class: props.b24ui?.itemLeadingAvatar, colorItem: item?.color })" />
480
560
  <B24Chip
481
561
  v-else-if="isInputItem(item) && item.chip"
482
- :size="props.b24ui?.itemLeadingChipSize || b24ui.itemLeadingChipSize()"
562
+ :size="((props.b24ui?.itemLeadingChipSize || b24ui.itemLeadingChipSize()) as ChipProps['size'])"
483
563
  inset
484
564
  standalone
485
565
  v-bind="item.chip"
@@ -488,18 +568,18 @@ defineExpose({
488
568
  </slot>
489
569
 
490
570
  <span :class="b24ui.itemLabel({ class: props.b24ui?.itemLabel })">
491
- <slot name="item-label" :item="item" :index="index">
492
- {{ isInputItem(item) ? get(item, props.labelKey) : item }}
571
+ <slot name="item-label" :item="(item as NestedItem<T>)" :index="index">
572
+ {{ isInputItem(item) ? get(item, props.labelKey as string) : item }}
493
573
  </slot>
494
574
  </span>
495
575
 
496
- <span :class="b24ui.itemTrailing({ class: props.b24ui?.itemTrailing, colorItem: isInputItem(item) ? item?.color : void 0 })">
497
- <slot name="item-trailing" :item="item" :index="index" />
576
+ <span :class="b24ui.itemTrailing({ class: props.b24ui?.itemTrailing, colorItem: isInputItem(item) ? item?.color : undefined })">
577
+ <slot name="item-trailing" :item="(item as NestedItem<T>)" :index="index" />
498
578
 
499
579
  <ComboboxItemIndicator as-child>
500
580
  <Component
501
581
  :is="selectedIcon || icons.check"
502
- :class="b24ui.itemTrailingIcon({ class: props.b24ui?.itemTrailingIcon, colorItem: isInputItem(item) ? item?.color : void 0 })"
582
+ :class="b24ui.itemTrailingIcon({ class: props.b24ui?.itemTrailingIcon, colorItem: isInputItem(item) ? item?.color : undefined })"
503
583
  />
504
584
  </ComboboxItemIndicator>
505
585
  </span>