@vuetify/nightly 3.9.0-beta.1-dev.2025-06-26 → 3.9.0-beta.1-dev.2025-07-02

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 (243) hide show
  1. package/CHANGELOG.md +105 -3
  2. package/dist/_component-variables-labs.sass +1 -0
  3. package/dist/json/attributes.json +2814 -2754
  4. package/dist/json/importMap-labs.json +16 -12
  5. package/dist/json/importMap.json +174 -174
  6. package/dist/json/tags.json +20 -0
  7. package/dist/json/web-types.json +5362 -5196
  8. package/dist/vuetify-labs.cjs +796 -64
  9. package/dist/vuetify-labs.css +3440 -3189
  10. package/dist/vuetify-labs.d.ts +452 -206
  11. package/dist/vuetify-labs.esm.js +796 -65
  12. package/dist/vuetify-labs.esm.js.map +1 -1
  13. package/dist/vuetify-labs.js +796 -64
  14. package/dist/vuetify-labs.min.css +2 -2
  15. package/dist/vuetify.cjs +378 -40
  16. package/dist/vuetify.cjs.map +1 -1
  17. package/dist/vuetify.css +3377 -3368
  18. package/dist/vuetify.d.ts +82 -62
  19. package/dist/vuetify.esm.js +378 -41
  20. package/dist/vuetify.esm.js.map +1 -1
  21. package/dist/vuetify.js +378 -40
  22. package/dist/vuetify.js.map +1 -1
  23. package/dist/vuetify.min.css +2 -2
  24. package/dist/vuetify.min.js +312 -274
  25. package/dist/vuetify.min.js.map +1 -1
  26. package/lib/components/VDataTable/VDataTableColumn.js +0 -1
  27. package/lib/components/VDataTable/VDataTableColumn.js.map +1 -1
  28. package/lib/components/VDataTable/VDataTableHeaders.js +5 -5
  29. package/lib/components/VDataTable/VDataTableHeaders.js.map +1 -1
  30. package/lib/components/VDataTable/composables/sort.js +2 -1
  31. package/lib/components/VDataTable/composables/sort.js.map +1 -1
  32. package/lib/components/VDatePicker/VDatePickerMonth.js +1 -2
  33. package/lib/components/VDatePicker/VDatePickerMonth.js.map +1 -1
  34. package/lib/components/VKbd/VKbd.css +14 -5
  35. package/lib/components/VKbd/VKbd.js.map +1 -1
  36. package/lib/components/VKbd/VKbd.scss +26 -0
  37. package/lib/components/VKbd/_variables.scss +12 -6
  38. package/lib/components/VKbd/index.js.map +1 -1
  39. package/lib/components/VOtpInput/VOtpInput.js +17 -14
  40. package/lib/components/VOtpInput/VOtpInput.js.map +1 -1
  41. package/lib/components/VOverlay/locationStrategies.js +1 -1
  42. package/lib/components/VOverlay/locationStrategies.js.map +1 -1
  43. package/lib/components/VTextField/VTextField.js +1 -1
  44. package/lib/components/VTextField/VTextField.js.map +1 -1
  45. package/lib/composables/calendar.d.ts +0 -1
  46. package/lib/composables/calendar.js +6 -10
  47. package/lib/composables/calendar.js.map +1 -1
  48. package/lib/composables/date/adapters/vuetify.js +1 -1
  49. package/lib/composables/date/adapters/vuetify.js.map +1 -1
  50. package/lib/composables/hotkey/hotkey-parsing.d.ts +15 -0
  51. package/lib/composables/hotkey/hotkey-parsing.js +154 -0
  52. package/lib/composables/hotkey/hotkey-parsing.js.map +1 -0
  53. package/lib/composables/hotkey/hotkey.d.ts +9 -0
  54. package/lib/composables/{hotkey.js → hotkey/hotkey.js} +31 -39
  55. package/lib/composables/hotkey/hotkey.js.map +1 -0
  56. package/lib/composables/hotkey/index.d.ts +1 -0
  57. package/lib/composables/hotkey/index.js +2 -0
  58. package/lib/composables/hotkey/index.js.map +1 -0
  59. package/lib/composables/hotkey/key-aliases.d.ts +14 -0
  60. package/lib/composables/hotkey/key-aliases.js +38 -0
  61. package/lib/composables/hotkey/key-aliases.js.map +1 -0
  62. package/lib/composables/icons.d.ts +11 -0
  63. package/lib/composables/icons.js.map +1 -1
  64. package/lib/composables/index.d.ts +1 -0
  65. package/lib/composables/index.js +1 -0
  66. package/lib/composables/index.js.map +1 -1
  67. package/lib/composables/virtual.js +1 -1
  68. package/lib/composables/virtual.js.map +1 -1
  69. package/lib/entry-bundler.js +1 -1
  70. package/lib/framework.d.ts +83 -62
  71. package/lib/framework.js +1 -1
  72. package/lib/iconsets/fa.js +12 -1
  73. package/lib/iconsets/fa.js.map +1 -1
  74. package/lib/iconsets/fa4.js +12 -1
  75. package/lib/iconsets/fa4.js.map +1 -1
  76. package/lib/iconsets/md.js +12 -1
  77. package/lib/iconsets/md.js.map +1 -1
  78. package/lib/iconsets/mdi-svg.js +12 -1
  79. package/lib/iconsets/mdi-svg.js.map +1 -1
  80. package/lib/iconsets/mdi.js +12 -1
  81. package/lib/iconsets/mdi.js.map +1 -1
  82. package/lib/labs/VCalendar/VCalendar.d.ts +33 -33
  83. package/lib/labs/VCalendar/VCalendar.js +9 -9
  84. package/lib/labs/VCalendar/VCalendar.js.map +1 -1
  85. package/lib/labs/VCalendar/VCalendarDay.d.ts +33 -33
  86. package/lib/labs/VCalendar/VCalendarDay.js +1 -1
  87. package/lib/labs/VCalendar/VCalendarDay.js.map +1 -1
  88. package/lib/labs/VCalendar/VCalendarInterval.d.ts +36 -36
  89. package/lib/labs/VCalendar/VCalendarInterval.js +9 -9
  90. package/lib/labs/VCalendar/VCalendarInterval.js.map +1 -1
  91. package/lib/labs/VCalendar/VCalendarIntervalEvent.d.ts +12 -12
  92. package/lib/labs/VCalendar/VCalendarIntervalEvent.js +1 -1
  93. package/lib/labs/VCalendar/VCalendarIntervalEvent.js.map +1 -1
  94. package/lib/labs/VCalendar/VCalendarMonthDay.d.ts +36 -36
  95. package/lib/labs/VCalendar/VCalendarMonthDay.js +4 -4
  96. package/lib/labs/VCalendar/VCalendarMonthDay.js.map +1 -1
  97. package/lib/labs/VHotkey/VHotkey.css +242 -0
  98. package/lib/labs/VHotkey/VHotkey.d.ts +387 -0
  99. package/lib/labs/VHotkey/VHotkey.js +432 -0
  100. package/lib/labs/VHotkey/VHotkey.js.map +1 -0
  101. package/lib/labs/VHotkey/VHotkey.scss +253 -0
  102. package/lib/labs/VHotkey/_variables.scss +43 -0
  103. package/lib/labs/VHotkey/index.d.ts +1 -0
  104. package/lib/labs/VHotkey/index.js +2 -0
  105. package/lib/labs/VHotkey/index.js.map +1 -0
  106. package/lib/labs/VIconBtn/VIconBtn.js +1 -0
  107. package/lib/labs/VIconBtn/VIconBtn.js.map +1 -1
  108. package/lib/labs/components.d.ts +1 -0
  109. package/lib/labs/components.js +1 -0
  110. package/lib/labs/components.js.map +1 -1
  111. package/lib/locale/af.d.ts +18 -0
  112. package/lib/locale/af.js +18 -0
  113. package/lib/locale/af.js.map +1 -1
  114. package/lib/locale/ar.d.ts +18 -0
  115. package/lib/locale/ar.js +18 -0
  116. package/lib/locale/ar.js.map +1 -1
  117. package/lib/locale/az.d.ts +18 -0
  118. package/lib/locale/az.js +18 -0
  119. package/lib/locale/az.js.map +1 -1
  120. package/lib/locale/bg.d.ts +18 -0
  121. package/lib/locale/bg.js +18 -0
  122. package/lib/locale/bg.js.map +1 -1
  123. package/lib/locale/ca.d.ts +18 -0
  124. package/lib/locale/ca.js +18 -0
  125. package/lib/locale/ca.js.map +1 -1
  126. package/lib/locale/ckb.d.ts +18 -0
  127. package/lib/locale/ckb.js +18 -0
  128. package/lib/locale/ckb.js.map +1 -1
  129. package/lib/locale/cs.d.ts +18 -0
  130. package/lib/locale/cs.js +18 -0
  131. package/lib/locale/cs.js.map +1 -1
  132. package/lib/locale/da.d.ts +18 -0
  133. package/lib/locale/da.js +18 -0
  134. package/lib/locale/da.js.map +1 -1
  135. package/lib/locale/de.d.ts +18 -0
  136. package/lib/locale/de.js +18 -0
  137. package/lib/locale/de.js.map +1 -1
  138. package/lib/locale/el.d.ts +18 -0
  139. package/lib/locale/el.js +18 -0
  140. package/lib/locale/el.js.map +1 -1
  141. package/lib/locale/en.d.ts +18 -0
  142. package/lib/locale/en.js +18 -0
  143. package/lib/locale/en.js.map +1 -1
  144. package/lib/locale/es.d.ts +18 -0
  145. package/lib/locale/es.js +18 -0
  146. package/lib/locale/es.js.map +1 -1
  147. package/lib/locale/et.d.ts +18 -0
  148. package/lib/locale/et.js +18 -0
  149. package/lib/locale/et.js.map +1 -1
  150. package/lib/locale/fa.d.ts +18 -0
  151. package/lib/locale/fa.js +18 -0
  152. package/lib/locale/fa.js.map +1 -1
  153. package/lib/locale/fi.d.ts +18 -0
  154. package/lib/locale/fi.js +18 -0
  155. package/lib/locale/fi.js.map +1 -1
  156. package/lib/locale/fr.d.ts +18 -0
  157. package/lib/locale/fr.js +18 -0
  158. package/lib/locale/fr.js.map +1 -1
  159. package/lib/locale/he.d.ts +18 -0
  160. package/lib/locale/he.js +18 -0
  161. package/lib/locale/he.js.map +1 -1
  162. package/lib/locale/hr.d.ts +18 -0
  163. package/lib/locale/hr.js +18 -0
  164. package/lib/locale/hr.js.map +1 -1
  165. package/lib/locale/hu.d.ts +18 -0
  166. package/lib/locale/hu.js +18 -0
  167. package/lib/locale/hu.js.map +1 -1
  168. package/lib/locale/id.d.ts +18 -0
  169. package/lib/locale/id.js +18 -0
  170. package/lib/locale/id.js.map +1 -1
  171. package/lib/locale/it.d.ts +18 -0
  172. package/lib/locale/it.js +18 -0
  173. package/lib/locale/it.js.map +1 -1
  174. package/lib/locale/ja.d.ts +18 -0
  175. package/lib/locale/ja.js +18 -0
  176. package/lib/locale/ja.js.map +1 -1
  177. package/lib/locale/km.d.ts +18 -0
  178. package/lib/locale/km.js +18 -0
  179. package/lib/locale/km.js.map +1 -1
  180. package/lib/locale/ko.d.ts +18 -0
  181. package/lib/locale/ko.js +18 -0
  182. package/lib/locale/ko.js.map +1 -1
  183. package/lib/locale/lt.d.ts +18 -0
  184. package/lib/locale/lt.js +18 -0
  185. package/lib/locale/lt.js.map +1 -1
  186. package/lib/locale/lv.d.ts +18 -0
  187. package/lib/locale/lv.js +18 -0
  188. package/lib/locale/lv.js.map +1 -1
  189. package/lib/locale/nl.d.ts +18 -0
  190. package/lib/locale/nl.js +18 -0
  191. package/lib/locale/nl.js.map +1 -1
  192. package/lib/locale/no.d.ts +18 -0
  193. package/lib/locale/no.js +18 -0
  194. package/lib/locale/no.js.map +1 -1
  195. package/lib/locale/pl.d.ts +18 -0
  196. package/lib/locale/pl.js +18 -0
  197. package/lib/locale/pl.js.map +1 -1
  198. package/lib/locale/pt.d.ts +18 -0
  199. package/lib/locale/pt.js +18 -0
  200. package/lib/locale/pt.js.map +1 -1
  201. package/lib/locale/ro.d.ts +18 -0
  202. package/lib/locale/ro.js +18 -0
  203. package/lib/locale/ro.js.map +1 -1
  204. package/lib/locale/ru.d.ts +18 -0
  205. package/lib/locale/ru.js +18 -0
  206. package/lib/locale/ru.js.map +1 -1
  207. package/lib/locale/sk.d.ts +18 -0
  208. package/lib/locale/sk.js +18 -0
  209. package/lib/locale/sk.js.map +1 -1
  210. package/lib/locale/sl.d.ts +18 -0
  211. package/lib/locale/sl.js +18 -0
  212. package/lib/locale/sl.js.map +1 -1
  213. package/lib/locale/sr-Cyrl.d.ts +18 -0
  214. package/lib/locale/sr-Cyrl.js +18 -0
  215. package/lib/locale/sr-Cyrl.js.map +1 -1
  216. package/lib/locale/sr-Latn.d.ts +18 -0
  217. package/lib/locale/sr-Latn.js +18 -0
  218. package/lib/locale/sr-Latn.js.map +1 -1
  219. package/lib/locale/sv.d.ts +18 -0
  220. package/lib/locale/sv.js +18 -0
  221. package/lib/locale/sv.js.map +1 -1
  222. package/lib/locale/th.d.ts +18 -0
  223. package/lib/locale/th.js +18 -0
  224. package/lib/locale/th.js.map +1 -1
  225. package/lib/locale/tr.d.ts +18 -0
  226. package/lib/locale/tr.js +18 -0
  227. package/lib/locale/tr.js.map +1 -1
  228. package/lib/locale/uk.d.ts +18 -0
  229. package/lib/locale/uk.js +18 -0
  230. package/lib/locale/uk.js.map +1 -1
  231. package/lib/locale/vi.d.ts +18 -0
  232. package/lib/locale/vi.js +18 -0
  233. package/lib/locale/vi.js.map +1 -1
  234. package/lib/locale/zh-Hans.d.ts +18 -0
  235. package/lib/locale/zh-Hans.js +18 -0
  236. package/lib/locale/zh-Hans.js.map +1 -1
  237. package/lib/locale/zh-Hant.d.ts +18 -0
  238. package/lib/locale/zh-Hant.js +18 -0
  239. package/lib/locale/zh-Hant.js.map +1 -1
  240. package/package.json +1 -1
  241. package/lib/components/VKbd/VKbd.sass +0 -15
  242. package/lib/composables/hotkey.d.ts +0 -9
  243. package/lib/composables/hotkey.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.9.0-beta.1-dev.2025-06-26
