@nuxt/ui 3.0.2 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. package/.nuxt/ui/accordion.ts +2 -2
  2. package/.nuxt/ui/alert.ts +29 -29
  3. package/.nuxt/ui/avatar-group.ts +1 -1
  4. package/.nuxt/ui/avatar.ts +3 -3
  5. package/.nuxt/ui/badge.ts +33 -33
  6. package/.nuxt/ui/breadcrumb.ts +5 -5
  7. package/.nuxt/ui/button.ts +43 -43
  8. package/.nuxt/ui/calendar.ts +17 -17
  9. package/.nuxt/ui/card.ts +5 -5
  10. package/.nuxt/ui/carousel.ts +6 -6
  11. package/.nuxt/ui/checkbox-group.ts +61 -0
  12. package/.nuxt/ui/checkbox.ts +140 -27
  13. package/.nuxt/ui/chip.ts +8 -8
  14. package/.nuxt/ui/color-picker.ts +3 -3
  15. package/.nuxt/ui/command-palette.ts +14 -14
  16. package/.nuxt/ui/context-menu.ts +33 -33
  17. package/.nuxt/ui/drawer.ts +10 -10
  18. package/.nuxt/ui/dropdown-menu.ts +34 -34
  19. package/.nuxt/ui/form-field.ts +6 -6
  20. package/.nuxt/ui/index.ts +1 -0
  21. package/.nuxt/ui/input-menu.ts +42 -42
  22. package/.nuxt/ui/input-number.ts +20 -20
  23. package/.nuxt/ui/input.ts +23 -23
  24. package/.nuxt/ui/kbd.ts +4 -4
  25. package/.nuxt/ui/link.ts +3 -3
  26. package/.nuxt/ui/modal.ts +5 -5
  27. package/.nuxt/ui/navigation-menu.ts +78 -80
  28. package/.nuxt/ui/pin-input.ts +20 -20
  29. package/.nuxt/ui/popover.ts +2 -2
  30. package/.nuxt/ui/progress.ts +17 -17
  31. package/.nuxt/ui/radio-group.ts +250 -35
  32. package/.nuxt/ui/select-menu.ts +36 -33
  33. package/.nuxt/ui/select.ts +32 -32
  34. package/.nuxt/ui/separator.ts +8 -8
  35. package/.nuxt/ui/skeleton.ts +1 -1
  36. package/.nuxt/ui/slideover.ts +4 -4
  37. package/.nuxt/ui/slider.ts +16 -16
  38. package/.nuxt/ui/stepper.ts +18 -18
  39. package/.nuxt/ui/switch.ts +20 -20
  40. package/.nuxt/ui/table.ts +15 -15
  41. package/.nuxt/ui/tabs.ts +32 -32
  42. package/.nuxt/ui/textarea.ts +40 -35
  43. package/.nuxt/ui/toast.ts +24 -24
  44. package/.nuxt/ui/tooltip.ts +2 -2
  45. package/.nuxt/ui/tree.ts +18 -18
  46. package/.nuxt/ui.css +63 -12
  47. package/README.md +15 -0
  48. package/cli/templates.mjs +18 -17
  49. package/dist/module.json +5 -5
  50. package/dist/module.mjs +12 -7
  51. package/dist/runtime/components/Accordion.vue +36 -93
  52. package/dist/runtime/components/Accordion.vue.d.ts +75 -0
  53. package/dist/runtime/components/Alert.vue +37 -100
  54. package/dist/runtime/components/Alert.vue.d.ts +81 -0
  55. package/dist/runtime/components/App.vue +28 -34
  56. package/dist/runtime/components/App.vue.d.ts +24 -0
  57. package/dist/runtime/components/Avatar.vue +42 -75
  58. package/dist/runtime/components/Avatar.vue.d.ts +39 -0
  59. package/dist/runtime/components/AvatarGroup.vue +40 -77
  60. package/dist/runtime/components/AvatarGroup.vue.d.ts +31 -0
  61. package/dist/runtime/components/Badge.vue +33 -62
  62. package/dist/runtime/components/Badge.vue.d.ts +41 -0
  63. package/dist/runtime/components/Breadcrumb.vue +37 -90
  64. package/dist/runtime/components/Breadcrumb.vue.d.ts +64 -0
  65. package/dist/runtime/components/Button.vue +95 -104
  66. package/dist/runtime/components/Button.vue.d.ts +48 -0
  67. package/dist/runtime/components/ButtonGroup.vue +20 -46
  68. package/dist/runtime/components/ButtonGroup.vue.d.ts +34 -0
  69. package/dist/runtime/components/Calendar.vue +67 -150
  70. package/dist/runtime/components/Calendar.vue.d.ts +111 -0
  71. package/dist/runtime/components/Card.vue +18 -40
  72. package/dist/runtime/components/Card.vue.d.ts +29 -0
  73. package/dist/runtime/components/Carousel.vue +112 -234
  74. package/dist/runtime/components/Carousel.vue.d.ts +122 -0
  75. package/dist/runtime/components/Checkbox.vue +52 -93
  76. package/dist/runtime/components/Checkbox.vue.d.ts +73 -0
  77. package/dist/runtime/components/CheckboxGroup.vue +121 -0
  78. package/dist/runtime/components/CheckboxGroup.vue.d.ts +78 -0
  79. package/dist/runtime/components/Chip.vue +26 -69
  80. package/dist/runtime/components/Chip.vue.d.ts +57 -0
  81. package/dist/runtime/components/Collapsible.vue +22 -41
  82. package/dist/runtime/components/Collapsible.vue.d.ts +35 -0
  83. package/dist/runtime/components/ColorPicker.vue +111 -197
  84. package/dist/runtime/components/ColorPicker.vue.d.ts +48 -0
  85. package/dist/runtime/components/CommandPalette.vue +96 -237
  86. package/dist/runtime/components/CommandPalette.vue.d.ts +161 -0
  87. package/dist/runtime/components/Container.vue +15 -28
  88. package/dist/runtime/components/Container.vue.d.ts +18 -0
  89. package/dist/runtime/components/ContextMenu.vue +34 -133
  90. package/dist/runtime/components/ContextMenu.vue.d.ts +107 -0
  91. package/dist/runtime/components/ContextMenuContent.vue +73 -81
  92. package/dist/runtime/components/ContextMenuContent.vue.d.ts +65 -0
  93. package/dist/runtime/components/Drawer.vue +49 -83
  94. package/dist/runtime/components/Drawer.vue.d.ts +78 -0
  95. package/dist/runtime/components/DropdownMenu.vue +39 -142
  96. package/dist/runtime/components/DropdownMenu.vue.d.ts +117 -0
  97. package/dist/runtime/components/DropdownMenuContent.vue +78 -88
  98. package/dist/runtime/components/DropdownMenuContent.vue.d.ts +68 -0
  99. package/dist/runtime/components/Form.vue +135 -220
  100. package/dist/runtime/components/Form.vue.d.ts +69 -0
  101. package/dist/runtime/components/FormField.vue +35 -77
  102. package/dist/runtime/components/FormField.vue.d.ts +61 -0
  103. package/dist/runtime/components/Icon.vue +12 -19
  104. package/dist/runtime/components/Icon.vue.d.ts +8 -0
  105. package/dist/runtime/components/Input.vue +82 -140
  106. package/dist/runtime/components/Input.vue.d.ts +76 -0
  107. package/dist/runtime/components/InputMenu.vue +185 -332
  108. package/dist/runtime/components/InputMenu.vue.d.ts +324 -0
  109. package/dist/runtime/components/InputNumber.vue +71 -133
  110. package/dist/runtime/components/InputNumber.vue.d.ts +182 -0
  111. package/dist/runtime/components/Kbd.vue +20 -46
  112. package/dist/runtime/components/Kbd.vue.d.ts +34 -0
  113. package/dist/runtime/components/Link.vue +98 -176
  114. package/dist/runtime/components/Link.vue.d.ts +93 -0
  115. package/dist/runtime/components/LinkBase.vue +33 -42
  116. package/dist/runtime/components/LinkBase.vue.d.ts +25 -0
  117. package/dist/runtime/components/Modal.vue +53 -116
  118. package/dist/runtime/components/Modal.vue.d.ts +93 -0
  119. package/dist/runtime/components/NavigationMenu.vue +77 -209
  120. package/dist/runtime/components/NavigationMenu.vue.d.ts +139 -0
  121. package/dist/runtime/components/OverlayProvider.vue +14 -18
  122. package/dist/runtime/components/OverlayProvider.vue.d.ts +2 -0
  123. package/dist/runtime/components/Pagination.vue +46 -140
  124. package/dist/runtime/components/Pagination.vue.d.ts +119 -0
  125. package/dist/runtime/components/PinInput.vue +61 -78
  126. package/dist/runtime/components/PinInput.vue.d.ts +57 -0
  127. package/dist/runtime/components/Popover.vue +47 -84
  128. package/dist/runtime/components/Popover.vue.d.ts +63 -0
  129. package/dist/runtime/components/Progress.vue +70 -131
  130. package/dist/runtime/components/Progress.vue.d.ts +66 -0
  131. package/dist/runtime/components/RadioGroup.vue +70 -132
  132. package/dist/runtime/components/RadioGroup.vue.d.ts +91 -0
  133. package/dist/runtime/components/Select.vue +110 -224
  134. package/dist/runtime/components/Select.vue.d.ts +145 -0
  135. package/dist/runtime/components/SelectMenu.vue +161 -310
  136. package/dist/runtime/components/SelectMenu.vue.d.ts +196 -0
  137. package/dist/runtime/components/Separator.vue +29 -71
  138. package/dist/runtime/components/Separator.vue.d.ts +54 -0
  139. package/dist/runtime/components/Skeleton.vue +21 -23
  140. package/dist/runtime/components/Skeleton.vue.d.ts +17 -0
  141. package/dist/runtime/components/Slideover.vue +53 -120
  142. package/dist/runtime/components/Slideover.vue.d.ts +94 -0
  143. package/dist/runtime/components/Slider.vue +46 -84
  144. package/dist/runtime/components/Slider.vue.d.ts +52 -0
  145. package/dist/runtime/components/Stepper.vue +45 -115
  146. package/dist/runtime/components/Stepper.vue.d.ts +83 -0
  147. package/dist/runtime/components/Switch.vue +45 -93
  148. package/dist/runtime/components/Switch.vue.d.ts +70 -0
  149. package/dist/runtime/components/Table.vue +163 -267
  150. package/dist/runtime/components/Table.vue.d.ts +183 -0
  151. package/dist/runtime/components/Tabs.vue +41 -107
  152. package/dist/runtime/components/Tabs.vue.d.ts +88 -0
  153. package/dist/runtime/components/Textarea.vue +113 -158
  154. package/dist/runtime/components/Textarea.vue.d.ts +78 -0
  155. package/dist/runtime/components/Toast.vue +49 -110
  156. package/dist/runtime/components/Toast.vue.d.ts +157 -0
  157. package/dist/runtime/components/Toaster.vue +70 -107
  158. package/dist/runtime/components/Toaster.vue.d.ts +38 -0
  159. package/dist/runtime/components/Tooltip.vue +38 -65
  160. package/dist/runtime/components/Tooltip.vue.d.ts +50 -0
  161. package/dist/runtime/components/Tree.vue +59 -166
  162. package/dist/runtime/components/Tree.vue.d.ts +111 -0
  163. package/dist/runtime/composables/defineShortcuts.d.ts +1 -1
  164. package/dist/runtime/composables/defineShortcuts.js +6 -0
  165. package/dist/runtime/composables/useAvatarGroup.d.ts +1 -1
  166. package/dist/runtime/composables/useButtonGroup.d.ts +2 -2
  167. package/dist/runtime/composables/useFormField.d.ts +2 -2
  168. package/dist/runtime/composables/useKbd.d.ts +1 -0
  169. package/dist/runtime/composables/useKbd.js +4 -3
  170. package/dist/runtime/composables/useOverlay.d.ts +14 -8
  171. package/dist/runtime/composables/useOverlay.js +20 -7
  172. package/dist/runtime/composables/usePortal.d.ts +6 -0
  173. package/dist/runtime/composables/usePortal.js +17 -0
  174. package/dist/runtime/index.css +1 -1
  175. package/dist/runtime/inertia/components/Link.vue +146 -0
  176. package/dist/runtime/inertia/components/Link.vue.d.ts +63 -0
  177. package/dist/runtime/inertia/stubs.d.ts +43 -0
  178. package/dist/runtime/inertia/stubs.js +82 -0
  179. package/dist/runtime/locale/bg.d.ts +3 -0
  180. package/dist/runtime/locale/bg.js +54 -0
  181. package/dist/runtime/locale/index.d.ts +5 -1
  182. package/dist/runtime/locale/index.js +5 -1
  183. package/dist/runtime/locale/kk.d.ts +3 -0
  184. package/dist/runtime/locale/kk.js +54 -0
  185. package/dist/runtime/locale/tj.d.ts +3 -0
  186. package/dist/runtime/locale/tj.js +54 -0
  187. package/dist/runtime/locale/ug_cn.d.ts +3 -0
  188. package/dist/runtime/locale/ug_cn.js +55 -0
  189. package/dist/runtime/types/form.d.ts +4 -1
  190. package/dist/runtime/types/index.d.ts +1 -0
  191. package/dist/runtime/types/index.js +1 -0
  192. package/dist/runtime/types/tv.d.ts +53 -0
  193. package/dist/runtime/types/tv.js +0 -0
  194. package/dist/runtime/types/utils.d.ts +7 -17
  195. package/dist/runtime/types/utils.js +1 -0
  196. package/dist/runtime/utils/link.d.ts +3 -3
  197. package/dist/runtime/utils/link.js +1 -0
  198. package/dist/runtime/utils/tv.js +2 -2
  199. package/dist/runtime/vue/components/Icon.vue +7 -8
  200. package/dist/runtime/vue/components/Icon.vue.d.ts +5 -0
  201. package/dist/runtime/vue/components/Link.vue +118 -202
  202. package/dist/runtime/vue/components/Link.vue.d.ts +93 -0
  203. package/dist/runtime/vue/stubs.d.ts +2 -2
  204. package/dist/shared/{ui.BkNUP964.mjs → ui.CbtTMMzt.mjs} +631 -366
  205. package/dist/types.d.mts +3 -5
  206. package/dist/unplugin.d.mts +6 -2
  207. package/dist/unplugin.mjs +25 -4
  208. package/dist/vite.d.mts +1 -1
  209. package/dist/vite.mjs +2 -2
  210. package/package.json +96 -54
  211. package/dist/module.cjs +0 -62
  212. package/dist/module.d.cts +0 -45
  213. package/dist/module.d.ts +0 -45
  214. package/dist/shared/ui.BL-XB3u1.cjs +0 -3555
  215. package/dist/types.d.ts +0 -7
  216. package/dist/unplugin.cjs +0 -232
  217. package/dist/unplugin.d.cts +0 -62
  218. package/dist/unplugin.d.ts +0 -62
  219. package/dist/vite.cjs +0 -23
  220. package/dist/vite.d.cts +0 -15
  221. package/dist/vite.d.ts +0 -15
