@nuxt/ui 3.0.1 → 3.1.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 (228) hide show
  1. package/.nuxt/ui/accordion.ts +25 -4
  2. package/.nuxt/ui/alert.ts +52 -31
  3. package/.nuxt/ui/avatar-group.ts +24 -3
  4. package/.nuxt/ui/avatar.ts +26 -5
  5. package/.nuxt/ui/badge.ts +56 -35
  6. package/.nuxt/ui/breadcrumb.ts +28 -7
  7. package/.nuxt/ui/button-group.ts +23 -2
  8. package/.nuxt/ui/button.ts +66 -45
  9. package/.nuxt/ui/calendar.ts +39 -18
  10. package/.nuxt/ui/card.ts +28 -7
  11. package/.nuxt/ui/carousel.ts +29 -8
  12. package/.nuxt/ui/checkbox-group.ts +82 -0
  13. package/.nuxt/ui/checkbox.ts +163 -29
  14. package/.nuxt/ui/chip.ts +31 -10
  15. package/.nuxt/ui/collapsible.ts +23 -2
  16. package/.nuxt/ui/color-picker.ts +26 -5
  17. package/.nuxt/ui/command-palette.ts +37 -16
  18. package/.nuxt/ui/container.ts +24 -3
  19. package/.nuxt/ui/context-menu.ts +56 -35
  20. package/.nuxt/ui/drawer.ts +33 -12
  21. package/.nuxt/ui/dropdown-menu.ts +57 -36
  22. package/.nuxt/ui/form-field.ts +29 -8
  23. package/.nuxt/ui/form.ts +23 -2
  24. package/.nuxt/ui/index.ts +1 -0
  25. package/.nuxt/ui/input-menu.ts +65 -44
  26. package/.nuxt/ui/input-number.ts +43 -22
  27. package/.nuxt/ui/input.ts +46 -25
  28. package/.nuxt/ui/kbd.ts +27 -6
  29. package/.nuxt/ui/link.ts +26 -5
  30. package/.nuxt/ui/modal.ts +28 -7
  31. package/.nuxt/ui/navigation-menu.ts +103 -84
  32. package/.nuxt/ui/pagination.ts +23 -2
  33. package/.nuxt/ui/pin-input.ts +43 -22
  34. package/.nuxt/ui/popover.ts +25 -4
  35. package/.nuxt/ui/progress.ts +40 -19
  36. package/.nuxt/ui/radio-group.ts +273 -37
  37. package/.nuxt/ui/select-menu.ts +59 -35
  38. package/.nuxt/ui/select.ts +55 -34
  39. package/.nuxt/ui/separator.ts +31 -10
  40. package/.nuxt/ui/skeleton.ts +24 -3
  41. package/.nuxt/ui/slideover.ts +27 -6
  42. package/.nuxt/ui/slider.ts +39 -18
  43. package/.nuxt/ui/stepper.ts +41 -20
  44. package/.nuxt/ui/switch.ts +44 -23
  45. package/.nuxt/ui/table.ts +38 -17
  46. package/.nuxt/ui/tabs.ts +55 -34
  47. package/.nuxt/ui/textarea.ts +63 -37
  48. package/.nuxt/ui/toast.ts +47 -26
  49. package/.nuxt/ui/toaster.ts +23 -2
  50. package/.nuxt/ui/tooltip.ts +25 -4
  51. package/.nuxt/ui/tree.ts +41 -20
  52. package/.nuxt/ui.css +56 -12
  53. package/README.md +11 -0
  54. package/cli/templates.mjs +18 -17
  55. package/dist/module.d.mts +2 -1
  56. package/dist/module.json +5 -5
  57. package/dist/module.mjs +11 -7
  58. package/dist/runtime/components/Accordion.vue +36 -92
  59. package/dist/runtime/components/Accordion.vue.d.ts +91 -0
  60. package/dist/runtime/components/Alert.vue +37 -100
  61. package/dist/runtime/components/Alert.vue.d.ts +96 -0
  62. package/dist/runtime/components/App.vue +28 -34
  63. package/dist/runtime/components/App.vue.d.ts +24 -0
  64. package/dist/runtime/components/Avatar.vue +47 -78
  65. package/dist/runtime/components/Avatar.vue.d.ts +60 -0
  66. package/dist/runtime/components/AvatarGroup.vue +40 -77
  67. package/dist/runtime/components/AvatarGroup.vue.d.ts +40 -0
  68. package/dist/runtime/components/Badge.vue +33 -62
  69. package/dist/runtime/components/Badge.vue.d.ts +62 -0
  70. package/dist/runtime/components/Breadcrumb.vue +36 -88
  71. package/dist/runtime/components/Breadcrumb.vue.d.ts +82 -0
  72. package/dist/runtime/components/Button.vue +96 -105
  73. package/dist/runtime/components/Button.vue.d.ts +73 -0
  74. package/dist/runtime/components/ButtonGroup.vue +20 -46
  75. package/dist/runtime/components/ButtonGroup.vue.d.ts +55 -0
  76. package/dist/runtime/components/Calendar.vue +73 -127
  77. package/dist/runtime/components/Calendar.vue.d.ts +107 -0
  78. package/dist/runtime/components/Card.vue +18 -40
  79. package/dist/runtime/components/Card.vue.d.ts +38 -0
  80. package/dist/runtime/components/Carousel.vue +112 -230
  81. package/dist/runtime/components/Carousel.vue.d.ts +120 -0
  82. package/dist/runtime/components/Checkbox.vue +52 -93
  83. package/dist/runtime/components/Checkbox.vue.d.ts +76 -0
  84. package/dist/runtime/components/CheckboxGroup.vue +121 -0
  85. package/dist/runtime/components/CheckboxGroup.vue.d.ts +75 -0
  86. package/dist/runtime/components/Chip.vue +26 -69
  87. package/dist/runtime/components/Chip.vue.d.ts +71 -0
  88. package/dist/runtime/components/Collapsible.vue +22 -41
  89. package/dist/runtime/components/Collapsible.vue.d.ts +50 -0
  90. package/dist/runtime/components/ColorPicker.vue +111 -197
  91. package/dist/runtime/components/ColorPicker.vue.d.ts +63 -0
  92. package/dist/runtime/components/CommandPalette.vue +94 -234
  93. package/dist/runtime/components/CommandPalette.vue.d.ts +173 -0
  94. package/dist/runtime/components/Container.vue +15 -28
  95. package/dist/runtime/components/Container.vue.d.ts +27 -0
  96. package/dist/runtime/components/ContextMenu.vue +32 -119
  97. package/dist/runtime/components/ContextMenu.vue.d.ts +127 -0
  98. package/dist/runtime/components/ContextMenuContent.vue +71 -72
  99. package/dist/runtime/components/ContextMenuContent.vue.d.ts +105 -0
  100. package/dist/runtime/components/Drawer.vue +49 -87
  101. package/dist/runtime/components/Drawer.vue.d.ts +88 -0
  102. package/dist/runtime/components/DropdownMenu.vue +37 -129
  103. package/dist/runtime/components/DropdownMenu.vue.d.ts +141 -0
  104. package/dist/runtime/components/DropdownMenuContent.vue +76 -79
  105. package/dist/runtime/components/DropdownMenuContent.vue.d.ts +55 -0
  106. package/dist/runtime/components/Form.vue +135 -219
  107. package/dist/runtime/components/Form.vue.d.ts +66 -0
  108. package/dist/runtime/components/FormField.vue +36 -77
  109. package/dist/runtime/components/FormField.vue.d.ts +70 -0
  110. package/dist/runtime/components/Icon.vue +12 -19
  111. package/dist/runtime/components/Icon.vue.d.ts +17 -0
  112. package/dist/runtime/components/Input.vue +82 -140
  113. package/dist/runtime/components/Input.vue.d.ts +91 -0
  114. package/dist/runtime/components/InputMenu.vue +193 -302
  115. package/dist/runtime/components/InputMenu.vue.d.ts +312 -0
  116. package/dist/runtime/components/InputNumber.vue +71 -133
  117. package/dist/runtime/components/InputNumber.vue.d.ts +193 -0
  118. package/dist/runtime/components/Kbd.vue +20 -46
  119. package/dist/runtime/components/Kbd.vue.d.ts +55 -0
  120. package/dist/runtime/components/Link.vue +98 -173
  121. package/dist/runtime/components/Link.vue.d.ts +124 -0
  122. package/dist/runtime/components/LinkBase.vue +33 -41
  123. package/dist/runtime/components/LinkBase.vue.d.ts +48 -0
  124. package/dist/runtime/components/Modal.vue +53 -116
  125. package/dist/runtime/components/Modal.vue.d.ts +109 -0
  126. package/dist/runtime/components/NavigationMenu.vue +78 -186
  127. package/dist/runtime/components/NavigationMenu.vue.d.ts +159 -0
  128. package/dist/runtime/components/OverlayProvider.vue +14 -18
  129. package/dist/runtime/components/OverlayProvider.vue.d.ts +2 -0
  130. package/dist/runtime/components/Pagination.vue +46 -140
  131. package/dist/runtime/components/Pagination.vue.d.ts +143 -0
  132. package/dist/runtime/components/PinInput.vue +61 -78
  133. package/dist/runtime/components/PinInput.vue.d.ts +68 -0
  134. package/dist/runtime/components/Popover.vue +47 -84
  135. package/dist/runtime/components/Popover.vue.d.ts +80 -0
  136. package/dist/runtime/components/Progress.vue +70 -131
  137. package/dist/runtime/components/Progress.vue.d.ts +97 -0
  138. package/dist/runtime/components/RadioGroup.vue +75 -126
  139. package/dist/runtime/components/RadioGroup.vue.d.ts +88 -0
  140. package/dist/runtime/components/Select.vue +115 -202
  141. package/dist/runtime/components/Select.vue.d.ts +139 -0
  142. package/dist/runtime/components/SelectMenu.vue +167 -281
  143. package/dist/runtime/components/SelectMenu.vue.d.ts +184 -0
  144. package/dist/runtime/components/Separator.vue +29 -71
  145. package/dist/runtime/components/Separator.vue.d.ts +75 -0
  146. package/dist/runtime/components/Skeleton.vue +21 -23
  147. package/dist/runtime/components/Skeleton.vue.d.ts +26 -0
  148. package/dist/runtime/components/Slideover.vue +53 -120
  149. package/dist/runtime/components/Slideover.vue.d.ts +111 -0
  150. package/dist/runtime/components/Slider.vue +46 -84
  151. package/dist/runtime/components/Slider.vue.d.ts +71 -0
  152. package/dist/runtime/components/Stepper.vue +44 -113
  153. package/dist/runtime/components/Stepper.vue.d.ts +89 -0
  154. package/dist/runtime/components/Switch.vue +45 -93
  155. package/dist/runtime/components/Switch.vue.d.ts +73 -0
  156. package/dist/runtime/components/Table.vue +165 -264
  157. package/dist/runtime/components/Table.vue.d.ts +183 -0
  158. package/dist/runtime/components/Tabs.vue +40 -105
  159. package/dist/runtime/components/Tabs.vue.d.ts +104 -0
  160. package/dist/runtime/components/Textarea.vue +113 -158
  161. package/dist/runtime/components/Textarea.vue.d.ts +95 -0
  162. package/dist/runtime/components/Toast.vue +49 -110
  163. package/dist/runtime/components/Toast.vue.d.ts +95 -0
  164. package/dist/runtime/components/Toaster.vue +70 -107
  165. package/dist/runtime/components/Toaster.vue.d.ts +63 -0
  166. package/dist/runtime/components/Tooltip.vue +38 -65
  167. package/dist/runtime/components/Tooltip.vue.d.ts +65 -0
  168. package/dist/runtime/components/Tree.vue +57 -150
  169. package/dist/runtime/components/Tree.vue.d.ts +128 -0
  170. package/dist/runtime/composables/defineShortcuts.d.ts +1 -1
  171. package/dist/runtime/composables/defineShortcuts.js +0 -1
  172. package/dist/runtime/composables/useAvatarGroup.d.ts +1 -1
  173. package/dist/runtime/composables/useButtonGroup.d.ts +2 -2
  174. package/dist/runtime/composables/useFormField.d.ts +2 -2
  175. package/dist/runtime/composables/useFormField.js +1 -1
  176. package/dist/runtime/composables/useOverlay.d.ts +16 -8
  177. package/dist/runtime/composables/useOverlay.js +14 -6
  178. package/dist/runtime/composables/usePortal.d.ts +6 -0
  179. package/dist/runtime/composables/usePortal.js +17 -0
  180. package/dist/runtime/index.css +1 -1
  181. package/dist/runtime/inertia/components/Link.vue +146 -0
  182. package/dist/runtime/inertia/components/Link.vue.d.ts +92 -0
  183. package/dist/runtime/inertia/stubs.d.ts +43 -0
  184. package/dist/runtime/inertia/stubs.js +82 -0
  185. package/dist/runtime/locale/bg.d.ts +3 -0
  186. package/dist/runtime/locale/bg.js +54 -0
  187. package/dist/runtime/locale/hy.d.ts +3 -0
  188. package/dist/runtime/locale/hy.js +54 -0
  189. package/dist/runtime/locale/index.d.ts +6 -1
  190. package/dist/runtime/locale/index.js +6 -1
  191. package/dist/runtime/locale/kk.d.ts +3 -0
  192. package/dist/runtime/locale/kk.js +54 -0
  193. package/dist/runtime/locale/tj.d.ts +3 -0
  194. package/dist/runtime/locale/tj.js +54 -0
  195. package/dist/runtime/locale/ug_cn.d.ts +3 -0
  196. package/dist/runtime/locale/ug_cn.js +55 -0
  197. package/dist/runtime/types/form.d.ts +5 -1
  198. package/dist/runtime/types/index.d.ts +2 -0
  199. package/dist/runtime/types/index.js +2 -0
  200. package/dist/runtime/types/utils.d.ts +70 -10
  201. package/dist/runtime/utils/index.d.ts +1 -0
  202. package/dist/runtime/utils/index.js +3 -0
  203. package/dist/runtime/utils/link.d.ts +4 -27
  204. package/dist/runtime/utils/link.js +32 -1
  205. package/dist/runtime/utils/tv.js +2 -2
  206. package/dist/runtime/vue/components/Icon.vue +7 -8
  207. package/dist/runtime/vue/components/Icon.vue.d.ts +14 -0
  208. package/dist/runtime/vue/components/Link.vue +118 -199
  209. package/dist/runtime/vue/components/Link.vue.d.ts +124 -0
  210. package/dist/runtime/vue/stubs.d.ts +5 -0
  211. package/dist/runtime/vue/stubs.js +11 -2
  212. package/dist/shared/{ui.BCaWD5Ek.mjs → ui.D7lOOabO.mjs} +623 -364
  213. package/dist/types.d.mts +5 -1
  214. package/dist/unplugin.d.mts +6 -1
  215. package/dist/unplugin.mjs +25 -4
  216. package/dist/vite.mjs +1 -1
  217. package/package.json +122 -64
  218. package/dist/module.cjs +0 -62
  219. package/dist/module.d.cts +0 -44
  220. package/dist/module.d.ts +0 -44
  221. package/dist/shared/ui.C6uTSFTI.cjs +0 -3555
  222. package/dist/types.d.ts +0 -1
  223. package/dist/unplugin.cjs +0 -232
  224. package/dist/unplugin.d.cts +0 -61
  225. package/dist/unplugin.d.ts +0 -61
  226. package/dist/vite.cjs +0 -23
  227. package/dist/vite.d.cts +0 -15
  228. package/dist/vite.d.ts +0 -15
