vuetify 3.3.10 → 3.3.12

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 (232) hide show
  1. package/dist/_component-variables-labs.sass +3 -1
  2. package/dist/json/attributes.json +225 -33
  3. package/dist/json/importMap-labs.json +28 -0
  4. package/dist/json/tags.json +80 -0
  5. package/dist/json/web-types.json +703 -34
  6. package/dist/vuetify-labs.css +1092 -899
  7. package/dist/vuetify-labs.d.ts +2810 -304
  8. package/dist/vuetify-labs.esm.js +784 -87
  9. package/dist/vuetify-labs.esm.js.map +1 -1
  10. package/dist/vuetify-labs.js +784 -87
  11. package/dist/vuetify-labs.min.css +2 -2
  12. package/dist/vuetify.css +349 -316
  13. package/dist/vuetify.d.ts +64 -29
  14. package/dist/vuetify.esm.js +141 -63
  15. package/dist/vuetify.esm.js.map +1 -1
  16. package/dist/vuetify.js +141 -63
  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 +7 -1
  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/VBanner/VBanner.css +2 -0
  31. package/lib/components/VBanner/VBanner.sass +2 -0
  32. package/lib/components/VBtn/VBtn.css +3 -0
  33. package/lib/components/VBtn/VBtn.sass +2 -0
  34. package/lib/components/VCarousel/index.d.mts +12 -10
  35. package/lib/components/VChip/VChip.mjs +4 -3
  36. package/lib/components/VChip/VChip.mjs.map +1 -1
  37. package/lib/components/VCombobox/VCombobox.mjs +10 -4
  38. package/lib/components/VCombobox/VCombobox.mjs.map +1 -1
  39. package/lib/components/VCombobox/index.d.mts +6 -0
  40. package/lib/components/VDialog/VDialog.css +15 -6
  41. package/lib/components/VDialog/VDialog.sass +41 -35
  42. package/lib/components/VExpansionPanel/VExpansionPanel.mjs +8 -3
  43. package/lib/components/VExpansionPanel/VExpansionPanel.mjs.map +1 -1
  44. package/lib/components/VField/VField.css +6 -2
  45. package/lib/components/VField/VField.sass +6 -2
  46. package/lib/components/VGrid/VGrid.css +4 -0
  47. package/lib/components/VGrid/VGrid.sass +4 -1
  48. package/lib/components/VGrid/VSpacer.mjs +1 -1
  49. package/lib/components/VGrid/VSpacer.mjs.map +1 -1
  50. package/lib/components/VList/VListItem.css +7 -1
  51. package/lib/components/VList/VListItem.mjs +1 -0
  52. package/lib/components/VList/VListItem.mjs.map +1 -1
  53. package/lib/components/VList/VListItem.sass +4 -0
  54. package/lib/components/VMenu/VMenu.mjs +29 -4
  55. package/lib/components/VMenu/VMenu.mjs.map +1 -1
  56. package/lib/components/VOverlay/useActivator.mjs +2 -2
  57. package/lib/components/VOverlay/useActivator.mjs.map +1 -1
  58. package/lib/components/VRangeSlider/VRangeSlider.mjs.map +1 -1
  59. package/lib/components/VRangeSlider/index.d.mts +8 -8
  60. package/lib/components/VRating/VRating.mjs +4 -2
  61. package/lib/components/VRating/VRating.mjs.map +1 -1
  62. package/lib/components/VSelect/VSelect.mjs +11 -4
  63. package/lib/components/VSelect/VSelect.mjs.map +1 -1
  64. package/lib/components/VSelect/index.d.mts +6 -0
  65. package/lib/components/VSelectionControl/VSelectionControl.mjs +2 -2
  66. package/lib/components/VSelectionControl/VSelectionControl.mjs.map +1 -1
  67. package/lib/components/VSlider/VSlider.mjs +2 -3
  68. package/lib/components/VSlider/VSlider.mjs.map +1 -1
  69. package/lib/components/VSlider/slider.mjs +1 -0
  70. package/lib/components/VSlider/slider.mjs.map +1 -1
  71. package/lib/components/VSwitch/VSwitch.css +3 -0
  72. package/lib/components/VSwitch/VSwitch.sass +3 -0
  73. package/lib/components/VSwitch/_variables.scss +1 -0
  74. package/lib/components/VTable/VTable.css +2 -0
  75. package/lib/components/VTable/VTable.sass +2 -0
  76. package/lib/components/VTimeline/VTimeline.css +2 -2
  77. package/lib/components/VTimeline/VTimeline.sass +2 -2
  78. package/lib/components/VTooltip/VTooltip.css +1 -1
  79. package/lib/components/VTooltip/_variables.scss +1 -1
  80. package/lib/components/VWindow/VWindow.mjs +1 -0
  81. package/lib/components/VWindow/VWindow.mjs.map +1 -1
  82. package/lib/components/VWindow/VWindowItem.mjs +3 -1
  83. package/lib/components/VWindow/VWindowItem.mjs.map +1 -1
  84. package/lib/components/VWindow/index.d.mts +29 -11
  85. package/lib/components/index.d.mts +57 -29
  86. package/lib/composables/group.mjs +1 -1
  87. package/lib/composables/group.mjs.map +1 -1
  88. package/lib/composables/theme.mjs +12 -6
  89. package/lib/composables/theme.mjs.map +1 -1
  90. package/lib/entry-bundler.mjs +1 -1
  91. package/lib/framework.mjs +1 -1
  92. package/lib/index.d.mts +7 -0
  93. package/lib/labs/VDateInput/composables.mjs +11 -1
  94. package/lib/labs/VDateInput/composables.mjs.map +1 -1
  95. package/lib/labs/VDatePicker/VDatePicker.css +6 -5
  96. package/lib/labs/VDatePicker/VDatePicker.mjs +36 -16
  97. package/lib/labs/VDatePicker/VDatePicker.mjs.map +1 -1
  98. package/lib/labs/VDatePicker/VDatePicker.sass +8 -9
  99. package/lib/labs/VDatePicker/VDatePickerMonth.mjs +1 -1
  100. package/lib/labs/VDatePicker/VDatePickerMonth.mjs.map +1 -1
  101. package/lib/labs/VDatePicker/composables.mjs +4 -2
  102. package/lib/labs/VDatePicker/composables.mjs.map +1 -1
  103. package/lib/labs/VDatePicker/index.d.mts +14 -0
  104. package/lib/labs/VDateRangePicker/VDateRangePickerHeader.mjs +2 -2
  105. package/lib/labs/VDateRangePicker/VDateRangePickerHeader.mjs.map +1 -1
  106. package/lib/labs/VInfiniteScroll/VInfiniteScroll.mjs +4 -5
  107. package/lib/labs/VInfiniteScroll/VInfiniteScroll.mjs.map +1 -1
  108. package/lib/labs/VOtpInput/VOtpInput.css +53 -0
  109. package/lib/labs/VOtpInput/VOtpInput.mjs +222 -0
  110. package/lib/labs/VOtpInput/VOtpInput.mjs.map +1 -0
  111. package/lib/labs/VOtpInput/VOtpInput.sass +55 -0
  112. package/lib/labs/VOtpInput/_variables.scss +2 -0
  113. package/lib/labs/VOtpInput/index.d.mts +459 -0
  114. package/lib/labs/VOtpInput/index.mjs +2 -0
  115. package/lib/labs/VOtpInput/index.mjs.map +1 -0
  116. package/lib/labs/VPicker/VPicker.mjs +1 -1
  117. package/lib/labs/VPicker/VPicker.mjs.map +1 -1
  118. package/lib/labs/VStepper/VStepper.css +42 -0
  119. package/lib/labs/VStepper/VStepper.mjs +150 -0
  120. package/lib/labs/VStepper/VStepper.mjs.map +1 -0
  121. package/lib/labs/VStepper/VStepper.sass +44 -0
  122. package/lib/labs/VStepper/VStepperActions.mjs +61 -0
  123. package/lib/labs/VStepper/VStepperActions.mjs.map +1 -0
  124. package/lib/labs/VStepper/VStepperHeader.mjs +4 -0
  125. package/lib/labs/VStepper/VStepperHeader.mjs.map +1 -0
  126. package/lib/labs/VStepper/VStepperItem.css +67 -0
  127. package/lib/labs/VStepper/VStepperItem.mjs +114 -0
  128. package/lib/labs/VStepper/VStepperItem.mjs.map +1 -0
  129. package/lib/labs/VStepper/VStepperItem.sass +71 -0
  130. package/lib/labs/VStepper/VStepperWindow.mjs +50 -0
  131. package/lib/labs/VStepper/VStepperWindow.mjs.map +1 -0
  132. package/lib/labs/VStepper/VStepperWindowItem.mjs +24 -0
  133. package/lib/labs/VStepper/VStepperWindowItem.mjs.map +1 -0
  134. package/lib/labs/VStepper/_variables.scss +4 -0
  135. package/lib/labs/VStepper/index.d.mts +2045 -0
  136. package/lib/labs/VStepper/index.mjs +7 -0
  137. package/lib/labs/VStepper/index.mjs.map +1 -0
  138. package/lib/labs/components.d.mts +2759 -267
  139. package/lib/labs/components.mjs +2 -0
  140. package/lib/labs/components.mjs.map +1 -1
  141. package/lib/labs/date/adapters/vuetify.mjs +7 -8
  142. package/lib/labs/date/adapters/vuetify.mjs.map +1 -1
  143. package/lib/locale/af.mjs +6 -1
  144. package/lib/locale/af.mjs.map +1 -1
  145. package/lib/locale/ar.mjs +6 -1
  146. package/lib/locale/ar.mjs.map +1 -1
  147. package/lib/locale/az.mjs +6 -1
  148. package/lib/locale/az.mjs.map +1 -1
  149. package/lib/locale/bg.mjs +6 -1
  150. package/lib/locale/bg.mjs.map +1 -1
  151. package/lib/locale/ca.mjs +6 -1
  152. package/lib/locale/ca.mjs.map +1 -1
  153. package/lib/locale/ckb.mjs +6 -1
  154. package/lib/locale/ckb.mjs.map +1 -1
  155. package/lib/locale/cs.mjs +6 -1
  156. package/lib/locale/cs.mjs.map +1 -1
  157. package/lib/locale/da.mjs +6 -1
  158. package/lib/locale/da.mjs.map +1 -1
  159. package/lib/locale/de.mjs +6 -1
  160. package/lib/locale/de.mjs.map +1 -1
  161. package/lib/locale/el.mjs +6 -1
  162. package/lib/locale/el.mjs.map +1 -1
  163. package/lib/locale/en.mjs +6 -1
  164. package/lib/locale/en.mjs.map +1 -1
  165. package/lib/locale/es.mjs +6 -1
  166. package/lib/locale/es.mjs.map +1 -1
  167. package/lib/locale/et.mjs +6 -1
  168. package/lib/locale/et.mjs.map +1 -1
  169. package/lib/locale/fa.mjs +6 -1
  170. package/lib/locale/fa.mjs.map +1 -1
  171. package/lib/locale/fi.mjs +6 -1
  172. package/lib/locale/fi.mjs.map +1 -1
  173. package/lib/locale/fr.mjs +6 -1
  174. package/lib/locale/fr.mjs.map +1 -1
  175. package/lib/locale/he.mjs +6 -1
  176. package/lib/locale/he.mjs.map +1 -1
  177. package/lib/locale/hr.mjs +6 -1
  178. package/lib/locale/hr.mjs.map +1 -1
  179. package/lib/locale/hu.mjs +6 -1
  180. package/lib/locale/hu.mjs.map +1 -1
  181. package/lib/locale/id.mjs +6 -1
  182. package/lib/locale/id.mjs.map +1 -1
  183. package/lib/locale/index.d.mts +210 -0
  184. package/lib/locale/it.mjs +6 -1
  185. package/lib/locale/it.mjs.map +1 -1
  186. package/lib/locale/ja.mjs +6 -1
  187. package/lib/locale/ja.mjs.map +1 -1
  188. package/lib/locale/ko.mjs +6 -1
  189. package/lib/locale/ko.mjs.map +1 -1
  190. package/lib/locale/lt.mjs +6 -1
  191. package/lib/locale/lt.mjs.map +1 -1
  192. package/lib/locale/lv.mjs +6 -1
  193. package/lib/locale/lv.mjs.map +1 -1
  194. package/lib/locale/nl.mjs +6 -1
  195. package/lib/locale/nl.mjs.map +1 -1
  196. package/lib/locale/no.mjs +19 -14
  197. package/lib/locale/no.mjs.map +1 -1
  198. package/lib/locale/pl.mjs +6 -1
  199. package/lib/locale/pl.mjs.map +1 -1
  200. package/lib/locale/pt.mjs +6 -1
  201. package/lib/locale/pt.mjs.map +1 -1
  202. package/lib/locale/ro.mjs +23 -18
  203. package/lib/locale/ro.mjs.map +1 -1
  204. package/lib/locale/ru.mjs +6 -1
  205. package/lib/locale/ru.mjs.map +1 -1
  206. package/lib/locale/sk.mjs +6 -1
  207. package/lib/locale/sk.mjs.map +1 -1
  208. package/lib/locale/sl.mjs +6 -1
  209. package/lib/locale/sl.mjs.map +1 -1
  210. package/lib/locale/sr-Cyrl.mjs +6 -1
  211. package/lib/locale/sr-Cyrl.mjs.map +1 -1
  212. package/lib/locale/sr-Latn.mjs +6 -1
  213. package/lib/locale/sr-Latn.mjs.map +1 -1
  214. package/lib/locale/sv.mjs +6 -1
  215. package/lib/locale/sv.mjs.map +1 -1
  216. package/lib/locale/th.mjs +6 -1
  217. package/lib/locale/th.mjs.map +1 -1
  218. package/lib/locale/tr.mjs +6 -1
  219. package/lib/locale/tr.mjs.map +1 -1
  220. package/lib/locale/uk.mjs +6 -1
  221. package/lib/locale/uk.mjs.map +1 -1
  222. package/lib/locale/vi.mjs +6 -1
  223. package/lib/locale/vi.mjs.map +1 -1
  224. package/lib/locale/zh-Hans.mjs +6 -1
  225. package/lib/locale/zh-Hans.mjs.map +1 -1
  226. package/lib/locale/zh-Hant.mjs +6 -1
  227. package/lib/locale/zh-Hant.mjs.map +1 -1
  228. package/lib/util/globals.mjs +0 -1
  229. package/lib/util/globals.mjs.map +1 -1
  230. package/lib/util/helpers.mjs +32 -12
  231. package/lib/util/helpers.mjs.map +1 -1
  232. package/package.json +3 -2
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.3.10
2
+ * Vuetify v3.3.12
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
  }
