@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,15 +1,16 @@
1
1
  <script lang="ts">
2
- import { tv, type VariantProps } from 'tailwind-variants'
3
- import type { ToastRootProps, ToastRootEmits } from 'radix-vue'
2
+ import type { VariantProps } from 'tailwind-variants'
3
+ import type { ToastRootProps, ToastRootEmits } 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/toast'
7
- import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
7
+ import { tv } from '../utils/tv'
8
8
  import type { AvatarProps, ButtonProps } from '../types'
9
+ import type { StringOrVNode } from '../types/utils'
9
10
 
10
- const appConfig = _appConfig as AppConfig & { ui: { toast: Partial<typeof theme> } }
11
+ const appConfigToast = _appConfig as AppConfig & { ui: { toast: Partial<typeof theme> } }
11
12
 
12
- const toast = tv({ extend: tv(theme), ...(appConfig.ui?.toast || {}) })
13
+ const toast = tv({ extend: tv(theme), ...(appConfigToast.ui?.toast || {}) })
13
14
 
14
15
  type ToastVariants = VariantProps<typeof toast>
15
16
 
@@ -19,15 +20,17 @@ export interface ToastProps extends Pick<ToastRootProps, 'defaultOpen' | 'open'
19
20
  * @defaultValue 'li'
20
21
  */
21
22
  as?: any
22
- title?: string
23
- description?: string
23
+ title?: StringOrVNode
24
+ description?: StringOrVNode
24
25
  icon?: string
25
26
  avatar?: AvatarProps
26
27
  color?: ToastVariants['color']
28
+ orientation?: ToastVariants['orientation']
27
29
  /**
28
30
  * Display a list of actions:
29
- * - under the title and description if multiline
30
- * - next to the close button if not multiline
31
+ * - under the title and description when orientation is `vertical`
32
+ * - next to the close button when orientation is `horizontal`
33
+ * `{ size: 'xs' }`{lang="ts-type"}
31
34
  */
32
35
  actions?: ButtonProps[]
33
36
  /**
@@ -35,7 +38,7 @@ export interface ToastProps extends Pick<ToastRootProps, 'defaultOpen' | 'open'
35
38
  * `{ size: 'md', color: 'neutral', variant: 'link' }`{lang="ts-type"}
36
39
  * @defaultValue true
37
40
  */
