@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
@@ -4,6 +4,7 @@ import type { CollapsibleRootProps, CollapsibleRootEmits } 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/collapsible'
7
+ import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
7
8
 
8
9
  const appConfig = _appConfig as AppConfig & { ui: { collapsible: Partial<typeof theme> } }
9
10
 
@@ -25,6 +26,8 @@ export interface CollapsibleSlots {
25
26
  default(props: { open: boolean }): any
26
27
  content(props?: {}): any
27
28
  }
29
+
30
+ extendDevtoolsMeta({ example: 'CollapsibleExample' })
28
31
  </script>
29
32
 
30
33
  <script setup lang="ts">
@@ -1,13 +1,13 @@
1
- <!-- eslint-disable vue/block-tag-newline -->
2
1
  <script lang="ts">
3
2
  import { tv } from 'tailwind-variants'
4
- import type { ComboboxRootProps, ComboboxRootEmits, ComboboxItemProps } from 'radix-vue'
3
+ import type { ComboboxRootProps, ComboboxRootEmits } from 'radix-vue'
5
4
  import type { FuseResult } from 'fuse.js'
6
5
  import type { AppConfig } from '@nuxt/schema'
7
6
  import type { UseFuseOptions } from '@vueuse/integrations/useFuse'
8
7
  import _appConfig from '#build/app.config'
9
8
  import theme from '#build/ui/command-palette'
10
9
  import type { UseComponentIconsProps } from '../composables/useComponentIcons'
10
+ import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
11
11
  import type { AvatarProps, ButtonProps, ChipProps, KbdProps, InputProps } from '../types'
12
12
  import type { DynamicSlots, PartialString } from '../types/utils'
13
13
 
