@gospore/theme 1.0.127 → 1.0.129

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/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export { default as Theme } from "./Theme.vue";
2
2
  export { default as ThemeSwitcher } from "./ThemeSwitcher.vue";
3
+ export { themePortalHostKey, useThemePortalTarget } from "./portalHost";
@@ -0,0 +1,2 @@
1
+ export function useThemePortalTarget(): import("vue").ComputedRef<any>;
2
+ export const themePortalHostKey: unique symbol;
package/dist/theme.cjs.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("vue");require("what-input");const N=require("@gospore/dropdown-menu"),x=["auto","light","dark"],K="gospore-theme-mode",re=60*60*24*365,ce="(prefers-color-scheme: dark)";function P(){if(typeof document>"u")return null;const o=se(K);return o&&x.includes(o)?o:null}function ae(o){if(typeof document>"u"||!x.includes(o))return;const a=typeof window<"u"?window.location.hostname:"",i=typeof window<"u"?window.location.protocol:"",s=ie(a),b=i==="https:",k=["path=/",`max-age=${re}`,"SameSite=Lax"];s&&k.push(`domain=${s}`),b&&k.push("Secure"),document.cookie=[`${encodeURIComponent(K)}=${encodeURIComponent(o)}`,...k].join("; ")}function Q(o){if(typeof document>"u")return;const a=typeof o=="string"&&x.includes(o)?o:P()??"auto";console.log("Applying theme mode:",a);const i=ue(a);document.documentElement.setAttribute("dark-mode",i)}function se(o){if(typeof document>"u"||!document.cookie)return null;const a=`${encodeURIComponent(o)}=`,i=document.cookie.split("; ");for(const s of i)if(s.startsWith(a))return decodeURIComponent(s.slice(a.length));return null}function ie(o){if(!o||o==="localhost")return null;if(/^\d+(?:\.\d+){3}$/.test(o))return o;const i=o.split(".");return i.length<=1?null:i.length===2?o:i.slice(-2).join(".")}function ue(o){if(o==="dark")return!0;if(o==="light"||typeof window>"u")return!1;try{const a=typeof window.matchMedia=="function"?window.matchMedia(ce):null;return a?a.matches:!1}catch{return!1}}const le="(prefers-color-scheme: dark)",de="(prefers-reduced-motion: reduce)",fe=200,me=Object.assign({name:"Theme"},{__name:"Theme",props:{mode:{type:String,validator:o=>["auto","light","dark"].includes(o)},accentColor:{type:String,required:!1,default:void 0},exposeGlobalAccent:{type:Boolean,default:!1}},setup(o){const a=o,i=[],s=new Set;function b(){const e=document.documentElement;if(!e)return;s.forEach(c=>{e.style.removeProperty(c)}),s.clear();const n=[...i].reverse().find(c=>c.enabled&&c.vars&&Object.keys(c.vars).length>0);n&&Object.entries(n.vars).forEach(([c,r])=>{e.style.setProperty(c,r),s.add(c)})}const k=window.matchMedia(le),U=window.matchMedia(de),T=G();Q(T);const I=t.ref(T),u=t.ref({darkMode:l(T)});k.addEventListener("change",M),t.watch(()=>a.mode,()=>{h()},{immediate:!0}),t.watch(()=>u.value.darkMode,(e,n)=>{if(n===void 0){V(e);return}z(()=>{V(e)})},{immediate:!0}),t.onBeforeUnmount(()=>{k.removeEventListener("change",M);const e=i.indexOf(A);e!==-1&&i.splice(e,1),b()});function h(){const e=G();I.value=e,u.value.darkMode=l(e)}function l(e){return e==="dark"?!0:e==="light"?!1:k.matches}function M(e){!e||I.value!=="auto"||(u.value.darkMode=e.matches)}function V(e){document.documentElement.setAttribute("dark-mode",e)}function z(e){if(U.matches){e();return}const n=document.startViewTransition?.bind(document);if(n){n(()=>{e()});return}e();const c=document.documentElement;typeof c.animate=="function"&&window.requestAnimationFrame(()=>{c.animate([{opacity:.85},{opacity:1}],{duration:fe,easing:"ease-in-out"})})}function G(){return a.mode??P()??"auto"}t.provide("theme",u);function q(e){if(!e)return null;const n=e.trim().toLowerCase();if(!/^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i.exec(n))return null;if(n.length===4){const r=n[1],d=n[2],m=n[3];return`#${r}${r}${d}${d}${m}${m}`}return n}function F(e){const n=q(e);if(!n)return null;const c=parseInt(n.slice(1,3),16),r=parseInt(n.slice(3,5),16),d=parseInt(n.slice(5,7),16);return{r:c,g:r,b:d}}function W({r:e,g:n,b:c}){const r=d=>d.toString(16).padStart(2,"0");return`#${r(e)}${r(n)}${r(c)}`}function p(e){return Math.max(0,Math.min(1,e))}function B(e){return e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)}function j(e){const n=p(e);return n<=.0031308?12.92*n:1.055*Math.pow(n,1/2.4)-.055}function J({r:e,g:n,b:c}){const r=e/255,d=n/255,m=c/255,S=B(r),D=B(d),f=B(m),v=.4122214708*S+.5363325363*D+.0514459929*f,w=.2119034982*S+.6806995451*D+.1073969566*f,E=.0883024619*S+.2817188376*D+.6299787005*f,g=Math.cbrt(v),y=Math.cbrt(w),_=Math.cbrt(E),$=.2104542553*g+.793617785*y-.0040720468*_,O=1.9779984951*g-2.428592205*y+.4505937099*_,R=.0259040371*g+.7827717662*y-.808675766*_,C=Math.sqrt(O*O+R*R);let L=Math.atan2(R,O)*(180/Math.PI);return L<0&&(L+=360),{l:$,c:C,h:L}}function H(e,n,c,r=!1){const d=c*Math.PI/180,m=n*Math.cos(d),S=n*Math.sin(d),D=e+.3963377774*m+.2158037573*S,f=e-.1055613458*m-.0638541728*S,v=e-.0894841775*m-1.291485548*S,w=r?p(D):D,E=r?p(f):f,g=r?p(v):v;if(!r&&(w<-1e-4||w>1.0001||E<-1e-4||E>1.0001||g<-1e-4||g>1.0001))return null;const y=w*w*w,_=E*E*E,$=g*g*g;let O=4.0767416621*y-3.3077115913*_+.2309699292*$,R=-1.2684380046*y+2.6097574011*_-.3413193965*$,C=-.0041960863*y-.7034186147*_+1.707614701*$;if(r)O=p(O),R=p(R),C=p(C);else if(O<-1e-4||O>1.0001||R<-1e-4||R>1.0001||C<-1e-4||C>1.0001)return null;const L=p(j(O)),te=p(j(R)),ne=p(j(C));return{r:Math.round(L*255),g:Math.round(te*255),b:Math.round(ne*255)}}function X(e,n,c){let r=n;for(let d=0;d<8;d+=1){const m=H(e,r,c);if(m)return m;r*=.9}return H(e,p(r),c,!0)||{r:0,g:0,b:0}}function Z(e){const n=q(e);if(!n)return null;const c=F(n);if(!c)return null;const r=J(c),d={100:{lightness:.35,chroma:.45},200:{lightness:.28,chroma:.5},300:{lightness:.22,chroma:.6},400:{lightness:.16,chroma:.75},500:{lightness:.08,chroma:.9},600:{lightness:0,chroma:1,base:!0},700:{lightness:-.08,chroma:1.05},800:{lightness:-.18,chroma:1.1},900:{lightness:-.28,chroma:1.15},1e3:{lightness:-.35,chroma:1.2}},m={},S=f=>f===0?r.l:f>0?p(r.l+f*(1-r.l)):p(r.l*(1+f)),D=f=>{if(f===1)return r.c;const v=r.c*f;return Math.max(0,Math.min(.4,v))};return Object.entries(d).forEach(([f,v])=>{const w=`--color-brand-${f}`;if(v.base){m[w]=n;return}const E=S(v.lightness),g=D(v.chroma),y=X(E,g,r.h);m[w]=W(y)}),m}const Y=t.computed(()=>Z(a.accentColor)??{}),ee=t.computed(()=>Y.value),A={vars:{},enabled:!!a.exposeGlobalAccent};return i.push(A),t.watch(()=>a.exposeGlobalAccent,e=>{A.enabled=!!e,b()},{immediate:!0}),t.watch(Y,e=>{e&&Object.keys(e).length>0?A.vars={...e}:A.vars={},b()},{immediate:!0}),(e,n)=>(t.openBlock(),t.createElementBlock("div",{class:"theme",style:t.normalizeStyle(ee.value)},[t.renderSlot(e.$slots,"default")],4))}}),he=(o,a)=>{const i=o.__vccOpts||o;for(const[s,b]of a)i[s]=b;return i},pe={__name:"ThemeSwitcher",props:{mode:{type:String,default:"auto",validator:o=>["auto","light","dark"].includes(o)}},emits:["update:mode"],setup(o,{emit:a}){const s=[{value:"auto",label:"System"},{value:"light",label:"Light"},{value:"dark",label:"Dark"}].reduce((h,l)=>(h[l.value]=l.label,h),{}),b=x,k=o,U=a;Q();const T=t.ref(!1),I=P()??k.mode,u=t.ref(b.includes(I)?I:"auto");return t.computed(()=>s[u.value]??s.auto),t.watch(()=>k.mode,h=>{b.includes(h)&&h!==u.value&&(u.value=h)}),t.watch(u,h=>{if(!b.includes(h)){u.value="auto";return}T.value=!1,U("update:mode",h),ae(h)},{immediate:!0}),(h,l)=>(t.openBlock(),t.createBlock(t.unref(N.DropdownMenu),{open:T.value,"onUpdate:open":l[3]||(l[3]=M=>T.value=M),text:"Theme","aria-label":"Select theme mode"},{default:t.withCtx(()=>[t.createVNode(t.unref(N.DropdownItemGroup),{title:"Theme"},{default:t.withCtx(()=>[t.createVNode(t.unref(N.DropdownItemRadio),{checked:u.value,"onUpdate:checked":l[0]||(l[0]=M=>u.value=M),value:"auto",label:t.unref(s).auto,"aria-label":`${t.unref(s).auto} mode`},null,8,["checked","label","aria-label"]),l[4]||(l[4]=t.createElementVNode("hr",{class:"theme-switcher-divider",role:"separator"},null,-1)),t.createVNode(t.unref(N.DropdownItemRadio),{checked:u.value,"onUpdate:checked":l[1]||(l[1]=M=>u.value=M),value:"light",label:t.unref(s).light,"aria-label":`${t.unref(s).light} mode`},null,8,["checked","label","aria-label"]),t.createVNode(t.unref(N.DropdownItemRadio),{checked:u.value,"onUpdate:checked":l[2]||(l[2]=M=>u.value=M),value:"dark",label:t.unref(s).dark,"aria-label":`${t.unref(s).dark} mode`},null,8,["checked","label","aria-label"])]),_:1})]),_:1},8,["open"]))}},be=he(pe,[["__scopeId","data-v-bcbc87cb"]]);exports.Theme=me;exports.ThemeSwitcher=be;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("vue");require("what-input");const L=require("@gospore/dropdown-menu"),x=["auto","light","dark"],z="gospore-theme-mode",ae=60*60*24*365,se="(prefers-color-scheme: dark)";function B(){if(typeof document>"u")return null;const o=ue(z);return o&&x.includes(o)?o:null}function le(o){if(typeof document>"u"||!x.includes(o))return;const a=typeof window<"u"?window.location.hostname:"",l=typeof window<"u"?window.location.protocol:"",s=ie(a),b=l==="https:",k=["path=/",`max-age=${ae}`,"SameSite=Lax"];s&&k.push(`domain=${s}`),b&&k.push("Secure"),document.cookie=[`${encodeURIComponent(z)}=${encodeURIComponent(o)}`,...k].join("; ")}function F(o){if(typeof document>"u")return;const a=typeof o=="string"&&x.includes(o)?o:B()??"auto";console.log("Applying theme mode:",a);const l=de(a);document.documentElement.setAttribute("dark-mode",l)}function ue(o){if(typeof document>"u"||!document.cookie)return null;const a=`${encodeURIComponent(o)}=`,l=document.cookie.split("; ");for(const s of l)if(s.startsWith(a))return decodeURIComponent(s.slice(a.length));return null}function ie(o){if(!o||o==="localhost")return null;if(/^\d+(?:\.\d+){3}$/.test(o))return o;const l=o.split(".");return l.length<=1?null:l.length===2?o:l.slice(-2).join(".")}function de(o){if(o==="dark")return!0;if(o==="light"||typeof window>"u")return!1;try{const a=typeof window.matchMedia=="function"?window.matchMedia(se):null;return a?a.matches:!1}catch{return!1}}const H=Symbol.for("gospore.theme.portalHost");function fe(){const o=t.inject(H,null);console.log("Using theme portal host:",o);const a=typeof document<"u"?document.body:"body";return t.computed(()=>o?.value??a)}const me="(prefers-color-scheme: dark)",he="(prefers-reduced-motion: reduce)",pe=200,be=Object.assign({name:"Theme"},{__name:"Theme",props:{mode:{type:String,validator:o=>["auto","light","dark"].includes(o)},accentColor:{type:String,required:!1,default:void 0},exposeGlobalAccent:{type:Boolean,default:!1}},setup(o){const a=o,l=[],s=new Set;function b(){const e=document.documentElement;if(!e)return;s.forEach(c=>{e.style.removeProperty(c)}),s.clear();const n=[...l].reverse().find(c=>c.enabled&&c.vars&&Object.keys(c.vars).length>0);n&&Object.entries(n.vars).forEach(([c,r])=>{e.style.setProperty(c,r),s.add(c)})}const k=window.matchMedia(me),U=window.matchMedia(he),_=q();F(_);const I=t.ref(_),u=t.ref({darkMode:M(_)}),h=t.ref(null);k.addEventListener("change",V),t.watch(()=>a.mode,()=>{f()},{immediate:!0}),t.watch(()=>u.value.darkMode,(e,n)=>{if(n===void 0){G(e);return}W(()=>{G(e)})},{immediate:!0}),t.onBeforeUnmount(()=>{k.removeEventListener("change",V);const e=l.indexOf(A);e!==-1&&l.splice(e,1),b()});function f(){const e=q();I.value=e,u.value.darkMode=M(e)}function M(e){return e==="dark"?!0:e==="light"?!1:k.matches}function V(e){!e||I.value!=="auto"||(u.value.darkMode=e.matches)}function G(e){document.documentElement.setAttribute("dark-mode",e)}function W(e){if(U.matches){e();return}const n=document.startViewTransition?.bind(document);if(n){n(()=>{e()});return}e();const c=document.documentElement;typeof c.animate=="function"&&window.requestAnimationFrame(()=>{c.animate([{opacity:.85},{opacity:1}],{duration:pe,easing:"ease-in-out"})})}function q(){return a.mode??B()??"auto"}t.provide("theme",u),t.provide(H,h);function K(e){if(!e)return null;const n=e.trim().toLowerCase();if(!/^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i.exec(n))return null;if(n.length===4){const r=n[1],i=n[2],m=n[3];return`#${r}${r}${i}${i}${m}${m}`}return n}function J(e){const n=K(e);if(!n)return null;const c=parseInt(n.slice(1,3),16),r=parseInt(n.slice(3,5),16),i=parseInt(n.slice(5,7),16);return{r:c,g:r,b:i}}function X({r:e,g:n,b:c}){const r=i=>i.toString(16).padStart(2,"0");return`#${r(e)}${r(n)}${r(c)}`}function p(e){return Math.max(0,Math.min(1,e))}function P(e){return e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)}function j(e){const n=p(e);return n<=.0031308?12.92*n:1.055*Math.pow(n,1/2.4)-.055}function Z({r:e,g:n,b:c}){const r=e/255,i=n/255,m=c/255,y=P(r),R=P(i),d=P(m),v=.4122214708*y+.5363325363*R+.0514459929*d,w=.2119034982*y+.6806995451*R+.1073969566*d,S=.0883024619*y+.2817188376*R+.6299787005*d,g=Math.cbrt(v),E=Math.cbrt(w),D=Math.cbrt(S),$=.2104542553*g+.793617785*E-.0040720468*D,O=1.9779984951*g-2.428592205*E+.4505937099*D,T=.0259040371*g+.7827717662*E-.808675766*D,C=Math.sqrt(O*O+T*T);let N=Math.atan2(T,O)*(180/Math.PI);return N<0&&(N+=360),{l:$,c:C,h:N}}function Y(e,n,c,r=!1){const i=c*Math.PI/180,m=n*Math.cos(i),y=n*Math.sin(i),R=e+.3963377774*m+.2158037573*y,d=e-.1055613458*m-.0638541728*y,v=e-.0894841775*m-1.291485548*y,w=r?p(R):R,S=r?p(d):d,g=r?p(v):v;if(!r&&(w<-1e-4||w>1.0001||S<-1e-4||S>1.0001||g<-1e-4||g>1.0001))return null;const E=w*w*w,D=S*S*S,$=g*g*g;let O=4.0767416621*E-3.3077115913*D+.2309699292*$,T=-1.2684380046*E+2.6097574011*D-.3413193965*$,C=-.0041960863*E-.7034186147*D+1.707614701*$;if(r)O=p(O),T=p(T),C=p(C);else if(O<-1e-4||O>1.0001||T<-1e-4||T>1.0001||C<-1e-4||C>1.0001)return null;const N=p(j(O)),oe=p(j(T)),re=p(j(C));return{r:Math.round(N*255),g:Math.round(oe*255),b:Math.round(re*255)}}function ee(e,n,c){let r=n;for(let i=0;i<8;i+=1){const m=Y(e,r,c);if(m)return m;r*=.9}return Y(e,p(r),c,!0)||{r:0,g:0,b:0}}function te(e){const n=K(e);if(!n)return null;const c=J(n);if(!c)return null;const r=Z(c),i={100:{lightness:.35,chroma:.45},200:{lightness:.28,chroma:.5},300:{lightness:.22,chroma:.6},400:{lightness:.16,chroma:.75},500:{lightness:.08,chroma:.9},600:{lightness:0,chroma:1,base:!0},700:{lightness:-.08,chroma:1.05},800:{lightness:-.18,chroma:1.1},900:{lightness:-.28,chroma:1.15},1e3:{lightness:-.35,chroma:1.2}},m={},y=d=>d===0?r.l:d>0?p(r.l+d*(1-r.l)):p(r.l*(1+d)),R=d=>{if(d===1)return r.c;const v=r.c*d;return Math.max(0,Math.min(.4,v))};return Object.entries(i).forEach(([d,v])=>{const w=`--color-brand-${d}`;if(v.base){m[w]=n;return}const S=y(v.lightness),g=R(v.chroma),E=ee(S,g,r.h);m[w]=X(E)}),m}const Q=t.computed(()=>te(a.accentColor)??{}),ne=t.computed(()=>Q.value),A={vars:{},enabled:!!a.exposeGlobalAccent};return l.push(A),t.watch(()=>a.exposeGlobalAccent,e=>{A.enabled=!!e,b()},{immediate:!0}),t.watch(Q,e=>{e&&Object.keys(e).length>0?A.vars={...e}:A.vars={},b()},{immediate:!0}),(e,n)=>(t.openBlock(),t.createElementBlock("div",{class:"theme",style:t.normalizeStyle(ne.value)},[t.renderSlot(e.$slots,"default"),t.createElementVNode("div",{ref_key:"portalHost",ref:h,class:"theme__portal-host"},null,512)],4))}}),ge=(o,a)=>{const l=o.__vccOpts||o;for(const[s,b]of a)l[s]=b;return l},ke={__name:"ThemeSwitcher",props:{mode:{type:String,default:"auto",validator:o=>["auto","light","dark"].includes(o)}},emits:["update:mode"],setup(o,{emit:a}){const s=[{value:"auto",label:"System"},{value:"light",label:"Light"},{value:"dark",label:"Dark"}].reduce((h,f)=>(h[f.value]=f.label,h),{}),b=x,k=o,U=a;F();const _=t.ref(!1),I=B()??k.mode,u=t.ref(b.includes(I)?I:"auto");return t.computed(()=>s[u.value]??s.auto),t.watch(()=>k.mode,h=>{b.includes(h)&&h!==u.value&&(u.value=h)}),t.watch(u,h=>{if(!b.includes(h)){u.value="auto";return}_.value=!1,U("update:mode",h),le(h)},{immediate:!0}),(h,f)=>(t.openBlock(),t.createBlock(t.unref(L.DropdownMenu),{open:_.value,"onUpdate:open":f[3]||(f[3]=M=>_.value=M),text:"Theme","aria-label":"Select theme mode"},{default:t.withCtx(()=>[t.createVNode(t.unref(L.DropdownItemGroup),{title:"Theme"},{default:t.withCtx(()=>[t.createVNode(t.unref(L.DropdownItemRadio),{checked:u.value,"onUpdate:checked":f[0]||(f[0]=M=>u.value=M),value:"auto",label:t.unref(s).auto,"aria-label":`${t.unref(s).auto} mode`},null,8,["checked","label","aria-label"]),f[4]||(f[4]=t.createElementVNode("hr",{class:"theme-switcher-divider",role:"separator"},null,-1)),t.createVNode(t.unref(L.DropdownItemRadio),{checked:u.value,"onUpdate:checked":f[1]||(f[1]=M=>u.value=M),value:"light",label:t.unref(s).light,"aria-label":`${t.unref(s).light} mode`},null,8,["checked","label","aria-label"]),t.createVNode(t.unref(L.DropdownItemRadio),{checked:u.value,"onUpdate:checked":f[2]||(f[2]=M=>u.value=M),value:"dark",label:t.unref(s).dark,"aria-label":`${t.unref(s).dark} mode`},null,8,["checked","label","aria-label"])]),_:1})]),_:1},8,["open"]))}},Me=ge(ke,[["__scopeId","data-v-bcbc87cb"]]);exports.Theme=be;exports.ThemeSwitcher=Me;exports.themePortalHostKey=H;exports.useThemePortalTarget=fe;
2
2
  //# sourceMappingURL=theme.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"theme.cjs.js","sources":["../src/modeStorage.js","../src/Theme.vue","../src/ThemeSwitcher.vue"],"sourcesContent":["const VALID_THEME_MODES = [\"auto\", \"light\", \"dark\"];\nconst STORAGE_KEY = \"gospore-theme-mode\";\nconst ONE_YEAR_IN_SECONDS = 60 * 60 * 24 * 365;\nconst DARK_MODE_QUERY = \"(prefers-color-scheme: dark)\";\n\nexport function readStoredMode() {\n if (typeof document === \"undefined\") {\n return null;\n }\n const stored = getCookie(STORAGE_KEY);\n return stored && VALID_THEME_MODES.includes(stored) ? stored : null;\n}\n\nexport function writeStoredMode(mode) {\n if (typeof document === \"undefined\" || !VALID_THEME_MODES.includes(mode)) {\n return;\n }\n const hostname =\n typeof window !== \"undefined\" ? window.location.hostname : \"\";\n const protocol =\n typeof window !== \"undefined\" ? window.location.protocol : \"\";\n const domain = getCookieDomain(hostname);\n const secure = protocol === \"https:\";\n const attributes = [\n \"path=/\",\n `max-age=${ONE_YEAR_IN_SECONDS}`,\n \"SameSite=Lax\",\n ];\n if (domain) {\n attributes.push(`domain=${domain}`);\n }\n if (secure) {\n attributes.push(\"Secure\");\n }\n document.cookie = [\n `${encodeURIComponent(STORAGE_KEY)}=${encodeURIComponent(mode)}`,\n ...attributes,\n ].join(\"; \");\n}\n\nexport function applyStoredModeToDocument(mode) {\n if (typeof document === \"undefined\") {\n return;\n }\n const resolvedMode =\n typeof mode === \"string\" && VALID_THEME_MODES.includes(mode)\n ? mode\n : readStoredMode() ?? \"auto\";\n console.log(\"Applying theme mode:\", resolvedMode);\n const darkMode = resolveDarkMode(resolvedMode);\n document.documentElement.setAttribute(\"dark-mode\", darkMode);\n}\n\nexport { VALID_THEME_MODES, STORAGE_KEY };\n\nfunction getCookie(name) {\n if (typeof document === \"undefined\" || !document.cookie) {\n return null;\n }\n const encodedName = `${encodeURIComponent(name)}=`;\n const cookies = document.cookie.split(\"; \");\n for (const cookie of cookies) {\n if (cookie.startsWith(encodedName)) {\n return decodeURIComponent(cookie.slice(encodedName.length));\n }\n }\n return null;\n}\n\nfunction getCookieDomain(hostname) {\n if (!hostname || hostname === \"localhost\") {\n return null;\n }\n const isIpAddress = /^\\d+(?:\\.\\d+){3}$/.test(hostname);\n if (isIpAddress) {\n return hostname;\n }\n const parts = hostname.split(\".\");\n if (parts.length <= 1) {\n return null;\n }\n if (parts.length === 2) {\n return hostname;\n }\n return parts.slice(-2).join(\".\");\n}\n\nfunction resolveDarkMode(mode) {\n if (mode === \"dark\") {\n return true;\n }\n if (mode === \"light\") {\n return false;\n }\n if (typeof window === \"undefined\") {\n return false;\n }\n try {\n const mediaQueryList =\n typeof window.matchMedia === \"function\"\n ? window.matchMedia(DARK_MODE_QUERY)\n : null;\n return mediaQueryList ? mediaQueryList.matches : false;\n } catch (error) {\n return false;\n }\n}\n","<template>\n <div class=\"theme\" :style=\"brandStyle\">\n <slot />\n </div>\n</template>\n\n<script setup>\nimport { provide, ref, watch, onBeforeUnmount, computed } from \"vue\";\nimport { applyStoredModeToDocument, readStoredMode } from \"./modeStorage\";\nimport \"what-input\";\n\ndefineOptions({\n name: \"Theme\",\n});\nconst props = defineProps({\n mode: {\n type: String,\n validator: (value) => [\"auto\", \"light\", \"dark\"].includes(value),\n },\n /**\n * Optional hex accent color (\"#RRGGBB\" or \"#RGB\"). When provided,\n * Theme derives the `--color-brand-*` palette and exposes the tokens on\n * the root .theme element (and the global document for portals).\n */\n accentColor: {\n type: String,\n required: false,\n default: undefined,\n },\n /**\n * When true the brand vars are also exposed on <html>, allowing portals\n * attached outside the Theme subtree to inherit the accent colors.\n */\n exposeGlobalAccent: {\n type: Boolean,\n default: false,\n },\n});\n\nconst globalAccentStack = [];\nconst appliedGlobalAccentKeys = new Set();\n\nfunction applyGlobalAccentFromStack() {\n const root = document.documentElement;\n if (!root) {\n return;\n }\n\n appliedGlobalAccentKeys.forEach((key) => {\n root.style.removeProperty(key);\n });\n appliedGlobalAccentKeys.clear();\n\n const activeEntry = [...globalAccentStack]\n .reverse()\n .find(\n (entry) =>\n entry.enabled &&\n entry.vars &&\n Object.keys(entry.vars).length > 0,\n );\n\n if (!activeEntry) {\n return;\n }\n\n Object.entries(activeEntry.vars).forEach(([key, value]) => {\n root.style.setProperty(key, value);\n appliedGlobalAccentKeys.add(key);\n });\n}\n\nconst DARK_MODE_QUERY = \"(prefers-color-scheme: dark)\";\nconst PREFERS_REDUCED_MOTION_QUERY = \"(prefers-reduced-motion: reduce)\";\nconst THEME_TRANSITION_DURATION = 200;\nconst darkModeMedia = window.matchMedia(DARK_MODE_QUERY);\nconst prefersReducedMotionMedia = window.matchMedia(\n PREFERS_REDUCED_MOTION_QUERY,\n);\n\nconst initialMode = getEffectiveMode();\napplyStoredModeToDocument(initialMode);\n\nconst currentMode = ref(initialMode);\n\nconst theme = ref({\n darkMode: resolveDarkMode(initialMode),\n});\n\ndarkModeMedia.addEventListener(\"change\", handleSystemPreferenceChange);\n\nwatch(\n () => props.mode,\n () => {\n syncDarkMode();\n },\n { immediate: true },\n);\n\nwatch(\n () => theme.value.darkMode,\n (darkMode, previousValue) => {\n if (previousValue === undefined) {\n setDocumentDarkModeAttribute(darkMode);\n return;\n }\n withThemeTransition(() => {\n setDocumentDarkModeAttribute(darkMode);\n });\n },\n { immediate: true },\n);\n\nonBeforeUnmount(() => {\n darkModeMedia.removeEventListener(\"change\", handleSystemPreferenceChange);\n const index = globalAccentStack.indexOf(accentStackEntry);\n if (index !== -1) {\n globalAccentStack.splice(index, 1);\n }\n applyGlobalAccentFromStack();\n});\n\nfunction syncDarkMode() {\n const mode = getEffectiveMode();\n currentMode.value = mode;\n theme.value.darkMode = resolveDarkMode(mode);\n}\n\nfunction resolveDarkMode(mode) {\n if (mode === \"dark\") {\n return true;\n }\n if (mode === \"light\") {\n return false;\n }\n return darkModeMedia.matches;\n}\n\nfunction handleSystemPreferenceChange(event) {\n if (!event || currentMode.value !== \"auto\") {\n return;\n }\n theme.value.darkMode = event.matches;\n}\n\nfunction setDocumentDarkModeAttribute(darkMode) {\n document.documentElement.setAttribute(\"dark-mode\", darkMode);\n}\n\nfunction withThemeTransition(applyTheme) {\n if (prefersReducedMotionMedia.matches) {\n applyTheme();\n return;\n }\n const startViewTransition = document.startViewTransition?.bind(document);\n if (startViewTransition) {\n startViewTransition(() => {\n applyTheme();\n });\n return;\n }\n applyTheme();\n const element = document.documentElement;\n if (typeof element.animate !== \"function\") {\n return;\n }\n window.requestAnimationFrame(() => {\n element.animate([{ opacity: 0.85 }, { opacity: 1 }], {\n duration: THEME_TRANSITION_DURATION,\n easing: \"ease-in-out\",\n });\n });\n}\n\nfunction getEffectiveMode() {\n return props.mode ?? readStoredMode() ?? \"auto\";\n}\n\nprovide(\"theme\", theme);\n\n// --- Accent helpers -------------------------------------------------------\nfunction normalizeHex(hex) {\n if (!hex) return null;\n const h = hex.trim().toLowerCase();\n const m = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i.exec(h);\n if (!m) return null;\n if (h.length === 4) {\n // expand #rgb -> #rrggbb\n const r = h[1],\n g = h[2],\n b = h[3];\n return `#${r}${r}${g}${g}${b}${b}`;\n }\n return h;\n}\n\nfunction hexToRgb(hex) {\n const h = normalizeHex(hex);\n if (!h) return null;\n const r = parseInt(h.slice(1, 3), 16);\n const g = parseInt(h.slice(3, 5), 16);\n const b = parseInt(h.slice(5, 7), 16);\n return { r, g, b };\n}\n\nfunction rgbToHex({ r, g, b }) {\n const toHex = (value) => value.toString(16).padStart(2, \"0\");\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`;\n}\n\nfunction clamp01(value) {\n return Math.max(0, Math.min(1, value));\n}\n\nfunction srgbChannelToLinear(channel) {\n if (channel <= 0.04045) {\n return channel / 12.92;\n }\n return Math.pow((channel + 0.055) / 1.055, 2.4);\n}\n\nfunction linearChannelToSrgb(channel) {\n const normalized = clamp01(channel);\n if (normalized <= 0.0031308) {\n return 12.92 * normalized;\n }\n return 1.055 * Math.pow(normalized, 1 / 2.4) - 0.055;\n}\n\nfunction rgbToOklch({ r, g, b }) {\n const rNorm = r / 255;\n const gNorm = g / 255;\n const bNorm = b / 255;\n\n const rLin = srgbChannelToLinear(rNorm);\n const gLin = srgbChannelToLinear(gNorm);\n const bLin = srgbChannelToLinear(bNorm);\n\n const l = 0.4122214708 * rLin + 0.5363325363 * gLin + 0.0514459929 * bLin;\n const m = 0.2119034982 * rLin + 0.6806995451 * gLin + 0.1073969566 * bLin;\n const s = 0.0883024619 * rLin + 0.2817188376 * gLin + 0.6299787005 * bLin;\n\n const lRoot = Math.cbrt(l);\n const mRoot = Math.cbrt(m);\n const sRoot = Math.cbrt(s);\n\n const oklabL =\n 0.2104542553 * lRoot + 0.793617785 * mRoot - 0.0040720468 * sRoot;\n const oklabA =\n 1.9779984951 * lRoot - 2.428592205 * mRoot + 0.4505937099 * sRoot;\n const oklabB =\n 0.0259040371 * lRoot + 0.7827717662 * mRoot - 0.808675766 * sRoot;\n\n const chroma = Math.sqrt(oklabA * oklabA + oklabB * oklabB);\n let hue = Math.atan2(oklabB, oklabA) * (180 / Math.PI);\n if (hue < 0) {\n hue += 360;\n }\n\n return { l: oklabL, c: chroma, h: hue };\n}\n\nfunction tryOklchToSrgb(l, c, h, clampLinear = false) {\n const angle = (h * Math.PI) / 180;\n const a = c * Math.cos(angle);\n const b = c * Math.sin(angle);\n\n const lComponent = l + 0.3963377774 * a + 0.2158037573 * b;\n const mComponent = l - 0.1055613458 * a - 0.0638541728 * b;\n const sComponent = l - 0.0894841775 * a - 1.291485548 * b;\n\n const lCube = clampLinear ? clamp01(lComponent) : lComponent;\n const mCube = clampLinear ? clamp01(mComponent) : mComponent;\n const sCube = clampLinear ? clamp01(sComponent) : sComponent;\n\n if (!clampLinear) {\n const outOfRange =\n lCube < -0.0001 ||\n lCube > 1.0001 ||\n mCube < -0.0001 ||\n mCube > 1.0001 ||\n sCube < -0.0001 ||\n sCube > 1.0001;\n if (outOfRange) {\n return null;\n }\n }\n\n const lLin = lCube * lCube * lCube;\n const mLin = mCube * mCube * mCube;\n const sLin = sCube * sCube * sCube;\n\n let rLin = 4.0767416621 * lLin - 3.3077115913 * mLin + 0.2309699292 * sLin;\n let gLin = -1.2684380046 * lLin + 2.6097574011 * mLin - 0.3413193965 * sLin;\n let bLin = -0.0041960863 * lLin - 0.7034186147 * mLin + 1.707614701 * sLin;\n\n if (clampLinear) {\n rLin = clamp01(rLin);\n gLin = clamp01(gLin);\n bLin = clamp01(bLin);\n } else {\n const outOfRange =\n rLin < -0.0001 ||\n rLin > 1.0001 ||\n gLin < -0.0001 ||\n gLin > 1.0001 ||\n bLin < -0.0001 ||\n bLin > 1.0001;\n if (outOfRange) {\n return null;\n }\n }\n\n const r = clamp01(linearChannelToSrgb(rLin));\n const g = clamp01(linearChannelToSrgb(gLin));\n const bValue = clamp01(linearChannelToSrgb(bLin));\n\n return {\n r: Math.round(r * 255),\n g: Math.round(g * 255),\n b: Math.round(bValue * 255),\n };\n}\n\nfunction oklchToSrgb(l, c, h) {\n let chroma = c;\n for (let attempt = 0; attempt < 8; attempt += 1) {\n const rgb = tryOklchToSrgb(l, chroma, h);\n if (rgb) {\n return rgb;\n }\n chroma *= 0.9;\n }\n return tryOklchToSrgb(l, clamp01(chroma), h, true) || { r: 0, g: 0, b: 0 };\n}\n\nfunction makeBrandScale(baseHex) {\n const norm = normalizeHex(baseHex);\n if (!norm) return null;\n const baseRgb = hexToRgb(norm);\n if (!baseRgb) return null;\n const baseOklch = rgbToOklch(baseRgb);\n const toneConfig = {\n 100: { lightness: 0.35, chroma: 0.45 },\n 200: { lightness: 0.28, chroma: 0.5 },\n 300: { lightness: 0.22, chroma: 0.6 },\n 400: { lightness: 0.16, chroma: 0.75 },\n 500: { lightness: 0.08, chroma: 0.9 },\n 600: { lightness: 0, chroma: 1, base: true },\n 700: { lightness: -0.08, chroma: 1.05 },\n 800: { lightness: -0.18, chroma: 1.1 },\n 900: { lightness: -0.28, chroma: 1.15 },\n 1000: { lightness: -0.35, chroma: 1.2 },\n };\n const tokens = {};\n\n const adjustLightness = (lightnessValue) => {\n if (lightnessValue === 0) {\n return baseOklch.l;\n }\n if (lightnessValue > 0) {\n return clamp01(baseOklch.l + lightnessValue * (1 - baseOklch.l));\n }\n return clamp01(baseOklch.l * (1 + lightnessValue));\n };\n\n const adjustChroma = (chromaScale) => {\n if (chromaScale === 1) {\n return baseOklch.c;\n }\n const scaled = baseOklch.c * chromaScale;\n return Math.max(0, Math.min(0.4, scaled));\n };\n\n Object.entries(toneConfig).forEach(([stop, config]) => {\n const tokenName = `--color-brand-${stop}`;\n if (config.base) {\n tokens[tokenName] = norm;\n return;\n }\n const toneL = adjustLightness(config.lightness);\n const toneC = adjustChroma(config.chroma);\n const toneRgb = oklchToSrgb(toneL, toneC, baseOklch.h);\n tokens[tokenName] = rgbToHex(toneRgb);\n });\n return tokens;\n}\n\nconst brandVars = computed(() => makeBrandScale(props.accentColor) ?? {});\nconst brandStyle = computed(() => brandVars.value);\n\nconst accentStackEntry = {\n vars: {},\n enabled: Boolean(props.exposeGlobalAccent),\n};\nglobalAccentStack.push(accentStackEntry);\n\nwatch(\n () => props.exposeGlobalAccent,\n (enabled) => {\n accentStackEntry.enabled = Boolean(enabled);\n applyGlobalAccentFromStack();\n },\n { immediate: true },\n);\n\nwatch(\n brandVars,\n (vars) => {\n if (vars && Object.keys(vars).length > 0) {\n accentStackEntry.vars = { ...vars };\n } else {\n accentStackEntry.vars = {};\n }\n applyGlobalAccentFromStack();\n },\n { immediate: true },\n);\n</script>\n\n<style lang=\"less\">\n@import \"index.less\";\n</style>\n","<template>\n <DropdownMenu\n v-model:open=\"open\"\n text=\"Theme\"\n aria-label=\"Select theme mode\"\n >\n <DropdownItemGroup title=\"Theme\">\n <DropdownItemRadio\n v-model:checked=\"internalMode\"\n value=\"auto\"\n :label=\"MODE_LABELS.auto\"\n :aria-label=\"`${MODE_LABELS.auto} mode`\"\n />\n <hr class=\"theme-switcher-divider\" role=\"separator\" />\n <DropdownItemRadio\n v-model:checked=\"internalMode\"\n value=\"light\"\n :label=\"MODE_LABELS.light\"\n :aria-label=\"`${MODE_LABELS.light} mode`\"\n />\n <DropdownItemRadio\n v-model:checked=\"internalMode\"\n value=\"dark\"\n :label=\"MODE_LABELS.dark\"\n :aria-label=\"`${MODE_LABELS.dark} mode`\"\n />\n </DropdownItemGroup>\n </DropdownMenu>\n</template>\n\n<script setup>\nimport { ref, computed, watch } from \"vue\";\nimport {\n DropdownMenu,\n DropdownItemGroup,\n DropdownItemRadio,\n} from \"@gospore/dropdown-menu\";\nimport {\n readStoredMode,\n writeStoredMode,\n VALID_THEME_MODES,\n applyStoredModeToDocument,\n} from \"./modeStorage\";\n\nconst MODE_OPTIONS = [\n { value: \"auto\", label: \"System\" },\n { value: \"light\", label: \"Light\" },\n { value: \"dark\", label: \"Dark\" },\n];\nconst MODE_LABELS = MODE_OPTIONS.reduce((map, option) => {\n map[option.value] = option.label;\n return map;\n}, {});\nconst VALID_MODES = VALID_THEME_MODES;\n\nconst props = defineProps({\n mode: {\n type: String,\n default: \"auto\",\n validator: (value) => [\"auto\", \"light\", \"dark\"].includes(value),\n },\n});\nconst emit = defineEmits([\"update:mode\"]);\n\napplyStoredModeToDocument();\n\nconst open = ref(false);\nconst initialMode = readStoredMode() ?? props.mode;\nconst internalMode = ref(\n VALID_MODES.includes(initialMode) ? initialMode : \"auto\",\n);\nconst label = computed(\n () => MODE_LABELS[internalMode.value] ?? MODE_LABELS.auto,\n);\n\nwatch(\n () => props.mode,\n (mode) => {\n if (VALID_MODES.includes(mode) && mode !== internalMode.value) {\n internalMode.value = mode;\n }\n },\n);\n\nwatch(\n internalMode,\n (mode) => {\n if (!VALID_MODES.includes(mode)) {\n internalMode.value = \"auto\";\n return;\n }\n open.value = false;\n emit(\"update:mode\", mode);\n writeStoredMode(mode);\n },\n { immediate: true },\n);\n</script>\n\n<style scoped lang=\"less\">\n.theme-switcher-divider {\n margin: 4px 0;\n}\n</style>\n"],"names":["VALID_THEME_MODES","STORAGE_KEY","ONE_YEAR_IN_SECONDS","DARK_MODE_QUERY","readStoredMode","stored","getCookie","writeStoredMode","mode","hostname","protocol","domain","getCookieDomain","secure","attributes","applyStoredModeToDocument","resolvedMode","darkMode","resolveDarkMode","name","encodedName","cookies","cookie","parts","mediaQueryList","props","__props","globalAccentStack","appliedGlobalAccentKeys","applyGlobalAccentFromStack","root","key","activeEntry","entry","value","darkModeMedia","prefersReducedMotionMedia","PREFERS_REDUCED_MOTION_QUERY","initialMode","getEffectiveMode","currentMode","ref","theme","handleSystemPreferenceChange","watch","syncDarkMode","previousValue","setDocumentDarkModeAttribute","withThemeTransition","onBeforeUnmount","index","accentStackEntry","event","applyTheme","startViewTransition","element","THEME_TRANSITION_DURATION","provide","normalizeHex","hex","h","g","b","hexToRgb","r","rgbToHex","toHex","clamp01","srgbChannelToLinear","channel","linearChannelToSrgb","normalized","rgbToOklch","rNorm","gNorm","bNorm","rLin","gLin","bLin","l","m","s","lRoot","mRoot","sRoot","oklabL","oklabA","oklabB","chroma","hue","tryOklchToSrgb","c","clampLinear","angle","a","lComponent","mComponent","sComponent","lCube","mCube","sCube","lLin","mLin","sLin","bValue","oklchToSrgb","attempt","rgb","makeBrandScale","baseHex","norm","baseRgb","baseOklch","toneConfig","tokens","adjustLightness","lightnessValue","adjustChroma","chromaScale","scaled","stop","config","tokenName","toneL","toneC","toneRgb","brandVars","computed","brandStyle","enabled","vars","_createElementBlock","_renderSlot","_ctx","MODE_LABELS","map","option","VALID_MODES","emit","__emit","open","internalMode","_createBlock","_unref","DropdownMenu","$event","_createVNode","DropdownItemGroup","DropdownItemRadio","_createElementVNode"],"mappings":"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"}
