@nuxt/ui 3.0.0-alpha.6 → 3.0.0-alpha.8

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 (257) hide show
  1. package/.nuxt/ui/accordion.ts +20 -0
  2. package/.nuxt/ui/alert.ts +242 -0
  3. package/.nuxt/ui/avatar-group.ts +40 -0
  4. package/.nuxt/ui/avatar.ts +42 -0
  5. package/.nuxt/ui/badge.ts +194 -0
  6. package/.nuxt/ui/breadcrumb.ts +45 -0
  7. package/.nuxt/ui/button-group.ts +16 -0
  8. package/.nuxt/ui/button.ts +344 -0
  9. package/.nuxt/ui/card.ts +8 -0
  10. package/.nuxt/ui/carousel.ts +41 -0
  11. package/.nuxt/ui/checkbox.ts +105 -0
  12. package/.nuxt/ui/chip.ts +67 -0
  13. package/.nuxt/ui/collapsible.ts +6 -0
  14. package/.nuxt/ui/command-palette.ts +40 -0
  15. package/.nuxt/ui/container.ts +3 -0
  16. package/.nuxt/ui/context-menu.ts +198 -0
  17. package/.nuxt/ui/drawer.ts +55 -0
  18. package/.nuxt/ui/dropdown-menu.ts +199 -0
  19. package/.nuxt/ui/form-field.ts +40 -0
  20. package/.nuxt/ui/form.ts +3 -0
  21. package/.nuxt/ui/index.ts +43 -0
  22. package/.nuxt/ui/input-menu.ts +411 -0
  23. package/.nuxt/ui/input.ts +263 -0
  24. package/.nuxt/ui/kbd.ts +19 -0
  25. package/.nuxt/ui/link.ts +15 -0
  26. package/.nuxt/ui/modal.ts +28 -0
  27. package/.nuxt/ui/navigation-menu.ts +390 -0
  28. package/.nuxt/ui/pagination.ts +8 -0
  29. package/.nuxt/ui/popover.ts +6 -0
  30. package/.nuxt/ui/progress.ts +258 -0
  31. package/.nuxt/ui/radio-group.ts +112 -0
  32. package/.nuxt/ui/select-menu.ts +321 -0
  33. package/.nuxt/ui/select.ts +314 -0
  34. package/.nuxt/ui/separator.ts +143 -0
  35. package/.nuxt/ui/skeleton.ts +3 -0
  36. package/.nuxt/ui/slideover.ts +63 -0
  37. package/.nuxt/ui/slider.ts +148 -0
  38. package/.nuxt/ui/switch.ts +113 -0
  39. package/.nuxt/ui/table.ts +128 -0
  40. package/.nuxt/ui/tabs.ts +227 -0
  41. package/.nuxt/ui/textarea.ts +263 -0
  42. package/.nuxt/ui/toast.ts +66 -0
  43. package/.nuxt/ui/toaster.ts +75 -0
  44. package/.nuxt/ui/tooltip.ts +9 -0
  45. package/cli/templates.mjs +1 -1
  46. package/dist/chunks/component-meta.cjs +73264 -0
  47. package/dist/chunks/component-meta.mjs +73262 -0
  48. package/dist/client/devtools/200.html +1 -0
  49. package/dist/client/devtools/404.html +1 -0
  50. package/dist/client/devtools/_fonts/rP2Wp2ywxg089UriCZaSExd86J3t9jz86MvyyKK58UfivUw4aw-SK92LTmKP0.woff2 +0 -0
  51. package/dist/client/devtools/_fonts/rP2Wp2ywxg089UriCZaSExd86J3t9jz86MvyyKy58UfivUw-9uYm8d48E4.woff2 +0 -0
  52. package/dist/client/devtools/_fonts/rP2Yp2ywxg089UriI5-g4vlH9VoD8Cmcqbu0-K6z9mXg-VNw7NHvqnp.woff2 +0 -0
  53. package/dist/client/devtools/_fonts/rP2Yp2ywxg089UriI5-g4vlH9VoD8Cmcqbu6-K6z9mXgjU0-EkYdMs3MAX.woff2 +0 -0
  54. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat-7DW3w-R7n06NbhGy.woff +0 -0
  55. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat-JDG3w-leGNfkTmsj.woff +0 -0
  56. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat-JDW3w-ciElMF03ku.woff +0 -0
  57. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat8JCm3w-sB722Uoa0f.woff +0 -0
  58. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat8JDW3w-PBDI1JDjwV.woff +0 -0
  59. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat8gCm3w-0q1hqVn09O.woff +0 -0
  60. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat9XCm3w-ByvzuLy2fa.woff +0 -0
  61. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat9uCm3w-5TKCIs6EEw.woff +0 -0
  62. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat_XDW3w-r2swRDGfn2.woff +0 -0
  63. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAC5thTQ-ldB60l5U8r.woff +0 -0
  64. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAIpthTQ-wbFKGFDrgo.woff +0 -0
  65. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAIpxhTQ-LLUBv5jskj.woff +0 -0
  66. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwARZthTQ-F71RdTRbNg.woff +0 -0
  67. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwA_JxhTQ-6nh65gZkc0.woff +0 -0
  68. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAfJthTQ-aMoWEJLmTt.woff +0 -0
  69. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAkJxhTQ-WMBvmLOgKm.woff +0 -0
  70. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAop1hTQ-utGC2hnWq2.woff +0 -0
  71. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAopxhTQ-YpyTieVa5B.woff +0 -0
  72. package/dist/client/devtools/_nuxt/Bj9hdafK.js +1 -0
  73. package/dist/client/devtools/_nuxt/DM3_wAgz.js +62 -0
  74. package/dist/client/devtools/_nuxt/builds/latest.json +1 -0
  75. package/dist/client/devtools/_nuxt/builds/meta/e6b425f7-b919-4014-915b-0ea07c316790.json +1 -0
  76. package/dist/client/devtools/_nuxt/entry.DaJP-ZMB.css +24 -0
  77. package/dist/client/devtools/_nuxt/error-404.B0Nmv3fV.css +1 -0
  78. package/dist/client/devtools/_nuxt/error-500.C8fgTxVz.css +1 -0
  79. package/dist/client/devtools/_nuxt/hKiujHsR.js +1 -0
  80. package/dist/client/devtools/favicon.svg +1 -0
  81. package/dist/client/devtools/index.html +1 -0
  82. package/dist/devtools/runtime/DevtoolsRenderer.vue +53 -0
  83. package/dist/devtools/runtime/examples/AvatarGroupExample.vue +7 -0
  84. package/dist/devtools/runtime/examples/ButtonGroupExample.vue +8 -0
  85. package/dist/devtools/runtime/examples/CardExample.vue +13 -0
  86. package/dist/devtools/runtime/examples/CarouselExample.vue +13 -0
  87. package/dist/devtools/runtime/examples/ChipExample.vue +5 -0
  88. package/dist/devtools/runtime/examples/CollapsibleExample.vue +8 -0
  89. package/dist/devtools/runtime/examples/CommandPaletteExample.vue +29 -0
  90. package/dist/devtools/runtime/examples/ContainerExample.vue +5 -0
  91. package/dist/devtools/runtime/examples/ContextMenuExample.vue +5 -0
  92. package/dist/devtools/runtime/examples/DrawerExample.vue +8 -0
  93. package/dist/devtools/runtime/examples/DropdownMenuExample.vue +5 -0
  94. package/dist/devtools/runtime/examples/FormExample.vue +30 -0
  95. package/dist/devtools/runtime/examples/FormFieldExample.vue +5 -0
  96. package/dist/devtools/runtime/examples/LinkExample.vue +5 -0
  97. package/dist/devtools/runtime/examples/ModalExample.vue +8 -0
  98. package/dist/devtools/runtime/examples/PopoverExample.vue +8 -0
  99. package/dist/devtools/runtime/examples/SkeletonExample.vue +3 -0
  100. package/dist/devtools/runtime/examples/SlideoverExample.vue +8 -0
  101. package/dist/devtools/runtime/examples/ToasterExample.vue +11 -0
  102. package/dist/devtools/runtime/examples/TooltipExample.vue +5 -0
  103. package/dist/module.cjs +222 -4
  104. package/dist/module.d.cts +54 -0
  105. package/dist/module.d.mts +16 -6
  106. package/dist/module.d.ts +16 -6
  107. package/dist/module.json +1 -1
  108. package/dist/module.mjs +157 -2629
  109. package/dist/runtime/components/Accordion.vue +45 -6
  110. package/dist/runtime/components/Alert.vue +4 -0
  111. package/dist/runtime/components/App.vue +8 -0
  112. package/dist/runtime/components/Avatar.vue +23 -5
  113. package/dist/runtime/components/AvatarGroup.vue +3 -0
  114. package/dist/runtime/components/Badge.vue +33 -3
  115. package/dist/runtime/components/Breadcrumb.vue +39 -7
  116. package/dist/runtime/components/Button.vue +10 -3
  117. package/dist/runtime/components/ButtonGroup.vue +4 -1
  118. package/dist/runtime/components/Card.vue +3 -0
  119. package/dist/runtime/components/Carousel.vue +13 -8
  120. package/dist/runtime/components/Checkbox.vue +7 -6
  121. package/dist/runtime/components/Chip.vue +9 -2
  122. package/dist/runtime/components/Collapsible.vue +3 -0
  123. package/dist/runtime/components/CommandPalette.vue +28 -17
  124. package/dist/runtime/components/Container.vue +3 -0
  125. package/dist/runtime/components/ContextMenu.vue +95 -10
  126. package/dist/runtime/components/ContextMenuContent.vue +41 -13
  127. package/dist/runtime/components/Drawer.vue +3 -0
  128. package/dist/runtime/components/DropdownMenu.vue +83 -10
  129. package/dist/runtime/components/DropdownMenuContent.vue +43 -13
  130. package/dist/runtime/components/Form.vue +6 -1
  131. package/dist/runtime/components/FormField.vue +3 -0
  132. package/dist/runtime/components/Input.vue +7 -4
  133. package/dist/runtime/components/InputMenu.vue +61 -34
  134. package/dist/runtime/components/Kbd.vue +2 -0
  135. package/dist/runtime/components/Link.vue +50 -1
  136. package/dist/runtime/components/LinkBase.vue +4 -2
  137. package/dist/runtime/components/Modal.vue +3 -0
  138. package/dist/runtime/components/NavigationMenu.vue +159 -75
  139. package/dist/runtime/components/Pagination.vue +5 -1
  140. package/dist/runtime/components/Popover.vue +3 -0
  141. package/dist/runtime/components/Progress.vue +1 -1
  142. package/dist/runtime/components/RadioGroup.vue +26 -4
  143. package/dist/runtime/components/Select.vue +44 -21
  144. package/dist/runtime/components/SelectMenu.vue +67 -43
  145. package/dist/runtime/components/Separator.vue +1 -1
  146. package/dist/runtime/components/Skeleton.vue +3 -0
  147. package/dist/runtime/components/Slideover.vue +3 -0
  148. package/dist/runtime/components/Slider.vue +1 -1
  149. package/dist/runtime/components/Switch.vue +5 -1
  150. package/dist/runtime/components/Table.vue +241 -0
  151. package/dist/runtime/components/Tabs.vue +35 -8
  152. package/dist/runtime/components/Toast.vue +4 -0
  153. package/dist/runtime/components/Toaster.vue +8 -1
  154. package/dist/runtime/components/Tooltip.vue +3 -0
  155. package/dist/runtime/composables/defineShortcuts.js +1 -7
  156. package/dist/runtime/composables/extendDevtoolsMeta.d.ts +7 -0
  157. package/dist/runtime/composables/extendDevtoolsMeta.js +2 -0
  158. package/dist/runtime/composables/useComponentIcons.d.ts +3 -0
  159. package/dist/runtime/composables/useKbd.d.ts +10 -3
  160. package/dist/runtime/composables/useKbd.js +14 -8
  161. package/dist/runtime/composables/useModal.d.ts +1 -1
  162. package/dist/runtime/composables/useSlideover.d.ts +1 -1
  163. package/dist/runtime/index.css +1 -1
  164. package/dist/runtime/keyframes.css +1 -0
  165. package/dist/runtime/types/form.d.ts +2 -1
  166. package/dist/runtime/types/index.d.ts +1 -0
  167. package/dist/runtime/types/index.js +1 -0
  168. package/dist/runtime/types/utils.d.ts +7 -0
  169. package/dist/runtime/utils/form.d.ts +3 -0
  170. package/dist/runtime/utils/form.js +14 -0
  171. package/dist/runtime/utils/index.d.ts +1 -0
  172. package/dist/runtime/utils/index.js +3 -0
  173. package/dist/runtime/utils/link.d.ts +1 -1
  174. package/dist/runtime/vue/components/Icon.vue +15 -0
  175. package/dist/runtime/vue/components/Link.vue +195 -0
  176. package/dist/runtime/vue/plugins/color-mode.d.ts +4 -0
  177. package/dist/runtime/vue/plugins/color-mode.js +6 -0
  178. package/dist/runtime/vue/plugins/head.d.ts +4 -0
  179. package/dist/runtime/vue/plugins/head.js +6 -0
  180. package/dist/runtime/vue/stubs.d.ts +15 -0
  181. package/dist/runtime/vue/stubs.js +27 -0
  182. package/dist/shared/ui.BU7wzH0D.cjs +2872 -0
  183. package/dist/shared/ui.BufKhDiD.mjs +2865 -0
  184. package/dist/unplugin.cjs +192 -0
  185. package/dist/unplugin.d.cts +47 -0
  186. package/dist/unplugin.d.mts +47 -0
  187. package/dist/unplugin.d.ts +47 -0
  188. package/dist/unplugin.mjs +181 -0
  189. package/dist/vite.cjs +22 -0
  190. package/dist/vite.d.cts +13 -0
  191. package/dist/vite.d.mts +13 -0
  192. package/dist/vite.d.ts +13 -0
  193. package/dist/vite.mjs +20 -0
  194. package/package.json +73 -32
  195. package/vue-plugin.d.ts +5 -0
  196. package/cli/node_modules/.ignored/citty/LICENSE +0 -36
  197. package/cli/node_modules/.ignored/citty/README.md +0 -134
  198. package/cli/node_modules/.ignored/citty/dist/index.cjs +0 -475
  199. package/cli/node_modules/.ignored/citty/dist/index.d.cts +0 -80
  200. package/cli/node_modules/.ignored/citty/dist/index.d.mts +0 -80
  201. package/cli/node_modules/.ignored/citty/dist/index.d.ts +0 -80
  202. package/cli/node_modules/.ignored/citty/dist/index.mjs +0 -463
  203. package/cli/node_modules/.ignored/citty/package.json +0 -49
  204. package/cli/node_modules/.ignored/consola/LICENSE +0 -47
  205. package/cli/node_modules/.ignored/consola/README.md +0 -318
  206. package/cli/node_modules/.ignored/consola/core.d.ts +0 -1
  207. package/cli/node_modules/.ignored/consola/dist/basic.cjs +0 -32
  208. package/cli/node_modules/.ignored/consola/dist/basic.d.ts +0 -9
  209. package/cli/node_modules/.ignored/consola/dist/basic.mjs +0 -24
  210. package/cli/node_modules/.ignored/consola/dist/browser.cjs +0 -80
  211. package/cli/node_modules/.ignored/consola/dist/browser.d.ts +0 -7
  212. package/cli/node_modules/.ignored/consola/dist/browser.mjs +0 -72
  213. package/cli/node_modules/.ignored/consola/dist/chunks/prompt.cjs +0 -436
  214. package/cli/node_modules/.ignored/consola/dist/chunks/prompt.mjs +0 -429
  215. package/cli/node_modules/.ignored/consola/dist/core.cjs +0 -415
  216. package/cli/node_modules/.ignored/consola/dist/core.d.ts +0 -124
  217. package/cli/node_modules/.ignored/consola/dist/core.mjs +0 -410
  218. package/cli/node_modules/.ignored/consola/dist/index.cjs +0 -21
  219. package/cli/node_modules/.ignored/consola/dist/index.d.ts +0 -9
  220. package/cli/node_modules/.ignored/consola/dist/index.mjs +0 -8
  221. package/cli/node_modules/.ignored/consola/dist/shared/consola.06ad8a64.mjs +0 -62
  222. package/cli/node_modules/.ignored/consola/dist/shared/consola.36c0034f.mjs +0 -636
  223. package/cli/node_modules/.ignored/consola/dist/shared/consola.4bbae468.cjs +0 -645
  224. package/cli/node_modules/.ignored/consola/dist/shared/consola.deac7d5a.cjs +0 -65
  225. package/cli/node_modules/.ignored/consola/dist/utils.cjs +0 -308
  226. package/cli/node_modules/.ignored/consola/dist/utils.d.ts +0 -169
  227. package/cli/node_modules/.ignored/consola/dist/utils.mjs +0 -284
  228. package/cli/node_modules/.ignored/consola/lib/index.cjs +0 -9
  229. package/cli/node_modules/.ignored/consola/package.json +0 -101
  230. package/cli/node_modules/.ignored/consola/utils.d.ts +0 -1
  231. package/cli/node_modules/.ignored/pathe/LICENSE +0 -44
  232. package/cli/node_modules/.ignored/pathe/README.md +0 -69
  233. package/cli/node_modules/.ignored/pathe/dist/index.cjs +0 -23
  234. package/cli/node_modules/.ignored/pathe/dist/index.d.cts +0 -36
  235. package/cli/node_modules/.ignored/pathe/dist/index.d.mts +0 -36
  236. package/cli/node_modules/.ignored/pathe/dist/index.d.ts +0 -36
  237. package/cli/node_modules/.ignored/pathe/dist/index.mjs +0 -1
  238. package/cli/node_modules/.ignored/pathe/dist/shared/pathe.1f0a373c.cjs +0 -238
  239. package/cli/node_modules/.ignored/pathe/dist/shared/pathe.ff20891b.mjs +0 -221
  240. package/cli/node_modules/.ignored/pathe/dist/utils.cjs +0 -58
  241. package/cli/node_modules/.ignored/pathe/dist/utils.d.cts +0 -5
  242. package/cli/node_modules/.ignored/pathe/dist/utils.d.mts +0 -5
  243. package/cli/node_modules/.ignored/pathe/dist/utils.d.ts +0 -5
  244. package/cli/node_modules/.ignored/pathe/dist/utils.mjs +0 -54
  245. package/cli/node_modules/.ignored/pathe/package.json +0 -48
  246. package/cli/node_modules/.ignored/pathe/utils.d.ts +0 -1
  247. package/cli/node_modules/.ignored/scule/LICENSE +0 -21
  248. package/cli/node_modules/.ignored/scule/README.md +0 -149
  249. package/cli/node_modules/.ignored/scule/dist/index.cjs +0 -92
  250. package/cli/node_modules/.ignored/scule/dist/index.d.cts +0 -57
  251. package/cli/node_modules/.ignored/scule/dist/index.d.mts +0 -57
  252. package/cli/node_modules/.ignored/scule/dist/index.d.ts +0 -57
  253. package/cli/node_modules/.ignored/scule/dist/index.mjs +0 -80
  254. package/cli/node_modules/.ignored/scule/package.json +0 -43
  255. package/cli/node_modules/.package-lock.json +0 -33
  256. package/dist/runtime/types/component.d.ts +0 -17
  257. package/dist/runtime/types/component.js +0 -0
