vuetify 3.10.9 → 3.10.10

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 (57) hide show
  1. package/dist/json/attributes.json +3507 -3507
  2. package/dist/json/importMap-labs.json +22 -22
  3. package/dist/json/importMap.json +170 -170
  4. package/dist/json/web-types.json +6186 -6186
  5. package/dist/vuetify-labs.cjs +201 -213
  6. package/dist/vuetify-labs.css +5293 -5301
  7. package/dist/vuetify-labs.d.ts +79 -79
  8. package/dist/vuetify-labs.esm.js +201 -213
  9. package/dist/vuetify-labs.esm.js.map +1 -1
  10. package/dist/vuetify-labs.js +201 -213
  11. package/dist/vuetify-labs.min.css +2 -2
  12. package/dist/vuetify.cjs +133 -96
  13. package/dist/vuetify.cjs.map +1 -1
  14. package/dist/vuetify.css +3094 -3090
  15. package/dist/vuetify.d.ts +63 -63
  16. package/dist/vuetify.esm.js +133 -96
  17. package/dist/vuetify.esm.js.map +1 -1
  18. package/dist/vuetify.js +133 -96
  19. package/dist/vuetify.js.map +1 -1
  20. package/dist/vuetify.min.css +2 -2
  21. package/dist/vuetify.min.js +332 -328
  22. package/dist/vuetify.min.js.map +1 -1
  23. package/lib/components/VAvatar/VAvatar.css +1 -1
  24. package/lib/components/VAvatar/_variables.scss +1 -1
  25. package/lib/components/VBtnToggle/VBtnToggle.sass +1 -1
  26. package/lib/components/VCard/VCard.js +8 -1
  27. package/lib/components/VCard/VCard.js.map +1 -1
  28. package/lib/components/VDatePicker/VDatePicker.js +7 -16
  29. package/lib/components/VDatePicker/VDatePicker.js.map +1 -1
  30. package/lib/components/VTextField/VTextField.js +17 -7
  31. package/lib/components/VTextField/VTextField.js.map +1 -1
  32. package/lib/components/VTextarea/VTextarea.js +17 -7
  33. package/lib/components/VTextarea/VTextarea.js.map +1 -1
  34. package/lib/composables/calendar.d.ts +6 -0
  35. package/lib/composables/calendar.js +37 -2
  36. package/lib/composables/calendar.js.map +1 -1
  37. package/lib/composables/delay.js +3 -2
  38. package/lib/composables/delay.js.map +1 -1
  39. package/lib/composables/hotkey/hotkey.js +42 -53
  40. package/lib/composables/hotkey/hotkey.js.map +1 -1
  41. package/lib/entry-bundler.js +1 -1
  42. package/lib/entry-bundler.js.map +1 -1
  43. package/lib/framework.d.ts +63 -63
  44. package/lib/framework.js +1 -1
  45. package/lib/framework.js.map +1 -1
  46. package/lib/labs/VDateInput/VDateInput.js +8 -12
  47. package/lib/labs/VDateInput/VDateInput.js.map +1 -1
  48. package/lib/labs/VHotkey/VHotkey.css +4 -16
  49. package/lib/labs/VHotkey/VHotkey.d.ts +29 -29
  50. package/lib/labs/VHotkey/VHotkey.js +62 -106
  51. package/lib/labs/VHotkey/VHotkey.js.map +1 -1
  52. package/lib/labs/VHotkey/VHotkey.scss +8 -25
  53. package/lib/styles/main.css +4 -0
  54. package/lib/styles/settings/_variables.scss +1 -0
  55. package/lib/util/box.js +3 -8
  56. package/lib/util/box.js.map +1 -1
  57. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.10.9
2
+ * Vuetify v3.10.10
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
@@ -680,7 +680,8 @@ function getAxis(anchor) {
680
680
  class Box {
681
681
  constructor(args) {
682
682
  const pageScale = document.body.currentCSSZoom ?? 1;
683
- const factor = args instanceof DOMRect ? 1 + (1 - pageScale) / pageScale : 1;
683
+ const ignoreZoom = args.top === undefined; // detect DOMRect without breaking in jsdom
684
+ const factor = ignoreZoom ? 1 : 1 + (1 - pageScale) / pageScale;
684
685
  const {
685
686
  x,
686
687
  y,
@@ -750,13 +751,7 @@ function getElementBox(el) {
750
751
  });
751
752
  }
752
753
  } else {
753
- const rect = el.getBoundingClientRect();
754
- return new Box({
755
- x: rect.x,
756
- y: rect.y,
757
- width: el.clientWidth,
758
- height: el.clientHeight
759
- });
754
+ return new Box(el.getBoundingClientRect());
760
755
  }
761
756
  }