@@ -1,255 +1,116 @@
1
- <!-- eslint-disable vue/block-tag-newline -->
2
- <script lang="ts">
3
- import type { ListboxRootProps, ListboxRootEmits } from 'reka-ui'
4
- import type { FuseResult } from 'fuse.js'
5
- import type { AppConfig } from '@nuxt/schema'
6
- import type { UseFuseOptions } from '@vueuse/integrations/useFuse'
7
- import _appConfig from '#build/app.config'
8
- import theme from '#build/ui/command-palette'
9
- import type { UseComponentIconsProps } from '../composables/useComponentIcons'
10
- import { tv } from '../utils/tv'
11
- import type { AvatarProps, ButtonProps, ChipProps, KbdProps, InputProps, LinkProps } from '../types'
12
- import type { DynamicSlots, PartialString } from '../types/utils'
13
-
14
- const appConfigCommandPalette = _appConfig as AppConfig & { ui: { commandPalette: Partial<typeof theme> } }
15
-
16
- const commandPalette = tv({ extend: tv(theme), ...(appConfigCommandPalette.ui?.commandPalette || {}) })
17
-
18
- export interface CommandPaletteItem extends Omit<LinkProps, 'type' | 'raw' | 'custom'> {
19
- prefix?: string
20
- label?: string
21
- suffix?: string
22
- /**
23
- * @IconifyIcon
24
- */
25
- icon?: string
26
- avatar?: AvatarProps
27
- chip?: ChipProps
28
- kbds?: KbdProps['value'][] | KbdProps[]
29
- active?: boolean
30
- loading?: boolean
31
- disabled?: boolean
32
- slot?: string
33
- onSelect?(e?: Event): void
34
- }
35
-
36
- export interface CommandPaletteGroup<T> {
37
- id: string
38
- label?: string
39
- slot?: string
40
- items?: T[]
41
- /**
42
- * Whether to filter group items with [useFuse](https://vueuse.org/integrations/useFuse).
43
- * When `true`, items will not be filtered which is useful for custom filtering (useAsyncData, useFetch, etc.).
44
- * @defaultValue false
45
- */
46
- ignoreFilter?: boolean
47
- /** Filter group items after the search happened. */
48
- postFilter?: (searchTerm: string, items: T[]) => T[]
49
- /**
50
- * The icon displayed when an item is highlighted.
51
- * @IconifyIcon
52
- */
53
- highlightedIcon?: string
54
- }
55
-
56
- export interface CommandPaletteProps<G, T> extends Pick<ListboxRootProps, 'multiple' | 'disabled' | 'modelValue' | 'defaultValue' | 'highlightOnHover'>, Pick<UseComponentIconsProps, 'loading' | 'loadingIcon'> {
57
- /**
58
- * The element or component this component should render as.
59
- * @defaultValue 'div'
60
- */
61
- as?: any
62
- /**
63
- * The icon displayed in the input.
64
- * @defaultValue appConfig.ui.icons.search
65
- * @IconifyIcon
66
- */
67
- icon?: string
68
- /**
69
- * The icon displayed when an item is selected.
70
- * @defaultValue appConfig.ui.icons.check
71
- * @IconifyIcon
72
- */
73
- selectedIcon?: string
74
- /**
75
- * The placeholder text for the input.
76
- * @defaultValue 'Type a command or search...'
77
- */
78
- placeholder?: InputProps['placeholder']
79
- /**
80
- * Automatically focus the input when component is mounted.
81
- * @defaultValue true
82
- */
83
- autofocus?: boolean
84
- /**
85
- * Display a close button in the input (useful when inside a Modal for example).
86
- * `{ size: 'md', color: 'neutral', variant: 'ghost' }`{lang="ts-type"}
87
- * @emits 'update:open'
88
- * @defaultValue false
89
- */
90
- close?: boolean | Partial<ButtonProps>
91
- /**
92
- * The icon displayed in the close button.
93
- * @defaultValue appConfig.ui.icons.close
94
- * @IconifyIcon
95
- */
96
- closeIcon?: string
97
- groups?: G[]
98
- /**
99
- * Options for [useFuse](https://vueuse.org/integrations/useFuse).
100
- * @defaultValue {
101
- fuseOptions: {
102
- ignoreLocation: true,
103
- threshold: 0.1,
104
- keys: ['label', 'suffix']
105
- },
106
- resultLimit: 12,
107
- matchAllWhenSearchEmpty: true
108
- }
109
- */
110
- fuse?: UseFuseOptions<T>
111
- /**
112
- * The key used to get the label from the item.
113
- * @defaultValue 'label'
114
- */
115
- labelKey?: string
116
- class?: any
117
- ui?: PartialString<typeof commandPalette.slots>
118
- }
119
-
120
- export type CommandPaletteEmits<T> = ListboxRootEmits<T> & {
121
- 'update:open': [value: boolean]
122
- }
123
-
124
- type SlotProps<T> = (props: { item: T, index: number }) => any
125
-
126
- export type CommandPaletteSlots<G extends { slot?: string }, T extends { slot?: string }> = {
127
- 'empty'(props: { searchTerm?: string }): any
128
- 'close'(props: { ui: any }): any
129
- 'item': SlotProps<T>
130
- 'item-leading': SlotProps<T>
131
- 'item-label': SlotProps<T>
132
- 'item-trailing': SlotProps<T>
133
- } & DynamicSlots<G, SlotProps<T>> & DynamicSlots<T, SlotProps<T>>
134
-
1
+ <script>
2
+ import theme from "#build/ui/command-palette";
135
3
  </script>