1
+ {"version":3,"file":"theme.cjs.js","sources":["../src/modeStorage.js","../src/portalHost.js","../src/Theme.vue","../src/ThemeSwitcher.vue"],"sourcesContent":["const VALID_THEME_MODES = [\"auto\", \"light\", \"dark\"];\nconst STORAGE_KEY = \"gospore-theme-mode\";\nconst ONE_YEAR_IN_SECONDS = 60 * 60 * 24 * 365;\nconst DARK_MODE_QUERY = \"(prefers-color-scheme: dark)\";\n\nexport function readStoredMode() {\n if (typeof document === \"undefined\") {\n return null;\n }\n const stored = getCookie(STORAGE_KEY);\n return stored && VALID_THEME_MODES.includes(stored) ? stored : null;\n}\n\nexport function writeStoredMode(mode) {\n if (typeof document === \"undefined\" || !VALID_THEME_MODES.includes(mode)) {\n return;\n }\n const hostname =\n typeof window !== \"undefined\" ? window.location.hostname : \"\";\n const protocol =\n typeof window !== \"undefined\" ? window.location.protocol : \"\";\n const domain = getCookieDomain(hostname);\n const secure = protocol === \"https:\";\n const attributes = [\n \"path=/\",\n `max-age=${ONE_YEAR_IN_SECONDS}`,\n \"SameSite=Lax\",\n ];\n if (domain) {\n attributes.push(`domain=${domain}`);\n }\n if (secure) {\n attributes.push(\"Secure\");\n }\n document.cookie = [\n `${encodeURIComponent(STORAGE_KEY)}=${encodeURIComponent(mode)}`,\n ...attributes,\n ].join(\"; \");\n}\n\nexport function applyStoredModeToDocument(mode) {\n if (typeof document === \"undefined\") {\n return;\n }\n const resolvedMode =\n typeof mode === \"string\" && VALID_THEME_MODES.includes(mode)\n ? mode\n : readStoredMode() ?? \"auto\";\n console.log(\"Applying theme mode:\", resolvedMode);\n const darkMode = resolveDarkMode(resolvedMode);\n document.documentElement.setAttribute(\"dark-mode\", darkMode);\n}\n\nexport { VALID_THEME_MODES, STORAGE_KEY };\n\nfunction getCookie(name) {\n if (typeof document === \"undefined\" || !document.cookie) {\n return null;\n }\n const encodedName = `${encodeURIComponent(name)}=`;\n const cookies = document.cookie.split(\"; \");\n for (const cookie of cookies) {\n if (cookie.startsWith(encodedName)) {\n return decodeURIComponent(cookie.slice(encodedName.length));\n }\n }\n return null;\n}\n\nfunction getCookieDomain(hostname) {\n if (!hostname || hostname === \"localhost\") {\n return null;\n }\n const isIpAddress = /^\\d+(?:\\.\\d+){3}$/.test(hostname);\n if (isIpAddress) {\n return hostname;\n }\n const parts = hostname.split(\".\");\n if (parts.length <= 1) {\n return null;\n }\n if (parts.length === 2) {\n return hostname;\n }\n return parts.slice(-2).join(\".\");\n}\n\nfunction resolveDarkMode(mode) {\n if (mode === \"dark\") {\n return true;\n }\n if (mode === \"light\") {\n return false;\n }\n if (typeof window === \"undefined\") {\n return false;\n }\n try {\n const mediaQueryList =\n typeof window.matchMedia === \"function\"\n ? window.matchMedia(DARK_MODE_QUERY)\n : null;\n return mediaQueryList ? mediaQueryList.matches : false;\n } catch (error) {\n return false;\n }\n}\n","import { computed, inject } from \"vue\";\n\nexport const themePortalHostKey = Symbol.for(\"gospore.theme.portalHost\");\n\nexport function useThemePortalTarget() {\n const hostRef = inject(themePortalHostKey, null);\n console.log(\"Using theme portal host:\", hostRef);\n const fallbackTarget =\n typeof document !== \"undefined\" ? document.body : \"body\";\n\n return computed(() => hostRef?.value ?? fallbackTarget);\n}\n","<template>\n <div class=\"theme\" :style=\"brandStyle\">\n <slot />\n <div ref=\"portalHost\" class=\"theme__portal-host\"></div>\n </div>\n</template>\n\n<script setup>\nimport { provide, ref, watch, onBeforeUnmount, computed } from \"vue\";\nimport { applyStoredModeToDocument, readStoredMode } from \"./modeStorage\";\nimport \"what-input\";\nimport { themePortalHostKey } from \"./portalHost\";\n\ndefineOptions({\n name: \"Theme\",\n});\nconst props = defineProps({\n mode: {\n type: String,\n validator: (value) => [\"auto\", \"light\", \"dark\"].includes(value),\n },\n /**\n * Optional hex accent color (\"#RRGGBB\" or \"#RGB\"). When provided,\n * Theme derives the `--color-brand-*` palette and exposes the tokens on\n * the root .theme element (and the global document for portals).\n */\n accentColor: {\n type: String,\n required: false,\n default: undefined,\n },\n /**\n * When true the brand vars are also exposed on <html>, allowing portals\n * attached outside the Theme subtree to inherit the accent colors.\n */\n exposeGlobalAccent: {\n type: Boolean,\n default: false,\n },\n});\n\nconst globalAccentStack = [];\nconst appliedGlobalAccentKeys = new Set();\n\nfunction applyGlobalAccentFromStack() {\n const root = document.documentElement;\n if (!root) {\n return;\n }\n\n appliedGlobalAccentKeys.forEach((key) => {\n root.style.removeProperty(key);\n });\n appliedGlobalAccentKeys.clear();\n\n const activeEntry = [...globalAccentStack]\n .reverse()\n .find(\n (entry) =>\n entry.enabled &&\n entry.vars &&\n Object.keys(entry.vars).length > 0,\n );\n\n if (!activeEntry) {\n return;\n }\n\n Object.entries(activeEntry.vars).forEach(([key, value]) => {\n root.style.setProperty(key, value);\n appliedGlobalAccentKeys.add(key);\n });\n}\n\nconst DARK_MODE_QUERY = \"(prefers-color-scheme: dark)\";\nconst PREFERS_REDUCED_MOTION_QUERY = \"(prefers-reduced-motion: reduce)\";\nconst THEME_TRANSITION_DURATION = 200;\nconst darkModeMedia = window.matchMedia(DARK_MODE_QUERY);\nconst prefersReducedMotionMedia = window.matchMedia(\n PREFERS_REDUCED_MOTION_QUERY,\n);\n\nconst initialMode = getEffectiveMode();\napplyStoredModeToDocument(initialMode);\n\nconst currentMode = ref(initialMode);\n\nconst theme = ref({\n darkMode: resolveDarkMode(initialMode),\n});\nconst portalHost = ref(null);\n\ndarkModeMedia.addEventListener(\"change\", handleSystemPreferenceChange);\n\nwatch(\n () => props.mode,\n () => {\n syncDarkMode();\n },\n { immediate: true },\n);\n\nwatch(\n () => theme.value.darkMode,\n (darkMode, previousValue) => {\n if (previousValue === undefined) {\n setDocumentDarkModeAttribute(darkMode);\n return;\n }\n withThemeTransition(() => {\n setDocumentDarkModeAttribute(darkMode);\n });\n },\n { immediate: true },\n);\n\nonBeforeUnmount(() => {\n darkModeMedia.removeEventListener(\"change\", handleSystemPreferenceChange);\n const index = globalAccentStack.indexOf(accentStackEntry);\n if (index !== -1) {\n globalAccentStack.splice(index, 1);\n }\n applyGlobalAccentFromStack();\n});\n\nfunction syncDarkMode() {\n const mode = getEffectiveMode();\n currentMode.value = mode;\n theme.value.darkMode = resolveDarkMode(mode);\n}\n\nfunction resolveDarkMode(mode) {\n if (mode === \"dark\") {\n return true;\n }\n if (mode === \"light\") {\n return false;\n }\n return darkModeMedia.matches;\n}\n\nfunction handleSystemPreferenceChange(event) {\n if (!event || currentMode.value !== \"auto\") {\n return;\n }\n theme.value.darkMode = event.matches;\n}\n\nfunction setDocumentDarkModeAttribute(darkMode) {\n document.documentElement.setAttribute(\"dark-mode\", darkMode);\n}\n\nfunction withThemeTransition(applyTheme) {\n if (prefersReducedMotionMedia.matches) {\n applyTheme();\n return;\n }\n const startViewTransition = document.startViewTransition?.bind(document);\n if (startViewTransition) {\n startViewTransition(() => {\n applyTheme();\n });\n return;\n }\n applyTheme();\n const element = document.documentElement;\n if (typeof element.animate !== \"function\") {\n return;\n }\n window.requestAnimationFrame(() => {\n element.animate([{ opacity: 0.85 }, { opacity: 1 }], {\n duration: THEME_TRANSITION_DURATION,\n easing: \"ease-in-out\",\n });\n });\n}\n\nfunction getEffectiveMode() {\n return props.mode ?? readStoredMode() ?? \"auto\";\n}\n\nprovide(\"theme\", theme);\nprovide(themePortalHostKey, portalHost);\n\n// --- Accent helpers -------------------------------------------------------\nfunction normalizeHex(hex) {\n if (!hex) return null;\n const h = hex.trim().toLowerCase();\n const m = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i.exec(h);\n if (!m) return null;\n if (h.length === 4) {\n // expand #rgb -> #rrggbb\n const r = h[1],\n g = h[2],\n b = h[3];\n return `#${r}${r}${g}${g}${b}${b}`;\n }\n return h;\n}\n\nfunction hexToRgb(hex) {\n const h = normalizeHex(hex);\n if (!h) return null;\n const r = parseInt(h.slice(1, 3), 16);\n const g = parseInt(h.slice(3, 5), 16);\n const b = parseInt(h.slice(5, 7), 16);\n return { r, g, b };\n}\n\nfunction rgbToHex({ r, g, b }) {\n const toHex = (value) => value.toString(16).padStart(2, \"0\");\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`;\n}\n\nfunction clamp01(value) {\n return Math.max(0, Math.min(1, value));\n}\n\nfunction srgbChannelToLinear(channel) {\n if (channel <= 0.04045) {\n return channel / 12.92;\n }\n return Math.pow((channel + 0.055) / 1.055, 2.4);\n}\n\nfunction linearChannelToSrgb(channel) {\n const normalized = clamp01(channel);\n if (normalized <= 0.0031308) {\n return 12.92 * normalized;\n }\n return 1.055 * Math.pow(normalized, 1 / 2.4) - 0.055;\n}\n\nfunction rgbToOklch({ r, g, b }) {\n const rNorm = r / 255;\n const gNorm = g / 255;\n const bNorm = b / 255;\n\n const rLin = srgbChannelToLinear(rNorm);\n const gLin = srgbChannelToLinear(gNorm);\n const bLin = srgbChannelToLinear(bNorm);\n\n const l = 0.4122214708 * rLin + 0.5363325363 * gLin + 0.0514459929 * bLin;\n const m = 0.2119034982 * rLin + 0.6806995451 * gLin + 0.1073969566 * bLin;\n const s = 0.0883024619 * rLin + 0.2817188376 * gLin + 0.6299787005 * bLin;\n\n const lRoot = Math.cbrt(l);\n const mRoot = Math.cbrt(m);\n const sRoot = Math.cbrt(s);\n\n const oklabL =\n 0.2104542553 * lRoot + 0.793617785 * mRoot - 0.0040720468 * sRoot;\n const oklabA =\n 1.9779984951 * lRoot - 2.428592205 * mRoot + 0.4505937099 * sRoot;\n const oklabB =\n 0.0259040371 * lRoot + 0.7827717662 * mRoot - 0.808675766 * sRoot;\n\n const chroma = Math.sqrt(oklabA * oklabA + oklabB * oklabB);\n let hue = Math.atan2(oklabB, oklabA) * (180 / Math.PI);\n if (hue < 0) {\n hue += 360;\n }\n\n return { l: oklabL, c: chroma, h: hue };\n}\n\nfunction tryOklchToSrgb(l, c, h, clampLinear = false) {\n const angle = (h * Math.PI) / 180;\n const a = c * Math.cos(angle);\n const b = c * Math.sin(angle);\n\n const lComponent = l + 0.3963377774 * a + 0.2158037573 * b;\n const mComponent = l - 0.1055613458 * a - 0.0638541728 * b;\n const sComponent = l - 0.0894841775 * a - 1.291485548 * b;\n\n const lCube = clampLinear ? clamp01(lComponent) : lComponent;\n const mCube = clampLinear ? clamp01(mComponent) : mComponent;\n const sCube = clampLinear ? clamp01(sComponent) : sComponent;\n\n if (!clampLinear) {\n const outOfRange =\n lCube < -0.0001 ||\n lCube > 1.0001 ||\n mCube < -0.0001 ||\n mCube > 1.0001 ||\n sCube < -0.0001 ||\n sCube > 1.0001;\n if (outOfRange) {\n return null;\n }\n }\n\n const lLin = lCube * lCube * lCube;\n const mLin = mCube * mCube * mCube;\n const sLin = sCube * sCube * sCube;\n\n let rLin = 4.0767416621 * lLin - 3.3077115913 * mLin + 0.2309699292 * sLin;\n let gLin = -1.2684380046 * lLin + 2.6097574011 * mLin - 0.3413193965 * sLin;\n let bLin = -0.0041960863 * lLin - 0.7034186147 * mLin + 1.707614701 * sLin;\n\n if (clampLinear) {\n rLin = clamp01(rLin);\n gLin = clamp01(gLin);\n bLin = clamp01(bLin);\n } else {\n const outOfRange =\n rLin < -0.0001 ||\n rLin > 1.0001 ||\n gLin < -0.0001 ||\n gLin > 1.0001 ||\n bLin < -0.0001 ||\n bLin > 1.0001;\n if (outOfRange) {\n return null;\n }\n }\n\n const r = clamp01(linearChannelToSrgb(rLin));\n const g = clamp01(linearChannelToSrgb(gLin));\n const bValue = clamp01(linearChannelToSrgb(bLin));\n\n return {\n r: Math.round(r * 255),\n g: Math.round(g * 255),\n b: Math.round(bValue * 255),\n };\n}\n\nfunction oklchToSrgb(l, c, h) {\n let chroma = c;\n for (let attempt = 0; attempt < 8; attempt += 1) {\n const rgb = tryOklchToSrgb(l, chroma, h);\n if (rgb) {\n return rgb;\n }\n chroma *= 0.9;\n }\n return tryOklchToSrgb(l, clamp01(chroma), h, true) || { r: 0, g: 0, b: 0 };\n}\n\nfunction makeBrandScale(baseHex) {\n const norm = normalizeHex(baseHex);\n if (!norm) return null;\n const baseRgb = hexToRgb(norm);\n if (!baseRgb) return null;\n const baseOklch = rgbToOklch(baseRgb);\n const toneConfig = {\n 100: { lightness: 0.35, chroma: 0.45 },\n 200: { lightness: 0.28, chroma: 0.5 },\n 300: { lightness: 0.22, chroma: 0.6 },\n 400: { lightness: 0.16, chroma: 0.75 },\n 500: { lightness: 0.08, chroma: 0.9 },\n 600: { lightness: 0, chroma: 1, base: true },\n 700: { lightness: -0.08, chroma: 1.05 },\n 800: { lightness: -0.18, chroma: 1.1 },\n 900: { lightness: -0.28, chroma: 1.15 },\n 1000: { lightness: -0.35, chroma: 1.2 },\n };\n const tokens = {};\n\n const adjustLightness = (lightnessValue) => {\n if (lightnessValue === 0) {\n return baseOklch.l;\n }\n if (lightnessValue > 0) {\n return clamp01(baseOklch.l + lightnessValue * (1 - baseOklch.l));\n }\n return clamp01(baseOklch.l * (1 + lightnessValue));\n };\n\n const adjustChroma = (chromaScale) => {\n if (chromaScale === 1) {\n return baseOklch.c;\n }\n const scaled = baseOklch.c * chromaScale;\n return Math.max(0, Math.min(0.4, scaled));\n };\n\n Object.entries(toneConfig).forEach(([stop, config]) => {\n const tokenName = `--color-brand-${stop}`;\n if (config.base) {\n tokens[tokenName] = norm;\n return;\n }\n const toneL = adjustLightness(config.lightness);\n const toneC = adjustChroma(config.chroma);\n const toneRgb = oklchToSrgb(toneL, toneC, baseOklch.h);\n tokens[tokenName] = rgbToHex(toneRgb);\n });\n return tokens;\n}\n\nconst brandVars = computed(() => makeBrandScale(props.accentColor) ?? {});\nconst brandStyle = computed(() => brandVars.value);\n\nconst accentStackEntry = {\n vars: {},\n enabled: Boolean(props.exposeGlobalAccent),\n};\nglobalAccentStack.push(accentStackEntry);\n\nwatch(\n () => props.exposeGlobalAccent,\n (enabled) => {\n accentStackEntry.enabled = Boolean(enabled);\n applyGlobalAccentFromStack();\n },\n { immediate: true },\n);\n\nwatch(\n brandVars,\n (vars) => {\n if (vars && Object.keys(vars).length > 0) {\n accentStackEntry.vars = { ...vars };\n } else {\n accentStackEntry.vars = {};\n }\n applyGlobalAccentFromStack();\n },\n { immediate: true },\n);\n</script>\n\n<style lang=\"less\">\n@import \"index.less\";\n</style>\n","<template>\n <DropdownMenu\n v-model:open=\"open\"\n text=\"Theme\"\n aria-label=\"Select theme mode\"\n >\n <DropdownItemGroup title=\"Theme\">\n <DropdownItemRadio\n v-model:checked=\"internalMode\"\n value=\"auto\"\n :label=\"MODE_LABELS.auto\"\n :aria-label=\"`${MODE_LABELS.auto} mode`\"\n />\n <hr class=\"theme-switcher-divider\" role=\"separator\" />\n <DropdownItemRadio\n v-model:checked=\"internalMode\"\n value=\"light\"\n :label=\"MODE_LABELS.light\"\n :aria-label=\"`${MODE_LABELS.light} mode`\"\n />\n <DropdownItemRadio\n v-model:checked=\"internalMode\"\n value=\"dark\"\n :label=\"MODE_LABELS.dark\"\n :aria-label=\"`${MODE_LABELS.dark} mode`\"\n />\n </DropdownItemGroup>\n </DropdownMenu>\n</template>\n\n<script setup>\nimport { ref, computed, watch } from \"vue\";\nimport {\n DropdownMenu,\n DropdownItemGroup,\n DropdownItemRadio,\n} from \"@gospore/dropdown-menu\";\nimport {\n readStoredMode,\n writeStoredMode,\n VALID_THEME_MODES,\n applyStoredModeToDocument,\n} from \"./modeStorage\";\n\nconst MODE_OPTIONS = [\n { value: \"auto\", label: \"System\" },\n { value: \"light\", label: \"Light\" },\n { value: \"dark\", label: \"Dark\" },\n];\nconst MODE_LABELS = MODE_OPTIONS.reduce((map, option) => {\n map[option.value] = option.label;\n return map;\n}, {});\nconst VALID_MODES = VALID_THEME_MODES;\n\nconst props = defineProps({\n mode: {\n type: String,\n default: \"auto\",\n validator: (value) => [\"auto\", \"light\", \"dark\"].includes(value),\n },\n});\nconst emit = defineEmits([\"update:mode\"]);\n\napplyStoredModeToDocument();\n\nconst open = ref(false);\nconst initialMode = readStoredMode() ?? props.mode;\nconst internalMode = ref(\n VALID_MODES.includes(initialMode) ? initialMode : \"auto\",\n);\nconst label = computed(\n () => MODE_LABELS[internalMode.value] ?? MODE_LABELS.auto,\n);\n\nwatch(\n () => props.mode,\n (mode) => {\n if (VALID_MODES.includes(mode) && mode !== internalMode.value) {\n internalMode.value = mode;\n }\n },\n);\n\nwatch(\n internalMode,\n (mode) => {\n if (!VALID_MODES.includes(mode)) {\n internalMode.value = \"auto\";\n return;\n }\n open.value = false;\n emit(\"update:mode\", mode);\n writeStoredMode(mode);\n },\n { immediate: true },\n);\n</script>\n\n<style scoped lang=\"less\">\n.theme-switcher-divider {\n margin: 4px 0;\n}\n</style>\n"],"names":["VALID_THEME_MODES","STORAGE_KEY","ONE_YEAR_IN_SECONDS","DARK_MODE_QUERY","readStoredMode","stored","getCookie","writeStoredMode","mode","hostname","protocol","domain","getCookieDomain","secure","attributes","applyStoredModeToDocument","resolvedMode","darkMode","resolveDarkMode","name","encodedName","cookies","cookie","parts","mediaQueryList","themePortalHostKey","useThemePortalTarget","hostRef","inject","fallbackTarget","computed","props","__props","globalAccentStack","appliedGlobalAccentKeys","applyGlobalAccentFromStack","root","key","activeEntry","entry","value","darkModeMedia","prefersReducedMotionMedia","PREFERS_REDUCED_MOTION_QUERY","initialMode","getEffectiveMode","currentMode","ref","theme","portalHost","handleSystemPreferenceChange","watch","syncDarkMode","previousValue","setDocumentDarkModeAttribute","withThemeTransition","onBeforeUnmount","index","accentStackEntry","event","applyTheme","startViewTransition","element","THEME_TRANSITION_DURATION","provide","normalizeHex","hex","h","g","b","hexToRgb","r","rgbToHex","toHex","clamp01","srgbChannelToLinear","channel","linearChannelToSrgb","normalized","rgbToOklch","rNorm","gNorm","bNorm","rLin","gLin","bLin","l","m","s","lRoot","mRoot","sRoot","oklabL","oklabA","oklabB","chroma","hue","tryOklchToSrgb","c","clampLinear","angle","a","lComponent","mComponent","sComponent","lCube","mCube","sCube","lLin","mLin","sLin","bValue","oklchToSrgb","attempt","rgb","makeBrandScale","baseHex","norm","baseRgb","baseOklch","toneConfig","tokens","adjustLightness","lightnessValue","adjustChroma","chromaScale","scaled","stop","config","tokenName","toneL","toneC","toneRgb","brandVars","brandStyle","enabled","vars","_createElementBlock","_renderSlot","_ctx","_createElementVNode","MODE_LABELS","map","option","VALID_MODES","emit","__emit","open","internalMode","_createBlock","_unref","DropdownMenu","$event","_createVNode","DropdownItemGroup","DropdownItemRadio"],"mappings":"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"}
package/dist/theme.es.js CHANGED
@@ -1,44 +1,44 @@
1
- import { ref as U, watch as A, onBeforeUnmount as ue, provide as de, computed as V, createElementBlock as me, openBlock as J, normalizeStyle as fe, renderSlot as he, createBlock as pe, unref as g, withCtx as W, createVNode as N, createElementVNode as be } from "vue";
1
+ import { inject as he, computed as j, ref as N, watch as A, onBeforeUnmount as pe, provide as J, createElementBlock as be, openBlock as Z, normalizeStyle as ge, renderSlot as ke, createElementVNode as ee, createBlock as Me, unref as g, withCtx as X, createVNode as U } from "vue";
2
2
  import "what-input";
