@maz-ui/themes 4.1.7-beta.3 → 4.1.7-beta.5

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 (34) hide show
  1. package/README.md +19 -15
  2. package/dist/build/index.js +10 -8
  3. package/dist/chunks/isServer.BAlEcRRr.js +6 -0
  4. package/dist/composables/index.js +2 -3
  5. package/dist/composables/useTheme.js +72 -130
  6. package/dist/index.js +4 -6
  7. package/dist/plugin/index.js +3 -1
  8. package/dist/plugin.js +99 -22
  9. package/dist/types/build/index.d.ts +7 -4
  10. package/dist/types/build/index.d.ts.map +1 -1
  11. package/dist/types/composables/useTheme.d.ts +49 -8
  12. package/dist/types/composables/useTheme.d.ts.map +1 -1
  13. package/dist/types/plugin.d.ts +7 -6
  14. package/dist/types/plugin.d.ts.map +1 -1
  15. package/dist/types/types/index.d.ts +41 -3
  16. package/dist/types/types/index.d.ts.map +1 -1
  17. package/dist/types/utils/cookie-storage.d.ts.map +1 -1
  18. package/dist/types/utils/css-generator.d.ts +12 -22
  19. package/dist/types/utils/css-generator.d.ts.map +1 -1
  20. package/dist/types/utils/get-color-mode.d.ts +2 -1
  21. package/dist/types/utils/get-color-mode.d.ts.map +1 -1
  22. package/dist/types/utils/index.d.ts +2 -0
  23. package/dist/types/utils/index.d.ts.map +1 -1
  24. package/dist/types/utils/no-transition.d.ts +2 -0
  25. package/dist/types/utils/no-transition.d.ts.map +1 -0
  26. package/dist/types/utils/update-document-class.d.ts +3 -0
  27. package/dist/types/utils/update-document-class.d.ts.map +1 -0
  28. package/dist/utils/cookie-storage.js +3 -2
  29. package/dist/utils/css-generator.js +58 -81
  30. package/dist/utils/get-color-mode.js +12 -5
  31. package/dist/utils/index.js +8 -5
  32. package/dist/utils/no-transition.js +18 -0
  33. package/dist/utils/update-document-class.js +9 -0
  34. package/package.json +6 -6
package/README.md CHANGED
@@ -23,14 +23,15 @@ npm install @maz-ui/themes
23
23
  ### 1. Plugin installation
24
24
 
25
25
  ```typescript
26
- import { MazUiTheme } from '@maz-ui/themes'
27
26
  // main.ts
27
+ import { MazUiTheme } from '@maz-ui/themes/plugin'
28
+ import { mazUi } from '@maz-ui/themes/presets/mazUi'
28
29
  import { createApp } from 'vue'
29
30
 
30
31
  const app = createApp(App)
31
32
 
32
33
  app.use(MazUiTheme, {
33
- preset: 'maz-ui',
34
+ preset: mazUi,
34
35
  strategy: 'hybrid',
35
36
  darkModeStrategy: 'class'
36
37
  })
@@ -40,9 +41,9 @@ app.use(MazUiTheme, {
40
41
 
41
42
  ```vue
42
43
  <script setup>
43
- import { useMazTheme } from '@maz-ui/themes'
44
+ import { useTheme } from '@maz-ui/themes'
44
45
 
45
- const { toggleDarkMode, isDark } = useMazTheme()
46
+ const { toggleDarkMode, isDark } = useTheme()
46
47
  </script>
47
48
 
48
49
  <template>
@@ -59,28 +60,28 @@ const { toggleDarkMode, isDark } = useMazTheme()
59
60
 
60
61
  ## Available presets
61
62
 
62
- ### Default (Shadcn-like)
63
+ ### Default
63
64
 
64
65
  ```typescript
65
- import { mazUi } from '@maz-ui/themes'
66
+ import { mazUi } from '@maz-ui/themes/presets/mazUi'
66
67
  ```
67
68
 
68
- ### Dark
69
+ ### Pristine
69
70
 
70
71
  ```typescript
71
- import { dark } from '@maz-ui/themes'
72
+ import { pristine } from '@maz-ui/themes/presets/pristine'
72
73
  ```
73
74
 
74
75
  ### Ocean
75
76
 
76
77
  ```typescript
77
- import { ocean } from '@maz-ui/themes'
78
+ import { ocean } from '@maz-ui/themes/presets/ocean'
78
79
  ```
79
80
 
