@nuxt/ui 3.0.0-alpha.8 → 3.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (310) hide show
  1. package/.nuxt/ui/accordion.ts +2 -2
  2. package/.nuxt/ui/alert.ts +122 -95
  3. package/.nuxt/ui/avatar-group.ts +14 -2
  4. package/.nuxt/ui/avatar.ts +16 -4
  5. package/.nuxt/ui/badge.ts +139 -93
  6. package/.nuxt/ui/breadcrumb.ts +5 -5
  7. package/.nuxt/ui/button-group.ts +13 -0
  8. package/.nuxt/ui/button.ts +167 -136
  9. package/.nuxt/ui/calendar.ts +103 -0
  10. package/.nuxt/ui/card.ts +27 -1
  11. package/.nuxt/ui/carousel.ts +9 -7
  12. package/.nuxt/ui/checkbox.ts +45 -27
  13. package/.nuxt/ui/chip.ts +44 -15
  14. package/.nuxt/ui/color-picker.ts +47 -0
  15. package/.nuxt/ui/command-palette.ts +28 -18
  16. package/.nuxt/ui/container.ts +1 -1
  17. package/.nuxt/ui/context-menu.ts +64 -46
  18. package/.nuxt/ui/drawer.ts +83 -15
  19. package/.nuxt/ui/dropdown-menu.ts +65 -47
  20. package/.nuxt/ui/form-field.ts +15 -7
  21. package/.nuxt/ui/index.ts +7 -1
  22. package/.nuxt/ui/input-menu.ts +150 -116
  23. package/.nuxt/ui/input-number.ts +235 -0
  24. package/.nuxt/ui/input.ts +111 -76
  25. package/.nuxt/ui/kbd.ts +18 -6
  26. package/.nuxt/ui/link.ts +3 -3
  27. package/.nuxt/ui/modal.ts +8 -7
  28. package/.nuxt/ui/navigation-menu.ts +244 -131
  29. package/.nuxt/ui/pin-input.ts +171 -0
  30. package/.nuxt/ui/popover.ts +2 -2
  31. package/.nuxt/ui/progress.ts +111 -72
  32. package/.nuxt/ui/radio-group.ts +45 -22
  33. package/.nuxt/ui/select-menu.ts +127 -96
  34. package/.nuxt/ui/select.ts +120 -84
  35. package/.nuxt/ui/separator.ts +60 -31
  36. package/.nuxt/ui/skeleton.ts +1 -1
  37. package/.nuxt/ui/slideover.ts +17 -9
  38. package/.nuxt/ui/slider.ts +61 -38
  39. package/.nuxt/ui/stepper.ts +202 -0
  40. package/.nuxt/ui/switch.ts +40 -22
  41. package/.nuxt/ui/table.ts +49 -31
  42. package/.nuxt/ui/tabs.ts +101 -73
  43. package/.nuxt/ui/textarea.ts +111 -76
  44. package/.nuxt/ui/toast.ts +53 -33
  45. package/.nuxt/ui/toaster.ts +31 -15
  46. package/.nuxt/ui/tooltip.ts +2 -2
  47. package/.nuxt/ui/tree.ts +154 -0
  48. package/.nuxt/ui.css +92 -0
  49. package/README.md +69 -18
  50. package/cli/commands/{init.mjs → make/component.mjs} +16 -4
  51. package/cli/commands/make/index.mjs +14 -0
  52. package/cli/commands/make/locale.mjs +64 -0
  53. package/cli/index.mjs +2 -2
  54. package/cli/package.json +2 -2
  55. package/cli/templates.mjs +62 -12
  56. package/cli/utils.mjs +14 -0
  57. package/dist/module.cjs +9 -170
  58. package/dist/module.d.cts +5 -15
  59. package/dist/module.d.mts +5 -15
  60. package/dist/module.d.ts +5 -15
  61. package/dist/module.json +2 -2
  62. package/dist/module.mjs +12 -167
  63. package/dist/runtime/components/Accordion.vue +8 -39
  64. package/dist/runtime/components/Alert.vue +25 -21
  65. package/dist/runtime/components/App.vue +15 -15
  66. package/dist/runtime/components/Avatar.vue +33 -21
  67. package/dist/runtime/components/AvatarGroup.vue +5 -7
  68. package/dist/runtime/components/Badge.vue +10 -8
  69. package/dist/runtime/components/Breadcrumb.vue +13 -34
  70. package/dist/runtime/components/Button.vue +5 -8
  71. package/dist/runtime/components/ButtonGroup.vue +5 -7
  72. package/dist/runtime/components/Calendar.vue +194 -0
  73. package/dist/runtime/components/Card.vue +10 -9
  74. package/dist/runtime/components/Carousel.vue +26 -17
  75. package/dist/runtime/components/Checkbox.vue +32 -38
  76. package/dist/runtime/components/Chip.vue +6 -8
  77. package/dist/runtime/components/Collapsible.vue +10 -11
  78. package/dist/runtime/components/ColorPicker.vue +297 -0
  79. package/dist/runtime/components/CommandPalette.vue +114 -98
  80. package/dist/runtime/components/Container.vue +4 -7
  81. package/dist/runtime/components/ContextMenu.vue +16 -69
  82. package/dist/runtime/components/ContextMenuContent.vue +14 -10
  83. package/dist/runtime/components/Drawer.vue +23 -12
  84. package/dist/runtime/components/DropdownMenu.vue +18 -59
  85. package/dist/runtime/components/DropdownMenuContent.vue +14 -10
  86. package/dist/runtime/components/Form.vue +78 -49
  87. package/dist/runtime/components/FormField.vue +28 -15
  88. package/dist/runtime/components/Icon.vue +1 -1
  89. package/dist/runtime/components/Input.vue +15 -7
  90. package/dist/runtime/components/InputMenu.vue +133 -66
  91. package/dist/runtime/components/InputNumber.vue +197 -0
  92. package/dist/runtime/components/Kbd.vue +5 -6
  93. package/dist/runtime/components/Link.vue +24 -13
  94. package/dist/runtime/components/LinkBase.vue +1 -1
  95. package/dist/runtime/components/Modal.vue +56 -34
  96. package/dist/runtime/components/NavigationMenu.vue +129 -112
  97. package/dist/runtime/components/OverlayProvider.vue +28 -0
  98. package/dist/runtime/components/Pagination.vue +18 -14
  99. package/dist/runtime/components/PinInput.vue +95 -0
  100. package/dist/runtime/components/Popover.vue +28 -14
  101. package/dist/runtime/components/Progress.vue +28 -12
  102. package/dist/runtime/components/RadioGroup.vue +9 -12
  103. package/dist/runtime/components/Select.vue +61 -35
  104. package/dist/runtime/components/SelectMenu.vue +201 -130
  105. package/dist/runtime/components/Separator.vue +6 -5
  106. package/dist/runtime/components/Skeleton.vue +4 -7
  107. package/dist/runtime/components/Slideover.vue +56 -33
  108. package/dist/runtime/components/Slider.vue +8 -7
  109. package/dist/runtime/components/Stepper.vue +170 -0
  110. package/dist/runtime/components/Switch.vue +19 -23
  111. package/dist/runtime/components/Table.vue +157 -32
  112. package/dist/runtime/components/Tabs.vue +12 -31
  113. package/dist/runtime/components/Textarea.vue +18 -9
  114. package/dist/runtime/components/Toast.vue +39 -25
  115. package/dist/runtime/components/Toaster.vue +31 -24
  116. package/dist/runtime/components/Tooltip.vue +9 -12
  117. package/dist/runtime/components/Tree.vue +196 -0
  118. package/dist/runtime/composables/defineLocale.d.ts +9 -0
  119. package/dist/runtime/composables/defineLocale.js +4 -0
  120. package/dist/runtime/composables/defineShortcuts.d.ts +1 -1
  121. package/dist/runtime/composables/defineShortcuts.js +2 -2
  122. package/dist/runtime/composables/useFormField.d.ts +11 -4
  123. package/dist/runtime/composables/useFormField.js +19 -9
  124. package/dist/runtime/composables/useLocale.d.ts +4 -0
  125. package/dist/runtime/composables/useLocale.js +10 -0
  126. package/dist/runtime/composables/useOverlay.d.ts +30 -0
  127. package/dist/runtime/composables/useOverlay.js +70 -0
  128. package/dist/runtime/composables/useToast.d.ts +4 -3
  129. package/dist/runtime/composables/useToast.js +20 -6
  130. package/dist/runtime/index.css +1 -1
  131. package/dist/runtime/keyframes.css +1 -1
  132. package/dist/runtime/locale/ar.d.ts +2 -0
  133. package/dist/runtime/locale/ar.js +55 -0
  134. package/dist/runtime/locale/az.d.ts +2 -0
  135. package/dist/runtime/locale/az.js +54 -0
  136. package/dist/runtime/locale/bn.d.ts +2 -0
  137. package/dist/runtime/locale/bn.js +54 -0
  138. package/dist/runtime/locale/cs.d.ts +2 -0
  139. package/dist/runtime/locale/cs.js +54 -0
  140. package/dist/runtime/locale/da.d.ts +2 -0
  141. package/dist/runtime/locale/da.js +54 -0
  142. package/dist/runtime/locale/de.d.ts +2 -0
  143. package/dist/runtime/locale/de.js +54 -0
  144. package/dist/runtime/locale/el.d.ts +2 -0
  145. package/dist/runtime/locale/el.js +54 -0
  146. package/dist/runtime/locale/en.d.ts +2 -0
  147. package/dist/runtime/locale/en.js +54 -0
  148. package/dist/runtime/locale/es.d.ts +2 -0
  149. package/dist/runtime/locale/es.js +54 -0
  150. package/dist/runtime/locale/et.d.ts +2 -0
  151. package/dist/runtime/locale/et.js +54 -0
  152. package/dist/runtime/locale/fa_ir.d.ts +2 -0
  153. package/dist/runtime/locale/fa_ir.js +55 -0
  154. package/dist/runtime/locale/fi.d.ts +2 -0
  155. package/dist/runtime/locale/fi.js +54 -0
  156. package/dist/runtime/locale/fr.d.ts +2 -0
  157. package/dist/runtime/locale/fr.js +54 -0
  158. package/dist/runtime/locale/he.d.ts +2 -0
  159. package/dist/runtime/locale/he.js +53 -0
  160. package/dist/runtime/locale/hi.d.ts +2 -0
  161. package/dist/runtime/locale/hi.js +54 -0
  162. package/dist/runtime/locale/hu.d.ts +2 -0
  163. package/dist/runtime/locale/hu.js +54 -0
  164. package/dist/runtime/locale/id.d.ts +2 -0
  165. package/dist/runtime/locale/id.js +54 -0
  166. package/dist/runtime/locale/index.d.ts +34 -0
  167. package/dist/runtime/locale/index.js +34 -0
  168. package/dist/runtime/locale/it.d.ts +2 -0
  169. package/dist/runtime/locale/it.js +54 -0
  170. package/dist/runtime/locale/ja.d.ts +2 -0
  171. package/dist/runtime/locale/ja.js +54 -0
  172. package/dist/runtime/locale/km.d.ts +2 -0
  173. package/dist/runtime/locale/km.js +54 -0
  174. package/dist/runtime/locale/ko.d.ts +2 -0
  175. package/dist/runtime/locale/ko.js +54 -0
  176. package/dist/runtime/locale/nb_no.d.ts +2 -0
  177. package/dist/runtime/locale/nb_no.js +54 -0
  178. package/dist/runtime/locale/nl.d.ts +2 -0
  179. package/dist/runtime/locale/nl.js +54 -0
  180. package/dist/runtime/locale/pl.d.ts +2 -0
  181. package/dist/runtime/locale/pl.js +54 -0
  182. package/dist/runtime/locale/pt.d.ts +2 -0
  183. package/dist/runtime/locale/pt.js +54 -0
  184. package/dist/runtime/locale/pt_br.d.ts +2 -0
  185. package/dist/runtime/locale/pt_br.js +54 -0
  186. package/dist/runtime/locale/ru.d.ts +2 -0
  187. package/dist/runtime/locale/ru.js +54 -0
  188. package/dist/runtime/locale/sk.d.ts +2 -0
  189. package/dist/runtime/locale/sk.js +54 -0
  190. package/dist/runtime/locale/sv.d.ts +2 -0
  191. package/dist/runtime/locale/sv.js +54 -0
  192. package/dist/runtime/locale/th.d.ts +2 -0
  193. package/dist/runtime/locale/th.js +54 -0
  194. package/dist/runtime/locale/tr.d.ts +2 -0
  195. package/dist/runtime/locale/tr.js +54 -0
  196. package/dist/runtime/locale/uk.d.ts +2 -0
  197. package/dist/runtime/locale/uk.js +54 -0
  198. package/dist/runtime/locale/vi.d.ts +2 -0
  199. package/dist/runtime/locale/vi.js +54 -0
  200. package/dist/runtime/locale/zh_cn.d.ts +2 -0
  201. package/dist/runtime/locale/zh_cn.js +54 -0
  202. package/dist/runtime/locale/zh_tw.d.ts +2 -0
  203. package/dist/runtime/locale/zh_tw.js +54 -0
  204. package/dist/runtime/plugins/colors.js +8 -5
  205. package/dist/runtime/types/form.d.ts +29 -15
  206. package/dist/runtime/types/form.js +2 -2
  207. package/dist/runtime/types/index.d.ts +8 -0
  208. package/dist/runtime/types/index.js +8 -0
  209. package/dist/runtime/types/locale.d.ts +56 -0
  210. package/dist/runtime/types/locale.js +0 -0
  211. package/dist/runtime/types/utils.d.ts +7 -3
  212. package/dist/runtime/utils/form.d.ts +5 -9
  213. package/dist/runtime/utils/form.js +113 -50
  214. package/dist/runtime/utils/index.d.ts +1 -1
  215. package/dist/runtime/utils/index.js +15 -2
  216. package/dist/runtime/utils/link.d.ts +1 -1
  217. package/dist/runtime/utils/locale.d.ts +15 -0
  218. package/dist/runtime/utils/locale.js +25 -0
  219. package/dist/runtime/utils/tv.d.ts +1 -0
  220. package/dist/runtime/utils/tv.js +4 -0
  221. package/dist/runtime/vue/components/Icon.vue +2 -2
  222. package/dist/runtime/vue/components/Link.vue +87 -23
  223. package/dist/runtime/vue/composables/useAppConfig.d.ts +1 -0
  224. package/dist/runtime/vue/composables/useAppConfig.js +2 -0
  225. package/dist/runtime/vue/plugins/head.d.ts +1 -1
  226. package/dist/runtime/vue/plugins/head.js +3 -3
  227. package/dist/runtime/vue/stubs.d.ts +19 -0
  228. package/dist/runtime/vue/stubs.js +37 -0
  229. package/dist/shared/{ui.BufKhDiD.mjs → ui.DSPu6Y8j.mjs} +1071 -409
  230. package/dist/shared/{ui.BU7wzH0D.cjs → ui.DfK2RX6G.cjs} +1074 -409
  231. package/dist/unplugin.cjs +62 -26
  232. package/dist/unplugin.d.cts +17 -3
  233. package/dist/unplugin.d.mts +17 -3
  234. package/dist/unplugin.d.ts +17 -3
  235. package/dist/unplugin.mjs +61 -25
  236. package/dist/vite.cjs +3 -2
  237. package/dist/vite.d.cts +2 -0
  238. package/dist/vite.d.mts +2 -0
  239. package/dist/vite.d.ts +2 -0
  240. package/dist/vite.mjs +3 -2
  241. package/package.json +110 -67
  242. package/dist/chunks/component-meta.cjs +0 -73264
  243. package/dist/chunks/component-meta.mjs +0 -73262
  244. package/dist/client/devtools/200.html +0 -1
  245. package/dist/client/devtools/404.html +0 -1
  246. package/dist/client/devtools/_fonts/rP2Wp2ywxg089UriCZaSExd86J3t9jz86MvyyKK58UfivUw4aw-SK92LTmKP0.woff2 +0 -0
  247. package/dist/client/devtools/_fonts/rP2Wp2ywxg089UriCZaSExd86J3t9jz86MvyyKy58UfivUw-9uYm8d48E4.woff2 +0 -0
  248. package/dist/client/devtools/_fonts/rP2Yp2ywxg089UriI5-g4vlH9VoD8Cmcqbu0-K6z9mXg-VNw7NHvqnp.woff2 +0 -0
  249. package/dist/client/devtools/_fonts/rP2Yp2ywxg089UriI5-g4vlH9VoD8Cmcqbu6-K6z9mXgjU0-EkYdMs3MAX.woff2 +0 -0
  250. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat-7DW3w-R7n06NbhGy.woff +0 -0
  251. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat-JDG3w-leGNfkTmsj.woff +0 -0
  252. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat-JDW3w-ciElMF03ku.woff +0 -0
  253. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat8JCm3w-sB722Uoa0f.woff +0 -0
  254. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat8JDW3w-PBDI1JDjwV.woff +0 -0
  255. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat8gCm3w-0q1hqVn09O.woff +0 -0
  256. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat9XCm3w-ByvzuLy2fa.woff +0 -0
  257. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat9uCm3w-5TKCIs6EEw.woff +0 -0
  258. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat_XDW3w-r2swRDGfn2.woff +0 -0
  259. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAC5thTQ-ldB60l5U8r.woff +0 -0
  260. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAIpthTQ-wbFKGFDrgo.woff +0 -0
  261. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAIpxhTQ-LLUBv5jskj.woff +0 -0
  262. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwARZthTQ-F71RdTRbNg.woff +0 -0
  263. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwA_JxhTQ-6nh65gZkc0.woff +0 -0
  264. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAfJthTQ-aMoWEJLmTt.woff +0 -0
  265. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAkJxhTQ-WMBvmLOgKm.woff +0 -0
  266. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAop1hTQ-utGC2hnWq2.woff +0 -0
  267. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAopxhTQ-YpyTieVa5B.woff +0 -0
  268. package/dist/client/devtools/_nuxt/Bj9hdafK.js +0 -1
  269. package/dist/client/devtools/_nuxt/DM3_wAgz.js +0 -62
  270. package/dist/client/devtools/_nuxt/builds/latest.json +0 -1
  271. package/dist/client/devtools/_nuxt/builds/meta/e6b425f7-b919-4014-915b-0ea07c316790.json +0 -1
  272. package/dist/client/devtools/_nuxt/entry.DaJP-ZMB.css +0 -24
  273. package/dist/client/devtools/_nuxt/error-404.B0Nmv3fV.css +0 -1
  274. package/dist/client/devtools/_nuxt/error-500.C8fgTxVz.css +0 -1
  275. package/dist/client/devtools/_nuxt/hKiujHsR.js +0 -1
  276. package/dist/client/devtools/favicon.svg +0 -1
  277. package/dist/client/devtools/index.html +0 -1
  278. package/dist/devtools/runtime/DevtoolsRenderer.vue +0 -53
  279. package/dist/devtools/runtime/examples/AvatarGroupExample.vue +0 -7
  280. package/dist/devtools/runtime/examples/ButtonGroupExample.vue +0 -8
  281. package/dist/devtools/runtime/examples/CardExample.vue +0 -13
  282. package/dist/devtools/runtime/examples/CarouselExample.vue +0 -13
  283. package/dist/devtools/runtime/examples/ChipExample.vue +0 -5
  284. package/dist/devtools/runtime/examples/CollapsibleExample.vue +0 -8
  285. package/dist/devtools/runtime/examples/CommandPaletteExample.vue +0 -29
  286. package/dist/devtools/runtime/examples/ContainerExample.vue +0 -5
  287. package/dist/devtools/runtime/examples/ContextMenuExample.vue +0 -5
  288. package/dist/devtools/runtime/examples/DrawerExample.vue +0 -8
  289. package/dist/devtools/runtime/examples/DropdownMenuExample.vue +0 -5
  290. package/dist/devtools/runtime/examples/FormExample.vue +0 -30
  291. package/dist/devtools/runtime/examples/FormFieldExample.vue +0 -5
  292. package/dist/devtools/runtime/examples/LinkExample.vue +0 -5
  293. package/dist/devtools/runtime/examples/ModalExample.vue +0 -8
  294. package/dist/devtools/runtime/examples/PopoverExample.vue +0 -8
  295. package/dist/devtools/runtime/examples/SkeletonExample.vue +0 -3
  296. package/dist/devtools/runtime/examples/SlideoverExample.vue +0 -8
  297. package/dist/devtools/runtime/examples/ToasterExample.vue +0 -11
  298. package/dist/devtools/runtime/examples/TooltipExample.vue +0 -5
  299. package/dist/runtime/components/ModalProvider.vue +0 -12
  300. package/dist/runtime/components/SlideoverProvider.vue +0 -12
  301. package/dist/runtime/composables/extendDevtoolsMeta.d.ts +0 -7
  302. package/dist/runtime/composables/extendDevtoolsMeta.js +0 -2
  303. package/dist/runtime/composables/useModal.d.ts +0 -17
  304. package/dist/runtime/composables/useModal.js +0 -46
  305. package/dist/runtime/composables/useSlideover.d.ts +0 -17
  306. package/dist/runtime/composables/useSlideover.js +0 -46
  307. package/dist/runtime/plugins/modal.d.ts +0 -2
  308. package/dist/runtime/plugins/modal.js +0 -10
  309. package/dist/runtime/plugins/slideover.d.ts +0 -2
  310. package/dist/runtime/plugins/slideover.js +0 -10
