@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
@@ -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
  */
@@ -85,6 +85,7 @@
85
85
  const SUPPORTS_INTERSECTION = IN_BROWSER && 'IntersectionObserver' in window;
86
86
  const SUPPORTS_TOUCH = IN_BROWSER && ('ontouchstart' in window || window.navigator.maxTouchPoints > 0);
87
87
  const SUPPORTS_EYE_DROPPER = IN_BROWSER && 'EyeDropper' in window;
88
+ const SUPPORTS_MATCH_MEDIA = IN_BROWSER && 'matchMedia' in window && typeof window.matchMedia === 'function';
88
89
 
89
90
  function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
90
91
  function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
@@ -416,6 +417,9 @@
416
417
  _classPrivateFieldInitSpec(this, _pointer, 0);
417
418
  this.size = size;
418
419
  }
420
+ get isFull() {
421
+ return _classPrivateFieldGet(_arr, this).length === this.size;
422
+ }
419
423
  push(val) {
420
424
  _classPrivateFieldGet(_arr, this)[_classPrivateFieldGet(_pointer, this)] = val;
421
425
  _classPrivateFieldSet(_pointer, this, (_classPrivateFieldGet(_pointer, this) + 1) % this.size);
@@ -423,6 +427,10 @@
423
427
  values() {
424
428
  return _classPrivateFieldGet(_arr, this).slice(_classPrivateFieldGet(_pointer, this)).concat(_classPrivateFieldGet(_arr, this).slice(0, _classPrivateFieldGet(_pointer, this)));
425
429
  }
430
+ clear() {
431
+ _classPrivateFieldGet(_arr, this).length = 0;
432
+ _classPrivateFieldSet(_pointer, this, 0);
433
+ }
426
434
  }
427
435
  function getEventCoordinates(e) {
428
436
  if ('touches' in e) {
@@ -1342,7 +1350,7 @@
1342
1350
  return newDefaults;
1343
1351
  }
1344
1352
  function propIsDefined(vnode, prop) {
1345
- return typeof vnode.props?.[prop] !== 'undefined' || typeof vnode.props?.[toKebabCase(prop)] !== 'undefined';
1353
+ return vnode.props && (typeof vnode.props[prop] !== 'undefined' || typeof vnode.props[toKebabCase(prop)] !== 'undefined');
1346
1354
  }
1347
1355
  function internalUseDefaults() {
1348
1356
  let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
@@ -1359,9 +1367,12 @@
1359
1367
  const propValue = Reflect.get(target, prop);
1360
1368
  if (prop === 'class' || prop === 'style') {
1361
1369
  return [componentDefaults.value?.[prop], propValue].filter(v => v != null);
1362
- } else if (typeof prop === 'string' && !propIsDefined(vm.vnode, prop)) {
1363
- return componentDefaults.value?.[prop] !== undefined ? componentDefaults.value?.[prop] : defaults.value?.global?.[prop] !== undefined ? defaults.value?.global?.[prop] : propValue;
1364
1370
  }
1371
+ if (propIsDefined(vm.vnode, prop)) return propValue;
1372
+ const _componentDefault = componentDefaults.value?.[prop];
1373
+ if (_componentDefault !== undefined) return _componentDefault;
1374
+ const _globalDefault = defaults.value?.global?.[prop];
1375
+ if (_globalDefault !== undefined) return _globalDefault;
1365
1376
  return propValue;
1366
1377
  }
1367
1378
  });
@@ -2289,6 +2300,7 @@
2289
2300
  function genDefaults$2() {
2290
2301
  return {
2291
2302
  defaultTheme: 'light',
2303
+ prefix: 'v-',
2292
2304
  variations: {
2293
2305
  colors: [],
2294
2306
  lighten: 0,
@@ -2370,7 +2382,10 @@
2370
2382
  }
2371
2383
  }
2372
2384
  },
2373
- stylesheetId: 'vuetify-theme-stylesheet'
2385
+ stylesheetId: 'vuetify-theme-stylesheet',
2386
+ scoped: false,
2387
+ unimportant: false,
2388
+ utilities: true
2374
2389
  };
2375
2390
  }
