@nuxt/ui 4.6.1 → 4.7.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 (168) hide show
  1. package/README.md +7 -4
  2. package/cli/package.json +1 -1
  3. package/dist/module.json +1 -1
  4. package/dist/module.mjs +3 -2
  5. package/dist/runtime/components/Accordion.d.vue.ts +6 -1
  6. package/dist/runtime/components/Accordion.vue +1 -1
  7. package/dist/runtime/components/Accordion.vue.d.ts +6 -1
  8. package/dist/runtime/components/AuthForm.d.vue.ts +22 -29
  9. package/dist/runtime/components/AuthForm.vue +8 -6
  10. package/dist/runtime/components/AuthForm.vue.d.ts +22 -29
  11. package/dist/runtime/components/Calendar.vue +4 -4
  12. package/dist/runtime/components/Card.d.vue.ts +4 -0
  13. package/dist/runtime/components/Card.vue +16 -2
  14. package/dist/runtime/components/Card.vue.d.ts +4 -0
  15. package/dist/runtime/components/ChatMessage.d.vue.ts +27 -17
  16. package/dist/runtime/components/ChatMessage.vue +10 -16
  17. package/dist/runtime/components/ChatMessage.vue.d.ts +27 -17
  18. package/dist/runtime/components/ChatMessages.d.vue.ts +27 -21
  19. package/dist/runtime/components/ChatMessages.vue +22 -23
  20. package/dist/runtime/components/ChatMessages.vue.d.ts +27 -21
  21. package/dist/runtime/components/ChatPromptSubmit.vue +3 -1
  22. package/dist/runtime/components/Checkbox.vue +5 -3
  23. package/dist/runtime/components/CommandPalette.d.vue.ts +18 -3
  24. package/dist/runtime/components/CommandPalette.vue +11 -7
  25. package/dist/runtime/components/CommandPalette.vue.d.ts +18 -3
  26. package/dist/runtime/components/ContextMenuContent.vue +68 -65
  27. package/dist/runtime/components/DashboardSearch.d.vue.ts +8 -37
  28. package/dist/runtime/components/DashboardSearch.vue +11 -10
  29. package/dist/runtime/components/DashboardSearch.vue.d.ts +8 -37
  30. package/dist/runtime/components/DashboardSidebar.vue +1 -5
  31. package/dist/runtime/components/Drawer.vue +44 -41
  32. package/dist/runtime/components/DropdownMenuContent.vue +90 -87
  33. package/dist/runtime/components/EditorEmojiMenu.d.vue.ts +1 -1
  34. package/dist/runtime/components/EditorEmojiMenu.vue +2 -0
  35. package/dist/runtime/components/EditorEmojiMenu.vue.d.ts +1 -1
  36. package/dist/runtime/components/EditorMentionMenu.d.vue.ts +1 -1
  37. package/dist/runtime/components/EditorMentionMenu.vue +2 -0
  38. package/dist/runtime/components/EditorMentionMenu.vue.d.ts +1 -1
  39. package/dist/runtime/components/EditorSuggestionMenu.d.vue.ts +1 -1
  40. package/dist/runtime/components/EditorSuggestionMenu.vue +2 -0
  41. package/dist/runtime/components/EditorSuggestionMenu.vue.d.ts +1 -1
  42. package/dist/runtime/components/FileUpload.vue +7 -5
  43. package/dist/runtime/components/Header.vue +1 -5
  44. package/dist/runtime/components/Input.vue +2 -2
  45. package/dist/runtime/components/InputDate.vue +6 -6
  46. package/dist/runtime/components/InputMenu.d.vue.ts +3 -3
  47. package/dist/runtime/components/InputMenu.vue +40 -38
  48. package/dist/runtime/components/InputMenu.vue.d.ts +3 -3
  49. package/dist/runtime/components/InputNumber.vue +2 -2
  50. package/dist/runtime/components/InputTags.vue +2 -2
  51. package/dist/runtime/components/InputTime.vue +2 -2
  52. package/dist/runtime/components/Link.vue +64 -8
  53. package/dist/runtime/components/Listbox.d.vue.ts +228 -0
  54. package/dist/runtime/components/Listbox.vue +242 -0
  55. package/dist/runtime/components/Listbox.vue.d.ts +228 -0
  56. package/dist/runtime/components/Modal.vue +13 -10
  57. package/dist/runtime/components/Popover.vue +7 -4
  58. package/dist/runtime/components/PricingTable.vue +60 -58
  59. package/dist/runtime/components/RadioGroup.vue +5 -3
  60. package/dist/runtime/components/Select.d.vue.ts +1 -1
  61. package/dist/runtime/components/Select.vue +84 -73
  62. package/dist/runtime/components/Select.vue.d.ts +1 -1
  63. package/dist/runtime/components/SelectMenu.d.vue.ts +3 -3
  64. package/dist/runtime/components/SelectMenu.vue +54 -52
  65. package/dist/runtime/components/SelectMenu.vue.d.ts +3 -3
  66. package/dist/runtime/components/Sidebar.vue +1 -4
  67. package/dist/runtime/components/Slideover.vue +67 -64
  68. package/dist/runtime/components/Table.d.vue.ts +1 -2
  69. package/dist/runtime/components/Table.vue +17 -29
  70. package/dist/runtime/components/Table.vue.d.ts +1 -2
  71. package/dist/runtime/components/Tabs.d.vue.ts +5 -1
  72. package/dist/runtime/components/Tabs.vue +2 -2
  73. package/dist/runtime/components/Tabs.vue.d.ts +5 -1
  74. package/dist/runtime/components/Textarea.d.vue.ts +1 -0
  75. package/dist/runtime/components/Textarea.vue +2 -1
  76. package/dist/runtime/components/Textarea.vue.d.ts +1 -0
  77. package/dist/runtime/components/Tooltip.vue +12 -9
  78. package/dist/runtime/components/content/ContentSearch.d.vue.ts +19 -35
  79. package/dist/runtime/components/content/ContentSearch.vue +10 -9
  80. package/dist/runtime/components/content/ContentSearch.vue.d.ts +19 -35
  81. package/dist/runtime/components/content/ContentToc.vue +19 -9
  82. package/dist/runtime/components/prose/Img.vue +2 -1
  83. package/dist/runtime/components/prose/Pre.vue +8 -3
  84. package/dist/runtime/components/prose/Prompt.d.vue.ts +32 -0
  85. package/dist/runtime/components/prose/Prompt.vue +88 -0
  86. package/dist/runtime/components/prose/Prompt.vue.d.ts +32 -0
  87. package/dist/runtime/composables/index.d.ts +1 -0
  88. package/dist/runtime/composables/index.js +1 -0
  89. package/dist/runtime/composables/useContentSearch.js +19 -5
  90. package/dist/runtime/composables/useEditorMenu.d.ts +5 -0
  91. package/dist/runtime/composables/useEditorMenu.js +3 -1
  92. package/dist/runtime/composables/useFieldGroup.d.ts +3 -0
  93. package/dist/runtime/composables/useFieldGroup.js +11 -1
  94. package/dist/runtime/composables/useResolvedVariants.d.ts +21 -0
  95. package/dist/runtime/composables/useResolvedVariants.js +14 -0
  96. package/dist/runtime/locale/ar.js +9 -0
  97. package/dist/runtime/locale/az.js +9 -0
  98. package/dist/runtime/locale/be.js +9 -0
  99. package/dist/runtime/locale/bg.js +9 -0
  100. package/dist/runtime/locale/bn.js +9 -0
  101. package/dist/runtime/locale/ca.js +9 -0
  102. package/dist/runtime/locale/ckb.js +10 -1
  103. package/dist/runtime/locale/cs.js +9 -0
  104. package/dist/runtime/locale/da.js +9 -0
  105. package/dist/runtime/locale/de.js +9 -0
  106. package/dist/runtime/locale/de_ch.js +9 -0
  107. package/dist/runtime/locale/el.js +9 -0
  108. package/dist/runtime/locale/en.js +10 -1
  109. package/dist/runtime/locale/es.js +9 -0
  110. package/dist/runtime/locale/et.js +9 -0
  111. package/dist/runtime/locale/eu.js +11 -2
  112. package/dist/runtime/locale/fa_ir.js +9 -0
  113. package/dist/runtime/locale/fi.js +9 -0
  114. package/dist/runtime/locale/fr.js +9 -0
  115. package/dist/runtime/locale/gl.js +9 -0
  116. package/dist/runtime/locale/he.js +9 -0
  117. package/dist/runtime/locale/hi.js +9 -0
  118. package/dist/runtime/locale/hr.js +9 -0
  119. package/dist/runtime/locale/hu.js +9 -0
  120. package/dist/runtime/locale/hy.js +9 -0
  121. package/dist/runtime/locale/id.js +9 -0
  122. package/dist/runtime/locale/is.js +9 -0
  123. package/dist/runtime/locale/it.js +9 -0
  124. package/dist/runtime/locale/ja.js +9 -0
  125. package/dist/runtime/locale/ka.js +9 -0
  126. package/dist/runtime/locale/kk.js +9 -0
  127. package/dist/runtime/locale/km.js +9 -0
  128. package/dist/runtime/locale/ko.js +9 -0
  129. package/dist/runtime/locale/ky.js +9 -0
  130. package/dist/runtime/locale/lb.js +11 -2
  131. package/dist/runtime/locale/lo.js +15 -6
  132. package/dist/runtime/locale/lt.js +9 -0
  133. package/dist/runtime/locale/mn.js +9 -0
  134. package/dist/runtime/locale/ms.js +9 -0
  135. package/dist/runtime/locale/nb_no.js +9 -0
  136. package/dist/runtime/locale/nl.js +9 -0
  137. package/dist/runtime/locale/pl.js +9 -0
  138. package/dist/runtime/locale/pt.js +9 -0
  139. package/dist/runtime/locale/pt_br.js +9 -0
  140. package/dist/runtime/locale/ro.js +9 -0
  141. package/dist/runtime/locale/ru.js +9 -0
  142. package/dist/runtime/locale/sk.js +9 -0
  143. package/dist/runtime/locale/sl.js +9 -0
  144. package/dist/runtime/locale/sq.js +9 -0
  145. package/dist/runtime/locale/sv.js +9 -0
  146. package/dist/runtime/locale/th.js +9 -0
  147. package/dist/runtime/locale/tj.js +9 -0
  148. package/dist/runtime/locale/tr.js +9 -0
  149. package/dist/runtime/locale/ug_cn.js +9 -0
  150. package/dist/runtime/locale/uk.js +9 -0
  151. package/dist/runtime/locale/ur.js +9 -0
  152. package/dist/runtime/locale/uz.js +9 -0
  153. package/dist/runtime/locale/vi.js +9 -0
  154. package/dist/runtime/locale/zh_cn.js +9 -0
  155. package/dist/runtime/locale/zh_tw.js +9 -0
  156. package/dist/runtime/plugins/colors.js +1 -1
  157. package/dist/runtime/types/index.d.ts +1 -0
  158. package/dist/runtime/types/index.js +1 -0
  159. package/dist/runtime/types/locale.d.ts +9 -0
  160. package/dist/runtime/types/prose.d.ts +1 -0
  161. package/dist/runtime/types/prose.js +1 -0
  162. package/dist/runtime/vue/overrides/inertia/Link.vue +3 -3
  163. package/dist/runtime/vue/overrides/none/Link.vue +3 -2
  164. package/dist/runtime/vue/overrides/vue-router/Link.vue +27 -31
  165. package/dist/shared/{ui.DJUbBpE2.mjs → ui.BIQuJqNV.mjs} +186 -34
  166. package/dist/unplugin.mjs +1 -1
  167. package/dist/vite.mjs +1 -1
  168. package/package.json +48 -39
