@vuetify/nightly 3.8.1-dev.2025-04-07 → 3.8.1-dev.2025-04-13

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.
package/dist/vuetify.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.8.1-dev.2025-04-07
2
+ * Vuetify v3.8.1-dev.2025-04-13
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"); }
@@ -2758,6 +2759,7 @@
2758
2759
  function genDefaults$1() {
2759
2760
  return {
2760
2761
  defaultTheme: 'light',
2762
+ prefix: 'v-',
2761
2763
  variations: {
2762
2764
  colors: [],
2763
2765
  lighten: 0,
@@ -2839,7 +2841,10 @@
2839
2841
  }
2840
2842
  }
2841
2843
  },
2842
- stylesheetId: 'vuetify-theme-stylesheet'
2844
+ stylesheetId: 'vuetify-theme-stylesheet',
2845
+ scoped: false,
2846
+ unimportant: false,
2847
+ utilities: true
2843
2848
  };
2844
2849
  }
2845
2850
  function parseThemeOptions() {
@@ -2862,21 +2867,21 @@
2862
2867
  function createCssClass(lines, selector, content, scope) {
2863
2868
  lines.push(`${getScopedSelector(selector, scope)} {\n`, ...content.map(line => ` ${line};\n`), '}\n');
2864
2869
  }
2865
- function genCssVariables(theme) {
2870
+ function genCssVariables(theme, prefix) {
2866
2871
  const lightOverlay = theme.dark ? 2 : 1;
2867
2872
  const darkOverlay = theme.dark ? 1 : 2;
2868
2873
  const variables = [];
2869
2874
  for (const [key, value] of Object.entries(theme.colors)) {
2870
2875
  const rgb = parseColor(value);
2871
- variables.push(`--v-theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2876
+ variables.push(`--${prefix}theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2872
2877
  if (!key.startsWith('on-')) {
2873
- variables.push(`--v-theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2878
+ variables.push(`--${prefix}theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2874
2879
  }
2875
2880
  }
2876
2881
  for (const [key, value] of Object.entries(theme.variables)) {
2877
2882
  const color = typeof value === 'string' && value.startsWith('#') ? parseColor(value) : undefined;
2878
2883
  const rgb = color ? `${color.r}, ${color.g}, ${color.b}` : undefined;
2879
- variables.push(`--v-${key}: ${rgb ?? value}`);
2884
+ variables.push(`--${prefix}${key}: ${rgb ?? value}`);
2880
2885
  }
2881
2886
  return variables;
2882
2887
  }
@@ -2920,7 +2925,8 @@
2920
2925
  const scopeSelector = `:where(${scope})`;
2921
2926
  return selector === ':root' ? scopeSelector : `${scopeSelector} ${selector}`;
2922
2927
  }
2923
- function upsertStyles(styleEl, styles) {
2928
+ function upsertStyles(id, cspNonce, styles) {
2929
+ const styleEl = getOrCreateStyleElement(id, cspNonce);
2924
2930
  if (!styleEl) return;
2925
2931
  styleEl.innerHTML = styles;
2926
2932
  }
@@ -2940,8 +2946,17 @@
2940
2946
  // Composables
2941
2947
  function createTheme(options) {
2942
2948
  const parsedOptions = parseThemeOptions(options);
2943
- const name = vue.shallowRef(parsedOptions.defaultTheme);
2949
+ const _name = vue.shallowRef(parsedOptions.defaultTheme);
2944
2950
  const themes = vue.ref(parsedOptions.themes);
2951
+ const systemName = vue.shallowRef('light');
2952
+ const name = vue.computed({
2953
+ get() {
2954
+ return _name.value === 'system' ? systemName.value : _name.value;
2955
+ },
2956
+ set(val) {
2957
+ _name.value = val;
2958
+ }
2959
+ });
2945
2960
  const computedThemes = vue.computed(() => {
2946
2961
  const acc = {};
2947
2962
  for (const [name, original] of Object.entries(themes.value)) {
@@ -2962,28 +2977,49 @@
2962
2977
  const current = vue.computed(() => computedThemes.value[name.value]);
2963
2978
  const styles = vue.computed(() => {
2964
2979
  const lines = [];
2980
+ const important = parsedOptions.unimportant ? '' : ' !important';
2981
+ const scoped = parsedOptions.scoped ? parsedOptions.prefix : '';
2965
2982
  if (current.value?.dark) {
2966
2983
  createCssClass(lines, ':root', ['color-scheme: dark'], parsedOptions.scope);
2967
2984
  }
2968
- createCssClass(lines, ':root', genCssVariables(current.value), parsedOptions.scope);
2985
+ createCssClass(lines, ':root', genCssVariables(current.value, parsedOptions.prefix), parsedOptions.scope);
2969
2986
  for (const [themeName, theme] of Object.entries(computedThemes.value)) {
2970
- createCssClass(lines, `.v-theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme)], parsedOptions.scope);
2971
- }
2972
- const bgLines = [];
2973
- const fgLines = [];
2974
- const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
2975
- for (const key of colors) {
2976
- if (key.startsWith('on-')) {
2977
- createCssClass(fgLines, `.${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
2978
- } else {
2979
- 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);
2980
- createCssClass(fgLines, `.text-${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
2981
- createCssClass(fgLines, `.border-${key}`, [`--v-border-color: var(--v-theme-${key})`], parsedOptions.scope);
2987
+ createCssClass(lines, `.${parsedOptions.prefix}theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme, parsedOptions.prefix)], parsedOptions.scope);
2988
+ }
2989
+ if (parsedOptions.utilities) {
2990
+ const bgLines = [];
2991
+ const fgLines = [];
2992
+ const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
2993
+ for (const key of colors) {
2994
+ if (key.startsWith('on-')) {
2995
+ createCssClass(fgLines, `.${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
2996
+ } else {
2997
+ 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);
2998
+ createCssClass(fgLines, `.${scoped}text-${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
2999
+ createCssClass(fgLines, `.${scoped}border-${key}`, [`--${parsedOptions.prefix}border-color: var(--${parsedOptions.prefix}theme-${key})`], parsedOptions.scope);
3000
+ }
2982
3001
  }
3002
+ lines.push(...bgLines, ...fgLines);
2983
3003
  }
2984
- lines.push(...bgLines, ...fgLines);
2985
3004
  return lines.map((str, i) => i === 0 ? str : ` ${str}`).join('');
2986
3005
  });
3006
+ const themeClasses = vue.computed(() => parsedOptions.isDisabled ? undefined : `${parsedOptions.prefix}theme--${name.value}`);
3007
+ const themeNames = vue.computed(() => Object.keys(computedThemes.value));
3008
+ if (SUPPORTS_MATCH_MEDIA) {
3009
+ const media = window.matchMedia('(prefers-color-scheme: dark)');
3010
+ function updateSystemName() {
3011
+ systemName.value = media.matches ? 'dark' : 'light';
3012
+ }
3013
+ updateSystemName();
3014
+ media.addEventListener('change', updateSystemName, {
3015
+ passive: true
3016
+ });
3017
+ if (vue.getCurrentScope()) {
3018
+ vue.onScopeDispose(() => {
3019
+ media.removeEventListener('change', updateSystemName);
3020
+ });
3021
+ }
3022
+ }
2987
3023
  function install(app) {
2988
3024
  if (parsedOptions.isDisabled) return;
2989
3025
  const head = app._context.provides.usehead;
@@ -3021,22 +3057,55 @@
3021
3057
  updateStyles();
3022
3058
  }
3023
3059
  function updateStyles() {
3024
- upsertStyles(getOrCreateStyleElement(parsedOptions.stylesheetId, parsedOptions.cspNonce), styles.value);
3060
+ upsertStyles(parsedOptions.stylesheetId, parsedOptions.cspNonce, styles.value);
3025
3061
  }
3026
3062
  }
3027
3063
  }
3028
- const themeClasses = vue.computed(() => parsedOptions.isDisabled ? undefined : `v-theme--${name.value}`);
3064
+ function change(themeName) {
3065
+ if (!themeNames.value.includes(themeName)) {
3066
+ consoleWarn(`Theme "${themeName}" not found on the Vuetify theme instance`);
3067
+ return;
3068
+ }
3069
+ name.value = themeName;
3070
+ }
3071
+ function cycle() {
3072
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : themeNames.value;
3073
+ const currentIndex = themeArray.indexOf(name.value);
3074
+ const nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % themeArray.length;
3075
+ change(themeArray[nextIndex]);
3076
+ }
3077
+ function toggle() {
3078
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['light', 'dark'];
3079
+ cycle(themeArray);
3080
+ }
3081
+ const globalName = new Proxy(name, {
3082
+ get(target, prop) {
3083
+ return target[prop];
3084
+ },
3085
+ set(target, prop, val) {
3086
+ if (prop === 'value') {
3087
+ deprecate(`theme.global.name.value = ${val}`, `theme.change('${val}')`);
3088
+ }
3089
+ // @ts-expect-error
3090
+ target[prop] = val;
3091
+ return true;
3092
+ }
3093
+ });
3029
3094
  return {
3030
3095
  install,
3096
+ change,
3097
+ cycle,
3098
+ toggle,
3031
3099
  isDisabled: parsedOptions.isDisabled,
3032
3100
  name,
3033
3101
  themes,
3034
3102
  current,
3035
3103
  computedThemes,
3104
+ prefix: parsedOptions.prefix,
3036
3105
  themeClasses,
3037
3106
  styles,
3038
3107
  global: {
3039
- name,
3108
+ name: globalName,
3040
3109
  current
3041
3110
  }
3042
3111
  };
@@ -3047,7 +3116,7 @@
3047
3116
  if (!theme) throw new Error('Could not find Vuetify theme injection');
3048
3117
  const name = vue.computed(() => props.theme ?? theme.name.value);
3049
3118
  const current = vue.computed(() => theme.themes.value[name.value]);
3050
- const themeClasses = vue.computed(() => theme.isDisabled ? undefined : `v-theme--${name.value}`);
3119
+ const themeClasses = vue.computed(() => theme.isDisabled ? undefined : `${theme.prefix}theme--${name.value}`);
3051
3120
  const newTheme = {
3052
3121
  ...theme,
3053
3122
  name,
@@ -29245,7 +29314,7 @@
29245
29314
  };
29246
29315
  });
29247
29316
  }
29248
- const version$1 = "3.8.1-dev.2025-04-07";
29317
+ const version$1 = "3.8.1-dev.2025-04-13";
29249
29318
  createVuetify$1.version = version$1;
29250
29319
 
29251
29320
  // Vue's inject() can only be used in setup
@@ -29270,7 +29339,7 @@
29270
29339
  ...options
29271
29340
  });
29272
29341
  };
29273
- const version = "3.8.1-dev.2025-04-07";
29342
+ const version = "3.8.1-dev.2025-04-13";
29274
29343
  createVuetify.version = version;
29275
29344
 
29276
29345
  exports.blueprints = index;