@vuetify/nightly 3.8.0-master.2025-04-06 → 3.8.1-dev.2025-04-12

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.d.ts CHANGED
@@ -132,11 +132,12 @@ type DeepPartial<T> = T extends object ? {
132
132
  } : T;
133
133
  type ThemeOptions = false | {
134
134
  cspNonce?: string;
135
- defaultTheme?: string;
135
+ defaultTheme?: 'light' | 'dark' | 'system' | string;
136
136
  variations?: false | VariationsOptions;
137
137
  themes?: Record<string, ThemeDefinition>;
138
138
  stylesheetId?: string;
139
139
  scope?: string;
140
+ unimportant?: boolean;
140
141
  };
141
142
  type ThemeDefinition = DeepPartial<InternalThemeDefinition>;
142
143
  interface VariationsOptions {
@@ -173,11 +174,15 @@ interface OnColors {
173
174
  'on-info': string;
174
175
  }
175
176
  interface ThemeInstance {
177
+ change: (themeName: string) => void;
178
+ cycle: (themeArray?: string[]) => void;
179
+ toggle: (themeArray?: [string, string]) => void;
176
180
  readonly isDisabled: boolean;
177
181
  readonly themes: Ref<Record<string, InternalThemeDefinition>>;
178
182
  readonly name: Readonly<Ref<string>>;
179
183
  readonly current: DeepReadonly<Ref<InternalThemeDefinition>>;
180
184
  readonly computedThemes: DeepReadonly<Ref<Record<string, InternalThemeDefinition>>>;
185
+ readonly prefix: string;
181
186
  readonly themeClasses: Readonly<Ref<string | undefined>>;
182
187
  readonly styles: Readonly<Ref<string>>;
183
188
  readonly global: {
@@ -82943,42 +82948,43 @@ declare module 'vue' {
82943
82948
  $children?: VNodeChild
82944
82949
  }
82945
82950
  export interface GlobalComponents {
82946
- VApp: VApp
82947
82951
  VAlert: VAlert
82948
82952
  VAlertTitle: VAlertTitle
82953
+ VApp: VApp
82949
82954
  VAutocomplete: VAutocomplete
82950
82955
  VAppBar: VAppBar
82951
82956
  VAppBarNavIcon: VAppBarNavIcon
82952
82957
  VAppBarTitle: VAppBarTitle
82953
82958
  VBadge: VBadge
82954
- VBottomSheet: VBottomSheet
82955
- VBottomNavigation: VBottomNavigation
82959
+ VAvatar: VAvatar
82956
82960
  VBanner: VBanner
82957
82961
  VBannerActions: VBannerActions
82958
82962
  VBannerText: VBannerText
82959
- VAvatar: VAvatar
82963
+ VBtn: VBtn
82960
82964
  VBtnGroup: VBtnGroup
82961
82965
  VBtnToggle: VBtnToggle
82962
- VBtn: VBtn
82966
+ VBottomNavigation: VBottomNavigation
82963
82967
  VBreadcrumbs: VBreadcrumbs
82964
82968
  VBreadcrumbsItem: VBreadcrumbsItem
82965
82969
  VBreadcrumbsDivider: VBreadcrumbsDivider
82970
+ VChip: VChip
82971
+ VCarousel: VCarousel
82972
+ VCarouselItem: VCarouselItem
82973
+ VBottomSheet: VBottomSheet
82974
+ VCode: VCode
82975
+ VChipGroup: VChipGroup
82966
82976
  VCard: VCard
82967
82977
  VCardActions: VCardActions
82968
82978
  VCardItem: VCardItem
82969
82979
  VCardSubtitle: VCardSubtitle
82970
82980
  VCardText: VCardText
82971
82981
  VCardTitle: VCardTitle
82982
+ VCombobox: VCombobox
82972
82983
  VCheckbox: VCheckbox
82973
82984
  VCheckboxBtn: VCheckboxBtn
82974
- VCarousel: VCarousel
82975
- VCarouselItem: VCarouselItem
82976
- VChip: VChip
82977
- VColorPicker: VColorPicker
82978
- VChipGroup: VChipGroup
82979
- VCode: VCode
82980
- VCombobox: VCombobox
82985
+ VDialog: VDialog
82981
82986
  VCounter: VCounter
82987
+ VColorPicker: VColorPicker
82982
82988
  VDataTable: VDataTable
82983
82989
  VDataTableHeaders: VDataTableHeaders
82984
82990
  VDataTableFooter: VDataTableFooter
@@ -82992,18 +82998,17 @@ declare module 'vue' {
82992
82998
  VDatePickerMonth: VDatePickerMonth
82993
82999
  VDatePickerMonths: VDatePickerMonths
82994
83000
  VDatePickerYears: VDatePickerYears
82995
- VDivider: VDivider
82996
- VDialog: VDialog
82997
- VFab: VFab
82998
- VField: VField
82999
- VFieldLabel: VFieldLabel
83000
- VFileInput: VFileInput
83001
- VEmptyState: VEmptyState
83002
83001
  VExpansionPanels: VExpansionPanels
83003
83002
  VExpansionPanel: VExpansionPanel
83004
83003
  VExpansionPanelText: VExpansionPanelText
83005
83004
  VExpansionPanelTitle: VExpansionPanelTitle
83005
+ VDivider: VDivider
83006
+ VEmptyState: VEmptyState
83007
+ VField: VField
83008
+ VFieldLabel: VFieldLabel
83009
+ VFileInput: VFileInput
83006
83010
  VFooter: VFooter
83011
+ VFab: VFab
83007
83012
  VIcon: VIcon
83008
83013
  VComponentIcon: VComponentIcon
83009
83014
  VSvgIcon: VSvgIcon
@@ -83012,7 +83017,6 @@ declare module 'vue' {
83012
83017
  VImg: VImg
83013
83018
  VItemGroup: VItemGroup
83014
83019
  VItem: VItem
83015
- VInfiniteScroll: VInfiniteScroll
83016
83020
  VInput: VInput
83017
83021
  VKbd: VKbd
83018
83022
  VLabel: VLabel
@@ -83025,29 +83029,29 @@ declare module 'vue' {
83025
83029
  VListItemSubtitle: VListItemSubtitle
83026
83030
  VListItemTitle: VListItemTitle
83027
83031
  VListSubheader: VListSubheader
83032
+ VInfiniteScroll: VInfiniteScroll
83028
83033
  VMain: VMain
83034
+ VMessages: VMessages
83029
83035
  VMenu: VMenu
83030
83036
  VNavigationDrawer: VNavigationDrawer
83031
- VOtpInput: VOtpInput
83032
- VMessages: VMessages
83033
83037
  VNumberInput: VNumberInput
83034
- VProgressCircular: VProgressCircular
83038
+ VOtpInput: VOtpInput
83039
+ VProgressLinear: VProgressLinear
83035
83040
  VPagination: VPagination
83036
83041
  VOverlay: VOverlay
83042
+ VProgressCircular: VProgressCircular
83037
83043
  VRadioGroup: VRadioGroup
83038
- VProgressLinear: VProgressLinear
83039
- VSelectionControl: VSelectionControl
83040
- VSelectionControlGroup: VSelectionControlGroup
83041
83044
  VRating: VRating
83042
- VSlider: VSlider
83043
- VSheet: VSheet
83044
83045
  VSelect: VSelect
83046
+ VSheet: VSheet
83047
+ VSelectionControl: VSelectionControl
83048
+ VSkeletonLoader: VSkeletonLoader
83049
+ VSelectionControlGroup: VSelectionControlGroup
83045
83050
  VSlideGroup: VSlideGroup
83046
83051
  VSlideGroupItem: VSlideGroupItem
83047
- VSkeletonLoader: VSkeletonLoader
83048
- VTextField: VTextField
83049
- VSwitch: VSwitch
83052
+ VSlider: VSlider
83050
83053
  VSnackbar: VSnackbar
83054
+ VSwitch: VSwitch
83051
83055
  VStepper: VStepper
83052
83056
  VStepperActions: VStepperActions
83053
83057
  VStepperHeader: VStepperHeader
@@ -83059,38 +83063,40 @@ declare module 'vue' {
83059
83063
  VTabs: VTabs
83060
83064
  VTabsWindow: VTabsWindow
83061
83065
  VTabsWindowItem: VTabsWindowItem
83062
- VSystemBar: VSystemBar
83066
+ VTimeline: VTimeline
83067
+ VTimelineItem: VTimelineItem
83068
+ VTextField: VTextField
83063
83069
  VToolbar: VToolbar
83064
83070
  VToolbarTitle: VToolbarTitle
83065
83071
  VToolbarItems: VToolbarItems
83066
- VTooltip: VTooltip
83067
83072
  VTextarea: VTextarea
83068
- VTimeline: VTimeline
83069
- VTimelineItem: VTimelineItem
83073
+ VTooltip: VTooltip
83070
83074
  VWindow: VWindow
83071
83075
  VWindowItem: VWindowItem
83076
+ VSystemBar: VSystemBar
83072
83077
  VConfirmEdit: VConfirmEdit
83073
83078
  VDataIterator: VDataIterator
83074
83079
  VDefaultsProvider: VDefaultsProvider
83075
83080
  VForm: VForm
83076
- VHover: VHover
83077
83081
  VContainer: VContainer
83078
83082
  VCol: VCol
83079
83083
  VRow: VRow
83080
83084
  VSpacer: VSpacer
83081
- VLazy: VLazy
83085
+ VHover: VHover
83082
83086
  VLayout: VLayout
83083
83087
  VLayoutItem: VLayoutItem
83084
- VNoSsr: VNoSsr
83088
+ VLazy: VLazy
83085
83089
  VLocaleProvider: VLocaleProvider
83086
- VParallax: VParallax
83090
+ VNoSsr: VNoSsr
83087
83091
  VRadio: VRadio
83092
+ VParallax: VParallax
83088
83093
  VRangeSlider: VRangeSlider
83089
83094
  VResponsive: VResponsive
83090
83095
  VSnackbarQueue: VSnackbarQueue
83091
83096
  VSparkline: VSparkline
83092
83097
  VSpeedDial: VSpeedDial
83093
83098
  VThemeProvider: VThemeProvider
83099
+ VValidation: VValidation
83094
83100
  VVirtualScroll: VVirtualScroll
83095
83101
  VFabTransition: VFabTransition
83096
83102
  VDialogBottomTransition: VDialogBottomTransition
@@ -83108,10 +83114,7 @@ declare module 'vue' {
83108
83114
  VExpandTransition: VExpandTransition
83109
83115
  VExpandXTransition: VExpandXTransition
83110
83116
  VDialogTransition: VDialogTransition
83111
- VValidation: VValidation
83112
- VStepperVertical: VStepperVertical
83113
- VStepperVerticalItem: VStepperVerticalItem
83114
- VStepperVerticalActions: VStepperVerticalActions
83117
+ VIconBtn: VIconBtn
83115
83118
  VCalendar: VCalendar
83116
83119
  VCalendarDay: VCalendarDay
83117
83120
  VCalendarHeader: VCalendarHeader
@@ -83120,15 +83123,17 @@ declare module 'vue' {
83120
83123
  VCalendarMonthDay: VCalendarMonthDay
83121
83124
  VFileUpload: VFileUpload
83122
83125
  VFileUploadItem: VFileUploadItem
83123
- VTimePicker: VTimePicker
83124
- VTimePickerClock: VTimePickerClock
83125
- VTimePickerControls: VTimePickerControls
83126
- VIconBtn: VIconBtn
83126
+ VStepperVertical: VStepperVertical
83127
+ VStepperVerticalItem: VStepperVerticalItem
83128
+ VStepperVerticalActions: VStepperVerticalActions
83127
83129
  VPicker: VPicker
83128
83130
  VPickerTitle: VPickerTitle
83129
83131
  VTreeview: VTreeview
83130
83132
  VTreeviewItem: VTreeviewItem
83131
83133
  VTreeviewGroup: VTreeviewGroup
83134
+ VTimePicker: VTimePicker
83135
+ VTimePickerClock: VTimePickerClock
83136
+ VTimePickerControls: VTimePickerControls
83132
83137
  VDateInput: VDateInput
83133
83138
  VPullToRefresh: VPullToRefresh
83134
83139
  }
@@ -1,15 +1,16 @@
1
1
  /*!
2
- * Vuetify v3.8.0-master.2025-04-06
2
+ * Vuetify v3.8.1-dev.2025-04-12
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
6
6
 
7
- import { shallowRef, reactive, computed, watchEffect, toRefs, capitalize, unref, Fragment, isVNode, Comment, warn, getCurrentInstance as getCurrentInstance$1, ref, provide, inject as inject$1, defineComponent as defineComponent$1, h, camelize, createVNode, mergeProps, onBeforeUnmount, watch, readonly, onMounted, useId, onDeactivated, onActivated, onScopeDispose, effectScope, toRaw, TransitionGroup, Transition, isRef, toRef, onBeforeMount, nextTick, withDirectives, resolveDirective, vShow, onUpdated, Text, resolveDynamicComponent, toDisplayString, markRaw, Teleport, cloneVNode, createTextVNode, onUnmounted, onBeforeUpdate, withModifiers, vModelText, resolveComponent, render } from 'vue';
7
+ import { shallowRef, reactive, computed, watchEffect, toRefs, capitalize, unref, Fragment, isVNode, Comment, warn, getCurrentInstance as getCurrentInstance$1, ref, provide, inject as inject$1, defineComponent as defineComponent$1, h, camelize, createVNode, mergeProps, onBeforeUnmount, watch, readonly, onMounted, useId, onDeactivated, onActivated, onScopeDispose, effectScope, toRaw, getCurrentScope, TransitionGroup, Transition, isRef, toRef, onBeforeMount, nextTick, withDirectives, resolveDirective, vShow, onUpdated, Text, resolveDynamicComponent, toDisplayString, markRaw, Teleport, cloneVNode, createTextVNode, onUnmounted, onBeforeUpdate, withModifiers, vModelText, resolveComponent, render } from 'vue';
8
8
 
9
9
  const IN_BROWSER = typeof window !== 'undefined';
10
10
  const SUPPORTS_INTERSECTION = IN_BROWSER && 'IntersectionObserver' in window;
11
11
  const SUPPORTS_TOUCH = IN_BROWSER && ('ontouchstart' in window || window.navigator.maxTouchPoints > 0);
12
12
  const SUPPORTS_EYE_DROPPER = IN_BROWSER && 'EyeDropper' in window;
13
+ const SUPPORTS_MATCH_MEDIA = IN_BROWSER && 'matchMedia' in window && typeof window.matchMedia === 'function';
13
14
 
14
15
  function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
15
16
  function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
@@ -2754,6 +2755,7 @@ const makeThemeProps = propsFactory({
2754
2755
  function genDefaults$1() {
2755
2756
  return {
2756
2757
  defaultTheme: 'light',
2758
+ prefix: 'v-',
2757
2759
  variations: {
2758
2760
  colors: [],
2759
2761
  lighten: 0,
@@ -2835,7 +2837,10 @@ function genDefaults$1() {
2835
2837
  }
2836
2838
  }
2837
2839
  },
2838
- stylesheetId: 'vuetify-theme-stylesheet'
2840
+ stylesheetId: 'vuetify-theme-stylesheet',
2841
+ scoped: false,
2842
+ unimportant: false,
2843
+ utilities: true
2839
2844
  };
2840
2845
  }
2841
2846
  function parseThemeOptions() {
@@ -2855,93 +2860,175 @@ function parseThemeOptions() {
2855
2860
  themes
2856
2861
  });
2857
2862
  }
2863
+ function createCssClass(lines, selector, content, scope) {
2864
+ lines.push(`${getScopedSelector(selector, scope)} {\n`, ...content.map(line => ` ${line};\n`), '}\n');
2865
+ }
2866
+ function genCssVariables(theme, prefix) {
2867
+ const lightOverlay = theme.dark ? 2 : 1;
2868
+ const darkOverlay = theme.dark ? 1 : 2;
2869
+ const variables = [];
2870
+ for (const [key, value] of Object.entries(theme.colors)) {
2871
+ const rgb = parseColor(value);
2872
+ variables.push(`--${prefix}theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2873
+ if (!key.startsWith('on-')) {
2874
+ variables.push(`--${prefix}theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2875
+ }
2876
+ }
2877
+ for (const [key, value] of Object.entries(theme.variables)) {
2878
+ const color = typeof value === 'string' && value.startsWith('#') ? parseColor(value) : undefined;
2879
+ const rgb = color ? `${color.r}, ${color.g}, ${color.b}` : undefined;
2880
+ variables.push(`--${prefix}${key}: ${rgb ?? value}`);
2881
+ }
2882
+ return variables;
2883
+ }
2884
+ function genVariation(name, color, variations) {
2885
+ const object = {};
2886
+ if (variations) {
2887
+ for (const variation of ['lighten', 'darken']) {
2888
+ const fn = variation === 'lighten' ? lighten : darken;
2889
+ for (const amount of createRange(variations[variation], 1)) {
2890
+ object[`${name}-${variation}-${amount}`] = RGBtoHex(fn(parseColor(color), amount));
2891
+ }
2892
+ }
2893
+ }
2894
+ return object;
2895
+ }
2896
+ function genVariations(colors, variations) {
2897
+ if (!variations) return {};
2898
+ let variationColors = {};
2899
+ for (const name of variations.colors) {
2900
+ const color = colors[name];
2901
+ if (!color) continue;
2902
+ variationColors = {
2903
+ ...variationColors,
2904
+ ...genVariation(name, color, variations)
2905
+ };
2906
+ }
2907
+ return variationColors;
2908
+ }
2909
+ function genOnColors(colors) {
2910
+ const onColors = {};
2911
+ for (const color of Object.keys(colors)) {
2912
+ if (color.startsWith('on-') || colors[`on-${color}`]) continue;
2913
+ const onColor = `on-${color}`;
2914
+ const colorVal = parseColor(colors[color]);
2915
+ onColors[onColor] = getForeground(colorVal);
2916
+ }
2917
+ return onColors;
2918
+ }
2919
+ function getScopedSelector(selector, scope) {
2920
+ if (!scope) return selector;
2921
+ const scopeSelector = `:where(${scope})`;
2922
+ return selector === ':root' ? scopeSelector : `${scopeSelector} ${selector}`;
2923
+ }
2924
+ function upsertStyles(id, cspNonce, styles) {
2925
+ const styleEl = getOrCreateStyleElement(id, cspNonce);
2926
+ if (!styleEl) return;
2927
+ styleEl.innerHTML = styles;
2928
+ }
2929
+ function getOrCreateStyleElement(id, cspNonce) {
2930
+ if (!IN_BROWSER) return null;
2931
+ let style = document.getElementById(id);
2932
+ if (!style) {
2933
+ style = document.createElement('style');
2934
+ style.id = id;
2935
+ style.type = 'text/css';
2936
+ if (cspNonce) style.setAttribute('nonce', cspNonce);
2937
+ document.head.appendChild(style);
2938
+ }
2939
+ return style;
2940
+ }
2858
2941
 
2859
2942
  // Composables
2860
2943
  function createTheme(options) {
2861
2944
  const parsedOptions = parseThemeOptions(options);
2862
- const name = ref(parsedOptions.defaultTheme);
2945
+ const _name = shallowRef(parsedOptions.defaultTheme);
2863
2946
  const themes = ref(parsedOptions.themes);
2947
+ const systemName = shallowRef('light');
2948
+ const name = computed({
2949
+ get() {
2950
+ return _name.value === 'system' ? systemName.value : _name.value;
2951
+ },
2952
+ set(val) {
2953
+ _name.value = val;
2954
+ }
2955
+ });
2864
2956
  const computedThemes = computed(() => {
2865
2957
  const acc = {};
2866
2958
  for (const [name, original] of Object.entries(themes.value)) {
2867
- const theme = acc[name] = {
2959
+ const colors = {
2960
+ ...original.colors,
2961
+ ...genVariations(original.colors, parsedOptions.variations)
2962
+ };
2963
+ acc[name] = {
2868
2964
  ...original,
2869
2965
  colors: {
2870
- ...original.colors
2966
+ ...colors,
2967
+ ...genOnColors(colors)
2871
2968
  }
2872
2969
  };
2873
- if (parsedOptions.variations) {
2874
- for (const name of parsedOptions.variations.colors) {
2875
- const color = theme.colors[name];
2876
- if (!color) continue;
2877
- for (const variation of ['lighten', 'darken']) {
2878
- const fn = variation === 'lighten' ? lighten : darken;
2879
- for (const amount of createRange(parsedOptions.variations[variation], 1)) {
2880
- theme.colors[`${name}-${variation}-${amount}`] = RGBtoHex(fn(parseColor(color), amount));
2881
- }
2882
- }
2883
- }
2884
- }
2885
- for (const color of Object.keys(theme.colors)) {
2886
- if (/^on-[a-z]/.test(color) || theme.colors[`on-${color}`]) continue;
2887
- const onColor = `on-${color}`;
2888
- const colorVal = parseColor(theme.colors[color]);
2889
- theme.colors[onColor] = getForeground(colorVal);
2890
- }
2891
2970
  }
2892
2971
  return acc;
2893
2972
  });
2894
2973
  const current = computed(() => computedThemes.value[name.value]);
2895
- function createCssClass(lines, selector, content) {
2896
- lines.push(`${getScopedSelector(selector)} {\n`, ...content.map(line => ` ${line};\n`), '}\n');
2897
- }
2898
- function getScopedSelector(selector) {
2899
- if (!parsedOptions.scope) {
2900
- return selector;
2901
- }
2902
- const scopeSelector = `:where(${parsedOptions.scope})`;
2903
- if (selector === ':root') {
2904
- return scopeSelector;
2905
- }
2906
- return `${scopeSelector} ${selector}`;
2907
- }
2908
2974
  const styles = computed(() => {
2909
2975
  const lines = [];
2976
+ const important = parsedOptions.unimportant ? '' : ' !important';
2977
+ const scoped = parsedOptions.scoped ? parsedOptions.prefix : '';
2910
2978
  if (current.value?.dark) {
2911
- createCssClass(lines, ':root', ['color-scheme: dark']);
2979
+ createCssClass(lines, ':root', ['color-scheme: dark'], parsedOptions.scope);
2912
2980
  }
2913
- createCssClass(lines, ':root', genCssVariables(current.value));
2981
+ createCssClass(lines, ':root', genCssVariables(current.value, parsedOptions.prefix), parsedOptions.scope);
2914
2982
  for (const [themeName, theme] of Object.entries(computedThemes.value)) {
2915
- createCssClass(lines, `.v-theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme)]);
2916
- }
2917
- const bgLines = [];
2918
- const fgLines = [];
2919
- const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
2920
- for (const key of colors) {
2921
- if (/^on-[a-z]/.test(key)) {
2922
- createCssClass(fgLines, `.${key}`, [`color: rgb(var(--v-theme-${key})) !important`]);
2923
- } else {
2924
- 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`]);
2925
- createCssClass(fgLines, `.text-${key}`, [`color: rgb(var(--v-theme-${key})) !important`]);
2926
- createCssClass(fgLines, `.border-${key}`, [`--v-border-color: var(--v-theme-${key})`]);
2983
+ createCssClass(lines, `.${parsedOptions.prefix}theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme, parsedOptions.prefix)], parsedOptions.scope);
2984
+ }
2985
+ if (parsedOptions.utilities) {
2986
+ const bgLines = [];
2987
+ const fgLines = [];
2988
+ const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
2989
+ for (const key of colors) {
2990
+ if (key.startsWith('on-')) {
2991
+ createCssClass(fgLines, `.${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
2992
+ } else {
2993
+ 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);
2994
+ createCssClass(fgLines, `.${scoped}text-${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
2995
+ createCssClass(fgLines, `.${scoped}border-${key}`, [`--${parsedOptions.prefix}border-color: var(--${parsedOptions.prefix}theme-${key})`], parsedOptions.scope);
2996
+ }
2927
2997
  }
2998
+ lines.push(...bgLines, ...fgLines);
2928
2999
  }
2929
- lines.push(...bgLines, ...fgLines);
2930
3000
  return lines.map((str, i) => i === 0 ? str : ` ${str}`).join('');
2931
3001
  });
2932
- function getHead() {
2933
- return {
2934
- style: [{
2935
- textContent: styles.value,
2936
- id: parsedOptions.stylesheetId,
2937
- nonce: parsedOptions.cspNonce || false
2938
- }]
2939
- };
3002
+ const themeClasses = computed(() => parsedOptions.isDisabled ? undefined : `${parsedOptions.prefix}theme--${name.value}`);
3003
+ const themeNames = computed(() => Object.keys(computedThemes.value));
3004
+ if (SUPPORTS_MATCH_MEDIA) {
3005
+ const media = window.matchMedia('(prefers-color-scheme: dark)');
3006
+ function updateSystemName() {
3007
+ systemName.value = media.matches ? 'dark' : 'light';
3008
+ }
3009
+ updateSystemName();
3010
+ media.addEventListener('change', updateSystemName, {
3011
+ passive: true
3012
+ });
3013
+ if (getCurrentScope()) {
3014
+ onScopeDispose(() => {
3015
+ media.removeEventListener('change', updateSystemName);
3016
+ });
3017
+ }
2940
3018
  }
2941
3019
  function install(app) {
2942
3020
  if (parsedOptions.isDisabled) return;
2943
3021
  const head = app._context.provides.usehead;
2944
3022
  if (head) {
3023
+ function getHead() {
3024
+ return {
3025
+ style: [{
3026
+ textContent: styles.value,
3027
+ id: parsedOptions.stylesheetId,
3028
+ nonce: parsedOptions.cspNonce || false
3029
+ }]
3030
+ };
3031
+ }
2945
3032
  if (head.push) {
2946
3033
  const entry = head.push(getHead);
2947
3034
  if (IN_BROWSER) {
@@ -2958,7 +3045,6 @@ function createTheme(options) {
2958
3045
  }
2959
3046
  }
2960
3047
  } else {
2961
- let styleEl = IN_BROWSER ? document.getElementById(parsedOptions.stylesheetId) : null;
2962
3048
  if (IN_BROWSER) {
2963
3049
  watch(styles, updateStyles, {
2964
3050
  immediate: true
@@ -2967,30 +3053,55 @@ function createTheme(options) {
2967
3053
  updateStyles();
2968
3054
  }
2969
3055
  function updateStyles() {
2970
- if (typeof document !== 'undefined' && !styleEl) {
2971
- const el = document.createElement('style');
2972
- el.type = 'text/css';
2973
- el.id = parsedOptions.stylesheetId;
2974
- if (parsedOptions.cspNonce) el.setAttribute('nonce', parsedOptions.cspNonce);
2975
- styleEl = el;
2976
- document.head.appendChild(styleEl);
2977
- }
2978
- if (styleEl) styleEl.innerHTML = styles.value;
3056
+ upsertStyles(parsedOptions.stylesheetId, parsedOptions.cspNonce, styles.value);
2979
3057
  }
2980
3058
  }
2981
3059
  }
2982
- const themeClasses = computed(() => parsedOptions.isDisabled ? undefined : `v-theme--${name.value}`);
3060
+ function change(themeName) {
3061
+ if (!themeNames.value.includes(themeName)) {
3062
+ consoleWarn(`Theme "${themeName}" not found on the Vuetify theme instance`);
3063
+ return;
3064
+ }
3065
+ name.value = themeName;
3066
+ }
3067
+ function cycle() {
3068
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : themeNames.value;
3069
+ const currentIndex = themeArray.indexOf(name.value);
3070
+ const nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % themeArray.length;
3071
+ change(themeArray[nextIndex]);
3072
+ }
3073
+ function toggle() {
3074
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['light', 'dark'];
3075
+ cycle(themeArray);
3076
+ }
3077
+ const globalName = new Proxy(name, {
3078
+ get(target, prop) {
3079
+ return target[prop];
3080
+ },
3081
+ set(target, prop, val) {
3082
+ if (prop === 'value') {
3083
+ deprecate(`theme.global.name.value = ${val}`, `theme.change('${val}')`);
3084
+ }
3085
+ // @ts-expect-error
3086
+ target[prop] = val;
3087
+ return true;
3088
+ }
3089
+ });
2983
3090
  return {
2984
3091
  install,
3092
+ change,
3093
+ cycle,
3094
+ toggle,
2985
3095
  isDisabled: parsedOptions.isDisabled,
2986
3096
  name,
2987
3097
  themes,
2988
3098
  current,
2989
3099
  computedThemes,
3100
+ prefix: parsedOptions.prefix,
2990
3101
  themeClasses,
2991
3102
  styles,
2992
3103
  global: {
2993
- name,
3104
+ name: globalName,
2994
3105
  current
2995
3106
  }
2996
3107
  };
@@ -2999,11 +3110,9 @@ function provideTheme(props) {
2999
3110
  getCurrentInstance('provideTheme');
3000
3111
  const theme = inject$1(ThemeSymbol, null);
3001
3112
  if (!theme) throw new Error('Could not find Vuetify theme injection');
3002
- const name = computed(() => {
3003
- return props.theme ?? theme.name.value;
3004
- });
3113
+ const name = computed(() => props.theme ?? theme.name.value);
3005
3114
  const current = computed(() => theme.themes.value[name.value]);
3006
- const themeClasses = computed(() => theme.isDisabled ? undefined : `v-theme--${name.value}`);
3115
+ const themeClasses = computed(() => theme.isDisabled ? undefined : `${theme.prefix}theme--${name.value}`);
3007
3116
  const newTheme = {
3008
3117
  ...theme,
3009
3118
  name,
@@ -3019,24 +3128,6 @@ function useTheme() {
3019
3128
  if (!theme) throw new Error('Could not find Vuetify theme injection');
3020
3129
  return theme;
3021
3130
  }
3022
- function genCssVariables(theme) {
3023
- const lightOverlay = theme.dark ? 2 : 1;
3024
- const darkOverlay = theme.dark ? 1 : 2;
3025
- const variables = [];
3026
- for (const [key, value] of Object.entries(theme.colors)) {
3027
- const rgb = parseColor(value);
3028
- variables.push(`--v-theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
3029
- if (!key.startsWith('on-')) {
3030
- variables.push(`--v-theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
3031
- }
3032
- }
3033
- for (const [key, value] of Object.entries(theme.variables)) {
3034
- const color = typeof value === 'string' && value.startsWith('#') ? parseColor(value) : undefined;
3035
- const rgb = color ? `${color.r}, ${color.g}, ${color.b}` : undefined;
3036
- variables.push(`--v-${key}: ${rgb ?? value}`);
3037
- }
3038
- return variables;
3039
- }
3040
3131
 
3041
3132
  const makeVAppProps = propsFactory({
3042
3133
  ...makeComponentProps(),
@@ -12546,7 +12637,12 @@ function useVirtual(props, items) {
12546
12637
  }
12547
12638
  function calculateOffset(index) {
12548
12639
  index = clamp(index, 0, items.value.length - 1);
12549
- return offsets[index] || 0;
12640
+ const whole = Math.floor(index);
12641
+ const fraction = index % 1;
12642
+ const next = whole + 1;
12643
+ const wholeOffset = offsets[whole] || 0;
12644
+ const nextOffset = offsets[next] || wholeOffset;
12645
+ return wholeOffset + (nextOffset - wholeOffset) * fraction;
12550
12646
  }
12551
12647
  function calculateIndex(scrollTop) {
12552
12648
  return binaryClosest(offsets, scrollTop);
@@ -29214,7 +29310,7 @@ function createVuetify$1() {
29214
29310
  };
29215
29311
  });
29216
29312
  }
29217
- const version$1 = "3.8.0-master.2025-04-06";
29313
+ const version$1 = "3.8.1-dev.2025-04-12";
29218
29314
  createVuetify$1.version = version$1;
29219
29315
 
29220
29316
  // Vue's inject() can only be used in setup
@@ -29239,7 +29335,7 @@ const createVuetify = function () {
29239
29335
  ...options
29240
29336
  });
29241
29337
  };
29242
- const version = "3.8.0-master.2025-04-06";
29338
+ const version = "3.8.1-dev.2025-04-12";
29243
29339
  createVuetify.version = version;
29244
29340
 
29245
29341
  export { index as blueprints, components, createVuetify, directives, useDate, useDefaults, useDisplay, useGoTo, useLayout, useLocale, useRtl, useTheme, version };