@@ -6766,6 +6798,7 @@
6766
6798
  const closeProps = vue.computed(() => ({
6767
6799
  'aria-label': t(props.closeLabel),
6768
6800
  onClick(e) {
6801
+ e.stopPropagation();
6769
6802
  isActive.value = false;
6770
6803
  emit('click:close', e);
6771
6804
  }
@@ -6815,7 +6848,7 @@
6815
6848
  }, [!slots.filter ? vue.createVNode(VIcon, {
6816
6849
  "key": "filter-icon",
6817
6850
  "icon": props.filterIcon
6818
- }, null) : vue.withDirectives(vue.createVNode(VDefaultsProvider, {
6851
+ }, null) : vue.createVNode(VDefaultsProvider, {
6819
6852
  "key": "filter-defaults",
6820
6853
  "disabled": !props.filterIcon,
6821
6854
  "defaults": {
@@ -6823,7 +6856,7 @@
6823
6856
  icon: props.filterIcon
6824
6857
  }
6825
6858
  }
6826
- }, null), [[vue.resolveDirective("slot"), slots.filter, "default"]])]), [[vue.vShow, group.isSelected.value]])]
6859
+ }, slots.filter)]), [[vue.vShow, group.isSelected.value]])]
6827
6860
  }), hasPrepend && vue.createVNode("div", {
6828
6861
  "key": "prepend",
6829
6862
  "class": "v-chip__prepend"
@@ -7637,6 +7670,7 @@
7637
7670
  "style": [colorStyles.value, dimensionStyles.value, props.style],
7638
7671
  "href": link.href.value,
7639
7672
  "tabindex": isClickable.value ? list ? -2 : 0 : undefined,
7673
+ "title": props.title,
7640
7674
  "onClick": onClick,
7641
7675
  "onKeydown": isClickable.value && !isLink.value && onKeyDown
7642
7676
  }, {
@@ -8904,7 +8938,7 @@
8904
8938
  runCloseDelay();
8905
8939
  },
8906
8940
  onFocus: e => {
8907
- if (SUPPORTS_FOCUS_VISIBLE && !e.target.matches(':focus-visible')) return;
8941
+ if (matchesSelector(e.target, ':focus-visible') === false) return;
8908
8942
  isFocused = true;
8909
8943
  e.stopPropagation();
8910
8944
  activatorEl.value = e.currentTarget || e.target;
@@ -9824,8 +9858,30 @@
9824
9858
  }, 40);