@@ -1,18 +1,19 @@
1
1
  <script lang="ts">
2
2
  import { tv, type VariantProps } from 'tailwind-variants'
3
- import type { SelectRootProps, SelectRootEmits, SelectContentProps, SelectArrowProps, SelectItemProps } from 'radix-vue'
3
+ import type { SelectRootProps, SelectRootEmits, SelectContentProps, SelectArrowProps } from 'radix-vue'
4
4
  import type { AppConfig } from '@nuxt/schema'
5
5
  import _appConfig from '#build/app.config'
6
6
  import theme from '#build/ui/select'
7
7
  import type { UseComponentIconsProps } from '../composables/useComponentIcons'
8
+ import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
8
9
  import type { AvatarProps, ChipProps, InputProps } from '../types'
9
- import type { AcceptableValue, PartialString } from '../types/utils'
10
+ import type { AcceptableValue, PartialString, MaybeArrayOfArray, MaybeArrayOfArrayItem, SelectModelValue, SelectModelValueEmits, SelectItemKey } from '../types/utils'
10
11
 
11
12
  const appConfig = _appConfig as AppConfig & { ui: { select: Partial<typeof theme> } }
12
13
 
13
14
  const select = tv({ extend: tv(theme), ...(appConfig.ui?.select || {}) })