136
4
 
137
- <script setup lang="ts" generic="G extends CommandPaletteGroup<T>, T extends CommandPaletteItem">
138
- import { computed } from 'vue'
139
- import { ListboxRoot, ListboxFilter, ListboxContent, ListboxGroup, ListboxGroupLabel, ListboxItem, ListboxItemIndicator, useForwardProps, useForwardPropsEmits } from 'reka-ui'
140
- import { defu } from 'defu'
141
- import { reactivePick } from '@vueuse/core'
142
- import { useFuse } from '@vueuse/integrations/useFuse'
143
- import { useAppConfig } from '#imports'
144
- import { useLocale } from '../composables/useLocale'
145
- import { omit, get } from '../utils'
146
- import { highlight } from '../utils/fuse'
147
- import { pickLinkProps } from '../utils/link'
148
- import UIcon from './Icon.vue'
149
- import UAvatar from './Avatar.vue'
150
- import UButton from './Button.vue'
151
- import UChip from './Chip.vue'
152
- import ULinkBase from './LinkBase.vue'
153
- import ULink from './Link.vue'
154
- import UInput from './Input.vue'
155
- import UKbd from './Kbd.vue'
156
-
157
- const props = withDefaults(defineProps<CommandPaletteProps<G, T>>(), {
158
- modelValue: '',
159
- labelKey: 'label',
160
- autofocus: true
161
- })
162
- const emits = defineEmits<CommandPaletteEmits<T>>()
163
- const slots = defineSlots<CommandPaletteSlots<G, T>>()
164
-
165
- const searchTerm = defineModel<string>('searchTerm', { default: '' })
166
-
167
- const { t } = useLocale()
168
- const appConfig = useAppConfig()
169
-
170
- const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'disabled', 'multiple', 'modelValue', 'defaultValue', 'highlightOnHover'), emits)
171
- const inputProps = useForwardProps(reactivePick(props, 'loading', 'loadingIcon'))
172
-
173
- // eslint-disable-next-line vue/no-dupe-keys
174
- const ui = commandPalette()
175
-
5
+ <script setup>
6
+ import { computed } from "vue";
7
+ import { ListboxRoot, ListboxFilter, ListboxContent, ListboxGroup, ListboxGroupLabel, ListboxItem, ListboxItemIndicator, useForwardProps, useForwardPropsEmits } from "reka-ui";
8
+ import { defu } from "defu";
9
+ import { reactivePick } from "@vueuse/core";
10
+ import { useFuse } from "@vueuse/integrations/useFuse";
11
+ import { useAppConfig } from "#imports";
12
+ import { useLocale } from "../composables/useLocale";
13
+ import { omit, get } from "../utils";
14
+ import { tv } from "../utils/tv";
15
+ import { highlight } from "../utils/fuse";
16
+ import { pickLinkProps } from "../utils/link";
17
+ import UIcon from "./Icon.vue";
18
+ import UAvatar from "./Avatar.vue";
19
+ import UButton from "./Button.vue";
20
+ import UChip from "./Chip.vue";
21
+ import ULinkBase from "./LinkBase.vue";
22
+ import ULink from "./Link.vue";
23
+ import UInput from "./Input.vue";
24
+ import UKbd from "./Kbd.vue";
25
+ const props = defineProps({
26
+ as: { type: null, required: false },
27
+ icon: { type: String, required: false },
28
+ selectedIcon: { type: String, required: false },
29
+ placeholder: { type: String, required: false },
30
+ autofocus: { type: Boolean, required: false, default: true },
31
+ close: { type: [Boolean, Object], required: false },
32
+ closeIcon: { type: String, required: false },
33
+ groups: { type: Array, required: false },
34
+ fuse: { type: Object, required: false },
35
+ labelKey: { type: String, required: false, default: "label" },
36
+ class: { type: null, required: false },
37
+ ui: { type: null, required: false },
38
+ multiple: { type: Boolean, required: false },
39
+ disabled: { type: Boolean, required: false },
40
+ modelValue: { type: null, required: false, default: "" },
41
+ defaultValue: { type: null, required: false },
42
+ highlightOnHover: { type: Boolean, required: false },
43
+ loading: { type: Boolean, required: false },
44
+ loadingIcon: { type: String, required: false }
45
+ });
46
+ const emits = defineEmits(["update:modelValue", "highlight", "entryFocus", "leave", "update:open"]);
47
+ const slots = defineSlots();
48
+ const searchTerm = defineModel("searchTerm", { type: String, ...{ default: "" } });
49
+ const { t } = useLocale();
50
+ const appConfig = useAppConfig();
51
+ const rootProps = useForwardPropsEmits(reactivePick(props, "as", "disabled", "multiple", "modelValue", "defaultValue", "highlightOnHover"), emits);
52
+ const inputProps = useForwardProps(reactivePick(props, "loading", "loadingIcon"));
53
+ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.commandPalette || {} })());
176
54
  const fuse = computed(() => defu({}, props.fuse, {
177
55
  fuseOptions: {
178
56
  ignoreLocation: true,
179
57
  threshold: 0.1,
180
- keys: [props.labelKey, 'suffix']
58
+ keys: [props.labelKey, "suffix"]
181
59
  },
182
60
  resultLimit: 12,
183
61
  matchAllWhenSearchEmpty: true
184
- }))
185
-
62
+ }));
186
63
  const items = computed(() => props.groups?.filter((group) => {
187
64
  if (!group.id) {
188
- console.warn(`[@nuxt/ui] CommandPalette group is missing an \`id\` property`)
189
- return false
65
+ console.warn(`[@nuxt/ui] CommandPalette group is missing an \`id\` property`);
66
+ return false;
190
67
  }
191
-
192
68
  if (group.ignoreFilter) {
193
- return false
69
+ return false;
194
70
  }
195
-
196
- return true
197
- }).flatMap(group => group.items?.map(item => ({ ...item, group: group.id })) || []) || [])
198
-
199
- const { results: fuseResults } = useFuse<typeof items.value[number]>(searchTerm, items, fuse)
200
-
201
- function getGroupWithItems(group: G, items: (T & { matches?: FuseResult<T>['matches'] })[]) {
202
- if (group?.postFilter && typeof group.postFilter === 'function') {
203
- items = group.postFilter(searchTerm.value, items)
71
+ return true;
72
+ }).flatMap((group) => group.items?.map((item) => ({ ...item, group: group.id })) || []) || []);
73
+ const { results: fuseResults } = useFuse(searchTerm, items, fuse);
74
+ function getGroupWithItems(group, items2) {
75
+ if (group?.postFilter && typeof group.postFilter === "function") {
76
+ items2 = group.postFilter(searchTerm.value, items2);
204
77
  }
205
-
206
78
  return {
207
79
  ...group,
208
- items: items.slice(0, fuse.value.resultLimit).map((item) => {
80
+ items: items2.slice(0, fuse.value.resultLimit).map((item) => {
209
81
  return {
210
82
  ...item,
211
- labelHtml: highlight<T>(item, searchTerm.value, props.labelKey),
212
- suffixHtml: highlight<T>(item, searchTerm.value, undefined, [props.labelKey])
213
- }
83
+ labelHtml: highlight(item, searchTerm.value, props.labelKey),
84
+ suffixHtml: highlight(item, searchTerm.value, void 0, [props.labelKey])
85
+ };
214
86
  })
215
- }
87
+ };
216
88
  }
