vuetify 3.3.13 → 3.3.15

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 (119) hide show
  1. package/dist/json/attributes.json +70 -66
  2. package/dist/json/importMap.json +12 -12
  3. package/dist/json/tags.json +5 -4
  4. package/dist/json/web-types.json +274 -185
  5. package/dist/vuetify-labs.css +565 -486
  6. package/dist/vuetify-labs.d.ts +831 -462
  7. package/dist/vuetify-labs.esm.js +453 -310
  8. package/dist/vuetify-labs.esm.js.map +1 -1
  9. package/dist/vuetify-labs.js +452 -309
  10. package/dist/vuetify-labs.min.css +2 -2
  11. package/dist/vuetify.css +318 -239
  12. package/dist/vuetify.d.ts +678 -301
  13. package/dist/vuetify.esm.js +253 -173
  14. package/dist/vuetify.esm.js.map +1 -1
  15. package/dist/vuetify.js +252 -172
  16. package/dist/vuetify.js.map +1 -1
  17. package/dist/vuetify.min.css +2 -2
  18. package/dist/vuetify.min.js +842 -830
  19. package/dist/vuetify.min.js.map +1 -1
  20. package/lib/components/VAppBar/VAppBar.mjs.map +1 -1
  21. package/lib/components/VAppBar/index.d.mts +6 -6
  22. package/lib/components/VAutocomplete/VAutocomplete.mjs +12 -2
  23. package/lib/components/VAutocomplete/VAutocomplete.mjs.map +1 -1
  24. package/lib/components/VBadge/VBadge.css +1 -1
  25. package/lib/components/VBadge/_variables.scss +1 -1
  26. package/lib/components/VBtnToggle/VBtnToggle.css +13 -2
  27. package/lib/components/VBtnToggle/VBtnToggle.sass +3 -3
  28. package/lib/components/VBtnToggle/_variables.scss +2 -1
  29. package/lib/components/VCheckbox/VCheckbox.mjs +2 -2
  30. package/lib/components/VCheckbox/VCheckbox.mjs.map +1 -1
  31. package/lib/components/VCheckbox/VCheckboxBtn.mjs +14 -11
  32. package/lib/components/VCheckbox/VCheckboxBtn.mjs.map +1 -1
  33. package/lib/components/VCheckbox/index.d.mts +203 -87
  34. package/lib/components/VColorPicker/VColorPickerEdit.css +4 -2
  35. package/lib/components/VColorPicker/VColorPickerPreview.css +11 -6
  36. package/lib/components/VCombobox/VCombobox.mjs +11 -1
  37. package/lib/components/VCombobox/VCombobox.mjs.map +1 -1
  38. package/lib/components/VField/VField.css +25 -7
  39. package/lib/components/VField/VField.sass +15 -1
  40. package/lib/components/VGrid/VGrid.css +153 -142
  41. package/lib/components/VIcon/VIcon.css +1 -0
  42. package/lib/components/VIcon/VIcon.sass +1 -0
  43. package/lib/components/VOverlay/useActivator.mjs +1 -1
  44. package/lib/components/VOverlay/useActivator.mjs.map +1 -1
  45. package/lib/components/VProgressLinear/VProgressLinear.css +3 -2
  46. package/lib/components/VRadio/index.d.mts +82 -23
  47. package/lib/components/VRadioGroup/VRadioGroup.mjs +2 -2
  48. package/lib/components/VRadioGroup/VRadioGroup.mjs.map +1 -1
  49. package/lib/components/VRadioGroup/index.d.mts +75 -109
  50. package/lib/components/VRangeSlider/index.d.mts +114 -33
  51. package/lib/components/VSelect/VSelect.mjs +12 -2
  52. package/lib/components/VSelect/VSelect.mjs.map +1 -1
  53. package/lib/components/VSelectionControl/VSelectionControl.mjs +19 -3
  54. package/lib/components/VSelectionControl/VSelectionControl.mjs.map +1 -1
  55. package/lib/components/VSelectionControl/index.d.mts +19 -5
  56. package/lib/components/VSlider/VSlider.mjs.map +1 -1
  57. package/lib/components/VSlider/VSliderThumb.css +8 -4
  58. package/lib/components/VSlider/VSliderTrack.css +22 -12
  59. package/lib/components/VSlider/index.d.mts +114 -33
  60. package/lib/components/VSwitch/VSwitch.css +7 -5
  61. package/lib/components/VSwitch/VSwitch.mjs +26 -16
  62. package/lib/components/VSwitch/VSwitch.mjs.map +1 -1
  63. package/lib/components/VSwitch/VSwitch.sass +6 -4
  64. package/lib/components/VSwitch/_variables.scss +5 -3
  65. package/lib/components/VSwitch/index.d.mts +82 -23
  66. package/lib/components/VTable/VTable.css +3 -0
  67. package/lib/components/VTable/VTable.sass +4 -0
  68. package/lib/components/VTable/_variables.scss +3 -0
  69. package/lib/components/VTabs/VTab.mjs +2 -2
  70. package/lib/components/VTabs/VTab.mjs.map +1 -1
  71. package/lib/components/VTextarea/VTextarea.mjs +1 -0
  72. package/lib/components/VTextarea/VTextarea.mjs.map +1 -1
  73. package/lib/components/VTimeline/VTimeline.css +19 -10
  74. package/lib/components/VTimeline/VTimeline.sass +5 -0
  75. package/lib/components/VToolbar/VToolbar.css +4 -2
  76. package/lib/components/index.d.mts +676 -299
  77. package/lib/composables/color.mjs +6 -1
  78. package/lib/composables/color.mjs.map +1 -1
  79. package/lib/composables/defaults.mjs +9 -9
  80. package/lib/composables/defaults.mjs.map +1 -1
  81. package/lib/composables/theme.mjs +8 -7
  82. package/lib/composables/theme.mjs.map +1 -1
  83. package/lib/entry-bundler.mjs +1 -1
  84. package/lib/framework.mjs +1 -1
  85. package/lib/index.d.mts +3 -3
  86. package/lib/labs/VDateInput/index.d.mts +2 -2
  87. package/lib/labs/VDatePicker/VDateCard.mjs +3 -0
  88. package/lib/labs/VDatePicker/VDateCard.mjs.map +1 -1
  89. package/lib/labs/VDatePicker/VDatePicker.mjs +51 -21
  90. package/lib/labs/VDatePicker/VDatePicker.mjs.map +1 -1
  91. package/lib/labs/VDatePicker/VDatePickerControls.css +1 -1
  92. package/lib/labs/VDatePicker/VDatePickerControls.mjs +53 -35
  93. package/lib/labs/VDatePicker/VDatePickerControls.mjs.map +1 -1
  94. package/lib/labs/VDatePicker/VDatePickerMonth.mjs +37 -28
  95. package/lib/labs/VDatePicker/VDatePickerMonth.mjs.map +1 -1
  96. package/lib/labs/VDatePicker/VDatePickerYears.mjs +19 -17
  97. package/lib/labs/VDatePicker/VDatePickerYears.mjs.map +1 -1
  98. package/lib/labs/VDatePicker/index.d.mts +148 -156
  99. package/lib/labs/VDateRangePicker/VDateRangeCard.mjs +3 -0
  100. package/lib/labs/VDateRangePicker/VDateRangeCard.mjs.map +1 -1
  101. package/lib/labs/VDateRangePicker/index.d.mts +59 -52
  102. package/lib/labs/VSkeletonLoader/VSkeletonLoader.mjs.map +1 -1
  103. package/lib/labs/VSkeletonLoader/index.d.mts +8 -8
  104. package/lib/labs/components.d.mts +156 -164
  105. package/lib/locale/bg.mjs +23 -23
  106. package/lib/locale/bg.mjs.map +1 -1
  107. package/lib/locale/fa.mjs +16 -16
  108. package/lib/locale/fa.mjs.map +1 -1
  109. package/lib/locale/no.mjs +1 -1
  110. package/lib/locale/no.mjs.map +1 -1
  111. package/lib/styles/tools/_rtl.sass +4 -2
  112. package/lib/styles/tools/_states.sass +5 -5
  113. package/lib/util/colorUtils.mjs +6 -0
  114. package/lib/util/colorUtils.mjs.map +1 -1
  115. package/lib/util/helpers.mjs +10 -4
  116. package/lib/util/helpers.mjs.map +1 -1
  117. package/lib/util/injectSelf.mjs +2 -1
  118. package/lib/util/injectSelf.mjs.map +1 -1
  119. package/package.json +2 -2
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.3.13
2
+ * Vuetify v3.3.15
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
@@ -233,14 +233,22 @@
233
233
  include.forEach(prop => clone[prop] = obj[prop]);
