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

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 (205) hide show
  1. package/CHANGELOG.md +8 -3
  2. package/dist/_component-variables-labs.sass +1 -0
  3. package/dist/json/attributes.json +2183 -2123
  4. package/dist/json/importMap-labs.json +28 -24
  5. package/dist/json/importMap.json +170 -170
  6. package/dist/json/tags.json +20 -0
  7. package/dist/json/web-types.json +4186 -4020
  8. package/dist/vuetify-labs.cjs +738 -4
  9. package/dist/vuetify-labs.css +4753 -4502
  10. package/dist/vuetify-labs.d.ts +309 -63
  11. package/dist/vuetify-labs.esm.js +738 -5
  12. package/dist/vuetify-labs.esm.js.map +1 -1
  13. package/dist/vuetify-labs.js +738 -4
  14. package/dist/vuetify-labs.min.css +2 -2
  15. package/dist/vuetify.cjs +345 -4
  16. package/dist/vuetify.cjs.map +1 -1
  17. package/dist/vuetify.css +4301 -4292
  18. package/dist/vuetify.d.ts +82 -62
  19. package/dist/vuetify.esm.js +345 -5
  20. package/dist/vuetify.esm.js.map +1 -1
  21. package/dist/vuetify.js +345 -4
  22. package/dist/vuetify.js.map +1 -1
  23. package/dist/vuetify.min.css +2 -2
  24. package/dist/vuetify.min.js +284 -245
  25. package/dist/vuetify.min.js.map +1 -1
  26. package/lib/components/VKbd/VKbd.css +14 -5
  27. package/lib/components/VKbd/VKbd.js.map +1 -1
  28. package/lib/components/VKbd/VKbd.scss +26 -0
  29. package/lib/components/VKbd/_variables.scss +12 -6
  30. package/lib/components/VKbd/index.js.map +1 -1
  31. package/lib/composables/hotkey/hotkey-parsing.d.ts +15 -0
  32. package/lib/composables/hotkey/hotkey-parsing.js +154 -0
  33. package/lib/composables/hotkey/hotkey-parsing.js.map +1 -0
  34. package/lib/composables/hotkey/hotkey.d.ts +9 -0
  35. package/lib/composables/{hotkey.js → hotkey/hotkey.js} +31 -39
  36. package/lib/composables/hotkey/hotkey.js.map +1 -0
  37. package/lib/composables/hotkey/index.d.ts +1 -0
  38. package/lib/composables/hotkey/index.js +2 -0
  39. package/lib/composables/hotkey/index.js.map +1 -0
  40. package/lib/composables/hotkey/key-aliases.d.ts +14 -0
  41. package/lib/composables/hotkey/key-aliases.js +38 -0
  42. package/lib/composables/hotkey/key-aliases.js.map +1 -0
  43. package/lib/composables/icons.d.ts +11 -0
  44. package/lib/composables/icons.js.map +1 -1
  45. package/lib/composables/index.d.ts +1 -0
  46. package/lib/composables/index.js +1 -0
  47. package/lib/composables/index.js.map +1 -1
  48. package/lib/entry-bundler.js +1 -1
  49. package/lib/framework.d.ts +83 -62
  50. package/lib/framework.js +1 -1
  51. package/lib/iconsets/fa.js +12 -1
  52. package/lib/iconsets/fa.js.map +1 -1
  53. package/lib/iconsets/fa4.js +12 -1
  54. package/lib/iconsets/fa4.js.map +1 -1
  55. package/lib/iconsets/md.js +12 -1
  56. package/lib/iconsets/md.js.map +1 -1
  57. package/lib/iconsets/mdi-svg.js +12 -1
  58. package/lib/iconsets/mdi-svg.js.map +1 -1
  59. package/lib/iconsets/mdi.js +12 -1
  60. package/lib/iconsets/mdi.js.map +1 -1
  61. package/lib/labs/VHotkey/VHotkey.css +242 -0
  62. package/lib/labs/VHotkey/VHotkey.d.ts +387 -0
  63. package/lib/labs/VHotkey/VHotkey.js +432 -0
  64. package/lib/labs/VHotkey/VHotkey.js.map +1 -0
  65. package/lib/labs/VHotkey/VHotkey.scss +253 -0
  66. package/lib/labs/VHotkey/_variables.scss +43 -0
  67. package/lib/labs/VHotkey/index.d.ts +1 -0
  68. package/lib/labs/VHotkey/index.js +2 -0
  69. package/lib/labs/VHotkey/index.js.map +1 -0
  70. package/lib/labs/components.d.ts +1 -0
  71. package/lib/labs/components.js +1 -0
  72. package/lib/labs/components.js.map +1 -1
  73. package/lib/locale/af.d.ts +18 -0
  74. package/lib/locale/af.js +18 -0
  75. package/lib/locale/af.js.map +1 -1
  76. package/lib/locale/ar.d.ts +18 -0
  77. package/lib/locale/ar.js +18 -0
  78. package/lib/locale/ar.js.map +1 -1
  79. package/lib/locale/az.d.ts +18 -0
  80. package/lib/locale/az.js +18 -0
  81. package/lib/locale/az.js.map +1 -1
  82. package/lib/locale/bg.d.ts +18 -0
  83. package/lib/locale/bg.js +18 -0
  84. package/lib/locale/bg.js.map +1 -1
  85. package/lib/locale/ca.d.ts +18 -0
  86. package/lib/locale/ca.js +18 -0
  87. package/lib/locale/ca.js.map +1 -1
  88. package/lib/locale/ckb.d.ts +18 -0
  89. package/lib/locale/ckb.js +18 -0
  90. package/lib/locale/ckb.js.map +1 -1
  91. package/lib/locale/cs.d.ts +18 -0
  92. package/lib/locale/cs.js +18 -0
  93. package/lib/locale/cs.js.map +1 -1
  94. package/lib/locale/da.d.ts +18 -0
  95. package/lib/locale/da.js +18 -0
  96. package/lib/locale/da.js.map +1 -1
  97. package/lib/locale/de.d.ts +18 -0
  98. package/lib/locale/de.js +18 -0
  99. package/lib/locale/de.js.map +1 -1
  100. package/lib/locale/el.d.ts +18 -0
  101. package/lib/locale/el.js +18 -0
  102. package/lib/locale/el.js.map +1 -1
  103. package/lib/locale/en.d.ts +18 -0
  104. package/lib/locale/en.js +18 -0
  105. package/lib/locale/en.js.map +1 -1
  106. package/lib/locale/es.d.ts +18 -0
  107. package/lib/locale/es.js +18 -0
  108. package/lib/locale/es.js.map +1 -1
  109. package/lib/locale/et.d.ts +18 -0
  110. package/lib/locale/et.js +18 -0
  111. package/lib/locale/et.js.map +1 -1
  112. package/lib/locale/fa.d.ts +18 -0
  113. package/lib/locale/fa.js +18 -0
  114. package/lib/locale/fa.js.map +1 -1
  115. package/lib/locale/fi.d.ts +18 -0
  116. package/lib/locale/fi.js +18 -0
  117. package/lib/locale/fi.js.map +1 -1
  118. package/lib/locale/fr.d.ts +18 -0
  119. package/lib/locale/fr.js +18 -0
  120. package/lib/locale/fr.js.map +1 -1
  121. package/lib/locale/he.d.ts +18 -0
  122. package/lib/locale/he.js +18 -0
  123. package/lib/locale/he.js.map +1 -1
  124. package/lib/locale/hr.d.ts +18 -0
  125. package/lib/locale/hr.js +18 -0
  126. package/lib/locale/hr.js.map +1 -1
  127. package/lib/locale/hu.d.ts +18 -0
  128. package/lib/locale/hu.js +18 -0
  129. package/lib/locale/hu.js.map +1 -1
  130. package/lib/locale/id.d.ts +18 -0
  131. package/lib/locale/id.js +18 -0
  132. package/lib/locale/id.js.map +1 -1
  133. package/lib/locale/it.d.ts +18 -0
  134. package/lib/locale/it.js +18 -0
  135. package/lib/locale/it.js.map +1 -1
  136. package/lib/locale/ja.d.ts +18 -0
  137. package/lib/locale/ja.js +18 -0
  138. package/lib/locale/ja.js.map +1 -1
  139. package/lib/locale/km.d.ts +18 -0
  140. package/lib/locale/km.js +18 -0
  141. package/lib/locale/km.js.map +1 -1
  142. package/lib/locale/ko.d.ts +18 -0
  143. package/lib/locale/ko.js +18 -0
  144. package/lib/locale/ko.js.map +1 -1
  145. package/lib/locale/lt.d.ts +18 -0
  146. package/lib/locale/lt.js +18 -0
  147. package/lib/locale/lt.js.map +1 -1
  148. package/lib/locale/lv.d.ts +18 -0
  149. package/lib/locale/lv.js +18 -0
  150. package/lib/locale/lv.js.map +1 -1
  151. package/lib/locale/nl.d.ts +18 -0
  152. package/lib/locale/nl.js +18 -0
  153. package/lib/locale/nl.js.map +1 -1
  154. package/lib/locale/no.d.ts +18 -0
  155. package/lib/locale/no.js +18 -0
  156. package/lib/locale/no.js.map +1 -1
  157. package/lib/locale/pl.d.ts +18 -0
  158. package/lib/locale/pl.js +18 -0
  159. package/lib/locale/pl.js.map +1 -1
  160. package/lib/locale/pt.d.ts +18 -0
  161. package/lib/locale/pt.js +18 -0
  162. package/lib/locale/pt.js.map +1 -1
  163. package/lib/locale/ro.d.ts +18 -0
  164. package/lib/locale/ro.js +18 -0
  165. package/lib/locale/ro.js.map +1 -1
  166. package/lib/locale/ru.d.ts +18 -0
  167. package/lib/locale/ru.js +18 -0
  168. package/lib/locale/ru.js.map +1 -1
  169. package/lib/locale/sk.d.ts +18 -0
  170. package/lib/locale/sk.js +18 -0
  171. package/lib/locale/sk.js.map +1 -1
  172. package/lib/locale/sl.d.ts +18 -0
  173. package/lib/locale/sl.js +18 -0
  174. package/lib/locale/sl.js.map +1 -1
  175. package/lib/locale/sr-Cyrl.d.ts +18 -0
  176. package/lib/locale/sr-Cyrl.js +18 -0
  177. package/lib/locale/sr-Cyrl.js.map +1 -1
  178. package/lib/locale/sr-Latn.d.ts +18 -0
  179. package/lib/locale/sr-Latn.js +18 -0
  180. package/lib/locale/sr-Latn.js.map +1 -1
  181. package/lib/locale/sv.d.ts +18 -0
  182. package/lib/locale/sv.js +18 -0
  183. package/lib/locale/sv.js.map +1 -1
  184. package/lib/locale/th.d.ts +18 -0
  185. package/lib/locale/th.js +18 -0
  186. package/lib/locale/th.js.map +1 -1
  187. package/lib/locale/tr.d.ts +18 -0
  188. package/lib/locale/tr.js +18 -0
  189. package/lib/locale/tr.js.map +1 -1
  190. package/lib/locale/uk.d.ts +18 -0
  191. package/lib/locale/uk.js +18 -0
  192. package/lib/locale/uk.js.map +1 -1
  193. package/lib/locale/vi.d.ts +18 -0
  194. package/lib/locale/vi.js +18 -0
  195. package/lib/locale/vi.js.map +1 -1
  196. package/lib/locale/zh-Hans.d.ts +18 -0
  197. package/lib/locale/zh-Hans.js +18 -0
  198. package/lib/locale/zh-Hans.js.map +1 -1
  199. package/lib/locale/zh-Hant.d.ts +18 -0
  200. package/lib/locale/zh-Hant.js +18 -0
  201. package/lib/locale/zh-Hant.js.map +1 -1
  202. package/package.json +1 -1
  203. package/lib/components/VKbd/VKbd.sass +0 -15
  204. package/lib/composables/hotkey.d.ts +0 -9
  205. 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-06-28
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
 
@@ -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({
@@ -30897,7 +31237,7 @@
30897
31237
  };
30898
31238
  });
30899
31239
  }
30900
- const version$1 = "3.9.0-beta.1-dev.2025-06-26";
31240
+ const version$1 = "3.9.0-beta.1-dev.2025-06-28";
30901
31241
  createVuetify$1.version = version$1;
30902
31242
 
30903
31243
  // Vue's inject() can only be used in setup
@@ -30922,7 +31262,7 @@
30922
31262
  ...options
30923
31263
  });
30924
31264
  };
30925
- const version = "3.9.0-beta.1-dev.2025-06-26";
31265
+ const version = "3.9.0-beta.1-dev.2025-06-28";
30926
31266
  createVuetify.version = version;
30927
31267
 
30928
31268
  exports.blueprints = index;
@@ -30933,6 +31273,7 @@
30933
31273
  exports.useDefaults = useDefaults;
30934
31274
  exports.useDisplay = useDisplay;
30935
31275
  exports.useGoTo = useGoTo;
31276
+ exports.useHotkey = useHotkey;
30936
31277
  exports.useLayout = useLayout;
30937
31278
  exports.useLocale = useLocale;
30938
31279
  exports.useRtl = useRtl;