@nuxt/ui 4.10.0 → 4.11.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 (97) hide show
  1. package/.nuxt/ui.static.css +11 -11
  2. package/README.md +1 -0
  3. package/cli/commands/make/locale.mjs +40 -11
  4. package/cli/templates.mjs +2 -2
  5. package/dist/module.d.mts +1 -1
  6. package/dist/module.json +2 -2
  7. package/dist/module.mjs +5 -2
  8. package/dist/runtime/components/AuthForm.d.vue.ts +7 -7
  9. package/dist/runtime/components/AuthForm.vue.d.ts +7 -7
  10. package/dist/runtime/components/Button.vue +11 -2
  11. package/dist/runtime/components/ChatPromptSubmit.d.vue.ts +2 -2
  12. package/dist/runtime/components/ChatPromptSubmit.vue.d.ts +2 -2
  13. package/dist/runtime/components/Checkbox.d.vue.ts +1 -1
  14. package/dist/runtime/components/Checkbox.vue +12 -6
  15. package/dist/runtime/components/Checkbox.vue.d.ts +1 -1
  16. package/dist/runtime/components/CheckboxGroup.d.vue.ts +6 -0
  17. package/dist/runtime/components/CheckboxGroup.vue +10 -4
  18. package/dist/runtime/components/CheckboxGroup.vue.d.ts +6 -0
  19. package/dist/runtime/components/Editor.vue +4 -1
  20. package/dist/runtime/components/Error.d.vue.ts +1 -1
  21. package/dist/runtime/components/Error.vue.d.ts +1 -1
  22. package/dist/runtime/components/FileUpload.vue +17 -10
  23. package/dist/runtime/components/Input.vue +12 -7
  24. package/dist/runtime/components/InputDate.vue +12 -8
  25. package/dist/runtime/components/InputMenu.vue +25 -11
  26. package/dist/runtime/components/InputNumber.vue +14 -9
  27. package/dist/runtime/components/InputRating.vue +10 -7
  28. package/dist/runtime/components/InputTags.vue +12 -7
  29. package/dist/runtime/components/InputTime.vue +12 -7
  30. package/dist/runtime/components/Listbox.vue +10 -6
  31. package/dist/runtime/components/Modal.vue +12 -5
  32. package/dist/runtime/components/PinInput.vue +13 -8
  33. package/dist/runtime/components/Popover.vue +0 -1
  34. package/dist/runtime/components/PricingTable.d.vue.ts +1 -1
  35. package/dist/runtime/components/PricingTable.vue.d.ts +1 -1
  36. package/dist/runtime/components/Progress.d.vue.ts +2 -1
  37. package/dist/runtime/components/Progress.vue +5 -6
  38. package/dist/runtime/components/Progress.vue.d.ts +2 -1
  39. package/dist/runtime/components/ProgressGroup.d.vue.ts +91 -0
  40. package/dist/runtime/components/ProgressGroup.vue +99 -0
  41. package/dist/runtime/components/ProgressGroup.vue.d.ts +91 -0
  42. package/dist/runtime/components/RadioGroup.d.vue.ts +7 -1
  43. package/dist/runtime/components/RadioGroup.vue +14 -5
  44. package/dist/runtime/components/RadioGroup.vue.d.ts +7 -1
  45. package/dist/runtime/components/Select.vue +21 -8
  46. package/dist/runtime/components/SelectMenu.vue +26 -12
  47. package/dist/runtime/components/Slider.vue +14 -7
  48. package/dist/runtime/components/Splitter.d.vue.ts +266 -0
  49. package/dist/runtime/components/Splitter.vue +99 -0
  50. package/dist/runtime/components/Splitter.vue.d.ts +266 -0
  51. package/dist/runtime/components/Switch.vue +8 -4
  52. package/dist/runtime/components/Textarea.vue +17 -7
  53. package/dist/runtime/components/Theme.d.vue.ts +1 -1
  54. package/dist/runtime/components/Theme.vue +4 -3
  55. package/dist/runtime/components/Theme.vue.d.ts +1 -1
  56. package/dist/runtime/components/Tree.vue +1 -1
  57. package/dist/runtime/components/content/ContentNavigation.vue +8 -1
  58. package/dist/runtime/components/content/ContentToc.vue +4 -1
  59. package/dist/runtime/composables/useComponentProps.d.ts +1 -1
  60. package/dist/runtime/composables/useComponentProps.js +6 -0
  61. package/dist/runtime/composables/useFormField.d.ts +10 -4
  62. package/dist/runtime/composables/useFormField.js +10 -3
  63. package/dist/runtime/keyframes.css +1 -1
  64. package/dist/runtime/locale/da.js +1 -1
  65. package/dist/runtime/locale/de_at.js +7 -0
  66. package/dist/runtime/locale/de_ch.js +1 -1
  67. package/dist/runtime/locale/eu.js +1 -1
  68. package/dist/runtime/locale/fi.js +1 -1
  69. package/dist/runtime/locale/he.js +1 -1
  70. package/dist/runtime/locale/hi.js +1 -1
  71. package/dist/runtime/locale/index.d.ts +2 -1
  72. package/dist/runtime/locale/index.js +2 -1
  73. package/dist/runtime/locale/is.js +1 -1
  74. package/dist/runtime/locale/lb.js +1 -1
  75. package/dist/runtime/locale/tg.d.ts +3 -0
  76. package/dist/runtime/locale/{tj.js → tg.js} +1 -1
  77. package/dist/runtime/locale/ur.js +1 -1
  78. package/dist/runtime/types/form.d.ts +1 -1
  79. package/dist/runtime/types/html.d.ts +3 -1
  80. package/dist/runtime/types/index.d.ts +2 -0
  81. package/dist/runtime/types/index.js +2 -0
  82. package/dist/runtime/types/theme.d.ts +2 -0
  83. package/dist/runtime/types/tv.d.ts +6 -2
  84. package/dist/runtime/utils/link-keys.d.ts +1 -0
  85. package/dist/runtime/utils/link-keys.js +40 -0
  86. package/dist/runtime/utils/link.d.ts +2 -1
  87. package/dist/runtime/utils/link.js +2 -40
  88. package/dist/runtime/utils/search.js +3 -12
  89. package/dist/runtime/utils/tv.d.ts +1 -1
  90. package/dist/runtime/utils/tv.js +103 -25
  91. package/dist/runtime/vue/components/Icon.vue +5 -2
  92. package/dist/shared/{ui.XkBrgXFP.mjs → ui.DNq7CNkE.mjs} +589 -213
  93. package/dist/unplugin.d.mts +1 -1
  94. package/dist/unplugin.mjs +22 -6
  95. package/dist/vite.mjs +4 -4
  96. package/package.json +51 -50
  97. /package/dist/runtime/locale/{tj.d.ts → de_at.d.ts} +0 -0