14
15
 
15
- export interface SelectItem extends Pick<SelectItemProps, 'disabled' | 'value'> {
16
+ export interface SelectItem {
16
17
  label?: string
17
18
  icon?: string
18
19
  avatar?: AvatarProps
@@ -22,11 +23,13 @@ export interface SelectItem extends Pick<SelectItemProps, 'disabled' | 'value'>
22
23
  * @defaultValue 'item'
23
24
  */
24
25
  type?: 'label' | 'separator' | 'item'
26
+ value?: string
27
+ disabled?: boolean
25
28
  }
26
29
 
27
30
  type SelectVariants = VariantProps<typeof select>
28
31
 
29
- export interface SelectProps<T> extends Omit<SelectRootProps, 'dir'>, UseComponentIconsProps {
32
+ export interface SelectProps<T extends MaybeArrayOfArrayItem<I>, I extends MaybeArrayOfArray<SelectItem | AcceptableValue> = MaybeArrayOfArray<SelectItem | AcceptableValue>, V extends SelectItemKey<T> | undefined = undefined> extends Omit<SelectRootProps, 'dir' | 'modelValue'>, UseComponentIconsProps {
30
33
  id?: string
31
34
  /** The placeholder text when the select is empty. */
32
35
  placeholder?: string
@@ -62,19 +65,26 @@ export interface SelectProps<T> extends Omit<SelectRootProps, 'dir'>, UseCompone
62
65
  * When `items` is an array of objects, select the field to use as the value.
63
66
  * @defaultValue 'value'
64
67
  */
65
- valueKey?: string
66
- items?: T[] | T[][]
68
+ valueKey?: V
69
+ /**
70
+ * When `items` is an array of objects, select the field to use as the label.
71
+ * @defaultValue 'label'
72
+ */
73
+ labelKey?: SelectItemKey<T>
74
+ items?: I
67
75
  /** Highlight the ring color like a focus state. */
68
76
  highlight?: boolean
69
77
  class?: any
70
78
  ui?: PartialString<typeof select.slots>
79
+ /** The controlled value of the Select. Can be bind as `v-model`. */
80
+ modelValue?: SelectModelValue<T, V, false, T extends { value: infer U } ? U : never>
71
81
  }
72
82
 
73
- export type SelectEmits = SelectRootEmits & {
83
+ export type SelectEmits<T, V> = Omit<SelectRootEmits, 'update:modelValue'> & {
74
84
  change: [payload: Event]
75
85
  blur: [payload: FocusEvent]
76
86
  focus: [payload: FocusEvent]
77
- }
87
+ } & SelectModelValueEmits<T, V, false, T extends { value: infer U } ? U : never>
78
88
 
79
89
  type SlotProps<T> = (props: { item: T, index: number }) => any
80
90
 
@@ -86,31 +96,36 @@ export interface SelectSlots<T> {
86
96
  'item-label': SlotProps<T>
87
97
  'item-trailing': SlotProps<T>
88
98
  }
99
+
100
+ extendDevtoolsMeta({ defaultProps: { items: ['Option 1', 'Option 2', 'Option 3'] } })
89
101
  </script>
90
102
 
91
- <script setup lang="ts" generic="T extends SelectItem | AcceptableValue">
103
+ <script setup lang="ts" generic="T extends MaybeArrayOfArrayItem<I>, I extends MaybeArrayOfArray<SelectItem | AcceptableValue> = MaybeArrayOfArray<SelectItem | AcceptableValue>, V extends SelectItemKey<T> | undefined = undefined">
92
104
  import { computed, toRef } from 'vue'
93
- import { SelectRoot, SelectTrigger, SelectValue, SelectPortal, SelectContent, SelectViewport, SelectLabel, SelectGroup, SelectItem, SelectItemIndicator, SelectItemText, SelectSeparator, useForwardPropsEmits } from 'radix-vue'
105
+ import { SelectRoot, SelectArrow, SelectTrigger, SelectValue, SelectPortal, SelectContent, SelectViewport, SelectLabel, SelectGroup, SelectItem, SelectItemIndicator, SelectItemText, SelectSeparator, useForwardPropsEmits } from 'radix-vue'
94
106
  import { defu } from 'defu'
95
107
  import { reactivePick } from '@vueuse/core'
96
108
  import { useAppConfig } from '#imports'
97
109
  import { useButtonGroup } from '../composables/useButtonGroup'
98
110
  import { useComponentIcons } from '../composables/useComponentIcons'
99
111
  import { useFormField } from '../composables/useFormField'
112
+ import { get } from '../utils'
100
113
  import UIcon from './Icon.vue'
101
114
  import UAvatar from './Avatar.vue'
102
115
  import UChip from './Chip.vue'
103
116
 
104
- const props = withDefaults(defineProps<SelectProps<T>>(), {
105
- valueKey: 'value',
117
+ const props = withDefaults(defineProps<SelectProps<T, I, V>>(), {
118
+ valueKey: 'value' as never,
119
+ labelKey: 'label' as never,
106
120
  portal: true
107
121
  })
108
- const emits = defineEmits<SelectEmits>()
122
+ const emits = defineEmits<SelectEmits<T, V>>()
109
123
  const slots = defineSlots<SelectSlots<T>>()
110
124
 
111
125
  const appConfig = useAppConfig()
112
126
  const rootProps = useForwardPropsEmits(reactivePick(props, 'modelValue', 'defaultValue', 'open', 'defaultOpen', 'disabled', 'autocomplete', 'required'), emits)
113
127
  const contentProps = toRef(() => defu(props.content, { side: 'bottom', sideOffset: 8, position: 'popper' }) as SelectContentProps)
128
+ const arrowProps = toRef(() => props.arrow as SelectArrowProps)
114
129
 
115
130
  const { emitFormChange, emitFormInput, emitFormBlur, size: formGroupSize, color, id, name, highlight, disabled } = useFormField<InputProps>(props)
116
131
  const { orientation, size: buttonGroupSize } = useButtonGroup<InputProps>(props)
@@ -124,7 +139,7 @@ const ui = computed(() => select({
124
139
  size: selectSize?.value,
125
140
  loading: props.loading,
126
141
  highlight: highlight.value,
127
- leading: isLeading.value || !!slots.leading,
142
+ leading: isLeading.value || !!props.avatar || !!slots.leading,
128
143
  trailing: isTrailing.value || !!slots.trailing,
129
144
  buttonGroup: orientation.value
130
145
  }))
@@ -157,14 +172,18 @@ function onUpdateOpen(value: boolean) {
157
172
  v-slot="{ modelValue, open }"
158
173
  v-bind="rootProps"
159
174
  :name="name"
175
+ :default-value="(defaultValue as string)"
176
+ :model-value="(modelValue as string)"
177
+ :autocomplete="autocomplete"
160
178
  :disabled="disabled"
161
179
  @update:model-value="onUpdate"
162
180
  @update:open="onUpdateOpen"
163
181
  >
164
182
  <SelectTrigger :class="ui.base({ class: [props.class, props.ui?.base] })">
165
- <span v-if="isLeading || !!slots.leading" :class="ui.leading({ class: props.ui?.leading })">
183
+ <span v-if="isLeading || !!avatar || !!slots.leading" :class="ui.leading({ class: props.ui?.leading })">
166
184
  <slot name="leading" :model-value="modelValue" :open="open" :ui="ui">
167
- <UIcon v-if="leadingIconName" :name="leadingIconName" :class="ui.leadingIcon({ class: props.ui?.leadingIcon })" />
185
+ <UIcon v-if="isLeading && leadingIconName" :name="leadingIconName" :class="ui.leadingIcon({ class: props.ui?.leadingIcon })" />
186
+ <UAvatar v-else-if="!!avatar" :size="((props.ui?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar })" />
168
187
  </slot>
169
188
  </span>
170
189
 
@@ -183,19 +202,21 @@ function onUpdateOpen(value: boolean) {
183
202
  <SelectGroup v-for="(group, groupIndex) in groups" :key="`group-${groupIndex}`" :class="ui.group({ class: props.ui?.group })">
184
203
  <template v-for="(item, index) in group" :key="`group-${groupIndex}-${index}`">
185
204
  <SelectLabel v-if="item?.type === 'label'" :class="ui.label({ class: props.ui?.label })">
186
- {{ item.label }}
205
+ {{ get(item, props.labelKey as string) }}
187
206
  </SelectLabel>
207
+
188
208
  <SelectSeparator v-else-if="item?.type === 'separator'" :class="ui.separator({ class: props.ui?.separator })" />
209
+
189
210
  <SelectItem
190
211
  v-else
191
212
  :class="ui.item({ class: props.ui?.item })"
192
213
  :disabled="item.disabled"
193
- :value="typeof item === 'object' ? (item[valueKey as keyof SelectItem] as string) : item"
214
+ :value="typeof item === 'object' ? get(item, props.valueKey as string) : item"
194
215
  >
195
216
  <slot name="item" :item="(item as T)" :index="index">
196
217
  <slot name="item-leading" :item="(item as T)" :index="index">
197
- <UAvatar v-if="item.avatar" :size="((props.ui?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="item.avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar })" />
198
- <UIcon v-else-if="item.icon" :name="item.icon" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon })" />
218
+ <UIcon v-if="item.icon" :name="item.icon" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon })" />
219
+ <UAvatar v-else-if="item.avatar" :size="((props.ui?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="item.avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar })" />
199
220
  <UChip