234
234
  return clone;
235
235
  }
236
+ const onRE = /^on[^a-z]/;
237
+ const isOn = key => onRE.test(key);
238
+ const bubblingEvents = ['onAfterscriptexecute', 'onAnimationcancel', 'onAnimationend', 'onAnimationiteration', 'onAnimationstart', 'onAuxclick', 'onBeforeinput', 'onBeforescriptexecute', 'onChange', 'onClick', 'onCompositionend', 'onCompositionstart', 'onCompositionupdate', 'onContextmenu', 'onCopy', 'onCut', 'onDblclick', 'onFocusin', 'onFocusout', 'onFullscreenchange', 'onFullscreenerror', 'onGesturechange', 'onGestureend', 'onGesturestart', 'onGotpointercapture', 'onInput', 'onKeydown', 'onKeypress', 'onKeyup', 'onLostpointercapture', 'onMousedown', 'onMousemove', 'onMouseout', 'onMouseover', 'onMouseup', 'onMousewheel', 'onPaste', 'onPointercancel', 'onPointerdown', 'onPointerenter', 'onPointerleave', 'onPointermove', 'onPointerout', 'onPointerover', 'onPointerup', 'onReset', 'onSelect', 'onSubmit', 'onTouchcancel', 'onTouchend', 'onTouchmove', 'onTouchstart', 'onTransitioncancel', 'onTransitionend', 'onTransitionrun', 'onTransitionstart', 'onWheel'];
236
239
 
237
240
  /**
238
241
  * Filter attributes that should be applied to
239
- * the root element of a an input component. Remaining
242
+ * the root element of an input component. Remaining
240
243
  * attributes should be passed to the <input> element inside.
241
244
  */
242
245
  function filterInputAttrs(attrs) {
243
- return pick(attrs, ['class', 'style', 'id', /^data-/]);
246
+ const [events, props] = pick(attrs, [onRE]);
247
+ const inputEvents = omit(events, bubblingEvents);
248
+ const [rootAttrs, inputAttrs] = pick(props, ['class', 'style', 'id', /^data-/]);
249
+ Object.assign(rootAttrs, events);
250
+ Object.assign(inputAttrs, inputEvents);
251
+ return [rootAttrs, inputAttrs];
244
252
  }
245
253
  function wrapInArray(v) {
246
254
  return v == null ? [] : Array.isArray(v) ? v : [v];
@@ -393,8 +401,6 @@
393
401
  function includes(arr, val) {
394
402
  return arr.includes(val);
395
403
  }
396
- const onRE = /^on[^a-z]/;
397
- const isOn = key => onRE.test(key);
398
404
  function eventName(propName) {
399
405
  return propName[2].toLowerCase() + propName.slice(3);
400
406
  }
@@ -664,6 +670,94 @@
664
670
  });
665
671
  }
666
672
 
673
+ /**
674
+ * WCAG 3.0 APCA perceptual contrast algorithm from https://github.com/Myndex/SAPC-APCA
675
+ * @licence https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
676
+ * @see https://www.w3.org/WAI/GL/task-forces/silver/wiki/Visual_Contrast_of_Text_Subgroup
677
+ */
678
+ // Types
679
+
680
+ // MAGICAL NUMBERS
681
+
682
+ // sRGB Conversion to Relative Luminance (Y)
683
+
684
+ // Transfer Curve (aka "Gamma") for sRGB linearization
685
+ // Simple power curve vs piecewise described in docs
686
+ // Essentially, 2.4 best models actual display
687
+ // characteristics in combination with the total method
688
+ const mainTRC = 2.4;
689
+ const Rco = 0.2126729; // sRGB Red Coefficient (from matrix)
690
+ const Gco = 0.7151522; // sRGB Green Coefficient (from matrix)
691
+ const Bco = 0.0721750; // sRGB Blue Coefficient (from matrix)
692
+
693
+ // For Finding Raw SAPC Contrast from Relative Luminance (Y)
694
+
695
+ // Constants for SAPC Power Curve Exponents
696
+ // One pair for normal text, and one for reverse
697
+ // These are the "beating heart" of SAPC
698
+ const normBG = 0.55;
699
+ const normTXT = 0.58;
700
+ const revTXT = 0.57;
701
+ const revBG = 0.62;
702
+
703
+ // For Clamping and Scaling Values
704
+
705
+ const blkThrs = 0.03; // Level that triggers the soft black clamp
706
+ const blkClmp = 1.45; // Exponent for the soft black clamp curve
707
+ const deltaYmin = 0.0005; // Lint trap
708
+ const scaleBoW = 1.25; // Scaling for dark text on light
709
+ const scaleWoB = 1.25; // Scaling for light text on dark
710
+ const loConThresh = 0.078; // Threshold for new simple offset scale
711
+ const loConFactor = 12.82051282051282; // = 1/0.078,
712
+ const loConOffset = 0.06; // The simple offset
713
+ const loClip = 0.001; // Output clip (lint trap #2)
714
+
715
+ function APCAcontrast(text, background) {
716
+ // Linearize sRGB
717
+ const Rtxt = (text.r / 255) ** mainTRC;
718
+ const Gtxt = (text.g / 255) ** mainTRC;
719
+ const Btxt = (text.b / 255) ** mainTRC;
720
+ const Rbg = (background.r / 255) ** mainTRC;
721
+ const Gbg = (background.g / 255) ** mainTRC;
722
+ const Bbg = (background.b / 255) ** mainTRC;
723
+
724
+ // Apply the standard coefficients and sum to Y
725
+ let Ytxt = Rtxt * Rco + Gtxt * Gco + Btxt * Bco;
726
+ let Ybg = Rbg * Rco + Gbg * Gco + Bbg * Bco;
727
+
728
+ // Soft clamp Y when near black.
729
+ // Now clamping all colors to prevent crossover errors
730
+ if (Ytxt <= blkThrs) Ytxt += (blkThrs - Ytxt) ** blkClmp;
731
+ if (Ybg <= blkThrs) Ybg += (blkThrs - Ybg) ** blkClmp;
732
+
733
+ // Return 0 Early for extremely low ∆Y (lint trap #1)
734
+ if (Math.abs(Ybg - Ytxt) < deltaYmin) return 0.0;
735
+
736
+ // SAPC CONTRAST
737
+
738
+ let outputContrast; // For weighted final values
739
+ if (Ybg > Ytxt) {
740
+ // For normal polarity, black text on white
741
+ // Calculate the SAPC contrast value and scale
742
+
743
+ const SAPC = (Ybg ** normBG - Ytxt ** normTXT) * scaleBoW;
744
+
745
+ // NEW! SAPC SmoothScale™
746
+ // Low Contrast Smooth Scale Rollout to prevent polarity reversal
747
+ // and also a low clip for very low contrasts (lint trap #2)
748
+ // much of this is for very low contrasts, less than 10
749
+ // therefore for most reversing needs, only loConOffset is important
750
+ outputContrast = SAPC < loClip ? 0.0 : SAPC < loConThresh ? SAPC - SAPC * loConFactor * loConOffset : SAPC - loConOffset;
751
+ } else {
752
+ // For reverse polarity, light text on dark
753
+ // WoB should always return negative value.
754
+
755
+ const SAPC = (Ybg ** revBG - Ytxt ** revTXT) * scaleWoB;
756
+ outputContrast = SAPC > -loClip ? 0.0 : SAPC > -loConThresh ? SAPC - SAPC * loConFactor * loConOffset : SAPC + loConOffset;
757
+ }
758
+ return outputContrast * 100;
759
+ }
760
+
667
761
  /* eslint-disable no-console */
668
762
 
669
763
  function consoleWarn(message) {
@@ -1020,36 +1114,13 @@
1020
1114
  const dark = Math.min(l1, l2);
1021
1115
  return (light + 0.05) / (dark + 0.05);
1022
1116
  }
