@vuetify/nightly 3.8.2-master.2025-04-27 → 3.8.3-dev.2025-04-29

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/CHANGELOG.md +13 -32
  2. package/dist/json/attributes.json +2092 -2084
  3. package/dist/json/importMap-labs.json +24 -24
  4. package/dist/json/importMap.json +148 -148
  5. package/dist/json/tags.json +2 -0
  6. package/dist/json/web-types.json +3854 -3834
  7. package/dist/vuetify-labs.cjs +146 -36
  8. package/dist/vuetify-labs.css +3420 -3397
  9. package/dist/vuetify-labs.d.ts +101 -64
  10. package/dist/vuetify-labs.esm.js +147 -37
  11. package/dist/vuetify-labs.esm.js.map +1 -1
  12. package/dist/vuetify-labs.js +146 -36
  13. package/dist/vuetify-labs.min.css +2 -2
  14. package/dist/vuetify.cjs +146 -36
  15. package/dist/vuetify.cjs.map +1 -1
  16. package/dist/vuetify.css +3284 -3261
  17. package/dist/vuetify.d.ts +101 -64
  18. package/dist/vuetify.esm.js +147 -37
  19. package/dist/vuetify.esm.js.map +1 -1
  20. package/dist/vuetify.js +146 -36
  21. package/dist/vuetify.js.map +1 -1
  22. package/dist/vuetify.min.css +2 -2
  23. package/dist/vuetify.min.js +1201 -1188
  24. package/dist/vuetify.min.js.map +1 -1
  25. package/lib/components/VBtnGroup/VBtnGroup.css +30 -7
  26. package/lib/components/VBtnGroup/VBtnGroup.d.ts +58 -32
  27. package/lib/components/VBtnGroup/VBtnGroup.js +7 -3
  28. package/lib/components/VBtnGroup/VBtnGroup.js.map +1 -1
  29. package/lib/components/VBtnGroup/VBtnGroup.sass +44 -17
  30. package/lib/components/VBtnToggle/VBtnToggle.d.ts +25 -0
  31. package/lib/components/VInput/VInput.d.ts +1 -1
  32. package/lib/components/VOverlay/VOverlay.css +1 -1
  33. package/lib/components/VOverlay/_variables.scss +1 -1
  34. package/lib/components/VOverlay/locationStrategies.d.ts +4 -0
  35. package/lib/components/VOverlay/locationStrategies.js +23 -3
  36. package/lib/components/VOverlay/locationStrategies.js.map +1 -1
  37. package/lib/composables/calendar.d.ts +1 -0
  38. package/lib/composables/calendar.js.map +1 -1
  39. package/lib/composables/defaults.js +6 -3
  40. package/lib/composables/defaults.js.map +1 -1
  41. package/lib/composables/theme.d.ts +6 -1
  42. package/lib/composables/theme.js +94 -26
  43. package/lib/composables/theme.js.map +1 -1
  44. package/lib/composables/virtual.js +6 -1
  45. package/lib/composables/virtual.js.map +1 -1
  46. package/lib/entry-bundler.js +1 -1
  47. package/lib/entry-bundler.js.map +1 -1
  48. package/lib/framework.d.ts +63 -54
  49. package/lib/framework.js +1 -1
  50. package/lib/framework.js.map +1 -1
  51. package/lib/util/globals.d.ts +1 -0
  52. package/lib/util/globals.js +1 -0
  53. package/lib/util/globals.js.map +1 -1
  54. package/lib/util/helpers.d.ts +2 -0
  55. package/lib/util/helpers.js +7 -0
  56. package/lib/util/helpers.js.map +1 -1
  57. package/package.json +3 -2
package/dist/vuetify.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.8.2-master.2025-04-27
2
+ * Vuetify v3.8.3-dev.2025-04-29
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
@@ -14,6 +14,7 @@
14
14
  const SUPPORTS_INTERSECTION = IN_BROWSER && 'IntersectionObserver' in window;
15
15
  const SUPPORTS_TOUCH = IN_BROWSER && ('ontouchstart' in window || window.navigator.maxTouchPoints > 0);
16
16
  const SUPPORTS_EYE_DROPPER = IN_BROWSER && 'EyeDropper' in window;
17
+ const SUPPORTS_MATCH_MEDIA = IN_BROWSER && 'matchMedia' in window && typeof window.matchMedia === 'function';
17
18
 
18
19
  function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
19
20
  function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
@@ -339,6 +340,9 @@
339
340
  _classPrivateFieldInitSpec(this, _pointer, 0);