762
757
 
@@ -11325,9 +11320,10 @@ function useDelay(props, cb) {
11325
11320
  let clearDelay = () => {};
11326
11321
  function runDelay(isOpening, options) {
11327
11322
  clearDelay?.();
11328
- const delay = Math.max(options?.minDelay ?? 0, Number(isOpening ? props.openDelay : props.closeDelay));
11323
+ const delay = isOpening ? props.openDelay : props.closeDelay;
11324
+ const normalizedDelay = Math.max(options?.minDelay ?? 0, Number(delay ?? 0));
11329
11325
  return new Promise(resolve => {
11330
- clearDelay = defer(delay, () => {
11326
+ clearDelay = defer(normalizedDelay, () => {
11331
11327
  cb?.(isOpening);
11332
11328
  resolve(isOpening);
11333
11329
  });
@@ -12834,14 +12830,24 @@ const VTextField = genericComponent()({
12834
12830
  }
12835
12831
  function onInput(e) {
12836
12832
  const el = e.target;
12837
- model.value = el.value;
12838
- if (props.modelModifiers?.trim && ['text', 'search', 'password', 'tel', 'url'].includes(props.type)) {
12839
- const caretPosition = [el.selectionStart, el.selectionEnd];
12840
- nextTick(() => {
12841
- el.selectionStart = caretPosition[0];
12842
- el.selectionEnd = caretPosition[1];
12843
- });
12833
+ if (!(props.modelModifiers?.trim && ['text', 'search', 'password', 'tel', 'url'].includes(props.type))) {
12834
+ model.value = el.value;
12835
+ return;
12844
12836
  }
12837
+ const value = el.value;
12838
+ const start = el.selectionStart;
12839
+ const end = el.selectionEnd;
12840
+ model.value = value;
12841
+ nextTick(() => {
12842
+ let offset = 0;
12843
+ if (value.trimStart().length === el.value.length) {
12844
+ // #22307 - Whitespace has been removed from the
12845
+ // start, offset the caret position to compensate
12846
+ offset = value.length - el.value.length;
12847
+ }
12848
+ if (start != null) el.selectionStart = start - offset;
12849
+ if (end != null) el.selectionEnd = end - offset;
12850
+ });
12845
12851
  }
12846
12852
  useRender(() => {
12847
12853
  const hasCounter = !!(slots.counter || props.counter !== false && props.counter != null);
@@ -15568,6 +15574,12 @@ const VCard = genericComponent()({
15568
15574
  roundedClasses
15569
15575
  } = useRounded(props);
15570
15576
  const link = useLink(props, attrs);
15577
+ const loadingColor = shallowRef(undefined);
15578
+ watch(() => props.loading, (val, old) => {
15579
+ loadingColor.value = !val && typeof old === 'string' ? old : typeof val === 'boolean' ? undefined : val;
15580
+ }, {
15581
+ immediate: true
15582
+ });
15571
15583
  useRender(() => {
15572
15584
  const isLink = props.link !== false && link.isLink.value;
15573
15585
  const isClickable = !props.disabled && props.link !== false && (props.link || link.isClickable.value);
@@ -15610,7 +15622,7 @@ const VCard = genericComponent()({
15610
15622
  }, slots.image)]), createVNode(LoaderSlot, {
15611
15623
  "name": "v-card",
15612
15624
  "active": !!props.loading,
15613
- "color": typeof props.loading === 'boolean' ? undefined : props.loading
15625
+ "color": loadingColor.value
15614
15626
  }, {
15615
15627
  default: slots.loader
15616
15628
  }), hasCardItem && createVNode(VCardItem, {
@@ -19033,11 +19045,6 @@ function useHotkey(keys, callback) {
19033
19045
  let keyGroups;
19034
19046
  let isSequence = false;
19035
19047
  let groupIndex = 0;
19036
- function clearTimer() {
19037
- if (!timeout) return;
19038
- clearTimeout(timeout);
19039
- timeout = 0;
19040
- }
19041
19048
  function isInputFocused() {
19042
19049
  if (toValue(inputs)) return false;
19043
19050
  const activeElement = document.activeElement;
@@ -19045,12 +19052,12 @@ function useHotkey(keys, callback) {
19045
19052
  }
19046
19053
  function resetSequence() {
19047
19054
  groupIndex = 0;
19048
- clearTimer();
19055
+ clearTimeout(timeout);
19049
19056
  }
19050
19057
  function handler(e) {
19051
19058
  const group = keyGroups[groupIndex];
19052
19059
  if (!group || isInputFocused()) return;
19053
- if (!matchesKeyGroup(e, group)) {
19060
+ if (!matchesKeyGroup(e, group, isMac)) {
19054
19061
  if (isSequence) resetSequence();
19055
19062
  return;
19056
19063
  }
@@ -19059,7 +19066,7 @@ function useHotkey(keys, callback) {
19059
19066
  callback(e);
19060
19067
  return;
19061
19068
  }
19062
- clearTimer();
19069
+ clearTimeout(timeout);
19063
19070
  groupIndex++;
19064
19071
  if (groupIndex === keyGroups.length) {
19065
19072
  callback(e);
@@ -19070,12 +19077,12 @@ function useHotkey(keys, callback) {
19070
19077
  }
19071
19078
  function cleanup() {
19072
19079
  window.removeEventListener(toValue(event), handler);
19073
- clearTimer();
19080
+ clearTimeout(timeout);
19074
19081
  }
19075
- watch(() => toValue(keys), function (unrefKeys) {
19082
+ watch(() => toValue(keys), newKeys => {
19076
19083
  cleanup();
19077
- if (unrefKeys) {
19078
- const groups = splitKeySequence(unrefKeys.toLowerCase());
19084
+ if (newKeys) {
19085
+ const groups = splitKeySequence(newKeys.toLowerCase());
19079
19086
  isSequence = groups.length > 1;
19080
19087
  keyGroups = groups;
19081
19088
  resetSequence();
@@ -19086,55 +19093,50 @@ function useHotkey(keys, callback) {
19086
19093
  });
19087
19094
 
19088
19095
  // Watch for changes in the event type to re-register the listener
19089
- watch(() => toValue(event), function (newEvent, oldEvent) {
19096
+ watch(() => toValue(event), (newEvent, oldEvent) => {
19090
19097
  if (oldEvent && keyGroups && keyGroups.length > 0) {
19091
19098
  window.removeEventListener(oldEvent, handler);
19092
19099
  window.addEventListener(newEvent, handler);
19093
19100
  }
19094
19101
  });
19095
- try {
19096
- getCurrentInstance('useHotkey');
19097
- onBeforeUnmount(cleanup);
19098
- } catch {
19099
- // Not in Vue setup context
19100
- }
19101
- function parseKeyGroup(group) {
19102
- const MODIFIERS = ['ctrl', 'shift', 'alt', 'meta', 'cmd'];
19102
+ onScopeDispose(cleanup, true);
19103
+ return cleanup;
19104
+ }
19105
+ function matchesKeyGroup(e, group, isMac) {
19106
+ const {
19107
+ modifiers,
19108
+ actualKey
19109
+ } = parseKeyGroup(group);
19110
+ const expectCtrl = modifiers.ctrl || !isMac && (modifiers.cmd || modifiers.meta);
19111
+ const expectMeta = isMac && (modifiers.cmd || modifiers.meta);
19112
+ return e.ctrlKey === expectCtrl && e.metaKey === expectMeta && e.shiftKey === modifiers.shift && e.altKey === modifiers.alt && e.key.toLowerCase() === actualKey?.toLowerCase();
19113
+ }
19114
+ function parseKeyGroup(group) {
19115
+ const MODIFIERS = ['ctrl', 'shift', 'alt', 'meta', 'cmd'];
19103
19116
 
19104
- // Use the shared combination splitting logic
19105
- const parts = splitKeyCombination(group.toLowerCase());
19117
+ // Use the shared combination splitting logic
19118
+ const parts = splitKeyCombination(group.toLowerCase());
19106
19119
 
19107
- // If the combination is invalid, return empty result
19108
- if (parts.length === 0) {
19109
- return {
19110
- modifiers: Object.fromEntries(MODIFIERS.map(m => [m, false])),
19111
- actualKey: undefined
19112
- };
19113
- }
19114
- const modifiers = Object.fromEntries(MODIFIERS.map(m => [m, false]));
19115
- let actualKey;
19116
- for (const part of parts) {
19117
- if (MODIFIERS.includes(part)) {
19118
- modifiers[part] = true;
19119
- } else {
19120
- actualKey = part;
19121
- }
19122
- }
19120
+ // If the combination is invalid, return empty result
19121
+ if (parts.length === 0) {
19123
19122
  return {
19124
- modifiers,
19125
- actualKey
19123
+ modifiers: Object.fromEntries(MODIFIERS.map(m => [m, false])),
19124
+ actualKey: undefined
19126
19125
  };
19127
19126
  }
19128
- function matchesKeyGroup(e, group) {
19129
- const {
19130
- modifiers,
19131
- actualKey
19132
- } = parseKeyGroup(group);
19133
- const expectCtrl = modifiers.ctrl || !isMac && (modifiers.cmd || modifiers.meta);
19134
- const expectMeta = isMac && (modifiers.cmd || modifiers.meta);
19135
- return e.ctrlKey === expectCtrl && e.metaKey === expectMeta && e.shiftKey === modifiers.shift && e.altKey === modifiers.alt && e.key.toLowerCase() === actualKey?.toLowerCase();
19127
+ const modifiers = Object.fromEntries(MODIFIERS.map(m => [m, false]));
19128
+ let actualKey;
19129
+ for (const part of parts) {
19130
+ if (MODIFIERS.includes(part)) {
19131
+ modifiers[part] = true;
19132
+ } else {
19133
+ actualKey = part;
19134
+ }
19136
19135
  }
19137
- return cleanup;
19136
+ return {
19137
+ modifiers,
19138
+ actualKey
19139
+ };
19138
19140
  }
19139
19141
 
19140
19142
  // Utilities
@@ -23764,11 +23766,15 @@ function useCalendar(props) {
23764
23766
  return week.length ? adapter.getWeek(week[0], props.firstDayOfWeek, props.firstDayOfYear) : null;
23765
23767
  });
23766
23768
  });
23769
+ const {
23770
+ minDate,
23771
+ maxDate
23772
+ } = useCalendarRange(props);
23767
23773
  function isDisabled(value) {
23768
23774
  if (props.disabled) return true;
23769
23775
  const date = adapter.date(value);
23770
- if (props.min && adapter.isBefore(adapter.endOfDay(date), adapter.date(props.min))) return true;
23771
- if (props.max && adapter.isAfter(date, adapter.date(props.max))) return true;
23776
+ if (minDate.value && adapter.isBefore(adapter.endOfDay(date), minDate.value)) return true;
23777
+ if (maxDate.value && adapter.isAfter(date, maxDate.value)) return true;
23772
23778
  if (Array.isArray(props.allowedDates) && props.allowedDates.length > 0) {
23773
23779
  return !props.allowedDates.some(d => adapter.isSameDay(adapter.date(d), date));
23774
23780
  }
@@ -23788,6 +23794,37 @@ function useCalendar(props) {
23788
23794
  weekNumbers
23789
23795
  };
23790
23796
  }
23797
+ function useCalendarRange(props) {
23798
+ const adapter = useDate();
23799
+ const minDate = computed(() => {
23800
+ if (!props.min) return null;
23801
+ const date = adapter.date(props.min);
23802
+ return adapter.isValid(date) ? date : null;
23803
+ });
23804
+ const maxDate = computed(() => {
23805
+ if (!props.max) return null;
23806
+ const date = adapter.date(props.max);
23807
+ return adapter.isValid(date) ? date : null;
23808
+ });
23809
+ function clampDate(date) {
23810
+ if (minDate.value && adapter.isBefore(date, minDate.value)) {
23811
+ return minDate.value;
23812
+ }
23813
+ if (maxDate.value && adapter.isAfter(date, maxDate.value)) {
23814
+ return maxDate.value;
23815
+ }
23816
+ return date;
23817
+ }
23818
+ function isInAllowedRange(date) {
23819
+ return (!minDate.value || adapter.isAfter(date, minDate.value)) && (!maxDate.value || adapter.isBefore(date, maxDate.value));
23820
+ }
23821
+ return {
23822
+ minDate,
23823
+ maxDate,
23824
+ clampDate,
23825
+ isInAllowedRange
23826
+ };
23827
+ }
23791
23828
 
23792
23829
  // Types
23793
23830
 
@@ -24228,24 +24265,14 @@ const VDatePicker = genericComponent()({
24228
24265
  const viewMode = useProxiedModel(props, 'viewMode');
24229
24266
  // const inputMode = useProxiedModel(props, 'inputMode')
24230
24267
 
24231
- const minDate = computed(() => {
24232
- const date = adapter.date(props.min);
24233
- return props.min && adapter.isValid(date) ? date : null;
24234
- });
24235
- const maxDate = computed(() => {
24236
- const date = adapter.date(props.max);
24237
- return props.max && adapter.isValid(date) ? date : null;
24238
- });
24268
+ const {
24269
+ minDate,
24270
+ maxDate,
24271
+ clampDate
24272
+ } = useCalendarRange(props);
24239
24273
  const internal = computed(() => {
24240
24274
  const today = adapter.date();
24241
- let value = today;
24242
- if (model.value?.[0]) {
24243
- value = adapter.date(model.value[0]);
24244
- } else if (minDate.value && adapter.isBefore(today, minDate.value)) {
24245
- value = minDate.value;
24246
- } else if (maxDate.value && adapter.isAfter(today, maxDate.value)) {
24247
- value = maxDate.value;
24248
- }
24275
+ const value = model.value?.[0] ? adapter.date(model.value[0]) : clampDate(today);
24249
24276
  return value && adapter.isValid(value) ? value : today;
24250
24277
  });
24251
24278
  const headerColor = toRef(() => props.headerColor ?? props.color);
@@ -30032,14 +30059,24 @@ const VTextarea = genericComponent()({
30032
30059
  }
30033
30060
  function onInput(e) {
30034
30061
  const el = e.target;
30035
- model.value = el.value;
30036
- if (props.modelModifiers?.trim) {
30037
- const caretPosition = [el.selectionStart, el.selectionEnd];
30038
- nextTick(() => {
30039
- el.selectionStart = caretPosition[0];
30040
- el.selectionEnd = caretPosition[1];
30041
- });
30062
+ if (!props.modelModifiers?.trim) {
30063
+ model.value = el.value;
30064
+ return;
30042
30065
  }
30066
+ const value = el.value;
30067
+ const start = el.selectionStart;
30068
+ const end = el.selectionEnd;
30069
+ model.value = value;
30070
+ nextTick(() => {
30071
+ let offset = 0;
30072
+ if (value.trimStart().length === el.value.length) {
30073
+ // #22307 - Whitespace has been removed from the
30074
+ // start, offset the caret position to compensate
30075
+ offset = value.length - el.value.length;
30076
+ }
30077
+ if (start != null) el.selectionStart = start - offset;
30078
+ if (end != null) el.selectionEnd = end - offset;
30079
+ });
30043
30080
  }
30044
30081
  const sizerRef = ref();
30045
30082
  const rows = ref(Number(props.rows));
@@ -34838,15 +34875,10 @@ const VDateInput = genericComponent()({
34838
34875
  const {
34839
34876
  mobile
34840
34877
  } = useDisplay(props);
34841
- const clamp = date => {
34842
- if (props.max && adapter.isAfter(date, props.max)) {
34843
- return props.max;
34844
- }
34845
- if (props.min && adapter.isBefore(date, props.min)) {
34846
- return props.min;
34847
- }
34848
- return date;
34849
- };
34878
+ const {
34879
+ clampDate,
34880
+ isInAllowedRange
34881
+ } = useCalendarRange(props);
34850
34882
  const emptyModelValue = () => props.multiple ? [] : null;
34851
34883
  const model = useProxiedModel(props, 'modelValue', emptyModelValue(), val => Array.isArray(val) ? val.map(item => adapter.toJsDate(item)) : val ? adapter.toJsDate(val) : val, val => Array.isArray(val) ? val.map(item => adapter.date(item)) : val ? adapter.date(val) : val);
34852
34884
  const menu = useProxiedModel(props, 'menu');
@@ -34942,16 +34974,16 @@ const VDateInput = genericComponent()({
34942
34974
  model.value = emptyModelValue();
34943
34975
  } else if (!props.multiple) {
34944
34976
  if (isValid(value)) {
34945
- model.value = clamp(parseDate(value));
34977
+ model.value = clampDate(parseDate(value));
34946
34978
  }
34947
34979
  } else {
34948
34980
  const parts = value.trim().split(/\D+-\D+|[^\d\-/.]+/);
34949
34981
  if (parts.every(isValid)) {
34950
34982
  if (props.multiple === 'range') {
34951
- const [start, stop] = parts.map(parseDate).map(clamp).toSorted((a, b) => adapter.isAfter(a, b) ? 1 : -1);
34983
+ const [start, stop] = parts.map(parseDate).map(clampDate).toSorted((a, b) => adapter.isAfter(a, b) ? 1 : -1);
34952
34984
  model.value = createDateRange(adapter, start, stop);
34953
34985
  } else {
34954
- model.value = parts.map(parseDate).map(clamp);
34986
+ model.value = parts.map(parseDate).filter(isInAllowedRange);
34955
34987
  }
34956
34988
  }
34957
34989
  }
@@ -36565,7 +36597,7 @@ const VPullToRefresh = genericComponent()({
36565
36597
 
36566
36598
  // Key display tuple: [mode, content] where content is string or IconValue
36567
36599
 
36568
- // Key tuple: [mode, content] where content is string or IconValue
36600
+ // Key tuple: [mode, content, keycode] where content is string or IconValue
36569
36601
 
36570
36602
  function processKey(config, requestedMode, isMac) {
36571
36603
  const keyCfg = isMac && config.mac ? config.mac : config.default;
@@ -36704,15 +36736,6 @@ const hotkeyMap = {
36704
36736
  }
36705
36737
  }
36706
36738
  };
36707
-
36708
- // Create custom variant props that extend the base variant props with our 'contained' option
36709
- const makeVHotkeyVariantProps = propsFactory({
36710
- variant: {
36711
- type: String,
36712
- default: 'elevated',
36713
- validator: v => ['elevated', 'flat', 'tonal', 'outlined', 'text', 'plain', 'contained'].includes(v)
36714
- }
36715
- }, 'VHotkeyVariant');
36716
36739
  const makeVHotkeyProps = propsFactory({
36717
36740
  // String representing keyboard shortcuts (e.g., "ctrl+k", "meta+shift+p")
36718
36741
  keys: String,
@@ -36734,30 +36757,21 @@ const makeVHotkeyProps = propsFactory({
36734
36757
  disabled: Boolean,
36735
36758
  prefix: String,
36736
36759
  suffix: String,
36760
+ variant: {
36761
+ type: String,
36762
+ default: 'elevated',
36763
+ validator: v => ['elevated', 'flat', 'tonal', 'outlined', 'text', 'plain', 'contained'].includes(v)
36764
+ },
36737
36765
  ...makeComponentProps(),
36738
36766
  ...makeThemeProps(),
36739
36767
  ...makeBorderProps(),
36740
36768
  ...makeRoundedProps(),
36741
36769
  ...makeElevationProps(),
36742
- ...makeVHotkeyVariantProps(),
36743
36770
  color: String
36744
36771
  }, 'VHotkey');
36745
- class Delineator {
36746
- constructor(delineator) {
36747
- if (['and', 'then'].includes(delineator)) this.val = delineator;else {
36748
- throw new Error('Not a valid delineator');
36749
- }
36750
- }
36751
- isEqual(d) {
36752
- return this.val === d.val;
36753
- }
36754
- }
36755
- function isDelineator(value) {
36756
- return value instanceof Delineator;
36757
- }
36758
- function isString(value) {
36759
- return typeof value === 'string';
36760
- }
36772
+ const AND_DELINEATOR = Symbol('VHotkey:AND_DELINEATOR'); // For + separators
36773
+ const THEN_DELINEATOR = Symbol('VHotkey:THEN_DELINEATOR'); // For - separators
36774
+
36761
36775
  function getKeyText(keyMap, key, isMac) {
36762
36776
  const lowerKey = key.toLowerCase();
36763
36777
  if (lowerKey in keyMap) {
@@ -36799,57 +36813,38 @@ const VHotkey = genericComponent()({
36799
36813
  const {
36800
36814
  elevationClasses
36801
36815
  } = useElevation(props);
36802
- const isContainedVariant = computed(() => props.variant === 'contained');
36803
- const effectiveVariantProps = computed(() => ({
36804
- ...props,
36805
- variant: isContainedVariant.value ? 'elevated' : props.variant
36806
- }));
36807
36816
  const {
36808
36817
  colorClasses,
36809
36818
  colorStyles,
36810
36819
  variantClasses
36811
- } = useVariant(effectiveVariantProps);
36820
+ } = useVariant(() => ({
36821
+ color: props.color,
36822
+ variant: props.variant === 'contained' ? 'elevated' : props.variant
36823
+ }));
36812
36824
  const isMac = computed(() => props.platform === 'auto' ? typeof navigator !== 'undefined' && /macintosh/i.test(navigator.userAgent) : props.platform === 'mac');
36813
- const effectiveDisplayMode = computed(() => props.displayMode);
36814
- const AND_DELINEATOR = new Delineator('and'); // For + separators
36815
- const THEN_DELINEATOR = new Delineator('then'); // For - separators
36816
-
36817
- const effectiveKeyMap = computed(() => props.keyMap);
36818
36825
  const keyCombinations = computed(() => {
36819
36826
  if (!props.keys) return [];
36820
36827
 
36821
36828
  // Split by spaces to handle multiple key combinations
36822
36829
  // Example: "ctrl+k meta+p" -> ["ctrl+k", "meta+p"]
36823
36830
  return props.keys.split(' ').map(combination => {
36824
- // Use the shared sequence splitting logic
36831
+ const result = [];
36825
36832
  const sequenceGroups = splitKeySequence(combination);
36826
-
36827
- // Process each sequence group
36828
- return sequenceGroups.flatMap((group, groupIndex) => {
36829
- // Use the shared key combination splitting logic
36830
- const keyParts = splitKeyCombination(group);
36831
- const parts = keyParts.reduce((acc, part, index) => {
36832
- if (index !== 0) {
36833
- // Add AND delineator between keys
36834
- return [...acc, AND_DELINEATOR, part];
36835
- }
36836
- return [...acc, part];
36837
- }, []);
36833
+ for (let i = 0; i < sequenceGroups.length; i++) {
36834
+ const group = sequenceGroups[i];
36838
36835
 
36839
36836
  // Add THEN delineator between sequence groups
36840
- const result = parts.map(key => {
36841
- if (isString(key)) {
36842
- return applyDisplayModeToKey(effectiveKeyMap.value, effectiveDisplayMode.value, key, isMac.value);
36843
- }
36844
- return key;
36845
- });
36837
+ if (i > 0) result.push(THEN_DELINEATOR);
36838
+ const keyParts = splitKeyCombination(group);
36839
+ for (let j = 0; j < keyParts.length; j++) {
36840
+ const part = keyParts[j];
36846
36841
 
36847
- // Add sequence separator if not the last group
36848
- if (groupIndex < sequenceGroups.length - 1) {
36849
- result.push(THEN_DELINEATOR);
36842
+ // Add AND delineator between keys
36843
+ if (j > 0) result.push(AND_DELINEATOR);
36844
+ result.push(applyDisplayModeToKey(props.keyMap, props.displayMode, part, isMac.value));
36850
36845
  }
36851
- return result;
36852
- });
36846
+ }
36847
+ return result;
36853
36848
  });
36854
36849
  });
36855
36850
  const accessibleLabel = computed(() => {
@@ -36859,16 +36854,16 @@ const VHotkey = genericComponent()({
36859
36854
  const readableShortcuts = keyCombinations.value.map(combination => {
36860
36855
  const readableParts = [];
36861
36856
  for (const key of combination) {
36862
- if (isDelineator(key)) {
36863
- if (AND_DELINEATOR.isEqual(key)) {
36864
- readableParts.push(t('$vuetify.hotkey.plus'));
36865
- } else if (THEN_DELINEATOR.isEqual(key)) {
36866
- readableParts.push(t('$vuetify.hotkey.then'));
36867
- }
36868
- } else {
36857
+ if (Array.isArray(key)) {
36869
36858
  // Always use text representation for screen readers
36870
36859
  const textKey = key[0] === 'icon' || key[0] === 'symbol' ? applyDisplayModeToKey(mergeDeep(hotkeyMap, props.keyMap), 'text', String(key[1]), isMac.value)[1] : key[1];
36871
36860
  readableParts.push(translateKey(textKey));
36861
+ } else {
36862
+ if (key === AND_DELINEATOR) {
36863
+ readableParts.push(t('$vuetify.hotkey.plus'));
36864
+ } else if (key === THEN_DELINEATOR) {
36865
+ readableParts.push(t('$vuetify.hotkey.then'));
36866
+ }
36872
36867
  }
36873
36868
  }
36874
36869
  return readableParts.join(' ');
@@ -36880,11 +36875,12 @@ const VHotkey = genericComponent()({
36880
36875
  return key.startsWith('$vuetify.') ? t(key) : key;
36881
36876
  }
36882
36877
  function getKeyTooltip(key) {
36883
- if (effectiveDisplayMode.value === 'text') return undefined;
36884
- const textKey = getKeyText(effectiveKeyMap.value, String(key[2]), isMac.value);
36878
+ if (props.displayMode === 'text') return undefined;
36879
+ const textKey = getKeyText(props.keyMap, String(key[2]), isMac.value);
36885
36880
  return translateKey(textKey);
36886
36881
  }
36887
- function renderKey(key, keyIndex, isContained) {
36882
+ function renderKey(key, keyIndex) {
36883
+ const isContained = props.variant === 'contained';
36888
36884
  const KeyComponent = isContained ? 'kbd' : VKbd;
36889
36885
  const keyClasses = ['v-hotkey__key', `v-hotkey__key-${key[0]}`, ...(isContained ? ['v-hotkey__key--nested'] : [borderClasses.value, roundedClasses.value, elevationClasses.value, colorClasses.value])];
36890
36886
  return createVNode(KeyComponent, {
@@ -36905,47 +36901,39 @@ const VHotkey = genericComponent()({
36905
36901
  "key": keyIndex,
36906
36902
  "class": "v-hotkey__divider",
36907
36903
  "aria-hidden": "true"
36908
- }, [AND_DELINEATOR.isEqual(key) ? '+' : t('$vuetify.hotkey.then')]);
36904
+ }, [key === AND_DELINEATOR ? '+' : t('$vuetify.hotkey.then')]);
36909
36905
  }
36910
- useRender(() => createElementVNode("div", {
36911
- "class": normalizeClass(['v-hotkey', {
36912
- 'v-hotkey--disabled': props.disabled,
36913
- 'v-hotkey--inline': props.inline,
36914
- 'v-hotkey--contained': isContainedVariant.value
36915
- }, themeClasses.value, rtlClasses.value, variantClasses.value, props.class]),
36916
- "style": normalizeStyle(props.style),
36917
- "role": "img",
36918
- "aria-label": accessibleLabel.value
36919
- }, [isContainedVariant.value ? createVNode(VKbd, {
36920
- "key": "contained",
36921
- "class": normalizeClass(['v-hotkey__contained-wrapper', borderClasses.value, roundedClasses.value, elevationClasses.value, colorClasses.value]),
36922
- "style": normalizeStyle(colorStyles.value),
36923
- "aria-hidden": "true"
36924
- }, {
36925
- default: () => [props.prefix && createElementVNode("span", {
36926
- "key": "contained-prefix",
36906
+ useRender(() => {
36907
+ const content = createElementVNode(Fragment, null, [props.prefix && createElementVNode("span", {
36908
+ "key": "prefix",
36927
36909
  "class": "v-hotkey__prefix"
36928
36910
  }, [props.prefix]), keyCombinations.value.map((combination, comboIndex) => createElementVNode("span", {
36929
36911
  "class": "v-hotkey__combination",
36930
36912
  "key": comboIndex
36931
- }, [combination.map((key, keyIndex) => isDelineator(key) ? renderDivider(key, keyIndex) : renderKey(key, keyIndex, true)), comboIndex < keyCombinations.value.length - 1 && createElementVNode("span", {
36913
+ }, [combination.map((key, keyIndex) => Array.isArray(key) ? renderKey(key, keyIndex) : renderDivider(key, keyIndex)), comboIndex < keyCombinations.value.length - 1 && createElementVNode("span", {
36932
36914
  "aria-hidden": "true"
36933
36915
  }, [createTextVNode("\xA0")])])), props.suffix && createElementVNode("span", {
36934
- "key": "contained-suffix",
36916
+ "key": "suffix",
36935
36917
  "class": "v-hotkey__suffix"
36936
- }, [props.suffix])]
36937
- }) : createElementVNode(Fragment, null, [props.prefix && createElementVNode("span", {
36938
- "key": "prefix",
36939
- "class": "v-hotkey__prefix"
36940
- }, [props.prefix]), keyCombinations.value.map((combination, comboIndex) => createElementVNode("span", {
36941
- "class": "v-hotkey__combination",
36942
- "key": comboIndex
36943
- }, [combination.map((key, keyIndex) => isDelineator(key) ? renderDivider(key, keyIndex) : renderKey(key, keyIndex, false)), comboIndex < keyCombinations.value.length - 1 && createElementVNode("span", {
36944
- "aria-hidden": "true"
36945
- }, [createTextVNode("\xA0")])])), props.suffix && createElementVNode("span", {
36946
- "key": "suffix",
36947
- "class": "v-hotkey__suffix"
36948
- }, [props.suffix])])]));
36918
+ }, [props.suffix])]);
36919
+ return createElementVNode("div", {
36920
+ "class": normalizeClass(['v-hotkey', {
36921
+ 'v-hotkey--disabled': props.disabled,
36922
+ 'v-hotkey--inline': props.inline,
36923
+ 'v-hotkey--contained': props.variant === 'contained'
36924
+ }, themeClasses.value, rtlClasses.value, variantClasses.value, props.class]),
36925
+ "style": normalizeStyle(props.style),
36926
+ "role": "img",
36927
+ "aria-label": accessibleLabel.value
36928
+ }, [props.variant !== 'contained' ? content : createVNode(VKbd, {
36929
+ "key": "contained",
36930
+ "class": normalizeClass(['v-hotkey__contained-wrapper', borderClasses.value, roundedClasses.value, elevationClasses.value, colorClasses.value]),
36931
+ "style": normalizeStyle(colorStyles.value),
36932
+ "aria-hidden": "true"
36933
+ }, {
36934
+ default: () => [content]
36935
+ })]);
36936
+ });
36949
36937
  }
36950
36938
  });
36951
36939
 
@@ -38151,7 +38139,7 @@ function createVuetify$1() {
38151
38139
  };
38152
38140
  });
38153
38141
  }
38154
- const version$1 = "3.10.9";
38142
+ const version$1 = "3.10.10";
38155
38143
  createVuetify$1.version = version$1;
38156
38144
 
38157
38145
  // Vue's inject() can only be used in setup
@@ -38449,7 +38437,7 @@ var index = /*#__PURE__*/Object.freeze({
38449
38437
 
38450
38438
  /* eslint-disable local-rules/sort-imports */
38451
38439
 
38452
- const version = "3.10.9";
38440
+ const version = "3.10.10";
38453
38441
 
38454
38442
  /* eslint-disable local-rules/sort-imports */
38455
38443