1023
-
1024
- // Utilities
1025
-
1026
- // Types
1027
-
1028
- function useToggleScope(source, fn) {
1029
- let scope;
1030
- function start() {
1031
- scope = vue.effectScope();
1032
- scope.run(() => fn.length ? fn(() => {
1033
- scope?.stop();
1034
- start();
1035
- }) : fn());
1036
- }
1037
- vue.watch(source, active => {
1038
- if (active && !scope) {
1039
- start();
1040
- } else if (!active) {
1041
- scope?.stop();
1042
- scope = undefined;
1043
- }
1044
- }, {
1045
- immediate: true
1046
- });
1047
- vue.onScopeDispose(() => {
1048
- scope?.stop();
1049
- });
1117
+ function getForeground(color) {
1118
+ const blackContrast = Math.abs(APCAcontrast(parseColor(0), parseColor(color)));
1119
+ const whiteContrast = Math.abs(APCAcontrast(parseColor(0xffffff), parseColor(color)));
1120
+ return whiteContrast > Math.min(blackContrast, 50) ? '#fff' : '#000';
1050
1121
  }
1051
1122
 
1052
- // Composables
1123
+ // Utilities
1053
1124
 
1054
1125
  // Types
1055
1126
 
@@ -1071,6 +1142,7 @@
1071
1142
  const scoped = vue.unref(options?.scoped);
1072
1143
  const reset = vue.unref(options?.reset);
1073
1144
  const root = vue.unref(options?.root);
1145
+ if (providedDefaults.value == null && !(scoped || reset || root)) return injectedDefaults.value;
1074
1146
  let properties = mergeDeep(providedDefaults.value, {
1075
1147
  prev: injectedDefaults.value
1076
1148
  });
@@ -1126,16 +1198,16 @@
1126
1198
  let [key] = _ref;
1127
1199
  return key.startsWith(key[0].toUpperCase());
1128
1200
  });
1129
- if (subComponents.length) _subcomponentDefaults.value = Object.fromEntries(subComponents);
1201
+ _subcomponentDefaults.value = subComponents.length ? Object.fromEntries(subComponents) : undefined;
1202
+ } else {
1203
+ _subcomponentDefaults.value = undefined;
1130
1204
  }
1131
1205
  });
1132
1206
  function provideSubDefaults() {
1133
- // If subcomponent defaults are provided, override any
1134
- // subcomponents provided by the component's setup function.
1135
- // This uses injectSelf so must be done after the original setup to work.
1136
- useToggleScope(_subcomponentDefaults, () => {
1137
- provideDefaults(mergeDeep(injectSelf(DefaultsSymbol)?.value ?? {}, _subcomponentDefaults.value));
1138
- });
1207
+ const injected = injectSelf(DefaultsSymbol, vm);
1208
+ vue.provide(DefaultsSymbol, vue.computed(() => {
1209
+ return _subcomponentDefaults.value ? mergeDeep(injected?.value ?? {}, _subcomponentDefaults.value) : injected?.value;
1210
+ }));
1139
1211
  }
1140
1212
  return {
1141
1213
  props: _props,
@@ -1317,9 +1389,10 @@
1317
1389
  // Types
1318
1390
 
1319
1391
  function injectSelf(key) {
1392
+ let vm = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstance('injectSelf');
1320
1393
  const {
1321
1394
  provides
1322
- } = getCurrentInstance('injectSelf');
1395
+ } = vm;
1323
1396
  if (provides && key in provides) {
1324
1397
  // TS doesn't allow symbol as index type
1325
1398
  return provides[key];
@@ -1796,6 +1869,34 @@
1796
1869
  zhHant: false
1797
1870
  };
1798
1871
 
1872
+ // Utilities
1873
+
1874
+ // Types
1875
+
1876
+ function useToggleScope(source, fn) {
1877
+ let scope;
1878
+ function start() {
1879
+ scope = vue.effectScope();
1880
+ scope.run(() => fn.length ? fn(() => {
1881
+ scope?.stop();
1882
+ start();
1883
+ }) : fn());
1884
+ }
1885
+ vue.watch(source, active => {
1886
+ if (active && !scope) {
1887
+ start();
1888
+ } else if (!active) {
1889
+ scope?.stop();
1890
+ scope = undefined;
1891
+ }
1892
+ }, {
1893
+ immediate: true
1894
+ });
1895
+ vue.onScopeDispose(() => {
1896
+ scope?.stop();
1897
+ });
1898
+ }
1899
+
1799
1900
  // Composables
1800
1901
 
1801
1902
  // Types
@@ -1997,94 +2098,6 @@
1997
2098
  };
1998
2099
  }
1999
2100
 
2000
- /**
2001
- * WCAG 3.0 APCA perceptual contrast algorithm from https://github.com/Myndex/SAPC-APCA
2002
- * @licence https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
2003
- * @see https://www.w3.org/WAI/GL/task-forces/silver/wiki/Visual_Contrast_of_Text_Subgroup
2004
- */
2005
- // Types
2006
-
2007
- // MAGICAL NUMBERS
2008
-
2009
- // sRGB Conversion to Relative Luminance (Y)
2010
-
2011
- // Transfer Curve (aka "Gamma") for sRGB linearization
2012
- // Simple power curve vs piecewise described in docs
2013
- // Essentially, 2.4 best models actual display
2014
- // characteristics in combination with the total method
2015
- const mainTRC = 2.4;
2016
- const Rco = 0.2126729; // sRGB Red Coefficient (from matrix)
2017
- const Gco = 0.7151522; // sRGB Green Coefficient (from matrix)
2018
- const Bco = 0.0721750; // sRGB Blue Coefficient (from matrix)
2019
-
2020
- // For Finding Raw SAPC Contrast from Relative Luminance (Y)
2021
-
2022
- // Constants for SAPC Power Curve Exponents
2023
- // One pair for normal text, and one for reverse
2024
- // These are the "beating heart" of SAPC
2025
- const normBG = 0.55;
2026
- const normTXT = 0.58;
2027
- const revTXT = 0.57;
2028
- const revBG = 0.62;
2029
-
2030
- // For Clamping and Scaling Values
2031
-
2032
- const blkThrs = 0.03; // Level that triggers the soft black clamp
2033
- const blkClmp = 1.45; // Exponent for the soft black clamp curve
2034
- const deltaYmin = 0.0005; // Lint trap
2035
- const scaleBoW = 1.25; // Scaling for dark text on light
2036
- const scaleWoB = 1.25; // Scaling for light text on dark
2037
- const loConThresh = 0.078; // Threshold for new simple offset scale
2038
- const loConFactor = 12.82051282051282; // = 1/0.078,
2039
- const loConOffset = 0.06; // The simple offset
2040
- const loClip = 0.001; // Output clip (lint trap #2)
2041
-
2042
- function APCAcontrast(text, background) {
2043
- // Linearize sRGB
2044
- const Rtxt = (text.r / 255) ** mainTRC;
2045
- const Gtxt = (text.g / 255) ** mainTRC;
2046
- const Btxt = (text.b / 255) ** mainTRC;
2047
- const Rbg = (background.r / 255) ** mainTRC;
2048
- const Gbg = (background.g / 255) ** mainTRC;
2049
- const Bbg = (background.b / 255) ** mainTRC;
2050
-
2051
- // Apply the standard coefficients and sum to Y
2052
- let Ytxt = Rtxt * Rco + Gtxt * Gco + Btxt * Bco;
2053
- let Ybg = Rbg * Rco + Gbg * Gco + Bbg * Bco;
2054
-
2055
- // Soft clamp Y when near black.
2056
- // Now clamping all colors to prevent crossover errors
2057
- if (Ytxt <= blkThrs) Ytxt += (blkThrs - Ytxt) ** blkClmp;
2058
- if (Ybg <= blkThrs) Ybg += (blkThrs - Ybg) ** blkClmp;
2059
-
2060
- // Return 0 Early for extremely low ∆Y (lint trap #1)
2061
- if (Math.abs(Ybg - Ytxt) < deltaYmin) return 0.0;
2062
-
2063
- // SAPC CONTRAST
2064
-
2065
- let outputContrast; // For weighted final values
2066
- if (Ybg > Ytxt) {
2067
- // For normal polarity, black text on white
2068
- // Calculate the SAPC contrast value and scale
2069
-
2070
- const SAPC = (Ybg ** normBG - Ytxt ** normTXT) * scaleBoW;
2071
-
2072
- // NEW! SAPC SmoothScale™
2073
- // Low Contrast Smooth Scale Rollout to prevent polarity reversal
2074
- // and also a low clip for very low contrasts (lint trap #2)
2075
- // much of this is for very low contrasts, less than 10
2076
- // therefore for most reversing needs, only loConOffset is important
2077
- outputContrast = SAPC < loClip ? 0.0 : SAPC < loConThresh ? SAPC - SAPC * loConFactor * loConOffset : SAPC - loConOffset;
2078
- } else {
2079
- // For reverse polarity, light text on dark
2080
- // WoB should always return negative value.
2081
-
2082
- const SAPC = (Ybg ** revBG - Ytxt ** revTXT) * scaleWoB;
2083
- outputContrast = SAPC > -loClip ? 0.0 : SAPC > -loConThresh ? SAPC - SAPC * loConFactor * loConOffset : SAPC + loConOffset;
2084
- }
2085
- return outputContrast * 100;
2086
- }
2087
-
2088
2101
  // Utilities
