@nuxt/ui 3.0.0-alpha.7 → 3.0.0-alpha.9

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 (296) 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 +45 -0
  22. package/.nuxt/ui/input-menu.ts +411 -0
  23. package/.nuxt/ui/input-number.ts +204 -0
  24. package/.nuxt/ui/input.ts +263 -0
  25. package/.nuxt/ui/kbd.ts +19 -0
  26. package/.nuxt/ui/link.ts +15 -0
  27. package/.nuxt/ui/modal.ts +28 -0
  28. package/.nuxt/ui/navigation-menu.ts +390 -0
  29. package/.nuxt/ui/pagination.ts +8 -0
  30. package/.nuxt/ui/pin-input.ts +145 -0
  31. package/.nuxt/ui/popover.ts +6 -0
  32. package/.nuxt/ui/progress.ts +258 -0
  33. package/.nuxt/ui/radio-group.ts +112 -0
  34. package/.nuxt/ui/select-menu.ts +316 -0
  35. package/.nuxt/ui/select.ts +314 -0
  36. package/.nuxt/ui/separator.ts +143 -0
  37. package/.nuxt/ui/skeleton.ts +3 -0
  38. package/.nuxt/ui/slideover.ts +63 -0
  39. package/.nuxt/ui/slider.ts +148 -0
  40. package/.nuxt/ui/switch.ts +113 -0
  41. package/.nuxt/ui/table.ts +129 -0
  42. package/.nuxt/ui/tabs.ts +227 -0
  43. package/.nuxt/ui/textarea.ts +263 -0
  44. package/.nuxt/ui/toast.ts +66 -0
  45. package/.nuxt/ui/toaster.ts +75 -0
  46. package/.nuxt/ui/tooltip.ts +9 -0
  47. package/README.md +52 -12
  48. package/cli/commands/{init.mjs → make/component.mjs} +4 -4
  49. package/cli/commands/make/index.mjs +14 -0
  50. package/cli/commands/make/locale.mjs +64 -0
  51. package/cli/index.mjs +2 -2
  52. package/cli/templates.mjs +47 -2
  53. package/cli/utils.mjs +14 -0
  54. package/dist/chunks/component-meta.cjs +77249 -0
  55. package/dist/chunks/component-meta.mjs +77247 -0
  56. package/dist/client/devtools/200.html +1 -0
  57. package/dist/client/devtools/404.html +1 -0
  58. package/dist/client/devtools/_fonts/rP2Wp2ywxg089UriCZaSExd86J3t9jz86MvyyKK58UfivUw4aw-SK92LTmKP0.woff2 +0 -0
  59. package/dist/client/devtools/_fonts/rP2Wp2ywxg089UriCZaSExd86J3t9jz86MvyyKy58UfivUw-9uYm8d48E4.woff2 +0 -0
  60. package/dist/client/devtools/_fonts/rP2Yp2ywxg089UriI5-g4vlH9VoD8Cmcqbu0-K6z9mXg-VNw7NHvqnp.woff2 +0 -0
  61. package/dist/client/devtools/_fonts/rP2Yp2ywxg089UriI5-g4vlH9VoD8Cmcqbu6-K6z9mXgjU0-EkYdMs3MAX.woff2 +0 -0
  62. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat-7DW3w-R7n06NbhGy.woff +0 -0
  63. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat-JDG3w-leGNfkTmsj.woff +0 -0
  64. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat-JDW3w-ciElMF03ku.woff +0 -0
  65. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat8JCm3w-sB722Uoa0f.woff +0 -0
  66. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat8JDW3w-PBDI1JDjwV.woff +0 -0
  67. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat8gCm3w-0q1hqVn09O.woff +0 -0
  68. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat9XCm3w-ByvzuLy2fa.woff +0 -0
  69. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat9uCm3w-5TKCIs6EEw.woff +0 -0
  70. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat_XDW3w-r2swRDGfn2.woff +0 -0
  71. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAC5thTQ-ldB60l5U8r.woff +0 -0
  72. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAIpthTQ-wbFKGFDrgo.woff +0 -0
  73. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAIpxhTQ-LLUBv5jskj.woff +0 -0
  74. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwARZthTQ-F71RdTRbNg.woff +0 -0
  75. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwA_JxhTQ-6nh65gZkc0.woff +0 -0
  76. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAfJthTQ-aMoWEJLmTt.woff +0 -0
  77. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAkJxhTQ-WMBvmLOgKm.woff +0 -0
  78. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAop1hTQ-utGC2hnWq2.woff +0 -0
  79. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAopxhTQ-YpyTieVa5B.woff +0 -0
  80. package/dist/client/devtools/_nuxt/BDC8ywlR.js +1 -0
  81. package/dist/client/devtools/_nuxt/BT004Uxp.js +53 -0
  82. package/dist/client/devtools/_nuxt/C1H2Soz3.js +1 -0
  83. package/dist/client/devtools/_nuxt/builds/latest.json +1 -0
  84. package/dist/client/devtools/_nuxt/builds/meta/f98c13ea-d751-4b37-8ce3-94e99708745f.json +1 -0
  85. package/dist/client/devtools/_nuxt/entry.Bx6WJjrx.css +1 -0
  86. package/dist/client/devtools/_nuxt/error-404.Cq4qshcf.css +1 -0
  87. package/dist/client/devtools/_nuxt/error-500.ax1aM34m.css +1 -0
  88. package/dist/client/devtools/favicon.svg +1 -0
  89. package/dist/client/devtools/index.html +1 -0
  90. package/dist/devtools/runtime/DevtoolsRenderer.vue +53 -0
  91. package/dist/devtools/runtime/examples/AvatarGroupExample.vue +7 -0
  92. package/dist/devtools/runtime/examples/ButtonGroupExample.vue +8 -0
  93. package/dist/devtools/runtime/examples/CardExample.vue +13 -0
  94. package/dist/devtools/runtime/examples/CarouselExample.vue +13 -0
  95. package/dist/devtools/runtime/examples/ChipExample.vue +5 -0
  96. package/dist/devtools/runtime/examples/CollapsibleExample.vue +8 -0
  97. package/dist/devtools/runtime/examples/CommandPaletteExample.vue +29 -0
  98. package/dist/devtools/runtime/examples/ContainerExample.vue +5 -0
  99. package/dist/devtools/runtime/examples/ContextMenuExample.vue +5 -0
  100. package/dist/devtools/runtime/examples/DrawerExample.vue +8 -0
  101. package/dist/devtools/runtime/examples/DropdownMenuExample.vue +5 -0
  102. package/dist/devtools/runtime/examples/FormExample.vue +30 -0
  103. package/dist/devtools/runtime/examples/FormFieldExample.vue +5 -0
  104. package/dist/devtools/runtime/examples/LinkExample.vue +5 -0
  105. package/dist/devtools/runtime/examples/ModalExample.vue +8 -0
  106. package/dist/devtools/runtime/examples/PopoverExample.vue +8 -0
  107. package/dist/devtools/runtime/examples/SkeletonExample.vue +3 -0
  108. package/dist/devtools/runtime/examples/SlideoverExample.vue +8 -0
  109. package/dist/devtools/runtime/examples/ToasterExample.vue +11 -0
  110. package/dist/devtools/runtime/examples/TooltipExample.vue +5 -0
  111. package/dist/module.cjs +223 -4
  112. package/dist/module.d.cts +54 -0
  113. package/dist/module.d.mts +10 -0
  114. package/dist/module.d.ts +10 -0
  115. package/dist/module.json +1 -1
  116. package/dist/module.mjs +158 -2763
  117. package/dist/runtime/components/Accordion.vue +32 -1
  118. package/dist/runtime/components/Alert.vue +8 -1
  119. package/dist/runtime/components/App.vue +19 -5
  120. package/dist/runtime/components/Avatar.vue +23 -5
  121. package/dist/runtime/components/AvatarGroup.vue +3 -0
  122. package/dist/runtime/components/Badge.vue +33 -3
  123. package/dist/runtime/components/Breadcrumb.vue +33 -4
  124. package/dist/runtime/components/Button.vue +6 -1
  125. package/dist/runtime/components/ButtonGroup.vue +4 -1
  126. package/dist/runtime/components/Card.vue +3 -0
  127. package/dist/runtime/components/Carousel.vue +17 -8
  128. package/dist/runtime/components/Checkbox.vue +4 -0
  129. package/dist/runtime/components/Chip.vue +9 -2
  130. package/dist/runtime/components/Collapsible.vue +3 -0
  131. package/dist/runtime/components/CommandPalette.vue +8 -4
  132. package/dist/runtime/components/Container.vue +3 -0
  133. package/dist/runtime/components/ContextMenu.vue +64 -3
  134. package/dist/runtime/components/ContextMenuContent.vue +10 -8
  135. package/dist/runtime/components/Drawer.vue +3 -0
  136. package/dist/runtime/components/DropdownMenu.vue +52 -3
  137. package/dist/runtime/components/DropdownMenuContent.vue +10 -8
  138. package/dist/runtime/components/Form.vue +21 -20
  139. package/dist/runtime/components/FormField.vue +10 -3
  140. package/dist/runtime/components/Input.vue +1 -0
  141. package/dist/runtime/components/InputMenu.vue +118 -31
  142. package/dist/runtime/components/InputNumber.vue +192 -0
  143. package/dist/runtime/components/Kbd.vue +2 -0
  144. package/dist/runtime/components/Link.vue +69 -6
  145. package/dist/runtime/components/Modal.vue +15 -3
  146. package/dist/runtime/components/NavigationMenu.vue +95 -46
  147. package/dist/runtime/components/Pagination.vue +17 -6
  148. package/dist/runtime/components/PinInput.vue +96 -0
  149. package/dist/runtime/components/Popover.vue +20 -1
  150. package/dist/runtime/components/Progress.vue +1 -1
  151. package/dist/runtime/components/RadioGroup.vue +4 -1
  152. package/dist/runtime/components/Select.vue +24 -13
  153. package/dist/runtime/components/SelectMenu.vue +130 -42
  154. package/dist/runtime/components/Separator.vue +1 -1
  155. package/dist/runtime/components/Skeleton.vue +3 -0
  156. package/dist/runtime/components/Slideover.vue +15 -3
  157. package/dist/runtime/components/Slider.vue +1 -1
  158. package/dist/runtime/components/Switch.vue +5 -1
  159. package/dist/runtime/components/Table.vue +27 -8
  160. package/dist/runtime/components/Tabs.vue +20 -1
  161. package/dist/runtime/components/Textarea.vue +1 -1
  162. package/dist/runtime/components/Toast.vue +8 -1
  163. package/dist/runtime/components/Toaster.vue +29 -14
  164. package/dist/runtime/components/Tooltip.vue +3 -0
  165. package/dist/runtime/composables/defineLocale.d.ts +9 -0
  166. package/dist/runtime/composables/defineLocale.js +4 -0
  167. package/dist/runtime/composables/defineShortcuts.js +0 -6
  168. package/dist/runtime/composables/extendDevtoolsMeta.d.ts +7 -0
  169. package/dist/runtime/composables/extendDevtoolsMeta.js +2 -0
  170. package/dist/runtime/composables/useFormField.d.ts +4 -1
  171. package/dist/runtime/composables/useFormField.js +1 -1
  172. package/dist/runtime/composables/useKbd.d.ts +10 -3
  173. package/dist/runtime/composables/useKbd.js +14 -8
  174. package/dist/runtime/composables/useLocale.d.ts +4 -0
  175. package/dist/runtime/composables/useLocale.js +10 -0
  176. package/dist/runtime/index.css +1 -1
  177. package/dist/runtime/locale/ar.d.ts +2 -0
  178. package/dist/runtime/locale/ar.js +47 -0
  179. package/dist/runtime/locale/cs.d.ts +2 -0
  180. package/dist/runtime/locale/cs.js +46 -0
  181. package/dist/runtime/locale/de.d.ts +2 -0
  182. package/dist/runtime/locale/de.js +46 -0
  183. package/dist/runtime/locale/en.d.ts +2 -0
  184. package/dist/runtime/locale/en.js +46 -0
  185. package/dist/runtime/locale/es.d.ts +2 -0
  186. package/dist/runtime/locale/es.js +46 -0
  187. package/dist/runtime/locale/fa_ir.d.ts +2 -0
  188. package/dist/runtime/locale/fa_ir.js +47 -0
  189. package/dist/runtime/locale/fr.d.ts +2 -0
  190. package/dist/runtime/locale/fr.js +46 -0
  191. package/dist/runtime/locale/index.d.ts +12 -0
  192. package/dist/runtime/locale/index.js +12 -0
  193. package/dist/runtime/locale/it.d.ts +2 -0
  194. package/dist/runtime/locale/it.js +46 -0
  195. package/dist/runtime/locale/pl.d.ts +2 -0
  196. package/dist/runtime/locale/pl.js +46 -0
  197. package/dist/runtime/locale/ru.d.ts +2 -0
  198. package/dist/runtime/locale/ru.js +46 -0
  199. package/dist/runtime/locale/zh_hans.d.ts +2 -0
  200. package/dist/runtime/locale/zh_hans.js +46 -0
  201. package/dist/runtime/locale/zh_hant.d.ts +2 -0
  202. package/dist/runtime/locale/zh_hant.js +46 -0
  203. package/dist/runtime/types/form.d.ts +7 -2
  204. package/dist/runtime/types/index.d.ts +3 -0
  205. package/dist/runtime/types/index.js +3 -0
  206. package/dist/runtime/types/locale.d.ts +48 -0
  207. package/dist/runtime/types/locale.js +0 -0
  208. package/dist/runtime/types/utils.d.ts +7 -0
  209. package/dist/runtime/utils/form.d.ts +5 -9
  210. package/dist/runtime/utils/form.js +115 -50
  211. package/dist/runtime/utils/index.js +1 -1
  212. package/dist/runtime/utils/link.d.ts +2 -2
  213. package/dist/runtime/utils/locale.d.ts +15 -0
  214. package/dist/runtime/utils/locale.js +25 -0
  215. package/dist/runtime/vue/components/Icon.vue +15 -0
  216. package/dist/runtime/vue/components/Link.vue +195 -0
  217. package/dist/runtime/vue/plugins/color-mode.d.ts +4 -0
  218. package/dist/runtime/vue/plugins/color-mode.js +6 -0
  219. package/dist/runtime/vue/plugins/head.d.ts +4 -0
  220. package/dist/runtime/vue/plugins/head.js +6 -0
  221. package/dist/runtime/vue/stubs.d.ts +15 -0
  222. package/dist/runtime/vue/stubs.js +27 -0
  223. package/dist/shared/ui.BPnAe4QS.cjs +3030 -0
  224. package/dist/shared/ui.d52SSCwA.mjs +3023 -0
  225. package/dist/unplugin.cjs +192 -0
  226. package/dist/unplugin.d.cts +49 -0
  227. package/dist/unplugin.d.mts +49 -0
  228. package/dist/unplugin.d.ts +49 -0
  229. package/dist/unplugin.mjs +181 -0
  230. package/dist/vite.cjs +22 -0
  231. package/dist/vite.d.cts +13 -0
  232. package/dist/vite.d.mts +13 -0
  233. package/dist/vite.d.ts +13 -0
  234. package/dist/vite.mjs +20 -0
  235. package/package.json +78 -33
  236. package/vue-plugin.d.ts +5 -0
  237. package/cli/node_modules/.ignored/citty/LICENSE +0 -36
  238. package/cli/node_modules/.ignored/citty/README.md +0 -134
  239. package/cli/node_modules/.ignored/citty/dist/index.cjs +0 -475
  240. package/cli/node_modules/.ignored/citty/dist/index.d.cts +0 -80
  241. package/cli/node_modules/.ignored/citty/dist/index.d.mts +0 -80
  242. package/cli/node_modules/.ignored/citty/dist/index.d.ts +0 -80
  243. package/cli/node_modules/.ignored/citty/dist/index.mjs +0 -463
  244. package/cli/node_modules/.ignored/citty/package.json +0 -49
  245. package/cli/node_modules/.ignored/consola/LICENSE +0 -47
  246. package/cli/node_modules/.ignored/consola/README.md +0 -318
  247. package/cli/node_modules/.ignored/consola/core.d.ts +0 -1
  248. package/cli/node_modules/.ignored/consola/dist/basic.cjs +0 -32
  249. package/cli/node_modules/.ignored/consola/dist/basic.d.ts +0 -9
  250. package/cli/node_modules/.ignored/consola/dist/basic.mjs +0 -24
  251. package/cli/node_modules/.ignored/consola/dist/browser.cjs +0 -80
  252. package/cli/node_modules/.ignored/consola/dist/browser.d.ts +0 -7
  253. package/cli/node_modules/.ignored/consola/dist/browser.mjs +0 -72
  254. package/cli/node_modules/.ignored/consola/dist/chunks/prompt.cjs +0 -436
  255. package/cli/node_modules/.ignored/consola/dist/chunks/prompt.mjs +0 -429
  256. package/cli/node_modules/.ignored/consola/dist/core.cjs +0 -415
  257. package/cli/node_modules/.ignored/consola/dist/core.d.ts +0 -124
  258. package/cli/node_modules/.ignored/consola/dist/core.mjs +0 -410
  259. package/cli/node_modules/.ignored/consola/dist/index.cjs +0 -21
  260. package/cli/node_modules/.ignored/consola/dist/index.d.ts +0 -9
  261. package/cli/node_modules/.ignored/consola/dist/index.mjs +0 -8
  262. package/cli/node_modules/.ignored/consola/dist/shared/consola.06ad8a64.mjs +0 -62
  263. package/cli/node_modules/.ignored/consola/dist/shared/consola.36c0034f.mjs +0 -636
  264. package/cli/node_modules/.ignored/consola/dist/shared/consola.4bbae468.cjs +0 -645
  265. package/cli/node_modules/.ignored/consola/dist/shared/consola.deac7d5a.cjs +0 -65
  266. package/cli/node_modules/.ignored/consola/dist/utils.cjs +0 -308
  267. package/cli/node_modules/.ignored/consola/dist/utils.d.ts +0 -169
  268. package/cli/node_modules/.ignored/consola/dist/utils.mjs +0 -284
  269. package/cli/node_modules/.ignored/consola/lib/index.cjs +0 -9
  270. package/cli/node_modules/.ignored/consola/package.json +0 -101
  271. package/cli/node_modules/.ignored/consola/utils.d.ts +0 -1
  272. package/cli/node_modules/.ignored/pathe/LICENSE +0 -44
  273. package/cli/node_modules/.ignored/pathe/README.md +0 -69
  274. package/cli/node_modules/.ignored/pathe/dist/index.cjs +0 -23
  275. package/cli/node_modules/.ignored/pathe/dist/index.d.cts +0 -36
  276. package/cli/node_modules/.ignored/pathe/dist/index.d.mts +0 -36
  277. package/cli/node_modules/.ignored/pathe/dist/index.d.ts +0 -36
  278. package/cli/node_modules/.ignored/pathe/dist/index.mjs +0 -1
  279. package/cli/node_modules/.ignored/pathe/dist/shared/pathe.1f0a373c.cjs +0 -238
  280. package/cli/node_modules/.ignored/pathe/dist/shared/pathe.ff20891b.mjs +0 -221
  281. package/cli/node_modules/.ignored/pathe/dist/utils.cjs +0 -58
  282. package/cli/node_modules/.ignored/pathe/dist/utils.d.cts +0 -5
  283. package/cli/node_modules/.ignored/pathe/dist/utils.d.mts +0 -5
  284. package/cli/node_modules/.ignored/pathe/dist/utils.d.ts +0 -5
  285. package/cli/node_modules/.ignored/pathe/dist/utils.mjs +0 -54
  286. package/cli/node_modules/.ignored/pathe/package.json +0 -48
  287. package/cli/node_modules/.ignored/pathe/utils.d.ts +0 -1
  288. package/cli/node_modules/.ignored/scule/LICENSE +0 -21
  289. package/cli/node_modules/.ignored/scule/README.md +0 -149
  290. package/cli/node_modules/.ignored/scule/dist/index.cjs +0 -92
  291. package/cli/node_modules/.ignored/scule/dist/index.d.cts +0 -57
  292. package/cli/node_modules/.ignored/scule/dist/index.d.mts +0 -57
  293. package/cli/node_modules/.ignored/scule/dist/index.d.ts +0 -57
  294. package/cli/node_modules/.ignored/scule/dist/index.mjs +0 -80
  295. package/cli/node_modules/.ignored/scule/package.json +0 -43
  296. package/cli/node_modules/.package-lock.json +0 -33
