@nuxt/ui 3.0.1 → 3.1.0
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/ui/accordion.ts +25 -4
- package/.nuxt/ui/alert.ts +52 -31
- package/.nuxt/ui/avatar-group.ts +24 -3
- package/.nuxt/ui/avatar.ts +26 -5
- package/.nuxt/ui/badge.ts +56 -35
- package/.nuxt/ui/breadcrumb.ts +28 -7
- package/.nuxt/ui/button-group.ts +23 -2
- package/.nuxt/ui/button.ts +66 -45
- package/.nuxt/ui/calendar.ts +39 -18
- package/.nuxt/ui/card.ts +28 -7
- package/.nuxt/ui/carousel.ts +29 -8
- package/.nuxt/ui/checkbox-group.ts +82 -0
- package/.nuxt/ui/checkbox.ts +163 -29
- package/.nuxt/ui/chip.ts +31 -10
- package/.nuxt/ui/collapsible.ts +23 -2
- package/.nuxt/ui/color-picker.ts +26 -5
- package/.nuxt/ui/command-palette.ts +37 -16
- package/.nuxt/ui/container.ts +24 -3
- package/.nuxt/ui/context-menu.ts +56 -35
- package/.nuxt/ui/drawer.ts +33 -12
- package/.nuxt/ui/dropdown-menu.ts +57 -36
- package/.nuxt/ui/form-field.ts +29 -8
- package/.nuxt/ui/form.ts +23 -2
- package/.nuxt/ui/index.ts +1 -0
- package/.nuxt/ui/input-menu.ts +65 -44
- package/.nuxt/ui/input-number.ts +43 -22
- package/.nuxt/ui/input.ts +46 -25
- package/.nuxt/ui/kbd.ts +27 -6
- package/.nuxt/ui/link.ts +26 -5
- package/.nuxt/ui/modal.ts +28 -7
- package/.nuxt/ui/navigation-menu.ts +103 -84
- package/.nuxt/ui/pagination.ts +23 -2
- package/.nuxt/ui/pin-input.ts +43 -22
- package/.nuxt/ui/popover.ts +25 -4
- package/.nuxt/ui/progress.ts +40 -19
- package/.nuxt/ui/radio-group.ts +273 -37
- package/.nuxt/ui/select-menu.ts +59 -35
- package/.nuxt/ui/select.ts +55 -34
- package/.nuxt/ui/separator.ts +31 -10
- package/.nuxt/ui/skeleton.ts +24 -3
- package/.nuxt/ui/slideover.ts +27 -6
- package/.nuxt/ui/slider.ts +39 -18
- package/.nuxt/ui/stepper.ts +41 -20
- package/.nuxt/ui/switch.ts +44 -23
- package/.nuxt/ui/table.ts +38 -17
- package/.nuxt/ui/tabs.ts +55 -34
- package/.nuxt/ui/textarea.ts +63 -37
- package/.nuxt/ui/toast.ts +47 -26
- package/.nuxt/ui/toaster.ts +23 -2
- package/.nuxt/ui/tooltip.ts +25 -4
- package/.nuxt/ui/tree.ts +41 -20
- package/.nuxt/ui.css +56 -12
- package/README.md +11 -0
- package/cli/templates.mjs +18 -17
- package/dist/module.d.mts +2 -1
- package/dist/module.json +5 -5
- package/dist/module.mjs +11 -7
- package/dist/runtime/components/Accordion.vue +36 -92
- package/dist/runtime/components/Accordion.vue.d.ts +91 -0
- package/dist/runtime/components/Alert.vue +37 -100
- package/dist/runtime/components/Alert.vue.d.ts +96 -0
- package/dist/runtime/components/App.vue +28 -34
- package/dist/runtime/components/App.vue.d.ts +24 -0
- package/dist/runtime/components/Avatar.vue +47 -78
- package/dist/runtime/components/Avatar.vue.d.ts +60 -0
- package/dist/runtime/components/AvatarGroup.vue +40 -77
- package/dist/runtime/components/AvatarGroup.vue.d.ts +40 -0
- package/dist/runtime/components/Badge.vue +33 -62
- package/dist/runtime/components/Badge.vue.d.ts +62 -0
- package/dist/runtime/components/Breadcrumb.vue +36 -88
- package/dist/runtime/components/Breadcrumb.vue.d.ts +82 -0
- package/dist/runtime/components/Button.vue +96 -105
- package/dist/runtime/components/Button.vue.d.ts +73 -0
- package/dist/runtime/components/ButtonGroup.vue +20 -46
- package/dist/runtime/components/ButtonGroup.vue.d.ts +55 -0
- package/dist/runtime/components/Calendar.vue +73 -127
- package/dist/runtime/components/Calendar.vue.d.ts +107 -0
- package/dist/runtime/components/Card.vue +18 -40
- package/dist/runtime/components/Card.vue.d.ts +38 -0
- package/dist/runtime/components/Carousel.vue +112 -230
- package/dist/runtime/components/Carousel.vue.d.ts +120 -0
- package/dist/runtime/components/Checkbox.vue +52 -93
- package/dist/runtime/components/Checkbox.vue.d.ts +76 -0
- package/dist/runtime/components/CheckboxGroup.vue +121 -0
- package/dist/runtime/components/CheckboxGroup.vue.d.ts +75 -0
- package/dist/runtime/components/Chip.vue +26 -69
- package/dist/runtime/components/Chip.vue.d.ts +71 -0
- package/dist/runtime/components/Collapsible.vue +22 -41
- package/dist/runtime/components/Collapsible.vue.d.ts +50 -0
- package/dist/runtime/components/ColorPicker.vue +111 -197
- package/dist/runtime/components/ColorPicker.vue.d.ts +63 -0
- package/dist/runtime/components/CommandPalette.vue +94 -234
- package/dist/runtime/components/CommandPalette.vue.d.ts +173 -0
- package/dist/runtime/components/Container.vue +15 -28
- package/dist/runtime/components/Container.vue.d.ts +27 -0
- package/dist/runtime/components/ContextMenu.vue +32 -119
- package/dist/runtime/components/ContextMenu.vue.d.ts +127 -0
- package/dist/runtime/components/ContextMenuContent.vue +71 -72
- package/dist/runtime/components/ContextMenuContent.vue.d.ts +105 -0
- package/dist/runtime/components/Drawer.vue +49 -87
- package/dist/runtime/components/Drawer.vue.d.ts +88 -0
- package/dist/runtime/components/DropdownMenu.vue +37 -129
- package/dist/runtime/components/DropdownMenu.vue.d.ts +141 -0
- package/dist/runtime/components/DropdownMenuContent.vue +76 -79
- package/dist/runtime/components/DropdownMenuContent.vue.d.ts +55 -0
- package/dist/runtime/components/Form.vue +135 -219
- package/dist/runtime/components/Form.vue.d.ts +66 -0
- package/dist/runtime/components/FormField.vue +36 -77
- package/dist/runtime/components/FormField.vue.d.ts +70 -0
- package/dist/runtime/components/Icon.vue +12 -19
- package/dist/runtime/components/Icon.vue.d.ts +17 -0
- package/dist/runtime/components/Input.vue +82 -140
- package/dist/runtime/components/Input.vue.d.ts +91 -0
- package/dist/runtime/components/InputMenu.vue +193 -302
- package/dist/runtime/components/InputMenu.vue.d.ts +312 -0
- package/dist/runtime/components/InputNumber.vue +71 -133
- package/dist/runtime/components/InputNumber.vue.d.ts +193 -0
- package/dist/runtime/components/Kbd.vue +20 -46
- package/dist/runtime/components/Kbd.vue.d.ts +55 -0
- package/dist/runtime/components/Link.vue +98 -173
- package/dist/runtime/components/Link.vue.d.ts +124 -0
- package/dist/runtime/components/LinkBase.vue +33 -41
- package/dist/runtime/components/LinkBase.vue.d.ts +48 -0
- package/dist/runtime/components/Modal.vue +53 -116
- package/dist/runtime/components/Modal.vue.d.ts +109 -0
- package/dist/runtime/components/NavigationMenu.vue +78 -186
- package/dist/runtime/components/NavigationMenu.vue.d.ts +159 -0
- package/dist/runtime/components/OverlayProvider.vue +14 -18
- package/dist/runtime/components/OverlayProvider.vue.d.ts +2 -0
- package/dist/runtime/components/Pagination.vue +46 -140
- package/dist/runtime/components/Pagination.vue.d.ts +143 -0
- package/dist/runtime/components/PinInput.vue +61 -78
- package/dist/runtime/components/PinInput.vue.d.ts +68 -0
- package/dist/runtime/components/Popover.vue +47 -84
- package/dist/runtime/components/Popover.vue.d.ts +80 -0
- package/dist/runtime/components/Progress.vue +70 -131
- package/dist/runtime/components/Progress.vue.d.ts +97 -0
- package/dist/runtime/components/RadioGroup.vue +75 -126
- package/dist/runtime/components/RadioGroup.vue.d.ts +88 -0
- package/dist/runtime/components/Select.vue +115 -202
- package/dist/runtime/components/Select.vue.d.ts +139 -0
- package/dist/runtime/components/SelectMenu.vue +167 -281
- package/dist/runtime/components/SelectMenu.vue.d.ts +184 -0
- package/dist/runtime/components/Separator.vue +29 -71
- package/dist/runtime/components/Separator.vue.d.ts +75 -0
- package/dist/runtime/components/Skeleton.vue +21 -23
- package/dist/runtime/components/Skeleton.vue.d.ts +26 -0
- package/dist/runtime/components/Slideover.vue +53 -120
- package/dist/runtime/components/Slideover.vue.d.ts +111 -0
- package/dist/runtime/components/Slider.vue +46 -84
- package/dist/runtime/components/Slider.vue.d.ts +71 -0
- package/dist/runtime/components/Stepper.vue +44 -113
- package/dist/runtime/components/Stepper.vue.d.ts +89 -0
- package/dist/runtime/components/Switch.vue +45 -93
- package/dist/runtime/components/Switch.vue.d.ts +73 -0
- package/dist/runtime/components/Table.vue +165 -264
- package/dist/runtime/components/Table.vue.d.ts +183 -0
- package/dist/runtime/components/Tabs.vue +40 -105
- package/dist/runtime/components/Tabs.vue.d.ts +104 -0
- package/dist/runtime/components/Textarea.vue +113 -158
- package/dist/runtime/components/Textarea.vue.d.ts +95 -0
- package/dist/runtime/components/Toast.vue +49 -110
- package/dist/runtime/components/Toast.vue.d.ts +95 -0
- package/dist/runtime/components/Toaster.vue +70 -107
- package/dist/runtime/components/Toaster.vue.d.ts +63 -0
- package/dist/runtime/components/Tooltip.vue +38 -65
- package/dist/runtime/components/Tooltip.vue.d.ts +65 -0
- package/dist/runtime/components/Tree.vue +57 -150
- package/dist/runtime/components/Tree.vue.d.ts +128 -0
- package/dist/runtime/composables/defineShortcuts.d.ts +1 -1
- package/dist/runtime/composables/defineShortcuts.js +0 -1
- package/dist/runtime/composables/useAvatarGroup.d.ts +1 -1
- package/dist/runtime/composables/useButtonGroup.d.ts +2 -2
- package/dist/runtime/composables/useFormField.d.ts +2 -2
- package/dist/runtime/composables/useFormField.js +1 -1
- package/dist/runtime/composables/useOverlay.d.ts +16 -8
- package/dist/runtime/composables/useOverlay.js +14 -6
- package/dist/runtime/composables/usePortal.d.ts +6 -0
- package/dist/runtime/composables/usePortal.js +17 -0
- package/dist/runtime/index.css +1 -1
- package/dist/runtime/inertia/components/Link.vue +146 -0
- package/dist/runtime/inertia/components/Link.vue.d.ts +92 -0
- package/dist/runtime/inertia/stubs.d.ts +43 -0
- package/dist/runtime/inertia/stubs.js +82 -0
- package/dist/runtime/locale/bg.d.ts +3 -0
- package/dist/runtime/locale/bg.js +54 -0
- package/dist/runtime/locale/hy.d.ts +3 -0
- package/dist/runtime/locale/hy.js +54 -0
- package/dist/runtime/locale/index.d.ts +6 -1
- package/dist/runtime/locale/index.js +6 -1
- package/dist/runtime/locale/kk.d.ts +3 -0
- package/dist/runtime/locale/kk.js +54 -0
- package/dist/runtime/locale/tj.d.ts +3 -0
- package/dist/runtime/locale/tj.js +54 -0
- package/dist/runtime/locale/ug_cn.d.ts +3 -0
- package/dist/runtime/locale/ug_cn.js +55 -0
- package/dist/runtime/types/form.d.ts +5 -1
- package/dist/runtime/types/index.d.ts +2 -0
- package/dist/runtime/types/index.js +2 -0
- package/dist/runtime/types/utils.d.ts +70 -10
- package/dist/runtime/utils/index.d.ts +1 -0
- package/dist/runtime/utils/index.js +3 -0
- package/dist/runtime/utils/link.d.ts +4 -27
- package/dist/runtime/utils/link.js +32 -1
- package/dist/runtime/utils/tv.js +2 -2
- package/dist/runtime/vue/components/Icon.vue +7 -8
- package/dist/runtime/vue/components/Icon.vue.d.ts +14 -0
- package/dist/runtime/vue/components/Link.vue +118 -199
- package/dist/runtime/vue/components/Link.vue.d.ts +124 -0
- package/dist/runtime/vue/stubs.d.ts +5 -0
- package/dist/runtime/vue/stubs.js +11 -2
- package/dist/shared/{ui.BCaWD5Ek.mjs → ui.D7lOOabO.mjs} +623 -364
- package/dist/types.d.mts +5 -1
- package/dist/unplugin.d.mts +6 -1
- package/dist/unplugin.mjs +25 -4
- package/dist/vite.mjs +1 -1
- package/package.json +122 -64
- package/dist/module.cjs +0 -62
- package/dist/module.d.cts +0 -44
- package/dist/module.d.ts +0 -44
- package/dist/shared/ui.C6uTSFTI.cjs +0 -3555
- package/dist/types.d.ts +0 -1
- package/dist/unplugin.cjs +0 -232
- package/dist/unplugin.d.cts +0 -61
- package/dist/unplugin.d.ts +0 -61
- package/dist/vite.cjs +0 -23
- package/dist/vite.d.cts +0 -15
- package/dist/vite.d.ts +0 -15
|
@@ -1,204 +1,85 @@
|
|
|
1
|
-
<script
|
|
2
|
-
import
|
|
3
|
-
import type { VariantProps } from 'tailwind-variants'
|
|
4
|
-
import type { ComboboxRootProps, ComboboxRootEmits, ComboboxContentProps, ComboboxContentEmits, ComboboxArrowProps, AcceptableValue } from 'reka-ui'
|
|
5
|
-
import type { AppConfig } from '@nuxt/schema'
|
|
6
|
-
import _appConfig from '#build/app.config'
|
|
7
|
-
import theme from '#build/ui/input-menu'
|
|
8
|
-
import type { UseComponentIconsProps } from '../composables/useComponentIcons'
|
|
9
|
-
import { tv } from '../utils/tv'
|
|
10
|
-
import type { AvatarProps, ChipProps, InputProps } from '../types'
|
|
11
|
-
import type { PartialString, MaybeArrayOfArray, MaybeArrayOfArrayItem, SelectModelValue, SelectModelValueEmits, SelectItemKey, EmitsToProps } from '../types/utils'
|
|
12
|
-
|
|
13
|
-
const appConfigInputMenu = _appConfig as AppConfig & { ui: { inputMenu: Partial<typeof theme> } }
|
|
14
|
-
|
|
15
|
-
const inputMenu = tv({ extend: tv(theme), ...(appConfigInputMenu.ui?.inputMenu || {}) })
|
|
16
|
-
|
|
17
|
-
export interface InputMenuItem {
|
|
18
|
-
label?: string
|
|
19
|
-
/**
|
|
20
|
-
* @IconifyIcon
|
|
21
|
-
*/
|
|
22
|
-
icon?: string
|
|
23
|
-
avatar?: AvatarProps
|
|
24
|
-
chip?: ChipProps
|
|
25
|
-
/**
|
|
26
|
-
* The item type.
|
|
27
|
-
* @defaultValue 'item'
|
|
28
|
-
*/
|
|
29
|
-
type?: 'label' | 'separator' | 'item'
|
|
30
|
-
disabled?: boolean
|
|
31
|
-
onSelect?(e?: Event): void
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
type InputMenuVariants = VariantProps<typeof inputMenu>
|
|
35
|
-
|
|
36
|
-
export interface InputMenuProps<T extends MaybeArrayOfArrayItem<I>, I extends MaybeArrayOfArray<InputMenuItem | AcceptableValue | boolean> = MaybeArrayOfArray<InputMenuItem | AcceptableValue | boolean>, V extends SelectItemKey<T> | undefined = undefined, M extends boolean = false> extends Pick<ComboboxRootProps<T>, 'open' | 'defaultOpen' | 'disabled' | 'name' | 'resetSearchTermOnBlur' | 'highlightOnHover'>, UseComponentIconsProps {
|
|
37
|
-
/**
|
|
38
|
-
* The element or component this component should render as.
|
|
39
|
-
* @defaultValue 'div'
|
|
40
|
-
*/
|
|
41
|
-
as?: any
|
|
42
|
-
id?: string
|
|
43
|
-
type?: InputHTMLAttributes['type']
|
|
44
|
-
/** The placeholder text when the input is empty. */
|
|
45
|
-
placeholder?: string
|
|
46
|
-
/**
|
|
47
|
-
* @defaultValue 'primary'
|
|
48
|
-
*/
|
|
49
|
-
color?: InputMenuVariants['color']
|
|
50
|
-
/**
|
|
51
|
-
* @defaultValue 'outline'
|
|
52
|
-
*/
|
|
53
|
-
variant?: InputMenuVariants['variant']
|
|
54
|
-
/**
|
|
55
|
-
* @defaultValue 'md'
|
|
56
|
-
*/
|
|
57
|
-
size?: InputMenuVariants['size']
|
|
58
|
-
required?: boolean
|
|
59
|
-
autofocus?: boolean
|
|
60
|
-
autofocusDelay?: number
|
|
61
|
-
/**
|
|
62
|
-
* The icon displayed to open the menu.
|
|
63
|
-
* @defaultValue appConfig.ui.icons.chevronDown
|
|
64
|
-
* @IconifyIcon
|
|
65
|
-
*/
|
|
66
|
-
trailingIcon?: string
|
|
67
|
-
/**
|
|
68
|
-
* The icon displayed when an item is selected.
|
|
69
|
-
* @defaultValue appConfig.ui.icons.check
|
|
70
|
-
* @IconifyIcon
|
|
71
|
-
*/
|
|
72
|
-
selectedIcon?: string
|
|
73
|
-
/**
|
|
74
|
-
* The icon displayed to delete a tag.
|
|
75
|
-
* Works only when `multiple` is `true`.
|
|
76
|
-
* @defaultValue appConfig.ui.icons.close
|
|
77
|
-
* @IconifyIcon
|
|
78
|
-
*/
|
|
79
|
-
deleteIcon?: string
|
|
80
|
-
/**
|
|
81
|
-
* The content of the menu.
|
|
82
|
-
* @defaultValue { side: 'bottom', sideOffset: 8, collisionPadding: 8, position: 'popper' }
|
|
83
|
-
*/
|
|
84
|
-
content?: Omit<ComboboxContentProps, 'as' | 'asChild' | 'forceMount'> & Partial<EmitsToProps<ComboboxContentEmits>>
|
|
85
|
-
/**
|
|
86
|
-
* Display an arrow alongside the menu.
|
|
87
|
-
* @defaultValue false
|
|
88
|
-
*/
|
|
89
|
-
arrow?: boolean | Omit<ComboboxArrowProps, 'as' | 'asChild'>
|
|
90
|
-
/**
|
|
91
|
-
* Render the menu in a portal.
|
|
92
|
-
* @defaultValue true
|
|
93
|
-
*/
|
|
94
|
-
portal?: boolean
|
|
95
|
-
/**
|
|
96
|
-
* When `items` is an array of objects, select the field to use as the value instead of the object itself.
|
|
97
|
-
* @defaultValue undefined
|
|
98
|
-
*/
|
|
99
|
-
valueKey?: V
|
|
100
|
-
/**
|
|
101
|
-
* When `items` is an array of objects, select the field to use as the label.
|
|
102
|
-
* @defaultValue 'label'
|
|
103
|
-
*/
|
|
104
|
-
labelKey?: V
|
|
105
|
-
items?: I
|
|
106
|
-
/** The value of the InputMenu when initially rendered. Use when you do not need to control the state of the InputMenu. */
|
|
107
|
-
defaultValue?: SelectModelValue<T, V, M>
|
|
108
|
-
/** The controlled value of the InputMenu. Can be binded-with with `v-model`. */
|
|
109
|
-
modelValue?: SelectModelValue<T, V, M>
|
|
110
|
-
/** Whether multiple options can be selected or not. */
|
|
111
|
-
multiple?: M & boolean
|
|
112
|
-
/** Highlight the ring color like a focus state. */
|
|
113
|
-
highlight?: boolean
|
|
114
|
-
/**
|
|
115
|
-
* Determines if custom user input that does not exist in options can be added.
|
|
116
|
-
* @defaultValue false
|
|
117
|
-
*/
|
|
118
|
-
createItem?: boolean | 'always' | { position?: 'top' | 'bottom', when?: 'empty' | 'always' }
|
|
119
|
-
/**
|
|
120
|
-
* Fields to filter items by.
|
|
121
|
-
* @defaultValue [labelKey]
|
|
122
|
-
*/
|
|
123
|
-
filterFields?: string[]
|
|
124
|
-
/**
|
|
125
|
-
* When `true`, disable the default filters, useful for custom filtering (useAsyncData, useFetch, etc.).
|
|
126
|
-
* @defaultValue false
|
|
127
|
-
*/
|
|
128
|
-
ignoreFilter?: boolean
|
|
129
|
-
class?: any
|
|
130
|
-
ui?: PartialString<typeof inputMenu.slots>
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export type InputMenuEmits<T, V, M extends boolean> = Omit<ComboboxRootEmits<T>, 'update:modelValue'> & {
|
|
134
|
-
change: [payload: Event]
|
|
135
|
-
blur: [payload: FocusEvent]
|
|
136
|
-
focus: [payload: FocusEvent]
|
|
137
|
-
create: [item: string]
|
|
138
|
-
} & SelectModelValueEmits<T, V, M>
|
|
139
|
-
|
|
140
|
-
type SlotProps<T> = (props: { item: T, index: number }) => any
|
|
141
|
-
|
|
142
|
-
export interface InputMenuSlots<T, M extends boolean> {
|
|
143
|
-
'leading'(props: { modelValue?: M extends true ? T[] : T, open: boolean, ui: any }): any
|
|
144
|
-
'trailing'(props: { modelValue?: M extends true ? T[] : T, open: boolean, ui: any }): any
|
|
145
|
-
'empty'(props: { searchTerm?: string }): any
|
|
146
|
-
'item': SlotProps<T>
|
|
147
|
-
'item-leading': SlotProps<T>
|
|
148
|
-
'item-label': SlotProps<T>
|
|
149
|
-
'item-trailing': SlotProps<T>
|
|
150
|
-
'tags-item-text': SlotProps<T>
|
|
151
|
-
'tags-item-delete': SlotProps<T>
|
|
152
|
-
'create-item-label'(props: { item: string }): any
|
|
153
|
-
}
|
|
1
|
+
<script>
|
|
2
|
+
import theme from "#build/ui/input-menu";
|
|
154
3
|
</script>
|
|
155
4
|
|
|
156
|
-
<script setup
|
|
157
|
-
import { computed, ref, toRef, onMounted, toRaw } from
|
|
158
|
-
import { ComboboxRoot, ComboboxArrow, ComboboxAnchor, ComboboxInput, ComboboxTrigger, ComboboxPortal, ComboboxContent, ComboboxViewport, ComboboxEmpty, ComboboxGroup, ComboboxLabel, ComboboxSeparator, ComboboxItem, ComboboxItemIndicator, TagsInputRoot, TagsInputItem, TagsInputItemText, TagsInputItemDelete, TagsInputInput, useForwardPropsEmits, useFilter } from
|
|
159
|
-
import { defu } from
|
|
160
|
-
import { isEqual } from
|
|
161
|
-
import { reactivePick, createReusableTemplate } from
|
|
162
|
-
import { useAppConfig } from
|
|
163
|
-
import { useButtonGroup } from
|
|
164
|
-
import { useComponentIcons } from
|
|
165
|
-
import { useFormField } from
|
|
166
|
-
import { useLocale } from
|
|
167
|
-
import {
|
|
168
|
-
import
|
|
169
|
-
import
|
|
170
|
-
import
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
const props =
|
|
175
|
-
type:
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
5
|
+
<script setup>
|
|
6
|
+
import { computed, ref, toRef, onMounted, toRaw } from "vue";
|
|
7
|
+
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";
|
|
8
|
+
import { defu } from "defu";
|
|
9
|
+
import { isEqual } from "ohash/utils";
|
|
10
|
+
import { reactivePick, createReusableTemplate } from "@vueuse/core";
|
|
11
|
+
import { useAppConfig } from "#imports";
|
|
12
|
+
import { useButtonGroup } from "../composables/useButtonGroup";
|
|
13
|
+
import { useComponentIcons } from "../composables/useComponentIcons";
|
|
14
|
+
import { useFormField } from "../composables/useFormField";
|
|
15
|
+
import { useLocale } from "../composables/useLocale";
|
|
16
|
+
import { usePortal } from "../composables/usePortal";
|
|
17
|
+
import { compare, get, isArrayOfArray } from "../utils";
|
|
18
|
+
import { tv } from "../utils/tv";
|
|
19
|
+
import UIcon from "./Icon.vue";
|
|
20
|
+
import UAvatar from "./Avatar.vue";
|
|
21
|
+
import UChip from "./Chip.vue";
|
|
22
|
+
defineOptions({ inheritAttrs: false });
|
|
23
|
+
const props = defineProps({
|
|
24
|
+
as: { type: null, required: false },
|
|
25
|
+
id: { type: String, required: false },
|
|
26
|
+
type: { type: null, required: false, default: "text" },
|
|
27
|
+
placeholder: { type: String, required: false },
|
|
28
|
+
color: { type: null, required: false },
|
|
29
|
+
variant: { type: null, required: false },
|
|
30
|
+
size: { type: null, required: false },
|
|
31
|
+
required: { type: Boolean, required: false },
|
|
32
|
+
autofocus: { type: Boolean, required: false },
|
|
33
|
+
autofocusDelay: { type: Number, required: false, default: 0 },
|
|
34
|
+
trailingIcon: { type: String, required: false },
|
|
35
|
+
selectedIcon: { type: String, required: false },
|
|
36
|
+
deleteIcon: { type: String, required: false },
|
|
37
|
+
content: { type: Object, required: false },
|
|
38
|
+
arrow: { type: [Boolean, Object], required: false },
|
|
39
|
+
portal: { type: [Boolean, String], required: false, skipCheck: true, default: true },
|
|
40
|
+
valueKey: { type: null, required: false },
|
|
41
|
+
labelKey: { type: null, required: false, default: "label" },
|
|
42
|
+
items: { type: null, required: false },
|
|
43
|
+
defaultValue: { type: null, required: false },
|
|
44
|
+
modelValue: { type: null, required: false },
|
|
45
|
+
multiple: { type: Boolean, required: false },
|
|
46
|
+
highlight: { type: Boolean, required: false },
|
|
47
|
+
createItem: { type: [Boolean, String, Object], required: false },
|
|
48
|
+
filterFields: { type: Array, required: false },
|
|
49
|
+
ignoreFilter: { type: Boolean, required: false },
|
|
50
|
+
class: { type: null, required: false },
|
|
51
|
+
ui: { type: null, required: false },
|
|
52
|
+
open: { type: Boolean, required: false },
|
|
53
|
+
defaultOpen: { type: Boolean, required: false },
|
|
54
|
+
disabled: { type: Boolean, required: false },
|
|
55
|
+
name: { type: String, required: false },
|
|
56
|
+
resetSearchTermOnBlur: { type: Boolean, required: false, default: true },
|
|
57
|
+
resetSearchTermOnSelect: { type: Boolean, required: false, default: true },
|
|
58
|
+
highlightOnHover: { type: Boolean, required: false },
|
|
59
|
+
icon: { type: String, required: false },
|
|
60
|
+
avatar: { type: Object, required: false },
|
|
61
|
+
leading: { type: Boolean, required: false },
|
|
62
|
+
leadingIcon: { type: String, required: false },
|
|
63
|
+
trailing: { type: Boolean, required: false },
|
|
64
|
+
loading: { type: Boolean, required: false },
|
|
65
|
+
loadingIcon: { type: String, required: false }
|
|
66
|
+
});
|
|
67
|
+
const emits = defineEmits(["update:open", "change", "blur", "focus", "create", "highlight", "update:modelValue"]);
|
|
68
|
+
const slots = defineSlots();
|
|
69
|
+
const searchTerm = defineModel("searchTerm", { type: String, ...{ default: "" } });
|
|
70
|
+
const { t } = useLocale();
|
|
71
|
+
const appConfig = useAppConfig();
|
|
72
|
+
const { contains } = useFilter({ sensitivity: "base" });
|
|
73
|
+
const rootProps = useForwardPropsEmits(reactivePick(props, "as", "modelValue", "defaultValue", "open", "defaultOpen", "required", "multiple", "resetSearchTermOnBlur", "resetSearchTermOnSelect", "highlightOnHover", "ignoreFilter"), emits);
|
|
74
|
+
const portalProps = usePortal(toRef(() => props.portal));
|
|
75
|
+
const contentProps = toRef(() => defu(props.content, { side: "bottom", sideOffset: 8, collisionPadding: 8, position: "popper" }));
|
|
76
|
+
const arrowProps = toRef(() => props.arrow);
|
|
77
|
+
const { emitFormBlur, emitFormFocus, emitFormChange, emitFormInput, size: formGroupSize, color, id, name, highlight, disabled, ariaAttrs } = useFormField(props);
|
|
78
|
+
const { orientation, size: buttonGroupSize } = useButtonGroup(props);
|
|
79
|
+
const { isLeading, isTrailing, leadingIconName, trailingIconName } = useComponentIcons(toRef(() => defu(props, { trailingIcon: appConfig.ui.icons.chevronDown })));
|
|
80
|
+
const inputSize = computed(() => buttonGroupSize.value || formGroupSize.value);
|
|
81
|
+
const [DefineCreateItemTemplate, ReuseCreateItemTemplate] = createReusableTemplate();
|
|
82
|
+
const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.inputMenu || {} })({
|
|
202
83
|
color: color.value,
|
|
203
84
|
variant: props.variant,
|
|
204
85
|
size: inputSize?.value,
|
|
@@ -208,117 +89,123 @@ const ui = computed(() => inputMenu({
|
|
|
208
89
|
trailing: isTrailing.value || !!slots.trailing,
|
|
209
90
|
multiple: props.multiple,
|
|
210
91
|
buttonGroup: orientation.value
|
|
211
|
-
}))
|
|
212
|
-
|
|
213
|
-
function displayValue(value: T): string {
|
|
92
|
+
}));
|
|
93
|
+
function displayValue(value) {
|
|
214
94
|
if (!props.valueKey) {
|
|
215
|
-
return value && (typeof value ===
|
|
95
|
+
return value && (typeof value === "object" ? get(value, props.labelKey) : value);
|
|
216
96
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
return item && (typeof item === 'object' ? get(item, props.labelKey as string) : item)
|
|
97
|
+
const item = items.value.find((item2) => compare(typeof item2 === "object" ? get(item2, props.valueKey) : item2, value));
|
|
98
|
+
return item && (typeof item === "object" ? get(item, props.labelKey) : item);
|
|
220
99
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
const items = computed(() => groups.value.flatMap(group => group)
|
|
225
|
-
|
|
100
|
+
const groups = computed(
|
|
101
|
+
() => props.items?.length ? isArrayOfArray(props.items) ? props.items : [props.items] : []
|
|
102
|
+
);
|
|
103
|
+
const items = computed(() => groups.value.flatMap((group) => group));
|
|
226
104
|
const filteredGroups = computed(() => {
|
|
227
105
|
if (props.ignoreFilter || !searchTerm.value) {
|
|
228
|
-
return groups.value
|
|
106
|
+
return groups.value;
|
|
229
107
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
if (typeof item !== 'object') {
|
|
235
|
-
return contains(item, searchTerm.value)
|
|
108
|
+
const fields = Array.isArray(props.filterFields) ? props.filterFields : [props.labelKey];
|
|
109
|
+
return groups.value.map((group) => group.filter((item) => {
|
|
110
|
+
if (typeof item !== "object" || item === null) {
|
|
111
|
+
return contains(String(item), searchTerm.value);
|
|
236
112
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
return true
|
|
113
|
+
if (item.type && ["label", "separator"].includes(item.type)) {
|
|
114
|
+
return true;
|
|
240
115
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
116
|
+
return fields.some((field) => contains(get(item, field), searchTerm.value));
|
|
117
|
+
})).filter((group) => group.filter(
|
|
118
|
+
(item) => !isInputItem(item) || (!item.type || !["label", "separator"].includes(item.type))
|
|
119
|
+
).length > 0);
|
|
120
|
+
});
|
|
121
|
+
const filteredItems = computed(() => filteredGroups.value.flatMap((group) => group));
|
|
247
122
|
const createItem = computed(() => {
|
|
248
123
|
if (!props.createItem || !searchTerm.value) {
|
|
249
|
-
return false
|
|
124
|
+
return false;
|
|
250
125
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
if ((typeof props.createItem === 'object' && props.createItem.when === 'always') || props.createItem === 'always') {
|
|
255
|
-
return !filteredItems.value.find(item => compare(item, newItem, props.valueKey))
|
|
126
|
+
const newItem = props.valueKey ? { [props.valueKey]: searchTerm.value } : searchTerm.value;
|
|
127
|
+
if (typeof props.createItem === "object" && props.createItem.when === "always" || props.createItem === "always") {
|
|
128
|
+
return !filteredItems.value.find((item) => compare(item, newItem, props.valueKey));
|
|
256
129
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
const inputRef = ref<InstanceType<typeof ComboboxInput> | null>(null)
|
|
263
|
-
|
|
130
|
+
return !filteredItems.value.length;
|
|
131
|
+
});
|
|
132
|
+
const createItemPosition = computed(() => typeof props.createItem === "object" ? props.createItem.position : "bottom");
|
|
133
|
+
const inputRef = ref(null);
|
|
264
134
|
function autoFocus() {
|
|
265
135
|
if (props.autofocus) {
|
|
266
|
-
inputRef.value?.$el?.focus()
|
|
136
|
+
inputRef.value?.$el?.focus();
|
|
267
137
|
}
|
|
268
138
|
}
|
|
269
|
-
|
|
270
139
|
onMounted(() => {
|
|
271
140
|
setTimeout(() => {
|
|
272
|
-
autoFocus()
|
|
273
|
-
}, props.autofocusDelay)
|
|
274
|
-
})
|
|
275
|
-
|
|
276
|
-
function onUpdate(value: any) {
|
|
141
|
+
autoFocus();
|
|
142
|
+
}, props.autofocusDelay);
|
|
143
|
+
});
|
|
144
|
+
function onUpdate(value) {
|
|
277
145
|
if (toRaw(props.modelValue) === value) {
|
|
278
|
-
return
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
const event = new Event("change", { target: { value } });
|
|
149
|
+
emits("change", event);
|
|
150
|
+
emitFormChange();
|
|
151
|
+
emitFormInput();
|
|
152
|
+
if (props.resetSearchTermOnSelect) {
|
|
153
|
+
searchTerm.value = "";
|
|
279
154
|
}
|
|
280
|
-
// @ts-expect-error - 'target' does not exist in type 'EventInit'
|
|
281
|
-
const event = new Event('change', { target: { value } })
|
|
282
|
-
emits('change', event)
|
|
283
|
-
emitFormChange()
|
|
284
|
-
emitFormInput()
|
|
285
155
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
emitFormBlur()
|
|
156
|
+
function onBlur(event) {
|
|
157
|
+
emits("blur", event);
|
|
158
|
+
emitFormBlur();
|
|
290
159
|
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
emitFormFocus()
|
|
160
|
+
function onFocus(event) {
|
|
161
|
+
emits("focus", event);
|
|
162
|
+
emitFormFocus();
|
|
295
163
|
}
|
|
296
|
-
|
|
297
|
-
|
|
164
|
+
function onUpdateOpen(value) {
|
|
165
|
+
let timeoutId;
|
|
298
166
|
if (!value) {
|
|
299
|
-
const event = new FocusEvent(
|
|
300
|
-
emits(
|
|
301
|
-
emitFormBlur()
|
|
167
|
+
const event = new FocusEvent("blur");
|
|
168
|
+
emits("blur", event);
|
|
169
|
+
emitFormBlur();
|
|
170
|
+
if (props.resetSearchTermOnBlur) {
|
|
171
|
+
const STATE_ANIMATION_DELAY_MS = 100;
|
|
172
|
+
timeoutId = setTimeout(() => {
|
|
173
|
+
searchTerm.value = "";
|
|
174
|
+
}, STATE_ANIMATION_DELAY_MS);
|
|
175
|
+
}
|
|
302
176
|
} else {
|
|
303
|
-
const event = new FocusEvent(
|
|
304
|
-
emits(
|
|
177
|
+
const event = new FocusEvent("focus");
|
|
178
|
+
emits("focus", event);
|
|
179
|
+
emitFormFocus();
|
|
180
|
+
clearTimeout(timeoutId);
|
|
305
181
|
}
|
|
306
182
|
}
|
|
307
|
-
|
|
308
|
-
function onRemoveTag(event: any) {
|
|
183
|
+
function onRemoveTag(event) {
|
|
309
184
|
if (props.multiple) {
|
|
310
|
-
const modelValue = props.modelValue
|
|
311
|
-
const filteredValue = modelValue.filter(value => !isEqual(value, event))
|
|
312
|
-
emits(
|
|
185
|
+
const modelValue = props.modelValue;
|
|
186
|
+
const filteredValue = modelValue.filter((value) => !isEqual(value, event));
|
|
187
|
+
emits("update:modelValue", filteredValue);
|
|
188
|
+
onUpdate(filteredValue);
|
|
313
189
|
}
|
|
314
190
|
}
|
|
315
|
-
|
|
191
|
+
function onSelect(e, item) {
|
|
192
|
+
if (!isInputItem(item)) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (item.disabled) {
|
|
196
|
+
e.preventDefault();
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
item.onSelect?.(e);
|
|
200
|
+
}
|
|
201
|
+
function isInputItem(item) {
|
|
202
|
+
return typeof item === "object" && item !== null;
|
|
203
|
+
}
|
|
316
204
|
defineExpose({
|
|
317
205
|
inputRef
|
|
318
|
-
})
|
|
206
|
+
});
|
|
319
207
|
</script>
|
|
320
208
|
|
|
321
|
-
<!-- eslint-disable vue/no-template-shadow -->
|
|
322
209
|
<template>
|
|
323
210
|
<DefineCreateItemTemplate>
|
|
324
211
|
<ComboboxGroup :class="ui.group({ class: props.ui?.group })">
|
|
@@ -353,7 +240,7 @@ defineExpose({
|
|
|
353
240
|
<TagsInputRoot
|
|
354
241
|
v-if="multiple"
|
|
355
242
|
v-slot="{ modelValue: tags }"
|
|
356
|
-
:model-value="
|
|
243
|
+
:model-value="modelValue"
|
|
357
244
|
:disabled="disabled"
|
|
358
245
|
:required="required"
|
|
359
246
|
delimiter=""
|
|
@@ -362,21 +249,21 @@ defineExpose({
|
|
|
362
249
|
@focus="onFocus"
|
|
363
250
|
@remove-tag="onRemoveTag"
|
|
364
251
|
>
|
|
365
|
-
<TagsInputItem v-for="(item, index) in tags" :key="index" :value="
|
|
252
|
+
<TagsInputItem v-for="(item, index) in tags" :key="index" :value="item" :class="ui.tagsItem({ class: props.ui?.tagsItem })">
|
|
366
253
|
<TagsInputItemText :class="ui.tagsItemText({ class: props.ui?.tagsItemText })">
|
|
367
|
-
<slot name="tags-item-text" :item="
|
|
368
|
-
{{ displayValue(item
|
|
254
|
+
<slot name="tags-item-text" :item="item" :index="index">
|
|
255
|
+
{{ displayValue(item) }}
|
|
369
256
|
</slot>
|
|
370
257
|
</TagsInputItemText>
|
|
371
258
|
|
|
372
259
|
<TagsInputItemDelete :class="ui.tagsItemDelete({ class: props.ui?.tagsItemDelete })" :disabled="disabled">
|
|
373
|
-
<slot name="tags-item-delete" :item="
|
|
260
|
+
<slot name="tags-item-delete" :item="item" :index="index">
|
|
374
261
|
<UIcon :name="deleteIcon || appConfig.ui.icons.close" :class="ui.tagsItemDeleteIcon({ class: props.ui?.tagsItemDeleteIcon })" />
|
|
375
262
|
</slot>
|
|
376
263
|
</TagsInputItemDelete>
|
|
377
264
|
</TagsInputItem>
|
|
378
265
|
|
|
379
|
-
<ComboboxInput v-model="searchTerm"
|
|
266
|
+
<ComboboxInput v-model="searchTerm" as-child>
|
|
380
267
|
<TagsInputInput
|
|
381
268
|
ref="inputRef"
|
|
382
269
|
v-bind="{ ...$attrs, ...ariaAttrs }"
|
|
@@ -390,7 +277,6 @@ defineExpose({
|
|
|
390
277
|
<ComboboxInput
|
|
391
278
|
v-else
|
|
392
279
|
ref="inputRef"
|
|
393
|
-
v-model="searchTerm"
|
|
394
280
|
:display-value="displayValue"
|
|
395
281
|
v-bind="{ ...$attrs, ...ariaAttrs }"
|
|
396
282
|
:type="type"
|
|
@@ -398,24 +284,27 @@ defineExpose({
|
|
|
398
284
|
:required="required"
|
|
399
285
|
@blur="onBlur"
|
|
400
286
|
@focus="onFocus"
|
|
287
|
+
@update:model-value="searchTerm = $event"
|
|
401
288
|
/>
|
|
402
289
|
|
|
403
290
|
<span v-if="isLeading || !!avatar || !!slots.leading" :class="ui.leading({ class: props.ui?.leading })">
|
|
404
|
-
<slot name="leading" :model-value="
|
|
291
|
+
<slot name="leading" :model-value="modelValue" :open="open" :ui="ui">
|
|
405
292
|
<UIcon v-if="isLeading && leadingIconName" :name="leadingIconName" :class="ui.leadingIcon({ class: props.ui?.leadingIcon })" />
|
|
406
|
-
<UAvatar v-else-if="!!avatar" :size="
|
|
293
|
+
<UAvatar v-else-if="!!avatar" :size="props.ui?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()" v-bind="avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar })" />
|
|
407
294
|
</slot>
|
|
408
295
|
</span>
|
|
409
296
|
|
|
410
297
|
<ComboboxTrigger v-if="isTrailing || !!slots.trailing" :class="ui.trailing({ class: props.ui?.trailing })">
|
|
411
|
-
<slot name="trailing" :model-value="
|
|
298
|
+
<slot name="trailing" :model-value="modelValue" :open="open" :ui="ui">
|
|
412
299
|
<UIcon v-if="trailingIconName" :name="trailingIconName" :class="ui.trailingIcon({ class: props.ui?.trailingIcon })" />
|
|
413
300
|
</slot>
|
|
414
301
|
</ComboboxTrigger>
|
|
415
302
|
</ComboboxAnchor>
|
|
416
303
|
|
|
417
|
-
<ComboboxPortal
|
|
304
|
+
<ComboboxPortal v-bind="portalProps">
|
|
418
305
|
<ComboboxContent :class="ui.content({ class: props.ui?.content })" v-bind="contentProps">
|
|
306
|
+
<slot name="content-top" />
|
|
307
|
+
|
|
419
308
|
<ComboboxEmpty :class="ui.empty({ class: props.ui?.empty })">
|
|
420
309
|
<slot name="empty" :search-term="searchTerm">
|
|
421
310
|
{{ searchTerm ? t('inputMenu.noMatch', { searchTerm }) : t('inputMenu.noData') }}
|
|
@@ -427,26 +316,26 @@ defineExpose({
|
|
|
427
316
|
|
|
428
317
|
<ComboboxGroup v-for="(group, groupIndex) in filteredGroups" :key="`group-${groupIndex}`" :class="ui.group({ class: props.ui?.group })">
|
|
429
318
|
<template v-for="(item, index) in group" :key="`group-${groupIndex}-${index}`">
|
|
430
|
-
<ComboboxLabel v-if="item
|
|
431
|
-
{{ get(item, props.labelKey
|
|
319
|
+
<ComboboxLabel v-if="isInputItem(item) && item.type === 'label'" :class="ui.label({ class: props.ui?.label })">
|
|
320
|
+
{{ get(item, props.labelKey) }}
|
|
432
321
|
</ComboboxLabel>
|
|
433
322
|
|
|
434
|
-
<ComboboxSeparator v-else-if="item
|
|
323
|
+
<ComboboxSeparator v-else-if="isInputItem(item) && item.type === 'separator'" :class="ui.separator({ class: props.ui?.separator })" />
|
|
435
324
|
|
|
436
325
|
<ComboboxItem
|
|
437
326
|
v-else
|
|
438
327
|
:class="ui.item({ class: props.ui?.item })"
|
|
439
|
-
:disabled="item.disabled"
|
|
440
|
-
:value="valueKey &&
|
|
441
|
-
@select="item
|
|
328
|
+
:disabled="isInputItem(item) && item.disabled"
|
|
329
|
+
:value="props.valueKey && isInputItem(item) ? get(item, props.valueKey) : item"
|
|
330
|
+
@select="onSelect($event, item)"
|
|
442
331
|
>
|
|
443
|
-
<slot name="item" :item="
|
|
444
|
-
<slot name="item-leading" :item="
|
|
445
|
-
<UIcon v-if="item.icon" :name="item.icon" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon })" />
|
|
446
|
-
<UAvatar v-else-if="item.avatar" :size="
|
|
332
|
+
<slot name="item" :item="item" :index="index">
|
|
333
|
+
<slot name="item-leading" :item="item" :index="index">
|
|
334
|
+
<UIcon v-if="isInputItem(item) && item.icon" :name="item.icon" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon })" />
|
|
335
|
+
<UAvatar v-else-if="isInputItem(item) && item.avatar" :size="props.ui?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()" v-bind="item.avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar })" />
|
|
447
336
|
<UChip
|
|
448
|
-
v-else-if="item.chip"
|
|
449
|
-
:size="
|
|
337
|
+
v-else-if="isInputItem(item) && item.chip"
|
|
338
|
+
:size="props.ui?.itemLeadingChipSize || ui.itemLeadingChipSize()"
|
|
450
339
|
inset
|
|
451
340
|
standalone
|
|
452
341
|
v-bind="item.chip"
|
|
@@ -455,13 +344,13 @@ defineExpose({
|
|
|
455
344
|
</slot>
|
|
456
345
|
|
|
457
346
|
<span :class="ui.itemLabel({ class: props.ui?.itemLabel })">
|
|
458
|
-
<slot name="item-label" :item="
|
|
459
|
-
{{
|
|
347
|
+
<slot name="item-label" :item="item" :index="index">
|
|
348
|
+
{{ isInputItem(item) ? get(item, props.labelKey) : item }}
|
|
460
349
|
</slot>
|
|
461
350
|
</span>
|
|
462
351
|
|
|
463
352
|
<span :class="ui.itemTrailing({ class: props.ui?.itemTrailing })">
|
|
464
|
-
<slot name="item-trailing" :item="
|
|
353
|
+
<slot name="item-trailing" :item="item" :index="index" />
|
|
465
354
|
|
|
466
355
|
<ComboboxItemIndicator as-child>
|
|
467
356
|
<UIcon :name="selectedIcon || appConfig.ui.icons.check" :class="ui.itemTrailingIcon({ class: props.ui?.itemTrailingIcon })" />
|
|
@@ -475,6 +364,8 @@ defineExpose({
|
|
|
475
364
|
<ReuseCreateItemTemplate v-if="createItem && createItemPosition === 'bottom'" />
|
|
476
365
|
</ComboboxViewport>
|
|
477
366
|
|
|
367
|
+
<slot name="content-bottom" />
|
|
368
|
+
|
|
478
369
|
<ComboboxArrow v-if="!!arrow" v-bind="arrowProps" :class="ui.arrow({ class: props.ui?.arrow })" />
|
|
479
370
|
</ComboboxContent>
|
|
480
371
|
</ComboboxPortal>
|