@nuxt/ui 4.8.1 → 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 (101) 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 +42 -6
  8. package/dist/runtime/components/Calendar.vue +180 -61
  9. package/dist/runtime/components/Calendar.vue.d.ts +42 -6
  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/Form.d.vue.ts +3 -3
  30. package/dist/runtime/components/Form.vue +2 -1
  31. package/dist/runtime/components/Form.vue.d.ts +3 -3
  32. package/dist/runtime/components/InputDate.d.vue.ts +2 -2
  33. package/dist/runtime/components/InputDate.vue +1 -0
  34. package/dist/runtime/components/InputDate.vue.d.ts +2 -2
  35. package/dist/runtime/components/InputMenu.vue +12 -1
  36. package/dist/runtime/components/InputNumber.d.vue.ts +1 -1
  37. package/dist/runtime/components/InputNumber.vue +3 -2
  38. package/dist/runtime/components/InputNumber.vue.d.ts +1 -1
  39. package/dist/runtime/components/InputTime.d.vue.ts +2 -2
  40. package/dist/runtime/components/InputTime.vue +1 -0
  41. package/dist/runtime/components/InputTime.vue.d.ts +2 -2
  42. package/dist/runtime/components/Link.d.vue.ts +1 -0
  43. package/dist/runtime/components/Link.vue +1 -1
  44. package/dist/runtime/components/Link.vue.d.ts +1 -0
  45. package/dist/runtime/components/LinkBase.d.vue.ts +1 -1
  46. package/dist/runtime/components/LinkBase.vue +1 -1
  47. package/dist/runtime/components/LinkBase.vue.d.ts +1 -1
  48. package/dist/runtime/components/Modal.d.vue.ts +6 -0
  49. package/dist/runtime/components/Modal.vue +3 -1
  50. package/dist/runtime/components/Modal.vue.d.ts +6 -0
  51. package/dist/runtime/components/PinInput.d.vue.ts +14 -2
  52. package/dist/runtime/components/PinInput.vue +36 -11
  53. package/dist/runtime/components/PinInput.vue.d.ts +14 -2
  54. package/dist/runtime/components/Popover.d.vue.ts +2 -0
  55. package/dist/runtime/components/Popover.vue +2 -2
  56. package/dist/runtime/components/Popover.vue.d.ts +2 -0
  57. package/dist/runtime/components/ScrollArea.d.vue.ts +8 -0
  58. package/dist/runtime/components/ScrollArea.vue +10 -0
  59. package/dist/runtime/components/ScrollArea.vue.d.ts +8 -0
  60. package/dist/runtime/components/Select.vue +8 -1
  61. package/dist/runtime/components/SelectMenu.vue +23 -5
  62. package/dist/runtime/components/Sidebar.d.vue.ts +5 -0
  63. package/dist/runtime/components/Sidebar.vue +3 -1
  64. package/dist/runtime/components/Sidebar.vue.d.ts +5 -0
  65. package/dist/runtime/components/Slideover.d.vue.ts +6 -0
  66. package/dist/runtime/components/Slideover.vue +3 -1
  67. package/dist/runtime/components/Slideover.vue.d.ts +6 -0
  68. package/dist/runtime/components/Toast.d.vue.ts +8 -1
  69. package/dist/runtime/components/Toast.vue +5 -5
  70. package/dist/runtime/components/Toast.vue.d.ts +8 -1
  71. package/dist/runtime/components/content/ContentSearch.d.vue.ts +7 -1
  72. package/dist/runtime/components/content/ContentSearch.vue +9 -2
  73. package/dist/runtime/components/content/ContentSearch.vue.d.ts +7 -1
  74. package/dist/runtime/components/content/ContentSearchButton.d.vue.ts +2 -2
  75. package/dist/runtime/components/content/ContentSearchButton.vue +2 -2
  76. package/dist/runtime/components/content/ContentSearchButton.vue.d.ts +2 -2
  77. package/dist/runtime/components/prose/Kbd.d.vue.ts +2 -1
  78. package/dist/runtime/components/prose/Kbd.vue.d.ts +2 -1
  79. package/dist/runtime/components/prose/Pre.vue +0 -1
  80. package/dist/runtime/composables/index.d.ts +1 -0
  81. package/dist/runtime/composables/index.js +1 -0
  82. package/dist/runtime/composables/useComponentProps.d.ts +3 -3
  83. package/dist/runtime/composables/useTour.d.ts +80 -0
  84. package/dist/runtime/composables/useTour.js +102 -0
  85. package/dist/runtime/index.css +1 -1
  86. package/dist/runtime/keyframes.css +1 -1
  87. package/dist/runtime/locale/index.d.ts +1 -0
  88. package/dist/runtime/locale/index.js +1 -0
  89. package/dist/runtime/locale/lv.d.ts +3 -0
  90. package/dist/runtime/locale/lv.js +152 -0
  91. package/dist/runtime/plugins/colors.js +5 -4
  92. package/dist/runtime/types/tv.d.ts +15 -3
  93. package/dist/runtime/utils/tv.d.ts +41 -1
  94. package/dist/runtime/utils/tv.js +91 -2
  95. package/dist/runtime/vue/stubs/base.d.ts +1 -1
  96. package/dist/runtime/vue/stubs/base.js +1 -1
  97. package/dist/shared/{ui.BzjkAvk7.mjs → ui.BfHSFiIO.mjs} +377 -234
  98. package/dist/unplugin.d.mts +8 -0
  99. package/dist/unplugin.mjs +2 -2
  100. package/dist/vite.mjs +1 -1
  101. package/package.json +61 -44