@@ -1,175 +1,69 @@
1
- <script lang="ts">
2
- import type { VariantProps } from 'tailwind-variants'
3
- import type { SelectRootProps, SelectRootEmits, SelectContentProps, SelectContentEmits, SelectArrowProps } 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 {
11
- AcceptableValue,
12
- ArrayOrNested,
13
- GetItemKeys,
14
- GetItemValue,
15
- GetModelValue,
16
- GetModelValueEmits,
17
- NestedItem,
18
- PartialString,
19
- EmitsToProps
20
- } from '../types/utils'
21
-
22
- const appConfigSelect = _appConfig as AppConfig & { ui: { select: Partial<typeof theme> } }
23
-
24
- const select = tv({ extend: tv(theme), ...(appConfigSelect.ui?.select || {}) })
25
-
26
- interface SelectItemBase {
27
- label?: string
28
- /**
29
- * @IconifyIcon
30
- */
31
- icon?: string
32
- avatar?: AvatarProps
33
- chip?: ChipProps
34
- /**
35
- * The item type.
36
- * @defaultValue 'item'
37
- */
38
- type?: 'label' | 'separator' | 'item'
39
- value?: string | number
40
- disabled?: boolean
41
- [key: string]: any
42
- }
43
- export type SelectItem = SelectItemBase | AcceptableValue | boolean
44
-
45
- type SelectVariants = VariantProps<typeof select>
46
-
47
- 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 {
48
- id?: string
49
- /** The placeholder text when the select is empty. */
50
- placeholder?: string
51
- /**
52
- * @defaultValue 'primary'
53
- */
54
- color?: SelectVariants['color']
55
- /**
56
- * @defaultValue 'outline'
57
- */
58
- variant?: SelectVariants['variant']
59
- /**
60
- * @defaultValue 'md'
61
- */
62
- size?: SelectVariants['size']
63
- /**
64
- * The icon displayed to open the menu.
65
- * @defaultValue appConfig.ui.icons.chevronDown
66
- * @IconifyIcon
67
- */
68
- trailingIcon?: string
69
- /**
70
- * The icon displayed when an item is selected.
71
- * @defaultValue appConfig.ui.icons.check
72
- * @IconifyIcon
73
- */
74
- selectedIcon?: string
75
- /**
76
- * The content of the menu.
77
- * @defaultValue { side: 'bottom', sideOffset: 8, collisionPadding: 8, position: 'popper' }
78
- */
79
- content?: Omit<SelectContentProps, 'as' | 'asChild' | 'forceMount'> & Partial<EmitsToProps<SelectContentEmits>>
80
- /**
81
- * Display an arrow alongside the menu.
82
- * @defaultValue false
83
- */
84
- arrow?: boolean | Omit<SelectArrowProps, 'as' | 'asChild'>
85
- /**
86
- * Render the menu in a portal.
87
- * @defaultValue true
88
- */
89
- portal?: boolean
90
- /**
91
- * When `items` is an array of objects, select the field to use as the value.
92
- * @defaultValue 'value'
93
- */
94
- valueKey?: VK
95
- /**
96
- * When `items` is an array of objects, select the field to use as the label.
97
- * @defaultValue 'label'
98
- */
99
- labelKey?: keyof NestedItem<T>
100
- items?: T
101
- /** The value of the Select when initially rendered. Use when you do not need to control the state of the Select. */
102
- defaultValue?: GetModelValue<T, VK, M>
103
- /** The controlled value of the Select. Can be bind as `v-model`. */
104
- modelValue?: GetModelValue<T, VK, M>
105
- /** Whether multiple options can be selected or not. */
106
- multiple?: M & boolean
107
- /** Highlight the ring color like a focus state. */
108
- highlight?: boolean
109
- class?: any
110
- ui?: PartialString<typeof select.slots>
111
- }
112
-
113
- export type SelectEmits<A extends ArrayOrNested<SelectItem>, VK extends GetItemKeys<A> | undefined, M extends boolean> = Omit<SelectRootEmits, 'update:modelValue'> & {
114
- change: [payload: Event]
115
- blur: [payload: FocusEvent]
116
- focus: [payload: FocusEvent]
117
- } & GetModelValueEmits<A, VK, M>
118
-
119
- type SlotProps<T extends SelectItem> = (props: { item: T, index: number }) => any
120
-
121
- export interface SelectSlots<
122
- A extends ArrayOrNested<SelectItem> = ArrayOrNested<SelectItem>,
123
- VK extends GetItemKeys<A> | undefined = undefined,
124
- M extends boolean = false,
125
- T extends NestedItem<A> = NestedItem<A>
126
- > {
127
- 'leading'(props: { modelValue?: GetModelValue<A, VK, M>, open: boolean, ui: ReturnType<typeof select> }): any
128
- 'default'(props: { modelValue?: GetModelValue<A, VK, M>, open: boolean }): any
129
- 'trailing'(props: { modelValue?: GetModelValue<A, VK, M>, open: boolean, ui: ReturnType<typeof select> }): any
130
- 'item': SlotProps<T>
131
- 'item-leading': SlotProps<T>
132
- 'item-label': SlotProps<T>
133
- 'item-trailing': SlotProps<T>
134
- }
1
+ <script>
2
+ import theme from "#build/ui/select";
135
3
  </script>