@@ -1,21 +1,20 @@
1
1
  <script lang="ts">
2
- import { tv } from 'tailwind-variants'
3
- import type { ComboboxRootProps, ComboboxRootEmits } from 'radix-vue'
2
+ import type { ListboxRootProps, ListboxRootEmits } from 'reka-ui'
4
3
  import type { FuseResult } from 'fuse.js'
5
4
  import type { AppConfig } from '@nuxt/schema'
6
5
  import type { UseFuseOptions } from '@vueuse/integrations/useFuse'
7
6
  import _appConfig from '#build/app.config'
8
7
  import theme from '#build/ui/command-palette'
9
8
  import type { UseComponentIconsProps } from '../composables/useComponentIcons'
10
- import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
11
- import type { AvatarProps, ButtonProps, ChipProps, KbdProps, InputProps } from '../types'
9
+ import { tv } from '../utils/tv'
10
+ import type { AvatarProps, ButtonProps, ChipProps, KbdProps, InputProps, LinkProps } from '../types'
12
11
  import type { DynamicSlots, PartialString } from '../types/utils'
13
12
 
14
- const appConfig = _appConfig as AppConfig & { ui: { commandPalette: Partial<typeof theme> } }
13
+ const appConfigCommandPalette = _appConfig as AppConfig & { ui: { commandPalette: Partial<typeof theme> } }
15
14
 