2
+ * Vuetify v3.9.0-beta.1-dev.2025-07-02
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
@@ -1832,7 +1832,18 @@ const aliases = {
1832
1832
  treeviewExpand: 'mdi-menu-right',
1833
1833
  eyeDropper: 'mdi-eyedropper',
1834
1834
  upload: 'mdi-cloud-upload',
1835
- color: 'mdi-palette'
1835
+ color: 'mdi-palette',
1836
+ command: 'mdi-apple-keyboard-command',
1837
+ ctrl: 'mdi-apple-keyboard-control',
1838
+ space: 'mdi-keyboard-space',
1839
+ shift: 'mdi-apple-keyboard-shift',
1840
+ alt: 'mdi-apple-keyboard-option',
1841
+ enter: 'mdi-keyboard-return',
1842
+ arrowup: 'mdi-arrow-up',
1843
+ arrowdown: 'mdi-arrow-down',
1844
+ arrowleft: 'mdi-arrow-left',
1845
+ arrowright: 'mdi-arrow-right',
1846
+ backspace: 'mdi-backspace'
1836
1847
  };
1837
1848
  const mdi = {
1838
1849
  // Not using mergeProps here, functional components merge props by default (?)
@@ -2628,6 +2639,24 @@ var en = {
2628
2639
  exclude: 'The {0} character is not allowed',
2629
2640
  notEmpty: 'Please choose at least one value',
2630
2641
  pattern: 'Invalid format'
2642
+ },
2643
+ hotkey: {
2644
+ then: 'then',
2645
+ ctrl: 'Ctrl',
2646
+ command: 'Command',
2647
+ space: 'Space',
2648
+ shift: 'Shift',
2649
+ alt: 'Alt',
2650
+ enter: 'Enter',
2651
+ escape: 'Escape',
2652
+ upArrow: 'Up Arrow',
2653
+ downArrow: 'Down Arrow',
2654
+ leftArrow: 'Left Arrow',
2655
+ rightArrow: 'Right Arrow',
2656
+ backspace: 'Backspace',
2657
+ option: 'Option',
2658
+ plus: 'plus',
2659
+ shortcut: 'Keyboard shortcut: {0}'
2631
2660
  }
2632
2661
  };
