vuetify 3.3.10 → 3.3.11

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 (207) hide show
  1. package/dist/_component-variables-labs.sass +3 -1
  2. package/dist/json/attributes.json +221 -33
  3. package/dist/json/importMap-labs.json +28 -0
  4. package/dist/json/tags.json +79 -0
  5. package/dist/json/web-types.json +693 -34
  6. package/dist/vuetify-labs.css +1050 -885
  7. package/dist/vuetify-labs.d.ts +2802 -304
  8. package/dist/vuetify-labs.esm.js +719 -68
  9. package/dist/vuetify-labs.esm.js.map +1 -1
  10. package/dist/vuetify-labs.js +719 -68
  11. package/dist/vuetify-labs.min.css +2 -2
  12. package/dist/vuetify.css +187 -182
  13. package/dist/vuetify.d.ts +64 -29
  14. package/dist/vuetify.esm.js +137 -61
  15. package/dist/vuetify.esm.js.map +1 -1
  16. package/dist/vuetify.js +137 -61
  17. package/dist/vuetify.js.map +1 -1
  18. package/dist/vuetify.min.css +2 -2
  19. package/dist/vuetify.min.js +954 -947
  20. package/dist/vuetify.min.js.map +1 -1
  21. package/lib/blueprints/md1.mjs +5 -0
  22. package/lib/blueprints/md1.mjs.map +1 -1
  23. package/lib/blueprints/md2.mjs +5 -0
  24. package/lib/blueprints/md2.mjs.map +1 -1
  25. package/lib/blueprints/md3.mjs +5 -0
  26. package/lib/blueprints/md3.mjs.map +1 -1
  27. package/lib/components/VAutocomplete/VAutocomplete.mjs +13 -10
  28. package/lib/components/VAutocomplete/VAutocomplete.mjs.map +1 -1
  29. package/lib/components/VAutocomplete/index.d.mts +6 -0
  30. package/lib/components/VCarousel/index.d.mts +12 -10
  31. package/lib/components/VChip/VChip.mjs +3 -3
  32. package/lib/components/VChip/VChip.mjs.map +1 -1
  33. package/lib/components/VCombobox/VCombobox.mjs +10 -4
  34. package/lib/components/VCombobox/VCombobox.mjs.map +1 -1
  35. package/lib/components/VCombobox/index.d.mts +6 -0
  36. package/lib/components/VExpansionPanel/VExpansionPanel.mjs +8 -3
  37. package/lib/components/VExpansionPanel/VExpansionPanel.mjs.map +1 -1
  38. package/lib/components/VMenu/VMenu.mjs +29 -4
  39. package/lib/components/VMenu/VMenu.mjs.map +1 -1
  40. package/lib/components/VOverlay/useActivator.mjs +2 -2
  41. package/lib/components/VOverlay/useActivator.mjs.map +1 -1
  42. package/lib/components/VRangeSlider/VRangeSlider.mjs.map +1 -1
  43. package/lib/components/VRangeSlider/index.d.mts +8 -8
  44. package/lib/components/VRating/VRating.mjs +4 -2
  45. package/lib/components/VRating/VRating.mjs.map +1 -1
  46. package/lib/components/VSelect/VSelect.mjs +11 -4
  47. package/lib/components/VSelect/VSelect.mjs.map +1 -1
  48. package/lib/components/VSelect/index.d.mts +6 -0
  49. package/lib/components/VSelectionControl/VSelectionControl.mjs +2 -2
  50. package/lib/components/VSelectionControl/VSelectionControl.mjs.map +1 -1
  51. package/lib/components/VSlider/VSlider.mjs +2 -3
  52. package/lib/components/VSlider/VSlider.mjs.map +1 -1
  53. package/lib/components/VSlider/slider.mjs +1 -0
  54. package/lib/components/VSlider/slider.mjs.map +1 -1
  55. package/lib/components/VSwitch/VSwitch.css +3 -0
  56. package/lib/components/VSwitch/VSwitch.sass +3 -0
  57. package/lib/components/VSwitch/_variables.scss +1 -0
  58. package/lib/components/VTable/VTable.css +2 -0
  59. package/lib/components/VTable/VTable.sass +2 -0
  60. package/lib/components/VTimeline/VTimeline.css +2 -2
  61. package/lib/components/VTimeline/VTimeline.sass +2 -2
  62. package/lib/components/VWindow/VWindow.mjs +1 -0
  63. package/lib/components/VWindow/VWindow.mjs.map +1 -1
  64. package/lib/components/VWindow/VWindowItem.mjs +3 -1
  65. package/lib/components/VWindow/VWindowItem.mjs.map +1 -1
  66. package/lib/components/VWindow/index.d.mts +29 -11
  67. package/lib/components/index.d.mts +57 -29
  68. package/lib/composables/group.mjs +1 -1
  69. package/lib/composables/group.mjs.map +1 -1
  70. package/lib/composables/theme.mjs +12 -6
  71. package/lib/composables/theme.mjs.map +1 -1
  72. package/lib/entry-bundler.mjs +1 -1
  73. package/lib/framework.mjs +1 -1
  74. package/lib/index.d.mts +7 -0
  75. package/lib/labs/VDatePicker/VDatePicker.css +6 -5
  76. package/lib/labs/VDatePicker/VDatePicker.mjs +3 -3
  77. package/lib/labs/VDatePicker/VDatePicker.mjs.map +1 -1
  78. package/lib/labs/VDatePicker/VDatePicker.sass +8 -9
  79. package/lib/labs/VDateRangePicker/VDateRangePickerHeader.mjs +2 -2
  80. package/lib/labs/VDateRangePicker/VDateRangePickerHeader.mjs.map +1 -1
  81. package/lib/labs/VInfiniteScroll/VInfiniteScroll.mjs +4 -5
  82. package/lib/labs/VInfiniteScroll/VInfiniteScroll.mjs.map +1 -1
  83. package/lib/labs/VOtpInput/VOtpInput.css +53 -0
  84. package/lib/labs/VOtpInput/VOtpInput.mjs +213 -0
  85. package/lib/labs/VOtpInput/VOtpInput.mjs.map +1 -0
  86. package/lib/labs/VOtpInput/VOtpInput.sass +55 -0
  87. package/lib/labs/VOtpInput/_variables.scss +2 -0
  88. package/lib/labs/VOtpInput/index.d.mts +459 -0
  89. package/lib/labs/VOtpInput/index.mjs +2 -0
  90. package/lib/labs/VOtpInput/index.mjs.map +1 -0
  91. package/lib/labs/VPicker/VPicker.mjs +1 -1
  92. package/lib/labs/VPicker/VPicker.mjs.map +1 -1
  93. package/lib/labs/VStepper/VStepper.css +42 -0
  94. package/lib/labs/VStepper/VStepper.mjs +147 -0
  95. package/lib/labs/VStepper/VStepper.mjs.map +1 -0
  96. package/lib/labs/VStepper/VStepper.sass +44 -0
  97. package/lib/labs/VStepper/VStepperActions.mjs +61 -0
  98. package/lib/labs/VStepper/VStepperActions.mjs.map +1 -0
  99. package/lib/labs/VStepper/VStepperHeader.mjs +4 -0
  100. package/lib/labs/VStepper/VStepperHeader.mjs.map +1 -0
  101. package/lib/labs/VStepper/VStepperItem.css +67 -0
  102. package/lib/labs/VStepper/VStepperItem.mjs +114 -0
  103. package/lib/labs/VStepper/VStepperItem.mjs.map +1 -0
  104. package/lib/labs/VStepper/VStepperItem.sass +71 -0
  105. package/lib/labs/VStepper/VStepperWindow.mjs +50 -0
  106. package/lib/labs/VStepper/VStepperWindow.mjs.map +1 -0
  107. package/lib/labs/VStepper/VStepperWindowItem.mjs +24 -0
  108. package/lib/labs/VStepper/VStepperWindowItem.mjs.map +1 -0
  109. package/lib/labs/VStepper/_variables.scss +4 -0
  110. package/lib/labs/VStepper/index.d.mts +2051 -0
  111. package/lib/labs/VStepper/index.mjs +7 -0
  112. package/lib/labs/VStepper/index.mjs.map +1 -0
  113. package/lib/labs/components.d.mts +2751 -267
  114. package/lib/labs/components.mjs +2 -0
  115. package/lib/labs/components.mjs.map +1 -1
  116. package/lib/labs/date/adapters/vuetify.mjs +6 -7
  117. package/lib/labs/date/adapters/vuetify.mjs.map +1 -1
  118. package/lib/locale/af.mjs +6 -1
  119. package/lib/locale/af.mjs.map +1 -1
  120. package/lib/locale/ar.mjs +6 -1
  121. package/lib/locale/ar.mjs.map +1 -1
  122. package/lib/locale/az.mjs +6 -1
  123. package/lib/locale/az.mjs.map +1 -1
  124. package/lib/locale/bg.mjs +6 -1
  125. package/lib/locale/bg.mjs.map +1 -1
  126. package/lib/locale/ca.mjs +6 -1
  127. package/lib/locale/ca.mjs.map +1 -1
  128. package/lib/locale/ckb.mjs +6 -1
  129. package/lib/locale/ckb.mjs.map +1 -1
  130. package/lib/locale/cs.mjs +6 -1
  131. package/lib/locale/cs.mjs.map +1 -1
  132. package/lib/locale/da.mjs +6 -1
  133. package/lib/locale/da.mjs.map +1 -1
  134. package/lib/locale/de.mjs +6 -1
  135. package/lib/locale/de.mjs.map +1 -1
  136. package/lib/locale/el.mjs +6 -1
  137. package/lib/locale/el.mjs.map +1 -1
  138. package/lib/locale/en.mjs +6 -1
  139. package/lib/locale/en.mjs.map +1 -1
  140. package/lib/locale/es.mjs +6 -1
  141. package/lib/locale/es.mjs.map +1 -1
  142. package/lib/locale/et.mjs +6 -1
  143. package/lib/locale/et.mjs.map +1 -1
  144. package/lib/locale/fa.mjs +6 -1
  145. package/lib/locale/fa.mjs.map +1 -1
  146. package/lib/locale/fi.mjs +6 -1
  147. package/lib/locale/fi.mjs.map +1 -1
  148. package/lib/locale/fr.mjs +6 -1
  149. package/lib/locale/fr.mjs.map +1 -1
  150. package/lib/locale/he.mjs +6 -1
  151. package/lib/locale/he.mjs.map +1 -1
  152. package/lib/locale/hr.mjs +6 -1
  153. package/lib/locale/hr.mjs.map +1 -1
  154. package/lib/locale/hu.mjs +6 -1
  155. package/lib/locale/hu.mjs.map +1 -1
  156. package/lib/locale/id.mjs +6 -1
  157. package/lib/locale/id.mjs.map +1 -1
  158. package/lib/locale/index.d.mts +210 -0
  159. package/lib/locale/it.mjs +6 -1
  160. package/lib/locale/it.mjs.map +1 -1
  161. package/lib/locale/ja.mjs +6 -1
  162. package/lib/locale/ja.mjs.map +1 -1
  163. package/lib/locale/ko.mjs +6 -1
  164. package/lib/locale/ko.mjs.map +1 -1
  165. package/lib/locale/lt.mjs +6 -1
  166. package/lib/locale/lt.mjs.map +1 -1
  167. package/lib/locale/lv.mjs +6 -1
  168. package/lib/locale/lv.mjs.map +1 -1
  169. package/lib/locale/nl.mjs +6 -1
  170. package/lib/locale/nl.mjs.map +1 -1
  171. package/lib/locale/no.mjs +6 -1
  172. package/lib/locale/no.mjs.map +1 -1
  173. package/lib/locale/pl.mjs +6 -1
  174. package/lib/locale/pl.mjs.map +1 -1
  175. package/lib/locale/pt.mjs +6 -1
  176. package/lib/locale/pt.mjs.map +1 -1
  177. package/lib/locale/ro.mjs +23 -18
  178. package/lib/locale/ro.mjs.map +1 -1
  179. package/lib/locale/ru.mjs +6 -1
  180. package/lib/locale/ru.mjs.map +1 -1
  181. package/lib/locale/sk.mjs +6 -1
  182. package/lib/locale/sk.mjs.map +1 -1
  183. package/lib/locale/sl.mjs +6 -1
  184. package/lib/locale/sl.mjs.map +1 -1
  185. package/lib/locale/sr-Cyrl.mjs +6 -1
  186. package/lib/locale/sr-Cyrl.mjs.map +1 -1
  187. package/lib/locale/sr-Latn.mjs +6 -1
  188. package/lib/locale/sr-Latn.mjs.map +1 -1
  189. package/lib/locale/sv.mjs +6 -1
  190. package/lib/locale/sv.mjs.map +1 -1
  191. package/lib/locale/th.mjs +6 -1
  192. package/lib/locale/th.mjs.map +1 -1
  193. package/lib/locale/tr.mjs +6 -1
  194. package/lib/locale/tr.mjs.map +1 -1
  195. package/lib/locale/uk.mjs +6 -1
  196. package/lib/locale/uk.mjs.map +1 -1
  197. package/lib/locale/vi.mjs +6 -1
  198. package/lib/locale/vi.mjs.map +1 -1
  199. package/lib/locale/zh-Hans.mjs +6 -1
  200. package/lib/locale/zh-Hans.mjs.map +1 -1
  201. package/lib/locale/zh-Hant.mjs +6 -1
  202. package/lib/locale/zh-Hant.mjs.map +1 -1
  203. package/lib/util/globals.mjs +0 -1
  204. package/lib/util/globals.mjs.map +1 -1
  205. package/lib/util/helpers.mjs +32 -12
  206. package/lib/util/helpers.mjs.map +1 -1
  207. package/package.json +3 -2
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.3.10
2
+ * Vuetify v3.3.11
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
@@ -75,6 +75,10 @@
75
75
  }
