@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
package/dist/vuetify.js CHANGED
@@ -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
  */
@@ -1836,7 +1836,18 @@
1836
1836
  treeviewExpand: 'mdi-menu-right',
1837
1837
  eyeDropper: 'mdi-eyedropper',
1838
1838
  upload: 'mdi-cloud-upload',
1839
- color: 'mdi-palette'
1839
+ color: 'mdi-palette',
1840
+ command: 'mdi-apple-keyboard-command',
1841
+ ctrl: 'mdi-apple-keyboard-control',
1842
+ space: 'mdi-keyboard-space',
1843
+ shift: 'mdi-apple-keyboard-shift',
1844
+ alt: 'mdi-apple-keyboard-option',
1845
+ enter: 'mdi-keyboard-return',
1846
+ arrowup: 'mdi-arrow-up',
1847
+ arrowdown: 'mdi-arrow-down',
1848
+ arrowleft: 'mdi-arrow-left',
1849
+ arrowright: 'mdi-arrow-right',
1850
+ backspace: 'mdi-backspace'
1840
1851
  };
1841
1852
  const mdi = {
1842
1853
  // Not using mergeProps here, functional components merge props by default (?)
@@ -2632,6 +2643,24 @@
2632
2643
  exclude: 'The {0} character is not allowed',
2633
2644
  notEmpty: 'Please choose at least one value',
2634
2645
  pattern: 'Invalid format'
2646
+ },
2647
+ hotkey: {
2648
+ then: 'then',
2649
+ ctrl: 'Ctrl',
2650
+ command: 'Command',
2651
+ space: 'Space',
2652
+ shift: 'Shift',
2653
+ alt: 'Alt',
2654
+ enter: 'Enter',
2655
+ escape: 'Escape',
2656
+ upArrow: 'Up Arrow',
2657
+ downArrow: 'Down Arrow',
2658
+ leftArrow: 'Left Arrow',
2659
+ rightArrow: 'Right Arrow',
2660
+ backspace: 'Backspace',
2661
+ option: 'Option',
2662
+ plus: 'plus',
2663
+ shortcut: 'Keyboard shortcut: {0}'
2635
2664
  }
2636
2665
  };
2637
2666
 
@@ -10705,7 +10734,7 @@
10705
10734
  });
10706
10735
  if (flipped.isFull) {
10707
10736
  const values = flipped.values();
10708
- if (deepEqual(values.at(-1), values.at(-3))) {
10737
+ if (deepEqual(values.at(-1), values.at(-3)) && !deepEqual(values.at(-1), values.at(-2))) {
10709
10738
  // Flipping is causing a container resize loop
10710
10739
  return;
10711
10740
  }
@@ -12555,7 +12584,7 @@
12555
12584
  if (!isFocused.value) focus();
12556
12585
  vue.nextTick(() => {
12557
12586
  if (inputRef.value !== document.activeElement) {
12558
- inputRef.value?.focus();
12587
+ vue.nextTick(() => inputRef.value?.focus());
12559
12588
  }
12560
12589
  });
12561
12590
  }
@@ -12894,7 +12923,7 @@
12894
12923
  raf = requestAnimationFrame(_calculateVisibleItems);
12895
12924
  }
12896
12925
  function _calculateVisibleItems() {
12897
- if (!containerRef.value || !viewportHeight.value) return;
12926
+ if (!containerRef.value || !viewportHeight.value || !itemHeight.value) return;
12898
12927
  const scrollTop = lastScrollTop - markerOffset;
12899
12928
  const direction = Math.sign(scrollVelocity);
12900
12929
  const startPx = Math.max(0, scrollTop - BUFFER_PX);
@@ -17777,7 +17806,7 @@
17777
17806
  case 'fullDate':
17778
17807
  options = {
17779
17808
  year: 'numeric',
17780
- month: 'long',
17809
+ month: 'short',
17781
17810
  day: 'numeric'
17782
17811
  };
17783
17812
  break;
@@ -18355,6 +18384,317 @@
18355
18384
  return createInstance(options, locale);
18356
18385
  }
18357
18386
 
