vuetify 3.10.8 → 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 (68) hide show
  1. package/dist/json/attributes.json +1543 -1543
  2. package/dist/json/importMap-labs.json +18 -18
  3. package/dist/json/importMap.json +174 -174
  4. package/dist/json/web-types.json +2937 -2937
  5. package/dist/vuetify-labs.cjs +205 -216
  6. package/dist/vuetify-labs.css +4754 -4730
  7. package/dist/vuetify-labs.d.ts +72 -72
  8. package/dist/vuetify-labs.esm.js +205 -216
  9. package/dist/vuetify-labs.esm.js.map +1 -1
  10. package/dist/vuetify-labs.js +205 -216
  11. package/dist/vuetify-labs.min.css +2 -2
  12. package/dist/vuetify.cjs +137 -99
  13. package/dist/vuetify.cjs.map +1 -1
  14. package/dist/vuetify.css +2766 -2730
  15. package/dist/vuetify.d.ts +56 -56
  16. package/dist/vuetify.esm.js +137 -99
  17. package/dist/vuetify.esm.js.map +1 -1
  18. package/dist/vuetify.js +137 -99
  19. package/dist/vuetify.js.map +1 -1
  20. package/dist/vuetify.min.css +2 -2
  21. package/dist/vuetify.min.js +334 -330
  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.css +21 -0
  26. package/lib/components/VBtnToggle/VBtnToggle.sass +22 -0
  27. package/lib/components/VCard/VCard.js +8 -1
  28. package/lib/components/VCard/VCard.js.map +1 -1
  29. package/lib/components/VDatePicker/VDatePicker.js +7 -16
  30. package/lib/components/VDatePicker/VDatePicker.js.map +1 -1
  31. package/lib/components/VList/VList.css +6 -0
  32. package/lib/components/VList/VList.sass +6 -0
  33. package/lib/components/VList/VListItem.css +0 -3
  34. package/lib/components/VList/VListItem.sass +0 -4
  35. package/lib/components/VOverlay/useActivator.js +2 -1
  36. package/lib/components/VOverlay/useActivator.js.map +1 -1
  37. package/lib/components/VTabs/VTab.css +8 -0
  38. package/lib/components/VTabs/VTab.sass +7 -0
  39. package/lib/components/VTextField/VTextField.js +17 -7
  40. package/lib/components/VTextField/VTextField.js.map +1 -1
  41. package/lib/components/VTextarea/VTextarea.js +17 -7
  42. package/lib/components/VTextarea/VTextarea.js.map +1 -1
  43. package/lib/composables/calendar.d.ts +6 -0
  44. package/lib/composables/calendar.js +37 -2
  45. package/lib/composables/calendar.js.map +1 -1
  46. package/lib/composables/delay.js +3 -2
  47. package/lib/composables/delay.js.map +1 -1
  48. package/lib/composables/hotkey/hotkey.js +42 -53
  49. package/lib/composables/hotkey/hotkey.js.map +1 -1
  50. package/lib/entry-bundler.js +1 -1
  51. package/lib/entry-bundler.js.map +1 -1
  52. package/lib/framework.d.ts +56 -56
  53. package/lib/framework.js +1 -1
  54. package/lib/framework.js.map +1 -1
  55. package/lib/labs/VDateInput/VDateInput.js +8 -12
  56. package/lib/labs/VDateInput/VDateInput.js.map +1 -1
  57. package/lib/labs/VHotkey/VHotkey.css +4 -16
  58. package/lib/labs/VHotkey/VHotkey.d.ts +29 -29
  59. package/lib/labs/VHotkey/VHotkey.js +62 -106
  60. package/lib/labs/VHotkey/VHotkey.js.map +1 -1
  61. package/lib/labs/VHotkey/VHotkey.scss +8 -25
  62. package/lib/styles/main.css +4 -0
  63. package/lib/styles/settings/_variables.scss +1 -0
  64. package/lib/util/box.js +3 -8
  65. package/lib/util/box.js.map +1 -1
  66. package/lib/util/throttle.js +2 -2
  67. package/lib/util/throttle.js.map +1 -1
  68. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.10.8
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
 