136
4
 
137
- <script setup lang="ts" generic="T extends ArrayOrNested<SelectItem>, VK extends GetItemKeys<T> = 'value', M extends boolean = false">
138
- import { computed, toRef } from 'vue'
139
- import { SelectRoot, SelectArrow, SelectTrigger, SelectPortal, SelectContent, SelectViewport, SelectLabel, SelectGroup, SelectItem, SelectItemIndicator, SelectItemText, SelectSeparator, useForwardPropsEmits } from 'reka-ui'
140
- import { defu } from 'defu'
141
- import { reactivePick } from '@vueuse/core'
142
- import { useAppConfig } from '#imports'
143
- import { useButtonGroup } from '../composables/useButtonGroup'
144
- import { useComponentIcons } from '../composables/useComponentIcons'
145
- import { useFormField } from '../composables/useFormField'
146
- import { compare, get, isArrayOfArray } from '../utils'
147
- import UIcon from './Icon.vue'
148
- import UAvatar from './Avatar.vue'
149
- import UChip from './Chip.vue'
150
-
151
- defineOptions({ inheritAttrs: false })
152
-
153
- const props = withDefaults(defineProps<SelectProps<T, VK, M>>(), {
154
- valueKey: 'value' as never,
155
- labelKey: 'label' as never,
156
- portal: true
157
- })
158
- const emits = defineEmits<SelectEmits<T, VK, M>>()
159
- const slots = defineSlots<SelectSlots<T, VK, M>>()
160
-
161
- const appConfig = useAppConfig()
162
- const rootProps = useForwardPropsEmits(reactivePick(props, 'open', 'defaultOpen', 'disabled', 'autocomplete', 'required', 'multiple'), emits)
163
- const contentProps = toRef(() => defu(props.content, { side: 'bottom', sideOffset: 8, collisionPadding: 8, position: 'popper' }) as SelectContentProps)
164
- const arrowProps = toRef(() => props.arrow as SelectArrowProps)
165
-
166
- const { emitFormChange, emitFormInput, emitFormBlur, emitFormFocus, size: formGroupSize, color, id, name, highlight, disabled, ariaAttrs } = useFormField<InputProps>(props)
167
- const { orientation, size: buttonGroupSize } = useButtonGroup<InputProps>(props)
168
- const { isLeading, isTrailing, leadingIconName, trailingIconName } = useComponentIcons(toRef(() => defu(props, { trailingIcon: appConfig.ui.icons.chevronDown })))
169
-
170
- const selectSize = computed(() => buttonGroupSize.value || formGroupSize.value)
171
-
172
- const ui = computed(() => select({
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 || {} })({
173
67
  color: color.value,
174
68
  variant: props.variant,
175
69
  size: selectSize?.value,
@@ -178,53 +72,40 @@ const ui = computed(() => select({
178
72
  leading: isLeading.value || !!props.avatar || !!slots.leading,
179
73
  trailing: isTrailing.value || !!slots.trailing,
180
74
  buttonGroup: orientation.value
181
- }))
182
-
183
- const groups = computed<SelectItem[][]>(() =>
184
- props.items?.length
185
- ? isArrayOfArray(props.items)
186
- ? props.items
187
- : [props.items]
188
- : []
189
- )
190
- // eslint-disable-next-line vue/no-dupe-keys
191
- const items = computed(() => groups.value.flatMap(group => group) as T[])
192
-
193
- function displayValue(value?: GetItemValue<T, VK> | GetItemValue<T, VK>[]): string {
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) {
194
81
  if (props.multiple && Array.isArray(value)) {
195
- return value.map(v => displayValue(v)).filter(Boolean).join(', ')
82
+ return value.map((v) => displayValue(v)).filter(Boolean).join(", ");
196
83
  }
197
-
198
- const item = items.value.find(item => compare(typeof item === 'object' ? get(item as Record<string, any>, props.valueKey as string) : item, value))
199
- 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);
200
86
  }
201
-
202
- function onUpdate(value: any) {
203
- // @ts-expect-error - 'target' does not exist in type 'EventInit'
204
- const event = new Event('change', { target: { value } })
205
- emits('change', event)
206
-
207
- emitFormChange()
208
- emitFormInput()
87
+ function onUpdate(value) {
88
+ const event = new Event("change", { target: { value } });
89
+ emits("change", event);
90
+ emitFormChange();
91
+ emitFormInput();
209
92
  }
210
- function onUpdateOpen(value: boolean) {
93
+ function onUpdateOpen(value) {
211
94
  if (!value) {
212
- const event = new FocusEvent('blur')
213
- emits('blur', event)
214
- emitFormBlur()
95
+ const event = new FocusEvent("blur");
96
+ emits("blur", event);
97
+ emitFormBlur();
215
98
  } else {
216
- const event = new FocusEvent('focus')
217
- emits('focus', event)
218
- emitFormFocus()
99
+ const event = new FocusEvent("focus");
100
+ emits("focus", event);
101
+ emitFormFocus();
219
102
  }
220
103
  }
221
-
222
- function isSelectItem(item: SelectItem): item is SelectItemBase {
223
- return typeof item === 'object' && item !== null
104
+ function isSelectItem(item) {
105
+ return typeof item === "object" && item !== null;
224
106
  }
225
107
  </script>
226
108
 
227
- <!-- eslint-disable vue/no-template-shadow -->
228
109
  <template>
229
110
  <SelectRoot
230
111
  v-slot="{ modelValue, open }"
@@ -232,44 +113,46 @@ function isSelectItem(item: SelectItem): item is SelectItemBase {
232
113
  v-bind="rootProps"
233
114
  :autocomplete="autocomplete"
234
115
  :disabled="disabled"
235
- :default-value="(defaultValue as (AcceptableValue | AcceptableValue[]))"
236
- :model-value="(modelValue as (AcceptableValue | AcceptableValue[]))"
116
+ :default-value="defaultValue"
117
+ :model-value="modelValue"
237
118
  @update:model-value="onUpdate"
238
119
  @update:open="onUpdateOpen"
239
120
  >
240
121
  <SelectTrigger :id="id" :class="ui.base({ class: [props.class, props.ui?.base] })" v-bind="{ ...$attrs, ...ariaAttrs }">
241
122
  <span v-if="isLeading || !!avatar || !!slots.leading" :class="ui.leading({ class: props.ui?.leading })">
242
- <slot name="leading" :model-value="(modelValue as GetModelValue<T, VK, M>)" :open="open" :ui="ui">
123
+ <slot name="leading" :model-value="modelValue" :open="open" :ui="ui">
243
124
  <UIcon v-if="isLeading && leadingIconName" :name="leadingIconName" :class="ui.leadingIcon({ class: props.ui?.leadingIcon })" />
244
- <UAvatar v-else-if="!!avatar" :size="((props.ui?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar })" />
125
+ <UAvatar v-else-if="!!avatar" :size="props.ui?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()" v-bind="avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar })" />
245
126
  </slot>
246
127
  </span>
247
128
 
248
- <slot :model-value="(modelValue as GetModelValue<T, VK, M>)" :open="open">
249
- <template v-for="displayedModelValue in [displayValue(modelValue as GetModelValue<T, VK, M>)]" :key="displayedModelValue">
129
+ <slot :model-value="modelValue" :open="open">
130
+ <template v-for="displayedModelValue in [displayValue(modelValue)]" :key="displayedModelValue">
250
131
  <span v-if="displayedModelValue" :class="ui.value({ class: props.ui?.value })">
251
132
  {{ displayedModelValue }}
252
133
  </span>
253
134
  <span v-else :class="ui.placeholder({ class: props.ui?.placeholder })">
254
- {{ placeholder ?? '&nbsp;' }}
135
+ {{ placeholder ?? '\xA0' }}
255
136
  </span>
256
137
  </template>
257
138
  </slot>
258
139
 
259
140
  <span v-if="isTrailing || !!slots.trailing" :class="ui.trailing({ class: props.ui?.trailing })">
260
- <slot name="trailing" :model-value="(modelValue as GetModelValue<T, VK, M>)" :open="open" :ui="ui">
141
+ <slot name="trailing" :model-value="modelValue" :open="open" :ui="ui">
261
142
  <UIcon v-if="trailingIconName" :name="trailingIconName" :class="ui.trailingIcon({ class: props.ui?.trailingIcon })" />
262
143
  </slot>
263
144
  </span>
264
145
  </SelectTrigger>
265
146
 
266
- <SelectPortal :disabled="!portal">
147
+ <SelectPortal v-bind="portalProps">
267
148
  <SelectContent :class="ui.content({ class: props.ui?.content })" v-bind="contentProps">
149
+ <slot name="content-top" />
150
+
268
151
  <SelectViewport :class="ui.viewport({ class: props.ui?.viewport })">
269
152
  <SelectGroup v-for="(group, groupIndex) in groups" :key="`group-${groupIndex}`" :class="ui.group({ class: props.ui?.group })">
270
153
  <template v-for="(item, index) in group" :key="`group-${groupIndex}-${index}`">
271
154
  <SelectLabel v-if="isSelectItem(item) && item.type === 'label'" :class="ui.label({ class: props.ui?.label })">
272
- {{ get(item, props.labelKey as string) }}
155
+ {{ get(item, props.labelKey) }}
273
156
  </SelectLabel>
274
157
 
275
158
  <SelectSeparator v-else-if="isSelectItem(item) && item.type === 'separator'" :class="ui.separator({ class: props.ui?.separator })" />
@@ -278,15 +161,16 @@ function isSelectItem(item: SelectItem): item is SelectItemBase {
278
161
  v-else
279
162
  :class="ui.item({ class: props.ui?.item })"
280
163
  :disabled="isSelectItem(item) && item.disabled"
281
- :value="isSelectItem(item) ? get(item, props.valueKey as string) : item"
164
+ :value="isSelectItem(item) ? get(item, props.valueKey) : item"
165
+ @select="isSelectItem(item) && item.onSelect?.($event)"
282
166
  >
283
- <slot name="item" :item="(item as NestedItem<T>)" :index="index">
284
- <slot name="item-leading" :item="(item as NestedItem<T>)" :index="index">
167
+ <slot name="item" :item="item" :index="index">
168
+ <slot name="item-leading" :item="item" :index="index">
285
169
  <UIcon v-if="isSelectItem(item) && item.icon" :name="item.icon" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon })" />
286
- <UAvatar v-else-if="isSelectItem(item) && item.avatar" :size="((props.ui?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="item.avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar })" />
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 })" />
287
171
  <UChip
288
172
  v-else-if="isSelectItem(item) && item.chip"
289
- :size="((props.ui?.itemLeadingChipSize || ui.itemLeadingChipSize()) as ChipProps['size'])"
173
+ :size="props.ui?.itemLeadingChipSize || ui.itemLeadingChipSize()"
290
174
  inset
291
175
  standalone
292
176
  v-bind="item.chip"
@@ -295,13 +179,13 @@ function isSelectItem(item: SelectItem): item is SelectItemBase {
295
179
  </slot>
296
180
 
297
181
  <SelectItemText :class="ui.itemLabel({ class: props.ui?.itemLabel })">
298
- <slot name="item-label" :item="(item as NestedItem<T>)" :index="index">
299
- {{ isSelectItem(item) ? get(item, props.labelKey as string) : item }}
182
+ <slot name="item-label" :item="item" :index="index">
183
+ {{ isSelectItem(item) ? get(item, props.labelKey) : item }}
300
184
  </slot>
301
185
  </SelectItemText>
302
186
 
303
187
  <span :class="ui.itemTrailing({ class: props.ui?.itemTrailing })">
304
- <slot name="item-trailing" :item="(item as NestedItem<T>)" :index="index" />
188
+ <slot name="item-trailing" :item="item" :index="index" />
305
189
 
306
190
  <SelectItemIndicator as-child>
307
191
  <UIcon :name="selectedIcon || appConfig.ui.icons.check" :class="ui.itemTrailingIcon({ class: props.ui?.itemTrailingIcon })" />
@@ -313,6 +197,8 @@ function isSelectItem(item: SelectItem): item is SelectItemBase {
313
197
  </SelectGroup>
314
198
  </SelectViewport>
315
199
 
200
+ <slot name="content-bottom" />
201
+
316
202
  <SelectArrow v-if="!!arrow" v-bind="arrowProps" :class="ui.arrow({ class: props.ui?.arrow })" />
317
203
  </SelectContent>
318
204
  </SelectPortal>
@@ -0,0 +1,145 @@
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<Pick<Partial<{}> & Omit<{
129
+ readonly onBlur?: ((payload: FocusEvent) => any) | undefined;
130
+ readonly onChange?: ((payload: Event) => any) | undefined;
131
+ readonly onFocus?: ((payload: FocusEvent) => any) | undefined;
132
+ readonly "onUpdate:open"?: ((value: boolean) => any) | undefined;
133
+ readonly "onUpdate:modelValue"?: ((payload: GetModelValue<T, VK, M>) => any) | undefined;
134
+ } & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onFocus" | "onBlur" | "onChange" | "onUpdate:open" | "onUpdate:modelValue"> & SelectProps<T, VK, M> & Partial<{}>> & import("vue").PublicProps;
135
+ expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
136
+ attrs: any;
137
+ slots: SelectSlots<T, VK, M, NestedItem<T>>;
138
+ 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);
139
+ }>) => import("vue").VNode & {
140
+ __ctx?: Awaited<typeof __VLS_setup>;
141
+ };
142
+ export default _default;
143
+ type __VLS_PrettifyLocal<T> = {
144
+ [K in keyof T]: T[K];
145
+ } & {};