9825
9859
  }
9826
9860
  });
9861
+ function onFocusIn(e) {
9862
+ const before = e.relatedTarget;
9863
+ const after = e.target;
9864
+ if (before !== after && overlay.value?.contentEl &&
9865
+ // We're the topmost menu
9866
+ overlay.value?.globalTop &&
9867
+ // It isn't the document or the menu body
9868
+ ![document, overlay.value.contentEl].includes(after) &&
9869
+ // It isn't inside the menu body
9870
+ !overlay.value.contentEl.contains(after)) {
9871
+ const focusable = focusableChildren(overlay.value.contentEl);
9872
+ focusable[0]?.focus();
9873
+ }
9874
+ }
9827
9875
  vue.watch(isActive, val => {
9828
- val ? parent?.register() : parent?.unregister();
9876
+ if (val) {
9877
+ parent?.register();
9878
+ document.addEventListener('focusin', onFocusIn, {
9879
+ once: true
9880
+ });
9881
+ } else {
9882
+ parent?.unregister();
9883
+ document.removeEventListener('focusin', onFocusIn);
9884
+ }
9829
9885
  });
9830
9886
  function onClickOutside() {
9831
9887
  parent?.closeParents();
@@ -9833,8 +9889,11 @@
9833
9889
  function onKeydown(e) {
9834
9890
  if (props.disabled) return;
9835
9891
  if (e.key === 'Tab') {
9836
- isActive.value = false;
9837
- overlay.value?.activatorEl?.focus();
9892
+ const nextElement = getNextElement(focusableChildren(overlay.value?.contentEl, false), e.shiftKey ? 'prev' : 'next', el => el.tabIndex >= 0);
9893
+ if (!nextElement) {
9894
+ isActive.value = false;
9895
+ overlay.value?.activatorEl?.focus();
9896
+ }
9838
9897
  }
9839
9898
  }
9840
9899
  function onActivatorKeydown(e) {
@@ -10748,6 +10807,7 @@
10748
10807
  type: Function,
10749
10808
  default: deepEqual
10750
10809
  },
10810
+ itemColor: String,
10751
10811
  ...makeItemsProps({
10752
10812
  itemChildren: false
10753
10813
  })
@@ -10800,7 +10860,12 @@
10800
10860
  const form = useForm();
10801
10861
  const selections = vue.computed(() => {
10802
10862
  return model.value.map(v => {
10803
- return items.value.find(item => props.valueComparator(item.value, v.value)) || v;
10863
+ return items.value.find(item => {
10864
+ const itemRawValue = getPropertyFromItem(item.raw, props.itemValue);
10865
+ const modelRawValue = getPropertyFromItem(v.raw, props.itemValue);
10866
+ if (itemRawValue === undefined || modelRawValue === undefined) return false;
10867
+ return props.returnObject ? props.valueComparator(itemRawValue, modelRawValue) : props.valueComparator(item.value, v.value);
10868
+ }) || v;
10804
10869
  });
10805
10870
  });
10806
10871
  const selected = vue.computed(() => selections.value.map(selection => selection.props.value));
@@ -10894,7 +10959,7 @@
10894
10959
  isFocused.value = true;
10895
10960
  }