@@ -15,7 +15,7 @@ const appConfig = _appConfig as AppConfig & { ui: { commandPalette: Partial<type
15
15
 
16
16
  const commandPalette = tv({ extend: tv(theme), ...(appConfig.ui?.commandPalette || {}) })
17
17
 
18
- export interface CommandPaletteItem extends Pick<ComboboxItemProps, 'disabled'> {
18
+ export interface CommandPaletteItem {
19
19
  prefix?: string
20
20
  label?: string
21
21
  suffix?: string
@@ -23,8 +23,10 @@ export interface CommandPaletteItem extends Pick<ComboboxItemProps, 'disabled'>
23
23
  avatar?: AvatarProps
24
24
  chip?: ChipProps
25
25
  kbds?: KbdProps['value'][] | KbdProps[]
26
+ loading?: boolean
27
+ disabled?: boolean
26
28
  slot?: string
27
- select?(e?: Event): void
29
+ onSelect?(e?: Event): void
28
30
  }
29
31
 
30
32
  export interface CommandPaletteGroup<T> {
@@ -90,6 +92,11 @@ export interface CommandPaletteProps<G, T> extends Pick<ComboboxRootProps, 'mult
90
92
  }
91
93
  */
92
94
  fuse?: UseFuseOptions<T>
95
+ /**
96
+ * The key used to get the label from the item.
97
+ * @defaultValue 'label'
98
+ */
99
+ labelKey?: string
93
100
  class?: any
94
101
  ui?: PartialString<typeof commandPalette.slots>
95
102
  }
@@ -107,6 +114,7 @@ export type CommandPaletteSlots<G extends { slot?: string }, T extends { slot?:
107
114
  'item-trailing': SlotProps<T>
108
115
  } & DynamicSlots<G, SlotProps<T>> & DynamicSlots<T, SlotProps<T>>
109
116
 
117
+ extendDevtoolsMeta({ example: 'CommandPaletteExample', ignoreProps: ['groups'] })
110
118
  </script>
111
119
 
112
120
  <script setup lang="ts" generic="G extends CommandPaletteGroup<T>, T extends CommandPaletteItem">
@@ -116,17 +124,19 @@ import { defu } from 'defu'
116
124
  import { reactivePick } from '@vueuse/core'
117
125
  import { useFuse } from '@vueuse/integrations/useFuse'
118
126
  import { useAppConfig } from '#imports'
127
+ import { omit, get } from '../utils'
128
+ import { highlight } from '../utils/fuse'
119
129
  import UIcon from './Icon.vue'
120
130
  import UAvatar from './Avatar.vue'
131
+ import UButton from './Button.vue'
121
132
  import UChip from './Chip.vue'
122
133
  import UKbd from './Kbd.vue'
123
134
  import UInput from './Input.vue'
124
- import { omit } from '../utils'
125
- import { highlight } from '../utils/fuse'
126
135
 
127
136
  const props = withDefaults(defineProps<CommandPaletteProps<G, T>>(), {
128
137
  modelValue: '',
129
- placeholder: 'Type a command or search...'
138
+ placeholder: 'Type a command or search...',
139
+ labelKey: 'label'
130
140
  })
131
141
  const emits = defineEmits<CommandPaletteEmits<T>>()
132
142
  const slots = defineSlots<CommandPaletteSlots<G, T>>()
@@ -144,7 +154,7 @@ const fuse = computed(() => defu({}, props.fuse, {
144
154
  fuseOptions: {
145
155
  ignoreLocation: true,
146
156
  threshold: 0.1,
147
- keys: ['label', 'suffix']
157
+ keys: [props.labelKey, 'suffix']
148
158
  },
149
159
  resultLimit: 12,
150
160
  matchAllWhenSearchEmpty: true
@@ -175,8 +185,8 @@ function getGroupWithItems(group: G, items: (T & { matches?: FuseResult<T>['matc
175
185
  items: items.slice(0, fuse.value.resultLimit).map((item) => {
176
186
  return {
177
187
  ...item,
178
- labelHtml: highlight<T>(item, searchTerm.value, 'label'),
179
- suffixHtml: highlight<T>(item, searchTerm.value, undefined, ['label'])
188
+ labelHtml: highlight<T>(item, searchTerm.value, props.labelKey),
189
+ suffixHtml: highlight<T>(item, searchTerm.value, undefined, [props.labelKey])
180
190
  }
181
191
  })
182
192
  }
@@ -255,22 +265,23 @@ const groups = computed(() => {
255
265
 
256
266
  <ComboboxViewport :class="ui.viewport({ class: props.ui?.viewport })">
257
267
  <ComboboxGroup v-for="(group, groupIndex) in groups" :key="`group-${groupIndex}`" :class="ui.group({ class: props.ui?.group })">
258
- <ComboboxLabel v-if="group.label" :class="ui.label({ class: props.ui?.label })">
259
- {{ group.label }}
268
+ <ComboboxLabel v-if="get(group, props.labelKey as string)" :class="ui.label({ class: props.ui?.label })">
269
+ {{ get(group, props.labelKey as string) }}
260
270
  </ComboboxLabel>
261
271
 
262
272
  <ComboboxItem
263
273
  v-for="(item, index) in group.items"
264
274
  :key="`group-${groupIndex}-${index}`"
265
- :value="omit(item, ['matches' as any, 'group' as any, 'select', 'labelHtml', 'suffixHtml'])"
275
+ :value="omit(item, ['matches' as any, 'group' as any, 'onSelect', 'labelHtml', 'suffixHtml'])"
266
276
  :disabled="item.disabled"
267
277
  :class="ui.item({ class: props.ui?.item })"
268
- @select="item.select"
278
+ @select="item.onSelect"
269
279
  >
270
280
  <slot :name="item.slot || group.slot || 'item'" :item="item" :index="index">
271
281
  <slot :name="item.slot ? `${item.slot}-leading` : group.slot ? `${group.slot}-leading` : `item-leading`" :item="item" :index="index">
272
- <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 })" />
282
+ <UIcon v-if="item.loading" :name="loadingIcon || appConfig.ui.icons.loading" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon, loading: true })" />
273
283
  <UIcon v-else-if="item.icon" :name="item.icon" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon })" />
284
+ <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 })" />
274
285
  <UChip
275
286
  v-else-if="item.chip"
276
287
  :size="((props.ui?.itemLeadingChipSize || ui.itemLeadingChipSize()) as ChipProps['size'])"
@@ -281,11 +292,11 @@ const groups = computed(() => {
281
292
  />
282
293
  </slot>
283
294
 
284
- <span v-if="item.label || !!slots[item.slot ? `${item.slot}-label` : group.slot ? `${group.slot}-label` : `item-label`]" :class="ui.itemLabel({ class: props.ui?.itemLabel })">
295
+ <span v-if="item.labelHtml || get(item, props.labelKey as string) || !!slots[item.slot ? `${item.slot}-label` : group.slot ? `${group.slot}-label` : `item-label`]" :class="ui.itemLabel({ class: props.ui?.itemLabel })">
285
296
  <slot :name="item.slot ? `${item.slot}-label` : group.slot ? `${group.slot}-label` : `item-label`" :item="item" :index="index">
286
297
  <span v-if="item.prefix" :class="ui.itemLabelPrefix({ class: props.ui?.itemLabelPrefix })">{{ item.prefix }}</span>
287
298
 
288
- <span :class="ui.itemLabelBase({ class: props.ui?.itemLabelBase })" v-html="item.labelHtml || item.label" />
299
+ <span :class="ui.itemLabelBase({ class: props.ui?.itemLabelBase })" v-html="item.labelHtml || get(item, props.labelKey as string)" />
289
300
 
290
301
  <span :class="ui.itemLabelSuffix({ class: props.ui?.itemLabelSuffix })" v-html="item.suffixHtml || item.suffix" />
291
302
  </slot>
@@ -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/container'
6
+ import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
6
7
 
7
8
  const appConfig = _appConfig as AppConfig & { ui: { container: Partial<typeof theme> } }
8
9
 
@@ -20,6 +21,8 @@ export interface ContainerProps {
20
21
  export interface ContainerSlots {
21
22
  default(props?: {}): any
22
23
  }
24
+
25
+ extendDevtoolsMeta({ example: 'ContainerExample' })
23
26
  </script>
24
27
 
25
28
  <script setup lang="ts">
@@ -1,10 +1,10 @@
1
- <!-- eslint-disable vue/block-tag-newline -->
2
1
  <script lang="ts">
3
2
  import { tv, type VariantProps } from 'tailwind-variants'
4
- import type { ContextMenuRootProps, ContextMenuRootEmits, ContextMenuContentProps, ContextMenuTriggerProps, ContextMenuItemProps } from 'radix-vue'
3
+ import type { ContextMenuRootProps, ContextMenuRootEmits, ContextMenuContentProps } from 'radix-vue'
5
4
  import type { AppConfig } from '@nuxt/schema'
6
5
  import _appConfig from '#build/app.config'
7
6
  import theme from '#build/ui/context-menu'
7
+ import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
8
8
  import type { AvatarProps, KbdProps, LinkProps } from '../types'
9
9
  import type { DynamicSlots, PartialString } from '../types/utils'
10
10
 
@@ -12,9 +12,12 @@ const appConfig = _appConfig as AppConfig & { ui: { contextMenu: Partial<typeof
12
12
 
13
13
  const contextMenu = tv({ extend: tv(theme), ...(appConfig.ui?.contextMenu || {}) })
14
14
 
15
- export interface ContextMenuItem extends Omit<LinkProps, 'type' | 'raw' | 'custom'>, Pick<ContextMenuItemProps, 'disabled'> {
15
+ type ContextMenuVariants = VariantProps<typeof contextMenu>
16
+
17
+ export interface ContextMenuItem extends Omit<LinkProps, 'type' | 'raw' | 'custom'> {
16
18
  label?: string
17
19
  icon?: string
20
+ color?: ContextMenuVariants['color']
18
21
  avatar?: AvatarProps
19
22
  content?: Omit<ContextMenuContentProps, 'as' | 'asChild' | 'forceMount'>
20
23
  kbds?: KbdProps['value'][] | KbdProps[]
@@ -22,19 +25,31 @@ export interface ContextMenuItem extends Omit<LinkProps, 'type' | 'raw' | 'custo
22
25
  * The item type.
23
26
  * @defaultValue 'link'
24
27
  */
25
- type?: 'label' | 'separator' | 'link'
28
+ type?: 'label' | 'separator' | 'link' | 'checkbox'
26
29
  slot?: string
30
+ loading?: boolean
31
+ disabled?: boolean
32
+ checked?: boolean
27
33
  open?: boolean
28
34
  defaultOpen?: boolean
29
35
  children?: ContextMenuItem[] | ContextMenuItem[][]
30
- select?(e: Event): void
36
+ onSelect?(e: Event): void
37
+ onUpdateChecked?(checked: boolean): void
31
38
  }
32
39
 
33
- type ContextMenuVariants = VariantProps<typeof contextMenu>
34
-
35
- export interface ContextMenuProps<T> extends Omit<ContextMenuRootProps, 'dir'>, Pick<ContextMenuTriggerProps, 'disabled'> {
40
+ export interface ContextMenuProps<T> extends Omit<ContextMenuRootProps, 'dir'> {
36
41
  size?: ContextMenuVariants['size']
37
42
  items?: T[] | T[][]
43
+ /**
44
+ * The icon displayed when an item is checked.
45
+ * @defaultValue appConfig.ui.icons.check
46
+ */
47
+ checkedIcon?: string
48
+ /**
49
+ * The icon displayed when an item is loading.
50
+ * @defaultValue appConfig.ui.icons.loading
51
+ */
52
+ loadingIcon?: string
38
53
  /** The content of the menu. */
39
54
  content?: Omit<ContextMenuContentProps, 'as' | 'asChild' | 'forceMount'>
40
55
  /**
@@ -42,6 +57,12 @@ export interface ContextMenuProps<T> extends Omit<ContextMenuRootProps, 'dir'>,
42
57
  * @defaultValue true
43
58
  */
44
59
  portal?: boolean
60
+ /**
61
+ * The key used to get the label from the item.
62
+ * @defaultValue 'label'
63
+ */
64
+ labelKey?: string
65
+ disabled?: boolean
45
66
  class?: any
46
67
  ui?: PartialString<typeof contextMenu.slots>
47
68
  }
@@ -58,18 +79,79 @@ export type ContextMenuSlots<T extends { slot?: string }> = {
58
79
  'item-trailing': SlotProps<T>
59
80
  } & DynamicSlots<T, SlotProps<T>>
60
81
 
82
+ extendDevtoolsMeta({
83
+ example: 'ContextMenuExample',
84
+ ignoreProps: ['items'],
85
+ defaultProps: {
86
+ items: [
87
+ [{
88
+ label: 'My account',
89
+ avatar: {
90
+ src: 'https://avatars.githubusercontent.com/u/739984?v=4'
91
+ }
92
+ }],
93
+ [{
94
+ label: 'Appearance',
95
+ children: [{
96
+ label: 'System',
97
+ icon: 'i-lucide-monitor'
98
+ }, {
99
+ label: 'Light',
100
+ icon: 'i-lucide-sun'
101
+ }, {
102
+ label: 'Dark',
103
+ icon: 'i-lucide-moon'
104
+ }]
105
+ }],
106
+ [{
107
+ label: 'Show Sidebar',
108
+ kbds: ['meta', 'S']
109
+ }, {
110
+ label: 'Show Toolbar',
111
+ kbds: ['shift', 'meta', 'D']
112
+ }, {
113
+ label: 'Collapse Pinned Tabs',
114
+ disabled: true
115
+ }], [{
116
+ label: 'Refresh the Page'
117
+ }, {
118
+ label: 'Clear Cookies and Refresh'
119
+ }, {
120
+ label: 'Clear Cache and Refresh'
121
+ }, {
122
+ type: 'separator'
123
+ }, {
124
+ label: 'Developer',
125
+ children: [[{
126
+ label: 'View Source',
127
+ kbds: ['option', 'meta', 'U']
128
+ }, {
129
+ label: 'Developer Tools',
130
+ kbds: ['option', 'meta', 'I']
131
+ }], [{
132
+ label: 'Inspect Elements',
133
+ kbds: ['option', 'meta', 'C']
134
+ }], [{
135
+ label: 'JavaScript Console',
136
+ kbds: ['option', 'meta', 'J']
137
+ }]]
138
+ }]
139
+ ]
140
+ }
141
+ })
61
142
  </script>
62
143
 
63
144
  <script setup lang="ts" generic="T extends ContextMenuItem">
64
145
  import { computed, toRef } from 'vue'
65
146
  import { ContextMenuRoot, ContextMenuTrigger, useForwardPropsEmits } from 'radix-vue'
66
147
  import { reactivePick } from '@vueuse/core'
67
- import UContextMenuContent from './ContextMenuContent.vue'
68
148
  import { omit } from '../utils'
149
+ import UContextMenuContent from './ContextMenuContent.vue'
69
150
 
70
151
  const props = withDefaults(defineProps<ContextMenuProps<T>>(), {
71
152
  portal: true,
72
- modal: true
153
+ modal: true,
154
+ labelKey: 'label'
73
155
  })
74
156
  const emits = defineEmits<ContextMenuEmits>()
75
157
  const slots = defineSlots<ContextMenuSlots<T>>()
@@ -96,6 +178,9 @@ const ui = computed(() => contextMenu({
96
178
  v-bind="contentProps"
97
179
  :items="items"
98
180
  :portal="portal"
181
+ :label-key="labelKey"
182
+ :checked-icon="checkedIcon"
183
+ :loading-icon="loadingIcon"
99
184
  >
100
185
  <template v-for="(_, name) in proxySlots" #[name]="slotData: any">
101
186
  <slot :name="name" v-bind="slotData" />
@@ -10,6 +10,9 @@ interface ContextMenuContentProps<T> extends Omit<RadixContextMenuContentProps,
10
10
  items?: T[] | T[][]
11
11
  portal?: boolean
12
12
  sub?: boolean
13
+ labelKey: string
14
+ checkedIcon?: string
15
+ loadingIcon?: string
13
16
  class?: any
14
17
  ui: typeof _contextMenu
15
18
  uiOverride?: any
@@ -24,13 +27,13 @@ import { ContextMenu } from 'radix-vue/namespaced'
24
27
  import { useForwardPropsEmits } from 'radix-vue'
25
28
  import { reactiveOmit, createReusableTemplate } from '@vueuse/core'
26
29
  import { useAppConfig } from '#imports'
30
+ import { omit, get } from '../utils'
31
+ import { pickLinkProps } from '../utils/link'
27
32
  import ULinkBase from './LinkBase.vue'
28
33
  import ULink from './Link.vue'
29
34
  import UAvatar from './Avatar.vue'
30
35
  import UIcon from './Icon.vue'
31
36
  import UKbd from './Kbd.vue'
32
- import { omit } from '../utils'
33
- import { pickLinkProps } from '../utils/link'
34
37
 
35
38
  const props = defineProps<ContextMenuContentProps<T>>()
36
39
  const emits = defineEmits<ContextMenuContentEmits>()
@@ -49,25 +52,30 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
49
52
  <DefineItemTemplate v-slot="{ item, active, index }">
50
53
  <slot :name="item.slot || 'item'" :item="(item as T)" :index="index">
51
54
  <slot :name="item.slot ? `${item.slot}-leading`: 'item-leading'" :item="(item as T)" :active="active" :index="index">
52
- <UAvatar v-if="item.avatar" :size="((props.uiOverride?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="item.avatar" :class="ui.itemLeadingAvatar({ class: uiOverride?.itemLeadingAvatar, active })" />
53
- <UIcon v-else-if="item.icon" :name="item.icon" :class="ui.itemLeadingIcon({ class: uiOverride?.itemLeadingIcon, active })" />
55
+ <UIcon v-if="item.loading" :name="loadingIcon || appConfig.ui.icons.loading" :class="ui.itemLeadingIcon({ class: uiOverride?.itemLeadingIcon, color: item?.color, loading: true })" />
56
+ <UIcon v-else-if="item.icon" :name="item.icon" :class="ui.itemLeadingIcon({ class: uiOverride?.itemLeadingIcon, color: item?.color, active })" />
57
+ <UAvatar v-else-if="item.avatar" :size="((props.uiOverride?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="item.avatar" :class="ui.itemLeadingAvatar({ class: uiOverride?.itemLeadingAvatar, active })" />
54
58
  </slot>
55
59
 
56
- <span v-if="item.label || !!slots[item.slot ? `${item.slot}-label`: 'item-label']" :class="ui.itemLabel({ class: uiOverride?.itemLabel, active })">
60
+ <span v-if="get(item, props.labelKey as string) || !!slots[item.slot ? `${item.slot}-label`: 'item-label']" :class="ui.itemLabel({ class: uiOverride?.itemLabel, active })">
57
61
  <slot :name="item.slot ? `${item.slot}-label`: 'item-label'" :item="(item as T)" :active="active" :index="index">
58
- {{ item.label }}
62
+ {{ get(item, props.labelKey as string) }}
59
63
  </slot>
60
64
 
61
- <UIcon v-if="item.target === '_blank'" :name="appConfig.ui.icons.external" :class="ui.itemLabelExternalIcon({ class: uiOverride?.itemLabelExternalIcon, active })" />
65
+ <UIcon v-if="item.target === '_blank'" :name="appConfig.ui.icons.external" :class="ui.itemLabelExternalIcon({ class: uiOverride?.itemLabelExternalIcon, color: item?.color, active })" />
62
66
  </span>
63
67
 
64
- <span v-if="item.children?.length || item.kbds?.length || !!slots[item.slot ? `${item.slot}-trailing`: 'item-trailing']" :class="ui.itemTrailing({ class: uiOverride?.itemTrailing })">
68
+ <span :class="ui.itemTrailing({ class: uiOverride?.itemTrailing })">
65
69
  <slot :name="item.slot ? `${item.slot}-trailing`: 'item-trailing'" :item="(item as T)" :active="active" :index="index">
66
- <UIcon v-if="item.children?.length" :name="appConfig.ui.icons.chevronRight" :class="ui.itemTrailingIcon({ class: uiOverride?.itemTrailingIcon, active })" />
70
+ <UIcon v-if="item.children?.length" :name="appConfig.ui.icons.chevronRight" :class="ui.itemTrailingIcon({ class: uiOverride?.itemTrailingIcon, color: item?.color, active })" />
67
71
  <span v-else-if="item.kbds?.length" :class="ui.itemTrailingKbds({ class: uiOverride?.itemTrailingKbds })">
68
72
  <UKbd v-for="(kbd, kbdIndex) in item.kbds" :key="kbdIndex" :size="((props.uiOverride?.itemTrailingKbdsSize || ui.itemTrailingKbdsSize()) as KbdProps['size'])" v-bind="typeof kbd === 'string' ? { value: kbd } : kbd" />
69
73
  </span>
70
74
  </slot>
75
+
76
+ <ContextMenu.ItemIndicator as-child>
77
+ <UIcon :name="checkedIcon || appConfig.ui.icons.check" :class="ui.itemTrailingIcon({ class: uiOverride?.itemTrailingIcon, color: item?.color })" />
78
+ </ContextMenu.ItemIndicator>
71
79
  </span>
72
80
  </slot>
73
81
  </DefineItemTemplate>
@@ -85,8 +93,8 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
85
93
  as="button"
86
94
  type="button"
87
95
  :disabled="item.disabled"
88
- :text-value="item.label"
89
- :class="ui.item({ class: uiOverride?.item })"
96
+ :text-value="get(item, props.labelKey as string)"
97
+ :class="ui.item({ class: uiOverride?.item, color: item?.color })"
90
98
  >
91
99
  <ReuseItemTemplate :item="item" :index="index" />
92
100
  </ContextMenu.SubTrigger>
@@ -99,6 +107,9 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
99
107
  :portal="portal"
100
108
  :items="item.children"
101
109
  :align-offset="-4"
110
+ :label-key="labelKey"
111
+ :checked-icon="checkedIcon"
112
+ :loading-icon="loadingIcon"
102
113
  v-bind="item.content"
103
114
  >
104
115
  <template v-for="(_, name) in proxySlots" #[name]="slotData: any">
@@ -106,9 +117,26 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
106
117
  </template>
107
118
  </UContextMenuContent>
108
119
  </ContextMenu.Sub>
109
- <ContextMenu.Item v-else as-child :disabled="item.disabled" :text-value="item.label" @select="item.select">
120
+ <ContextMenu.CheckboxItem
121
+ v-else-if="item.type === 'checkbox'"
122
+ :checked="item.checked"
123
+ :disabled="item.disabled"
124
+ :text-value="get(item, props.labelKey as string)"
125
+ :class="ui.item({ class: [uiOverride?.item, item.class], color: item?.color })"
126
+ @update:checked="item.onUpdateChecked"
127
+ @select="item.onSelect"
128
+ >
129
+ <ReuseItemTemplate :item="item" :index="index" />
130
+ </ContextMenu.CheckboxItem>
131
+ <ContextMenu.Item
132
+ v-else
133
+ as-child
134
+ :disabled="item.disabled"
135
+ :text-value="get(item, props.labelKey as string)"
136
+ @select="item.onSelect"
137
+ >
110
138
  <ULink v-slot="{ active, ...slotProps }" v-bind="pickLinkProps(item as Omit<ContextMenuItem, 'type'>)" custom>
111
- <ULinkBase v-bind="slotProps" :class="ui.item({ class: [uiOverride?.item, item.class], active })">
139
+ <ULinkBase v-bind="slotProps" :class="ui.item({ class: [uiOverride?.item, item.class], active, color: item?.color })">
112
140
  <ReuseItemTemplate :item="item" :active="active" :index="index" />
113
141
  </ULinkBase>
114
142
  </ULink>
@@ -5,6 +5,7 @@ import type { DialogContentProps } from 'radix-vue'
5
5
  import type { AppConfig } from '@nuxt/schema'
6
6
  import _appConfig from '#build/app.config'
7
7
  import theme from '#build/ui/drawer'
8
+ import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
8
9
 
9
10
  const appConfig = _appConfig as AppConfig & { ui: { drawer: Partial<typeof theme> } }
10
11
 
@@ -51,6 +52,8 @@ export interface DrawerSlots {
51
52
  body(props?: {}): any
52
53
  footer(props?: {}): any
53
54
  }
55
+
56
+ extendDevtoolsMeta({ example: 'DrawerExample' })
54
57
  </script>
55
58
 
56
59
  <script setup lang="ts">
@@ -1,10 +1,10 @@
1
- <!-- eslint-disable vue/block-tag-newline -->
2
1
  <script lang="ts">
3
2
  import { tv, type VariantProps } from 'tailwind-variants'
4
- import type { DropdownMenuRootProps, DropdownMenuRootEmits, DropdownMenuContentProps, DropdownMenuArrowProps, DropdownMenuTriggerProps, DropdownMenuItemProps } from 'radix-vue'
3
+ import type { DropdownMenuRootProps, DropdownMenuRootEmits, DropdownMenuContentProps, DropdownMenuArrowProps } from 'radix-vue'
5
4
  import type { AppConfig } from '@nuxt/schema'
6
5
  import _appConfig from '#build/app.config'
7
6
  import theme from '#build/ui/dropdown-menu'
7
+ import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
8
8
  import type { AvatarProps, KbdProps, LinkProps } from '../types'
9
9
  import type { DynamicSlots, PartialString } from '../types/utils'
10
10
 
@@ -12,9 +12,12 @@ const appConfig = _appConfig as AppConfig & { ui: { dropdownMenu: Partial<typeof
12
12
 
13
13
  const dropdownMenu = tv({ extend: tv(theme), ...(appConfig.ui?.dropdownMenu || {}) })
14
14
 
15
- export interface DropdownMenuItem extends Omit<LinkProps, 'type' | 'raw' | 'custom'>, Pick<DropdownMenuItemProps, 'disabled'> {
15
+ type DropdownMenuVariants = VariantProps<typeof dropdownMenu>
16
+
17
+ export interface DropdownMenuItem extends Omit<LinkProps, 'type' | 'raw' | 'custom'> {
16
18
  label?: string
17
19
  icon?: string
20
+ color?: DropdownMenuVariants['color']
18
21
  avatar?: AvatarProps
19
22
  content?: Omit<DropdownMenuContentProps, 'as' | 'asChild' | 'forceMount'>
20
23
  kbds?: KbdProps['value'][] | KbdProps[]
@@ -22,19 +25,31 @@ export interface DropdownMenuItem extends Omit<LinkProps, 'type' | 'raw' | 'cust
22
25
  * The item type.
23
26
  * @defaultValue 'link'
24
27
  */
25
- type?: 'label' | 'separator' | 'link'
28
+ type?: 'label' | 'separator' | 'link' | 'checkbox'
26
29
  slot?: string
30
+ loading?: boolean
31
+ disabled?: boolean
32
+ checked?: boolean
27
33
  open?: boolean
28
34
  defaultOpen?: boolean
29
35
  children?: DropdownMenuItem[] | DropdownMenuItem[][]
30
- select?(e: Event): void
36
+ onSelect?(e: Event): void
37
+ onUpdateChecked?(checked: boolean): void
31
38
  }
32
39
 
33
- type DropdownMenuVariants = VariantProps<typeof dropdownMenu>
34
-
35
- export interface DropdownMenuProps<T> extends Omit<DropdownMenuRootProps, 'dir'>, Pick<DropdownMenuTriggerProps, 'disabled'> {
40
+ export interface DropdownMenuProps<T> extends Omit<DropdownMenuRootProps, 'dir'> {
36
41
  size?: DropdownMenuVariants['size']
37
42
  items?: T[] | T[][]
43
+ /**
44
+ * The icon displayed when an item is checked.
45
+ * @defaultValue appConfig.ui.icons.check
46
+ */
47
+ checkedIcon?: string
48
+ /**
49
+ * The icon displayed when an item is loading.
50
+ * @defaultValue appConfig.ui.icons.loading
51
+ */
52
+ loadingIcon?: string
38
53
  /**
39
54
  * The content of the menu.
40
55
  * @defaultValue { side: 'bottom', sideOffset: 8 }
@@ -50,6 +65,12 @@ export interface DropdownMenuProps<T> extends Omit<DropdownMenuRootProps, 'dir'>
50
65
  * @defaultValue true
51
66
  */
52
67
  portal?: boolean
68
+ /**
69
+ * The key used to get the label from the item.
70
+ * @defaultValue 'label'
71
+ */
72
+ labelKey?: string
73
+ disabled?: boolean
53
74
  class?: any
54
75
  ui?: PartialString<typeof dropdownMenu.slots>
55
76
  }
@@ -66,6 +87,54 @@ export type DropdownMenuSlots<T extends { slot?: string }> = {
66
87
  'item-trailing': SlotProps<T>
67
88
  } & DynamicSlots<T, SlotProps<T>>
68
89
 
90
+ extendDevtoolsMeta({
91
+ example: 'DropdownMenuExample',
92
+ ignoreProps: ['items'],
93
+ defaultProps: {
94
+ items: [
95
+ [{
96
+ label: 'My account',
97
+ avatar: {
98
+ src: 'https://avatars.githubusercontent.com/u/739984?v=4'
99
+ },
100
+ type: 'label'
101
+ }], [{
102
+ label: 'Profile',
103
+ icon: 'i-lucide-user',
104
+ slot: 'custom'
105
+ }, {
106
+ label: 'Billing',
107
+ icon: 'i-lucide-credit-card',
108
+ kbds: ['meta', 'b']
109
+ }, {
110
+ label: 'Settings',
111
+ icon: 'i-lucide-cog',
112
+ kbds: ['?']
113
+ }], [{
114
+ label: 'Invite users',
115
+ icon: 'i-lucide-user-plus',
116
+ children: [[{
117
+ label: 'Invite by email',
118
+ icon: 'i-lucide-send-horizontal'
119
+ }, {
120
+ label: 'Invite by link',
121
+ icon: 'i-lucide-link',
122
+ kbds: ['meta', 'i']
123
+ }]]
124
+ }],
125
+ [{
126
+ label: 'GitHub',
127
+ icon: 'i-simple-icons-github',
128
+ to: 'https://github.com/nuxt/ui',
129
+ target: '_blank'
130
+ }, {
131
+ label: 'Support',
132
+ icon: 'i-lucide-life-buoy',
133
+ to: '/components/dropdown-menu'
134
+ }]
135
+ ]
136
+ }
137
+ })
69
138
  </script>
70
139
 
71
140
  <script setup lang="ts" generic="T extends DropdownMenuItem">
@@ -73,12 +142,13 @@ import { computed, toRef } from 'vue'
73
142
  import { defu } from 'defu'
74
143
  import { DropdownMenuRoot, DropdownMenuTrigger, DropdownMenuArrow, useForwardPropsEmits } from 'radix-vue'
75
144
  import { reactivePick } from '@vueuse/core'
76
- import UDropdownMenuContent from './DropdownMenuContent.vue'
77
145
  import { omit } from '../utils'
146
+ import UDropdownMenuContent from './DropdownMenuContent.vue'
78
147
 
79
148
  const props = withDefaults(defineProps<DropdownMenuProps<T>>(), {
80
149
  portal: true,
81
- modal: true
150
+ modal: true,
151
+ labelKey: 'label'
82
152
  })
83
153
  const emits = defineEmits<DropdownMenuEmits>()
84
154
  const slots = defineSlots<DropdownMenuSlots<T>>()
@@ -106,6 +176,9 @@ const ui = computed(() => dropdownMenu({
106
176
  v-bind="contentProps"
107
177
  :items="items"
108
178
  :portal="portal"
179
+ :label-key="labelKey"
180
+ :checked-icon="checkedIcon"
181
+ :loading-icon="loadingIcon"
109
182
  >
110
183
  <template v-for="(_, name) in proxySlots" #[name]="slotData: any">
111
184
  <slot :name="name" v-bind="slotData" />