3
- import { DropdownMenu as ge, DropdownItemGroup as ke, DropdownItemRadio as H } from "@gospore/dropdown-menu";
4
- const B = ["auto", "light", "dark"], X = "gospore-theme-mode", Me = 60 * 60 * 24 * 365, ve = "(prefers-color-scheme: dark)";
5
- function Y() {
3
+ import { DropdownMenu as ve, DropdownItemGroup as ye, DropdownItemRadio as K } from "@gospore/dropdown-menu";
4
+ const B = ["auto", "light", "dark"], te = "gospore-theme-mode", Ee = 60 * 60 * 24 * 365, Se = "(prefers-color-scheme: dark)";
5
+ function V() {
6
6
  if (typeof document > "u")
7
7
  return null;
8
- const n = we(X);
8
+ const n = Oe(te);
9
9
  return n && B.includes(n) ? n : null;
10
10
  }
11
- function Ee(n) {
11
+ function we(n) {
12
12
  if (typeof document > "u" || !B.includes(n))
13
13
  return;
14
- const c = typeof window < "u" ? window.location.hostname : "", s = typeof window < "u" ? window.location.protocol : "", a = Se(c), p = s === "https:", k = [
14
+ const a = typeof window < "u" ? window.location.hostname : "", s = typeof window < "u" ? window.location.protocol : "", c = _e(a), p = s === "https:", k = [
15
15
  "path=/",
16
- `max-age=${Me}`,
16
+ `max-age=${Ee}`,
17
17
  "SameSite=Lax"
18
18
  ];
19
- a && k.push(`domain=${a}`), p && k.push("Secure"), document.cookie = [
20
- `${encodeURIComponent(X)}=${encodeURIComponent(n)}`,
19
+ c && k.push(`domain=${c}`), p && k.push("Secure"), document.cookie = [
20
+ `${encodeURIComponent(te)}=${encodeURIComponent(n)}`,
21
21
  ...k
22
22
  ].join("; ");
23
23
  }
24
- function Z(n) {
24
+ function ne(n) {
25
25
  if (typeof document > "u")
26
26
  return;
27
- const c = typeof n == "string" && B.includes(n) ? n : Y() ?? "auto";
28
- console.log("Applying theme mode:", c);
29
- const s = ye(c);
27
+ const a = typeof n == "string" && B.includes(n) ? n : V() ?? "auto";
28
+ console.log("Applying theme mode:", a);
29
+ const s = Re(a);
30
30
  document.documentElement.setAttribute("dark-mode", s);
31
31
  }
32
- function we(n) {
32
+ function Oe(n) {
33
33
  if (typeof document > "u" || !document.cookie)
34
34
  return null;
35
- const c = `${encodeURIComponent(n)}=`, s = document.cookie.split("; ");
36
- for (const a of s)
37
- if (a.startsWith(c))
38
- return decodeURIComponent(a.slice(c.length));
35
+ const a = `${encodeURIComponent(n)}=`, s = document.cookie.split("; ");
36
+ for (const c of s)
37
+ if (c.startsWith(a))
38
+ return decodeURIComponent(c.slice(a.length));
39
39
  return null;
40
40
  }
41
- function Se(n) {
41
+ function _e(n) {
42
42
  if (!n || n === "localhost")
43
43
  return null;
44
44
  if (/^\d+(?:\.\d+){3}$/.test(n))
@@ -46,19 +46,26 @@ function Se(n) {
46
46
  const s = n.split(".");
47
47
  return s.length <= 1 ? null : s.length === 2 ? n : s.slice(-2).join(".");
48
48
  }
49
- function ye(n) {
49
+ function Re(n) {
50
50
  if (n === "dark")
51
51
  return !0;
52
52
  if (n === "light" || typeof window > "u")
53
53
  return !1;
54
54
  try {
55
- const c = typeof window.matchMedia == "function" ? window.matchMedia(ve) : null;
56
- return c ? c.matches : !1;
55
+ const a = typeof window.matchMedia == "function" ? window.matchMedia(Se) : null;
56
+ return a ? a.matches : !1;
57
57
  } catch {
58
58
  return !1;
59
59
  }
60
60
  }
61
- const Oe = "(prefers-color-scheme: dark)", Re = "(prefers-reduced-motion: reduce)", _e = 200, $e = /* @__PURE__ */ Object.assign({
61
+ const oe = Symbol.for("gospore.theme.portalHost");
62
+ function Ne() {
63
+ const n = he(oe, null);
64
+ console.log("Using theme portal host:", n);
65
+ const a = typeof document < "u" ? document.body : "body";
66
+ return j(() => n?.value ?? a);
67
+ }
68
+ const Te = "(prefers-color-scheme: dark)", De = "(prefers-reduced-motion: reduce)", Ce = 200, Ue = /* @__PURE__ */ Object.assign({
62
69
  name: "Theme"
63
70
  }, {
64
71
  __name: "Theme",
@@ -87,66 +94,66 @@ const Oe = "(prefers-color-scheme: dark)", Re = "(prefers-reduced-motion: reduce
87
94
  }
88
95
  },
89
96
  setup(n) {
90
- const c = n, s = [], a = /* @__PURE__ */ new Set();
97
+ const a = n, s = [], c = /* @__PURE__ */ new Set();
91
98
  function p() {
92
99
  const e = document.documentElement;
93
100
  if (!e)
94
101
  return;
95
- a.forEach((r) => {
102
+ c.forEach((r) => {
96
103
  e.style.removeProperty(r);
97
- }), a.clear();
104
+ }), c.clear();
98
105
  const t = [...s].reverse().find(
99
106
  (r) => r.enabled && r.vars && Object.keys(r.vars).length > 0
100
107
  );
101
108
  t && Object.entries(t.vars).forEach(([r, o]) => {
102
- e.style.setProperty(r, o), a.add(r);
109
+ e.style.setProperty(r, o), c.add(r);
103
110
  });
104
111
  }
105
- const k = window.matchMedia(Oe), j = window.matchMedia(
106
- Re
107
- ), D = Q();
108
- Z(D);
109
- const I = U(D), i = U({
110
- darkMode: l(D)
111
- });
112
- k.addEventListener("change", M), A(
113
- () => c.mode,
112
+ const k = window.matchMedia(Te), P = window.matchMedia(
113
+ De
114
+ ), T = q();
115
+ ne(T);
116
+ const I = N(T), l = N({
117
+ darkMode: M(T)
118
+ }), f = N(null);
119
+ k.addEventListener("change", Y), A(
120
+ () => a.mode,
114
121
  () => {
115
- f();
122
+ d();
116
123
  },
117
124
  { immediate: !0 }
118
125
  ), A(
119
- () => i.value.darkMode,
126
+ () => l.value.darkMode,
120
127
  (e, t) => {
121
128
  if (t === void 0) {
122
- K(e);
129
+ Q(e);
123
130
  return;
124
131
  }
125
- ee(() => {
126
- K(e);
132
+ re(() => {
133
+ Q(e);
127
134
  });
128
135
  },
129
136
  { immediate: !0 }
130
- ), ue(() => {
131
- k.removeEventListener("change", M);
137
+ ), pe(() => {
138
+ k.removeEventListener("change", Y);
132
139
  const e = s.indexOf($);
133
140
  e !== -1 && s.splice(e, 1), p();
134
141
  });
135
- function f() {
136
- const e = Q();
137
- I.value = e, i.value.darkMode = l(e);
142
+ function d() {
143
+ const e = q();
144
+ I.value = e, l.value.darkMode = M(e);
138
145
  }
139
- function l(e) {
146
+ function M(e) {
140
147
  return e === "dark" ? !0 : e === "light" ? !1 : k.matches;
141
148
  }
142
- function M(e) {
143
- !e || I.value !== "auto" || (i.value.darkMode = e.matches);
149
+ function Y(e) {
150
+ !e || I.value !== "auto" || (l.value.darkMode = e.matches);
144
151
  }
145
- function K(e) {
152
+ function Q(e) {
146
153
  document.documentElement.setAttribute("dark-mode", e);
147
154
  }
148
- function ee(e) {
149
- if (j.matches) {
155
+ function re(e) {
156
+ if (P.matches) {
150
157
  e();
151
158
  return;
152
159
  }
@@ -161,83 +168,83 @@ const Oe = "(prefers-color-scheme: dark)", Re = "(prefers-reduced-motion: reduce
161
168
  const r = document.documentElement;
162
169
  typeof r.animate == "function" && window.requestAnimationFrame(() => {
163
170
  r.animate([{ opacity: 0.85 }, { opacity: 1 }], {
164
- duration: _e,
171
+ duration: Ce,
165
172
  easing: "ease-in-out"
166
173
  });
167
174
  });
168
175
  }
169
- function Q() {
170
- return c.mode ?? Y() ?? "auto";
176
+ function q() {
177
+ return a.mode ?? V() ?? "auto";
171
178
  }
172
- de("theme", i);
173
- function q(e) {
179
+ J("theme", l), J(oe, f);
180
+ function z(e) {
174
181
  if (!e) return null;
175
182
  const t = e.trim().toLowerCase();
176
183
  if (!/^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i.exec(t)) return null;
177
184
  if (t.length === 4) {
178
- const o = t[1], u = t[2], m = t[3];
179
- return `#${o}${o}${u}${u}${m}${m}`;
185
+ const o = t[1], i = t[2], m = t[3];
186
+ return `#${o}${o}${i}${i}${m}${m}`;
180
187
  }
181
188
  return t;
182
189
  }
183
- function te(e) {
184
- const t = q(e);
190
+ function ae(e) {
191
+ const t = z(e);
185
192
  if (!t) return null;
186
- const r = parseInt(t.slice(1, 3), 16), o = parseInt(t.slice(3, 5), 16), u = parseInt(t.slice(5, 7), 16);
187
- return { r, g: o, b: u };
193
+ const r = parseInt(t.slice(1, 3), 16), o = parseInt(t.slice(3, 5), 16), i = parseInt(t.slice(5, 7), 16);
194
+ return { r, g: o, b: i };
188
195
  }
189
- function ne({ r: e, g: t, b: r }) {
190
- const o = (u) => u.toString(16).padStart(2, "0");
196
+ function ce({ r: e, g: t, b: r }) {
197
+ const o = (i) => i.toString(16).padStart(2, "0");
191
198
  return `#${o(e)}${o(t)}${o(r)}`;
192
199
  }
193
200
  function h(e) {
194
201
  return Math.max(0, Math.min(1, e));
195
202
  }
196
- function P(e) {
203
+ function H(e) {
197
204
  return e <= 0.04045 ? e / 12.92 : Math.pow((e + 0.055) / 1.055, 2.4);
198
205
  }
199
206
  function G(e) {
200
207
  const t = h(e);
201
208
  return t <= 31308e-7 ? 12.92 * t : 1.055 * Math.pow(t, 1 / 2.4) - 0.055;
202
209
  }
203
- function oe({ r: e, g: t, b: r }) {
204
- const o = e / 255, u = t / 255, m = r / 255, w = P(o), _ = P(u), d = P(m), v = 0.4122214708 * w + 0.5363325363 * _ + 0.0514459929 * d, E = 0.2119034982 * w + 0.6806995451 * _ + 0.1073969566 * d, S = 0.0883024619 * w + 0.2817188376 * _ + 0.6299787005 * d, b = Math.cbrt(v), y = Math.cbrt(E), T = Math.cbrt(S), L = 0.2104542553 * b + 0.793617785 * y - 0.0040720468 * T, O = 1.9779984951 * b - 2.428592205 * y + 0.4505937099 * T, R = 0.0259040371 * b + 0.7827717662 * y - 0.808675766 * T, C = Math.sqrt(O * O + R * R);
205
- let x = Math.atan2(R, O) * (180 / Math.PI);
210
+ function se({ r: e, g: t, b: r }) {
211
+ const o = e / 255, i = t / 255, m = r / 255, E = H(o), R = H(i), u = H(m), v = 0.4122214708 * E + 0.5363325363 * R + 0.0514459929 * u, y = 0.2119034982 * E + 0.6806995451 * R + 0.1073969566 * u, S = 0.0883024619 * E + 0.2817188376 * R + 0.6299787005 * u, b = Math.cbrt(v), w = Math.cbrt(y), D = Math.cbrt(S), L = 0.2104542553 * b + 0.793617785 * w - 0.0040720468 * D, O = 1.9779984951 * b - 2.428592205 * w + 0.4505937099 * D, _ = 0.0259040371 * b + 0.7827717662 * w - 0.808675766 * D, C = Math.sqrt(O * O + _ * _);
212
+ let x = Math.atan2(_, O) * (180 / Math.PI);
206
213
  return x < 0 && (x += 360), { l: L, c: C, h: x };
207
214
  }
208
- function z(e, t, r, o = !1) {
209
- const u = r * Math.PI / 180, m = t * Math.cos(u), w = t * Math.sin(u), _ = e + 0.3963377774 * m + 0.2158037573 * w, d = e - 0.1055613458 * m - 0.0638541728 * w, v = e - 0.0894841775 * m - 1.291485548 * w, E = o ? h(_) : _, S = o ? h(d) : d, b = o ? h(v) : v;
210
- if (!o && (E < -1e-4 || E > 1.0001 || S < -1e-4 || S > 1.0001 || b < -1e-4 || b > 1.0001))
215
+ function F(e, t, r, o = !1) {
216
+ const i = r * Math.PI / 180, m = t * Math.cos(i), E = t * Math.sin(i), R = e + 0.3963377774 * m + 0.2158037573 * E, u = e - 0.1055613458 * m - 0.0638541728 * E, v = e - 0.0894841775 * m - 1.291485548 * E, y = o ? h(R) : R, S = o ? h(u) : u, b = o ? h(v) : v;
217
+ if (!o && (y < -1e-4 || y > 1.0001 || S < -1e-4 || S > 1.0001 || b < -1e-4 || b > 1.0001))
211
218
  return null;
212
- const y = E * E * E, T = S * S * S, L = b * b * b;
213
- let O = 4.0767416621 * y - 3.3077115913 * T + 0.2309699292 * L, R = -1.2684380046 * y + 2.6097574011 * T - 0.3413193965 * L, C = -0.0041960863 * y - 0.7034186147 * T + 1.707614701 * L;
219
+ const w = y * y * y, D = S * S * S, L = b * b * b;
220
+ let O = 4.0767416621 * w - 3.3077115913 * D + 0.2309699292 * L, _ = -1.2684380046 * w + 2.6097574011 * D - 0.3413193965 * L, C = -0.0041960863 * w - 0.7034186147 * D + 1.707614701 * L;
214
221
  if (o)
215
- O = h(O), R = h(R), C = h(C);
216
- else if (O < -1e-4 || O > 1.0001 || R < -1e-4 || R > 1.0001 || C < -1e-4 || C > 1.0001)
222
+ O = h(O), _ = h(_), C = h(C);
223
+ else if (O < -1e-4 || O > 1.0001 || _ < -1e-4 || _ > 1.0001 || C < -1e-4 || C > 1.0001)
217
224
  return null;
218
- const x = h(G(O)), se = h(G(R)), ie = h(G(C));
225
+ const x = h(G(O)), de = h(G(_)), me = h(G(C));
219
226
  return {
220
227
  r: Math.round(x * 255),
221
- g: Math.round(se * 255),
222
- b: Math.round(ie * 255)
228
+ g: Math.round(de * 255),
229
+ b: Math.round(me * 255)
223
230
  };
224
231
  }
225
- function re(e, t, r) {
232
+ function le(e, t, r) {
226
233
  let o = t;
227
- for (let u = 0; u < 8; u += 1) {
228
- const m = z(e, o, r);
234
+ for (let i = 0; i < 8; i += 1) {
235
+ const m = F(e, o, r);
229
236
  if (m)
230
237
  return m;
231
238
  o *= 0.9;
232
239
  }
233
- return z(e, h(o), r, !0) || { r: 0, g: 0, b: 0 };
240
+ return F(e, h(o), r, !0) || { r: 0, g: 0, b: 0 };
234
241
  }
235
- function ce(e) {
236
- const t = q(e);
242
+ function ie(e) {
243
+ const t = z(e);
237
244
  if (!t) return null;
238
- const r = te(t);
245
+ const r = ae(t);
239
246
  if (!r) return null;
240
- const o = oe(r), u = {
247
+ const o = se(r), i = {
241
248
  100: { lightness: 0.35, chroma: 0.45 },
242
249
  200: { lightness: 0.28, chroma: 0.5 },
243
250
  300: { lightness: 0.22, chroma: 0.6 },
@@ -248,51 +255,56 @@ const Oe = "(prefers-color-scheme: dark)", Re = "(prefers-reduced-motion: reduce
248
255
  800: { lightness: -0.18, chroma: 1.1 },
249
256
  900: { lightness: -0.28, chroma: 1.15 },
250
257
  1e3: { lightness: -0.35, chroma: 1.2 }
251
- }, m = {}, w = (d) => d === 0 ? o.l : d > 0 ? h(o.l + d * (1 - o.l)) : h(o.l * (1 + d)), _ = (d) => {
252
- if (d === 1)
258
+ }, m = {}, E = (u) => u === 0 ? o.l : u > 0 ? h(o.l + u * (1 - o.l)) : h(o.l * (1 + u)), R = (u) => {
259
+ if (u === 1)
253
260
  return o.c;
254
- const v = o.c * d;
261
+ const v = o.c * u;
255
262
  return Math.max(0, Math.min(0.4, v));
256
263
  };
257
- return Object.entries(u).forEach(([d, v]) => {
258
- const E = `--color-brand-${d}`;
264
+ return Object.entries(i).forEach(([u, v]) => {
265
+ const y = `--color-brand-${u}`;
259
266
  if (v.base) {
260
- m[E] = t;
267
+ m[y] = t;
261
268
  return;
262
269
  }
263
- const S = w(v.lightness), b = _(v.chroma), y = re(S, b, o.h);
264
- m[E] = ne(y);
270
+ const S = E(v.lightness), b = R(v.chroma), w = le(S, b, o.h);
271
+ m[y] = ce(w);
265
272
  }), m;
266
273
  }
267
- const F = V(() => ce(c.accentColor) ?? {}), ae = V(() => F.value), $ = {
274
+ const W = j(() => ie(a.accentColor) ?? {}), ue = j(() => W.value), $ = {
268
275
  vars: {},
269
- enabled: !!c.exposeGlobalAccent
276
+ enabled: !!a.exposeGlobalAccent
270
277
  };
271
278
  return s.push($), A(
272
- () => c.exposeGlobalAccent,
279
+ () => a.exposeGlobalAccent,
273
280
  (e) => {
274
281
  $.enabled = !!e, p();
275
282
  },
276
283
  { immediate: !0 }
277
284
  ), A(
278
- F,
285
+ W,
279
286
  (e) => {
280
287
  e && Object.keys(e).length > 0 ? $.vars = { ...e } : $.vars = {}, p();
281
288
  },
282
289
  { immediate: !0 }
283
- ), (e, t) => (J(), me("div", {
290
+ ), (e, t) => (Z(), be("div", {
284
291
  class: "theme",
285
- style: fe(ae.value)
292
+ style: ge(ue.value)
286
293
  }, [
287
- he(e.$slots, "default")
294
+ ke(e.$slots, "default"),
295
+ ee("div", {
296
+ ref_key: "portalHost",
297
+ ref: f,
298
+ class: "theme__portal-host"
299
+ }, null, 512)
288
300
  ], 4));
289
301
  }
290
- }), De = (n, c) => {
302
+ }), Ae = (n, a) => {
291
303
  const s = n.__vccOpts || n;
292
- for (const [a, p] of c)
293
- s[a] = p;
304
+ for (const [c, p] of a)
305
+ s[c] = p;
294
306
  return s;
295
- }, Te = {
307
+ }, Ie = {
296
308
  __name: "ThemeSwitcher",
297
309
  props: {
298
310
  mode: {
@@ -302,66 +314,66 @@ const Oe = "(prefers-color-scheme: dark)", Re = "(prefers-reduced-motion: reduce
302
314
  }
303
315
  },
304
316
  emits: ["update:mode"],
305
- setup(n, { emit: c }) {
306
- const a = [
317
+ setup(n, { emit: a }) {
318
+ const c = [
307
319
  { value: "auto", label: "System" },
308
320
  { value: "light", label: "Light" },
309
321
  { value: "dark", label: "Dark" }
310
- ].reduce((f, l) => (f[l.value] = l.label, f), {}), p = B, k = n, j = c;
311
- Z();
312
- const D = U(!1), I = Y() ?? k.mode, i = U(
322
+ ].reduce((f, d) => (f[d.value] = d.label, f), {}), p = B, k = n, P = a;
323
+ ne();
324
+ const T = N(!1), I = V() ?? k.mode, l = N(
313
325
  p.includes(I) ? I : "auto"
314
326
  );
315
- return V(
316
- () => a[i.value] ?? a.auto
327
+ return j(
328
+ () => c[l.value] ?? c.auto
317
329
  ), A(
318
330
  () => k.mode,
319
331
  (f) => {
320
- p.includes(f) && f !== i.value && (i.value = f);
332
+ p.includes(f) && f !== l.value && (l.value = f);
321
333
  }
322
334
  ), A(
323
- i,
335
+ l,
324
336
  (f) => {
325
337
  if (!p.includes(f)) {
326
- i.value = "auto";
338
+ l.value = "auto";
327
339
  return;
328
340
  }
329
- D.value = !1, j("update:mode", f), Ee(f);
341
+ T.value = !1, P("update:mode", f), we(f);
330
342
  },
331
343
  { immediate: !0 }
332
- ), (f, l) => (J(), pe(g(ge), {
333
- open: D.value,
334
- "onUpdate:open": l[3] || (l[3] = (M) => D.value = M),
344
+ ), (f, d) => (Z(), Me(g(ve), {
345
+ open: T.value,
346
+ "onUpdate:open": d[3] || (d[3] = (M) => T.value = M),
335
347
  text: "Theme",
336
348
  "aria-label": "Select theme mode"
337
349
  }, {
338
- default: W(() => [
339
- N(g(ke), { title: "Theme" }, {
340
- default: W(() => [
341
- N(g(H), {
342
- checked: i.value,
343
- "onUpdate:checked": l[0] || (l[0] = (M) => i.value = M),
350
+ default: X(() => [
351
+ U(g(ye), { title: "Theme" }, {
352
+ default: X(() => [
353
+ U(g(K), {
354
+ checked: l.value,
355
+ "onUpdate:checked": d[0] || (d[0] = (M) => l.value = M),
344
356
  value: "auto",
345
- label: g(a).auto,
346
- "aria-label": `${g(a).auto} mode`
357
+ label: g(c).auto,
358
+ "aria-label": `${g(c).auto} mode`
347
359
  }, null, 8, ["checked", "label", "aria-label"]),
348
- l[4] || (l[4] = be("hr", {
360
+ d[4] || (d[4] = ee("hr", {
349
361
  class: "theme-switcher-divider",
350
362
  role: "separator"
351
363
  }, null, -1)),
352
- N(g(H), {
353
- checked: i.value,
354
- "onUpdate:checked": l[1] || (l[1] = (M) => i.value = M),
364
+ U(g(K), {
365
+ checked: l.value,
366
+ "onUpdate:checked": d[1] || (d[1] = (M) => l.value = M),
355
367
  value: "light",
356
- label: g(a).light,
357
- "aria-label": `${g(a).light} mode`
368
+ label: g(c).light,
369
+ "aria-label": `${g(c).light} mode`
358
370
  }, null, 8, ["checked", "label", "aria-label"]),
359
- N(g(H), {
360
- checked: i.value,
361
- "onUpdate:checked": l[2] || (l[2] = (M) => i.value = M),
371
+ U(g(K), {
372
+ checked: l.value,
373
+ "onUpdate:checked": d[2] || (d[2] = (M) => l.value = M),
362
374
  value: "dark",
363
- label: g(a).dark,
364
- "aria-label": `${g(a).dark} mode`
375
+ label: g(c).dark,
376
+ "aria-label": `${g(c).dark} mode`
365
377
  }, null, 8, ["checked", "label", "aria-label"])
366
378
  ]),
367
379
  _: 1
@@ -370,9 +382,11 @@ const Oe = "(prefers-color-scheme: dark)", Re = "(prefers-reduced-motion: reduce
370
382
  _: 1
371
383
  }, 8, ["open"]));
372
384
  }
373
- }, Le = /* @__PURE__ */ De(Te, [["__scopeId", "data-v-bcbc87cb"]]);
385
+ }, je = /* @__PURE__ */ Ae(Ie, [["__scopeId", "data-v-bcbc87cb"]]);
374
386
  export {
375
- $e as Theme,
376
- Le as ThemeSwitcher
387
+ Ue as Theme,
388
+ je as ThemeSwitcher,
389
+ oe as themePortalHostKey,
390
+ Ne as useThemePortalTarget
377
391
  };
378
392
  //# sourceMappingURL=theme.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"theme.es.js","sources":["../src/modeStorage.js","../src/Theme.vue","../src/ThemeSwitcher.vue"],"sourcesContent":["const VALID_THEME_MODES = [\"auto\", \"light\", \"dark\"];\nconst STORAGE_KEY = \"gospore-theme-mode\";\nconst ONE_YEAR_IN_SECONDS = 60 * 60 * 24 * 365;\nconst DARK_MODE_QUERY = \"(prefers-color-scheme: dark)\";\n\nexport function readStoredMode() {\n if (typeof document === \"undefined\") {\n return null;\n }\n const stored = getCookie(STORAGE_KEY);\n return stored && VALID_THEME_MODES.includes(stored) ? stored : null;\n}\n\nexport function writeStoredMode(mode) {\n if (typeof document === \"undefined\" || !VALID_THEME_MODES.includes(mode)) {\n return;\n }\n const hostname =\n typeof window !== \"undefined\" ? window.location.hostname : \"\";\n const protocol =\n typeof window !== \"undefined\" ? window.location.protocol : \"\";\n const domain = getCookieDomain(hostname);\n const secure = protocol === \"https:\";\n const attributes = [\n \"path=/\",\n `max-age=${ONE_YEAR_IN_SECONDS}`,\n \"SameSite=Lax\",\n ];\n if (domain) {\n attributes.push(`domain=${domain}`);\n }\n if (secure) {\n attributes.push(\"Secure\");\n }\n document.cookie = [\n `${encodeURIComponent(STORAGE_KEY)}=${encodeURIComponent(mode)}`,\n ...attributes,\n ].join(\"; \");\n}\n\nexport function applyStoredModeToDocument(mode) {\n if (typeof document === \"undefined\") {\n return;\n }\n const resolvedMode =\n typeof mode === \"string\" && VALID_THEME_MODES.includes(mode)\n ? mode\n : readStoredMode() ?? \"auto\";\n console.log(\"Applying theme mode:\", resolvedMode);\n const darkMode = resolveDarkMode(resolvedMode);\n document.documentElement.setAttribute(\"dark-mode\", darkMode);\n}\n\nexport { VALID_THEME_MODES, STORAGE_KEY };\n\nfunction getCookie(name) {\n if (typeof document === \"undefined\" || !document.cookie) {\n return null;\n }\n const encodedName = `${encodeURIComponent(name)}=`;\n const cookies = document.cookie.split(\"; \");\n for (const cookie of cookies) {\n if (cookie.startsWith(encodedName)) {\n return decodeURIComponent(cookie.slice(encodedName.length));\n }\n }\n return null;\n}\n\nfunction getCookieDomain(hostname) {\n if (!hostname || hostname === \"localhost\") {\n return null;\n }\n const isIpAddress = /^\\d+(?:\\.\\d+){3}$/.test(hostname);\n if (isIpAddress) {\n return hostname;\n }\n const parts = hostname.split(\".\");\n if (parts.length <= 1) {\n return null;\n }\n if (parts.length === 2) {\n return hostname;\n }\n return parts.slice(-2).join(\".\");\n}\n\nfunction resolveDarkMode(mode) {\n if (mode === \"dark\") {\n return true;\n }\n if (mode === \"light\") {\n return false;\n }\n if (typeof window === \"undefined\") {\n return false;\n }\n try {\n const mediaQueryList =\n typeof window.matchMedia === \"function\"\n ? window.matchMedia(DARK_MODE_QUERY)\n : null;\n return mediaQueryList ? mediaQueryList.matches : false;\n } catch (error) {\n return false;\n }\n}\n","<template>\n <div class=\"theme\" :style=\"brandStyle\">\n <slot />\n </div>\n</template>\n\n<script setup>\nimport { provide, ref, watch, onBeforeUnmount, computed } from \"vue\";\nimport { applyStoredModeToDocument, readStoredMode } from \"./modeStorage\";\nimport \"what-input\";\n\ndefineOptions({\n name: \"Theme\",\n});\nconst props = defineProps({\n mode: {\n type: String,\n validator: (value) => [\"auto\", \"light\", \"dark\"].includes(value),\n },\n /**\n * Optional hex accent color (\"#RRGGBB\" or \"#RGB\"). When provided,\n * Theme derives the `--color-brand-*` palette and exposes the tokens on\n * the root .theme element (and the global document for portals).\n */\n accentColor: {\n type: String,\n required: false,\n default: undefined,\n },\n /**\n * When true the brand vars are also exposed on <html>, allowing portals\n * attached outside the Theme subtree to inherit the accent colors.\n */\n exposeGlobalAccent: {\n type: Boolean,\n default: false,\n },\n});\n\nconst globalAccentStack = [];\nconst appliedGlobalAccentKeys = new Set();\n\nfunction applyGlobalAccentFromStack() {\n const root = document.documentElement;\n if (!root) {\n return;\n }\n\n appliedGlobalAccentKeys.forEach((key) => {\n root.style.removeProperty(key);\n });\n appliedGlobalAccentKeys.clear();\n\n const activeEntry = [...globalAccentStack]\n .reverse()\n .find(\n (entry) =>\n entry.enabled &&\n entry.vars &&\n Object.keys(entry.vars).length > 0,\n );\n\n if (!activeEntry) {\n return;\n }\n\n Object.entries(activeEntry.vars).forEach(([key, value]) => {\n root.style.setProperty(key, value);\n appliedGlobalAccentKeys.add(key);\n });\n}\n\nconst DARK_MODE_QUERY = \"(prefers-color-scheme: dark)\";\nconst PREFERS_REDUCED_MOTION_QUERY = \"(prefers-reduced-motion: reduce)\";\nconst THEME_TRANSITION_DURATION = 200;\nconst darkModeMedia = window.matchMedia(DARK_MODE_QUERY);\nconst prefersReducedMotionMedia = window.matchMedia(\n PREFERS_REDUCED_MOTION_QUERY,\n);\n\nconst initialMode = getEffectiveMode();\napplyStoredModeToDocument(initialMode);\n\nconst currentMode = ref(initialMode);\n\nconst theme = ref({\n darkMode: resolveDarkMode(initialMode),\n});\n\ndarkModeMedia.addEventListener(\"change\", handleSystemPreferenceChange);\n\nwatch(\n () => props.mode,\n () => {\n syncDarkMode();\n },\n { immediate: true },\n);\n\nwatch(\n () => theme.value.darkMode,\n (darkMode, previousValue) => {\n if (previousValue === undefined) {\n setDocumentDarkModeAttribute(darkMode);\n return;\n }\n withThemeTransition(() => {\n setDocumentDarkModeAttribute(darkMode);\n });\n },\n { immediate: true },\n);\n\nonBeforeUnmount(() => {\n darkModeMedia.removeEventListener(\"change\", handleSystemPreferenceChange);\n const index = globalAccentStack.indexOf(accentStackEntry);\n if (index !== -1) {\n globalAccentStack.splice(index, 1);\n }\n applyGlobalAccentFromStack();\n});\n\nfunction syncDarkMode() {\n const mode = getEffectiveMode();\n currentMode.value = mode;\n theme.value.darkMode = resolveDarkMode(mode);\n}\n\nfunction resolveDarkMode(mode) {\n if (mode === \"dark\") {\n return true;\n }\n if (mode === \"light\") {\n return false;\n }\n return darkModeMedia.matches;\n}\n\nfunction handleSystemPreferenceChange(event) {\n if (!event || currentMode.value !== \"auto\") {\n return;\n }\n theme.value.darkMode = event.matches;\n}\n\nfunction setDocumentDarkModeAttribute(darkMode) {\n document.documentElement.setAttribute(\"dark-mode\", darkMode);\n}\n\nfunction withThemeTransition(applyTheme) {\n if (prefersReducedMotionMedia.matches) {\n applyTheme();\n return;\n }\n const startViewTransition = document.startViewTransition?.bind(document);\n if (startViewTransition) {\n startViewTransition(() => {\n applyTheme();\n });\n return;\n }\n applyTheme();\n const element = document.documentElement;\n if (typeof element.animate !== \"function\") {\n return;\n }\n window.requestAnimationFrame(() => {\n element.animate([{ opacity: 0.85 }, { opacity: 1 }], {\n duration: THEME_TRANSITION_DURATION,\n easing: \"ease-in-out\",\n });\n });\n}\n\nfunction getEffectiveMode() {\n return props.mode ?? readStoredMode() ?? \"auto\";\n}\n\nprovide(\"theme\", theme);\n\n// --- Accent helpers -------------------------------------------------------\nfunction normalizeHex(hex) {\n if (!hex) return null;\n const h = hex.trim().toLowerCase();\n const m = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i.exec(h);\n if (!m) return null;\n if (h.length === 4) {\n // expand #rgb -> #rrggbb\n const r = h[1],\n g = h[2],\n b = h[3];\n return `#${r}${r}${g}${g}${b}${b}`;\n }\n return h;\n}\n\nfunction hexToRgb(hex) {\n const h = normalizeHex(hex);\n if (!h) return null;\n const r = parseInt(h.slice(1, 3), 16);\n const g = parseInt(h.slice(3, 5), 16);\n const b = parseInt(h.slice(5, 7), 16);\n return { r, g, b };\n}\n\nfunction rgbToHex({ r, g, b }) {\n const toHex = (value) => value.toString(16).padStart(2, \"0\");\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`;\n}\n\nfunction clamp01(value) {\n return Math.max(0, Math.min(1, value));\n}\n\nfunction srgbChannelToLinear(channel) {\n if (channel <= 0.04045) {\n return channel / 12.92;\n }\n return Math.pow((channel + 0.055) / 1.055, 2.4);\n}\n\nfunction linearChannelToSrgb(channel) {\n const normalized = clamp01(channel);\n if (normalized <= 0.0031308) {\n return 12.92 * normalized;\n }\n return 1.055 * Math.pow(normalized, 1 / 2.4) - 0.055;\n}\n\nfunction rgbToOklch({ r, g, b }) {\n const rNorm = r / 255;\n const gNorm = g / 255;\n const bNorm = b / 255;\n\n const rLin = srgbChannelToLinear(rNorm);\n const gLin = srgbChannelToLinear(gNorm);\n const bLin = srgbChannelToLinear(bNorm);\n\n const l = 0.4122214708 * rLin + 0.5363325363 * gLin + 0.0514459929 * bLin;\n const m = 0.2119034982 * rLin + 0.6806995451 * gLin + 0.1073969566 * bLin;\n const s = 0.0883024619 * rLin + 0.2817188376 * gLin + 0.6299787005 * bLin;\n\n const lRoot = Math.cbrt(l);\n const mRoot = Math.cbrt(m);\n const sRoot = Math.cbrt(s);\n\n const oklabL =\n 0.2104542553 * lRoot + 0.793617785 * mRoot - 0.0040720468 * sRoot;\n const oklabA =\n 1.9779984951 * lRoot - 2.428592205 * mRoot + 0.4505937099 * sRoot;\n const oklabB =\n 0.0259040371 * lRoot + 0.7827717662 * mRoot - 0.808675766 * sRoot;\n\n const chroma = Math.sqrt(oklabA * oklabA + oklabB * oklabB);\n let hue = Math.atan2(oklabB, oklabA) * (180 / Math.PI);\n if (hue < 0) {\n hue += 360;\n }\n\n return { l: oklabL, c: chroma, h: hue };\n}\n\nfunction tryOklchToSrgb(l, c, h, clampLinear = false) {\n const angle = (h * Math.PI) / 180;\n const a = c * Math.cos(angle);\n const b = c * Math.sin(angle);\n\n const lComponent = l + 0.3963377774 * a + 0.2158037573 * b;\n const mComponent = l - 0.1055613458 * a - 0.0638541728 * b;\n const sComponent = l - 0.0894841775 * a - 1.291485548 * b;\n\n const lCube = clampLinear ? clamp01(lComponent) : lComponent;\n const mCube = clampLinear ? clamp01(mComponent) : mComponent;\n const sCube = clampLinear ? clamp01(sComponent) : sComponent;\n\n if (!clampLinear) {\n const outOfRange =\n lCube < -0.0001 ||\n lCube > 1.0001 ||\n mCube < -0.0001 ||\n mCube > 1.0001 ||\n sCube < -0.0001 ||\n sCube > 1.0001;\n if (outOfRange) {\n return null;\n }\n }\n\n const lLin = lCube * lCube * lCube;\n const mLin = mCube * mCube * mCube;\n const sLin = sCube * sCube * sCube;\n\n let rLin = 4.0767416621 * lLin - 3.3077115913 * mLin + 0.2309699292 * sLin;\n let gLin = -1.2684380046 * lLin + 2.6097574011 * mLin - 0.3413193965 * sLin;\n let bLin = -0.0041960863 * lLin - 0.7034186147 * mLin + 1.707614701 * sLin;\n\n if (clampLinear) {\n rLin = clamp01(rLin);\n gLin = clamp01(gLin);\n bLin = clamp01(bLin);\n } else {\n const outOfRange =\n rLin < -0.0001 ||\n rLin > 1.0001 ||\n gLin < -0.0001 ||\n gLin > 1.0001 ||\n bLin < -0.0001 ||\n bLin > 1.0001;\n if (outOfRange) {\n return null;\n }\n }\n\n const r = clamp01(linearChannelToSrgb(rLin));\n const g = clamp01(linearChannelToSrgb(gLin));\n const bValue = clamp01(linearChannelToSrgb(bLin));\n\n return {\n r: Math.round(r * 255),\n g: Math.round(g * 255),\n b: Math.round(bValue * 255),\n };\n}\n\nfunction oklchToSrgb(l, c, h) {\n let chroma = c;\n for (let attempt = 0; attempt < 8; attempt += 1) {\n const rgb = tryOklchToSrgb(l, chroma, h);\n if (rgb) {\n return rgb;\n }\n chroma *= 0.9;\n }\n return tryOklchToSrgb(l, clamp01(chroma), h, true) || { r: 0, g: 0, b: 0 };\n}\n\nfunction makeBrandScale(baseHex) {\n const norm = normalizeHex(baseHex);\n if (!norm) return null;\n const baseRgb = hexToRgb(norm);\n if (!baseRgb) return null;\n const baseOklch = rgbToOklch(baseRgb);\n const toneConfig = {\n 100: { lightness: 0.35, chroma: 0.45 },\n 200: { lightness: 0.28, chroma: 0.5 },\n 300: { lightness: 0.22, chroma: 0.6 },\n 400: { lightness: 0.16, chroma: 0.75 },\n 500: { lightness: 0.08, chroma: 0.9 },\n 600: { lightness: 0, chroma: 1, base: true },\n 700: { lightness: -0.08, chroma: 1.05 },\n 800: { lightness: -0.18, chroma: 1.1 },\n 900: { lightness: -0.28, chroma: 1.15 },\n 1000: { lightness: -0.35, chroma: 1.2 },\n };\n const tokens = {};\n\n const adjustLightness = (lightnessValue) => {\n if (lightnessValue === 0) {\n return baseOklch.l;\n }\n if (lightnessValue > 0) {\n return clamp01(baseOklch.l + lightnessValue * (1 - baseOklch.l));\n }\n return clamp01(baseOklch.l * (1 + lightnessValue));\n };\n\n const adjustChroma = (chromaScale) => {\n if (chromaScale === 1) {\n return baseOklch.c;\n }\n const scaled = baseOklch.c * chromaScale;\n return Math.max(0, Math.min(0.4, scaled));\n };\n\n Object.entries(toneConfig).forEach(([stop, config]) => {\n const tokenName = `--color-brand-${stop}`;\n if (config.base) {\n tokens[tokenName] = norm;\n return;\n }\n const toneL = adjustLightness(config.lightness);\n const toneC = adjustChroma(config.chroma);\n const toneRgb = oklchToSrgb(toneL, toneC, baseOklch.h);\n tokens[tokenName] = rgbToHex(toneRgb);\n });\n return tokens;\n}\n\nconst brandVars = computed(() => makeBrandScale(props.accentColor) ?? {});\nconst brandStyle = computed(() => brandVars.value);\n\nconst accentStackEntry = {\n vars: {},\n enabled: Boolean(props.exposeGlobalAccent),\n};\nglobalAccentStack.push(accentStackEntry);\n\nwatch(\n () => props.exposeGlobalAccent,\n (enabled) => {\n accentStackEntry.enabled = Boolean(enabled);\n applyGlobalAccentFromStack();\n },\n { immediate: true },\n);\n\nwatch(\n brandVars,\n (vars) => {\n if (vars && Object.keys(vars).length > 0) {\n accentStackEntry.vars = { ...vars };\n } else {\n accentStackEntry.vars = {};\n }\n applyGlobalAccentFromStack();\n },\n { immediate: true },\n);\n</script>\n\n<style lang=\"less\">\n@import \"index.less\";\n</style>\n","<template>\n <DropdownMenu\n v-model:open=\"open\"\n text=\"Theme\"\n aria-label=\"Select theme mode\"\n >\n <DropdownItemGroup title=\"Theme\">\n <DropdownItemRadio\n v-model:checked=\"internalMode\"\n value=\"auto\"\n :label=\"MODE_LABELS.auto\"\n :aria-label=\"`${MODE_LABELS.auto} mode`\"\n />\n <hr class=\"theme-switcher-divider\" role=\"separator\" />\n <DropdownItemRadio\n v-model:checked=\"internalMode\"\n value=\"light\"\n :label=\"MODE_LABELS.light\"\n :aria-label=\"`${MODE_LABELS.light} mode`\"\n />\n <DropdownItemRadio\n v-model:checked=\"internalMode\"\n value=\"dark\"\n :label=\"MODE_LABELS.dark\"\n :aria-label=\"`${MODE_LABELS.dark} mode`\"\n />\n </DropdownItemGroup>\n </DropdownMenu>\n</template>\n\n<script setup>\nimport { ref, computed, watch } from \"vue\";\nimport {\n DropdownMenu,\n DropdownItemGroup,\n DropdownItemRadio,\n} from \"@gospore/dropdown-menu\";\nimport {\n readStoredMode,\n writeStoredMode,\n VALID_THEME_MODES,\n applyStoredModeToDocument,\n} from \"./modeStorage\";\n\nconst MODE_OPTIONS = [\n { value: \"auto\", label: \"System\" },\n { value: \"light\", label: \"Light\" },\n { value: \"dark\", label: \"Dark\" },\n];\nconst MODE_LABELS = MODE_OPTIONS.reduce((map, option) => {\n map[option.value] = option.label;\n return map;\n}, {});\nconst VALID_MODES = VALID_THEME_MODES;\n\nconst props = defineProps({\n mode: {\n type: String,\n default: \"auto\",\n validator: (value) => [\"auto\", \"light\", \"dark\"].includes(value),\n },\n});\nconst emit = defineEmits([\"update:mode\"]);\n\napplyStoredModeToDocument();\n\nconst open = ref(false);\nconst initialMode = readStoredMode() ?? props.mode;\nconst internalMode = ref(\n VALID_MODES.includes(initialMode) ? initialMode : \"auto\",\n);\nconst label = computed(\n () => MODE_LABELS[internalMode.value] ?? MODE_LABELS.auto,\n);\n\nwatch(\n () => props.mode,\n (mode) => {\n if (VALID_MODES.includes(mode) && mode !== internalMode.value) {\n internalMode.value = mode;\n }\n },\n);\n\nwatch(\n internalMode,\n (mode) => {\n if (!VALID_MODES.includes(mode)) {\n internalMode.value = \"auto\";\n return;\n }\n open.value = false;\n emit(\"update:mode\", mode);\n writeStoredMode(mode);\n },\n { immediate: true },\n);\n</script>\n\n<style scoped lang=\"less\">\n.theme-switcher-divider {\n margin: 4px 0;\n}\n</style>\n"],"names":["VALID_THEME_MODES","STORAGE_KEY","ONE_YEAR_IN_SECONDS","DARK_MODE_QUERY","readStoredMode","stored","getCookie","writeStoredMode","mode","hostname","protocol","domain","getCookieDomain","secure","attributes","applyStoredModeToDocument","resolvedMode","darkMode","resolveDarkMode","name","encodedName","cookies","cookie","parts","mediaQueryList","props","__props","globalAccentStack","appliedGlobalAccentKeys","applyGlobalAccentFromStack","root","key","activeEntry","entry","value","darkModeMedia","prefersReducedMotionMedia","PREFERS_REDUCED_MOTION_QUERY","initialMode","getEffectiveMode","currentMode","ref","theme","handleSystemPreferenceChange","watch","syncDarkMode","previousValue","setDocumentDarkModeAttribute","withThemeTransition","onBeforeUnmount","index","accentStackEntry","event","applyTheme","startViewTransition","element","THEME_TRANSITION_DURATION","provide","normalizeHex","hex","h","r","g","b","hexToRgb","rgbToHex","toHex","clamp01","srgbChannelToLinear","channel","linearChannelToSrgb","normalized","rgbToOklch","rNorm","gNorm","bNorm","rLin","gLin","bLin","l","m","s","lRoot","mRoot","sRoot","oklabL","oklabA","oklabB","chroma","hue","tryOklchToSrgb","c","clampLinear","angle","a","lComponent","mComponent","sComponent","lCube","mCube","sCube","lLin","mLin","sLin","bValue","oklchToSrgb","attempt","rgb","makeBrandScale","baseHex","norm","baseRgb","baseOklch","toneConfig","tokens","adjustLightness","lightnessValue","adjustChroma","chromaScale","scaled","stop","config","tokenName","toneL","toneC","toneRgb","brandVars","computed","brandStyle","enabled","vars","_createElementBlock","_renderSlot","_ctx","MODE_LABELS","map","option","VALID_MODES","emit","__emit","open","internalMode","_createBlock","_unref","DropdownMenu","$event","_createVNode","DropdownItemGroup","DropdownItemRadio","_createElementVNode"],"mappings":";;;AAAA,MAAMA,IAAoB,CAAC,QAAQ,SAAS,MAAM,GAC5CC,IAAc,sBACdC,KAAsB,KAAK,KAAK,KAAK,KACrCC,KAAkB;AAEjB,SAASC,IAAiB;AAC7B,MAAI,OAAO,WAAa;AACpB,WAAO;AAEX,QAAMC,IAASC,GAAUL,CAAW;AACpC,SAAOI,KAAUL,EAAkB,SAASK,CAAM,IAAIA,IAAS;AACnE;AAEO,SAASE,GAAgBC,GAAM;AAClC,MAAI,OAAO,WAAa,OAAe,CAACR,EAAkB,SAASQ,CAAI;AACnE;AAEJ,QAAMC,IACF,OAAO,SAAW,MAAc,OAAO,SAAS,WAAW,IACzDC,IACF,OAAO,SAAW,MAAc,OAAO,SAAS,WAAW,IACzDC,IAASC,GAAgBH,CAAQ,GACjCI,IAASH,MAAa,UACtBI,IAAa;AAAA,IACf;AAAA,IACA,WAAWZ,EAAmB;AAAA,IAC9B;AAAA,EACR;AACI,EAAIS,KACAG,EAAW,KAAK,UAAUH,CAAM,EAAE,GAElCE,KACAC,EAAW,KAAK,QAAQ,GAE5B,SAAS,SAAS;AAAA,IACd,GAAG,mBAAmBb,CAAW,CAAC,IAAI,mBAAmBO,CAAI,CAAC;AAAA,IAC9D,GAAGM;AAAA,EACX,EAAM,KAAK,IAAI;AACf;AAEO,SAASC,EAA0BP,GAAM;AAC5C,MAAI,OAAO,WAAa;AACpB;AAEJ,QAAMQ,IACF,OAAOR,KAAS,YAAYR,EAAkB,SAASQ,CAAI,IACrDA,IACAJ,EAAc,KAAM;AAC9B,UAAQ,IAAI,wBAAwBY,CAAY;AAChD,QAAMC,IAAWC,GAAgBF,CAAY;AAC7C,WAAS,gBAAgB,aAAa,aAAaC,CAAQ;AAC/D;AAIA,SAASX,GAAUa,GAAM;AACrB,MAAI,OAAO,WAAa,OAAe,CAAC,SAAS;AAC7C,WAAO;AAEX,QAAMC,IAAc,GAAG,mBAAmBD,CAAI,CAAC,KACzCE,IAAU,SAAS,OAAO,MAAM,IAAI;AAC1C,aAAWC,KAAUD;AACjB,QAAIC,EAAO,WAAWF,CAAW;AAC7B,aAAO,mBAAmBE,EAAO,MAAMF,EAAY,MAAM,CAAC;AAGlE,SAAO;AACX;AAEA,SAASR,GAAgBH,GAAU;AAC/B,MAAI,CAACA,KAAYA,MAAa;AAC1B,WAAO;AAGX,MADoB,oBAAoB,KAAKA,CAAQ;AAEjD,WAAOA;AAEX,QAAMc,IAAQd,EAAS,MAAM,GAAG;AAChC,SAAIc,EAAM,UAAU,IACT,OAEPA,EAAM,WAAW,IACVd,IAEJc,EAAM,MAAM,EAAE,EAAE,KAAK,GAAG;AACnC;AAEA,SAASL,GAAgBV,GAAM;AAC3B,MAAIA,MAAS;AACT,WAAO;AAKX,MAHIA,MAAS,WAGT,OAAO,SAAW;AAClB,WAAO;AAEX,MAAI;AACA,UAAMgB,IACF,OAAO,OAAO,cAAe,aACvB,OAAO,WAAWrB,EAAe,IACjC;AACV,WAAOqB,IAAiBA,EAAe,UAAU;AAAA,EACrD,QAAgB;AACZ,WAAO;AAAA,EACX;AACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5FA,UAAMC,IAAQC,GAyBRC,IAAoB,CAAA,GACpBC,IAA0B,oBAAI,IAAG;AAEvC,aAASC,IAA6B;AAClC,YAAMC,IAAO,SAAS;AACtB,UAAI,CAACA;AACD;AAGJ,MAAAF,EAAwB,QAAQ,CAACG,MAAQ;AACrC,QAAAD,EAAK,MAAM,eAAeC,CAAG;AAAA,MACjC,CAAC,GACDH,EAAwB,MAAK;AAE7B,YAAMI,IAAc,CAAC,GAAGL,CAAiB,EACpC,QAAO,EACP;AAAA,QACG,CAACM,MACGA,EAAM,WACNA,EAAM,QACN,OAAO,KAAKA,EAAM,IAAI,EAAE,SAAS;AAAA,MACjD;AAEI,MAAKD,KAIL,OAAO,QAAQA,EAAY,IAAI,EAAE,QAAQ,CAAC,CAACD,GAAKG,CAAK,MAAM;AACvD,QAAAJ,EAAK,MAAM,YAAYC,GAAKG,CAAK,GACjCN,EAAwB,IAAIG,CAAG;AAAA,MACnC,CAAC;AAAA,IACL;AAKA,UAAMI,IAAgB,OAAO,WAAWhC,EAAe,GACjDiC,IAA4B,OAAO;AAAA,MACrCC;AAAA,IACJ,GAEMC,IAAcC,EAAgB;AACpC,IAAAxB,EAA0BuB,CAAW;AAErC,UAAME,IAAcC,EAAIH,CAAW,GAE7BI,IAAQD,EAAI;AAAA,MACd,UAAUvB,EAAgBoB,CAAW;AAAA,IACzC,CAAC;AAED,IAAAH,EAAc,iBAAiB,UAAUQ,CAA4B,GAErEC;AAAA,MACI,MAAMnB,EAAM;AAAA,MACZ,MAAM;AACF,QAAAoB,EAAY;AAAA,MAChB;AAAA,MACA,EAAE,WAAW,GAAI;AAAA,IACrB,GAEAD;AAAA,MACI,MAAMF,EAAM,MAAM;AAAA,MAClB,CAACzB,GAAU6B,MAAkB;AACzB,YAAIA,MAAkB,QAAW;AAC7B,UAAAC,EAA6B9B,CAAQ;AACrC;AAAA,QACJ;AACA,QAAA+B,GAAoB,MAAM;AACtB,UAAAD,EAA6B9B,CAAQ;AAAA,QACzC,CAAC;AAAA,MACL;AAAA,MACA,EAAE,WAAW,GAAI;AAAA,IACrB,GAEAgC,GAAgB,MAAM;AAClB,MAAAd,EAAc,oBAAoB,UAAUQ,CAA4B;AACxE,YAAMO,IAAQvB,EAAkB,QAAQwB,CAAgB;AACxD,MAAID,MAAU,MACVvB,EAAkB,OAAOuB,GAAO,CAAC,GAErCrB,EAA0B;AAAA,IAC9B,CAAC;AAED,aAASgB,IAAe;AACpB,YAAMrC,IAAO+B,EAAgB;AAC7B,MAAAC,EAAY,QAAQhC,GACpBkC,EAAM,MAAM,WAAWxB,EAAgBV,CAAI;AAAA,IAC/C;AAEA,aAASU,EAAgBV,GAAM;AAC3B,aAAIA,MAAS,SACF,KAEPA,MAAS,UACF,KAEJ2B,EAAc;AAAA,IACzB;AAEA,aAASQ,EAA6BS,GAAO;AACzC,MAAI,CAACA,KAASZ,EAAY,UAAU,WAGpCE,EAAM,MAAM,WAAWU,EAAM;AAAA,IACjC;AAEA,aAASL,EAA6B9B,GAAU;AAC5C,eAAS,gBAAgB,aAAa,aAAaA,CAAQ;AAAA,IAC/D;AAEA,aAAS+B,GAAoBK,GAAY;AACrC,UAAIjB,EAA0B,SAAS;AACnC,QAAAiB,EAAU;AACV;AAAA,MACJ;AACA,YAAMC,IAAsB,SAAS,qBAAqB,KAAK,QAAQ;AACvE,UAAIA,GAAqB;AACrB,QAAAA,EAAoB,MAAM;AACtB,UAAAD,EAAU;AAAA,QACd,CAAC;AACD;AAAA,MACJ;AACA,MAAAA,EAAU;AACV,YAAME,IAAU,SAAS;AACzB,MAAI,OAAOA,EAAQ,WAAY,cAG/B,OAAO,sBAAsB,MAAM;AAC/B,QAAAA,EAAQ,QAAQ,CAAC,EAAE,SAAS,KAAI,GAAI,EAAE,SAAS,EAAC,CAAE,GAAG;AAAA,UACjD,UAAUC;AAAA,UACV,QAAQ;AAAA,QACpB,CAAS;AAAA,MACL,CAAC;AAAA,IACL;AAEA,aAASjB,IAAmB;AACxB,aAAOd,EAAM,QAAQrB,EAAc,KAAM;AAAA,IAC7C;AAEA,IAAAqD,GAAQ,SAASf,CAAK;AAGtB,aAASgB,EAAaC,GAAK;AACvB,UAAI,CAACA,EAAK,QAAO;AACjB,YAAMC,IAAID,EAAI,KAAI,EAAG,YAAW;AAEhC,UAAI,CADM,kCAAkC,KAAKC,CAAC,EAC1C,QAAO;AACf,UAAIA,EAAE,WAAW,GAAG;AAEhB,cAAMC,IAAID,EAAE,CAAC,GACTE,IAAIF,EAAE,CAAC,GACPG,IAAIH,EAAE,CAAC;AACX,eAAO,IAAIC,CAAC,GAAGA,CAAC,GAAGC,CAAC,GAAGA,CAAC,GAAGC,CAAC,GAAGA,CAAC;AAAA,MACpC;AACA,aAAOH;AAAA,IACX;AAEA,aAASI,GAASL,GAAK;AACnB,YAAMC,IAAIF,EAAaC,CAAG;AAC1B,UAAI,CAACC,EAAG,QAAO;AACf,YAAM,IAAI,SAASA,EAAE,MAAM,GAAG,CAAC,GAAG,EAAE,GAC9BE,IAAI,SAASF,EAAE,MAAM,GAAG,CAAC,GAAG,EAAE,GAC9BG,IAAI,SAASH,EAAE,MAAM,GAAG,CAAC,GAAG,EAAE;AACpC,aAAO,EAAE,GAAG,GAAAE,GAAG,GAAAC,EAAC;AAAA,IACpB;AAEA,aAASE,GAAS,EAAE,GAAAJ,GAAG,GAAAC,GAAG,GAAAC,EAAC,GAAI;AAC3B,YAAMG,IAAQ,CAAChC,MAAUA,EAAM,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AAC3D,aAAO,IAAIgC,EAAML,CAAC,CAAC,GAAGK,EAAMJ,CAAC,CAAC,GAAGI,EAAMH,CAAC,CAAC;AAAA,IAC7C;AAEA,aAASI,EAAQjC,GAAO;AACpB,aAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAGA,CAAK,CAAC;AAAA,IACzC;AAEA,aAASkC,EAAoBC,GAAS;AAClC,aAAIA,KAAW,UACJA,IAAU,QAEd,KAAK,KAAKA,IAAU,SAAS,OAAO,GAAG;AAAA,IAClD;AAEA,aAASC,EAAoBD,GAAS;AAClC,YAAME,IAAaJ,EAAQE,CAAO;AAClC,aAAIE,KAAc,WACP,QAAQA,IAEZ,QAAQ,KAAK,IAAIA,GAAY,IAAI,GAAG,IAAI;AAAA,IACnD;AAEA,aAASC,GAAW,EAAE,GAAAX,GAAG,GAAAC,GAAG,GAAAC,EAAC,GAAI;AAC7B,YAAMU,IAAQZ,IAAI,KACZa,IAAQZ,IAAI,KACZa,IAAQZ,IAAI,KAEZa,IAAOR,EAAoBK,CAAK,GAChCI,IAAOT,EAAoBM,CAAK,GAChCI,IAAOV,EAAoBO,CAAK,GAEhCI,IAAI,eAAeH,IAAO,eAAeC,IAAO,eAAeC,GAC/DE,IAAI,eAAeJ,IAAO,eAAeC,IAAO,eAAeC,GAC/DG,IAAI,eAAeL,IAAO,eAAeC,IAAO,eAAeC,GAE/DI,IAAQ,KAAK,KAAKH,CAAC,GACnBI,IAAQ,KAAK,KAAKH,CAAC,GACnBI,IAAQ,KAAK,KAAKH,CAAC,GAEnBI,IACF,eAAeH,IAAQ,cAAcC,IAAQ,eAAeC,GAC1DE,IACF,eAAeJ,IAAQ,cAAcC,IAAQ,eAAeC,GAC1DG,IACF,eAAeL,IAAQ,eAAeC,IAAQ,cAAcC,GAE1DI,IAAS,KAAK,KAAKF,IAASA,IAASC,IAASA,CAAM;AAC1D,UAAIE,IAAM,KAAK,MAAMF,GAAQD,CAAM,KAAK,MAAM,KAAK;AACnD,aAAIG,IAAM,MACNA,KAAO,MAGJ,EAAE,GAAGJ,GAAQ,GAAGG,GAAQ,GAAGC,EAAG;AAAA,IACzC;AAEA,aAASC,EAAeX,GAAGY,GAAG/B,GAAGgC,IAAc,IAAO;AAClD,YAAMC,IAASjC,IAAI,KAAK,KAAM,KACxBkC,IAAIH,IAAI,KAAK,IAAIE,CAAK,GACtB9B,IAAI4B,IAAI,KAAK,IAAIE,CAAK,GAEtBE,IAAahB,IAAI,eAAee,IAAI,eAAe/B,GACnDiC,IAAajB,IAAI,eAAee,IAAI,eAAe/B,GACnDkC,IAAalB,IAAI,eAAee,IAAI,cAAc/B,GAElDmC,IAAQN,IAAczB,EAAQ4B,CAAU,IAAIA,GAC5CI,IAAQP,IAAczB,EAAQ6B,CAAU,IAAIA,GAC5CI,IAAQR,IAAczB,EAAQ8B,CAAU,IAAIA;AAElD,UAAI,CAACL,MAEGM,IAAQ,SACRA,IAAQ,UACRC,IAAQ,SACRA,IAAQ,UACRC,IAAQ,SACRA,IAAQ;AAER,eAAO;AAIf,YAAMC,IAAOH,IAAQA,IAAQA,GACvBI,IAAOH,IAAQA,IAAQA,GACvBI,IAAOH,IAAQA,IAAQA;AAE7B,UAAIxB,IAAO,eAAeyB,IAAO,eAAeC,IAAO,eAAeC,GAClE1B,IAAO,gBAAgBwB,IAAO,eAAeC,IAAO,eAAeC,GACnEzB,IAAO,gBAAgBuB,IAAO,eAAeC,IAAO,cAAcC;AAEtE,UAAIX;AACA,QAAAhB,IAAOT,EAAQS,CAAI,GACnBC,IAAOV,EAAQU,CAAI,GACnBC,IAAOX,EAAQW,CAAI;AAAA,eAGfF,IAAO,SACPA,IAAO,UACPC,IAAO,SACPA,IAAO,UACPC,IAAO,SACPA,IAAO;AAEP,eAAO;AAIf,YAAMjB,IAAIM,EAAQG,EAAoBM,CAAI,CAAC,GACrCd,KAAIK,EAAQG,EAAoBO,CAAI,CAAC,GACrC2B,KAASrC,EAAQG,EAAoBQ,CAAI,CAAC;AAEhD,aAAO;AAAA,QACH,GAAG,KAAK,MAAMjB,IAAI,GAAG;AAAA,QACrB,GAAG,KAAK,MAAMC,KAAI,GAAG;AAAA,QACrB,GAAG,KAAK,MAAM0C,KAAS,GAAG;AAAA,MAClC;AAAA,IACA;AAEA,aAASC,GAAY1B,GAAGY,GAAG/B,GAAG;AAC1B,UAAI4B,IAASG;AACb,eAASe,IAAU,GAAGA,IAAU,GAAGA,KAAW,GAAG;AAC7C,cAAMC,IAAMjB,EAAeX,GAAGS,GAAQ5B,CAAC;AACvC,YAAI+C;AACA,iBAAOA;AAEX,QAAAnB,KAAU;AAAA,MACd;AACA,aAAOE,EAAeX,GAAGZ,EAAQqB,CAAM,GAAG5B,GAAG,EAAI,KAAK,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAC;AAAA,IAC5E;AAEA,aAASgD,GAAeC,GAAS;AAC7B,YAAMC,IAAOpD,EAAamD,CAAO;AACjC,UAAI,CAACC,EAAM,QAAO;AAClB,YAAMC,IAAU/C,GAAS8C,CAAI;AAC7B,UAAI,CAACC,EAAS,QAAO;AACrB,YAAMC,IAAYxC,GAAWuC,CAAO,GAC9BE,IAAa;AAAA,QACf,KAAK,EAAE,WAAW,MAAM,QAAQ,KAAI;AAAA,QACpC,KAAK,EAAE,WAAW,MAAM,QAAQ,IAAG;AAAA,QACnC,KAAK,EAAE,WAAW,MAAM,QAAQ,IAAG;AAAA,QACnC,KAAK,EAAE,WAAW,MAAM,QAAQ,KAAI;AAAA,QACpC,KAAK,EAAE,WAAW,MAAM,QAAQ,IAAG;AAAA,QACnC,KAAK,EAAE,WAAW,GAAG,QAAQ,GAAG,MAAM,GAAI;AAAA,QAC1C,KAAK,EAAE,WAAW,OAAO,QAAQ,KAAI;AAAA,QACrC,KAAK,EAAE,WAAW,OAAO,QAAQ,IAAG;AAAA,QACpC,KAAK,EAAE,WAAW,OAAO,QAAQ,KAAI;AAAA,QACrC,KAAM,EAAE,WAAW,OAAO,QAAQ,IAAG;AAAA,MAC7C,GACUC,IAAS,CAAA,GAETC,IAAkB,CAACC,MACjBA,MAAmB,IACZJ,EAAU,IAEjBI,IAAiB,IACVjD,EAAQ6C,EAAU,IAAII,KAAkB,IAAIJ,EAAU,EAAE,IAE5D7C,EAAQ6C,EAAU,KAAK,IAAII,EAAe,GAG/CC,IAAe,CAACC,MAAgB;AAClC,YAAIA,MAAgB;AAChB,iBAAON,EAAU;AAErB,cAAMO,IAASP,EAAU,IAAIM;AAC7B,eAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAKC,CAAM,CAAC;AAAA,MAC5C;AAEA,oBAAO,QAAQN,CAAU,EAAE,QAAQ,CAAC,CAACO,GAAMC,CAAM,MAAM;AACnD,cAAMC,IAAY,iBAAiBF,CAAI;AACvC,YAAIC,EAAO,MAAM;AACb,UAAAP,EAAOQ,CAAS,IAAIZ;AACpB;AAAA,QACJ;AACA,cAAMa,IAAQR,EAAgBM,EAAO,SAAS,GACxCG,IAAQP,EAAaI,EAAO,MAAM,GAClCI,IAAUpB,GAAYkB,GAAOC,GAAOZ,EAAU,CAAC;AACrD,QAAAE,EAAOQ,CAAS,IAAIzD,GAAS4D,CAAO;AAAA,MACxC,CAAC,GACMX;AAAA,IACX;AAEA,UAAMY,IAAYC,EAAS,MAAMnB,GAAenF,EAAM,WAAW,KAAK,EAAE,GAClEuG,KAAaD,EAAS,MAAMD,EAAU,KAAK,GAE3C3E,IAAmB;AAAA,MACrB,MAAM,CAAA;AAAA,MACN,SAAS,EAAQ1B,EAAM;AAAA,IAC3B;AACA,WAAAE,EAAkB,KAAKwB,CAAgB,GAEvCP;AAAA,MACI,MAAMnB,EAAM;AAAA,MACZ,CAACwG,MAAY;AACT,QAAA9E,EAAiB,UAAU,EAAQ8E,GACnCpG,EAA0B;AAAA,MAC9B;AAAA,MACA,EAAE,WAAW,GAAI;AAAA,IACrB,GAEAe;AAAA,MACIkF;AAAA,MACA,CAACI,MAAS;AACN,QAAIA,KAAQ,OAAO,KAAKA,CAAI,EAAE,SAAS,IACnC/E,EAAiB,OAAO,EAAE,GAAG+E,EAAI,IAEjC/E,EAAiB,OAAO,CAAA,GAE5BtB,EAA0B;AAAA,MAC9B;AAAA,MACA,EAAE,WAAW,GAAI;AAAA,IACrB,mBAhaIsG,GAEK,OAAA;AAAA,MAFA,OAAM;AAAA,MAAS,UAAOH,GAAA,KAAU;AAAA;MACjCI,GAAOC,EAAA,QAAA,SAAA;AAAA;;;;;;;;;;;;;;;;;;AC+Cf,UAAMC,IALe;AAAA,MACjB,EAAE,OAAO,QAAQ,OAAO,SAAQ;AAAA,MAChC,EAAE,OAAO,SAAS,OAAO,QAAO;AAAA,MAChC,EAAE,OAAO,QAAQ,OAAO,OAAM;AAAA,IAClC,EACiC,OAAO,CAACC,GAAKC,OAC1CD,EAAIC,EAAO,KAAK,IAAIA,EAAO,OACpBD,IACR,EAAE,GACCE,IAAczI,GAEdyB,IAAQC,GAORgH,IAAOC;AAEb,IAAA5H,EAAyB;AAEzB,UAAM6H,IAAOnG,EAAI,EAAK,GAChBH,IAAclC,OAAoBqB,EAAM,MACxCoH,IAAepG;AAAA,MACjBgG,EAAY,SAASnG,CAAW,IAAIA,IAAc;AAAA,IACtD;AACc,WAAAyF;AAAA,MACV,MAAMO,EAAYO,EAAa,KAAK,KAAKP,EAAY;AAAA,IACzD,GAEA1F;AAAA,MACI,MAAMnB,EAAM;AAAA,MACZ,CAACjB,MAAS;AACN,QAAIiI,EAAY,SAASjI,CAAI,KAAKA,MAASqI,EAAa,UACpDA,EAAa,QAAQrI;AAAA,MAE7B;AAAA,IACJ,GAEAoC;AAAA,MACIiG;AAAA,MACA,CAACrI,MAAS;AACN,YAAI,CAACiI,EAAY,SAASjI,CAAI,GAAG;AAC7B,UAAAqI,EAAa,QAAQ;AACrB;AAAA,QACJ;AACA,QAAAD,EAAK,QAAQ,IACbF,EAAK,eAAelI,CAAI,GACxBD,GAAgBC,CAAI;AAAA,MACxB;AAAA,MACA,EAAE,WAAW,GAAI;AAAA,IACrB,mBA/FIsI,GA0BeC,EAAAC,EAAA,GAAA;AAAA,MAzBH,MAAMJ,EAAA;AAAA,8CAAAA,EAAI,QAAAK;AAAA,MAClB,MAAK;AAAA,MACL,cAAW;AAAA;iBAEX,MAoBoB;AAAA,QApBpBC,EAoBoBH,EAAAI,EAAA,GAAA,EApBD,OAAM,QAAO,GAAA;AAAA,qBAC5B,MAKE;AAAA,YALFD,EAKEH,EAAAK,CAAA,GAAA;AAAA,cAJU,SAASP,EAAA;AAAA,yDAAAA,EAAY,QAAAI;AAAA,cAC7B,OAAM;AAAA,cACL,OAAOF,EAAAT,CAAA,EAAY;AAAA,cACnB,cAAU,GAAKS,EAAAT,CAAA,EAAY,IAAI;AAAA;4BAEpCe,GAAsD,MAAA;AAAA,cAAlD,OAAM;AAAA,cAAyB,MAAK;AAAA;YACxCH,EAKEH,EAAAK,CAAA,GAAA;AAAA,cAJU,SAASP,EAAA;AAAA,yDAAAA,EAAY,QAAAI;AAAA,cAC7B,OAAM;AAAA,cACL,OAAOF,EAAAT,CAAA,EAAY;AAAA,cACnB,cAAU,GAAKS,EAAAT,CAAA,EAAY,KAAK;AAAA;YAErCY,EAKEH,EAAAK,CAAA,GAAA;AAAA,cAJU,SAASP,EAAA;AAAA,yDAAAA,EAAY,QAAAI;AAAA,cAC7B,OAAM;AAAA,cACL,OAAOF,EAAAT,CAAA,EAAY;AAAA,cACnB,cAAU,GAAKS,EAAAT,CAAA,EAAY,IAAI;AAAA;;;;;;;;;"}
1
+ {"version":3,"file":"theme.es.js","sources":["../src/modeStorage.js","../src/portalHost.js","../src/Theme.vue","../src/ThemeSwitcher.vue"],"sourcesContent":["const VALID_THEME_MODES = [\"auto\", \"light\", \"dark\"];\nconst STORAGE_KEY = \"gospore-theme-mode\";\nconst ONE_YEAR_IN_SECONDS = 60 * 60 * 24 * 365;\nconst DARK_MODE_QUERY = \"(prefers-color-scheme: dark)\";\n\nexport function readStoredMode() {\n if (typeof document === \"undefined\") {\n return null;\n }\n const stored = getCookie(STORAGE_KEY);\n return stored && VALID_THEME_MODES.includes(stored) ? stored : null;\n}\n\nexport function writeStoredMode(mode) {\n if (typeof document === \"undefined\" || !VALID_THEME_MODES.includes(mode)) {\n return;\n }\n const hostname =\n typeof window !== \"undefined\" ? window.location.hostname : \"\";\n const protocol =\n typeof window !== \"undefined\" ? window.location.protocol : \"\";\n const domain = getCookieDomain(hostname);\n const secure = protocol === \"https:\";\n const attributes = [\n \"path=/\",\n `max-age=${ONE_YEAR_IN_SECONDS}`,\n \"SameSite=Lax\",\n ];\n if (domain) {\n attributes.push(`domain=${domain}`);\n }\n if (secure) {\n attributes.push(\"Secure\");\n }\n document.cookie = [\n `${encodeURIComponent(STORAGE_KEY)}=${encodeURIComponent(mode)}`,\n ...attributes,\n ].join(\"; \");\n}\n\nexport function applyStoredModeToDocument(mode) {\n if (typeof document === \"undefined\") {\n return;\n }\n const resolvedMode =\n typeof mode === \"string\" && VALID_THEME_MODES.includes(mode)\n ? mode\n : readStoredMode() ?? \"auto\";\n console.log(\"Applying theme mode:\", resolvedMode);\n const darkMode = resolveDarkMode(resolvedMode);\n document.documentElement.setAttribute(\"dark-mode\", darkMode);\n}\n\nexport { VALID_THEME_MODES, STORAGE_KEY };\n\nfunction getCookie(name) {\n if (typeof document === \"undefined\" || !document.cookie) {\n return null;\n }\n const encodedName = `${encodeURIComponent(name)}=`;\n const cookies = document.cookie.split(\"; \");\n for (const cookie of cookies) {\n if (cookie.startsWith(encodedName)) {\n return decodeURIComponent(cookie.slice(encodedName.length));\n }\n }\n return null;\n}\n\nfunction getCookieDomain(hostname) {\n if (!hostname || hostname === \"localhost\") {\n return null;\n }\n const isIpAddress = /^\\d+(?:\\.\\d+){3}$/.test(hostname);\n if (isIpAddress) {\n return hostname;\n }\n const parts = hostname.split(\".\");\n if (parts.length <= 1) {\n return null;\n }\n if (parts.length === 2) {\n return hostname;\n }\n return parts.slice(-2).join(\".\");\n}\n\nfunction resolveDarkMode(mode) {\n if (mode === \"dark\") {\n return true;\n }\n if (mode === \"light\") {\n return false;\n }\n if (typeof window === \"undefined\") {\n return false;\n }\n try {\n const mediaQueryList =\n typeof window.matchMedia === \"function\"\n ? window.matchMedia(DARK_MODE_QUERY)\n : null;\n return mediaQueryList ? mediaQueryList.matches : false;\n } catch (error) {\n return false;\n }\n}\n","import { computed, inject } from \"vue\";\n\nexport const themePortalHostKey = Symbol.for(\"gospore.theme.portalHost\");\n\nexport function useThemePortalTarget() {\n const hostRef = inject(themePortalHostKey, null);\n console.log(\"Using theme portal host:\", hostRef);\n const fallbackTarget =\n typeof document !== \"undefined\" ? document.body : \"body\";\n\n return computed(() => hostRef?.value ?? fallbackTarget);\n}\n","<template>\n <div class=\"theme\" :style=\"brandStyle\">\n <slot />\n <div ref=\"portalHost\" class=\"theme__portal-host\"></div>\n </div>\n</template>\n\n<script setup>\nimport { provide, ref, watch, onBeforeUnmount, computed } from \"vue\";\nimport { applyStoredModeToDocument, readStoredMode } from \"./modeStorage\";\nimport \"what-input\";\nimport { themePortalHostKey } from \"./portalHost\";\n\ndefineOptions({\n name: \"Theme\",\n});\nconst props = defineProps({\n mode: {\n type: String,\n validator: (value) => [\"auto\", \"light\", \"dark\"].includes(value),\n },\n /**\n * Optional hex accent color (\"#RRGGBB\" or \"#RGB\"). When provided,\n * Theme derives the `--color-brand-*` palette and exposes the tokens on\n * the root .theme element (and the global document for portals).\n */\n accentColor: {\n type: String,\n required: false,\n default: undefined,\n },\n /**\n * When true the brand vars are also exposed on <html>, allowing portals\n * attached outside the Theme subtree to inherit the accent colors.\n */\n exposeGlobalAccent: {\n type: Boolean,\n default: false,\n },\n});\n\nconst globalAccentStack = [];\nconst appliedGlobalAccentKeys = new Set();\n\nfunction applyGlobalAccentFromStack() {\n const root = document.documentElement;\n if (!root) {\n return;\n }\n\n appliedGlobalAccentKeys.forEach((key) => {\n root.style.removeProperty(key);\n });\n appliedGlobalAccentKeys.clear();\n\n const activeEntry = [...globalAccentStack]\n .reverse()\n .find(\n (entry) =>\n entry.enabled &&\n entry.vars &&\n Object.keys(entry.vars).length > 0,\n );\n\n if (!activeEntry) {\n return;\n }\n\n Object.entries(activeEntry.vars).forEach(([key, value]) => {\n root.style.setProperty(key, value);\n appliedGlobalAccentKeys.add(key);\n });\n}\n\nconst DARK_MODE_QUERY = \"(prefers-color-scheme: dark)\";\nconst PREFERS_REDUCED_MOTION_QUERY = \"(prefers-reduced-motion: reduce)\";\nconst THEME_TRANSITION_DURATION = 200;\nconst darkModeMedia = window.matchMedia(DARK_MODE_QUERY);\nconst prefersReducedMotionMedia = window.matchMedia(\n PREFERS_REDUCED_MOTION_QUERY,\n);\n\nconst initialMode = getEffectiveMode();\napplyStoredModeToDocument(initialMode);\n\nconst currentMode = ref(initialMode);\n\nconst theme = ref({\n darkMode: resolveDarkMode(initialMode),\n});\nconst portalHost = ref(null);\n\ndarkModeMedia.addEventListener(\"change\", handleSystemPreferenceChange);\n\nwatch(\n () => props.mode,\n () => {\n syncDarkMode();\n },\n { immediate: true },\n);\n\nwatch(\n () => theme.value.darkMode,\n (darkMode, previousValue) => {\n if (previousValue === undefined) {\n setDocumentDarkModeAttribute(darkMode);\n return;\n }\n withThemeTransition(() => {\n setDocumentDarkModeAttribute(darkMode);\n });\n },\n { immediate: true },\n);\n\nonBeforeUnmount(() => {\n darkModeMedia.removeEventListener(\"change\", handleSystemPreferenceChange);\n const index = globalAccentStack.indexOf(accentStackEntry);\n if (index !== -1) {\n globalAccentStack.splice(index, 1);\n }\n applyGlobalAccentFromStack();\n});\n\nfunction syncDarkMode() {\n const mode = getEffectiveMode();\n currentMode.value = mode;\n theme.value.darkMode = resolveDarkMode(mode);\n}\n\nfunction resolveDarkMode(mode) {\n if (mode === \"dark\") {\n return true;\n }\n if (mode === \"light\") {\n return false;\n }\n return darkModeMedia.matches;\n}\n\nfunction handleSystemPreferenceChange(event) {\n if (!event || currentMode.value !== \"auto\") {\n return;\n }\n theme.value.darkMode = event.matches;\n}\n\nfunction setDocumentDarkModeAttribute(darkMode) {\n document.documentElement.setAttribute(\"dark-mode\", darkMode);\n}\n\nfunction withThemeTransition(applyTheme) {\n if (prefersReducedMotionMedia.matches) {\n applyTheme();\n return;\n }\n const startViewTransition = document.startViewTransition?.bind(document);\n if (startViewTransition) {\n startViewTransition(() => {\n applyTheme();\n });\n return;\n }\n applyTheme();\n const element = document.documentElement;\n if (typeof element.animate !== \"function\") {\n return;\n }\n window.requestAnimationFrame(() => {\n element.animate([{ opacity: 0.85 }, { opacity: 1 }], {\n duration: THEME_TRANSITION_DURATION,\n easing: \"ease-in-out\",\n });\n });\n}\n\nfunction getEffectiveMode() {\n return props.mode ?? readStoredMode() ?? \"auto\";\n}\n\nprovide(\"theme\", theme);\nprovide(themePortalHostKey, portalHost);\n\n// --- Accent helpers -------------------------------------------------------\nfunction normalizeHex(hex) {\n if (!hex) return null;\n const h = hex.trim().toLowerCase();\n const m = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i.exec(h);\n if (!m) return null;\n if (h.length === 4) {\n // expand #rgb -> #rrggbb\n const r = h[1],\n g = h[2],\n b = h[3];\n return `#${r}${r}${g}${g}${b}${b}`;\n }\n return h;\n}\n\nfunction hexToRgb(hex) {\n const h = normalizeHex(hex);\n if (!h) return null;\n const r = parseInt(h.slice(1, 3), 16);\n const g = parseInt(h.slice(3, 5), 16);\n const b = parseInt(h.slice(5, 7), 16);\n return { r, g, b };\n}\n\nfunction rgbToHex({ r, g, b }) {\n const toHex = (value) => value.toString(16).padStart(2, \"0\");\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`;\n}\n\nfunction clamp01(value) {\n return Math.max(0, Math.min(1, value));\n}\n\nfunction srgbChannelToLinear(channel) {\n if (channel <= 0.04045) {\n return channel / 12.92;\n }\n return Math.pow((channel + 0.055) / 1.055, 2.4);\n}\n\nfunction linearChannelToSrgb(channel) {\n const normalized = clamp01(channel);\n if (normalized <= 0.0031308) {\n return 12.92 * normalized;\n }\n return 1.055 * Math.pow(normalized, 1 / 2.4) - 0.055;\n}\n\nfunction rgbToOklch({ r, g, b }) {\n const rNorm = r / 255;\n const gNorm = g / 255;\n const bNorm = b / 255;\n\n const rLin = srgbChannelToLinear(rNorm);\n const gLin = srgbChannelToLinear(gNorm);\n const bLin = srgbChannelToLinear(bNorm);\n\n const l = 0.4122214708 * rLin + 0.5363325363 * gLin + 0.0514459929 * bLin;\n const m = 0.2119034982 * rLin + 0.6806995451 * gLin + 0.1073969566 * bLin;\n const s = 0.0883024619 * rLin + 0.2817188376 * gLin + 0.6299787005 * bLin;\n\n const lRoot = Math.cbrt(l);\n const mRoot = Math.cbrt(m);\n const sRoot = Math.cbrt(s);\n\n const oklabL =\n 0.2104542553 * lRoot + 0.793617785 * mRoot - 0.0040720468 * sRoot;\n const oklabA =\n 1.9779984951 * lRoot - 2.428592205 * mRoot + 0.4505937099 * sRoot;\n const oklabB =\n 0.0259040371 * lRoot + 0.7827717662 * mRoot - 0.808675766 * sRoot;\n\n const chroma = Math.sqrt(oklabA * oklabA + oklabB * oklabB);\n let hue = Math.atan2(oklabB, oklabA) * (180 / Math.PI);\n if (hue < 0) {\n hue += 360;\n }\n\n return { l: oklabL, c: chroma, h: hue };\n}\n\nfunction tryOklchToSrgb(l, c, h, clampLinear = false) {\n const angle = (h * Math.PI) / 180;\n const a = c * Math.cos(angle);\n const b = c * Math.sin(angle);\n\n const lComponent = l + 0.3963377774 * a + 0.2158037573 * b;\n const mComponent = l - 0.1055613458 * a - 0.0638541728 * b;\n const sComponent = l - 0.0894841775 * a - 1.291485548 * b;\n\n const lCube = clampLinear ? clamp01(lComponent) : lComponent;\n const mCube = clampLinear ? clamp01(mComponent) : mComponent;\n const sCube = clampLinear ? clamp01(sComponent) : sComponent;\n\n if (!clampLinear) {\n const outOfRange =\n lCube < -0.0001 ||\n lCube > 1.0001 ||\n mCube < -0.0001 ||\n mCube > 1.0001 ||\n sCube < -0.0001 ||\n sCube > 1.0001;\n if (outOfRange) {\n return null;\n }\n }\n\n const lLin = lCube * lCube * lCube;\n const mLin = mCube * mCube * mCube;\n const sLin = sCube * sCube * sCube;\n\n let rLin = 4.0767416621 * lLin - 3.3077115913 * mLin + 0.2309699292 * sLin;\n let gLin = -1.2684380046 * lLin + 2.6097574011 * mLin - 0.3413193965 * sLin;\n let bLin = -0.0041960863 * lLin - 0.7034186147 * mLin + 1.707614701 * sLin;\n\n if (clampLinear) {\n rLin = clamp01(rLin);\n gLin = clamp01(gLin);\n bLin = clamp01(bLin);\n } else {\n const outOfRange =\n rLin < -0.0001 ||\n rLin > 1.0001 ||\n gLin < -0.0001 ||\n gLin > 1.0001 ||\n bLin < -0.0001 ||\n bLin > 1.0001;\n if (outOfRange) {\n return null;\n }\n }\n\n const r = clamp01(linearChannelToSrgb(rLin));\n const g = clamp01(linearChannelToSrgb(gLin));\n const bValue = clamp01(linearChannelToSrgb(bLin));\n\n return {\n r: Math.round(r * 255),\n g: Math.round(g * 255),\n b: Math.round(bValue * 255),\n };\n}\n\nfunction oklchToSrgb(l, c, h) {\n let chroma = c;\n for (let attempt = 0; attempt < 8; attempt += 1) {\n const rgb = tryOklchToSrgb(l, chroma, h);\n if (rgb) {\n return rgb;\n }\n chroma *= 0.9;\n }\n return tryOklchToSrgb(l, clamp01(chroma), h, true) || { r: 0, g: 0, b: 0 };\n}\n\nfunction makeBrandScale(baseHex) {\n const norm = normalizeHex(baseHex);\n if (!norm) return null;\n const baseRgb = hexToRgb(norm);\n if (!baseRgb) return null;\n const baseOklch = rgbToOklch(baseRgb);\n const toneConfig = {\n 100: { lightness: 0.35, chroma: 0.45 },\n 200: { lightness: 0.28, chroma: 0.5 },\n 300: { lightness: 0.22, chroma: 0.6 },\n 400: { lightness: 0.16, chroma: 0.75 },\n 500: { lightness: 0.08, chroma: 0.9 },\n 600: { lightness: 0, chroma: 1, base: true },\n 700: { lightness: -0.08, chroma: 1.05 },\n 800: { lightness: -0.18, chroma: 1.1 },\n 900: { lightness: -0.28, chroma: 1.15 },\n 1000: { lightness: -0.35, chroma: 1.2 },\n };\n const tokens = {};\n\n const adjustLightness = (lightnessValue) => {\n if (lightnessValue === 0) {\n return baseOklch.l;\n }\n if (lightnessValue > 0) {\n return clamp01(baseOklch.l + lightnessValue * (1 - baseOklch.l));\n }\n return clamp01(baseOklch.l * (1 + lightnessValue));\n };\n\n const adjustChroma = (chromaScale) => {\n if (chromaScale === 1) {\n return baseOklch.c;\n }\n const scaled = baseOklch.c * chromaScale;\n return Math.max(0, Math.min(0.4, scaled));\n };\n\n Object.entries(toneConfig).forEach(([stop, config]) => {\n const tokenName = `--color-brand-${stop}`;\n if (config.base) {\n tokens[tokenName] = norm;\n return;\n }\n const toneL = adjustLightness(config.lightness);\n const toneC = adjustChroma(config.chroma);\n const toneRgb = oklchToSrgb(toneL, toneC, baseOklch.h);\n tokens[tokenName] = rgbToHex(toneRgb);\n });\n return tokens;\n}\n\nconst brandVars = computed(() => makeBrandScale(props.accentColor) ?? {});\nconst brandStyle = computed(() => brandVars.value);\n\nconst accentStackEntry = {\n vars: {},\n enabled: Boolean(props.exposeGlobalAccent),\n};\nglobalAccentStack.push(accentStackEntry);\n\nwatch(\n () => props.exposeGlobalAccent,\n (enabled) => {\n accentStackEntry.enabled = Boolean(enabled);\n applyGlobalAccentFromStack();\n },\n { immediate: true },\n);\n\nwatch(\n brandVars,\n (vars) => {\n if (vars && Object.keys(vars).length > 0) {\n accentStackEntry.vars = { ...vars };\n } else {\n accentStackEntry.vars = {};\n }\n applyGlobalAccentFromStack();\n },\n { immediate: true },\n);\n</script>\n\n<style lang=\"less\">\n@import \"index.less\";\n</style>\n","<template>\n <DropdownMenu\n v-model:open=\"open\"\n text=\"Theme\"\n aria-label=\"Select theme mode\"\n >\n <DropdownItemGroup title=\"Theme\">\n <DropdownItemRadio\n v-model:checked=\"internalMode\"\n value=\"auto\"\n :label=\"MODE_LABELS.auto\"\n :aria-label=\"`${MODE_LABELS.auto} mode`\"\n />\n <hr class=\"theme-switcher-divider\" role=\"separator\" />\n <DropdownItemRadio\n v-model:checked=\"internalMode\"\n value=\"light\"\n :label=\"MODE_LABELS.light\"\n :aria-label=\"`${MODE_LABELS.light} mode`\"\n />\n <DropdownItemRadio\n v-model:checked=\"internalMode\"\n value=\"dark\"\n :label=\"MODE_LABELS.dark\"\n :aria-label=\"`${MODE_LABELS.dark} mode`\"\n />\n </DropdownItemGroup>\n </DropdownMenu>\n</template>\n\n<script setup>\nimport { ref, computed, watch } from \"vue\";\nimport {\n DropdownMenu,\n DropdownItemGroup,\n DropdownItemRadio,\n} from \"@gospore/dropdown-menu\";\nimport {\n readStoredMode,\n writeStoredMode,\n VALID_THEME_MODES,\n applyStoredModeToDocument,\n} from \"./modeStorage\";\n\nconst MODE_OPTIONS = [\n { value: \"auto\", label: \"System\" },\n { value: \"light\", label: \"Light\" },\n { value: \"dark\", label: \"Dark\" },\n];\nconst MODE_LABELS = MODE_OPTIONS.reduce((map, option) => {\n map[option.value] = option.label;\n return map;\n}, {});\nconst VALID_MODES = VALID_THEME_MODES;\n\nconst props = defineProps({\n mode: {\n type: String,\n default: \"auto\",\n validator: (value) => [\"auto\", \"light\", \"dark\"].includes(value),\n },\n});\nconst emit = defineEmits([\"update:mode\"]);\n\napplyStoredModeToDocument();\n\nconst open = ref(false);\nconst initialMode = readStoredMode() ?? props.mode;\nconst internalMode = ref(\n VALID_MODES.includes(initialMode) ? initialMode : \"auto\",\n);\nconst label = computed(\n () => MODE_LABELS[internalMode.value] ?? MODE_LABELS.auto,\n);\n\nwatch(\n () => props.mode,\n (mode) => {\n if (VALID_MODES.includes(mode) && mode !== internalMode.value) {\n internalMode.value = mode;\n }\n },\n);\n\nwatch(\n internalMode,\n (mode) => {\n if (!VALID_MODES.includes(mode)) {\n internalMode.value = \"auto\";\n return;\n }\n open.value = false;\n emit(\"update:mode\", mode);\n writeStoredMode(mode);\n },\n { immediate: true },\n);\n</script>\n\n<style scoped lang=\"less\">\n.theme-switcher-divider {\n margin: 4px 0;\n}\n</style>\n"],"names":["VALID_THEME_MODES","STORAGE_KEY","ONE_YEAR_IN_SECONDS","DARK_MODE_QUERY","readStoredMode","stored","getCookie","writeStoredMode","mode","hostname","protocol","domain","getCookieDomain","secure","attributes","applyStoredModeToDocument","resolvedMode","darkMode","resolveDarkMode","name","encodedName","cookies","cookie","parts","mediaQueryList","themePortalHostKey","useThemePortalTarget","hostRef","inject","fallbackTarget","computed","props","__props","globalAccentStack","appliedGlobalAccentKeys","applyGlobalAccentFromStack","root","key","activeEntry","entry","value","darkModeMedia","prefersReducedMotionMedia","PREFERS_REDUCED_MOTION_QUERY","initialMode","getEffectiveMode","currentMode","ref","theme","portalHost","handleSystemPreferenceChange","watch","syncDarkMode","previousValue","setDocumentDarkModeAttribute","withThemeTransition","onBeforeUnmount","index","accentStackEntry","event","applyTheme","startViewTransition","element","THEME_TRANSITION_DURATION","provide","normalizeHex","hex","h","r","g","b","hexToRgb","rgbToHex","toHex","clamp01","srgbChannelToLinear","channel","linearChannelToSrgb","normalized","rgbToOklch","rNorm","gNorm","bNorm","rLin","gLin","bLin","l","m","s","lRoot","mRoot","sRoot","oklabL","oklabA","oklabB","chroma","hue","tryOklchToSrgb","c","clampLinear","angle","a","lComponent","mComponent","sComponent","lCube","mCube","sCube","lLin","mLin","sLin","bValue","oklchToSrgb","attempt","rgb","makeBrandScale","baseHex","norm","baseRgb","baseOklch","toneConfig","tokens","adjustLightness","lightnessValue","adjustChroma","chromaScale","scaled","stop","config","tokenName","toneL","toneC","toneRgb","brandVars","brandStyle","enabled","vars","_createElementBlock","_renderSlot","_ctx","_createElementVNode","MODE_LABELS","map","option","VALID_MODES","emit","__emit","open","internalMode","_createBlock","_unref","DropdownMenu","$event","_createVNode","DropdownItemGroup","DropdownItemRadio"],"mappings":"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"}
package/dist/theme.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- (function(k,t){typeof exports=="object"&&typeof module<"u"?t(exports,require("vue"),require("what-input"),require("@gospore/dropdown-menu")):typeof define=="function"&&define.amd?define(["exports","vue","what-input","@gospore/dropdown-menu"],t):(k=typeof globalThis<"u"?globalThis:k||self,t(k.theme={},k.Vue,k.whatInput,k.DropdownMenu))})(this,function(k,t,pe,$){"use strict";const v=["auto","light","dark"],G="gospore-theme-mode",F="(prefers-color-scheme: dark)";function j(){if(typeof document>"u")return null;const o=J(G);return o&&v.includes(o)?o:null}function W(o){if(typeof document>"u"||!v.includes(o))return;const a=typeof window<"u"?window.location.hostname:"",i=typeof window<"u"?window.location.protocol:"",s=X(a),b=i==="https:",M=["path=/","max-age=31536000","SameSite=Lax"];s&&M.push(`domain=${s}`),b&&M.push("Secure"),document.cookie=[`${encodeURIComponent(G)}=${encodeURIComponent(o)}`,...M].join("; ")}function q(o){if(typeof document>"u")return;const a=typeof o=="string"&&v.includes(o)?o:j()??"auto";console.log("Applying theme mode:",a);const i=Z(a);document.documentElement.setAttribute("dark-mode",i)}function J(o){if(typeof document>"u"||!document.cookie)return null;const a=`${encodeURIComponent(o)}=`,i=document.cookie.split("; ");for(const s of i)if(s.startsWith(a))return decodeURIComponent(s.slice(a.length));return null}function X(o){if(!o||o==="localhost")return null;if(/^\d+(?:\.\d+){3}$/.test(o))return o;const i=o.split(".");return i.length<=1?null:i.length===2?o:i.slice(-2).join(".")}function Z(o){if(o==="dark")return!0;if(o==="light"||typeof window>"u")return!1;try{const a=typeof window.matchMedia=="function"?window.matchMedia(F):null;return a?a.matches:!1}catch{return!1}}const ee="(prefers-color-scheme: dark)",te="(prefers-reduced-motion: reduce)",ne=200,oe=Object.assign({name:"Theme"},{__name:"Theme",props:{mode:{type:String,validator:o=>["auto","light","dark"].includes(o)},accentColor:{type:String,required:!1,default:void 0},exposeGlobalAccent:{type:Boolean,default:!1}},setup(o){const a=o,i=[],s=new Set;function b(){const e=document.documentElement;if(!e)return;s.forEach(c=>{e.style.removeProperty(c)}),s.clear();const n=[...i].reverse().find(c=>c.enabled&&c.vars&&Object.keys(c.vars).length>0);n&&Object.entries(n.vars).forEach(([c,r])=>{e.style.setProperty(c,r),s.add(c)})}const M=window.matchMedia(ee),B=window.matchMedia(te),I=H();q(I);const N=t.ref(I),l=t.ref({darkMode:u(I)});M.addEventListener("change",w),t.watch(()=>a.mode,()=>{h()},{immediate:!0}),t.watch(()=>l.value.darkMode,(e,n)=>{if(n===void 0){Y(e);return}ce(()=>{Y(e)})},{immediate:!0}),t.onBeforeUnmount(()=>{M.removeEventListener("change",w);const e=i.indexOf(x);e!==-1&&i.splice(e,1),b()});function h(){const e=H();N.value=e,l.value.darkMode=u(e)}function u(e){return e==="dark"?!0:e==="light"?!1:M.matches}function w(e){!e||N.value!=="auto"||(l.value.darkMode=e.matches)}function Y(e){document.documentElement.setAttribute("dark-mode",e)}function ce(e){if(B.matches){e();return}const n=document.startViewTransition?.bind(document);if(n){n(()=>{e()});return}e();const c=document.documentElement;typeof c.animate=="function"&&window.requestAnimationFrame(()=>{c.animate([{opacity:.85},{opacity:1}],{duration:ne,easing:"ease-in-out"})})}function H(){return a.mode??j()??"auto"}t.provide("theme",l);function K(e){if(!e)return null;const n=e.trim().toLowerCase();if(!/^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i.exec(n))return null;if(n.length===4){const r=n[1],d=n[2],m=n[3];return`#${r}${r}${d}${d}${m}${m}`}return n}function ae(e){const n=K(e);if(!n)return null;const c=parseInt(n.slice(1,3),16),r=parseInt(n.slice(3,5),16),d=parseInt(n.slice(5,7),16);return{r:c,g:r,b:d}}function se({r:e,g:n,b:c}){const r=d=>d.toString(16).padStart(2,"0");return`#${r(e)}${r(n)}${r(c)}`}function p(e){return Math.max(0,Math.min(1,e))}function P(e){return e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)}function V(e){const n=p(e);return n<=.0031308?12.92*n:1.055*Math.pow(n,1/2.4)-.055}function ie({r:e,g:n,b:c}){const r=e/255,d=n/255,m=c/255,y=P(r),T=P(d),f=P(m),E=.4122214708*y+.5363325363*T+.0514459929*f,S=.2119034982*y+.6806995451*T+.1073969566*f,O=.0883024619*y+.2817188376*T+.6299787005*f,g=Math.cbrt(E),_=Math.cbrt(S),C=Math.cbrt(O),L=.2104542553*g+.793617785*_-.0040720468*C,R=1.9779984951*g-2.428592205*_+.4505937099*C,D=.0259040371*g+.7827717662*_-.808675766*C,A=Math.sqrt(R*R+D*D);let U=Math.atan2(D,R)*(180/Math.PI);return U<0&&(U+=360),{l:L,c:A,h:U}}function Q(e,n,c,r=!1){const d=c*Math.PI/180,m=n*Math.cos(d),y=n*Math.sin(d),T=e+.3963377774*m+.2158037573*y,f=e-.1055613458*m-.0638541728*y,E=e-.0894841775*m-1.291485548*y,S=r?p(T):T,O=r?p(f):f,g=r?p(E):E;if(!r&&(S<-1e-4||S>1.0001||O<-1e-4||O>1.0001||g<-1e-4||g>1.0001))return null;const _=S*S*S,C=O*O*O,L=g*g*g;let R=4.0767416621*_-3.3077115913*C+.2309699292*L,D=-1.2684380046*_+2.6097574011*C-.3413193965*L,A=-.0041960863*_-.7034186147*C+1.707614701*L;if(r)R=p(R),D=p(D),A=p(A);else if(R<-1e-4||R>1.0001||D<-1e-4||D>1.0001||A<-1e-4||A>1.0001)return null;const U=p(V(R)),fe=p(V(D)),me=p(V(A));return{r:Math.round(U*255),g:Math.round(fe*255),b:Math.round(me*255)}}function le(e,n,c){let r=n;for(let d=0;d<8;d+=1){const m=Q(e,r,c);if(m)return m;r*=.9}return Q(e,p(r),c,!0)||{r:0,g:0,b:0}}function ue(e){const n=K(e);if(!n)return null;const c=ae(n);if(!c)return null;const r=ie(c),d={100:{lightness:.35,chroma:.45},200:{lightness:.28,chroma:.5},300:{lightness:.22,chroma:.6},400:{lightness:.16,chroma:.75},500:{lightness:.08,chroma:.9},600:{lightness:0,chroma:1,base:!0},700:{lightness:-.08,chroma:1.05},800:{lightness:-.18,chroma:1.1},900:{lightness:-.28,chroma:1.15},1e3:{lightness:-.35,chroma:1.2}},m={},y=f=>f===0?r.l:f>0?p(r.l+f*(1-r.l)):p(r.l*(1+f)),T=f=>{if(f===1)return r.c;const E=r.c*f;return Math.max(0,Math.min(.4,E))};return Object.entries(d).forEach(([f,E])=>{const S=`--color-brand-${f}`;if(E.base){m[S]=n;return}const O=y(E.lightness),g=T(E.chroma),_=le(O,g,r.h);m[S]=se(_)}),m}const z=t.computed(()=>ue(a.accentColor)??{}),de=t.computed(()=>z.value),x={vars:{},enabled:!!a.exposeGlobalAccent};return i.push(x),t.watch(()=>a.exposeGlobalAccent,e=>{x.enabled=!!e,b()},{immediate:!0}),t.watch(z,e=>{e&&Object.keys(e).length>0?x.vars={...e}:x.vars={},b()},{immediate:!0}),(e,n)=>(t.openBlock(),t.createElementBlock("div",{class:"theme",style:t.normalizeStyle(de.value)},[t.renderSlot(e.$slots,"default")],4))}}),re=((o,a)=>{const i=o.__vccOpts||o;for(const[s,b]of a)i[s]=b;return i})({__name:"ThemeSwitcher",props:{mode:{type:String,default:"auto",validator:o=>["auto","light","dark"].includes(o)}},emits:["update:mode"],setup(o,{emit:a}){const s=[{value:"auto",label:"System"},{value:"light",label:"Light"},{value:"dark",label:"Dark"}].reduce((h,u)=>(h[u.value]=u.label,h),{}),b=v,M=o,B=a;q();const I=t.ref(!1),N=j()??M.mode,l=t.ref(b.includes(N)?N:"auto");return t.computed(()=>s[l.value]??s.auto),t.watch(()=>M.mode,h=>{b.includes(h)&&h!==l.value&&(l.value=h)}),t.watch(l,h=>{if(!b.includes(h)){l.value="auto";return}I.value=!1,B("update:mode",h),W(h)},{immediate:!0}),(h,u)=>(t.openBlock(),t.createBlock(t.unref($.DropdownMenu),{open:I.value,"onUpdate:open":u[3]||(u[3]=w=>I.value=w),text:"Theme","aria-label":"Select theme mode"},{default:t.withCtx(()=>[t.createVNode(t.unref($.DropdownItemGroup),{title:"Theme"},{default:t.withCtx(()=>[t.createVNode(t.unref($.DropdownItemRadio),{checked:l.value,"onUpdate:checked":u[0]||(u[0]=w=>l.value=w),value:"auto",label:t.unref(s).auto,"aria-label":`${t.unref(s).auto} mode`},null,8,["checked","label","aria-label"]),u[4]||(u[4]=t.createElementVNode("hr",{class:"theme-switcher-divider",role:"separator"},null,-1)),t.createVNode(t.unref($.DropdownItemRadio),{checked:l.value,"onUpdate:checked":u[1]||(u[1]=w=>l.value=w),value:"light",label:t.unref(s).light,"aria-label":`${t.unref(s).light} mode`},null,8,["checked","label","aria-label"]),t.createVNode(t.unref($.DropdownItemRadio),{checked:l.value,"onUpdate:checked":u[2]||(u[2]=w=>l.value=w),value:"dark",label:t.unref(s).dark,"aria-label":`${t.unref(s).dark} mode`},null,8,["checked","label","aria-label"])]),_:1})]),_:1},8,["open"]))}},[["__scopeId","data-v-bcbc87cb"]]);k.Theme=oe,k.ThemeSwitcher=re,Object.defineProperty(k,Symbol.toStringTag,{value:"Module"})});
1
+ (function(b,t){typeof exports=="object"&&typeof module<"u"?t(exports,require("vue"),require("what-input"),require("@gospore/dropdown-menu")):typeof define=="function"&&define.amd?define(["exports","vue","what-input","@gospore/dropdown-menu"],t):(b=typeof globalThis<"u"?globalThis:b||self,t(b.theme={},b.Vue,b.whatInput,b.DropdownMenu))})(this,function(b,t,ke,N){"use strict";const P=["auto","light","dark"],G="gospore-theme-mode",J="(prefers-color-scheme: dark)";function j(){if(typeof document>"u")return null;const o=Z(G);return o&&P.includes(o)?o:null}function X(o){if(typeof document>"u"||!P.includes(o))return;const a=typeof window<"u"?window.location.hostname:"",i=typeof window<"u"?window.location.protocol:"",s=ee(a),g=i==="https:",M=["path=/","max-age=31536000","SameSite=Lax"];s&&M.push(`domain=${s}`),g&&M.push("Secure"),document.cookie=[`${encodeURIComponent(G)}=${encodeURIComponent(o)}`,...M].join("; ")}function q(o){if(typeof document>"u")return;const a=typeof o=="string"&&P.includes(o)?o:j()??"auto";console.log("Applying theme mode:",a);const i=te(a);document.documentElement.setAttribute("dark-mode",i)}function Z(o){if(typeof document>"u"||!document.cookie)return null;const a=`${encodeURIComponent(o)}=`,i=document.cookie.split("; ");for(const s of i)if(s.startsWith(a))return decodeURIComponent(s.slice(a.length));return null}function ee(o){if(!o||o==="localhost")return null;if(/^\d+(?:\.\d+){3}$/.test(o))return o;const i=o.split(".");return i.length<=1?null:i.length===2?o:i.slice(-2).join(".")}function te(o){if(o==="dark")return!0;if(o==="light"||typeof window>"u")return!1;try{const a=typeof window.matchMedia=="function"?window.matchMedia(J):null;return a?a.matches:!1}catch{return!1}}const v=Symbol.for("gospore.theme.portalHost");function ne(){const o=t.inject(v,null);console.log("Using theme portal host:",o);const a=typeof document<"u"?document.body:"body";return t.computed(()=>o?.value??a)}const oe="(prefers-color-scheme: dark)",re="(prefers-reduced-motion: reduce)",ce=200,ae=Object.assign({name:"Theme"},{__name:"Theme",props:{mode:{type:String,validator:o=>["auto","light","dark"].includes(o)},accentColor:{type:String,required:!1,default:void 0},exposeGlobalAccent:{type:Boolean,default:!1}},setup(o){const a=o,i=[],s=new Set;function g(){const e=document.documentElement;if(!e)return;s.forEach(c=>{e.style.removeProperty(c)}),s.clear();const n=[...i].reverse().find(c=>c.enabled&&c.vars&&Object.keys(c.vars).length>0);n&&Object.entries(n.vars).forEach(([c,r])=>{e.style.setProperty(c,r),s.add(c)})}const M=window.matchMedia(oe),B=window.matchMedia(re),I=Q();q(I);const $=t.ref(I),l=t.ref({darkMode:w(I)}),h=t.ref(null);M.addEventListener("change",K),t.watch(()=>a.mode,()=>{f()},{immediate:!0}),t.watch(()=>l.value.darkMode,(e,n)=>{if(n===void 0){Y(e);return}ie(()=>{Y(e)})},{immediate:!0}),t.onBeforeUnmount(()=>{M.removeEventListener("change",K);const e=i.indexOf(L);e!==-1&&i.splice(e,1),g()});function f(){const e=Q();$.value=e,l.value.darkMode=w(e)}function w(e){return e==="dark"?!0:e==="light"?!1:M.matches}function K(e){!e||$.value!=="auto"||(l.value.darkMode=e.matches)}function Y(e){document.documentElement.setAttribute("dark-mode",e)}function ie(e){if(B.matches){e();return}const n=document.startViewTransition?.bind(document);if(n){n(()=>{e()});return}e();const c=document.documentElement;typeof c.animate=="function"&&window.requestAnimationFrame(()=>{c.animate([{opacity:.85},{opacity:1}],{duration:ce,easing:"ease-in-out"})})}function Q(){return a.mode??j()??"auto"}t.provide("theme",l),t.provide(v,h);function z(e){if(!e)return null;const n=e.trim().toLowerCase();if(!/^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i.exec(n))return null;if(n.length===4){const r=n[1],u=n[2],m=n[3];return`#${r}${r}${u}${u}${m}${m}`}return n}function le(e){const n=z(e);if(!n)return null;const c=parseInt(n.slice(1,3),16),r=parseInt(n.slice(3,5),16),u=parseInt(n.slice(5,7),16);return{r:c,g:r,b:u}}function ue({r:e,g:n,b:c}){const r=u=>u.toString(16).padStart(2,"0");return`#${r(e)}${r(n)}${r(c)}`}function p(e){return Math.max(0,Math.min(1,e))}function H(e){return e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)}function V(e){const n=p(e);return n<=.0031308?12.92*n:1.055*Math.pow(n,1/2.4)-.055}function de({r:e,g:n,b:c}){const r=e/255,u=n/255,m=c/255,S=H(r),D=H(u),d=H(m),y=.4122214708*S+.5363325363*D+.0514459929*d,E=.2119034982*S+.6806995451*D+.1073969566*d,_=.0883024619*S+.2817188376*D+.6299787005*d,k=Math.cbrt(y),O=Math.cbrt(E),C=Math.cbrt(_),x=.2104542553*k+.793617785*O-.0040720468*C,T=1.9779984951*k-2.428592205*O+.4505937099*C,R=.0259040371*k+.7827717662*O-.808675766*C,A=Math.sqrt(T*T+R*R);let U=Math.atan2(R,T)*(180/Math.PI);return U<0&&(U+=360),{l:x,c:A,h:U}}function F(e,n,c,r=!1){const u=c*Math.PI/180,m=n*Math.cos(u),S=n*Math.sin(u),D=e+.3963377774*m+.2158037573*S,d=e-.1055613458*m-.0638541728*S,y=e-.0894841775*m-1.291485548*S,E=r?p(D):D,_=r?p(d):d,k=r?p(y):y;if(!r&&(E<-1e-4||E>1.0001||_<-1e-4||_>1.0001||k<-1e-4||k>1.0001))return null;const O=E*E*E,C=_*_*_,x=k*k*k;let T=4.0767416621*O-3.3077115913*C+.2309699292*x,R=-1.2684380046*O+2.6097574011*C-.3413193965*x,A=-.0041960863*O-.7034186147*C+1.707614701*x;if(r)T=p(T),R=p(R),A=p(A);else if(T<-1e-4||T>1.0001||R<-1e-4||R>1.0001||A<-1e-4||A>1.0001)return null;const U=p(V(T)),pe=p(V(R)),be=p(V(A));return{r:Math.round(U*255),g:Math.round(pe*255),b:Math.round(be*255)}}function fe(e,n,c){let r=n;for(let u=0;u<8;u+=1){const m=F(e,r,c);if(m)return m;r*=.9}return F(e,p(r),c,!0)||{r:0,g:0,b:0}}function me(e){const n=z(e);if(!n)return null;const c=le(n);if(!c)return null;const r=de(c),u={100:{lightness:.35,chroma:.45},200:{lightness:.28,chroma:.5},300:{lightness:.22,chroma:.6},400:{lightness:.16,chroma:.75},500:{lightness:.08,chroma:.9},600:{lightness:0,chroma:1,base:!0},700:{lightness:-.08,chroma:1.05},800:{lightness:-.18,chroma:1.1},900:{lightness:-.28,chroma:1.15},1e3:{lightness:-.35,chroma:1.2}},m={},S=d=>d===0?r.l:d>0?p(r.l+d*(1-r.l)):p(r.l*(1+d)),D=d=>{if(d===1)return r.c;const y=r.c*d;return Math.max(0,Math.min(.4,y))};return Object.entries(u).forEach(([d,y])=>{const E=`--color-brand-${d}`;if(y.base){m[E]=n;return}const _=S(y.lightness),k=D(y.chroma),O=fe(_,k,r.h);m[E]=ue(O)}),m}const W=t.computed(()=>me(a.accentColor)??{}),he=t.computed(()=>W.value),L={vars:{},enabled:!!a.exposeGlobalAccent};return i.push(L),t.watch(()=>a.exposeGlobalAccent,e=>{L.enabled=!!e,g()},{immediate:!0}),t.watch(W,e=>{e&&Object.keys(e).length>0?L.vars={...e}:L.vars={},g()},{immediate:!0}),(e,n)=>(t.openBlock(),t.createElementBlock("div",{class:"theme",style:t.normalizeStyle(he.value)},[t.renderSlot(e.$slots,"default"),t.createElementVNode("div",{ref_key:"portalHost",ref:h,class:"theme__portal-host"},null,512)],4))}}),se=((o,a)=>{const i=o.__vccOpts||o;for(const[s,g]of a)i[s]=g;return i})({__name:"ThemeSwitcher",props:{mode:{type:String,default:"auto",validator:o=>["auto","light","dark"].includes(o)}},emits:["update:mode"],setup(o,{emit:a}){const s=[{value:"auto",label:"System"},{value:"light",label:"Light"},{value:"dark",label:"Dark"}].reduce((h,f)=>(h[f.value]=f.label,h),{}),g=P,M=o,B=a;q();const I=t.ref(!1),$=j()??M.mode,l=t.ref(g.includes($)?$:"auto");return t.computed(()=>s[l.value]??s.auto),t.watch(()=>M.mode,h=>{g.includes(h)&&h!==l.value&&(l.value=h)}),t.watch(l,h=>{if(!g.includes(h)){l.value="auto";return}I.value=!1,B("update:mode",h),X(h)},{immediate:!0}),(h,f)=>(t.openBlock(),t.createBlock(t.unref(N.DropdownMenu),{open:I.value,"onUpdate:open":f[3]||(f[3]=w=>I.value=w),text:"Theme","aria-label":"Select theme mode"},{default:t.withCtx(()=>[t.createVNode(t.unref(N.DropdownItemGroup),{title:"Theme"},{default:t.withCtx(()=>[t.createVNode(t.unref(N.DropdownItemRadio),{checked:l.value,"onUpdate:checked":f[0]||(f[0]=w=>l.value=w),value:"auto",label:t.unref(s).auto,"aria-label":`${t.unref(s).auto} mode`},null,8,["checked","label","aria-label"]),f[4]||(f[4]=t.createElementVNode("hr",{class:"theme-switcher-divider",role:"separator"},null,-1)),t.createVNode(t.unref(N.DropdownItemRadio),{checked:l.value,"onUpdate:checked":f[1]||(f[1]=w=>l.value=w),value:"light",label:t.unref(s).light,"aria-label":`${t.unref(s).light} mode`},null,8,["checked","label","aria-label"]),t.createVNode(t.unref(N.DropdownItemRadio),{checked:l.value,"onUpdate:checked":f[2]||(f[2]=w=>l.value=w),value:"dark",label:t.unref(s).dark,"aria-label":`${t.unref(s).dark} mode`},null,8,["checked","label","aria-label"])]),_:1})]),_:1},8,["open"]))}},[["__scopeId","data-v-bcbc87cb"]]);b.Theme=ae,b.ThemeSwitcher=se,b.themePortalHostKey=v,b.useThemePortalTarget=ne,Object.defineProperty(b,Symbol.toStringTag,{value:"Module"})});
2
2
  //# sourceMappingURL=theme.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"theme.umd.js","sources":["../src/modeStorage.js","../src/Theme.vue","../src/ThemeSwitcher.vue"],"sourcesContent":["const VALID_THEME_MODES = [\"auto\", \"light\", \"dark\"];\nconst STORAGE_KEY = \"gospore-theme-mode\";\nconst ONE_YEAR_IN_SECONDS = 60 * 60 * 24 * 365;\nconst DARK_MODE_QUERY = \"(prefers-color-scheme: dark)\";\n\nexport function readStoredMode() {\n if (typeof document === \"undefined\") {\n return null;\n }\n const stored = getCookie(STORAGE_KEY);\n return stored && VALID_THEME_MODES.includes(stored) ? stored : null;\n}\n\nexport function writeStoredMode(mode) {\n if (typeof document === \"undefined\" || !VALID_THEME_MODES.includes(mode)) {\n return;\n }\n const hostname =\n typeof window !== \"undefined\" ? window.location.hostname : \"\";\n const protocol =\n typeof window !== \"undefined\" ? window.location.protocol : \"\";\n const domain = getCookieDomain(hostname);\n const secure = protocol === \"https:\";\n const attributes = [\n \"path=/\",\n `max-age=${ONE_YEAR_IN_SECONDS}`,\n \"SameSite=Lax\",\n ];\n if (domain) {\n attributes.push(`domain=${domain}`);\n }\n if (secure) {\n attributes.push(\"Secure\");\n }\n document.cookie = [\n `${encodeURIComponent(STORAGE_KEY)}=${encodeURIComponent(mode)}`,\n ...attributes,\n ].join(\"; \");\n}\n\nexport function applyStoredModeToDocument(mode) {\n if (typeof document === \"undefined\") {\n return;\n }\n const resolvedMode =\n typeof mode === \"string\" && VALID_THEME_MODES.includes(mode)\n ? mode\n : readStoredMode() ?? \"auto\";\n console.log(\"Applying theme mode:\", resolvedMode);\n const darkMode = resolveDarkMode(resolvedMode);\n document.documentElement.setAttribute(\"dark-mode\", darkMode);\n}\n\nexport { VALID_THEME_MODES, STORAGE_KEY };\n\nfunction getCookie(name) {\n if (typeof document === \"undefined\" || !document.cookie) {\n return null;\n }\n const encodedName = `${encodeURIComponent(name)}=`;\n const cookies = document.cookie.split(\"; \");\n for (const cookie of cookies) {\n if (cookie.startsWith(encodedName)) {\n return decodeURIComponent(cookie.slice(encodedName.length));\n }\n }\n return null;\n}\n\nfunction getCookieDomain(hostname) {\n if (!hostname || hostname === \"localhost\") {\n return null;\n }\n const isIpAddress = /^\\d+(?:\\.\\d+){3}$/.test(hostname);\n if (isIpAddress) {\n return hostname;\n }\n const parts = hostname.split(\".\");\n if (parts.length <= 1) {\n return null;\n }\n if (parts.length === 2) {\n return hostname;\n }\n return parts.slice(-2).join(\".\");\n}\n\nfunction resolveDarkMode(mode) {\n if (mode === \"dark\") {\n return true;\n }\n if (mode === \"light\") {\n return false;\n }\n if (typeof window === \"undefined\") {\n return false;\n }\n try {\n const mediaQueryList =\n typeof window.matchMedia === \"function\"\n ? window.matchMedia(DARK_MODE_QUERY)\n : null;\n return mediaQueryList ? mediaQueryList.matches : false;\n } catch (error) {\n return false;\n }\n}\n","<template>\n <div class=\"theme\" :style=\"brandStyle\">\n <slot />\n </div>\n</template>\n\n<script setup>\nimport { provide, ref, watch, onBeforeUnmount, computed } from \"vue\";\nimport { applyStoredModeToDocument, readStoredMode } from \"./modeStorage\";\nimport \"what-input\";\n\ndefineOptions({\n name: \"Theme\",\n});\nconst props = defineProps({\n mode: {\n type: String,\n validator: (value) => [\"auto\", \"light\", \"dark\"].includes(value),\n },\n /**\n * Optional hex accent color (\"#RRGGBB\" or \"#RGB\"). When provided,\n * Theme derives the `--color-brand-*` palette and exposes the tokens on\n * the root .theme element (and the global document for portals).\n */\n accentColor: {\n type: String,\n required: false,\n default: undefined,\n },\n /**\n * When true the brand vars are also exposed on <html>, allowing portals\n * attached outside the Theme subtree to inherit the accent colors.\n */\n exposeGlobalAccent: {\n type: Boolean,\n default: false,\n },\n});\n\nconst globalAccentStack = [];\nconst appliedGlobalAccentKeys = new Set();\n\nfunction applyGlobalAccentFromStack() {\n const root = document.documentElement;\n if (!root) {\n return;\n }\n\n appliedGlobalAccentKeys.forEach((key) => {\n root.style.removeProperty(key);\n });\n appliedGlobalAccentKeys.clear();\n\n const activeEntry = [...globalAccentStack]\n .reverse()\n .find(\n (entry) =>\n entry.enabled &&\n entry.vars &&\n Object.keys(entry.vars).length > 0,\n );\n\n if (!activeEntry) {\n return;\n }\n\n Object.entries(activeEntry.vars).forEach(([key, value]) => {\n root.style.setProperty(key, value);\n appliedGlobalAccentKeys.add(key);\n });\n}\n\nconst DARK_MODE_QUERY = \"(prefers-color-scheme: dark)\";\nconst PREFERS_REDUCED_MOTION_QUERY = \"(prefers-reduced-motion: reduce)\";\nconst THEME_TRANSITION_DURATION = 200;\nconst darkModeMedia = window.matchMedia(DARK_MODE_QUERY);\nconst prefersReducedMotionMedia = window.matchMedia(\n PREFERS_REDUCED_MOTION_QUERY,\n);\n\nconst initialMode = getEffectiveMode();\napplyStoredModeToDocument(initialMode);\n\nconst currentMode = ref(initialMode);\n\nconst theme = ref({\n darkMode: resolveDarkMode(initialMode),\n});\n\ndarkModeMedia.addEventListener(\"change\", handleSystemPreferenceChange);\n\nwatch(\n () => props.mode,\n () => {\n syncDarkMode();\n },\n { immediate: true },\n);\n\nwatch(\n () => theme.value.darkMode,\n (darkMode, previousValue) => {\n if (previousValue === undefined) {\n setDocumentDarkModeAttribute(darkMode);\n return;\n }\n withThemeTransition(() => {\n setDocumentDarkModeAttribute(darkMode);\n });\n },\n { immediate: true },\n);\n\nonBeforeUnmount(() => {\n darkModeMedia.removeEventListener(\"change\", handleSystemPreferenceChange);\n const index = globalAccentStack.indexOf(accentStackEntry);\n if (index !== -1) {\n globalAccentStack.splice(index, 1);\n }\n applyGlobalAccentFromStack();\n});\n\nfunction syncDarkMode() {\n const mode = getEffectiveMode();\n currentMode.value = mode;\n theme.value.darkMode = resolveDarkMode(mode);\n}\n\nfunction resolveDarkMode(mode) {\n if (mode === \"dark\") {\n return true;\n }\n if (mode === \"light\") {\n return false;\n }\n return darkModeMedia.matches;\n}\n\nfunction handleSystemPreferenceChange(event) {\n if (!event || currentMode.value !== \"auto\") {\n return;\n }\n theme.value.darkMode = event.matches;\n}\n\nfunction setDocumentDarkModeAttribute(darkMode) {\n document.documentElement.setAttribute(\"dark-mode\", darkMode);\n}\n\nfunction withThemeTransition(applyTheme) {\n if (prefersReducedMotionMedia.matches) {\n applyTheme();\n return;\n }\n const startViewTransition = document.startViewTransition?.bind(document);\n if (startViewTransition) {\n startViewTransition(() => {\n applyTheme();\n });\n return;\n }\n applyTheme();\n const element = document.documentElement;\n if (typeof element.animate !== \"function\") {\n return;\n }\n window.requestAnimationFrame(() => {\n element.animate([{ opacity: 0.85 }, { opacity: 1 }], {\n duration: THEME_TRANSITION_DURATION,\n easing: \"ease-in-out\",\n });\n });\n}\n\nfunction getEffectiveMode() {\n return props.mode ?? readStoredMode() ?? \"auto\";\n}\n\nprovide(\"theme\", theme);\n\n// --- Accent helpers -------------------------------------------------------\nfunction normalizeHex(hex) {\n if (!hex) return null;\n const h = hex.trim().toLowerCase();\n const m = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i.exec(h);\n if (!m) return null;\n if (h.length === 4) {\n // expand #rgb -> #rrggbb\n const r = h[1],\n g = h[2],\n b = h[3];\n return `#${r}${r}${g}${g}${b}${b}`;\n }\n return h;\n}\n\nfunction hexToRgb(hex) {\n const h = normalizeHex(hex);\n if (!h) return null;\n const r = parseInt(h.slice(1, 3), 16);\n const g = parseInt(h.slice(3, 5), 16);\n const b = parseInt(h.slice(5, 7), 16);\n return { r, g, b };\n}\n\nfunction rgbToHex({ r, g, b }) {\n const toHex = (value) => value.toString(16).padStart(2, \"0\");\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`;\n}\n\nfunction clamp01(value) {\n return Math.max(0, Math.min(1, value));\n}\n\nfunction srgbChannelToLinear(channel) {\n if (channel <= 0.04045) {\n return channel / 12.92;\n }\n return Math.pow((channel + 0.055) / 1.055, 2.4);\n}\n\nfunction linearChannelToSrgb(channel) {\n const normalized = clamp01(channel);\n if (normalized <= 0.0031308) {\n return 12.92 * normalized;\n }\n return 1.055 * Math.pow(normalized, 1 / 2.4) - 0.055;\n}\n\nfunction rgbToOklch({ r, g, b }) {\n const rNorm = r / 255;\n const gNorm = g / 255;\n const bNorm = b / 255;\n\n const rLin = srgbChannelToLinear(rNorm);\n const gLin = srgbChannelToLinear(gNorm);\n const bLin = srgbChannelToLinear(bNorm);\n\n const l = 0.4122214708 * rLin + 0.5363325363 * gLin + 0.0514459929 * bLin;\n const m = 0.2119034982 * rLin + 0.6806995451 * gLin + 0.1073969566 * bLin;\n const s = 0.0883024619 * rLin + 0.2817188376 * gLin + 0.6299787005 * bLin;\n\n const lRoot = Math.cbrt(l);\n const mRoot = Math.cbrt(m);\n const sRoot = Math.cbrt(s);\n\n const oklabL =\n 0.2104542553 * lRoot + 0.793617785 * mRoot - 0.0040720468 * sRoot;\n const oklabA =\n 1.9779984951 * lRoot - 2.428592205 * mRoot + 0.4505937099 * sRoot;\n const oklabB =\n 0.0259040371 * lRoot + 0.7827717662 * mRoot - 0.808675766 * sRoot;\n\n const chroma = Math.sqrt(oklabA * oklabA + oklabB * oklabB);\n let hue = Math.atan2(oklabB, oklabA) * (180 / Math.PI);\n if (hue < 0) {\n hue += 360;\n }\n\n return { l: oklabL, c: chroma, h: hue };\n}\n\nfunction tryOklchToSrgb(l, c, h, clampLinear = false) {\n const angle = (h * Math.PI) / 180;\n const a = c * Math.cos(angle);\n const b = c * Math.sin(angle);\n\n const lComponent = l + 0.3963377774 * a + 0.2158037573 * b;\n const mComponent = l - 0.1055613458 * a - 0.0638541728 * b;\n const sComponent = l - 0.0894841775 * a - 1.291485548 * b;\n\n const lCube = clampLinear ? clamp01(lComponent) : lComponent;\n const mCube = clampLinear ? clamp01(mComponent) : mComponent;\n const sCube = clampLinear ? clamp01(sComponent) : sComponent;\n\n if (!clampLinear) {\n const outOfRange =\n lCube < -0.0001 ||\n lCube > 1.0001 ||\n mCube < -0.0001 ||\n mCube > 1.0001 ||\n sCube < -0.0001 ||\n sCube > 1.0001;\n if (outOfRange) {\n return null;\n }\n }\n\n const lLin = lCube * lCube * lCube;\n const mLin = mCube * mCube * mCube;\n const sLin = sCube * sCube * sCube;\n\n let rLin = 4.0767416621 * lLin - 3.3077115913 * mLin + 0.2309699292 * sLin;\n let gLin = -1.2684380046 * lLin + 2.6097574011 * mLin - 0.3413193965 * sLin;\n let bLin = -0.0041960863 * lLin - 0.7034186147 * mLin + 1.707614701 * sLin;\n\n if (clampLinear) {\n rLin = clamp01(rLin);\n gLin = clamp01(gLin);\n bLin = clamp01(bLin);\n } else {\n const outOfRange =\n rLin < -0.0001 ||\n rLin > 1.0001 ||\n gLin < -0.0001 ||\n gLin > 1.0001 ||\n bLin < -0.0001 ||\n bLin > 1.0001;\n if (outOfRange) {\n return null;\n }\n }\n\n const r = clamp01(linearChannelToSrgb(rLin));\n const g = clamp01(linearChannelToSrgb(gLin));\n const bValue = clamp01(linearChannelToSrgb(bLin));\n\n return {\n r: Math.round(r * 255),\n g: Math.round(g * 255),\n b: Math.round(bValue * 255),\n };\n}\n\nfunction oklchToSrgb(l, c, h) {\n let chroma = c;\n for (let attempt = 0; attempt < 8; attempt += 1) {\n const rgb = tryOklchToSrgb(l, chroma, h);\n if (rgb) {\n return rgb;\n }\n chroma *= 0.9;\n }\n return tryOklchToSrgb(l, clamp01(chroma), h, true) || { r: 0, g: 0, b: 0 };\n}\n\nfunction makeBrandScale(baseHex) {\n const norm = normalizeHex(baseHex);\n if (!norm) return null;\n const baseRgb = hexToRgb(norm);\n if (!baseRgb) return null;\n const baseOklch = rgbToOklch(baseRgb);\n const toneConfig = {\n 100: { lightness: 0.35, chroma: 0.45 },\n 200: { lightness: 0.28, chroma: 0.5 },\n 300: { lightness: 0.22, chroma: 0.6 },\n 400: { lightness: 0.16, chroma: 0.75 },\n 500: { lightness: 0.08, chroma: 0.9 },\n 600: { lightness: 0, chroma: 1, base: true },\n 700: { lightness: -0.08, chroma: 1.05 },\n 800: { lightness: -0.18, chroma: 1.1 },\n 900: { lightness: -0.28, chroma: 1.15 },\n 1000: { lightness: -0.35, chroma: 1.2 },\n };\n const tokens = {};\n\n const adjustLightness = (lightnessValue) => {\n if (lightnessValue === 0) {\n return baseOklch.l;\n }\n if (lightnessValue > 0) {\n return clamp01(baseOklch.l + lightnessValue * (1 - baseOklch.l));\n }\n return clamp01(baseOklch.l * (1 + lightnessValue));\n };\n\n const adjustChroma = (chromaScale) => {\n if (chromaScale === 1) {\n return baseOklch.c;\n }\n const scaled = baseOklch.c * chromaScale;\n return Math.max(0, Math.min(0.4, scaled));\n };\n\n Object.entries(toneConfig).forEach(([stop, config]) => {\n const tokenName = `--color-brand-${stop}`;\n if (config.base) {\n tokens[tokenName] = norm;\n return;\n }\n const toneL = adjustLightness(config.lightness);\n const toneC = adjustChroma(config.chroma);\n const toneRgb = oklchToSrgb(toneL, toneC, baseOklch.h);\n tokens[tokenName] = rgbToHex(toneRgb);\n });\n return tokens;\n}\n\nconst brandVars = computed(() => makeBrandScale(props.accentColor) ?? {});\nconst brandStyle = computed(() => brandVars.value);\n\nconst accentStackEntry = {\n vars: {},\n enabled: Boolean(props.exposeGlobalAccent),\n};\nglobalAccentStack.push(accentStackEntry);\n\nwatch(\n () => props.exposeGlobalAccent,\n (enabled) => {\n accentStackEntry.enabled = Boolean(enabled);\n applyGlobalAccentFromStack();\n },\n { immediate: true },\n);\n\nwatch(\n brandVars,\n (vars) => {\n if (vars && Object.keys(vars).length > 0) {\n accentStackEntry.vars = { ...vars };\n } else {\n accentStackEntry.vars = {};\n }\n applyGlobalAccentFromStack();\n },\n { immediate: true },\n);\n</script>\n\n<style lang=\"less\">\n@import \"index.less\";\n</style>\n","<template>\n <DropdownMenu\n v-model:open=\"open\"\n text=\"Theme\"\n aria-label=\"Select theme mode\"\n >\n <DropdownItemGroup title=\"Theme\">\n <DropdownItemRadio\n v-model:checked=\"internalMode\"\n value=\"auto\"\n :label=\"MODE_LABELS.auto\"\n :aria-label=\"`${MODE_LABELS.auto} mode`\"\n />\n <hr class=\"theme-switcher-divider\" role=\"separator\" />\n <DropdownItemRadio\n v-model:checked=\"internalMode\"\n value=\"light\"\n :label=\"MODE_LABELS.light\"\n :aria-label=\"`${MODE_LABELS.light} mode`\"\n />\n <DropdownItemRadio\n v-model:checked=\"internalMode\"\n value=\"dark\"\n :label=\"MODE_LABELS.dark\"\n :aria-label=\"`${MODE_LABELS.dark} mode`\"\n />\n </DropdownItemGroup>\n </DropdownMenu>\n</template>\n\n<script setup>\nimport { ref, computed, watch } from \"vue\";\nimport {\n DropdownMenu,\n DropdownItemGroup,\n DropdownItemRadio,\n} from \"@gospore/dropdown-menu\";\nimport {\n readStoredMode,\n writeStoredMode,\n VALID_THEME_MODES,\n applyStoredModeToDocument,\n} from \"./modeStorage\";\n\nconst MODE_OPTIONS = [\n { value: \"auto\", label: \"System\" },\n { value: \"light\", label: \"Light\" },\n { value: \"dark\", label: \"Dark\" },\n];\nconst MODE_LABELS = MODE_OPTIONS.reduce((map, option) => {\n map[option.value] = option.label;\n return map;\n}, {});\nconst VALID_MODES = VALID_THEME_MODES;\n\nconst props = defineProps({\n mode: {\n type: String,\n default: \"auto\",\n validator: (value) => [\"auto\", \"light\", \"dark\"].includes(value),\n },\n});\nconst emit = defineEmits([\"update:mode\"]);\n\napplyStoredModeToDocument();\n\nconst open = ref(false);\nconst initialMode = readStoredMode() ?? props.mode;\nconst internalMode = ref(\n VALID_MODES.includes(initialMode) ? initialMode : \"auto\",\n);\nconst label = computed(\n () => MODE_LABELS[internalMode.value] ?? MODE_LABELS.auto,\n);\n\nwatch(\n () => props.mode,\n (mode) => {\n if (VALID_MODES.includes(mode) && mode !== internalMode.value) {\n internalMode.value = mode;\n }\n },\n);\n\nwatch(\n internalMode,\n (mode) => {\n if (!VALID_MODES.includes(mode)) {\n internalMode.value = \"auto\";\n return;\n }\n open.value = false;\n emit(\"update:mode\", mode);\n writeStoredMode(mode);\n },\n { immediate: true },\n);\n</script>\n\n<style scoped lang=\"less\">\n.theme-switcher-divider {\n margin: 4px 0;\n}\n</style>\n"],"names":["VALID_THEME_MODES","STORAGE_KEY","DARK_MODE_QUERY","readStoredMode","stored","getCookie","writeStoredMode","mode","hostname","protocol","domain","getCookieDomain","secure","attributes","applyStoredModeToDocument","resolvedMode","darkMode","resolveDarkMode","name","encodedName","cookies","cookie","parts","mediaQueryList","props","__props","globalAccentStack","appliedGlobalAccentKeys","applyGlobalAccentFromStack","root","key","activeEntry","entry","value","darkModeMedia","prefersReducedMotionMedia","PREFERS_REDUCED_MOTION_QUERY","initialMode","getEffectiveMode","currentMode","ref","theme","handleSystemPreferenceChange","watch","syncDarkMode","previousValue","setDocumentDarkModeAttribute","withThemeTransition","onBeforeUnmount","index","accentStackEntry","event","applyTheme","startViewTransition","element","THEME_TRANSITION_DURATION","provide","normalizeHex","hex","h","g","b","hexToRgb","r","rgbToHex","toHex","clamp01","srgbChannelToLinear","channel","linearChannelToSrgb","normalized","rgbToOklch","rNorm","gNorm","bNorm","rLin","gLin","bLin","l","m","s","lRoot","mRoot","sRoot","oklabL","oklabA","oklabB","chroma","hue","tryOklchToSrgb","c","clampLinear","angle","a","lComponent","mComponent","sComponent","lCube","mCube","sCube","lLin","mLin","sLin","bValue","oklchToSrgb","attempt","rgb","makeBrandScale","baseHex","norm","baseRgb","baseOklch","toneConfig","tokens","adjustLightness","lightnessValue","adjustChroma","chromaScale","scaled","stop","config","tokenName","toneL","toneC","toneRgb","brandVars","computed","brandStyle","enabled","vars","_createElementBlock","_renderSlot","_ctx","MODE_LABELS","map","option","VALID_MODES","emit","__emit","open","internalMode","_createBlock","_unref","DropdownMenu","$event","_createVNode","DropdownItemGroup","DropdownItemRadio","_createElementVNode"],"mappings":"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"}
1
+ {"version":3,"file":"theme.umd.js","sources":["../src/modeStorage.js","../src/portalHost.js","../src/Theme.vue","../src/ThemeSwitcher.vue"],"sourcesContent":["const VALID_THEME_MODES = [\"auto\", \"light\", \"dark\"];\nconst STORAGE_KEY = \"gospore-theme-mode\";\nconst ONE_YEAR_IN_SECONDS = 60 * 60 * 24 * 365;\nconst DARK_MODE_QUERY = \"(prefers-color-scheme: dark)\";\n\nexport function readStoredMode() {\n if (typeof document === \"undefined\") {\n return null;\n }\n const stored = getCookie(STORAGE_KEY);\n return stored && VALID_THEME_MODES.includes(stored) ? stored : null;\n}\n\nexport function writeStoredMode(mode) {\n if (typeof document === \"undefined\" || !VALID_THEME_MODES.includes(mode)) {\n return;\n }\n const hostname =\n typeof window !== \"undefined\" ? window.location.hostname : \"\";\n const protocol =\n typeof window !== \"undefined\" ? window.location.protocol : \"\";\n const domain = getCookieDomain(hostname);\n const secure = protocol === \"https:\";\n const attributes = [\n \"path=/\",\n `max-age=${ONE_YEAR_IN_SECONDS}`,\n \"SameSite=Lax\",\n ];\n if (domain) {\n attributes.push(`domain=${domain}`);\n }\n if (secure) {\n attributes.push(\"Secure\");\n }\n document.cookie = [\n `${encodeURIComponent(STORAGE_KEY)}=${encodeURIComponent(mode)}`,\n ...attributes,\n ].join(\"; \");\n}\n\nexport function applyStoredModeToDocument(mode) {\n if (typeof document === \"undefined\") {\n return;\n }\n const resolvedMode =\n typeof mode === \"string\" && VALID_THEME_MODES.includes(mode)\n ? mode\n : readStoredMode() ?? \"auto\";\n console.log(\"Applying theme mode:\", resolvedMode);\n const darkMode = resolveDarkMode(resolvedMode);\n document.documentElement.setAttribute(\"dark-mode\", darkMode);\n}\n\nexport { VALID_THEME_MODES, STORAGE_KEY };\n\nfunction getCookie(name) {\n if (typeof document === \"undefined\" || !document.cookie) {\n return null;\n }\n const encodedName = `${encodeURIComponent(name)}=`;\n const cookies = document.cookie.split(\"; \");\n for (const cookie of cookies) {\n if (cookie.startsWith(encodedName)) {\n return decodeURIComponent(cookie.slice(encodedName.length));\n }\n }\n return null;\n}\n\nfunction getCookieDomain(hostname) {\n if (!hostname || hostname === \"localhost\") {\n return null;\n }\n const isIpAddress = /^\\d+(?:\\.\\d+){3}$/.test(hostname);\n if (isIpAddress) {\n return hostname;\n }\n const parts = hostname.split(\".\");\n if (parts.length <= 1) {\n return null;\n }\n if (parts.length === 2) {\n return hostname;\n }\n return parts.slice(-2).join(\".\");\n}\n\nfunction resolveDarkMode(mode) {\n if (mode === \"dark\") {\n return true;\n }\n if (mode === \"light\") {\n return false;\n }\n if (typeof window === \"undefined\") {\n return false;\n }\n try {\n const mediaQueryList =\n typeof window.matchMedia === \"function\"\n ? window.matchMedia(DARK_MODE_QUERY)\n : null;\n return mediaQueryList ? mediaQueryList.matches : false;\n } catch (error) {\n return false;\n }\n}\n","import { computed, inject } from \"vue\";\n\nexport const themePortalHostKey = Symbol.for(\"gospore.theme.portalHost\");\n\nexport function useThemePortalTarget() {\n const hostRef = inject(themePortalHostKey, null);\n console.log(\"Using theme portal host:\", hostRef);\n const fallbackTarget =\n typeof document !== \"undefined\" ? document.body : \"body\";\n\n return computed(() => hostRef?.value ?? fallbackTarget);\n}\n","<template>\n <div class=\"theme\" :style=\"brandStyle\">\n <slot />\n <div ref=\"portalHost\" class=\"theme__portal-host\"></div>\n </div>\n</template>\n\n<script setup>\nimport { provide, ref, watch, onBeforeUnmount, computed } from \"vue\";\nimport { applyStoredModeToDocument, readStoredMode } from \"./modeStorage\";\nimport \"what-input\";\nimport { themePortalHostKey } from \"./portalHost\";\n\ndefineOptions({\n name: \"Theme\",\n});\nconst props = defineProps({\n mode: {\n type: String,\n validator: (value) => [\"auto\", \"light\", \"dark\"].includes(value),\n },\n /**\n * Optional hex accent color (\"#RRGGBB\" or \"#RGB\"). When provided,\n * Theme derives the `--color-brand-*` palette and exposes the tokens on\n * the root .theme element (and the global document for portals).\n */\n accentColor: {\n type: String,\n required: false,\n default: undefined,\n },\n /**\n * When true the brand vars are also exposed on <html>, allowing portals\n * attached outside the Theme subtree to inherit the accent colors.\n */\n exposeGlobalAccent: {\n type: Boolean,\n default: false,\n },\n});\n\nconst globalAccentStack = [];\nconst appliedGlobalAccentKeys = new Set();\n\nfunction applyGlobalAccentFromStack() {\n const root = document.documentElement;\n if (!root) {\n return;\n }\n\n appliedGlobalAccentKeys.forEach((key) => {\n root.style.removeProperty(key);\n });\n appliedGlobalAccentKeys.clear();\n\n const activeEntry = [...globalAccentStack]\n .reverse()\n .find(\n (entry) =>\n entry.enabled &&\n entry.vars &&\n Object.keys(entry.vars).length > 0,\n );\n\n if (!activeEntry) {\n return;\n }\n\n Object.entries(activeEntry.vars).forEach(([key, value]) => {\n root.style.setProperty(key, value);\n appliedGlobalAccentKeys.add(key);\n });\n}\n\nconst DARK_MODE_QUERY = \"(prefers-color-scheme: dark)\";\nconst PREFERS_REDUCED_MOTION_QUERY = \"(prefers-reduced-motion: reduce)\";\nconst THEME_TRANSITION_DURATION = 200;\nconst darkModeMedia = window.matchMedia(DARK_MODE_QUERY);\nconst prefersReducedMotionMedia = window.matchMedia(\n PREFERS_REDUCED_MOTION_QUERY,\n);\n\nconst initialMode = getEffectiveMode();\napplyStoredModeToDocument(initialMode);\n\nconst currentMode = ref(initialMode);\n\nconst theme = ref({\n darkMode: resolveDarkMode(initialMode),\n});\nconst portalHost = ref(null);\n\ndarkModeMedia.addEventListener(\"change\", handleSystemPreferenceChange);\n\nwatch(\n () => props.mode,\n () => {\n syncDarkMode();\n },\n { immediate: true },\n);\n\nwatch(\n () => theme.value.darkMode,\n (darkMode, previousValue) => {\n if (previousValue === undefined) {\n setDocumentDarkModeAttribute(darkMode);\n return;\n }\n withThemeTransition(() => {\n setDocumentDarkModeAttribute(darkMode);\n });\n },\n { immediate: true },\n);\n\nonBeforeUnmount(() => {\n darkModeMedia.removeEventListener(\"change\", handleSystemPreferenceChange);\n const index = globalAccentStack.indexOf(accentStackEntry);\n if (index !== -1) {\n globalAccentStack.splice(index, 1);\n }\n applyGlobalAccentFromStack();\n});\n\nfunction syncDarkMode() {\n const mode = getEffectiveMode();\n currentMode.value = mode;\n theme.value.darkMode = resolveDarkMode(mode);\n}\n\nfunction resolveDarkMode(mode) {\n if (mode === \"dark\") {\n return true;\n }\n if (mode === \"light\") {\n return false;\n }\n return darkModeMedia.matches;\n}\n\nfunction handleSystemPreferenceChange(event) {\n if (!event || currentMode.value !== \"auto\") {\n return;\n }\n theme.value.darkMode = event.matches;\n}\n\nfunction setDocumentDarkModeAttribute(darkMode) {\n document.documentElement.setAttribute(\"dark-mode\", darkMode);\n}\n\nfunction withThemeTransition(applyTheme) {\n if (prefersReducedMotionMedia.matches) {\n applyTheme();\n return;\n }\n const startViewTransition = document.startViewTransition?.bind(document);\n if (startViewTransition) {\n startViewTransition(() => {\n applyTheme();\n });\n return;\n }\n applyTheme();\n const element = document.documentElement;\n if (typeof element.animate !== \"function\") {\n return;\n }\n window.requestAnimationFrame(() => {\n element.animate([{ opacity: 0.85 }, { opacity: 1 }], {\n duration: THEME_TRANSITION_DURATION,\n easing: \"ease-in-out\",\n });\n });\n}\n\nfunction getEffectiveMode() {\n return props.mode ?? readStoredMode() ?? \"auto\";\n}\n\nprovide(\"theme\", theme);\nprovide(themePortalHostKey, portalHost);\n\n// --- Accent helpers -------------------------------------------------------\nfunction normalizeHex(hex) {\n if (!hex) return null;\n const h = hex.trim().toLowerCase();\n const m = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i.exec(h);\n if (!m) return null;\n if (h.length === 4) {\n // expand #rgb -> #rrggbb\n const r = h[1],\n g = h[2],\n b = h[3];\n return `#${r}${r}${g}${g}${b}${b}`;\n }\n return h;\n}\n\nfunction hexToRgb(hex) {\n const h = normalizeHex(hex);\n if (!h) return null;\n const r = parseInt(h.slice(1, 3), 16);\n const g = parseInt(h.slice(3, 5), 16);\n const b = parseInt(h.slice(5, 7), 16);\n return { r, g, b };\n}\n\nfunction rgbToHex({ r, g, b }) {\n const toHex = (value) => value.toString(16).padStart(2, \"0\");\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`;\n}\n\nfunction clamp01(value) {\n return Math.max(0, Math.min(1, value));\n}\n\nfunction srgbChannelToLinear(channel) {\n if (channel <= 0.04045) {\n return channel / 12.92;\n }\n return Math.pow((channel + 0.055) / 1.055, 2.4);\n}\n\nfunction linearChannelToSrgb(channel) {\n const normalized = clamp01(channel);\n if (normalized <= 0.0031308) {\n return 12.92 * normalized;\n }\n return 1.055 * Math.pow(normalized, 1 / 2.4) - 0.055;\n}\n\nfunction rgbToOklch({ r, g, b }) {\n const rNorm = r / 255;\n const gNorm = g / 255;\n const bNorm = b / 255;\n\n const rLin = srgbChannelToLinear(rNorm);\n const gLin = srgbChannelToLinear(gNorm);\n const bLin = srgbChannelToLinear(bNorm);\n\n const l = 0.4122214708 * rLin + 0.5363325363 * gLin + 0.0514459929 * bLin;\n const m = 0.2119034982 * rLin + 0.6806995451 * gLin + 0.1073969566 * bLin;\n const s = 0.0883024619 * rLin + 0.2817188376 * gLin + 0.6299787005 * bLin;\n\n const lRoot = Math.cbrt(l);\n const mRoot = Math.cbrt(m);\n const sRoot = Math.cbrt(s);\n\n const oklabL =\n 0.2104542553 * lRoot + 0.793617785 * mRoot - 0.0040720468 * sRoot;\n const oklabA =\n 1.9779984951 * lRoot - 2.428592205 * mRoot + 0.4505937099 * sRoot;\n const oklabB =\n 0.0259040371 * lRoot + 0.7827717662 * mRoot - 0.808675766 * sRoot;\n\n const chroma = Math.sqrt(oklabA * oklabA + oklabB * oklabB);\n let hue = Math.atan2(oklabB, oklabA) * (180 / Math.PI);\n if (hue < 0) {\n hue += 360;\n }\n\n return { l: oklabL, c: chroma, h: hue };\n}\n\nfunction tryOklchToSrgb(l, c, h, clampLinear = false) {\n const angle = (h * Math.PI) / 180;\n const a = c * Math.cos(angle);\n const b = c * Math.sin(angle);\n\n const lComponent = l + 0.3963377774 * a + 0.2158037573 * b;\n const mComponent = l - 0.1055613458 * a - 0.0638541728 * b;\n const sComponent = l - 0.0894841775 * a - 1.291485548 * b;\n\n const lCube = clampLinear ? clamp01(lComponent) : lComponent;\n const mCube = clampLinear ? clamp01(mComponent) : mComponent;\n const sCube = clampLinear ? clamp01(sComponent) : sComponent;\n\n if (!clampLinear) {\n const outOfRange =\n lCube < -0.0001 ||\n lCube > 1.0001 ||\n mCube < -0.0001 ||\n mCube > 1.0001 ||\n sCube < -0.0001 ||\n sCube > 1.0001;\n if (outOfRange) {\n return null;\n }\n }\n\n const lLin = lCube * lCube * lCube;\n const mLin = mCube * mCube * mCube;\n const sLin = sCube * sCube * sCube;\n\n let rLin = 4.0767416621 * lLin - 3.3077115913 * mLin + 0.2309699292 * sLin;\n let gLin = -1.2684380046 * lLin + 2.6097574011 * mLin - 0.3413193965 * sLin;\n let bLin = -0.0041960863 * lLin - 0.7034186147 * mLin + 1.707614701 * sLin;\n\n if (clampLinear) {\n rLin = clamp01(rLin);\n gLin = clamp01(gLin);\n bLin = clamp01(bLin);\n } else {\n const outOfRange =\n rLin < -0.0001 ||\n rLin > 1.0001 ||\n gLin < -0.0001 ||\n gLin > 1.0001 ||\n bLin < -0.0001 ||\n bLin > 1.0001;\n if (outOfRange) {\n return null;\n }\n }\n\n const r = clamp01(linearChannelToSrgb(rLin));\n const g = clamp01(linearChannelToSrgb(gLin));\n const bValue = clamp01(linearChannelToSrgb(bLin));\n\n return {\n r: Math.round(r * 255),\n g: Math.round(g * 255),\n b: Math.round(bValue * 255),\n };\n}\n\nfunction oklchToSrgb(l, c, h) {\n let chroma = c;\n for (let attempt = 0; attempt < 8; attempt += 1) {\n const rgb = tryOklchToSrgb(l, chroma, h);\n if (rgb) {\n return rgb;\n }\n chroma *= 0.9;\n }\n return tryOklchToSrgb(l, clamp01(chroma), h, true) || { r: 0, g: 0, b: 0 };\n}\n\nfunction makeBrandScale(baseHex) {\n const norm = normalizeHex(baseHex);\n if (!norm) return null;\n const baseRgb = hexToRgb(norm);\n if (!baseRgb) return null;\n const baseOklch = rgbToOklch(baseRgb);\n const toneConfig = {\n 100: { lightness: 0.35, chroma: 0.45 },\n 200: { lightness: 0.28, chroma: 0.5 },\n 300: { lightness: 0.22, chroma: 0.6 },\n 400: { lightness: 0.16, chroma: 0.75 },\n 500: { lightness: 0.08, chroma: 0.9 },\n 600: { lightness: 0, chroma: 1, base: true },\n 700: { lightness: -0.08, chroma: 1.05 },\n 800: { lightness: -0.18, chroma: 1.1 },\n 900: { lightness: -0.28, chroma: 1.15 },\n 1000: { lightness: -0.35, chroma: 1.2 },\n };\n const tokens = {};\n\n const adjustLightness = (lightnessValue) => {\n if (lightnessValue === 0) {\n return baseOklch.l;\n }\n if (lightnessValue > 0) {\n return clamp01(baseOklch.l + lightnessValue * (1 - baseOklch.l));\n }\n return clamp01(baseOklch.l * (1 + lightnessValue));\n };\n\n const adjustChroma = (chromaScale) => {\n if (chromaScale === 1) {\n return baseOklch.c;\n }\n const scaled = baseOklch.c * chromaScale;\n return Math.max(0, Math.min(0.4, scaled));\n };\n\n Object.entries(toneConfig).forEach(([stop, config]) => {\n const tokenName = `--color-brand-${stop}`;\n if (config.base) {\n tokens[tokenName] = norm;\n return;\n }\n const toneL = adjustLightness(config.lightness);\n const toneC = adjustChroma(config.chroma);\n const toneRgb = oklchToSrgb(toneL, toneC, baseOklch.h);\n tokens[tokenName] = rgbToHex(toneRgb);\n });\n return tokens;\n}\n\nconst brandVars = computed(() => makeBrandScale(props.accentColor) ?? {});\nconst brandStyle = computed(() => brandVars.value);\n\nconst accentStackEntry = {\n vars: {},\n enabled: Boolean(props.exposeGlobalAccent),\n};\nglobalAccentStack.push(accentStackEntry);\n\nwatch(\n () => props.exposeGlobalAccent,\n (enabled) => {\n accentStackEntry.enabled = Boolean(enabled);\n applyGlobalAccentFromStack();\n },\n { immediate: true },\n);\n\nwatch(\n brandVars,\n (vars) => {\n if (vars && Object.keys(vars).length > 0) {\n accentStackEntry.vars = { ...vars };\n } else {\n accentStackEntry.vars = {};\n }\n applyGlobalAccentFromStack();\n },\n { immediate: true },\n);\n</script>\n\n<style lang=\"less\">\n@import \"index.less\";\n</style>\n","<template>\n <DropdownMenu\n v-model:open=\"open\"\n text=\"Theme\"\n aria-label=\"Select theme mode\"\n >\n <DropdownItemGroup title=\"Theme\">\n <DropdownItemRadio\n v-model:checked=\"internalMode\"\n value=\"auto\"\n :label=\"MODE_LABELS.auto\"\n :aria-label=\"`${MODE_LABELS.auto} mode`\"\n />\n <hr class=\"theme-switcher-divider\" role=\"separator\" />\n <DropdownItemRadio\n v-model:checked=\"internalMode\"\n value=\"light\"\n :label=\"MODE_LABELS.light\"\n :aria-label=\"`${MODE_LABELS.light} mode`\"\n />\n <DropdownItemRadio\n v-model:checked=\"internalMode\"\n value=\"dark\"\n :label=\"MODE_LABELS.dark\"\n :aria-label=\"`${MODE_LABELS.dark} mode`\"\n />\n </DropdownItemGroup>\n </DropdownMenu>\n</template>\n\n<script setup>\nimport { ref, computed, watch } from \"vue\";\nimport {\n DropdownMenu,\n DropdownItemGroup,\n DropdownItemRadio,\n} from \"@gospore/dropdown-menu\";\nimport {\n readStoredMode,\n writeStoredMode,\n VALID_THEME_MODES,\n applyStoredModeToDocument,\n} from \"./modeStorage\";\n\nconst MODE_OPTIONS = [\n { value: \"auto\", label: \"System\" },\n { value: \"light\", label: \"Light\" },\n { value: \"dark\", label: \"Dark\" },\n];\nconst MODE_LABELS = MODE_OPTIONS.reduce((map, option) => {\n map[option.value] = option.label;\n return map;\n}, {});\nconst VALID_MODES = VALID_THEME_MODES;\n\nconst props = defineProps({\n mode: {\n type: String,\n default: \"auto\",\n validator: (value) => [\"auto\", \"light\", \"dark\"].includes(value),\n },\n});\nconst emit = defineEmits([\"update:mode\"]);\n\napplyStoredModeToDocument();\n\nconst open = ref(false);\nconst initialMode = readStoredMode() ?? props.mode;\nconst internalMode = ref(\n VALID_MODES.includes(initialMode) ? initialMode : \"auto\",\n);\nconst label = computed(\n () => MODE_LABELS[internalMode.value] ?? MODE_LABELS.auto,\n);\n\nwatch(\n () => props.mode,\n (mode) => {\n if (VALID_MODES.includes(mode) && mode !== internalMode.value) {\n internalMode.value = mode;\n }\n },\n);\n\nwatch(\n internalMode,\n (mode) => {\n if (!VALID_MODES.includes(mode)) {\n internalMode.value = \"auto\";\n return;\n }\n open.value = false;\n emit(\"update:mode\", mode);\n writeStoredMode(mode);\n },\n { immediate: true },\n);\n</script>\n\n<style scoped lang=\"less\">\n.theme-switcher-divider {\n margin: 4px 0;\n}\n</style>\n"],"names":["VALID_THEME_MODES","STORAGE_KEY","DARK_MODE_QUERY","readStoredMode","stored","getCookie","writeStoredMode","mode","hostname","protocol","domain","getCookieDomain","secure","attributes","applyStoredModeToDocument","resolvedMode","darkMode","resolveDarkMode","name","encodedName","cookies","cookie","parts","mediaQueryList","themePortalHostKey","useThemePortalTarget","hostRef","inject","fallbackTarget","computed","props","__props","globalAccentStack","appliedGlobalAccentKeys","applyGlobalAccentFromStack","root","key","activeEntry","entry","value","darkModeMedia","prefersReducedMotionMedia","PREFERS_REDUCED_MOTION_QUERY","initialMode","getEffectiveMode","currentMode","ref","theme","portalHost","handleSystemPreferenceChange","watch","syncDarkMode","previousValue","setDocumentDarkModeAttribute","withThemeTransition","onBeforeUnmount","index","accentStackEntry","event","applyTheme","startViewTransition","element","THEME_TRANSITION_DURATION","provide","normalizeHex","hex","h","g","b","hexToRgb","r","rgbToHex","toHex","clamp01","srgbChannelToLinear","channel","linearChannelToSrgb","normalized","rgbToOklch","rNorm","gNorm","bNorm","rLin","gLin","bLin","l","m","s","lRoot","mRoot","sRoot","oklabL","oklabA","oklabB","chroma","hue","tryOklchToSrgb","c","clampLinear","angle","a","lComponent","mComponent","sComponent","lCube","mCube","sCube","lLin","mLin","sLin","bValue","oklchToSrgb","attempt","rgb","makeBrandScale","baseHex","norm","baseRgb","baseOklch","toneConfig","tokens","adjustLightness","lightnessValue","adjustChroma","chromaScale","scaled","stop","config","tokenName","toneL","toneC","toneRgb","brandVars","brandStyle","enabled","vars","_createElementBlock","_renderSlot","_ctx","_createElementVNode","MODE_LABELS","map","option","VALID_MODES","emit","__emit","open","internalMode","_createBlock","_unref","DropdownMenu","$event","_createVNode","DropdownItemGroup","DropdownItemRadio"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gospore/theme",
3
- "version": "1.0.127",
3
+ "version": "1.0.129",
4
4
  "description": "",
5
5
  "author": "Gospore",
6
6
  "type": "module",
@@ -15,6 +15,7 @@
15
15
  "require": "./dist/theme.cjs.js",
16
16
  "types": "./dist/index.d.ts"
17
17
  },
18
+ "./theme.css": "./dist/theme.css",
18
19
  "./umd": {
19
20
  "import": "./dist/theme.umd.js",
20
21
  "require": "./dist/theme.umd.js"
@@ -27,7 +28,7 @@
27
28
  "vue": "^3.4.20"
28
29
  },
29
30
  "dependencies": {
30
- "@gospore/dropdown-menu": "^1.0.95",
31
+ "@gospore/dropdown-menu": "^1.0.97",
31
32
  "what-input": "^5.2.12"
32
33
  },
33
34
  "devDependencies": {
@@ -35,6 +36,6 @@
35
36
  "unplugin-vue-macros": "^2.14.5",
36
37
  "vite": "^7.1.12"
37
38
  },
38
- "gitHead": "e73c4ea733b4b8e06e3d9cbb2d516c7544cb0750",
39
+ "gitHead": "1aad85b2c8f227e30d6d3a9c2d2b0daecfdd40d3",
39
40
  "types": "./dist/index.d.ts"
40
41
  }