@@ -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.
@@ -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 (): {
@@ -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'];
@@ -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>;
@@ -22,6 +22,7 @@ const _props = defineProps({
22
22
  autofocusDelay: { type: Number, required: false, default: 0 },
23
23
  highlight: { type: Boolean, required: false },
24
24
  fixed: { type: Boolean, required: false },
25
+ separator: { type: [Number, Array], required: false },
25
26
  class: { type: null, required: false },
26
27
  ui: { type: Object, required: false },
27
28
  defaultValue: { type: null, required: false },
@@ -36,6 +37,7 @@ const _props = defineProps({
36
37
  type: { type: null, required: false, default: "text" }
37
38
  });
38
39
  const emits = defineEmits(["update:modelValue", "complete", "change", "blur"]);
40
+ defineSlots();
39
41
  const props = useComponentProps("pinInput", _props);
40
42
  const appConfig = useAppConfig();
41
43
  const rootProps = useForwardProps(reactivePick(props, "disabled", "id", "mask", "name", "otp", "required", "type"), emits);
@@ -68,6 +70,20 @@ function autoFocus() {
68
70
  inputsRef.value[0]?.$el?.focus();
69
71
  }
70
72
  }
73
+ function shouldInsertSeparator(index) {
74
+ if (props.separator === void 0) {
75
+ return false;
76
+ }
77
+ const position = index + 1;
78
+ if (position >= looseToNumber(props.length)) {
79
+ return false;
80
+ }
81
+ if (Array.isArray(props.separator)) {
82
+ return props.separator.includes(position);
83
+ }
84
+ const separator = looseToNumber(props.separator);
85
+ return Number.isInteger(separator) && separator > 0 && position % separator === 0;
86
+ }
71
87
  onMounted(() => {
72
88
  setTimeout(() => {
73
89
  autoFocus();
@@ -91,16 +107,25 @@ defineExpose({
91
107
  @update:model-value="emitFormInput()"
92
108
  @complete="onComplete"
93
109
  >
94
- <PinInputInput
95
- v-for="(ids, index) in looseToNumber(props.length)"
96
- :key="ids"
97
- :ref="(el) => setInputRef(index, el)"
98
- :index="index"
99
- data-slot="base"
100
- :class="ui.base({ class: props.ui?.base })"
101
- :disabled="disabled"
102
- @blur="onBlur"
103
- @focus="emitFormFocus"
104
- />
110
+ <template v-for="(ids, index) in looseToNumber(props.length)" :key="ids">
111
+ <PinInputInput
112
+ :ref="(el) => setInputRef(index, el)"
113
+ :index="index"
114
+ data-slot="base"
115
+ :class="ui.base({ class: props.ui?.base })"
116
+ :disabled="disabled"
117
+ @blur="onBlur"
118
+ @focus="emitFormFocus"
119
+ />
120
+ <span
121
+ v-if="shouldInsertSeparator(index)"
122
+ data-slot="separator"
123
+ role="presentation"
124
+ aria-hidden="true"
125
+ :class="ui.separator({ class: props.ui?.separator })"
126
+ >
127
+ <slot name="separator" :index="index">•</slot>
128
+ </span>
129
+ </template>
105
130
  </PinInputRoot>
106
131
  </template>
@@ -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>;
@@ -32,6 +32,8 @@ export interface PopoverProps<M extends PopoverMode = PopoverMode> extends Popov
32
32
  /**
33
33
  * The reference (or anchor) element that is being referred to for positioning.
34
34
  *
35
+ * Accepts an element or a virtual element (anything with `getBoundingClientRect`),
36
+ * and can be changed reactively to re-anchor the popover (e.g. for a guided tour).
35
37
  * If not provided will use the current component as anchor.
36
38
  */
37
39
  reference?: HoverCardTriggerProps['reference'];
@@ -62,7 +62,7 @@ const Component = computed(() => props.mode === "hover" ? HoverCard : Popover);
62
62
 
63
63
  <template>
64
64
  <Component.Root v-slot="{ open, close }" v-bind="rootProps">
65
- <Component.Trigger v-if="!!slots.default || !!props.reference" as-child :reference="props.reference" :class="props.class">
65
+ <Component.Trigger v-if="!!slots.default" as-child :class="props.class">
66
66
  <slot :open="open" />
67
67
  </Component.Trigger>
68
68
 
@@ -72,7 +72,7 @@ const Component = computed(() => props.mode === "hover" ? HoverCard : Popover);
72
72
 
73
73
  <Component.Portal v-bind="portalProps">
74
74
  <FieldGroupReset>
75
- <Component.Content v-bind="contentProps" data-slot="content" :class="ui.content({ class: [!slots.default && props.class, props.ui?.content] })" v-on="contentEvents">
75
+ <Component.Content v-bind="contentProps" :reference="props.reference ?? props.content?.reference" data-slot="content" :class="ui.content({ class: [!slots.default && props.class, props.ui?.content] })" v-on="contentEvents">
76
76
  <slot name="content" v-bind="close ? { close } : {}" />
77
77
 
78
78
  <Component.Arrow v-if="!!props.arrow" v-bind="arrowProps" data-slot="arrow" :class="ui.arrow({ class: props.ui?.arrow })" />
@@ -32,6 +32,8 @@ export interface PopoverProps<M extends PopoverMode = PopoverMode> extends Popov
32
32
  /**
33
33
  * The reference (or anchor) element that is being referred to for positioning.
34
34
  *
35
+ * Accepts an element or a virtual element (anything with `getBoundingClientRect`),
36
+ * and can be changed reactively to re-anchor the popover (e.g. for a guided tour).
35
37
  * If not provided will use the current component as anchor.
36
38
  */
37
39
  reference?: HoverCardTriggerProps['reference'];
@@ -51,6 +51,14 @@ export interface ScrollAreaProps<T extends ScrollAreaItem = ScrollAreaItem> {
51
51
  * @defaultValue false
52
52
  */
53
53
  virtualize?: boolean | ScrollAreaVirtualizeOptions;
54
+ /**
55
+ * Display fade shadows on the scrollable edges to indicate more content.
56
+ * Pass an object to configure the shadow size (in px).
57
+ * @defaultValue false
58
+ */
59
+ shadow?: boolean | {
60
+ size?: number;
61
+ };
54
62
  class?: any;
55
63
  ui?: ScrollArea['slots'];
56
64
  }
@@ -11,11 +11,13 @@ import { useAppConfig } from "#imports";
11
11
  import { useComponentProps } from "../composables/useComponentProps";
12
12
  import { tv } from "../utils/tv";
13
13
  import { useLocale } from "../composables/useLocale";
14
+ import { useScrollShadow } from "../composables/useScrollShadow";
14
15
  const _props = defineProps({
15
16
  as: { type: null, required: false },
16
17
  orientation: { type: null, required: false, default: "vertical" },
17
18
  items: { type: Array, required: false },
18
19
  virtualize: { type: [Boolean, Object], required: false, default: false },
20
+ shadow: { type: [Boolean, Object], required: false, default: false },
19
21
  class: { type: null, required: false },
20
22
  ui: { type: Object, required: false }
21
23
  });
@@ -28,6 +30,13 @@ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.scrollArea ||
28
30
  orientation: props.orientation
29
31
  }));
30
32
  const rootRef = useTemplateRef("rootRef");
33
+ const scrollShadowStyle = props.shadow ? useScrollShadow(
34
+ computed(() => rootRef.value?.$el),
35
+ {
36
+ orientation: () => props.orientation ?? "vertical",
37
+ size: typeof props.shadow === "object" ? props.shadow.size : void 0
38
+ }
39
+ ).style : void 0;
31
40
  const isRtl = computed(() => dir.value === "rtl");
32
41
  const isHorizontal = computed(() => props.orientation === "horizontal");
33
42
  const isVertical = computed(() => !isHorizontal.value);
@@ -164,6 +173,7 @@ defineExpose({
164
173
  data-slot="root"
165
174
  :data-orientation="props.orientation"
166
175
  :class="ui.root({ class: [props.ui?.root, props.class] })"
176
+ :style="scrollShadowStyle"
167
177
  >
168
178
  <template v-if="virtualizer">
169
179
  <div
@@ -51,6 +51,14 @@ export interface ScrollAreaProps<T extends ScrollAreaItem = ScrollAreaItem> {
51
51
  * @defaultValue false
52
52
  */
53
53
  virtualize?: boolean | ScrollAreaVirtualizeOptions;
54
+ /**
55
+ * Display fade shadows on the scrollable edges to indicate more content.
56
+ * Pass an object to configure the shadow size (in px).
57
+ * @defaultValue false
58
+ */
59
+ shadow?: boolean | {
60
+ size?: number;
61
+ };
54
62
  class?: any;
55
63
  ui?: ScrollArea['slots'];
56
64
  }
@@ -81,7 +81,8 @@ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.select || {}
81
81
  leading: isLeading.value || !!props.avatar || !!slots.leading,
82
82
  trailing: isTrailing.value || !!slots.trailing,
83
83
  fieldGroup: orientation.value,
84
- position: position.value
84
+ position: position.value,
85
+ multiple: props.multiple
85
86
  }));
86
87
  const groups = computed(
87
88
  () => props.items?.length ? isArrayOfArray(props.items) ? props.items : [props.items] : []
@@ -145,6 +146,11 @@ function onUpdateOpen(value) {
145
146
  function isSelectItem(item) {
146
147
  return typeof item === "object" && item !== null;
147
148
  }
149
+ function onTriggerClick(open) {
150
+ if (!open) {
151
+ triggerRef.value?.$el?.dispatchEvent(new PointerEvent("pointerdown", { bubbles: true, button: 0 }));
152
+ }
153
+ }
148
154
  const viewportRef = useTemplateRef("viewportRef");
149
155
  defineExpose({
150
156
  triggerRef: toRef(() => triggerRef.value?.$el),
@@ -173,6 +179,7 @@ defineExpose({
173
179
  data-slot="base"
174
180
  :class="ui.base({ class: [props.ui?.base, props.class] })"
175
181
  v-bind="{ ...$attrs, ...ariaAttrs }"
182
+ @click="onTriggerClick(open)"
176
183
  >
177
184
  <span v-if="isLeading || !!props.avatar || !!slots.leading" data-slot="leading" :class="ui.leading({ class: props.ui?.leading })">
178
185
  <slot name="leading" :model-value="modelValue" :open="open" :ui="ui">
@@ -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";
@@ -119,7 +119,8 @@ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.selectMenu ||
119
119
  leading: isLeading.value || !!props.avatar || !!slots.leading,
120
120
  trailing: isTrailing.value || !!slots.trailing,
121
121
  fieldGroup: orientation.value,
122
- virtualize: !!props.virtualize
122
+ virtualize: !!props.virtualize,
123
+ multiple: props.multiple
123
124
  }));
124
125
  function displayValue(value) {
125
126
  if (props.multiple && Array.isArray(value)) {
@@ -199,7 +200,9 @@ function onUpdate(value) {
199
200
  searchTerm.value = "";
200
201
  }
201
202
  }
203
+ const isOpen = ref(false);
202
204
  function onUpdateOpen(value) {
205
+ isOpen.value = value;
203
206
  let timeoutId;
204
207
  if (!value) {
205
208
  const event = new FocusEvent("blur");
@@ -246,6 +249,14 @@ function onClear() {
246
249
  emits("clear");
247
250
  }
248
251
  const viewportRef = useTemplateRef("viewportRef");
252
+ const comboboxRootRef = useTemplateRef("comboboxRootRef");
253
+ watch(() => props.items, async () => {
254
+ if (!isOpen.value) {
255
+ return;
256
+ }
257
+ await nextTick();
258
+ comboboxRootRef.value?.highlightFirstItem?.();
259
+ }, { flush: "post" });
249
260
  defineExpose({
250
261
  triggerRef: toRef(() => triggerRef.value?.$el),
251
262
  viewportRef: toRef(() => viewportRef.value)
@@ -324,9 +335,9 @@ defineExpose({
324
335
  </DefineItemTemplate>
325
336
 
326
337
  <ComboboxRoot
327
- :id="id"
338
+ ref="comboboxRootRef"
328
339
  v-slot="{ modelValue, open }"
329
- v-bind="{ ...rootProps, ...$attrs, ...ariaAttrs }"
340
+ v-bind="rootProps"
330
341
  ignore-filter
331
342
  as-child
332
343
  :name="name"
@@ -335,7 +346,14 @@ defineExpose({
335
346
  @update:open="onUpdateOpen"
336
347
  >
337
348
  <ComboboxAnchor as-child>
338
- <ComboboxTrigger ref="triggerRef" data-slot="base" :class="ui.base({ class: [props.ui?.base, props.class] })" tabindex="0">
349
+ <ComboboxTrigger
350
+ :id="id"
351
+ ref="triggerRef"
352
+ data-slot="base"
353
+ :class="ui.base({ class: [props.ui?.base, props.class] })"
354
+ tabindex="0"
355
+ v-bind="{ ...$attrs, ...ariaAttrs }"
356
+ >
339
357
  <span v-if="isLeading || !!props.avatar || !!slots.leading" data-slot="leading" :class="ui.leading({ class: props.ui?.leading })">
340
358
  <slot name="leading" :model-value="modelValue" :open="open" :ui="ui">
341
359
  <UIcon v-if="isLeading && leadingIconName" :name="leadingIconName" data-slot="leadingIcon" :class="ui.leadingIcon({ class: props.ui?.leadingIcon })" />
@@ -58,6 +58,11 @@ export interface SidebarProps<T extends SidebarMode = SidebarMode> {
58
58
  * @defaultValue false
59
59
  */
60
60
  rail?: boolean;
61
+ /**
62
+ * Animate the sidebar when collapsing or expanding.
63
+ * @defaultValue true
64
+ */
65
+ transition?: boolean;
61
66
  /**
62
67
  * The mode of the sidebar menu on mobile.
63
68
  * @defaultValue 'slideover'
@@ -26,6 +26,7 @@ const _props = defineProps({
26
26
  close: { type: [Boolean, Object], required: false, default: false },
27
27
  closeIcon: { type: null, required: false },
28
28
  rail: { type: Boolean, required: false, default: false },
29
+ transition: { type: Boolean, required: false, default: true },
29
30
  mode: { type: null, required: false, default: "slideover" },
30
31
  menu: { type: null, required: false },
31
32
  class: { type: null, required: false },
@@ -83,7 +84,8 @@ const hasHeader = computed(() => !!slots.header || props.title || !!slots.title
83
84
  const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.sidebar || {} })({
84
85
  side: props.side,
85
86
  variant: props.variant,
86
- collapsible: props.collapsible
87
+ collapsible: props.collapsible,
88
+ transition: props.transition
87
89
  }));
88
90
  const Menu = computed(() => ({
89
91
  slideover: USlideover,
@@ -58,6 +58,11 @@ export interface SidebarProps<T extends SidebarMode = SidebarMode> {
58
58
  * @defaultValue false
59
59
  */
60
60
  rail?: boolean;
61
+ /**
62
+ * Animate the sidebar when collapsing or expanding.
63
+ * @defaultValue true
64
+ */
65
+ transition?: boolean;
61
66
  /**
62
67
  * The mode of the sidebar menu on mobile.
63
68
  * @defaultValue 'slideover'
@@ -57,7 +57,9 @@ export interface SlideoverProps extends DialogRootProps {
57
57
  ui?: Slideover['slots'];
58
58
  }
59
59
  export interface SlideoverEmits 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 SlideoverSlots {
87
89
  declare const _default: typeof __VLS_export;
88
90
  export default _default;
89
91
  declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<SlideoverProps, {}, {}, {}, {}, 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<SlideoverProps> & 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("slideover", _props);
39
39
  const { t } = useLocale();
@@ -78,7 +78,9 @@ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.slideover ||
78
78
  data-slot="content"
79
79
  :class="ui.content({ class: [!slots.default && props.class, props.ui?.content] })"
80
80
  v-bind="contentProps"
81
+ @enter="emits('enter')"
81
82
  @after-enter="emits('after:enter')"
83
+ @leave="emits('leave')"
82
84
  @after-leave="emits('after:leave')"
83
85
  v-on="contentEvents"
84
86
  >