18387
+ /**
18388
+ * Centralized key alias mapping for consistent key normalization across the hotkey system.
18389
+ *
18390
+ * This maps various user-friendly aliases to canonical key names that match
18391
+ * KeyboardEvent.key values (in lowercase) where possible.
18392
+ */
18393
+ const keyAliasMap = {
18394
+ // Modifier aliases (from vue-use, other libraries, and current implementation)
18395
+ control: 'ctrl',
18396
+ command: 'cmd',
18397
+ option: 'alt',
18398
+ // Arrow key aliases (common abbreviations)
18399
+ up: 'arrowup',
18400
+ down: 'arrowdown',
18401
+ left: 'arrowleft',
18402
+ right: 'arrowright',
18403
+ // Other common key aliases
18404
+ esc: 'escape',
18405
+ spacebar: ' ',
18406
+ space: ' ',
18407
+ return: 'enter',
18408
+ del: 'delete',
18409
+ // Symbol aliases (existing from hotkey-parsing.ts)
18410
+ minus: '-',
18411
+ hyphen: '-'
18412
+ };
18413
+
18414
+ /**
18415
+ * Normalizes a key string to its canonical form using the alias map.
18416
+ *
18417
+ * @param key - The key string to normalize
18418
+ * @returns The canonical key name in lowercase
18419
+ */
18420
+ function normalizeKey(key) {
18421
+ const lowerKey = key.toLowerCase();
18422
+ return keyAliasMap[lowerKey] || lowerKey;
18423
+ }
18424
+
18425
+ // Utilities
18426
+
18427
+ /**
18428
+ * Splits a single combination string into individual key parts.
18429
+ *
18430
+ * A combination is a set of keys that must be pressed simultaneously.
18431
+ * e.g. `ctrl+k`, `shift--`
18432
+ */
18433
+ function splitKeyCombination(combination) {
18434
+ let isInternal = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
18435
+ if (!combination) {
18436
+ if (!isInternal) consoleWarn('Invalid hotkey combination: empty string provided');
18437
+ return [];
18438
+ }
18439
+
18440
+ // --- VALIDATION ---
18441
+ const startsWithPlusOrUnderscore = combination.startsWith('+') || combination.startsWith('_');
18442
+ const hasInvalidLeadingSeparator =
18443
+ // Starts with a single '+' or '_' followed by a non-separator character (e.g. '+a', '_a')
18444
+ startsWithPlusOrUnderscore && !(combination.startsWith('++') || combination.startsWith('__'));
18445
+ const hasInvalidStructure =
18446
+ // Invalid leading separator patterns
18447
+ combination.length > 1 && hasInvalidLeadingSeparator ||
18448
+ // Disallow literal + or _ keys (they require shift)
18449
+ combination.includes('++') || combination.includes('__') || combination === '+' || combination === '_' ||
18450
+ // Ends with a separator that is not part of a doubled literal
18451
+ combination.length > 1 && (combination.endsWith('+') || combination.endsWith('_')) && combination.at(-2) !== combination.at(-1) ||
18452
+ // Stand-alone doubled separators (dangling)
18453
+ combination === '++' || combination === '--' || combination === '__';
18454
+ if (hasInvalidStructure) {
18455
+ if (!isInternal) consoleWarn(`Invalid hotkey combination: "${combination}" has invalid structure`);
18456
+ return [];
18457
+ }
18458
+ const keys = [];
18459
+ let buffer = '';
18460
+ const flushBuffer = () => {
18461
+ if (buffer) {
18462
+ keys.push(normalizeKey(buffer));
18463
+ buffer = '';
18464
+ }
18465
+ };
18466
+ for (let i = 0; i < combination.length; i++) {
18467
+ const char = combination[i];
18468
+ const nextChar = combination[i + 1];
18469
+ if (char === '+' || char === '_' || char === '-') {
18470
+ if (char === nextChar) {
18471
+ flushBuffer();
18472
+ keys.push(char);
18473
+ i++;
18474
+ } else if (char === '+' || char === '_') {
18475
+ flushBuffer();
18476
+ } else {
18477
+ buffer += char;
18478
+ }
18479
+ } else {
18480
+ buffer += char;
18481
+ }
18482
+ }
18483
+ flushBuffer();
18484
+
18485
+ // Within a combination, `-` is only valid as a literal key (e.g., `ctrl+-`).
18486
+ // `-` cannot be part of a longer key name within a combination.
18487
+ const hasInvalidMinus = keys.some(key => key.length > 1 && key.includes('-') && key !== '--');
18488
+ if (hasInvalidMinus) {
18489
+ if (!isInternal) consoleWarn(`Invalid hotkey combination: "${combination}" has invalid structure`);
18490
+ return [];
18491
+ }
18492
+ if (keys.length === 0 && combination) {
18493
+ return [normalizeKey(combination)];
18494
+ }
18495
+ return keys;
18496
+ }
18497
+
18498
+ /**
18499
+ * Splits a hotkey string into its constituent combination groups.
18500
+ *
18501
+ * A sequence is a series of combinations that must be pressed in order.
18502
+ * e.g. `a-b`, `ctrl+k-p`
18503
+ */
18504
+ function splitKeySequence(str) {
18505
+ if (!str) {
18506
+ consoleWarn('Invalid hotkey sequence: empty string provided');
18507
+ return [];
18508
+ }
18509
+
18510
+ // A sequence is invalid if it starts or ends with a separator,
18511
+ // unless it is part of a combination (e.g., `shift+-`).
18512
+ const hasInvalidStart = str.startsWith('-') && !['---', '--+'].includes(str);
18513
+ const hasInvalidEnd = str.endsWith('-') && !str.endsWith('+-') && !str.endsWith('_-') && str !== '-' && str !== '---';
18514
+ if (hasInvalidStart || hasInvalidEnd) {
18515
+ consoleWarn(`Invalid hotkey sequence: "${str}" contains invalid combinations`);
18516
+ return [];
18517
+ }
18518
+ const result = [];
18519
+ let buffer = '';
18520
+ let i = 0;
18521
+ while (i < str.length) {
18522
+ const char = str[i];
18523
+ if (char === '-') {
18524
+ // Determine if this hyphen is part of the current combination
18525
+ const prevChar = str[i - 1];
18526
+ const prevPrevChar = i > 1 ? str[i - 2] : undefined;
18527
+ const precededBySinglePlusOrUnderscore = (prevChar === '+' || prevChar === '_') && prevPrevChar !== '+';
18528
+ if (precededBySinglePlusOrUnderscore) {
18529
+ // Treat as part of the combination (e.g., 'ctrl+-')
18530
+ buffer += char;
18531
+ i++;
18532
+ } else {
18533
+ // Treat as sequence separator
18534
+ if (buffer) {
18535
+ result.push(buffer);
18536
+ buffer = '';
18537
+ } else {
18538
+ // Empty buffer means we have a literal '-' key
18539
+ result.push('-');
18540
+ }
18541
+ i++;
18542
+ }
18543
+ } else {
18544
+ buffer += char;
18545
+ i++;
18546
+ }
18547
+ }
18548
+
18549
+ // Add final buffer if it exists
18550
+ if (buffer) {
18551
+ result.push(buffer);
18552
+ }
18553
+
18554
+ // Collapse runs of '-' so that every second '-' is removed
18555
+ const collapsed = [];
18556
+ let minusCount = 0;
18557
+ for (const part of result) {
18558
+ if (part === '-') {
18559
+ if (minusCount % 2 === 0) collapsed.push('-');
18560
+ minusCount++;
18561
+ } else {
18562
+ minusCount = 0;
18563
+ collapsed.push(part);
18564
+ }
18565
+ }
18566
+
18567
+ // Validate that each part of the sequence is a valid combination
18568
+ const areAllValid = collapsed.every(s => splitKeyCombination(s, true).length > 0);
18569
+ if (!areAllValid) {
18570
+ consoleWarn(`Invalid hotkey sequence: "${str}" contains invalid combinations`);
18571
+ return [];
18572
+ }
18573
+ return collapsed;
18574
+ }
18575
+
18576
+ // Composables
18577
+
18578
+ // Types
18579
+
18580
+ function useHotkey(keys, callback) {
18581
+ let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
18582
+ if (!IN_BROWSER) return function () {};
18583
+ const {
18584
+ event = 'keydown',
18585
+ inputs = false,
18586
+ preventDefault = true,
18587
+ sequenceTimeout = 1000
18588
+ } = options;
18589
+ const isMac = navigator?.userAgent?.includes('Macintosh') ?? false;
18590
+ let timeout = 0;
18591
+ let keyGroups;
18592
+ let isSequence = false;
18593
+ let groupIndex = 0;
18594
+ function clearTimer() {
18595
+ if (!timeout) return;
18596
+ clearTimeout(timeout);
18597
+ timeout = 0;
18598
+ }
18599
+ function isInputFocused() {
18600
+ if (vue.toValue(inputs)) return false;
18601
+ const activeElement = document.activeElement;
18602
+ return activeElement && (activeElement.tagName === 'INPUT' || activeElement.tagName === 'TEXTAREA' || activeElement.isContentEditable || activeElement.contentEditable === 'true');
18603
+ }
18604
+ function resetSequence() {
18605
+ groupIndex = 0;
18606
+ clearTimer();
18607
+ }
18608
+ function handler(e) {
18609
+ const group = keyGroups[groupIndex];
18610
+ if (!group || isInputFocused()) return;
18611
+ if (!matchesKeyGroup(e, group)) {
18612
+ if (isSequence) resetSequence();
18613
+ return;
18614
+ }
18615
+ if (vue.toValue(preventDefault)) e.preventDefault();
18616
+ if (!isSequence) {
18617
+ callback(e);
18618
+ return;
18619
+ }
18620
+ clearTimer();
18621
+ groupIndex++;
18622
+ if (groupIndex === keyGroups.length) {
18623
+ callback(e);
18624
+ resetSequence();
18625
+ return;
18626
+ }
18627
+ timeout = window.setTimeout(resetSequence, vue.toValue(sequenceTimeout));
18628
+ }
18629
+ function cleanup() {
18630
+ window.removeEventListener(vue.toValue(event), handler);
18631
+ clearTimer();
18632
+ }
18633
+ vue.watch(() => vue.toValue(keys), function (unrefKeys) {
18634
+ cleanup();
18635
+ if (unrefKeys) {
18636
+ const groups = splitKeySequence(unrefKeys.toLowerCase());
18637
+ isSequence = groups.length > 1;
18638
+ keyGroups = groups;
18639
+ resetSequence();
18640
+ window.addEventListener(vue.toValue(event), handler);
18641
+ }
18642
+ }, {
18643
+ immediate: true
18644
+ });
18645
+
18646
+ // Watch for changes in the event type to re-register the listener
18647
+ vue.watch(() => vue.toValue(event), function (newEvent, oldEvent) {
18648
+ if (oldEvent && keyGroups && keyGroups.length > 0) {
18649
+ window.removeEventListener(oldEvent, handler);
18650
+ window.addEventListener(newEvent, handler);
18651
+ }
18652
+ });
18653
+ try {
18654
+ getCurrentInstance('useHotkey');
18655
+ vue.onBeforeUnmount(cleanup);
18656
+ } catch {
18657
+ // Not in Vue setup context
18658
+ }
18659
+ function parseKeyGroup(group) {
18660
+ const MODIFIERS = ['ctrl', 'shift', 'alt', 'meta', 'cmd'];
18661
+
18662
+ // Use the shared combination splitting logic
18663
+ const parts = splitKeyCombination(group.toLowerCase());
18664
+
18665
+ // If the combination is invalid, return empty result
18666
+ if (parts.length === 0) {
18667
+ return {
18668
+ modifiers: Object.fromEntries(MODIFIERS.map(m => [m, false])),
18669
+ actualKey: undefined
18670
+ };
18671
+ }
18672
+ const modifiers = Object.fromEntries(MODIFIERS.map(m => [m, false]));
18673
+ let actualKey;
18674
+ for (const part of parts) {
18675
+ if (MODIFIERS.includes(part)) {
18676
+ modifiers[part] = true;
18677
+ } else {
18678
+ actualKey = part;
18679
+ }
18680
+ }
18681
+ return {
18682
+ modifiers,
18683
+ actualKey
18684
+ };
18685
+ }
18686
+ function matchesKeyGroup(e, group) {
18687
+ const {
18688
+ modifiers,
18689
+ actualKey
18690
+ } = parseKeyGroup(group);
18691
+ const expectCtrl = modifiers.ctrl || !isMac && (modifiers.cmd || modifiers.meta);
18692
+ const expectMeta = isMac && (modifiers.cmd || modifiers.meta);
18693
+ return e.ctrlKey === expectCtrl && e.metaKey === expectMeta && e.shiftKey === modifiers.shift && e.altKey === modifiers.alt && e.key.toLowerCase() === actualKey?.toLowerCase();
18694
+ }
18695
+ return cleanup;
18696
+ }
18697
+
18358
18698
  // Types
