@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,158 +1,69 @@
|
|
|
1
|
-
<script
|
|
2
|
-
import
|
|
3
|
-
import type { SelectRootProps, SelectRootEmits, SelectContentProps, SelectContentEmits, SelectArrowProps, AcceptableValue } from 'reka-ui'
|
|
4
|
-
import type { AppConfig } from '@nuxt/schema'
|
|
5
|
-
import _appConfig from '#build/app.config'
|
|
6
|
-
import theme from '#build/ui/select'
|
|
7
|
-
import type { UseComponentIconsProps } from '../composables/useComponentIcons'
|
|
8
|
-
import { tv } from '../utils/tv'
|
|
9
|
-
import type { AvatarProps, ChipProps, InputProps } from '../types'
|
|
10
|
-
import type { PartialString, MaybeArrayOfArray, MaybeArrayOfArrayItem, SelectModelValue, SelectModelValueEmits, SelectItemKey, EmitsToProps } from '../types/utils'
|
|
11
|
-
|
|
12
|
-
const appConfigSelect = _appConfig as AppConfig & { ui: { select: Partial<typeof theme> } }
|
|
13
|
-
|
|
14
|
-
const select = tv({ extend: tv(theme), ...(appConfigSelect.ui?.select || {}) })
|
|
15
|
-
|
|
16
|
-
export interface SelectItem {
|
|
17
|
-
label?: string
|
|
18
|
-
/**
|
|
19
|
-
* @IconifyIcon
|
|
20
|
-
*/
|
|
21
|
-
icon?: string
|
|
22
|
-
avatar?: AvatarProps
|
|
23
|
-
chip?: ChipProps
|
|
24
|
-
/**
|
|
25
|
-
* The item type.
|
|
26
|
-
* @defaultValue 'item'
|
|
27
|
-
*/
|
|
28
|
-
type?: 'label' | 'separator' | 'item'
|
|
29
|
-
value?: string
|
|
30
|
-
disabled?: boolean
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
type SelectVariants = VariantProps<typeof select>
|
|
34
|
-
|
|
35
|
-
export interface SelectProps<T extends MaybeArrayOfArrayItem<I>, I extends MaybeArrayOfArray<SelectItem | AcceptableValue | boolean> = MaybeArrayOfArray<SelectItem | AcceptableValue | boolean>, V extends SelectItemKey<T> | undefined = undefined, M extends boolean = false> extends Omit<SelectRootProps<T>, 'dir' | 'multiple' | 'modelValue' | 'defaultValue' | 'by'>, UseComponentIconsProps {
|
|
36
|
-
id?: string
|
|
37
|
-
/** The placeholder text when the select is empty. */
|
|
38
|
-
placeholder?: string
|
|
39
|
-
/**
|
|
40
|
-
* @defaultValue 'primary'
|
|
41
|
-
*/
|
|
42
|
-
color?: SelectVariants['color']
|
|
43
|
-
/**
|
|
44
|
-
* @defaultValue 'outline'
|
|
45
|
-
*/
|
|
46
|
-
variant?: SelectVariants['variant']
|
|
47
|
-
/**
|
|
48
|
-
* @defaultValue 'md'
|
|
49
|
-
*/
|
|
50
|
-
size?: SelectVariants['size']
|
|
51
|
-
/**
|
|
52
|
-
* The icon displayed to open the menu.
|
|
53
|
-
* @defaultValue appConfig.ui.icons.chevronDown
|
|
54
|
-
* @IconifyIcon
|
|
55
|
-
*/
|
|
56
|
-
trailingIcon?: string
|
|
57
|
-
/**
|
|
58
|
-
* The icon displayed when an item is selected.
|
|
59
|
-
* @defaultValue appConfig.ui.icons.check
|
|
60
|
-
* @IconifyIcon
|
|
61
|
-
*/
|
|
62
|
-
selectedIcon?: string
|
|
63
|
-
/**
|
|
64
|
-
* The content of the menu.
|
|
65
|
-
* @defaultValue { side: 'bottom', sideOffset: 8, collisionPadding: 8, position: 'popper' }
|
|
66
|
-
*/
|
|
67
|
-
content?: Omit<SelectContentProps, 'as' | 'asChild' | 'forceMount'> & Partial<EmitsToProps<SelectContentEmits>>
|
|
68
|
-
/**
|
|
69
|
-
* Display an arrow alongside the menu.
|
|
70
|
-
* @defaultValue false
|
|
71
|
-
*/
|
|
72
|
-
arrow?: boolean | Omit<SelectArrowProps, 'as' | 'asChild'>
|
|
73
|
-
/**
|
|
74
|
-
* Render the menu in a portal.
|
|
75
|
-
* @defaultValue true
|
|
76
|
-
*/
|
|
77
|
-
portal?: boolean
|
|
78
|
-
/**
|
|
79
|
-
* When `items` is an array of objects, select the field to use as the value.
|
|
80
|
-
* @defaultValue 'value'
|
|
81
|
-
*/
|
|
82
|
-
valueKey?: V
|
|
83
|
-
/**
|
|
84
|
-
* When `items` is an array of objects, select the field to use as the label.
|
|
85
|
-
* @defaultValue 'label'
|
|
86
|
-
*/
|
|
87
|
-
labelKey?: V
|
|
88
|
-
items?: I
|
|
89
|
-
/** The value of the Select when initially rendered. Use when you do not need to control the state of the Select. */
|
|
90
|
-
defaultValue?: SelectModelValue<T, V, M, T extends { value: infer U } ? U : never>
|
|
91
|
-
/** The controlled value of the Select. Can be bind as `v-model`. */
|
|
92
|
-
modelValue?: SelectModelValue<T, V, M, T extends { value: infer U } ? U : never>
|
|
93
|
-
/** Whether multiple options can be selected or not. */
|
|
94
|
-
multiple?: M & boolean
|
|
95
|
-
/** Highlight the ring color like a focus state. */
|
|
96
|
-
highlight?: boolean
|
|
97
|
-
class?: any
|
|
98
|
-
ui?: PartialString<typeof select.slots>
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export type SelectEmits<T, V, M extends boolean> = Omit<SelectRootEmits<T>, 'update:modelValue'> & {
|
|
102
|
-
change: [payload: Event]
|
|
103
|
-
blur: [payload: FocusEvent]
|
|
104
|
-
focus: [payload: FocusEvent]
|
|
105
|
-
} & SelectModelValueEmits<T, V, M, T extends { value: infer U } ? U : never>
|
|
106
|
-
|
|
107
|
-
type SlotProps<T> = (props: { item: T, index: number }) => any
|
|
108
|
-
|
|
109
|
-
export interface SelectSlots<T, M extends boolean> {
|
|
110
|
-
'leading'(props: { modelValue?: M extends true ? AcceptableValue[] : AcceptableValue, open: boolean, ui: any }): any
|
|
111
|
-
'default'(props: { modelValue?: M extends true ? AcceptableValue[] : AcceptableValue, open: boolean }): any
|
|
112
|
-
'trailing'(props: { modelValue?: M extends true ? AcceptableValue[] : AcceptableValue, open: boolean, ui: any }): any
|
|
113
|
-
'item': SlotProps<T>
|
|
114
|
-
'item-leading': SlotProps<T>
|
|
115
|
-
'item-label': SlotProps<T>
|
|
116
|
-
'item-trailing': SlotProps<T>
|
|
117
|
-
}
|
|
1
|
+
<script>
|
|
2
|
+
import theme from "#build/ui/select";
|
|
118
3
|
</script>
|
|
119
4
|
|
|
120
|
-
<script setup
|
|
121
|
-
import { computed, toRef } from
|
|
122
|
-
import { SelectRoot, SelectArrow, SelectTrigger, SelectPortal, SelectContent, SelectViewport, SelectLabel, SelectGroup, SelectItem, SelectItemIndicator, SelectItemText, SelectSeparator, useForwardPropsEmits } from
|
|
123
|
-
import { defu } from
|
|
124
|
-
import { reactivePick } from
|
|
125
|
-
import { useAppConfig } from
|
|
126
|
-
import { useButtonGroup } from
|
|
127
|
-
import { useComponentIcons } from
|
|
128
|
-
import { useFormField } from
|
|
129
|
-
import {
|
|
130
|
-
import
|
|
131
|
-
import
|
|
132
|
-
import
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
const props =
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
5
|
+
<script setup>
|
|
6
|
+
import { computed, toRef } from "vue";
|
|
7
|
+
import { SelectRoot, SelectArrow, SelectTrigger, SelectPortal, SelectContent, SelectViewport, SelectLabel, SelectGroup, SelectItem, SelectItemIndicator, SelectItemText, SelectSeparator, useForwardPropsEmits } from "reka-ui";
|
|
8
|
+
import { defu } from "defu";
|
|
9
|
+
import { reactivePick } from "@vueuse/core";
|
|
10
|
+
import { useAppConfig } from "#imports";
|
|
11
|
+
import { useButtonGroup } from "../composables/useButtonGroup";
|
|
12
|
+
import { useComponentIcons } from "../composables/useComponentIcons";
|
|
13
|
+
import { useFormField } from "../composables/useFormField";
|
|
14
|
+
import { usePortal } from "../composables/usePortal";
|
|
15
|
+
import { compare, get, isArrayOfArray } from "../utils";
|
|
16
|
+
import { tv } from "../utils/tv";
|
|
17
|
+
import UIcon from "./Icon.vue";
|
|
18
|
+
import UAvatar from "./Avatar.vue";
|
|
19
|
+
import UChip from "./Chip.vue";
|
|
20
|
+
defineOptions({ inheritAttrs: false });
|
|
21
|
+
const props = defineProps({
|
|
22
|
+
id: { type: String, required: false },
|
|
23
|
+
placeholder: { type: String, required: false },
|
|
24
|
+
color: { type: null, required: false },
|
|
25
|
+
variant: { type: null, required: false },
|
|
26
|
+
size: { type: null, required: false },
|
|
27
|
+
trailingIcon: { type: String, required: false },
|
|
28
|
+
selectedIcon: { type: String, required: false },
|
|
29
|
+
content: { type: Object, required: false },
|
|
30
|
+
arrow: { type: [Boolean, Object], required: false },
|
|
31
|
+
portal: { type: [Boolean, String], required: false, skipCheck: true, default: true },
|
|
32
|
+
valueKey: { type: null, required: false, default: "value" },
|
|
33
|
+
labelKey: { type: null, required: false, default: "label" },
|
|
34
|
+
items: { type: null, required: false },
|
|
35
|
+
defaultValue: { type: null, required: false },
|
|
36
|
+
modelValue: { type: null, required: false },
|
|
37
|
+
multiple: { type: Boolean, required: false },
|
|
38
|
+
highlight: { type: Boolean, required: false },
|
|
39
|
+
class: { type: null, required: false },
|
|
40
|
+
ui: { type: null, required: false },
|
|
41
|
+
open: { type: Boolean, required: false },
|
|
42
|
+
defaultOpen: { type: Boolean, required: false },
|
|
43
|
+
autocomplete: { type: String, required: false },
|
|
44
|
+
disabled: { type: Boolean, required: false },
|
|
45
|
+
name: { type: String, required: false },
|
|
46
|
+
required: { type: Boolean, required: false },
|
|
47
|
+
icon: { type: String, required: false },
|
|
48
|
+
avatar: { type: Object, required: false },
|
|
49
|
+
leading: { type: Boolean, required: false },
|
|
50
|
+
leadingIcon: { type: String, required: false },
|
|
51
|
+
trailing: { type: Boolean, required: false },
|
|
52
|
+
loading: { type: Boolean, required: false },
|
|
53
|
+
loadingIcon: { type: String, required: false }
|
|
54
|
+
});
|
|
55
|
+
const emits = defineEmits(["update:open", "change", "blur", "focus", "update:modelValue"]);
|
|
56
|
+
const slots = defineSlots();
|
|
57
|
+
const appConfig = useAppConfig();
|
|
58
|
+
const rootProps = useForwardPropsEmits(reactivePick(props, "open", "defaultOpen", "disabled", "autocomplete", "required", "multiple"), emits);
|
|
59
|
+
const portalProps = usePortal(toRef(() => props.portal));
|
|
60
|
+
const contentProps = toRef(() => defu(props.content, { side: "bottom", sideOffset: 8, collisionPadding: 8, position: "popper" }));
|
|
61
|
+
const arrowProps = toRef(() => props.arrow);
|
|
62
|
+
const { emitFormChange, emitFormInput, emitFormBlur, emitFormFocus, size: formGroupSize, color, id, name, highlight, disabled, ariaAttrs } = useFormField(props);
|
|
63
|
+
const { orientation, size: buttonGroupSize } = useButtonGroup(props);
|
|
64
|
+
const { isLeading, isTrailing, leadingIconName, trailingIconName } = useComponentIcons(toRef(() => defu(props, { trailingIcon: appConfig.ui.icons.chevronDown })));
|
|
65
|
+
const selectSize = computed(() => buttonGroupSize.value || formGroupSize.value);
|
|
66
|
+
const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.select || {} })({
|
|
156
67
|
color: color.value,
|
|
157
68
|
variant: props.variant,
|
|
158
69
|
size: selectSize?.value,
|
|
@@ -161,43 +72,40 @@ const ui = computed(() => select({
|
|
|
161
72
|
leading: isLeading.value || !!props.avatar || !!slots.leading,
|
|
162
73
|
trailing: isTrailing.value || !!slots.trailing,
|
|
163
74
|
buttonGroup: orientation.value
|
|
164
|
-
}))
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
const items = computed(() => groups.value.flatMap(group => group)
|
|
169
|
-
|
|
170
|
-
function displayValue(value?: AcceptableValue | AcceptableValue[]): string | undefined {
|
|
75
|
+
}));
|
|
76
|
+
const groups = computed(
|
|
77
|
+
() => props.items?.length ? isArrayOfArray(props.items) ? props.items : [props.items] : []
|
|
78
|
+
);
|
|
79
|
+
const items = computed(() => groups.value.flatMap((group) => group));
|
|
80
|
+
function displayValue(value) {
|
|
171
81
|
if (props.multiple && Array.isArray(value)) {
|
|
172
|
-
return value.map(v => displayValue(v)).filter(Boolean).join(
|
|
82
|
+
return value.map((v) => displayValue(v)).filter(Boolean).join(", ");
|
|
173
83
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
return item && (typeof item === 'object' ? get(item, props.labelKey as string) : item)
|
|
84
|
+
const item = items.value.find((item2) => compare(typeof item2 === "object" ? get(item2, props.valueKey) : item2, value));
|
|
85
|
+
return item && (typeof item === "object" ? get(item, props.labelKey) : item);
|
|
177
86
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
emitFormChange()
|
|
185
|
-
emitFormInput()
|
|
87
|
+
function onUpdate(value) {
|
|
88
|
+
const event = new Event("change", { target: { value } });
|
|
89
|
+
emits("change", event);
|
|
90
|
+
emitFormChange();
|
|
91
|
+
emitFormInput();
|
|
186
92
|
}
|
|
187
|
-
function onUpdateOpen(value
|
|
93
|
+
function onUpdateOpen(value) {
|
|
188
94
|
if (!value) {
|
|
189
|
-
const event = new FocusEvent(
|
|
190
|
-
emits(
|
|
191
|
-
emitFormBlur()
|
|
95
|
+
const event = new FocusEvent("blur");
|
|
96
|
+
emits("blur", event);
|
|
97
|
+
emitFormBlur();
|
|
192
98
|
} else {
|
|
193
|
-
const event = new FocusEvent(
|
|
194
|
-
emits(
|
|
195
|
-
emitFormFocus()
|
|
99
|
+
const event = new FocusEvent("focus");
|
|
100
|
+
emits("focus", event);
|
|
101
|
+
emitFormFocus();
|
|
196
102
|
}
|
|
197
103
|
}
|
|
104
|
+
function isSelectItem(item) {
|
|
105
|
+
return typeof item === "object" && item !== null;
|
|
106
|
+
}
|
|
198
107
|
</script>
|
|
199
108
|
|
|
200
|
-
<!-- eslint-disable vue/no-template-shadow -->
|
|
201
109
|
<template>
|
|
202
110
|
<SelectRoot
|
|
203
111
|
v-slot="{ modelValue, open }"
|
|
@@ -205,61 +113,64 @@ function onUpdateOpen(value: boolean) {
|
|
|
205
113
|
v-bind="rootProps"
|
|
206
114
|
:autocomplete="autocomplete"
|
|
207
115
|
:disabled="disabled"
|
|
208
|
-
:default-value="
|
|
209
|
-
:model-value="
|
|
116
|
+
:default-value="defaultValue"
|
|
117
|
+
:model-value="modelValue"
|
|
210
118
|
@update:model-value="onUpdate"
|
|
211
119
|
@update:open="onUpdateOpen"
|
|
212
120
|
>
|
|
213
121
|
<SelectTrigger :id="id" :class="ui.base({ class: [props.class, props.ui?.base] })" v-bind="{ ...$attrs, ...ariaAttrs }">
|
|
214
122
|
<span v-if="isLeading || !!avatar || !!slots.leading" :class="ui.leading({ class: props.ui?.leading })">
|
|
215
|
-
<slot name="leading" :model-value="
|
|
123
|
+
<slot name="leading" :model-value="modelValue" :open="open" :ui="ui">
|
|
216
124
|
<UIcon v-if="isLeading && leadingIconName" :name="leadingIconName" :class="ui.leadingIcon({ class: props.ui?.leadingIcon })" />
|
|
217
|
-
<UAvatar v-else-if="!!avatar" :size="
|
|
125
|
+
<UAvatar v-else-if="!!avatar" :size="props.ui?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()" v-bind="avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar })" />
|
|
218
126
|
</slot>
|
|
219
127
|
</span>
|
|
220
128
|
|
|
221
|
-
<slot :model-value="
|
|
129
|
+
<slot :model-value="modelValue" :open="open">
|
|
222
130
|
<template v-for="displayedModelValue in [displayValue(modelValue)]" :key="displayedModelValue">
|
|
223
131
|
<span v-if="displayedModelValue" :class="ui.value({ class: props.ui?.value })">
|
|
224
132
|
{{ displayedModelValue }}
|
|
225
133
|
</span>
|
|
226
134
|
<span v-else :class="ui.placeholder({ class: props.ui?.placeholder })">
|
|
227
|
-
{{ placeholder ?? '
|
|
135
|
+
{{ placeholder ?? '\xA0' }}
|
|
228
136
|
</span>
|
|
229
137
|
</template>
|
|
230
138
|
</slot>
|
|
231
139
|
|
|
232
140
|
<span v-if="isTrailing || !!slots.trailing" :class="ui.trailing({ class: props.ui?.trailing })">
|
|
233
|
-
<slot name="trailing" :model-value="
|
|
141
|
+
<slot name="trailing" :model-value="modelValue" :open="open" :ui="ui">
|
|
234
142
|
<UIcon v-if="trailingIconName" :name="trailingIconName" :class="ui.trailingIcon({ class: props.ui?.trailingIcon })" />
|
|
235
143
|
</slot>
|
|
236
144
|
</span>
|
|
237
145
|
</SelectTrigger>
|
|
238
146
|
|
|
239
|
-
<SelectPortal
|
|
147
|
+
<SelectPortal v-bind="portalProps">
|
|
240
148
|
<SelectContent :class="ui.content({ class: props.ui?.content })" v-bind="contentProps">
|
|
149
|
+
<slot name="content-top" />
|
|
150
|
+
|
|
241
151
|
<SelectViewport :class="ui.viewport({ class: props.ui?.viewport })">
|
|
242
152
|
<SelectGroup v-for="(group, groupIndex) in groups" :key="`group-${groupIndex}`" :class="ui.group({ class: props.ui?.group })">
|
|
243
153
|
<template v-for="(item, index) in group" :key="`group-${groupIndex}-${index}`">
|
|
244
|
-
<SelectLabel v-if="item
|
|
245
|
-
{{ get(item, props.labelKey
|
|
154
|
+
<SelectLabel v-if="isSelectItem(item) && item.type === 'label'" :class="ui.label({ class: props.ui?.label })">
|
|
155
|
+
{{ get(item, props.labelKey) }}
|
|
246
156
|
</SelectLabel>
|
|
247
157
|
|
|
248
|
-
<SelectSeparator v-else-if="item
|
|
158
|
+
<SelectSeparator v-else-if="isSelectItem(item) && item.type === 'separator'" :class="ui.separator({ class: props.ui?.separator })" />
|
|
249
159
|
|
|
250
160
|
<SelectItem
|
|
251
161
|
v-else
|
|
252
162
|
:class="ui.item({ class: props.ui?.item })"
|
|
253
|
-
:disabled="item.disabled"
|
|
254
|
-
:value="
|
|
163
|
+
:disabled="isSelectItem(item) && item.disabled"
|
|
164
|
+
:value="isSelectItem(item) ? get(item, props.valueKey) : item"
|
|
165
|
+
@select="isSelectItem(item) && item.onSelect?.($event)"
|
|
255
166
|
>
|
|
256
|
-
<slot name="item" :item="
|
|
257
|
-
<slot name="item-leading" :item="
|
|
258
|
-
<UIcon v-if="item.icon" :name="item.icon" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon })" />
|
|
259
|
-
<UAvatar v-else-if="item.avatar" :size="
|
|
167
|
+
<slot name="item" :item="item" :index="index">
|
|
168
|
+
<slot name="item-leading" :item="item" :index="index">
|
|
169
|
+
<UIcon v-if="isSelectItem(item) && item.icon" :name="item.icon" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon })" />
|
|
170
|
+
<UAvatar v-else-if="isSelectItem(item) && item.avatar" :size="props.ui?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()" v-bind="item.avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar })" />
|
|
260
171
|
<UChip
|
|
261
|
-
v-else-if="item.chip"
|
|
262
|
-
:size="
|
|
172
|
+
v-else-if="isSelectItem(item) && item.chip"
|
|
173
|
+
:size="props.ui?.itemLeadingChipSize || ui.itemLeadingChipSize()"
|
|
263
174
|
inset
|
|
264
175
|
standalone
|
|
265
176
|
v-bind="item.chip"
|
|
@@ -268,13 +179,13 @@ function onUpdateOpen(value: boolean) {
|
|
|
268
179
|
</slot>
|
|
269
180
|
|
|
270
181
|
<SelectItemText :class="ui.itemLabel({ class: props.ui?.itemLabel })">
|
|
271
|
-
<slot name="item-label" :item="
|
|
272
|
-
{{
|
|
182
|
+
<slot name="item-label" :item="item" :index="index">
|
|
183
|
+
{{ isSelectItem(item) ? get(item, props.labelKey) : item }}
|
|
273
184
|
</slot>
|
|
274
185
|
</SelectItemText>
|
|
275
186
|
|
|
276
187
|
<span :class="ui.itemTrailing({ class: props.ui?.itemTrailing })">
|
|
277
|
-
<slot name="item-trailing" :item="
|
|
188
|
+
<slot name="item-trailing" :item="item" :index="index" />
|
|
278
189
|
|
|
279
190
|
<SelectItemIndicator as-child>
|
|
280
191
|
<UIcon :name="selectedIcon || appConfig.ui.icons.check" :class="ui.itemTrailingIcon({ class: props.ui?.itemTrailingIcon })" />
|
|
@@ -286,6 +197,8 @@ function onUpdateOpen(value: boolean) {
|
|
|
286
197
|
</SelectGroup>
|
|
287
198
|
</SelectViewport>
|
|
288
199
|
|
|
200
|
+
<slot name="content-bottom" />
|
|
201
|
+
|
|
289
202
|
<SelectArrow v-if="!!arrow" v-bind="arrowProps" :class="ui.arrow({ class: props.ui?.arrow })" />
|
|
290
203
|
</SelectContent>
|
|
291
204
|
</SelectPortal>
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import type { SelectRootProps, SelectRootEmits, SelectContentProps, SelectContentEmits, SelectArrowProps } from 'reka-ui';
|
|
2
|
+
import type { AppConfig } from '@nuxt/schema';
|
|
3
|
+
import theme from '#build/ui/select';
|
|
4
|
+
import type { UseComponentIconsProps } from '../composables/useComponentIcons';
|
|
5
|
+
import type { AvatarProps, ChipProps } from '../types';
|
|
6
|
+
import type { AcceptableValue, ArrayOrNested, GetItemKeys, GetModelValue, GetModelValueEmits, NestedItem, EmitsToProps, ComponentConfig } from '../types/utils';
|
|
7
|
+
type Select = ComponentConfig<typeof theme, AppConfig, 'select'>;
|
|
8
|
+
interface SelectItemBase {
|
|
9
|
+
label?: string;
|
|
10
|
+
/**
|
|
11
|
+
* @IconifyIcon
|
|
12
|
+
*/
|
|
13
|
+
icon?: string;
|
|
14
|
+
avatar?: AvatarProps;
|
|
15
|
+
chip?: ChipProps;
|
|
16
|
+
/**
|
|
17
|
+
* The item type.
|
|
18
|
+
* @defaultValue 'item'
|
|
19
|
+
*/
|
|
20
|
+
type?: 'label' | 'separator' | 'item';
|
|
21
|
+
value?: string | number;
|
|
22
|
+
disabled?: boolean;
|
|
23
|
+
onSelect?(e?: Event): void;
|
|
24
|
+
[key: string]: any;
|
|
25
|
+
}
|
|
26
|
+
export type SelectItem = SelectItemBase | AcceptableValue | boolean;
|
|
27
|
+
export interface SelectProps<T extends ArrayOrNested<SelectItem> = ArrayOrNested<SelectItem>, VK extends GetItemKeys<T> = 'value', M extends boolean = false> extends Omit<SelectRootProps<T>, 'dir' | 'multiple' | 'modelValue' | 'defaultValue' | 'by'>, UseComponentIconsProps {
|
|
28
|
+
id?: string;
|
|
29
|
+
/** The placeholder text when the select is empty. */
|
|
30
|
+
placeholder?: string;
|
|
31
|
+
/**
|
|
32
|
+
* @defaultValue 'primary'
|
|
33
|
+
*/
|
|
34
|
+
color?: Select['variants']['color'];
|
|
35
|
+
/**
|
|
36
|
+
* @defaultValue 'outline'
|
|
37
|
+
*/
|
|
38
|
+
variant?: Select['variants']['variant'];
|
|
39
|
+
/**
|
|
40
|
+
* @defaultValue 'md'
|
|
41
|
+
*/
|
|
42
|
+
size?: Select['variants']['size'];
|
|
43
|
+
/**
|
|
44
|
+
* The icon displayed to open the menu.
|
|
45
|
+
* @defaultValue appConfig.ui.icons.chevronDown
|
|
46
|
+
* @IconifyIcon
|
|
47
|
+
*/
|
|
48
|
+
trailingIcon?: string;
|
|
49
|
+
/**
|
|
50
|
+
* The icon displayed when an item is selected.
|
|
51
|
+
* @defaultValue appConfig.ui.icons.check
|
|
52
|
+
* @IconifyIcon
|
|
53
|
+
*/
|
|
54
|
+
selectedIcon?: string;
|
|
55
|
+
/**
|
|
56
|
+
* The content of the menu.
|
|
57
|
+
* @defaultValue { side: 'bottom', sideOffset: 8, collisionPadding: 8, position: 'popper' }
|
|
58
|
+
*/
|
|
59
|
+
content?: Omit<SelectContentProps, 'as' | 'asChild' | 'forceMount'> & Partial<EmitsToProps<SelectContentEmits>>;
|
|
60
|
+
/**
|
|
61
|
+
* Display an arrow alongside the menu.
|
|
62
|
+
* @defaultValue false
|
|
63
|
+
*/
|
|
64
|
+
arrow?: boolean | Omit<SelectArrowProps, 'as' | 'asChild'>;
|
|
65
|
+
/**
|
|
66
|
+
* Render the menu in a portal.
|
|
67
|
+
* @defaultValue true
|
|
68
|
+
*/
|
|
69
|
+
portal?: boolean | string | HTMLElement;
|
|
70
|
+
/**
|
|
71
|
+
* When `items` is an array of objects, select the field to use as the value.
|
|
72
|
+
* @defaultValue 'value'
|
|
73
|
+
*/
|
|
74
|
+
valueKey?: VK;
|
|
75
|
+
/**
|
|
76
|
+
* When `items` is an array of objects, select the field to use as the label.
|
|
77
|
+
* @defaultValue 'label'
|
|
78
|
+
*/
|
|
79
|
+
labelKey?: keyof NestedItem<T>;
|
|
80
|
+
items?: T;
|
|
81
|
+
/** The value of the Select when initially rendered. Use when you do not need to control the state of the Select. */
|
|
82
|
+
defaultValue?: GetModelValue<T, VK, M>;
|
|
83
|
+
/** The controlled value of the Select. Can be bind as `v-model`. */
|
|
84
|
+
modelValue?: GetModelValue<T, VK, M>;
|
|
85
|
+
/** Whether multiple options can be selected or not. */
|
|
86
|
+
multiple?: M & boolean;
|
|
87
|
+
/** Highlight the ring color like a focus state. */
|
|
88
|
+
highlight?: boolean;
|
|
89
|
+
class?: any;
|
|
90
|
+
ui?: Select['slots'];
|
|
91
|
+
}
|
|
92
|
+
export type SelectEmits<A extends ArrayOrNested<SelectItem>, VK extends GetItemKeys<A> | undefined, M extends boolean> = Omit<SelectRootEmits, 'update:modelValue'> & {
|
|
93
|
+
change: [payload: Event];
|
|
94
|
+
blur: [payload: FocusEvent];
|
|
95
|
+
focus: [payload: FocusEvent];
|
|
96
|
+
} & GetModelValueEmits<A, VK, M>;
|
|
97
|
+
type SlotProps<T extends SelectItem> = (props: {
|
|
98
|
+
item: T;
|
|
99
|
+
index: number;
|
|
100
|
+
}) => any;
|
|
101
|
+
export interface SelectSlots<A extends ArrayOrNested<SelectItem> = ArrayOrNested<SelectItem>, VK extends GetItemKeys<A> | undefined = undefined, M extends boolean = false, T extends NestedItem<A> = NestedItem<A>> {
|
|
102
|
+
'leading'(props: {
|
|
103
|
+
modelValue?: GetModelValue<A, VK, M>;
|
|
104
|
+
open: boolean;
|
|
105
|
+
ui: {
|
|
106
|
+
[K in keyof Required<Select['slots']>]: (props?: Record<string, any>) => string;
|
|
107
|
+
};
|
|
108
|
+
}): any;
|
|
109
|
+
'default'(props: {
|
|
110
|
+
modelValue?: GetModelValue<A, VK, M>;
|
|
111
|
+
open: boolean;
|
|
112
|
+
}): any;
|
|
113
|
+
'trailing'(props: {
|
|
114
|
+
modelValue?: GetModelValue<A, VK, M>;
|
|
115
|
+
open: boolean;
|
|
116
|
+
ui: {
|
|
117
|
+
[K in keyof Required<Select['slots']>]: (props?: Record<string, any>) => string;
|
|
118
|
+
};
|
|
119
|
+
}): any;
|
|
120
|
+
'item': SlotProps<T>;
|
|
121
|
+
'item-leading': SlotProps<T>;
|
|
122
|
+
'item-label': SlotProps<T>;
|
|
123
|
+
'item-trailing': SlotProps<T>;
|
|
124
|
+
'content-top': (props?: {}) => any;
|
|
125
|
+
'content-bottom': (props?: {}) => any;
|
|
126
|
+
}
|
|
127
|
+
declare const _default: <T extends ArrayOrNested<SelectItem>, VK extends GetItemKeys<T> = "value", M extends boolean = false>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
128
|
+
props: __VLS_PrettifyLocal<any & SelectProps<T, VK, M> & Partial<{}>> & (import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps);
|
|
129
|
+
expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
|
|
130
|
+
attrs: any;
|
|
131
|
+
slots: Readonly<SelectSlots<T, VK, M, NestedItem<T>>> & SelectSlots<T, VK, M, NestedItem<T>>;
|
|
132
|
+
emit: ((evt: "blur", payload: FocusEvent) => void) & ((evt: "change", payload: Event) => void) & ((evt: "focus", payload: FocusEvent) => void) & ((evt: "update:open", value: boolean) => void) & ((evt: "update:modelValue", payload: GetModelValue<T, VK, M>) => void);
|
|
133
|
+
}>) => import("vue").VNode & {
|
|
134
|
+
__ctx?: Awaited<typeof __VLS_setup>;
|
|
135
|
+
};
|
|
136
|
+
export default _default;
|
|
137
|
+
type __VLS_PrettifyLocal<T> = {
|
|
138
|
+
[K in keyof T]: T[K];
|
|
139
|
+
} & {};
|