340
341
  this.size = size;
341
342
  }
343
+ get isFull() {
344
+ return _classPrivateFieldGet(_arr, this).length === this.size;
345
+ }
342
346
  push(val) {
343
347
  _classPrivateFieldGet(_arr, this)[_classPrivateFieldGet(_pointer, this)] = val;
344
348
  _classPrivateFieldSet(_pointer, this, (_classPrivateFieldGet(_pointer, this) + 1) % this.size);
@@ -346,6 +350,10 @@
346
350
  values() {
347
351
  return _classPrivateFieldGet(_arr, this).slice(_classPrivateFieldGet(_pointer, this)).concat(_classPrivateFieldGet(_arr, this).slice(0, _classPrivateFieldGet(_pointer, this)));
348
352
  }
353
+ clear() {
354
+ _classPrivateFieldGet(_arr, this).length = 0;
355
+ _classPrivateFieldSet(_pointer, this, 0);
356
+ }
349
357
  }
350
358
  function getEventCoordinates(e) {
351
359
  if ('touches' in e) {
@@ -1336,7 +1344,7 @@
1336
1344
  return newDefaults;
1337
1345
  }
1338
1346
  function propIsDefined(vnode, prop) {
1339
- return typeof vnode.props?.[prop] !== 'undefined' || typeof vnode.props?.[toKebabCase(prop)] !== 'undefined';
1347
+ return vnode.props && (typeof vnode.props[prop] !== 'undefined' || typeof vnode.props[toKebabCase(prop)] !== 'undefined');
1340
1348
  }
1341
1349
  function internalUseDefaults() {
1342
1350
  let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
@@ -1353,9 +1361,12 @@
1353
1361
  const propValue = Reflect.get(target, prop);
1354
1362
  if (prop === 'class' || prop === 'style') {
1355
1363
  return [componentDefaults.value?.[prop], propValue].filter(v => v != null);
1356
- } else if (typeof prop === 'string' && !propIsDefined(vm.vnode, prop)) {
1357
- return componentDefaults.value?.[prop] !== undefined ? componentDefaults.value?.[prop] : defaults.value?.global?.[prop] !== undefined ? defaults.value?.global?.[prop] : propValue;
1358
1364
  }
1365
+ if (propIsDefined(vm.vnode, prop)) return propValue;
1366
+ const _componentDefault = componentDefaults.value?.[prop];
1367
+ if (_componentDefault !== undefined) return _componentDefault;
1368
+ const _globalDefault = defaults.value?.global?.[prop];
1369
+ if (_globalDefault !== undefined) return _globalDefault;
1359
1370
  return propValue;
1360
1371
  }
1361
1372
  });
@@ -2775,6 +2786,7 @@
2775
2786
  function genDefaults$1() {
2776
2787
  return {
2777
2788
  defaultTheme: 'light',
2789
+ prefix: 'v-',
2778
2790
  variations: {
2779
2791
  colors: [],
2780
2792
  lighten: 0,
@@ -2856,7 +2868,10 @@
2856
2868
  }
2857
2869
  }
2858
2870
  },
2859
- stylesheetId: 'vuetify-theme-stylesheet'
2871
+ stylesheetId: 'vuetify-theme-stylesheet',
2872
+ scoped: false,
2873
+ unimportant: false,
2874
+ utilities: true
2860
2875
  };
2861
2876
  }