217
-
218
89
  const groups = computed(() => {
219
90
  const groupsById = fuseResults.value.reduce((acc, result) => {
220
- const { item, matches } = result
91
+ const { item, matches } = result;
221
92
  if (!item.group) {
222
- return acc
93
+ return acc;
223
94
  }
224
-
225
- acc[item.group] ||= []
226
- acc[item.group]?.push({ ...item, matches })
227
-
228
- return acc
229
- }, {} as Record<string, (T & { matches?: FuseResult<T>['matches'] })[]>)
230
-
231
- const fuseGroups = Object.entries(groupsById).map(([id, items]) => {
232
- const group = props.groups?.find(group => group.id === id)
95
+ acc[item.group] ||= [];
96
+ acc[item.group]?.push({ ...item, matches });
97
+ return acc;
98
+ }, {});
99
+ const fuseGroups = Object.entries(groupsById).map(([id, items2]) => {
100
+ const group = props.groups?.find((group2) => group2.id === id);
233
101
  if (!group) {
234
- return
102
+ return;
235
103
  }
236
-
237
- return getGroupWithItems(group, items)
238
- }).filter(group => !!group)
239
-
240
- const nonFuseGroups = props.groups
241
- ?.map((group, index) => ({ ...group, index }))
242
- ?.filter(group => group.ignoreFilter && group.items?.length)
243
- ?.map(group => ({ ...getGroupWithItems(group, group.items || []), index: group.index })) || []
244
-
104
+ return getGroupWithItems(group, items2);
105
+ }).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 })) || [];
245
107
  return nonFuseGroups.reduce((acc, group) => {
246
- acc.splice(group.index, 0, group)
247
- return acc
248
- }, [...fuseGroups])
249
- })
108
+ acc.splice(group.index, 0, group);
109
+ return acc;
110
+ }, [...fuseGroups]);
111
+ });
250
112
  </script>
