@bitrix24/b24ui-nuxt 0.5.2 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.nuxt/b24ui/button.ts +10 -10
- package/.nuxt/b24ui/container.ts +1 -1
- package/.nuxt/b24ui/navigation-menu.ts +185 -11
- package/.nuxt/b24ui/switch.ts +1 -1
- package/.nuxt/b24ui/tabs.ts +1 -1
- package/dist/meta.cjs +48504 -45664
- package/dist/meta.d.cts +48504 -45664
- package/dist/meta.d.mts +48504 -45664
- package/dist/meta.d.ts +48504 -45664
- package/dist/meta.mjs +48504 -45664
- package/dist/module.cjs +1 -1
- package/dist/module.d.cts +2 -1
- package/dist/module.d.mts +2 -1
- package/dist/module.d.ts +2 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +1 -1
- package/dist/runtime/components/Alert.vue +1 -1
- package/dist/runtime/components/App.vue +1 -1
- package/dist/runtime/components/Button.vue +1 -1
- package/dist/runtime/components/Calendar.vue +40 -12
- package/dist/runtime/components/DescriptionList.vue +99 -85
- package/dist/runtime/components/DropdownMenu.vue +23 -12
- package/dist/runtime/components/DropdownMenuContent.vue +22 -15
- package/dist/runtime/components/InputMenu.vue +91 -53
- package/dist/runtime/components/Link.vue +3 -0
- package/dist/runtime/components/LinkBase.vue +1 -0
- package/dist/runtime/components/Modal.vue +1 -1
- package/dist/runtime/components/NavigationMenu.vue +65 -26
- package/dist/runtime/components/RadioGroup.vue +23 -12
- package/dist/runtime/components/Select.vue +74 -47
- package/dist/runtime/components/SelectMenu.vue +95 -56
- package/dist/runtime/components/Slideover.vue +1 -1
- package/dist/runtime/components/Tabs.vue +6 -5
- package/dist/runtime/components/Toast.vue +1 -1
- package/dist/runtime/composables/defineShortcuts.js +0 -1
- package/dist/runtime/composables/useComponentIcons.d.ts +2 -2
- package/dist/runtime/types/utils.d.ts +28 -7
- package/dist/runtime/utils/index.d.ts +1 -0
- package/dist/runtime/utils/index.js +3 -0
- package/dist/runtime/utils/link.d.ts +2 -25
- package/dist/runtime/utils/link.js +31 -1
- package/dist/runtime/vue/components/Link.vue +3 -0
- package/dist/runtime/vue/stubs.d.ts +3 -3
- package/dist/shared/{b24ui-nuxt.CKEqlXJP.cjs → b24ui-nuxt.BfU7TRfz.cjs} +311 -22
- package/dist/shared/{b24ui-nuxt.DQ3Ix7rC.mjs → b24ui-nuxt.CTERD7XY.mjs} +311 -22
- package/dist/types.d.mts +7 -1
- package/dist/types.d.ts +7 -1
- package/dist/unplugin.cjs +1 -1
- package/dist/unplugin.d.cts +2 -1
- package/dist/unplugin.d.mts +2 -1
- package/dist/unplugin.d.ts +2 -1
- package/dist/unplugin.mjs +1 -1
- package/dist/vite.cjs +1 -1
- package/dist/vite.mjs +1 -1
- package/package.json +34 -18
|
@@ -4,14 +4,15 @@ import type { DropdownMenuContentProps as RekaDropdownMenuContentProps, Dropdown
|
|
|
4
4
|
import theme from '#build/b24ui/dropdown-menu'
|
|
5
5
|
import { tv } from '../utils/tv'
|
|
6
6
|
import type { KbdProps, AvatarProps, DropdownMenuItem, DropdownMenuSlots, IconComponent } from '../types'
|
|
7
|
+
import type { ArrayOrNested, NestedItem } from '../types/utils'
|
|
7
8
|
|
|
8
9
|
const _dropdownMenu = tv(theme)()
|
|
9
10
|
|
|
10
|
-
interface DropdownMenuContentProps<T
|
|
11
|
-
items?: T
|
|
11
|
+
interface DropdownMenuContentProps<T extends ArrayOrNested<DropdownMenuItem>> extends Omit<RekaDropdownMenuContentProps, 'as' | 'asChild' | 'forceMount'> {
|
|
12
|
+
items?: T
|
|
12
13
|
portal?: boolean
|
|
13
14
|
sub?: boolean
|
|
14
|
-
labelKey:
|
|
15
|
+
labelKey: keyof NestedItem<T>
|
|
15
16
|
/**
|
|
16
17
|
* @IconComponent
|
|
17
18
|
*/
|
|
@@ -27,17 +28,17 @@ interface DropdownMenuContentProps<T> extends Omit<RekaDropdownMenuContentProps,
|
|
|
27
28
|
|
|
28
29
|
interface DropdownMenuContentEmits extends RekaDropdownMenuContentEmits {}
|
|
29
30
|
|
|
30
|
-
type DropdownMenuContentSlots<T extends
|
|
31
|
+
type DropdownMenuContentSlots<T extends ArrayOrNested<DropdownMenuItem>> = Omit<DropdownMenuSlots<T>, 'default'> & {
|
|
31
32
|
default(props?: {}): any
|
|
32
33
|
}
|
|
33
34
|
</script>
|
|
34
35
|
|
|
35
|
-
<script setup lang="ts" generic="T extends DropdownMenuItem">
|
|
36
|
+
<script setup lang="ts" generic="T extends ArrayOrNested<DropdownMenuItem>">
|
|
36
37
|
import { computed } from 'vue'
|
|
37
38
|
import { DropdownMenu } from 'reka-ui/namespaced'
|
|
38
39
|
import { useForwardPropsEmits } from 'reka-ui'
|
|
39
40
|
import { reactiveOmit, createReusableTemplate } from '@vueuse/core'
|
|
40
|
-
import { omit, get } from '../utils'
|
|
41
|
+
import { omit, get, isArrayOfArray } from '../utils'
|
|
41
42
|
import { pickLinkProps } from '../utils/link'
|
|
42
43
|
import icons from '../dictionary/icons'
|
|
43
44
|
import B24LinkBase from './LinkBase.vue'
|
|
@@ -52,17 +53,23 @@ const emits = defineEmits<DropdownMenuContentEmits>()
|
|
|
52
53
|
const slots = defineSlots<DropdownMenuContentSlots<T>>()
|
|
53
54
|
|
|
54
55
|
const contentProps = useForwardPropsEmits(reactiveOmit(props, 'sub', 'items', 'portal', 'labelKey', 'checkedIcon', 'externalIcon', 'class', 'b24ui', 'b24uiOverride'), emits)
|
|
55
|
-
const proxySlots = omit(slots, ['default'])
|
|
56
|
+
const proxySlots = omit(slots, ['default'])
|
|
56
57
|
|
|
57
58
|
const [DefineItemTemplate, ReuseItemTemplate] = createReusableTemplate<{ item: DropdownMenuItem, active?: boolean, index: number }>()
|
|
58
59
|
|
|
59
|
-
const groups = computed
|
|
60
|
+
const groups = computed<DropdownMenuItem[][]>(() =>
|
|
61
|
+
props.items?.length
|
|
62
|
+
? isArrayOfArray(props.items)
|
|
63
|
+
? props.items
|
|
64
|
+
: [props.items]
|
|
65
|
+
: []
|
|
66
|
+
)
|
|
60
67
|
</script>
|
|
61
68
|
|
|
62
69
|
<template>
|
|
63
70
|
<DefineItemTemplate v-slot="{ item, active, index }">
|
|
64
|
-
<slot :name="item.slot || 'item'" :item="(item as T)" :index="index">
|
|
65
|
-
<slot :name="item.slot ? `${item.slot}-leading`: 'item-leading'" :item="(item as T)" :active="active" :index="index">
|
|
71
|
+
<slot :name="((item.slot || 'item') as keyof DropdownMenuContentSlots<T>)" :item="(item as Extract<NestedItem<T>, { slot: string; }>)" :index="index">
|
|
72
|
+
<slot :name="((item.slot ? `${item.slot}-leading`: 'item-leading') as keyof DropdownMenuContentSlots<T>)" :item="(item as Extract<NestedItem<T>, { slot: string; }>)" :active="active" :index="index">
|
|
66
73
|
<Component
|
|
67
74
|
:is="icons.loading"
|
|
68
75
|
v-if="item.loading"
|
|
@@ -81,8 +88,8 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
|
|
|
81
88
|
/>
|
|
82
89
|
</slot>
|
|
83
90
|
|
|
84
|
-
<span v-if="get(item, props.labelKey as string) || !!slots[item.slot ? `${item.slot}-label`: 'item-label']" :class="b24ui.itemLabel({ class: b24uiOverride?.itemLabel, active })">
|
|
85
|
-
<slot :name="item.slot ? `${item.slot}-label`: 'item-label'" :item="(item as T)" :active="active" :index="index">
|
|
91
|
+
<span v-if="get(item, props.labelKey as string) || !!slots[(item.slot ? `${item.slot}-label`: 'item-label') as keyof DropdownMenuContentSlots<T>]" :class="b24ui.itemLabel({ class: b24uiOverride?.itemLabel, active })">
|
|
92
|
+
<slot :name="((item.slot ? `${item.slot}-label`: 'item-label') as keyof DropdownMenuContentSlots<T>)" :item="(item as Extract<NestedItem<T>, { slot: string; }>)" :active="active" :index="index">
|
|
86
93
|
{{ get(item, props.labelKey as string) }}
|
|
87
94
|
</slot>
|
|
88
95
|
<Component
|
|
@@ -93,7 +100,7 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
|
|
|
93
100
|
</span>
|
|
94
101
|
|
|
95
102
|
<span :class="b24ui.itemTrailing({ class: b24uiOverride?.itemTrailing })">
|
|
96
|
-
<slot :name="item.slot ? `${item.slot}-trailing`: 'item-trailing'" :item="(item as T)" :active="active" :index="index">
|
|
103
|
+
<slot :name="((item.slot ? `${item.slot}-trailing`: 'item-trailing') as keyof DropdownMenuContentSlots<T>)" :item="(item as Extract<NestedItem<T>, { slot: string; }>)" :active="active" :index="index">
|
|
97
104
|
<Component
|
|
98
105
|
:is="icons.chevronRight"
|
|
99
106
|
v-if="item.children?.length"
|
|
@@ -139,7 +146,7 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
|
|
|
139
146
|
:b24ui="b24ui"
|
|
140
147
|
:b24ui-override="b24uiOverride"
|
|
141
148
|
:portal="portal"
|
|
142
|
-
:items="item.children"
|
|
149
|
+
:items="(item.children as T)"
|
|
143
150
|
side="right"
|
|
144
151
|
align="start"
|
|
145
152
|
:align-offset="-4"
|
|
@@ -150,7 +157,7 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
|
|
|
150
157
|
v-bind="item.content"
|
|
151
158
|
>
|
|
152
159
|
<template v-for="(_, name) in proxySlots" #[name]="slotData: any">
|
|
153
|
-
<slot :name="name" v-bind="slotData" />
|
|
160
|
+
<slot :name="(name as keyof DropdownMenuContentSlots<T>)" v-bind="slotData" />
|
|
154
161
|
</template>
|
|
155
162
|
</B24DropdownMenuContent>
|
|
156
163
|
</DropdownMenu.Sub>
|
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { InputHTMLAttributes } from 'vue'
|
|
3
3
|
import type { VariantProps } from 'tailwind-variants'
|
|
4
|
-
import type { ComboboxRootProps, ComboboxRootEmits, ComboboxContentProps, ComboboxContentEmits, ComboboxArrowProps
|
|
4
|
+
import type { ComboboxRootProps, ComboboxRootEmits, ComboboxContentProps, ComboboxContentEmits, ComboboxArrowProps } from 'reka-ui'
|
|
5
5
|
import type { AppConfig } from '@nuxt/schema'
|
|
6
6
|
import _appConfig from '#build/app.config'
|
|
7
7
|
import theme from '#build/b24ui/input-menu'
|
|
8
8
|
import type { UseComponentIconsProps } from '../composables/useComponentIcons'
|
|
9
9
|
import { tv } from '../utils/tv'
|
|
10
10
|
import type { AvatarProps, ChipProps, InputProps, IconComponent } from '../types'
|
|
11
|
-
import type {
|
|
11
|
+
import type {
|
|
12
|
+
AcceptableValue,
|
|
13
|
+
ArrayOrNested,
|
|
14
|
+
GetItemKeys,
|
|
15
|
+
GetModelValue,
|
|
16
|
+
GetModelValueEmits,
|
|
17
|
+
NestedItem,
|
|
18
|
+
PartialString,
|
|
19
|
+
EmitsToProps
|
|
20
|
+
} from '../types/utils'
|
|
12
21
|
|
|
13
22
|
const appConfigInputMenu = _appConfig as AppConfig & { b24ui: { inputMenu: Partial<typeof theme> } }
|
|
14
23
|
|
|
@@ -16,7 +25,7 @@ const inputMenu = tv({ extend: tv(theme), ...(appConfigInputMenu.b24ui?.inputMen
|
|
|
16
25
|
|
|
17
26
|
type InputMenuVariants = VariantProps<typeof inputMenu>
|
|
18
27
|
|
|
19
|
-
|
|
28
|
+
interface _InputMenuItem {
|
|
20
29
|
label?: string
|
|
21
30
|
/**
|
|
22
31
|
* Display an icon on the left side.
|
|
@@ -31,11 +40,14 @@ export interface InputMenuItem {
|
|
|
31
40
|
* @defaultValue 'item'
|
|
32
41
|
*/
|
|
33
42
|
type?: 'label' | 'separator' | 'item'
|
|
43
|
+
value?: string | number
|
|
34
44
|
disabled?: boolean
|
|
35
45
|
onSelect?(e?: Event): void
|
|
46
|
+
[key: string]: any
|
|
36
47
|
}
|
|
48
|
+
export type InputMenuItem = _InputMenuItem | AcceptableValue | boolean
|
|
37
49
|
|
|
38
|
-
export interface InputMenuProps<T extends
|
|
50
|
+
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 {
|
|
39
51
|
/**
|
|
40
52
|
* The element or component this component should render as.
|
|
41
53
|
* @defaultValue 'div'
|
|
@@ -128,21 +140,21 @@ export interface InputMenuProps<T extends MaybeArrayOfArrayItem<I>, I extends Ma
|
|
|
128
140
|
* When `items` is an array of objects, select the field to use as the value instead of the object itself.
|
|
129
141
|
* @defaultValue undefined
|
|
130
142
|
*/
|
|
131
|
-
valueKey?:
|
|
143
|
+
valueKey?: VK
|
|
132
144
|
/**
|
|
133
145
|
* When `items` is an array of objects, select the field to use as the label.
|
|
134
146
|
* @defaultValue 'label'
|
|
135
147
|
*/
|
|
136
|
-
labelKey?:
|
|
137
|
-
items?:
|
|
148
|
+
labelKey?: keyof NestedItem<T>
|
|
149
|
+
items?: T
|
|
138
150
|
/**
|
|
139
151
|
* The value of the InputMenu when initially rendered. Use when you do not need to control the state of the InputMenu
|
|
140
152
|
*/
|
|
141
|
-
defaultValue?:
|
|
153
|
+
defaultValue?: GetModelValue<T, VK, M>
|
|
142
154
|
/**
|
|
143
155
|
* The controlled value of the InputMenu. Can be binded-with with `v-model`
|
|
144
156
|
*/
|
|
145
|
-
modelValue?:
|
|
157
|
+
modelValue?: GetModelValue<T, VK, M>
|
|
146
158
|
/**
|
|
147
159
|
* Whether multiple options can be selected or not
|
|
148
160
|
* @defaultValue false
|
|
@@ -177,18 +189,28 @@ export interface InputMenuProps<T extends MaybeArrayOfArrayItem<I>, I extends Ma
|
|
|
177
189
|
b24ui?: PartialString<typeof inputMenu.slots>
|
|
178
190
|
}
|
|
179
191
|
|
|
180
|
-
export type InputMenuEmits<
|
|
192
|
+
export type InputMenuEmits<A extends ArrayOrNested<InputMenuItem>, VK extends GetItemKeys<A> | undefined, M extends boolean> = Pick<ComboboxRootEmits, 'update:open'> & {
|
|
181
193
|
change: [payload: Event]
|
|
182
194
|
blur: [payload: FocusEvent]
|
|
183
195
|
focus: [payload: FocusEvent]
|
|
184
196
|
create: [item: string]
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
197
|
+
/** Event handler when highlighted element changes. */
|
|
198
|
+
highlight: [payload: {
|
|
199
|
+
ref: HTMLElement
|
|
200
|
+
value: GetModelValue<A, VK, M>
|
|
201
|
+
} | undefined]
|
|
202
|
+
} & GetModelValueEmits<A, VK, M>
|
|
203
|
+
|
|
204
|
+
type SlotProps<T extends InputMenuItem> = (props: { item: T, index: number }) => any
|
|
205
|
+
|
|
206
|
+
export interface InputMenuSlots<
|
|
207
|
+
A extends ArrayOrNested<InputMenuItem> = ArrayOrNested<InputMenuItem>,
|
|
208
|
+
VK extends GetItemKeys<A> | undefined = undefined,
|
|
209
|
+
M extends boolean = false,
|
|
210
|
+
T extends NestedItem<A> = NestedItem<A>
|
|
211
|
+
> {
|
|
212
|
+
'leading'(props: { modelValue?: GetModelValue<A, VK, M>, open: boolean, b24ui: ReturnType<typeof inputMenu> }): any
|
|
213
|
+
'trailing'(props: { modelValue?: GetModelValue<A, VK, M>, open: boolean, b24ui: ReturnType<typeof inputMenu> }): any
|
|
192
214
|
'empty'(props: { searchTerm?: string }): any
|
|
193
215
|
'item': SlotProps<T>
|
|
194
216
|
'item-leading': SlotProps<T>
|
|
@@ -200,7 +222,7 @@ export interface InputMenuSlots<T, M extends boolean> {
|
|
|
200
222
|
}
|
|
201
223
|
</script>
|
|
202
224
|
|
|
203
|
-
<script setup lang="ts" generic="T extends
|
|
225
|
+
<script setup lang="ts" generic="T extends ArrayOrNested<InputMenuItem>, VK extends GetItemKeys<T> | undefined = undefined, M extends boolean = false">
|
|
204
226
|
import { computed, ref, toRef, onMounted, toRaw } from 'vue'
|
|
205
227
|
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'
|
|
206
228
|
import { defu } from 'defu'
|
|
@@ -210,21 +232,21 @@ import { useButtonGroup } from '../composables/useButtonGroup'
|
|
|
210
232
|
import { useComponentIcons } from '../composables/useComponentIcons'
|
|
211
233
|
import { useFormField } from '../composables/useFormField'
|
|
212
234
|
import { useLocale } from '../composables/useLocale'
|
|
213
|
-
import { get,
|
|
235
|
+
import { compare, get, isArrayOfArray } from '../utils'
|
|
214
236
|
import icons from '../dictionary/icons'
|
|
215
237
|
import B24Avatar from './Avatar.vue'
|
|
216
238
|
import B24Chip from './Chip.vue'
|
|
217
239
|
|
|
218
240
|
defineOptions({ inheritAttrs: false })
|
|
219
241
|
|
|
220
|
-
const props = withDefaults(defineProps<InputMenuProps<T,
|
|
242
|
+
const props = withDefaults(defineProps<InputMenuProps<T, VK, M>>(), {
|
|
221
243
|
type: 'text',
|
|
222
244
|
autofocusDelay: 0,
|
|
223
245
|
portal: true,
|
|
224
246
|
labelKey: 'label' as never
|
|
225
247
|
})
|
|
226
|
-
const emits = defineEmits<InputMenuEmits<T,
|
|
227
|
-
const slots = defineSlots<InputMenuSlots<T, M>>()
|
|
248
|
+
const emits = defineEmits<InputMenuEmits<T, VK, M>>()
|
|
249
|
+
const slots = defineSlots<InputMenuSlots<T, VK, M>>()
|
|
228
250
|
|
|
229
251
|
const searchTerm = defineModel<string>('searchTerm', { default: '' })
|
|
230
252
|
|
|
@@ -272,9 +294,15 @@ function displayValue(value: T): string {
|
|
|
272
294
|
return item && (typeof item === 'object' ? get(item, props.labelKey as string) : item)
|
|
273
295
|
}
|
|
274
296
|
|
|
275
|
-
const groups = computed
|
|
297
|
+
const groups = computed<InputMenuItem[][]>(() =>
|
|
298
|
+
props.items?.length
|
|
299
|
+
? isArrayOfArray(props.items)
|
|
300
|
+
? props.items
|
|
301
|
+
: [props.items]
|
|
302
|
+
: []
|
|
303
|
+
)
|
|
276
304
|
// eslint-disable-next-line vue/no-dupe-keys
|
|
277
|
-
const items = computed(() => groups.value.flatMap(group => group)
|
|
305
|
+
const items = computed(() => groups.value.flatMap(group => group))
|
|
278
306
|
|
|
279
307
|
const filteredGroups = computed(() => {
|
|
280
308
|
if (props.ignoreFilter || !searchTerm.value) {
|
|
@@ -283,9 +311,9 @@ const filteredGroups = computed(() => {
|
|
|
283
311
|
|
|
284
312
|
const fields = Array.isArray(props.filterFields) ? props.filterFields : [props.labelKey] as string[]
|
|
285
313
|
|
|
286
|
-
return groups.value.map(
|
|
287
|
-
if (typeof item !== 'object') {
|
|
288
|
-
return contains(item, searchTerm.value)
|
|
314
|
+
return groups.value.map(group => group.filter((item) => {
|
|
315
|
+
if (typeof item !== 'object' || item === null) {
|
|
316
|
+
return contains(String(item), searchTerm.value)
|
|
289
317
|
}
|
|
290
318
|
|
|
291
319
|
if (item.type && ['label', 'separator'].includes(item.type)) {
|
|
@@ -293,19 +321,25 @@ const filteredGroups = computed(() => {
|
|
|
293
321
|
}
|
|
294
322
|
|
|
295
323
|
return fields.some(field => contains(get(item, field), searchTerm.value))
|
|
296
|
-
})).filter(group => group.filter(item =>
|
|
324
|
+
})).filter(group => group.filter(item =>
|
|
325
|
+
/**
|
|
326
|
+
* @memo fix not obj
|
|
327
|
+
* @see selectMenu
|
|
328
|
+
*/
|
|
329
|
+
typeof item !== 'object' || (isInputItem(item) && (!item.type || !['label', 'separator'].includes(item.type)))
|
|
330
|
+
).length > 0)
|
|
297
331
|
})
|
|
298
|
-
const filteredItems = computed(() => filteredGroups.value.flatMap(group => group)
|
|
332
|
+
const filteredItems = computed(() => filteredGroups.value.flatMap(group => group))
|
|
299
333
|
|
|
300
334
|
const createItem = computed(() => {
|
|
301
335
|
if (!props.createItem || !searchTerm.value) {
|
|
302
336
|
return false
|
|
303
337
|
}
|
|
304
338
|
|
|
305
|
-
const newItem = props.valueKey ? { [props.valueKey]: searchTerm.value } as T : searchTerm.value
|
|
339
|
+
const newItem = props.valueKey ? { [props.valueKey]: searchTerm.value } as NestedItem<T> : searchTerm.value
|
|
306
340
|
|
|
307
341
|
if ((typeof props.createItem === 'object' && props.createItem.when === 'always') || props.createItem === 'always') {
|
|
308
|
-
return !filteredItems.value.find(item => compare(item, newItem, props.valueKey))
|
|
342
|
+
return !filteredItems.value.find(item => compare(item, newItem, String(props.valueKey)))
|
|
309
343
|
}
|
|
310
344
|
|
|
311
345
|
return !filteredItems.value.length
|
|
@@ -360,12 +394,16 @@ function onUpdateOpen(value: boolean) {
|
|
|
360
394
|
|
|
361
395
|
function onRemoveTag(event: any) {
|
|
362
396
|
if (props.multiple) {
|
|
363
|
-
const modelValue = props.modelValue as
|
|
397
|
+
const modelValue = props.modelValue as GetModelValue<T, VK, true>
|
|
364
398
|
const filteredValue = modelValue.filter(value => !isEqual(value, event))
|
|
365
|
-
emits('update:modelValue', filteredValue as
|
|
399
|
+
emits('update:modelValue', filteredValue as GetModelValue<T, VK, M>)
|
|
366
400
|
}
|
|
367
401
|
}
|
|
368
402
|
|
|
403
|
+
function isInputItem(item: InputMenuItem): item is _InputMenuItem {
|
|
404
|
+
return typeof item === 'object' && item !== null
|
|
405
|
+
}
|
|
406
|
+
|
|
369
407
|
defineExpose({
|
|
370
408
|
inputRef
|
|
371
409
|
})
|
|
@@ -424,13 +462,13 @@ defineExpose({
|
|
|
424
462
|
>
|
|
425
463
|
<TagsInputItem v-for="(item, index) in tags" :key="index" :value="(item as string)" :class="b24ui.tagsItem({ class: props.b24ui?.tagsItem })">
|
|
426
464
|
<TagsInputItemText :class="b24ui.tagsItemText({ class: props.b24ui?.tagsItemText })">
|
|
427
|
-
<slot name="tags-item-text" :item="(item as T)" :index="index">
|
|
465
|
+
<slot name="tags-item-text" :item="(item as NestedItem<T>)" :index="index">
|
|
428
466
|
{{ displayValue(item as T) }}
|
|
429
467
|
</slot>
|
|
430
468
|
</TagsInputItemText>
|
|
431
469
|
|
|
432
470
|
<TagsInputItemDelete :class="b24ui.tagsItemDelete({ class: props.b24ui?.tagsItemDelete })" :disabled="disabled">
|
|
433
|
-
<slot name="tags-item-delete" :item="(item as T)" :index="index">
|
|
471
|
+
<slot name="tags-item-delete" :item="(item as NestedItem<T>)" :index="index">
|
|
434
472
|
<Component
|
|
435
473
|
:is="deleteIcon || icons.close"
|
|
436
474
|
:class="b24ui.tagsItemDeleteIcon({ class: props.b24ui?.tagsItemDeleteIcon })"
|
|
@@ -464,7 +502,7 @@ defineExpose({
|
|
|
464
502
|
/>
|
|
465
503
|
|
|
466
504
|
<span v-if="isLeading || !!avatar || !!slots.leading" :class="b24ui.leading({ class: props.b24ui?.leading })">
|
|
467
|
-
<slot name="leading" :model-value="(modelValue as
|
|
505
|
+
<slot name="leading" :model-value="(modelValue as GetModelValue<T, VK, M>)" :open="open" :b24ui="b24ui">
|
|
468
506
|
<Component
|
|
469
507
|
:is="leadingIconName"
|
|
470
508
|
v-if="isLeading && leadingIconName"
|
|
@@ -475,7 +513,7 @@ defineExpose({
|
|
|
475
513
|
</span>
|
|
476
514
|
|
|
477
515
|
<ComboboxTrigger v-if="isTrailing || !!slots.trailing" :class="b24ui.trailing({ class: props.b24ui?.trailing })">
|
|
478
|
-
<slot name="trailing" :model-value="(modelValue as
|
|
516
|
+
<slot name="trailing" :model-value="(modelValue as GetModelValue<T, VK, M>)" :open="open" :b24ui="b24ui">
|
|
479
517
|
<Component
|
|
480
518
|
:is="trailingIconName"
|
|
481
519
|
v-if="trailingIconName"
|
|
@@ -498,29 +536,29 @@ defineExpose({
|
|
|
498
536
|
|
|
499
537
|
<ComboboxGroup v-for="(group, groupIndex) in filteredGroups" :key="`group-${groupIndex}`" :class="b24ui.group({ class: props.b24ui?.group })">
|
|
500
538
|
<template v-for="(item, index) in group" :key="`group-${groupIndex}-${index}`">
|
|
501
|
-
<ComboboxLabel v-if="item
|
|
539
|
+
<ComboboxLabel v-if="isInputItem(item) && item.type === 'label'" :class="b24ui.label({ class: props.b24ui?.label })">
|
|
502
540
|
{{ get(item, props.labelKey as string) }}
|
|
503
541
|
</ComboboxLabel>
|
|
504
542
|
|
|
505
|
-
<ComboboxSeparator v-else-if="item
|
|
543
|
+
<ComboboxSeparator v-else-if="isInputItem(item) && item.type === 'separator'" :class="b24ui.separator({ class: props.b24ui?.separator })" />
|
|
506
544
|
|
|
507
545
|
<ComboboxItem
|
|
508
546
|
v-else
|
|
509
|
-
:class="b24ui.item({ class: props.b24ui?.item, colorItem: item?.color })"
|
|
510
|
-
:disabled="item.disabled"
|
|
511
|
-
:value="valueKey &&
|
|
512
|
-
@select="item.onSelect"
|
|
547
|
+
:class="b24ui.item({ class: props.b24ui?.item, colorItem: isInputItem(item) ? item?.color : undefined })"
|
|
548
|
+
:disabled="isInputItem(item) && item.disabled"
|
|
549
|
+
:value="props.valueKey && isInputItem(item) ? get(item, String(props.valueKey)) : item"
|
|
550
|
+
@select="isInputItem(item) && item.onSelect"
|
|
513
551
|
>
|
|
514
|
-
<slot name="item" :item="(item as T)" :index="index">
|
|
515
|
-
<slot name="item-leading" :item="(item as T)" :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">
|
|
516
554
|
<Component
|
|
517
555
|
:is="item.icon"
|
|
518
|
-
v-if="item.icon"
|
|
556
|
+
v-if="isInputItem(item) && item.icon"
|
|
519
557
|
:class="b24ui.itemLeadingIcon({ class: props.b24ui?.itemLeadingIcon, colorItem: item?.color })"
|
|
520
558
|
/>
|
|
521
|
-
<B24Avatar v-else-if="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 })" />
|
|
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 })" />
|
|
522
560
|
<B24Chip
|
|
523
|
-
v-else-if="item.chip"
|
|
561
|
+
v-else-if="isInputItem(item) && item.chip"
|
|
524
562
|
:size="((props.b24ui?.itemLeadingChipSize || b24ui.itemLeadingChipSize()) as ChipProps['size'])"
|
|
525
563
|
inset
|
|
526
564
|
standalone
|
|
@@ -530,18 +568,18 @@ defineExpose({
|
|
|
530
568
|
</slot>
|
|
531
569
|
|
|
532
570
|
<span :class="b24ui.itemLabel({ class: props.b24ui?.itemLabel })">
|
|
533
|
-
<slot name="item-label" :item="(item as T)" :index="index">
|
|
534
|
-
{{
|
|
571
|
+
<slot name="item-label" :item="(item as NestedItem<T>)" :index="index">
|
|
572
|
+
{{ isInputItem(item) ? get(item, props.labelKey as string) : item }}
|
|
535
573
|
</slot>
|
|
536
574
|
</span>
|
|
537
575
|
|
|
538
|
-
<span :class="b24ui.itemTrailing({ class: props.b24ui?.itemTrailing, colorItem: item?.color })">
|
|
539
|
-
<slot name="item-trailing" :item="(item as T)" :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" />
|
|
540
578
|
|
|
541
579
|
<ComboboxItemIndicator as-child>
|
|
542
580
|
<Component
|
|
543
581
|
:is="selectedIcon || icons.check"
|
|
544
|
-
:class="b24ui.itemTrailingIcon({ class: props.b24ui?.itemTrailingIcon, colorItem: item?.color })"
|
|
582
|
+
:class="b24ui.itemTrailingIcon({ class: props.b24ui?.itemTrailingIcon, colorItem: isInputItem(item) ? item?.color : undefined })"
|
|
545
583
|
/>
|
|
546
584
|
</ComboboxItemIndicator>
|
|
547
585
|
</span>
|
|
@@ -104,6 +104,7 @@ defineOptions({ inheritAttrs: false })
|
|
|
104
104
|
const props = withDefaults(defineProps<LinkProps>(), {
|
|
105
105
|
as: 'button',
|
|
106
106
|
type: 'button',
|
|
107
|
+
ariaCurrentValue: 'page',
|
|
107
108
|
active: undefined,
|
|
108
109
|
isAction: false,
|
|
109
110
|
activeClass: '',
|
|
@@ -190,6 +191,7 @@ function resolveLinkClass({ route, isActive, isExactActive }: any) {
|
|
|
190
191
|
<slot
|
|
191
192
|
v-bind="{
|
|
192
193
|
...$attrs,
|
|
194
|
+
...(exact && isExactActive ? { 'aria-current': props.ariaCurrentValue } : {}),
|
|
193
195
|
as,
|
|
194
196
|
type,
|
|
195
197
|
disabled,
|
|
@@ -206,6 +208,7 @@ function resolveLinkClass({ route, isActive, isExactActive }: any) {
|
|
|
206
208
|
v-else
|
|
207
209
|
v-bind="{
|
|
208
210
|
...$attrs,
|
|
211
|
+
...(exact && isExactActive ? { 'aria-current': props.ariaCurrentValue } : {}),
|
|
209
212
|
as,
|
|
210
213
|
type,
|
|
211
214
|
disabled,
|
|
@@ -82,7 +82,7 @@ export interface ModalSlots {
|
|
|
82
82
|
header(props?: {}): any
|
|
83
83
|
title(props?: {}): any
|
|
84
84
|
description(props?: {}): any
|
|
85
|
-
close(props: { b24ui:
|
|
85
|
+
close(props: { b24ui: ReturnType<typeof modal> }): any
|
|
86
86
|
body(props?: {}): any
|
|
87
87
|
footer(props?: {}): any
|
|
88
88
|
}
|