@nuxt/ui 3.1.3 → 3.3.0

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 (208) hide show
  1. package/.nuxt/ui/avatar.ts +1 -1
  2. package/.nuxt/ui/button.ts +42 -42
  3. package/.nuxt/ui/card.ts +1 -1
  4. package/.nuxt/ui/carousel.ts +1 -1
  5. package/.nuxt/ui/command-palette.ts +3 -1
  6. package/.nuxt/ui/drawer.ts +1 -1
  7. package/.nuxt/ui/file-upload.ts +290 -0
  8. package/.nuxt/ui/index.ts +3 -0
  9. package/.nuxt/ui/input-menu.ts +24 -10
  10. package/.nuxt/ui/input-tags.ts +310 -0
  11. package/.nuxt/ui/kbd.ts +167 -3
  12. package/.nuxt/ui/modal.ts +1 -1
  13. package/.nuxt/ui/navigation-menu.ts +1 -1
  14. package/.nuxt/ui/select-menu.ts +11 -6
  15. package/.nuxt/ui/select.ts +11 -6
  16. package/.nuxt/ui/table.ts +11 -2
  17. package/.nuxt/ui/tabs.ts +4 -2
  18. package/.nuxt/ui/timeline.ts +321 -0
  19. package/.nuxt/ui/toast.ts +8 -15
  20. package/.nuxt/ui/toaster.ts +1 -1
  21. package/.nuxt/ui/tooltip.ts +1 -1
  22. package/cli/templates.mjs +11 -7
  23. package/dist/module.d.mts +15 -1
  24. package/dist/module.json +1 -1
  25. package/dist/module.mjs +3 -3
  26. package/dist/runtime/components/Accordion.vue.d.ts +1 -1
  27. package/dist/runtime/components/Alert.vue +0 -1
  28. package/dist/runtime/components/Alert.vue.d.ts +2 -2
  29. package/dist/runtime/components/App.vue.d.ts +1 -1
  30. package/dist/runtime/components/Avatar.vue +10 -2
  31. package/dist/runtime/components/Avatar.vue.d.ts +3 -1
  32. package/dist/runtime/components/AvatarGroup.vue.d.ts +1 -1
  33. package/dist/runtime/components/Badge.vue.d.ts +1 -1
  34. package/dist/runtime/components/Breadcrumb.vue.d.ts +1 -1
  35. package/dist/runtime/components/Button.vue +6 -6
  36. package/dist/runtime/components/Button.vue.d.ts +1 -5
  37. package/dist/runtime/components/ButtonGroup.vue.d.ts +1 -1
  38. package/dist/runtime/components/Calendar.vue +4 -1
  39. package/dist/runtime/components/Calendar.vue.d.ts +1 -1
  40. package/dist/runtime/components/Card.vue.d.ts +1 -1
  41. package/dist/runtime/components/Carousel.vue +19 -16
  42. package/dist/runtime/components/Carousel.vue.d.ts +1 -1
  43. package/dist/runtime/components/Checkbox.vue +1 -1
  44. package/dist/runtime/components/Checkbox.vue.d.ts +1 -1
  45. package/dist/runtime/components/CheckboxGroup.vue.d.ts +1 -1
  46. package/dist/runtime/components/Chip.vue.d.ts +2 -2
  47. package/dist/runtime/components/Collapsible.vue.d.ts +1 -1
  48. package/dist/runtime/components/ColorPicker.vue +1 -2
  49. package/dist/runtime/components/ColorPicker.vue.d.ts +1 -1
  50. package/dist/runtime/components/CommandPalette.vue +84 -16
  51. package/dist/runtime/components/CommandPalette.vue.d.ts +38 -9
  52. package/dist/runtime/components/Container.vue.d.ts +1 -1
  53. package/dist/runtime/components/ContextMenu.vue.d.ts +1 -1
  54. package/dist/runtime/components/ContextMenuContent.vue.d.ts +5 -21
  55. package/dist/runtime/components/Drawer.vue +4 -4
  56. package/dist/runtime/components/Drawer.vue.d.ts +6 -1
  57. package/dist/runtime/components/DropdownMenu.vue.d.ts +1 -1
  58. package/dist/runtime/components/DropdownMenuContent.vue.d.ts +12 -25
  59. package/dist/runtime/components/FileUpload.vue +242 -0
  60. package/dist/runtime/components/FileUpload.vue.d.ts +167 -0
  61. package/dist/runtime/components/Form.vue +6 -6
  62. package/dist/runtime/components/Form.vue.d.ts +15 -13
  63. package/dist/runtime/components/FormField.vue +2 -2
  64. package/dist/runtime/components/FormField.vue.d.ts +4 -4
  65. package/dist/runtime/components/Icon.vue.d.ts +1 -1
  66. package/dist/runtime/components/Input.vue +10 -7
  67. package/dist/runtime/components/Input.vue.d.ts +9 -9
  68. package/dist/runtime/components/InputMenu.vue +17 -10
  69. package/dist/runtime/components/InputMenu.vue.d.ts +19 -16
  70. package/dist/runtime/components/InputNumber.vue +3 -2
  71. package/dist/runtime/components/InputNumber.vue.d.ts +5 -5
  72. package/dist/runtime/components/InputTags.vue +161 -0
  73. package/dist/runtime/components/InputTags.vue.d.ts +185 -0
  74. package/dist/runtime/components/Kbd.vue +2 -1
  75. package/dist/runtime/components/Kbd.vue.d.ts +5 -1
  76. package/dist/runtime/components/Link.vue +6 -5
  77. package/dist/runtime/components/Link.vue.d.ts +1 -3
  78. package/dist/runtime/components/LinkBase.vue.d.ts +1 -1
  79. package/dist/runtime/components/Modal.vue +14 -13
  80. package/dist/runtime/components/Modal.vue.d.ts +16 -6
  81. package/dist/runtime/components/NavigationMenu.vue +19 -17
  82. package/dist/runtime/components/NavigationMenu.vue.d.ts +1 -1
  83. package/dist/runtime/components/OverlayProvider.vue +2 -2
  84. package/dist/runtime/components/OverlayProvider.vue.d.ts +1 -1
  85. package/dist/runtime/components/Pagination.vue +1 -1
  86. package/dist/runtime/components/Pagination.vue.d.ts +1 -2
  87. package/dist/runtime/components/PinInput.vue +4 -3
  88. package/dist/runtime/components/PinInput.vue.d.ts +22 -19
  89. package/dist/runtime/components/Popover.vue +2 -1
  90. package/dist/runtime/components/Popover.vue.d.ts +8 -2
  91. package/dist/runtime/components/Progress.vue +2 -1
  92. package/dist/runtime/components/Progress.vue.d.ts +2 -2
  93. package/dist/runtime/components/RadioGroup.vue +3 -3
  94. package/dist/runtime/components/RadioGroup.vue.d.ts +5 -4
  95. package/dist/runtime/components/Select.vue +23 -4
  96. package/dist/runtime/components/Select.vue.d.ts +108 -2
  97. package/dist/runtime/components/SelectMenu.vue +33 -11
  98. package/dist/runtime/components/SelectMenu.vue.d.ts +106 -2
  99. package/dist/runtime/components/Separator.vue.d.ts +1 -1
  100. package/dist/runtime/components/Skeleton.vue.d.ts +1 -1
  101. package/dist/runtime/components/Slideover.vue +14 -13
  102. package/dist/runtime/components/Slideover.vue.d.ts +16 -6
  103. package/dist/runtime/components/Slider.vue.d.ts +5 -5
  104. package/dist/runtime/components/Stepper.vue.d.ts +1 -1
  105. package/dist/runtime/components/Switch.vue.d.ts +1 -1
  106. package/dist/runtime/components/Table.vue +90 -9
  107. package/dist/runtime/components/Table.vue.d.ts +30 -12
  108. package/dist/runtime/components/Tabs.vue +24 -4
  109. package/dist/runtime/components/Tabs.vue.d.ts +12 -4
  110. package/dist/runtime/components/Textarea.vue +10 -7
  111. package/dist/runtime/components/Textarea.vue.d.ts +14 -12
  112. package/dist/runtime/components/Timeline.vue +92 -0
  113. package/dist/runtime/components/Timeline.vue.d.ts +70 -0
  114. package/dist/runtime/components/Toast.vue +16 -9
  115. package/dist/runtime/components/Toast.vue.d.ts +14 -13
  116. package/dist/runtime/components/Toaster.vue.d.ts +1 -1
  117. package/dist/runtime/components/Tooltip.vue +2 -1
  118. package/dist/runtime/components/Tooltip.vue.d.ts +8 -2
  119. package/dist/runtime/components/Tree.vue +6 -4
  120. package/dist/runtime/components/Tree.vue.d.ts +2 -2
  121. package/dist/runtime/composables/defineLocale.d.ts +2 -0
  122. package/dist/runtime/composables/defineLocale.js +4 -0
  123. package/dist/runtime/composables/defineShortcuts.js +7 -5
  124. package/dist/runtime/composables/useAvatarGroup.d.ts +1 -1
  125. package/dist/runtime/composables/useComponentIcons.d.ts +1 -1
  126. package/dist/runtime/composables/useFileUpload.d.ts +19 -0
  127. package/dist/runtime/composables/useFileUpload.js +63 -0
  128. package/dist/runtime/composables/useFormField.d.ts +3 -6
  129. package/dist/runtime/composables/useFormField.js +5 -2
  130. package/dist/runtime/composables/useKbd.d.ts +1 -1
  131. package/dist/runtime/composables/useLocale.js +2 -2
  132. package/dist/runtime/composables/useOverlay.d.ts +30 -2
  133. package/dist/runtime/composables/useOverlay.js +8 -7
  134. package/dist/runtime/composables/usePortal.d.ts +1 -1
  135. package/dist/runtime/inertia/components/Link.vue.d.ts +1 -1
  136. package/dist/runtime/inertia/components/LinkBase.vue.d.ts +1 -1
  137. package/dist/runtime/inertia/stubs.d.ts +1 -0
  138. package/dist/runtime/inertia/stubs.js +4 -2
  139. package/dist/runtime/locale/ar.js +4 -2
  140. package/dist/runtime/locale/az.js +3 -1
  141. package/dist/runtime/locale/bg.js +3 -1
  142. package/dist/runtime/locale/bn.js +3 -1
  143. package/dist/runtime/locale/ca.js +3 -1
  144. package/dist/runtime/locale/ckb.js +4 -2
  145. package/dist/runtime/locale/cs.js +3 -1
  146. package/dist/runtime/locale/da.js +3 -1
  147. package/dist/runtime/locale/de.js +3 -1
  148. package/dist/runtime/locale/el.js +3 -1
  149. package/dist/runtime/locale/en.js +3 -1
  150. package/dist/runtime/locale/es.js +3 -1
  151. package/dist/runtime/locale/et.js +3 -1
  152. package/dist/runtime/locale/fa_ir.js +3 -1
  153. package/dist/runtime/locale/fi.js +3 -1
  154. package/dist/runtime/locale/fr.js +3 -1
  155. package/dist/runtime/locale/he.js +3 -1
  156. package/dist/runtime/locale/hi.js +4 -2
  157. package/dist/runtime/locale/hu.js +3 -1
  158. package/dist/runtime/locale/hy.js +3 -1
  159. package/dist/runtime/locale/id.js +3 -1
  160. package/dist/runtime/locale/index.d.ts +1 -0
  161. package/dist/runtime/locale/index.js +1 -0
  162. package/dist/runtime/locale/it.js +3 -1
  163. package/dist/runtime/locale/ja.js +3 -1
  164. package/dist/runtime/locale/kk.js +3 -1
  165. package/dist/runtime/locale/km.js +4 -2
  166. package/dist/runtime/locale/ko.js +3 -1
  167. package/dist/runtime/locale/ky.js +3 -1
  168. package/dist/runtime/locale/lb.d.ts +3 -0
  169. package/dist/runtime/locale/lb.js +56 -0
  170. package/dist/runtime/locale/lt.js +3 -1
  171. package/dist/runtime/locale/mn.js +3 -1
  172. package/dist/runtime/locale/ms.js +3 -1
  173. package/dist/runtime/locale/nb_no.js +3 -1
  174. package/dist/runtime/locale/nl.js +3 -1
  175. package/dist/runtime/locale/pl.js +3 -1
  176. package/dist/runtime/locale/pt.js +3 -1
  177. package/dist/runtime/locale/pt_br.js +3 -1
  178. package/dist/runtime/locale/ro.js +3 -1
  179. package/dist/runtime/locale/ru.js +3 -1
  180. package/dist/runtime/locale/sk.js +3 -1
  181. package/dist/runtime/locale/sl.js +3 -1
  182. package/dist/runtime/locale/sv.js +3 -1
  183. package/dist/runtime/locale/th.js +3 -1
  184. package/dist/runtime/locale/tj.js +3 -1
  185. package/dist/runtime/locale/tr.js +3 -1
  186. package/dist/runtime/locale/ug_cn.js +3 -1
  187. package/dist/runtime/locale/uk.js +3 -1
  188. package/dist/runtime/locale/ur.js +3 -1
  189. package/dist/runtime/locale/uz.js +3 -1
  190. package/dist/runtime/locale/vi.js +3 -1
  191. package/dist/runtime/locale/zh_cn.js +3 -1
  192. package/dist/runtime/locale/zh_tw.js +3 -1
  193. package/dist/runtime/types/form.d.ts +11 -10
  194. package/dist/runtime/types/index.d.ts +3 -0
  195. package/dist/runtime/types/index.js +3 -0
  196. package/dist/runtime/types/locale.d.ts +2 -0
  197. package/dist/runtime/types/utils.d.ts +3 -0
  198. package/dist/runtime/utils/index.d.ts +1 -0
  199. package/dist/runtime/utils/index.js +9 -0
  200. package/dist/runtime/vue/components/Icon.vue.d.ts +1 -1
  201. package/dist/runtime/vue/components/Link.vue.d.ts +1 -1
  202. package/dist/runtime/vue/stubs.d.ts +1 -0
  203. package/dist/runtime/vue/stubs.js +3 -1
  204. package/dist/shared/{ui.Bix4DSU4.mjs → ui.BkSj2DmF.mjs} +560 -55
  205. package/dist/unplugin.d.mts +2 -0
  206. package/dist/unplugin.mjs +6 -3
  207. package/dist/vite.mjs +1 -1
  208. package/package.json +37 -38
