@maz-ui/themes 5.0.0-beta.44 → 5.0.0-beta.46

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/README.md CHANGED
@@ -47,7 +47,7 @@ app.use(MazUiTheme, {
47
47
 
48
48
  ### Preset persistence
49
49
 
50
- The active preset name is stored in a `maz-preset` cookie (1-year TTL, `SameSite=Lax`). At boot the cookie takes priority over `options.preset` (string name **or** preset object — both treated as the default the app boots with), so the user's last choice survives across reloads. The cookie is written on every successful resolution and on every `useTheme().updateTheme()` call, and auto-cleared if the saved name no longer resolves. Set `persistPreset: false` to opt out — no cookie is read or written.
50
+ The active preset is stored in a `maz-preset` cookie (1-year TTL, `SameSite=Lax`) as a `base:active` pair, where `base` is the identity of the preset declared in `options.preset` and `active` is the one currently applied. The configured `options.preset` is always authoritative: a runtime switch made via `useTheme().updateTheme()` is only restored on reload when its `base` matches the configured preset, so a stale cookie - or a cookie written by another app on the same host - can never override the preset your app declares. A foreign or legacy (plain-name) cookie is ignored and healed on the next resolution. Set `persistPreset: false` to opt out - no cookie is read or written.
51
51
 
52
52
  ### 2. Usage in components
53
53
 
@@ -1 +1 @@
1
- {"version":3,"file":"useTheme.d.ts","sourceRoot":"","sources":["../../src/composables/useTheme.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe,EAAE,oBAAoB,EAAc,MAAM,UAAU,CAAA;AAgCzG,iBAAe,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,oBAAoB,GAAG,eAAe,iBAgCtF;AAED,iBAAe,YAAY,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBpG;AAED,iBAAS,cAAc,CAAC,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1E;AAiCD,wBAAgB,QAAQ;IAkBpB;;OAEG;;IAEH;;OAEG;;IAEH;;;OAGG;;IAEH;;OAEG;;IAEH;;OAEG;;IAEH;;;;OAIG;wBACiB,WAAW,GAAG,oBAAoB,GAAG,eAAe,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC;IAGzG;;;;;;OAMG;;IAEH;;;;;OAKG;;IAEH;;;OAGG;;IAEH;;;OAGG;;IAEH;;OAEG;;EAGN"}
1
+ {"version":3,"file":"useTheme.d.ts","sourceRoot":"","sources":["../../src/composables/useTheme.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe,EAAE,oBAAoB,EAAc,MAAM,UAAU,CAAA;AAgCzG,iBAAe,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,oBAAoB,GAAG,eAAe,iBAmCtF;AAED,iBAAe,YAAY,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBpG;AAED,iBAAS,cAAc,CAAC,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1E;AAiCD,wBAAgB,QAAQ;IAkBpB;;OAEG;;IAEH;;OAEG;;IAEH;;;OAGG;;IAEH;;OAEG;;IAEH;;OAEG;;IAEH;;;;OAIG;wBACiB,WAAW,GAAG,oBAAoB,GAAG,eAAe,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC;IAGzG;;;;;;OAMG;;IAEH;;;;;OAKG;;IAEH;;;OAGG;;IAEH;;;OAGG;;IAEH;;OAEG;;EAGN"}
@@ -1 +1 @@
1
- import{saveResolvedPresetName}from"../utils/cookie-storage.js";import{CSS_ID,generateCSS,injectCSS}from"../utils/css-generator.js";import{getPreset}from"../utils/get-preset.js";import{noTransition}from"../utils/no-transition.js";import{mergePresets}from"../utils/preset-merger.js";import{getSystemColorMode,saveResolvedColorMode}from"../utils/get-color-mode.js";import{isServer}from"@maz-ui/utils/helpers/isServer";import{setCookie}from"@maz-ui/utils/helpers/cookie";import{computed,getCurrentInstance,inject,ref,watch}from"vue";var themeState=ref();var colorMode=computed({get:()=>themeState.value?.colorMode,set:mode=>void setColorMode(mode)});var isDark=computed(()=>themeState.value?.isDark||!1);var strategy=computed(()=>themeState.value?.strategy);var mode=computed(()=>themeState.value?.mode);var darkModeStrategy=computed(()=>themeState.value?.darkModeStrategy);var preset=computed(()=>themeState.value?.preset);var presetName=computed(()=>preset.value?.name);async function updateTheme(preset){if(!themeState.value)return;let _preset=typeof preset==`string`?await getPreset(preset):preset;if(!_preset||!themeState.value.preset){console.error(`[@maz-ui/themes] No preset found — with buildtime strategy you must pass a full preset`);return}let newPreset=`name`in _preset&&_preset.name!==themeState.value.preset.name?_preset:mergePresets(themeState.value.preset,_preset);if(themeState.value.preset=newPreset,themeState.value.persistPreset&&saveResolvedPresetName(newPreset.name),themeState.value.strategy===`runtime`){let fullCSS=generateCSS(newPreset,{mode:themeState.value.mode,darkSelectorStrategy:themeState.value.darkModeStrategy,prefix:`maz`,darkClass:themeState.value.darkClass,lightClass:themeState.value.lightClass});injectCSS(CSS_ID,fullCSS)}}async function setColorMode(colorMode,options={}){if(!themeState.value)return;let apply=()=>{themeState.value.colorMode=colorMode,setCookie(`maz-color-mode`,colorMode),colorMode===`auto`&&saveResolvedColorMode(getSystemColorMode()===`dark`?`dark`:`light`)};if(options.animate){let{runViewTransition}=await import(`../utils/view-transition.js`);await runViewTransition(apply)}else apply()}function toggleDarkMode(options={}){return setColorMode(isDark.value?`light`:`dark`,options)}var stopInjectedWatch;function setThemeStateFromGlobalProperties(){themeState.value=void 0,stopInjectedWatch?.(),stopInjectedWatch=void 0;try{let injectedState=inject(`mazThemeState`,void 0);if(themeState.value=injectedState?.value,injectedState&&(stopInjectedWatch=watch(injectedState,newState=>{newState&&(themeState.value=newState)},{deep:!0})),!themeState.value)throw Error(`mazThemeState not found`)}catch{let instance=getCurrentInstance();instance?.appContext?.app?.config?.globalProperties&&(themeState.value=instance.appContext.app.config.globalProperties.$mazThemeState.value)}}function useTheme(){isServer()&&(themeState.value=void 0);try{if(themeState.value||setThemeStateFromGlobalProperties(),!themeState.value)throw Error(`[@maz-ui/themes] no theme state found`)}catch{throw Error(`[@maz-ui/themes] useTheme requires the MazUi/MazUiTheme plugin or a MazUiProvider wrapper`)}return{preset,presetName,colorMode,isDark,strategy,updateTheme(preset){return noTransition(updateTheme,preset)},setColorMode,toggleDarkMode,mode,darkModeStrategy,currentPreset:preset}}export{useTheme};
1
+ import{getSavedPreset,savePreset}from"../utils/cookie-storage.js";import{CSS_ID,generateCSS,injectCSS}from"../utils/css-generator.js";import{getPreset}from"../utils/get-preset.js";import{noTransition}from"../utils/no-transition.js";import{mergePresets}from"../utils/preset-merger.js";import{getSystemColorMode,saveResolvedColorMode}from"../utils/get-color-mode.js";import{isServer}from"@maz-ui/utils/helpers/isServer";import{setCookie}from"@maz-ui/utils/helpers/cookie";import{computed,getCurrentInstance,inject,ref,watch}from"vue";var themeState=ref();var colorMode=computed({get:()=>themeState.value?.colorMode,set:mode=>void setColorMode(mode)});var isDark=computed(()=>themeState.value?.isDark||!1);var strategy=computed(()=>themeState.value?.strategy);var mode=computed(()=>themeState.value?.mode);var darkModeStrategy=computed(()=>themeState.value?.darkModeStrategy);var preset=computed(()=>themeState.value?.preset);var presetName=computed(()=>preset.value?.name);async function updateTheme(preset){if(!themeState.value)return;let _preset=typeof preset==`string`?await getPreset(preset):preset;if(!_preset||!themeState.value.preset){console.error(`[@maz-ui/themes] No preset found — with buildtime strategy you must pass a full preset`);return}let newPreset=`name`in _preset&&_preset.name!==themeState.value.preset.name?_preset:mergePresets(themeState.value.preset,_preset);if(themeState.value.preset=newPreset,themeState.value.persistPreset){let base=getSavedPreset()?.base??newPreset.name;savePreset(base,newPreset.name)}if(themeState.value.strategy===`runtime`){let fullCSS=generateCSS(newPreset,{mode:themeState.value.mode,darkSelectorStrategy:themeState.value.darkModeStrategy,prefix:`maz`,darkClass:themeState.value.darkClass,lightClass:themeState.value.lightClass});injectCSS(CSS_ID,fullCSS)}}async function setColorMode(colorMode,options={}){if(!themeState.value)return;let apply=()=>{themeState.value.colorMode=colorMode,setCookie(`maz-color-mode`,colorMode),colorMode===`auto`&&saveResolvedColorMode(getSystemColorMode()===`dark`?`dark`:`light`)};if(options.animate){let{runViewTransition}=await import(`../utils/view-transition.js`);await runViewTransition(apply)}else apply()}function toggleDarkMode(options={}){return setColorMode(isDark.value?`light`:`dark`,options)}var stopInjectedWatch;function setThemeStateFromGlobalProperties(){themeState.value=void 0,stopInjectedWatch?.(),stopInjectedWatch=void 0;try{let injectedState=inject(`mazThemeState`,void 0);if(themeState.value=injectedState?.value,injectedState&&(stopInjectedWatch=watch(injectedState,newState=>{newState&&(themeState.value=newState)},{deep:!0})),!themeState.value)throw Error(`mazThemeState not found`)}catch{let instance=getCurrentInstance();instance?.appContext?.app?.config?.globalProperties&&(themeState.value=instance.appContext.app.config.globalProperties.$mazThemeState.value)}}function useTheme(){isServer()&&(themeState.value=void 0);try{if(themeState.value||setThemeStateFromGlobalProperties(),!themeState.value)throw Error(`[@maz-ui/themes] no theme state found`)}catch{throw Error(`[@maz-ui/themes] useTheme requires the MazUi/MazUiTheme plugin or a MazUiProvider wrapper`)}return{preset,presetName,colorMode,isDark,strategy,updateTheme(preset){return noTransition(updateTheme,preset)},setColorMode,toggleDarkMode,mode,darkModeStrategy,currentPreset:preset}}export{useTheme};
@@ -1,7 +1,19 @@
1
- /** Persisted preset name from `maz-preset` cookie, or `null`. */
2
- export declare function getSavedPresetName(): string | null;
3
- /** Write `name` to the `maz-preset` cookie, no-op if value already matches. */
4
- export declare function saveResolvedPresetName(name: string): void;
5
- /** Drop the `maz-preset` cookie (saved name no longer resolves). */
1
+ export interface SavedPreset {
2
+ /** Identity of the preset declared in the app config (the "base"). */
3
+ base: string;
4
+ /** Currently active preset name (equals `base` unless switched at runtime). */
5
+ active: string;
6
+ }
7
+ /**
8
+ * Parse the `maz-preset` cookie. Format is `"<base>:<active>"` where `base` is
9
+ * the configured preset identity, so a cookie written by another app or a
10
+ * previous config on the same host is detectable as foreign. A legacy
11
+ * plain-name value (no `:`) is treated as unscoped and returns `null` so it
12
+ * cannot hijack the configured preset.
13
+ */
14
+ export declare function getSavedPreset(): SavedPreset | null;
15
+ /** Serialize `base`/`active` into the `maz-preset` cookie, no-op if unchanged. */
16
+ export declare function savePreset(base: string, active: string): void;
17
+ /** Drop the `maz-preset` cookie (saved preset no longer resolves). */
6
18
  export declare function clearSavedPresetName(): void;
7
19
  //# sourceMappingURL=cookie-storage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cookie-storage.d.ts","sourceRoot":"","sources":["../../src/utils/cookie-storage.ts"],"names":[],"mappings":"AAIA,iEAAiE;AACjE,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAElD;AAED,+EAA+E;AAC/E,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAIzD;AAED,oEAAoE;AACpE,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}
1
+ {"version":3,"file":"cookie-storage.d.ts","sourceRoot":"","sources":["../../src/utils/cookie-storage.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAA;IACZ,+EAA+E;IAC/E,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,IAAI,WAAW,GAAG,IAAI,CAenD;AAED,kFAAkF;AAClF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAS7D;AAED,sEAAsE;AACtE,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}
@@ -1 +1 @@
1
- import{deleteCookie,getCookie,setCookie}from"@maz-ui/utils/helpers/cookie";var PRESET_COOKIE=`maz-preset`;function getSavedPresetName(){return getCookie(PRESET_COOKIE)}function saveResolvedPresetName(name){name&&getCookie(PRESET_COOKIE)!==name&&setCookie(PRESET_COOKIE,name)}function clearSavedPresetName(){deleteCookie(PRESET_COOKIE)}export{clearSavedPresetName,getSavedPresetName,saveResolvedPresetName};
1
+ import{deleteCookie,getCookie,setCookie}from"@maz-ui/utils/helpers/cookie";var PRESET_COOKIE=`maz-preset`;function getSavedPreset(){let raw=getCookie(PRESET_COOKIE);if(!raw)return null;let separatorIndex=raw.indexOf(`:`);if(separatorIndex===-1)return null;let base=raw.slice(0,separatorIndex);let active=raw.slice(separatorIndex+1);return!base||!active?null:{base,active}}function savePreset(base,active){if(!base||!active)return;let value=`${base}:${active}`;getCookie(PRESET_COOKIE)!==value&&setCookie(PRESET_COOKIE,value)}function clearSavedPresetName(){deleteCookie(PRESET_COOKIE)}export{clearSavedPresetName,getSavedPreset,savePreset};
@@ -1 +1 @@
1
- import{colorToHex,formatAsHSL,formatAsOklch,parseColor,parseColorAsOklch}from"./color-conversions.js";import{isCompleteCSSColor,normalizeColor}from"./color-parser.js";import{injectColorSchemeMeta,resolveColorSchemeContent}from"./color-scheme-meta.js";import{clearSavedPresetName,getSavedPresetName,saveResolvedPresetName}from"./cookie-storage.js";import{CSS_ID,generateCSS,injectCSS,removeCSS}from"./css-generator.js";import{getPreset,isPresetObject}from"./get-preset.js";import{injectThemeState}from"./inject.js";import{injectThemeCSS}from"./inject-theme-css.js";import{noTransition}from"./no-transition.js";import{deepMerge,mergePresets}from"./preset-merger.js";import{updateDocumentClass}from"./update-document-class.js";import{defaultOptions,setupTheme}from"./setup-theme.js";export{CSS_ID,clearSavedPresetName,colorToHex,deepMerge,defaultOptions,formatAsHSL,formatAsOklch,generateCSS,getPreset,getSavedPresetName,injectCSS,injectColorSchemeMeta,injectThemeCSS,injectThemeState,isCompleteCSSColor,isPresetObject,mergePresets,noTransition,normalizeColor,parseColor,parseColorAsOklch,removeCSS,resolveColorSchemeContent,saveResolvedPresetName,setupTheme,updateDocumentClass};
1
+ import{colorToHex,formatAsHSL,formatAsOklch,parseColor,parseColorAsOklch}from"./color-conversions.js";import{isCompleteCSSColor,normalizeColor}from"./color-parser.js";import{injectColorSchemeMeta,resolveColorSchemeContent}from"./color-scheme-meta.js";import{clearSavedPresetName,getSavedPreset,savePreset}from"./cookie-storage.js";import{CSS_ID,generateCSS,injectCSS,removeCSS}from"./css-generator.js";import{getPreset,isPresetObject}from"./get-preset.js";import{injectThemeState}from"./inject.js";import{injectThemeCSS}from"./inject-theme-css.js";import{noTransition}from"./no-transition.js";import{deepMerge,mergePresets}from"./preset-merger.js";import{updateDocumentClass}from"./update-document-class.js";import{defaultOptions,setupTheme}from"./setup-theme.js";export{CSS_ID,clearSavedPresetName,colorToHex,deepMerge,defaultOptions,formatAsHSL,formatAsOklch,generateCSS,getPreset,getSavedPreset,injectCSS,injectColorSchemeMeta,injectThemeCSS,injectThemeState,isCompleteCSSColor,isPresetObject,mergePresets,noTransition,normalizeColor,parseColor,parseColorAsOklch,removeCSS,resolveColorSchemeContent,savePreset,setupTheme,updateDocumentClass};
@@ -1 +1 @@
1
- {"version":3,"file":"setup-theme.d.ts","sourceRoot":"","sources":["../../src/utils/setup-theme.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAC9B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,KAAK,EAAgC,UAAU,EAAE,MAAM,UAAU,CAAA;AA8DxE,eAAO,MAAM,cAAc;;;;;;;;;;CAUgE,CAAA;AAE3F,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,CAAA;IAC3B,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB;AA8FD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,gBAAgB,CAoCvE"}
1
+ {"version":3,"file":"setup-theme.d.ts","sourceRoot":"","sources":["../../src/utils/setup-theme.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAC9B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,KAAK,EAAgC,UAAU,EAAE,MAAM,UAAU,CAAA;AA8DxE,eAAO,MAAM,cAAc;;;;;;;;;;CAUgE,CAAA;AAE3F,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,CAAA;IAC3B,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB;AA0GD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,gBAAgB,CAmDvE"}
@@ -1 +1 @@
1
- import{injectColorSchemeMeta,resolveColorSchemeContent}from"./color-scheme-meta.js";import{clearSavedPresetName,getSavedPresetName,saveResolvedPresetName}from"./cookie-storage.js";import{getPreset}from"./get-preset.js";import{injectThemeCSS}from"./inject-theme-css.js";import{mergePresets}from"./preset-merger.js";import{getColorMode,getSavedColorMode,getSystemColorMode,saveResolvedColorMode}from"./get-color-mode.js";import{updateDocumentClass}from"./update-document-class.js";import{useMutationObserver}from"./use-mutation-observer.js";import{isServer}from"@maz-ui/utils/helpers/isServer";import{ref,watch}from"vue";function noop(){}function watchColorSchemeFromMedia(themeState){if(isServer())return noop;let mediaQuery=globalThis.matchMedia(`(prefers-color-scheme: dark)`);let onChange=()=>{if(themeState.value.colorMode!==`auto`)return;let next=mediaQuery.matches?`dark`:`light`;updateDocumentClass(`auto`,themeState.value),themeState.value.isDark=next===`dark`,saveResolvedColorMode(next)};mediaQuery.addEventListener(`change`,onChange);let stopWatch=watch(()=>themeState.value.colorMode,colorMode=>{let isDark=colorMode===`auto`?getSystemColorMode()===`dark`:colorMode===`dark`;updateDocumentClass(colorMode,themeState.value),injectColorSchemeMeta(resolveColorSchemeContent(themeState.value.mode,colorMode)),colorMode===`auto`&&saveResolvedColorMode(isDark?`dark`:`light`)});return()=>{mediaQuery.removeEventListener(`change`,onChange),stopWatch()}}function watchMutationClassOnHtmlElement(themeState){return isServer()?noop:useMutationObserver(document.documentElement,()=>{if(isServer()||!themeState.value)return;let active=document.documentElement.classList.contains(themeState.value.darkClass)?`dark`:`light`;themeState.value.isDark=active===`dark`,themeState.value.colorMode!==active&&themeState.value.colorMode!==`auto`&&(themeState.value.colorMode=active)},{attributes:!0}).stop}var defaultOptions={strategy:`runtime`,overrides:{},darkModeStrategy:`class`,preset:void 0,mode:`both`,darkClass:`dark`,lightClass:`light`,colorMode:`auto`,persistPreset:!0};function resolveConfig(options){return{...defaultOptions,...options,colorMode:getSavedColorMode()??options.colorMode??(options.mode===`dark`?`dark`:`auto`)}}function createThemeState(options,config){let isDark=config.colorMode===`auto`&&config.mode===`both`?getSystemColorMode()===`dark`||getColorMode(config.colorMode)===`dark`:getColorMode(config.colorMode)===`dark`||config.mode===`dark`;!isServer()&&config.colorMode===`auto`&&saveResolvedColorMode(isDark?`dark`:`light`);let themeState=ref({strategy:config.strategy,darkClass:config.darkClass,lightClass:config.lightClass,darkModeStrategy:config.darkModeStrategy,colorMode:config.colorMode,mode:config.mode,preset:void 0,persistPreset:config.persistPreset,isDark:options._isDark||isDark});if(!isServer()&&config.darkModeStrategy===`class`&&config.mode===`both`){let html=document.documentElement;html.classList.contains(config.darkClass)||html.classList.contains(config.lightClass)||updateDocumentClass(themeState.value.colorMode,themeState.value)}else updateDocumentClass(themeState.value.colorMode,themeState.value);return themeState}function finalizeTheme(themeState,preset,config){let finalPreset=preset&&Object.keys(config.overrides).length>0?mergePresets(preset,config.overrides):preset;if(finalPreset&&(themeState.value.preset=finalPreset,config.persistPreset&&saveResolvedPresetName(finalPreset.name)),config.strategy===`buildtime`||!finalPreset)return{themeState,cleanup:noop};injectThemeCSS(finalPreset,config);let stopMedia=watchColorSchemeFromMedia(themeState);let stopMutation=watchMutationClassOnHtmlElement(themeState);return{themeState,cleanup:()=>{stopMedia(),stopMutation()}}}function swapPreset(themeState,preset,config){let final=Object.keys(config.overrides).length>0?mergePresets(preset,config.overrides):preset;themeState.value.preset=final,saveResolvedPresetName(final.name),injectThemeCSS(final,config)}function setupTheme(options){let config=resolveConfig(options);let themeState=createThemeState(options,config);injectColorSchemeMeta(resolveColorSchemeContent(themeState.value.mode,themeState.value.colorMode));let savedName=config.persistPreset?getSavedPresetName():null;let presetObject=config.preset&&typeof config.preset!=`string`?config.preset:null;if(presetObject||config.strategy===`buildtime`){let setup=finalizeTheme(themeState,presetObject??config.preset,config);return savedName&&config.strategy!==`buildtime`&&(!presetObject||savedName!==presetObject.name)&&getPreset(savedName).then(preset=>swapPreset(themeState,preset,config)).catch(()=>clearSavedPresetName()),setup}return(savedName?getPreset(savedName).catch(()=>(clearSavedPresetName(),getPreset(config.preset))):getPreset(config.preset)).catch(error=>{console.error(`[@maz-ui/themes] Failed to resolve preset`,error)}).then(preset=>finalizeTheme(themeState,preset,config)),{themeState,cleanup:noop}}export{defaultOptions,setupTheme};
1
+ import{injectColorSchemeMeta,resolveColorSchemeContent}from"./color-scheme-meta.js";import{getSavedPreset,savePreset}from"./cookie-storage.js";import{getPreset}from"./get-preset.js";import{injectThemeCSS}from"./inject-theme-css.js";import{mergePresets}from"./preset-merger.js";import{getColorMode,getSavedColorMode,getSystemColorMode,saveResolvedColorMode}from"./get-color-mode.js";import{updateDocumentClass}from"./update-document-class.js";import{useMutationObserver}from"./use-mutation-observer.js";import{isServer}from"@maz-ui/utils/helpers/isServer";import{ref,watch}from"vue";function noop(){}function watchColorSchemeFromMedia(themeState){if(isServer())return noop;let mediaQuery=globalThis.matchMedia(`(prefers-color-scheme: dark)`);let onChange=()=>{if(themeState.value.colorMode!==`auto`)return;let next=mediaQuery.matches?`dark`:`light`;updateDocumentClass(`auto`,themeState.value),themeState.value.isDark=next===`dark`,saveResolvedColorMode(next)};mediaQuery.addEventListener(`change`,onChange);let stopWatch=watch(()=>themeState.value.colorMode,colorMode=>{let isDark=colorMode===`auto`?getSystemColorMode()===`dark`:colorMode===`dark`;updateDocumentClass(colorMode,themeState.value),injectColorSchemeMeta(resolveColorSchemeContent(themeState.value.mode,colorMode)),colorMode===`auto`&&saveResolvedColorMode(isDark?`dark`:`light`)});return()=>{mediaQuery.removeEventListener(`change`,onChange),stopWatch()}}function watchMutationClassOnHtmlElement(themeState){return isServer()?noop:useMutationObserver(document.documentElement,()=>{if(isServer()||!themeState.value)return;let active=document.documentElement.classList.contains(themeState.value.darkClass)?`dark`:`light`;themeState.value.isDark=active===`dark`,themeState.value.colorMode!==active&&themeState.value.colorMode!==`auto`&&(themeState.value.colorMode=active)},{attributes:!0}).stop}var defaultOptions={strategy:`runtime`,overrides:{},darkModeStrategy:`class`,preset:void 0,mode:`both`,darkClass:`dark`,lightClass:`light`,colorMode:`auto`,persistPreset:!0};function resolveConfig(options){return{...defaultOptions,...options,colorMode:getSavedColorMode()??options.colorMode??(options.mode===`dark`?`dark`:`auto`)}}function createThemeState(options,config){let isDark=config.colorMode===`auto`&&config.mode===`both`?getSystemColorMode()===`dark`||getColorMode(config.colorMode)===`dark`:getColorMode(config.colorMode)===`dark`||config.mode===`dark`;!isServer()&&config.colorMode===`auto`&&saveResolvedColorMode(isDark?`dark`:`light`);let themeState=ref({strategy:config.strategy,darkClass:config.darkClass,lightClass:config.lightClass,darkModeStrategy:config.darkModeStrategy,colorMode:config.colorMode,mode:config.mode,preset:void 0,persistPreset:config.persistPreset,isDark:options._isDark||isDark});if(!isServer()&&config.darkModeStrategy===`class`&&config.mode===`both`){let html=document.documentElement;html.classList.contains(config.darkClass)||html.classList.contains(config.lightClass)||updateDocumentClass(themeState.value.colorMode,themeState.value)}else updateDocumentClass(themeState.value.colorMode,themeState.value);return themeState}function finalizeTheme(themeState,preset,config,baseName){let finalPreset=preset&&Object.keys(config.overrides).length>0?mergePresets(preset,config.overrides):preset;if(finalPreset&&(themeState.value.preset=finalPreset,config.persistPreset&&savePreset(baseName,finalPreset.name)),config.strategy===`buildtime`||!finalPreset)return{themeState,cleanup:noop};injectThemeCSS(finalPreset,config);let stopMedia=watchColorSchemeFromMedia(themeState);let stopMutation=watchMutationClassOnHtmlElement(themeState);return{themeState,cleanup:()=>{stopMedia(),stopMutation()}}}function swapPreset(themeState,preset,config,baseName){let final=Object.keys(config.overrides).length>0?mergePresets(preset,config.overrides):preset;themeState.value.preset=final,savePreset(baseName,final.name),injectThemeCSS(final,config)}var DEFAULT_PRESET_NAME=`maz-ui`;function getConfiguredPresetName(preset){return typeof preset==`string`?preset:DEFAULT_PRESET_NAME}function setupTheme(options){let config=resolveConfig(options);let themeState=createThemeState(options,config);injectColorSchemeMeta(resolveColorSchemeContent(themeState.value.mode,themeState.value.colorMode));let saved=config.persistPreset?getSavedPreset():null;let presetObject=config.preset&&typeof config.preset!=`string`?config.preset:null;if(presetObject||config.strategy===`buildtime`){let baseName=presetObject?presetObject.name:getConfiguredPresetName(config.preset);let setup=finalizeTheme(themeState,presetObject??config.preset,config,baseName);let activeOverride=saved&&saved.base===baseName&&saved.active!==baseName?saved.active:null;return activeOverride&&config.strategy!==`buildtime`&&getPreset(activeOverride).then(preset=>swapPreset(themeState,preset,config,baseName)).catch(()=>savePreset(baseName,baseName)),setup}return(async()=>{let basePreset=await getPreset(config.preset);let baseName=basePreset.name;if(saved&&saved.base===baseName&&saved.active!==baseName)try{return{preset:await getPreset(saved.active),baseName}}catch{}return{preset:basePreset,baseName}})().catch(error=>(console.error(`[@maz-ui/themes] Failed to resolve preset`,error),{preset:void 0,baseName:getConfiguredPresetName(config.preset)})).then(({preset,baseName})=>finalizeTheme(themeState,preset,config,baseName)),{themeState,cleanup:noop}}export{defaultOptions,setupTheme};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@maz-ui/themes",
3
3
  "type": "module",
4
- "version": "5.0.0-beta.44",
4
+ "version": "5.0.0-beta.46",
5
5
  "description": "Theme system for Maz-UI with TypeScript support and CSS variables",
6
6
  "author": "Louis Mazel <me@loicmazuel.com>",
7
7
  "license": "MIT",
@@ -89,6 +89,7 @@
89
89
  "types": "./dist/index.d.ts",
90
90
  "files": [
91
91
  "LICENSE",
92
+ "README.md",
92
93
  "dist"
93
94
  ],
94
95
  "engines": {
@@ -98,7 +99,7 @@
98
99
  "vue": ">=3.5.0 <4.0.0"
99
100
  },
100
101
  "dependencies": {
101
- "@maz-ui/utils": "5.0.0-beta.44"
102
+ "@maz-ui/utils": "5.0.0-beta.46"
102
103
  },
103
104
  "devDependencies": {
104
105
  "@maz-ui/vite-config": "0.0.0"