@nuxt/ui 4.11.1 → 4.11.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.
Files changed (85) hide show
  1. package/README.md +3 -3
  2. package/dist/module.json +1 -1
  3. package/dist/module.mjs +2 -2
  4. package/dist/runtime/components/Accordion.d.vue.ts +1 -1
  5. package/dist/runtime/components/Accordion.vue.d.ts +1 -1
  6. package/dist/runtime/components/Breadcrumb.d.vue.ts +1 -1
  7. package/dist/runtime/components/Breadcrumb.vue.d.ts +1 -1
  8. package/dist/runtime/components/Carousel.d.vue.ts +1 -1
  9. package/dist/runtime/components/Carousel.vue.d.ts +1 -1
  10. package/dist/runtime/components/CheckboxGroup.d.vue.ts +1 -1
  11. package/dist/runtime/components/CheckboxGroup.vue.d.ts +1 -1
  12. package/dist/runtime/components/CommandPalette.d.vue.ts +1 -1
  13. package/dist/runtime/components/CommandPalette.vue.d.ts +1 -1
  14. package/dist/runtime/components/ContextMenu.d.vue.ts +1 -1
  15. package/dist/runtime/components/ContextMenu.vue.d.ts +1 -1
  16. package/dist/runtime/components/DashboardNavbar.vue +1 -1
  17. package/dist/runtime/components/DropdownMenu.d.vue.ts +1 -1
  18. package/dist/runtime/components/DropdownMenu.vue.d.ts +1 -1
  19. package/dist/runtime/components/FooterColumns.d.vue.ts +1 -1
  20. package/dist/runtime/components/FooterColumns.vue.d.ts +1 -1
  21. package/dist/runtime/components/Form.vue +1 -1
  22. package/dist/runtime/components/Input.vue +5 -5
  23. package/dist/runtime/components/InputDate.vue +12 -6
  24. package/dist/runtime/components/InputMenu.d.vue.ts +1 -1
  25. package/dist/runtime/components/InputMenu.vue +18 -7
  26. package/dist/runtime/components/InputMenu.vue.d.ts +1 -1
  27. package/dist/runtime/components/InputTime.vue +12 -6
  28. package/dist/runtime/components/LinkBase.vue +3 -1
  29. package/dist/runtime/components/Listbox.d.vue.ts +1 -1
  30. package/dist/runtime/components/Listbox.vue.d.ts +1 -1
  31. package/dist/runtime/components/NavigationMenu.d.vue.ts +1 -1
  32. package/dist/runtime/components/NavigationMenu.vue.d.ts +1 -1
  33. package/dist/runtime/components/PageAnchors.d.vue.ts +1 -1
  34. package/dist/runtime/components/PageAnchors.vue.d.ts +1 -1
  35. package/dist/runtime/components/PageLinks.d.vue.ts +1 -1
  36. package/dist/runtime/components/PageLinks.vue.d.ts +1 -1
  37. package/dist/runtime/components/PinInput.d.vue.ts +3 -1
  38. package/dist/runtime/components/PinInput.vue +15 -7
  39. package/dist/runtime/components/PinInput.vue.d.ts +3 -1
  40. package/dist/runtime/components/ProgressGroup.d.vue.ts +1 -1
  41. package/dist/runtime/components/ProgressGroup.vue.d.ts +1 -1
  42. package/dist/runtime/components/RadioGroup.d.vue.ts +1 -1
  43. package/dist/runtime/components/RadioGroup.vue.d.ts +1 -1
  44. package/dist/runtime/components/Select.d.vue.ts +1 -1
  45. package/dist/runtime/components/Select.vue.d.ts +1 -1
  46. package/dist/runtime/components/SelectMenu.d.vue.ts +1 -1
  47. package/dist/runtime/components/SelectMenu.vue +15 -2
  48. package/dist/runtime/components/SelectMenu.vue.d.ts +1 -1
  49. package/dist/runtime/components/Splitter.d.vue.ts +1 -1
  50. package/dist/runtime/components/Splitter.vue.d.ts +1 -1
  51. package/dist/runtime/components/Stepper.d.vue.ts +1 -1
  52. package/dist/runtime/components/Stepper.vue.d.ts +1 -1
  53. package/dist/runtime/components/Table.vue +24 -2
  54. package/dist/runtime/components/Tabs.d.vue.ts +1 -1
  55. package/dist/runtime/components/Tabs.vue.d.ts +1 -1
  56. package/dist/runtime/components/Textarea.vue +5 -5
  57. package/dist/runtime/components/Timeline.d.vue.ts +1 -1
  58. package/dist/runtime/components/Timeline.vue.d.ts +1 -1
  59. package/dist/runtime/components/Toaster.vue +1 -1
  60. package/dist/runtime/components/Tree.d.vue.ts +1 -1
  61. package/dist/runtime/components/Tree.vue +1 -1
  62. package/dist/runtime/components/Tree.vue.d.ts +1 -1
  63. package/dist/runtime/components/content/ContentNavigation.d.vue.ts +1 -1
  64. package/dist/runtime/components/content/ContentNavigation.vue.d.ts +1 -1
  65. package/dist/runtime/components/content/ContentSurround.d.vue.ts +1 -1
  66. package/dist/runtime/components/content/ContentSurround.vue.d.ts +1 -1
  67. package/dist/runtime/components/content/ContentToc.d.vue.ts +1 -1
  68. package/dist/runtime/components/content/ContentToc.vue.d.ts +1 -1
  69. package/dist/runtime/composables/useForwardProps.js +2 -2
  70. package/dist/runtime/composables/useResizable.js +1 -1
  71. package/dist/runtime/utils/virtualizer.d.ts +1 -1
  72. package/dist/runtime/utils/virtualizer.js +9 -11
  73. package/dist/runtime/vue/overrides/inertia/LinkBase.vue +3 -1
  74. package/dist/shared/{ui.DCJ9twx8.mjs → ui.oNygBd3N.mjs} +28 -1
  75. package/dist/unplugin.d.mts +2 -1
  76. package/dist/unplugin.mjs +22 -10
  77. package/dist/vite.mjs +1 -1
  78. package/package.json +55 -59
  79. package/cli/commands/make/component.mjs +0 -86
  80. package/cli/commands/make/index.mjs +0 -14
  81. package/cli/commands/make/locale.mjs +0 -93
  82. package/cli/index.mjs +0 -15
  83. package/cli/package.json +0 -13
  84. package/cli/templates.mjs +0 -256
  85. package/cli/utils.mjs +0 -50