@@ -1,26 +1,23 @@
1
- <!-- eslint-disable vue/block-tag-newline -->
2
1
  <script lang="ts">
3
2
  import { tv, type VariantProps } from 'tailwind-variants'
4
- import type { NavigationMenuRootProps, NavigationMenuRootEmits, NavigationMenuContentProps } from 'radix-vue'
3
+ import type { NavigationMenuRootProps, NavigationMenuRootEmits, NavigationMenuContentProps, CollapsibleRootProps } 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/navigation-menu'
7
+ import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
8
8
  import type { AvatarProps, BadgeProps, LinkProps } from '../types'
9
- import type { DynamicSlots, PartialString } from '../types/utils'
9
+ import type { DynamicSlots, MaybeArrayOfArray, MaybeArrayOfArrayItem, PartialString } from '../types/utils'
10
10
 
11
11
  const appConfig = _appConfig as AppConfig & { ui: { navigationMenu: Partial<typeof theme> } }
12
12
 
13
13
  const navigationMenu = tv({ extend: tv(theme), ...(appConfig.ui?.navigationMenu || {}) })
14
14
 
15
- export interface NavigationMenuChildItem extends Omit<LinkProps, 'raw' | 'custom'> {
16
- label: string
15
+ export interface NavigationMenuChildItem extends Omit<NavigationMenuItem, 'children'> {
16
+ /** Description is only used when `orientation` is `horizontal`. */
17
17
  description?: string
18
- icon?: string
19
- badge?: string | number | BadgeProps
20
- onSelect?(e: Event): void
21
18
  }
22
19
 
23
- export interface NavigationMenuItem extends Omit<LinkProps, 'raw' | 'custom'> {
20
+ export interface NavigationMenuItem extends Omit<LinkProps, 'raw' | 'custom'>, Pick<CollapsibleRootProps, 'defaultOpen' | 'open'> {
24
21
  label?: string
25
22
  icon?: string
26
23
  avatar?: AvatarProps
@@ -37,7 +34,7 @@ type NavigationMenuVariants = VariantProps<typeof navigationMenu>
37
34
  export interface NavigationMenuProps<T> extends Pick<NavigationMenuRootProps, 'defaultValue' | 'delayDuration' | 'disableClickTrigger' | 'disableHoverTrigger' | 'modelValue' | 'skipDelayDuration'> {
38
35
  /**
39
36
  * The element or component this component should render as.
40
- * @defaultValue `div`
37
+ * @defaultValue 'div'
41
38
  */
42
39
  as?: any
43
40
  /**
@@ -45,7 +42,7 @@ export interface NavigationMenuProps<T> extends Pick<NavigationMenuRootProps, 'd
45
42
  * @defaultValue appConfig.ui.icons.chevronDown
46
43
  */
47
44
  trailingIcon?: string
48
- items?: T[] | T[][]
45
+ items?: T
49
46
  color?: NavigationMenuVariants['color']
50
47
  variant?: NavigationMenuVariants['variant']
51
48
  /**
@@ -81,14 +78,53 @@ export type NavigationMenuSlots<T extends { slot?: string }> = {
81
78
  'item-leading': SlotProps<T>
82
79
  'item-label': SlotProps<T>
83
80
  'item-trailing': SlotProps<T>
81
+ 'item-content': SlotProps<T>
84
82
  } & DynamicSlots<T, SlotProps<T>>
85
83
 
84
+ extendDevtoolsMeta({
85
+ ignoreProps: ['items'],
86
+ defaultProps: {
87
+ items: [
88
+ [{
89
+ label: 'Documentation',
90
+ icon: 'i-lucide-book-open',
91
+ badge: 10,
92
+ children: [{
93
+ label: 'Introduction',
94
+ description: 'Fully styled and customizable components for Nuxt.',
95
+ icon: 'i-lucide-house'
96
+ }, {
97
+ label: 'Installation',
98
+ description: 'Learn how to install and configure Nuxt UI in your application.',
99
+ icon: 'i-lucide-cloud-download'
100
+ }, {
101
+ label: 'Theming',
102
+ description: 'Learn how to customize the look and feel of the components.',
103
+ icon: 'i-lucide-swatch-book'
104
+ }, {
105
+ label: 'Shortcuts',
106
+ description: 'Learn how to display and define keyboard shortcuts in your app.',
107
+ icon: 'i-lucide-monitor'
108
+ }]
109
+ }, {
110
+ label: 'GitHub',
111
+ icon: 'i-simple-icons-github',
112
+ to: 'https://github.com/nuxt/ui',
113
+ target: '_blank'
114
+ }, {
115
+ label: 'Help',
116
+ icon: 'i-lucide-circle-help',
117
+ disabled: true
118
+ }]
119
+ ]
120
+ }
121
+ })
86
122
  </script>
87
123
 
88
- <script setup lang="ts" generic="T extends NavigationMenuItem">
89
- import { computed, toRef } from 'vue'
124
+ <script setup lang="ts" generic="T extends MaybeArrayOfArrayItem<I>, I extends MaybeArrayOfArray<NavigationMenuItem>">
125
+ import { computed, reactive, toRef } from 'vue'
90
126
  import { NavigationMenuRoot, NavigationMenuList, NavigationMenuItem, NavigationMenuTrigger, NavigationMenuContent, NavigationMenuLink, NavigationMenuIndicator, NavigationMenuViewport, useForwardPropsEmits } from 'radix-vue'
91
- import { reactivePick, createReusableTemplate } from '@vueuse/core'
127
+ import { createReusableTemplate } from '@vueuse/core'
92
128
  import { get } from '../utils'
93
129
  import { pickLinkProps } from '../utils/link'
94
130
  import ULinkBase from './LinkBase.vue'
@@ -98,7 +134,7 @@ import UIcon from './Icon.vue'
98
134
  import UBadge from './Badge.vue'
99
135
  import UCollapsible from './Collapsible.vue'
100
136
 
101
- const props = withDefaults(defineProps<NavigationMenuProps<T>>(), {
137
+ const props = withDefaults(defineProps<NavigationMenuProps<I>>(), {
102
138
  orientation: 'horizontal',
103
139
  delayDuration: 0,
104
140
  labelKey: 'label'
@@ -106,7 +142,15 @@ const props = withDefaults(defineProps<NavigationMenuProps<T>>(), {
106
142
  const emits = defineEmits<NavigationMenuEmits>()
107
143
  const slots = defineSlots<NavigationMenuSlots<T>>()
108
144
 
109
- const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'modelValue', 'defaultValue', 'delayDuration', 'skipDelayDuration', 'orientation'), emits)
145
+ const rootProps = useForwardPropsEmits(reactive({
146
+ as: props.as,
147
+ modelValue: props.modelValue,
148
+ defaultValue: props.defaultValue,
149
+ delayDuration: props.delayDuration,
150
+ skipDelayDuration: props.skipDelayDuration,
151
+ orientation: props.orientation
152
+ }), emits)
153
+
110
154
  const contentProps = toRef(() => props.content)
111
155
 
112
156
  const [DefineItemTemplate, ReuseItemTemplate] = createReusableTemplate<{ item: NavigationMenuItem, active?: boolean, index: number }>()
@@ -148,13 +192,14 @@ const lists = computed(() => props.items?.length ? (Array.isArray(props.items[0]
148
192
  v-bind="(typeof item.badge === 'string' || typeof item.badge === 'number') ? { label: item.badge } : item.badge"
149
193
  :class="ui.linkTrailingBadge({ class: props.ui?.linkTrailingBadge })"
150
194
  />
151
- <UIcon v-if="item.children?.length" :name="item.trailingIcon || trailingIcon || appConfig.ui.icons.chevronDown" :class="ui.linkTrailingIcon({ class: props.ui?.linkTrailingIcon, active })" />
195
+
196
+ <UIcon v-if="(orientation === 'horizontal' && (item.children?.length || !!slots[item.slot ? `${item.slot}-content` : 'item-content'])) || (orientation === 'vertical' && item.children?.length)" :name="item.trailingIcon || trailingIcon || appConfig.ui.icons.chevronDown" :class="ui.linkTrailingIcon({ class: props.ui?.linkTrailingIcon, active })" />
152
197
  </slot>
153
198
  </span>
154
199
  </slot>
155
200
  </DefineItemTemplate>
156
201
 
157
- <NavigationMenuRoot v-bind="rootProps" :class="ui.root({ class: [props.class, props.ui?.root] })">
202
+ <NavigationMenuRoot v-bind="rootProps" :data-orientation="orientation" :class="ui.root({ class: [props.class, props.ui?.root] })">
158
203
  <template v-for="(list, listIndex) in lists" :key="`list-${listIndex}`">
159
204
  <NavigationMenuList :class="ui.list({ class: props.ui?.list })">
160
205
  <component
@@ -163,54 +208,58 @@ const lists = computed(() => props.items?.length ? (Array.isArray(props.items[0]
163
208
  :key="`list-${listIndex}-${index}`"
164
209
  as="li"
165
210
  :value="item.value || String(index)"
211
+ :default-open="item.defaultOpen"
212
+ :open="item.open"
166
213
  :class="ui.item({ class: props.ui?.item })"
167
214
  >
168
215
  <ULink v-slot="{ active, ...slotProps }" v-bind="pickLinkProps(item)" custom>
169
216
  <component
170
- :is="(item.children?.length && orientation === 'horizontal') ? NavigationMenuTrigger : NavigationMenuLink"
171
- v-bind="item.children?.length ? { disabled: item.disabled } : { active }"
217
+ :is="(orientation === 'horizontal' && (item.children?.length || !!slots[item.slot ? `${item.slot}-content` : 'item-content'])) ? NavigationMenuTrigger : NavigationMenuLink"
172
218
  as-child
173
219
  :active="active"
220
+ :disabled="item.disabled"
174
221
  @select="item.onSelect"
175
222
  >
176
223
  <ULinkBase v-bind="slotProps" :class="ui.link({ class: [props.ui?.link, item.class], active, disabled: !!item.disabled })">
177
- <ReuseItemTemplate :item="item" :active="active" :index="index" />
224
+ <ReuseItemTemplate :item="(item as T)" :active="active" :index="index" />
178
225
  </ULinkBase>
179
226
  </component>
180
227
 
181
- <NavigationMenuContent v-if="item.children?.length && orientation === 'horizontal'" v-bind="contentProps" :class="ui.content({ class: props.ui?.content })">
182
- <ul :class="ui.childList({ class: props.ui?.childList })">
183
- <li v-for="(childItem, childIndex) in item.children" :key="childIndex" :class="ui.childItem({ class: props.ui?.childItem })">
184
- <ULink v-slot="{ active: childActive, ...childSlotProps }" v-bind="pickLinkProps(childItem)" custom>
185
- <NavigationMenuLink as-child :active="childActive" @select="childItem.onSelect">
186
- <ULinkBase v-bind="childSlotProps" :class="ui.childLink({ class: [props.ui?.childLink, childItem.class], active: childActive })">
187
- <UIcon v-if="childItem.icon" :name="childItem.icon" :class="ui.childLinkIcon({ class: props.ui?.childLinkIcon, active: childActive })" />
188
-
189
- <div :class="ui.childLinkWrapper({ class: props.ui?.childLinkWrapper })">
190
- <p :class="ui.childLinkLabel({ class: props.ui?.childLinkLabel, active: childActive })">
191
- {{ get(childItem, props.labelKey as string) }}
192
-
193
- <UIcon v-if="childItem.target === '_blank'" :name="appConfig.ui.icons.external" :class="ui.childLinkLabelExternalIcon({ class: props.ui?.childLinkLabelExternalIcon, active: childActive })" />
194
- </p>
195
- <p v-if="childItem.description" :class="ui.childLinkDescription({ class: props.ui?.childLinkDescription, active: childActive })">
196
- {{ childItem.description }}
197
- </p>
198
- </div>
199
- </ULinkBase>
200
- </NavigationMenuLink>
201
- </ULink>
202
- </li>
203
- </ul>
228
+ <NavigationMenuContent v-if="orientation === 'horizontal' && (item.children?.length || !!slots[item.slot ? `${item.slot}-content` : 'item-content'])" v-bind="contentProps" :class="ui.content({ class: props.ui?.content })">
229
+ <slot :name="item.slot ? `${item.slot}-content` : 'item-content'" :item="(item as T)" :active="active" :index="index">
230
+ <ul :class="ui.childList({ class: props.ui?.childList })">
231
+ <li v-for="(childItem, childIndex) in item.children" :key="childIndex" :class="ui.childItem({ class: props.ui?.childItem })">
232
+ <ULink v-slot="{ active: childActive, ...childSlotProps }" v-bind="pickLinkProps(childItem)" custom>
233
+ <NavigationMenuLink as-child :active="childActive" @select="childItem.onSelect">
234
+ <ULinkBase v-bind="childSlotProps" :class="ui.childLink({ class: [props.ui?.childLink, childItem.class], active: childActive })">
235
+ <UIcon v-if="childItem.icon" :name="childItem.icon" :class="ui.childLinkIcon({ class: props.ui?.childLinkIcon, active: childActive })" />
236
+
237
+ <div :class="ui.childLinkWrapper({ class: props.ui?.childLinkWrapper })">
238
+ <p :class="ui.childLinkLabel({ class: props.ui?.childLinkLabel, active: childActive })">
239
+ {{ get(childItem, props.labelKey as string) }}
240
+
241
+ <UIcon v-if="childItem.target === '_blank'" :name="appConfig.ui.icons.external" :class="ui.childLinkLabelExternalIcon({ class: props.ui?.childLinkLabelExternalIcon, active: childActive })" />
242
+ </p>
243
+ <p v-if="childItem.description" :class="ui.childLinkDescription({ class: props.ui?.childLinkDescription, active: childActive })">
244
+ {{ childItem.description }}
245
+ </p>
246
+ </div>
247
+ </ULinkBase>
248
+ </NavigationMenuLink>
249
+ </ULink>
250
+ </li>
251
+ </ul>
252
+ </slot>
204
253
  </NavigationMenuContent>
205
254
  </ULink>
206
255
 
207
- <template v-if="item.children?.length && orientation === 'vertical'" #content>
256
+ <template v-if="orientation === 'vertical' && item.children?.length" #content>
208
257
  <ul :class="ui.childList({ class: props.ui?.childList })">
209
258
  <li v-for="(childItem, childIndex) in item.children" :key="childIndex" :class="ui.childItem({ class: props.ui?.childItem })">
210
259
  <ULink v-slot="{ active: childActive, ...childSlotProps }" v-bind="pickLinkProps(childItem)" custom>
211
260
  <NavigationMenuLink as-child :active="childActive" @select="childItem.onSelect">
212
261
  <ULinkBase v-bind="childSlotProps" :class="ui.link({ class: [props.ui?.link, childItem.class], active: childActive, disabled: !!childItem.disabled })">
213
- <ReuseItemTemplate :item="childItem" :active="childActive" :index="childIndex" />
262
+ <ReuseItemTemplate :item="(childItem as T)" :active="childActive" :index="childIndex" />
214
263
  </ULinkBase>
215
264
  </NavigationMenuLink>
216
265
  </ULink>
@@ -5,6 +5,7 @@ import type { AppConfig } from '@nuxt/schema'
5
5
  import type { RouteLocationRaw } from '#vue-router'
6
6
  import _appConfig from '#build/app.config'
7
7
  import theme from '#build/ui/pagination'
8
+ import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
8
9
  import type { ButtonProps } from '../types'
9
10
 
10
11
  const appConfig = _appConfig as AppConfig & { ui: { pagination: Partial<typeof theme> } }
@@ -14,7 +15,7 @@ const pagination = tv({ extend: tv(theme), ...(appConfig.ui?.pagination || {}) }
14
15
  export interface PaginationProps extends Pick<PaginationRootProps, 'defaultPage' | 'disabled' | 'itemsPerPage' | 'page' | 'showEdges' | 'siblingCount' | 'total'> {
15
16
  /**
16
17
  * The element or component this component should render as.
17
- * @defaultValue `div`
18
+ * @defaultValue 'div'
18
19
  */
19
20
  as?: any
20
21
  /**
@@ -97,12 +98,17 @@ export interface PaginationSlots {
97
98
  index: number
98
99
  }): any
99
100
  }
101
+
102
+ extendDevtoolsMeta({ defaultProps: { total: 50 } })
100
103
  </script>
101
104
 
102
105
  <script setup lang="ts">
106
+ import { computed } from 'vue'
103
107
  import { PaginationRoot, PaginationList, PaginationListItem, PaginationFirst, PaginationPrev, PaginationEllipsis, PaginationNext, PaginationLast, useForwardPropsEmits } from 'radix-vue'
104
108
  import { reactivePick } from '@vueuse/core'
105
109
  import { useAppConfig } from '#imports'
110
+ import { useLocale } from '../composables/useLocale'
111
+ import UButton from './Button.vue'
106
112
 
107
113
  const props = withDefaults(defineProps<PaginationProps>(), {
108
114
  size: 'md',
@@ -120,9 +126,14 @@ const emits = defineEmits<PaginationEmits>()
120
126
  const slots = defineSlots<PaginationSlots>()
121
127
 
122
128
  const appConfig = useAppConfig()
123
-
129
+ const { dir } = useLocale()
124
130
  const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'defaultPage', 'disabled', 'itemsPerPage', 'page', 'showEdges', 'siblingCount', 'total'), emits)
125
131
 
132
+ const firstIcon = computed(() => props.firstIcon || (dir.value === 'rtl' ? appConfig.ui.icons.chevronDoubleRight : appConfig.ui.icons.chevronDoubleLeft))
133
+ const prevIcon = computed(() => props.prevIcon || (dir.value === 'rtl' ? appConfig.ui.icons.chevronRight : appConfig.ui.icons.chevronLeft))
134
+ const nextIcon = computed(() => props.nextIcon || (dir.value === 'rtl' ? appConfig.ui.icons.chevronLeft : appConfig.ui.icons.chevronRight))
135
+ const lastIcon = computed(() => props.lastIcon || (dir.value === 'rtl' ? appConfig.ui.icons.chevronDoubleLeft : appConfig.ui.icons.chevronDoubleRight))
136
+
126
137
  // eslint-disable-next-line vue/no-dupe-keys
127
138
  const ui = pagination()
128
139
  </script>
@@ -132,12 +143,12 @@ const ui = pagination()
132
143
  <PaginationList v-slot="{ items }" :class="ui.list({ class: props.ui?.list })">
133
144
  <PaginationFirst v-if="showControls || !!slots.first" as-child>
134
145
  <slot name="first">
135
- <UButton :color="color" :variant="variant" :size="size" :icon="firstIcon || appConfig.ui.icons.chevronDoubleLeft" :to="to?.(1)" />
146
+ <UButton :color="color" :variant="variant" :size="size" :icon="firstIcon" :to="to?.(1)" />
136
147
  </slot>
137
148
  </PaginationFirst>
138
149
  <PaginationPrev v-if="showControls || !!slots.prev" as-child>
139
150
  <slot name="prev">
140
- <UButton :color="color" :variant="variant" :size="size" :icon="prevIcon || appConfig.ui.icons.chevronLeft" :to="page > 1 ? to?.(page - 1) : undefined" />
151
+ <UButton :color="color" :variant="variant" :size="size" :icon="prevIcon" :to="page > 1 ? to?.(page - 1) : undefined" />
141
152
  </slot>
142
153
  </PaginationPrev>
143
154
 
@@ -165,12 +176,12 @@ const ui = pagination()
165
176
 
166
177
  <PaginationNext v-if="showControls || !!slots.next" as-child>
167
178
  <slot name="next">
168
- <UButton :color="color" :variant="variant" :size="size" :icon="nextIcon || appConfig.ui.icons.chevronRight" :to="page < pageCount ? to?.(pageCount) : undefined" />
179
+ <UButton :color="color" :variant="variant" :size="size" :icon="nextIcon" :to="page < pageCount ? to?.(pageCount) : undefined" />
169
180
  </slot>
170
181
  </PaginationNext>
171
182
  <PaginationLast v-if="showControls || !!slots.last" as-child>
172
183
  <slot name="last">
173
- <UButton :color="color" :variant="variant" :size="size" :icon="lastIcon || appConfig.ui.icons.chevronDoubleRight" :to=" to?.(pageCount)" />
184
+ <UButton :color="color" :variant="variant" :size="size" :icon="lastIcon" :to=" to?.(pageCount)" />
174
185
  </slot>
175
186
  </PaginationLast>
176
187
  </PaginationList>
@@ -0,0 +1,96 @@
1
+ <script lang="ts">
2
+ import _appConfig from '#build/app.config'
3
+ import theme from '#build/ui/pin-input'
4
+ import type { AppConfig } from '@nuxt/schema'
5
+ import type { PinInputRootEmits, PinInputRootProps } from 'radix-vue'
6
+ import { tv, type VariantProps } from 'tailwind-variants'
7
+ import type { PartialString } from '../types/utils'
8
+
9
+ const appConfig = _appConfig as AppConfig & { ui: { pinInput: Partial<typeof theme> } }
10
+
11
+ const pinInput = tv({ extend: tv(theme), ...(appConfig.ui?.pinInput || {}) })
12
+
13
+ type PinInputVariants = VariantProps<typeof pinInput>
14
+
15
+ export interface PinInputProps extends Pick<PinInputRootProps, 'defaultValue' | 'disabled' | 'id' | 'mask' | 'modelValue' | 'name' | 'otp' | 'placeholder' | 'required' | 'type'> {
16
+ /**
17
+ * The element or component this component should render as.
18
+ * @defaultValue 'div'
19
+ */
20
+ as?: any
21
+ color?: PinInputVariants['color']
22
+ variant?: PinInputVariants['variant']
23
+ size?: PinInputVariants['size']
24
+ length?: number | string
25
+ highlight?: boolean
26
+ class?: any
27
+ ui?: PartialString<typeof pinInput.slots>
28
+ }
29
+
30
+ export type PinInputEmits = PinInputRootEmits & {
31
+ change: [payload: Event]
32
+ blur: [payload: Event]
33
+ }
34
+ </script>
35
+
36
+ <script setup lang="ts">
37
+ import { ref, computed } from 'vue'
38
+ import { PinInputInput, PinInputRoot, useForwardPropsEmits } from 'radix-vue'
39
+ import { reactivePick } from '@vueuse/core'
40
+ import { useFormField } from '../composables/useFormField'
41
+ import { looseToNumber } from '../utils'
42
+
43
+ defineOptions({ inheritAttrs: false })
44
+
45
+ const props = withDefaults(defineProps<PinInputProps>(), {
46
+ type: 'text',
47
+ length: 5
48
+ })
49
+ const emits = defineEmits<PinInputEmits>()
50
+
51
+ const rootProps = useForwardPropsEmits(reactivePick(props, 'defaultValue', 'disabled', 'id', 'mask', 'modelValue', 'name', 'otp', 'placeholder', 'required', 'type'), emits)
52
+ const { emitFormInput, emitFormChange, emitFormBlur, size, color, id, name, highlight, disabled } = useFormField<PinInputProps>(props)
53
+
54
+ const ui = computed(() => pinInput({
55
+ color: color.value,
56
+ variant: props.variant,
57
+ size: size.value,
58
+ highlight: highlight.value
59
+ }))
60
+
61
+ const completed = ref(false)
62
+ function onComplete(value: string[]) {
63
+ // @ts-expect-error - 'target' does not exist in type 'EventInit'
64
+ const event = new Event('change', { target: { value } })
65
+ emits('change', event)
66
+ emitFormChange()
67
+ }
68
+
69
+ function onBlur(event: FocusEvent) {
70
+ if (!event.relatedTarget || completed.value) {
71
+ emits('blur', event)
72
+ emitFormBlur()
73
+ }
74
+ }
75
+ </script>
76
+
77
+ <template>
78
+ <PinInputRoot
79
+ v-bind="rootProps"
80
+ :id="id"
81
+ :name="name"
82
+ :class="ui.root({ class: [props.class, props.ui?.root] })"
83
+ @update:model-value="emitFormInput()"
84
+ @complete="onComplete"
85
+ >
86
+ <PinInputInput
87
+ v-for="(ids, index) in looseToNumber(props.length)"
88
+ :key="ids"
89
+ :index="index"
90
+ :class="ui.base({ class: props.ui?.base })"
91
+ v-bind="$attrs"
92
+ :disabled="disabled"
93
+ @blur="onBlur"
94
+ />
95
+ </PinInputRoot>
96
+ </template>
@@ -4,6 +4,7 @@ import type { PopoverRootProps, HoverCardRootProps, PopoverRootEmits, PopoverCon
4
4
  import type { AppConfig } from '@nuxt/schema'
5
5
  import _appConfig from '#build/app.config'
6
6
  import theme from '#build/ui/popover'
7
+ import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
7
8
 
8
9
  const appConfig = _appConfig as AppConfig & { ui: { popover: Partial<typeof theme> } }
9
10
 
@@ -30,6 +31,11 @@ export interface PopoverProps extends PopoverRootProps, Pick<HoverCardRootProps,
30
31
  * @defaultValue true
31
32
  */
32
33
  portal?: boolean
34
+ /**
35
+ * When `true`, the popover will not close when clicking outside.
36
+ * @defaultValue false
37
+ */
38
+ preventClose?: boolean
33
39
  class?: any
34
40
  ui?: Partial<typeof popover.slots>
35
41
  }
@@ -40,6 +46,8 @@ export interface PopoverSlots {
40
46
  default(props: { open: boolean }): any
41
47
  content(props?: {}): any
42
48
  }
49
+
50
+ extendDevtoolsMeta({ example: 'PopoverExample' })
43
51
  </script>
44
52
 
45
53
  <script setup lang="ts">
@@ -61,6 +69,17 @@ const slots = defineSlots<PopoverSlots>()
61
69
  const pick = props.mode === 'hover' ? reactivePick(props, 'defaultOpen', 'open', 'openDelay', 'closeDelay') : reactivePick(props, 'defaultOpen', 'open', 'modal')
62
70
  const rootProps = useForwardPropsEmits(pick, emits)
63
71
  const contentProps = toRef(() => defu(props.content, { side: 'bottom', sideOffset: 8 }) as PopoverContentProps)
72
+ const contentEvents = computed(() => {
73
+ if (props.preventClose) {
74
+ return {
75
+ pointerDownOutside: (e: Event) => e.preventDefault(),
76
+ interactOutside: (e: Event) => e.preventDefault(),
77
+ escapeKeyDown: (e: Event) => e.preventDefault()
78
+ }
79
+ }
80
+
81
+ return {}
82
+ })
64
83
  const arrowProps = toRef(() => props.arrow as PopoverArrowProps)
65
84
 
66
85
  // eslint-disable-next-line vue/no-dupe-keys
@@ -78,7 +97,7 @@ const Component = computed(() => props.mode === 'hover' ? HoverCard : Popover)
78
97
  </Component.Trigger>
79
98
 
80
99
  <Component.Portal :disabled="!portal">
81
- <Component.Content v-bind="contentProps" :class="ui.content({ class: [props.class, props.ui?.content] })">
100
+ <Component.Content v-bind="contentProps" :class="ui.content({ class: [props.class, props.ui?.content] })" v-on="contentEvents">
82
101
  <slot name="content" />
83
102
 
84
103
  <Component.Arrow v-if="!!arrow" v-bind="arrowProps" :class="ui.arrow({ class: props.ui?.arrow })" />
@@ -15,7 +15,7 @@ type ProgressVariants = VariantProps<typeof progress>
15
15
  export interface ProgressProps extends Pick<ProgressRootProps, 'getValueLabel' | 'modelValue'> {
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
  /** The maximum progress value. */
@@ -4,6 +4,7 @@ import type { RadioGroupRootProps, RadioGroupRootEmits } 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/radio-group'
7
+ import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
7
8
  import type { AcceptableValue } from '../types/utils'
8
9
 
9
10
  const appConfig = _appConfig as AppConfig & { ui: { radioGroup: Partial<typeof theme> } }
@@ -22,7 +23,7 @@ export interface RadioGroupItem {
22
23
  export interface RadioGroupProps<T> extends Pick<RadioGroupRootProps, 'defaultValue' | 'disabled' | 'loop' | 'modelValue' | 'name' | 'required'> {
23
24
  /**
24
25
  * The element or component this component should render as.
25
- * @defaultValue `div`
26
+ * @defaultValue 'div'
26
27
  */
27
28
  as?: any
28
29
  legend?: string
@@ -64,6 +65,8 @@ export interface RadioGroupSlots<T> {
64
65
  label: SlotProps<T>
65
66
  description: SlotProps<T>
66
67
  }
68
+
69
+ extendDevtoolsMeta({ defaultProps: { items: ['Option 1', 'Option 2', 'Option 3'] } })
67
70
  </script>
68
71
 
69
72
  <script setup lang="ts" generic="T extends RadioGroupItem | AcceptableValue">
@@ -5,8 +5,9 @@ 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
 
@@ -28,7 +29,7 @@ export interface SelectItem {
28
29
 
29
30
  type SelectVariants = VariantProps<typeof select>
30
31
 
31
- 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 {
32
33
  id?: string
33
34
  /** The placeholder text when the select is empty. */
34
35
  placeholder?: string
@@ -64,24 +65,26 @@ export interface SelectProps<T> extends Omit<SelectRootProps, 'dir'>, UseCompone
64
65
  * When `items` is an array of objects, select the field to use as the value.
65
66
  * @defaultValue 'value'
66
67
  */
67
- valueKey?: string
68
+ valueKey?: V
68
69
  /**
69
70
  * When `items` is an array of objects, select the field to use as the label.
70
71
  * @defaultValue 'label'
71
72
  */
72
- labelKey?: string
73
- items?: T[] | T[][]
73
+ labelKey?: V
74
+ items?: I
74
75
  /** Highlight the ring color like a focus state. */
75
76
  highlight?: boolean
76
77
  class?: any
77
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>
78
81
  }
79
82
 
80
- export type SelectEmits = SelectRootEmits & {
83
+ export type SelectEmits<T, V> = Omit<SelectRootEmits, 'update:modelValue'> & {
81
84
  change: [payload: Event]
82
85
  blur: [payload: FocusEvent]
83
86
  focus: [payload: FocusEvent]
84
- }
87
+ } & SelectModelValueEmits<T, V, false, T extends { value: infer U } ? U : never>
85
88
 
86
89
  type SlotProps<T> = (props: { item: T, index: number }) => any
87
90
 
@@ -93,11 +96,13 @@ export interface SelectSlots<T> {
93
96
  'item-label': SlotProps<T>
94
97
  'item-trailing': SlotProps<T>
95
98
  }
99
+
100
+ extendDevtoolsMeta({ defaultProps: { items: ['Option 1', 'Option 2', 'Option 3'] } })
96
101
  </script>
97
102
 
98
- <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">
99
104
  import { computed, toRef } from 'vue'
100
- 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'
101
106
  import { defu } from 'defu'
102
107
  import { reactivePick } from '@vueuse/core'
103
108
  import { useAppConfig } from '#imports'
@@ -109,17 +114,18 @@ import UIcon from './Icon.vue'
109
114
  import UAvatar from './Avatar.vue'
110
115
  import UChip from './Chip.vue'
111
116
 
112
- const props = withDefaults(defineProps<SelectProps<T>>(), {
113
- valueKey: 'value',
114
- labelKey: 'label',
117
+ const props = withDefaults(defineProps<SelectProps<T, I, V>>(), {
118
+ valueKey: 'value' as never,
119
+ labelKey: 'label' as never,
115
120
  portal: true
116
121
  })
117
- const emits = defineEmits<SelectEmits>()
122
+ const emits = defineEmits<SelectEmits<T, V>>()
118
123
  const slots = defineSlots<SelectSlots<T>>()
119
124
 
120
125
  const appConfig = useAppConfig()
121
126
  const rootProps = useForwardPropsEmits(reactivePick(props, 'modelValue', 'defaultValue', 'open', 'defaultOpen', 'disabled', 'autocomplete', 'required'), emits)
122
127
  const contentProps = toRef(() => defu(props.content, { side: 'bottom', sideOffset: 8, position: 'popper' }) as SelectContentProps)
128
+ const arrowProps = toRef(() => props.arrow as SelectArrowProps)
123
129
 
124
130
  const { emitFormChange, emitFormInput, emitFormBlur, size: formGroupSize, color, id, name, highlight, disabled } = useFormField<InputProps>(props)
125
131
  const { orientation, size: buttonGroupSize } = useButtonGroup<InputProps>(props)
@@ -166,6 +172,9 @@ function onUpdateOpen(value: boolean) {
166
172
  v-slot="{ modelValue, open }"
167
173
  v-bind="rootProps"
168
174
  :name="name"
175
+ :default-value="(defaultValue as string)"
176
+ :model-value="(modelValue as string)"
177
+ :autocomplete="autocomplete"
169
178
  :disabled="disabled"
170
179
  @update:model-value="onUpdate"
171
180
  @update:open="onUpdateOpen"
@@ -236,6 +245,8 @@ function onUpdateOpen(value: boolean) {
236
245
  </template>
237
246
  </SelectGroup>
238
247
  </SelectViewport>
248
+
249
+ <SelectArrow v-if="!!arrow" v-bind="arrowProps" :class="ui.arrow({ class: props.ui?.arrow })" />
239
250
  </SelectContent>
240
251
  </SelectPortal>
241
252
  </SelectRoot>