@nuxt/ui 4.8.2 → 4.9.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 (82) hide show
  1. package/dist/module.d.mts +7 -0
  2. package/dist/module.json +1 -1
  3. package/dist/module.mjs +2 -2
  4. package/dist/runtime/components/Avatar.vue +1 -1
  5. package/dist/runtime/components/Banner.vue +0 -1
  6. package/dist/runtime/components/BlogPost.vue +8 -10
  7. package/dist/runtime/components/Calendar.d.vue.ts +40 -4
  8. package/dist/runtime/components/Calendar.vue +179 -61
  9. package/dist/runtime/components/Calendar.vue.d.ts +40 -4
  10. package/dist/runtime/components/ChatMessages.d.vue.ts +7 -3
  11. package/dist/runtime/components/ChatMessages.vue +4 -1
  12. package/dist/runtime/components/ChatMessages.vue.d.ts +7 -3
  13. package/dist/runtime/components/ChatPrompt.vue +8 -2
  14. package/dist/runtime/components/ChatPromptSubmit.d.vue.ts +2 -2
  15. package/dist/runtime/components/ChatPromptSubmit.vue +2 -2
  16. package/dist/runtime/components/ChatPromptSubmit.vue.d.ts +2 -2
  17. package/dist/runtime/components/CommandPalette.d.vue.ts +2 -2
  18. package/dist/runtime/components/CommandPalette.vue +10 -4
  19. package/dist/runtime/components/CommandPalette.vue.d.ts +2 -2
  20. package/dist/runtime/components/DashboardSearch.d.vue.ts +7 -1
  21. package/dist/runtime/components/DashboardSearch.vue +9 -2
  22. package/dist/runtime/components/DashboardSearch.vue.d.ts +7 -1
  23. package/dist/runtime/components/DashboardSearchButton.d.vue.ts +2 -2
  24. package/dist/runtime/components/DashboardSearchButton.vue +2 -2
  25. package/dist/runtime/components/DashboardSearchButton.vue.d.ts +2 -2
  26. package/dist/runtime/components/FileUpload.d.vue.ts +5 -2
  27. package/dist/runtime/components/FileUpload.vue +8 -6
  28. package/dist/runtime/components/FileUpload.vue.d.ts +5 -2
  29. package/dist/runtime/components/Link.d.vue.ts +1 -0
  30. package/dist/runtime/components/Link.vue +1 -1
  31. package/dist/runtime/components/Link.vue.d.ts +1 -0
  32. package/dist/runtime/components/Modal.d.vue.ts +6 -0
  33. package/dist/runtime/components/Modal.vue +3 -1
  34. package/dist/runtime/components/Modal.vue.d.ts +6 -0
  35. package/dist/runtime/components/PinInput.d.vue.ts +14 -2
  36. package/dist/runtime/components/PinInput.vue +36 -11
  37. package/dist/runtime/components/PinInput.vue.d.ts +14 -2
  38. package/dist/runtime/components/Popover.d.vue.ts +2 -0
  39. package/dist/runtime/components/Popover.vue +2 -2
  40. package/dist/runtime/components/Popover.vue.d.ts +2 -0
  41. package/dist/runtime/components/ScrollArea.d.vue.ts +8 -0
  42. package/dist/runtime/components/ScrollArea.vue +10 -0
  43. package/dist/runtime/components/ScrollArea.vue.d.ts +8 -0
  44. package/dist/runtime/components/Select.vue +8 -1
  45. package/dist/runtime/components/SelectMenu.vue +11 -4
  46. package/dist/runtime/components/Sidebar.d.vue.ts +5 -0
  47. package/dist/runtime/components/Sidebar.vue +3 -1
  48. package/dist/runtime/components/Sidebar.vue.d.ts +5 -0
  49. package/dist/runtime/components/Slideover.d.vue.ts +6 -0
  50. package/dist/runtime/components/Slideover.vue +3 -1
  51. package/dist/runtime/components/Slideover.vue.d.ts +6 -0
  52. package/dist/runtime/components/content/ContentSearch.d.vue.ts +7 -1
  53. package/dist/runtime/components/content/ContentSearch.vue +9 -2
  54. package/dist/runtime/components/content/ContentSearch.vue.d.ts +7 -1
  55. package/dist/runtime/components/content/ContentSearchButton.d.vue.ts +2 -2
  56. package/dist/runtime/components/content/ContentSearchButton.vue +2 -2
  57. package/dist/runtime/components/content/ContentSearchButton.vue.d.ts +2 -2
  58. package/dist/runtime/components/prose/Kbd.d.vue.ts +2 -1
  59. package/dist/runtime/components/prose/Kbd.vue.d.ts +2 -1
  60. package/dist/runtime/components/prose/Pre.vue +0 -1
  61. package/dist/runtime/composables/index.d.ts +1 -0
  62. package/dist/runtime/composables/index.js +1 -0
  63. package/dist/runtime/composables/useComponentProps.d.ts +3 -3
  64. package/dist/runtime/composables/useTour.d.ts +80 -0
  65. package/dist/runtime/composables/useTour.js +102 -0
  66. package/dist/runtime/index.css +1 -1
  67. package/dist/runtime/keyframes.css +1 -1
  68. package/dist/runtime/locale/index.d.ts +1 -0
  69. package/dist/runtime/locale/index.js +1 -0
  70. package/dist/runtime/locale/lv.d.ts +3 -0
  71. package/dist/runtime/locale/lv.js +152 -0
  72. package/dist/runtime/plugins/colors.js +5 -4
  73. package/dist/runtime/types/tv.d.ts +15 -3
  74. package/dist/runtime/utils/tv.d.ts +41 -1
  75. package/dist/runtime/utils/tv.js +91 -2
  76. package/dist/runtime/vue/stubs/base.d.ts +1 -1
  77. package/dist/runtime/vue/stubs/base.js +1 -1
  78. package/dist/shared/{ui.C-lVg1QQ.mjs → ui.BfHSFiIO.mjs} +375 -232
  79. package/dist/unplugin.d.mts +8 -0
  80. package/dist/unplugin.mjs +2 -2
  81. package/dist/vite.mjs +1 -1
  82. package/package.json +57 -40