76
76
  }, 'component');
77
77
 
78
+ const IN_BROWSER = typeof window !== 'undefined';
79
+ const SUPPORTS_INTERSECTION = IN_BROWSER && 'IntersectionObserver' in window;
80
+ const SUPPORTS_TOUCH = IN_BROWSER && ('ontouchstart' in window || window.navigator.maxTouchPoints > 0);
81
+
78
82
  function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
79
83
  function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
80
84
  function _classPrivateFieldSet(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set"); _classApplyDescriptorSet(receiver, descriptor, value); return value; }
@@ -224,6 +228,11 @@
224
228
  exclude.forEach(prop => delete clone[prop]);
225
229
  return clone;
226
230
  }
231
+ function only(obj, include) {
232
+ const clone = {};
233
+ include.forEach(prop => clone[prop] = obj[prop]);
234
+ return clone;
235
+ }
227
236
 
228
237
  /**
229
238
  * Filter attributes that should be applied to
@@ -407,12 +416,22 @@
407
416
  }
408
417
  }
409
418
  function focusableChildren(el) {
410
- const targets = ['button', '[href]', 'input:not([type="hidden"])', 'select', 'textarea', '[tabindex]'].map(s => `${s}:not([tabindex="-1"]):not([disabled])`).join(', ');
419
+ let filterByTabIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
420
+ const targets = ['button', '[href]', 'input:not([type="hidden"])', 'select', 'textarea', '[tabindex]'].map(s => `${s}${filterByTabIndex ? ':not([tabindex="-1"])' : ''}:not([disabled])`).join(', ');
411
421
  return [...el.querySelectorAll(targets)];
412
422
  }
423
+ function getNextElement(elements, location, condition) {
424
+ let _el;
425
+ let idx = elements.indexOf(document.activeElement);
426
+ const inc = location === 'next' ? 1 : -1;
427
+ do {
428
+ idx += inc;
429
+ _el = elements[idx];
430
+ } while ((!_el || _el.offsetParent == null || !(condition?.(_el) ?? true)) && idx < elements.length && idx >= 0);
431
+ return _el;
432
+ }
413
433
  function focusChild(el, location) {
414
434
  const focusable = focusableChildren(el);
415
- const idx = focusable.indexOf(document.activeElement);
416
435
  if (!location) {
417
436
  if (el === document.activeElement || !el.contains(document.activeElement)) {
418
437
  focusable[0]?.focus();
@@ -421,14 +440,10 @@
421
440
  focusable[0]?.focus();
422
441
  } else if (location === 'last') {
423
442
  focusable.at(-1)?.focus();
443
+ } else if (typeof location === 'number') {
444
+ focusable[location]?.focus();
424
445
  } else {
425
- let _el;
426
- let idxx = idx;
427
- const inc = location === 'next' ? 1 : -1;
428
- do {
429
- idxx += inc;
430
- _el = focusable[idxx];
431
- } while ((!_el || _el.offsetParent == null) && idxx < focusable.length && idxx >= 0);
446
+ const _el = getNextElement(focusable, location);
432
447
  if (_el) _el.focus();else focusChild(el, location === 'next' ? 'first' : 'last');
433
448
  }
434
449
  }
@@ -437,6 +452,17 @@
437
452
  }
438
453
  function noop() {}
439
454
 
455
+ /** Returns null if the selector is not supported or we can't check */
456
+ function matchesSelector(el, selector) {
457
+ const supportsSelector = IN_BROWSER && typeof CSS !== 'undefined' && typeof CSS.supports !== 'undefined' && CSS.supports(`selector(${selector})`);
458
+ if (!supportsSelector) return null;
459
+ try {
460
+ return !!el && el.matches(selector);
461
+ } catch (err) {
462
+ return null;
463
+ }
464
+ }
465
+
440
466
  // Utilities