@@ -8,6 +8,7 @@ import { ContextMenu } from "reka-ui/namespaced";
8
8
  import { useForwardPropsEmits } from "reka-ui";
9
9
  import { reactiveOmit, createReusableTemplate } from "@vueuse/core";
10
10
  import { useAppConfig } from "#imports";
11
+ import { FieldGroupReset } from "../composables/useFieldGroup";
11
12
  import { useLocale } from "../composables/useLocale";
12
13
  import { usePortal } from "../composables/usePortal";
13
14
  import { omit, get, isArrayOfArray } from "../utils";
@@ -100,79 +101,81 @@ const groups = computed(
100
101
  </DefineItemTemplate>
101
102
 
102
103
  <ContextMenu.Portal v-bind="portalProps">
103
- <component :is="sub ? ContextMenu.SubContent : ContextMenu.Content" data-slot="content" :class="ui.content({ class: [uiOverride?.content, props.class] })" v-bind="contentProps">
104
- <slot name="content-top" :sub="sub ?? false" />
104
+ <FieldGroupReset>
105
+ <component :is="sub ? ContextMenu.SubContent : ContextMenu.Content" data-slot="content" :class="ui.content({ class: [uiOverride?.content, props.class] })" v-bind="contentProps">
106
+ <slot name="content-top" :sub="sub ?? false" />
105
107
 
106
- <div role="presentation" data-slot="viewport" :class="ui.viewport({ class: uiOverride?.viewport })">
107
- <ContextMenu.Group v-for="(group, groupIndex) in groups" :key="`group-${groupIndex}`" data-slot="group" :class="ui.group({ class: uiOverride?.group })">
108
- <template v-for="(item, index) in group" :key="`group-${groupIndex}-${index}`">
109
- <ContextMenu.Label v-if="item.type === 'label'" data-slot="label" :class="ui.label({ class: [uiOverride?.label, item.ui?.label, item.class] })">
110
- <ReuseItemTemplate :item="item" :index="index" />
111
- </ContextMenu.Label>
112
- <ContextMenu.Separator v-else-if="item.type === 'separator'" data-slot="separator" :class="ui.separator({ class: [uiOverride?.separator, item.ui?.separator, item.class] })" />
113
- <ContextMenu.Sub v-else-if="item?.children?.length" :open="item.open" :default-open="item.defaultOpen">
114
- <ContextMenu.SubTrigger
115
- as="button"
116
- type="button"
117
- :disabled="item.disabled"
118
- :text-value="get(item, props.labelKey)"
119
- data-slot="item"
120
- :class="ui.item({ class: [uiOverride?.item, item.ui?.item, item.class], color: item?.color })"
121
- >
108
+ <div role="presentation" data-slot="viewport" :class="ui.viewport({ class: uiOverride?.viewport })">
109
+ <ContextMenu.Group v-for="(group, groupIndex) in groups" :key="`group-${groupIndex}`" data-slot="group" :class="ui.group({ class: uiOverride?.group })">
110
+ <template v-for="(item, index) in group" :key="`group-${groupIndex}-${index}`">
111
+ <ContextMenu.Label v-if="item.type === 'label'" data-slot="label" :class="ui.label({ class: [uiOverride?.label, item.ui?.label, item.class] })">
122
112
  <ReuseItemTemplate :item="item" :index="index" />
123
- </ContextMenu.SubTrigger>
113
+ </ContextMenu.Label>
114
+ <ContextMenu.Separator v-else-if="item.type === 'separator'" data-slot="separator" :class="ui.separator({ class: [uiOverride?.separator, item.ui?.separator, item.class] })" />
115
+ <ContextMenu.Sub v-else-if="item?.children?.length" :open="item.open" :default-open="item.defaultOpen">
116
+ <ContextMenu.SubTrigger
117
+ as="button"
118
+ type="button"
119
+ :disabled="item.disabled"
120
+ :text-value="get(item, props.labelKey)"
121
+ data-slot="item"
122
+ :class="ui.item({ class: [uiOverride?.item, item.ui?.item, item.class], color: item?.color })"
123
+ >
124
+ <ReuseItemTemplate :item="item" :index="index" />
125
+ </ContextMenu.SubTrigger>
124
126
 
125
- <UContextMenuContent
126
- sub
127
- :class="item.ui?.content"
128
- :ui="ui"
129
- :ui-override="uiOverride"
130
- :portal="portal"
131
- :items="item.children"
132
- :align-offset="-4"
133
- :label-key="labelKey"
134
- :description-key="descriptionKey"
135
- :checked-icon="checkedIcon"
136
- :loading-icon="loadingIcon"
137
- :external-icon="externalIcon"
138
- v-bind="item.content"
139
- >
140
- <template v-for="(_, name) in getProxySlots()" #[name]="slotData">
141
- <slot :name="name" v-bind="slotData" />
142
- </template>
143
- </UContextMenuContent>
144
- </ContextMenu.Sub>
145
- <ContextMenu.CheckboxItem
146
- v-else-if="item.type === 'checkbox'"
147
- :model-value="item.checked"
148
- :disabled="item.disabled"
149
- :text-value="get(item, props.labelKey)"
150
- data-slot="item"
151
- :class="ui.item({ class: [uiOverride?.item, item.ui?.item, item.class], color: item?.color })"
152
- @update:model-value="item.onUpdateChecked"
153
- @select="item.onSelect"
154
- >
155
- <ReuseItemTemplate :item="item" :index="index" />
156
- </ContextMenu.CheckboxItem>
157
- <ULink v-else v-slot="{ active, ...slotProps }" v-bind="pickLinkProps(item)" custom>
158
- <ContextMenu.Item
159
- as-child
127
+ <UContextMenuContent
128
+ sub
129
+ :class="item.ui?.content"
130
+ :ui="ui"
131
+ :ui-override="uiOverride"
132
+ :portal="portal"
133
+ :items="item.children"
134
+ :align-offset="-4"
135
+ :label-key="labelKey"
136
+ :description-key="descriptionKey"
137
+ :checked-icon="checkedIcon"
138
+ :loading-icon="loadingIcon"
139
+ :external-icon="externalIcon"
140
+ v-bind="item.content"
141
+ >
142
+ <template v-for="(_, name) in getProxySlots()" #[name]="slotData">
143
+ <slot :name="name" v-bind="slotData" />
144
+ </template>
145
+ </UContextMenuContent>
146
+ </ContextMenu.Sub>
147
+ <ContextMenu.CheckboxItem
148
+ v-else-if="item.type === 'checkbox'"
149
+ :model-value="item.checked"
160
150
  :disabled="item.disabled"
161
151
  :text-value="get(item, props.labelKey)"
152
+ data-slot="item"
153
+ :class="ui.item({ class: [uiOverride?.item, item.ui?.item, item.class], color: item?.color })"
154
+ @update:model-value="item.onUpdateChecked"
162
155
  @select="item.onSelect"
163
156
  >
164
- <ULinkBase v-bind="slotProps" data-slot="item" :class="ui.item({ class: [uiOverride?.item, item.ui?.item, item.class], active, color: item?.color })">
165
- <ReuseItemTemplate :item="item" :active="active" :index="index" />
166
- </ULinkBase>
167
- </ContextMenu.Item>
168
- </ULink>
169
- </template>
170
- </ContextMenu.Group>
171
- </div>
157
+ <ReuseItemTemplate :item="item" :index="index" />
158
+ </ContextMenu.CheckboxItem>
159
+ <ULink v-else v-slot="{ active, ...slotProps }" v-bind="pickLinkProps(item)" custom>
160
+ <ContextMenu.Item
161
+ as-child
162
+ :disabled="item.disabled"
163
+ :text-value="get(item, props.labelKey)"
164
+ @select="item.onSelect"
165
+ >
166
+ <ULinkBase v-bind="slotProps" data-slot="item" :class="ui.item({ class: [uiOverride?.item, item.ui?.item, item.class], active, color: item?.color })">
167
+ <ReuseItemTemplate :item="item" :active="active" :index="index" />
168
+ </ULinkBase>
169
+ </ContextMenu.Item>
170
+ </ULink>
171
+ </template>
172
+ </ContextMenu.Group>
173
+ </div>
172
174
 
173
- <slot />
175
+ <slot />
174
176
 
175
- <slot name="content-bottom" :sub="sub ?? false" />
176
- </component>
177
+ <slot name="content-bottom" :sub="sub ?? false" />
178
+ </component>
179
+ </FieldGroupReset>
177
180
  </ContextMenu.Portal>
178
181
  </template>
@@ -1,39 +1,14 @@
1
1
  import type { VNode } from 'vue';
2
2
  import type { AppConfig } from '@nuxt/schema';
3
- import type { UseFuseOptions } from '@vueuse/integrations/useFuse';
4
3
  import theme from '#build/ui/dashboard-search';
5
- import type { ButtonProps, InputProps, ModalProps, CommandPaletteProps, CommandPaletteSlots, CommandPaletteGroup, CommandPaletteItem, IconProps, LinkPropsKeys } from '../types';
4
+ import type { ButtonProps, ModalProps, CommandPaletteProps, CommandPaletteSlots, CommandPaletteGroup, CommandPaletteItem, LinkPropsKeys } from '../types';
6
5
  import type { ComponentConfig } from '../types/tv';
7
6
  type DashboardSearch = ComponentConfig<typeof theme, AppConfig, 'dashboardSearch'>;
8
- export interface DashboardSearchProps<T extends CommandPaletteItem = CommandPaletteItem> extends Pick<ModalProps, 'title' | 'description' | 'overlay' | 'transition' | 'content' | 'dismissible' | 'fullscreen' | 'modal' | 'portal'> {
7
+ export interface DashboardSearchProps<T extends CommandPaletteItem = CommandPaletteItem> extends Pick<ModalProps, 'title' | 'description' | 'overlay' | 'transition' | 'content' | 'dismissible' | 'fullscreen' | 'modal' | 'portal'>, Pick<CommandPaletteProps<CommandPaletteGroup<T>, T>, 'icon' | 'placeholder' | 'autofocus' | 'loading' | 'loadingIcon' | 'closeIcon' | 'groups' | 'fuse'> {
9
8
  /**
10
9
  * @defaultValue 'md'
11
10
  */
12
11
  size?: DashboardSearch['variants']['size'];
13
- /**
14
- * The icon displayed in the input.
15
- * @defaultValue appConfig.ui.icons.search
16
- * @IconifyIcon
17
- */
18
- icon?: IconProps['name'];
19
- /**
20
- * The placeholder text for the input.
21
- * @defaultValue t('commandPalette.placeholder')
22
- */
23
- placeholder?: InputProps['placeholder'];
24
- /**
25
- * Automatically focus the input when component is mounted.
26
- * @defaultValue true
27
- */
28
- autofocus?: boolean;
29
- /** When `true`, the loading icon will be displayed. */
30
- loading?: boolean;
31
- /**
32
- * The icon when the `loading` prop is `true`.
33
- * @defaultValue appConfig.ui.icons.loading
34
- * @IconifyIcon
35
- */
36
- loadingIcon?: IconProps['name'];
37
12
  /**
38
13
  * Display a close button in the input (useful when inside a Modal for example).
39
14
  * `{ size: 'md', color: 'neutral', variant: 'ghost' }`{lang="ts-type"}
@@ -41,23 +16,18 @@ export interface DashboardSearchProps<T extends CommandPaletteItem = CommandPale
41
16
  * @defaultValue true
42
17
  */
43
18
  close?: boolean | Omit<ButtonProps, LinkPropsKeys>;
44
- /**
45
- * The icon displayed in the close button.
46
- * @defaultValue appConfig.ui.icons.close
47
- * @IconifyIcon
48
- */
49
- closeIcon?: IconProps['name'];
50
19
  /**
51
20
  * Keyboard shortcut to open the search (used by [`defineShortcuts`](https://ui.nuxt.com/docs/composables/define-shortcuts))
52
21
  * @defaultValue 'meta_k'
53
22
  */
54
23
  shortcut?: string;
55
- groups?: CommandPaletteGroup<T>[];
56
24
  /**
57
- * Options for [useFuse](https://vueuse.org/integrations/useFuse) passed to the [CommandPalette](https://ui.nuxt.com/docs/components/command-palette).
58
- * @defaultValue {}
25
+ * Delay (in milliseconds) before the search term is passed to Fuse (debounced).
26
+ * Useful for large datasets where running fuzzy search on every keystroke is the bottleneck — the input stays responsive while Fuse only re-runs after typing settles.
27
+ * Set to `0` to disable.
28
+ * @defaultValue 100
59
29
  */
60
- fuse?: UseFuseOptions<T>;
30
+ searchDelay?: number;
61
31
  /**
62
32
  * When `true`, the theme command will be added to the groups.
63
33
  * @defaultValue true
@@ -90,6 +60,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<Dashbo
90
60
  }>, {
91
61
  close: boolean | Omit<ButtonProps, LinkPropsKeys>;
92
62
  colorMode: boolean;
63
+ searchDelay: number;
93
64
  fullscreen: boolean;
94
65
  shortcut: string;
95
66
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, DashboardSearchSlots>;
@@ -16,16 +16,9 @@ import UCommandPalette from "./CommandPalette.vue";
16
16
  import UModal from "./Modal.vue";
17
17
  const props = defineProps({
18
18
  size: { type: null, required: false },
19
- icon: { type: null, required: false },
20
- placeholder: { type: String, required: false },
21
- autofocus: { type: Boolean, required: false },
22
- loading: { type: Boolean, required: false },
23
- loadingIcon: { type: null, required: false },
24
19
  close: { type: [Boolean, Object], required: false, default: true },
25
- closeIcon: { type: null, required: false },
26
20
  shortcut: { type: String, required: false, default: "meta_k" },
27
- groups: { type: Array, required: false },
28
- fuse: { type: Object, required: false },
21
+ searchDelay: { type: Number, required: false, default: 100 },
29
22
  colorMode: { type: Boolean, required: false, default: true },
30
23
  class: { type: null, required: false },
31
24
  ui: { type: Object, required: false },
@@ -37,7 +30,15 @@ const props = defineProps({
37
30
  dismissible: { type: Boolean, required: false },
38
31
  fullscreen: { type: Boolean, required: false, default: false },
39
32
  modal: { type: Boolean, required: false },
40
- portal: { type: [Boolean, String], required: false, skipCheck: true }
33
+ portal: { type: [Boolean, String], required: false, skipCheck: true },
34
+ icon: { type: null, required: false },
35
+ placeholder: { type: String, required: false },
36
+ autofocus: { type: Boolean, required: false },
37
+ loading: { type: Boolean, required: false },
38
+ loadingIcon: { type: null, required: false },
39
+ closeIcon: { type: null, required: false },
40
+ groups: { type: Array, required: false },
41
+ fuse: { type: Object, required: false }
41
42
  });
42
43
  const slots = defineSlots();
43
44
  const open = defineModel("open", { type: Boolean, ...{ default: false } });
@@ -49,7 +50,7 @@ const { t } = useLocale();
49
50
  const colorMode = useColorMode();
50
51
  const appConfig = useAppConfig();
51
52
  const uiProp = useComponentUI("dashboardSearch", props);
52
- const commandPaletteProps = useForwardProps(reactivePick(props, "size", "icon", "placeholder", "autofocus", "loading", "loadingIcon", "close", "closeIcon"));
53
+ const commandPaletteProps = useForwardProps(reactivePick(props, "size", "icon", "placeholder", "autofocus", "loading", "loadingIcon", "close", "closeIcon", "searchDelay"));
53
54
  const modalProps = useForwardProps(reactivePick(props, "overlay", "transition", "content", "dismissible", "fullscreen", "modal", "portal"));
54
55
  const getProxySlots = () => omit(slots, ["content"]);
55
56
  const fuse = computed(() => defu({}, props.fuse, {
@@ -1,39 +1,14 @@
1
1
  import type { VNode } from 'vue';
2
2
  import type { AppConfig } from '@nuxt/schema';
3
- import type { UseFuseOptions } from '@vueuse/integrations/useFuse';
4
3
  import theme from '#build/ui/dashboard-search';
5
- import type { ButtonProps, InputProps, ModalProps, CommandPaletteProps, CommandPaletteSlots, CommandPaletteGroup, CommandPaletteItem, IconProps, LinkPropsKeys } from '../types';
4
+ import type { ButtonProps, ModalProps, CommandPaletteProps, CommandPaletteSlots, CommandPaletteGroup, CommandPaletteItem, LinkPropsKeys } from '../types';
6
5
  import type { ComponentConfig } from '../types/tv';
7
6
  type DashboardSearch = ComponentConfig<typeof theme, AppConfig, 'dashboardSearch'>;
8
- export interface DashboardSearchProps<T extends CommandPaletteItem = CommandPaletteItem> extends Pick<ModalProps, 'title' | 'description' | 'overlay' | 'transition' | 'content' | 'dismissible' | 'fullscreen' | 'modal' | 'portal'> {
7
+ export interface DashboardSearchProps<T extends CommandPaletteItem = CommandPaletteItem> extends Pick<ModalProps, 'title' | 'description' | 'overlay' | 'transition' | 'content' | 'dismissible' | 'fullscreen' | 'modal' | 'portal'>, Pick<CommandPaletteProps<CommandPaletteGroup<T>, T>, 'icon' | 'placeholder' | 'autofocus' | 'loading' | 'loadingIcon' | 'closeIcon' | 'groups' | 'fuse'> {
9
8
  /**
10
9
  * @defaultValue 'md'
11
10
  */
12
11
  size?: DashboardSearch['variants']['size'];
13
- /**
14
- * The icon displayed in the input.
15
- * @defaultValue appConfig.ui.icons.search
16
- * @IconifyIcon
17
- */
18
- icon?: IconProps['name'];
19
- /**
20
- * The placeholder text for the input.
21
- * @defaultValue t('commandPalette.placeholder')
22
- */
23
- placeholder?: InputProps['placeholder'];
24
- /**
25
- * Automatically focus the input when component is mounted.
26
- * @defaultValue true
27
- */
28
- autofocus?: boolean;
29
- /** When `true`, the loading icon will be displayed. */
30
- loading?: boolean;
31
- /**
32
- * The icon when the `loading` prop is `true`.
33
- * @defaultValue appConfig.ui.icons.loading
34
- * @IconifyIcon
35
- */
36
- loadingIcon?: IconProps['name'];
37
12
  /**
38
13
  * Display a close button in the input (useful when inside a Modal for example).
39
14
  * `{ size: 'md', color: 'neutral', variant: 'ghost' }`{lang="ts-type"}
@@ -41,23 +16,18 @@ export interface DashboardSearchProps<T extends CommandPaletteItem = CommandPale
41
16
  * @defaultValue true
42
17
  */
43
18
  close?: boolean | Omit<ButtonProps, LinkPropsKeys>;
44
- /**
45
- * The icon displayed in the close button.
46
- * @defaultValue appConfig.ui.icons.close
47
- * @IconifyIcon
48
- */
49
- closeIcon?: IconProps['name'];
50
19
  /**
51
20
  * Keyboard shortcut to open the search (used by [`defineShortcuts`](https://ui.nuxt.com/docs/composables/define-shortcuts))
52
21
  * @defaultValue 'meta_k'
53
22
  */
54
23
  shortcut?: string;
55
- groups?: CommandPaletteGroup<T>[];
56
24
  /**
57
- * Options for [useFuse](https://vueuse.org/integrations/useFuse) passed to the [CommandPalette](https://ui.nuxt.com/docs/components/command-palette).
58
- * @defaultValue {}
25
+ * Delay (in milliseconds) before the search term is passed to Fuse (debounced).
26
+ * Useful for large datasets where running fuzzy search on every keystroke is the bottleneck — the input stays responsive while Fuse only re-runs after typing settles.
27
+ * Set to `0` to disable.
28
+ * @defaultValue 100
59
29
  */
60
- fuse?: UseFuseOptions<T>;
30
+ searchDelay?: number;
61
31
  /**
62
32
  * When `true`, the theme command will be added to the groups.
63
33
  * @defaultValue true
@@ -90,6 +60,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<Dashbo
90
60
  }>, {
91
61
  close: boolean | Omit<ButtonProps, LinkPropsKeys>;
92
62
  colorMode: boolean;
63
+ searchDelay: number;
93
64
  fullscreen: boolean;
94
65
  shortcut: string;
95
66
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, DashboardSearchSlots>;
@@ -72,11 +72,7 @@ const Menu = computed(() => ({
72
72
  modal: UModal,
73
73
  drawer: UDrawer
74
74
  })[props.mode]);
75
- const menuProps = toRef(() => defu(props.menu, {
76
- content: {
77
- onOpenAutoFocus: (e) => e.preventDefault()
78
- }
79
- }, props.mode === "modal" ? { fullscreen: true, transition: false } : props.mode === "slideover" ? { side: "left" } : {}));
75
+ const menuProps = toRef(() => defu(props.menu, {}, props.mode === "modal" ? { fullscreen: true, transition: false } : props.mode === "slideover" ? { side: "left" } : {}));
80
76
  function toggleOpen() {
81
77
  open.value = !open.value;
82
78
  }
@@ -9,6 +9,7 @@ import { DrawerRoot, DrawerRootNested, DrawerTrigger, DrawerPortal, DrawerOverla
9
9
  import { reactivePick } from "@vueuse/core";
10
10
  import { useAppConfig } from "#imports";
11
11
  import { useComponentUI } from "../composables/useComponentUI";
12
+ import { FieldGroupReset } from "../composables/useFieldGroup";
12
13
  import { usePortal } from "../composables/usePortal";
13
14
  import { pointerDownOutside } from "../utils/overlay";
14
15
  import { tv } from "../utils/tv";
@@ -76,55 +77,57 @@ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.drawer || {}
76
77
  </DrawerTrigger>
77
78
 
78
79
  <DrawerPortal v-bind="portalProps">
79
- <DrawerOverlay v-if="overlay" data-slot="overlay" :class="ui.overlay({ class: uiProp?.overlay })" />
80
+ <FieldGroupReset>
81
+ <DrawerOverlay v-if="overlay" data-slot="overlay" :class="ui.overlay({ class: uiProp?.overlay })" />
80
82
 
81
- <DrawerContent data-slot="content" :class="ui.content({ class: [!slots.default && props.class, uiProp?.content] })" v-bind="contentProps" v-on="contentEvents">
82
- <DrawerHandle v-if="handle" data-slot="handle" :class="ui.handle({ class: uiProp?.handle })" />
83
+ <DrawerContent data-slot="content" :class="ui.content({ class: [!slots.default && props.class, uiProp?.content] })" v-bind="contentProps" v-on="contentEvents">
84
+ <DrawerHandle v-if="handle" data-slot="handle" :class="ui.handle({ class: uiProp?.handle })" />
83
85
 
84
- <VisuallyHidden v-if="!title && !slots.title || !description && !slots.description || !!slots.content">
85
- <DrawerTitle v-if="!title && !slots.title" />
86
- <DrawerTitle v-else-if="!!slots.content">
87
- <slot name="title">
88
- {{ title }}
89
- </slot>
90
- </DrawerTitle>
86
+ <VisuallyHidden v-if="!title && !slots.title || !description && !slots.description || !!slots.content">
87
+ <DrawerTitle v-if="!title && !slots.title" />
88
+ <DrawerTitle v-else-if="!!slots.content">
89
+ <slot name="title">
90
+ {{ title }}
91
+ </slot>
92
+ </DrawerTitle>
91
93
 
92
- <DrawerDescription v-if="!description && !slots.description" />
93
- <DrawerDescription v-else-if="!!slots.content">
94
- <slot name="description">
95
- {{ description }}
96
- </slot>
97
- </DrawerDescription>
98
- </VisuallyHidden>
94
+ <DrawerDescription v-if="!description && !slots.description" />
95
+ <DrawerDescription v-else-if="!!slots.content">
96
+ <slot name="description">
97
+ {{ description }}
98
+ </slot>
99
+ </DrawerDescription>
100
+ </VisuallyHidden>
99
101
 
100
- <slot name="content">
101
- <div data-slot="container" :class="ui.container({ class: uiProp?.container })">
102
- <div v-if="!!slots.header || (title || !!slots.title) || (description || !!slots.description)" data-slot="header" :class="ui.header({ class: uiProp?.header })">
103
- <slot name="header">
104
- <DrawerTitle v-if="title || !!slots.title" data-slot="title" :class="ui.title({ class: uiProp?.title })">
105
- <slot name="title">
106
- {{ title }}
107
- </slot>
108
- </DrawerTitle>
102
+ <slot name="content">
103
+ <div data-slot="container" :class="ui.container({ class: uiProp?.container })">
104
+ <div v-if="!!slots.header || (title || !!slots.title) || (description || !!slots.description)" data-slot="header" :class="ui.header({ class: uiProp?.header })">
105
+ <slot name="header">
106
+ <DrawerTitle v-if="title || !!slots.title" data-slot="title" :class="ui.title({ class: uiProp?.title })">
107
+ <slot name="title">
108
+ {{ title }}
109
+ </slot>
110
+ </DrawerTitle>
109
111
 
110
- <DrawerDescription v-if="description || !!slots.description" data-slot="description" :class="ui.description({ class: uiProp?.description })">
111
- <slot name="description">
112
- {{ description }}
113
- </slot>
114
- </DrawerDescription>
115
- </slot>
116
- </div>
112
+ <DrawerDescription v-if="description || !!slots.description" data-slot="description" :class="ui.description({ class: uiProp?.description })">
113
+ <slot name="description">
114
+ {{ description }}
115
+ </slot>
116
+ </DrawerDescription>
117
+ </slot>
118
+ </div>
117
119
 
118
- <div v-if="!!slots.body" data-slot="body" :class="ui.body({ class: uiProp?.body })">
119
- <slot name="body" />
120
- </div>
120
+ <div v-if="!!slots.body" data-slot="body" :class="ui.body({ class: uiProp?.body })">
121
+ <slot name="body" />
122
+ </div>
121
123
 
122
- <div v-if="!!slots.footer" data-slot="footer" :class="ui.footer({ class: uiProp?.footer })">
123
- <slot name="footer" />
124
+ <div v-if="!!slots.footer" data-slot="footer" :class="ui.footer({ class: uiProp?.footer })">
125
+ <slot name="footer" />
126
+ </div>
124
127
  </div>
125
- </div>
126
- </slot>
127
- </DrawerContent>
128
+ </slot>
129
+ </DrawerContent>
130
+ </FieldGroupReset>
128
131
  </DrawerPortal>
129
132
  </component>
130
133
  </template>