251
113
 
252
- <!-- eslint-disable vue/no-v-html -->
253
114
  <template>
254
115
  <ListboxRoot v-bind="rootProps" :class="ui.root({ class: [props.class, props.ui?.root] })">
255
116
  <ListboxFilter v-model="searchTerm" as-child>
@@ -257,7 +118,6 @@ const groups = computed(() => {
257
118
  :placeholder="placeholder || t('commandPalette.placeholder')"
258
119
  variant="none"
259
120
  :autofocus="autofocus"
260
- size="lg"
261
121
  v-bind="inputProps"
262
122
  :icon="icon || appConfig.ui.icons.search"
263
123
  :class="ui.input({ class: props.ui?.input })"
@@ -271,7 +131,7 @@ const groups = computed(() => {
271
131
  color="neutral"
272
132
  variant="ghost"
273
133
  :aria-label="t('commandPalette.close')"
274
- v-bind="(typeof close === 'object' ? close as Partial<ButtonProps> : {})"
134
+ v-bind="typeof close === 'object' ? close : {}"
275
135
  :class="ui.close({ class: props.ui?.close })"
276
136
  @click="emits('update:open', false)"
277
137
  />
@@ -282,15 +142,15 @@ const groups = computed(() => {
282
142
 
283
143
  <ListboxContent :class="ui.content({ class: props.ui?.content })">
284
144
  <div v-if="groups?.length" :class="ui.viewport({ class: props.ui?.viewport })">
285
- <ListboxGroup v-for="(group, groupIndex) in groups" :key="`group-${groupIndex}`" :class="ui.group({ class: props.ui?.group })">
286
- <ListboxGroupLabel v-if="get(group, props.labelKey as string)" :class="ui.label({ class: props.ui?.label })">
287
- {{ get(group, props.labelKey as string) }}
145
+ <ListboxGroup v-for="group in groups" :key="`group-${group.id}`" :class="ui.group({ class: props.ui?.group })">
146
+ <ListboxGroupLabel v-if="get(group, props.labelKey)" :class="ui.label({ class: props.ui?.label })">
147
+ {{ get(group, props.labelKey) }}
288
148
  </ListboxGroupLabel>
289
149
 
290
150
  <ListboxItem
291
151
  v-for="(item, index) in group.items"
292
- :key="`group-${groupIndex}-${index}`"
293
- :value="omit(item, ['matches' as any, 'group' as any, 'onSelect', 'labelHtml', 'suffixHtml'])"
152
+ :key="`group-${group.id}-${index}`"
153
+ :value="omit(item, ['matches', 'group', 'onSelect', 'labelHtml', 'suffixHtml'])"
294
154
  :disabled="item.disabled"
295
155
  as-child
296
156
  @select="item.onSelect"
@@ -301,10 +161,10 @@ const groups = computed(() => {
301
161
  <slot :name="item.slot ? `${item.slot}-leading` : group.slot ? `${group.slot}-leading` : `item-leading`" :item="item" :index="index">
302
162
  <UIcon v-if="item.loading" :name="loadingIcon || appConfig.ui.icons.loading" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon, loading: true })" />
303
163
  <UIcon v-else-if="item.icon" :name="item.icon" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon, active: active || item.active })" />
304
- <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 })" />
164
+ <UAvatar v-else-if="item.avatar" :size="props.ui?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()" v-bind="item.avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar, active: active || item.active })" />
305
165
  <UChip
306
166
  v-else-if="item.chip"
307
- :size="((props.ui?.itemLeadingChipSize || ui.itemLeadingChipSize()) as ChipProps['size'])"
167
+ :size="props.ui?.itemLeadingChipSize || ui.itemLeadingChipSize()"
308
168
  inset
309
169
  standalone
310
170
  v-bind="item.chip"
@@ -312,11 +172,11 @@ const groups = computed(() => {
312
172
  />
313
173
  </slot>
314
174
 
315
- <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 })">
175
+ <span v-if="item.labelHtml || get(item, props.labelKey) || !!slots[item.slot ? `${item.slot}-label` : group.slot ? `${group.slot}-label` : `item-label`]" :class="ui.itemLabel({ class: props.ui?.itemLabel, active: active || item.active })">
316
176
  <slot :name="item.slot ? `${item.slot}-label` : group.slot ? `${group.slot}-label` : `item-label`" :item="item" :index="index">
317
177
  <span v-if="item.prefix" :class="ui.itemLabelPrefix({ class: props.ui?.itemLabelPrefix })">{{ item.prefix }}</span>
318
178
 
319
- <span :class="ui.itemLabelBase({ class: props.ui?.itemLabelBase, active: active || item.active })" v-html="item.labelHtml || get(item, props.labelKey as string)" />
179
+ <span :class="ui.itemLabelBase({ class: props.ui?.itemLabelBase, active: active || item.active })" v-html="item.labelHtml || get(item, props.labelKey)" />
320
180
 
321
181
  <span :class="ui.itemLabelSuffix({ class: props.ui?.itemLabelSuffix, active: active || item.active })" v-html="item.suffixHtml || item.suffix" />
322
182
  </slot>
@@ -325,7 +185,7 @@ const groups = computed(() => {
325
185
  <span :class="ui.itemTrailing({ class: props.ui?.itemTrailing })">
326
186
  <slot :name="item.slot ? `${item.slot}-trailing` : group.slot ? `${group.slot}-trailing` : `item-trailing`" :item="item" :index="index">
327
187
  <span v-if="item.kbds?.length" :class="ui.itemTrailingKbds({ class: props.ui?.itemTrailingKbds })">
328
- <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" />
188
+ <UKbd v-for="(kbd, kbdIndex) in item.kbds" :key="kbdIndex" :size="props.ui?.itemTrailingKbdsSize || ui.itemTrailingKbdsSize()" v-bind="typeof kbd === 'string' ? { value: kbd } : kbd" />
329
189
  </span>
330
190
  <UIcon v-else-if="group.highlightedIcon" :name="group.highlightedIcon" :class="ui.itemTrailingHighlightedIcon({ class: props.ui?.itemTrailingHighlightedIcon })" />
331
191
  </slot>
@@ -0,0 +1,173 @@
1
+ import type { ListboxRootProps, ListboxRootEmits } from 'reka-ui';
2
+ import type { AppConfig } from '@nuxt/schema';
3
+ import type { UseFuseOptions } from '@vueuse/integrations/useFuse';
4
+ import theme from '#build/ui/command-palette';
5
+ import type { UseComponentIconsProps } from '../composables/useComponentIcons';
6
+ import type { AvatarProps, ButtonProps, ChipProps, KbdProps, InputProps, LinkProps } from '../types';
7
+ import type { ComponentConfig } from '../types/utils';
8
+ type CommandPalette = ComponentConfig<typeof theme, AppConfig, 'commandPalette'>;
9
+ export interface CommandPaletteItem extends Omit<LinkProps, 'type' | 'raw' | 'custom'> {
10
+ prefix?: string;
11
+ label?: string;
12
+ suffix?: string;
13
+ /**
14
+ * @IconifyIcon
15
+ */
16
+ icon?: string;
17
+ avatar?: AvatarProps;
18
+ chip?: ChipProps;
19
+ kbds?: KbdProps['value'][] | KbdProps[];
20
+ active?: boolean;
21
+ loading?: boolean;
22
+ disabled?: boolean;
23
+ slot?: string;
24
+ onSelect?(e?: Event): void;
25
+ [key: string]: any;
26
+ }
27
+ export interface CommandPaletteGroup<T> {
28
+ id: string;
29
+ label?: string;
30
+ slot?: string;
31
+ items?: T[];
32
+ /**
33
+ * Whether to filter group items with [useFuse](https://vueuse.org/integrations/useFuse).
34
+ * When `true`, items will not be filtered which is useful for custom filtering (useAsyncData, useFetch, etc.).
35
+ * @defaultValue false
36
+ */
37
+ ignoreFilter?: boolean;
38
+ /** Filter group items after the search happened. */
39
+ postFilter?: (searchTerm: string, items: T[]) => T[];
40
+ /**
41
+ * The icon displayed when an item is highlighted.
42
+ * @IconifyIcon
43
+ */
44
+ highlightedIcon?: string;
45
+ }
46
+ export interface CommandPaletteProps<G, T> extends Pick<ListboxRootProps, 'multiple' | 'disabled' | 'modelValue' | 'defaultValue' | 'highlightOnHover'>, Pick<UseComponentIconsProps, 'loading' | 'loadingIcon'> {
47
+ /**
48
+ * The element or component this component should render as.
49
+ * @defaultValue 'div'
50
+ */
51
+ as?: any;
52
+ /**
53
+ * The icon displayed in the input.
54
+ * @defaultValue appConfig.ui.icons.search
55
+ * @IconifyIcon
56
+ */
57
+ icon?: string;
58
+ /**
59
+ * The icon displayed when an item is selected.
60
+ * @defaultValue appConfig.ui.icons.check
61
+ * @IconifyIcon
62
+ */
63
+ selectedIcon?: string;
64
+ /**
65
+ * The placeholder text for the input.
66
+ * @defaultValue t('commandPalette.placeholder')
67
+ */
68
+ placeholder?: InputProps['placeholder'];
69
+ /**
70
+ * Automatically focus the input when component is mounted.
71
+ * @defaultValue true
72
+ */
73
+ autofocus?: boolean;
74
+ /**
75
+ * Display a close button in the input (useful when inside a Modal for example).
76
+ * `{ size: 'md', color: 'neutral', variant: 'ghost' }`{lang="ts-type"}
77
+ * @emits 'update:open'
78
+ * @defaultValue false
79
+ */
80
+ close?: boolean | Partial<ButtonProps>;
81
+ /**
82
+ * The icon displayed in the close button.
83
+ * @defaultValue appConfig.ui.icons.close
84
+ * @IconifyIcon
85
+ */
86
+ closeIcon?: string;
87
+ groups?: G[];
88
+ /**
89
+ * Options for [useFuse](https://vueuse.org/integrations/useFuse).
90
+ * @defaultValue {
91
+ fuseOptions: {
92
+ ignoreLocation: true,
93
+ threshold: 0.1,
94
+ keys: ['label', 'suffix']
95
+ },
96
+ resultLimit: 12,
97
+ matchAllWhenSearchEmpty: true
98
+ }
99
+ */
100
+ fuse?: UseFuseOptions<T>;
101
+ /**
102
+ * The key used to get the label from the item.
103
+ * @defaultValue 'label'
104
+ */
105
+ labelKey?: string;
106
+ class?: any;
107
+ ui?: CommandPalette['slots'];
108
+ }
109
+ export type CommandPaletteEmits<T> = ListboxRootEmits<T> & {
110
+ 'update:open': [value: boolean];
111
+ };
112
+ type SlotProps<T> = (props: {
113
+ item: T;
114
+ index: number;
115
+ }) => any;
116
+ export type CommandPaletteSlots<G extends {
117
+ slot?: string;
118
+ }, T extends {
119
+ slot?: string;
120
+ }> = {
121
+ 'empty'(props: {
122
+ searchTerm?: string;
123
+ }): any;
124
+ 'close'(props: {
125
+ ui: {
126
+ [K in keyof Required<CommandPalette['slots']>]: (props?: Record<string, any>) => string;
127
+ };
128
+ }): any;
129
+ 'item': SlotProps<T>;
130
+ 'item-leading': SlotProps<T>;
131
+ 'item-label': SlotProps<T>;
132
+ 'item-trailing': SlotProps<T>;
133
+ } & Record<string, SlotProps<G>> & Record<string, SlotProps<T>>;
134
+ declare const _default: <G extends CommandPaletteGroup<T>, T extends CommandPaletteItem>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
135
+ props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, never> & ({
136
+ searchTerm?: string;
137
+ } & CommandPaletteProps<G, T>) & Partial<{}>> & (import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps);
138
+ expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
139
+ attrs: any;
140
+ slots: Readonly<{
141
+ empty(props: {
142
+ searchTerm?: string;
143
+ }): any;
144
+ close(props: {
145
+ ui: { [K in keyof Required<CommandPalette["slots"]>]: (props?: Record<string, any>) => string; };
146
+ }): any;
147
+ item: SlotProps<T>;
148
+ 'item-leading': SlotProps<T>;
149
+ 'item-label': SlotProps<T>;
150
+ 'item-trailing': SlotProps<T>;
151
+ } & Record<string, SlotProps<G>> & Record<string, SlotProps<T>>> & {
152
+ empty(props: {
153
+ searchTerm?: string;
154
+ }): any;
155
+ close(props: {
156
+ ui: { [K in keyof Required<CommandPalette["slots"]>]: (props?: Record<string, any>) => string; };
157
+ }): any;
158
+ item: SlotProps<T>;
159
+ 'item-leading': SlotProps<T>;
160
+ 'item-label': SlotProps<T>;
161
+ 'item-trailing': SlotProps<T>;
162
+ } & Record<string, SlotProps<G>> & Record<string, SlotProps<T>>;
163
+ emit: (((evt: "highlight", payload: {
164
+ ref: HTMLElement;
165
+ value: T;
166
+ } | undefined) => void) & ((evt: "update:open", value: boolean) => void) & ((evt: "update:modelValue", value: T) => void) & ((evt: "entryFocus", event: CustomEvent<any>) => void) & ((evt: "leave", event: Event) => void)) & ((evt: "update:searchTerm", value: string) => void);
167
+ }>) => import("vue").VNode & {
168
+ __ctx?: Awaited<typeof __VLS_setup>;
169
+ };
170
+ export default _default;
171
+ type __VLS_PrettifyLocal<T> = {
172
+ [K in keyof T]: T[K];
173
+ } & {};
@@ -1,36 +1,23 @@
1
- <script lang="ts">
2
- import type { AppConfig } from '@nuxt/schema'
3
- import _appConfig from '#build/app.config'
4
- import theme from '#build/ui/container'
5
- import { tv } from '../utils/tv'
6
-
7
- const appConfigContainer = _appConfig as AppConfig & { ui: { container: Partial<typeof theme> } }
8
-
9
- const container = tv({ extend: tv(theme), ...(appConfigContainer.ui?.container || {}) })
10
-
11
- export interface ContainerProps {
12
- /**
13
- * The element or component this component should render as.
14
- * @defaultValue 'div'
15
- */
16
- as?: any
17
- class?: any
18
- }
19
-
20
- export interface ContainerSlots {
21
- default(props?: {}): any
22
- }
1
+ <script>
2
+ import theme from "#build/ui/container";
23
3
  </script>
24
4
 
25
- <script setup lang="ts">
26
- import { Primitive } from 'reka-ui'
27
-
28
- const props = defineProps<ContainerProps>()
29
- defineSlots<ContainerSlots>()
5
+ <script setup>
6
+ import { computed } from "vue";
7
+ import { Primitive } from "reka-ui";
8
+ import { useAppConfig } from "#imports";
9
+ import { tv } from "../utils/tv";
10
+ const props = defineProps({
11
+ as: { type: null, required: false },
12
+ class: { type: null, required: false }
13
+ });
14
+ defineSlots();
15
+ const appConfig = useAppConfig();
16
+ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.container || {} }));
30
17
  </script>