441
467
  const block = ['top', 'bottom'];
442
468
  const inline = ['start', 'end', 'left', 'right'];
@@ -1286,11 +1312,6 @@
1286
1312
  return ['scroll', 'auto'].includes(style.overflowY);
1287
1313
  }
1288
1314
 
1289
- const IN_BROWSER = typeof window !== 'undefined';
1290
- const SUPPORTS_INTERSECTION = IN_BROWSER && 'IntersectionObserver' in window;
1291
- const SUPPORTS_TOUCH = IN_BROWSER && ('ontouchstart' in window || window.navigator.maxTouchPoints > 0);
1292
- const SUPPORTS_FOCUS_VISIBLE = IN_BROWSER && typeof CSS !== 'undefined' && typeof CSS.supports !== 'undefined' && CSS.supports('selector(:focus-visible)');
1293
-
1294
1315
  // Utilities
1295
1316
 
1296
1317
  // Types
@@ -1692,7 +1713,8 @@
1692
1713
  input: {
1693
1714
  clear: 'Clear {0}',
1694
1715
  prependAction: '{0} prepended action',
1695
- appendAction: '{0} appended action'
1716
+ appendAction: '{0} appended action',
1717
+ otp: 'Please enter OTP character {0}'
1696
1718
  },
1697
1719
  fileInput: {
1698
1720
  counter: '{0} files',
@@ -1713,6 +1735,10 @@
1713
1735
  last: 'Last page'
1714
1736
  }
1715
1737
  },
1738
+ stepper: {
1739
+ next: 'Next',
1740
+ prev: 'Previous'
1741
+ },
1716
1742
  rating: {
1717
1743
  ariaLabel: {
1718
1744
  item: 'Rating {0} of {1}'
@@ -2251,9 +2277,11 @@
2251
2277
  if (head) {
2252
2278
  if (head.push) {
2253
2279
  const entry = head.push(getHead);
2254
- vue.watch(styles, () => {
2255
- entry.patch(getHead);
2256
- });
2280
+ if (IN_BROWSER) {
2281
+ vue.watch(styles, () => {
2282
+ entry.patch(getHead);
2283
+ });
2284
+ }
2257
2285
  } else {
2258
2286
  if (IN_BROWSER) {
2259
2287
  head.addHeadObjs(vue.computed(getHead));
@@ -2264,9 +2292,13 @@
2264
2292
  }
2265
2293
  } else {
2266
2294
  let styleEl = IN_BROWSER ? document.getElementById('vuetify-theme-stylesheet') : null;
2267
- vue.watch(styles, updateStyles, {
2268
- immediate: true
2269
- });
2295
+ if (IN_BROWSER) {
2296
+ vue.watch(styles, updateStyles, {
2297
+ immediate: true
2298
+ });
2299
+ } else {
2300
+ updateStyles();
2301
+ }
2270
2302
  function updateStyles() {
2271
2303
  if (typeof document !== 'undefined' && !styleEl) {
2272
2304
  const el = document.createElement('style');
@@ -3871,7 +3903,7 @@
3871
3903
  throw new Error(`[Vuetify] Could not find useGroup injection with symbol ${injectKey.description}`);
3872
3904
  }
3873
3905
  const value = vue.toRef(props, 'value');
3874
- const disabled = vue.computed(() => group.disabled.value || props.disabled);
3906
+ const disabled = vue.computed(() => !!(group.disabled.value || props.disabled));
3875
3907
  group.register({
3876
3908
  id,
3877
3909
  value,
@@ -5806,7 +5838,7 @@
5806
5838
  });
5807
5839
  function onFocus(e) {
5808
5840
  isFocused.value = true;
5809
- if (!SUPPORTS_FOCUS_VISIBLE || SUPPORTS_FOCUS_VISIBLE && e.target.matches(':focus-visible')) {
5841
+ if (matchesSelector(e.target, ':focus-visible') !== false) {
5810
5842
  isFocusVisible.value = true;
5811
5843
  }
5812
5844
  }
@@ -6815,7 +6847,7 @@
6815
6847
  }, [!slots.filter ? vue.createVNode(VIcon, {
6816
6848
  "key": "filter-icon",
6817
6849
  "icon": props.filterIcon
6818
- }, null) : vue.withDirectives(vue.createVNode(VDefaultsProvider, {
6850
+ }, null) : vue.createVNode(VDefaultsProvider, {
6819
6851
  "key": "filter-defaults",
6820
6852
  "disabled": !props.filterIcon,
6821
6853
  "defaults": {
@@ -6823,7 +6855,7 @@
6823
6855
  icon: props.filterIcon
6824
6856
  }
6825
6857
  }
6826
- }, null), [[vue.resolveDirective("slot"), slots.filter, "default"]])]), [[vue.vShow, group.isSelected.value]])]
6858
+ }, slots.filter)]), [[vue.vShow, group.isSelected.value]])]
6827
6859
  }), hasPrepend && vue.createVNode("div", {
6828
6860
  "key": "prepend",
6829
6861
  "class": "v-chip__prepend"
@@ -8904,7 +8936,7 @@
8904
8936
  runCloseDelay();
8905
8937
  },
8906
8938
  onFocus: e => {
8907
- if (SUPPORTS_FOCUS_VISIBLE && !e.target.matches(':focus-visible')) return;
8939
+ if (matchesSelector(e.target, ':focus-visible') === false) return;
8908
8940
  isFocused = true;
8909
8941
  e.stopPropagation();
8910
8942
  activatorEl.value = e.currentTarget || e.target;
@@ -9824,8 +9856,30 @@
9824
9856
  }, 40);
9825
9857
  }
9826
9858
  });
9859
+ function onFocusIn(e) {
9860
+ const before = e.relatedTarget;
9861
+ const after = e.target;
9862
+ if (before !== after && overlay.value?.contentEl &&
9863
+ // We're the topmost menu
9864
+ overlay.value?.globalTop &&
9865
+ // It isn't the document or the menu body
9866
+ ![document, overlay.value.contentEl].includes(after) &&
9867
+ // It isn't inside the menu body
9868
+ !overlay.value.contentEl.contains(after)) {
9869
+ const focusable = focusableChildren(overlay.value.contentEl);
9870
+ focusable[0]?.focus();
9871
+ }
9872
+ }
9827
9873
  vue.watch(isActive, val => {
9828
- val ? parent?.register() : parent?.unregister();
9874
+ if (val) {
9875
+ parent?.register();
9876
+ document.addEventListener('focusin', onFocusIn, {
9877
+ once: true
9878
+ });
9879
+ } else {
9880
+ parent?.unregister();
9881
+ document.removeEventListener('focusin', onFocusIn);
9882
+ }
9829
9883
  });