@@ -183,6 +183,9 @@ onMounted(() => {
183
183
  }, { childList: true, subtree: true });
184
184
  }
185
185
  });
186
+ defineExpose({
187
+ registerMessageRef
188
+ });
186
189
  </script>
187
190
 
188
191
  <template>
@@ -193,7 +196,7 @@ onMounted(() => {
193
196
  :class="ui.root({ class: [props.ui?.root, props.class] })"
194
197
  :style="{ '--last-message-height': `${lastMessageHeight}px` }"
195
198
  >
196
- <slot>
199
+ <slot :register-message-ref="registerMessageRef">
197
200
  <template v-for="message in props.messages" :key="message.id">
198
201
  <UChatMessage
199
202
  v-if="message.parts?.length"
@@ -1,4 +1,4 @@
1
- import type { VNode } from 'vue';
1
+ import type { ComponentPublicInstance, VNode } from 'vue';
2
2
  import type { AppConfig } from '@nuxt/schema';
3
3
  import type { UIDataTypes, UIMessage, UITools, ChatStatus } from 'ai';
4
4
  import theme from '#build/ui/chat-messages';
@@ -57,7 +57,9 @@ export interface ChatMessagesProps<T extends UIMessage[] = UIMessage[]> {
57
57
  ui?: ChatMessages['slots'];
58
58
  }
59
59
  export type ChatMessagesSlots<T extends UIMessage[] = UIMessage[]> = {
60
- default?(props?: {}): VNode[];
60
+ default?(props: {
61
+ registerMessageRef: (id: string, element: ComponentPublicInstance | null) => void;
62
+ }): VNode[];
61
63
  indicator?(props: {
62
64
  ui: ChatMessages['ui'];
63
65
  }): VNode[];
@@ -76,7 +78,9 @@ declare const __VLS_export: <T extends UIMessage[] = UIMessage[]>(__VLS_props: N
76
78
  props: import("vue").PublicProps & __VLS_PrettifyLocal<ChatMessagesProps<T>> & (typeof globalThis extends {
77
79
  __VLS_PROPS_FALLBACK: infer P;
78
80
  } ? P : {});
79
- expose: (exposed: {}) => void;
81
+ expose: (exposed: import("vue").ShallowUnwrapRef<{
82
+ registerMessageRef: (id: string, element: ComponentPublicInstance | null) => void;
83
+ }>) => void;
80
84
  attrs: any;
81
85
  slots: ChatMessagesSlots<T>;
82
86
  emit: {};
@@ -68,6 +68,13 @@ function handleEnter(event) {
68
68
  }
69
69
  onEnter(event);
70
70
  }
71
+ function onKeydown(event) {
72
+ if (event.key === "Enter") {
73
+ handleEnter(event);
74
+ } else if (event.key === "Escape") {
75
+ blur(event);
76
+ }
77
+ }
71
78
  defineExpose({
72
79
  textareaRef: toRef(() => textareaRef.value?.textareaRef)
73
80
  });
@@ -90,9 +97,8 @@ defineExpose({
90
97
  :ui="transformUI(omit(ui, ['root', 'body', 'header', 'footer']), props.ui)"
91
98
  data-slot="body"
92
99
  :class="ui.body({ class: props.ui?.body })"
93
- @keydown.enter="handleEnter"
100
+ @keydown="onKeydown"
94
101
  @compositionend="onCompositionEnd"
95
- @keydown.esc="blur"
96
102
  >
97
103
  <template v-for="(_, name) in getProxySlots()" #[name]="slotData">
98
104
  <slot :name="name" v-bind="slotData" />
@@ -7,11 +7,11 @@ type ChatPromptSubmit = ComponentConfig<typeof theme, AppConfig, 'chatPromptSubm
7
7
  export interface ChatPromptSubmitProps extends Omit<ButtonProps, LinkPropsKeys | 'icon' | 'color' | 'variant'> {
8
8
  status?: ChatStatus;
9
9
  /**
10
- * The icon displayed in the button when the status is `ready`.
10
+ * The icon displayed in the button when the status is `ready`. Set to `false` to hide the icon.
11
11
  * @defaultValue appConfig.ui.icons.arrowUp
12
12
  * @IconifyIcon
13
13
  */
14
- icon?: IconProps['name'];
14
+ icon?: IconProps['name'] | false;
15
15
  /**
16
16
  * The color of the button when the status is `ready`.
17
17
  * @defaultValue 'primary'
@@ -15,7 +15,7 @@ import UButton from "./Button.vue";
15
15
  defineOptions({ inheritAttrs: false });
16
16
  const _props = defineProps({
17
17
  status: { type: String, required: false, default: "ready" },
18
- icon: { type: null, required: false },
18
+ icon: { type: [String, Boolean], required: false, skipCheck: true },
19
19
  color: { type: null, required: false },
20
20
  variant: { type: null, required: false },
21
21
  streamingIcon: { type: null, required: false },
@@ -59,7 +59,7 @@ const buttonProps = useForwardProps(reactiveOmit(props, "icon", "color", "varian
59
59
  const disabled = computed(() => props.status === "ready" ? props.disabled : false);
60
60
  const statusButtonProps = computed(() => ({
61
61
  ready: {
62
- icon: props.icon || appConfig.ui.icons.arrowUp,
62
+ icon: props.icon === false ? void 0 : props.icon ?? appConfig.ui.icons.arrowUp,
63
63
  color: props.color,
64
64
  variant: props.variant,
65
65
  type: "submit"
@@ -7,11 +7,11 @@ type ChatPromptSubmit = ComponentConfig<typeof theme, AppConfig, 'chatPromptSubm
7
7
  export interface ChatPromptSubmitProps extends Omit<ButtonProps, LinkPropsKeys | 'icon' | 'color' | 'variant'> {
8
8
  status?: ChatStatus;
9
9
  /**
10
- * The icon displayed in the button when the status is `ready`.
10
+ * The icon displayed in the button when the status is `ready`. Set to `false` to hide the icon.
11
11
  * @defaultValue appConfig.ui.icons.arrowUp
12
12
  * @IconifyIcon
13
13
  */
14
- icon?: IconProps['name'];
14
+ icon?: IconProps['name'] | false;
15
15
  /**
16
16
  * The color of the button when the status is `ready`.
17
17
  * @defaultValue 'primary'
@@ -64,11 +64,11 @@ export interface CommandPaletteProps<G extends CommandPaletteGroup<T> = CommandP
64
64
  */
65
65
  size?: CommandPalette['variants']['size'];
66
66
  /**
67
- * The icon displayed in the input.
67
+ * The icon displayed in the input. Set to `false` to hide the icon.
68
68
  * @defaultValue appConfig.ui.icons.search
69
69
  * @IconifyIcon
70
70
  */
71
- icon?: IconProps['name'];
71
+ icon?: IconProps['name'] | false;
72
72
  /**
73
73
  * The icon displayed on the right side of the input.
74
74
  * @defaultValue appConfig.ui.icons.search
@@ -29,7 +29,7 @@ defineOptions({ inheritAttrs: false });
29
29
  const _props = defineProps({
30
30
  as: { type: null, required: false },
31
31
  size: { type: null, required: false },
32
- icon: { type: null, required: false },
32
+ icon: { type: [String, Boolean], required: false, skipCheck: true },
33
33
  trailingIcon: { type: null, required: false },
34
34
  selectedIcon: { type: null, required: false },
35
35
  childrenIcon: { type: null, required: false },
@@ -199,7 +199,13 @@ const filteredItems = computed(() => filteredGroups.value.flatMap((group) => gro
199
199
  const rootRef = useTemplateRef("rootRef");
200
200
  watch(filteredGroups, () => {
201
201
  nextTick(() => {
202
- rootRef.value?.highlightFirstItem();
202
+ const root = rootRef.value;
203
+ const rootEl = root?.$el;
204
+ if (rootEl?.contains(document.activeElement)) {
205
+ root?.highlightFirstItem();
206
+ } else {
207
+ root?.highlightSelected(void 0, false);
208
+ }
203
209
  });
204
210
  });
205
211
  function navigate(item) {
@@ -317,13 +323,13 @@ function onSelect(e, item) {
317
323
  <UInput
318
324
  variant="none"
319
325
  :size="props.size"
320
- v-bind="typeof props.input === 'object' ? props.input : {}"
321
326
  :placeholder="placeholder"
322
327
  :autofocus="props.autofocus"
323
328
  :loading="props.loading"
324
329
  :loading-icon="props.loadingIcon"
325
330
  :trailing-icon="props.trailingIcon"
326
- :icon="props.icon || appConfig.ui.icons.search"
331
+ :icon="props.icon === false ? void 0 : props.icon ?? appConfig.ui.icons.search"
332
+ v-bind="typeof props.input === 'object' ? props.input : {}"
327
333
  data-slot="input"
328
334
  :class="ui.input({ class: props.ui?.input })"
329
335
  @keydown.backspace="onBackspace"
@@ -64,11 +64,11 @@ export interface CommandPaletteProps<G extends CommandPaletteGroup<T> = CommandP
64
64
  */
65
65
  size?: CommandPalette['variants']['size'];
66
66
  /**
67
- * The icon displayed in the input.
67
+ * The icon displayed in the input. Set to `false` to hide the icon.
68
68
  * @defaultValue appConfig.ui.icons.search
69
69
  * @IconifyIcon
70
70
  */
71
- icon?: IconProps['name'];
71
+ icon?: IconProps['name'] | false;
72
72
  /**
73
73
  * The icon displayed on the right side of the input.
74
74
  * @defaultValue appConfig.ui.icons.search
@@ -2,7 +2,7 @@ import type { VNode } from 'vue';
2
2
  import type { AppConfig } from '@nuxt/schema';
3
3
  import theme from '#build/ui/dashboard-search';
4
4
  import type { UseFuseOptions } from '@vueuse/integrations/useFuse';
5
- import type { ButtonProps, ModalProps, CommandPaletteProps, CommandPaletteSlots, CommandPaletteGroup, CommandPaletteItem, LinkPropsKeys } from '../types';
5
+ import type { ButtonProps, ModalProps, CommandPaletteProps, CommandPaletteSlots, CommandPaletteGroup, CommandPaletteItem, LinkPropsKeys, InputProps } from '../types';
6
6
  import type { ComponentConfig } from '../types/tv';
7
7
  type DashboardSearch = ComponentConfig<typeof theme, AppConfig, 'dashboardSearch'>;
8
8
  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' | 'trailingIcon' | 'selectedIcon' | 'childrenIcon' | 'placeholder' | 'autofocus' | 'loading' | 'loadingIcon' | 'closeIcon' | 'back' | 'backIcon' | 'disabled' | 'highlightOnHover' | 'labelKey' | 'descriptionKey' | 'preserveGroupOrder' | 'virtualize' | 'groups'> {
@@ -17,6 +17,12 @@ export interface DashboardSearchProps<T extends CommandPaletteItem = CommandPale
17
17
  * @defaultValue true
18
18
  */
19
19
  close?: boolean | Omit<ButtonProps, LinkPropsKeys>;
20
+ /**
21
+ * Configure the input or hide it with `false`.
22
+ * `{ fixed: true }`{lang="ts-type"}
23
+ * @defaultValue true
24
+ */
25
+ input?: boolean | Omit<InputProps, 'modelValue' | 'defaultValue'>;
20
26
  /**
21
27
  * Keyboard shortcut to open the search (used by [`defineShortcuts`](https://ui.nuxt.com/docs/composables/define-shortcuts))
22
28
  * @defaultValue 'meta_k'
@@ -17,6 +17,7 @@ import UModal from "./Modal.vue";
17
17
  const _props = defineProps({
18
18
  size: { type: null, required: false },
19
19
  close: { type: [Boolean, Object], required: false, default: true },
20
+ input: { type: [Boolean, Object], required: false },
20
21
  shortcut: { type: String, required: false, default: "meta_k" },
21
22
  fuse: { type: Object, required: false },
22
23
  searchDelay: { type: Number, required: false, default: 100 },
@@ -32,7 +33,7 @@ const _props = defineProps({
32
33
  fullscreen: { type: Boolean, required: false, default: false },
33
34
  modal: { type: Boolean, required: false },
34
35
  portal: { type: [Boolean, String], required: false, skipCheck: true },
35
- icon: { type: null, required: false },
36
+ icon: { type: [String, Boolean], required: false, skipCheck: true },
36
37
  trailingIcon: { type: null, required: false },
37
38
  selectedIcon: { type: null, required: false },
38
39
  childrenIcon: { type: null, required: false },
@@ -63,6 +64,12 @@ const colorMode = useColorMode();
63
64
  const appConfig = useAppConfig();
64
65
  const commandPaletteProps = useForwardProps(reactivePick(props, "size", "icon", "trailingIcon", "selectedIcon", "childrenIcon", "placeholder", "autofocus", "loading", "loadingIcon", "close", "closeIcon", "back", "backIcon", "disabled", "highlightOnHover", "labelKey", "descriptionKey", "preserveGroupOrder", "virtualize", "searchDelay"));
65
66
  const modalProps = useForwardProps(reactivePick(props, "overlay", "transition", "content", "dismissible", "fullscreen", "modal", "portal"));
67
+ const inputProps = computed(() => {
68
+ if (props.input === false) {
69
+ return false;
70
+ }
71
+ return defu(typeof props.input === "object" ? props.input : {}, { fixed: true });
72
+ });
66
73
  const getProxySlots = () => omit(slots, ["content"]);
67
74
  const fuse = computed(() => defu({}, props.fuse, {
68
75
  fuseOptions: {
@@ -142,7 +149,7 @@ defineExpose({
142
149
  v-bind="commandPaletteProps"
143
150
  :groups="groups"
144
151
  :fuse="fuse"
145
- :input="{ fixed: true }"
152
+ :input="inputProps"
146
153
  :ui="transformUI(omit(ui, ['modal']), props.ui)"
147
154
  @update:model-value="onSelect"
148
155
  @update:open="open = $event"
@@ -2,7 +2,7 @@ import type { VNode } from 'vue';
2
2
  import type { AppConfig } from '@nuxt/schema';
3
3
  import theme from '#build/ui/dashboard-search';
4
4
  import type { UseFuseOptions } from '@vueuse/integrations/useFuse';
5
- import type { ButtonProps, ModalProps, CommandPaletteProps, CommandPaletteSlots, CommandPaletteGroup, CommandPaletteItem, LinkPropsKeys } from '../types';
5
+ import type { ButtonProps, ModalProps, CommandPaletteProps, CommandPaletteSlots, CommandPaletteGroup, CommandPaletteItem, LinkPropsKeys, InputProps } from '../types';
6
6
  import type { ComponentConfig } from '../types/tv';
7
7
  type DashboardSearch = ComponentConfig<typeof theme, AppConfig, 'dashboardSearch'>;
8
8
  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' | 'trailingIcon' | 'selectedIcon' | 'childrenIcon' | 'placeholder' | 'autofocus' | 'loading' | 'loadingIcon' | 'closeIcon' | 'back' | 'backIcon' | 'disabled' | 'highlightOnHover' | 'labelKey' | 'descriptionKey' | 'preserveGroupOrder' | 'virtualize' | 'groups'> {
@@ -17,6 +17,12 @@ export interface DashboardSearchProps<T extends CommandPaletteItem = CommandPale
17
17
  * @defaultValue true
18
18
  */
19
19
  close?: boolean | Omit<ButtonProps, LinkPropsKeys>;
20
+ /**
21
+ * Configure the input or hide it with `false`.
22
+ * `{ fixed: true }`{lang="ts-type"}
23
+ * @defaultValue true
24
+ */
25
+ input?: boolean | Omit<InputProps, 'modelValue' | 'defaultValue'>;
20
26
  /**
21
27
  * Keyboard shortcut to open the search (used by [`defineShortcuts`](https://ui.nuxt.com/docs/composables/define-shortcuts))
22
28
  * @defaultValue 'meta_k'
@@ -5,11 +5,11 @@ import type { ComponentConfig } from '../types/tv';
5
5
  type DashboardSearchButton = ComponentConfig<typeof theme, AppConfig, 'dashboardSearchButton'>;
6
6
  export interface DashboardSearchButtonProps extends Omit<ButtonProps, LinkPropsKeys | 'icon' | 'label' | 'color' | 'variant'> {
7
7
  /**
8
- * The icon displayed in the button.
8
+ * The icon displayed in the button. Set to `false` to hide the icon.
9
9
  * @defaultValue appConfig.ui.icons.search
10
10
  * @IconifyIcon
11
11
  */
12
- icon?: IconProps['name'];
12
+ icon?: IconProps['name'] | false;
13
13
  /**
14
14
  * The label displayed in the button.
15
15
  * @defaultValue t('dashboardSearchButton.label')
@@ -18,7 +18,7 @@ import UKbd from "./Kbd.vue";
18
18
  import UTooltip from "./Tooltip.vue";
19
19
  defineOptions({ inheritAttrs: false });
20
20
  const _props = defineProps({
21
- icon: { type: null, required: false },
21
+ icon: { type: [String, Boolean], required: false, skipCheck: true },
22
22
  label: { type: String, required: false },
23
23
  color: { type: null, required: false, default: "neutral" },
24
24
  variant: { type: null, required: false },
@@ -65,7 +65,7 @@ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.dashboardSear
65
65
  <template>
66
66
  <DefineButtonTemplate>
67
67
  <UButton
68
- :icon="props.icon || appConfig.ui.icons.search"
68
+ :icon="props.icon === false ? void 0 : props.icon ?? appConfig.ui.icons.search"
69
69
  :label="props.label || t('dashboardSearchButton.label')"
70
70
  :variant="props.variant || (props.collapsed ? 'ghost' : 'outline')"
71
71
  v-bind="{
@@ -5,11 +5,11 @@ import type { ComponentConfig } from '../types/tv';
5
5
  type DashboardSearchButton = ComponentConfig<typeof theme, AppConfig, 'dashboardSearchButton'>;
6
6
  export interface DashboardSearchButtonProps extends Omit<ButtonProps, LinkPropsKeys | 'icon' | 'label' | 'color' | 'variant'> {
7
7
  /**
8
- * The icon displayed in the button.
8
+ * The icon displayed in the button. Set to `false` to hide the icon.
9
9
  * @defaultValue appConfig.ui.icons.search
10
10
  * @IconifyIcon
11
11
  */
12
- icon?: IconProps['name'];
12
+ icon?: IconProps['name'] | false;
13
13
  /**
14
14
  * The label displayed in the button.
15
15
  * @defaultValue t('dashboardSearchButton.label')
@@ -15,11 +15,11 @@ export interface FileUploadProps<M extends boolean = false> extends /** @vue-ign
15
15
  id?: string;
16
16
  name?: string;
17
17
  /**
18
- * The icon to display.
18
+ * The icon to display. Set to `false` to hide the icon.
19
19
  * @defaultValue appConfig.ui.icons.upload
20
20
  * @IconifyIcon
21
21
  */
22
- icon?: IconProps['name'];
22
+ icon?: IconProps['name'] | false;
23
23
  label?: string;
24
24
  description?: string;
25
25
  /**
@@ -127,6 +127,7 @@ export interface FileUploadSlots<M extends boolean = false> {
127
127
  }): VNode[];
128
128
  'files'?(props: {
129
129
  files: FileUploadFiles<M>;
130
+ removeFile: (index?: number) => void;
130
131
  }): VNode[];
131
132
  'files-top'?(props: {
132
133
  files: FileUploadFiles<M>;
@@ -141,6 +142,7 @@ export interface FileUploadSlots<M extends boolean = false> {
141
142
  'file'?(props: {
142
143
  file: File;
143
144
  index: number;
145
+ removeFile: (index?: number) => void;
144
146
  }): VNode[];
145
147
  'file-leading'?(props: {
146
148
  file: File;
@@ -159,6 +161,7 @@ export interface FileUploadSlots<M extends boolean = false> {
159
161
  file: File;
160
162
  index: number;
161
163
  ui: FileUpload['ui'];
164
+ removeFile: (index?: number) => void;
162
165
  }): VNode[];
163
166
  }
164
167
  declare const _default: typeof __VLS_export;
@@ -20,7 +20,7 @@ const _props = defineProps({
20
20
  as: { type: null, required: false },
21
21
  id: { type: String, required: false },
22
22
  name: { type: String, required: false },
23
- icon: { type: null, required: false },
23
+ icon: { type: [String, Boolean], required: false, skipCheck: true },
24
24
  label: { type: String, required: false },
25
25
  description: { type: String, required: false },
26
26
  color: { type: null, required: false },
@@ -146,9 +146,9 @@ defineExpose({
146
146
  <slot name="files-top" :files="modelValue" :open="open" :remove-file="removeFile" />
147
147
 
148
148
  <div data-slot="files" :class="ui.files({ class: props.ui?.files })">
149
- <slot name="files" :files="modelValue">
149
+ <slot name="files" :files="modelValue" :remove-file="removeFile">
150
150
  <div v-for="(file, index) in Array.isArray(modelValue) ? modelValue : [modelValue]" :key="file.name" data-slot="file" :class="ui.file({ class: props.ui?.file })">
151
- <slot name="file" :file="file" :index="index">
151
+ <slot name="file" :file="file" :index="index" :remove-file="removeFile">
152
152
  <slot name="file-leading" :file="file" :index="index" :ui="ui">
153
153
  <UAvatar
154
154
  :as="{ img: 'img' }"
@@ -174,7 +174,7 @@ defineExpose({
174
174
  </span>
175
175
  </div>
176
176
 
177
- <slot name="file-trailing" :file="file" :index="index" :ui="ui">
177
+ <slot name="file-trailing" :file="file" :index="index" :ui="ui" :remove-file="removeFile">
178
178
  <UButton
179
179
  v-if="props.fileDelete"
180
180
  color="neutral"
@@ -224,8 +224,10 @@ defineExpose({
224
224
 
225
225
  <div v-if="position === 'inside' ? !props.preview || (multiple ? !modelValue?.length : !modelValue) : true" data-slot="wrapper" :class="ui.wrapper({ class: props.ui?.wrapper })">
226
226
  <slot name="leading" :ui="ui">
227
- <UIcon v-if="variant === 'button'" :name="props.icon || appConfig.ui.icons.upload" data-slot="icon" :class="ui.icon({ class: props.ui?.icon })" />
228
- <UAvatar v-else :icon="props.icon || appConfig.ui.icons.upload" :size="props.size" data-slot="avatar" :class="ui.avatar({ class: props.ui?.avatar })" />
227
+ <template v-if="props.icon !== false">
228
+ <UIcon v-if="variant === 'button'" :name="props.icon ?? appConfig.ui.icons.upload" data-slot="icon" :class="ui.icon({ class: props.ui?.icon })" />
229
+ <UAvatar v-else :icon="props.icon ?? appConfig.ui.icons.upload" :size="props.size" data-slot="avatar" :class="ui.avatar({ class: props.ui?.avatar })" />
230
+ </template>
229
231
  </slot>
230
232
 
231
233
  <template v-if="variant !== 'button'">
@@ -15,11 +15,11 @@ export interface FileUploadProps<M extends boolean = false> extends /** @vue-ign
15
15
  id?: string;
16
16
  name?: string;
17
17
  /**
18
- * The icon to display.
18
+ * The icon to display. Set to `false` to hide the icon.
19
19
  * @defaultValue appConfig.ui.icons.upload
20
20
  * @IconifyIcon
21
21
  */
22
- icon?: IconProps['name'];
22
+ icon?: IconProps['name'] | false;
23
23
  label?: string;
24
24
  description?: string;
25
25
  /**
@@ -127,6 +127,7 @@ export interface FileUploadSlots<M extends boolean = false> {
127
127
  }): VNode[];
128
128
  'files'?(props: {
129
129
  files: FileUploadFiles<M>;
130
+ removeFile: (index?: number) => void;
130
131
  }): VNode[];
131
132
  'files-top'?(props: {
132
133
  files: FileUploadFiles<M>;
@@ -141,6 +142,7 @@ export interface FileUploadSlots<M extends boolean = false> {
141
142
  'file'?(props: {
142
143
  file: File;
143
144
  index: number;
145
+ removeFile: (index?: number) => void;
144
146
  }): VNode[];
145
147
  'file-leading'?(props: {
146
148
  file: File;
@@ -159,6 +161,7 @@ export interface FileUploadSlots<M extends boolean = false> {
159
161
  file: File;
160
162
  index: number;
161
163
  ui: FileUpload['ui'];
164
+ removeFile: (index?: number) => void;
162
165
  }): VNode[];
163
166
  }
164
167
  declare const _default: typeof __VLS_export;
@@ -104,6 +104,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<LinkPr
104
104
  as: any;
105
105
  active: boolean;
106
106
  ariaCurrentValue: "page" | "step" | "location" | "date" | "time" | "true" | "false";
107
+ locale: boolean | string;
107
108
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, LinkSlots>;
108
109
  type __VLS_WithSlots<T, S> = T & {
109
110
  new (): {
@@ -26,7 +26,7 @@ const props = defineProps({
26
26
  inactiveClass: { type: String, required: false },
27
27
  custom: { type: Boolean, required: false },
28
28
  raw: { type: Boolean, required: false },
29
- locale: { type: [Boolean, String], required: false },
29
+ locale: { type: [Boolean, String], required: false, default: void 0 },
30
30
  class: { type: null, required: false },
31
31
  to: { type: null, required: false },
32
32
  href: { type: null, required: false },
@@ -104,6 +104,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<LinkPr
104
104
  as: any;
105
105
  active: boolean;
106
106
  ariaCurrentValue: "page" | "step" | "location" | "date" | "time" | "true" | "false";
107
+ locale: boolean | string;
107
108
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, LinkSlots>;
108
109
  type __VLS_WithSlots<T, S> = T & {
109
110
  new (): {
@@ -57,7 +57,9 @@ export interface ModalProps extends DialogRootProps {
57
57
  ui?: Modal['slots'];
58
58
  }
59
59
  export interface ModalEmits extends DialogRootEmits {
60
+ 'leave': [];
60
61
  'after:leave': [];
62
+ 'enter': [];
61
63
  'after:enter': [];
62
64
  'close:prevent': [];
63
65
  }
@@ -87,13 +89,17 @@ export interface ModalSlots {
87
89
  declare const _default: typeof __VLS_export;
88
90
  export default _default;
89
91
  declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<ModalProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
92
+ enter: () => any;
90
93
  "update:open": (value: boolean) => any;
91
94
  "after:leave": () => any;
95
+ leave: () => any;
92
96
  "after:enter": () => any;
93
97
  "close:prevent": () => any;
94
98
  }, string, import("vue").PublicProps, Readonly<ModalProps> & Readonly<{
99
+ onEnter?: (() => any) | undefined;
95
100
  "onUpdate:open"?: ((value: boolean) => any) | undefined;
96
101
  "onAfter:leave"?: (() => any) | undefined;
102
+ onLeave?: (() => any) | undefined;
97
103
  "onAfter:enter"?: (() => any) | undefined;
98
104
  "onClose:prevent"?: (() => any) | undefined;
99
105
  }>, {
@@ -33,7 +33,7 @@ const _props = defineProps({
33
33
  defaultOpen: { type: Boolean, required: false },
34
34
  modal: { type: Boolean, required: false, default: true }
35
35
  });
36
- const emits = defineEmits(["after:leave", "after:enter", "close:prevent", "update:open"]);
36
+ const emits = defineEmits(["leave", "after:leave", "enter", "after:enter", "close:prevent", "update:open"]);
37
37
  const slots = defineSlots();
38
38
  const props = useComponentProps("modal", _props);
39
39
  const { t } = useLocale();
@@ -72,7 +72,9 @@ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.modal || {} }
72
72
  data-slot="content"
73
73
  :class="ui.content({ class: [!slots.default && props.class, props.ui?.content] })"
74
74
  v-bind="contentProps"
75
+ @enter="emits('enter')"
75
76
  @after-enter="emits('after:enter')"
77
+ @leave="emits('leave')"
76
78
  @after-leave="emits('after:leave')"
77
79
  v-on="contentEvents"
78
80
  >
@@ -57,7 +57,9 @@ export interface ModalProps extends DialogRootProps {
57
57
  ui?: Modal['slots'];
58
58
  }
59
59
  export interface ModalEmits extends DialogRootEmits {
60
+ 'leave': [];
60
61
  'after:leave': [];
62
+ 'enter': [];
61
63
  'after:enter': [];
62
64
  'close:prevent': [];
63
65
  }
@@ -87,13 +89,17 @@ export interface ModalSlots {
87
89
  declare const _default: typeof __VLS_export;
88
90
  export default _default;
89
91
  declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<ModalProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
92
+ enter: () => any;
90
93
  "update:open": (value: boolean) => any;
91
94
  "after:leave": () => any;
95
+ leave: () => any;
92
96
  "after:enter": () => any;
93
97
  "close:prevent": () => any;
94
98
  }, string, import("vue").PublicProps, Readonly<ModalProps> & Readonly<{
99
+ onEnter?: (() => any) | undefined;
95
100
  "onUpdate:open"?: ((value: boolean) => any) | undefined;
96
101
  "onAfter:leave"?: (() => any) | undefined;
102
+ onLeave?: (() => any) | undefined;
97
103
  "onAfter:enter"?: (() => any) | undefined;
98
104
  "onClose:prevent"?: (() => any) | undefined;
99
105
  }>, {
@@ -1,4 +1,4 @@
1
- import type { ComponentPublicInstance } from 'vue';
1
+ import type { ComponentPublicInstance, VNode } from 'vue';
2
2
  import type { PinInputRootEmits, PinInputRootProps } from 'reka-ui';
3
3
  import type { AppConfig } from '@nuxt/schema';
4
4
  import theme from '#build/ui/pin-input';
@@ -33,6 +33,13 @@ export interface PinInputProps<T extends PinInputType = 'text'> extends Pick<Pin
33
33
  highlight?: boolean;
34
34
  /** Keep the mobile text size on all breakpoints. */
35
35
  fixed?: boolean;
36
+ /**
37
+ * Group inputs by inserting a separator between them.
38
+ * Pass a number to insert one after every Nth input, or an array of positions to insert after specific inputs.
39
+ * @example 3 // after every 3rd input → [X][X][X] • [X][X][X]
40
+ * @example [3, 4] // after the 3rd and 4th inputs → [X][X][X] • [X] • [X][X][X]
41
+ */
42
+ separator?: number | number[];
36
43
  class?: any;
37
44
  ui?: PinInput['slots'];
38
45
  }
@@ -40,6 +47,11 @@ export type PinInputEmits<T extends PinInputType = 'text'> = PinInputRootEmits<T
40
47
  change: [event: Event];
41
48
  blur: [event: Event];
42
49
  };
50
+ export interface PinInputSlots {
51
+ separator?(props: {
52
+ index: number;
53
+ }): VNode[];
54
+ }
43
55
  declare const _default: typeof __VLS_export;
44
56
  export default _default;
45
57
  declare const __VLS_export: <T extends PinInputType>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
@@ -55,7 +67,7 @@ declare const __VLS_export: <T extends PinInputType>(__VLS_props: NonNullable<Aw
55
67
  inputsRef: import("vue").Ref<ComponentPublicInstance[], ComponentPublicInstance[]>;
56
68
  }>) => void;
57
69
  attrs: any;
58
- slots: {};
70
+ slots: PinInputSlots;
59
71
  emit: ((evt: "blur", event: Event) => void) & ((evt: "change", event: Event) => void) & ((evt: "update:modelValue", value: [T] extends ["number"] ? number[] : string[]) => void) & ((evt: "complete", value: [T] extends ["number"] ? number[] : string[]) => void);
60
72
  }>) => import("vue").VNode & {
61
73
  __ctx?: Awaited<typeof __VLS_setup>;