2376
2391
  function parseThemeOptions() {
@@ -2393,21 +2408,21 @@
2393
2408
  function createCssClass(lines, selector, content, scope) {
2394
2409
  lines.push(`${getScopedSelector(selector, scope)} {\n`, ...content.map(line => ` ${line};\n`), '}\n');
2395
2410
  }
2396
- function genCssVariables(theme) {
2411
+ function genCssVariables(theme, prefix) {
2397
2412
  const lightOverlay = theme.dark ? 2 : 1;
2398
2413
  const darkOverlay = theme.dark ? 1 : 2;
2399
2414
  const variables = [];
2400
2415
  for (const [key, value] of Object.entries(theme.colors)) {
2401
2416
  const rgb = parseColor(value);
2402
- variables.push(`--v-theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2417
+ variables.push(`--${prefix}theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2403
2418
  if (!key.startsWith('on-')) {
2404
- variables.push(`--v-theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2419
+ variables.push(`--${prefix}theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2405
2420
  }
2406
2421
  }
2407
2422
  for (const [key, value] of Object.entries(theme.variables)) {
2408
2423
  const color = typeof value === 'string' && value.startsWith('#') ? parseColor(value) : undefined;
2409
2424
  const rgb = color ? `${color.r}, ${color.g}, ${color.b}` : undefined;
2410
- variables.push(`--v-${key}: ${rgb ?? value}`);
2425
+ variables.push(`--${prefix}${key}: ${rgb ?? value}`);
2411
2426
  }
2412
2427
  return variables;
2413
2428
  }
@@ -2451,7 +2466,8 @@
2451
2466
  const scopeSelector = `:where(${scope})`;
2452
2467
  return selector === ':root' ? scopeSelector : `${scopeSelector} ${selector}`;
2453
2468
  }
2454
- function upsertStyles(styleEl, styles) {
2469
+ function upsertStyles(id, cspNonce, styles) {
2470
+ const styleEl = getOrCreateStyleElement(id, cspNonce);
2455
2471
  if (!styleEl) return;
2456
2472
  styleEl.innerHTML = styles;
2457
2473
  }
@@ -2471,8 +2487,17 @@
2471
2487
  // Composables
2472
2488
  function createTheme(options) {
2473
2489
  const parsedOptions = parseThemeOptions(options);
2474
- const name = vue.shallowRef(parsedOptions.defaultTheme);
2490
+ const _name = vue.shallowRef(parsedOptions.defaultTheme);
2475
2491
  const themes = vue.ref(parsedOptions.themes);
2492
+ const systemName = vue.shallowRef('light');
2493
+ const name = vue.computed({
2494
+ get() {
2495
+ return _name.value === 'system' ? systemName.value : _name.value;
2496
+ },
2497
+ set(val) {
2498
+ _name.value = val;
2499
+ }
2500
+ });
2476
2501
  const computedThemes = vue.computed(() => {
2477
2502
  const acc = {};
2478
2503
  for (const [name, original] of Object.entries(themes.value)) {
@@ -2493,28 +2518,49 @@
2493
2518
  const current = vue.toRef(() => computedThemes.value[name.value]);
2494
2519
  const styles = vue.computed(() => {
2495
2520
  const lines = [];
2521
+ const important = parsedOptions.unimportant ? '' : ' !important';
2522
+ const scoped = parsedOptions.scoped ? parsedOptions.prefix : '';
2496
2523
  if (current.value?.dark) {
2497
2524
  createCssClass(lines, ':root', ['color-scheme: dark'], parsedOptions.scope);
2498
2525
  }
2499
- createCssClass(lines, ':root', genCssVariables(current.value), parsedOptions.scope);
2526
+ createCssClass(lines, ':root', genCssVariables(current.value, parsedOptions.prefix), parsedOptions.scope);
2500
2527
  for (const [themeName, theme] of Object.entries(computedThemes.value)) {
2501
- createCssClass(lines, `.v-theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme)], parsedOptions.scope);
2502
- }
2503
- const bgLines = [];
2504
- const fgLines = [];
2505
- const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
2506
- for (const key of colors) {
2507
- if (key.startsWith('on-')) {
2508
- createCssClass(fgLines, `.${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
2509
- } else {
2510
- 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);
2511
- createCssClass(fgLines, `.text-${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
2512
- createCssClass(fgLines, `.border-${key}`, [`--v-border-color: var(--v-theme-${key})`], parsedOptions.scope);
2528
+ createCssClass(lines, `.${parsedOptions.prefix}theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme, parsedOptions.prefix)], parsedOptions.scope);
2529
+ }
2530
+ if (parsedOptions.utilities) {
2531
+ const bgLines = [];
2532
+ const fgLines = [];
2533
+ const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
2534
+ for (const key of colors) {
2535
+ if (key.startsWith('on-')) {
2536
+ createCssClass(fgLines, `.${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
2537
+ } else {
2538
+ 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);
2539
+ createCssClass(fgLines, `.${scoped}text-${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
2540
+ createCssClass(fgLines, `.${scoped}border-${key}`, [`--${parsedOptions.prefix}border-color: var(--${parsedOptions.prefix}theme-${key})`], parsedOptions.scope);
2541
+ }
2513
2542
  }
2543
+ lines.push(...bgLines, ...fgLines);
2514
2544
  }
2515
- lines.push(...bgLines, ...fgLines);
2516
2545
  return lines.map((str, i) => i === 0 ? str : ` ${str}`).join('');
2517
2546
  });
2547
+ const themeClasses = vue.toRef(() => parsedOptions.isDisabled ? undefined : `${parsedOptions.prefix}theme--${name.value}`);
2548
+ const themeNames = vue.toRef(() => Object.keys(computedThemes.value));
2549
+ if (SUPPORTS_MATCH_MEDIA) {
2550
+ const media = window.matchMedia('(prefers-color-scheme: dark)');
2551
+ function updateSystemName() {
2552
+ systemName.value = media.matches ? 'dark' : 'light';
2553
+ }
2554
+ updateSystemName();
2555
+ media.addEventListener('change', updateSystemName, {
2556
+ passive: true
2557
+ });
2558
+ if (vue.getCurrentScope()) {
2559
+ vue.onScopeDispose(() => {
2560
+ media.removeEventListener('change', updateSystemName);
2561
+ });
2562
+ }
2563
+ }
2518
2564
  function install(app) {
2519
2565
  if (parsedOptions.isDisabled) return;
2520
2566
  const head = app._context.provides.usehead;
@@ -2552,22 +2598,55 @@
2552
2598
  updateStyles();
2553
2599
  }
2554
2600
  function updateStyles() {
2555
- upsertStyles(getOrCreateStyleElement(parsedOptions.stylesheetId, parsedOptions.cspNonce), styles.value);
2601
+ upsertStyles(parsedOptions.stylesheetId, parsedOptions.cspNonce, styles.value);
2556
2602
  }
2557
2603
  }
2558
2604
  }
2559
- const themeClasses = vue.toRef(() => parsedOptions.isDisabled ? undefined : `v-theme--${name.value}`);
2605
+ function change(themeName) {
2606
+ if (!themeNames.value.includes(themeName)) {
2607
+ consoleWarn(`Theme "${themeName}" not found on the Vuetify theme instance`);
2608
+ return;
2609
+ }
2610
+ name.value = themeName;
2611
+ }
2612
+ function cycle() {
2613
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : themeNames.value;
2614
+ const currentIndex = themeArray.indexOf(name.value);
2615
+ const nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % themeArray.length;
2616
+ change(themeArray[nextIndex]);
2617
+ }
2618
+ function toggle() {
2619
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['light', 'dark'];
2620
+ cycle(themeArray);
2621
+ }
2622
+ const globalName = new Proxy(name, {
2623
+ get(target, prop) {
2624
+ return target[prop];
2625
+ },
2626
+ set(target, prop, val) {
2627
+ if (prop === 'value') {
2628
+ deprecate(`theme.global.name.value = ${val}`, `theme.change('${val}')`);
2629
+ }
2630
+ // @ts-expect-error
2631
+ target[prop] = val;
2632
+ return true;
2633
+ }
2634
+ });
2560
2635
  return {
2561
2636
  install,
2637
+ change,
2638
+ cycle,
2639
+ toggle,
2562
2640
  isDisabled: parsedOptions.isDisabled,
2563
2641
  name,
2564
2642
  themes,
2565
2643
  current,
2566
2644
  computedThemes,
2645
+ prefix: parsedOptions.prefix,
2567
2646
  themeClasses,
2568
2647
  styles,
2569
2648
  global: {
2570
- name,
2649
+ name: globalName,
2571
2650
  current
2572
2651
  }
2573
2652
  };
@@ -2578,7 +2657,7 @@
2578
2657
  if (!theme) throw new Error('Could not find Vuetify theme injection');
2579
2658
  const name = vue.toRef(() => props.theme ?? theme.name.value);
2580
2659
  const current = vue.toRef(() => theme.themes.value[name.value]);
2581
- const themeClasses = vue.toRef(() => theme.isDisabled ? undefined : `v-theme--${name.value}`);
2660
+ const themeClasses = vue.toRef(() => theme.isDisabled ? undefined : `${theme.prefix}theme--${name.value}`);
2582
2661
  const newTheme = {
2583
2662
  ...theme,
2584
2663
  name,
@@ -4122,9 +4201,15 @@
4122
4201
  };
4123
4202
  }
4124
4203
 
4204
+ // Types
4205
+
4125
4206
  const makeVBtnGroupProps = propsFactory({
4126
4207
  baseColor: String,
4127
4208
  divided: Boolean,
4209
+ direction: {
4210
+ type: String,
4211
+ default: 'horizontal'
4212
+ },
4128
4213
  ...makeBorderProps(),
4129
4214
  ...makeComponentProps(),
4130
4215
  ...makeDensityProps(),
@@ -4158,7 +4243,7 @@
4158
4243
  } = useRounded(props);
4159
4244
  provideDefaults({
4160
4245
  VBtn: {
4161
- height: 'auto',
4246
+ height: vue.toRef(() => props.direction === 'horizontal' ? 'auto' : null),
4162
4247
  baseColor: vue.toRef(() => props.baseColor),
4163
4248
  color: vue.toRef(() => props.color),
4164
4249
  density: vue.toRef(() => props.density),
@@ -4168,7 +4253,7 @@
4168
4253
  });
4169
4254
  useRender(() => {
4170
4255
  return vue.createVNode(props.tag, {
4171
- "class": ['v-btn-group', {
4256
+ "class": ['v-btn-group', `v-btn-group--${props.direction}`, {
4172
4257
  'v-btn-group--divided': props.divided
4173
4258
  }, themeClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, roundedClasses.value, props.class],
4174
4259
  "style": props.style
@@ -10108,8 +10193,27 @@
10108
10193
  return typeof props.offset === 'number' ? [props.offset, 0] : [0, 0];
10109
10194
  });
10110
10195
  let observe = false;
10196
+ let lastFrame = -1;
10197
+ const flipped = new CircularBuffer(4);
10111
10198
  const observer = new ResizeObserver(() => {
10112
- if (observe) updateLocation();
10199
+ if (!observe) return;
10200
+
10201
+ // Detect consecutive frames
10202
+ requestAnimationFrame(newTime => {
10203
+ if (newTime !== lastFrame) flipped.clear();
10204
+ requestAnimationFrame(newNewTime => {
10205
+ lastFrame = newNewTime;
10206
+ });
10207
+ });
10208
+ if (flipped.isFull) {
10209
+ const values = flipped.values();
10210
+ if (deepEqual(values.at(-1), values.at(-3))) {
10211
+ // Flipping is causing a container resize loop
10212
+ return;
10213
+ }
10214
+ }
10215
+ const result = updateLocation();
10216
+ if (result) flipped.push(result.flipped);
10113
10217
  });
10114
10218
  vue.watch([data.target, data.contentEl], (_ref, _ref2) => {
10115
10219
  let [newTarget, newContentEl] = _ref;
@@ -10324,7 +10428,8 @@
10324
10428
  });
10325
10429
  return {
10326
10430
  available,
10327
- contentBox
10431
+ contentBox,
10432
+ flipped
10328
10433
  };
10329
10434
  }
10330
10435
  vue.watch(() => [preferredAnchor.value, preferredOrigin.value, props.offset, props.minWidth, props.minHeight, props.maxWidth, props.maxHeight], () => updateLocation());
@@ -12321,7 +12426,12 @@
12321
12426
  }
12322
12427
  function calculateOffset(index) {
12323
12428
  index = clamp(index, 0, items.value.length - 1);
12324
- return offsets[index] || 0;
12429
+ const whole = Math.floor(index);
12430
+ const fraction = index % 1;
12431
+ const next = whole + 1;
12432
+ const wholeOffset = offsets[whole] || 0;
12433
+ const nextOffset = offsets[next] || wholeOffset;
12434
+ return wholeOffset + (nextOffset - wholeOffset) * fraction;
12325
12435
  }
12326
12436
  function calculateIndex(scrollTop) {
12327
12437
  return binaryClosest(offsets, scrollTop);
@@ -31608,7 +31718,7 @@
31608
31718
  };
31609
31719
  });
31610
31720
  }
31611
- const version$1 = "3.8.2-master.2025-04-27";
31721
+ const version$1 = "3.8.3-dev.2025-04-29";
31612
31722
  createVuetify$1.version = version$1;
31613
31723
 
31614
31724
  // Vue's inject() can only be used in setup
@@ -31906,7 +32016,7 @@
31906
32016
 
31907
32017
  /* eslint-disable local-rules/sort-imports */
31908
32018
 
31909
- const version = "3.8.2-master.2025-04-27";
32019
+ const version = "3.8.3-dev.2025-04-29";
31910
32020
 
31911
32021
  /* eslint-disable local-rules/sort-imports */
31912
32022