18359
18699
 
18360
18700
  const makeVColorPickerProps = propsFactory({
@@ -19783,7 +20123,8 @@
19783
20123
 
19784
20124
  // Dates should be compared numerically
19785
20125
  if (sortA instanceof Date && sortB instanceof Date) {
19786
- return sortA.getTime() - sortB.getTime();
20126
+ sortA = sortA.getTime();
20127
+ sortB = sortB.getTime();
19787
20128
  }
19788
20129
  [sortA, sortB] = [sortA, sortB].map(s => s != null ? s.toString().toLocaleLowerCase() : s);
19789
20130
  if (sortA !== sortB) {
@@ -20507,7 +20848,6 @@
20507
20848
  } = _ref;
20508
20849
  const Tag = props.tag ?? 'td';
20509
20850
  return vue.createVNode(Tag, {
20510
- "tabindex": "0",
20511
20851
  "class": vue.normalizeClass(['v-data-table__td', {
20512
20852
  'v-data-table-column--fixed': props.fixed,
20513
20853
  'v-data-table-column--last-fixed': props.lastFixed,
@@ -20910,14 +21250,14 @@
20910
21250
  },
20911
21251
  "colspan": column.colspan,
20912
21252
  "rowspan": column.rowspan,
20913
- "onClick": column.sortable ? () => toggleSort(column) : undefined,
20914
21253
  "fixed": column.fixed,
20915
21254
  "nowrap": column.nowrap,
20916
21255
  "lastFixed": column.lastFixed,
20917
- "noPadding": noPadding
20918
- }, headerProps, {
20919
- "onKeydown": event => column.sortable && handleEnterKeyPress(event, column)
20920
- }), {
21256
+ "noPadding": noPadding,
21257
+ "tabindex": column.sortable ? 0 : undefined,
21258
+ "onClick": column.sortable ? () => toggleSort(column) : undefined,
21259
+ "onKeydown": column.sortable ? event => handleEnterKeyPress(event, column) : undefined
21260
+ }, headerProps), {
20921
21261
  default: () => {
20922
21262
  const columnSlotName = `header.${column.key}`;
20923
21263
  const columnSlotProps = {
@@ -22603,13 +22943,9 @@
22603
22943
  const date = adapter.setYear(adapter.startOfMonth(adapter.date()), adapter.getYear(year.value));
22604
22944
  return adapter.setMonth(date, value);
22605
22945
  }, v => adapter.getMonth(v));
22606
- const weekDays = vue.computed(() => {
22607
- const firstDayOfWeek = adapter.toJsDate(adapter.startOfWeek(adapter.date(), props.firstDayOfWeek)).getDay();
22608
- return props.weekdays.map(day => (day + firstDayOfWeek) % 7);
22609
- });
22610
22946
  const weekdayLabels = vue.computed(() => {
22611
- const labels = adapter.getWeekdays(props.firstDayOfWeek, props.weekdayFormat);
22612
- return weekDays.value.map(day => labels[day]);
22947
+ const firstDayOfWeek = adapter.toJsDate(adapter.startOfWeek(adapter.date(), props.firstDayOfWeek)).getDay();
22948
+ return adapter.getWeekdays(props.firstDayOfWeek, props.weekdayFormat).filter((_, i) => props.weekdays.includes((i + firstDayOfWeek) % 7));
22613
22949
  });
22614
22950
  const weeksInMonth = vue.computed(() => {
22615
22951
  const weeks = adapter.getWeekArray(month.value, props.firstDayOfWeek);
@@ -22633,13 +22969,14 @@
22633
22969
  });
22634
22970
  function genDays(days, today) {
22635
22971
  return days.filter(date => {
22636
- return weekDays.value.includes(adapter.toJsDate(date).getDay());
22972
+ return props.weekdays.includes(adapter.toJsDate(date).getDay());
22637
22973
  }).map((date, index) => {
22638
22974
  const isoDate = adapter.toISO(date);
22639
22975
  const isAdjacent = !adapter.isSameMonth(date, month.value);
22640
22976
  const isStart = adapter.isSameDay(date, adapter.startOfMonth(month.value));
22641
22977
  const isEnd = adapter.isSameDay(date, adapter.endOfMonth(month.value));
22642
22978
  const isSame = adapter.isSameDay(date, month.value);
22979
+ const weekdaysCount = props.weekdays.length;
22643
22980
  return {
22644
22981
  date,
22645
22982
  formatted: adapter.format(date, 'keyboardDate'),
@@ -22651,8 +22988,8 @@
22651
22988
  isSelected: model.value.some(value => adapter.isSameDay(date, value)),
22652
22989
  isStart,
22653
22990
  isToday: adapter.isSameDay(date, today),
22654
- isWeekEnd: index % 7 === 6,
22655
- isWeekStart: index % 7 === 0,
22991
+ isWeekEnd: index % weekdaysCount === weekdaysCount - 1,
22992
+ isWeekStart: index % weekdaysCount === 0,
22656
22993
  isoDate,
22657
22994
  localized: adapter.format(date, 'dayOfMonth'),
22658
22995
  month: adapter.getMonth(date),
@@ -22699,7 +23036,6 @@
22699
23036
  genDays,
22700
23037
  model,
22701
23038
  weeksInMonth,
22702
- weekDays,
22703
23039
  weekdayLabels,
22704
23040
  weekNumbers
22705
23041
  };
@@ -22740,7 +23076,6 @@
22740
23076
  daysInMonth,
22741
23077
  model,
22742
23078
  weekNumbers,
22743
- weekDays,
22744
23079
  weekdayLabels
22745
23080
  } = useCalendar(props);
22746
23081
  const adapter = useDate();
@@ -22815,7 +23150,7 @@
22815
23150
  useRender(() => vue.createElementVNode("div", {
22816
23151
  "class": "v-date-picker-month",
22817
23152
  "style": {
22818
- '--v-date-picker-days-in-week': weekDays.value.length
23153
+ '--v-date-picker-days-in-week': props.weekdays.length
22819
23154
  }
22820
23155
  }, [props.showWeek && vue.createElementVNode("div", {
22821
23156
  "key": "weeks",
@@ -25986,19 +26321,21 @@
25986
26321
  const contentRef = vue.ref();
25987
26322
  const inputRef = vue.ref([]);
25988
26323
  const current = vue.computed(() => inputRef.value[focusIndex.value]);
25989
- const intersectScope = vue.effectScope();
25990
- intersectScope.run(() => {
25991
- const {
25992
- intersectionRef,
25993
- isIntersecting
25994
- } = useIntersectionObserver();
25995
- vue.watch(isIntersecting, v => {
25996
- if (!v) return;
25997
- intersectionRef.value?.focus();
25998
- intersectScope.stop();
25999
- });
26000
- vue.watchEffect(() => {
26001
- intersectionRef.value = inputRef.value[0];
26324
+ useToggleScope(() => props.autofocus, () => {
26325
+ const intersectScope = vue.effectScope();
26326
+ intersectScope.run(() => {
26327
+ const {
26328
+ intersectionRef,
26329
+ isIntersecting
26330
+ } = useIntersectionObserver();
26331
+ vue.watchEffect(() => {
26332
+ intersectionRef.value = inputRef.value[0];
26333
+ });
26334
+ vue.watch(isIntersecting, v => {
26335
+ if (!v) return;
26336
+ intersectionRef.value?.focus();
26337
+ intersectScope.stop();
26338
+ });
26002
26339
  });
26003
26340
  });
26004
26341
  function onInput() {
@@ -30897,7 +31234,7 @@
30897
31234
  };
30898
31235
  });
30899
31236
  }
30900
- const version$1 = "3.9.0-beta.1-dev.2025-06-26";
31237
+ const version$1 = "3.9.0-beta.1-dev.2025-07-02";
30901
31238
  createVuetify$1.version = version$1;
30902
31239
 
30903
31240
  // Vue's inject() can only be used in setup
@@ -30922,7 +31259,7 @@
30922
31259
  ...options
30923
31260
  });
30924
31261
  };
30925
- const version = "3.9.0-beta.1-dev.2025-06-26";
31262
+ const version = "3.9.0-beta.1-dev.2025-07-02";
30926
31263
  createVuetify.version = version;
30927
31264
 
30928
31265
  exports.blueprints = index;
@@ -30933,6 +31270,7 @@
30933
31270
  exports.useDefaults = useDefaults;
30934
31271
  exports.useDisplay = useDisplay;
30935
31272
  exports.useGoTo = useGoTo;
31273
+ exports.useHotkey = useHotkey;
30936
31274
  exports.useLayout = useLayout;
30937
31275
  exports.useLocale = useLocale;
30938
31276
  exports.useRtl = useRtl;