38
- close?: ButtonProps | boolean
41
+ close?: boolean | Partial<ButtonProps>
39
42
  /**
40
43
  * The icon displayed in the close button.
41
44
  * @defaultValue appConfig.ui.icons.close
@@ -54,32 +57,34 @@ export interface ToastSlots {
54
57
  actions(props?: {}): any
55
58
  close(props: { ui: any }): any
56
59
  }
57
-
58
- extendDevtoolsMeta<ToastProps>({ ignore: true })
59
60
  </script>
60
61
 
61
62
  <script setup lang="ts">
62
63
  import { ref, computed, onMounted } from 'vue'
63
- import { ToastRoot, ToastTitle, ToastDescription, ToastAction, ToastClose, useForwardPropsEmits } from 'radix-vue'
64
+ import { ToastRoot, ToastTitle, ToastDescription, ToastAction, ToastClose, useForwardPropsEmits } from 'reka-ui'
64
65
  import { reactivePick } from '@vueuse/core'
65
66
  import { useAppConfig } from '#imports'
67
+ import { useLocale } from '../composables/useLocale'
66
68
  import UIcon from './Icon.vue'
67
69
  import UAvatar from './Avatar.vue'
68
70
  import UButton from './Button.vue'
69
71
 
70
72
  const props = withDefaults(defineProps<ToastProps>(), {
71
- close: true
73
+ close: true,
74
+ orientation: 'vertical'
72
75
  })
73
76
  const emits = defineEmits<ToastEmits>()
74
77
  const slots = defineSlots<ToastSlots>()
75
78
 
79
+ const { t } = useLocale()
76
80
  const appConfig = useAppConfig()
77
- const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'defaultOpen', 'open', 'duration', 'type'), emits)
78
81
 
79
- const multiline = computed(() => !!props.title && !!props.description)
82
+ const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'defaultOpen', 'open', 'duration', 'type'), emits)
80
83
 
81
84
  const ui = computed(() => toast({
82
- color: props.color
85
+ color: props.color,
86
+ orientation: props.orientation,
87
+ title: !!props.title || !!slots.title
83
88
  }))
84
89
 
85
90
  const el = ref()
@@ -105,7 +110,8 @@ defineExpose({
105
110
  ref="el"
106
111
  v-slot="{ remaining, duration }"
107
112
  v-bind="rootProps"
108
- :class="ui.root({ class: [props.class, props.ui?.root], multiline })"
113
+ :data-orientation="orientation"
114
+ :class="ui.root({ class: [props.class, props.ui?.root] })"
109
115
  :style="{ '--height': height }"
110
116
  >
111
117
  <slot name="leading">
@@ -116,16 +122,24 @@ defineExpose({
116
122
  <div :class="ui.wrapper({ class: props.ui?.wrapper })">
117
123
  <ToastTitle v-if="title || !!slots.title" :class="ui.title({ class: props.ui?.title })">
118
124
  <slot name="title">
119
- {{ title }}
125
+ <component :is="title()" v-if="typeof title === 'function'" />
126
+ <component :is="title" v-else-if="typeof title === 'object'" />
127
+ <template v-else>
128
+ {{ title }}
129
+ </template>
120
130
  </slot>
121
131
  </ToastTitle>
122
132
  <ToastDescription v-if="description || !!slots.description" :class="ui.description({ class: props.ui?.description })">
123
133
  <slot name="description">
124
- {{ description }}
134
+ <component :is="description()" v-if="typeof description === 'function'" />
135
+ <component :is="description" v-else-if="typeof description === 'object'" />
136
+ <template v-else>
137
+ {{ description }}
138
+ </template>
125
139
  </slot>
126
140
  </ToastDescription>
127
141
 
128
- <div v-if="multiline && actions?.length" :class="ui.actions({ class: props.ui?.actions, multiline: true })">
142
+ <div v-if="orientation === 'vertical' && actions?.length" :class="ui.actions({ class: props.ui?.actions })">
129
143
  <slot name="actions">
130
144
  <ToastAction v-for="(action, index) in actions" :key="index" :alt-text="action.label || 'Action'" as-child @click.stop>
131
145
  <UButton size="xs" :color="color" v-bind="action" />
@@ -134,8 +148,8 @@ defineExpose({
134
148
  </div>
135
149
  </div>
136
150
 
137
- <div v-if="(!multiline && actions?.length) || close !== null" :class="ui.actions({ class: props.ui?.actions, multiline: false })">
138
- <template v-if="!multiline">
151
+ <div v-if="(orientation === 'horizontal' && actions?.length) || close" :class="ui.actions({ class: props.ui?.actions, orientation: 'horizontal' })">
152
+ <template v-if="orientation === 'horizontal' && actions?.length">
139
153
  <slot name="actions">
140
154
  <ToastAction v-for="(action, index) in actions" :key="index" :alt-text="action.label || 'Action'" as-child @click.stop>
141
155
  <UButton size="xs" :color="color" v-bind="action" />
@@ -151,8 +165,8 @@ defineExpose({
151
165
  size="md"
152
166
  color="neutral"
153
167
  variant="link"
154
- aria-label="Close"
155
- v-bind="typeof close === 'object' ? close : undefined"
168
+ :aria-label="t('toast.close')"
169
+ v-bind="(typeof close === 'object' ? close as Partial<ButtonProps> : {})"
156
170
  :class="ui.close({ class: props.ui?.close })"
157
171
  @click.stop
158
172
  />
@@ -1,14 +1,14 @@
1
1
  <script lang="ts">
2
- import { tv, type VariantProps } from 'tailwind-variants'
3
- import type { ToastProviderProps } from 'radix-vue'
2
+ import type { VariantProps } from 'tailwind-variants'
3
+ import type { ToastProviderProps } 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/toaster'
7
- import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
7
+ import { tv } from '../utils/tv'
8
8
 
9
- const appConfig = _appConfig as AppConfig & { ui: { toaster: Partial<typeof theme> } }
9
+ const appConfigToaster = _appConfig as AppConfig & { ui: { toaster: Partial<typeof theme> } }
10
10
 
11
- const toaster = tv({ extend: tv(theme), ...(appConfig.ui?.toaster || {}) })
11
+ const toaster = tv({ extend: tv(theme), ...(appConfigToaster.ui?.toaster || {}) })
12
12
 
13
13
  type ToasterVariants = VariantProps<typeof toaster>
14
14
 
@@ -19,6 +19,11 @@ export interface ToasterProps extends Omit<ToastProviderProps, 'swipeDirection'>
19
19
  * @defaultValue true
20
20
  */