@@ -36,7 +36,7 @@ const _props = defineProps({
36
36
  required: { type: Boolean, required: false },
37
37
  type: { type: null, required: false, default: "text" }
38
38
  });
39
- const emits = defineEmits(["update:modelValue", "complete", "change", "blur"]);
39
+ const emits = defineEmits(["update:modelValue", "complete", "change", "blur", "focus"]);
40
40
  defineSlots();
41
41
  const props = useComponentProps("pinInput", _props);
42
42
  const appConfig = useAppConfig();
@@ -62,11 +62,19 @@ function onComplete(value) {
62
62
  emits("change", event);
63
63
  emitFormChange();
64
64
  }
65
- function onBlur(event) {
66
- if (!event.relatedTarget) {
67
- emits("blur", event);
68
- emitFormBlur();
65
+ function onFocusOut(event) {
66
+ if (event.relatedTarget && event.currentTarget.contains(event.relatedTarget)) {
67
+ return;
69
68
  }
69
+ emits("blur", event);
70
+ emitFormBlur();
71
+ }
72
+ function onFocusIn(event) {
73
+ if (event.relatedTarget && event.currentTarget.contains(event.relatedTarget)) {
74
+ return;
75
+ }
76
+ emits("focus", event);
77
+ emitFormFocus();
70
78
  }
71
79
  function autoFocus() {
72
80
  if (props.autofocus) {
@@ -111,6 +119,8 @@ defineExpose({
111
119
  :class="ui.root({ class: [props.ui?.root, props.class] })"
112
120
  @update:model-value="emitFormInput()"
113
121
  @complete="onComplete"
122
+ @focusout="onFocusOut"
123
+ @focusin="onFocusIn"
114
124
  >
115
125
  <template v-for="(ids, index) in looseToNumber(props.length)" :key="ids">
116
126
  <PinInputInput
@@ -119,8 +129,6 @@ defineExpose({
119
129
  data-slot="base"
120
130
  :class="ui.base({ class: props.ui?.base })"
121
131
  :disabled="disabled"
122
- @blur="onBlur"
123
- @focus="emitFormFocus"
124
132
  />
125
133
  <span
126
134
  v-if="shouldInsertSeparator(index)"
@@ -46,6 +46,7 @@ export interface PinInputProps<T extends PinInputType = 'text'> extends Pick<Pin
46
46
  export type PinInputEmits<T extends PinInputType = 'text'> = PinInputRootEmits<T> & {
47
47
  change: [event: Event];
48
48
  blur: [event: Event];
49
+ focus: [event: Event];
49
50
  };
50
51
  export interface PinInputSlots {
51
52
  separator?(props: {
@@ -58,6 +59,7 @@ declare const __VLS_export: <T extends PinInputType>(__VLS_props: NonNullable<Aw
58
59
  props: import("vue").PublicProps & __VLS_PrettifyLocal<PinInputProps<T> & {
59
60
  onBlur?: ((event: Event) => any) | undefined;
60
61
  onChange?: ((event: Event) => any) | undefined;
62
+ onFocus?: ((event: Event) => any) | undefined;
61
63
  "onUpdate:modelValue"?: ((value: [T] extends ["number"] ? number[] : string[]) => any) | undefined;
62
64
  onComplete?: ((value: [T] extends ["number"] ? number[] : string[]) => any) | undefined;
63
65
  }> & (typeof globalThis extends {
@@ -68,7 +70,7 @@ declare const __VLS_export: <T extends PinInputType>(__VLS_props: NonNullable<Aw
68
70
  }>) => void;
69
71
  attrs: any;
70
72
  slots: PinInputSlots;
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);
73
+ emit: ((evt: "blur", event: Event) => void) & ((evt: "change", event: Event) => void) & ((evt: "focus", event: Event) => void) & ((evt: "update:modelValue", value: [T] extends ["number"] ? number[] : string[]) => void) & ((evt: "complete", value: [T] extends ["number"] ? number[] : string[]) => void);
72
74
  }>) => import("vue").VNode & {
73
75
  __ctx?: NonNullable<Awaited<typeof __VLS_setup>>;
74
76
  };
@@ -20,7 +20,7 @@ export interface ProgressGroupItem {
20
20
  color?: ProgressGroup['variants']['color'] | (string & {});
21
21
  slot?: string;
22
22
  class?: any;
23
- ui?: Pick<ProgressGroup['slots'], 'segment' | 'indicator' | 'item' | 'itemLeadingIcon' | 'itemLeadingDot' | 'itemLabel' | 'itemTrailing'>;
23
+ ui?: Partial<Pick<ProgressGroup['slots'], 'segment' | 'indicator' | 'item' | 'itemLeadingIcon' | 'itemLeadingDot' | 'itemLabel' | 'itemTrailing'>>;
24
24
  [key: string]: any;
25
25
  }
26
26
  export interface ProgressGroupProps<T extends ProgressGroupItem = ProgressGroupItem> {
@@ -20,7 +20,7 @@ export interface ProgressGroupItem {
20
20
  color?: ProgressGroup['variants']['color'] | (string & {});
21
21
  slot?: string;
22
22
  class?: any;
23
- ui?: Pick<ProgressGroup['slots'], 'segment' | 'indicator' | 'item' | 'itemLeadingIcon' | 'itemLeadingDot' | 'itemLabel' | 'itemTrailing'>;
23
+ ui?: Partial<Pick<ProgressGroup['slots'], 'segment' | 'indicator' | 'item' | 'itemLeadingIcon' | 'itemLeadingDot' | 'itemLabel' | 'itemTrailing'>>;
24
24
  [key: string]: any;
25
25
  }
26
26
  export interface ProgressGroupProps<T extends ProgressGroupItem = ProgressGroupItem> {
@@ -18,7 +18,7 @@ export type RadioGroupItem = RadioGroupValue | {
18
18
  */
19
19
  icon?: IconProps['name'];
20
20
  class?: any;
21
- ui?: Pick<RadioGroup['slots'], 'item' | 'container' | 'base' | 'indicator' | 'wrapper' | 'label' | 'icon' | 'description'>;
21
+ ui?: Partial<Pick<RadioGroup['slots'], 'item' | 'container' | 'base' | 'indicator' | 'wrapper' | 'label' | 'icon' | 'description'>>;
22
22
  [key: string]: any;
23
23
  };
24
24
  export interface RadioGroupProps<T extends RadioGroupItem[] = RadioGroupItem[], VK extends GetItemKeys<T> = 'value'> extends Pick<RadioGroupRootProps, 'disabled' | 'loop' | 'name' | 'required'> {
@@ -18,7 +18,7 @@ export type RadioGroupItem = RadioGroupValue | {
18
18
  */
19
19
  icon?: IconProps['name'];
20
20
  class?: any;
21
- ui?: Pick<RadioGroup['slots'], 'item' | 'container' | 'base' | 'indicator' | 'wrapper' | 'label' | 'icon' | 'description'>;
21
+ ui?: Partial<Pick<RadioGroup['slots'], 'item' | 'container' | 'base' | 'indicator' | 'wrapper' | 'label' | 'icon' | 'description'>>;
22
22
  [key: string]: any;
23
23
  };
24
24
  export interface RadioGroupProps<T extends RadioGroupItem[] = RadioGroupItem[], VK extends GetItemKeys<T> = 'value'> extends Pick<RadioGroupRootProps, 'disabled' | 'loop' | 'name' | 'required'> {
@@ -30,7 +30,7 @@ export type SelectItem = SelectValue | {
30
30
  disabled?: boolean;
31
31
  onSelect?: (e: Event) => void;
32
32
  class?: any;
33
- ui?: Pick<Select['slots'], 'label' | 'separator' | 'item' | 'itemLeadingIcon' | 'itemLeadingAvatarSize' | 'itemLeadingAvatar' | 'itemLeadingChipSize' | 'itemLeadingChip' | 'itemWrapper' | 'itemLabel' | 'itemDescription' | 'itemTrailing' | 'itemTrailingIcon'>;
33
+ ui?: Partial<Pick<Select['slots'], 'label' | 'separator' | 'item' | 'itemLeadingIcon' | 'itemLeadingAvatarSize' | 'itemLeadingAvatar' | 'itemLeadingChipSize' | 'itemLeadingChip' | 'itemWrapper' | 'itemLabel' | 'itemDescription' | 'itemTrailing' | 'itemTrailingIcon'>>;
34
34
  [key: string]: any;
35
35
  };
36
36
  type ExcludeItem = {
@@ -30,7 +30,7 @@ export type SelectItem = SelectValue | {
30
30
  disabled?: boolean;
31
31
  onSelect?: (e: Event) => void;
32
32
  class?: any;
33
- ui?: Pick<Select['slots'], 'label' | 'separator' | 'item' | 'itemLeadingIcon' | 'itemLeadingAvatarSize' | 'itemLeadingAvatar' | 'itemLeadingChipSize' | 'itemLeadingChip' | 'itemWrapper' | 'itemLabel' | 'itemDescription' | 'itemTrailing' | 'itemTrailingIcon'>;
33
+ ui?: Partial<Pick<Select['slots'], 'label' | 'separator' | 'item' | 'itemLeadingIcon' | 'itemLeadingAvatarSize' | 'itemLeadingAvatar' | 'itemLeadingChipSize' | 'itemLeadingChip' | 'itemWrapper' | 'itemLabel' | 'itemDescription' | 'itemTrailing' | 'itemTrailingIcon'>>;
34
34
  [key: string]: any;
35
35
  };
36
36
  type ExcludeItem = {
@@ -32,7 +32,7 @@ export type SelectMenuItem = SelectMenuValue | {
32
32
  disabled?: boolean;
33
33
  onSelect?: (e: Event) => void;
34
34
  class?: any;
35
- ui?: Pick<SelectMenu['slots'], 'label' | 'separator' | 'item' | 'itemLeadingIcon' | 'itemLeadingAvatarSize' | 'itemLeadingAvatar' | 'itemLeadingChipSize' | 'itemLeadingChip' | 'itemWrapper' | 'itemLabel' | 'itemDescription' | 'itemTrailing' | 'itemTrailingIcon'>;
35
+ ui?: Partial<Pick<SelectMenu['slots'], 'label' | 'separator' | 'item' | 'itemLeadingIcon' | 'itemLeadingAvatarSize' | 'itemLeadingAvatar' | 'itemLeadingChipSize' | 'itemLeadingChip' | 'itemWrapper' | 'itemLabel' | 'itemDescription' | 'itemTrailing' | 'itemTrailingIcon'>>;
36
36
  [key: string]: any;
37
37
  };
38
38
  type ExcludeItem = {
@@ -237,6 +237,14 @@ function onUpdateOpen(value) {
237
237
  clearTimeout(timeoutId);
238
238
  }
239
239
  }
240
+ function onTriggerKeydown(e) {
241
+ if (isOpen.value) {
242
+ return;
243
+ }
244
+ const trigger = e.currentTarget;
245
+ e.preventDefault();
246
+ trigger.click();
247
+ }
240
248
  function onCreate(e) {
241
249
  e.preventDefault();
242
250
  e.stopPropagation();
@@ -262,6 +270,9 @@ function isModelValueEmpty(modelValue) {
262
270
  return modelValue === void 0 || modelValue === null || modelValue === "";
263
271
  }
264
272
  function onClear() {
273
+ if (disabled.value) {
274
+ return;
275
+ }
265
276
  emits("clear");
266
277
  }
267
278
  function onMountAutoFocus(event) {
@@ -373,7 +384,9 @@ defineExpose({
373
384
  data-slot="base"
374
385
  :class="ui.base({ class: [props.ui?.base, props.class] })"
375
386
  tabindex="0"
376
- v-bind="{ ...$attrs, ...ariaAttrs }"
387
+ v-bind="{ 'aria-label': void 0, ...$attrs, ...ariaAttrs }"
388
+ @keydown.down="onTriggerKeydown"
389
+ @keydown.up="onTriggerKeydown"
377
390
  >
378
391
  <span v-if="isLeading || !!props.avatar || !!slots.leading" data-slot="leading" :class="ui.leading({ class: props.ui?.leading })">
379
392
  <slot name="leading" :model-value="modelValue" :open="open" :ui="ui">
@@ -395,7 +408,7 @@ defineExpose({
395
408
 
396
409
  <span v-if="isTrailing || !!slots.trailing || !!props.clear" data-slot="trailing" :class="ui.trailing({ class: props.ui?.trailing })">
397
410
  <slot name="trailing" :model-value="modelValue" :open="open" :ui="ui">
398
- <ComboboxCancel v-if="!!props.clear && !isModelValueEmpty(modelValue)" as-child>
411
+ <ComboboxCancel v-if="!!props.clear && !disabled && !isModelValueEmpty(modelValue)" as-child>
399
412
  <UButton
400
413
  as="span"
401
414
  :icon="props.clearIcon || appConfig.ui.icons.close"
@@ -32,7 +32,7 @@ export type SelectMenuItem = SelectMenuValue | {
32
32
  disabled?: boolean;
33
33
  onSelect?: (e: Event) => void;
34
34
  class?: any;
35
- ui?: Pick<SelectMenu['slots'], 'label' | 'separator' | 'item' | 'itemLeadingIcon' | 'itemLeadingAvatarSize' | 'itemLeadingAvatar' | 'itemLeadingChipSize' | 'itemLeadingChip' | 'itemWrapper' | 'itemLabel' | 'itemDescription' | 'itemTrailing' | 'itemTrailingIcon'>;
35
+ ui?: Partial<Pick<SelectMenu['slots'], 'label' | 'separator' | 'item' | 'itemLeadingIcon' | 'itemLeadingAvatarSize' | 'itemLeadingAvatar' | 'itemLeadingChipSize' | 'itemLeadingChip' | 'itemWrapper' | 'itemLabel' | 'itemDescription' | 'itemTrailing' | 'itemTrailingIcon'>>;
36
36
  [key: string]: any;
37
37
  };
38
38
  type ExcludeItem = {
@@ -12,7 +12,7 @@ export interface SplitterItem extends Omit<SplitterPanelProps, 'as' | 'asChild'>
12
12
  id?: string;
13
13
  slot?: string;
14
14
  class?: any;
15
- ui?: Pick<Splitter['slots'], 'panel'>;
15
+ ui?: Partial<Pick<Splitter['slots'], 'panel'>>;
16
16
  [key: string]: any;
17
17
  }
18
18
  export interface SplitterProps<T extends SplitterItem = SplitterItem> extends Pick<SplitterGroupProps, 'autoSaveId' | 'keyboardResizeBy' | 'storage'>, Pick<SplitterResizeHandleProps, 'hitAreaMargins'> {
@@ -12,7 +12,7 @@ export interface SplitterItem extends Omit<SplitterPanelProps, 'as' | 'asChild'>
12
12
  id?: string;
13
13
  slot?: string;
14
14
  class?: any;
15
- ui?: Pick<Splitter['slots'], 'panel'>;
15
+ ui?: Partial<Pick<Splitter['slots'], 'panel'>>;
16
16
  [key: string]: any;
17
17
  }
18
18
  export interface SplitterProps<T extends SplitterItem = SplitterItem> extends Pick<SplitterGroupProps, 'autoSaveId' | 'keyboardResizeBy' | 'storage'>, Pick<SplitterResizeHandleProps, 'hitAreaMargins'> {
@@ -18,7 +18,7 @@ export interface StepperItem {
18
18
  content?: string;
19
19
  disabled?: boolean;
20
20
  class?: any;
21
- ui?: Pick<Stepper['slots'], 'item' | 'container' | 'trigger' | 'indicator' | 'icon' | 'separator' | 'wrapper' | 'title' | 'description'>;
21
+ ui?: Partial<Pick<Stepper['slots'], 'item' | 'container' | 'trigger' | 'indicator' | 'icon' | 'separator' | 'wrapper' | 'title' | 'description'>>;
22
22
  [key: string]: any;
23
23
  }
24
24
  export interface StepperProps<T extends StepperItem = StepperItem> extends Pick<StepperRootProps, 'linear'> {
@@ -18,7 +18,7 @@ export interface StepperItem {
18
18
  content?: string;
19
19
  disabled?: boolean;
20
20
  class?: any;
21
- ui?: Pick<Stepper['slots'], 'item' | 'container' | 'trigger' | 'indicator' | 'icon' | 'separator' | 'wrapper' | 'title' | 'description'>;
21
+ ui?: Partial<Pick<Stepper['slots'], 'item' | 'container' | 'trigger' | 'indicator' | 'icon' | 'separator' | 'wrapper' | 'title' | 'description'>>;
22
22
  [key: string]: any;
23
23
  }
24
24
  export interface StepperProps<T extends StepperItem = StepperItem> extends Pick<StepperRootProps, 'linear'> {
@@ -259,12 +259,15 @@ function onRowSelect(e, row) {
259
259
  return;
260
260
  }
261
261
  const target = e.target;
262
- const isInteractive = target.closest("button") || target.closest("a");
262
+ const isInteractive = target.closest("a, button, input, label, select, textarea");
263
263
  if (isInteractive) {
264
264
  return;
265
265
  }
266
266
  e.preventDefault();
267
267
  e.stopPropagation();
268
+ if (e.repeat) {
269
+ return;
270
+ }
268
271
  props.onSelect(e, row);
269
272
  }
270
273
  function onRowHover(e, row) {
@@ -299,6 +302,24 @@ function getColumnStyles(column) {
299
302
  }
300
303
  return styles;
301
304
  }
305
+ function isSortable(column) {
306
+ return column.columnDef.enableSorting === true && column.getCanSort();
307
+ }
308
+ function getAriaSort(header) {
309
+ if (header.isPlaceholder || !isSortable(header.column)) {
310
+ return void 0;
311
+ }
312
+ const sorted = header.column.getIsSorted();
313
+ if (!sorted) {
314
+ return "none";
315
+ }
316
+ const sortableIds = new Set(tableApi.getVisibleLeafColumns().filter(isSortable).map((column) => column.id));
317
+ const primary = tableApi.getState().sorting.find(({ id }) => sortableIds.has(id));
318
+ if (primary?.id !== header.column.id) {
319
+ return "none";
320
+ }
321
+ return sorted === "asc" ? "ascending" : "descending";
322
+ }
302
323
  watch(() => props.data, () => {
303
324
  data.value = props.data ? [...props.data] : [];
304
325
  }, props.watchOptions);
@@ -318,7 +339,6 @@ defineExpose({
318
339
  :data-selectable="!!props.onSelect || !!props.onHover || !!props.onContextmenu"
319
340
  :data-expanded="row.getIsExpanded()"
320
341
  :data-pinned="row.getIsPinned() || void 0"
321
- :role="props.onSelect ? 'button' : void 0"
322
342
  :tabindex="props.onSelect ? 0 : void 0"
323
343
  data-slot="tr"
324
344
  :class="ui.tr({
@@ -329,6 +349,7 @@ defineExpose({
329
349
  })"
330
350
  :style="[resolveValue(tableApi.options.meta?.style?.tr, row), style]"
331
351
  @click="onRowSelect($event, row)"
352
+ @keydown.self.exact.enter.space="onRowSelect($event, row)"
332
353
  @pointerenter="onRowHover($event, row)"
333
354
  @pointerleave="onRowHover($event, null)"
334
355
  @contextmenu="onRowContextmenu($event, row)"
@@ -382,6 +403,7 @@ defineExpose({
382
403
  :scope="header.colSpan > 1 ? 'colgroup' : 'col'"
383
404
  :colspan="header.colSpan > 1 ? header.colSpan : void 0"
384
405
  :rowspan="header.rowSpan > 1 ? header.rowSpan : void 0"
406
+ :aria-sort="getAriaSort(header)"
385
407
  data-slot="th"
386
408
  :class="ui.th({
387
409
  class: [
@@ -30,7 +30,7 @@ export interface TabsItem {
30
30
  value?: string | number;
31
31
  disabled?: boolean;
32
32
  class?: any;
33
- ui?: Pick<Tabs['slots'], 'trigger' | 'leadingIcon' | 'leadingAvatar' | 'leadingAvatarSize' | 'label' | 'trailingBadge' | 'trailingBadgeSize' | 'content'>;
33
+ ui?: Partial<Pick<Tabs['slots'], 'trigger' | 'leadingIcon' | 'leadingAvatar' | 'leadingAvatarSize' | 'label' | 'trailingBadge' | 'trailingBadgeSize' | 'content'>>;
34
34
  [key: string]: any;
35
35
  }
36
36
  export interface TabsProps<T extends TabsItem = TabsItem> extends Pick<TabsRootProps<string | number>, 'defaultValue' | 'modelValue' | 'activationMode' | 'unmountOnHide'> {
@@ -30,7 +30,7 @@ export interface TabsItem {
30
30
  value?: string | number;
31
31
  disabled?: boolean;
32
32
  class?: any;
33
- ui?: Pick<Tabs['slots'], 'trigger' | 'leadingIcon' | 'leadingAvatar' | 'leadingAvatarSize' | 'label' | 'trailingBadge' | 'trailingBadgeSize' | 'content'>;
33
+ ui?: Partial<Pick<Tabs['slots'], 'trigger' | 'leadingIcon' | 'leadingAvatar' | 'leadingAvatarSize' | 'label' | 'trailingBadge' | 'trailingBadgeSize' | 'content'>>;
34
34
  [key: string]: any;
35
35
  }
36
36
  export interface TabsProps<T extends TabsItem = TabsItem> extends Pick<TabsRootProps<string | number>, 'defaultValue' | 'modelValue' | 'activationMode' | 'unmountOnHide'> {
@@ -10,7 +10,7 @@ import { useAppConfig } from "#imports";
10
10
  import { useComponentProps } from "../composables/useComponentProps";
11
11
  import { useComponentIcons } from "../composables/useComponentIcons";
12
12
  import { useFormField } from "../composables/useFormField";
13
- import { looseToNumber } from "../utils";
13
+ import { isEmpty, looseToNumber } from "../utils";
14
14
  import { tv } from "../utils/tv";
15
15
  import UIcon from "./Icon.vue";
16
16
  import UAvatar from "./Avatar.vue";
@@ -77,11 +77,11 @@ function updateInput(value) {
77
77
  if (props.modelModifiers?.number) {
78
78
  value = looseToNumber(value);
79
79
  }
80
- if (props.modelModifiers?.nullable) {
81
- value ||= null;
80
+ if (props.modelModifiers?.nullable && isEmpty(value)) {
81
+ value = null;
82
82
  }
83
- if (props.modelModifiers?.optional && !props.modelModifiers?.nullable && value !== null) {
84
- value ||= void 0;
83
+ if (props.modelModifiers?.optional && !props.modelModifiers?.nullable && value !== null && isEmpty(value)) {
84
+ value = void 0;
85
85
  }
86
86
  modelValue.value = value;
87
87
  emitFormInput();
@@ -15,7 +15,7 @@ export interface TimelineItem {
15
15
  value?: string | number;
16
16
  slot?: string;
17
17
  class?: any;
18
- ui?: Pick<Timeline['slots'], 'item' | 'container' | 'indicator' | 'separator' | 'wrapper' | 'date' | 'title' | 'description'>;
18
+ ui?: Partial<Pick<Timeline['slots'], 'item' | 'container' | 'indicator' | 'separator' | 'wrapper' | 'date' | 'title' | 'description'>>;
19
19
  [key: string]: any;
20
20
  }
21
21
  export interface TimelineProps<T extends TimelineItem = TimelineItem> {
@@ -15,7 +15,7 @@ export interface TimelineItem {
15
15
  value?: string | number;
16
16
  slot?: string;
17
17
  class?: any;
18
- ui?: Pick<Timeline['slots'], 'item' | 'container' | 'indicator' | 'separator' | 'wrapper' | 'date' | 'title' | 'description'>;
18
+ ui?: Partial<Pick<Timeline['slots'], 'item' | 'container' | 'indicator' | 'separator' | 'wrapper' | 'date' | 'title' | 'description'>>;
19
19
  [key: string]: any;
20
20
  }
21
21
  export interface TimelineProps<T extends TimelineItem = TimelineItem> {
@@ -81,7 +81,7 @@ function getOffset(index) {
81
81
  :key="toast.id"
82
82
  ref="refs"
83
83
  :progress="props.progress"
84
- v-bind="omit(toast, ['id', 'close', '_duplicate', '_updated'])"
84
+ v-bind="omit(toast, ['id', 'close', '_duplicate', '_updated', 'onClick'])"
85
85
  :close="toast.close"
86
86
  :data-expanded="expanded"
87
87
  :data-front="!expanded && index === toasts.length - 1"
@@ -23,7 +23,7 @@ export type TreeItem = {
23
23
  onToggle?: (e: TreeItemToggleEvent<TreeItem>) => void;
24
24
  onSelect?: (e: TreeItemSelectEvent<TreeItem>) => void;
25
25
  class?: any;
26
- ui?: Pick<Tree['slots'], 'item' | 'itemWithChildren' | 'link' | 'linkLeadingIcon' | 'linkLabel' | 'linkTrailing' | 'linkTrailingIcon' | 'listWithChildren'>;
26
+ ui?: Partial<Pick<Tree['slots'], 'item' | 'itemWithChildren' | 'link' | 'linkLeadingIcon' | 'linkLabel' | 'linkTrailing' | 'linkTrailingIcon' | 'listWithChildren'>>;
27
27
  [key: string]: any;
28
28
  };
29
29
  export interface TreeProps<T extends TreeItem[] = TreeItem[], M extends boolean = false> extends Pick<TreeRootProps<T>, 'expanded' | 'defaultExpanded' | 'selectionBehavior' | 'propagateSelect' | 'disabled' | 'bubbleSelect'> {
@@ -66,7 +66,7 @@ const flattenedPaddingFormula = computed(() => {
66
66
  xl: { base: 3, perLevel: 7.5 }
67
67
  // px-3, ms-6 + ps-1.5
68
68
  };
69
- const config = sizeConfig[props.size || "md"];
69
+ const config = sizeConfig[props.size] ?? sizeConfig.md;
70
70
  return (level) => `calc(var(--spacing) * ${(level - 1) * config.perLevel + config.base})`;
71
71
  });
72
72
  const virtualizerProps = toRef(() => {
@@ -23,7 +23,7 @@ export type TreeItem = {
23
23
  onToggle?: (e: TreeItemToggleEvent<TreeItem>) => void;
24
24
  onSelect?: (e: TreeItemSelectEvent<TreeItem>) => void;
25
25
  class?: any;
26
- ui?: Pick<Tree['slots'], 'item' | 'itemWithChildren' | 'link' | 'linkLeadingIcon' | 'linkLabel' | 'linkTrailing' | 'linkTrailingIcon' | 'listWithChildren'>;
26
+ ui?: Partial<Pick<Tree['slots'], 'item' | 'itemWithChildren' | 'link' | 'linkLeadingIcon' | 'linkLabel' | 'linkTrailing' | 'linkTrailingIcon' | 'listWithChildren'>>;
27
27
  [key: string]: any;
28
28
  };
29
29
  export interface TreeProps<T extends TreeItem[] = TreeItem[], M extends boolean = false> extends Pick<TreeRootProps<T>, 'expanded' | 'defaultExpanded' | 'selectionBehavior' | 'propagateSelect' | 'disabled' | 'bubbleSelect'> {
@@ -28,7 +28,7 @@ export interface ContentNavigationLink extends ContentNavigationItem {
28
28
  defaultOpen?: boolean;
29
29
  active?: boolean;
30
30
  class?: any;
31
- ui?: Pick<ContentNavigation['slots'], 'link' | 'linkLeadingIcon' | 'linkTitle' | 'linkTrailing' | 'linkTrailingIcon' | 'linkTrailingBadge' | 'linkTrailingBadgeSize' | 'linkTrailingIcon' | 'linkTitleExternalIcon' | 'trigger' | 'content' | 'item' | 'itemWithChildren'>;
31
+ ui?: Partial<Pick<ContentNavigation['slots'], 'link' | 'linkLeadingIcon' | 'linkTitle' | 'linkTrailing' | 'linkTrailingIcon' | 'linkTrailingBadge' | 'linkTrailingBadgeSize' | 'linkTrailingIcon' | 'linkTitleExternalIcon' | 'trigger' | 'content' | 'item' | 'itemWithChildren'>>;
32
32
  }
33
33
  export interface ContentNavigationProps<T extends ContentNavigationLink = ContentNavigationLink> extends Pick<AccordionRootProps, 'disabled' | 'type' | 'unmountOnHide'> {
34
34
  /**
@@ -28,7 +28,7 @@ export interface ContentNavigationLink extends ContentNavigationItem {
28
28
  defaultOpen?: boolean;
29
29
  active?: boolean;
30
30
  class?: any;
31
- ui?: Pick<ContentNavigation['slots'], 'link' | 'linkLeadingIcon' | 'linkTitle' | 'linkTrailing' | 'linkTrailingIcon' | 'linkTrailingBadge' | 'linkTrailingBadgeSize' | 'linkTrailingIcon' | 'linkTitleExternalIcon' | 'trigger' | 'content' | 'item' | 'itemWithChildren'>;
31
+ ui?: Partial<Pick<ContentNavigation['slots'], 'link' | 'linkLeadingIcon' | 'linkTitle' | 'linkTrailing' | 'linkTrailingIcon' | 'linkTrailingBadge' | 'linkTrailingBadgeSize' | 'linkTrailingIcon' | 'linkTitleExternalIcon' | 'trigger' | 'content' | 'item' | 'itemWithChildren'>>;
32
32
  }
33
33
  export interface ContentNavigationProps<T extends ContentNavigationLink = ContentNavigationLink> extends Pick<AccordionRootProps, 'disabled' | 'type' | 'unmountOnHide'> {
34
34
  /**
@@ -12,7 +12,7 @@ export interface ContentSurroundLink extends ContentNavigationItem {
12
12
  */
13
13
  icon?: IconProps['name'];
14
14
  class?: any;
15
- ui?: Pick<ContentSurround['slots'], 'link' | 'linkLeading' | 'linkLeadingIcon' | 'linkTitle' | 'linkDescription'>;
15
+ ui?: Partial<Pick<ContentSurround['slots'], 'link' | 'linkLeading' | 'linkLeadingIcon' | 'linkTitle' | 'linkDescription'>>;
16
16
  }
17
17
  export interface ContentSurroundProps<T extends ContentSurroundLink = ContentSurroundLink> {
18
18
  /**
@@ -12,7 +12,7 @@ export interface ContentSurroundLink extends ContentNavigationItem {
12
12
  */
13
13
  icon?: IconProps['name'];
14
14
  class?: any;
15
- ui?: Pick<ContentSurround['slots'], 'link' | 'linkLeading' | 'linkLeadingIcon' | 'linkTitle' | 'linkDescription'>;
15
+ ui?: Partial<Pick<ContentSurround['slots'], 'link' | 'linkLeading' | 'linkLeadingIcon' | 'linkTitle' | 'linkDescription'>>;
16
16
  }
17
17
  export interface ContentSurroundProps<T extends ContentSurroundLink = ContentSurroundLink> {
18
18
  /**
@@ -8,7 +8,7 @@ import type { ComponentConfig } from '../../types/tv';
8
8
  type ContentToc = ComponentConfig<typeof theme, AppConfig, 'contentToc'>;
9
9
  export type ContentTocLink = TocLink & {
10
10
  class?: any;
11
- ui?: Pick<ContentToc['slots'], 'item' | 'itemWithChildren' | 'link' | 'linkText'>;
11
+ ui?: Partial<Pick<ContentToc['slots'], 'item' | 'itemWithChildren' | 'link' | 'linkText'>>;
12
12
  };
13
13
  export interface ContentTocProps<T extends ContentTocLink = ContentTocLink> extends Pick<CollapsibleRootProps, 'defaultOpen' | 'open'> {
14
14
  /**
@@ -8,7 +8,7 @@ import type { ComponentConfig } from '../../types/tv';
8
8
  type ContentToc = ComponentConfig<typeof theme, AppConfig, 'contentToc'>;
9
9
  export type ContentTocLink = TocLink & {
10
10
  class?: any;
11
- ui?: Pick<ContentToc['slots'], 'item' | 'itemWithChildren' | 'link' | 'linkText'>;
11
+ ui?: Partial<Pick<ContentToc['slots'], 'item' | 'itemWithChildren' | 'link' | 'linkText'>>;
12
12
  };
13
13
  export interface ContentTocProps<T extends ContentTocLink = ContentTocLink> extends Pick<CollapsibleRootProps, 'defaultOpen' | 'open'> {
14
14
  /**
@@ -1,9 +1,9 @@
1
- import { computed, isRef } from "vue";
1
+ import { computed, unref } from "vue";
2
2
  import { useEmitAsProps } from "reka-ui";
3
3
  export function useForwardProps(source, emits) {
4
4
  const emitAsProps = emits ? useEmitAsProps(emits) : {};
5
5
  return computed(() => {
6
- const src = isRef(source) ? source.value : source;
6
+ const src = unref(source);
7
7
  const out = { ...emitAsProps };
8
8
  for (const key in src) {
9
9
  const value = src[key];
@@ -15,7 +15,7 @@ export function useResizable(key, options = {}, { collapsed = ref(false) } = {})
15
15
  collapsedSize: 0,
16
16
  resizable: true,
17
17
  unit: "%",
18
- ...isRef(options) ? options.value : options
18
+ ...unref(options)
19
19
  }));
20
20
  const { dir } = useLocale();
21
21
  const defaultStorageValue = {
@@ -1,4 +1,4 @@
1
1
  /**
2
2
  * Get estimate size for virtualizers that checks each item individually
3
3
  */
4
- export declare function getEstimateSize(items: any[], size: 'xs' | 'sm' | 'md' | 'lg' | 'xl', descriptionKey?: string, hasDescriptionSlot?: boolean): (index: number) => number;
4
+ export declare function getEstimateSize(items: any[], size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | (string & {}), descriptionKey?: string, hasDescriptionSlot?: boolean): (index: number) => number;
@@ -7,22 +7,20 @@ function itemHasDescription(item, descriptionKey) {
7
7
  return value !== void 0 && value !== null && value !== "";
8
8
  }
9
9
  function getSize(size, hasDescription) {
10
- if (hasDescription) {
11
- return {
12
- xs: 44,
13
- sm: 48,
14
- md: 52,
15
- lg: 56,
16
- xl: 60
17
- }[size];
18
- }
19
- return {
10
+ const sizes = hasDescription ? {
11
+ xs: 44,
12
+ sm: 48,
13
+ md: 52,
14
+ lg: 56,
15
+ xl: 60
16
+ } : {
20
17
  xs: 24,
21
18
  sm: 28,
22
19
  md: 32,
23
20
  lg: 36,
24
21
  xl: 40
25
- }[size];
22
+ };
23
+ return sizes[size] ?? sizes.md;
26
24
  }
27
25
  export function getEstimateSize(items, size, descriptionKey, hasDescriptionSlot) {
28
26
  const sizeWithDescription = getSize(size, true);
@@ -23,11 +23,13 @@ function onClickWrapper(e) {
23
23
  e.preventDefault();
24
24
  return;
25
25
  }
26
+ const results = [];
26
27
  if (props.onClick) {
27
28
  for (const onClick of Array.isArray(props.onClick) ? props.onClick : [props.onClick]) {
28
- onClick(e);
29
+ results.push(onClick(e));
29
30
  }
30
31
  }
32
+ return Promise.all(results);
31
33
  }
32
34
  </script>
33
35
 
@@ -581,6 +581,9 @@ const fieldGroup$1 = {
581
581
  horizontal: "inline-flex -space-x-px",
582
582
  vertical: "flex flex-col -space-y-px"
583
583
  }
584
+ },
585
+ defaultVariants: {
586
+ size: "md"
584
587
  }
585
588
  };
586
589
 
@@ -3651,6 +3654,14 @@ const inputMenu = (options) => {
3651
3654
  tagsInput: "flex-1 border-0 bg-transparent placeholder:text-dimmed focus:outline-none disabled:cursor-not-allowed disabled:opacity-75"
3652
3655
  },
3653
3656
  variants: {
3657
+ // `root` and `base` are the same element in `multiple` mode, so the
3658
+ // `group-*` rounding utilities inherited from `input` never match there.
3659
+ // Keep the `group` marker here and pick the right rounding in
3660
+ // `compoundVariants` depending on `multiple`.
3661
+ fieldGroup: {
3662
+ horizontal: () => ({ root: fieldGroupVariantWithRoot.fieldGroup.horizontal.root }),
3663
+ vertical: () => ({ root: fieldGroupVariantWithRoot.fieldGroup.vertical.root })
3664
+ },
3654
3665
  virtualize: {
3655
3666
  true: {
3656
3667
  viewport: "p-1 isolate"
@@ -3731,6 +3742,22 @@ const inputMenu = (options) => {
3731
3742
  }
3732
3743
  },
3733
3744
  compoundVariants: [{
3745
+ multiple: false,
3746
+ fieldGroup: "horizontal",
3747
+ class: { base: fieldGroupVariantWithRoot.fieldGroup.horizontal.base }
3748
+ }, {
3749
+ multiple: false,
3750
+ fieldGroup: "vertical",
3751
+ class: { base: fieldGroupVariantWithRoot.fieldGroup.vertical.base }
3752
+ }, {
3753
+ multiple: true,
3754
+ fieldGroup: "horizontal",
3755
+ class: { base: fieldGroupVariant.fieldGroup.horizontal }
3756
+ }, {
3757
+ multiple: true,
3758
+ fieldGroup: "vertical",
3759
+ class: { base: fieldGroupVariant.fieldGroup.vertical }
3760
+ }, {
3734
3761
  variant: "soft",
3735
3762
  multiple: true,
3736
3763
  class: "has-focus:bg-elevated has-focus-visible:outline-3"
@@ -7005,7 +7032,7 @@ const table$1 = (options) => ({
7005
7032
  base: "min-w-full overflow-clip",
7006
7033
  caption: "sr-only",
7007
7034
  thead: "relative",
7008
- tbody: "isolate [&>tr]:data-[selectable=true]:hover:bg-elevated/50 [&>tr]:data-[selectable=true]:outline-primary/25 [&>tr]:data-[selectable=true]:focus-visible:outline-3 divide-y divide-default",
7035
+ tbody: "isolate [&>tr]:data-[selectable=true]:hover:bg-elevated/50 [&>tr]:data-[selectable=true]:outline-primary/25 [&>tr]:data-[selectable=true]:focus-visible:outline-3 [&>tr]:data-[selectable=true]:-outline-offset-3 divide-y divide-default",
7009
7036
  tfoot: "relative",
7010
7037
  tr: "data-[selected=true]:bg-elevated/50",
7011
7038
  th: "px-4 py-3.5 text-sm text-highlighted text-start font-semibold [&:has([role=checkbox])]:pe-0",