@@ -53,7 +53,7 @@ export interface AlertProps {
53
53
  ui?: Alert['slots'];
54
54
  }
55
55
  export interface AlertEmits {
56
- (e: 'update:open', value: boolean): void;
56
+ 'update:open': [value: boolean];
57
57
  }
58
58
  export interface AlertSlots {
59
59
  leading(props?: {}): any;
@@ -66,7 +66,7 @@ export interface AlertSlots {
66
66
  };
67
67
  }): any;
68
68
  }
69
- declare const _default: __VLS_WithSlots<import("vue").DefineComponent<AlertProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
69
+ declare const _default: __VLS_WithSlots<import("vue").DefineComponent<AlertProps, void, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
70
70
  "update:open": (value: boolean) => any;
71
71
  }, string, import("vue").PublicProps, Readonly<AlertProps> & Readonly<{
72
72
  "onUpdate:open"?: ((value: boolean) => any) | undefined;
@@ -20,5 +20,5 @@ declare const _default: <T extends Messages>(__VLS_props: NonNullable<Awaited<ty
20
20
  };
21
21
  export default _default;
22
22
  type __VLS_PrettifyLocal<T> = {
23
- [K in keyof T]: T[K];
23
+ [K in keyof T as K]: T[K];
24
24
  } & {};
@@ -10,6 +10,7 @@ import ImageComponent from "#build/ui-image-component";
10
10
  import { useAvatarGroup } from "../composables/useAvatarGroup";
11
11
  import { tv } from "../utils/tv";
12
12
  import UIcon from "./Icon.vue";
13
+ import UChip from "./Chip.vue";
13
14
  defineOptions({ inheritAttrs: false });
14
15
  const props = defineProps({
15
16
  as: { type: null, required: false, default: "span" },
@@ -18,6 +19,7 @@ const props = defineProps({
18
19
  icon: { type: String, required: false },
19
20
  text: { type: String, required: false },
20
21
  size: { type: null, required: false },
22
+ chip: { type: [Boolean, Object], required: false },
21
23
  class: { type: null, required: false },
22
24
  style: { type: null, required: false },
23
25
  ui: { type: null, required: false }
@@ -51,7 +53,13 @@ function onError() {
51
53
  </script>
52
54
 
53
55
  <template>
54
- <Primitive :as="as" :class="ui.root({ class: [props.ui?.root, props.class] })" :style="props.style">
56
+ <component
57
+ :is="props.chip ? UChip : Primitive"
58
+ :as="as"
59
+ v-bind="props.chip ? typeof props.chip === 'object' ? { inset: true, ...props.chip } : { inset: true } : {}"
60
+ :class="ui.root({ class: [props.ui?.root, props.class] })"
61
+ :style="props.style"
62
+ >
55
63
  <component
56
64
  :is="ImageComponent"
57
65
  v-if="src && !error"
@@ -71,5 +79,5 @@ function onError() {
71
79
  <span v-else :class="ui.fallback({ class: props.ui?.fallback })">{{ fallback || "\xA0" }}</span>
72
80
  </slot>
73
81
  </Slot>
74
- </Primitive>
82
+ </component>
75
83
  </template>
@@ -1,5 +1,6 @@
1
1
  import type { AppConfig } from '@nuxt/schema';
2
2
  import theme from '#build/ui/avatar';
3
+ import type { ChipProps } from '../types';
3
4
  import type { ComponentConfig } from '../types/utils';
4
5
  type Avatar = ComponentConfig<typeof theme, AppConfig, 'avatar'>;
5
6
  export interface AvatarProps {
@@ -19,6 +20,7 @@ export interface AvatarProps {
19
20
  * @defaultValue 'md'
20
21
  */
21
22
  size?: Avatar['variants']['size'];
23
+ chip?: boolean | ChipProps;
22
24
  class?: any;
23
25
  style?: any;
24
26
  ui?: Avatar['slots'];
@@ -26,7 +28,7 @@ export interface AvatarProps {
26
28
  export interface AvatarSlots {
27
29
  default(props?: {}): any;
28
30
  }
29
- declare const _default: __VLS_WithSlots<import("vue").DefineComponent<AvatarProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<AvatarProps> & Readonly<{}>, {
31
+ declare const _default: __VLS_WithSlots<import("vue").DefineComponent<AvatarProps, void, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<AvatarProps> & Readonly<{}>, {
30
32
  as: any;
31
33
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
32
34
  default?: (props: {}) => any;
@@ -22,7 +22,7 @@ export interface AvatarGroupProps {
22
22
  export interface AvatarGroupSlots {
23
23
  default(props?: {}): any;
24
24
  }
25
- declare const _default: __VLS_WithSlots<import("vue").DefineComponent<AvatarGroupProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<AvatarGroupProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, AvatarGroupSlots>;
25
+ declare const _default: __VLS_WithSlots<import("vue").DefineComponent<AvatarGroupProps, void, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<AvatarGroupProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, AvatarGroupSlots>;
26
26
  export default _default;
27
27
  type __VLS_WithSlots<T, S> = T & {
28
28
  new (): {
@@ -32,7 +32,7 @@ export interface BadgeSlots {
32
32
  default(props?: {}): any;
33
33
  trailing(props?: {}): any;
34
34
  }
35
- declare const _default: __VLS_WithSlots<import("vue").DefineComponent<BadgeProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<BadgeProps> & Readonly<{}>, {
35
+ declare const _default: __VLS_WithSlots<import("vue").DefineComponent<BadgeProps, void, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<BadgeProps> & Readonly<{}>, {
36
36
  as: any;
37
37
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, BadgeSlots>;
38
38
  export default _default;
@@ -62,5 +62,5 @@ declare const _default: <T extends BreadcrumbItem>(__VLS_props: NonNullable<Awai
62
62
  };
63
63
  export default _default;
64
64
  type __VLS_PrettifyLocal<T> = {
65
- [K in keyof T]: T[K];
65
+ [K in keyof T as K]: T[K];
66
66
  } & {};
@@ -10,7 +10,7 @@ import { useAppConfig } from "#imports";
10
10
  import { useComponentIcons } from "../composables/useComponentIcons";
11
11
  import { useButtonGroup } from "../composables/useButtonGroup";
12
12
  import { formLoadingInjectionKey } from "../composables/useFormField";
13
- import { omit } from "../utils";
13
+ import { omit, mergeClasses } from "../utils";
14
14
  import { tv } from "../utils/tv";
15
15
  import { pickLinkProps } from "../utils/link";
16
16
  import UIcon from "./Icon.vue";
@@ -41,11 +41,11 @@ const props = defineProps({
41
41
  as: { type: null, required: false },
42
42
  type: { type: null, required: false },
43
43
  disabled: { type: Boolean, required: false },
44
- active: { type: Boolean, required: false, default: void 0 },
44
+ active: { type: Boolean, required: false },
45
45
  exact: { type: Boolean, required: false },
46
46
  exactQuery: { type: [Boolean, String], required: false },
47
47
  exactHash: { type: Boolean, required: false },
48
- inactiveClass: { type: String, required: false, default: "" },
48
+ inactiveClass: { type: String, required: false },
49
49
  to: { type: null, required: false },
50
50
  href: { type: null, required: false },
51
51
  external: { type: Boolean, required: false },
@@ -56,7 +56,7 @@ const props = defineProps({
56
56
  prefetch: { type: Boolean, required: false },
57
57
  prefetchOn: { type: [String, Object], required: false },
58
58
  noPrefetch: { type: Boolean, required: false },
59
- activeClass: { type: String, required: false, default: "" },
59
+ activeClass: { type: String, required: false },
60
60
  exactActiveClass: { type: String, required: false },
61
61
  ariaCurrentValue: { type: String, required: false },
62
62
  viewTransition: { type: Boolean, required: false },
@@ -89,10 +89,10 @@ const ui = computed(() => tv({
89
89
  variants: {
90
90
  active: {
91
91
  true: {
92
- base: props.activeClass
92
+ base: mergeClasses(appConfig.ui?.button?.variants?.active?.true?.base, props.activeClass)
93
93
  },
94
94
  false: {
95
- base: props.inactiveClass
95
+ base: mergeClasses(appConfig.ui?.button?.variants?.active?.false?.base, props.inactiveClass)
96
96
  }
97
97
  }
98
98
  }
@@ -35,11 +35,7 @@ export interface ButtonSlots {
35
35
  default(props?: {}): any;
36
36
  trailing(props?: {}): any;
37
37
  }
38
- declare const _default: __VLS_WithSlots<import("vue").DefineComponent<ButtonProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ButtonProps> & Readonly<{}>, {
39
- activeClass: string;
40
- active: boolean;
41
- inactiveClass: string;
42
- }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, ButtonSlots>;
38
+ declare const _default: __VLS_WithSlots<import("vue").DefineComponent<ButtonProps, void, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ButtonProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, ButtonSlots>;
43
39
  export default _default;
44
40
  type __VLS_WithSlots<T, S> = T & {
45
41
  new (): {
@@ -23,7 +23,7 @@ export interface ButtonGroupProps {
23
23
  export interface ButtonGroupSlots {
24
24
  default(props?: {}): any;
25
25
  }
26
- declare const _default: __VLS_WithSlots<import("vue").DefineComponent<ButtonGroupProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ButtonGroupProps> & Readonly<{}>, {
26
+ declare const _default: __VLS_WithSlots<import("vue").DefineComponent<ButtonGroupProps, void, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ButtonGroupProps> & Readonly<{}>, {
27
27
  orientation: ButtonGroup["variants"]["orientation"];
28
28
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, ButtonGroupSlots>;
29
29
  export default _default;
@@ -36,6 +36,7 @@ const props = defineProps({
36
36
  allowNonContiguousRanges: { type: Boolean, required: false },
37
37
  pagedNavigation: { type: Boolean, required: false },
38
38
  preventDeselect: { type: Boolean, required: false },
39
+ maximumDays: { type: Number, required: false },
39
40
  weekStartsOn: { type: Number, required: false },
40
41
  weekdayFormat: { type: String, required: false },
41
42
  fixedWeeks: { type: Boolean, required: false, default: true },
@@ -49,7 +50,9 @@ const props = defineProps({
49
50
  isDateUnavailable: { type: Function, required: false },
50
51
  isDateHighlightable: { type: Function, required: false },
51
52
  nextPage: { type: Function, required: false },
52
- prevPage: { type: Function, required: false }
53
+ prevPage: { type: Function, required: false },
54
+ disableDaysOutsideCurrentView: { type: Boolean, required: false },
55
+ fixedDate: { type: String, required: false }
53
56
  });
54
57
  const emits = defineEmits(["update:modelValue", "update:placeholder", "update:startValue"]);
55
58
  defineSlots();
@@ -107,5 +107,5 @@ declare const _default: <R extends boolean, M extends boolean>(__VLS_props: NonN
107
107
  };
108
108
  export default _default;
109
109
  type __VLS_PrettifyLocal<T> = {
110
- [K in keyof T]: T[K];
110
+ [K in keyof T as K]: T[K];
111
111
  } & {};
@@ -20,7 +20,7 @@ export interface CardSlots {
20
20
  default(props?: {}): any;
21
21
  footer(props?: {}): any;
22
22
  }
23
- declare const _default: __VLS_WithSlots<import("vue").DefineComponent<CardProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<CardProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, CardSlots>;
23
+ declare const _default: __VLS_WithSlots<import("vue").DefineComponent<CardProps, void, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<CardProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, CardSlots>;
24
24
  export default _default;
25
25
  type __VLS_WithSlots<T, S> = T & {
26
26
  new (): {
@@ -6,7 +6,7 @@ import theme from "#build/ui/carousel";
6
6
  import { computed, ref, watch, onMounted } from "vue";
7
7
  import useEmblaCarousel from "embla-carousel-vue";
8
8
  import { Primitive, useForwardProps } from "reka-ui";
9
- import { reactivePick, computedAsync } from "@vueuse/core";
9
+ import { reactivePick } from "@vueuse/core";
10
10
  import { useAppConfig } from "#imports";
11
11
  import { useLocale } from "../composables/useLocale";
12
12
  import { tv } from "../utils/tv";
@@ -62,34 +62,36 @@ const options = computed(() => ({
62
62
  axis: props.orientation === "horizontal" ? "x" : "y",
63
63
  direction: dir.value === "rtl" ? "rtl" : "ltr"
64
64
  }));
65
- const plugins = computedAsync(async () => {
66
- const plugins2 = [];
65
+ const plugins = ref([]);
66
+ async function loadPlugins() {
67
+ const emblaPlugins = [];
67
68
  if (props.autoplay) {
68
69
  const AutoplayPlugin = await import("embla-carousel-autoplay").then((r) => r.default);
69
- plugins2.push(AutoplayPlugin(typeof props.autoplay === "boolean" ? {} : props.autoplay));
70
+ emblaPlugins.push(AutoplayPlugin(typeof props.autoplay === "boolean" ? {} : props.autoplay));
70
71
  }
71
72
  if (props.autoScroll) {
72
73
  const AutoScrollPlugin = await import("embla-carousel-auto-scroll").then((r) => r.default);
73
- plugins2.push(AutoScrollPlugin(typeof props.autoScroll === "boolean" ? {} : props.autoScroll));
74
+ emblaPlugins.push(AutoScrollPlugin(typeof props.autoScroll === "boolean" ? {} : props.autoScroll));
74
75
  }
75
76
  if (props.autoHeight) {
76
77
  const AutoHeightPlugin = await import("embla-carousel-auto-height").then((r) => r.default);
77
- plugins2.push(AutoHeightPlugin(typeof props.autoHeight === "boolean" ? {} : props.autoHeight));
78
+ emblaPlugins.push(AutoHeightPlugin(typeof props.autoHeight === "boolean" ? {} : props.autoHeight));
78
79
  }
79
80
  if (props.classNames) {
80
81
  const ClassNamesPlugin = await import("embla-carousel-class-names").then((r) => r.default);
81
- plugins2.push(ClassNamesPlugin(typeof props.classNames === "boolean" ? {} : props.classNames));
82
+ emblaPlugins.push(ClassNamesPlugin(typeof props.classNames === "boolean" ? {} : props.classNames));
82
83
  }
83
84
  if (props.fade) {
84
85
  const FadePlugin = await import("embla-carousel-fade").then((r) => r.default);
85
- plugins2.push(FadePlugin(typeof props.fade === "boolean" ? {} : props.fade));
86
+ emblaPlugins.push(FadePlugin(typeof props.fade === "boolean" ? {} : props.fade));
86
87
  }
87
88
  if (props.wheelGestures) {
88
89
  const { WheelGesturesPlugin } = await import("embla-carousel-wheel-gestures");
89
- plugins2.push(WheelGesturesPlugin(typeof props.wheelGestures === "boolean" ? {} : props.wheelGestures));
90
+ emblaPlugins.push(WheelGesturesPlugin(typeof props.wheelGestures === "boolean" ? {} : props.wheelGestures));
90
91
  }
91
- return plugins2;
92
- });
92
+ plugins.value = emblaPlugins;
93
+ }
94
+ watch(() => [props.autoplay, props.autoScroll, props.autoHeight, props.classNames, props.fade, props.wheelGestures], loadPlugins, { immediate: true });
93
95
  const [emblaRef, emblaApi] = useEmblaCarousel(options.value, plugins.value);
94
96
  watch([options, plugins], () => {
95
97
  emblaApi.value?.reInit(options.value, plugins.value);
@@ -162,8 +164,7 @@ defineExpose({
162
164
  <div
163
165
  v-for="(item, index) in items"
164
166
  :key="index"
165
- role="group"
166
- aria-roledescription="slide"
167
+ v-bind="dots ? { role: 'tabpanel' } : { 'role': 'group', 'aria-roledescription': 'slide' }"
167
168
  :class="ui.item({ class: [props.ui?.item, isCarouselItem(item) && item.ui?.item, isCarouselItem(item) && item.class] })"
168
169
  >
169
170
  <slot :item="item" :index="index" />
@@ -176,7 +177,6 @@ defineExpose({
176
177
  <UButton
177
178
  :disabled="!canScrollPrev"
178
179
  :icon="prevIcon"
179
- size="md"
180
180
  color="neutral"
181
181
  variant="outline"
182
182
  :aria-label="t('carousel.prev')"
@@ -187,7 +187,6 @@ defineExpose({
187
187
  <UButton
188
188
  :disabled="!canScrollNext"
189
189
  :icon="nextIcon"
190
- size="md"
191
190
  color="neutral"
192
191
  variant="outline"
193
192
  :aria-label="t('carousel.next')"
@@ -197,11 +196,15 @@ defineExpose({
197
196
  />
198
197
  </div>
199
198
 
200
- <div v-if="dots" :class="ui.dots({ class: props.ui?.dots })">
199
+ <div v-if="dots" role="tablist" :aria-label="t('carousel.dots')" :class="ui.dots({ class: props.ui?.dots })">
201
200
  <template v-for="(_, index) in scrollSnaps" :key="index">
202
201
  <button
202
+ type="button"
203
+ role="tab"
203
204
  :aria-label="t('carousel.goto', { slide: index + 1 })"
205
+ :aria-selected="selectedIndex === index"
204
206
  :class="ui.dot({ class: props.ui?.dot, active: selectedIndex === index })"
207
+ :data-state="selectedIndex === index ? 'active' : void 0"
205
208
  @click="scrollTo(index)"
206
209
  />
207
210
  </template>
@@ -123,5 +123,5 @@ declare const _default: <T extends CarouselItem>(__VLS_props: NonNullable<Awaite
123
123
  };
124
124
  export default _default;
125
125
  type __VLS_PrettifyLocal<T> = {
126
- [K in keyof T]: T[K];
126
+ [K in keyof T as K]: T[K];
127
127
  } & {};
@@ -26,7 +26,7 @@ const props = defineProps({
26
26
  disabled: { type: Boolean, required: false },
27
27
  required: { type: Boolean, required: false },
28
28
  name: { type: String, required: false },
29
- value: { type: [String, Number, Object, null], required: false },
29
+ value: { type: null, required: false },
30
30
  id: { type: String, required: false },
31
31
  defaultValue: { type: [Boolean, String], required: false }
32
32
  });
@@ -56,7 +56,7 @@ export interface CheckboxSlots {
56
56
  }
57
57
  declare const _default: __VLS_WithSlots<import("vue").DefineComponent<CheckboxProps & {
58
58
  modelValue?: boolean | "indeterminate";
59
- }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
59
+ }, void, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
60
60
  change: (payload: Event) => any;
61
61
  "update:modelValue": (value: boolean | "indeterminate") => any;
62
62
  }, string, import("vue").PublicProps, Readonly<CheckboxProps & {
@@ -80,5 +80,5 @@ declare const _default: <T extends CheckboxGroupItem>(__VLS_props: NonNullable<A
80
80
  };
81
81
  export default _default;
82
82
  type __VLS_PrettifyLocal<T> = {
83
- [K in keyof T]: T[K];
83
+ [K in keyof T as K]: T[K];
84
84
  } & {};
@@ -31,7 +31,7 @@ export interface ChipProps {
31
31
  ui?: Chip['slots'];
32
32
  }
33
33
  export interface ChipEmits {
34
- (e: 'update:show', payload: boolean): void;
34
+ 'update:show': [payload: boolean];
35
35
  }
36
36
  export interface ChipSlots {
37
37
  default(props?: {}): any;
@@ -39,7 +39,7 @@ export interface ChipSlots {
39
39
  }
40
40
  declare const _default: __VLS_WithSlots<import("vue").DefineComponent<ChipProps & {
41
41
  show?: boolean;
42
- }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
42
+ }, void, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
43
43
  "update:show": (value: boolean) => any;
44
44
  }, string, import("vue").PublicProps, Readonly<ChipProps & {
45
45
  show?: boolean;
@@ -20,7 +20,7 @@ export interface CollapsibleSlots {
20
20
  }): any;
21
21
  content(props?: {}): any;
22
22
  }
23
- declare const _default: __VLS_WithSlots<import("vue").DefineComponent<CollapsibleProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
23
+ declare const _default: __VLS_WithSlots<import("vue").DefineComponent<CollapsibleProps, void, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
24
24
  "update:open": (value: boolean) => any;
25
25
  }, string, import("vue").PublicProps, Readonly<CollapsibleProps> & Readonly<{
26
26
  "onUpdate:open"?: ((value: boolean) => any) | undefined;
@@ -14,7 +14,7 @@ function HSVtoHSL(hsv) {
14
14
  return {
15
15
  H: hsv.h,
16
16
  S: x === 0 || x === 200 ? 0 : Math.round(hsv.s * hsv.v / (x <= 100 ? x : 200 - x)),
17
- L: Math.round(x / 2)
17
+ L: x / 2
18
18
  };
19
19
  }
20
20
  </script>
@@ -53,7 +53,6 @@ const pickedColor = computed({
53
53
  },
54
54
  set(value) {
55
55
  const color = new ColorTranslator(HSVtoHSL(value), {
56
- decimals: 2,
57
56
  labUnit: "percent",
58
57
  cmykUnit: "percent",
59
58
  cmykFunction: "cmyk"
@@ -34,7 +34,7 @@ export type ColorPickerProps = {
34
34
  };
35
35
  declare const _default: import("vue").DefineComponent<ColorPickerProps & {
36
36
  modelValue?: string;
37
- }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
37
+ }, void, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
38
38
  "update:modelValue": (value: string | undefined) => any;
39
39
  }, string, import("vue").PublicProps, Readonly<ColorPickerProps & {
40
40
  modelValue?: string;
@@ -3,7 +3,7 @@ import theme from "#build/ui/command-palette";
3
3
  </script>
4
4
 
5
5
  <script setup>
6
- import { computed } from "vue";
6
+ import { computed, ref, useTemplateRef } from "vue";
7
7
  import { ListboxRoot, ListboxFilter, ListboxContent, ListboxGroup, ListboxGroupLabel, ListboxItem, ListboxItemIndicator, useForwardProps, useForwardPropsEmits } from "reka-ui";
8
8
  import { defu } from "defu";
9
9
  import { reactivePick } from "@vueuse/core";
@@ -26,10 +26,13 @@ const props = defineProps({
26
26
  as: { type: null, required: false },
27
27
  icon: { type: String, required: false },
28
28
  selectedIcon: { type: String, required: false },
29
+ trailingIcon: { type: String, required: false },
29
30
  placeholder: { type: String, required: false },
30
31
  autofocus: { type: Boolean, required: false, default: true },
31
32
  close: { type: [Boolean, Object], required: false },
32
33
  closeIcon: { type: String, required: false },
34
+ back: { type: [Boolean, Object], required: false, default: true },
35
+ backIcon: { type: String, required: false },
33
36
  groups: { type: Array, required: false },
34
37
  fuse: { type: Object, required: false },
35
38
  labelKey: { type: String, required: false, default: "label" },
@@ -40,6 +43,7 @@ const props = defineProps({
40
43
  modelValue: { type: null, required: false, default: "" },
41
44
  defaultValue: { type: null, required: false },
42
45
  highlightOnHover: { type: Boolean, required: false },
46
+ selectionBehavior: { type: String, required: false },
43
47
  loading: { type: Boolean, required: false },
44
48
  loadingIcon: { type: String, required: false }
45
49
  });
@@ -48,7 +52,7 @@ const slots = defineSlots();
48
52
  const searchTerm = defineModel("searchTerm", { type: String, ...{ default: "" } });
49
53
  const { t } = useLocale();
50
54
  const appConfig = useAppConfig();
51
- const rootProps = useForwardPropsEmits(reactivePick(props, "as", "disabled", "multiple", "modelValue", "defaultValue", "highlightOnHover"), emits);
55
+ const rootProps = useForwardPropsEmits(reactivePick(props, "as", "disabled", "multiple", "modelValue", "defaultValue", "highlightOnHover", "selectionBehavior"), emits);
52
56
  const inputProps = useForwardProps(reactivePick(props, "loading", "loadingIcon"));
53
57
  const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.commandPalette || {} })());
54
58
  const fuse = computed(() => defu({}, props.fuse, {
@@ -60,7 +64,10 @@ const fuse = computed(() => defu({}, props.fuse, {
60
64
  resultLimit: 12,
61
65
  matchAllWhenSearchEmpty: true
62
66
  }));
63
- const items = computed(() => props.groups?.filter((group) => {
67
+ const history = ref([]);
68
+ const placeholder = computed(() => history.value[history.value.length - 1]?.placeholder || props.placeholder || t("commandPalette.placeholder"));
69
+ const groups = computed(() => history.value?.length ? [history.value[history.value.length - 1]] : props.groups);
70
+ const items = computed(() => groups.value?.filter((group) => {
64
71
  if (!group.id) {
65
72
  console.warn(`[@nuxt/ui] CommandPalette group is missing an \`id\` property`);
66
73
  return false;
@@ -69,7 +76,7 @@ const items = computed(() => props.groups?.filter((group) => {
69
76
  return false;
70
77
  }
71
78
  return true;
72
- }).flatMap((group) => group.items?.map((item) => ({ ...item, group: group.id })) || []) || []);
79
+ })?.flatMap((group) => group.items?.map((item) => ({ ...item, group: group.id })) || []) || []);
73
80
  const { results: fuseResults } = useFuse(searchTerm, items, fuse);
74
81
  function getGroupWithItems(group, items2) {
75
82
  if (group?.postFilter && typeof group.postFilter === "function") {
@@ -86,7 +93,7 @@ function getGroupWithItems(group, items2) {
86
93
  })
87
94
  };
88
95
  }
89
- const groups = computed(() => {
96
+ const filteredGroups = computed(() => {
90
97
  const groupsById = fuseResults.value.reduce((acc, result) => {
91
98
  const { item, matches } = result;
92
99
  if (!item.group) {
@@ -97,37 +104,87 @@ const groups = computed(() => {
97
104
  return acc;
98
105
  }, {});
99
106
  const fuseGroups = Object.entries(groupsById).map(([id, items2]) => {
100
- const group = props.groups?.find((group2) => group2.id === id);
107
+ const group = groups.value?.find((group2) => group2.id === id);
101
108
  if (!group) {
102
109
  return;
103
110
  }
104
111
  return getGroupWithItems(group, items2);
105
112
  }).filter((group) => !!group);
106
- const nonFuseGroups = props.groups?.map((group, index) => ({ ...group, index }))?.filter((group) => group.ignoreFilter && group.items?.length)?.map((group) => ({ ...getGroupWithItems(group, group.items || []), index: group.index })) || [];
113
+ const nonFuseGroups = groups.value?.map((group, index) => ({ ...group, index }))?.filter((group) => group.ignoreFilter && group.items?.length)?.map((group) => ({ ...getGroupWithItems(group, group.items || []), index: group.index })) || [];
107
114
  return nonFuseGroups.reduce((acc, group) => {
108
115
  acc.splice(group.index, 0, group);
109
116
  return acc;
110
117
  }, [...fuseGroups]);
111
118
  });
119
+ const listboxRootRef = useTemplateRef("listboxRootRef");
120
+ function navigate(item) {
121
+ if (!item.children?.length) {
122
+ return;
123
+ }
124
+ history.value.push({
125
+ id: `history-${history.value.length}`,
126
+ label: item.label,
127
+ slot: item.slot,
128
+ placeholder: item.placeholder,
129
+ items: item.children
130
+ });
131
+ searchTerm.value = "";
132
+ listboxRootRef.value?.highlightFirstItem();
133
+ }
134
+ function navigateBack() {
135
+ if (!history.value.length) {
136
+ return;
137
+ }
138
+ history.value.pop();
139
+ searchTerm.value = "";
140
+ listboxRootRef.value?.highlightFirstItem();
141
+ }
142
+ function onBackspace() {
143
+ if (!searchTerm.value) {
144
+ navigateBack();
145
+ }
146
+ }
147
+ function onSelect(e, item) {
148
+ if (item.children?.length) {
149
+ e.preventDefault();
150
+ navigate(item);
151
+ } else {
152
+ item.onSelect?.(e);
153
+ }
154
+ }
112
155
  </script>
113
156
 
114
157
  <template>
115
- <ListboxRoot v-bind="rootProps" :class="ui.root({ class: [props.ui?.root, props.class] })">
158
+ <ListboxRoot v-bind="rootProps" ref="listboxRootRef" :class="ui.root({ class: [props.ui?.root, props.class] })">
116
159
  <ListboxFilter v-model="searchTerm" as-child>
117
160
  <UInput
118
- :placeholder="placeholder || t('commandPalette.placeholder')"
161
+ :placeholder="placeholder"
119
162
  variant="none"
120
163
  :autofocus="autofocus"
121
164
  v-bind="inputProps"
122
165
  :icon="icon || appConfig.ui.icons.search"
123
166
  :class="ui.input({ class: props.ui?.input })"
167
+ @keydown.backspace="onBackspace"
124
168
  >
169
+ <template v-if="history?.length && (back || !!slots.back)" #leading>
170
+ <slot name="back" :ui="ui">
171
+ <UButton
172
+ :icon="backIcon || appConfig.ui.icons.arrowLeft"
173
+ color="neutral"
174
+ variant="link"
175
+ :aria-label="t('commandPalette.back')"
176
+ v-bind="typeof back === 'object' ? back : {}"
177
+ :class="ui.back({ class: props.ui?.back })"
178
+ @click="navigateBack"
179
+ />
180
+ </slot>
181
+ </template>
182
+
125
183
  <template v-if="close || !!slots.close" #trailing>
126
184
  <slot name="close" :ui="ui">
127
185
  <UButton
128
186
  v-if="close"
129
187
  :icon="closeIcon || appConfig.ui.icons.close"
130
- size="md"
131
188
  color="neutral"
132
189
  variant="ghost"
133
190
  :aria-label="t('commandPalette.close')"
@@ -141,8 +198,8 @@ const groups = computed(() => {
141
198
  </ListboxFilter>
142
199
 
143
200
  <ListboxContent :class="ui.content({ class: props.ui?.content })">
144
- <div v-if="groups?.length" role="presentation" :class="ui.viewport({ class: props.ui?.viewport })">
145
- <ListboxGroup v-for="group in groups" :key="`group-${group.id}`" :class="ui.group({ class: props.ui?.group })">
201
+ <div v-if="filteredGroups?.length" role="presentation" :class="ui.viewport({ class: props.ui?.viewport })">
202
+ <ListboxGroup v-for="group in filteredGroups" :key="`group-${group.id}`" :class="ui.group({ class: props.ui?.group })">
146
203
  <ListboxGroupLabel v-if="get(group, props.labelKey)" :class="ui.label({ class: props.ui?.label })">
147
204
  {{ get(group, props.labelKey) }}
148
205
  </ListboxGroupLabel>
@@ -150,10 +207,10 @@ const groups = computed(() => {
150
207
  <ListboxItem
151
208
  v-for="(item, index) in group.items"
152
209
  :key="`group-${group.id}-${index}`"
153
- :value="omit(item, ['matches', 'group', 'onSelect', 'labelHtml', 'suffixHtml'])"
210
+ :value="omit(item, ['matches', 'group', 'onSelect', 'labelHtml', 'suffixHtml', 'children'])"
154
211
  :disabled="item.disabled"
155
212
  as-child
156
- @select="item.onSelect"
213
+ @select="onSelect($event, item)"
157
214
  >
158
215
  <ULink v-slot="{ active, ...slotProps }" v-bind="pickLinkProps(item)" custom>
159
216
  <ULinkBase v-bind="slotProps" :class="ui.item({ class: [props.ui?.item, item.ui?.item, item.class], active: active || item.active })">
@@ -184,13 +241,20 @@ const groups = computed(() => {
184
241
 
185
242
  <span :class="ui.itemTrailing({ class: [props.ui?.itemTrailing, item.ui?.itemTrailing] })">
186
243
  <slot :name="item.slot ? `${item.slot}-trailing` : group.slot ? `${group.slot}-trailing` : `item-trailing`" :item="item" :index="index">
187
- <span v-if="item.kbds?.length" :class="ui.itemTrailingKbds({ class: [props.ui?.itemTrailingKbds, item.ui?.itemTrailingKbds] })">
244
+ <UIcon
245
+ v-if="item.children && item.children.length > 0"
246
+ :name="trailingIcon || appConfig.ui.icons.chevronRight"
247
+ :class="ui.itemTrailingIcon({ class: [props.ui?.itemTrailingIcon, item.ui?.itemTrailingIcon] })"
248
+ />
249
+
250
+ <span v-else-if="item.kbds?.length" :class="ui.itemTrailingKbds({ class: [props.ui?.itemTrailingKbds, item.ui?.itemTrailingKbds] })">
188
251
  <UKbd v-for="(kbd, kbdIndex) in item.kbds" :key="kbdIndex" :size="item.ui?.itemTrailingKbdsSize || props.ui?.itemTrailingKbdsSize || ui.itemTrailingKbdsSize()" v-bind="typeof kbd === 'string' ? { value: kbd } : kbd" />
189
252
  </span>
253
+
190
254
  <UIcon v-else-if="group.highlightedIcon" :name="group.highlightedIcon" :class="ui.itemTrailingHighlightedIcon({ class: [props.ui?.itemTrailingHighlightedIcon, item.ui?.itemTrailingHighlightedIcon] })" />
191
255
  </slot>
192
256
 
193
- <ListboxItemIndicator as-child>
257
+ <ListboxItemIndicator v-if="!item.children?.length" as-child>
194
258
  <UIcon :name="selectedIcon || appConfig.ui.icons.check" :class="ui.itemTrailingIcon({ class: [props.ui?.itemTrailingIcon, item.ui?.itemTrailingIcon] })" />
195
259
  </ListboxItemIndicator>
196
260
  </span>
@@ -207,5 +271,9 @@ const groups = computed(() => {
207
271
  </slot>
208
272
  </div>
209
273
  </ListboxContent>
274
+
275
+ <div v-if="!!slots.footer" :class="ui.footer({ class: props.ui?.footer })">
276
+ <slot name="footer" :ui="ui" />
277
+ </div>
210
278
  </ListboxRoot>
211
279
  </template>