9830
9884
  function onClickOutside() {
9831
9885
  parent?.closeParents();
@@ -9833,8 +9887,11 @@
9833
9887
  function onKeydown(e) {
9834
9888
  if (props.disabled) return;
9835
9889
  if (e.key === 'Tab') {
9836
- isActive.value = false;
9837
- overlay.value?.activatorEl?.focus();
9890
+ const nextElement = getNextElement(focusableChildren(overlay.value?.contentEl, false), e.shiftKey ? 'prev' : 'next', el => el.tabIndex >= 0);
9891
+ if (!nextElement) {
9892
+ isActive.value = false;
9893
+ overlay.value?.activatorEl?.focus();
9894
+ }
9838
9895
  }
9839
9896
  }
9840
9897
  function onActivatorKeydown(e) {
@@ -10748,6 +10805,7 @@
10748
10805
  type: Function,
10749
10806
  default: deepEqual
10750
10807
  },
10808
+ itemColor: String,
10751
10809
  ...makeItemsProps({
10752
10810
  itemChildren: false
10753
10811
  })
@@ -10800,7 +10858,12 @@
10800
10858
  const form = useForm();
10801
10859
  const selections = vue.computed(() => {
10802
10860
  return model.value.map(v => {
10803
- return items.value.find(item => props.valueComparator(item.value, v.value)) || v;
10861
+ return items.value.find(item => {
10862
+ const itemRawValue = getPropertyFromItem(item.raw, props.itemValue);
10863
+ const modelRawValue = getPropertyFromItem(v.raw, props.itemValue);
10864
+ if (itemRawValue === undefined || modelRawValue === undefined) return false;
10865
+ return props.returnObject ? props.valueComparator(itemRawValue, modelRawValue) : props.valueComparator(item.value, v.value);
10866
+ }) || v;
10804
10867
  });
10805
10868
  });
10806
10869
  const selected = vue.computed(() => selections.value.map(selection => selection.props.value));
@@ -10894,7 +10957,7 @@
10894
10957
  isFocused.value = true;
10895
10958
  }