80
81
  ### Obsidian
81
82
 
82
83
  ```typescript
83
- import { obsidian } from '@maz-ui/themes'
84
+ import { obsidian } from '@maz-ui/themes/presets/obsidian'
84
85
  ```
85
86
 
86
87
  ## Creating custom presets
@@ -110,15 +111,18 @@ const myPreset = definePreset({
110
111
  ## Composable API
111
112
 
112
113
  ```typescript
114
+ import { useTheme } from '@maz-ui/themes'
115
+
113
116
  const {
114
- currentPreset, // Ref<ThemePreset>
117
+ preset, // ComputedRef<ThemePreset>
118
+ presetName, // ComputedRef<string>
115
119
  colorMode, // Ref<'light' | 'dark' | 'auto'>
116
- isDark, // Ref<boolean>
117
- strategy, // Ref<'runtime' | 'build' | 'hybrid'>
120
+ isDark, // ComputedRef<boolean>
121
+ strategy, // ComputedRef<'runtime' | 'build' | 'hybrid'>
118
122
  updateTheme, // (preset: ThemePreset | ThemePresetName | ThemePresetOverrides) => void
119
123
  setColorMode, // (mode: 'light' | 'dark' | 'auto') => void
120
- toggleDarkMode // () => void
121
- } = useMazTheme()
124
+ toggleDarkMode, // () => void
125
+ } = useTheme()
122
126
  ```
123
127
 
124
128
  ## Strategies
@@ -1,19 +1,21 @@
1
- import { generateCriticalCSS, generateFullCSS } from "../utils/css-generator.js";
1
+ import { generateCSS } from "../utils/css-generator.js";
2
2
  function buildThemeCSS(options) {
3
3
  const {
4
4
  preset,
5
5
  mode = "both",
6
6
  darkSelector = "class",
7
7
  prefix = "maz",
8
+ darkClass = "dark",
8
9
  criticalOnly = !1
9
10
  } = options, cssOptions = {
10
11
  mode,
11
12
  darkSelectorStrategy: darkSelector,
12
- prefix
13
- };
13
+ prefix,
14
+ darkClass
15
+ }, criticalCSS = generateCSS(preset, { ...cssOptions, onlyCritical: !0 });
14
16
  if (criticalOnly)
15
- return generateCriticalCSS(preset, cssOptions);
16
- const criticalCSS = generateCriticalCSS(preset, cssOptions), fullCSS = generateFullCSS(preset, cssOptions);
17
+ return criticalCSS;
18
+ const fullCSS = generateCSS(preset, cssOptions);
17
19
  return `${criticalCSS}
18
20
  ${fullCSS}`;
19
21
  }
@@ -40,10 +42,10 @@ ${css}
40
42
  </style>`, styleTag;
41
43
  }
42
44
  function buildSeparateThemeFiles(preset, options = {}) {
43
- const { prefix = "maz", darkSelector = "class" } = options, baseOptions = { prefix, darkSelectorStrategy: darkSelector };
45
+ const { prefix = "maz", darkSelector = "class", darkClass = "dark" } = options, baseOptions = { prefix, darkSelectorStrategy: darkSelector, darkClass };
44
46
  return {
45
- critical: generateCriticalCSS(preset, { ...baseOptions, mode: "both" }),
46
- full: generateFullCSS(preset, { ...baseOptions, mode: "both" }),
47
+ critical: generateCSS(preset, { ...baseOptions, mode: "both", onlyCritical: !0 }),
48
+ full: generateCSS(preset, { ...baseOptions, mode: "both" }),
47
49
  lightOnly: buildThemeCSS({ preset, mode: "light", ...options }),
48
50
  darkOnly: buildThemeCSS({ preset, mode: "dark", ...options })
49
51
  };
@@ -0,0 +1,6 @@
1
+ function isServer() {
2
+ return typeof document > "u" || typeof globalThis.window > "u";
3
+ }
4
+ export {
5
+ isServer as i
6
+ };
@@ -1,11 +1,10 @@
1
- import { initThemeState, useTheme } from "./useTheme.js";
1
+ import "../chunks/isServer.BAlEcRRr.js";
2
2
  import "vue";
3
3
  import "../utils/cookie-storage.js";
4
4
  import "../utils/css-generator.js";
5
- import "../utils/get-color-mode.js";
6
5
  import "../utils/get-preset.js";
7
6
  import "../utils/preset-merger.js";
7
+ import { useTheme } from "./useTheme.js";
8
8
  export {
9
- initThemeState,
10
9
  useTheme
11
10
  };
@@ -1,165 +1,107 @@
1
- import { ref, onMounted, computed, toValue, watch, watchEffect, inject, getCurrentInstance } from "vue";
1
+ import { i as isServer } from "../chunks/isServer.BAlEcRRr.js";
2
+ import { ref, computed, inject, getCurrentInstance } from "vue";
2
3
  import { setCookie } from "../utils/cookie-storage.js";
3
- import { generateCriticalCSS, generateFullCSS, injectCSS, CSS_IDS } from "../utils/css-generator.js";
4
- import { getColorMode, isSystemPrefersDark } from "../utils/get-color-mode.js";
4
+ import { generateCSS, injectCSS, CSS_ID } from "../utils/css-generator.js";
5
5
  import { getPreset } from "../utils/get-preset.js";
6
6
  import { mergePresets } from "../utils/preset-merger.js";
7
- function isServer() {
8
- return typeof document > "u" || typeof globalThis.window > "u";
9
- }
10
- function isClient() {
11
- return typeof document < "u";
12
- }
13
- function truthyFilter(value) {
14
- return !!value;
15
- }
16
- function useMutationObserver(target, callback, options = {}) {
17
- const {
18
- internalWindow = isClient() ? globalThis : void 0,
19
- ...mutationOptions
20
- } = options;
21
- let observer;
22
- const isSupported = ref(!1);
23
- onMounted(() => {
24
- isSupported.value = (internalWindow && "MutationObserver" in internalWindow) ?? !1;
25
- });
26
- const cleanup = () => {
27
- observer && (observer.disconnect(), observer = void 0);
28
- }, targets = computed(() => {
29
- const value = toValue(target);
30
- let element;
31
- return value && "$el" in value ? element = value.$el : value && (element = value), new Set([element].filter(truthyFilter));
32
- }), stopWatch = watch(
33
- targets,
34
- (newTargets) => {
35
- cleanup(), isSupported.value && newTargets.size && (observer = new MutationObserver(callback), newTargets.forEach((el) => observer.observe(el, mutationOptions)));
36
- },
37
- { immediate: !0, flush: "post" }
38
- );
39
- return {
40
- isSupported,
41
- stop: () => {
42
- stopWatch(), cleanup();
43
- },
44
- takeRecords: () => observer?.takeRecords()
45
- };
46
- }
47
- const state = ref();
48
- function updateDocumentClass(themeState) {
49
- typeof document > "u" || !themeState || themeState.darkModeStrategy === "media" || themeState.mode === "light" || (themeState.isDark ? document.documentElement.classList.add("dark") : document.documentElement.classList.remove("dark"));
50
- }
51
- function updateGlobalProperties() {
52
- const app = getCurrentInstance()?.appContext.app;
53
- app && state.value && (app.config.globalProperties.$mazThemeState = state.value);
54
- }
55
- function initializeThemeFromData(themeData) {
56
- if (themeData.currentPreset && themeData.colorMode !== void 0) {
57
- initThemeState({
58
- currentPreset: themeData.currentPreset,
59
- colorMode: themeData.colorMode,
60
- mode: themeData.mode,
61
- isDark: themeData.isDark,
62
- strategy: themeData.strategy,
63
- darkModeStrategy: themeData.darkModeStrategy
64
- });
65
- return;
66
- }
67
- const colorMode2 = getColorMode(themeData.colorMode), isDark2 = colorMode2 === "auto" ? isSystemPrefersDark() : colorMode2 === "dark";
68
- initThemeState({
69
- currentPreset: themeData.currentPreset,
70
- colorMode: colorMode2,
71
- mode: themeData.mode,
72
- isDark: isDark2,
73
- strategy: themeData.strategy,
74
- darkModeStrategy: themeData.darkModeStrategy
75
- });
76
- }
77
- function initThemeState(initialState) {
78
- if (state.value = initialState, typeof globalThis.window < "u" && state.value.colorMode === "auto") {
79
- const mediaQuery = globalThis.matchMedia("(prefers-color-scheme: dark)"), updateFromMedia = () => {
80
- state.value && state.value.colorMode === "auto" && (state.value.isDark = mediaQuery.matches);
81
- };
82
- mediaQuery.addEventListener("change", updateFromMedia), updateFromMedia();
83
- }
84
- watchEffect(() => {
85
- state.value && (updateDocumentClass(state.value), updateGlobalProperties());
86
- });
87
- }
88
- const colorMode = computed({
89
- get: () => state.value?.colorMode,
7
+ const themeState = ref(), colorMode = computed({
8
+ get: () => themeState.value?.colorMode,
90
9
  set: (mode2) => setColorMode(mode2)
91
- }), isDark = computed(() => state.value?.isDark ?? !1), strategy = computed(() => state.value?.strategy), mode = computed(() => state.value?.mode), darkModeStrategy = computed(() => state.value?.darkModeStrategy), currentPreset = computed(() => state.value?.currentPreset), presetName = computed(() => currentPreset.value?.name);
92
- async function updateTheme(preset) {
93
- if (!state.value)
10
+ }), isDark = computed(() => themeState.value?.isDark || !1), strategy = computed(() => themeState.value?.strategy), mode = computed(() => themeState.value?.mode), darkModeStrategy = computed(() => themeState.value?.darkModeStrategy), preset = computed(() => themeState.value?.preset), presetName = computed(() => preset.value?.name);
11
+ async function updateTheme(preset2) {
12
+ if (!themeState.value)
94
13
  return;
95
- const _preset = typeof preset == "string" ? await getPreset(preset) : preset;
96
- if (!_preset || !state.value.currentPreset) {
14
+ const _preset = typeof preset2 == "string" ? await getPreset(preset2) : preset2;
15
+ if (!_preset || !themeState.value.preset) {
97
16
  console.error("[@maz-ui/themes] No preset found - If you are using the buildtime strategy, you must provide a complete preset");
98
17
  return;
99
18
  }
100
- const newPreset = "name" in _preset && _preset.name !== state.value.currentPreset.name ? _preset : mergePresets(state.value.currentPreset, _preset);
101
- if (state.value.currentPreset = newPreset, state.value.strategy === "runtime" || state.value.strategy === "hybrid") {
19
+ const newPreset = "name" in _preset && _preset.name !== themeState.value.preset.name ? _preset : mergePresets(themeState.value.preset, _preset);
20
+ if (themeState.value.preset = newPreset, themeState.value.strategy === "runtime" || themeState.value.strategy === "hybrid") {
102
21
  const cssOptions = {
103
- mode: state.value.mode,
104
- darkSelectorStrategy: state.value.darkModeStrategy,
105
- prefix: "maz"
106
- }, criticalCSS = generateCriticalCSS(newPreset, cssOptions), fullCSS = generateFullCSS(newPreset, cssOptions);
107
- injectCSS(CSS_IDS.CRITICAL, criticalCSS), injectCSS(CSS_IDS.FULL, fullCSS);
22
+ mode: themeState.value.mode,
23
+ darkSelectorStrategy: themeState.value.darkModeStrategy,
24
+ prefix: "maz",
25
+ darkClass: themeState.value.darkClass
26
+ }, fullCSS = generateCSS(newPreset, cssOptions);
27
+ injectCSS(CSS_ID, fullCSS);
108
28
  }
109
29
  }
110
- function setColorMode(colorMode2, updateClass = !0) {
111
- state.value && (state.value.colorMode = colorMode2, colorMode2 === "auto" ? state.value.isDark = typeof globalThis.window < "u" && globalThis.matchMedia("(prefers-color-scheme: dark)").matches : state.value.isDark = colorMode2 === "dark", updateClass && updateDocumentClass(state.value), setCookie("maz-color-mode", colorMode2));
30
+ function setColorMode(colorMode2) {
31
+ themeState.value && (themeState.value.colorMode = colorMode2, setCookie("maz-color-mode", colorMode2));
112
32
  }
113
33
  function toggleDarkMode() {
114
- state.value && setColorMode(state.value.isDark ? "light" : "dark");
34
+ setColorMode(isDark.value ? "light" : "dark");
115
35
  }
116
- function useTheme() {
117
- const htmlElement = ref();
118
- onMounted(() => {
119
- htmlElement.value = document.documentElement;
120
- }), useMutationObserver(
121
- htmlElement,
122
- () => {
123
- if (isServer() || !state.value)
124
- return;
125
- const colorMode2 = document.documentElement.classList.contains("dark") ? "dark" : "light";
126
- state.value.colorMode !== colorMode2 && setColorMode(colorMode2, !1);
127
- },
128
- {
129
- attributes: !0
130
- }
131
- );
132
- let mazThemeState;
36
+ function setThemeStateFromGlobalProperties() {
37
+ themeState.value = void 0;
133
38
  try {
134
- if (mazThemeState = inject("mazThemeState", void 0), !mazThemeState)
39
+ const injectedState = inject("mazThemeState", void 0);
40
+ if (themeState.value = injectedState?.value, !themeState.value)
135
41
  throw new Error("mazThemeState not found");
136
42
  } catch {
137
43
  const instance = getCurrentInstance();
138
- instance?.appContext?.app?.config?.globalProperties && (mazThemeState = instance.appContext.app.config.globalProperties.$mazThemeState);
44
+ instance?.appContext?.app?.config?.globalProperties && (themeState.value = instance.appContext.app.config.globalProperties.$mazThemeState.value);
139
45
  }
140
- if (mazThemeState && (state.value ? (typeof document > "u" || typeof globalThis.window > "u") && (state.value = {
141
- ...state.value,
142
- ...mazThemeState
143
- }) : initializeThemeFromData(mazThemeState)), watch(() => mazThemeState?.currentPreset, (preset) => {
144
- state.value && preset && (state.value.currentPreset = preset);
145
- }, {
146
- once: !0
147
- }), !state.value)
46
+ }
47
+ function useTheme() {
48
+ if (isServer() && (themeState.value = void 0), themeState.value || setThemeStateFromGlobalProperties(), !themeState.value)
148
49
  throw new Error("[@maz-ui/themes] You must install the MazUi or MazUiTheme plugin before using useTheme composable");
149
50
  return {
51
+ /**
52
+ * Current theme preset
53
+ */
54
+ preset,
55
+ /**
56
+ * Current theme name
57
+ */
150
58
  presetName,
59
+ /**
60
+ * Current color mode
61
+ * @description The color mode - Can be 'auto', 'dark' or 'light'
62
+ */
151
63
  colorMode,
64
+ /**
65
+ * Whether the current color mode is dark
66
+ */
152
67
  isDark,
68
+ /**
69
+ * Strategy used to apply the theme
70
+ */
153
71
  strategy,
72
+ /**
73
+ * Update the theme
74
+ * @param preset The new theme preset
75
+ * @description Update the theme with a new preset or override some tokens
76
+ */
154
77
  updateTheme,
78
+ /**
79
+ * Set the color mode
80
+ * @description Set the color mode - Can be 'auto', 'dark' or 'light'
81
+ * @param colorMode The new color mode
82
+ */
155
83
  setColorMode,
84
+ /**
85
+ * Toggle the dark mode
86
+ * @description Toggle the dark mode
87
+ */
156
88
  toggleDarkMode,
89
+ /**
90
+ * Mode
91
+ * @description Supported themes - Can be 'both', 'light' or 'dark'
92
+ */
157
93
  mode,
94
+ /**
95
+ * Dark mode strategy
96
+ * @description Strategy used to apply the dark mode - Can be 'class' or 'media'
97
+ */
158
98
  darkModeStrategy,
159
- currentPreset
99
+ /**
100
+ * @deprecated use `preset` instead
101
+ */
102
+ currentPreset: preset
160
103
  };
161
104
  }
162
105
  export {
163
- initThemeState,
164
106
  useTheme
165
107
  };
package/dist/index.js CHANGED
@@ -1,16 +1,16 @@
1
1
  import { buildSeparateThemeFiles, buildThemeCSS, createThemeStylesheet, generateThemeBundle } from "./build/index.js";
2
- import { initThemeState, useTheme } from "./composables/useTheme.js";
2
+ import { useTheme } from "./composables/useTheme.js";
3
3
  import { definePreset } from "./define-preset.js";
4
4
  import { MazUiTheme } from "./plugin.js";
5
5
  import { adjustColorLightness, formatHSL, generateColorScale, getContrastColor, parseHSL } from "./utils/color-utils.js";
6
- import { CSS_IDS, generateCriticalCSS, generateFullCSS, injectCSS, removeCSS } from "./utils/css-generator.js";
6
+ import { CSS_ID, generateCSS, injectCSS, removeCSS } from "./utils/css-generator.js";
7
7
  import { deepMerge, mergePresets } from "./utils/preset-merger.js";
8
8
  import { mazUi } from "./presets/mazUi.js";
9
9
  import { obsidian } from "./presets/obsidian.js";
10
10
  import { ocean } from "./presets/ocean.js";
11
11
  import { pristine } from "./presets/pristine.js";
12
12
  export {
13
- CSS_IDS,
13
+ CSS_ID,
14
14
  MazUiTheme,
15
15
  adjustColorLightness,
16
16
  buildSeparateThemeFiles,
@@ -19,12 +19,10 @@ export {
19
19
  deepMerge,
20
20
  definePreset,
21
21
  formatHSL,
22
+ generateCSS,
22
23
  generateColorScale,
23
- generateCriticalCSS,
24
- generateFullCSS,
25
24
  generateThemeBundle,
26
25
  getContrastColor,
27
- initThemeState,
28
26
  injectCSS,
29
27
  mazUi,
30
28
  mergePresets,
@@ -1,9 +1,11 @@
1
+ import "../chunks/isServer.BAlEcRRr.js";
1
2
  import "vue";
3
+ import { MazUiTheme } from "../plugin.js";
2
4
  import "../utils/css-generator.js";
3
5
  import "../utils/get-color-mode.js";
6
+ import "../utils/update-document-class.js";
4
7
  import "../utils/get-preset.js";
5
8
  import "../utils/preset-merger.js";
6
- import { MazUiTheme } from "../plugin.js";
7
9
  export {
8
10
  MazUiTheme
9
11
  };
package/dist/plugin.js CHANGED
@@ -1,54 +1,131 @@
1
- import { reactive } from "vue";
2
- import { generateCriticalCSS, injectCSS, CSS_IDS, generateFullCSS } from "./utils/css-generator.js";
3
- import { getColorMode, isSystemPrefersDark } from "./utils/get-color-mode.js";
1
+ import { i as isServer } from "./chunks/isServer.BAlEcRRr.js";
2
+ import { ref, onMounted, computed, toValue, watch } from "vue";
3
+ import { generateCSS, injectCSS, CSS_ID } from "./utils/css-generator.js";
4
+ import { getSavedColorMode, getSystemColorMode, getColorMode } from "./utils/get-color-mode.js";
5
+ import { updateDocumentClass } from "./utils/update-document-class.js";
4
6
  import { getPreset } from "./utils/get-preset.js";
5
7
  import { mergePresets } from "./utils/preset-merger.js";
6
- function applyDarkMode(darkModeStrategy, isDark) {
7
- typeof document > "u" || darkModeStrategy !== "class" || (isDark ? document.documentElement.classList.add("dark") : document.documentElement.classList.remove("dark"));
8
+ function isClient() {
9
+ return typeof document < "u";
10
+ }
11
+ function truthyFilter(value) {
12
+ return !!value;
13
+ }
14
+ function useMutationObserver(target, callback, options = {}) {
15
+ const {
16
+ internalWindow = isClient() ? globalThis : void 0,
17
+ ...mutationOptions
18
+ } = options;
19
+ let observer;
20
+ const isSupported = ref((internalWindow && "MutationObserver" in internalWindow) ?? !1);
21
+ isSupported.value || onMounted(() => {
22
+ isSupported.value = (internalWindow && "MutationObserver" in internalWindow) ?? !1;
23
+ });
24
+ const cleanup = () => {
25
+ observer && (observer.disconnect(), observer = void 0);
26
+ }, targets = computed(() => {
27
+ const value = toValue(target);
28
+ let element;
29
+ return value && "$el" in value ? element = value.$el : value && (element = value), new Set([element].filter(truthyFilter));
30
+ }), stopWatch = watch(
31
+ [targets, isSupported],
32
+ ([newTargets, isSupported2]) => {
33
+ cleanup(), isSupported2 && newTargets.size && (observer = new MutationObserver(callback), newTargets.forEach((el) => observer?.observe(el, mutationOptions)));
34
+ },
35
+ { immediate: !0, flush: "post" }
36
+ );
37
+ return {
38
+ isSupported,
39
+ stop: () => {
40
+ stopWatch(), cleanup();
41
+ },
42
+ takeRecords: () => observer?.takeRecords()
43
+ };
8
44
  }
9
45
  function injectThemeCSS(finalPreset, config) {
10
46
  if (typeof document > "u")
11
47
  return;
12
48
  const cssOptions = {
13
49
  mode: config.mode,
14
- darkSelectorStrategy: config.darkModeStrategy
50
+ darkSelectorStrategy: config.darkModeStrategy,
51
+ darkClass: config.darkClass
15
52
  };
16
53
  if (config.injectCriticalCSS) {
17
- const criticalCSS = generateCriticalCSS(finalPreset, cssOptions);
18
- injectCSS(CSS_IDS.CRITICAL, criticalCSS);
54
+ const criticalCSS = generateCSS(finalPreset, {
55
+ ...cssOptions,
56
+ onlyCritical: !0
57
+ });
58
+ injectCSS(CSS_ID, criticalCSS);
19
59
  }
20
60
  if (!config.injectFullCSS)
21
61
  return;
22
- const fullCSS = generateFullCSS(finalPreset, cssOptions);
23
- config.strategy === "runtime" ? injectCSS(CSS_IDS.FULL, fullCSS) : config.strategy === "hybrid" && requestIdleCallback(() => {
24
- injectCSS(CSS_IDS.FULL, fullCSS);
62
+ const fullCSS = generateCSS(finalPreset, cssOptions);
63
+ config.strategy === "runtime" ? injectCSS(CSS_ID, fullCSS) : config.strategy === "hybrid" && requestIdleCallback(() => {
64
+ injectCSS(CSS_ID, fullCSS);
25
65
  }, { timeout: 100 });
26
66
  }
27
67
  function injectThemeState(app, themeState) {
28
68
  app.provide("mazThemeState", themeState), app.config.globalProperties.$mazThemeState = themeState;
29
69
  }
70
+ function watchColorSchemeFromMedia(themeState) {
71
+ if (!isServer()) {
72
+ if (themeState.value && themeState.value.colorMode === "auto") {
73
+ const mediaQuery = globalThis.matchMedia("(prefers-color-scheme: dark)"), updateFromMedia = () => {
74
+ if (themeState.value.colorMode === "auto") {
75
+ const newColorMode = mediaQuery.matches ? "dark" : "light";
76
+ updateDocumentClass(newColorMode === "dark", themeState.value), themeState.value.isDark = newColorMode === "dark";
77
+ }
78
+ };
79
+ mediaQuery.addEventListener("change", updateFromMedia);
80
+ }
81
+ watch(() => themeState.value.colorMode, (colorMode) => {
82
+ updateDocumentClass(
83
+ colorMode === "auto" ? getSystemColorMode() === "dark" : colorMode === "dark",
84
+ themeState.value
85
+ );
86
+ });
87
+ }
88
+ }
89
+ function watchMutationClassOnHtmlElement(themeState) {
90
+ isServer() || useMutationObserver(
91
+ document.documentElement,
92
+ () => {
93
+ if (isServer() || !themeState.value)
94
+ return;
95
+ const activeColorMode = document.documentElement.classList.contains(themeState.value.darkClass) ? "dark" : "light";
96
+ themeState.value.isDark = activeColorMode === "dark", themeState.value.colorMode !== activeColorMode && themeState.value.colorMode !== "auto" && (themeState.value.colorMode = activeColorMode);
97
+ },
98
+ {
99
+ attributes: !0
100
+ }
101
+ );
102
+ }
30
103
  const MazUiTheme = {
31
104
  async install(app, options) {
32
105
  const config = {
33
- strategy: "runtime",
106
+ strategy: "hybrid",
34
107
  overrides: {},
35
108
  darkModeStrategy: "class",
36
- colorMode: (options?.mode !== "both" ? options?.mode : options?.colorMode) ?? "auto",
109
+ preset: void 0,
37
110
  injectCriticalCSS: !0,
38
111
  injectFullCSS: !0,
39
112
  mode: "both",
40
- ...options
41
- }, colorMode = config.mode !== "both" ? config.mode : getColorMode(config.colorMode), isDark = colorMode === "auto" && config.mode === "both" ? isSystemPrefersDark() : colorMode === "dark" || config.mode === "dark", themeState = reactive({
42
- currentPreset: void 0,
43
- mode: config.mode,
44
- colorMode,
45
- isDark,
113
+ darkClass: "dark",
114
+ ...options,
115
+ colorMode: getSavedColorMode() ?? options.colorMode ?? (options.mode === "dark" ? "dark" : "auto")
116
+ }, isDark = config.colorMode === "auto" && config.mode === "both" ? getSystemColorMode() === "dark" || getColorMode(config.colorMode) === "dark" : getColorMode(config.colorMode) === "dark" || config.mode === "dark", themeState = ref({
46
117
  strategy: config.strategy,
47
- darkModeStrategy: config.darkModeStrategy
118
+ darkClass: config.darkClass,
119
+ darkModeStrategy: config.darkModeStrategy,
120
+ colorMode: config.colorMode,
121
+ mode: config.mode,
122
+ preset: void 0,
123
+ // @ts-expect-error _isDark is a private property
124
+ isDark: options._isDark || isDark
48
125
  });
49
- applyDarkMode(config.darkModeStrategy, isDark), injectThemeState(app, themeState);
126
+ injectThemeState(app, themeState), updateDocumentClass(themeState.value.isDark, themeState.value);
50
127
  const preset = config.strategy === "buildtime" ? config.preset : await getPreset(config.preset), finalPreset = Object.keys(config.overrides).length > 0 && preset ? mergePresets(preset, config.overrides) : preset;
51
- finalPreset && (themeState.currentPreset = finalPreset), !(config.strategy === "buildtime" || !finalPreset) && injectThemeCSS(finalPreset, config);
128
+ finalPreset && (themeState.value.preset = finalPreset), !(config.strategy === "buildtime" || !finalPreset) && (injectThemeCSS(finalPreset, config), watchColorSchemeFromMedia(themeState), watchMutationClassOnHtmlElement(themeState));
52
129
  }
53
130
  };
54
131
  export {
@@ -1,14 +1,16 @@
1
1
  import { ThemePreset } from '../types';
2
2
  export interface BuildThemeOptions {
3
3
  preset: ThemePreset;
4
- /** Mode de thème à générer */
4
+ /** Theme mode to generate */
5
5
  mode?: 'light' | 'dark' | 'both';
6
- /** Sélecteur pour le mode sombre */
6
+ /** Dark mode selector: 'class' (.dark) | 'media' (@media) */
7
7
  darkSelector?: 'class' | 'media';
8
- /** Préfixe des variables CSS */
8
+ /** CSS variables prefix */
9
9
  prefix?: string;
10
- /** Générer seulement le CSS critique */
10
+ /** Generate only critical CSS */
11
11
  criticalOnly?: boolean;
12
+ /** Dark class name */
13
+ darkClass?: string;
12
14
  }
13
15
  export declare function buildThemeCSS(options: BuildThemeOptions): string;
14
16
  export declare function generateThemeBundle(presets: ThemePreset[], options?: {
@@ -28,6 +30,7 @@ export declare function createThemeStylesheet(css: string, options?: {
28
30
  export declare function buildSeparateThemeFiles(preset: ThemePreset, options?: {
29
31
  prefix?: string;
30
32
  darkSelector?: 'class' | 'media';
33
+ darkClass?: string;
31
34
  }): {
32
35
  critical: string;
33
36
  full: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/build/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAG3C,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,WAAW,CAAA;IACnB,8BAA8B;IAC9B,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;IAChC,oCAAoC;IACpC,YAAY,CAAC,EAAE,OAAO,GAAG,OAAO,CAAA;IAChC,gCAAgC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,wCAAwC;IACxC,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAwBhE;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,OAAO,GAAE;IACnE,8BAA8B;IAC9B,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;IAChC,oCAAoC;IACpC,YAAY,CAAC,EAAE,OAAO,GAAG,OAAO,CAAA;IAChC,gCAAgC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,wCAAwC;IACxC,YAAY,CAAC,EAAE,OAAO,CAAA;CAClB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAkB9B;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE;IAC1D,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;CACV,GAAG,MAAM,CAYd;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,GAAE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,OAAO,GAAG,OAAO,CAAA;CAC5B,GAAG;IACP,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;CACjB,CAWA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/build/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAG3C,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,WAAW,CAAA;IACnB,6BAA6B;IAC7B,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;IAChC,6DAA6D;IAC7D,YAAY,CAAC,EAAE,OAAO,GAAG,OAAO,CAAA;IAChC,2BAA2B;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,iCAAiC;IACjC,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,sBAAsB;IACtB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CA0BhE;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,OAAO,GAAE;IACnE,8BAA8B;IAC9B,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;IAChC,oCAAoC;IACpC,YAAY,CAAC,EAAE,OAAO,GAAG,OAAO,CAAA;IAChC,gCAAgC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,wCAAwC;IACxC,YAAY,CAAC,EAAE,OAAO,CAAA;CAClB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAkB9B;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE;IAC1D,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;CACV,GAAG,MAAM,CAYd;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,GAAE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,OAAO,GAAG,OAAO,CAAA;IAChC,SAAS,CAAC,EAAE,MAAM,CAAA;CACd,GAAG;IACP,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;CACjB,CAWA"}