@nuxt/ui 4.8.1 → 4.8.2

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.
package/dist/module.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuxt/ui",
3
- "version": "4.8.1",
3
+ "version": "4.8.2",
4
4
  "docs": "https://ui.nuxt.com/docs/getting-started/installation/nuxt",
5
5
  "configKey": "ui",
6
6
  "compatibility": {
package/dist/module.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { defu } from 'defu';
2
2
  import { defineNuxtModule, createResolver, addPlugin, hasNuxtModule, addComponentsDir, addImportsDir, addImports } from '@nuxt/kit';
3
- import { d as defaultOptions, r as resolveColors, g as getDefaultConfig, p as publicComposables, a as addTemplates } from './shared/ui.BzjkAvk7.mjs';
3
+ import { d as defaultOptions, r as resolveColors, g as getDefaultConfig, p as publicComposables, a as addTemplates } from './shared/ui.C-lVg1QQ.mjs';
4
4
  import '../dist/runtime/utils/index.js';
5
5
  import 'node:url';
6
6
  import 'scule';
@@ -11,7 +11,7 @@ import 'pathe';
11
11
  import 'tinyglobby';
12
12
 
13
13
  const name = "@nuxt/ui";
14
- const version = "4.8.1";
14
+ const version = "4.8.2";
15
15
 
16
16
  const module$1 = defineNuxtModule({
17
17
  meta: {
@@ -8,8 +8,8 @@ import type { ComponentConfig } from '../types/tv';
8
8
  type Calendar = ComponentConfig<typeof theme, AppConfig, 'calendar'>;
9
9
  type CalendarDefaultValue<R extends boolean = false, M extends boolean = false> = R extends true ? DateRange : M extends true ? DateValue[] : DateValue;
10
10
  type CalendarModelValue<R extends boolean = false, M extends boolean = false> = R extends true ? (DateRange | null) : M extends true ? (DateValue[] | undefined) : (DateValue | undefined);
11
- type _CalendarRootProps = Omit<CalendarRootProps, 'as' | 'asChild' | 'modelValue' | 'defaultValue' | 'dir' | 'locale' | 'calendarLabel' | 'multiple'>;
12
- type _RangeCalendarRootProps = Omit<RangeCalendarRootProps, 'as' | 'asChild' | 'modelValue' | 'defaultValue' | 'dir' | 'locale' | 'calendarLabel' | 'multiple'>;
11
+ type _CalendarRootProps = Omit<CalendarRootProps, 'as' | 'asChild' | 'modelValue' | 'defaultValue' | 'dir' | 'calendarLabel' | 'multiple'>;
12
+ type _RangeCalendarRootProps = Omit<RangeCalendarRootProps, 'as' | 'asChild' | 'modelValue' | 'defaultValue' | 'dir' | 'calendarLabel' | 'multiple'>;
13
13
  export interface CalendarProps<R extends boolean = false, M extends boolean = false> extends _RangeCalendarRootProps, _CalendarRootProps {
14
14
  /**
15
15
  * The element or component this component should render as.
@@ -47,6 +47,7 @@ const _props = defineProps({
47
47
  fixedWeeks: { type: Boolean, required: false, default: true },
48
48
  maxValue: { type: Object, required: false },
49
49
  minValue: { type: Object, required: false },
50
+ locale: { type: String, required: false },
50
51
  numberOfMonths: { type: Number, required: false },
51
52
  disabled: { type: Boolean, required: false },
52
53
  readonly: { type: Boolean, required: false },
@@ -146,7 +147,7 @@ const Calendar = computed(() => props.range ? RangeCalendar : SingleCalendar);
146
147
  data-slot="cellWeek"
147
148
  :class="ui.cellWeek({ class: props.ui?.cellWeek })"
148
149
  >
149
- {{ getWeekNumber(weekDates[0], locale.code) }}
150
+ {{ getWeekNumber(weekDates[0], props.locale ?? locale.code) }}
150
151
  </td>
151
152
  <Calendar.Cell
152
153
  v-for="weekDate in weekDates"
@@ -8,8 +8,8 @@ import type { ComponentConfig } from '../types/tv';
8
8
  type Calendar = ComponentConfig<typeof theme, AppConfig, 'calendar'>;
9
9
  type CalendarDefaultValue<R extends boolean = false, M extends boolean = false> = R extends true ? DateRange : M extends true ? DateValue[] : DateValue;
10
10
  type CalendarModelValue<R extends boolean = false, M extends boolean = false> = R extends true ? (DateRange | null) : M extends true ? (DateValue[] | undefined) : (DateValue | undefined);
11
- type _CalendarRootProps = Omit<CalendarRootProps, 'as' | 'asChild' | 'modelValue' | 'defaultValue' | 'dir' | 'locale' | 'calendarLabel' | 'multiple'>;
12
- type _RangeCalendarRootProps = Omit<RangeCalendarRootProps, 'as' | 'asChild' | 'modelValue' | 'defaultValue' | 'dir' | 'locale' | 'calendarLabel' | 'multiple'>;
11
+ type _CalendarRootProps = Omit<CalendarRootProps, 'as' | 'asChild' | 'modelValue' | 'defaultValue' | 'dir' | 'calendarLabel' | 'multiple'>;
12
+ type _RangeCalendarRootProps = Omit<RangeCalendarRootProps, 'as' | 'asChild' | 'modelValue' | 'defaultValue' | 'dir' | 'calendarLabel' | 'multiple'>;
13
13
  export interface CalendarProps<R extends boolean = false, M extends boolean = false> extends _RangeCalendarRootProps, _CalendarRootProps {
14
14
  /**
15
15
  * The element or component this component should render as.
@@ -22,10 +22,10 @@ export type FormProps<S extends FormSchema, T extends boolean = true, N extends
22
22
  /** Disable all inputs inside the form. */
23
23
  disabled?: boolean;
24
24
  /**
25
- * Path of the form's state within it's parent form.
26
- * Used for nesting forms. Only available if `nested` is true.
25
+ * The `name` attribute of the form element.
26
+ * For nested forms (`nested` is true), this is also used as the path of the form's state within its parent form.
27
27
  */
28
- name?: N extends true ? string : never;
28
+ name?: string;
29
29
  /**
30
30
  * Delay in milliseconds before validating the form on input events.
31
31
  * @defaultValue `300`
@@ -20,7 +20,7 @@ const _props = defineProps({
20
20
  return ["input", "blur", "change"];
21
21
  } },
22
22
  disabled: { type: Boolean, required: false },
23
- name: { type: null, required: false },
23
+ name: { type: String, required: false },
24
24
  validateOnInputDelay: { type: Number, required: false, default: 300 },
25
25
  transform: { type: null, required: false, default: () => true },
26
26
  nested: { type: Boolean, required: false },
@@ -293,6 +293,7 @@ defineExpose(api);
293
293
  :is="parentBus ? 'div' : 'form'"
294
294
  :id="formId"
295
295
  ref="formRef"
296
+ :name="parentBus ? void 0 : props.name"
296
297
  method="post"
297
298
  :class="ui({ class: [props.ui?.base, props.class] })"
298
299
  @submit.prevent="onSubmitWrapper"
@@ -22,10 +22,10 @@ export type FormProps<S extends FormSchema, T extends boolean = true, N extends
22
22
  /** Disable all inputs inside the form. */
23
23
  disabled?: boolean;
24
24
  /**
25
- * Path of the form's state within it's parent form.
26
- * Used for nesting forms. Only available if `nested` is true.
25
+ * The `name` attribute of the form element.
26
+ * For nested forms (`nested` is true), this is also used as the path of the form's state within its parent form.
27
27
  */
28
- name?: N extends true ? string : never;
28
+ name?: string;
29
29
  /**
30
30
  * Delay in milliseconds before validating the form on input events.
31
31
  * @defaultValue `300`
@@ -6,8 +6,8 @@ import type { IconProps } from '../types';
6
6
  import type { ComponentConfig } from '../types/tv';
7
7
  import theme from '#build/ui/input-date';
8
8
  type InputDate = ComponentConfig<typeof theme, AppConfig, 'inputDate'>;
9
- type _DateFieldRootProps = Omit<DateFieldRootProps, 'as' | 'asChild' | 'modelValue' | 'defaultValue' | 'dir' | 'locale'>;
10
- type _RangeDateFieldRootProps = Omit<DateRangeFieldRootProps, 'as' | 'asChild' | 'modelValue' | 'defaultValue' | 'dir' | 'locale'>;
9
+ type _DateFieldRootProps = Omit<DateFieldRootProps, 'as' | 'asChild' | 'modelValue' | 'defaultValue' | 'dir'>;
10
+ type _RangeDateFieldRootProps = Omit<DateRangeFieldRootProps, 'as' | 'asChild' | 'modelValue' | 'defaultValue' | 'dir'>;
11
11
  type InputDateDefaultValue<R extends boolean = false> = R extends true ? DateRangeFieldRootProps['defaultValue'] : DateFieldRootProps['defaultValue'];
12
12
  type InputDateModelValue<R extends boolean = false> = (R extends true ? DateRangeFieldRootProps['modelValue'] : DateFieldRootProps['modelValue']) | undefined;
13
13
  export interface InputDateProps<R extends boolean = false> extends UseComponentIconsProps, _DateFieldRootProps, _RangeDateFieldRootProps {
@@ -48,6 +48,7 @@ const _props = defineProps({
48
48
  hideTimeZone: { type: Boolean, required: false },
49
49
  maxValue: { type: Object, required: false },
50
50
  minValue: { type: Object, required: false },
51
+ locale: { type: String, required: false },
51
52
  disabled: { type: Boolean, required: false },
52
53
  readonly: { type: Boolean, required: false },
53
54
  isDateUnavailable: { type: Function, required: false },
@@ -6,8 +6,8 @@ import type { IconProps } from '../types';
6
6
  import type { ComponentConfig } from '../types/tv';
7
7
  import theme from '#build/ui/input-date';
8
8
  type InputDate = ComponentConfig<typeof theme, AppConfig, 'inputDate'>;
9
- type _DateFieldRootProps = Omit<DateFieldRootProps, 'as' | 'asChild' | 'modelValue' | 'defaultValue' | 'dir' | 'locale'>;
10
- type _RangeDateFieldRootProps = Omit<DateRangeFieldRootProps, 'as' | 'asChild' | 'modelValue' | 'defaultValue' | 'dir' | 'locale'>;
9
+ type _DateFieldRootProps = Omit<DateFieldRootProps, 'as' | 'asChild' | 'modelValue' | 'defaultValue' | 'dir'>;
10
+ type _RangeDateFieldRootProps = Omit<DateRangeFieldRootProps, 'as' | 'asChild' | 'modelValue' | 'defaultValue' | 'dir'>;
11
11
  type InputDateDefaultValue<R extends boolean = false> = R extends true ? DateRangeFieldRootProps['defaultValue'] : DateFieldRootProps['defaultValue'];
12
12
  type InputDateModelValue<R extends boolean = false> = (R extends true ? DateRangeFieldRootProps['modelValue'] : DateFieldRootProps['modelValue']) | undefined;
13
13
  export interface InputDateProps<R extends boolean = false> extends UseComponentIconsProps, _DateFieldRootProps, _RangeDateFieldRootProps {
@@ -3,7 +3,7 @@ import theme from "#build/ui/input-menu";
3
3
  </script>
4
4
 
5
5
  <script setup>
6
- import { computed, useTemplateRef, toRef, onMounted, toRaw, nextTick, watch } from "vue";
6
+ import { computed, ref, useTemplateRef, toRef, onMounted, toRaw, nextTick, watch } from "vue";
7
7
  import { TagsInputRoot, TagsInputItem, TagsInputItemText, TagsInputItemDelete, TagsInputInput } from "reka-ui";
8
8
  import { useForwardProps } from "../composables/useForwardProps";
9
9
  import { Combobox, Autocomplete } from "reka-ui/namespaced";
@@ -228,7 +228,9 @@ function onFocus(event) {
228
228
  emits("focus", event);
229
229
  emitFormFocus();
230
230
  }
231
+ const isOpen = ref(false);
231
232
  function onUpdateOpen(value) {
233
+ isOpen.value = value;
232
234
  let timeoutId;
233
235
  if (!value) {
234
236
  const event = new FocusEvent("blur");
@@ -283,6 +285,14 @@ function onClear() {
283
285
  emits("clear");
284
286
  }
285
287
  const viewportRef = useTemplateRef("viewportRef");
288
+ const comboboxRootRef = useTemplateRef("comboboxRootRef");
289
+ watch(() => props.items, async () => {
290
+ if (!isOpen.value) {
291
+ return;
292
+ }
293
+ await nextTick();
294
+ comboboxRootRef.value?.highlightFirstItem?.();
295
+ }, { flush: "post" });
286
296
  defineExpose({
287
297
  inputRef: toRef(() => inputRef.value?.$el),
288
298
  viewportRef: toRef(() => viewportRef.value)
@@ -361,6 +371,7 @@ defineExpose({
361
371
  </DefineItemTemplate>
362
372
 
363
373
  <Component.Root
374
+ ref="comboboxRootRef"
364
375
  v-slot="{ modelValue, open }"
365
376
  v-bind="rootProps"
366
377
  :name="name"
@@ -11,7 +11,7 @@ type InputNumberValue = number | null;
11
11
  type ApplyModifiers<T extends InputNumberValue, Mod extends Pick<ModelModifiers, 'optional'>> = T | (Mod extends {
12
12
  optional: true;
13
13
  } ? undefined : never);
14
- export interface InputNumberProps<T extends InputNumberValue = InputNumberValue, Mod extends Pick<ModelModifiers, 'optional'> = Pick<ModelModifiers, 'optional'>> extends Pick<NumberFieldRootProps, 'min' | 'max' | 'step' | 'stepSnapping' | 'disabled' | 'required' | 'id' | 'name' | 'formatOptions' | 'disableWheelChange' | 'invertWheelChange' | 'readonly' | 'focusOnChange'>, /** @vue-ignore */ Omit<InputHTMLAttributes, 'disabled' | 'min' | 'max' | 'readonly' | 'required' | 'step' | 'name' | 'placeholder' | 'type' | 'autofocus' | 'maxlength' | 'minlength' | 'pattern' | 'size'> {
14
+ export interface InputNumberProps<T extends InputNumberValue = InputNumberValue, Mod extends Pick<ModelModifiers, 'optional'> = Pick<ModelModifiers, 'optional'>> extends Pick<NumberFieldRootProps, 'min' | 'max' | 'step' | 'stepSnapping' | 'disabled' | 'required' | 'id' | 'name' | 'formatOptions' | 'disableWheelChange' | 'invertWheelChange' | 'readonly' | 'focusOnChange' | 'locale'>, /** @vue-ignore */ Omit<InputHTMLAttributes, 'disabled' | 'min' | 'max' | 'readonly' | 'required' | 'step' | 'name' | 'placeholder' | 'type' | 'autofocus' | 'maxlength' | 'minlength' | 'pattern' | 'size'> {
15
15
  /**
16
16
  * The element or component this component should render as.
17
17
  * @defaultValue 'div'
@@ -49,7 +49,8 @@ const _props = defineProps({
49
49
  disableWheelChange: { type: Boolean, required: false },
50
50
  invertWheelChange: { type: Boolean, required: false },
51
51
  readonly: { type: Boolean, required: false },
52
- focusOnChange: { type: Boolean, required: false }
52
+ focusOnChange: { type: Boolean, required: false },
53
+ locale: { type: String, required: false }
53
54
  });
54
55
  const emits = defineEmits(["update:modelValue", "blur", "change"]);
55
56
  defineSlots();
@@ -57,7 +58,7 @@ const props = useComponentProps("inputNumber", _props);
57
58
  const modelValue = useVModel(props, "modelValue", emits, { defaultValue: props.defaultValue });
58
59
  const { t } = useLocale();
59
60
  const appConfig = useAppConfig();
60
- const rootProps = useForwardProps(reactivePick(props, "as", "stepSnapping", "formatOptions", "disableWheelChange", "invertWheelChange", "required", "readonly", "focusOnChange"), emits);
61
+ const rootProps = useForwardProps(reactivePick(props, "as", "stepSnapping", "formatOptions", "disableWheelChange", "invertWheelChange", "required", "readonly", "focusOnChange", "locale"), emits);
61
62
  const { emitFormBlur, emitFormFocus, emitFormChange, emitFormInput, id, color, size: formFieldSize, name, highlight, disabled, ariaAttrs } = useFormField(_props);
62
63
  const { orientation, size: fieldGroupSize } = useFieldGroup(_props);
63
64
  const inputSize = computed(() => fieldGroupSize.value || formFieldSize.value);
@@ -11,7 +11,7 @@ type InputNumberValue = number | null;
11
11
  type ApplyModifiers<T extends InputNumberValue, Mod extends Pick<ModelModifiers, 'optional'>> = T | (Mod extends {
12
12
  optional: true;
13
13
  } ? undefined : never);
14
- export interface InputNumberProps<T extends InputNumberValue = InputNumberValue, Mod extends Pick<ModelModifiers, 'optional'> = Pick<ModelModifiers, 'optional'>> extends Pick<NumberFieldRootProps, 'min' | 'max' | 'step' | 'stepSnapping' | 'disabled' | 'required' | 'id' | 'name' | 'formatOptions' | 'disableWheelChange' | 'invertWheelChange' | 'readonly' | 'focusOnChange'>, /** @vue-ignore */ Omit<InputHTMLAttributes, 'disabled' | 'min' | 'max' | 'readonly' | 'required' | 'step' | 'name' | 'placeholder' | 'type' | 'autofocus' | 'maxlength' | 'minlength' | 'pattern' | 'size'> {
14
+ export interface InputNumberProps<T extends InputNumberValue = InputNumberValue, Mod extends Pick<ModelModifiers, 'optional'> = Pick<ModelModifiers, 'optional'>> extends Pick<NumberFieldRootProps, 'min' | 'max' | 'step' | 'stepSnapping' | 'disabled' | 'required' | 'id' | 'name' | 'formatOptions' | 'disableWheelChange' | 'invertWheelChange' | 'readonly' | 'focusOnChange' | 'locale'>, /** @vue-ignore */ Omit<InputHTMLAttributes, 'disabled' | 'min' | 'max' | 'readonly' | 'required' | 'step' | 'name' | 'placeholder' | 'type' | 'autofocus' | 'maxlength' | 'minlength' | 'pattern' | 'size'> {
15
15
  /**
16
16
  * The element or component this component should render as.
17
17
  * @defaultValue 'div'
@@ -8,8 +8,8 @@ import type { ComponentConfig } from '../types/tv';
8
8
  type InputTime = ComponentConfig<typeof theme, AppConfig, 'inputTime'>;
9
9
  type InputTimeDefaultValue<R extends boolean = false> = R extends true ? TimeRangeFieldRootProps['defaultValue'] : TimeFieldRootProps['defaultValue'];
10
10
  type InputTimeModelValue<R extends boolean = false> = (R extends true ? TimeRangeFieldRootProps['modelValue'] : TimeFieldRootProps['modelValue']) | undefined;
11
- type _TimeFieldRootProps = Omit<TimeFieldRootProps, 'as' | 'asChild' | 'modelValue' | 'defaultValue' | 'dir' | 'locale'>;
12
- type _TimeRangeFieldRootProps = Omit<TimeRangeFieldRootProps, 'as' | 'asChild' | 'modelValue' | 'defaultValue' | 'dir' | 'locale'>;
11
+ type _TimeFieldRootProps = Omit<TimeFieldRootProps, 'as' | 'asChild' | 'modelValue' | 'defaultValue' | 'dir'>;
12
+ type _TimeRangeFieldRootProps = Omit<TimeRangeFieldRootProps, 'as' | 'asChild' | 'modelValue' | 'defaultValue' | 'dir'>;
13
13
  export interface InputTimeProps<R extends boolean = false> extends UseComponentIconsProps, _TimeFieldRootProps, _TimeRangeFieldRootProps {
14
14
  /**
15
15
  * The element or component this component should render as.
@@ -49,6 +49,7 @@ const _props = defineProps({
49
49
  hideTimeZone: { type: Boolean, required: false },
50
50
  maxValue: { type: Object, required: false },
51
51
  minValue: { type: Object, required: false },
52
+ locale: { type: String, required: false },
52
53
  disabled: { type: Boolean, required: false },
53
54
  readonly: { type: Boolean, required: false },
54
55
  id: { type: String, required: false },
@@ -8,8 +8,8 @@ import type { ComponentConfig } from '../types/tv';
8
8
  type InputTime = ComponentConfig<typeof theme, AppConfig, 'inputTime'>;
9
9
  type InputTimeDefaultValue<R extends boolean = false> = R extends true ? TimeRangeFieldRootProps['defaultValue'] : TimeFieldRootProps['defaultValue'];
10
10
  type InputTimeModelValue<R extends boolean = false> = (R extends true ? TimeRangeFieldRootProps['modelValue'] : TimeFieldRootProps['modelValue']) | undefined;
11
- type _TimeFieldRootProps = Omit<TimeFieldRootProps, 'as' | 'asChild' | 'modelValue' | 'defaultValue' | 'dir' | 'locale'>;
12
- type _TimeRangeFieldRootProps = Omit<TimeRangeFieldRootProps, 'as' | 'asChild' | 'modelValue' | 'defaultValue' | 'dir' | 'locale'>;
11
+ type _TimeFieldRootProps = Omit<TimeFieldRootProps, 'as' | 'asChild' | 'modelValue' | 'defaultValue' | 'dir'>;
12
+ type _TimeRangeFieldRootProps = Omit<TimeRangeFieldRootProps, 'as' | 'asChild' | 'modelValue' | 'defaultValue' | 'dir'>;
13
13
  export interface InputTimeProps<R extends boolean = false> extends UseComponentIconsProps, _TimeFieldRootProps, _TimeRangeFieldRootProps {
14
14
  /**
15
15
  * The element or component this component should render as.
@@ -4,7 +4,7 @@ export interface LinkBaseProps {
4
4
  type?: string;
5
5
  disabled?: boolean;
6
6
  onClick?: ((e: MouseEvent) => void | Promise<void>) | Array<((e: MouseEvent) => void | Promise<void>)>;
7
- href?: string;
7
+ href?: string | null;
8
8
  navigate?: (e: MouseEvent) => void;
9
9
  target?: LinkProps['target'];
10
10
  rel?: LinkProps['rel'];
@@ -9,7 +9,7 @@ const props = defineProps({
9
9
  type: { type: String, required: false, default: "button" },
10
10
  disabled: { type: Boolean, required: false },
11
11
  onClick: { type: [Function, Array], required: false },
12
- href: { type: String, required: false },
12
+ href: { type: [String, null], required: false },
13
13
  navigate: { type: Function, required: false },
14
14
  target: { type: [String, Object, null], required: false },
15
15
  rel: { type: [String, Object, null], required: false },
@@ -4,7 +4,7 @@ export interface LinkBaseProps {
4
4
  type?: string;
5
5
  disabled?: boolean;
6
6
  onClick?: ((e: MouseEvent) => void | Promise<void>) | Array<((e: MouseEvent) => void | Promise<void>)>;
7
- href?: string;
7
+ href?: string | null;
8
8
  navigate?: (e: MouseEvent) => void;
9
9
  target?: LinkProps['target'];
10
10
  rel?: LinkProps['rel'];
@@ -3,7 +3,7 @@ import theme from "#build/ui/select-menu";
3
3
  </script>
4
4
 
5
5
  <script setup>
6
- import { useTemplateRef, computed, onMounted, toRef, toRaw } from "vue";
6
+ import { useTemplateRef, computed, ref, onMounted, toRef, toRaw, watch, nextTick } from "vue";
7
7
  import { ComboboxRoot, ComboboxArrow, ComboboxAnchor, ComboboxInput, ComboboxTrigger, ComboboxCancel, ComboboxPortal, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxVirtualizer, ComboboxLabel, ComboboxSeparator, ComboboxItem, ComboboxItemIndicator, FocusScope } from "reka-ui";
8
8
  import { useForwardProps } from "../composables/useForwardProps";
9
9
  import { defu } from "defu";
@@ -199,7 +199,9 @@ function onUpdate(value) {
199
199
  searchTerm.value = "";
200
200
  }
201
201
  }
202
+ const isOpen = ref(false);
202
203
  function onUpdateOpen(value) {
204
+ isOpen.value = value;
203
205
  let timeoutId;
204
206
  if (!value) {
205
207
  const event = new FocusEvent("blur");
@@ -246,6 +248,14 @@ function onClear() {
246
248
  emits("clear");
247
249
  }
248
250
  const viewportRef = useTemplateRef("viewportRef");
251
+ const comboboxRootRef = useTemplateRef("comboboxRootRef");
252
+ watch(() => props.items, async () => {
253
+ if (!isOpen.value) {
254
+ return;
255
+ }
256
+ await nextTick();
257
+ comboboxRootRef.value?.highlightFirstItem?.();
258
+ }, { flush: "post" });
249
259
  defineExpose({
250
260
  triggerRef: toRef(() => triggerRef.value?.$el),
251
261
  viewportRef: toRef(() => viewportRef.value)
@@ -325,6 +335,7 @@ defineExpose({
325
335
 
326
336
  <ComboboxRoot
327
337
  :id="id"
338
+ ref="comboboxRootRef"
328
339
  v-slot="{ modelValue, open }"
329
340
  v-bind="{ ...rootProps, ...$attrs, ...ariaAttrs }"
330
341
  ignore-filter
@@ -6,7 +6,7 @@ import type { AvatarProps, ButtonProps, IconProps, ProgressProps, LinkPropsKeys
6
6
  import type { StringOrVNode } from '../types/utils';
7
7
  import type { ComponentConfig } from '../types/tv';
8
8
  type Toast = ComponentConfig<typeof theme, AppConfig, 'toast'>;
9
- export interface ToastProps extends Pick<ToastRootProps, 'defaultOpen' | 'open' | 'type' | 'duration'> {
9
+ export interface ToastProps extends Pick<ToastRootProps, 'defaultOpen' | 'open' | 'type'> {
10
10
  /**
11
11
  * The element or component this component should render as.
12
12
  * @defaultValue 'li'
@@ -47,6 +47,13 @@ export interface ToastProps extends Pick<ToastRootProps, 'defaultOpen' | 'open'
47
47
  * `{ size: 'xs' }`{lang="ts-type"}
48
48
  */
49
49
  actions?: ButtonProps[];
50
+ /**
51
+ * The time in milliseconds before the toast automatically closes. Overrides the global `toaster.duration`.
52
+ *
53
+ * Set to `0` to keep the toast open until it's manually closed.
54
+ * @defaultValue 5000
55
+ */
56
+ duration?: number;
50
57
  /**
51
58
  * Display a progress bar showing the toast's remaining duration.
52
59
  * `{ size: 'sm' }`{lang="ts-type"}
@@ -26,13 +26,13 @@ const _props = defineProps({
26
26
  close: { type: [Boolean, Object], required: false, default: true },
27
27
  closeIcon: { type: null, required: false },
28
28
  actions: { type: Array, required: false },
29
+ duration: { type: Number, required: false },
29
30
  progress: { type: [Boolean, Object], required: false, default: true },
30
31
  class: { type: null, required: false },
31
32
  ui: { type: Object, required: false },
32
33
  defaultOpen: { type: Boolean, required: false },
33
34
  open: { type: Boolean, required: false },
34
- type: { type: String, required: false },
35
- duration: { type: Number, required: false }
35
+ type: { type: String, required: false }
36
36
  });
37
37
  const emits = defineEmits(["escapeKeyDown", "pause", "resume", "swipeStart", "swipeMove", "swipeCancel", "swipeEnd", "update:open"]);
38
38
  const slots = defineSlots();
@@ -61,7 +61,7 @@ defineExpose({
61
61
  <template>
62
62
  <ToastRoot
63
63
  ref="rootRef"
64
- v-slot="{ remaining, duration, open }"
64
+ v-slot="{ remaining, duration: totalDuration, open }"
65
65
  v-bind="rootProps"
66
66
  :data-orientation="props.orientation"
67
67
  data-slot="root"
@@ -129,8 +129,8 @@ defineExpose({
129
129
  </div>
130
130
 
131
131
  <UProgress
132
- v-if="props.progress && open && remaining > 0 && duration"
133
- :model-value="remaining / duration * 100"
132
+ v-if="props.progress && open && remaining > 0 && totalDuration"
133
+ :model-value="remaining / totalDuration * 100"
134
134
  :color="props.color"
135
135
  v-bind="typeof props.progress === 'object' ? props.progress : {}"
136
136
  size="sm"
@@ -6,7 +6,7 @@ import type { AvatarProps, ButtonProps, IconProps, ProgressProps, LinkPropsKeys
6
6
  import type { StringOrVNode } from '../types/utils';
7
7
  import type { ComponentConfig } from '../types/tv';
8
8
  type Toast = ComponentConfig<typeof theme, AppConfig, 'toast'>;
9
- export interface ToastProps extends Pick<ToastRootProps, 'defaultOpen' | 'open' | 'type' | 'duration'> {
9
+ export interface ToastProps extends Pick<ToastRootProps, 'defaultOpen' | 'open' | 'type'> {
10
10
  /**
11
11
  * The element or component this component should render as.
12
12
  * @defaultValue 'li'
@@ -47,6 +47,13 @@ export interface ToastProps extends Pick<ToastRootProps, 'defaultOpen' | 'open'
47
47
  * `{ size: 'xs' }`{lang="ts-type"}
48
48
  */
49
49
  actions?: ButtonProps[];
50
+ /**
51
+ * The time in milliseconds before the toast automatically closes. Overrides the global `toaster.duration`.
52
+ *
53
+ * Set to `0` to keep the toast open until it's manually closed.
54
+ * @defaultValue 5000
55
+ */
56
+ duration?: number;
50
57
  /**
51
58
  * Display a progress bar showing the toast's remaining duration.
52
59
  * `{ size: 'sm' }`{lang="ts-type"}
@@ -8326,7 +8326,7 @@ type AppConfigUI = {
8326
8326
  tv?: typeof defaultConfig
8327
8327
  } & TVConfig<typeof ui>
8328
8328
 
8329
- type AppConfigRuntimeUI = DeepRequired<Pick<AppConfigUI, 'colors' | 'icons' | 'tv'>> & Omit<AppConfigUI, 'colors' | 'icons' | 'tv'>
8329
+ type AppConfigRuntimeUI = DeepRequired<Pick<AppConfigUI, 'colors' | 'icons' | 'tv'>> & typeof ui
8330
8330
 
8331
8331
  declare module '@nuxt/schema' {
8332
8332
  interface AppConfigInput {
@@ -8336,7 +8336,7 @@ declare module '@nuxt/schema' {
8336
8336
  */
8337
8337
  ui?: AppConfigUI
8338
8338
  }
8339
- interface AppConfig {
8339
+ interface CustomAppConfig {
8340
8340
  ui: AppConfigRuntimeUI
8341
8341
  }
8342
8342
  }
package/dist/unplugin.mjs CHANGED
@@ -3,7 +3,7 @@ import { join, normalize } from 'pathe';
3
3
  import { createUnplugin } from 'unplugin';
4
4
  import { defu } from 'defu';
5
5
  import tailwind from '@tailwindcss/vite';
6
- import { b as getTemplates, p as publicComposables, d as defaultOptions, r as resolveColors, g as getDefaultConfig } from './shared/ui.BzjkAvk7.mjs';
6
+ import { b as getTemplates, p as publicComposables, d as defaultOptions, r as resolveColors, g as getDefaultConfig } from './shared/ui.C-lVg1QQ.mjs';
7
7
  import fs from 'node:fs';
8
8
  import path from 'node:path';
9
9
  import MagicString from 'magic-string';
package/dist/vite.mjs CHANGED
@@ -4,7 +4,7 @@ import 'pathe';
4
4
  import 'unplugin';
5
5
  import 'defu';
6
6
  import '@tailwindcss/vite';
7
- import './shared/ui.BzjkAvk7.mjs';
7
+ import './shared/ui.C-lVg1QQ.mjs';
8
8
  import '../dist/runtime/utils/index.js';
9
9
  import 'scule';
10
10
  import 'knitwork';
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@nuxt/ui",
3
3
  "description": "A UI Library for Modern Web Apps, powered by Vue & Tailwind CSS.",
4
- "version": "4.8.1",
5
- "packageManager": "pnpm@11.3.0",
4
+ "version": "4.8.2",
5
+ "packageManager": "pnpm@11.5.0",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/nuxt/ui.git"
@@ -129,35 +129,35 @@
129
129
  "dependencies": {
130
130
  "@floating-ui/dom": "^1.7.6",
131
131
  "@iconify/vue": "^5.0.1",
132
- "@internationalized/date": "^3.12.1",
133
- "@internationalized/number": "^3.6.6",
132
+ "@internationalized/date": "^3.12.2",
133
+ "@internationalized/number": "^3.6.7",
134
134
  "@nuxt/fonts": "^0.14.0",
135
135
  "@nuxt/icon": "^2.2.2",
136
- "@nuxt/kit": "^4.4.6",
137
- "@nuxt/schema": "^4.4.6",
136
+ "@nuxt/kit": "^4.4.7",
137
+ "@nuxt/schema": "^4.4.7",
138
138
  "@nuxtjs/color-mode": "^3.5.2",
139
139
  "@standard-schema/spec": "^1.1.0",
140
140
  "@tailwindcss/postcss": "^4.3.0",
141
141
  "@tailwindcss/vite": "^4.3.0",
142
142
  "@tanstack/vue-table": "^8.21.3",
143
- "@tanstack/vue-virtual": "^3.13.25",
144
- "@tiptap/core": "^3.23.6",
145
- "@tiptap/extension-bubble-menu": "^3.23.6",
146
- "@tiptap/extension-code": "^3.23.6",
147
- "@tiptap/extension-collaboration": "^3.23.6",
148
- "@tiptap/extension-drag-handle": "^3.23.6",
149
- "@tiptap/extension-drag-handle-vue-3": "^3.23.6",
150
- "@tiptap/extension-floating-menu": "^3.23.6",
151
- "@tiptap/extension-horizontal-rule": "^3.23.6",
152
- "@tiptap/extension-image": "^3.23.6",
153
- "@tiptap/extension-mention": "^3.23.6",
154
- "@tiptap/extension-node-range": "^3.23.6",
155
- "@tiptap/extension-placeholder": "^3.23.6",
156
- "@tiptap/markdown": "^3.23.6",
157
- "@tiptap/pm": "^3.23.6",
158
- "@tiptap/starter-kit": "^3.23.6",
159
- "@tiptap/suggestion": "^3.23.6",
160
- "@tiptap/vue-3": "^3.23.6",
143
+ "@tanstack/vue-virtual": "^3.13.26",
144
+ "@tiptap/core": "^3.24.0",
145
+ "@tiptap/extension-bubble-menu": "^3.24.0",
146
+ "@tiptap/extension-code": "^3.24.0",
147
+ "@tiptap/extension-collaboration": "^3.24.0",
148
+ "@tiptap/extension-drag-handle": "^3.24.0",
149
+ "@tiptap/extension-drag-handle-vue-3": "^3.24.0",
150
+ "@tiptap/extension-floating-menu": "^3.24.0",
151
+ "@tiptap/extension-horizontal-rule": "^3.24.0",
152
+ "@tiptap/extension-image": "^3.24.0",
153
+ "@tiptap/extension-mention": "^3.24.0",
154
+ "@tiptap/extension-node-range": "^3.24.0",
155
+ "@tiptap/extension-placeholder": "^3.24.0",
156
+ "@tiptap/markdown": "^3.24.0",
157
+ "@tiptap/pm": "^3.24.0",
158
+ "@tiptap/starter-kit": "^3.24.0",
159
+ "@tiptap/suggestion": "^3.24.0",
160
+ "@tiptap/vue-3": "^3.24.0",
161
161
  "@unhead/vue": "^2.1.15",
162
162
  "@vueuse/core": "^14.3.0",
163
163
  "@vueuse/integrations": "^14.3.0",
@@ -172,7 +172,7 @@
172
172
  "embla-carousel-fade": "^8.6.0",
173
173
  "embla-carousel-vue": "^8.6.0",
174
174
  "embla-carousel-wheel-gestures": "^8.1.0",
175
- "fuse.js": "^7.3.0",
175
+ "fuse.js": "^7.4.0",
176
176
  "hookable": "^6.1.1",
177
177
  "knitwork": "^1.3.0",
178
178
  "magic-string": "^0.30.21",
@@ -180,18 +180,18 @@
180
180
  "motion-v": "^2.2.1",
181
181
  "ohash": "^2.0.11",
182
182
  "pathe": "^2.0.3",
183
- "reka-ui": "2.9.8",
183
+ "reka-ui": "2.9.9",
184
184
  "scule": "^1.3.0",
185
185
  "tailwind-merge": "^3.6.0",
186
186
  "tailwind-variants": "^3.2.2",
187
187
  "tailwindcss": "^4.3.0",
188
- "tinyglobby": "^0.2.16",
188
+ "tinyglobby": "^0.2.17",
189
189
  "ufo": "^1.6.4",
190
190
  "unplugin": "^3.0.0",
191
191
  "unplugin-auto-import": "^21.0.0",
192
192
  "unplugin-vue-components": "^32.1.0",
193
193
  "vaul-vue": "0.4.1",
194
- "vue-component-type-helpers": "^3.3.0"
194
+ "vue-component-type-helpers": "^3.3.3"
195
195
  },
196
196
  "devDependencies": {
197
197
  "@nuxt/eslint-config": "^1.15.2",
@@ -201,18 +201,18 @@
201
201
  "@tanstack/table-core": "^8.21.3",
202
202
  "@vitejs/plugin-vue": "^6.0.7",
203
203
  "@vue/test-utils": "^2.4.10",
204
- "ai": "^6.0.191",
204
+ "ai": "^6.0.193",
205
205
  "embla-carousel": "^8.6.0",
206
- "eslint": "^10.4.0",
206
+ "eslint": "^10.4.1",
207
207
  "happy-dom": "^20.9.0",
208
- "nuxt": "^4.4.6",
208
+ "nuxt": "^4.4.7",
209
209
  "release-it": "^19.2.4",
210
210
  "unbuild": "^3.6.1",
211
211
  "vitest": "^4.1.7",
212
212
  "vitest-axe": "^0.1.0",
213
- "vitest-environment-nuxt": "^1.0.1",
214
- "vue": "^3.5.34",
215
- "vue-tsc": "^3.3.0"
213
+ "vitest-environment-nuxt": "^2.0.0",
214
+ "vue": "^3.5.35",
215
+ "vue-tsc": "^3.3.3"
216
216
  },
217
217
  "peerDependencies": {
218
218
  "@inertiajs/vue3": "^2.0.7 || ^3.0.0",