2089
2102
 
2090
2103
  // Types
@@ -2106,6 +2119,7 @@
2106
2119
  colors: {
2107
2120
  background: '#FFFFFF',
2108
2121
  surface: '#FFFFFF',
2122
+ 'surface-bright': '#FFFFFF',
2109
2123
  'surface-variant': '#424242',
2110
2124
  'on-surface-variant': '#EEEEEE',
2111
2125
  primary: '#6200EE',
@@ -2141,7 +2155,8 @@
2141
2155
  colors: {
2142
2156
  background: '#121212',
2143
2157
  surface: '#212121',
2144
- 'surface-variant': '#BDBDBD',
2158
+ 'surface-bright': '#ccbfd6',
2159
+ 'surface-variant': '#a3a3a3',
2145
2160
  'on-surface-variant': '#424242',
2146
2161
  primary: '#BB86FC',
2147
2162
  'primary-darken-1': '#3700B3',
@@ -2220,8 +2235,6 @@
2220
2235
  if (/^on-[a-z]/.test(color) || theme.colors[`on-${color}`]) continue;
2221
2236
  const onColor = `on-${color}`;
2222
2237
  const colorVal = parseColor(theme.colors[color]);
2223
- const blackContrast = Math.abs(APCAcontrast(parseColor(0), colorVal));
2224
- const whiteContrast = Math.abs(APCAcontrast(parseColor(0xffffff), colorVal));
2225
2238
 
2226
2239
  // TODO: warn about poor color selections
2227
2240
  // const contrastAsText = Math.abs(APCAcontrast(colorVal, colorToInt(theme.colors.background)))
@@ -2233,7 +2246,7 @@
2233
2246
  // }
2234
2247
 
2235
2248
  // Prefer white text if both have an acceptable contrast ratio
2236
- theme.colors[onColor] = whiteContrast > Math.min(blackContrast, 50) ? '#fff' : '#000';
2249
+ theme.colors[onColor] = getForeground(colorVal);
2237
2250
  }
2238
2251
  }
2239
2252
  return acc;
@@ -2334,12 +2347,14 @@
2334
2347
  const theme = vue.inject(ThemeSymbol, null);
2335
2348
  if (!theme) throw new Error('Could not find Vuetify theme injection');
2336
2349
  const name = vue.computed(() => {
2337
- return props.theme ?? theme?.name.value;
2350
+ return props.theme ?? theme.name.value;
2338
2351
  });
2352
+ const current = vue.computed(() => theme.themes.value[name.value]);
2339
2353
  const themeClasses = vue.computed(() => theme.isDisabled ? undefined : `v-theme--${name.value}`);
2340
2354
  const newTheme = {
2341
2355
  ...theme,
2342
2356
  name,
2357
+ current,
2343
2358
  themeClasses
2344
2359
  };
2345
2360
  vue.provide(ThemeSymbol, newTheme);
@@ -3262,6 +3277,11 @@
3262
3277
  if (colors.value.background) {
3263
3278
  if (isCssColor(colors.value.background)) {
3264
3279
  styles.backgroundColor = colors.value.background;
3280
+ if (!colors.value.text) {
3281
+ const textColor = getForeground(styles.backgroundColor);
3282
+ styles.color = textColor;
3283
+ styles.caretColor = textColor;
3284
+ }
3265
3285
  } else {
3266
3286
  classes.push(`bg-${colors.value.background}`);
3267
3287
  }
@@ -5791,6 +5811,12 @@
5791
5811
  } = useTextColor(vue.computed(() => {
5792
5812
  return model.value && !props.error && !props.disabled ? props.color : undefined;
5793
5813
  }));
5814
+ const {
5815
+ backgroundColorClasses,
5816
+ backgroundColorStyles
5817
+ } = useBackgroundColor(vue.computed(() => {
5818
+ return model.value && !props.error && !props.disabled ? props.color : undefined;
5819
+ }));
5794
5820
  const icon = vue.computed(() => model.value ? props.trueIcon : props.falseIcon);
5795
5821
  return {
5796
5822
  group,
@@ -5800,6 +5826,8 @@
5800
5826
  model,
5801
5827
  textColorClasses,
5802
5828
  textColorStyles,
5829
+ backgroundColorClasses,
5830
+ backgroundColorStyles,
5803
5831
  icon
5804
5832
  };
5805
5833
  }
@@ -5825,6 +5853,8 @@
5825
5853
  model,
5826
5854
  textColorClasses,
5827
5855
  textColorStyles,
5856
+ backgroundColorClasses,
5857
+ backgroundColorStyles,
5828
5858
  trueValue
5829
5859
  } = useSelectionControl(props);
5830
5860
  const uid = getUid();
@@ -5889,12 +5919,17 @@
5889
5919
  }), [vue.createVNode("div", {
5890
5920
  "class": ['v-selection-control__wrapper', textColorClasses.value],
5891
5921
  "style": textColorStyles.value
5892
- }, [slots.default?.(), vue.withDirectives(vue.createVNode("div", {
5922
+ }, [slots.default?.({
5923
+ backgroundColorClasses,
5924
+ backgroundColorStyles
5925
+ }), vue.withDirectives(vue.createVNode("div", {
5893
5926
  "class": ['v-selection-control__input']
5894
5927
  }, [slots.input?.({
5895
5928
  model,
5896
5929
  textColorClasses,
5897
5930
  textColorStyles,
5931
+ backgroundColorClasses,
5932
+ backgroundColorStyles,
5898
5933
  inputNode,
5899
5934
  icon: icon.value,
5900
5935
  props: {
@@ -5907,7 +5942,8 @@
5907
5942
  "icon": icon.value
5908
5943
  }, null), inputNode])]), [[vue.resolveDirective("ripple"), props.ripple && [!props.disabled && !props.readonly, null, ['center', 'circle']]]])]), label && vue.createVNode(VLabel, {
5909
5944
  "for": id.value,
5910
- "clickable": true
5945
+ "clickable": true,
5946
+ "onClick": e => e.stopPropagation()
5911
5947
  }, {
5912
5948
  default: () => [label]
5913
5949
  })]);
@@ -5956,16 +5992,19 @@
5956
5992
  const trueIcon = vue.computed(() => {
5957
5993
  return indeterminate.value ? props.indeterminateIcon : props.trueIcon;
5958
5994
  });
5959
- useRender(() => vue.createVNode(VSelectionControl, vue.mergeProps(props, {
5960
- "modelValue": model.value,
5961
- "onUpdate:modelValue": [$event => model.value = $event, onChange],
5962
- "class": ['v-checkbox-btn', props.class],
5963
- "style": props.style,
5964
- "type": "checkbox",
5965
- "falseIcon": falseIcon.value,
5966
- "trueIcon": trueIcon.value,
5967
- "aria-checked": indeterminate.value ? 'mixed' : undefined
5968
- }), slots));
5995
+ useRender(() => {
5996
+ const controlProps = omit(VSelectionControl.filterProps(props)[0], ['modelValue']);
5997
+ return vue.createVNode(VSelectionControl, vue.mergeProps(controlProps, {
5998
+ "modelValue": model.value,
5999
+ "onUpdate:modelValue": [$event => model.value = $event, onChange],
6000
+ "class": ['v-checkbox-btn', props.class],
6001
+ "style": props.style,
6002
+ "type": "checkbox",
6003
+ "falseIcon": falseIcon.value,
6004
+ "trueIcon": trueIcon.value,
6005
+ "aria-checked": indeterminate.value ? 'mixed' : undefined
6006
+ }), slots);
6007
+ });
5969
6008
  return {};
5970
6009
  }
5971
6010
  });
@@ -6529,12 +6568,12 @@
6529
6568
  const uid = getUid();
6530
6569
  const id = vue.computed(() => props.id || `checkbox-${uid}`);