@@ -3,7 +3,7 @@ import theme from "#build/ui/input";
3
3
  </script>
4
4
 
5
5
  <script setup>
6
- import { useTemplateRef, computed, onMounted } from "vue";
6
+ import { useTemplateRef, computed, onMounted, onScopeDispose } from "vue";
7
7
  import { Primitive } from "reka-ui";
8
8
  import { useVModel } from "@vueuse/core";
9
9
  import { useAppConfig } from "#imports";
@@ -51,17 +51,20 @@ const slots = defineSlots();
51
51
  const props = useComponentProps("input", _props);
52
52
  const modelValue = useVModel(props, "modelValue", emits, { defaultValue: props.defaultValue });
53
53
  const appConfig = useAppConfig();
54
- const { emitFormBlur, emitFormInput, emitFormChange, size: formFieldSize, color, id, name, highlight, disabled, emitFormFocus, ariaAttrs } = useFormField(_props, { deferInputValidation: true });
54
+ const { emitFormBlur, emitFormInput, emitFormChange, size: formFieldSize, color: formFieldColor, id, name, highlight: formFieldHighlight, disabled: formFieldDisabled, emitFormFocus, ariaAttrs } = useFormField(_props, { deferInputValidation: true });
55
55
  const { orientation, size: fieldGroupSize } = useFieldGroup(_props);
56
56
  const { isLeading, isTrailing, leadingIconName, trailingIconName } = useComponentIcons(props);
