@nuxt/ui 3.0.0-alpha.9 → 3.0.0-beta.2

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 (289) 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 +7 -5
  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 +5 -1
  22. package/.nuxt/ui/input-menu.ts +150 -116
  23. package/.nuxt/ui/input-number.ts +102 -71
  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 +77 -51
  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 +122 -86
  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 +48 -31
  42. package/.nuxt/ui/tabs.ts +100 -72
  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 +19 -8
  50. package/cli/commands/make/component.mjs +12 -0
  51. package/cli/package.json +2 -2
  52. package/cli/templates.mjs +27 -22
  53. package/dist/module.cjs +9 -171
  54. package/dist/module.d.cts +5 -15
  55. package/dist/module.d.mts +5 -15
  56. package/dist/module.d.ts +5 -15
  57. package/dist/module.json +2 -2
  58. package/dist/module.mjs +12 -168
  59. package/dist/runtime/components/Accordion.vue +8 -39
  60. package/dist/runtime/components/Alert.vue +22 -21
  61. package/dist/runtime/components/App.vue +9 -15
  62. package/dist/runtime/components/Avatar.vue +33 -21
  63. package/dist/runtime/components/AvatarGroup.vue +5 -7
  64. package/dist/runtime/components/Badge.vue +10 -8
  65. package/dist/runtime/components/Breadcrumb.vue +5 -31
  66. package/dist/runtime/components/Button.vue +5 -8
  67. package/dist/runtime/components/ButtonGroup.vue +5 -7
  68. package/dist/runtime/components/Calendar.vue +194 -0
  69. package/dist/runtime/components/Card.vue +10 -9
  70. package/dist/runtime/components/Carousel.vue +15 -10
  71. package/dist/runtime/components/Checkbox.vue +32 -38
  72. package/dist/runtime/components/Chip.vue +6 -8
  73. package/dist/runtime/components/Collapsible.vue +10 -11
  74. package/dist/runtime/components/ColorPicker.vue +297 -0
  75. package/dist/runtime/components/CommandPalette.vue +111 -97
  76. package/dist/runtime/components/Container.vue +4 -7
  77. package/dist/runtime/components/ContextMenu.vue +16 -69
  78. package/dist/runtime/components/ContextMenuContent.vue +12 -10
  79. package/dist/runtime/components/Drawer.vue +23 -12
  80. package/dist/runtime/components/DropdownMenu.vue +18 -59
  81. package/dist/runtime/components/DropdownMenuContent.vue +12 -10
  82. package/dist/runtime/components/Form.vue +65 -34
  83. package/dist/runtime/components/FormField.vue +22 -13
  84. package/dist/runtime/components/Icon.vue +1 -1
  85. package/dist/runtime/components/Input.vue +15 -7
  86. package/dist/runtime/components/InputMenu.vue +95 -104
  87. package/dist/runtime/components/InputNumber.vue +14 -9
  88. package/dist/runtime/components/Kbd.vue +5 -6
  89. package/dist/runtime/components/Link.vue +5 -8
  90. package/dist/runtime/components/LinkBase.vue +1 -1
  91. package/dist/runtime/components/Modal.vue +51 -38
  92. package/dist/runtime/components/NavigationMenu.vue +129 -114
  93. package/dist/runtime/components/OverlayProvider.vue +29 -0
  94. package/dist/runtime/components/Pagination.vue +6 -9
  95. package/dist/runtime/components/PinInput.vue +10 -11
  96. package/dist/runtime/components/Popover.vue +16 -18
  97. package/dist/runtime/components/Progress.vue +28 -12
  98. package/dist/runtime/components/RadioGroup.vue +9 -12
  99. package/dist/runtime/components/Select.vue +60 -34
  100. package/dist/runtime/components/SelectMenu.vue +160 -165
  101. package/dist/runtime/components/Separator.vue +6 -5
  102. package/dist/runtime/components/Skeleton.vue +4 -7
  103. package/dist/runtime/components/Slideover.vue +51 -37
  104. package/dist/runtime/components/Slider.vue +8 -7
  105. package/dist/runtime/components/Stepper.vue +170 -0
  106. package/dist/runtime/components/Switch.vue +19 -23
  107. package/dist/runtime/components/Table.vue +146 -31
  108. package/dist/runtime/components/Tabs.vue +12 -31
  109. package/dist/runtime/components/Textarea.vue +17 -8
  110. package/dist/runtime/components/Toast.vue +36 -25
  111. package/dist/runtime/components/Toaster.vue +10 -11
  112. package/dist/runtime/components/Tooltip.vue +9 -12
  113. package/dist/runtime/components/Tree.vue +196 -0
  114. package/dist/runtime/composables/defineShortcuts.d.ts +1 -1
  115. package/dist/runtime/composables/defineShortcuts.js +2 -2
  116. package/dist/runtime/composables/useFormField.d.ts +7 -3
  117. package/dist/runtime/composables/useFormField.js +18 -8
  118. package/dist/runtime/composables/useLocale.js +1 -1
  119. package/dist/runtime/composables/useOverlay.d.ts +30 -0
  120. package/dist/runtime/composables/useOverlay.js +71 -0
  121. package/dist/runtime/composables/useToast.d.ts +4 -3
  122. package/dist/runtime/composables/useToast.js +20 -6
  123. package/dist/runtime/index.css +1 -1
  124. package/dist/runtime/keyframes.css +1 -1
  125. package/dist/runtime/locale/ar.js +9 -1
  126. package/dist/runtime/locale/az.js +54 -0
  127. package/dist/runtime/locale/bn.js +54 -0
  128. package/dist/runtime/locale/cs.js +9 -1
  129. package/dist/runtime/locale/da.d.ts +2 -0
  130. package/dist/runtime/locale/da.js +54 -0
  131. package/dist/runtime/locale/de.js +11 -3
  132. package/dist/runtime/locale/el.d.ts +2 -0
  133. package/dist/runtime/locale/el.js +54 -0
  134. package/dist/runtime/locale/en.js +9 -1
  135. package/dist/runtime/locale/es.js +9 -1
  136. package/dist/runtime/locale/et.d.ts +2 -0
  137. package/dist/runtime/locale/et.js +54 -0
  138. package/dist/runtime/locale/fa_ir.js +9 -1
  139. package/dist/runtime/locale/fi.d.ts +2 -0
  140. package/dist/runtime/locale/fi.js +54 -0
  141. package/dist/runtime/locale/fr.js +9 -1
  142. package/dist/runtime/locale/he.d.ts +2 -0
  143. package/dist/runtime/locale/he.js +53 -0
  144. package/dist/runtime/locale/hi.d.ts +2 -0
  145. package/dist/runtime/locale/hi.js +54 -0
  146. package/dist/runtime/locale/hu.d.ts +2 -0
  147. package/dist/runtime/locale/hu.js +54 -0
  148. package/dist/runtime/locale/id.d.ts +2 -0
  149. package/dist/runtime/locale/id.js +54 -0
  150. package/dist/runtime/locale/index.d.ts +25 -3
  151. package/dist/runtime/locale/index.js +25 -3
  152. package/dist/runtime/locale/it.js +9 -1
  153. package/dist/runtime/locale/ja.d.ts +2 -0
  154. package/dist/runtime/locale/ja.js +54 -0
  155. package/dist/runtime/locale/km.d.ts +2 -0
  156. package/dist/runtime/locale/km.js +54 -0
  157. package/dist/runtime/locale/ko.d.ts +2 -0
  158. package/dist/runtime/locale/ko.js +54 -0
  159. package/dist/runtime/locale/nb_no.d.ts +2 -0
  160. package/dist/runtime/locale/nb_no.js +54 -0
  161. package/dist/runtime/locale/nl.d.ts +2 -0
  162. package/dist/runtime/locale/nl.js +54 -0
  163. package/dist/runtime/locale/pl.js +9 -1
  164. package/dist/runtime/locale/pt.d.ts +2 -0
  165. package/dist/runtime/locale/pt.js +54 -0
  166. package/dist/runtime/locale/pt_br.d.ts +2 -0
  167. package/dist/runtime/locale/pt_br.js +54 -0
  168. package/dist/runtime/locale/ru.js +9 -1
  169. package/dist/runtime/locale/sk.d.ts +2 -0
  170. package/dist/runtime/locale/sk.js +54 -0
  171. package/dist/runtime/locale/sv.d.ts +2 -0
  172. package/dist/runtime/locale/sv.js +54 -0
  173. package/dist/runtime/locale/th.d.ts +2 -0
  174. package/dist/runtime/locale/th.js +54 -0
  175. package/dist/runtime/locale/tr.d.ts +2 -0
  176. package/dist/runtime/locale/tr.js +54 -0
  177. package/dist/runtime/locale/uk.d.ts +2 -0
  178. package/dist/runtime/locale/uk.js +54 -0
  179. package/dist/runtime/locale/vi.d.ts +2 -0
  180. package/dist/runtime/locale/vi.js +54 -0
  181. package/dist/runtime/locale/zh_cn.d.ts +2 -0
  182. package/dist/runtime/locale/{zh_hans.js → zh_cn.js} +10 -2
  183. package/dist/runtime/locale/zh_tw.d.ts +2 -0
  184. package/dist/runtime/locale/{zh_hant.js → zh_tw.js} +16 -8
  185. package/dist/runtime/plugins/colors.js +8 -5
  186. package/dist/runtime/types/form.d.ts +24 -15
  187. package/dist/runtime/types/form.js +2 -2
  188. package/dist/runtime/types/index.d.ts +5 -0
  189. package/dist/runtime/types/index.js +5 -0
  190. package/dist/runtime/types/locale.d.ts +8 -0
  191. package/dist/runtime/types/utils.d.ts +7 -3
  192. package/dist/runtime/utils/form.d.ts +4 -4
  193. package/dist/runtime/utils/form.js +6 -8
  194. package/dist/runtime/utils/index.d.ts +1 -1
  195. package/dist/runtime/utils/index.js +15 -2
  196. package/dist/runtime/utils/tv.d.ts +1 -0
  197. package/dist/runtime/utils/tv.js +4 -0
  198. package/dist/runtime/vue/components/Icon.vue +2 -2
  199. package/dist/runtime/vue/components/Link.vue +87 -23
  200. package/dist/runtime/vue/composables/useAppConfig.d.ts +1 -0
  201. package/dist/runtime/vue/composables/useAppConfig.js +2 -0
  202. package/dist/runtime/vue/plugins/head.d.ts +1 -1
  203. package/dist/runtime/vue/plugins/head.js +3 -3
  204. package/dist/runtime/vue/stubs.d.ts +19 -0
  205. package/dist/runtime/vue/stubs.js +37 -0
  206. package/dist/shared/{ui.d52SSCwA.mjs → ui.DSPu6Y8j.mjs} +905 -401
  207. package/dist/shared/{ui.BPnAe4QS.cjs → ui.DfK2RX6G.cjs} +908 -401
  208. package/dist/unplugin.cjs +62 -26
  209. package/dist/unplugin.d.cts +13 -1
  210. package/dist/unplugin.d.mts +13 -1
  211. package/dist/unplugin.d.ts +13 -1
  212. package/dist/unplugin.mjs +61 -25
  213. package/dist/vite.cjs +3 -2
  214. package/dist/vite.d.cts +2 -0
  215. package/dist/vite.d.mts +2 -0
  216. package/dist/vite.d.ts +2 -0
  217. package/dist/vite.mjs +3 -2
  218. package/package.json +103 -67
  219. package/dist/chunks/component-meta.cjs +0 -77249
  220. package/dist/chunks/component-meta.mjs +0 -77247
  221. package/dist/client/devtools/200.html +0 -1
  222. package/dist/client/devtools/404.html +0 -1
  223. package/dist/client/devtools/_fonts/rP2Wp2ywxg089UriCZaSExd86J3t9jz86MvyyKK58UfivUw4aw-SK92LTmKP0.woff2 +0 -0
  224. package/dist/client/devtools/_fonts/rP2Wp2ywxg089UriCZaSExd86J3t9jz86MvyyKy58UfivUw-9uYm8d48E4.woff2 +0 -0
  225. package/dist/client/devtools/_fonts/rP2Yp2ywxg089UriI5-g4vlH9VoD8Cmcqbu0-K6z9mXg-VNw7NHvqnp.woff2 +0 -0
  226. package/dist/client/devtools/_fonts/rP2Yp2ywxg089UriI5-g4vlH9VoD8Cmcqbu6-K6z9mXgjU0-EkYdMs3MAX.woff2 +0 -0
  227. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat-7DW3w-R7n06NbhGy.woff +0 -0
  228. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat-JDG3w-leGNfkTmsj.woff +0 -0
  229. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat-JDW3w-ciElMF03ku.woff +0 -0
  230. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat8JCm3w-sB722Uoa0f.woff +0 -0
  231. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat8JDW3w-PBDI1JDjwV.woff +0 -0
  232. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat8gCm3w-0q1hqVn09O.woff +0 -0
  233. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat9XCm3w-ByvzuLy2fa.woff +0 -0
  234. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat9uCm3w-5TKCIs6EEw.woff +0 -0
  235. package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat_XDW3w-r2swRDGfn2.woff +0 -0
  236. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAC5thTQ-ldB60l5U8r.woff +0 -0
  237. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAIpthTQ-wbFKGFDrgo.woff +0 -0
  238. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAIpxhTQ-LLUBv5jskj.woff +0 -0
  239. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwARZthTQ-F71RdTRbNg.woff +0 -0
  240. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwA_JxhTQ-6nh65gZkc0.woff +0 -0
  241. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAfJthTQ-aMoWEJLmTt.woff +0 -0
  242. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAkJxhTQ-WMBvmLOgKm.woff +0 -0
  243. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAop1hTQ-utGC2hnWq2.woff +0 -0
  244. package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAopxhTQ-YpyTieVa5B.woff +0 -0
  245. package/dist/client/devtools/_nuxt/BDC8ywlR.js +0 -1
  246. package/dist/client/devtools/_nuxt/BT004Uxp.js +0 -53
  247. package/dist/client/devtools/_nuxt/C1H2Soz3.js +0 -1
  248. package/dist/client/devtools/_nuxt/builds/latest.json +0 -1
  249. package/dist/client/devtools/_nuxt/builds/meta/f98c13ea-d751-4b37-8ce3-94e99708745f.json +0 -1
  250. package/dist/client/devtools/_nuxt/entry.Bx6WJjrx.css +0 -1
  251. package/dist/client/devtools/_nuxt/error-404.Cq4qshcf.css +0 -1
  252. package/dist/client/devtools/_nuxt/error-500.ax1aM34m.css +0 -1
  253. package/dist/client/devtools/favicon.svg +0 -1
  254. package/dist/client/devtools/index.html +0 -1
  255. package/dist/devtools/runtime/DevtoolsRenderer.vue +0 -53
  256. package/dist/devtools/runtime/examples/AvatarGroupExample.vue +0 -7
  257. package/dist/devtools/runtime/examples/ButtonGroupExample.vue +0 -8
  258. package/dist/devtools/runtime/examples/CardExample.vue +0 -13
  259. package/dist/devtools/runtime/examples/CarouselExample.vue +0 -13
  260. package/dist/devtools/runtime/examples/ChipExample.vue +0 -5
  261. package/dist/devtools/runtime/examples/CollapsibleExample.vue +0 -8
  262. package/dist/devtools/runtime/examples/CommandPaletteExample.vue +0 -29
  263. package/dist/devtools/runtime/examples/ContainerExample.vue +0 -5
  264. package/dist/devtools/runtime/examples/ContextMenuExample.vue +0 -5
  265. package/dist/devtools/runtime/examples/DrawerExample.vue +0 -8
  266. package/dist/devtools/runtime/examples/DropdownMenuExample.vue +0 -5
  267. package/dist/devtools/runtime/examples/FormExample.vue +0 -30
  268. package/dist/devtools/runtime/examples/FormFieldExample.vue +0 -5
  269. package/dist/devtools/runtime/examples/LinkExample.vue +0 -5
  270. package/dist/devtools/runtime/examples/ModalExample.vue +0 -8
  271. package/dist/devtools/runtime/examples/PopoverExample.vue +0 -8
  272. package/dist/devtools/runtime/examples/SkeletonExample.vue +0 -3
  273. package/dist/devtools/runtime/examples/SlideoverExample.vue +0 -8
  274. package/dist/devtools/runtime/examples/ToasterExample.vue +0 -11
  275. package/dist/devtools/runtime/examples/TooltipExample.vue +0 -5
  276. package/dist/runtime/components/ModalProvider.vue +0 -12
  277. package/dist/runtime/components/SlideoverProvider.vue +0 -12
  278. package/dist/runtime/composables/extendDevtoolsMeta.d.ts +0 -7
  279. package/dist/runtime/composables/extendDevtoolsMeta.js +0 -2
  280. package/dist/runtime/composables/useModal.d.ts +0 -17
  281. package/dist/runtime/composables/useModal.js +0 -46
  282. package/dist/runtime/composables/useSlideover.d.ts +0 -17
  283. package/dist/runtime/composables/useSlideover.js +0 -46
  284. package/dist/runtime/plugins/modal.d.ts +0 -2
  285. package/dist/runtime/plugins/modal.js +0 -10
  286. package/dist/runtime/plugins/slideover.d.ts +0 -2
  287. package/dist/runtime/plugins/slideover.js +0 -10
  288. /package/dist/runtime/locale/{zh_hans.d.ts → az.d.ts} +0 -0
  289. /package/dist/runtime/locale/{zh_hant.d.ts → bn.d.ts} +0 -0