@@ -1794,7 +1789,7 @@ function throttle(fn, delay) {
1794
1789
  const elapsed = now - Math.max(start, lastExec);
1795
1790
  function invoke() {
1796
1791
  lastExec = Date.now();
1797
- timeoutId = window.setTimeout(clear, delay);
1792
+ timeoutId = setTimeout(clear, delay);
1798
1793
  fn(...args);
1799
1794
  }
1800
1795
  if (!throttling) {
@@ -1805,7 +1800,7 @@ function throttle(fn, delay) {
1805
1800
  } else if (elapsed >= delay) {
1806
1801
  invoke();
1807
1802
  } else if (options.trailing) {
1808
- timeoutId = window.setTimeout(invoke, delay - elapsed);
1803
+ timeoutId = setTimeout(invoke, delay - elapsed);
1809
1804
  }
1810
1805
  };
1811
1806
  wrap.clear = clear;
@@ -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
  });
@@ -11455,7 +11451,8 @@ function useActivator(props, _ref) {
11455
11451
  };
11456
11452
  }
11457
11453
  if (openOnFocus.value) {
11458
- events.onFocusin = () => {
11454
+ events.onFocusin = e => {
11455
+ if (!e.target.matches(':focus-visible')) return;
11459
11456
  isFocused = true;
11460
11457
  runOpenDelay();
11461
11458
  };
@@ -12833,14 +12830,24 @@ const VTextField = genericComponent()({
12833
12830
  }
12834
12831
  function onInput(e) {
12835
12832
  const el = e.target;
12836
- model.value = el.value;
12837
- if (props.modelModifiers?.trim && ['text', 'search', 'password', 'tel', 'url'].includes(props.type)) {
12838
- const caretPosition = [el.selectionStart, el.selectionEnd];
12839
- nextTick(() => {
12840
- el.selectionStart = caretPosition[0];
12841
- el.selectionEnd = caretPosition[1];
12842
- });
12833
+ if (!(props.modelModifiers?.trim && ['text', 'search', 'password', 'tel', 'url'].includes(props.type))) {
12834
+ model.value = el.value;
12835
+ return;
12843
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
+ });
12844
12851
  }
12845
12852
  useRender(() => {
12846
12853
  const hasCounter = !!(slots.counter || props.counter !== false && props.counter != null);
@@ -15567,6 +15574,12 @@ const VCard = genericComponent()({
15567
15574
  roundedClasses
15568
15575
  } = useRounded(props);
15569
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
+ });
15570
15583
  useRender(() => {
15571
15584
  const isLink = props.link !== false && link.isLink.value;
15572
15585
  const isClickable = !props.disabled && props.link !== false && (props.link || link.isClickable.value);
@@ -15609,7 +15622,7 @@ const VCard = genericComponent()({
15609
15622
  }, slots.image)]), createVNode(LoaderSlot, {
15610
15623
  "name": "v-card",
15611
15624
  "active": !!props.loading,
15612
- "color": typeof props.loading === 'boolean' ? undefined : props.loading
15625
+ "color": loadingColor.value
15613
15626
  }, {
15614
15627
  default: slots.loader
15615
15628
  }), hasCardItem && createVNode(VCardItem, {
@@ -19032,11 +19045,6 @@ function useHotkey(keys, callback) {
19032
19045
  let keyGroups;
19033
19046
  let isSequence = false;
19034
19047
  let groupIndex = 0;
19035
- function clearTimer() {
19036
- if (!timeout) return;
19037
- clearTimeout(timeout);
19038
- timeout = 0;
19039
- }
19040
19048
  function isInputFocused() {
19041
19049
  if (toValue(inputs)) return false;
19042
19050
  const activeElement = document.activeElement;
@@ -19044,12 +19052,12 @@ function useHotkey(keys, callback) {
19044
19052
  }
19045
19053
  function resetSequence() {
19046
19054
  groupIndex = 0;
19047
- clearTimer();
19055
+ clearTimeout(timeout);
19048
19056
  }
19049
19057
  function handler(e) {
19050
19058
  const group = keyGroups[groupIndex];
19051
19059
  if (!group || isInputFocused()) return;
19052
- if (!matchesKeyGroup(e, group)) {
19060
+ if (!matchesKeyGroup(e, group, isMac)) {
19053
19061
  if (isSequence) resetSequence();
19054
19062
  return;
19055
19063
  }
@@ -19058,7 +19066,7 @@ function useHotkey(keys, callback) {
19058
19066
  callback(e);
19059
19067
  return;
19060
19068
  }
19061
- clearTimer();
19069
+ clearTimeout(timeout);
19062
19070
  groupIndex++;
19063
19071
  if (groupIndex === keyGroups.length) {
19064
19072
  callback(e);
@@ -19069,12 +19077,12 @@ function useHotkey(keys, callback) {
19069
19077
  }
19070
19078
  function cleanup() {
19071
19079
  window.removeEventListener(toValue(event), handler);
19072
- clearTimer();
19080
+ clearTimeout(timeout);
19073
19081
  }
19074
- watch(() => toValue(keys), function (unrefKeys) {
19082
+ watch(() => toValue(keys), newKeys => {
19075
19083
  cleanup();
19076
- if (unrefKeys) {
19077
- const groups = splitKeySequence(unrefKeys.toLowerCase());
19084
+ if (newKeys) {
19085
+ const groups = splitKeySequence(newKeys.toLowerCase());
19078
19086
  isSequence = groups.length > 1;
19079
19087
  keyGroups = groups;
19080
19088
  resetSequence();
@@ -19085,55 +19093,50 @@ function useHotkey(keys, callback) {
19085
19093
  });
19086
19094
 
19087
19095
  // Watch for changes in the event type to re-register the listener
19088
- watch(() => toValue(event), function (newEvent, oldEvent) {
19096
+ watch(() => toValue(event), (newEvent, oldEvent) => {
19089
19097
  if (oldEvent && keyGroups && keyGroups.length > 0) {
19090
19098
  window.removeEventListener(oldEvent, handler);
19091
19099
  window.addEventListener(newEvent, handler);
19092
19100
  }
19093
19101
  });
19094
- try {
19095
- getCurrentInstance('useHotkey');
19096
- onBeforeUnmount(cleanup);
19097
- } catch {
19098
- // Not in Vue setup context
19099
- }
19100
- function parseKeyGroup(group) {
19101
- 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'];
19102
19116
 
19103
- // Use the shared combination splitting logic
19104
- const parts = splitKeyCombination(group.toLowerCase());
19117
+ // Use the shared combination splitting logic
19118
+ const parts = splitKeyCombination(group.toLowerCase());
19105
19119
 
19106
- // If the combination is invalid, return empty result
19107
- if (parts.length === 0) {
19108
- return {
19109
- modifiers: Object.fromEntries(MODIFIERS.map(m => [m, false])),
19110
- actualKey: undefined
19111
- };
19112
- }
19113
- const modifiers = Object.fromEntries(MODIFIERS.map(m => [m, false]));
19114
- let actualKey;
19115
- for (const part of parts) {
19116
- if (MODIFIERS.includes(part)) {
19117
- modifiers[part] = true;
19118
- } else {
19119
- actualKey = part;
19120
- }
19121
- }
19120
+ // If the combination is invalid, return empty result
19121
+ if (parts.length === 0) {
19122
19122
  return {
19123
- modifiers,
19124
- actualKey
19123
+ modifiers: Object.fromEntries(MODIFIERS.map(m => [m, false])),
19124
+ actualKey: undefined
19125
19125
  };
19126
19126
  }
19127
- function matchesKeyGroup(e, group) {
19128
- const {
19129
- modifiers,
19130
- actualKey
19131
- } = parseKeyGroup(group);
19132
- const expectCtrl = modifiers.ctrl || !isMac && (modifiers.cmd || modifiers.meta);
19133
- const expectMeta = isMac && (modifiers.cmd || modifiers.meta);
19134
- 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
+ }
19135
19135
  }
19136
- return cleanup;
19136
+ return {
19137
+ modifiers,
19138
+ actualKey
19139
+ };
19137
19140
  }
19138
19141
 
19139
19142
  // Utilities
@@ -23763,11 +23766,15 @@ function useCalendar(props) {
23763
23766
  return week.length ? adapter.getWeek(week[0], props.firstDayOfWeek, props.firstDayOfYear) : null;
23764
23767
  });
23765
23768
  });
23769
+ const {
23770
+ minDate,
23771
+ maxDate
23772
+ } = useCalendarRange(props);
23766
23773
  function isDisabled(value) {
23767
23774
  if (props.disabled) return true;
23768
23775
  const date = adapter.date(value);
23769
- if (props.min && adapter.isBefore(adapter.endOfDay(date), adapter.date(props.min))) return true;
23770
- 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;
23771
23778
  if (Array.isArray(props.allowedDates) && props.allowedDates.length > 0) {
23772
23779
  return !props.allowedDates.some(d => adapter.isSameDay(adapter.date(d), date));
23773
23780
  }
@@ -23787,6 +23794,37 @@ function useCalendar(props) {
23787
23794
  weekNumbers
23788
23795
  };
23789
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
+ }
23790
23828
 
23791
23829
  // Types
23792
23830
 
@@ -24227,24 +24265,14 @@ const VDatePicker = genericComponent()({
24227
24265
  const viewMode = useProxiedModel(props, 'viewMode');
24228
24266
  // const inputMode = useProxiedModel(props, 'inputMode')
24229
24267
 
24230
- const minDate = computed(() => {
24231
- const date = adapter.date(props.min);
24232
- return props.min && adapter.isValid(date) ? date : null;
24233
- });
24234
- const maxDate = computed(() => {
24235
- const date = adapter.date(props.max);
24236
- return props.max && adapter.isValid(date) ? date : null;
24237
- });
24268
+ const {
24269
+ minDate,
24270
+ maxDate,
24271
+ clampDate
24272
+ } = useCalendarRange(props);
24238
24273
  const internal = computed(() => {
24239
24274
  const today = adapter.date();
24240
- let value = today;
24241
- if (model.value?.[0]) {
24242
- value = adapter.date(model.value[0]);
24243
- } else if (minDate.value && adapter.isBefore(today, minDate.value)) {
24244
- value = minDate.value;
24245
- } else if (maxDate.value && adapter.isAfter(today, maxDate.value)) {
24246
- value = maxDate.value;
24247
- }
24275
+ const value = model.value?.[0] ? adapter.date(model.value[0]) : clampDate(today);
24248
24276
  return value && adapter.isValid(value) ? value : today;
24249
24277
  });
24250
24278
  const headerColor = toRef(() => props.headerColor ?? props.color);
@@ -30031,14 +30059,24 @@ const VTextarea = genericComponent()({
30031
30059
  }
30032
30060
  function onInput(e) {
30033
30061
  const el = e.target;
30034
- model.value = el.value;
30035
- if (props.modelModifiers?.trim) {
30036
- const caretPosition = [el.selectionStart, el.selectionEnd];
30037
- nextTick(() => {
30038
- el.selectionStart = caretPosition[0];
30039
- el.selectionEnd = caretPosition[1];
30040
- });
30062
+ if (!props.modelModifiers?.trim) {
30063
+ model.value = el.value;
30064
+ return;
30041
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
+ });
30042
30080
  }
30043
30081
  const sizerRef = ref();
30044
30082
  const rows = ref(Number(props.rows));
@@ -34837,15 +34875,10 @@ const VDateInput = genericComponent()({
34837
34875
  const {
34838
34876
  mobile
34839
34877
  } = useDisplay(props);
34840
- const clamp = date => {
34841
- if (props.max && adapter.isAfter(date, props.max)) {
34842
- return props.max;
34843
- }
34844
- if (props.min && adapter.isBefore(date, props.min)) {
34845
- return props.min;
34846
- }
34847
- return date;
34848
- };
34878
+ const {
34879
+ clampDate,
34880
+ isInAllowedRange
34881
+ } = useCalendarRange(props);
34849
34882
  const emptyModelValue = () => props.multiple ? [] : null;
34850
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);
34851
34884
  const menu = useProxiedModel(props, 'menu');
@@ -34941,16 +34974,16 @@ const VDateInput = genericComponent()({
34941
34974
  model.value = emptyModelValue();
34942
34975
  } else if (!props.multiple) {
34943
34976
  if (isValid(value)) {
34944
- model.value = clamp(parseDate(value));
34977
+ model.value = clampDate(parseDate(value));
34945
34978
  }
34946
34979
  } else {
34947
34980
  const parts = value.trim().split(/\D+-\D+|[^\d\-/.]+/);
34948
34981
  if (parts.every(isValid)) {
34949
34982
  if (props.multiple === 'range') {
34950
- 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);
34951
34984
  model.value = createDateRange(adapter, start, stop);
34952
34985
  } else {
34953
- model.value = parts.map(parseDate).map(clamp);
34986
+ model.value = parts.map(parseDate).filter(isInAllowedRange);
34954
34987
  }
34955
34988
  }
34956
34989
  }
@@ -36564,7 +36597,7 @@ const VPullToRefresh = genericComponent()({
36564
36597
 
36565
36598
  // Key display tuple: [mode, content] where content is string or IconValue
36566
36599
 
36567
- // Key tuple: [mode, content] where content is string or IconValue
36600
+ // Key tuple: [mode, content, keycode] where content is string or IconValue
36568
36601
 
36569
36602
  function processKey(config, requestedMode, isMac) {
36570
36603
  const keyCfg = isMac && config.mac ? config.mac : config.default;
@@ -36703,15 +36736,6 @@ const hotkeyMap = {
36703
36736
  }
36704
36737
  }
36705
36738
  };
36706
-
36707
- // Create custom variant props that extend the base variant props with our 'contained' option
36708
- const makeVHotkeyVariantProps = propsFactory({
36709
- variant: {
36710
- type: String,
36711
- default: 'elevated',
36712
- validator: v => ['elevated', 'flat', 'tonal', 'outlined', 'text', 'plain', 'contained'].includes(v)
36713
- }
36714
- }, 'VHotkeyVariant');
36715
36739
  const makeVHotkeyProps = propsFactory({
36716
36740
  // String representing keyboard shortcuts (e.g., "ctrl+k", "meta+shift+p")
36717
36741
  keys: String,
@@ -36733,30 +36757,21 @@ const makeVHotkeyProps = propsFactory({
36733
36757
  disabled: Boolean,
36734
36758
  prefix: String,
36735
36759
  suffix: String,
36760
+ variant: {
36761
+ type: String,
36762
+ default: 'elevated',
36763
+ validator: v => ['elevated', 'flat', 'tonal', 'outlined', 'text', 'plain', 'contained'].includes(v)
36764
+ },
36736
36765
  ...makeComponentProps(),
36737
36766
  ...makeThemeProps(),
36738
36767
  ...makeBorderProps(),
36739
36768
  ...makeRoundedProps(),
36740
36769
  ...makeElevationProps(),
36741
- ...makeVHotkeyVariantProps(),
36742
36770
  color: String
36743
36771
  }, 'VHotkey');
36744
- class Delineator {
36745
- constructor(delineator) {
36746
- if (['and', 'then'].includes(delineator)) this.val = delineator;else {
36747
- throw new Error('Not a valid delineator');
36748
- }
36749
- }
36750
- isEqual(d) {
36751
- return this.val === d.val;
36752
- }
36753
- }
36754
- function isDelineator(value) {
36755
- return value instanceof Delineator;
36756
- }
36757
- function isString(value) {
36758
- return typeof value === 'string';
36759
- }
36772
+ const AND_DELINEATOR = Symbol('VHotkey:AND_DELINEATOR'); // For + separators
36773
+ const THEN_DELINEATOR = Symbol('VHotkey:THEN_DELINEATOR'); // For - separators
36774
+
36760
36775
  function getKeyText(keyMap, key, isMac) {
36761
36776
  const lowerKey = key.toLowerCase();
36762
36777
  if (lowerKey in keyMap) {
@@ -36798,57 +36813,38 @@ const VHotkey = genericComponent()({
36798
36813
  const {
36799
36814
  elevationClasses
36800
36815
  } = useElevation(props);
36801
- const isContainedVariant = computed(() => props.variant === 'contained');
36802
- const effectiveVariantProps = computed(() => ({
36803
- ...props,
36804
- variant: isContainedVariant.value ? 'elevated' : props.variant
36805
- }));
36806
36816
  const {
36807
36817
  colorClasses,
36808
36818
  colorStyles,
36809
36819
  variantClasses
36810
- } = useVariant(effectiveVariantProps);
36820
+ } = useVariant(() => ({
36821
+ color: props.color,
36822
+ variant: props.variant === 'contained' ? 'elevated' : props.variant
36823
+ }));
36811
36824
  const isMac = computed(() => props.platform === 'auto' ? typeof navigator !== 'undefined' && /macintosh/i.test(navigator.userAgent) : props.platform === 'mac');
36812
- const effectiveDisplayMode = computed(() => props.displayMode);
36813
- const AND_DELINEATOR = new Delineator('and'); // For + separators
36814
- const THEN_DELINEATOR = new Delineator('then'); // For - separators
36815
-
36816
- const effectiveKeyMap = computed(() => props.keyMap);
36817
36825
  const keyCombinations = computed(() => {
36818
36826
  if (!props.keys) return [];
36819
36827
 
36820
36828
  // Split by spaces to handle multiple key combinations
36821
36829
  // Example: "ctrl+k meta+p" -> ["ctrl+k", "meta+p"]
36822
36830
  return props.keys.split(' ').map(combination => {
36823
- // Use the shared sequence splitting logic
36831
+ const result = [];
36824
36832
  const sequenceGroups = splitKeySequence(combination);
36825
-
36826
- // Process each sequence group
36827
- return sequenceGroups.flatMap((group, groupIndex) => {
36828
- // Use the shared key combination splitting logic
36829
- const keyParts = splitKeyCombination(group);
36830
- const parts = keyParts.reduce((acc, part, index) => {
36831
- if (index !== 0) {
36832
- // Add AND delineator between keys
36833
- return [...acc, AND_DELINEATOR, part];
36834
- }
36835
- return [...acc, part];
36836
- }, []);
36833
+ for (let i = 0; i < sequenceGroups.length; i++) {
36834
+ const group = sequenceGroups[i];
36837
36835
 
36838
36836
  // Add THEN delineator between sequence groups
36839
- const result = parts.map(key => {
36840
- if (isString(key)) {
36841
- return applyDisplayModeToKey(effectiveKeyMap.value, effectiveDisplayMode.value, key, isMac.value);
36842
- }
36843
- return key;
36844
- });
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];
36845
36841
 
36846
- // Add sequence separator if not the last group
36847
- if (groupIndex < sequenceGroups.length - 1) {
36848
- 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));
36849
36845
  }
36850
- return result;
36851
- });
36846
+ }
36847
+ return result;
36852
36848
  });
36853
36849
  });
36854
36850
  const accessibleLabel = computed(() => {
@@ -36858,16 +36854,16 @@ const VHotkey = genericComponent()({
36858
36854
  const readableShortcuts = keyCombinations.value.map(combination => {
36859
36855
  const readableParts = [];
36860
36856
  for (const key of combination) {
36861
- if (isDelineator(key)) {
36862
- if (AND_DELINEATOR.isEqual(key)) {
36863
- readableParts.push(t('$vuetify.hotkey.plus'));
36864
- } else if (THEN_DELINEATOR.isEqual(key)) {
36865
- readableParts.push(t('$vuetify.hotkey.then'));
36866
- }
36867
- } else {
36857
+ if (Array.isArray(key)) {
36868
36858
  // Always use text representation for screen readers
36869
36859
  const textKey = key[0] === 'icon' || key[0] === 'symbol' ? applyDisplayModeToKey(mergeDeep(hotkeyMap, props.keyMap), 'text', String(key[1]), isMac.value)[1] : key[1];
36870
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
+ }
36871
36867
  }
36872
36868
  }
36873
36869
  return readableParts.join(' ');
@@ -36879,11 +36875,12 @@ const VHotkey = genericComponent()({
36879
36875
  return key.startsWith('$vuetify.') ? t(key) : key;
36880
36876
  }
36881
36877
  function getKeyTooltip(key) {
36882
- if (effectiveDisplayMode.value === 'text') return undefined;
36883
- 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);
36884
36880
  return translateKey(textKey);
36885
36881
  }
36886
- function renderKey(key, keyIndex, isContained) {
36882
+ function renderKey(key, keyIndex) {
36883
+ const isContained = props.variant === 'contained';
36887
36884
  const KeyComponent = isContained ? 'kbd' : VKbd;
36888
36885
  const keyClasses = ['v-hotkey__key', `v-hotkey__key-${key[0]}`, ...(isContained ? ['v-hotkey__key--nested'] : [borderClasses.value, roundedClasses.value, elevationClasses.value, colorClasses.value])];
36889
36886
  return createVNode(KeyComponent, {
@@ -36904,47 +36901,39 @@ const VHotkey = genericComponent()({
36904
36901
  "key": keyIndex,
36905
36902
  "class": "v-hotkey__divider",
36906
36903
  "aria-hidden": "true"
36907
- }, [AND_DELINEATOR.isEqual(key) ? '+' : t('$vuetify.hotkey.then')]);
36904
+ }, [key === AND_DELINEATOR ? '+' : t('$vuetify.hotkey.then')]);
36908
36905
  }
36909
- useRender(() => createElementVNode("div", {
36910
- "class": normalizeClass(['v-hotkey', {
36911
- 'v-hotkey--disabled': props.disabled,
36912
- 'v-hotkey--inline': props.inline,
36913
- 'v-hotkey--contained': isContainedVariant.value
36914
- }, themeClasses.value, rtlClasses.value, variantClasses.value, props.class]),
36915
- "style": normalizeStyle(props.style),
36916
- "role": "img",
36917
- "aria-label": accessibleLabel.value
36918
- }, [isContainedVariant.value ? createVNode(VKbd, {
36919
- "key": "contained",
36920
- "class": normalizeClass(['v-hotkey__contained-wrapper', borderClasses.value, roundedClasses.value, elevationClasses.value, colorClasses.value]),
36921
- "style": normalizeStyle(colorStyles.value),
36922
- "aria-hidden": "true"
36923
- }, {
36924
- default: () => [props.prefix && createElementVNode("span", {
36925
- "key": "contained-prefix",
36906
+ useRender(() => {
36907
+ const content = createElementVNode(Fragment, null, [props.prefix && createElementVNode("span", {
36908
+ "key": "prefix",
36926
36909
  "class": "v-hotkey__prefix"
36927
36910
  }, [props.prefix]), keyCombinations.value.map((combination, comboIndex) => createElementVNode("span", {
36928
36911
  "class": "v-hotkey__combination",
36929
36912
  "key": comboIndex
36930
- }, [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", {
36931
36914
  "aria-hidden": "true"
36932
36915
  }, [createTextVNode("\xA0")])])), props.suffix && createElementVNode("span", {
36933
- "key": "contained-suffix",
36916
+ "key": "suffix",
36934
36917
  "class": "v-hotkey__suffix"
36935
- }, [props.suffix])]
36936
- }) : createElementVNode(Fragment, null, [props.prefix && createElementVNode("span", {
36937
- "key": "prefix",
36938
- "class": "v-hotkey__prefix"
36939
- }, [props.prefix]), keyCombinations.value.map((combination, comboIndex) => createElementVNode("span", {
36940
- "class": "v-hotkey__combination",
36941
- "key": comboIndex
36942
- }, [combination.map((key, keyIndex) => isDelineator(key) ? renderDivider(key, keyIndex) : renderKey(key, keyIndex, false)), comboIndex < keyCombinations.value.length - 1 && createElementVNode("span", {
36943
- "aria-hidden": "true"
36944
- }, [createTextVNode("\xA0")])])), props.suffix && createElementVNode("span", {
36945
- "key": "suffix",
36946
- "class": "v-hotkey__suffix"
36947
- }, [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
+ });
36948
36937
  }
36949
36938
  });
36950
36939
 
@@ -38150,7 +38139,7 @@ function createVuetify$1() {
38150
38139
  };
38151
38140
  });
38152
38141
  }
38153
- const version$1 = "3.10.8";
38142
+ const version$1 = "3.10.10";
38154
38143
  createVuetify$1.version = version$1;
38155
38144
 
38156
38145
  // Vue's inject() can only be used in setup
@@ -38448,7 +38437,7 @@ var index = /*#__PURE__*/Object.freeze({
38448
38437
 
38449
38438
  /* eslint-disable local-rules/sort-imports */
38450
38439
 
38451
- const version = "3.10.8";
38440
+ const version = "3.10.10";
38452
38441
 
38453
38442
  /* eslint-disable local-rules/sort-imports */
38454
38443