10896
10959
  function onModelUpdate(v) {
10897
- if (v == null) model.value = [];else if (vTextFieldRef.value?.matches(':autofill') || vTextFieldRef.value?.matches(':-webkit-autofill')) {
10960
+ if (v == null) model.value = [];else if (matchesSelector(vTextFieldRef.value, ':autofill') || matchesSelector(vTextFieldRef.value, ':-webkit-autofill')) {
10898
10961
  const item = items.value.find(item => item.title === v);
10899
10962
  if (item) {
10900
10963
  select(item);
@@ -10956,7 +11019,8 @@
10956
11019
  "onKeydown": onListKeydown,
10957
11020
  "onFocusin": onFocusin,
10958
11021
  "onScrollPassive": onListScroll,
10959
- "tabindex": "-1"
11022
+ "tabindex": "-1",
11023
+ "color": props.itemColor ?? props.color
10960
11024
  }, {
10961
11025
  default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? vue.createVNode(VListItem, {
10962
11026
  "title": t(props.noDataText)
@@ -11218,7 +11282,7 @@
11218
11282
  const vTextFieldRef = vue.ref();
11219
11283
  const isFocused = vue.shallowRef(false);
11220
11284
  const isPristine = vue.shallowRef(true);
11221
- const listHasFocus = vue.ref(false);
11285
+ const listHasFocus = vue.shallowRef(false);
11222
11286
  const vMenuRef = vue.ref();
11223
11287
  const _menu = useProxiedModel(props, 'menu');
11224
11288
  const menu = vue.computed({
@@ -11251,7 +11315,12 @@
11251
11315
  } = useFilter(props, items, () => isPristine.value ? '' : search.value);
11252
11316
  const selections = vue.computed(() => {
11253
11317
  return model.value.map(v => {
11254
- return items.value.find(item => props.valueComparator(item.value, v.value)) || v;
11318
+ return items.value.find(item => {
11319
+ const itemRawValue = getPropertyFromItem(item.raw, props.itemValue);
11320
+ const modelRawValue = getPropertyFromItem(v.raw, props.itemValue);
11321
+ if (itemRawValue === undefined || modelRawValue === undefined) return false;
11322
+ return props.returnObject ? props.valueComparator(itemRawValue, modelRawValue) : props.valueComparator(item.value, v.value);
11323
+ }) || v;
11255
11324
  });
11256
11325
  });
11257
11326
  const displayItems = vue.computed(() => {
@@ -11303,11 +11372,8 @@
11303
11372
  if (['Escape'].includes(e.key)) {
11304
11373
  menu.value = false;
11305
11374
  }
11306
- if (['Enter', 'Escape', 'Tab'].includes(e.key)) {
11307
- if (highlightFirst.value && ['Enter', 'Tab'].includes(e.key)) {
11308
- select(filteredItems.value[0]);
11309
- }
11310
- isPristine.value = true;
11375
+ if (highlightFirst.value && ['Enter', 'Tab'].includes(e.key)) {
11376
+ select(filteredItems.value[0]);
11311
11377
  }
11312
11378
  if (e.key === 'ArrowDown' && highlightFirst.value) {
11313
11379
  listRef.value?.focus('next');
@@ -11349,7 +11415,7 @@
11349
11415
  search.value = e.target.value;
11350
11416
  }
11351
11417
  function onChange(e) {
11352
- if (vTextFieldRef.value?.matches(':autofill') || vTextFieldRef.value?.matches(':-webkit-autofill')) {
11418
+ if (matchesSelector(vTextFieldRef.value, ':autofill') || matchesSelector(vTextFieldRef.value, ':-webkit-autofill')) {
11353
11419
  const item = items.value.find(item => item.title === e.target.value);
11354
11420
  if (item) {
11355
11421
  select(item);
@@ -11473,7 +11539,8 @@
11473
11539
  "onFocusin": onFocusin,
11474
11540
  "onFocusout": onFocusout,
11475
11541
  "onScrollPassive": onListScroll,
11476
- "tabindex": "-1"
11542
+ "tabindex": "-1",
11543
+ "color": props.itemColor ?? props.color
11477
11544
  }, {
11478
11545
  default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? vue.createVNode(VListItem, {
11479
11546
  "title": t(props.noDataText)
@@ -12521,6 +12588,7 @@
12521
12588
  },
12522
12589
  // TODO: mandatory should probably not be exposed but do this for now
12523
12590
  mandatory: {
12591
+ type: [Boolean, String],
12524
12592
  default: 'force'
12525
12593
  },
12526
12594
  ...makeComponentProps(),
@@ -12888,7 +12956,9 @@
12888
12956
  "style": props.style
12889
12957
  }, [hasContent.value && slots.default?.()]), [[vue.vShow, groupItem.isSelected.value]])]
12890
12958
  }));
12891
- return {};
12959
+ return {
12960
+ groupItem
12961
+ };
12892
12962
  }
12893
12963
  });
12894
12964
 
@@ -13442,6 +13512,7 @@
13442
13512
  const step = vue.computed(() => +props.step > 0 ? parseFloat(props.step) : 0);
13443
13513
  const decimals = vue.computed(() => Math.max(getDecimals(step.value), getDecimals(min.value)));
13444
13514
  function roundValue(value) {
13515
+ value = parseFloat(value);
13445
13516
  if (step.value <= 0) return value;
13446
13517
  const clamped = clamp(value, min.value, max.value);
13447
13518
  const offset = min.value % step.value;
@@ -13945,9 +14016,8 @@
13945
14016
  rtlClasses
13946
14017
  } = useRtl();
13947
14018
  const steps = useSteps(props);
13948
- const model = useProxiedModel(props, 'modelValue', undefined, v => {
13949
- const value = typeof v === 'string' ? parseFloat(v) : v == null ? steps.min.value : v;
13950
- return steps.roundValue(value);
14019
+ const model = useProxiedModel(props, 'modelValue', undefined, value => {
14020
+ return steps.roundValue(value == null ? steps.min.value : value);
13951
14021
  });
13952
14022
  const {
13953
14023
  min,
@@ -14741,7 +14811,7 @@
14741
14811
  const vTextFieldRef = vue.ref();
14742
14812
  const isFocused = vue.shallowRef(false);
14743
14813
  const isPristine = vue.shallowRef(true);
14744
- const listHasFocus = vue.ref(false);
14814
+ const listHasFocus = vue.shallowRef(false);
14745
14815
  const vMenuRef = vue.ref();
14746
14816
  const _menu = useProxiedModel(props, 'menu');
14747
14817
  const menu = vue.computed({
@@ -14813,7 +14883,12 @@
14813
14883
  } = useFilter(props, items, () => isPristine.value ? '' : search.value);
14814
14884
  const selections = vue.computed(() => {
14815
14885
  return model.value.map(v => {
14816
- return items.value.find(item => props.valueComparator(item.value, v.value)) || v;
14886
+ return items.value.find(item => {
14887
+ const itemRawValue = getPropertyFromItem(item.raw, props.itemValue);
14888
+ const modelRawValue = getPropertyFromItem(v.raw, props.itemValue);
14889
+ if (itemRawValue === undefined || modelRawValue === undefined) return false;
14890
+ return props.returnObject ? props.valueComparator(itemRawValue, modelRawValue) : props.valueComparator(item.value, v.value);
14891
+ }) || v;
14817
14892
  });
14818
14893
  });
14819
14894
  const displayItems = vue.computed(() => {
@@ -15022,7 +15097,8 @@
15022
15097
  "onFocusin": onFocusin,
15023
15098
  "onFocusout": onFocusout,
15024
15099
  "onScrollPassive": onListScroll,
15025
- "tabindex": "-1"
15100
+ "tabindex": "-1",
15101
+ "color": props.itemColor ?? props.color
15026
15102
  }, {
15027
15103
  default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? vue.createVNode(VListItem, {
15028
15104
  "title": t(props.noDataText)
@@ -15440,6 +15516,11 @@
15440
15516
  return !groupItem.isSelected.value && selectedIndices.value.some(selectedIndex => selectedIndex - index === -1);
15441
15517
  });
15442
15518
  vue.provide(VExpansionPanelSymbol, groupItem);
15519
+ provideDefaults({
15520
+ VExpansionPanelText: {
15521
+ eager: vue.toRef(props, 'eager')
15522
+ }
15523
+ });
15443
15524
  useRender(() => {
15444
15525
  const hasText = !!(slots.text || props.text);
15445
15526
  const hasTitle = !!(slots.title || props.title);
@@ -15464,8 +15545,7 @@
15464
15545
  }, {
15465
15546
  default: () => [slots.title ? slots.title() : props.title]
15466
15547
  }), hasText && vue.createVNode(VExpansionPanelText, {
15467
- "key": "text",
15468
- "eager": props.eager
15548
+ "key": "text"
15469
15549
  }, {
15470
15550
  default: () => [slots.text ? slots.text() : props.text]
15471
15551
  }), slots.default?.()]
@@ -17807,7 +17887,9 @@
17807
17887
  value,
17808
17888
  index,
17809
17889
  rating: normalizedValue.value
17810
- }) : vue.createVNode(VBtn, btnProps, null)]), vue.createVNode("input", {
17890
+ }) : vue.createVNode(VBtn, vue.mergeProps({
17891
+ "aria-label": t(props.itemAriaLabel, value, props.length)
17892
+ }, btnProps), null)]), vue.createVNode("input", {
17811
17893
  "class": "v-rating__hidden",
17812
17894
  "name": name.value,
17813
17895
  "id": id,
@@ -21797,12 +21879,11 @@
21797
21879
  function endOfMonth(date) {
21798
21880
  return new Date(date.getFullYear(), date.getMonth() + 1, 0);
21799
21881
  }
21800
- function formatYyyyMmDd(value) {
21801
- const formattedValue = value.split('-').map(d => d.padStart(2, '0')).join('-');
21802
- const offsetMin = new Date().getTimezoneOffset() / -60;
21803
- const offsetSign = offsetMin < 0 ? '-' : '+';
21804
- const offsetValue = Math.abs(offsetMin).toString().padStart(2, '0');
21805
- return `${formattedValue}T00:00:00.000${offsetSign}${offsetValue}:00`;
21882
+ function parseLocalDate(value) {
21883
+ const parts = value.split('-').map(Number);
21884
+
21885
+ // new Date() uses local time zone when passing individual date component values
21886
+ return new Date(parts[0], parts[1] - 1, parts[2]);
21806
21887
  }
21807
21888
  const _YYYMMDD = /([12]\d{3}-([1-9]|0[1-9]|1[0-2])-([1-9]|0[1-9]|[12]\d|3[01]))/;
21808
21889
  function date(value) {
@@ -21811,7 +21892,7 @@
21811
21892
  if (typeof value === 'string') {
21812
21893
  let parsed;
21813
21894
  if (_YYYMMDD.test(value)) {
21814
- parsed = Date.parse(formatYyyyMmDd(value));
21895
+ return parseLocalDate(value);
21815
21896
  } else {
21816
21897
  parsed = Date.parse(value);
21817
21898
  }
@@ -22798,7 +22879,7 @@
22798
22879
  "class": "v-picker__header"
22799
22880
  }, [slots.header()]), vue.createVNode("div", {
22800
22881
  "class": "v-picker__body"
22801
- }, [slots.default?.()]), slots.actions && vue.createVNode("div", {
22882
+ }, [slots.default?.()]), slots.actions?.()[0]?.children && vue.createVNode("div", {
22802
22883
  "class": "v-picker__actions"
22803
22884
  }, [slots.actions()])]
22804
22885
  });
@@ -22866,7 +22947,7 @@
22866
22947
  viewMode,
22867
22948
  inputMode
22868
22949
  } = createDatePicker(props);
22869
- const isReversing = vue.ref(false);
22950
+ const isReversing = vue.shallowRef(false);
22870
22951
  const inputModel = vue.computed(() => model.value.length ? adapter.format(model.value[0], 'keyboardDate') : '');
22871
22952
  const title = vue.computed(() => t(props.title));
22872
22953
  const header = vue.computed(() => model.value.length ? adapter.format(model.value[0], 'normalDateWithWeekday') : t(props.header));
@@ -22948,7 +23029,7 @@
22948
23029
  "label": t(props.inputText),
22949
23030
  "placeholder": "dd/mm/yyyy"
22950
23031
  }, null)]),