2633
2662
 
@@ -10701,7 +10730,7 @@ function connectedLocationStrategy(data, props, contentStyles) {
10701
10730
  });
10702
10731
  if (flipped.isFull) {
10703
10732
  const values = flipped.values();
10704
- if (deepEqual(values.at(-1), values.at(-3))) {
10733
+ if (deepEqual(values.at(-1), values.at(-3)) && !deepEqual(values.at(-1), values.at(-2))) {
10705
10734
  // Flipping is causing a container resize loop
10706
10735
  return;
10707
10736
  }
@@ -12551,7 +12580,7 @@ const VTextField = genericComponent()({
12551
12580
  if (!isFocused.value) focus();
12552
12581
  nextTick(() => {
12553
12582
  if (inputRef.value !== document.activeElement) {
12554
- inputRef.value?.focus();
12583
+ nextTick(() => inputRef.value?.focus());
12555
12584
  }
12556
12585
  });
12557
12586
  }
@@ -12890,7 +12919,7 @@ function useVirtual(props, items) {
12890
12919
  raf = requestAnimationFrame(_calculateVisibleItems);
12891
12920
  }
12892
12921
  function _calculateVisibleItems() {
12893
- if (!containerRef.value || !viewportHeight.value) return;
12922
+ if (!containerRef.value || !viewportHeight.value || !itemHeight.value) return;
12894
12923
  const scrollTop = lastScrollTop - markerOffset;
12895
12924
  const direction = Math.sign(scrollVelocity);
12896
12925
  const startPx = Math.max(0, scrollTop - BUFFER_PX);
@@ -17773,7 +17802,7 @@ function format(value, formatString, locale, formats) {
17773
17802
  case 'fullDate':
17774
17803
  options = {
17775
17804
  year: 'numeric',
17776
- month: 'long',
17805
+ month: 'short',
17777
17806
  day: 'numeric'
17778
17807
  };
17779
17808
  break;
@@ -18351,6 +18380,317 @@ function useDate() {
18351
18380
  return createInstance(options, locale);
18352
18381
  }
18353
18382
 
18383
+ /**
18384
+ * Centralized key alias mapping for consistent key normalization across the hotkey system.
18385
+ *
18386
+ * This maps various user-friendly aliases to canonical key names that match
18387
+ * KeyboardEvent.key values (in lowercase) where possible.
18388
+ */
18389
+ const keyAliasMap = {
18390
+ // Modifier aliases (from vue-use, other libraries, and current implementation)
18391
+ control: 'ctrl',
18392
+ command: 'cmd',
18393
+ option: 'alt',
18394
+ // Arrow key aliases (common abbreviations)
18395
+ up: 'arrowup',
18396
+ down: 'arrowdown',
18397
+ left: 'arrowleft',
18398
+ right: 'arrowright',
18399
+ // Other common key aliases
18400
+ esc: 'escape',
18401
+ spacebar: ' ',
18402
+ space: ' ',
18403
+ return: 'enter',
18404
+ del: 'delete',
18405
+ // Symbol aliases (existing from hotkey-parsing.ts)
18406
+ minus: '-',
18407
+ hyphen: '-'
18408
+ };
18409
+
18410
+ /**
18411
+ * Normalizes a key string to its canonical form using the alias map.
18412
+ *
18413
+ * @param key - The key string to normalize
18414
+ * @returns The canonical key name in lowercase
18415
+ */
18416
+ function normalizeKey(key) {
18417
+ const lowerKey = key.toLowerCase();
18418
+ return keyAliasMap[lowerKey] || lowerKey;
18419
+ }
18420
+
18421
+ // Utilities
18422
+
18423
+ /**
18424
+ * Splits a single combination string into individual key parts.
18425
+ *
18426
+ * A combination is a set of keys that must be pressed simultaneously.
18427
+ * e.g. `ctrl+k`, `shift--`
18428
+ */
18429
+ function splitKeyCombination(combination) {
18430
+ let isInternal = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
18431
+ if (!combination) {
18432
+ if (!isInternal) consoleWarn('Invalid hotkey combination: empty string provided');
18433
+ return [];
18434
+ }
18435
+
18436
+ // --- VALIDATION ---
18437
+ const startsWithPlusOrUnderscore = combination.startsWith('+') || combination.startsWith('_');
18438
+ const hasInvalidLeadingSeparator =
18439
+ // Starts with a single '+' or '_' followed by a non-separator character (e.g. '+a', '_a')
18440
+ startsWithPlusOrUnderscore && !(combination.startsWith('++') || combination.startsWith('__'));
18441
+ const hasInvalidStructure =
18442
+ // Invalid leading separator patterns
18443
+ combination.length > 1 && hasInvalidLeadingSeparator ||
18444
+ // Disallow literal + or _ keys (they require shift)
18445
+ combination.includes('++') || combination.includes('__') || combination === '+' || combination === '_' ||
18446
+ // Ends with a separator that is not part of a doubled literal
18447
+ combination.length > 1 && (combination.endsWith('+') || combination.endsWith('_')) && combination.at(-2) !== combination.at(-1) ||
18448
+ // Stand-alone doubled separators (dangling)
18449
+ combination === '++' || combination === '--' || combination === '__';
18450
+ if (hasInvalidStructure) {
18451
+ if (!isInternal) consoleWarn(`Invalid hotkey combination: "${combination}" has invalid structure`);
18452
+ return [];
18453
+ }
18454
+ const keys = [];
18455
+ let buffer = '';
18456
+ const flushBuffer = () => {
18457
+ if (buffer) {
18458
+ keys.push(normalizeKey(buffer));
18459
+ buffer = '';
18460
+ }
18461
+ };
18462
+ for (let i = 0; i < combination.length; i++) {
18463
+ const char = combination[i];
18464
+ const nextChar = combination[i + 1];
18465
+ if (char === '+' || char === '_' || char === '-') {
18466
+ if (char === nextChar) {
18467
+ flushBuffer();
18468
+ keys.push(char);
18469
+ i++;
18470
+ } else if (char === '+' || char === '_') {
18471
+ flushBuffer();
18472
+ } else {
18473
+ buffer += char;
18474
+ }
18475
+ } else {
18476
+ buffer += char;
18477
+ }
18478
+ }
18479
+ flushBuffer();
18480
+
18481
+ // Within a combination, `-` is only valid as a literal key (e.g., `ctrl+-`).
18482
+ // `-` cannot be part of a longer key name within a combination.
18483
+ const hasInvalidMinus = keys.some(key => key.length > 1 && key.includes('-') && key !== '--');
18484
+ if (hasInvalidMinus) {
18485
+ if (!isInternal) consoleWarn(`Invalid hotkey combination: "${combination}" has invalid structure`);
18486
+ return [];
18487
+ }
18488
+ if (keys.length === 0 && combination) {
18489
+ return [normalizeKey(combination)];
18490
+ }
18491
+ return keys;
18492
+ }
18493
+
18494
+ /**
18495
+ * Splits a hotkey string into its constituent combination groups.
18496
+ *
18497
+ * A sequence is a series of combinations that must be pressed in order.
18498
+ * e.g. `a-b`, `ctrl+k-p`
18499
+ */
18500
+ function splitKeySequence(str) {
18501
+ if (!str) {
18502
+ consoleWarn('Invalid hotkey sequence: empty string provided');
18503
+ return [];
18504
+ }
18505
+
18506
+ // A sequence is invalid if it starts or ends with a separator,
18507
+ // unless it is part of a combination (e.g., `shift+-`).
18508
+ const hasInvalidStart = str.startsWith('-') && !['---', '--+'].includes(str);
18509
+ const hasInvalidEnd = str.endsWith('-') && !str.endsWith('+-') && !str.endsWith('_-') && str !== '-' && str !== '---';
18510
+ if (hasInvalidStart || hasInvalidEnd) {
18511
+ consoleWarn(`Invalid hotkey sequence: "${str}" contains invalid combinations`);
18512
+ return [];
18513
+ }
18514
+ const result = [];
18515
+ let buffer = '';
18516
+ let i = 0;
18517
+ while (i < str.length) {
18518
+ const char = str[i];
18519
+ if (char === '-') {
18520
+ // Determine if this hyphen is part of the current combination
18521
+ const prevChar = str[i - 1];
18522
+ const prevPrevChar = i > 1 ? str[i - 2] : undefined;
18523
+ const precededBySinglePlusOrUnderscore = (prevChar === '+' || prevChar === '_') && prevPrevChar !== '+';
18524
+ if (precededBySinglePlusOrUnderscore) {
18525
+ // Treat as part of the combination (e.g., 'ctrl+-')
18526
+ buffer += char;
18527
+ i++;
18528
+ } else {
18529
+ // Treat as sequence separator
18530
+ if (buffer) {
18531
+ result.push(buffer);
18532
+ buffer = '';
18533
+ } else {
18534
+ // Empty buffer means we have a literal '-' key
18535
+ result.push('-');
18536
+ }
18537
+ i++;
18538
+ }
18539
+ } else {
18540
+ buffer += char;
18541
+ i++;
18542
+ }
18543
+ }
18544
+
18545
+ // Add final buffer if it exists
18546
+ if (buffer) {
18547
+ result.push(buffer);
18548
+ }
18549
+
18550
+ // Collapse runs of '-' so that every second '-' is removed
18551
+ const collapsed = [];
18552
+ let minusCount = 0;
18553
+ for (const part of result) {
18554
+ if (part === '-') {
18555
+ if (minusCount % 2 === 0) collapsed.push('-');
18556
+ minusCount++;
18557
+ } else {
18558
+ minusCount = 0;
18559
+ collapsed.push(part);
18560
+ }
18561
+ }
18562
+
18563
+ // Validate that each part of the sequence is a valid combination
18564
+ const areAllValid = collapsed.every(s => splitKeyCombination(s, true).length > 0);
18565
+ if (!areAllValid) {
18566
+ consoleWarn(`Invalid hotkey sequence: "${str}" contains invalid combinations`);
18567
+ return [];
18568
+ }
18569
+ return collapsed;
18570
+ }
18571
+
18572
+ // Composables
18573
+
18574
+ // Types
18575
+
18576
+ function useHotkey(keys, callback) {
18577
+ let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
18578
+ if (!IN_BROWSER) return function () {};
18579
+ const {
18580
+ event = 'keydown',
18581
+ inputs = false,
18582
+ preventDefault = true,
18583
+ sequenceTimeout = 1000
18584
+ } = options;
18585
+ const isMac = navigator?.userAgent?.includes('Macintosh') ?? false;
18586
+ let timeout = 0;
18587
+ let keyGroups;
18588
+ let isSequence = false;
18589
+ let groupIndex = 0;
18590
+ function clearTimer() {
18591
+ if (!timeout) return;
18592
+ clearTimeout(timeout);
18593
+ timeout = 0;
18594
+ }
18595
+ function isInputFocused() {
18596
+ if (toValue(inputs)) return false;
18597
+ const activeElement = document.activeElement;
18598
+ return activeElement && (activeElement.tagName === 'INPUT' || activeElement.tagName === 'TEXTAREA' || activeElement.isContentEditable || activeElement.contentEditable === 'true');
18599
+ }
18600
+ function resetSequence() {
18601
+ groupIndex = 0;
18602
+ clearTimer();
18603
+ }
18604
+ function handler(e) {
18605
+ const group = keyGroups[groupIndex];
18606
+ if (!group || isInputFocused()) return;
18607
+ if (!matchesKeyGroup(e, group)) {
18608
+ if (isSequence) resetSequence();
18609
+ return;
18610
+ }
18611
+ if (toValue(preventDefault)) e.preventDefault();
18612
+ if (!isSequence) {
18613
+ callback(e);
18614
+ return;
18615
+ }
18616
+ clearTimer();
18617
+ groupIndex++;
18618
+ if (groupIndex === keyGroups.length) {
18619
+ callback(e);
18620
+ resetSequence();
18621
+ return;
18622
+ }
18623
+ timeout = window.setTimeout(resetSequence, toValue(sequenceTimeout));
18624
+ }
18625
+ function cleanup() {
18626
+ window.removeEventListener(toValue(event), handler);
18627
+ clearTimer();
18628
+ }
18629
+ watch(() => toValue(keys), function (unrefKeys) {
18630
+ cleanup();
18631
+ if (unrefKeys) {
18632
+ const groups = splitKeySequence(unrefKeys.toLowerCase());
18633
+ isSequence = groups.length > 1;
18634
+ keyGroups = groups;
18635
+ resetSequence();
18636
+ window.addEventListener(toValue(event), handler);
18637
+ }
18638
+ }, {
18639
+ immediate: true
18640
+ });
18641
+
18642
+ // Watch for changes in the event type to re-register the listener
18643
+ watch(() => toValue(event), function (newEvent, oldEvent) {
18644
+ if (oldEvent && keyGroups && keyGroups.length > 0) {
18645
+ window.removeEventListener(oldEvent, handler);
18646
+ window.addEventListener(newEvent, handler);
18647
+ }
18648
+ });
18649
+ try {
18650
+ getCurrentInstance('useHotkey');
18651
+ onBeforeUnmount(cleanup);
18652
+ } catch {
18653
+ // Not in Vue setup context
18654
+ }
18655
+ function parseKeyGroup(group) {
18656
+ const MODIFIERS = ['ctrl', 'shift', 'alt', 'meta', 'cmd'];
18657
+
18658
+ // Use the shared combination splitting logic
18659
+ const parts = splitKeyCombination(group.toLowerCase());
18660
+
18661
+ // If the combination is invalid, return empty result
18662
+ if (parts.length === 0) {
18663
+ return {
18664
+ modifiers: Object.fromEntries(MODIFIERS.map(m => [m, false])),
18665
+ actualKey: undefined
18666
+ };
18667
+ }
18668
+ const modifiers = Object.fromEntries(MODIFIERS.map(m => [m, false]));
18669
+ let actualKey;
18670
+ for (const part of parts) {
18671
+ if (MODIFIERS.includes(part)) {
18672
+ modifiers[part] = true;
18673
+ } else {
18674
+ actualKey = part;
18675
+ }
18676
+ }
18677
+ return {
18678
+ modifiers,
18679
+ actualKey
18680
+ };
18681
+ }
18682
+ function matchesKeyGroup(e, group) {
18683
+ const {
18684
+ modifiers,
18685
+ actualKey
18686
+ } = parseKeyGroup(group);
18687
+ const expectCtrl = modifiers.ctrl || !isMac && (modifiers.cmd || modifiers.meta);
18688
+ const expectMeta = isMac && (modifiers.cmd || modifiers.meta);
18689
+ return e.ctrlKey === expectCtrl && e.metaKey === expectMeta && e.shiftKey === modifiers.shift && e.altKey === modifiers.alt && e.key.toLowerCase() === actualKey?.toLowerCase();
18690
+ }
18691
+ return cleanup;
18692
+ }
18693
+
18354
18694
  // Types
18355
18695
 
18356
18696
  const makeVColorPickerProps = propsFactory({
@@ -19779,7 +20119,8 @@ function sortItems(items, sortByItems, locale, options) {
19779
20119
 
19780
20120
  // Dates should be compared numerically
19781
20121
  if (sortA instanceof Date && sortB instanceof Date) {
19782
- return sortA.getTime() - sortB.getTime();
20122
+ sortA = sortA.getTime();
20123
+ sortB = sortB.getTime();
19783
20124
  }
19784
20125
  [sortA, sortB] = [sortA, sortB].map(s => s != null ? s.toString().toLocaleLowerCase() : s);
19785
20126
  if (sortA !== sortB) {
@@ -20503,7 +20844,6 @@ const VDataTableColumn = defineFunctionalComponent({
20503
20844
  } = _ref;
20504
20845
  const Tag = props.tag ?? 'td';
20505
20846
  return createVNode(Tag, {
20506
- "tabindex": "0",
20507
20847
  "class": normalizeClass(['v-data-table__td', {
20508
20848
  'v-data-table-column--fixed': props.fixed,
20509
20849
  'v-data-table-column--last-fixed': props.lastFixed,
@@ -20906,14 +21246,14 @@ const VDataTableHeaders = genericComponent()({
20906
21246
  },
20907
21247
  "colspan": column.colspan,
20908
21248
  "rowspan": column.rowspan,
20909
- "onClick": column.sortable ? () => toggleSort(column) : undefined,
20910
21249
  "fixed": column.fixed,
20911
21250
  "nowrap": column.nowrap,
20912
21251
  "lastFixed": column.lastFixed,
20913
- "noPadding": noPadding
20914
- }, headerProps, {
20915
- "onKeydown": event => column.sortable && handleEnterKeyPress(event, column)
20916
- }), {
21252
+ "noPadding": noPadding,
21253
+ "tabindex": column.sortable ? 0 : undefined,
21254
+ "onClick": column.sortable ? () => toggleSort(column) : undefined,
21255
+ "onKeydown": column.sortable ? event => handleEnterKeyPress(event, column) : undefined
21256
+ }, headerProps), {
20917
21257
  default: () => {
20918
21258
  const columnSlotName = `header.${column.key}`;
20919
21259
  const columnSlotProps = {
@@ -22599,13 +22939,9 @@ function useCalendar(props) {
22599
22939
  const date = adapter.setYear(adapter.startOfMonth(adapter.date()), adapter.getYear(year.value));
22600
22940
  return adapter.setMonth(date, value);
22601
22941
  }, v => adapter.getMonth(v));
22602
- const weekDays = computed(() => {
22603
- const firstDayOfWeek = adapter.toJsDate(adapter.startOfWeek(adapter.date(), props.firstDayOfWeek)).getDay();
22604
- return props.weekdays.map(day => (day + firstDayOfWeek) % 7);
22605
- });
22606
22942
  const weekdayLabels = computed(() => {
22607
- const labels = adapter.getWeekdays(props.firstDayOfWeek, props.weekdayFormat);
22608
- return weekDays.value.map(day => labels[day]);
22943
+ const firstDayOfWeek = adapter.toJsDate(adapter.startOfWeek(adapter.date(), props.firstDayOfWeek)).getDay();
22944
+ return adapter.getWeekdays(props.firstDayOfWeek, props.weekdayFormat).filter((_, i) => props.weekdays.includes((i + firstDayOfWeek) % 7));
22609
22945
  });
22610
22946
  const weeksInMonth = computed(() => {
22611
22947
  const weeks = adapter.getWeekArray(month.value, props.firstDayOfWeek);
@@ -22629,13 +22965,14 @@ function useCalendar(props) {
22629
22965
  });
22630
22966
  function genDays(days, today) {
22631
22967
  return days.filter(date => {
22632
- return weekDays.value.includes(adapter.toJsDate(date).getDay());
22968
+ return props.weekdays.includes(adapter.toJsDate(date).getDay());
22633
22969
  }).map((date, index) => {
22634
22970
  const isoDate = adapter.toISO(date);
22635
22971
  const isAdjacent = !adapter.isSameMonth(date, month.value);
22636
22972
  const isStart = adapter.isSameDay(date, adapter.startOfMonth(month.value));
22637
22973
  const isEnd = adapter.isSameDay(date, adapter.endOfMonth(month.value));
22638
22974
  const isSame = adapter.isSameDay(date, month.value);
22975
+ const weekdaysCount = props.weekdays.length;
22639
22976
  return {
22640
22977
  date,
22641
22978
  formatted: adapter.format(date, 'keyboardDate'),
@@ -22647,8 +22984,8 @@ function useCalendar(props) {
22647
22984
  isSelected: model.value.some(value => adapter.isSameDay(date, value)),
22648
22985
  isStart,
22649
22986
  isToday: adapter.isSameDay(date, today),
22650
- isWeekEnd: index % 7 === 6,
22651
- isWeekStart: index % 7 === 0,
22987
+ isWeekEnd: index % weekdaysCount === weekdaysCount - 1,
22988
+ isWeekStart: index % weekdaysCount === 0,
22652
22989
  isoDate,
22653
22990
  localized: adapter.format(date, 'dayOfMonth'),
22654
22991
  month: adapter.getMonth(date),
@@ -22695,7 +23032,6 @@ function useCalendar(props) {
22695
23032
  genDays,
22696
23033
  model,
22697
23034
  weeksInMonth,
22698
- weekDays,
22699
23035
  weekdayLabels,
22700
23036
  weekNumbers
22701
23037
  };
@@ -22736,7 +23072,6 @@ const VDatePickerMonth = genericComponent()({
22736
23072
  daysInMonth,
22737
23073
  model,
22738
23074
  weekNumbers,
22739
- weekDays,
22740
23075
  weekdayLabels
22741
23076
  } = useCalendar(props);
22742
23077
  const adapter = useDate();
@@ -22811,7 +23146,7 @@ const VDatePickerMonth = genericComponent()({
22811
23146
  useRender(() => createElementVNode("div", {
22812
23147
  "class": "v-date-picker-month",
22813
23148
  "style": {
22814
- '--v-date-picker-days-in-week': weekDays.value.length
23149
+ '--v-date-picker-days-in-week': props.weekdays.length
22815
23150
  }
22816
23151
  }, [props.showWeek && createElementVNode("div", {
22817
23152
  "key": "weeks",
@@ -25982,19 +26317,21 @@ const VOtpInput = genericComponent()({
25982
26317
  const contentRef = ref();
25983
26318
  const inputRef = ref([]);
25984
26319
  const current = computed(() => inputRef.value[focusIndex.value]);
25985
- const intersectScope = effectScope();
25986
- intersectScope.run(() => {
25987
- const {
25988
- intersectionRef,
25989
- isIntersecting
25990
- } = useIntersectionObserver();
25991
- watch(isIntersecting, v => {
25992
- if (!v) return;
25993
- intersectionRef.value?.focus();
25994
- intersectScope.stop();
25995
- });
25996
- watchEffect(() => {
25997
- intersectionRef.value = inputRef.value[0];
26320
+ useToggleScope(() => props.autofocus, () => {
26321
+ const intersectScope = effectScope();
26322
+ intersectScope.run(() => {
26323
+ const {
26324
+ intersectionRef,
26325
+ isIntersecting
26326
+ } = useIntersectionObserver();
26327
+ watchEffect(() => {
26328
+ intersectionRef.value = inputRef.value[0];
26329
+ });
26330
+ watch(isIntersecting, v => {
26331
+ if (!v) return;
26332
+ intersectionRef.value?.focus();
26333
+ intersectScope.stop();
26334
+ });
25998
26335
  });
25999
26336
  });
26000
26337
  function onInput() {
@@ -30893,7 +31230,7 @@ function createVuetify$1() {
30893
31230
  };
30894
31231
  });
30895
31232
  }
30896
- const version$1 = "3.9.0-beta.1-dev.2025-06-26";
31233
+ const version$1 = "3.9.0-beta.1-dev.2025-07-02";
30897
31234
  createVuetify$1.version = version$1;
30898
31235
 
30899
31236
  // Vue's inject() can only be used in setup
@@ -30918,8 +31255,8 @@ const createVuetify = function () {
30918
31255
  ...options
30919
31256
  });
30920
31257
  };
30921
- const version = "3.9.0-beta.1-dev.2025-06-26";
31258
+ const version = "3.9.0-beta.1-dev.2025-07-02";
30922
31259
  createVuetify.version = version;
30923
31260
 
30924
- export { index as blueprints, components, createVuetify, directives, useDate, useDefaults, useDisplay, useGoTo, useLayout, useLocale, useRtl, useTheme, version };
31261
+ export { index as blueprints, components, createVuetify, directives, useDate, useDefaults, useDisplay, useGoTo, useHotkey, useLayout, useLocale, useRtl, useTheme, version };
30925
31262
  //# sourceMappingURL=vuetify.esm.js.map