200
221
  v-else-if="item.chip"
201
222
  :size="((props.ui?.itemLeadingChipSize || ui.itemLeadingChipSize()) as ChipProps['size'])"
@@ -208,7 +229,7 @@ function onUpdateOpen(value: boolean) {
208
229
 
209
230
  <SelectItemText :class="ui.itemLabel({ class: props.ui?.itemLabel })">
210
231
  <slot name="item-label" :item="(item as T)" :index="index">
211
- {{ typeof item === 'object' ? item.label : item }}
232
+ {{ typeof item === 'object' ? get(item, props.labelKey as string) : item }}
212
233
  </slot>
213
234
  </SelectItemText>
214
235
 
@@ -224,6 +245,8 @@ function onUpdateOpen(value: boolean) {
224
245
  </template>
225
246
  </SelectGroup>
226
247
  </SelectViewport>
248
+
249
+ <SelectArrow v-if="!!arrow" v-bind="arrowProps" :class="ui.arrow({ class: props.ui?.arrow })" />
227
250
  </SelectContent>
228
251
  </SelectPortal>
229
252
  </SelectRoot>
@@ -1,18 +1,19 @@
1
1
  <script lang="ts">
2
2
  import { tv, type VariantProps } from 'tailwind-variants'
3
- import type { ComboboxRootProps, ComboboxRootEmits, ComboboxContentProps, ComboboxItemProps, ComboboxArrowProps } from 'radix-vue'
3
+ import type { ComboboxRootProps, ComboboxRootEmits, ComboboxContentProps, ComboboxArrowProps } from 'radix-vue'
4
4
  import type { AppConfig } from '@nuxt/schema'
5
5
  import _appConfig from '#build/app.config'
6
6
  import theme from '#build/ui/select-menu'
7
7
  import type { UseComponentIconsProps } from '../composables/useComponentIcons'
8
+ import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
8
9
  import type { AvatarProps, ChipProps, InputProps } from '../types'
9
- import type { AcceptableValue, ArrayOrWrapped, PartialString } from '../types/utils'
10
+ import type { AcceptableValue, ArrayOrWrapped, PartialString, MaybeArrayOfArray, MaybeArrayOfArrayItem, SelectModelValue, SelectModelValueEmits, SelectItemKey } from '../types/utils'
10
11
 
11
12
  const appConfig = _appConfig as AppConfig & { ui: { selectMenu: Partial<typeof theme> } }
12
13
 
13
14
  const selectMenu = tv({ extend: tv(theme), ...(appConfig.ui?.selectMenu || {}) })
14
15
 
15
- export interface SelectMenuItem extends Pick<ComboboxItemProps, 'disabled'> {
16
+ export interface SelectMenuItem {
16
17
  label?: string
17
18
  icon?: string
18
19
  avatar?: AvatarProps
@@ -22,12 +23,13 @@ export interface SelectMenuItem extends Pick<ComboboxItemProps, 'disabled'> {
22
23
  * @defaultValue 'item'
23
24
  */
24
25
  type?: 'label' | 'separator' | 'item'
25
- select?(e?: Event): void
26
+ disabled?: boolean
27
+ onSelect?(e?: Event): void
26
28
  }
27
29
 
28
30
  type SelectMenuVariants = VariantProps<typeof selectMenu>
29
31
 
30
- export interface SelectMenuProps<T> extends Pick<ComboboxRootProps<T>, 'modelValue' | 'defaultValue' | 'selectedValue' | 'open' | 'defaultOpen' | 'searchTerm' | 'multiple' | 'disabled' | 'name' | 'resetSearchTermOnBlur'>, UseComponentIconsProps {
32
+ export interface SelectMenuProps<T extends MaybeArrayOfArrayItem<I>, I extends MaybeArrayOfArray<SelectMenuItem | AcceptableValue> = MaybeArrayOfArray<SelectMenuItem | AcceptableValue>, V extends SelectItemKey<T> | undefined = undefined, M extends boolean = false> extends Pick<ComboboxRootProps<T>, 'defaultValue' | 'selectedValue' | 'open' | 'defaultOpen' | 'searchTerm' | 'disabled' | 'name' | 'resetSearchTermOnBlur'>, UseComponentIconsProps {
31
33
  id?: string
32
34
  /** The placeholder text when the select is empty. */
33
35
  placeholder?: string
@@ -76,19 +78,28 @@ export interface SelectMenuProps<T> extends Pick<ComboboxRootProps<T>, 'modelVal
76
78
  * When `items` is an array of objects, select the field to use as the value instead of the object itself.
77
79
  * @defaultValue undefined
78
80
  */
79
- valueKey?: keyof T
80
- items?: T[] | T[][]
81
+ valueKey?: V
82
+ /**
83
+ * When `items` is an array of objects, select the field to use as the label.
84
+ * @defaultValue 'label'
85
+ */
86
+ labelKey?: SelectItemKey<T>
87
+ items?: I
81
88
  /** Highlight the ring color like a focus state. */
82
89
  highlight?: boolean
83
90
  class?: any
84
91
  ui?: PartialString<typeof selectMenu.slots>
92
+ /** The controlled value of the Combobox. Can be binded-with with `v-model`. */
93
+ modelValue?: SelectModelValue<T, V, M>
94
+ /** Whether multiple options can be selected or not. */
95
+ multiple?: M
85
96
  }
86
97
 
87
- export type SelectMenuEmits<T> = ComboboxRootEmits<T> & {
98
+ export type SelectMenuEmits<T, V, M extends boolean> = Omit<ComboboxRootEmits<T>, 'update:modelValue'> & {
88
99
  change: [payload: Event]
89
100
  blur: [payload: FocusEvent]
90
101
  focus: [payload: FocusEvent]
91
- }
102
+ } & SelectModelValueEmits<T, V, M>
92
103
 
93
104
  type SlotProps<T> = (props: { item: T, index: number }) => any
94
105
 
@@ -102,30 +113,35 @@ export interface SelectMenuSlots<T> {
102
113
  'item-label': SlotProps<T>
103
114
  'item-trailing': SlotProps<T>
104
115
  }
116
+
117
+ extendDevtoolsMeta({ defaultProps: { items: ['Option 1', 'Option 2', 'Option 3'] } })
105
118
  </script>
106
119
 
107
- <script setup lang="ts" generic="T extends SelectMenuItem | AcceptableValue">
120
+ <script setup lang="ts" generic="T extends MaybeArrayOfArrayItem<I>, I extends MaybeArrayOfArray<SelectMenuItem | AcceptableValue> = MaybeArrayOfArray<SelectMenuItem | AcceptableValue>, V extends SelectItemKey<T> | undefined = undefined, M extends boolean = false">
108
121
  import { computed, toRef } from 'vue'
109
- import { ComboboxRoot, ComboboxAnchor, ComboboxInput, ComboboxTrigger, ComboboxPortal, ComboboxContent, ComboboxViewport, ComboboxEmpty, ComboboxGroup, ComboboxLabel, ComboboxSeparator, ComboboxItem, ComboboxItemIndicator, useForwardPropsEmits } from 'radix-vue'
122
+ import { ComboboxRoot, ComboboxArrow, ComboboxAnchor, ComboboxInput, ComboboxTrigger, ComboboxPortal, ComboboxContent, ComboboxViewport, ComboboxEmpty, ComboboxGroup, ComboboxLabel, ComboboxSeparator, ComboboxItem, ComboboxItemIndicator, useForwardPropsEmits } from 'radix-vue'
110
123
  import { defu } from 'defu'
124
+ import * as isEqual from 'fast-deep-equal'
111
125
  import { reactivePick } from '@vueuse/core'
112
126
  import { useAppConfig } from '#imports'
113
127
  import { useButtonGroup } from '../composables/useButtonGroup'
114
128
  import { useComponentIcons } from '../composables/useComponentIcons'
115
129
  import { useFormField } from '../composables/useFormField'
130
+ import { get, escapeRegExp } from '../utils'
116
131
  import UIcon from './Icon.vue'
117
132
  import UAvatar from './Avatar.vue'
118
133
  import UChip from './Chip.vue'
119
- import { get } from '../utils'
120
134
 
121
- const props = withDefaults(defineProps<SelectMenuProps<T>>(), {
135
+ const props = withDefaults(defineProps<SelectMenuProps<T, I, V, M>>(), {
122
136
  search: true,
123
137
  portal: true,
124
138
  autofocusDelay: 0,
125
139
  searchInput: () => ({ placeholder: 'Search...' }),
126
- filter: () => ['label']
140
+ filter: () => ['label'],
141
+ labelKey: 'label' as never
127
142
  })
128
- const emits = defineEmits<SelectMenuEmits<T>>()
143
+
144
+ const emits = defineEmits<SelectMenuEmits<T, V, M>>()
129
145
  const slots = defineSlots<SelectMenuSlots<T>>()
130
146
 
131
147
  const searchTerm = defineModel<string>('searchTerm', { default: '' })
@@ -133,6 +149,8 @@ const searchTerm = defineModel<string>('searchTerm', { default: '' })
133
149
  const appConfig = useAppConfig()
134
150
  const rootProps = useForwardPropsEmits(reactivePick(props, 'modelValue', 'defaultValue', 'selectedValue', 'open', 'defaultOpen', 'multiple', 'resetSearchTermOnBlur'), emits)
135
151
  const contentProps = toRef(() => defu(props.content, { side: 'bottom', sideOffset: 8, position: 'popper' }) as ComboboxContentProps)
152
+ const arrowProps = toRef(() => props.arrow as ComboboxArrowProps)
153
+
136
154
  const { emitFormBlur, emitFormInput, emitFormChange, size: formGroupSize, color, id, name, highlight, disabled } = useFormField<InputProps>(props)
137
155
  const { orientation, size: buttonGroupSize } = useButtonGroup<InputProps>(props)
138
156
  const { isLeading, isTrailing, leadingIconName, trailingIconName } = useComponentIcons(toRef(() => defu(props, { trailingIcon: appConfig.ui.icons.chevronDown })))
@@ -145,44 +163,45 @@ const ui = computed(() => selectMenu({
145
163
  size: selectSize?.value,
146
164
  loading: props.loading,
147
165
  highlight: highlight.value,
148
- leading: isLeading.value || !!slots.leading,
166
+ leading: isLeading.value || !!props.avatar || !!slots.leading,
149
167
  trailing: isTrailing.value || !!slots.trailing,
150
168
  buttonGroup: orientation.value
151
169
  }))
152
170
 
153
- function displayValue(val: T, multiple?: boolean): string {
154
- if (multiple && Array.isArray(val)) {
155
- return val.map(v => displayValue(v)).join(', ')
171
+ function displayValue(value: T | T[]): string {
172
+ if (props.multiple && Array.isArray(value)) {
173
+ return value.map(v => displayValue(v)).join(', ')
156
174
  }
157
175
 
158
- if (typeof val === 'object') {
159
- return val.label
160
- }
176
+ const item = items.value.find(item => props.valueKey ? isEqual.default(get(item as Record<string, any>, props.valueKey as string), value) : isEqual.default(item, value))
161
177
 
162
- return val && String(val)
178
+ return item && (typeof item === 'object' ? get(item, props.labelKey as string) : item)
163
179
  }
164
180
 
165
- function filterFunction(items: ArrayOrWrapped<AcceptableValue>, searchTerm: string): ArrayOrWrapped<AcceptableValue> {
181
+ function filterFunction(items: ArrayOrWrapped<T>, searchTerm: string): ArrayOrWrapped<T> {
166
182
  if (props.filter === false) {
167
183
  return items
168
184
  }
169
185
 
170
- const fields = Array.isArray(props.filter) ? props.filter : ['label']
186
+ const fields = Array.isArray(props.filter) ? props.filter : [props.labelKey]
187
+ const escapedSearchTerm = escapeRegExp(searchTerm)
171
188
 
172
- return items.filter((item) => {
189
+ return items.filter((item: T) => {
173
190
  if (typeof item !== 'object') {
174
- return String(item).search(new RegExp(searchTerm, 'i')) !== -1
191
+ return String(item).search(new RegExp(escapedSearchTerm, 'i')) !== -1
175
192
  }
176
193
 
177
194
  return fields.some((field) => {
178
- const child = get(item, field)
195
+ const child = get(item, field as string)
179
196
 
180
- return child !== null && child !== undefined && String(child).search(new RegExp(searchTerm, 'i')) !== -1
197
+ return child !== null && child !== undefined && String(child).search(new RegExp(escapedSearchTerm, 'i')) !== -1
181
198
  })
182
199
  }) as ArrayOrWrapped<T>
183
200
  }
184
201
 
185
202
  const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0]) ? props.items : [props.items]) as SelectMenuItem[][] : [])
203
+ // eslint-disable-next-line vue/no-dupe-keys
204
+ const items = computed(() => groups.value.flatMap(group => group) as T[])
186
205
 
187
206
  function onUpdate(value: any) {
188
207
  // @ts-expect-error - 'target' does not exist in type 'EventInit'
@@ -220,19 +239,22 @@ function onUpdateOpen(value: boolean) {
220
239
  >
221
240
  <ComboboxAnchor as-child>
222
241
  <ComboboxTrigger :class="ui.base({ class: [props.class, props.ui?.base] })" tabindex="0">
223
- <span v-if="isLeading || !!slots.leading" :class="ui.leading({ class: props.ui?.leading })">
242
+ <span v-if="isLeading || !!avatar || !!slots.leading" :class="ui.leading({ class: props.ui?.leading })">
224
243
  <slot name="leading" :model-value="(modelValue as T)" :open="open" :ui="ui">
225
- <UIcon v-if="leadingIconName" :name="leadingIconName" :class="ui.leadingIcon({ class: props.ui?.leadingIcon })" />
244
+ <UIcon v-if="isLeading && leadingIconName" :name="leadingIconName" :class="ui.leadingIcon({ class: props.ui?.leadingIcon })" />
245
+ <UAvatar v-else-if="!!avatar" :size="((props.ui?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar })" />
226
246
  </slot>
227
247
  </span>
228
248
 
229
249
  <slot :model-value="(modelValue as T)" :open="open">
230
- <span v-if="multiple ? modelValue?.length : modelValue !== undefined" :class="ui.value({ class: props.ui?.value })">
231
- {{ displayValue(modelValue as T, multiple) }}
232
- </span>
233
- <span v-else :class="ui.placeholder({ class: props.ui?.placeholder })">
234
- {{ placeholder ?? '&nbsp;' }}
235
- </span>
250
+ <template v-for="displayedModelValue in [displayValue(modelValue)]" :key="displayedModelValue">
251
+ <span v-if="displayedModelValue" :class="ui.value({ class: props.ui?.value })">
252
+ {{ displayedModelValue }}
253
+ </span>
254
+ <span v-else :class="ui.placeholder({ class: props.ui?.placeholder })">
255
+ {{ placeholder ?? '&nbsp;' }}
256
+ </span>
257
+ </template>
236
258
  </slot>
237
259
 
238
260
  <span v-if="isTrailing || !!slots.trailing" :class="ui.trailing({ class: props.ui?.trailing })">
@@ -263,7 +285,7 @@ function onUpdateOpen(value: boolean) {
263
285
  <ComboboxGroup v-for="(group, groupIndex) in groups" :key="`group-${groupIndex}`" :class="ui.group({ class: props.ui?.group })">
264
286
  <template v-for="(item, index) in group" :key="`group-${groupIndex}-${index}`">
265
287
  <ComboboxLabel v-if="item?.type === 'label'" :class="ui.label({ class: props.ui?.label })">
266
- {{ item.label }}
288
+ {{ get(item, props.labelKey as string) }}
267
289
  </ComboboxLabel>
268
290
 
269
291
  <ComboboxSeparator v-else-if="item?.type === 'separator'" :class="ui.separator({ class: props.ui?.separator })" />
@@ -272,13 +294,13 @@ function onUpdateOpen(value: boolean) {
272
294
  v-else
273
295
  :class="ui.item({ class: props.ui?.item })"
274
296
  :disabled="item.disabled"
275
- :value="valueKey && typeof item === 'object' ? (item[valueKey as keyof SelectMenuItem]) as AcceptableValue : item"
276
- @select="item.select"
297
+ :value="valueKey && typeof item === 'object' ? get(item, props.valueKey as string) : item"
298
+ @select="item.onSelect"
277
299
  >
278
300
  <slot name="item" :item="(item as T)" :index="index">
279
301
  <slot name="item-leading" :item="(item as T)" :index="index">
280
- <UAvatar v-if="item.avatar" :size="((props.ui?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="item.avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar })" />
281
- <UIcon v-else-if="item.icon" :name="item.icon" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon })" />
302
+ <UIcon v-if="item.icon" :name="item.icon" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon })" />
303
+ <UAvatar v-else-if="item.avatar" :size="((props.ui?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="item.avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar })" />
282
304
  <UChip
283
305
  v-else-if="item.chip"
284
306
  :size="((props.ui?.itemLeadingChipSize || ui.itemLeadingChipSize()) as ChipProps['size'])"
@@ -291,7 +313,7 @@ function onUpdateOpen(value: boolean) {
291
313
 
292
314
  <span :class="ui.itemLabel({ class: props.ui?.itemLabel })">
293
315
  <slot name="item-label" :item="(item as T)" :index="index">
294
- {{ displayValue(item as T) }}
316
+ {{ typeof item === 'object' ? get(item, props.labelKey as string) : item }}
295
317
  </slot>
296
318
  </span>
297
319
 
@@ -307,6 +329,8 @@ function onUpdateOpen(value: boolean) {
307
329
  </template>
308
330
  </ComboboxGroup>
309
331
  </ComboboxViewport>
332
+
333
+ <ComboboxArrow v-if="!!arrow" v-bind="arrowProps" :class="ui.arrow({ class: props.ui?.arrow })" />
310
334
  </ComboboxContent>
311
335
  </ComboboxPortal>
312
336
  </ComboboxRoot>
@@ -15,7 +15,7 @@ type SeparatorVariants = VariantProps<typeof separator>
15
15
  export interface SeparatorProps extends Pick<_SeparatorProps, 'decorative'> {
16
16
  /**
17
17
  * The element or component this component should render as.
18
- * @defaultValue `div`
18
+ * @defaultValue 'div'
19
19
  */
20
20
  as?: any
21
21
  /** Display a label in the middle. */
@@ -3,6 +3,7 @@ import { tv } from 'tailwind-variants'
3
3
  import type { AppConfig } from '@nuxt/schema'
4
4
  import _appConfig from '#build/app.config'
5
5
  import theme from '#build/ui/skeleton'
6
+ import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
6
7
 
7
8
  const appConfig = _appConfig as AppConfig & { ui: { skeleton: Partial<typeof theme> } }
8
9
 
@@ -16,6 +17,8 @@ export interface SkeletonProps {
16
17
  as?: any
17
18
  class?: any
18
19
  }
20
+
21
+ extendDevtoolsMeta({ example: 'SkeletonExample' })
19
22
  </script>
20
23
 
21
24
  <script setup lang="ts">
@@ -4,6 +4,7 @@ import type { DialogRootProps, DialogRootEmits, DialogContentProps } from 'radix
4
4
  import type { AppConfig } from '@nuxt/schema'
5
5
  import _appConfig from '#build/app.config'
6
6
  import theme from '#build/ui/slideover'
7
+ import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
7
8
  import type { ButtonProps } from '../types'
8
9
 
9
10
  const appConfig = _appConfig as AppConfig & { ui: { slideover: Partial<typeof theme> } }
@@ -65,6 +66,8 @@ export interface SlideoverSlots {
65
66
  body(props?: {}): any
66
67
  footer(props?: {}): any
67
68
  }
69
+
70
+ extendDevtoolsMeta({ example: 'SlideoverExample' })
68
71
  </script>
69
72
 
70
73
  <script setup lang="ts">
@@ -14,7 +14,7 @@ type SliderVariants = VariantProps<typeof slider>
14
14
  export interface SliderProps extends Pick<SliderRootProps, 'name' | 'disabled' | 'inverted' | 'min' | 'max' | 'step' | 'minStepsBetweenThumbs'> {
15
15
  /**
16
16
  * The element or component this component should render as.
17
- * @defaultValue `div`
17
+ * @defaultValue 'div'
18
18
  */
19
19
  as?: any
20
20
  size?: SliderVariants['size']
@@ -4,6 +4,7 @@ import type { SwitchRootProps } from 'radix-vue'
4
4
  import type { AppConfig } from '@nuxt/schema'
5
5
  import _appConfig from '#build/app.config'
6
6
  import theme from '#build/ui/switch'
7
+ import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
7
8
  import type { PartialString } from '../types/utils'
8
9
 
9
10
  const appConfig = _appConfig as AppConfig & { ui: { switch: Partial<typeof theme> } }
@@ -15,7 +16,7 @@ type SwitchVariants = VariantProps<typeof switchTv>
15
16
  export interface SwitchProps extends Pick<SwitchRootProps, 'disabled' | 'id' | 'name' | 'required' | 'value'> {
16
17
  /**
17
18
  * The element or component this component should render as.
18
- * @defaultValue `div`
19
+ * @defaultValue 'div'
19
20
  */
20
21
  as?: any
21
22
  color?: SwitchVariants['color']
@@ -48,6 +49,8 @@ export interface SwitchSlots {
48
49
  label(props: { label?: string }): any
49
50
  description(props: { description?: string }): any
50
51
  }
52
+
53
+ extendDevtoolsMeta({ defaultProps: { label: 'Switch me!' } })
51
54
  </script>
52
55
 
53
56
  <script setup lang="ts">
@@ -56,6 +59,7 @@ import { SwitchRoot, SwitchThumb, useForwardProps, Label } from 'radix-vue'
56
59
  import { reactivePick } from '@vueuse/core'
57
60
  import { useAppConfig } from '#imports'
58
61
  import { useFormField } from '../composables/useFormField'
62
+ import UIcon from './Icon.vue'
59
63
 
60
64
  const props = defineProps<SwitchProps>()
61
65
  const slots = defineSlots<SwitchSlots>()