22951
- actions: !props.hideActions ? () => vue.createVNode("div", null, [vue.createVNode(VBtn, {
23032
+ actions: () => !props.hideActions ? vue.createVNode("div", null, [vue.createVNode(VBtn, {
22952
23033
  "variant": "text",
22953
23034
  "color": props.color,
22954
23035
  "onClick": onClickCancel,
@@ -23017,7 +23098,6 @@
23017
23098
  intersectionRef,
23018
23099
  isIntersecting
23019
23100
  } = useIntersectionObserver(entries => {}, props.rootMargin ? {
23020
- root: props.rootRef,
23021
23101
  rootMargin: props.rootMargin
23022
23102
  } : undefined);
23023
23103
  vue.watch(isIntersecting, async val => {
@@ -23042,10 +23122,10 @@
23042
23122
  emit
23043
23123
  } = _ref2;
23044
23124
  const rootEl = vue.ref();
23045
- const startStatus = vue.ref('ok');
23046
- const endStatus = vue.ref('ok');
23125
+ const startStatus = vue.shallowRef('ok');
23126
+ const endStatus = vue.shallowRef('ok');
23047
23127
  const margin = vue.computed(() => convertToUnit(props.margin));
23048
- const isIntersecting = vue.ref(false);
23128
+ const isIntersecting = vue.shallowRef(false);
23049
23129
  function setScrollAmount(amount) {
23050
23130
  if (!rootEl.value) return;
23051
23131
  const property = props.direction === 'vertical' ? 'scrollTop' : 'scrollLeft';
@@ -23197,6 +23277,206 @@
23197
23277
 
23198
23278
  // Types
23199
23279
 
23280
+ const makeVOtpInputProps = propsFactory({
23281
+ autofocus: Boolean,
23282
+ divider: String,
23283
+ focusAll: Boolean,
23284
+ label: {
23285
+ type: String,
23286
+ default: '$vuetify.input.otp'
23287
+ },
23288
+ length: {
23289
+ type: [Number, String],
23290
+ default: 6
23291
+ },
23292
+ modelValue: {
23293
+ type: [Number, String],
23294
+ default: undefined
23295
+ },
23296
+ placeholder: String,
23297
+ type: {
23298
+ type: String,
23299
+ default: 'text'
23300
+ },
23301
+ ...makeDimensionProps(),
23302
+ ...makeFocusProps(),
23303
+ ...only(makeVFieldProps({
23304
+ variant: 'outlined'
23305
+ }), ['baseColor', 'bgColor', 'class', 'color', 'disabled', 'error', 'loading', 'rounded', 'style', 'theme', 'variant'])
23306
+ }, 'VOtpInput');
23307
+ const VOtpInput = genericComponent()({
23308
+ name: 'VOtpInput',
23309
+ props: makeVOtpInputProps(),
23310
+ emits: {
23311
+ finish: val => true,
23312
+ 'update:focused': val => true,
23313
+ 'update:modelValue': val => true
23314
+ },
23315
+ setup(props, _ref) {
23316
+ let {
23317
+ emit,
23318
+ slots
23319
+ } = _ref;
23320
+ const {
23321
+ dimensionStyles
23322
+ } = useDimension(props);
23323
+ const {
23324
+ isFocused,
23325
+ focus,
23326
+ blur
23327
+ } = useFocus(props);
23328
+ const model = useProxiedModel(props, 'modelValue', '', val => String(val).split(''), val => val.join(''));
23329
+ const {
23330
+ t
23331
+ } = useLocale();
23332
+ const fields = vue.computed(() => Array(Number(props.length)).fill(0));
23333
+ const focusIndex = vue.ref(-1);
23334
+ const contentRef = vue.ref();
23335
+ const inputRef = vue.ref([]);
23336
+ const current = vue.computed(() => inputRef.value[focusIndex.value]);
23337
+ function onInput() {
23338
+ const array = model.value.slice();
23339
+ const value = current.value.value;
23340
+ array[focusIndex.value] = value;
23341
+ model.value = array;
23342
+ }
23343
+ function onKeydown(e) {
23344
+ const array = model.value.slice();
23345
+ const index = focusIndex.value;
23346
+ let target = null;
23347
+ if (e.key === 'ArrowLeft') {
23348
+ target = 'prev';
23349
+ } else if (e.key === 'ArrowRight') {
23350
+ target = 'next';
23351
+ } else if (e.key === 'Backspace') {
23352
+ if (focusIndex.value > 0) {
23353
+ target = 'prev';
23354
+ }
23355
+ } else if (e.key === 'Delete') {
23356
+ array[focusIndex.value] = '';
23357
+ model.value = array;
23358
+ requestAnimationFrame(() => {
23359
+ inputRef.value[index].select();
23360
+ });
23361
+ } else if (props.type === 'number' && isNaN(parseInt(e.key))) {
23362
+ return;
23363
+ } else if (focusIndex.value > model.value.length) {
23364
+ target = model.value.length + 1;
23365
+ } else if (focusIndex.value + 1 !== Number(props.length)) {
23366
+ target = 'next';
23367
+ } else {
23368
+ requestAnimationFrame(() => current.value?.blur());
23369
+ return;
23370
+ }
23371
+ requestAnimationFrame(() => {
23372
+ if (target != null) {
23373
+ focusChild(contentRef.value, target);
23374
+ }
23375
+ });
23376
+ }
23377
+ function onPaste(index, e) {
23378
+ e.preventDefault();
23379
+ e.stopPropagation();
23380
+ model.value = (e?.clipboardData?.getData('Text') ?? '').split('');
23381
+ inputRef.value?.[index].blur();
23382
+ }
23383
+ function reset() {
23384
+ model.value = [];
23385
+ }
23386
+ function onFocus(e, index) {
23387
+ focus();
23388
+ focusIndex.value = index;
23389
+ }
23390
+ function onBlur() {
23391
+ blur();
23392
+ focusIndex.value = -1;
23393
+ }
23394
+ provideDefaults({
23395
+ VField: {
23396
+ disabled: vue.computed(() => props.disabled),
23397
+ error: vue.computed(() => props.error),
23398
+ variant: vue.computed(() => props.variant)
23399
+ }
23400
+ }, {
23401
+ scoped: true
23402
+ });
23403
+ vue.watch(model, val => {
23404
+ if (val.length === props.length) emit('finish', val.join(''));
23405
+ }, {
23406
+ deep: true
23407
+ });
23408
+ vue.watch(focusIndex, val => {
23409
+ if (val < 0) return;
23410
+ IN_BROWSER && window.requestAnimationFrame(() => {
23411
+ inputRef.value[val].select();
23412
+ });
23413
+ });
23414
+ useRender(() => {
23415
+ return vue.createVNode("div", {
23416
+ "class": ['v-otp-input', {
23417
+ 'v-otp-input--divided': !!props.divider
23418
+ }, props.class],
23419
+ "style": [props.style]
23420
+ }, [vue.createVNode("div", {
23421
+ "ref": contentRef,
23422
+ "class": "v-otp-input__content",
23423
+ "style": [dimensionStyles.value]
23424
+ }, [fields.value.map((_, i) => vue.createVNode(vue.Fragment, null, [props.divider && i !== 0 && vue.createVNode("span", {
23425
+ "class": "v-otp-input__divider"
23426
+ }, [props.divider]), vue.createVNode(VField, {
23427
+ "focused": isFocused.value && props.focusAll || focusIndex.value === i,
23428
+ "key": i
23429
+ }, {
23430
+ ...slots,
23431
+ default: () => {
23432
+ return vue.createVNode("input", {
23433
+ "ref": val => inputRef.value[i] = val,
23434
+ "aria-label": t(props.label, i + 1),
23435
+ "autofocus": i === 0 && props.autofocus,
23436
+ "autocomplete": "one-time-code",
23437
+ "class": ['v-otp-input__field'],
23438
+ "inputmode": "text",
23439
+ "min": props.type === 'number' ? 0 : undefined,
23440
+ "maxlength": "1",
23441
+ "placeholder": props.placeholder,
23442
+ "type": props.type,
23443
+ "value": model.value[i],
23444
+ "onInput": onInput,
23445
+ "onFocus": e => onFocus(e, i),
23446
+ "onBlur": onBlur,
23447
+ "onKeydown": onKeydown,
23448
+ "onPaste": event => onPaste(i, event)
23449
+ }, null);
23450
+ }
23451
+ })])), vue.createVNode(VOverlay, {
23452
+ "contained": true,
23453
+ "content-class": "v-otp-input__loader",
23454
+ "model-value": !!props.loading,
23455
+ "persistent": true
23456
+ }, {
23457
+ default: () => [slots.loader?.() ?? vue.createVNode(VProgressCircular, {
23458
+ "color": typeof props.loading === 'boolean' ? undefined : props.loading,
23459
+ "indeterminate": true,
23460
+ "size": "24",
23461
+ "width": "2"
23462
+ }, null)]
23463
+ }), slots.default?.()])]);
23464
+ });
23465
+ return {
23466
+ blur: () => {
23467
+ inputRef.value?.some(input => input.blur());
23468
+ },
23469
+ focus: () => {
23470
+ inputRef.value?.[0].focus();
23471
+ },
23472
+ reset,
23473
+ isFocused
23474
+ };
23475
+ }
23476
+ });
23477
+
23478
+ // Types
23479
+
23200
23480
  const rootTypes = {
23201
23481
  actions: 'button@2',
23202
23482
  article: 'heading, paragraph',
@@ -23328,6 +23608,370 @@
23328
23608
  }
23329
23609
  });
23330
23610
 
23611
+ // Types
23612
+
23613
+ const makeVStepperActionsProps = propsFactory({
23614
+ color: String,
23615
+ disabled: {
23616
+ type: [Boolean, String],
23617
+ default: false
23618
+ },
23619
+ prevText: {
23620
+ type: String,
23621
+ default: '$vuetify.stepper.prev'
23622
+ },
23623
+ nextText: {
23624
+ type: String,
23625
+ default: '$vuetify.stepper.next'
23626
+ }
23627
+ }, 'VStepperActions');
23628
+ const VStepperActions = genericComponent()({
23629
+ name: 'VStepperActions',
23630
+ props: makeVStepperActionsProps(),
23631
+ emits: {
23632
+ 'click:prev': () => true,
23633
+ 'click:next': () => true
23634
+ },
23635
+ setup(props, _ref) {
23636
+ let {
23637
+ emit,
23638
+ slots
23639
+ } = _ref;
23640
+ const {
23641
+ t
23642
+ } = useLocale();
23643
+ function onClickPrev() {
23644
+ emit('click:prev');
23645
+ }
23646
+ function onClickNext() {
23647
+ emit('click:next');
23648
+ }
23649
+ useRender(() => {
23650
+ return vue.createVNode("div", {
23651
+ "class": "v-stepper-actions"
23652
+ }, [vue.createVNode(VBtn, {
23653
+ "disabled": ['prev', true].includes(props.disabled),
23654
+ "text": t(props.prevText),
23655
+ "variant": "text",
23656
+ "onClick": onClickPrev
23657
+ }, null), vue.createVNode(VBtn, {
23658
+ "disabled": ['next', true].includes(props.disabled),
23659
+ "color": props.color,
23660
+ "text": t(props.nextText),
23661
+ "variant": "tonal",
23662
+ "onClick": onClickNext
23663
+ }, null)]);
23664
+ });
23665
+ return {};
23666
+ }
23667
+ });
23668
+
23669
+ // Utilities
23670
+ const VStepperHeader = createSimpleFunctional('v-stepper-header');
23671
+
23672
+ // Types
23673
+
23674
+ const makeVStepperItemProps = propsFactory({
23675
+ color: String,
23676
+ title: String,
23677
+ subtitle: String,
23678
+ complete: Boolean,
23679
+ completeIcon: {
23680
+ type: String,
23681
+ default: '$complete'
23682
+ },
23683
+ editable: Boolean,
23684
+ editIcon: {
23685
+ type: String,
23686
+ default: '$edit'
23687
+ },
23688
+ error: Boolean,
23689
+ errorIcon: {
23690
+ type: String,
23691
+ default: '$error'
23692
+ },
23693
+ icon: String,
23694
+ ripple: {
23695
+ type: [Boolean, Object],
23696
+ default: true
23697
+ },
23698
+ rules: {
23699
+ type: Array,
23700
+ default: () => []
23701
+ },
23702
+ ...makeGroupItemProps()
23703
+ }, 'VStepperItem');
23704
+ const VStepperItem = genericComponent()({
23705
+ name: 'VStepperItem',
23706
+ directives: {
23707
+ Ripple
23708
+ },
23709
+ props: makeVStepperItemProps(),
23710
+ emits: {
23711
+ 'group:selected': val => true
23712
+ },
23713
+ setup(props, _ref) {
23714
+ let {
23715
+ slots
23716
+ } = _ref;
23717
+ const group = useGroupItem(props, VStepperSymbol, true);
23718
+ const step = vue.computed(() => group?.value.value ?? props.value);
23719
+ const isValid = vue.computed(() => props.rules.every(handler => handler() === true));
23720
+ const canEdit = vue.computed(() => !props.disabled && props.editable);
23721
+ const hasError = vue.computed(() => props.error || !isValid.value);
23722
+ const hasCompleted = vue.computed(() => props.complete || props.rules.length > 0 && isValid.value);
23723
+ const icon = vue.computed(() => {
23724
+ if (hasError.value) return props.errorIcon;
23725
+ if (hasCompleted.value) return props.completeIcon;
23726
+ if (props.editable) return props.editIcon;
23727
+ return props.icon;
23728
+ });
23729
+ const slotProps = vue.computed(() => ({
23730
+ canEdit: canEdit.value,
23731
+ hasError: hasError.value,
23732
+ hasCompleted: hasCompleted.value,
23733
+ title: props.title,
23734
+ subtitle: props.subtitle,
23735
+ step: step.value,
23736
+ value: props.value
23737
+ }));
23738
+ useRender(() => {
23739
+ const hasColor = (!group || group.isSelected.value || hasCompleted.value || canEdit.value) && !hasError.value && !props.disabled;
23740
+ const hasTitle = !!(props.title || slots.title);
23741
+ const hasSubtitle = !!(props.subtitle || slots.subtitle);
23742
+ function onClick() {
23743
+ group?.toggle();
23744
+ }
23745
+ return vue.withDirectives(vue.createVNode("button", {
23746
+ "class": ['v-stepper-item', {
23747
+ 'v-stepper-item--complete': hasCompleted.value,
23748
+ 'v-stepper-item--disabled': props.disabled,
23749
+ 'v-stepper-item--error': hasError.value
23750
+ }, group?.selectedClass.value],
23751
+ "disabled": !props.editable,
23752
+ "onClick": onClick
23753
+ }, [vue.createVNode(VAvatar, {
23754
+ "key": "stepper-avatar",
23755
+ "class": "v-stepper-item__avatar",
23756
+ "color": hasColor ? props.color : undefined,
23757
+ "size": 24
23758
+ }, {
23759
+ default: () => [slots.icon?.(slotProps.value) ?? (icon.value ? vue.createVNode(VIcon, {
23760
+ "icon": icon.value
23761
+ }, null) : step.value)]
23762
+ }), vue.createVNode("div", {
23763
+ "class": "v-stepper-item__content"
23764
+ }, [hasTitle && vue.createVNode("div", {
23765
+ "key": "title",
23766
+ "class": "v-stepper-item__title"
23767
+ }, [slots.title?.(slotProps.value) ?? props.title]), hasSubtitle && vue.createVNode("div", {
23768
+ "key": "subtitle",
23769
+ "class": "v-stepper-item__subtitle"
23770
+ }, [slots.subtitle?.(slotProps.value) ?? props.subtitle]), slots.default?.(slotProps.value)])]), [[vue.resolveDirective("ripple"), props.ripple && props.editable, null]]);
23771
+ });
23772
+ return {};
23773
+ }
23774
+ });
23775
+
23776
+ // Types
23777
+
23778
+ const VStepperSymbol$1 = Symbol.for('vuetify:v-stepper');
23779
+ const makeVStepperWindowProps = propsFactory({
23780
+ ...makeVWindowProps({
23781
+ mandatory: false
23782
+ })
23783
+ }, 'VStepperWindow');
23784
+ const VStepperWindow = genericComponent()({
23785
+ name: 'VStepperWindow',
23786
+ props: makeVStepperWindowProps(),
23787
+ emits: {
23788
+ 'update:modelValue': v => true
23789
+ },
23790
+ setup(props, _ref) {
23791
+ let {
23792
+ slots
23793
+ } = _ref;
23794
+ const group = vue.inject(VStepperSymbol$1, null);
23795
+ const _model = useProxiedModel(props, 'modelValue');
23796
+ const model = vue.computed({
23797
+ get() {
23798
+ // Always return modelValue if defined
23799
+ // or if not within a VStepper group
23800
+ if (_model.value != null || !group) return _model.value;
23801
+
23802
+ // If inside of a VStepper, find the currently selected
23803
+ // item by id. Item value may be assigned by its index
23804
+ return group.items.value.find(item => group.selected.value.includes(item.id))?.value;
23805
+ },
23806
+ set(val) {
23807
+ _model.value = val;
23808
+ }
23809
+ });
23810
+ useRender(() => {
23811
+ const [windowProps] = VWindow.filterProps(props);
23812
+ return vue.createVNode(VWindow, vue.mergeProps(windowProps, {
23813
+ "modelValue": model.value,
23814
+ "onUpdate:modelValue": $event => model.value = $event,
23815
+ "class": "v-stepper-window"
23816
+ }), slots);
23817
+ });
23818
+ return {};
23819
+ }
23820
+ });
23821
+
23822
+ const makeVStepperWindowItemProps = propsFactory({
23823
+ ...makeVWindowItemProps()
23824
+ }, 'VStepperWindowItem');
23825
+ const VStepperWindowItem = genericComponent()({
23826
+ name: 'VStepperWindowItem',
23827
+ props: makeVStepperWindowItemProps(),
23828
+ setup(props, _ref) {
23829
+ let {
23830
+ slots
23831
+ } = _ref;
23832
+ useRender(() => {
23833
+ const [windowItemProps] = VWindowItem.filterProps(props);
23834
+ return vue.createVNode(VWindowItem, vue.mergeProps(windowItemProps, {
23835
+ "class": "v-stepper-window-item"
23836
+ }), slots);
23837
+ });
23838
+ return {};
23839
+ }
23840
+ });
23841
+
23842
+ // Types
23843
+
23844
+ const VStepperSymbol = Symbol.for('vuetify:v-stepper');
23845
+ const makeVStepperProps = propsFactory({
23846
+ altLabels: Boolean,
23847
+ bgColor: String,
23848
+ editable: Boolean,
23849
+ hideActions: Boolean,
23850
+ items: {
23851
+ type: Array,
23852
+ default: () => []
23853
+ },
23854
+ itemTitle: {
23855
+ type: String,
23856
+ default: 'title'
23857
+ },
23858
+ itemValue: {
23859
+ type: String,
23860
+ default: 'value'
23861
+ },
23862
+ mobile: Boolean,
23863
+ nonLinear: Boolean,
23864
+ flat: Boolean,
23865
+ ...makeGroupProps({
23866
+ mandatory: 'force',
23867
+ selectedClass: 'v-stepper-item--selected'
23868
+ }),
23869
+ ...omit(makeVSheetProps(), ['color']),
23870
+ ...makeVStepperActionsProps()
23871
+ }, 'VStepper');
23872
+ const VStepper = genericComponent()({
23873
+ name: 'VStepper',
23874
+ props: makeVStepperProps(),
23875
+ emits: {
23876
+ 'update:modelValue': v => true
23877
+ },
23878
+ setup(props, _ref) {
23879
+ let {
23880
+ slots
23881
+ } = _ref;
23882
+ // TODO: fix typing
23883
+ const {
23884
+ items: _items,
23885
+ next,
23886
+ prev,
23887
+ selected
23888
+ } = useGroup(props, VStepperSymbol);
23889
+ const {
23890
+ editable,
23891
+ prevText,
23892
+ nextText
23893
+ } = vue.toRefs(props);
23894
+ const items = vue.computed(() => props.items.map((item, index) => {
23895
+ const title = getPropertyFromItem(item, props.itemTitle, item);
23896
+ const value = getPropertyFromItem(item, props.itemValue, index + 1);
23897
+ return {
23898
+ title,
23899
+ value,
23900
+ raw: item
23901
+ };
23902
+ }));
23903
+ const activeIndex = vue.computed(() => {
23904
+ return _items.value.findIndex(item => selected.value.includes(item.id));
23905
+ });
23906
+ const disabled = vue.computed(() => {
23907
+ if (props.disabled) return props.disabled;
23908
+ if (activeIndex.value === 0) return 'prev';
23909
+ if (activeIndex.value === _items.value.length - 1) return 'next';
23910
+ return false;
23911
+ });
23912
+ provideDefaults({
23913
+ VStepperItem: {
23914
+ editable,
23915
+ prevText,
23916
+ nextText
23917
+ },
23918
+ VStepperActions: {
23919
+ disabled
23920
+ }
23921
+ });
23922
+ useRender(() => {
23923
+ const [sheetProps] = VSheet.filterProps(props);
23924
+ const [stepperActionProps] = VStepperActions.filterProps(props);
23925
+ const hasHeader = !!(slots.header || props.items.length);
23926
+ const hasWindow = props.items.length > 0;
23927
+ const hasActions = !props.hideActions && !!(hasWindow || slots.actions);
23928
+ return vue.createVNode(VSheet, vue.mergeProps(sheetProps, {
23929
+ "class": ['v-stepper', {
23930
+ 'v-stepper--alt-labels': props.altLabels,
23931
+ 'v-stepper--flat': props.flat,
23932
+ 'v-stepper--non-linear': props.nonLinear,
23933
+ 'v-stepper--mobile': props.mobile
23934
+ }, props.class],
23935
+ "style": props.style
23936
+ }), {
23937
+ default: () => [hasHeader && vue.createVNode(VStepperHeader, {
23938
+ "key": "stepper-header"
23939
+ }, {
23940
+ default: () => [items.value.map((item, index) => vue.createVNode(vue.Fragment, null, [!!index && vue.createVNode(VDivider, null, null), vue.createVNode(VStepperItem, item, {
23941
+ default: slots[`header-item.${item.value}`] ?? slots.header,
23942
+ icon: slots.icon,
23943
+ title: slots.title,
23944
+ subtitle: slots.subtitle
23945
+ })]))]
23946
+ }), hasWindow && vue.createVNode(VStepperWindow, {
23947
+ "key": "stepper-window"
23948
+ }, {
23949
+ default: () => [items.value.map(item => vue.createVNode(VStepperWindowItem, {
23950
+ "value": item.value
23951
+ }, {
23952
+ default: () => slots[`item.${item.value}`]?.(item) ?? slots.item?.(item)
23953
+ }))]
23954
+ }), slots.default?.({
23955
+ prev,
23956
+ next
23957
+ }), hasActions && (slots.actions?.({
23958
+ next,
23959
+ prev
23960
+ }) ?? vue.createVNode(VStepperActions, vue.mergeProps({
23961
+ "key": "stepper-actions"
23962
+ }, stepperActionProps, {
23963
+ "onClick:prev": prev,
23964
+ "onClick:next": next
23965
+ }), null))]
23966
+ });
23967
+ });
23968
+ return {
23969
+ prev,
23970
+ next
23971
+ };
23972
+ }
23973
+ });
23974
+
23331
23975
  var components = /*#__PURE__*/Object.freeze({
23332
23976
  __proto__: null,
23333
23977
  VAlert: VAlert,
@@ -23430,6 +24074,7 @@
23430
24074
  VMessages: VMessages,
23431
24075
  VNavigationDrawer: VNavigationDrawer,
23432
24076
  VNoSsr: VNoSsr,
24077
+ VOtpInput: VOtpInput,
23433
24078
  VOverlay: VOverlay,
23434
24079
  VPagination: VPagination,
23435
24080
  VParallax: VParallax,
@@ -23462,6 +24107,12 @@
23462
24107
  VSlider: VSlider,
23463
24108
  VSnackbar: VSnackbar,
23464
24109
  VSpacer: VSpacer,
24110
+ VStepper: VStepper,
24111
+ VStepperActions: VStepperActions,
24112
+ VStepperHeader: VStepperHeader,
24113
+ VStepperItem: VStepperItem,
24114
+ VStepperWindow: VStepperWindow,
24115
+ VStepperWindowItem: VStepperWindowItem,
23465
24116
  VSvgIcon: VSvgIcon,
23466
24117
  VSwitch: VSwitch,
23467
24118
  VSystemBar: VSystemBar,
@@ -23699,7 +24350,7 @@
23699
24350
  date
23700
24351
  };
23701
24352
  }
23702
- const version$1 = "3.3.10";
24353
+ const version$1 = "3.3.11";
23703
24354
  createVuetify$1.version = version$1;
23704
24355
 
23705
24356
  // Vue's inject() can only be used in setup
@@ -23713,7 +24364,7 @@
23713
24364
 
23714
24365
  /* eslint-disable local-rules/sort-imports */
23715
24366
 
23716
- const version = "3.3.10";
24367
+ const version = "3.3.11";
23717
24368
 
23718
24369
  /* eslint-disable local-rules/sort-imports */
23719
24370