6531
6570
  useRender(() => {
6532
- const [inputAttrs, controlAttrs] = filterInputAttrs(attrs);
6571
+ const [rootAttrs, controlAttrs] = filterInputAttrs(attrs);
6533
6572
  const [inputProps, _1] = VInput.filterProps(props);
6534
6573
  const [checkboxProps, _2] = VCheckboxBtn.filterProps(props);
6535
6574
  return vue.createVNode(VInput, vue.mergeProps({
6536
6575
  "class": ['v-checkbox', props.class]
6537
- }, inputAttrs, inputProps, {
6576
+ }, rootAttrs, inputProps, {
6538
6577
  "modelValue": model.value,
6539
6578
  "onUpdate:modelValue": $event => model.value = $event,
6540
6579
  "id": id.value,
@@ -9101,7 +9140,7 @@
9101
9140
  if (selector) {
9102
9141
  if (selector === 'parent') {
9103
9142
  let el = vm?.proxy?.$el?.parentNode;
9104
- while (el.hasAttribute('data-no-activator')) {
9143
+ while (el?.hasAttribute('data-no-activator')) {
9105
9144
  el = el.parentNode;
9106
9145
  }
9107
9146
  activator = el;
@@ -10862,6 +10901,7 @@
10862
10901
  } = useLocale();
10863
10902
  const vTextFieldRef = vue.ref();
10864
10903
  const vMenuRef = vue.ref();
10904
+ const vVirtualScrollRef = vue.ref();
10865
10905
  const _menu = useProxiedModel(props, 'menu');
10866
10906
  const menu = vue.computed({
10867
10907
  get: () => _menu.value,
@@ -10991,6 +11031,14 @@
10991
11031
  vTextFieldRef.value.value = '';
10992
11032
  }
10993
11033
  }
11034
+ vue.watch(menu, () => {
11035
+ if (!props.hideSelected && menu.value && selections.value.length) {
11036
+ const index = displayItems.value.findIndex(item => selections.value.some(s => item.value === s.value));
11037
+ IN_BROWSER && window.requestAnimationFrame(() => {
11038
+ index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
11039
+ });
11040
+ }
11041
+ });
10994
11042
  useRender(() => {
10995
11043
  const hasChips = !!(props.chips || slots.chip);
10996
11044
  const hasList = !!(!props.hideNoData || displayItems.value.length || slots['prepend-item'] || slots['append-item'] || slots['no-data']);
@@ -11052,6 +11100,7 @@
11052
11100
  default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? vue.createVNode(VListItem, {
11053
11101
  "title": t(props.noDataText)
11054
11102
  }, null)), vue.createVNode(VVirtualScroll, {
11103
+ "ref": vVirtualScrollRef,
11055
11104
  "renderless": true,
11056
11105
  "items": displayItems.value
11057
11106
  }, {
@@ -11312,6 +11361,7 @@
11312
11361
  const isPristine = vue.shallowRef(true);
11313
11362
  const listHasFocus = vue.shallowRef(false);
11314
11363
  const vMenuRef = vue.ref();
11364
+ const vVirtualScrollRef = vue.ref();
11315
11365
  const _menu = useProxiedModel(props, 'menu');
11316
11366
  const menu = vue.computed({
11317
11367
  get: () => _menu.value,
@@ -11402,7 +11452,7 @@
11402
11452
  menu.value = false;
11403
11453
  }
11404
11454
  if (highlightFirst.value && ['Enter', 'Tab'].includes(e.key)) {
11405
- select(filteredItems.value[0]);
11455
+ select(displayItems.value[0]);
11406
11456
  }
11407
11457
  if (e.key === 'ArrowDown' && highlightFirst.value) {
11408
11458
  listRef.value?.focus('next');
@@ -11515,6 +11565,14 @@
11515
11565
  if (val) menu.value = true;
11516
11566
  isPristine.value = !val;
11517
11567
  });
11568
+ vue.watch(menu, () => {
11569
+ if (!props.hideSelected && menu.value && selections.value.length) {
11570
+ const index = displayItems.value.findIndex(item => selections.value.some(s => item.value === s.value));
11571
+ IN_BROWSER && window.requestAnimationFrame(() => {
11572
+ index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
11573
+ });
11574
+ }
11575
+ });
11518
11576
  useRender(() => {
11519
11577
  const hasChips = !!(props.chips || slots.chip);
11520
11578
  const hasList = !!(!props.hideNoData || displayItems.value.length || slots['prepend-item'] || slots['append-item'] || slots['no-data']);
@@ -11574,6 +11632,7 @@
11574
11632
  default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? vue.createVNode(VListItem, {
11575
11633
  "title": t(props.noDataText)
11576
11634
  }, null)), vue.createVNode(VVirtualScroll, {
11635
+ "ref": vVirtualScrollRef,
11577
11636
  "renderless": true,
11578
11637
  "items": displayItems.value
11579
11638
  }, {
@@ -14845,6 +14904,7 @@
14845
14904
  const isPristine = vue.shallowRef(true);
14846
14905
  const listHasFocus = vue.shallowRef(false);
14847
14906
  const vMenuRef = vue.ref();
14907
+ const vVirtualScrollRef = vue.ref();
14848
14908
  const _menu = useProxiedModel(props, 'menu');
14849
14909
  const menu = vue.computed({
14850
14910
  get: () => _menu.value,
@@ -15078,6 +15138,14 @@
15078
15138
  search.value = '';
15079
15139
  }
15080
15140
  });
15141
+ vue.watch(menu, () => {
15142
+ if (!props.hideSelected && menu.value && selections.value.length) {
15143
+ const index = displayItems.value.findIndex(item => selections.value.some(s => item.value === s.value));
15144
+ IN_BROWSER && window.requestAnimationFrame(() => {
15145
+ index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
15146
+ });
15147
+ }
15148
+ });
15081
15149
  useRender(() => {
15082
15150
  const hasChips = !!(props.chips || slots.chip);
15083
15151
  const hasList = !!(!props.hideNoData || displayItems.value.length || slots['prepend-item'] || slots['append-item'] || slots['no-data']);
@@ -15136,6 +15204,7 @@
15136
15204
  default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? vue.createVNode(VListItem, {
15137
15205
  "title": t(props.noDataText)
15138
15206
  }, null)), vue.createVNode(VVirtualScroll, {
15207
+ "ref": vVirtualScrollRef,
15139
15208
  "renderless": true,
15140
15209
  "items": displayItems.value
15141
15210
  }, {
@@ -17527,7 +17596,7 @@
17527
17596
  const id = vue.computed(() => props.id || `radio-group-${uid}`);
17528
17597
  const model = useProxiedModel(props, 'modelValue');
17529
17598
  useRender(() => {
17530
- const [inputAttrs, controlAttrs] = filterInputAttrs(attrs);
17599
+ const [rootAttrs, controlAttrs] = filterInputAttrs(attrs);
17531
17600
  const [inputProps, _1] = VInput.filterProps(props);
17532
17601
  const [controlProps, _2] = VSelectionControl.filterProps(props);
17533
17602
  const label = slots.label ? slots.label({
@@ -17539,7 +17608,7 @@
17539
17608
  return vue.createVNode(VInput, vue.mergeProps({
17540
17609
  "class": ['v-radio-group', props.class],
17541
17610
  "style": props.style
17542
- }, inputAttrs, inputProps, {
17611
+ }, rootAttrs, inputProps, {
17543
17612
  "modelValue": model.value,
17544
17613
  "onUpdate:modelValue": $event => model.value = $event,
17545
17614
  "id": id.value
@@ -18516,6 +18585,7 @@
18516
18585
  focus,
18517
18586
  blur
18518
18587
  } = useFocus(props);
18588
+ const control = vue.ref();
18519
18589
  const loaderColor = vue.computed(() => {
18520
18590
  return typeof props.loading === 'string' && props.loading !== '' ? props.loading : props.color;
18521
18591
  });
@@ -18526,16 +18596,15 @@
18526
18596
  indeterminate.value = false;
18527
18597
  }
18528
18598
  }
18599
+ function onTrackClick(e) {
18600
+ e.stopPropagation();
18601
+ e.preventDefault();
18602
+ control.value?.input?.click();
18603
+ }
18529
18604
  useRender(() => {
18530
- const [inputAttrs, controlAttrs] = filterInputAttrs(attrs);
18605
+ const [rootAttrs, controlAttrs] = filterInputAttrs(attrs);
18531
18606
  const [inputProps, _1] = VInput.filterProps(props);
18532
18607
  const [controlProps, _2] = VSelectionControl.filterProps(props);
18533
- const control = vue.ref();
18534
- function onClick(e) {
18535
- e.stopPropagation();
18536
- e.preventDefault();
18537
- control.value?.input?.click();
18538
- }
18539
18608
  return vue.createVNode(VInput, vue.mergeProps({
18540
18609
  "class": ['v-switch', {
18541
18610
  'v-switch--inset': props.inset
@@ -18543,7 +18612,7 @@
18543
18612
  'v-switch--indeterminate': indeterminate.value
18544
18613
  }, loaderClasses.value, props.class],
18545
18614
  "style": props.style
18546
- }, inputAttrs, inputProps, {
18615
+ }, rootAttrs, inputProps, {
18547
18616
  "id": id.value,
18548
18617
  "focused": isFocused.value
18549
18618
  }), {
@@ -18571,19 +18640,29 @@
18571
18640
  "onBlur": blur
18572
18641
  }, controlAttrs), {
18573
18642
  ...slots,
18574
- default: () => vue.createVNode("div", {
18575
- "class": "v-switch__track",
18576
- "onClick": onClick
18577
- }, null),
18578
- input: _ref3 => {
18643
+ default: _ref3 => {
18579
18644
  let {
18580
- inputNode,
18581
- icon
18645
+ backgroundColorClasses,
18646
+ backgroundColorStyles
18582
18647
  } = _ref3;
18648
+ return vue.createVNode("div", {
18649
+ "class": ['v-switch__track', ...backgroundColorClasses.value],
18650
+ "style": backgroundColorStyles.value,
18651
+ "onClick": onTrackClick
18652
+ }, null);
18653
+ },
18654
+ input: _ref4 => {
18655
+ let {
18656
+ inputNode,
18657
+ icon,
18658
+ backgroundColorClasses,
18659
+ backgroundColorStyles
18660
+ } = _ref4;
18583
18661
  return vue.createVNode(vue.Fragment, null, [inputNode, vue.createVNode("div", {
18584
18662
  "class": ['v-switch__thumb', {
18585
18663
  'v-switch__thumb--filled': icon || props.loading
18586
- }]
18664
+ }, props.inset ? undefined : backgroundColorClasses.value],
18665
+ "style": props.inset ? undefined : backgroundColorStyles.value
18587
18666
  }, [vue.createVNode(VScaleTransition, null, {
18588
18667
  default: () => [!props.loading ? icon && vue.createVNode(VIcon, {
18589
18668
  "key": icon,
@@ -18724,8 +18803,8 @@
18724
18803
  const delta = prevPos > nextPos ? prevBox[rightBottom] - nextBox[rightBottom] : prevBox[xy] - nextBox[xy];
18725
18804
  const origin = Math.sign(delta) > 0 ? isHorizontal.value ? 'right' : 'bottom' : Math.sign(delta) < 0 ? isHorizontal.value ? 'left' : 'top' : 'center';
18726
18805
  const size = Math.abs(delta) + (Math.sign(delta) < 0 ? prevBox[widthHeight] : nextBox[widthHeight]);
18727
- const scale = size / Math.max(prevBox[widthHeight], nextBox[widthHeight]);
18728
- const initialScale = prevBox[widthHeight] / nextBox[widthHeight];
18806
+ const scale = size / Math.max(prevBox[widthHeight], nextBox[widthHeight]) || 0;
18807
+ const initialScale = prevBox[widthHeight] / nextBox[widthHeight] || 0;
18729
18808
  const sigma = 1.5;
18730
18809
  animate(nextEl, {
18731
18810
  backgroundColor: [color, 'currentcolor'],
@@ -19121,6 +19200,7 @@
19121
19200
  once: true
19122
19201
  }]]), props.autoGrow && vue.withDirectives(vue.createVNode("textarea", {
19123
19202
  "class": [fieldClass, 'v-textarea__sizer'],
19203
+ "id": `${slotProps.id}-sizer`,
19124
19204
  "onUpdate:modelValue": $event => model.value = $event,
19125
19205
  "ref": sizerRef,
19126
19206
  "readonly": true,
@@ -21725,6 +21805,98 @@
21725
21805
  }
21726
21806
  });
21727
21807
 
21808
+ // Types
21809
+
21810
+ const makeVDatePickerControlsProps = propsFactory({
21811
+ displayDate: String,
21812
+ disabled: {
21813
+ type: [Boolean, String],
21814
+ default: false
21815
+ },
21816
+ nextIcon: {
21817
+ type: [String],
21818
+ default: '$next'
21819
+ },
21820
+ prevIcon: {
21821
+ type: [String],
21822
+ default: '$prev'
21823
+ },
21824
+ expandIcon: {
21825
+ type: [String],
21826
+ default: '$expand'
21827
+ },
21828
+ collapseIcon: {
21829
+ type: [String],
21830
+ default: '$collapse'
21831
+ },
21832
+ viewMode: {
21833
+ type: String,
21834
+ default: 'month'
21835
+ }
21836
+ }, 'VDatePickerControls');
21837
+ const VDatePickerControls = genericComponent()({
21838
+ name: 'VDatePickerControls',
21839
+ props: makeVDatePickerControlsProps(),
21840
+ emits: {
21841
+ 'click:mode': () => true,
21842
+ 'click:prev': () => true,
21843
+ 'click:next': () => true
21844
+ },
21845
+ setup(props, _ref) {
21846
+ let {
21847
+ emit
21848
+ } = _ref;
21849
+ const modeIcon = vue.computed(() => {
21850
+ return props.viewMode === 'month' ? props.expandIcon : props.collapseIcon;
21851
+ });
21852
+ const disableMode = vue.computed(() => {
21853
+ return Array.isArray(props.disabled) ? props.disabled.includes('mode') : props.disabled;
21854
+ });
21855
+ const disablePrev = vue.computed(() => {
21856
+ return Array.isArray(props.disabled) ? props.disabled.includes('prev') : props.disabled;
21857
+ });
21858
+ const disableNext = vue.computed(() => {
21859
+ return Array.isArray(props.disabled) ? props.disabled.includes('next') : props.disabled;
21860
+ });
21861
+ function onClickPrev() {
21862
+ emit('click:prev');
21863
+ }
21864
+ function onClickNext() {
21865
+ emit('click:next');
21866
+ }
21867
+ function onClickMode() {
21868
+ emit('click:mode');
21869
+ }
21870
+ useRender(() => {
21871
+ return vue.createVNode("div", {
21872
+ "class": "v-date-picker-controls"
21873
+ }, [vue.createVNode("div", {
21874
+ "class": "v-date-picker-controls__date"
21875
+ }, [props.displayDate]), vue.createVNode(VBtn, {
21876
+ "disabled": disableMode.value,
21877
+ "key": "expand-btn",
21878
+ "icon": modeIcon.value,
21879
+ "variant": "text",
21880
+ "onClick": onClickMode
21881
+ }, null), vue.createVNode(VSpacer, null, null), vue.createVNode("div", {
21882
+ "key": "month-buttons",
21883
+ "class": "v-date-picker-controls__month"
21884
+ }, [vue.createVNode(VBtn, {
21885
+ "disabled": disablePrev.value,
21886
+ "icon": props.prevIcon,
21887
+ "variant": "text",
21888
+ "onClick": onClickPrev
21889
+ }, null), vue.createVNode(VBtn, {
21890
+ "disabled": disableNext.value,
21891
+ "icon": props.nextIcon,
21892
+ "variant": "text",
21893
+ "onClick": onClickNext
21894
+ }, null)])]);
21895
+ });
21896
+ return {};
21897
+ }
21898
+ });
21899
+
21728
21900
  // Utilities
21729
21901
 
21730
21902
  // Types
@@ -22293,76 +22465,6 @@
22293
22465
  };
22294
22466
  }
22295
22467
 
22296
- const makeVDatePickerControlsProps = propsFactory({
22297
- nextIcon: {
22298
- type: [String],
22299
- default: '$next'
22300
- },
22301
- prevIcon: {
22302
- type: [String],
22303
- default: '$prev'
22304
- },
22305
- expandIcon: {
22306
- type: [String],
22307
- default: '$expand'
22308
- },
22309
- collapseIcon: {
22310
- type: [String],
22311
- default: '$collapse'
22312
- },
22313
- range: {
22314
- default: false,
22315
- type: [Boolean, String],
22316
- validator: v => v === false || ['start', 'end'].includes(v)
22317
- },
22318
- ...omit(makeDateProps(), ['modelValue', 'inputMode'])
22319
- }, 'VDatePickerControls');
22320
- const VDatePickerControls = genericComponent()({
22321
- name: 'VDatePickerControls',
22322
- props: makeVDatePickerControlsProps(),
22323
- emits: {
22324
- ...omit(dateEmits, ['update:modelValue', 'update:inputMode'])
22325
- },
22326
- setup(props, _ref) {
22327
- let {
22328
- emit
22329
- } = _ref;
22330
- const adapter = useDate();
22331
- const monthAndYear = vue.computed(() => {
22332
- const month = props.range === 'end' ? adapter.addMonths(props.displayDate, 1) : props.displayDate;
22333
- return adapter.format(month, 'monthAndYear');
22334
- });
22335
- useRender(() => {
22336
- const prevBtn = vue.createVNode(VBtn, {
22337
- "variant": "text",
22338
- "icon": props.prevIcon,
22339
- "onClick": () => emit('update:displayDate', adapter.addMonths(props.displayDate, -1))
22340
- }, null);
22341
- const nextBtn = vue.createVNode(VBtn, {
22342
- "variant": "text",
22343
- "icon": props.nextIcon,
22344
- "onClick": () => emit('update:displayDate', adapter.addMonths(props.displayDate, 1))
22345
- }, null);
22346
- return vue.createVNode("div", {
22347
- "class": "v-date-picker-controls"
22348
- }, [props.viewMode === 'month' && props.range === 'start' && prevBtn, !!props.range && vue.createVNode(VSpacer, {
22349
- "key": "range-spacer"
22350
- }, null), vue.createVNode("div", {
22351
- "class": "v-date-picker-controls__date"
22352
- }, [monthAndYear.value]), vue.createVNode(VBtn, {
22353
- "key": "expand-btn",
22354
- "variant": "text",
22355
- "icon": props.viewMode === 'month' ? props.expandIcon : props.collapseIcon,
22356
- "onClick": () => emit('update:viewMode', props.viewMode === 'month' ? 'year' : 'month')
22357
- }, null), vue.createVNode(VSpacer, null, null), props.viewMode === 'month' && !props.range && vue.createVNode("div", {
22358
- "class": "v-date-picker-controls__month",
22359
- "key": "month-buttons"
22360
- }, [prevBtn, nextBtn]), props.viewMode === 'month' && props.range === 'end' && nextBtn]);
22361
- });
22362
- return {};
22363
- }
22364
- });
22365
-
22366
22468
  // Composables
22367
22469
 
22368
22470
  // Types
@@ -22419,6 +22521,8 @@
22419
22521
  side: {
22420
22522
  type: String
22421
22523
  },
22524
+ min: [Number, String, Date],
22525
+ max: [Number, String, Date],
22422
22526
  ...omit(makeDateProps(), ['inputMode', 'viewMode'])
22423
22527
  }, 'VDatePickerMonth');
22424
22528
  const VDatePickerMonth = genericComponent()({
@@ -22494,6 +22598,7 @@
22494
22598
  const startDate = validDates[0];
22495
22599
  const endDate = validDates[1];
22496
22600
  return days.map((date, index) => {
22601
+ const isDisabled = !!(props.min && adapter.isAfter(props.min, date) || props.max && adapter.isAfter(date, props.max));
22497
22602
  const isStart = startDate && adapter.isSameDay(date, startDate);
22498
22603
  const isEnd = endDate && adapter.isSameDay(date, endDate);
22499
22604
  const isAdjacent = !adapter.isSameMonth(date, month.value);
@@ -22504,6 +22609,7 @@
22504
22609
  formatted: adapter.format(date, 'keyboardDate'),
22505
22610
  year: adapter.getYear(date),
22506
22611
  month: adapter.getMonth(date),
22612
+ isDisabled,
22507
22613
  isWeekStart: index % 7 === 0,
22508
22614
  isWeekEnd: index % 7 === 6,
22509
22615
  isSelected: isStart || isEnd,
@@ -22646,50 +22752,55 @@
22646
22752
  "onTouchstart": handleMousedown
22647
22753
  }, [!props.hideWeekdays && adapter.getWeekdays().map(weekDay => vue.createVNode("div", {
22648
22754
  "class": ['v-date-picker-month__day', 'v-date-picker-month__weekday']
22649
- }, [weekDay])), daysInMonth.value.map((item, index) => vue.createVNode("div", {
22650
- "class": ['v-date-picker-month__day', {
22651
- 'v-date-picker-month__day--selected': item.isSelected,
22652
- 'v-date-picker-month__day--start': item.isStart,
22653
- 'v-date-picker-month__day--end': item.isEnd,
22654
- 'v-date-picker-month__day--adjacent': item.isAdjacent,
22655
- 'v-date-picker-month__day--hide-adjacent': item.isHidden,
22656
- 'v-date-picker-month__day--week-start': item.isWeekStart,
22657
- 'v-date-picker-month__day--week-end': item.isWeekEnd,
22658
- 'v-date-picker-month__day--hovered': item.isHovered
22659
- }],
22660
- "data-v-date": !item.isHidden ? item.isoDate : undefined
22661
- }, [item.inRange && vue.createVNode("div", {
22662
- "key": "in-range",
22663
- "class": ['v-date-picker-month__day--range', backgroundColorClasses.value],
22664
- "style": backgroundColorStyles.value
22665
- }, null), item.inHover && !item.isStart && !item.isEnd && !item.isHovered && !item.inRange && vue.createVNode("div", {
22666
- "key": "in-hover",
22667
- "class": "v-date-picker-month__day--hover"
22668
- }, null), (props.showAdjacentMonths || !item.isAdjacent) && vue.createVNode(VBtn, {
22669
- "icon": true,
22670
- "ripple": false,
22671
- "variant": (item.isToday || item.isHovered) && !item.isSelected ? 'outlined' : 'flat',
22672
- "active": item.isSelected,
22673
- "color": item.isSelected || item.isToday ? props.color : item.isHovered ? undefined : 'transparent'
22674
- }, {
22675
- default: () => [item.localized]
22676
- })]))])]);
22755
+ }, [weekDay])), daysInMonth.value.map((item, index) => {
22756
+ const color = item.isSelected || item.isToday ? props.color : item.isHovered || item.isDisabled ? undefined : 'transparent';
22757
+ const variant = item.isDisabled ? 'text' : (item.isToday || item.isHovered) && !item.isSelected ? 'outlined' : 'flat';
22758
+ return vue.createVNode("div", {
22759
+ "class": ['v-date-picker-month__day', {
22760
+ 'v-date-picker-month__day--selected': item.isSelected,
22761
+ 'v-date-picker-month__day--start': item.isStart,
22762
+ 'v-date-picker-month__day--end': item.isEnd,
22763
+ 'v-date-picker-month__day--adjacent': item.isAdjacent,
22764
+ 'v-date-picker-month__day--hide-adjacent': item.isHidden,
22765
+ 'v-date-picker-month__day--week-start': item.isWeekStart,
22766
+ 'v-date-picker-month__day--week-end': item.isWeekEnd,
22767
+ 'v-date-picker-month__day--hovered': item.isHovered
22768
+ }],
22769
+ "data-v-date": !item.isHidden && !item.isDisabled ? item.isoDate : undefined
22770
+ }, [item.inRange && vue.createVNode("div", {
22771
+ "key": "in-range",
22772
+ "class": ['v-date-picker-month__day--range', backgroundColorClasses.value],
22773
+ "style": backgroundColorStyles.value
22774
+ }, null), item.inHover && !item.isStart && !item.isEnd && !item.isHovered && !item.inRange && vue.createVNode("div", {
22775
+ "key": "in-hover",
22776
+ "class": "v-date-picker-month__day--hover"
22777
+ }, null), (props.showAdjacentMonths || !item.isAdjacent) && vue.createVNode(VBtn, {
22778
+ "active": item.isSelected,
22779
+ "color": color,
22780
+ "disabled": item.isDisabled,
22781
+ "icon": true,
22782
+ "ripple": false,
22783
+ "variant": variant
22784
+ }, {
22785
+ default: () => [item.localized]
22786
+ })]);
22787
+ })])]);
22677
22788
  }
22678
22789
  });
22679
22790
 
22680
22791
  const makeVDatePickerYearsProps = propsFactory({
22681
22792
  color: String,
22682
- min: Number,
22683
- max: Number,
22684
22793
  height: [String, Number],
22685
- displayDate: null
22794
+ displayDate: null,
22795
+ min: [Number, String, Date],
22796
+ max: [Number, String, Date]
22686
22797
  }, 'VDatePickerYears');
22687
22798
  const VDatePickerYears = genericComponent()({
22688
22799
  name: 'VDatePickerYears',
22689
22800
  props: makeVDatePickerYearsProps(),
22690
22801
  emits: {
22691
22802
  'update:displayDate': date => true,
22692
- 'update:viewMode': date => true
22803
+ 'click:mode': () => true
22693
22804
  },
22694
22805
  setup(props, _ref) {
22695
22806
  let {
@@ -22698,8 +22809,8 @@
22698
22809
  const adapter = useDate();
22699
22810
  const displayYear = vue.computed(() => adapter.getYear(props.displayDate ?? new Date()));
22700
22811
  const years = vue.computed(() => {
22701
- const min = props.min ?? displayYear.value - 50 - 2;
22702
- const max = props.max ?? displayYear.value + 50;
22812
+ const min = props.min ? adapter.date(props.min).getFullYear() : displayYear.value - 100;
22813
+ const max = props.max ? adapter.date(props.max).getFullYear() : displayYear.value + 50;
22703
22814
  return createRange(max - min, min);
22704
22815
  });
22705
22816
  const yearRef = vue.ref();
@@ -22715,19 +22826,21 @@
22715
22826
  }
22716
22827
  }, [vue.createVNode("div", {
22717
22828
  "class": "v-date-picker-years__content"
22718
- }, [years.value.map(year => vue.createVNode(VBtn, {
22719
- "ref": year === displayYear.value ? yearRef : undefined,
22720
- "variant": year === displayYear.value ? 'flat' : 'text',
22721
- "rounded": "xl",
22722
- "active": year === displayYear.value,
22723
- "color": year === displayYear.value ? props.color : undefined,
22724
- "onClick": () => {
22829
+ }, [years.value.map(year => {
22830
+ function onClick() {
22725
22831
  emit('update:displayDate', adapter.setYear(props.displayDate, year));
22726
- emit('update:viewMode', 'month');
22727
- }
22728
- }, {
22729
- default: () => [year]
22730
- }))])]));
22832
+ emit('click:mode');
22833
+ }
22834
+ return vue.createVNode(VBtn, {
22835
+ "ref": year === displayYear.value ? yearRef : undefined,
22836
+ "active": year === displayYear.value,
22837
+ "color": year === displayYear.value ? props.color : undefined,
22838
+ "rounded": "xl",
22839
+ "text": String(year),
22840
+ "variant": year === displayYear.value ? 'flat' : 'text',
22841
+ "onClick": onClick
22842
+ }, null);
22843
+ })])]));
22731
22844
  return {};
22732
22845
  }
22733
22846
  });
@@ -23012,21 +23125,24 @@
23012
23125
  const header = vue.computed(() => model.value.length ? adapter.format(model.value[0], 'normalDateWithWeekday') : t(props.header));
23013
23126
  const headerIcon = vue.computed(() => inputMode.value === 'calendar' ? props.keyboardIcon : props.calendarIcon);
23014
23127
  const headerTransition = vue.computed(() => `date-picker-header${isReversing.value ? '-reverse' : ''}-transition`);
23015
- function updateFromInput(input, index) {
23016
- const {
23017
- isValid,
23018
- date
23019
- } = adapter;
23020
- if (isValid(input)) {
23021
- const newModel = model.value.slice();
23022
- newModel[index] = date(input);
23023
- if (props.hideActions) {
23024
- model.value = newModel;
23025
- } else {
23026
- temporaryModel.value = newModel;
23027
- }
23128
+ const minDate = vue.computed(() => props.min && adapter.isValid(props.min) ? adapter.date(props.min) : null);
23129
+ const maxDate = vue.computed(() => props.max && adapter.isValid(props.max) ? adapter.date(props.max) : null);
23130
+ const disabled = vue.computed(() => {
23131
+ if (!minDate.value && !maxDate.value) return false;
23132
+ const targets = [];
23133
+ if (minDate.value) {
23134
+ const date = adapter.addDays(adapter.startOfMonth(displayDate.value), -1);
23135
+ adapter.isAfter(minDate.value, date) && targets.push('prev');
23028
23136
  }
23029
- }
23137
+ if (maxDate.value) {
23138
+ const date = adapter.addDays(adapter.endOfMonth(displayDate.value), 1);
23139
+ adapter.isAfter(date, maxDate.value) && targets.push('next');
23140
+ }
23141
+ if (minDate.value?.getFullYear() === maxDate.value?.getFullYear()) {
23142
+ targets.push('mode');
23143
+ }
23144
+ return targets;
23145
+ });
23030
23146
  vue.watch(model, val => {
23031
23147
  if (!isEqual(val, temporaryModel.value)) {
23032
23148
  temporaryModel.value = val;
@@ -23041,6 +23157,21 @@
23041
23157
  isReversing.value = adapter.isBefore(val[0], oldVal[0]);
23042
23158
  }
23043
23159
  });
23160
+ function updateFromInput(input, index) {
23161
+ const {
23162
+ isValid,
23163
+ date
23164
+ } = adapter;
23165
+ if (isValid(input)) {
23166
+ const newModel = model.value.slice();
23167
+ newModel[index] = date(input);
23168
+ if (props.hideActions) {
23169
+ model.value = newModel;
23170
+ } else {
23171
+ temporaryModel.value = newModel;
23172
+ }
23173
+ }
23174
+ }
23044
23175
  function onClickCancel() {
23045
23176
  emit('click:cancel');
23046
23177
  }
@@ -23051,6 +23182,15 @@
23051
23182
  function onClickAppend() {
23052
23183
  inputMode.value = inputMode.value === 'calendar' ? 'keyboard' : 'calendar';
23053
23184
  }
23185
+ function onClickNext() {
23186
+ displayDate.value = adapter.addMonths(displayDate.value, 1);
23187
+ }
23188
+ function onClickPrev() {
23189
+ displayDate.value = adapter.addMonths(displayDate.value, -1);
23190
+ }
23191
+ function onClickMode() {
23192
+ viewMode.value = viewMode.value === 'month' ? 'year' : 'month';
23193
+ }
23054
23194
  const headerSlotProps = vue.computed(() => ({
23055
23195
  header: header.value,
23056
23196
  appendIcon: headerIcon.value,
@@ -23072,10 +23212,11 @@
23072
23212
  "key": "header"
23073
23213
  }, headerSlotProps.value), null),
23074
23214
  default: () => inputMode.value === 'calendar' ? vue.createVNode(vue.Fragment, null, [vue.createVNode(VDatePickerControls, vue.mergeProps(datePickerControlsProps, {
23075
- "displayDate": displayDate.value,
23076
- "onUpdate:displayDate": $event => displayDate.value = $event,
23077
- "viewMode": viewMode.value,
23078
- "onUpdate:viewMode": $event => viewMode.value = $event
23215
+ "disabled": disabled.value,
23216
+ "displayDate": adapter.format(displayDate.value, 'monthAndYear'),
23217
+ "onClick:next": onClickNext,
23218
+ "onClick:prev": onClickPrev,
23219
+ "onClick:mode": onClickMode
23079
23220
  }), null), vue.createVNode(VFadeTransition, {
23080
23221
  "hideOnLeave": true
23081
23222
  }, {
@@ -23085,14 +23226,16 @@
23085
23226
  "modelValue": temporaryModel.value,
23086
23227
  "onUpdate:modelValue": $event => temporaryModel.value = $event,
23087
23228
  "displayDate": displayDate.value,
23088
- "onUpdate:displayDate": $event => displayDate.value = $event
23229
+ "min": minDate.value,
23230
+ "max": maxDate.value
23089
23231
  }), null) : vue.createVNode(VDatePickerYears, vue.mergeProps({
23090
23232
  "key": "date-picker-years"
23091
23233
  }, datePickerYearsProps, {
23092
23234
  "displayDate": displayDate.value,
23093
23235
  "onUpdate:displayDate": $event => displayDate.value = $event,
23094
- "viewMode": viewMode.value,
23095
- "onUpdate:viewMode": $event => viewMode.value = $event
23236
+ "min": minDate.value,
23237
+ "max": maxDate.value,
23238
+ "onClick:mode": onClickMode
23096
23239
  }), null)]
23097
23240
  })]) : vue.createVNode("div", {
23098
23241
  "class": "v-date-picker__input"
@@ -24435,7 +24578,7 @@
24435
24578
  date
24436
24579
  };
24437
24580
  }
24438
- const version$1 = "3.3.13";
24581
+ const version$1 = "3.3.15";
24439
24582
  createVuetify$1.version = version$1;
24440
24583
 
24441
24584
  // Vue's inject() can only be used in setup
@@ -24449,7 +24592,7 @@
24449
24592
 
24450
24593
  /* eslint-disable local-rules/sort-imports */
24451
24594
 
24452
- const version = "3.3.13";
24595
+ const version = "3.3.15";
24453
24596
 
24454
24597
  /* eslint-disable local-rules/sort-imports */
24455
24598