57
- const inputSize = computed(() => fieldGroupSize.value || formFieldSize.value);
57
+ const color = computed(() => formFieldColor.value ?? props.color);
58
+ const highlight = computed(() => formFieldHighlight.value ?? props.highlight);
59
+ const size = computed(() => fieldGroupSize.value ?? formFieldSize.value ?? props.size);
60
+ const disabled = computed(() => formFieldDisabled.value ?? props.disabled);
58
61
  const ui = computed(() => tv({ extend: theme, ...appConfig.ui?.input || {} })({
59
62
  type: props.type,
60
- color: color.value ?? props.color,
63
+ color: color.value,
61
64
  variant: props.variant,
62
- size: inputSize?.value ?? props.size,
65
+ size: size.value,
63
66
  loading: props.loading,
64
- highlight: highlight.value ?? props.highlight,
67
+ highlight: highlight.value,
65
68
  fixed: props.fixed,
66
69
  leading: isLeading.value || !!props.avatar || !!slots.leading,
67
70
  trailing: isTrailing.value || !!slots.trailing,
@@ -109,11 +112,13 @@ function autoFocus() {
109
112
  inputRef.value?.focus();
110
113
  }
111
114
  }
115
+ let autofocusTimeoutId;
112
116
  onMounted(() => {
113
- setTimeout(() => {
117
+ autofocusTimeoutId = setTimeout(() => {
114
118
  autoFocus();
115
119
  }, props.autofocusDelay);
116
120
  });
121
+ onScopeDispose(() => clearTimeout(autofocusTimeoutId));
117
122
  defineExpose({
118
123
  inputRef
119
124
  });
@@ -3,8 +3,7 @@ import theme from "#build/ui/input-date";
3
3
  </script>
4
4
 
5
5
  <script setup>
6
- import { computed, onMounted, ref } from "vue";
7
- import {} from "reka-ui";
6
+ import { computed, onMounted, onScopeDispose, ref } from "vue";
8
7
  import { useForwardProps } from "../composables/useForwardProps";
9
8
  import { DateField as SingleDateField, DateRangeField as RangeDateField } from "reka-ui/namespaced";
10
9
  import { reactiveOmit, createReusableTemplate } from "@vueuse/core";
@@ -62,16 +61,19 @@ const slots = defineSlots();
62
61
  const props = useComponentProps("inputDate", _props);
63
62
  const appConfig = useAppConfig();
64
63
  const rootProps = useForwardProps(reactiveOmit(props, "id", "name", "range", "modelValue", "defaultValue", "color", "variant", "size", "highlight", "fixed", "disabled", "autofocus", "autofocusDelay", "icon", "avatar", "leading", "leadingIcon", "trailing", "trailingIcon", "loading", "loadingIcon", "separatorIcon", "class", "ui"), emits);
65
- const { emitFormBlur, emitFormFocus, emitFormChange, emitFormInput, size: formFieldSize, color, id, name, highlight, disabled, ariaAttrs } = useFormField(_props);
64
+ const { emitFormBlur, emitFormFocus, emitFormChange, emitFormInput, size: formFieldSize, color: formFieldColor, id, name, highlight: formFieldHighlight, disabled: formFieldDisabled, ariaAttrs } = useFormField(_props);
66
65
  const { orientation, size: fieldGroupSize } = useFieldGroup(_props);
67
66
  const { isLeading, isTrailing, leadingIconName, trailingIconName } = useComponentIcons(props);
68
67
  const [DefineSegmentsTemplate, ReuseSegmentsTemplate] = createReusableTemplate();
69
- const inputSize = computed(() => fieldGroupSize.value || formFieldSize.value);
68
+ const color = computed(() => formFieldColor.value ?? props.color);
69
+ const highlight = computed(() => formFieldHighlight.value ?? props.highlight);
70
+ const size = computed(() => fieldGroupSize.value ?? formFieldSize.value ?? props.size);
71
+ const disabled = computed(() => formFieldDisabled.value ?? props.disabled);
70
72
  const ui = computed(() => tv({ extend: theme, ...appConfig.ui?.inputDate || {} })({
71
- color: color.value ?? props.color,
73
+ color: color.value,
72
74
  variant: props.variant,
73
- size: inputSize.value ?? props.size,
74
- highlight: highlight.value ?? props.highlight,
75
+ size: size.value,
76
+ highlight: highlight.value,
75
77
  fixed: props.fixed,
76
78
  loading: props.loading,
77
79
  leading: isLeading.value || !!props.avatar || !!slots.leading,
@@ -101,11 +103,13 @@ function autoFocus() {
101
103
  inputsRef.value[0]?.$el?.focus();
102
104
  }
103
105
  }
106
+ let autofocusTimeoutId;
104
107
  onMounted(() => {
105
- setTimeout(() => {
108
+ autofocusTimeoutId = setTimeout(() => {
106
109
  autoFocus();
107
110
  }, props.autofocusDelay);
108
111
  });
112
+ onScopeDispose(() => clearTimeout(autofocusTimeoutId));
109
113
  const DateField = computed(() => props.range ? RangeDateField : SingleDateField);
110
114
  defineExpose({
111
115
  inputsRef
@@ -3,7 +3,7 @@ import theme from "#build/ui/input-menu";
3
3
  </script>
4
4
 
5
5
  <script setup>
6
- import { computed, ref, useAttrs, useTemplateRef, toRef, onMounted, toRaw, nextTick, watch } from "vue";
6
+ import { computed, ref, useAttrs, useTemplateRef, toRef, onMounted, onScopeDispose, 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";
@@ -102,13 +102,24 @@ const clearProps = computed(() => typeof props.clear === "object" ? props.clear
102
102
  const virtualizerProps = toRef(() => {
103
103
  if (!props.virtualize) return false;
104
104
  return defu(typeof props.virtualize === "boolean" ? {} : props.virtualize, {
105
- estimateSize: getEstimateSize(filteredItems.value, inputSize.value || "md", props.descriptionKey, !!slots["item-description"])
105
+ estimateSize: getEstimateSize(filteredItems.value, size.value ?? "md", props.descriptionKey, !!slots["item-description"])
106
106
  });
107
107
  });
108
- const { emitFormBlur, emitFormFocus, emitFormChange, emitFormInput, size: formFieldSize, color, id, name, highlight, disabled, ariaAttrs } = useFormField(_props);
108
+ const { emitFormBlur, emitFormFocus, emitFormChange, emitFormInput, size: formFieldSize, color: formFieldColor, id, name, highlight: formFieldHighlight, disabled: formFieldDisabled, ariaAttrs } = useFormField(_props);
109
109
  const { orientation, size: fieldGroupSize } = useFieldGroup(_props);
110
- const { isLeading, isTrailing, leadingIconName, trailingIconName } = useComponentIcons(toRef(() => defu(props, { trailingIcon: appConfig.ui.icons.chevronDown })));
111
- const inputSize = computed(() => fieldGroupSize.value || formFieldSize.value);
110
+ const { isLeading, isTrailing, leadingIconName, trailingIconName } = useComponentIcons(computed(() => ({
111
+ icon: props.icon,
112
+ leading: props.leading,
113
+ leadingIcon: props.leadingIcon,
114
+ trailing: props.trailing,
115
+ trailingIcon: props.trailingIcon ?? appConfig.ui.icons.chevronDown,
116
+ loading: props.loading,
117
+ loadingIcon: props.loadingIcon
118
+ })));
119
+ const color = computed(() => formFieldColor.value ?? props.color);
120
+ const highlight = computed(() => formFieldHighlight.value ?? props.highlight);
121
+ const size = computed(() => fieldGroupSize.value ?? formFieldSize.value ?? props.size);
122
+ const disabled = computed(() => formFieldDisabled.value ?? props.disabled);
112
123
  const [DefineCreateItemTemplate, ReuseCreateItemTemplate] = createReusableTemplate();
113
124
  const [DefineItemTemplate, ReuseItemTemplate] = createReusableTemplate({
114
125
  props: {
@@ -123,11 +134,11 @@ const [DefineItemTemplate, ReuseItemTemplate] = createReusableTemplate({
123
134
  }
124
135
  });
125
136
  const ui = computed(() => tv({ extend: theme, ...appConfig.ui?.inputMenu || {} })({
126
- color: color.value ?? props.color,
137
+ color: color.value,
127
138
  variant: props.variant,
128
- size: inputSize?.value ?? props.size,
139
+ size: size.value,
129
140
  loading: props.loading,
130
- highlight: highlight.value ?? props.highlight,
141
+ highlight: highlight.value,
131
142
  fixed: props.fixed,
132
143
  leading: isLeading.value || !!props.avatar || !!slots.leading,
133
144
  trailing: isTrailing.value || !!slots.trailing,
@@ -174,6 +185,7 @@ function autoFocus() {
174
185
  inputRef.value?.$el?.focus();
175
186
  }
176
187
  }
188
+ let autofocusTimeoutId;
177
189
  onMounted(() => {
178
190
  nextTick(() => {
179
191
  if (isAutocomplete.value) {
@@ -182,10 +194,11 @@ onMounted(() => {
182
194
  searchTerm.value = "";
183
195
  }
184
196
  });
185
- setTimeout(() => {
197
+ autofocusTimeoutId = setTimeout(() => {
186
198
  autoFocus();
187
199
  }, props.autofocusDelay);
188
200
  });
201
+ onScopeDispose(() => clearTimeout(autofocusTimeoutId));
189
202
  watch(() => props.modelValue, (newValue) => {
190
203
  if (isAutocomplete.value) {
191
204
  searchTerm.value = String(newValue ?? "");
@@ -231,9 +244,10 @@ function onFocus(event) {
231
244
  emitFormFocus();
232
245
  }
233
246
  const isOpen = ref(false);
247
+ let timeoutId;
248
+ onScopeDispose(() => clearTimeout(timeoutId));
234
249
  function onUpdateOpen(value) {
235
250
  isOpen.value = value;
236
- let timeoutId;
237
251
  if (!value) {
238
252
  const event = new FocusEvent("blur");
239
253
  emits("blur", event);
@@ -453,7 +467,7 @@ defineExpose({
453
467
  <UButton
454
468
  as="span"
455
469
  :icon="props.clearIcon || appConfig.ui.icons.close"
456
- :size="inputSize"
470
+ :size="size"
457
471
  variant="link"
458
472
  color="neutral"
459
473
  tabindex="-1"
@@ -3,7 +3,7 @@ import theme from "#build/ui/input-number";
3
3
  </script>
4
4
 
5
5
  <script setup>
6
- import { onMounted, computed, useTemplateRef, toRef } from "vue";
6
+ import { onMounted, onScopeDispose, computed, useTemplateRef, toRef } from "vue";
7
7
  import { NumberFieldRoot, NumberFieldInput, NumberFieldDecrement, NumberFieldIncrement } from "reka-ui";
8
8
  import { useForwardProps } from "../composables/useForwardProps";
9
9
  import { reactivePick, useVModel } from "@vueuse/core";
@@ -59,14 +59,17 @@ const modelValue = useVModel(props, "modelValue", emits, { defaultValue: props.d
59
59
  const { t } = useLocale();
60
60
  const appConfig = useAppConfig();
61
61
  const rootProps = useForwardProps(reactivePick(props, "as", "stepSnapping", "formatOptions", "disableWheelChange", "invertWheelChange", "required", "readonly", "focusOnChange", "locale"), emits);
62
- const { emitFormBlur, emitFormFocus, emitFormChange, emitFormInput, id, color, size: formFieldSize, name, highlight, disabled, ariaAttrs } = useFormField(_props);
62
+ const { emitFormBlur, emitFormFocus, emitFormChange, emitFormInput, id, color: formFieldColor, size: formFieldSize, name, highlight: formFieldHighlight, disabled: formFieldDisabled, ariaAttrs } = useFormField(_props);
63
63
  const { orientation, size: fieldGroupSize } = useFieldGroup(_props);
64
- const inputSize = computed(() => fieldGroupSize.value || formFieldSize.value);
64
+ const color = computed(() => formFieldColor.value ?? props.color);
65
+ const highlight = computed(() => formFieldHighlight.value ?? props.highlight);
66
+ const size = computed(() => fieldGroupSize.value ?? formFieldSize.value ?? props.size);
67
+ const disabled = computed(() => formFieldDisabled.value ?? props.disabled);
65
68
  const ui = computed(() => tv({ extend: theme, ...appConfig.ui?.inputNumber || {} })({
66
- color: color.value ?? props.color,
69
+ color: color.value,
67
70
  variant: props.variant,
68
- size: inputSize.value ?? props.size,
69
- highlight: highlight.value ?? props.highlight,
71
+ size: size.value,
72
+ highlight: highlight.value,
70
73
  fixed: props.fixed,
71
74
  orientation: props.orientation,
72
75
  fieldGroup: orientation.value,
@@ -94,11 +97,13 @@ function autoFocus() {
94
97
  inputRef.value?.$el?.focus();
95
98
  }
96
99
  }
100
+ let autofocusTimeoutId;
97
101
  onMounted(() => {
98
- setTimeout(() => {
102
+ autofocusTimeoutId = setTimeout(() => {
99
103
  autoFocus();
100
104
  }, props.autofocusDelay);
101
105
  });
106
+ onScopeDispose(() => clearTimeout(autofocusTimeoutId));
102
107
  defineExpose({
103
108
  inputRef: toRef(() => inputRef.value?.$el)
104
109
  });
@@ -136,7 +141,7 @@ defineExpose({
136
141
  <UButton
137
142
  :icon="incrementIcon"
138
143
  :color="color"
139
- :size="inputSize"
144
+ :size="size"
140
145
  variant="link"
141
146
  :aria-label="t('inputNumber.increment')"
142
147
  v-bind="typeof props.increment === 'object' ? props.increment : void 0"
@@ -151,7 +156,7 @@ defineExpose({
151
156
  <UButton
152
157
  :icon="decrementIcon"
153
158
  :color="color"
154
- :size="inputSize"
159
+ :size="size"
155
160
  variant="link"
156
161
  :aria-label="t('inputNumber.decrement')"
157
162
  v-bind="typeof props.decrement === 'object' ? props.decrement : void 0"
@@ -39,14 +39,17 @@ defineSlots();
39
39
  const props = useComponentProps("inputRating", _props);
40
40
  const appConfig = useAppConfig();
41
41
  const rootProps = useForwardProps(reactivePick(props, "as", "length", "step", "hoverable", "clearable", "required", "modelValue", "defaultValue"), emits);
42
- const { id, emitFormChange, emitFormInput, size, color, name, disabled: formDisabled, ariaAttrs } = useFormField(_props);
43
- const disabled = computed(() => formDisabled.value || props.readonly);
42
+ const { id, emitFormChange, emitFormInput, size: formFieldSize, color: formFieldColor, name, disabled: formFieldDisabled, ariaAttrs } = useFormField(_props);
43
+ const color = computed(() => formFieldColor.value ?? props.color);
44
+ const size = computed(() => formFieldSize.value ?? props.size);
45
+ const disabled = computed(() => formFieldDisabled.value ?? props.disabled);
46
+ const rootDisabled = computed(() => disabled.value || props.readonly);
44
47
  const ui = computed(() => tv({ extend: theme, ...appConfig.ui?.inputRating || {} })({
45
- size: size.value ?? props.size,
46
- color: color.value ?? props.color,
48
+ size: size.value,
49
+ color: color.value,
47
50
  orientation: props.orientation,
48
- readonly: props.readonly && !formDisabled.value,
49
- disabled: formDisabled.value
51
+ readonly: props.readonly && !disabled.value,
52
+ disabled: disabled.value
50
53
  }));
51
54
  const starIcon = computed(() => props.icon ?? appConfig.ui.icons.star);
52
55
  function onUpdate(value) {
@@ -64,7 +67,7 @@ function onUpdate(value) {
64
67
  data-slot="root"
65
68
  v-bind="{ ...rootProps, ...$attrs, ...ariaAttrs }"
66
69
  :name="name"
67
- :disabled="disabled"
70
+ :disabled="rootDisabled"
68
71
  :aria-readonly="props.readonly || void 0"
69
72
  :orientation="props.orientation"
70
73
  :class="ui.root({ class: [props.ui?.root, props.class] })"
@@ -3,7 +3,7 @@ import theme from "#build/ui/input-tags";
3
3
  </script>
4
4
 
5
5
  <script setup>
6
- import { computed, useTemplateRef, onMounted, toRaw, toRef } from "vue";
6
+ import { computed, useTemplateRef, onMounted, onScopeDispose, toRaw, toRef } from "vue";
7
7
  import { TagsInputRoot, TagsInputItem, TagsInputItemText, TagsInputItemDelete, TagsInputInput } from "reka-ui";
8
8
  import { useForwardProps } from "../composables/useForwardProps";
9
9
  import { reactivePick } from "@vueuse/core";
@@ -58,16 +58,19 @@ const slots = defineSlots();
58
58
  const props = useComponentProps("inputTags", _props);
59
59
  const appConfig = useAppConfig();
60
60
  const rootProps = useForwardProps(reactivePick(props, "as", "addOnPaste", "addOnTab", "addOnBlur", "duplicate", "delimiter", "max", "convertValue", "displayValue", "required"), emits);
61
- const { emitFormBlur, emitFormFocus, emitFormChange, emitFormInput, size: formFieldSize, color, id, name, highlight, disabled, ariaAttrs } = useFormField(_props);
61
+ const { emitFormBlur, emitFormFocus, emitFormChange, emitFormInput, size: formFieldSize, color: formFieldColor, id, name, highlight: formFieldHighlight, disabled: formFieldDisabled, ariaAttrs } = useFormField(_props);
62
62
  const { orientation, size: fieldGroupSize } = useFieldGroup(_props);
63
63
  const { isLeading, isTrailing, leadingIconName, trailingIconName } = useComponentIcons(props);
64
- const inputSize = computed(() => fieldGroupSize.value || formFieldSize.value);
64
+ const color = computed(() => formFieldColor.value ?? props.color);
65
+ const highlight = computed(() => formFieldHighlight.value ?? props.highlight);
66
+ const size = computed(() => fieldGroupSize.value ?? formFieldSize.value ?? props.size);
67
+ const disabled = computed(() => formFieldDisabled.value ?? props.disabled);
65
68
  const ui = computed(() => tv({ extend: theme, ...appConfig.ui?.inputTags || {} })({
66
- color: color.value ?? props.color,
69
+ color: color.value,
67
70
  variant: props.variant,
68
- size: inputSize?.value ?? props.size,
71
+ size: size.value,
69
72
  loading: props.loading,
70
- highlight: highlight.value ?? props.highlight,
73
+ highlight: highlight.value,
71
74
  fixed: props.fixed,
72
75
  leading: isLeading.value || !!props.avatar || !!slots.leading,
73
76
  trailing: isTrailing.value || !!slots.trailing,
@@ -79,11 +82,13 @@ function autoFocus() {
79
82
  inputRef.value?.$el?.focus();
80
83
  }
81
84
  }
85
+ let autofocusTimeoutId;
82
86
  onMounted(() => {
83
- setTimeout(() => {
87
+ autofocusTimeoutId = setTimeout(() => {
84
88
  autoFocus();
85
89
  }, props.autofocusDelay);
86
90
  });
91
+ onScopeDispose(() => clearTimeout(autofocusTimeoutId));
87
92
  function onUpdate(value) {
88
93
  if (toRaw(props.modelValue) === value) {
89
94
  return;
@@ -3,7 +3,7 @@ import theme from "#build/ui/input-time";
3
3
  </script>
4
4
 
5
5
  <script setup>
6
- import { computed, onMounted, ref } from "vue";
6
+ import { computed, onMounted, onScopeDispose, ref } from "vue";
7
7
  import { TimeRangeFieldRoot, TimeRangeFieldInput } from "reka-ui";
8
8
  import { useForwardProps } from "../composables/useForwardProps";
9
9
  import { TimeField as SingleTimeField } from "reka-ui/namespaced";
@@ -62,16 +62,19 @@ const slots = defineSlots();
62
62
  const props = useComponentProps("inputTime", _props);
63
63
  const appConfig = useAppConfig();
64
64
  const rootProps = useForwardProps(reactiveOmit(props, "id", "name", "range", "modelValue", "defaultValue", "color", "variant", "size", "highlight", "fixed", "disabled", "autofocus", "autofocusDelay", "icon", "avatar", "leading", "leadingIcon", "trailing", "trailingIcon", "loading", "loadingIcon", "separatorIcon", "class", "ui"), emits);
65
- const { emitFormBlur, emitFormFocus, emitFormChange, emitFormInput, id, color, size: formFieldSize, name, highlight, disabled, ariaAttrs } = useFormField(_props);
65
+ const { emitFormBlur, emitFormFocus, emitFormChange, emitFormInput, id, color: formFieldColor, size: formFieldSize, name, highlight: formFieldHighlight, disabled: formFieldDisabled, ariaAttrs } = useFormField(_props);
66
66
  const { orientation, size: fieldGroupSize } = useFieldGroup(_props);
67
67
  const { isLeading, isTrailing, leadingIconName, trailingIconName } = useComponentIcons(props);
68
- const inputSize = computed(() => fieldGroupSize.value || formFieldSize.value);
68
+ const color = computed(() => formFieldColor.value ?? props.color);
69
+ const highlight = computed(() => formFieldHighlight.value ?? props.highlight);
70
+ const size = computed(() => fieldGroupSize.value ?? formFieldSize.value ?? props.size);
71
+ const disabled = computed(() => formFieldDisabled.value ?? props.disabled);
69
72
  const ui = computed(() => tv({ extend: theme, ...appConfig.ui?.inputTime || {} })({
70
- color: color.value ?? props.color,
73
+ color: color.value,
71
74
  variant: props.variant,
72
- size: inputSize.value ?? props.size,
75
+ size: size.value,
73
76
  loading: props.loading,
74
- highlight: highlight.value ?? props.highlight,
77
+ highlight: highlight.value,
75
78
  fixed: props.fixed,
76
79
  leading: isLeading.value || !!props.avatar || !!slots.leading,
77
80
  trailing: isTrailing.value || !!slots.trailing,
@@ -103,11 +106,13 @@ function autoFocus() {
103
106
  inputsRef.value[0]?.$el?.focus();
104
107
  }
105
108
  }
109
+ let autofocusTimeoutId;
106
110
  onMounted(() => {
107
- setTimeout(() => {
111
+ autofocusTimeoutId = setTimeout(() => {
108
112
  autoFocus();
109
113
  }, props.autofocusDelay);
110
114
  });
115
+ onScopeDispose(() => clearTimeout(autofocusTimeoutId));
111
116
  defineExpose({
112
117
  inputsRef
113
118
  });
@@ -1,9 +1,9 @@
1
1
  <script>
2
- import { computed, toRaw, toRef } from "vue";
3
2
  import theme from "#build/ui/listbox";
4
3
  </script>
5
4
 
6
5
  <script setup>
6
+ import { computed, toRaw, toRef } from "vue";
7
7
  import { ListboxRoot, ListboxContent, ListboxGroup, ListboxGroupLabel, ListboxVirtualizer, ListboxItem as RekaListboxItem, ListboxItemIndicator, ListboxFilter } from "reka-ui";
8
8
  import { useForwardProps } from "../composables/useForwardProps";
9
9
  import { createReusableTemplate, reactivePick } from "@vueuse/core";
@@ -65,11 +65,15 @@ const rootProps = useForwardProps(reactivePick(props, "as", "modelValue", "defau
65
65
  const virtualizerProps = toRef(() => {
66
66
  if (!props.virtualize) return false;
67
67
  return defu(typeof props.virtualize === "boolean" ? {} : props.virtualize, {
68
- estimateSize: getEstimateSize(filteredItems.value, size.value || "md", props.descriptionKey, !!slots["item-description"])
68
+ estimateSize: getEstimateSize(filteredItems.value, size.value ?? "md", props.descriptionKey, !!slots["item-description"])
69
69
  });
70
70
  });
71
71
  const inputProps = toRef(() => defu(typeof props.filter === "object" ? props.filter : {}, { placeholder: t("listbox.search"), variant: "none" }));
72
- const { emitFormChange, emitFormInput, name, size, color, id, highlight, disabled, ariaAttrs } = useFormField(_props, { bind: false });
72
+ const { emitFormChange, emitFormInput, name, size: formFieldSize, color: formFieldColor, id, highlight: formFieldHighlight, disabled: formFieldDisabled, ariaAttrs } = useFormField(_props, { bind: false });
73
+ const color = computed(() => formFieldColor.value ?? props.color);
74
+ const highlight = computed(() => formFieldHighlight.value ?? props.highlight);
75
+ const size = computed(() => formFieldSize.value ?? props.size);
76
+ const disabled = computed(() => formFieldDisabled.value ?? props.disabled);
73
77
  const [DefineItemTemplate, ReuseItemTemplate] = createReusableTemplate({
74
78
  props: {
75
79
  item: {
@@ -83,9 +87,9 @@ const [DefineItemTemplate, ReuseItemTemplate] = createReusableTemplate({
83
87
  }
84
88
  });
85
89
  const ui = computed(() => tv({ extend: theme, ...appConfig.ui?.listbox || {} })({
86
- color: color.value ?? props.color,
87
- size: size.value ?? props.size,
88
- highlight: highlight.value ?? props.highlight,
90
+ color: color.value,
91
+ size: size.value,
92
+ highlight: highlight.value,
89
93
  disabled: disabled.value,
90
94
  virtualize: !!props.virtualize
91
95
  }));
@@ -73,10 +73,10 @@ const ui = computed(() => tv({ extend: theme, ...appConfig.ui?.modal || {} })({
73
73
  data-slot="content"
74
74
  :class="ui.content({ class: [!slots.default && props.class, props.ui?.content] })"
75
75
  v-bind="contentProps"
76
- @enter="emits('enter')"
77
- @after-enter="emits('after:enter')"
78
- @leave="emits('leave')"
79
- @after-leave="emits('after:leave')"
76
+ @enter="!props.scrollable && emits('enter')"
77
+ @after-enter="!props.scrollable && emits('after:enter')"
78
+ @leave="!props.scrollable && emits('leave')"
79
+ @after-leave="!props.scrollable && emits('after:leave')"
80
80
  v-on="contentEvents"
81
81
  >
82
82
  <VisuallyHidden v-if="!props.title && !slots.title || !props.description && !slots.description || !!slots.content">
@@ -149,7 +149,14 @@ const ui = computed(() => tv({ extend: theme, ...appConfig.ui?.modal || {} })({
149
149
  <DialogPortal v-bind="portalProps" :force-mount="portalProps.disabled && props.unmountOnHide === false || void 0">
150
150
  <FieldGroupReset>
151
151
  <template v-if="props.scrollable">
152
- <DialogOverlay data-slot="overlay" :class="ui.overlay({ class: props.ui?.overlay })">
152
+ <DialogOverlay
153
+ data-slot="overlay"
154
+ :class="ui.overlay({ class: props.ui?.overlay })"
155
+ @enter="emits('enter')"
156
+ @after-enter="emits('after:enter')"
157
+ @leave="emits('leave')"
158
+ @after-leave="emits('after:leave')"
159
+ >
153
160
  <ReuseContentTemplate />
154
161
  </DialogOverlay>
155
162
  </template>
@@ -3,7 +3,7 @@ import theme from "#build/ui/pin-input";
3
3
  </script>
4
4
 
5
5
  <script setup>
6
- import { ref, computed, onMounted } from "vue";
6
+ import { ref, computed, onMounted, onScopeDispose } from "vue";
7
7
  import { PinInputInput, PinInputRoot } from "reka-ui";
8
8
  import { useForwardProps } from "../composables/useForwardProps";
9
9
  import { reactivePick } from "@vueuse/core";
@@ -41,26 +41,29 @@ defineSlots();
41
41
  const props = useComponentProps("pinInput", _props);
42
42
  const appConfig = useAppConfig();
43
43
  const rootProps = useForwardProps(reactivePick(props, "disabled", "id", "mask", "name", "otp", "required", "type"), emits);
44
- const { emitFormInput, emitFormFocus, emitFormChange, emitFormBlur, size, color, id, name, highlight, disabled, ariaAttrs } = useFormField(_props);
44
+ const { emitFormInput, emitFormFocus, emitFormChange, emitFormBlur, size: formFieldSize, color: formFieldColor, id, name, highlight: formFieldHighlight, disabled: formFieldDisabled, ariaAttrs } = useFormField(_props);
45
+ const color = computed(() => formFieldColor.value ?? props.color);
46
+ const highlight = computed(() => formFieldHighlight.value ?? props.highlight);
47
+ const size = computed(() => formFieldSize.value ?? props.size);
48
+ const disabled = computed(() => formFieldDisabled.value ?? props.disabled);
45
49
  const ui = computed(() => tv({ extend: theme, ...appConfig.ui?.pinInput || {} })({
46
- color: color.value ?? props.color,
50
+ color: color.value,
47
51
  variant: props.variant,
48
- size: size.value ?? props.size,
49
- highlight: highlight.value ?? props.highlight,
52
+ size: size.value,
53
+ highlight: highlight.value,
50
54
  fixed: props.fixed
51
55
  }));
52
56
  const inputsRef = ref([]);
53
57
  function setInputRef(index, el) {
54
58
  inputsRef.value[index] = el;
55
59
  }
56
- const completed = ref(false);
57
60
  function onComplete(value) {
58
61
  const event = new Event("change", { target: { value } });
59
62
  emits("change", event);
60
63
  emitFormChange();
61
64
  }
62
65
  function onBlur(event) {
63
- if (!event.relatedTarget || completed.value) {
66
+ if (!event.relatedTarget) {
64
67
  emits("blur", event);
65
68
  emitFormBlur();
66
69
  }
@@ -84,11 +87,13 @@ function shouldInsertSeparator(index) {
84
87
  const separator = looseToNumber(props.separator);
85
88
  return Number.isInteger(separator) && separator > 0 && position % separator === 0;
86
89
  }
90
+ let autofocusTimeoutId;
87
91
  onMounted(() => {
88
- setTimeout(() => {
92
+ autofocusTimeoutId = setTimeout(() => {
89
93
  autoFocus();
90
94
  }, props.autofocusDelay);
91
95
  });
96
+ onScopeDispose(() => clearTimeout(autofocusTimeoutId));
92
97
  defineExpose({
93
98
  inputsRef
94
99
  });
@@ -5,7 +5,6 @@ import theme from "#build/ui/popover";
5
5
  <script setup>
6
6
  import { computed, toRef } from "vue";
7
7
  import { defu } from "defu";
8
- import {} from "reka-ui";
9
8
  import { useForwardProps } from "../composables/useForwardProps";
10
9
  import { Popover, HoverCard } from "reka-ui/namespaced";
11
10
  import { reactivePick } from "@vueuse/core";
@@ -49,7 +49,7 @@ export interface PricingTableProps<T extends PricingTableTier = PricingTableTier
49
49
  as?: any;
50
50
  /**
51
51
  * The caption to display above the table.
52
- * @defeaultValue t('pricingTable.caption')
52
+ * @defaultValue t('pricingTable.caption')
53
53
  */
54
54
  caption?: string;
55
55
  /**
@@ -49,7 +49,7 @@ export interface PricingTableProps<T extends PricingTableTier = PricingTableTier
49
49
  as?: any;
50
50
  /**
51
51
  * The caption to display above the table.
52
- * @defeaultValue t('pricingTable.caption')
52
+ * @defaultValue t('pricingTable.caption')
53
53
  */
54
54
  caption?: string;
55
55
  /**
@@ -21,9 +21,10 @@ export interface ProgressProps extends Pick<ProgressRootProps, 'getValueLabel' |
21
21
  */
22
22
  size?: Progress['variants']['size'];
23
23
  /**
24
+ * Any theme color, or any CSS color value for palettes outside the theme.
24
25
  * @defaultValue 'primary'
25
26
  */
26
- color?: Progress['variants']['color'];
27
+ color?: Progress['variants']['color'] | (string & {});
27
28
  /**
28
29
  * The orientation of the progress bar.
29
30
  * @defaultValue 'horizontal'
@@ -76,10 +76,7 @@ const indicatorStyle = computed(() => {
76
76
  }
77
77
  }
78
78
  });
79
- const statusStyle = computed(() => {
80
- const value = `${Math.max(percent.value ?? 0, 0)}%`;
81
- return props.orientation === "vertical" ? { height: value } : { width: value };
82
- });
79
+ const statusStyle = computed(() => ({ "--percent": `${Math.max(percent.value ?? 0, 0)}%` }));
83
80
  function isActive(index) {
84
81
  return index === Number(props.modelValue);
85
82
  }
@@ -109,6 +106,8 @@ const ui = computed(() => tv({ extend: theme, ...appConfig.ui?.progress || {} })
109
106
  orientation: props.orientation,
110
107
  inverted: props.inverted
111
108
  }));
109
+ const themeColors = computed(() => Object.keys({ ...theme.variants?.color, ...appConfig.ui?.progress?.variants?.color }));
110
+ const customColor = computed(() => props.color && !themeColors.value.includes(props.color) ? props.color : void 0);
112
111
  </script>
113
112
 
114
113
  <template>
@@ -120,10 +119,10 @@ const ui = computed(() => tv({ extend: theme, ...appConfig.ui?.progress || {} })
120
119
  </div>
121
120
 
122
121
  <ProgressRoot v-bind="rootProps" :max="realMax" data-slot="base" :class="ui.base({ class: props.ui?.base })" style="transform: translateZ(0)">
123
- <ProgressIndicator data-slot="indicator" :class="ui.indicator({ class: props.ui?.indicator })" :style="indicatorStyle" />
122
+ <ProgressIndicator data-slot="indicator" :class="ui.indicator({ class: props.ui?.indicator })" :style="[indicatorStyle, customColor ? { backgroundColor: customColor } : void 0]" />
124
123
  </ProgressRoot>
125
124
 
126
- <div v-if="hasSteps" data-slot="steps" :class="ui.steps({ class: props.ui?.steps })">
125
+ <div v-if="hasSteps" data-slot="steps" :class="ui.steps({ class: props.ui?.steps })" :style="customColor ? { color: customColor } : void 0">
127
126
  <div v-for="(step, index) in props.max" :key="index" data-slot="step" :class="ui.step({ class: props.ui?.step, step: stepVariant(index) })">
128
127
  <slot :name="`step-${index}`" :step="step">
129
128
  {{ step }}
@@ -21,9 +21,10 @@ export interface ProgressProps extends Pick<ProgressRootProps, 'getValueLabel' |
21
21
  */
22
22
  size?: Progress['variants']['size'];
23
23
  /**
24
+ * Any theme color, or any CSS color value for palettes outside the theme.
24
25
  * @defaultValue 'primary'
25
26
  */
26
- color?: Progress['variants']['color'];
27
+ color?: Progress['variants']['color'] | (string & {});
27
28
  /**
28
29
  * The orientation of the progress bar.
29
30
  * @defaultValue 'horizontal'