16
- const commandPalette = tv({ extend: tv(theme), ...(appConfig.ui?.commandPalette || {}) })
15
+ const commandPalette = tv({ extend: tv(theme), ...(appConfigCommandPalette.ui?.commandPalette || {}) })
17
16
 
18
- export interface CommandPaletteItem {
17
+ export interface CommandPaletteItem extends Omit<LinkProps, 'type' | 'raw' | 'custom'> {
19
18
  prefix?: string
20
19
  label?: string
21
20
  suffix?: string
@@ -23,6 +22,7 @@ export interface CommandPaletteItem {
23
22
  avatar?: AvatarProps
24
23
  chip?: ChipProps
25
24
  kbds?: KbdProps['value'][] | KbdProps[]
25
+ active?: boolean
26
26
  loading?: boolean
27
27
  disabled?: boolean
28
28
  slot?: string
@@ -35,18 +35,18 @@ export interface CommandPaletteGroup<T> {
35
35
  slot?: string
36
36
  items?: T[]
37
37
  /**
38
- * Wether to filter group items with [useFuse](https://vueuse.org/integrations/useFuse).
39
- * When `false`, items will not be filtered which is useful for custom filtering (useAsyncData, useFetch, etc.).
40
- * @defaultValue true
38
+ * Whether to filter group items with [useFuse](https://vueuse.org/integrations/useFuse).
39
+ * When `true`, items will not be filtered which is useful for custom filtering (useAsyncData, useFetch, etc.).
40
+ * @defaultValue false
41
41
  */
42
- filter?: boolean
42
+ ignoreFilter?: boolean
43
43
  /** Filter group items after the search happened. */
44
44
  postFilter?: (searchTerm: string, items: T[]) => T[]
45
45
  /** The icon displayed when an item is highlighted. */
46
46
  highlightedIcon?: string
47
47
  }
48
48
 
49
- export interface CommandPaletteProps<G, T> extends Pick<ComboboxRootProps, 'multiple' | 'disabled' | 'modelValue' | 'defaultValue' | 'selectedValue' | 'resetSearchTermOnBlur'>, Pick<UseComponentIconsProps, 'loading' | 'loadingIcon'> {
49
+ export interface CommandPaletteProps<G, T> extends Pick<ListboxRootProps, 'multiple' | 'disabled' | 'modelValue' | 'defaultValue' | 'highlightOnHover'>, Pick<UseComponentIconsProps, 'loading' | 'loadingIcon'> {
50
50
  /**
51
51
  * The element or component this component should render as.
52
52
  * @defaultValue 'div'
@@ -67,12 +67,18 @@ export interface CommandPaletteProps<G, T> extends Pick<ComboboxRootProps, 'mult
67
67
  * @defaultValue 'Type a command or search...'
68
68
  */
69
69
  placeholder?: InputProps['placeholder']
70
+ /**
71
+ * Automatically focus the input when component is mounted.
72
+ * @defaultValue true
73
+ */
74
+ autofocus?: boolean
70
75
  /**
71
76
  * Display a close button in the input (useful when inside a Modal for example).
72
77
  * `{ size: 'md', color: 'neutral', variant: 'ghost' }`{lang="ts-type"}
78
+ * @emits 'update:open'
73
79
  * @defaultValue false
74
80
  */
75
- close?: ButtonProps | boolean
81
+ close?: boolean | Partial<ButtonProps>
76
82
  /**
77
83
  * The icon displayed in the close button.
78
84
  * @defaultValue appConfig.ui.icons.close
@@ -101,7 +107,9 @@ export interface CommandPaletteProps<G, T> extends Pick<ComboboxRootProps, 'mult
101
107
  ui?: PartialString<typeof commandPalette.slots>
102
108
  }
103
109
 
104
- export type CommandPaletteEmits<T> = ComboboxRootEmits<T>
110
+ export type CommandPaletteEmits<T> = ListboxRootEmits<T> & {
111
+ 'update:open': [value: boolean]
112
+ }
105
113
 
106
114
  type SlotProps<T> = (props: { item: T, index: number }) => any
107
115
 
@@ -113,39 +121,43 @@ export type CommandPaletteSlots<G extends { slot?: string }, T extends { slot?:
113
121
  'item-label': SlotProps<T>
114
122
  'item-trailing': SlotProps<T>
115
123
  } & DynamicSlots<G, SlotProps<T>> & DynamicSlots<T, SlotProps<T>>
116
-
117
- extendDevtoolsMeta({ example: 'CommandPaletteExample', ignoreProps: ['groups'] })
118
124
  </script>
119
125
 
120
126
  <script setup lang="ts" generic="G extends CommandPaletteGroup<T>, T extends CommandPaletteItem">
121
127
  import { computed } from 'vue'
122
- import { ComboboxRoot, ComboboxInput, ComboboxPortal, ComboboxContent, ComboboxEmpty, ComboboxViewport, ComboboxGroup, ComboboxLabel, ComboboxItem, ComboboxItemIndicator, useForwardProps, useForwardPropsEmits } from 'radix-vue'
128
+ import { ListboxRoot, ListboxFilter, ListboxContent, ListboxGroup, ListboxGroupLabel, ListboxItem, ListboxItemIndicator, useForwardProps, useForwardPropsEmits } from 'reka-ui'
123
129
  import { defu } from 'defu'
124
130
  import { reactivePick } from '@vueuse/core'
125
131
  import { useFuse } from '@vueuse/integrations/useFuse'
126
132
  import { useAppConfig } from '#imports'
133
+ import { useLocale } from '../composables/useLocale'
127
134
  import { omit, get } from '../utils'
128
135
  import { highlight } from '../utils/fuse'
136
+ import { pickLinkProps } from '../utils/link'
129
137
  import UIcon from './Icon.vue'
130
138
  import UAvatar from './Avatar.vue'
131
139
  import UButton from './Button.vue'
132
140
  import UChip from './Chip.vue'
133
- import UKbd from './Kbd.vue'
141
+ import ULinkBase from './LinkBase.vue'
142
+ import ULink from './Link.vue'
134
143
  import UInput from './Input.vue'
144
+ import UKbd from './Kbd.vue'
135
145
 
136
146
  const props = withDefaults(defineProps<CommandPaletteProps<G, T>>(), {
137
147
  modelValue: '',
138
- placeholder: 'Type a command or search...',
139
- labelKey: 'label'
148
+ labelKey: 'label',
149
+ autofocus: true
140
150
  })
141
151
  const emits = defineEmits<CommandPaletteEmits<T>>()
142
152
  const slots = defineSlots<CommandPaletteSlots<G, T>>()
143
153
 
144
154
  const searchTerm = defineModel<string>('searchTerm', { default: '' })
145
155
 
156
+ const { t } = useLocale()
146
157
  const appConfig = useAppConfig()
147
- const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'disabled', 'multiple', 'modelValue', 'defaultValue', 'selectedValue', 'resetSearchTermOnBlur'), emits)
148
- const inputProps = useForwardProps(reactivePick(props, 'loading', 'loadingIcon', 'placeholder'))
158
+
159
+ const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'disabled', 'multiple', 'modelValue', 'defaultValue', 'highlightOnHover'), emits)
160
+ const inputProps = useForwardProps(reactivePick(props, 'loading', 'loadingIcon'))
149
161
 
150
162
  // eslint-disable-next-line vue/no-dupe-keys
151
163
  const ui = commandPalette()
@@ -166,7 +178,7 @@ const items = computed(() => props.groups?.filter((group) => {
166
178
  return false
167
179
  }
168
180
 
169
- if (group.filter === false) {
181
+ if (group.ignoreFilter) {
170
182
  return false
171
183
  }
172
184
 
@@ -214,24 +226,26 @@ const groups = computed(() => {
214
226
  return getGroupWithItems(group, items)
215
227
  }).filter(group => !!group)
216
228
 
217
- const nonFuseGroups = props.groups?.filter(group => group.filter === false && group.items?.length).map((group) => {
218
- return getGroupWithItems(group, group.items || [])
219
- }) || []
229
+ const nonFuseGroups = props.groups
230
+ ?.map((group, index) => ({ ...group, index }))
231
+ ?.filter(group => group.ignoreFilter && group.items?.length)
232
+ ?.map(group => ({ ...getGroupWithItems(group, group.items || []), index: group.index })) || []
220
233
 
221
- return [
222
- ...fuseGroups,
223
- ...nonFuseGroups
224
- ]
234
+ return nonFuseGroups.reduce((acc, group) => {
235
+ acc.splice(group.index, 0, group)
236
+ return acc
237
+ }, [...fuseGroups])
225
238
  })
226
239
  </script>
227
240
 
228
241
  <!-- eslint-disable vue/no-v-html -->
229
242
  <template>
230
- <ComboboxRoot v-bind="rootProps" v-model:search-term="searchTerm" open :class="ui.root({ class: [props.class, props.ui?.root] })">
231
- <ComboboxInput as-child>
243
+ <ListboxRoot v-bind="rootProps" :class="ui.root({ class: [props.class, props.ui?.root] })">
244
+ <ListboxFilter v-model="searchTerm" as-child>
232
245
  <UInput
246
+ :placeholder="placeholder || t('commandPalette.placeholder')"
233
247
  variant="none"
234
- autofocus
248
+ :autofocus="autofocus"
235
249
  size="lg"
236
250
  v-bind="inputProps"
237
251
  :icon="icon || appConfig.ui.icons.search"
@@ -245,80 +259,82 @@ const groups = computed(() => {
245
259
  size="md"
246
260
  color="neutral"
247
261
  variant="ghost"
248
- aria-label="Close"
249
- v-bind="typeof close === 'object' ? close : undefined"
262
+ :aria-label="t('commandPalette.close')"
263
+ v-bind="(typeof close === 'object' ? close as Partial<ButtonProps> : {})"
250
264
  :class="ui.close({ class: props.ui?.close })"
251
265
  @click="emits('update:open', false)"
252
266
  />
253
267
  </slot>
254
268
  </template>
255
269
  </UInput>
256
- </ComboboxInput>
270
+ </ListboxFilter>
271
+
272
+ <ListboxContent :class="ui.content({ class: props.ui?.content })">
273
+ <div v-if="groups?.length" :class="ui.viewport({ class: props.ui?.viewport })">
274
+ <ListboxGroup v-for="(group, groupIndex) in groups" :key="`group-${groupIndex}`" :class="ui.group({ class: props.ui?.group })">
275
+ <ListboxGroupLabel v-if="get(group, props.labelKey as string)" :class="ui.label({ class: props.ui?.label })">
276
+ {{ get(group, props.labelKey as string) }}
277
+ </ListboxGroupLabel>
278
+
279
+ <ListboxItem
280
+ v-for="(item, index) in group.items"
281
+ :key="`group-${groupIndex}-${index}`"
282
+ :value="omit(item, ['matches' as any, 'group' as any, 'onSelect', 'labelHtml', 'suffixHtml'])"
283
+ :disabled="item.disabled"
284
+ as-child
285
+ @select="item.onSelect"
286
+ >
287
+ <ULink v-slot="{ active, ...slotProps }" v-bind="pickLinkProps(item)" custom>
288
+ <ULinkBase v-bind="slotProps" :class="ui.item({ class: props.ui?.item, active: active || item.active })">
289
+ <slot :name="item.slot || group.slot || 'item'" :item="item" :index="index">
290
+ <slot :name="item.slot ? `${item.slot}-leading` : group.slot ? `${group.slot}-leading` : `item-leading`" :item="item" :index="index">
291
+ <UIcon v-if="item.loading" :name="loadingIcon || appConfig.ui.icons.loading" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon, loading: true })" />
292
+ <UIcon v-else-if="item.icon" :name="item.icon" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon, active: active || item.active })" />
293
+ <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, active: active || item.active })" />
294
+ <UChip
295
+ v-else-if="item.chip"
296
+ :size="((props.ui?.itemLeadingChipSize || ui.itemLeadingChipSize()) as ChipProps['size'])"
297
+ inset
298
+ standalone
299
+ v-bind="item.chip"
300
+ :class="ui.itemLeadingChip({ class: props.ui?.itemLeadingChip, active: active || item.active })"
301
+ />
302
+ </slot>
257
303
 
258
- <ComboboxPortal disabled>
259
- <ComboboxContent :class="ui.content({ class: props.ui?.content })" :dismissable="false">
260
- <ComboboxEmpty :class="ui.empty({ class: props.ui?.empty })">
261
- <slot name="empty" :search-term="searchTerm">
262
- {{ searchTerm ? `No results for ${searchTerm}` : 'No results' }}
263
- </slot>
264
- </ComboboxEmpty>
265
-
266
- <ComboboxViewport :class="ui.viewport({ class: props.ui?.viewport })">
267
- <ComboboxGroup v-for="(group, groupIndex) in groups" :key="`group-${groupIndex}`" :class="ui.group({ class: props.ui?.group })">
268
- <ComboboxLabel v-if="get(group, props.labelKey as string)" :class="ui.label({ class: props.ui?.label })">
269
- {{ get(group, props.labelKey as string) }}
270
- </ComboboxLabel>
271
-
272
- <ComboboxItem
273
- v-for="(item, index) in group.items"
274
- :key="`group-${groupIndex}-${index}`"
275
- :value="omit(item, ['matches' as any, 'group' as any, 'onSelect', 'labelHtml', 'suffixHtml'])"
276
- :disabled="item.disabled"
277
- :class="ui.item({ class: props.ui?.item })"
278
- @select="item.onSelect"
279
- >
280
- <slot :name="item.slot || group.slot || 'item'" :item="item" :index="index">
281
- <slot :name="item.slot ? `${item.slot}-leading` : group.slot ? `${group.slot}-leading` : `item-leading`" :item="item" :index="index">
282
- <UIcon v-if="item.loading" :name="loadingIcon || appConfig.ui.icons.loading" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon, loading: true })" />
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 })" />
285
- <UChip
286
- v-else-if="item.chip"
287
- :size="((props.ui?.itemLeadingChipSize || ui.itemLeadingChipSize()) as ChipProps['size'])"
288
- inset
289
- standalone
290
- v-bind="item.chip"
291
- :class="ui.itemLeadingChip({ class: props.ui?.itemLeadingChip })"
292
- />
293
- </slot>
304
+ <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, active: active || item.active })">
305
+ <slot :name="item.slot ? `${item.slot}-label` : group.slot ? `${group.slot}-label` : `item-label`" :item="item" :index="index">
306
+ <span v-if="item.prefix" :class="ui.itemLabelPrefix({ class: props.ui?.itemLabelPrefix })">{{ item.prefix }}</span>
294
307
 
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 })">
296
- <slot :name="item.slot ? `${item.slot}-label` : group.slot ? `${group.slot}-label` : `item-label`" :item="item" :index="index">
297
- <span v-if="item.prefix" :class="ui.itemLabelPrefix({ class: props.ui?.itemLabelPrefix })">{{ item.prefix }}</span>
308
+ <span :class="ui.itemLabelBase({ class: props.ui?.itemLabelBase, active: active || item.active })" v-html="item.labelHtml || get(item, props.labelKey as string)" />
298
309
 
299
- <span :class="ui.itemLabelBase({ class: props.ui?.itemLabelBase })" v-html="item.labelHtml || get(item, props.labelKey as string)" />
310
+ <span :class="ui.itemLabelSuffix({ class: props.ui?.itemLabelSuffix, active: active || item.active })" v-html="item.suffixHtml || item.suffix" />
311
+ </slot>
312
+ </span>
300
313
 
301
- <span :class="ui.itemLabelSuffix({ class: props.ui?.itemLabelSuffix })" v-html="item.suffixHtml || item.suffix" />
302
- </slot>
303
- </span>
304
-
305
- <span :class="ui.itemTrailing({ class: props.ui?.itemTrailing })">
306
- <slot :name="item.slot ? `${item.slot}-trailing` : group.slot ? `${group.slot}-trailing` : `item-trailing`" :item="item" :index="index">
307
- <span v-if="item.kbds?.length" :class="ui.itemTrailingKbds({ class: props.ui?.itemTrailingKbds })">
308
- <UKbd v-for="(kbd, kbdIndex) in item.kbds" :key="kbdIndex" :size="((props.ui?.itemTrailingKbdsSize || ui.itemTrailingKbdsSize()) as KbdProps['size'])" v-bind="typeof kbd === 'string' ? { value: kbd } : kbd" />
309
- </span>
310
- <UIcon v-else-if="group.highlightedIcon" :name="group.highlightedIcon" :class="ui.itemTrailingHighlightedIcon({ class: props.ui?.itemTrailingHighlightedIcon })" />
311
- </slot>
314
+ <span :class="ui.itemTrailing({ class: props.ui?.itemTrailing })">
315
+ <slot :name="item.slot ? `${item.slot}-trailing` : group.slot ? `${group.slot}-trailing` : `item-trailing`" :item="item" :index="index">
316
+ <span v-if="item.kbds?.length" :class="ui.itemTrailingKbds({ class: props.ui?.itemTrailingKbds })">
317
+ <UKbd v-for="(kbd, kbdIndex) in item.kbds" :key="kbdIndex" :size="((props.ui?.itemTrailingKbdsSize || ui.itemTrailingKbdsSize()) as KbdProps['size'])" v-bind="typeof kbd === 'string' ? { value: kbd } : kbd" />
318
+ </span>
319
+ <UIcon v-else-if="group.highlightedIcon" :name="group.highlightedIcon" :class="ui.itemTrailingHighlightedIcon({ class: props.ui?.itemTrailingHighlightedIcon })" />
320
+ </slot>
312
321
 
313
- <ComboboxItemIndicator as-child>
314
- <UIcon :name="selectedIcon || appConfig.ui.icons.check" :class="ui.itemTrailingIcon({ class: props.ui?.itemTrailingIcon })" />
315
- </ComboboxItemIndicator>
316
- </span>
317
- </slot>
318
- </ComboboxItem>
319
- </ComboboxGroup>
320
- </ComboboxViewport>
321
- </ComboboxContent>
322
- </ComboboxPortal>
323
- </ComboboxRoot>
322
+ <ListboxItemIndicator as-child>
323
+ <UIcon :name="selectedIcon || appConfig.ui.icons.check" :class="ui.itemTrailingIcon({ class: props.ui?.itemTrailingIcon })" />
324
+ </ListboxItemIndicator>
325
+ </span>
326
+ </slot>
327
+ </ULinkBase>
328
+ </ULink>
329
+ </ListboxItem>
330
+ </ListboxGroup>
331
+ </div>
332
+
333
+ <div v-else :class="ui.empty({ class: props.ui?.empty })">
334
+ <slot name="empty" :search-term="searchTerm">
335
+ {{ searchTerm ? t('commandPalette.noMatch', { searchTerm }) : t('commandPalette.noData') }}
336
+ </slot>
337
+ </div>
338
+ </ListboxContent>
339
+ </ListboxRoot>
324
340
  </template>
@@ -1,13 +1,12 @@
1
1
  <script lang="ts">
2
- import { tv } from 'tailwind-variants'
3
2
  import type { AppConfig } from '@nuxt/schema'
4
3
  import _appConfig from '#build/app.config'
5
4
  import theme from '#build/ui/container'
6
- import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
5
+ import { tv } from '../utils/tv'
7
6
 
8
- const appConfig = _appConfig as AppConfig & { ui: { container: Partial<typeof theme> } }
7
+ const appConfigContainer = _appConfig as AppConfig & { ui: { container: Partial<typeof theme> } }
9
8
 
10
- const container = tv({ extend: tv(theme), ...(appConfig.ui?.container || {}) })
9
+ const container = tv({ extend: tv(theme), ...(appConfigContainer.ui?.container || {}) })
11
10
 
12
11
  export interface ContainerProps {
13
12
  /**
@@ -21,12 +20,10 @@ export interface ContainerProps {
21
20
  export interface ContainerSlots {
22
21
  default(props?: {}): any
23
22
  }
24
-
25
- extendDevtoolsMeta({ example: 'ContainerExample' })
26
23
  </script>
27
24
 
28
25
  <script setup lang="ts">
29
- import { Primitive } from 'radix-vue'
26
+ import { Primitive } from 'reka-ui'
30
27
 
31
28
  const props = defineProps<ContainerProps>()
32
29
  defineSlots<ContainerSlots>()
@@ -1,16 +1,16 @@
1
1
  <script lang="ts">
2
- import { tv, type VariantProps } from 'tailwind-variants'
3
- import type { ContextMenuRootProps, ContextMenuRootEmits, ContextMenuContentProps } from 'radix-vue'
2
+ import type { VariantProps } from 'tailwind-variants'
3
+ import type { ContextMenuRootProps, ContextMenuRootEmits, ContextMenuContentProps } from 'reka-ui'
4
4
  import type { AppConfig } from '@nuxt/schema'
5
5
  import _appConfig from '#build/app.config'
6
6
  import theme from '#build/ui/context-menu'
7
- import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
7
+ import { tv } from '../utils/tv'
8
8
  import type { AvatarProps, KbdProps, LinkProps } from '../types'
9
9
  import type { DynamicSlots, PartialString } from '../types/utils'
10
10
 
11
- const appConfig = _appConfig as AppConfig & { ui: { contextMenu: Partial<typeof theme> } }
11
+ const appConfigContextMenu = _appConfig as AppConfig & { ui: { contextMenu: Partial<typeof theme> } }
12
12
 
13
- const contextMenu = tv({ extend: tv(theme), ...(appConfig.ui?.contextMenu || {}) })
13
+ const contextMenu = tv({ extend: tv(theme), ...(appConfigContextMenu.ui?.contextMenu || {}) })
14
14
 
15
15
  type ContextMenuVariants = VariantProps<typeof contextMenu>
16
16
 
@@ -50,6 +50,12 @@ export interface ContextMenuProps<T> extends Omit<ContextMenuRootProps, 'dir'> {
50
50
  * @defaultValue appConfig.ui.icons.loading
51
51
  */
52
52
  loadingIcon?: string
53
+ /**
54
+ * The icon displayed when the item is an external link.
55
+ * Set to `false` to hide the external icon.
56
+ * @defaultValue appConfig.ui.icons.external
57
+ */
58
+ externalIcon?: boolean | string
53
59
  /** The content of the menu. */
54
60
  content?: Omit<ContextMenuContentProps, 'as' | 'asChild' | 'forceMount'>
55
61
  /**
@@ -78,72 +84,11 @@ export type ContextMenuSlots<T extends { slot?: string }> = {
78
84
  'item-label': SlotProps<T>
79
85
  'item-trailing': SlotProps<T>
80
86
  } & DynamicSlots<T, SlotProps<T>>
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
- })
142
87
  </script>
143
88
 
144
89
  <script setup lang="ts" generic="T extends ContextMenuItem">
145
90
  import { computed, toRef } from 'vue'
146
- import { ContextMenuRoot, ContextMenuTrigger, useForwardPropsEmits } from 'radix-vue'
91
+ import { ContextMenuRoot, ContextMenuTrigger, useForwardPropsEmits } from 'reka-ui'
147
92
  import { reactivePick } from '@vueuse/core'
148
93
  import { omit } from '../utils'
149
94
  import UContextMenuContent from './ContextMenuContent.vue'
@@ -151,6 +96,7 @@ import UContextMenuContent from './ContextMenuContent.vue'
151
96
  const props = withDefaults(defineProps<ContextMenuProps<T>>(), {
152
97
  portal: true,
153
98
  modal: true,
99
+ externalIcon: true,
154
100
  labelKey: 'label'
155
101
  })
156
102
  const emits = defineEmits<ContextMenuEmits>()
@@ -167,12 +113,12 @@ const ui = computed(() => contextMenu({
167
113
 
168
114
  <template>
169
115
  <ContextMenuRoot v-bind="rootProps">
170
- <ContextMenuTrigger v-if="!!slots.default" as-child :disabled="disabled">
116
+ <ContextMenuTrigger v-if="!!slots.default" as-child :disabled="disabled" :class="props.class">
171
117
  <slot />
172
118
  </ContextMenuTrigger>
173
119
 
174
120
  <UContextMenuContent
175
- :class="ui.content({ class: [props.class, props.ui?.content] })"
121
+ :class="ui.content({ class: [!slots.default && props.class, props.ui?.content] })"
176
122
  :ui="ui"
177
123
  :ui-override="props.ui"
178
124
  v-bind="contentProps"
@@ -181,6 +127,7 @@ const ui = computed(() => contextMenu({
181
127
  :label-key="labelKey"
182
128
  :checked-icon="checkedIcon"
183
129
  :loading-icon="loadingIcon"
130
+ :external-icon="externalIcon"
184
131
  >
185
132
  <template v-for="(_, name) in proxySlots" #[name]="slotData: any">
186
133
  <slot :name="name" v-bind="slotData" />
@@ -1,30 +1,31 @@
1
1
  <script lang="ts">
2
- import { tv } from 'tailwind-variants'
3
- import type { ContextMenuContentProps as RadixContextMenuContentProps, ContextMenuContentEmits as RadixContextMenuContentEmits } from 'radix-vue'
2
+ import type { ContextMenuContentProps as RekaContextMenuContentProps, ContextMenuContentEmits as RekaContextMenuContentEmits } from 'reka-ui'
4
3
  import theme from '#build/ui/context-menu'
4
+ import { tv } from '../utils/tv'
5
5
  import type { KbdProps, AvatarProps, ContextMenuItem, ContextMenuSlots } from '../types'
6
6
 
7
7
  const _contextMenu = tv(theme)()
8
8
 
9
- interface ContextMenuContentProps<T> extends Omit<RadixContextMenuContentProps, 'as' | 'asChild' | 'forceMount'> {
9
+ interface ContextMenuContentProps<T> extends Omit<RekaContextMenuContentProps, 'as' | 'asChild' | 'forceMount'> {
10
10
  items?: T[] | T[][]
11
11
  portal?: boolean
12
12
  sub?: boolean
13
13
  labelKey: string
14
14
  checkedIcon?: string
15
15
  loadingIcon?: string
16
+ externalIcon?: boolean | string
16
17
  class?: any
17
18
  ui: typeof _contextMenu
18
19
  uiOverride?: any
19
20
  }
20
21
 
21
- interface ContextMenuContentEmits extends RadixContextMenuContentEmits {}
22
+ interface ContextMenuContentEmits extends RekaContextMenuContentEmits {}
22
23
  </script>
23
24
 
24
25
  <script setup lang="ts" generic="T extends ContextMenuItem">
25
26
  import { computed } from 'vue'
26
- import { ContextMenu } from 'radix-vue/namespaced'
27
- import { useForwardPropsEmits } from 'radix-vue'
27
+ import { ContextMenu } from 'reka-ui/namespaced'
28
+ import { useForwardPropsEmits } from 'reka-ui'
28
29
  import { reactiveOmit, createReusableTemplate } from '@vueuse/core'
29
30
  import { useAppConfig } from '#imports'
30
31
  import { omit, get } from '../utils'
@@ -34,13 +35,15 @@ import ULink from './Link.vue'
34
35
  import UAvatar from './Avatar.vue'
35
36
  import UIcon from './Icon.vue'
36
37
  import UKbd from './Kbd.vue'
38
+ // eslint-disable-next-line import/no-self-import
39
+ import UContextMenuContent from './ContextMenuContent.vue'
37
40
 
38
41
  const props = defineProps<ContextMenuContentProps<T>>()
39
42
  const emits = defineEmits<ContextMenuContentEmits>()
40
43
  const slots = defineSlots<ContextMenuSlots<T>>()
41
44
 
42
45
  const appConfig = useAppConfig()
43
- const contentProps = useForwardPropsEmits(reactiveOmit(props, 'sub', 'items', 'portal', 'class', 'ui'), emits)
46
+ const contentProps = useForwardPropsEmits(reactiveOmit(props, 'sub', 'items', 'portal', 'labelKey', 'checkedIcon', 'loadingIcon', 'externalIcon', 'class', 'ui', 'uiOverride'), emits)
44
47
  const proxySlots = omit(slots, ['default']) as Record<string, ContextMenuSlots<T>[string]>
45
48
 
46
49
  const [DefineItemTemplate, ReuseItemTemplate] = createReusableTemplate<{ item: ContextMenuItem, active?: boolean, index: number }>()
@@ -62,7 +65,7 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
62
65
  {{ get(item, props.labelKey as string) }}
63
66
  </slot>
64
67
 
65
- <UIcon v-if="item.target === '_blank'" :name="appConfig.ui.icons.external" :class="ui.itemLabelExternalIcon({ class: uiOverride?.itemLabelExternalIcon, color: item?.color, active })" />
68
+ <UIcon v-if="item.target === '_blank' && externalIcon !== false" :name="typeof externalIcon === 'string' ? externalIcon : appConfig.ui.icons.external" :class="ui.itemLabelExternalIcon({ class: uiOverride?.itemLabelExternalIcon, color: item?.color, active })" />
66
69
  </span>
67
70
 
68
71
  <span :class="ui.itemTrailing({ class: uiOverride?.itemTrailing })">
@@ -110,6 +113,7 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
110
113
  :label-key="labelKey"
111
114
  :checked-icon="checkedIcon"
112
115
  :loading-icon="loadingIcon"
116
+ :external-icon="externalIcon"
113
117
  v-bind="item.content"
114
118
  >
115
119
  <template v-for="(_, name) in proxySlots" #[name]="slotData: any">
@@ -119,11 +123,11 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
119
123
  </ContextMenu.Sub>
120
124
  <ContextMenu.CheckboxItem
121
125
  v-else-if="item.type === 'checkbox'"
122
- :checked="item.checked"
126
+ :model-value="item.checked"
123
127
  :disabled="item.disabled"
124
128
  :text-value="get(item, props.labelKey as string)"
125
129
  :class="ui.item({ class: [uiOverride?.item, item.class], color: item?.color })"
126
- @update:checked="item.onUpdateChecked"
130
+ @update:model-value="item.onUpdateChecked"
127
131
  @select="item.onSelect"
128
132
  >
129
133
  <ReuseItemTemplate :item="item" :index="index" />