21
21
  expand?: boolean
22
+ /**
23
+ * Render the toaster in a portal.
24
+ * @defaultValue true
25
+ */
26
+ portal?: boolean
22
27
  class?: any
23
28
  ui?: Partial<typeof toaster.slots>
24
29
  }
@@ -30,13 +35,11 @@ export interface ToasterSlots {
30
35
  export default {
31
36
  name: 'Toaster'
32
37
  }
33
-
34
- extendDevtoolsMeta({ example: 'ToasterExample' })
35
38
  </script>
36
39
 
37
40
  <script setup lang="ts">
38
41
  import { ref, computed } from 'vue'
39
- import { ToastProvider, ToastViewport, useForwardProps } from 'radix-vue'
42
+ import { ToastProvider, ToastViewport, ToastPortal, useForwardProps } from 'reka-ui'
40
43
  import { reactivePick } from '@vueuse/core'
41
44
  import { useToast } from '../composables/useToast'
42
45
  import { omit } from '../utils'
@@ -44,6 +47,7 @@ import UToast from './Toast.vue'
44
47
 
45
48
  const props = withDefaults(defineProps<ToasterProps>(), {
46
49
  expand: true,
50
+ portal: true,
47
51
  duration: 5000
48
52
  })
49
53
  defineSlots<ToasterSlots>()
@@ -102,7 +106,8 @@ function getOffset(index: number) {
102
106
  v-for="(toast, index) of toasts"
103
107
  :key="toast.id"
104
108
  ref="refs"
105
- v-bind="omit(toast, ['id'])"
109
+ v-bind="omit(toast, ['id', 'close'])"
110
+ :close="(toast.close as boolean)"
106
111
  :data-expanded="expanded"
107
112
  :data-front="!expanded && index === toasts.length - 1"
108
113
  :style="{
@@ -114,24 +119,26 @@ function getOffset(index: number) {
114
119
  '--transform': 'translateY(var(--translate)) scale(var(--scale))'
115
120
  }"
116
121
  :class="[ui.base(), {
117
- 'cursor-pointer': !!toast.click
122
+ 'cursor-pointer': !!toast.onClick
118
123
  }]"
119
124
  @update:open="onUpdateOpen($event, toast.id)"
120
- @click="toast.click && toast.click(toast)"
125
+ @click="toast.onClick && toast.onClick(toast)"
121
126
  />
122
127
 
123
- <ToastViewport
124
- :data-expanded="expanded"
125
- :class="ui.viewport({ class: [props.class, props.ui?.viewport] })"
126
- :style="{
127
- '--scale-factor': '0.05',
128
- '--translate-factor': position?.startsWith('top') ? '1px' : '-1px',
129
- '--gap': position?.startsWith('top') ? '16px' : '-16px',
130
- '--front-height': `${frontHeight}px`,
131
- '--height': `${height}px`
132
- }"
133
- @mouseenter="hovered = true"
134
- @mouseleave="hovered = false"
135
- />
128
+ <ToastPortal :disabled="!portal">
129
+ <ToastViewport
130
+ :data-expanded="expanded"
131
+ :class="ui.viewport({ class: [props.class, props.ui?.viewport] })"
132
+ :style="{
133
+ '--scale-factor': '0.05',
134
+ '--translate-factor': position?.startsWith('top') ? '1px' : '-1px',
135
+ '--gap': position?.startsWith('top') ? '16px' : '-16px',
136
+ '--front-height': `${frontHeight}px`,
137
+ '--height': `${height}px`
138
+ }"
139
+ @mouseenter="hovered = true"
140
+ @mouseleave="hovered = false"
141
+ />
142
+ </ToastPortal>
136
143
  </ToastProvider>
137
144
  </template>
@@ -1,15 +1,14 @@
1
1
  <script lang="ts">
2
- import { tv } from 'tailwind-variants'
3
- import type { TooltipRootProps, TooltipRootEmits, TooltipContentProps, TooltipArrowProps } from 'radix-vue'
2
+ import type { TooltipRootProps, TooltipRootEmits, TooltipContentProps, TooltipArrowProps } from 'reka-ui'
4
3
  import type { AppConfig } from '@nuxt/schema'