10896
10961
  function onModelUpdate(v) {
10897
- if (v == null) model.value = [];else if (vTextFieldRef.value?.matches(':autofill') || vTextFieldRef.value?.matches(':-webkit-autofill')) {
10962
+ if (v == null) model.value = [];else if (matchesSelector(vTextFieldRef.value, ':autofill') || matchesSelector(vTextFieldRef.value, ':-webkit-autofill')) {
10898
10963
  const item = items.value.find(item => item.title === v);
10899
10964
  if (item) {
10900
10965
  select(item);
@@ -10956,7 +11021,8 @@
10956
11021
  "onKeydown": onListKeydown,
10957
11022
  "onFocusin": onFocusin,
10958
11023
  "onScrollPassive": onListScroll,
10959
- "tabindex": "-1"
11024
+ "tabindex": "-1",
11025
+ "color": props.itemColor ?? props.color
10960
11026
  }, {
10961
11027
  default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? vue.createVNode(VListItem, {
10962
11028
  "title": t(props.noDataText)
@@ -11218,7 +11284,7 @@
11218
11284
  const vTextFieldRef = vue.ref();
11219
11285
  const isFocused = vue.shallowRef(false);
11220
11286
  const isPristine = vue.shallowRef(true);
11221
- const listHasFocus = vue.ref(false);
11287
+ const listHasFocus = vue.shallowRef(false);
11222
11288
  const vMenuRef = vue.ref();
11223
11289
  const _menu = useProxiedModel(props, 'menu');
11224
11290
  const menu = vue.computed({
@@ -11251,7 +11317,12 @@
11251
11317
  } = useFilter(props, items, () => isPristine.value ? '' : search.value);
11252
11318
  const selections = vue.computed(() => {
11253
11319
  return model.value.map(v => {
11254
- return items.value.find(item => props.valueComparator(item.value, v.value)) || v;
11320
+ return items.value.find(item => {
11321
+ const itemRawValue = getPropertyFromItem(item.raw, props.itemValue);
11322
+ const modelRawValue = getPropertyFromItem(v.raw, props.itemValue);
11323
+ if (itemRawValue === undefined || modelRawValue === undefined) return false;
11324
+ return props.returnObject ? props.valueComparator(itemRawValue, modelRawValue) : props.valueComparator(item.value, v.value);
11325
+ }) || v;
11255
11326
  });
11256
11327
  });
11257
11328
  const displayItems = vue.computed(() => {
@@ -11303,11 +11374,8 @@
11303
11374
  if (['Escape'].includes(e.key)) {
11304
11375
  menu.value = false;
11305
11376
  }
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;
11377
+ if (highlightFirst.value && ['Enter', 'Tab'].includes(e.key)) {
11378
+ select(filteredItems.value[0]);
11311
11379
  }
11312
11380
  if (e.key === 'ArrowDown' && highlightFirst.value) {
11313
11381
  listRef.value?.focus('next');
@@ -11349,7 +11417,7 @@
11349
11417
  search.value = e.target.value;
11350
11418
  }
11351
11419
  function onChange(e) {
11352
- if (vTextFieldRef.value?.matches(':autofill') || vTextFieldRef.value?.matches(':-webkit-autofill')) {
11420
+ if (matchesSelector(vTextFieldRef.value, ':autofill') || matchesSelector(vTextFieldRef.value, ':-webkit-autofill')) {
11353
11421
  const item = items.value.find(item => item.title === e.target.value);
11354
11422
  if (item) {
11355
11423
  select(item);
@@ -11473,7 +11541,8 @@
11473
11541
  "onFocusin": onFocusin,
11474
11542
  "onFocusout": onFocusout,
11475
11543
  "onScrollPassive": onListScroll,
11476
- "tabindex": "-1"
11544
+ "tabindex": "-1",
11545
+ "color": props.itemColor ?? props.color
11477
11546
  }, {
11478
11547
  default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? vue.createVNode(VListItem, {
11479
11548
  "title": t(props.noDataText)
@@ -12521,6 +12590,7 @@
12521
12590
  },
12522
12591
  // TODO: mandatory should probably not be exposed but do this for now
12523
12592
  mandatory: {
12593
+ type: [Boolean, String],
12524
12594
  default: 'force'
12525
12595
  },
12526
12596
  ...makeComponentProps(),
@@ -12888,7 +12958,9 @@
12888
12958
  "style": props.style
12889
12959
  }, [hasContent.value && slots.default?.()]), [[vue.vShow, groupItem.isSelected.value]])]
12890
12960
  }));
12891
- return {};
12961
+ return {
12962
+ groupItem
12963
+ };
12892
12964
  }
12893
12965
  });
12894
12966
 
@@ -13442,6 +13514,7 @@
13442
13514
  const step = vue.computed(() => +props.step > 0 ? parseFloat(props.step) : 0);
13443
13515
  const decimals = vue.computed(() => Math.max(getDecimals(step.value), getDecimals(min.value)));
13444
13516
  function roundValue(value) {
13517
+ value = parseFloat(value);
13445
13518
  if (step.value <= 0) return value;
13446
13519
  const clamped = clamp(value, min.value, max.value);
13447
13520
  const offset = min.value % step.value;
@@ -13945,9 +14018,8 @@
13945
14018
  rtlClasses
13946
14019
  } = useRtl();
13947
14020
  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);
14021
+ const model = useProxiedModel(props, 'modelValue', undefined, value => {
14022
+ return steps.roundValue(value == null ? steps.min.value : value);
13951
14023
  });
13952
14024
  const {
13953
14025
  min,
@@ -14741,7 +14813,7 @@
14741
14813
  const vTextFieldRef = vue.ref();
14742
14814
  const isFocused = vue.shallowRef(false);
14743
14815
  const isPristine = vue.shallowRef(true);
14744
- const listHasFocus = vue.ref(false);
14816
+ const listHasFocus = vue.shallowRef(false);
14745
14817
  const vMenuRef = vue.ref();
14746
14818
  const _menu = useProxiedModel(props, 'menu');
14747
14819
  const menu = vue.computed({
@@ -14813,7 +14885,12 @@
14813
14885
  } = useFilter(props, items, () => isPristine.value ? '' : search.value);
14814
14886
  const selections = vue.computed(() => {
14815
14887
  return model.value.map(v => {
14816
- return items.value.find(item => props.valueComparator(item.value, v.value)) || v;
14888
+ return items.value.find(item => {
14889
+ const itemRawValue = getPropertyFromItem(item.raw, props.itemValue);
14890
+ const modelRawValue = getPropertyFromItem(v.raw, props.itemValue);
14891
+ if (itemRawValue === undefined || modelRawValue === undefined) return false;
14892
+ return props.returnObject ? props.valueComparator(itemRawValue, modelRawValue) : props.valueComparator(item.value, v.value);
14893
+ }) || v;
14817
14894
  });
14818
14895
  });
14819
14896
  const displayItems = vue.computed(() => {
@@ -15022,7 +15099,8 @@
15022
15099
  "onFocusin": onFocusin,
15023
15100
  "onFocusout": onFocusout,
15024
15101
  "onScrollPassive": onListScroll,
15025
- "tabindex": "-1"
15102
+ "tabindex": "-1",
15103
+ "color": props.itemColor ?? props.color
15026
15104
  }, {
15027
15105
  default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? vue.createVNode(VListItem, {
15028
15106
  "title": t(props.noDataText)
@@ -15440,6 +15518,11 @@
15440
15518
  return !groupItem.isSelected.value && selectedIndices.value.some(selectedIndex => selectedIndex - index === -1);
15441
15519
  });
15442
15520
  vue.provide(VExpansionPanelSymbol, groupItem);
15521
+ provideDefaults({
15522
+ VExpansionPanelText: {
15523
+ eager: vue.toRef(props, 'eager')
15524
+ }
15525
+ });
15443
15526
  useRender(() => {
15444
15527
  const hasText = !!(slots.text || props.text);
15445
15528
  const hasTitle = !!(slots.title || props.title);
@@ -15464,8 +15547,7 @@
15464
15547
  }, {
15465
15548
  default: () => [slots.title ? slots.title() : props.title]
15466
15549
  }), hasText && vue.createVNode(VExpansionPanelText, {
15467
- "key": "text",
15468
- "eager": props.eager
15550
+ "key": "text"
15469
15551
  }, {
15470
15552
  default: () => [slots.text ? slots.text() : props.text]
15471
15553
  }), slots.default?.()]
@@ -16083,7 +16165,7 @@
16083
16165
  });
16084
16166
 
16085
16167
  // Utilities
16086
- const VSpacer = createSimpleFunctional('flex-grow-1', 'div', 'VSpacer');
16168
+ const VSpacer = createSimpleFunctional('v-spacer', 'div', 'VSpacer');
16087
16169
 
16088
16170
  // Composables
16089
16171
  const makeVHoverProps = propsFactory({
@@ -17807,7 +17889,9 @@
17807
17889
  value,
17808
17890
  index,
17809
17891
  rating: normalizedValue.value
17810
- }) : vue.createVNode(VBtn, btnProps, null)]), vue.createVNode("input", {
17892
+ }) : vue.createVNode(VBtn, vue.mergeProps({
17893
+ "aria-label": t(props.itemAriaLabel, value, props.length)
17894
+ }, btnProps), null)]), vue.createVNode("input", {
17811
17895
  "class": "v-rating__hidden",
17812
17896
  "name": name.value,
17813
17897
  "id": id,
@@ -21797,12 +21881,11 @@
21797
21881
  function endOfMonth(date) {
21798
21882
  return new Date(date.getFullYear(), date.getMonth() + 1, 0);
21799
21883
  }
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`;
21884
+ function parseLocalDate(value) {
21885
+ const parts = value.split('-').map(Number);
21886
+
21887
+ // new Date() uses local time zone when passing individual date component values
21888
+ return new Date(parts[0], parts[1] - 1, parts[2]);
21806
21889
  }
21807
21890
  const _YYYMMDD = /([12]\d{3}-([1-9]|0[1-9]|1[0-2])-([1-9]|0[1-9]|[12]\d|3[01]))/;
21808
21891
  function date(value) {
@@ -21811,7 +21894,7 @@
21811
21894
  if (typeof value === 'string') {
21812
21895
  let parsed;
21813
21896
  if (_YYYMMDD.test(value)) {
21814
- parsed = Date.parse(formatYyyyMmDd(value));
21897
+ return parseLocalDate(value);
21815
21898
  } else {
21816
21899
  parsed = Date.parse(value);
21817
21900
  }
@@ -21826,7 +21909,7 @@
21826
21909
  const weekday = new Date(sundayJanuarySecond2000);
21827
21910
  weekday.setDate(sundayJanuarySecond2000.getDate() + daysFromSunday + i);
21828
21911
  return new Intl.DateTimeFormat(locale, {
21829
- weekday: 'short'
21912
+ weekday: 'narrow'
21830
21913
  }).format(weekday);
21831
21914
  });
21832
21915
  }
@@ -22151,13 +22234,23 @@
22151
22234
  const date = adapter.date(input);
22152
22235
  return adapter.isValid(date) ? date : fallback;
22153
22236
  }
22237
+ function isEqual(model, comparing) {
22238
+ if (model.length !== comparing.length) return false;
22239
+ for (let i = 0; i < model.length; i++) {
22240
+ if (comparing[i] && !adapter.isEqual(model[i], comparing[i])) {
22241
+ return false;
22242
+ }
22243
+ }
22244
+ return true;
22245
+ }
22154
22246
  return {
22155
22247
  model,
22156
22248
  adapter,
22157
22249
  inputMode,
22158
22250
  viewMode,
22159
22251
  displayDate,
22160
- parseKeyboardDate
22252
+ parseKeyboardDate,
22253
+ isEqual
22161
22254
  };
22162
22255
  }
22163
22256
 
@@ -22255,7 +22348,8 @@
22255
22348
  model,
22256
22349
  displayDate,
22257
22350
  viewMode,
22258
- inputMode
22351
+ inputMode,
22352
+ isEqual
22259
22353
  } = createDateInput(props, !!props.multiple);
22260
22354
  return {
22261
22355
  hoverDate,
@@ -22266,7 +22360,8 @@
22266
22360
  model,
22267
22361
  displayDate,
22268
22362
  viewMode,
22269
- inputMode
22363
+ inputMode,
22364
+ isEqual
22270
22365
  };
22271
22366
  }
22272
22367
  function useDatePicker() {
@@ -22512,7 +22607,7 @@
22512
22607
  "onTouchstart": handleMousedown
22513
22608
  }, [!props.hideWeekdays && adapter.getWeekdays().map(weekDay => vue.createVNode("div", {
22514
22609
  "class": ['v-date-picker-month__day', 'v-date-picker-month__weekday']
22515
- }, [weekDay.charAt(0)])), daysInMonth.value.map((item, index) => vue.createVNode("div", {
22610
+ }, [weekDay])), daysInMonth.value.map((item, index) => vue.createVNode("div", {
22516
22611
  "class": ['v-date-picker-month__day', {
22517
22612
  'v-date-picker-month__day--selected': item.isSelected,
22518
22613
  'v-date-picker-month__day--start': item.isStart,
@@ -22798,7 +22893,7 @@
22798
22893
  "class": "v-picker__header"
22799
22894
  }, [slots.header()]), vue.createVNode("div", {
22800
22895
  "class": "v-picker__body"
22801
- }, [slots.default?.()]), slots.actions && vue.createVNode("div", {
22896
+ }, [slots.default?.()]), slots.actions?.()[0]?.children && vue.createVNode("div", {
22802
22897
  "class": "v-picker__actions"
22803
22898
  }, [slots.actions()])]
22804
22899
  });
@@ -22830,6 +22925,10 @@
22830
22925
  type: String,
22831
22926
  default: '$vuetify.datePicker.input.placeholder'
22832
22927
  },
22928
+ inputPlaceholder: {
22929
+ type: String,
22930
+ default: 'dd/mm/yyyy'
22931
+ },
22833
22932
  header: {
22834
22933
  type: String,
22835
22934
  default: '$vuetify.datePicker.header'
@@ -22864,24 +22963,40 @@
22864
22963
  model,
22865
22964
  displayDate,
22866
22965
  viewMode,
22867
- inputMode
22966
+ inputMode,
22967
+ isEqual
22868
22968
  } = createDatePicker(props);
22869
- const isReversing = vue.ref(false);
22870
- const inputModel = vue.computed(() => model.value.length ? adapter.format(model.value[0], 'keyboardDate') : '');
22969
+ const isReversing = vue.shallowRef(false);
22970
+ const inputModel = vue.ref(model.value.map(date => adapter.format(date, 'keyboardDate')));
22971
+ const temporaryModel = vue.ref(model.value);
22871
22972
  const title = vue.computed(() => t(props.title));
22872
22973
  const header = vue.computed(() => model.value.length ? adapter.format(model.value[0], 'normalDateWithWeekday') : t(props.header));
22873
22974
  const headerIcon = vue.computed(() => inputMode.value === 'calendar' ? props.keyboardIcon : props.calendarIcon);
22874
22975
  const headerTransition = vue.computed(() => `date-picker-header${isReversing.value ? '-reverse' : ''}-transition`);
22875
- vue.watch(inputModel, () => {
22976
+ function updateFromInput(input, index) {
22876
22977
  const {
22877
22978
  isValid,
22878
22979
  date
22879
22980
  } = adapter;
22880
- model.value = isValid(inputModel.value) ? [date(inputModel.value)] : [];
22981
+ if (isValid(input)) {
22982
+ const newModel = model.value.slice();
22983
+ newModel[index] = date(input);
22984
+ if (props.hideActions) {
22985
+ model.value = newModel;
22986
+ } else {
22987
+ temporaryModel.value = newModel;
22988
+ }
22989
+ }
22990
+ }
22991
+ vue.watch(model, val => {
22992
+ if (!isEqual(val, temporaryModel.value)) {
22993
+ temporaryModel.value = val;
22994
+ }
22995
+ inputModel.value = val.map(date => adapter.format(date, 'keyboardDate'));
22881
22996
  });
22882
- vue.watch(model, (val, oldVal) => {
22883
- if (props.hideActions) {
22884
- emit('update:modelValue', val);
22997
+ vue.watch(temporaryModel, (val, oldVal) => {
22998
+ if (props.hideActions && !isEqual(val, model.value)) {
22999
+ model.value = val;
22885
23000
  }
22886
23001
  if (val[0] && oldVal[0]) {
22887
23002
  isReversing.value = adapter.isBefore(val[0], oldVal[0]);
@@ -22892,7 +23007,7 @@
22892
23007
  }
22893
23008
  function onClickSave() {
22894
23009
  emit('click:save');
22895
- emit('update:modelValue', model.value);
23010
+ model.value = temporaryModel.value;
22896
23011
  }
22897
23012
  function onClickAppend() {
22898
23013
  inputMode.value = inputMode.value === 'calendar' ? 'keyboard' : 'calendar';
@@ -22928,8 +23043,8 @@
22928
23043
  default: () => [viewMode.value === 'month' ? vue.createVNode(VDatePickerMonth, vue.mergeProps({
22929
23044
  "key": "date-picker-month"
22930
23045
  }, datePickerMonthProps, {
22931
- "modelValue": model.value,
22932
- "onUpdate:modelValue": $event => model.value = $event,
23046
+ "modelValue": temporaryModel.value,
23047
+ "onUpdate:modelValue": $event => temporaryModel.value = $event,
22933
23048
  "displayDate": displayDate.value,
22934
23049
  "onUpdate:displayDate": $event => displayDate.value = $event
22935
23050
  }), null) : vue.createVNode(VDatePickerYears, vue.mergeProps({
@@ -22943,12 +23058,12 @@
22943
23058
  })]) : vue.createVNode("div", {
22944
23059
  "class": "v-date-picker__input"
22945
23060
  }, [vue.createVNode(VTextField, {
22946
- "modelValue": inputModel.value,
22947
- "onUpdate:modelValue": $event => inputModel.value = $event,
23061
+ "modelValue": inputModel.value[0],
23062
+ "onUpdate:modelValue": v => updateFromInput(v, 0),
22948
23063
  "label": t(props.inputText),
22949
- "placeholder": "dd/mm/yyyy"
23064
+ "placeholder": props.inputPlaceholder
22950
23065
  }, null)]),
22951
- actions: !props.hideActions ? () => vue.createVNode("div", null, [vue.createVNode(VBtn, {
23066
+ actions: () => !props.hideActions ? vue.createVNode("div", null, [vue.createVNode(VBtn, {
22952
23067
  "variant": "text",
22953
23068
  "color": props.color,
22954
23069
  "onClick": onClickCancel,
@@ -23017,7 +23132,6 @@
23017
23132
  intersectionRef,
23018
23133
  isIntersecting
23019
23134
  } = useIntersectionObserver(entries => {}, props.rootMargin ? {
23020
- root: props.rootRef,
23021
23135
  rootMargin: props.rootMargin
23022
23136
  } : undefined);
23023
23137
  vue.watch(isIntersecting, async val => {
@@ -23042,10 +23156,10 @@
23042
23156
  emit
23043
23157
  } = _ref2;
23044
23158
  const rootEl = vue.ref();
23045
- const startStatus = vue.ref('ok');
23046
- const endStatus = vue.ref('ok');
23159
+ const startStatus = vue.shallowRef('ok');
23160
+ const endStatus = vue.shallowRef('ok');
23047
23161
  const margin = vue.computed(() => convertToUnit(props.margin));
23048
- const isIntersecting = vue.ref(false);
23162
+ const isIntersecting = vue.shallowRef(false);
23049
23163
  function setScrollAmount(amount) {
23050
23164
  if (!rootEl.value) return;
23051
23165
  const property = props.direction === 'vertical' ? 'scrollTop' : 'scrollLeft';
@@ -23197,6 +23311,215 @@
23197
23311
 
23198
23312
  // Types
23199
23313
 
23314
+ const makeVOtpInputProps = propsFactory({
23315
+ autofocus: Boolean,
23316
+ divider: String,
23317
+ focusAll: Boolean,
23318
+ label: {
23319
+ type: String,
23320
+ default: '$vuetify.input.otp'
23321
+ },
23322
+ length: {
23323
+ type: [Number, String],
23324
+ default: 6
23325
+ },
23326
+ modelValue: {
23327
+ type: [Number, String],
23328
+ default: undefined
23329
+ },
23330
+ placeholder: String,
23331
+ type: {
23332
+ type: String,
23333
+ default: 'text'
23334
+ },
23335
+ ...makeDimensionProps(),
23336
+ ...makeFocusProps(),
23337
+ ...only(makeVFieldProps({
23338
+ variant: 'outlined'
23339
+ }), ['baseColor', 'bgColor', 'class', 'color', 'disabled', 'error', 'loading', 'rounded', 'style', 'theme', 'variant'])
23340
+ }, 'VOtpInput');
23341
+ const VOtpInput = genericComponent()({
23342
+ name: 'VOtpInput',
23343
+ props: makeVOtpInputProps(),
23344
+ emits: {
23345
+ finish: val => true,
23346
+ 'update:focused': val => true,
23347
+ 'update:modelValue': val => true
23348
+ },
23349
+ setup(props, _ref) {
23350
+ let {
23351
+ attrs,
23352
+ emit,
23353
+ slots
23354
+ } = _ref;
23355
+ const {
23356
+ dimensionStyles
23357
+ } = useDimension(props);
23358
+ const {
23359
+ isFocused,
23360
+ focus,
23361
+ blur
23362
+ } = useFocus(props);
23363
+ const model = useProxiedModel(props, 'modelValue', '', val => String(val).split(''), val => val.join(''));
23364
+ const {
23365
+ t
23366
+ } = useLocale();
23367
+ const fields = vue.computed(() => Array(Number(props.length)).fill(0));
23368
+ const focusIndex = vue.ref(-1);
23369
+ const contentRef = vue.ref();
23370
+ const inputRef = vue.ref([]);
23371
+ const current = vue.computed(() => inputRef.value[focusIndex.value]);
23372
+ function onInput() {
23373
+ const array = model.value.slice();
23374
+ const value = current.value.value;
23375
+ array[focusIndex.value] = value;
23376
+ model.value = array;
23377
+ let target = null;
23378
+ if (focusIndex.value > model.value.length) {
23379
+ target = model.value.length + 1;
23380
+ } else if (focusIndex.value + 1 !== Number(props.length)) {
23381
+ target = 'next';
23382
+ } else {
23383
+ requestAnimationFrame(() => current.value?.blur());
23384
+ }
23385
+ if (target) focusChild(contentRef.value, target);
23386
+ }
23387
+ function onKeydown(e) {
23388
+ const array = model.value.slice();
23389
+ const index = focusIndex.value;
23390
+ let target = null;
23391
+ if (!['ArrowLeft', 'ArrowRight', 'Backspace', 'Delete'].includes(e.key)) return;
23392
+ e.preventDefault();
23393
+ if (e.key === 'ArrowLeft') {
23394
+ target = 'prev';
23395
+ } else if (e.key === 'ArrowRight') {
23396
+ target = 'next';
23397
+ } else if (['Backspace', 'Delete'].includes(e.key)) {
23398
+ array[focusIndex.value] = '';
23399
+ model.value = array;
23400
+ if (focusIndex.value > 0 && e.key === 'Backspace') {
23401
+ target = 'prev';
23402
+ } else {
23403
+ requestAnimationFrame(() => {
23404
+ inputRef.value[index].select();
23405
+ });
23406
+ }
23407
+ }
23408
+ requestAnimationFrame(() => {
23409
+ if (target != null) {
23410
+ focusChild(contentRef.value, target);
23411
+ }
23412
+ });
23413
+ }
23414
+ function onPaste(index, e) {
23415
+ e.preventDefault();
23416
+ e.stopPropagation();
23417
+ model.value = (e?.clipboardData?.getData('Text') ?? '').split('');
23418
+ inputRef.value?.[index].blur();
23419
+ }
23420
+ function reset() {
23421
+ model.value = [];
23422
+ }
23423
+ function onFocus(e, index) {
23424
+ focus();
23425
+ focusIndex.value = index;
23426
+ }
23427
+ function onBlur() {
23428
+ blur();
23429
+ focusIndex.value = -1;
23430
+ }
23431
+ provideDefaults({
23432
+ VField: {
23433
+ disabled: vue.computed(() => props.disabled),
23434
+ error: vue.computed(() => props.error),
23435
+ variant: vue.computed(() => props.variant)
23436
+ }
23437
+ }, {
23438
+ scoped: true
23439
+ });
23440
+ vue.watch(model, val => {
23441
+ if (val.length === props.length) emit('finish', val.join(''));
23442
+ }, {
23443
+ deep: true
23444
+ });
23445
+ vue.watch(focusIndex, val => {
23446
+ if (val < 0) return;
23447
+ IN_BROWSER && window.requestAnimationFrame(() => {
23448
+ inputRef.value[val].select();
23449
+ });
23450
+ });
23451
+ useRender(() => {
23452
+ const [rootAttrs, inputAttrs] = filterInputAttrs(attrs);
23453
+ return vue.createVNode("div", vue.mergeProps({
23454
+ "class": ['v-otp-input', {
23455
+ 'v-otp-input--divided': !!props.divider
23456
+ }, props.class],
23457
+ "style": [props.style]
23458
+ }, rootAttrs), [vue.createVNode("div", {
23459
+ "ref": contentRef,
23460
+ "class": "v-otp-input__content",
23461
+ "style": [dimensionStyles.value]
23462
+ }, [fields.value.map((_, i) => vue.createVNode(vue.Fragment, null, [props.divider && i !== 0 && vue.createVNode("span", {
23463
+ "class": "v-otp-input__divider"
23464
+ }, [props.divider]), vue.createVNode(VField, {
23465
+ "focused": isFocused.value && props.focusAll || focusIndex.value === i,
23466
+ "key": i
23467
+ }, {
23468
+ ...slots,
23469
+ default: () => {
23470
+ return vue.createVNode("input", {
23471
+ "ref": val => inputRef.value[i] = val,
23472
+ "aria-label": t(props.label, i + 1),
23473
+ "autofocus": i === 0 && props.autofocus,
23474
+ "autocomplete": "one-time-code",
23475
+ "class": ['v-otp-input__field'],
23476
+ "inputmode": "text",
23477
+ "min": props.type === 'number' ? 0 : undefined,
23478
+ "maxlength": "1",
23479
+ "placeholder": props.placeholder,
23480
+ "type": props.type,
23481
+ "value": model.value[i],
23482
+ "onInput": onInput,
23483
+ "onFocus": e => onFocus(e, i),
23484
+ "onBlur": onBlur,
23485
+ "onKeydown": onKeydown,
23486
+ "onPaste": event => onPaste(i, event)
23487
+ }, null);
23488
+ }
23489
+ })])), vue.createVNode("input", vue.mergeProps({
23490
+ "class": "v-otp-input-input",
23491
+ "type": "hidden"
23492
+ }, inputAttrs, {
23493
+ "value": model.value.join('')
23494
+ }), null), vue.createVNode(VOverlay, {
23495
+ "contained": true,
23496
+ "content-class": "v-otp-input__loader",
23497
+ "model-value": !!props.loading,
23498
+ "persistent": true
23499
+ }, {
23500
+ default: () => [slots.loader?.() ?? vue.createVNode(VProgressCircular, {
23501
+ "color": typeof props.loading === 'boolean' ? undefined : props.loading,
23502
+ "indeterminate": true,
23503
+ "size": "24",
23504
+ "width": "2"
23505
+ }, null)]
23506
+ }), slots.default?.()])]);
23507
+ });
23508
+ return {
23509
+ blur: () => {
23510
+ inputRef.value?.some(input => input.blur());
23511
+ },
23512
+ focus: () => {
23513
+ inputRef.value?.[0].focus();
23514
+ },
23515
+ reset,
23516
+ isFocused
23517
+ };
23518
+ }
23519
+ });
23520
+
23521
+ // Types
23522
+
23200
23523
  const rootTypes = {
23201
23524
  actions: 'button@2',
23202
23525
  article: 'heading, paragraph',
@@ -23328,6 +23651,373 @@
23328
23651
  }
23329
23652
  });
23330
23653
 
23654
+ // Types
23655
+
23656
+ const makeVStepperActionsProps = propsFactory({
23657
+ color: String,
23658
+ disabled: {
23659
+ type: [Boolean, String],
23660
+ default: false
23661
+ },
23662
+ prevText: {
23663
+ type: String,
23664
+ default: '$vuetify.stepper.prev'
23665
+ },
23666
+ nextText: {
23667
+ type: String,
23668
+ default: '$vuetify.stepper.next'
23669
+ }
23670
+ }, 'VStepperActions');
23671
+ const VStepperActions = genericComponent()({
23672
+ name: 'VStepperActions',
23673
+ props: makeVStepperActionsProps(),
23674
+ emits: {
23675
+ 'click:prev': () => true,
23676
+ 'click:next': () => true
23677
+ },
23678
+ setup(props, _ref) {
23679
+ let {
23680
+ emit,
23681
+ slots
23682
+ } = _ref;
23683
+ const {
23684
+ t
23685
+ } = useLocale();
23686
+ function onClickPrev() {
23687
+ emit('click:prev');
23688
+ }
23689
+ function onClickNext() {
23690
+ emit('click:next');
23691
+ }
23692
+ useRender(() => {
23693
+ return vue.createVNode("div", {
23694
+ "class": "v-stepper-actions"
23695
+ }, [vue.createVNode(VBtn, {
23696
+ "disabled": ['prev', true].includes(props.disabled),
23697
+ "text": t(props.prevText),
23698
+ "variant": "text",
23699
+ "onClick": onClickPrev
23700
+ }, null), vue.createVNode(VBtn, {
23701
+ "disabled": ['next', true].includes(props.disabled),
23702
+ "color": props.color,
23703
+ "text": t(props.nextText),
23704
+ "variant": "tonal",
23705
+ "onClick": onClickNext
23706
+ }, null)]);
23707
+ });
23708
+ return {};
23709
+ }
23710
+ });
23711
+
23712
+ // Utilities
23713
+ const VStepperHeader = createSimpleFunctional('v-stepper-header');
23714
+
23715
+ // Types
23716
+
23717
+ const makeVStepperItemProps = propsFactory({
23718
+ color: String,
23719
+ title: String,
23720
+ subtitle: String,
23721
+ complete: Boolean,
23722
+ completeIcon: {
23723
+ type: String,
23724
+ default: '$complete'
23725
+ },
23726
+ editable: Boolean,
23727
+ editIcon: {
23728
+ type: String,
23729
+ default: '$edit'
23730
+ },
23731
+ error: Boolean,
23732
+ errorIcon: {
23733
+ type: String,
23734
+ default: '$error'
23735
+ },
23736
+ icon: String,
23737
+ ripple: {
23738
+ type: [Boolean, Object],
23739
+ default: true
23740
+ },
23741
+ rules: {
23742
+ type: Array,
23743
+ default: () => []
23744
+ },
23745
+ ...makeGroupItemProps()
23746
+ }, 'VStepperItem');
23747
+ const VStepperItem = genericComponent()({
23748
+ name: 'VStepperItem',
23749
+ directives: {
23750
+ Ripple
23751
+ },
23752
+ props: makeVStepperItemProps(),
23753
+ emits: {
23754
+ 'group:selected': val => true
23755
+ },
23756
+ setup(props, _ref) {
23757
+ let {
23758
+ slots
23759
+ } = _ref;
23760
+ const group = useGroupItem(props, VStepperSymbol, true);
23761
+ const step = vue.computed(() => group?.value.value ?? props.value);
23762
+ const isValid = vue.computed(() => props.rules.every(handler => handler() === true));
23763
+ const canEdit = vue.computed(() => !props.disabled && props.editable);
23764
+ const hasError = vue.computed(() => props.error || !isValid.value);
23765
+ const hasCompleted = vue.computed(() => props.complete || props.rules.length > 0 && isValid.value);
23766
+ const icon = vue.computed(() => {
23767
+ if (hasError.value) return props.errorIcon;
23768
+ if (hasCompleted.value) return props.completeIcon;
23769
+ if (props.editable) return props.editIcon;
23770
+ return props.icon;
23771
+ });
23772
+ const slotProps = vue.computed(() => ({
23773
+ canEdit: canEdit.value,
23774
+ hasError: hasError.value,
23775
+ hasCompleted: hasCompleted.value,
23776
+ title: props.title,
23777
+ subtitle: props.subtitle,
23778
+ step: step.value,
23779
+ value: props.value
23780
+ }));
23781
+ useRender(() => {
23782
+ const hasColor = (!group || group.isSelected.value || hasCompleted.value || canEdit.value) && !hasError.value && !props.disabled;
23783
+ const hasTitle = !!(props.title || slots.title);
23784
+ const hasSubtitle = !!(props.subtitle || slots.subtitle);
23785
+ function onClick() {
23786
+ group?.toggle();
23787
+ }
23788
+ return vue.withDirectives(vue.createVNode("button", {
23789
+ "class": ['v-stepper-item', {
23790
+ 'v-stepper-item--complete': hasCompleted.value,
23791
+ 'v-stepper-item--disabled': props.disabled,
23792
+ 'v-stepper-item--error': hasError.value
23793
+ }, group?.selectedClass.value],
23794
+ "disabled": !props.editable,
23795
+ "onClick": onClick
23796
+ }, [vue.createVNode(VAvatar, {
23797
+ "key": "stepper-avatar",
23798
+ "class": "v-stepper-item__avatar",
23799
+ "color": hasColor ? props.color : undefined,
23800
+ "size": 24
23801
+ }, {
23802
+ default: () => [slots.icon?.(slotProps.value) ?? (icon.value ? vue.createVNode(VIcon, {
23803
+ "icon": icon.value
23804
+ }, null) : step.value)]
23805
+ }), vue.createVNode("div", {
23806
+ "class": "v-stepper-item__content"
23807
+ }, [hasTitle && vue.createVNode("div", {
23808
+ "key": "title",
23809
+ "class": "v-stepper-item__title"
23810
+ }, [slots.title?.(slotProps.value) ?? props.title]), hasSubtitle && vue.createVNode("div", {
23811
+ "key": "subtitle",
23812
+ "class": "v-stepper-item__subtitle"
23813
+ }, [slots.subtitle?.(slotProps.value) ?? props.subtitle]), slots.default?.(slotProps.value)])]), [[vue.resolveDirective("ripple"), props.ripple && props.editable, null]]);
23814
+ });
23815
+ return {};
23816
+ }
23817
+ });
23818
+
23819
+ // Types
23820
+
23821
+ const VStepperSymbol$1 = Symbol.for('vuetify:v-stepper');
23822
+ const makeVStepperWindowProps = propsFactory({
23823
+ ...makeVWindowProps({
23824
+ mandatory: false
23825
+ })
23826
+ }, 'VStepperWindow');
23827
+ const VStepperWindow = genericComponent()({
23828
+ name: 'VStepperWindow',
23829
+ props: makeVStepperWindowProps(),
23830
+ emits: {
23831
+ 'update:modelValue': v => true
23832
+ },
23833
+ setup(props, _ref) {
23834
+ let {
23835
+ slots
23836
+ } = _ref;
23837
+ const group = vue.inject(VStepperSymbol$1, null);
23838
+ const _model = useProxiedModel(props, 'modelValue');
23839
+ const model = vue.computed({
23840
+ get() {
23841
+ // Always return modelValue if defined
23842
+ // or if not within a VStepper group
23843
+ if (_model.value != null || !group) return _model.value;
23844
+
23845
+ // If inside of a VStepper, find the currently selected
23846
+ // item by id. Item value may be assigned by its index
23847
+ return group.items.value.find(item => group.selected.value.includes(item.id))?.value;
23848
+ },
23849
+ set(val) {
23850
+ _model.value = val;
23851
+ }
23852
+ });
23853
+ useRender(() => {
23854
+ const [windowProps] = VWindow.filterProps(props);
23855
+ return vue.createVNode(VWindow, vue.mergeProps(windowProps, {
23856
+ "modelValue": model.value,
23857
+ "onUpdate:modelValue": $event => model.value = $event,
23858
+ "class": "v-stepper-window"
23859
+ }), slots);
23860
+ });
23861
+ return {};
23862
+ }
23863
+ });
23864
+
23865
+ const makeVStepperWindowItemProps = propsFactory({
23866
+ ...makeVWindowItemProps()
23867
+ }, 'VStepperWindowItem');
23868
+ const VStepperWindowItem = genericComponent()({
23869
+ name: 'VStepperWindowItem',
23870
+ props: makeVStepperWindowItemProps(),
23871
+ setup(props, _ref) {
23872
+ let {
23873
+ slots
23874
+ } = _ref;
23875
+ useRender(() => {
23876
+ const [windowItemProps] = VWindowItem.filterProps(props);
23877
+ return vue.createVNode(VWindowItem, vue.mergeProps(windowItemProps, {
23878
+ "class": "v-stepper-window-item"
23879
+ }), slots);
23880
+ });
23881
+ return {};
23882
+ }
23883
+ });
23884
+
23885
+ // Types
23886
+
23887
+ const VStepperSymbol = Symbol.for('vuetify:v-stepper');
23888
+ const makeVStepperProps = propsFactory({
23889
+ altLabels: Boolean,
23890
+ bgColor: String,
23891
+ editable: Boolean,
23892
+ hideActions: Boolean,
23893
+ items: {
23894
+ type: Array,
23895
+ default: () => []
23896
+ },
23897
+ itemTitle: {
23898
+ type: String,
23899
+ default: 'title'
23900
+ },
23901
+ itemValue: {
23902
+ type: String,
23903
+ default: 'value'
23904
+ },
23905
+ mobile: Boolean,
23906
+ nonLinear: Boolean,
23907
+ flat: Boolean,
23908
+ ...makeGroupProps({
23909
+ mandatory: 'force',
23910
+ selectedClass: 'v-stepper-item--selected'
23911
+ }),
23912
+ ...makeVSheetProps(),
23913
+ ...only(makeVStepperActionsProps(), ['prevText', 'nextText'])
23914
+ }, 'VStepper');
23915
+ const VStepper = genericComponent()({
23916
+ name: 'VStepper',
23917
+ props: makeVStepperProps(),
23918
+ emits: {
23919
+ 'update:modelValue': v => true
23920
+ },
23921
+ setup(props, _ref) {
23922
+ let {
23923
+ slots
23924
+ } = _ref;
23925
+ // TODO: fix typing
23926
+ const {
23927
+ items: _items,
23928
+ next,
23929
+ prev,
23930
+ selected
23931
+ } = useGroup(props, VStepperSymbol);
23932
+ const {
23933
+ color,
23934
+ editable,
23935
+ prevText,
23936
+ nextText
23937
+ } = vue.toRefs(props);
23938
+ const items = vue.computed(() => props.items.map((item, index) => {
23939
+ const title = getPropertyFromItem(item, props.itemTitle, item);
23940
+ const value = getPropertyFromItem(item, props.itemValue, index + 1);
23941
+ return {
23942
+ title,
23943
+ value,
23944
+ raw: item
23945
+ };
23946
+ }));
23947
+ const activeIndex = vue.computed(() => {
23948
+ return _items.value.findIndex(item => selected.value.includes(item.id));
23949
+ });
23950
+ const disabled = vue.computed(() => {
23951
+ if (props.disabled) return props.disabled;
23952
+ if (activeIndex.value === 0) return 'prev';
23953
+ if (activeIndex.value === _items.value.length - 1) return 'next';
23954
+ return false;
23955
+ });
23956
+ provideDefaults({
23957
+ VStepperItem: {
23958
+ editable,
23959
+ prevText,
23960
+ nextText
23961
+ },
23962
+ VStepperActions: {
23963
+ color,
23964
+ disabled,
23965
+ prevText,
23966
+ nextText
23967
+ }
23968
+ });
23969
+ useRender(() => {
23970
+ const [sheetProps] = VSheet.filterProps(props);
23971
+ const hasHeader = !!(slots.header || props.items.length);
23972
+ const hasWindow = props.items.length > 0;
23973
+ const hasActions = !props.hideActions && !!(hasWindow || slots.actions);
23974
+ return vue.createVNode(VSheet, vue.mergeProps(sheetProps, {
23975
+ "color": props.bgColor,
23976
+ "class": ['v-stepper', {
23977
+ 'v-stepper--alt-labels': props.altLabels,
23978
+ 'v-stepper--flat': props.flat,
23979
+ 'v-stepper--non-linear': props.nonLinear,
23980
+ 'v-stepper--mobile': props.mobile
23981
+ }, props.class],
23982
+ "style": props.style
23983
+ }), {
23984
+ default: () => [hasHeader && vue.createVNode(VStepperHeader, {
23985
+ "key": "stepper-header"
23986
+ }, {
23987
+ default: () => [items.value.map((item, index) => vue.createVNode(vue.Fragment, null, [!!index && vue.createVNode(VDivider, null, null), vue.createVNode(VStepperItem, item, {
23988
+ default: slots[`header-item.${item.value}`] ?? slots.header,
23989
+ icon: slots.icon,
23990
+ title: slots.title,
23991
+ subtitle: slots.subtitle
23992
+ })]))]
23993
+ }), hasWindow && vue.createVNode(VStepperWindow, {
23994
+ "key": "stepper-window"
23995
+ }, {
23996
+ default: () => [items.value.map(item => vue.createVNode(VStepperWindowItem, {
23997
+ "value": item.value
23998
+ }, {
23999
+ default: () => slots[`item.${item.value}`]?.(item) ?? slots.item?.(item)
24000
+ }))]
24001
+ }), slots.default?.({
24002
+ prev,
24003
+ next
24004
+ }), hasActions && (slots.actions?.({
24005
+ next,
24006
+ prev
24007
+ }) ?? vue.createVNode(VStepperActions, {
24008
+ "key": "stepper-actions",
24009
+ "onClick:prev": prev,
24010
+ "onClick:next": next
24011
+ }, null))]
24012
+ });
24013
+ });
24014
+ return {
24015
+ prev,
24016
+ next
24017
+ };
24018
+ }
24019
+ });
24020
+
23331
24021
  var components = /*#__PURE__*/Object.freeze({
23332
24022
  __proto__: null,
23333
24023
  VAlert: VAlert,
@@ -23430,6 +24120,7 @@
23430
24120
  VMessages: VMessages,
23431
24121
  VNavigationDrawer: VNavigationDrawer,
23432
24122
  VNoSsr: VNoSsr,
24123
+ VOtpInput: VOtpInput,
23433
24124
  VOverlay: VOverlay,
23434
24125
  VPagination: VPagination,
23435
24126
  VParallax: VParallax,
@@ -23462,6 +24153,12 @@
23462
24153
  VSlider: VSlider,
23463
24154
  VSnackbar: VSnackbar,
23464
24155
  VSpacer: VSpacer,
24156
+ VStepper: VStepper,
24157
+ VStepperActions: VStepperActions,
24158
+ VStepperHeader: VStepperHeader,
24159
+ VStepperItem: VStepperItem,
24160
+ VStepperWindow: VStepperWindow,
24161
+ VStepperWindowItem: VStepperWindowItem,
23465
24162
  VSvgIcon: VSvgIcon,
23466
24163
  VSwitch: VSwitch,
23467
24164
  VSystemBar: VSystemBar,
@@ -23699,7 +24396,7 @@
23699
24396
  date
23700
24397
  };
23701
24398
  }
23702
- const version$1 = "3.3.10";
24399
+ const version$1 = "3.3.12";
23703
24400
  createVuetify$1.version = version$1;
23704
24401
 
23705
24402
  // Vue's inject() can only be used in setup
@@ -23713,7 +24410,7 @@
23713
24410
 
23714
24411
  /* eslint-disable local-rules/sort-imports */
23715
24412
 
23716
- const version = "3.3.10";
24413
+ const version = "3.3.12";
23717
24414
 
23718
24415
  /* eslint-disable local-rules/sort-imports */
23719
24416