@@ -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
@@ -36,17 +36,17 @@ export interface CommandPaletteGroup<T> {
36
36
  items?: T[]
37
37
  /**
38
38
  * Whether 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
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,13 +121,11 @@ 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'
@@ -127,27 +133,31 @@ import { useAppConfig } from '#imports'
127
133
  import { useLocale } from '../composables/useLocale'
128
134
  import { omit, get } from '../utils'
129
135
  import { highlight } from '../utils/fuse'
136
+ import { pickLinkProps } from '../utils/link'
130
137
  import UIcon from './Icon.vue'
131
138
  import UAvatar from './Avatar.vue'
132
139
  import UButton from './Button.vue'
133
140
  import UChip from './Chip.vue'
134
- import UKbd from './Kbd.vue'
141
+ import ULinkBase from './LinkBase.vue'
142
+ import ULink from './Link.vue'
135
143
  import UInput from './Input.vue'
144
+ import UKbd from './Kbd.vue'
136
145
 
137
146
  const props = withDefaults(defineProps<CommandPaletteProps<G, T>>(), {
138
147
  modelValue: '',
139
- placeholder: 'Type a command or search...',
140
- labelKey: 'label'
148
+ labelKey: 'label',
149
+ autofocus: true
141
150
  })
142
151
  const emits = defineEmits<CommandPaletteEmits<T>>()
143
152
  const slots = defineSlots<CommandPaletteSlots<G, T>>()
144
153
 
145
154
  const searchTerm = defineModel<string>('searchTerm', { default: '' })
146
155
 
147
- const appConfig = useAppConfig()
148
156
  const { t } = useLocale()
149
- const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'disabled', 'multiple', 'modelValue', 'defaultValue', 'selectedValue', 'resetSearchTermOnBlur'), emits)
150
- const inputProps = useForwardProps(reactivePick(props, 'loading', 'loadingIcon', 'placeholder'))
157
+ const appConfig = useAppConfig()
158
+
159
+ const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'disabled', 'multiple', 'modelValue', 'defaultValue', 'highlightOnHover'), emits)
160
+ const inputProps = useForwardProps(reactivePick(props, 'loading', 'loadingIcon'))
151
161
 
152
162
  // eslint-disable-next-line vue/no-dupe-keys
153
163
  const ui = commandPalette()
@@ -168,7 +178,7 @@ const items = computed(() => props.groups?.filter((group) => {
168
178
  return false
169
179
  }
170
180
 
171
- if (group.filter === false) {
181
+ if (group.ignoreFilter) {
172
182
  return false
173
183
  }
174
184
 
@@ -216,24 +226,26 @@ const groups = computed(() => {
216
226
  return getGroupWithItems(group, items)
217
227
  }).filter(group => !!group)
218
228
 
219
- const nonFuseGroups = props.groups?.filter(group => group.filter === false && group.items?.length).map((group) => {
220
- return getGroupWithItems(group, group.items || [])
221
- }) || []
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 })) || []
222
233
 
223
- return [
224
- ...fuseGroups,
225
- ...nonFuseGroups
226
- ]
234
+ return nonFuseGroups.reduce((acc, group) => {
235
+ acc.splice(group.index, 0, group)
236
+ return acc
237
+ }, [...fuseGroups])
227
238
  })
228
239
  </script>
229
240
 
230
241
  <!-- eslint-disable vue/no-v-html -->
231
242
  <template>
232
- <ComboboxRoot v-bind="rootProps" v-model:search-term="searchTerm" open :class="ui.root({ class: [props.class, props.ui?.root] })">
233
- <ComboboxInput as-child>
243
+ <ListboxRoot v-bind="rootProps" :class="ui.root({ class: [props.class, props.ui?.root] })">
244
+ <ListboxFilter v-model="searchTerm" as-child>
234
245
  <UInput
246
+ :placeholder="placeholder || t('commandPalette.placeholder')"
235
247
  variant="none"
236
- autofocus
248
+ :autofocus="autofocus"
237
249
  size="lg"
238
250
  v-bind="inputProps"
239
251
  :icon="icon || appConfig.ui.icons.search"
@@ -248,79 +260,81 @@ const groups = computed(() => {
248
260
  color="neutral"
249
261
  variant="ghost"
250
262
  :aria-label="t('commandPalette.close')"
251
- v-bind="typeof close === 'object' ? close : undefined"
263
+ v-bind="(typeof close === 'object' ? close as Partial<ButtonProps> : {})"
252
264
  :class="ui.close({ class: props.ui?.close })"
253
265
  @click="emits('update:open', false)"
254
266
  />
255
267
  </slot>
256
268
  </template>
257
269
  </UInput>
258
- </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>
259
303
 
260
- <ComboboxPortal disabled>
261
- <ComboboxContent :class="ui.content({ class: props.ui?.content })" :dismissable="false">
262
- <ComboboxEmpty :class="ui.empty({ class: props.ui?.empty })">
263
- <slot name="empty" :search-term="searchTerm">
264
- {{ searchTerm ? t('commandPalette.noMatch', { searchTerm }) : t('commandPalette.noData') }}
265
- </slot>
266
- </ComboboxEmpty>
267
-
268
- <ComboboxViewport :class="ui.viewport({ class: props.ui?.viewport })">
269
- <ComboboxGroup v-for="(group, groupIndex) in groups" :key="`group-${groupIndex}`" :class="ui.group({ class: props.ui?.group })">
270
- <ComboboxLabel v-if="get(group, props.labelKey as string)" :class="ui.label({ class: props.ui?.label })">
271
- {{ get(group, props.labelKey as string) }}
272
- </ComboboxLabel>
273
-
274
- <ComboboxItem
275
- v-for="(item, index) in group.items"
276
- :key="`group-${groupIndex}-${index}`"
277
- :value="omit(item, ['matches' as any, 'group' as any, 'onSelect', 'labelHtml', 'suffixHtml'])"
278
- :disabled="item.disabled"
279
- :class="ui.item({ class: props.ui?.item })"
280
- @select="item.onSelect"
281
- >
282
- <slot :name="item.slot || group.slot || 'item'" :item="item" :index="index">
283
- <slot :name="item.slot ? `${item.slot}-leading` : group.slot ? `${group.slot}-leading` : `item-leading`" :item="item" :index="index">
284
- <UIcon v-if="item.loading" :name="loadingIcon || appConfig.ui.icons.loading" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon, loading: true })" />
285
- <UIcon v-else-if="item.icon" :name="item.icon" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon })" />
286
- <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 })" />
287
- <UChip
288
- v-else-if="item.chip"
289
- :size="((props.ui?.itemLeadingChipSize || ui.itemLeadingChipSize()) as ChipProps['size'])"
290
- inset
291
- standalone
292
- v-bind="item.chip"
293
- :class="ui.itemLeadingChip({ class: props.ui?.itemLeadingChip })"
294
- />
295
- </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>
296
307
 
297
- <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 })">
298
- <slot :name="item.slot ? `${item.slot}-label` : group.slot ? `${group.slot}-label` : `item-label`" :item="item" :index="index">
299
- <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)" />
300
309
 
301
- <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>
302
313
 
303
- <span :class="ui.itemLabelSuffix({ class: props.ui?.itemLabelSuffix })" v-html="item.suffixHtml || item.suffix" />
304
- </slot>
305
- </span>
306
-
307
- <span :class="ui.itemTrailing({ class: props.ui?.itemTrailing })">
308
- <slot :name="item.slot ? `${item.slot}-trailing` : group.slot ? `${group.slot}-trailing` : `item-trailing`" :item="item" :index="index">
309
- <span v-if="item.kbds?.length" :class="ui.itemTrailingKbds({ class: props.ui?.itemTrailingKbds })">
310
- <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" />
311
- </span>
312
- <UIcon v-else-if="group.highlightedIcon" :name="group.highlightedIcon" :class="ui.itemTrailingHighlightedIcon({ class: props.ui?.itemTrailingHighlightedIcon })" />
313
- </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>
314
321
 
315
- <ComboboxItemIndicator as-child>
316
- <UIcon :name="selectedIcon || appConfig.ui.icons.check" :class="ui.itemTrailingIcon({ class: props.ui?.itemTrailingIcon })" />
317
- </ComboboxItemIndicator>
318
- </span>
319
- </slot>
320
- </ComboboxItem>
321
- </ComboboxGroup>
322
- </ComboboxViewport>
323
- </ComboboxContent>
324
- </ComboboxPortal>
325
- </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>
326
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'
@@ -42,7 +43,7 @@ const emits = defineEmits<ContextMenuContentEmits>()
42
43
  const slots = defineSlots<ContextMenuSlots<T>>()
43
44
 
44
45
  const appConfig = useAppConfig()
45
- 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)
46
47
  const proxySlots = omit(slots, ['default']) as Record<string, ContextMenuSlots<T>[string]>
47
48
 
48
49
  const [DefineItemTemplate, ReuseItemTemplate] = createReusableTemplate<{ item: ContextMenuItem, active?: boolean, index: number }>()
@@ -64,7 +65,7 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
64
65
  {{ get(item, props.labelKey as string) }}
65
66
  </slot>
66
67
 
67
- <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 })" />
68
69
  </span>
69
70
 
70
71
  <span :class="ui.itemTrailing({ class: uiOverride?.itemTrailing })">
@@ -112,6 +113,7 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
112
113
  :label-key="labelKey"
113
114
  :checked-icon="checkedIcon"
114
115
  :loading-icon="loadingIcon"
116
+ :external-icon="externalIcon"
115
117
  v-bind="item.content"
116
118
  >
117
119
  <template v-for="(_, name) in proxySlots" #[name]="slotData: any">
@@ -121,11 +123,11 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
121
123
  </ContextMenu.Sub>
122
124
  <ContextMenu.CheckboxItem
123
125
  v-else-if="item.type === 'checkbox'"
124
- :checked="item.checked"
126
+ :model-value="item.checked"
125
127
  :disabled="item.disabled"
126
128
  :text-value="get(item, props.labelKey as string)"
127
129
  :class="ui.item({ class: [uiOverride?.item, item.class], color: item?.color })"
128
- @update:checked="item.onUpdateChecked"
130
+ @update:model-value="item.onUpdateChecked"
129
131
  @select="item.onSelect"
130
132
  >
131
133
  <ReuseItemTemplate :item="item" :index="index" />