5
4
  import _appConfig from '#build/app.config'
6
5
  import theme from '#build/ui/tooltip'
7
- import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
6
+ import { tv } from '../utils/tv'
8
7
  import type { KbdProps } from '../types'
9
8
 
10
- const appConfig = _appConfig as AppConfig & { ui: { tooltip: Partial<typeof theme> } }
9
+ const appConfigTooltip = _appConfig as AppConfig & { ui: { tooltip: Partial<typeof theme> } }
11
10
 
12
- const tooltip = tv({ extend: tv(theme), ...(appConfig.ui?.tooltip || {}) })
11
+ const tooltip = tv({ extend: tv(theme), ...(appConfigTooltip.ui?.tooltip || {}) })
13
12
 
14
13
  export interface TooltipProps extends TooltipRootProps {
15
14
  /** The text content of the tooltip. */
@@ -18,7 +17,7 @@ export interface TooltipProps extends TooltipRootProps {
18
17
  kbds?: KbdProps['value'][] | KbdProps[]
19
18
  /**
20
19
  * The content of the tooltip.
21
- * @defaultValue { side: 'bottom', sideOffset: 8 }
20
+ * @defaultValue { side: 'bottom', sideOffset: 8, collisionPadding: 8 }
22
21
  */
23
22
  content?: Omit<TooltipContentProps, 'as' | 'asChild'>
24
23
  /**
@@ -41,14 +40,12 @@ export interface TooltipSlots {
41
40
  default(props: { open: boolean }): any
42
41
  content(props?: {}): any
43
42
  }
44
-
45
- extendDevtoolsMeta({ example: 'TooltipExample', defaultProps: { text: 'Hello world!' } })
46
43
  </script>
47
44
 
48
45
  <script setup lang="ts">
49
46
  import { computed, toRef } from 'vue'
50
47
  import { defu } from 'defu'
51
- import { TooltipRoot, TooltipTrigger, TooltipPortal, TooltipContent, TooltipArrow, useForwardPropsEmits } from 'radix-vue'
48
+ import { TooltipRoot, TooltipTrigger, TooltipPortal, TooltipContent, TooltipArrow, useForwardPropsEmits } from 'reka-ui'
52
49
  import { reactivePick } from '@vueuse/core'
53
50
  import UKbd from './Kbd.vue'
54
51
 
@@ -59,7 +56,7 @@ const emits = defineEmits<TooltipEmits>()
59
56
  const slots = defineSlots<TooltipSlots>()
60
57
 
61
58
  const rootProps = useForwardPropsEmits(reactivePick(props, 'defaultOpen', 'open', 'delayDuration', 'disableHoverableContent', 'disableClosingTrigger', 'disabled', 'ignoreNonKeyboardFocus'), emits)
62
- const contentProps = toRef(() => defu(props.content, { side: 'bottom', sideOffset: 8 }) as TooltipContentProps)
59
+ const contentProps = toRef(() => defu(props.content, { side: 'bottom', sideOffset: 8, collisionPadding: 8 }) as TooltipContentProps)
63
60
  const arrowProps = toRef(() => props.arrow as TooltipArrowProps)
64
61
 
65
62
  // eslint-disable-next-line vue/no-dupe-keys
@@ -70,12 +67,12 @@ const ui = computed(() => tooltip({
70
67
 
71
68
  <template>
72
69
  <TooltipRoot v-slot="{ open }" v-bind="rootProps">
73
- <TooltipTrigger v-if="!!slots.default" as-child>
70
+ <TooltipTrigger v-if="!!slots.default" v-bind="$attrs" as-child :class="props.class">
74
71
  <slot :open="open" />
75
72
  </TooltipTrigger>
76
73
 
77
74
  <TooltipPortal :disabled="!portal">
78
- <TooltipContent v-bind="contentProps" :class="ui.content({ class: [props.class, props.ui?.content] })">
75
+ <TooltipContent v-bind="contentProps" :class="ui.content({ class: [!slots.default && props.class, props.ui?.content] })">
79
76
  <slot name="content">
80
77
  <span v-if="text" :class="ui.text({ class: props.ui?.text })">{{ text }}</span>
81
78
 
@@ -0,0 +1,196 @@
1
+ <script lang="ts">
2
+ import type { VariantProps } from 'tailwind-variants'
3
+ import type { TreeRootProps, TreeRootEmits } from 'reka-ui'
4
+ import type { AppConfig } from '@nuxt/schema'
5
+ import _appConfig from '#build/app.config'
6
+ import theme from '#build/ui/tree'
7
+ import { tv } from '../utils/tv'
8
+ import type { PartialString, DynamicSlots, MaybeMultipleModelValue, SelectItemKey } from '../types/utils'
9
+
10
+ const appConfig = _appConfig as AppConfig & { ui: { tree: Partial<typeof theme> } }
11
+
12
+ const tree = tv({ extend: tv(theme), ...(appConfig.ui?.tree || {}) })
13
+
14
+ type TreeVariants = VariantProps<typeof tree>
15
+
16
+ export type TreeItem = {
17
+ icon?: string
18
+ label?: string
19
+ trailingIcon?: string
20
+ defaultExpanded?: boolean
21
+ disabled?: boolean
22
+ value?: string
23
+ slot?: string
24
+ children?: TreeItem[]
25
+ onToggle?(e: Event): void
26
+ onSelect?(e?: Event): void
27
+ }
28
+
29
+ export interface TreeProps<T extends TreeItem, M extends boolean = false, K extends SelectItemKey<T> | undefined = undefined> extends Pick<TreeRootProps<T>, 'expanded' | 'defaultExpanded' | 'selectionBehavior' | 'propagateSelect' | 'disabled'> {
30
+ /**
31
+ * The element or component this component should render as.
32
+ * @defaultValue 'ul'
33
+ */
34
+ as?: any
35
+ color?: TreeVariants['color']
36
+ size?: TreeVariants['size']
37
+ /**
38
+ * The key used to get the value from the item.
39
+ * @defaultValue 'value'
40
+ */
41
+ valueKey?: K
42
+ /**
43
+ * The key used to get the label from the item.
44
+ * @defaultValue 'label'
45
+ */
46
+ labelKey?: K
47
+ /**
48
+ * The icon displayed on the right side of a parent node.
49
+ * @defaultValue appConfig.ui.icons.chevronDown
50
+ */
51
+ trailingIcon?: string
52
+ /**
53
+ * The icon displayed when a parent node is expanded.
54
+ * @defaultValue appConfig.ui.icons.folderOpen
55
+ */
56
+ expandedIcon?: string
57
+ /**
58
+ * The icon displayed when a parent node is collapsed.
59
+ * @defaultValue appConfig.ui.icons.folder
60
+ */
61
+ collapsedIcon?: string
62
+ items?: T[]
63
+ /** The controlled value of the Tree. Can be bind as `v-model`. */
64
+ modelValue?: MaybeMultipleModelValue<T, M>
65
+ /** The value of the Tree when initially rendered. Use when you do not need to control the state of the Tree. */
66
+ defaultValue?: MaybeMultipleModelValue<T, M>
67
+ /** Whether multiple options can be selected or not. */
68
+ multiple?: M & boolean
69
+ class?: any
70
+ ui?: PartialString<typeof tree.slots>
71
+ }
72
+
73
+ export type TreeEmits<T, M extends boolean = false> = Omit<TreeRootEmits, 'update:modelValue'> & {
74
+ 'update:modelValue': [payload: MaybeMultipleModelValue<T, M>]
75
+ }
76
+
77
+ type SlotProps<T> = (props: { item: T, index: number, level: number, expanded: boolean, selected: boolean }) => any
78
+
79
+ export type TreeSlots<T extends { slot?: string }> = {
80
+ 'item': SlotProps<T>
81
+ 'item-leading': SlotProps<T>
82
+ 'item-label': SlotProps<T>
83
+ 'item-trailing': SlotProps<T>
84
+ } & DynamicSlots<T, SlotProps<T>>
85
+ </script>
86
+
87
+ <script setup lang="ts" generic="T extends TreeItem, M extends boolean = false, K extends SelectItemKey<T> | undefined = undefined">
88
+ import { computed } from 'vue'
89
+ import type { PropType } from 'vue'
90
+ import { TreeRoot, TreeItem, useForwardPropsEmits } from 'reka-ui'
91
+ import { reactivePick, createReusableTemplate } from '@vueuse/core'
92
+ import { get } from '../utils'
93
+ import UIcon from './Icon.vue'
94
+
95
+ const props = withDefaults(defineProps<TreeProps<T, M, K>>(), {
96
+ labelKey: 'label' as never,
97
+ valueKey: 'value' as never
98
+ })
99
+ const emits = defineEmits<TreeEmits<T, M>>()
100
+ const slots = defineSlots<TreeSlots<T>>()
101
+
102
+ const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'modelValue', 'defaultValue', 'items', 'multiple', 'expanded', 'disabled', 'propagateSelect'), emits)
103
+
104
+ const [DefineTreeTemplate, ReuseTreeTemplate] = createReusableTemplate<{ items?: T[], level: number }>({
105
+ props: {
106
+ items: Array as PropType<T[]>,
107
+ level: Number
108
+ }
109
+ })
110
+
111
+ const ui = computed(() => tree({
112
+ color: props.color,
113
+ size: props.size
114
+ }))
115
+
116
+ function getItemLabel(item: T) {
117
+ return get(item, props.labelKey as string)
118
+ }
119
+
120
+ function getItemValue(item?: T) {
121
+ return get(item, props.valueKey as string) ?? get(item, props.labelKey as string)
122
+ }
123
+
124
+ function getDefaultOpenedItems(item: T): string[] {
125
+ const currentItem = item.defaultExpanded ? getItemValue(item) : null
126
+ const childItems = item.children?.flatMap(child => getDefaultOpenedItems(child as T)) ?? []
127
+
128
+ return [currentItem, ...childItems].filter(Boolean) as string[]
129
+ }
130
+
131
+ const defaultExpanded = computed(() => props.defaultExpanded ?? props.items?.flatMap(getDefaultOpenedItems))
132
+ </script>
133
+
134
+ <!-- eslint-disable vue/no-template-shadow -->
135
+ <template>
136
+ <DefineTreeTemplate v-slot="{ items, level }">
137
+ <li
138
+ v-for="(item, index) in items"
139
+ :key="`${level}-${index}`"
140
+ :class="level > 0 ? ui.itemWithChildren({ class: props.ui?.itemWithChildren }) : ui.item({ class: props.ui?.item })"
141
+ >
142
+ <TreeItem
143
+ v-slot="{ isExpanded, isSelected }"
144
+ as-child
145
+ :level="level"
146
+ :value="item"
147
+ @toggle="item.onToggle"
148
+ @select="item.onSelect"
149
+ >
150
+ <button :disabled="item.disabled || disabled" :class="ui.link({ class: props.ui?.link, selected: isSelected, disabled: item.disabled || disabled })">
151
+ <slot :name="item.slot || 'item'" v-bind="{ item, index, level, expanded: isExpanded, selected: isSelected }">
152
+ <slot :name="item.slot ? `${item.slot}-leading`: 'item-leading'" v-bind="{ item, index, level, expanded: isExpanded, selected: isSelected }">
153
+ <UIcon
154
+ v-if="item.icon"
155
+ :name="item.icon"
156
+ :class="ui.linkLeadingIcon({ class: props.ui?.linkLeadingIcon })"
157
+ />
158
+ <UIcon
159
+ v-else-if="item.children?.length"
160
+ :name="isExpanded ? (expandedIcon ?? appConfig.ui.icons.folderOpen) : (collapsedIcon ?? appConfig.ui.icons.folder)"
161
+ :class="ui.linkLeadingIcon({ class: props.ui?.linkLeadingIcon })"
162
+ />
163
+ </slot>
164
+
165
+ <span v-if="getItemLabel(item) || !!slots[item.slot ? `${item.slot}-label`: 'item-label']" :class="ui.linkLabel({ class: props.ui?.linkLabel })">
166
+ <slot :name="item.slot ? `${item.slot}-label`: 'item-label'" v-bind="{ item, index, level, expanded: isExpanded, selected: isSelected }">
167
+ {{ getItemLabel(item) }}
168
+ </slot>
169
+ </span>
170
+
171
+ <span v-if="item.trailingIcon || item.children?.length || !!slots[item.slot ? `${item.slot}-trailing`: 'item-trailing']" :class="ui.linkTrailing({ class: props.ui?.linkTrailing })">
172
+ <slot :name="item.slot ? `${item.slot}-trailing`: 'item-trailing'" v-bind="{ item, index, level, expanded: isExpanded, selected: isSelected }">
173
+ <UIcon v-if="item.trailingIcon" :name="item.trailingIcon" :class="ui.linkTrailingIcon({ class: props.ui?.linkTrailingIcon })" />
174
+ <UIcon v-else-if="item.children?.length" :name="trailingIcon ?? appConfig.ui.icons.chevronDown" :class="ui.linkTrailingIcon({ class: props.ui?.linkTrailingIcon })" />
175
+ </slot>
176
+ </span>
177
+ </slot>
178
+ </button>
179
+
180
+ <ul v-if="item.children?.length && isExpanded" :class="ui.listWithChildren({ class: props.ui?.listWithChildren })">
181
+ <ReuseTreeTemplate :items="(item.children as T[])" :level="level + 1" />
182
+ </ul>
183
+ </TreeItem>
184
+ </li>
185
+ </DefineTreeTemplate>
186
+
187
+ <TreeRoot
188
+ v-bind="rootProps"
189
+ :class="ui.root({ class: [props.class, props.ui?.root] })"
190
+ :get-key="getItemValue"
191
+ :default-expanded="defaultExpanded"
192
+ :selection-behavior="selectionBehavior"
193
+ >
194
+ <ReuseTreeTemplate :items="items" :level="0" />
195
+ </TreeRoot>
196
+ </template>
@@ -0,0 +1,9 @@
1
+ import type { Locale, Direction, Messages } from '../types/locale';
2
+ interface DefineLocaleOptions {
3
+ name: string;
4
+ code: string;
5
+ dir?: Direction;
6
+ messages: Messages;
7
+ }
8
+ export declare function defineLocale(options: DefineLocaleOptions): Locale;
9
+ export {};
@@ -0,0 +1,4 @@
1
+ import { defu } from "defu";
2
+ export function defineLocale(options) {
3
+ return defu(options, { dir: "ltr" });
4
+ }
@@ -11,5 +11,5 @@ export interface ShortcutsOptions {
11
11
  chainDelay?: number;
12
12
  }
