@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.
- package/CHANGELOG.md +105 -3
- package/dist/_component-variables-labs.sass +1 -0
- package/dist/json/attributes.json +2814 -2754
- package/dist/json/importMap-labs.json +16 -12
- package/dist/json/importMap.json +174 -174
- package/dist/json/tags.json +20 -0
- package/dist/json/web-types.json +5362 -5196
- package/dist/vuetify-labs.cjs +796 -64
- package/dist/vuetify-labs.css +3440 -3189
- package/dist/vuetify-labs.d.ts +452 -206
- package/dist/vuetify-labs.esm.js +796 -65
- package/dist/vuetify-labs.esm.js.map +1 -1
- package/dist/vuetify-labs.js +796 -64
- package/dist/vuetify-labs.min.css +2 -2
- package/dist/vuetify.cjs +378 -40
- package/dist/vuetify.cjs.map +1 -1
- package/dist/vuetify.css +3377 -3368
- package/dist/vuetify.d.ts +82 -62
- package/dist/vuetify.esm.js +378 -41
- package/dist/vuetify.esm.js.map +1 -1
- package/dist/vuetify.js +378 -40
- package/dist/vuetify.js.map +1 -1
- package/dist/vuetify.min.css +2 -2
- package/dist/vuetify.min.js +312 -274
- package/dist/vuetify.min.js.map +1 -1
- package/lib/components/VDataTable/VDataTableColumn.js +0 -1
- package/lib/components/VDataTable/VDataTableColumn.js.map +1 -1
- package/lib/components/VDataTable/VDataTableHeaders.js +5 -5
- package/lib/components/VDataTable/VDataTableHeaders.js.map +1 -1
- package/lib/components/VDataTable/composables/sort.js +2 -1
- package/lib/components/VDataTable/composables/sort.js.map +1 -1
- package/lib/components/VDatePicker/VDatePickerMonth.js +1 -2
- package/lib/components/VDatePicker/VDatePickerMonth.js.map +1 -1
- package/lib/components/VKbd/VKbd.css +14 -5
- package/lib/components/VKbd/VKbd.js.map +1 -1
- package/lib/components/VKbd/VKbd.scss +26 -0
- package/lib/components/VKbd/_variables.scss +12 -6
- package/lib/components/VKbd/index.js.map +1 -1
- package/lib/components/VOtpInput/VOtpInput.js +17 -14
- package/lib/components/VOtpInput/VOtpInput.js.map +1 -1
- package/lib/components/VOverlay/locationStrategies.js +1 -1
- package/lib/components/VOverlay/locationStrategies.js.map +1 -1
- package/lib/components/VTextField/VTextField.js +1 -1
- package/lib/components/VTextField/VTextField.js.map +1 -1
- package/lib/composables/calendar.d.ts +0 -1
- package/lib/composables/calendar.js +6 -10
- package/lib/composables/calendar.js.map +1 -1
- package/lib/composables/date/adapters/vuetify.js +1 -1
- package/lib/composables/date/adapters/vuetify.js.map +1 -1
- package/lib/composables/hotkey/hotkey-parsing.d.ts +15 -0
- package/lib/composables/hotkey/hotkey-parsing.js +154 -0
- package/lib/composables/hotkey/hotkey-parsing.js.map +1 -0
- package/lib/composables/hotkey/hotkey.d.ts +9 -0
- package/lib/composables/{hotkey.js → hotkey/hotkey.js} +31 -39
- package/lib/composables/hotkey/hotkey.js.map +1 -0
- package/lib/composables/hotkey/index.d.ts +1 -0
- package/lib/composables/hotkey/index.js +2 -0
- package/lib/composables/hotkey/index.js.map +1 -0
- package/lib/composables/hotkey/key-aliases.d.ts +14 -0
- package/lib/composables/hotkey/key-aliases.js +38 -0
- package/lib/composables/hotkey/key-aliases.js.map +1 -0
- package/lib/composables/icons.d.ts +11 -0
- package/lib/composables/icons.js.map +1 -1
- package/lib/composables/index.d.ts +1 -0
- package/lib/composables/index.js +1 -0
- package/lib/composables/index.js.map +1 -1
- package/lib/composables/virtual.js +1 -1
- package/lib/composables/virtual.js.map +1 -1
- package/lib/entry-bundler.js +1 -1
- package/lib/framework.d.ts +83 -62
- package/lib/framework.js +1 -1
- package/lib/iconsets/fa.js +12 -1
- package/lib/iconsets/fa.js.map +1 -1
- package/lib/iconsets/fa4.js +12 -1
- package/lib/iconsets/fa4.js.map +1 -1
- package/lib/iconsets/md.js +12 -1
- package/lib/iconsets/md.js.map +1 -1
- package/lib/iconsets/mdi-svg.js +12 -1
- package/lib/iconsets/mdi-svg.js.map +1 -1
- package/lib/iconsets/mdi.js +12 -1
- package/lib/iconsets/mdi.js.map +1 -1
- package/lib/labs/VCalendar/VCalendar.d.ts +33 -33
- package/lib/labs/VCalendar/VCalendar.js +9 -9
- package/lib/labs/VCalendar/VCalendar.js.map +1 -1
- package/lib/labs/VCalendar/VCalendarDay.d.ts +33 -33
- package/lib/labs/VCalendar/VCalendarDay.js +1 -1
- package/lib/labs/VCalendar/VCalendarDay.js.map +1 -1
- package/lib/labs/VCalendar/VCalendarInterval.d.ts +36 -36
- package/lib/labs/VCalendar/VCalendarInterval.js +9 -9
- package/lib/labs/VCalendar/VCalendarInterval.js.map +1 -1
- package/lib/labs/VCalendar/VCalendarIntervalEvent.d.ts +12 -12
- package/lib/labs/VCalendar/VCalendarIntervalEvent.js +1 -1
- package/lib/labs/VCalendar/VCalendarIntervalEvent.js.map +1 -1
- package/lib/labs/VCalendar/VCalendarMonthDay.d.ts +36 -36
- package/lib/labs/VCalendar/VCalendarMonthDay.js +4 -4
- package/lib/labs/VCalendar/VCalendarMonthDay.js.map +1 -1
- package/lib/labs/VHotkey/VHotkey.css +242 -0
- package/lib/labs/VHotkey/VHotkey.d.ts +387 -0
- package/lib/labs/VHotkey/VHotkey.js +432 -0
- package/lib/labs/VHotkey/VHotkey.js.map +1 -0
- package/lib/labs/VHotkey/VHotkey.scss +253 -0
- package/lib/labs/VHotkey/_variables.scss +43 -0
- package/lib/labs/VHotkey/index.d.ts +1 -0
- package/lib/labs/VHotkey/index.js +2 -0
- package/lib/labs/VHotkey/index.js.map +1 -0
- package/lib/labs/VIconBtn/VIconBtn.js +1 -0
- package/lib/labs/VIconBtn/VIconBtn.js.map +1 -1
- package/lib/labs/components.d.ts +1 -0
- package/lib/labs/components.js +1 -0
- package/lib/labs/components.js.map +1 -1
- package/lib/locale/af.d.ts +18 -0
- package/lib/locale/af.js +18 -0
- package/lib/locale/af.js.map +1 -1
- package/lib/locale/ar.d.ts +18 -0
- package/lib/locale/ar.js +18 -0
- package/lib/locale/ar.js.map +1 -1
- package/lib/locale/az.d.ts +18 -0
- package/lib/locale/az.js +18 -0
- package/lib/locale/az.js.map +1 -1
- package/lib/locale/bg.d.ts +18 -0
- package/lib/locale/bg.js +18 -0
- package/lib/locale/bg.js.map +1 -1
- package/lib/locale/ca.d.ts +18 -0
- package/lib/locale/ca.js +18 -0
- package/lib/locale/ca.js.map +1 -1
- package/lib/locale/ckb.d.ts +18 -0
- package/lib/locale/ckb.js +18 -0
- package/lib/locale/ckb.js.map +1 -1
- package/lib/locale/cs.d.ts +18 -0
- package/lib/locale/cs.js +18 -0
- package/lib/locale/cs.js.map +1 -1
- package/lib/locale/da.d.ts +18 -0
- package/lib/locale/da.js +18 -0
- package/lib/locale/da.js.map +1 -1
- package/lib/locale/de.d.ts +18 -0
- package/lib/locale/de.js +18 -0
- package/lib/locale/de.js.map +1 -1
- package/lib/locale/el.d.ts +18 -0
- package/lib/locale/el.js +18 -0
- package/lib/locale/el.js.map +1 -1
- package/lib/locale/en.d.ts +18 -0
- package/lib/locale/en.js +18 -0
- package/lib/locale/en.js.map +1 -1
- package/lib/locale/es.d.ts +18 -0
- package/lib/locale/es.js +18 -0
- package/lib/locale/es.js.map +1 -1
- package/lib/locale/et.d.ts +18 -0
- package/lib/locale/et.js +18 -0
- package/lib/locale/et.js.map +1 -1
- package/lib/locale/fa.d.ts +18 -0
- package/lib/locale/fa.js +18 -0
- package/lib/locale/fa.js.map +1 -1
- package/lib/locale/fi.d.ts +18 -0
- package/lib/locale/fi.js +18 -0
- package/lib/locale/fi.js.map +1 -1
- package/lib/locale/fr.d.ts +18 -0
- package/lib/locale/fr.js +18 -0
- package/lib/locale/fr.js.map +1 -1
- package/lib/locale/he.d.ts +18 -0
- package/lib/locale/he.js +18 -0
- package/lib/locale/he.js.map +1 -1
- package/lib/locale/hr.d.ts +18 -0
- package/lib/locale/hr.js +18 -0
- package/lib/locale/hr.js.map +1 -1
- package/lib/locale/hu.d.ts +18 -0
- package/lib/locale/hu.js +18 -0
- package/lib/locale/hu.js.map +1 -1
- package/lib/locale/id.d.ts +18 -0
- package/lib/locale/id.js +18 -0
- package/lib/locale/id.js.map +1 -1
- package/lib/locale/it.d.ts +18 -0
- package/lib/locale/it.js +18 -0
- package/lib/locale/it.js.map +1 -1
- package/lib/locale/ja.d.ts +18 -0
- package/lib/locale/ja.js +18 -0
- package/lib/locale/ja.js.map +1 -1
- package/lib/locale/km.d.ts +18 -0
- package/lib/locale/km.js +18 -0
- package/lib/locale/km.js.map +1 -1
- package/lib/locale/ko.d.ts +18 -0
- package/lib/locale/ko.js +18 -0
- package/lib/locale/ko.js.map +1 -1
- package/lib/locale/lt.d.ts +18 -0
- package/lib/locale/lt.js +18 -0
- package/lib/locale/lt.js.map +1 -1
- package/lib/locale/lv.d.ts +18 -0
- package/lib/locale/lv.js +18 -0
- package/lib/locale/lv.js.map +1 -1
- package/lib/locale/nl.d.ts +18 -0
- package/lib/locale/nl.js +18 -0
- package/lib/locale/nl.js.map +1 -1
- package/lib/locale/no.d.ts +18 -0
- package/lib/locale/no.js +18 -0
- package/lib/locale/no.js.map +1 -1
- package/lib/locale/pl.d.ts +18 -0
- package/lib/locale/pl.js +18 -0
- package/lib/locale/pl.js.map +1 -1
- package/lib/locale/pt.d.ts +18 -0
- package/lib/locale/pt.js +18 -0
- package/lib/locale/pt.js.map +1 -1
- package/lib/locale/ro.d.ts +18 -0
- package/lib/locale/ro.js +18 -0
- package/lib/locale/ro.js.map +1 -1
- package/lib/locale/ru.d.ts +18 -0
- package/lib/locale/ru.js +18 -0
- package/lib/locale/ru.js.map +1 -1
- package/lib/locale/sk.d.ts +18 -0
- package/lib/locale/sk.js +18 -0
- package/lib/locale/sk.js.map +1 -1
- package/lib/locale/sl.d.ts +18 -0
- package/lib/locale/sl.js +18 -0
- package/lib/locale/sl.js.map +1 -1
- package/lib/locale/sr-Cyrl.d.ts +18 -0
- package/lib/locale/sr-Cyrl.js +18 -0
- package/lib/locale/sr-Cyrl.js.map +1 -1
- package/lib/locale/sr-Latn.d.ts +18 -0
- package/lib/locale/sr-Latn.js +18 -0
- package/lib/locale/sr-Latn.js.map +1 -1
- package/lib/locale/sv.d.ts +18 -0
- package/lib/locale/sv.js +18 -0
- package/lib/locale/sv.js.map +1 -1
- package/lib/locale/th.d.ts +18 -0
- package/lib/locale/th.js +18 -0
- package/lib/locale/th.js.map +1 -1
- package/lib/locale/tr.d.ts +18 -0
- package/lib/locale/tr.js +18 -0
- package/lib/locale/tr.js.map +1 -1
- package/lib/locale/uk.d.ts +18 -0
- package/lib/locale/uk.js +18 -0
- package/lib/locale/uk.js.map +1 -1
- package/lib/locale/vi.d.ts +18 -0
- package/lib/locale/vi.js +18 -0
- package/lib/locale/vi.js.map +1 -1
- package/lib/locale/zh-Hans.d.ts +18 -0
- package/lib/locale/zh-Hans.js +18 -0
- package/lib/locale/zh-Hans.js.map +1 -1
- package/lib/locale/zh-Hant.d.ts +18 -0
- package/lib/locale/zh-Hant.js +18 -0
- package/lib/locale/zh-Hant.js.map +1 -1
- package/package.json +1 -1
- package/lib/components/VKbd/VKbd.sass +0 -15
- package/lib/composables/hotkey.d.ts +0 -9
- package/lib/composables/hotkey.js.map +0 -1
package/dist/vuetify-labs.cjs
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/*!
|
2
|
-
* Vuetify v3.9.0-beta.1-dev.2025-
|
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
|
*/
|
@@ -2145,6 +2145,24 @@
|
|
2145
2145
|
exclude: 'The {0} character is not allowed',
|
2146
2146
|
notEmpty: 'Please choose at least one value',
|
2147
2147
|
pattern: 'Invalid format'
|
2148
|
+
},
|
2149
|
+
hotkey: {
|
2150
|
+
then: 'then',
|
2151
|
+
ctrl: 'Ctrl',
|
2152
|
+
command: 'Command',
|
2153
|
+
space: 'Space',
|
2154
|
+
shift: 'Shift',
|
2155
|
+
alt: 'Alt',
|
2156
|
+
enter: 'Enter',
|
2157
|
+
escape: 'Escape',
|
2158
|
+
upArrow: 'Up Arrow',
|
2159
|
+
downArrow: 'Down Arrow',
|
2160
|
+
leftArrow: 'Left Arrow',
|
2161
|
+
rightArrow: 'Right Arrow',
|
2162
|
+
backspace: 'Backspace',
|
2163
|
+
option: 'Option',
|
2164
|
+
plus: 'plus',
|
2165
|
+
shortcut: 'Keyboard shortcut: {0}'
|
2148
2166
|
}
|
2149
2167
|
};
|
2150
2168
|
|
@@ -4655,7 +4673,18 @@
|
|
4655
4673
|
treeviewExpand: 'mdi-menu-right',
|
4656
4674
|
eyeDropper: 'mdi-eyedropper',
|
4657
4675
|
upload: 'mdi-cloud-upload',
|
4658
|
-
color: 'mdi-palette'
|
4676
|
+
color: 'mdi-palette',
|
4677
|
+
command: 'mdi-apple-keyboard-command',
|
4678
|
+
ctrl: 'mdi-apple-keyboard-control',
|
4679
|
+
space: 'mdi-keyboard-space',
|
4680
|
+
shift: 'mdi-apple-keyboard-shift',
|
4681
|
+
alt: 'mdi-apple-keyboard-option',
|
4682
|
+
enter: 'mdi-keyboard-return',
|
4683
|
+
arrowup: 'mdi-arrow-up',
|
4684
|
+
arrowdown: 'mdi-arrow-down',
|
4685
|
+
arrowleft: 'mdi-arrow-left',
|
4686
|
+
arrowright: 'mdi-arrow-right',
|
4687
|
+
backspace: 'mdi-backspace'
|
4659
4688
|
};
|
4660
4689
|
const mdi = {
|
4661
4690
|
// Not using mergeProps here, functional components merge props by default (?)
|
@@ -10427,7 +10456,7 @@
|
|
10427
10456
|
});
|
10428
10457
|
if (flipped.isFull) {
|
10429
10458
|
const values = flipped.values();
|
10430
|
-
if (deepEqual(values.at(-1), values.at(-3))) {
|
10459
|
+
if (deepEqual(values.at(-1), values.at(-3)) && !deepEqual(values.at(-1), values.at(-2))) {
|
10431
10460
|
// Flipping is causing a container resize loop
|
10432
10461
|
return;
|
10433
10462
|
}
|
@@ -12277,7 +12306,7 @@
|
|
12277
12306
|
if (!isFocused.value) focus();
|
12278
12307
|
vue.nextTick(() => {
|
12279
12308
|
if (inputRef.value !== document.activeElement) {
|
12280
|
-
inputRef.value?.focus();
|
12309
|
+
vue.nextTick(() => inputRef.value?.focus());
|
12281
12310
|
}
|
12282
12311
|
});
|
12283
12312
|
}
|
@@ -12616,7 +12645,7 @@
|
|
12616
12645
|
raf = requestAnimationFrame(_calculateVisibleItems);
|
12617
12646
|
}
|
12618
12647
|
function _calculateVisibleItems() {
|
12619
|
-
if (!containerRef.value || !viewportHeight.value) return;
|
12648
|
+
if (!containerRef.value || !viewportHeight.value || !itemHeight.value) return;
|
12620
12649
|
const scrollTop = lastScrollTop - markerOffset;
|
12621
12650
|
const direction = Math.sign(scrollVelocity);
|
12622
12651
|
const startPx = Math.max(0, scrollTop - BUFFER_PX);
|
@@ -17499,7 +17528,7 @@
|
|
17499
17528
|
case 'fullDate':
|
17500
17529
|
options = {
|
17501
17530
|
year: 'numeric',
|
17502
|
-
month: '
|
17531
|
+
month: 'short',
|
17503
17532
|
day: 'numeric'
|
17504
17533
|
};
|
17505
17534
|
break;
|
@@ -18077,6 +18106,317 @@
|
|
18077
18106
|
return createInstance(options, locale);
|
18078
18107
|
}
|
18079
18108
|
|
18109
|
+
/**
|
18110
|
+
* Centralized key alias mapping for consistent key normalization across the hotkey system.
|
18111
|
+
*
|
18112
|
+
* This maps various user-friendly aliases to canonical key names that match
|
18113
|
+
* KeyboardEvent.key values (in lowercase) where possible.
|
18114
|
+
*/
|
18115
|
+
const keyAliasMap = {
|
18116
|
+
// Modifier aliases (from vue-use, other libraries, and current implementation)
|
18117
|
+
control: 'ctrl',
|
18118
|
+
command: 'cmd',
|
18119
|
+
option: 'alt',
|
18120
|
+
// Arrow key aliases (common abbreviations)
|
18121
|
+
up: 'arrowup',
|
18122
|
+
down: 'arrowdown',
|
18123
|
+
left: 'arrowleft',
|
18124
|
+
right: 'arrowright',
|
18125
|
+
// Other common key aliases
|
18126
|
+
esc: 'escape',
|
18127
|
+
spacebar: ' ',
|
18128
|
+
space: ' ',
|
18129
|
+
return: 'enter',
|
18130
|
+
del: 'delete',
|
18131
|
+
// Symbol aliases (existing from hotkey-parsing.ts)
|
18132
|
+
minus: '-',
|
18133
|
+
hyphen: '-'
|
18134
|
+
};
|
18135
|
+
|
18136
|
+
/**
|
18137
|
+
* Normalizes a key string to its canonical form using the alias map.
|
18138
|
+
*
|
18139
|
+
* @param key - The key string to normalize
|
18140
|
+
* @returns The canonical key name in lowercase
|
18141
|
+
*/
|
18142
|
+
function normalizeKey(key) {
|
18143
|
+
const lowerKey = key.toLowerCase();
|
18144
|
+
return keyAliasMap[lowerKey] || lowerKey;
|
18145
|
+
}
|
18146
|
+
|
18147
|
+
// Utilities
|
18148
|
+
|
18149
|
+
/**
|
18150
|
+
* Splits a single combination string into individual key parts.
|
18151
|
+
*
|
18152
|
+
* A combination is a set of keys that must be pressed simultaneously.
|
18153
|
+
* e.g. `ctrl+k`, `shift--`
|
18154
|
+
*/
|
18155
|
+
function splitKeyCombination(combination) {
|
18156
|
+
let isInternal = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
18157
|
+
if (!combination) {
|
18158
|
+
if (!isInternal) consoleWarn('Invalid hotkey combination: empty string provided');
|
18159
|
+
return [];
|
18160
|
+
}
|
18161
|
+
|
18162
|
+
// --- VALIDATION ---
|
18163
|
+
const startsWithPlusOrUnderscore = combination.startsWith('+') || combination.startsWith('_');
|
18164
|
+
const hasInvalidLeadingSeparator =
|
18165
|
+
// Starts with a single '+' or '_' followed by a non-separator character (e.g. '+a', '_a')
|
18166
|
+
startsWithPlusOrUnderscore && !(combination.startsWith('++') || combination.startsWith('__'));
|
18167
|
+
const hasInvalidStructure =
|
18168
|
+
// Invalid leading separator patterns
|
18169
|
+
combination.length > 1 && hasInvalidLeadingSeparator ||
|
18170
|
+
// Disallow literal + or _ keys (they require shift)
|
18171
|
+
combination.includes('++') || combination.includes('__') || combination === '+' || combination === '_' ||
|
18172
|
+
// Ends with a separator that is not part of a doubled literal
|
18173
|
+
combination.length > 1 && (combination.endsWith('+') || combination.endsWith('_')) && combination.at(-2) !== combination.at(-1) ||
|
18174
|
+
// Stand-alone doubled separators (dangling)
|
18175
|
+
combination === '++' || combination === '--' || combination === '__';
|
18176
|
+
if (hasInvalidStructure) {
|
18177
|
+
if (!isInternal) consoleWarn(`Invalid hotkey combination: "${combination}" has invalid structure`);
|
18178
|
+
return [];
|
18179
|
+
}
|
18180
|
+
const keys = [];
|
18181
|
+
let buffer = '';
|
18182
|
+
const flushBuffer = () => {
|
18183
|
+
if (buffer) {
|
18184
|
+
keys.push(normalizeKey(buffer));
|
18185
|
+
buffer = '';
|
18186
|
+
}
|
18187
|
+
};
|
18188
|
+
for (let i = 0; i < combination.length; i++) {
|
18189
|
+
const char = combination[i];
|
18190
|
+
const nextChar = combination[i + 1];
|
18191
|
+
if (char === '+' || char === '_' || char === '-') {
|
18192
|
+
if (char === nextChar) {
|
18193
|
+
flushBuffer();
|
18194
|
+
keys.push(char);
|
18195
|
+
i++;
|
18196
|
+
} else if (char === '+' || char === '_') {
|
18197
|
+
flushBuffer();
|
18198
|
+
} else {
|
18199
|
+
buffer += char;
|
18200
|
+
}
|
18201
|
+
} else {
|
18202
|
+
buffer += char;
|
18203
|
+
}
|
18204
|
+
}
|
18205
|
+
flushBuffer();
|
18206
|
+
|
18207
|
+
// Within a combination, `-` is only valid as a literal key (e.g., `ctrl+-`).
|
18208
|
+
// `-` cannot be part of a longer key name within a combination.
|
18209
|
+
const hasInvalidMinus = keys.some(key => key.length > 1 && key.includes('-') && key !== '--');
|
18210
|
+
if (hasInvalidMinus) {
|
18211
|
+
if (!isInternal) consoleWarn(`Invalid hotkey combination: "${combination}" has invalid structure`);
|
18212
|
+
return [];
|
18213
|
+
}
|
18214
|
+
if (keys.length === 0 && combination) {
|
18215
|
+
return [normalizeKey(combination)];
|
18216
|
+
}
|
18217
|
+
return keys;
|
18218
|
+
}
|
18219
|
+
|
18220
|
+
/**
|
18221
|
+
* Splits a hotkey string into its constituent combination groups.
|
18222
|
+
*
|
18223
|
+
* A sequence is a series of combinations that must be pressed in order.
|
18224
|
+
* e.g. `a-b`, `ctrl+k-p`
|
18225
|
+
*/
|
18226
|
+
function splitKeySequence(str) {
|
18227
|
+
if (!str) {
|
18228
|
+
consoleWarn('Invalid hotkey sequence: empty string provided');
|
18229
|
+
return [];
|
18230
|
+
}
|
18231
|
+
|
18232
|
+
// A sequence is invalid if it starts or ends with a separator,
|
18233
|
+
// unless it is part of a combination (e.g., `shift+-`).
|
18234
|
+
const hasInvalidStart = str.startsWith('-') && !['---', '--+'].includes(str);
|
18235
|
+
const hasInvalidEnd = str.endsWith('-') && !str.endsWith('+-') && !str.endsWith('_-') && str !== '-' && str !== '---';
|
18236
|
+
if (hasInvalidStart || hasInvalidEnd) {
|
18237
|
+
consoleWarn(`Invalid hotkey sequence: "${str}" contains invalid combinations`);
|
18238
|
+
return [];
|
18239
|
+
}
|
18240
|
+
const result = [];
|
18241
|
+
let buffer = '';
|
18242
|
+
let i = 0;
|
18243
|
+
while (i < str.length) {
|
18244
|
+
const char = str[i];
|
18245
|
+
if (char === '-') {
|
18246
|
+
// Determine if this hyphen is part of the current combination
|
18247
|
+
const prevChar = str[i - 1];
|
18248
|
+
const prevPrevChar = i > 1 ? str[i - 2] : undefined;
|
18249
|
+
const precededBySinglePlusOrUnderscore = (prevChar === '+' || prevChar === '_') && prevPrevChar !== '+';
|
18250
|
+
if (precededBySinglePlusOrUnderscore) {
|
18251
|
+
// Treat as part of the combination (e.g., 'ctrl+-')
|
18252
|
+
buffer += char;
|
18253
|
+
i++;
|
18254
|
+
} else {
|
18255
|
+
// Treat as sequence separator
|
18256
|
+
if (buffer) {
|
18257
|
+
result.push(buffer);
|
18258
|
+
buffer = '';
|
18259
|
+
} else {
|
18260
|
+
// Empty buffer means we have a literal '-' key
|
18261
|
+
result.push('-');
|
18262
|
+
}
|
18263
|
+
i++;
|
18264
|
+
}
|
18265
|
+
} else {
|
18266
|
+
buffer += char;
|
18267
|
+
i++;
|
18268
|
+
}
|
18269
|
+
}
|
18270
|
+
|
18271
|
+
// Add final buffer if it exists
|
18272
|
+
if (buffer) {
|
18273
|
+
result.push(buffer);
|
18274
|
+
}
|
18275
|
+
|
18276
|
+
// Collapse runs of '-' so that every second '-' is removed
|
18277
|
+
const collapsed = [];
|
18278
|
+
let minusCount = 0;
|
18279
|
+
for (const part of result) {
|
18280
|
+
if (part === '-') {
|
18281
|
+
if (minusCount % 2 === 0) collapsed.push('-');
|
18282
|
+
minusCount++;
|
18283
|
+
} else {
|
18284
|
+
minusCount = 0;
|
18285
|
+
collapsed.push(part);
|
18286
|
+
}
|
18287
|
+
}
|
18288
|
+
|
18289
|
+
// Validate that each part of the sequence is a valid combination
|
18290
|
+
const areAllValid = collapsed.every(s => splitKeyCombination(s, true).length > 0);
|
18291
|
+
if (!areAllValid) {
|
18292
|
+
consoleWarn(`Invalid hotkey sequence: "${str}" contains invalid combinations`);
|
18293
|
+
return [];
|
18294
|
+
}
|
18295
|
+
return collapsed;
|
18296
|
+
}
|
18297
|
+
|
18298
|
+
// Composables
|
18299
|
+
|
18300
|
+
// Types
|
18301
|
+
|
18302
|
+
function useHotkey(keys, callback) {
|
18303
|
+
let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
18304
|
+
if (!IN_BROWSER) return function () {};
|
18305
|
+
const {
|
18306
|
+
event = 'keydown',
|
18307
|
+
inputs = false,
|
18308
|
+
preventDefault = true,
|
18309
|
+
sequenceTimeout = 1000
|
18310
|
+
} = options;
|
18311
|
+
const isMac = navigator?.userAgent?.includes('Macintosh') ?? false;
|
18312
|
+
let timeout = 0;
|
18313
|
+
let keyGroups;
|
18314
|
+
let isSequence = false;
|
18315
|
+
let groupIndex = 0;
|
18316
|
+
function clearTimer() {
|
18317
|
+
if (!timeout) return;
|
18318
|
+
clearTimeout(timeout);
|
18319
|
+
timeout = 0;
|
18320
|
+
}
|
18321
|
+
function isInputFocused() {
|
18322
|
+
if (vue.toValue(inputs)) return false;
|
18323
|
+
const activeElement = document.activeElement;
|
18324
|
+
return activeElement && (activeElement.tagName === 'INPUT' || activeElement.tagName === 'TEXTAREA' || activeElement.isContentEditable || activeElement.contentEditable === 'true');
|
18325
|
+
}
|
18326
|
+
function resetSequence() {
|
18327
|
+
groupIndex = 0;
|
18328
|
+
clearTimer();
|
18329
|
+
}
|
18330
|
+
function handler(e) {
|
18331
|
+
const group = keyGroups[groupIndex];
|
18332
|
+
if (!group || isInputFocused()) return;
|
18333
|
+
if (!matchesKeyGroup(e, group)) {
|
18334
|
+
if (isSequence) resetSequence();
|
18335
|
+
return;
|
18336
|
+
}
|
18337
|
+
if (vue.toValue(preventDefault)) e.preventDefault();
|
18338
|
+
if (!isSequence) {
|
18339
|
+
callback(e);
|
18340
|
+
return;
|
18341
|
+
}
|
18342
|
+
clearTimer();
|
18343
|
+
groupIndex++;
|
18344
|
+
if (groupIndex === keyGroups.length) {
|
18345
|
+
callback(e);
|
18346
|
+
resetSequence();
|
18347
|
+
return;
|
18348
|
+
}
|
18349
|
+
timeout = window.setTimeout(resetSequence, vue.toValue(sequenceTimeout));
|
18350
|
+
}
|
18351
|
+
function cleanup() {
|
18352
|
+
window.removeEventListener(vue.toValue(event), handler);
|
18353
|
+
clearTimer();
|
18354
|
+
}
|
18355
|
+
vue.watch(() => vue.toValue(keys), function (unrefKeys) {
|
18356
|
+
cleanup();
|
18357
|
+
if (unrefKeys) {
|
18358
|
+
const groups = splitKeySequence(unrefKeys.toLowerCase());
|
18359
|
+
isSequence = groups.length > 1;
|
18360
|
+
keyGroups = groups;
|
18361
|
+
resetSequence();
|
18362
|
+
window.addEventListener(vue.toValue(event), handler);
|
18363
|
+
}
|
18364
|
+
}, {
|
18365
|
+
immediate: true
|
18366
|
+
});
|
18367
|
+
|
18368
|
+
// Watch for changes in the event type to re-register the listener
|
18369
|
+
vue.watch(() => vue.toValue(event), function (newEvent, oldEvent) {
|
18370
|
+
if (oldEvent && keyGroups && keyGroups.length > 0) {
|
18371
|
+
window.removeEventListener(oldEvent, handler);
|
18372
|
+
window.addEventListener(newEvent, handler);
|
18373
|
+
}
|
18374
|
+
});
|
18375
|
+
try {
|
18376
|
+
getCurrentInstance('useHotkey');
|
18377
|
+
vue.onBeforeUnmount(cleanup);
|
18378
|
+
} catch {
|
18379
|
+
// Not in Vue setup context
|
18380
|
+
}
|
18381
|
+
function parseKeyGroup(group) {
|
18382
|
+
const MODIFIERS = ['ctrl', 'shift', 'alt', 'meta', 'cmd'];
|
18383
|
+
|
18384
|
+
// Use the shared combination splitting logic
|
18385
|
+
const parts = splitKeyCombination(group.toLowerCase());
|
18386
|
+
|
18387
|
+
// If the combination is invalid, return empty result
|
18388
|
+
if (parts.length === 0) {
|
18389
|
+
return {
|
18390
|
+
modifiers: Object.fromEntries(MODIFIERS.map(m => [m, false])),
|
18391
|
+
actualKey: undefined
|
18392
|
+
};
|
18393
|
+
}
|
18394
|
+
const modifiers = Object.fromEntries(MODIFIERS.map(m => [m, false]));
|
18395
|
+
let actualKey;
|
18396
|
+
for (const part of parts) {
|
18397
|
+
if (MODIFIERS.includes(part)) {
|
18398
|
+
modifiers[part] = true;
|
18399
|
+
} else {
|
18400
|
+
actualKey = part;
|
18401
|
+
}
|
18402
|
+
}
|
18403
|
+
return {
|
18404
|
+
modifiers,
|
18405
|
+
actualKey
|
18406
|
+
};
|
18407
|
+
}
|
18408
|
+
function matchesKeyGroup(e, group) {
|
18409
|
+
const {
|
18410
|
+
modifiers,
|
18411
|
+
actualKey
|
18412
|
+
} = parseKeyGroup(group);
|
18413
|
+
const expectCtrl = modifiers.ctrl || !isMac && (modifiers.cmd || modifiers.meta);
|
18414
|
+
const expectMeta = isMac && (modifiers.cmd || modifiers.meta);
|
18415
|
+
return e.ctrlKey === expectCtrl && e.metaKey === expectMeta && e.shiftKey === modifiers.shift && e.altKey === modifiers.alt && e.key.toLowerCase() === actualKey?.toLowerCase();
|
18416
|
+
}
|
18417
|
+
return cleanup;
|
18418
|
+
}
|
18419
|
+
|
18080
18420
|
// Types
|
18081
18421
|
|
18082
18422
|
const makeVColorPickerProps = propsFactory({
|
@@ -19505,7 +19845,8 @@
|
|
19505
19845
|
|
19506
19846
|
// Dates should be compared numerically
|
19507
19847
|
if (sortA instanceof Date && sortB instanceof Date) {
|
19508
|
-
|
19848
|
+
sortA = sortA.getTime();
|
19849
|
+
sortB = sortB.getTime();
|
19509
19850
|
}
|
19510
19851
|
[sortA, sortB] = [sortA, sortB].map(s => s != null ? s.toString().toLocaleLowerCase() : s);
|
19511
19852
|
if (sortA !== sortB) {
|
@@ -20229,7 +20570,6 @@
|
|
20229
20570
|
} = _ref;
|
20230
20571
|
const Tag = props.tag ?? 'td';
|
20231
20572
|
return vue.createVNode(Tag, {
|
20232
|
-
"tabindex": "0",
|
20233
20573
|
"class": vue.normalizeClass(['v-data-table__td', {
|
20234
20574
|
'v-data-table-column--fixed': props.fixed,
|
20235
20575
|
'v-data-table-column--last-fixed': props.lastFixed,
|
@@ -20632,14 +20972,14 @@
|
|
20632
20972
|
},
|
20633
20973
|
"colspan": column.colspan,
|
20634
20974
|
"rowspan": column.rowspan,
|
20635
|
-
"onClick": column.sortable ? () => toggleSort(column) : undefined,
|
20636
20975
|
"fixed": column.fixed,
|
20637
20976
|
"nowrap": column.nowrap,
|
20638
20977
|
"lastFixed": column.lastFixed,
|
20639
|
-
"noPadding": noPadding
|
20640
|
-
|
20641
|
-
"
|
20642
|
-
|
20978
|
+
"noPadding": noPadding,
|
20979
|
+
"tabindex": column.sortable ? 0 : undefined,
|
20980
|
+
"onClick": column.sortable ? () => toggleSort(column) : undefined,
|
20981
|
+
"onKeydown": column.sortable ? event => handleEnterKeyPress(event, column) : undefined
|
20982
|
+
}, headerProps), {
|
20643
20983
|
default: () => {
|
20644
20984
|
const columnSlotName = `header.${column.key}`;
|
20645
20985
|
const columnSlotProps = {
|
@@ -22325,13 +22665,9 @@
|
|
22325
22665
|
const date = adapter.setYear(adapter.startOfMonth(adapter.date()), adapter.getYear(year.value));
|
22326
22666
|
return adapter.setMonth(date, value);
|
22327
22667
|
}, v => adapter.getMonth(v));
|
22328
|
-
const weekDays = vue.computed(() => {
|
22329
|
-
const firstDayOfWeek = adapter.toJsDate(adapter.startOfWeek(adapter.date(), props.firstDayOfWeek)).getDay();
|
22330
|
-
return props.weekdays.map(day => (day + firstDayOfWeek) % 7);
|
22331
|
-
});
|
22332
22668
|
const weekdayLabels = vue.computed(() => {
|
22333
|
-
const
|
22334
|
-
return
|
22669
|
+
const firstDayOfWeek = adapter.toJsDate(adapter.startOfWeek(adapter.date(), props.firstDayOfWeek)).getDay();
|
22670
|
+
return adapter.getWeekdays(props.firstDayOfWeek, props.weekdayFormat).filter((_, i) => props.weekdays.includes((i + firstDayOfWeek) % 7));
|
22335
22671
|
});
|
22336
22672
|
const weeksInMonth = vue.computed(() => {
|
22337
22673
|
const weeks = adapter.getWeekArray(month.value, props.firstDayOfWeek);
|
@@ -22355,13 +22691,14 @@
|
|
22355
22691
|
});
|
22356
22692
|
function genDays(days, today) {
|
22357
22693
|
return days.filter(date => {
|
22358
|
-
return
|
22694
|
+
return props.weekdays.includes(adapter.toJsDate(date).getDay());
|
22359
22695
|
}).map((date, index) => {
|
22360
22696
|
const isoDate = adapter.toISO(date);
|
22361
22697
|
const isAdjacent = !adapter.isSameMonth(date, month.value);
|
22362
22698
|
const isStart = adapter.isSameDay(date, adapter.startOfMonth(month.value));
|
22363
22699
|
const isEnd = adapter.isSameDay(date, adapter.endOfMonth(month.value));
|
22364
22700
|
const isSame = adapter.isSameDay(date, month.value);
|
22701
|
+
const weekdaysCount = props.weekdays.length;
|
22365
22702
|
return {
|
22366
22703
|
date,
|
22367
22704
|
formatted: adapter.format(date, 'keyboardDate'),
|
@@ -22373,8 +22710,8 @@
|
|
22373
22710
|
isSelected: model.value.some(value => adapter.isSameDay(date, value)),
|
22374
22711
|
isStart,
|
22375
22712
|
isToday: adapter.isSameDay(date, today),
|
22376
|
-
isWeekEnd: index %
|
22377
|
-
isWeekStart: index %
|
22713
|
+
isWeekEnd: index % weekdaysCount === weekdaysCount - 1,
|
22714
|
+
isWeekStart: index % weekdaysCount === 0,
|
22378
22715
|
isoDate,
|
22379
22716
|
localized: adapter.format(date, 'dayOfMonth'),
|
22380
22717
|
month: adapter.getMonth(date),
|
@@ -22421,7 +22758,6 @@
|
|
22421
22758
|
genDays,
|
22422
22759
|
model,
|
22423
22760
|
weeksInMonth,
|
22424
|
-
weekDays,
|
22425
22761
|
weekdayLabels,
|
22426
22762
|
weekNumbers
|
22427
22763
|
};
|
@@ -22462,7 +22798,6 @@
|
|
22462
22798
|
daysInMonth,
|
22463
22799
|
model,
|
22464
22800
|
weekNumbers,
|
22465
|
-
weekDays,
|
22466
22801
|
weekdayLabels
|
22467
22802
|
} = useCalendar(props);
|
22468
22803
|
const adapter = useDate();
|
@@ -22537,7 +22872,7 @@
|
|
22537
22872
|
useRender(() => vue.createElementVNode("div", {
|
22538
22873
|
"class": "v-date-picker-month",
|
22539
22874
|
"style": {
|
22540
|
-
'--v-date-picker-days-in-week':
|
22875
|
+
'--v-date-picker-days-in-week': props.weekdays.length
|
22541
22876
|
}
|
22542
22877
|
}, [props.showWeek && vue.createElementVNode("div", {
|
22543
22878
|
"key": "weeks",
|
@@ -25708,19 +26043,21 @@
|
|
25708
26043
|
const contentRef = vue.ref();
|
25709
26044
|
const inputRef = vue.ref([]);
|
25710
26045
|
const current = vue.computed(() => inputRef.value[focusIndex.value]);
|
25711
|
-
|
25712
|
-
|
25713
|
-
|
25714
|
-
|
25715
|
-
|
25716
|
-
|
25717
|
-
|
25718
|
-
|
25719
|
-
|
25720
|
-
|
25721
|
-
|
25722
|
-
|
25723
|
-
|
26046
|
+
useToggleScope(() => props.autofocus, () => {
|
26047
|
+
const intersectScope = vue.effectScope();
|
26048
|
+
intersectScope.run(() => {
|
26049
|
+
const {
|
26050
|
+
intersectionRef,
|
26051
|
+
isIntersecting
|
26052
|
+
} = useIntersectionObserver();
|
26053
|
+
vue.watchEffect(() => {
|
26054
|
+
intersectionRef.value = inputRef.value[0];
|
26055
|
+
});
|
26056
|
+
vue.watch(isIntersecting, v => {
|
26057
|
+
if (!v) return;
|
26058
|
+
intersectionRef.value?.focus();
|
26059
|
+
intersectScope.stop();
|
26060
|
+
});
|
25724
26061
|
});
|
25725
26062
|
});
|
25726
26063
|
function onInput() {
|
@@ -30188,7 +30525,7 @@
|
|
30188
30525
|
}
|
30189
30526
|
};
|
30190
30527
|
useRender(() => {
|
30191
|
-
return vue.createElementVNode("div", null, [slots
|
30528
|
+
return vue.createElementVNode("div", null, [slots['interval-event']?.({
|
30192
30529
|
height: calcHeight().height,
|
30193
30530
|
margin: calcHeight().margin,
|
30194
30531
|
eventClass: 'v-calendar-internal-event',
|
@@ -30285,13 +30622,13 @@
|
|
30285
30622
|
"style": vue.normalizeStyle(`height: ${convertToUnit(props.intervalHeight)}`)
|
30286
30623
|
}, [vue.createElementVNode("div", vue.mergeProps({
|
30287
30624
|
"class": "v-calendar-day__row-label"
|
30288
|
-
}, getPrefixedEventHandlers(attrs, ':time', () => props)), [slots
|
30625
|
+
}, getPrefixedEventHandlers(attrs, ':time', () => props)), [slots['interval-title']?.({
|
30289
30626
|
interval: interval.value
|
30290
30627
|
}) ?? (props.index ? props.intervalFormat ? typeof props.intervalFormat === 'string' ? adapter.format(interval.value.start, 'hours12h') : props.intervalFormat(interval.value) : interval.value.label : '12 AM')]), vue.createElementVNode("div", {
|
30291
30628
|
"class": "v-calendar-day__row-hairline"
|
30292
30629
|
}, null), vue.createElementVNode("div", vue.mergeProps({
|
30293
30630
|
"class": ['v-calendar-day__row-content', interval.value.events.some(e => !e.last) ? 'v-calendar-day__row-content-through' : '']
|
30294
|
-
}, getPrefixedEventHandlers(attrs, ':interval', () => interval.value)), [slots
|
30631
|
+
}, getPrefixedEventHandlers(attrs, ':interval', () => interval.value)), [slots['interval-body']?.({
|
30295
30632
|
interval: interval.value
|
30296
30633
|
}) ?? vue.createElementVNode("div", null, [interval.value.events?.map(event => vue.createVNode(VCalendarIntervalEvent, vue.mergeProps({
|
30297
30634
|
"event": event,
|
@@ -30300,8 +30637,8 @@
|
|
30300
30637
|
"intervalDuration": props.intervalDuration,
|
30301
30638
|
"intervalHeight": props.intervalHeight
|
30302
30639
|
}, attrs), {
|
30303
|
-
...(slots
|
30304
|
-
|
30640
|
+
...(slots['interval-event'] ? {
|
30641
|
+
'interval-event': _ref2 => {
|
30305
30642
|
let {
|
30306
30643
|
height,
|
30307
30644
|
margin,
|
@@ -30309,7 +30646,7 @@
|
|
30309
30646
|
event,
|
30310
30647
|
interval
|
30311
30648
|
} = _ref2;
|
30312
|
-
return slots
|
30649
|
+
return slots['interval-event']?.({
|
30313
30650
|
height,
|
30314
30651
|
margin,
|
30315
30652
|
eventClass,
|
@@ -30323,7 +30660,7 @@
|
|
30323
30660
|
"style": vue.normalizeStyle(`height: ${convertToUnit(props.intervalHeight)}`)
|
30324
30661
|
}, [vue.createElementVNode("div", vue.mergeProps({
|
30325
30662
|
"class": ['v-calendar-day__row-content', interval.value.events.some(e => !e.last) ? 'v-calendar-day__row-content-through' : '']
|
30326
|
-
}, getPrefixedEventHandlers(attrs, ':interval', () => interval.value)), [slots
|
30663
|
+
}, getPrefixedEventHandlers(attrs, ':interval', () => interval.value)), [slots['interval-body']?.({
|
30327
30664
|
interval: interval.value
|
30328
30665
|
}) ?? interval.value.events?.map(event => vue.createVNode(VCalendarIntervalEvent, vue.mergeProps({
|
30329
30666
|
"event": event,
|
@@ -30332,8 +30669,8 @@
|
|
30332
30669
|
"intervalDuration": props.intervalDuration,
|
30333
30670
|
"intervalHeight": props.intervalHeight
|
30334
30671
|
}, attrs), {
|
30335
|
-
...(slots
|
30336
|
-
|
30672
|
+
...(slots['interval-event'] ? {
|
30673
|
+
'interval-event': _ref3 => {
|
30337
30674
|
let {
|
30338
30675
|
height,
|
30339
30676
|
margin,
|
@@ -30341,7 +30678,7 @@
|
|
30341
30678
|
event,
|
30342
30679
|
interval
|
30343
30680
|
} = _ref3;
|
30344
|
-
return slots
|
30681
|
+
return slots['interval-event']?.({
|
30345
30682
|
height,
|
30346
30683
|
margin,
|
30347
30684
|
eventClass,
|
@@ -30396,7 +30733,7 @@
|
|
30396
30733
|
}), null)])]), intervals.value.map((_, index) => slots.interval?.(calendarIntervalProps) ?? vue.createVNode(VCalendarInterval, vue.mergeProps({
|
30397
30734
|
"index": index
|
30398
30735
|
}, calendarIntervalProps, attrs, getPrefixedEventHandlers(attrs, ':interval', () => calendarIntervalProps)), {
|
30399
|
-
...pick(slots, ['
|
30736
|
+
...pick(slots, ['interval-body', 'interval-event', 'interval-title'])
|
30400
30737
|
}))]);
|
30401
30738
|
});
|
30402
30739
|
return {
|
@@ -30540,7 +30877,7 @@
|
|
30540
30877
|
}, getPrefixedEventHandlers(attrs, ':day', () => props)), [!props.day?.isHidden ? vue.createElementVNode("div", {
|
30541
30878
|
"key": "title",
|
30542
30879
|
"class": "v-calendar-weekly__day-label"
|
30543
|
-
}, [slots
|
30880
|
+
}, [slots['day-title']?.({
|
30544
30881
|
title: props.title
|
30545
30882
|
}) ?? vue.createVNode(VBtn, vue.mergeProps({
|
30546
30883
|
"class": props.day?.isToday ? 'v-calendar-weekly__day-label__today' : undefined,
|
@@ -30553,12 +30890,12 @@
|
|
30553
30890
|
}, getPrefixedEventHandlers(attrs, ':date', () => props)), null)]) : undefined, !props.day?.isHidden ? vue.createElementVNode("div", {
|
30554
30891
|
"key": "content",
|
30555
30892
|
"class": "v-calendar-weekly__day-content"
|
30556
|
-
}, [slots
|
30893
|
+
}, [slots['day-body']?.({
|
30557
30894
|
day: props.day,
|
30558
30895
|
events: props.events
|
30559
30896
|
}) ?? vue.createElementVNode("div", null, [vue.createElementVNode("div", {
|
30560
30897
|
"class": "v-calendar-weekly__day-alldayevents-container"
|
30561
|
-
}, [props.events?.filter(event => event.allDay).map(event => slots
|
30898
|
+
}, [props.events?.filter(event => event.allDay).map(event => slots['day-event'] ? slots['day-event']({
|
30562
30899
|
day: props.day,
|
30563
30900
|
allDay: true,
|
30564
30901
|
event
|
@@ -30568,7 +30905,7 @@
|
|
30568
30905
|
"allDay": true
|
30569
30906
|
}, attrs), null))]), vue.createElementVNode("div", {
|
30570
30907
|
"class": "v-calendar-weekly__day-events-container"
|
30571
|
-
}, [props.events?.filter(event => !event.allDay).map(event => slots
|
30908
|
+
}, [props.events?.filter(event => !event.allDay).map(event => slots['day-event'] ? slots['day-event']({
|
30572
30909
|
day: props.day,
|
30573
30910
|
event,
|
30574
30911
|
allDay: false
|
@@ -30613,9 +30950,8 @@
|
|
30613
30950
|
model,
|
30614
30951
|
displayValue,
|
30615
30952
|
weekNumbers,
|
30616
|
-
|
30953
|
+
weekdayLabels
|
30617
30954
|
} = useCalendar(props);
|
30618
|
-
const dayNames = adapter.getWeekdays();
|
30619
30955
|
function onClickNext() {
|
30620
30956
|
if (props.viewMode === 'month') {
|
30621
30957
|
model.value = [adapter.addMonths(displayValue.value, 1)];
|
@@ -30653,6 +30989,7 @@
|
|
30653
30989
|
useRender(() => {
|
30654
30990
|
const calendarDayProps = VCalendarDay.filterProps(props);
|
30655
30991
|
const calendarHeaderProps = VCalendarHeader.filterProps(props);
|
30992
|
+
const weekdaysCount = daysInWeek.value.length;
|
30656
30993
|
return vue.createElementVNode("div", {
|
30657
30994
|
"class": vue.normalizeClass(['v-calendar', {
|
30658
30995
|
'v-calendar-monthly': props.viewMode === 'month',
|
@@ -30674,19 +31011,19 @@
|
|
30674
31011
|
}), {
|
30675
31012
|
title: slots.title
|
30676
31013
|
}))]), vue.createElementVNode("div", {
|
30677
|
-
"class": vue.normalizeClass(['v-calendar__container', `days__${
|
31014
|
+
"class": vue.normalizeClass(['v-calendar__container', `days__${weekdaysCount}`])
|
30678
31015
|
}, [props.viewMode === 'month' && !props.hideDayHeader && vue.createElementVNode("div", {
|
30679
|
-
"class": vue.normalizeClass(['v-calendar-weekly__head', `days__${
|
31016
|
+
"class": vue.normalizeClass(['v-calendar-weekly__head', `days__${weekdaysCount}`, ...(!props.hideWeekNumber ? ['v-calendar-weekly__head-weeknumbers'] : [])]),
|
30680
31017
|
"key": "calendarWeeklyHead"
|
30681
31018
|
}, [!props.hideWeekNumber ? vue.createElementVNode("div", {
|
30682
31019
|
"key": "weekNumber0",
|
30683
31020
|
"class": "v-calendar-weekly__head-weeknumber"
|
30684
|
-
}, null) : '',
|
31021
|
+
}, null) : '', weekdayLabels.value.map(weekday => vue.createElementVNode("div", {
|
30685
31022
|
"class": vue.normalizeClass(`v-calendar-weekly__head-weekday${!props.hideWeekNumber ? '-with-weeknumber' : ''}`)
|
30686
|
-
}, [
|
31023
|
+
}, [weekday]))]), props.viewMode === 'month' && vue.createElementVNode("div", {
|
30687
31024
|
"key": "VCalendarMonth",
|
30688
|
-
"class": vue.normalizeClass(['v-calendar-month__days', `days${!props.hideWeekNumber ? '-with-weeknumbers' : ''}__${
|
30689
|
-
}, [chunkArray(daysInMonth.value,
|
31025
|
+
"class": vue.normalizeClass(['v-calendar-month__days', `days${!props.hideWeekNumber ? '-with-weeknumbers' : ''}__${weekdaysCount}`, ...(!props.hideWeekNumber ? ['v-calendar-month__weeknumbers'] : [])])
|
31026
|
+
}, [chunkArray(daysInMonth.value, weekdaysCount).map((week, wi) => [!props.hideWeekNumber ? vue.createElementVNode("div", vue.mergeProps({
|
30690
31027
|
"class": "v-calendar-month__weeknumber"
|
30691
31028
|
}, getPrefixedEventHandlers(attrs, ':weekNumber', () => ({
|
30692
31029
|
weekNumber: weekNumbers.value[wi],
|
@@ -30709,7 +31046,7 @@
|
|
30709
31046
|
"dayIndex": i,
|
30710
31047
|
"events": props.events?.filter(e => adapter.isSameDay(e.start, day.date) || adapter.isSameDay(e.end, day.date))
|
30711
31048
|
}, attrs), {
|
30712
|
-
...pick(slots, ['interval', '
|
31049
|
+
...pick(slots, ['interval', 'interval-body', 'interval-event', 'interval-title'])
|
30713
31050
|
})), props.viewMode === 'day' && (slots['day-interval'] ? slots['day-interval']({
|
30714
31051
|
day: genDays([displayValue.value], adapter.date())[0],
|
30715
31052
|
dayIndex: 0,
|
@@ -31624,6 +31961,7 @@
|
|
31624
31961
|
opacity: props.opacity
|
31625
31962
|
};
|
31626
31963
|
return vue.createVNode(props.tag, {
|
31964
|
+
"type": props.tag === 'button' ? 'button' : undefined,
|
31627
31965
|
"class": vue.normalizeClass([{
|
31628
31966
|
'v-icon-btn': true,
|
31629
31967
|
'v-icon-btn--active': isActive.value,
|
@@ -32282,6 +32620,398 @@
|
|
32282
32620
|
}
|
32283
32621
|
});
|
32284
32622
|
|
32623
|
+
// Types
|
32624
|
+
|
32625
|
+
// Display mode types for different visual representations
|
32626
|
+
|
32627
|
+
// Extended variant type that includes our custom 'contained' variant
|
32628
|
+
|
32629
|
+
// Key display tuple: [mode, content] where content is string or IconValue
|
32630
|
+
|
32631
|
+
// Key tuple: [mode, content] where content is string or IconValue
|
32632
|
+
|
32633
|
+
function processKey(config, requestedMode, isMac) {
|
32634
|
+
const keyCfg = isMac && config.mac ? config.mac : config.default;
|
32635
|
+
|
32636
|
+
// 1. Resolve the safest display mode for the current platform
|
32637
|
+
const mode = (() => {
|
32638
|
+
// Non-Mac platforms rarely use icons – prefer text
|
32639
|
+
if (requestedMode === 'icon' && !isMac) return 'text';
|
32640
|
+
|
32641
|
+
// If the requested mode lacks an asset, fall back to text
|
32642
|
+
if (requestedMode === 'icon' && !keyCfg.icon) return 'text';
|
32643
|
+
if (requestedMode === 'symbol' && !keyCfg.symbol) return 'text';
|
32644
|
+
return requestedMode;
|
32645
|
+
})();
|
32646
|
+
|
32647
|
+
// 2. Pick value for the chosen mode, defaulting to text representation
|
32648
|
+
let value = keyCfg[mode] ?? keyCfg.text;
|
32649
|
+
|
32650
|
+
// 3. Guard against icon tokens leaking into text mode (e.g. "$ctrl")
|
32651
|
+
if (mode === 'text' && typeof value === 'string' && value.startsWith('$') && !value.startsWith('$vuetify.')) {
|
32652
|
+
value = value.slice(1).toUpperCase(); // "$ctrl" → "CTRL"
|
32653
|
+
}
|
32654
|
+
return mode === 'icon' ? ['icon', value] : [mode, value];
|
32655
|
+
}
|
32656
|
+
const hotkeyMap = {
|
32657
|
+
ctrl: {
|
32658
|
+
mac: {
|
32659
|
+
symbol: '⌃',
|
32660
|
+
icon: '$ctrl',
|
32661
|
+
text: '$vuetify.hotkey.ctrl'
|
32662
|
+
},
|
32663
|
+
default: {
|
32664
|
+
text: 'Ctrl'
|
32665
|
+
}
|
32666
|
+
},
|
32667
|
+
meta: {
|
32668
|
+
mac: {
|
32669
|
+
symbol: '⌘',
|
32670
|
+
icon: '$command',
|
32671
|
+
text: '$vuetify.hotkey.command'
|
32672
|
+
},
|
32673
|
+
default: {
|
32674
|
+
text: 'Ctrl'
|
32675
|
+
}
|
32676
|
+
},
|
32677
|
+
cmd: {
|
32678
|
+
mac: {
|
32679
|
+
symbol: '⌘',
|
32680
|
+
icon: '$command',
|
32681
|
+
text: '$vuetify.hotkey.command'
|
32682
|
+
},
|
32683
|
+
default: {
|
32684
|
+
text: 'Ctrl'
|
32685
|
+
}
|
32686
|
+
},
|
32687
|
+
shift: {
|
32688
|
+
mac: {
|
32689
|
+
symbol: '⇧',
|
32690
|
+
icon: '$shift',
|
32691
|
+
text: '$vuetify.hotkey.shift'
|
32692
|
+
},
|
32693
|
+
default: {
|
32694
|
+
text: 'Shift'
|
32695
|
+
}
|
32696
|
+
},
|
32697
|
+
alt: {
|
32698
|
+
mac: {
|
32699
|
+
symbol: '⌥',
|
32700
|
+
icon: '$alt',
|
32701
|
+
text: '$vuetify.hotkey.option'
|
32702
|
+
},
|
32703
|
+
default: {
|
32704
|
+
text: 'Alt'
|
32705
|
+
}
|
32706
|
+
},
|
32707
|
+
enter: {
|
32708
|
+
default: {
|
32709
|
+
symbol: '↵',
|
32710
|
+
icon: '$enter',
|
32711
|
+
text: '$vuetify.hotkey.enter'
|
32712
|
+
}
|
32713
|
+
},
|
32714
|
+
arrowup: {
|
32715
|
+
default: {
|
32716
|
+
symbol: '↑',
|
32717
|
+
icon: '$arrowup',
|
32718
|
+
text: '$vuetify.hotkey.upArrow'
|
32719
|
+
}
|
32720
|
+
},
|
32721
|
+
arrowdown: {
|
32722
|
+
default: {
|
32723
|
+
symbol: '↓',
|
32724
|
+
icon: '$arrowdown',
|
32725
|
+
text: '$vuetify.hotkey.downArrow'
|
32726
|
+
}
|
32727
|
+
},
|
32728
|
+
arrowleft: {
|
32729
|
+
default: {
|
32730
|
+
symbol: '←',
|
32731
|
+
icon: '$arrowleft',
|
32732
|
+
text: '$vuetify.hotkey.leftArrow'
|
32733
|
+
}
|
32734
|
+
},
|
32735
|
+
arrowright: {
|
32736
|
+
default: {
|
32737
|
+
symbol: '→',
|
32738
|
+
icon: '$arrowright',
|
32739
|
+
text: '$vuetify.hotkey.rightArrow'
|
32740
|
+
}
|
32741
|
+
},
|
32742
|
+
backspace: {
|
32743
|
+
default: {
|
32744
|
+
symbol: '⌫',
|
32745
|
+
icon: '$backspace',
|
32746
|
+
text: '$vuetify.hotkey.backspace'
|
32747
|
+
}
|
32748
|
+
},
|
32749
|
+
escape: {
|
32750
|
+
default: {
|
32751
|
+
text: '$vuetify.hotkey.escape'
|
32752
|
+
}
|
32753
|
+
},
|
32754
|
+
' ': {
|
32755
|
+
mac: {
|
32756
|
+
symbol: '␣',
|
32757
|
+
icon: '$space',
|
32758
|
+
text: '$vuetify.hotkey.space'
|
32759
|
+
},
|
32760
|
+
default: {
|
32761
|
+
text: '$vuetify.hotkey.space'
|
32762
|
+
}
|
32763
|
+
},
|
32764
|
+
'-': {
|
32765
|
+
default: {
|
32766
|
+
text: '-'
|
32767
|
+
}
|
32768
|
+
}
|
32769
|
+
};
|
32770
|
+
|
32771
|
+
// Create custom variant props that extend the base variant props with our 'contained' option
|
32772
|
+
const makeVHotkeyVariantProps = propsFactory({
|
32773
|
+
variant: {
|
32774
|
+
type: String,
|
32775
|
+
default: 'elevated',
|
32776
|
+
validator: v => ['elevated', 'flat', 'tonal', 'outlined', 'text', 'plain', 'contained'].includes(v)
|
32777
|
+
}
|
32778
|
+
}, 'VHotkeyVariant');
|
32779
|
+
const makeVHotkeyProps = propsFactory({
|
32780
|
+
// String representing keyboard shortcuts (e.g., "ctrl+k", "meta+shift+p")
|
32781
|
+
keys: String,
|
32782
|
+
// How to display keys: 'symbol' uses special characters (⌘, ⌃), 'icon' uses SVG icons, 'text' uses words
|
32783
|
+
displayMode: {
|
32784
|
+
type: String,
|
32785
|
+
default: 'icon'
|
32786
|
+
},
|
32787
|
+
// Custom key mapping configuration. Users can import and modify the exported hotkeyMap as needed
|
32788
|
+
keyMap: {
|
32789
|
+
type: Object,
|
32790
|
+
default: () => hotkeyMap
|
32791
|
+
},
|
32792
|
+
platform: {
|
32793
|
+
type: String,
|
32794
|
+
default: 'auto'
|
32795
|
+
},
|
32796
|
+
inline: Boolean,
|
32797
|
+
disabled: Boolean,
|
32798
|
+
prefix: String,
|
32799
|
+
suffix: String,
|
32800
|
+
...makeComponentProps(),
|
32801
|
+
...makeThemeProps(),
|
32802
|
+
...makeBorderProps(),
|
32803
|
+
...makeRoundedProps(),
|
32804
|
+
...makeElevationProps(),
|
32805
|
+
...makeVHotkeyVariantProps(),
|
32806
|
+
color: String
|
32807
|
+
}, 'VHotkey');
|
32808
|
+
class Delineator {
|
32809
|
+
constructor(delineator) {
|
32810
|
+
if (['and', 'then'].includes(delineator)) this.val = delineator;else {
|
32811
|
+
throw new Error('Not a valid delineator');
|
32812
|
+
}
|
32813
|
+
}
|
32814
|
+
isEqual(d) {
|
32815
|
+
return this.val === d.val;
|
32816
|
+
}
|
32817
|
+
}
|
32818
|
+
function isDelineator(value) {
|
32819
|
+
return value instanceof Delineator;
|
32820
|
+
}
|
32821
|
+
function isString(value) {
|
32822
|
+
return typeof value === 'string';
|
32823
|
+
}
|
32824
|
+
function getKeyText(keyMap, key, isMac) {
|
32825
|
+
const lowerKey = key.toLowerCase();
|
32826
|
+
if (lowerKey in keyMap) {
|
32827
|
+
const result = processKey(keyMap[lowerKey], 'text', isMac);
|
32828
|
+
return typeof result[1] === 'string' ? result[1] : String(result[1]);
|
32829
|
+
}
|
32830
|
+
return key.toUpperCase();
|
32831
|
+
}
|
32832
|
+
function applyDisplayModeToKey(keyMap, mode, key, isMac) {
|
32833
|
+
const lowerKey = key.toLowerCase();
|
32834
|
+
if (lowerKey in keyMap) {
|
32835
|
+
const result = processKey(keyMap[lowerKey], mode, isMac);
|
32836
|
+
if (result[0] === 'text' && typeof result[1] === 'string' && result[1].startsWith('$') && !result[1].startsWith('$vuetify.')) {
|
32837
|
+
return ['text', result[1].replace('$', '').toUpperCase(), key];
|
32838
|
+
}
|
32839
|
+
return [...result, key];
|
32840
|
+
}
|
32841
|
+
return ['text', key.toUpperCase(), key];
|
32842
|
+
}
|
32843
|
+
const VHotkey = genericComponent()({
|
32844
|
+
name: 'VHotkey',
|
32845
|
+
props: makeVHotkeyProps(),
|
32846
|
+
setup(props) {
|
32847
|
+
const {
|
32848
|
+
t
|
32849
|
+
} = useLocale();
|
32850
|
+
const {
|
32851
|
+
themeClasses
|
32852
|
+
} = provideTheme(props);
|
32853
|
+
const {
|
32854
|
+
rtlClasses
|
32855
|
+
} = useRtl();
|
32856
|
+
const {
|
32857
|
+
borderClasses
|
32858
|
+
} = useBorder(props);
|
32859
|
+
const {
|
32860
|
+
roundedClasses
|
32861
|
+
} = useRounded(props);
|
32862
|
+
const {
|
32863
|
+
elevationClasses
|
32864
|
+
} = useElevation(props);
|
32865
|
+
const isContainedVariant = vue.computed(() => props.variant === 'contained');
|
32866
|
+
const effectiveVariantProps = vue.computed(() => ({
|
32867
|
+
...props,
|
32868
|
+
variant: isContainedVariant.value ? 'elevated' : props.variant
|
32869
|
+
}));
|
32870
|
+
const {
|
32871
|
+
colorClasses,
|
32872
|
+
colorStyles,
|
32873
|
+
variantClasses
|
32874
|
+
} = useVariant(effectiveVariantProps);
|
32875
|
+
const isMac = vue.computed(() => props.platform === 'auto' ? typeof navigator !== 'undefined' && /macintosh/i.test(navigator.userAgent) : props.platform === 'mac');
|
32876
|
+
const effectiveDisplayMode = vue.computed(() => props.displayMode);
|
32877
|
+
const AND_DELINEATOR = new Delineator('and'); // For + separators
|
32878
|
+
const THEN_DELINEATOR = new Delineator('then'); // For - separators
|
32879
|
+
|
32880
|
+
const effectiveKeyMap = vue.computed(() => props.keyMap);
|
32881
|
+
const keyCombinations = vue.computed(() => {
|
32882
|
+
if (!props.keys) return [];
|
32883
|
+
|
32884
|
+
// Split by spaces to handle multiple key combinations
|
32885
|
+
// Example: "ctrl+k meta+p" -> ["ctrl+k", "meta+p"]
|
32886
|
+
return props.keys.split(' ').map(combination => {
|
32887
|
+
// Use the shared sequence splitting logic
|
32888
|
+
const sequenceGroups = splitKeySequence(combination);
|
32889
|
+
|
32890
|
+
// Process each sequence group
|
32891
|
+
return sequenceGroups.flatMap((group, groupIndex) => {
|
32892
|
+
// Use the shared key combination splitting logic
|
32893
|
+
const keyParts = splitKeyCombination(group);
|
32894
|
+
const parts = keyParts.reduce((acc, part, index) => {
|
32895
|
+
if (index !== 0) {
|
32896
|
+
// Add AND delineator between keys
|
32897
|
+
return [...acc, AND_DELINEATOR, part];
|
32898
|
+
}
|
32899
|
+
return [...acc, part];
|
32900
|
+
}, []);
|
32901
|
+
|
32902
|
+
// Add THEN delineator between sequence groups
|
32903
|
+
const result = parts.map(key => {
|
32904
|
+
if (isString(key)) {
|
32905
|
+
return applyDisplayModeToKey(effectiveKeyMap.value, effectiveDisplayMode.value, key, isMac.value);
|
32906
|
+
}
|
32907
|
+
return key;
|
32908
|
+
});
|
32909
|
+
|
32910
|
+
// Add sequence separator if not the last group
|
32911
|
+
if (groupIndex < sequenceGroups.length - 1) {
|
32912
|
+
result.push(THEN_DELINEATOR);
|
32913
|
+
}
|
32914
|
+
return result;
|
32915
|
+
});
|
32916
|
+
});
|
32917
|
+
});
|
32918
|
+
const accessibleLabel = vue.computed(() => {
|
32919
|
+
if (!props.keys) return '';
|
32920
|
+
|
32921
|
+
// Convert the parsed key combinations into readable text
|
32922
|
+
const readableShortcuts = keyCombinations.value.map(combination => {
|
32923
|
+
const readableParts = [];
|
32924
|
+
for (const key of combination) {
|
32925
|
+
if (isDelineator(key)) {
|
32926
|
+
if (AND_DELINEATOR.isEqual(key)) {
|
32927
|
+
readableParts.push(t('$vuetify.hotkey.plus'));
|
32928
|
+
} else if (THEN_DELINEATOR.isEqual(key)) {
|
32929
|
+
readableParts.push(t('$vuetify.hotkey.then'));
|
32930
|
+
}
|
32931
|
+
} else {
|
32932
|
+
// Always use text representation for screen readers
|
32933
|
+
const textKey = key[0] === 'icon' || key[0] === 'symbol' ? applyDisplayModeToKey(mergeDeep(hotkeyMap, props.keyMap), 'text', String(key[1]), isMac.value)[1] : key[1];
|
32934
|
+
readableParts.push(translateKey(textKey));
|
32935
|
+
}
|
32936
|
+
}
|
32937
|
+
return readableParts.join(' ');
|
32938
|
+
});
|
32939
|
+
const shortcutText = readableShortcuts.join(', ');
|
32940
|
+
return t('$vuetify.hotkey.shortcut', shortcutText);
|
32941
|
+
});
|
32942
|
+
function translateKey(key) {
|
32943
|
+
return key.startsWith('$vuetify.') ? t(key) : key;
|
32944
|
+
}
|
32945
|
+
function getKeyTooltip(key) {
|
32946
|
+
if (effectiveDisplayMode.value === 'text') return undefined;
|
32947
|
+
const textKey = getKeyText(effectiveKeyMap.value, String(key[2]), isMac.value);
|
32948
|
+
return translateKey(textKey);
|
32949
|
+
}
|
32950
|
+
function renderKey(key, keyIndex, isContained) {
|
32951
|
+
const KeyComponent = isContained ? 'kbd' : VKbd;
|
32952
|
+
const keyClasses = ['v-hotkey__key', `v-hotkey__key-${key[0]}`, ...(isContained ? ['v-hotkey__key--nested'] : [borderClasses.value, roundedClasses.value, elevationClasses.value, colorClasses.value])];
|
32953
|
+
return vue.createVNode(KeyComponent, {
|
32954
|
+
"key": keyIndex,
|
32955
|
+
"class": vue.normalizeClass(keyClasses),
|
32956
|
+
"style": vue.normalizeStyle(isContained ? undefined : colorStyles.value),
|
32957
|
+
"aria-hidden": "true",
|
32958
|
+
"title": getKeyTooltip(key)
|
32959
|
+
}, {
|
32960
|
+
default: () => [key[0] === 'icon' ? vue.createVNode(VIcon, {
|
32961
|
+
"icon": key[1],
|
32962
|
+
"aria-hidden": "true"
|
32963
|
+
}, null) : translateKey(key[1])]
|
32964
|
+
});
|
32965
|
+
}
|
32966
|
+
function renderDivider(key, keyIndex) {
|
32967
|
+
return vue.createElementVNode("span", {
|
32968
|
+
"key": keyIndex,
|
32969
|
+
"class": "v-hotkey__divider",
|
32970
|
+
"aria-hidden": "true"
|
32971
|
+
}, [AND_DELINEATOR.isEqual(key) ? '+' : t('$vuetify.hotkey.then')]);
|
32972
|
+
}
|
32973
|
+
useRender(() => vue.createElementVNode("div", {
|
32974
|
+
"class": vue.normalizeClass(['v-hotkey', {
|
32975
|
+
'v-hotkey--disabled': props.disabled,
|
32976
|
+
'v-hotkey--inline': props.inline,
|
32977
|
+
'v-hotkey--contained': isContainedVariant.value
|
32978
|
+
}, themeClasses.value, rtlClasses.value, variantClasses.value, props.class]),
|
32979
|
+
"style": vue.normalizeStyle(props.style),
|
32980
|
+
"role": "img",
|
32981
|
+
"aria-label": accessibleLabel.value
|
32982
|
+
}, [isContainedVariant.value ? vue.createVNode(VKbd, {
|
32983
|
+
"key": "contained",
|
32984
|
+
"class": vue.normalizeClass(['v-hotkey__contained-wrapper', borderClasses.value, roundedClasses.value, elevationClasses.value, colorClasses.value]),
|
32985
|
+
"style": vue.normalizeStyle(colorStyles.value),
|
32986
|
+
"aria-hidden": "true"
|
32987
|
+
}, {
|
32988
|
+
default: () => [props.prefix && vue.createElementVNode("span", {
|
32989
|
+
"key": "contained-prefix",
|
32990
|
+
"class": "v-hotkey__prefix"
|
32991
|
+
}, [props.prefix]), keyCombinations.value.map((combination, comboIndex) => vue.createElementVNode("span", {
|
32992
|
+
"class": "v-hotkey__combination",
|
32993
|
+
"key": comboIndex
|
32994
|
+
}, [combination.map((key, keyIndex) => isDelineator(key) ? renderDivider(key, keyIndex) : renderKey(key, keyIndex, true)), comboIndex < keyCombinations.value.length - 1 && vue.createElementVNode("span", {
|
32995
|
+
"aria-hidden": "true"
|
32996
|
+
}, [vue.createTextVNode("\xA0")])])), props.suffix && vue.createElementVNode("span", {
|
32997
|
+
"key": "contained-suffix",
|
32998
|
+
"class": "v-hotkey__suffix"
|
32999
|
+
}, [props.suffix])]
|
33000
|
+
}) : vue.createElementVNode(vue.Fragment, null, [props.prefix && vue.createElementVNode("span", {
|
33001
|
+
"key": "prefix",
|
33002
|
+
"class": "v-hotkey__prefix"
|
33003
|
+
}, [props.prefix]), keyCombinations.value.map((combination, comboIndex) => vue.createElementVNode("span", {
|
33004
|
+
"class": "v-hotkey__combination",
|
33005
|
+
"key": comboIndex
|
33006
|
+
}, [combination.map((key, keyIndex) => isDelineator(key) ? renderDivider(key, keyIndex) : renderKey(key, keyIndex, false)), comboIndex < keyCombinations.value.length - 1 && vue.createElementVNode("span", {
|
33007
|
+
"aria-hidden": "true"
|
33008
|
+
}, [vue.createTextVNode("\xA0")])])), props.suffix && vue.createElementVNode("span", {
|
33009
|
+
"key": "suffix",
|
33010
|
+
"class": "v-hotkey__suffix"
|
33011
|
+
}, [props.suffix])])]));
|
33012
|
+
}
|
33013
|
+
});
|
33014
|
+
|
32285
33015
|
var components = /*#__PURE__*/Object.freeze({
|
32286
33016
|
__proto__: null,
|
32287
33017
|
VAlert: VAlert,
|
@@ -32370,6 +33100,7 @@
|
|
32370
33100
|
VFileUploadItem: VFileUploadItem,
|
32371
33101
|
VFooter: VFooter,
|
32372
33102
|
VForm: VForm,
|
33103
|
+
VHotkey: VHotkey,
|
32373
33104
|
VHover: VHover,
|
32374
33105
|
VIcon: VIcon,
|
32375
33106
|
VIconBtn: VIconBtn,
|
@@ -32793,7 +33524,7 @@
|
|
32793
33524
|
};
|
32794
33525
|
});
|
32795
33526
|
}
|
32796
|
-
const version$1 = "3.9.0-beta.1-dev.2025-
|
33527
|
+
const version$1 = "3.9.0-beta.1-dev.2025-07-02";
|
32797
33528
|
createVuetify$1.version = version$1;
|
32798
33529
|
|
32799
33530
|
// Vue's inject() can only be used in setup
|
@@ -33091,7 +33822,7 @@
|
|
33091
33822
|
|
33092
33823
|
/* eslint-disable local-rules/sort-imports */
|
33093
33824
|
|
33094
|
-
const version = "3.9.0-beta.1-dev.2025-
|
33825
|
+
const version = "3.9.0-beta.1-dev.2025-07-02";
|
33095
33826
|
|
33096
33827
|
/* eslint-disable local-rules/sort-imports */
|
33097
33828
|
|
@@ -33112,6 +33843,7 @@
|
|
33112
33843
|
exports.useDefaults = useDefaults;
|
33113
33844
|
exports.useDisplay = useDisplay;
|
33114
33845
|
exports.useGoTo = useGoTo;
|
33846
|
+
exports.useHotkey = useHotkey;
|
33115
33847
|
exports.useLayout = useLayout;
|
33116
33848
|
exports.useLocale = useLocale;
|
33117
33849
|
exports.useRtl = useRtl;
|