31
18
 
32
19
  <template>
33
- <Primitive :as="as" :class="container({ class: props.class })">
20
+ <Primitive :as="as" :class="ui({ class: props.class })">
34
21
  <slot />
35
22
  </Primitive>
36
23
  </template>
@@ -0,0 +1,27 @@
1
+ export interface ContainerProps {
2
+ /**
3
+ * The element or component this component should render as.
4
+ * @defaultValue 'div'
5
+ */
6
+ as?: any;
7
+ class?: any;
8
+ }
9
+ export interface ContainerSlots {
10
+ default(props?: {}): any;
11
+ }
12
+ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<import("vue").ExtractPropTypes<__VLS_TypePropsToOption<ContainerProps>>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_TypePropsToOption<ContainerProps>>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>, Readonly<ContainerSlots> & ContainerSlots>;
13
+ export default _default;
14
+ type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
15
+ type __VLS_TypePropsToOption<T> = {
16
+ [K in keyof T]-?: {} extends Pick<T, K> ? {
17
+ type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
18
+ } : {
19
+ type: import('vue').PropType<T[K]>;
20
+ required: true;
21
+ };
22
+ };
23
+ type __VLS_WithTemplateSlots<T, S> = T & {
24
+ new (): {
25
+ $slots: S;
26
+ };
27
+ };