13
13
  export declare function extractShortcuts(items: any[] | any[][]): Record<string, Handler>;
14
- export declare function defineShortcuts(config: MaybeRef<ShortcutsConfig>, options?: ShortcutsOptions): void;
14
+ export declare function defineShortcuts(config: MaybeRef<ShortcutsConfig>, options?: ShortcutsOptions): import("@vueuse/core").Fn;
15
15
  export {};
@@ -6,7 +6,7 @@ export function extractShortcuts(items) {
6
6
  const shortcuts = {};
7
7
  function traverse(items2) {
8
8
  items2.forEach((item) => {
9
- if (item.kbds?.length && (item.select || item.click)) {
9
+ if (item.kbds?.length && (item.onSelect || item.onClick)) {
10
10
  const shortcutKey = item.kbds.join("_");
11
11
  shortcuts[shortcutKey] = item.onSelect || item.onClick;
12
12
  }
@@ -131,5 +131,5 @@ export function defineShortcuts(config, options = {}) {
131
131
  return shortcut;
132
132
  }).filter(Boolean);
133
133
  });
134
- useEventListener("keydown", onKeyDown);
134
+ return useEventListener("keydown", onKeyDown);
135
135
  }
@@ -8,19 +8,21 @@ type Props<T> = {
8
8
  name?: string;
9
9
  size?: GetObjectField<T, 'size'>;
10
10
  color?: GetObjectField<T, 'color'>;
11
- eagerValidation?: boolean;
12
- legend?: string;
13
11
  highlight?: boolean;
14
12
  disabled?: boolean;
15
13
  };
16
14
  export declare const formOptionsInjectionKey: InjectionKey<ComputedRef<FormInjectedOptions>>;
17
- export declare const formBusInjectionKey: InjectionKey<UseEventBusReturn<FormEvent, string>>;
15
+ export declare const formBusInjectionKey: InjectionKey<UseEventBusReturn<FormEvent<any>, string>>;
18
16
  export declare const formFieldInjectionKey: InjectionKey<ComputedRef<FormFieldInjectedOptions<FormFieldProps>>>;
19
17
  export declare const inputIdInjectionKey: InjectionKey<Ref<string | undefined>>;
20
- export declare const formInputsInjectionKey: InjectionKey<Ref<Record<string, string>>>;
18
+ export declare const formInputsInjectionKey: InjectionKey<Ref<Record<string, {
19
+ id?: string;
20
+ pattern?: RegExp;
21
+ }>>>;
21
22
  export declare const formLoadingInjectionKey: InjectionKey<Readonly<Ref<boolean>>>;
22
23
  export declare function useFormField<T>(props?: Props<T>, opts?: {
23
24
  bind?: boolean;
25
+ deferInputValidation?: boolean;
24
26
  }): {
25
27
  id: ComputedRef<string | undefined>;
26
28
  name: ComputedRef<string | undefined>;
@@ -31,5 +33,10 @@ export declare function useFormField<T>(props?: Props<T>, opts?: {
31
33
  emitFormBlur: () => void;
32
34
  emitFormInput: import("@vueuse/core").PromisifyFn<() => void>;
33
35
  emitFormChange: () => void;
36
+ emitFormFocus: () => void;
37
+ ariaAttrs: ComputedRef<{
38
+ 'aria-describedby': string;
39
+ 'aria-invalid': boolean;
40
+ } | undefined>;
34
41
  };
35
42
  export {};
@@ -1,4 +1,4 @@
1
- import { inject, ref, computed } from "vue";
1
+ import { inject, computed } from "vue";
2
2
  import { useDebounceFn } from "@vueuse/core";
3
3
  export const formOptionsInjectionKey = Symbol("nuxt-ui.form-options");
4
4
  export const formBusInjectionKey = Symbol("nuxt-ui.form-events");
@@ -13,31 +13,32 @@ export function useFormField(props, opts) {
13
13
  const formInputs = inject(formInputsInjectionKey, void 0);
14
14
  const inputId = inject(inputIdInjectionKey, void 0);
15
15
  if (formField && inputId) {
16
- if (opts?.bind === false || props?.legend) {
16
+ if (opts?.bind === false) {
17
17
  inputId.value = void 0;
18
18
  } else if (props?.id) {
19
19
  inputId.value = props?.id;
20
20
  }
21
21
  if (formInputs && formField.value.name && inputId.value) {
22
- formInputs.value[formField.value.name] = inputId.value;
22
+ formInputs.value[formField.value.name] = { id: inputId.value, pattern: formField.value.errorPattern };
23
23
  }
24
24
  }
25
- const blurred = ref(false);
26
- function emitFormEvent(type, name) {
25
+ function emitFormEvent(type, name, eager) {
27
26
  if (formBus && formField && name) {
28
- formBus.emit({ type, name });
27
+ formBus.emit({ type, name, eager });
29
28
  }
30
29
  }
31
30
  function emitFormBlur() {
32
31
  emitFormEvent("blur", formField?.value.name);
33
- blurred.value = true;
32
+ }
33
+ function emitFormFocus() {
34
+ emitFormEvent("focus", formField?.value.name);
34
35
  }
35
36
  function emitFormChange() {
36
37
  emitFormEvent("change", formField?.value.name);
37
38
  }
38
39
  const emitFormInput = useDebounceFn(
39
40
  () => {
40
- emitFormEvent("input", formField?.value.name);
41
+ emitFormEvent("input", formField?.value.name, !opts?.deferInputValidation || formField?.value.eagerValidation);
41
42
  },
42
43
  formField?.value.validateOnInputDelay ?? formOptions?.value.validateOnInputDelay ?? 0
43
44
  );
@@ -50,6 +51,15 @@ export function useFormField(props, opts) {
50
51
  disabled: computed(() => formOptions?.value.disabled || props?.disabled),
51
52
  emitFormBlur,
52
53
  emitFormInput,
53
- emitFormChange
54
+ emitFormChange,
55
+ emitFormFocus,
56
+ ariaAttrs: computed(() => {
57
+ if (!formField?.value) return;
58
+ const descriptiveAttrs = ["error", "hint", "description"].filter((type) => formField?.value?.[type]).map((type) => `${formField?.value.ariaId}-${type}`) || [];
59
+ return {
60
+ "aria-describedby": descriptiveAttrs.join(" "),
61
+ "aria-invalid": !!formField?.value.error
62
+ };
63
+ })
54
64
  };
55
65
  }