2862
2877
  function parseThemeOptions() {
@@ -2879,21 +2894,21 @@
2879
2894
  function createCssClass(lines, selector, content, scope) {
2880
2895
  lines.push(`${getScopedSelector(selector, scope)} {\n`, ...content.map(line => ` ${line};\n`), '}\n');
2881
2896
  }
2882
- function genCssVariables(theme) {
2897
+ function genCssVariables(theme, prefix) {
2883
2898
  const lightOverlay = theme.dark ? 2 : 1;
2884
2899
  const darkOverlay = theme.dark ? 1 : 2;
2885
2900
  const variables = [];
2886
2901
  for (const [key, value] of Object.entries(theme.colors)) {
2887
2902
  const rgb = parseColor(value);
2888
- variables.push(`--v-theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2903
+ variables.push(`--${prefix}theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2889
2904
  if (!key.startsWith('on-')) {
2890
- variables.push(`--v-theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2905
+ variables.push(`--${prefix}theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2891
2906
  }
2892
2907
  }
2893
2908
  for (const [key, value] of Object.entries(theme.variables)) {
2894
2909
  const color = typeof value === 'string' && value.startsWith('#') ? parseColor(value) : undefined;
2895
2910
  const rgb = color ? `${color.r}, ${color.g}, ${color.b}` : undefined;
2896
- variables.push(`--v-${key}: ${rgb ?? value}`);
2911
+ variables.push(`--${prefix}${key}: ${rgb ?? value}`);
2897
2912
  }
2898
2913
  return variables;
2899
2914
  }
@@ -2937,7 +2952,8 @@
2937
2952
  const scopeSelector = `:where(${scope})`;
2938
2953
  return selector === ':root' ? scopeSelector : `${scopeSelector} ${selector}`;
2939
2954
  }
2940
- function upsertStyles(styleEl, styles) {
2955
+ function upsertStyles(id, cspNonce, styles) {
2956
+ const styleEl = getOrCreateStyleElement(id, cspNonce);
2941
2957
  if (!styleEl) return;
2942
2958
  styleEl.innerHTML = styles;
2943
2959
  }
@@ -2957,8 +2973,17 @@
2957
2973
  // Composables
2958
2974
  function createTheme(options) {
2959
2975
  const parsedOptions = parseThemeOptions(options);
2960
- const name = vue.shallowRef(parsedOptions.defaultTheme);
2976
+ const _name = vue.shallowRef(parsedOptions.defaultTheme);
2961
2977
  const themes = vue.ref(parsedOptions.themes);
2978
+ const systemName = vue.shallowRef('light');
2979
+ const name = vue.computed({
2980
+ get() {
2981
+ return _name.value === 'system' ? systemName.value : _name.value;
2982
+ },
2983
+ set(val) {
2984
+ _name.value = val;
2985
+ }
2986
+ });
2962
2987
  const computedThemes = vue.computed(() => {
2963
2988
  const acc = {};
2964
2989
  for (const [name, original] of Object.entries(themes.value)) {
@@ -2979,28 +3004,49 @@
2979
3004
  const current = vue.toRef(() => computedThemes.value[name.value]);
2980
3005
  const styles = vue.computed(() => {
2981
3006
  const lines = [];
3007
+ const important = parsedOptions.unimportant ? '' : ' !important';
3008
+ const scoped = parsedOptions.scoped ? parsedOptions.prefix : '';
2982
3009
  if (current.value?.dark) {
2983
3010
  createCssClass(lines, ':root', ['color-scheme: dark'], parsedOptions.scope);
2984
3011
  }
2985
- createCssClass(lines, ':root', genCssVariables(current.value), parsedOptions.scope);
3012
+ createCssClass(lines, ':root', genCssVariables(current.value, parsedOptions.prefix), parsedOptions.scope);
2986
3013
  for (const [themeName, theme] of Object.entries(computedThemes.value)) {
2987
- createCssClass(lines, `.v-theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme)], parsedOptions.scope);
2988
- }
2989
- const bgLines = [];
2990
- const fgLines = [];
2991
- const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
2992
- for (const key of colors) {
2993
- if (key.startsWith('on-')) {
2994
- createCssClass(fgLines, `.${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
2995
- } else {
2996
- createCssClass(bgLines, `.bg-${key}`, [`--v-theme-overlay-multiplier: var(--v-theme-${key}-overlay-multiplier)`, `background-color: rgb(var(--v-theme-${key})) !important`, `color: rgb(var(--v-theme-on-${key})) !important`], parsedOptions.scope);
2997
- createCssClass(fgLines, `.text-${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
2998
- createCssClass(fgLines, `.border-${key}`, [`--v-border-color: var(--v-theme-${key})`], parsedOptions.scope);
3014
+ createCssClass(lines, `.${parsedOptions.prefix}theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme, parsedOptions.prefix)], parsedOptions.scope);
3015
+ }
3016
+ if (parsedOptions.utilities) {
3017
+ const bgLines = [];
3018
+ const fgLines = [];
3019
+ const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
3020
+ for (const key of colors) {
3021
+ if (key.startsWith('on-')) {
3022
+ createCssClass(fgLines, `.${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
3023
+ } else {
3024
+ createCssClass(bgLines, `.${scoped}bg-${key}`, [`--${parsedOptions.prefix}theme-overlay-multiplier: var(--${parsedOptions.prefix}theme-${key}-overlay-multiplier)`, `background-color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`, `color: rgb(var(--${parsedOptions.prefix}theme-on-${key}))${important}`], parsedOptions.scope);
3025
+ createCssClass(fgLines, `.${scoped}text-${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
3026
+ createCssClass(fgLines, `.${scoped}border-${key}`, [`--${parsedOptions.prefix}border-color: var(--${parsedOptions.prefix}theme-${key})`], parsedOptions.scope);
3027
+ }
2999
3028
  }
3029
+ lines.push(...bgLines, ...fgLines);
3000
3030
  }
3001
- lines.push(...bgLines, ...fgLines);
3002
3031
  return lines.map((str, i) => i === 0 ? str : ` ${str}`).join('');
3003
3032
  });
3033
+ const themeClasses = vue.toRef(() => parsedOptions.isDisabled ? undefined : `${parsedOptions.prefix}theme--${name.value}`);
3034
+ const themeNames = vue.toRef(() => Object.keys(computedThemes.value));
3035
+ if (SUPPORTS_MATCH_MEDIA) {
3036
+ const media = window.matchMedia('(prefers-color-scheme: dark)');
3037
+ function updateSystemName() {
3038
+ systemName.value = media.matches ? 'dark' : 'light';
3039
+ }
3040
+ updateSystemName();
3041
+ media.addEventListener('change', updateSystemName, {
3042
+ passive: true
3043
+ });
3044
+ if (vue.getCurrentScope()) {
3045
+ vue.onScopeDispose(() => {
3046
+ media.removeEventListener('change', updateSystemName);
3047
+ });
3048
+ }
3049
+ }
3004
3050
  function install(app) {
3005
3051
  if (parsedOptions.isDisabled) return;
3006
3052
  const head = app._context.provides.usehead;
@@ -3038,22 +3084,55 @@
3038
3084
  updateStyles();
3039
3085
  }
3040
3086
  function updateStyles() {
3041
- upsertStyles(getOrCreateStyleElement(parsedOptions.stylesheetId, parsedOptions.cspNonce), styles.value);
3087
+ upsertStyles(parsedOptions.stylesheetId, parsedOptions.cspNonce, styles.value);
3042
3088
  }
3043
3089
  }
3044
3090
  }
3045
- const themeClasses = vue.toRef(() => parsedOptions.isDisabled ? undefined : `v-theme--${name.value}`);
3091
+ function change(themeName) {
3092
+ if (!themeNames.value.includes(themeName)) {
3093
+ consoleWarn(`Theme "${themeName}" not found on the Vuetify theme instance`);
3094
+ return;
3095
+ }
3096
+ name.value = themeName;
3097
+ }
3098
+ function cycle() {
3099
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : themeNames.value;
3100
+ const currentIndex = themeArray.indexOf(name.value);
3101
+ const nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % themeArray.length;
3102
+ change(themeArray[nextIndex]);
3103
+ }
3104
+ function toggle() {
3105
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['light', 'dark'];
3106
+ cycle(themeArray);
3107
+ }
3108
+ const globalName = new Proxy(name, {
3109
+ get(target, prop) {
3110
+ return target[prop];
3111
+ },
3112
+ set(target, prop, val) {
3113
+ if (prop === 'value') {
3114
+ deprecate(`theme.global.name.value = ${val}`, `theme.change('${val}')`);
3115
+ }
3116
+ // @ts-expect-error
3117
+ target[prop] = val;
3118
+ return true;
3119
+ }
3120
+ });
3046
3121
  return {
3047
3122
  install,
3123
+ change,
3124
+ cycle,
3125
+ toggle,
3048
3126
  isDisabled: parsedOptions.isDisabled,
3049
3127
  name,
3050
3128
  themes,
3051
3129
  current,
3052
3130
  computedThemes,
3131
+ prefix: parsedOptions.prefix,
3053
3132
  themeClasses,
3054
3133
  styles,
3055
3134
  global: {
3056
- name,
3135
+ name: globalName,
3057
3136
  current
3058
3137
  }
3059
3138
  };
@@ -3064,7 +3143,7 @@
3064
3143
  if (!theme) throw new Error('Could not find Vuetify theme injection');
3065
3144
  const name = vue.toRef(() => props.theme ?? theme.name.value);
3066
3145
  const current = vue.toRef(() => theme.themes.value[name.value]);
3067
- const themeClasses = vue.toRef(() => theme.isDisabled ? undefined : `v-theme--${name.value}`);
3146
+ const themeClasses = vue.toRef(() => theme.isDisabled ? undefined : `${theme.prefix}theme--${name.value}`);
3068
3147
  const newTheme = {
3069
3148
  ...theme,
3070
3149
  name,
@@ -4608,9 +4687,15 @@
4608
4687
  };
4609
4688
  }
4610
4689
 
4690
+ // Types
4691
+
4611
4692
  const makeVBtnGroupProps = propsFactory({
4612
4693
  baseColor: String,
4613
4694
  divided: Boolean,
4695
+ direction: {
4696
+ type: String,
4697
+ default: 'horizontal'
4698
+ },
4614
4699
  ...makeBorderProps(),
4615
4700
  ...makeComponentProps(),
4616
4701
  ...makeDensityProps(),
@@ -4644,7 +4729,7 @@
4644
4729
  } = useRounded(props);
4645
4730
  provideDefaults({
4646
4731
  VBtn: {
4647
- height: 'auto',
4732
+ height: vue.toRef(() => props.direction === 'horizontal' ? 'auto' : null),
4648
4733
  baseColor: vue.toRef(() => props.baseColor),
4649
4734
  color: vue.toRef(() => props.color),
4650
4735
  density: vue.toRef(() => props.density),
@@ -4654,7 +4739,7 @@
4654
4739
  });
4655
4740
  useRender(() => {
4656
4741
  return vue.createVNode(props.tag, {
4657
- "class": ['v-btn-group', {
4742
+ "class": ['v-btn-group', `v-btn-group--${props.direction}`, {
4658
4743
  'v-btn-group--divided': props.divided
4659
4744
  }, themeClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, roundedClasses.value, props.class],
4660
4745
  "style": props.style
@@ -10386,8 +10471,27 @@
10386
10471
  return typeof props.offset === 'number' ? [props.offset, 0] : [0, 0];
10387
10472
  });
10388
10473
  let observe = false;
10474
+ let lastFrame = -1;
10475
+ const flipped = new CircularBuffer(4);
10389
10476
  const observer = new ResizeObserver(() => {
10390
- if (observe) updateLocation();
10477
+ if (!observe) return;
10478
+
10479
+ // Detect consecutive frames
10480
+ requestAnimationFrame(newTime => {
10481
+ if (newTime !== lastFrame) flipped.clear();
10482
+ requestAnimationFrame(newNewTime => {
10483
+ lastFrame = newNewTime;
10484
+ });
10485
+ });
10486
+ if (flipped.isFull) {
10487
+ const values = flipped.values();
10488
+ if (deepEqual(values.at(-1), values.at(-3))) {
10489
+ // Flipping is causing a container resize loop
10490
+ return;
10491
+ }
10492
+ }
10493
+ const result = updateLocation();
10494
+ if (result) flipped.push(result.flipped);
10391
10495
  });
10392
10496
  vue.watch([data.target, data.contentEl], (_ref, _ref2) => {
10393
10497
  let [newTarget, newContentEl] = _ref;
@@ -10602,7 +10706,8 @@
10602
10706
  });
10603
10707
  return {
10604
10708
  available,
10605
- contentBox
10709
+ contentBox,
10710
+ flipped
10606
10711
  };
10607
10712
  }
10608
10713
  vue.watch(() => [preferredAnchor.value, preferredOrigin.value, props.offset, props.minWidth, props.minHeight, props.maxWidth, props.maxHeight], () => updateLocation());
@@ -12599,7 +12704,12 @@
12599
12704
  }
12600
12705
  function calculateOffset(index) {
12601
12706
  index = clamp(index, 0, items.value.length - 1);
12602
- return offsets[index] || 0;
12707
+ const whole = Math.floor(index);
12708
+ const fraction = index % 1;
12709
+ const next = whole + 1;
12710
+ const wholeOffset = offsets[whole] || 0;
12711
+ const nextOffset = offsets[next] || wholeOffset;
12712
+ return wholeOffset + (nextOffset - wholeOffset) * fraction;
12603
12713
  }
12604
12714
  function calculateIndex(scrollTop) {
12605
12715
  return binaryClosest(offsets, scrollTop);
@@ -29185,7 +29295,7 @@
29185
29295
  };
29186
29296
  });
29187
29297
  }
29188
- const version$1 = "3.8.2-master.2025-04-27";
29298
+ const version$1 = "3.8.3-dev.2025-04-29";
29189
29299
  createVuetify$1.version = version$1;
29190
29300
 
29191
29301
  // Vue's inject() can only be used in setup
@@ -29210,7 +29320,7 @@
29210
29320
  ...options
29211
29321
  });
29212
29322
  };
29213
- const version = "3.8.2-master.2025-04-27";
29323
+ const version = "3.8.3-dev.2025-04-29";
29214
29324
  createVuetify.version = version;
29215
29325
 
29216
29326
  exports.blueprints = index;