@gospore/theme 1.0.125 → 1.0.127

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/theme.es.js CHANGED
@@ -1,22 +1,22 @@
1
- import { ref as U, watch as L, onBeforeUnmount as le, provide as de, computed as Y, createElementBlock as me, openBlock as J, normalizeStyle as fe, renderSlot as he, createBlock as pe, unref as b, withCtx as W, createVNode as x, createElementVNode as be } from "vue";
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";
2
2
  import "what-input";
3
- import { DropdownMenu as ge, DropdownItemGroup as ke, DropdownItemRadio as V } from "@gospore/dropdown-menu";
4
- const j = ["auto", "light", "dark"], X = "gospore-theme-mode", Me = 60 * 60 * 24 * 365, ve = "(prefers-color-scheme: dark)";
5
- function G() {
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() {
6
6
  if (typeof document > "u")
7
7
  return null;
8
8
  const n = we(X);
9
- return n && j.includes(n) ? n : null;
9
+ return n && B.includes(n) ? n : null;
10
10
  }
11
11
  function Ee(n) {
12
- if (typeof document > "u" || !j.includes(n))
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), g = s === "https:", k = [
14
+ const c = typeof window < "u" ? window.location.hostname : "", s = typeof window < "u" ? window.location.protocol : "", a = Se(c), p = s === "https:", k = [
15
15
  "path=/",
16
16
  `max-age=${Me}`,
17
17
  "SameSite=Lax"
18
18
  ];
19
- a && k.push(`domain=${a}`), g && k.push("Secure"), document.cookie = [
19
+ a && k.push(`domain=${a}`), p && k.push("Secure"), document.cookie = [
20
20
  `${encodeURIComponent(X)}=${encodeURIComponent(n)}`,
21
21
  ...k
22
22
  ].join("; ");
@@ -24,7 +24,7 @@ function Ee(n) {
24
24
  function Z(n) {
25
25
  if (typeof document > "u")
26
26
  return;
27
- const c = typeof n == "string" && j.includes(n) ? n : G() ?? "auto";
27
+ const c = typeof n == "string" && B.includes(n) ? n : Y() ?? "auto";
28
28
  console.log("Applying theme mode:", c);
29
29
  const s = ye(c);
30
30
  document.documentElement.setAttribute("dark-mode", s);
@@ -58,7 +58,7 @@ function ye(n) {
58
58
  return !1;
59
59
  }
60
60
  }
61
- const Oe = "(prefers-color-scheme: dark)", Re = "(prefers-reduced-motion: reduce)", _e = 200, Ae = /* @__PURE__ */ Object.assign({
61
+ const Oe = "(prefers-color-scheme: dark)", Re = "(prefers-reduced-motion: reduce)", _e = 200, $e = /* @__PURE__ */ Object.assign({
62
62
  name: "Theme"
63
63
  }, {
64
64
  __name: "Theme",
@@ -76,36 +76,46 @@ const Oe = "(prefers-color-scheme: dark)", Re = "(prefers-reduced-motion: reduce
76
76
  type: String,
77
77
  required: !1,
78
78
  default: void 0
79
+ },
80
+ /**
81
+ * When true the brand vars are also exposed on <html>, allowing portals
82
+ * attached outside the Theme subtree to inherit the accent colors.
83
+ */
84
+ exposeGlobalAccent: {
85
+ type: Boolean,
86
+ default: !1
79
87
  }
80
88
  },
81
89
  setup(n) {
82
90
  const c = n, s = [], a = /* @__PURE__ */ new Set();
83
- function g() {
91
+ function p() {
84
92
  const e = document.documentElement;
85
93
  if (!e)
86
94
  return;
87
95
  a.forEach((r) => {
88
96
  e.style.removeProperty(r);
89
97
  }), a.clear();
90
- const t = [...s].reverse().find((r) => r.vars && Object.keys(r.vars).length > 0);
98
+ const t = [...s].reverse().find(
99
+ (r) => r.enabled && r.vars && Object.keys(r.vars).length > 0
100
+ );
91
101
  t && Object.entries(t.vars).forEach(([r, o]) => {
92
102
  e.style.setProperty(r, o), a.add(r);
93
103
  });
94
104
  }
95
- const k = window.matchMedia(Oe), P = window.matchMedia(
105
+ const k = window.matchMedia(Oe), j = window.matchMedia(
96
106
  Re
97
107
  ), D = Q();
98
108
  Z(D);
99
109
  const I = U(D), i = U({
100
- darkMode: u(D)
110
+ darkMode: l(D)
101
111
  });
102
- k.addEventListener("change", M), L(
112
+ k.addEventListener("change", M), A(
103
113
  () => c.mode,
104
114
  () => {
105
115
  f();
106
116
  },
107
117
  { immediate: !0 }
108
- ), L(
118
+ ), A(
109
119
  () => i.value.darkMode,
110
120
  (e, t) => {
111
121
  if (t === void 0) {
@@ -117,16 +127,16 @@ const Oe = "(prefers-color-scheme: dark)", Re = "(prefers-reduced-motion: reduce
117
127
  });
118
128
  },
119
129
  { immediate: !0 }
120
- ), le(() => {
130
+ ), ue(() => {
121
131
  k.removeEventListener("change", M);
122
- const e = s.indexOf(N);
123
- e !== -1 && s.splice(e, 1), g();
132
+ const e = s.indexOf($);
133
+ e !== -1 && s.splice(e, 1), p();
124
134
  });
125
135
  function f() {
126
136
  const e = Q();
127
- I.value = e, i.value.darkMode = u(e);
137
+ I.value = e, i.value.darkMode = l(e);
128
138
  }
129
- function u(e) {
139
+ function l(e) {
130
140
  return e === "dark" ? !0 : e === "light" ? !1 : k.matches;
131
141
  }
132
142
  function M(e) {
@@ -136,7 +146,7 @@ const Oe = "(prefers-color-scheme: dark)", Re = "(prefers-reduced-motion: reduce
136
146
  document.documentElement.setAttribute("dark-mode", e);
137
147
  }
138
148
  function ee(e) {
139
- if (P.matches) {
149
+ if (j.matches) {
140
150
  e();
141
151
  return;
142
152
  }
@@ -157,7 +167,7 @@ const Oe = "(prefers-color-scheme: dark)", Re = "(prefers-reduced-motion: reduce
157
167
  });
158
168
  }
159
169
  function Q() {
160
- return c.mode ?? G() ?? "auto";
170
+ return c.mode ?? Y() ?? "auto";
161
171
  }
162
172
  de("theme", i);
163
173
  function q(e) {
@@ -165,56 +175,56 @@ const Oe = "(prefers-color-scheme: dark)", Re = "(prefers-reduced-motion: reduce
165
175
  const t = e.trim().toLowerCase();
166
176
  if (!/^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i.exec(t)) return null;
167
177
  if (t.length === 4) {
168
- const o = t[1], l = t[2], m = t[3];
169
- return `#${o}${o}${l}${l}${m}${m}`;
178
+ const o = t[1], u = t[2], m = t[3];
179
+ return `#${o}${o}${u}${u}${m}${m}`;
170
180
  }
171
181
  return t;
172
182
  }
173
183
  function te(e) {
174
184
  const t = q(e);
175
185
  if (!t) return null;
176
- const r = parseInt(t.slice(1, 3), 16), o = parseInt(t.slice(3, 5), 16), l = parseInt(t.slice(5, 7), 16);
177
- return { r, g: o, b: l };
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 };
178
188
  }
179
189
  function ne({ r: e, g: t, b: r }) {
180
- const o = (l) => l.toString(16).padStart(2, "0");
190
+ const o = (u) => u.toString(16).padStart(2, "0");
181
191
  return `#${o(e)}${o(t)}${o(r)}`;
182
192
  }
183
193
  function h(e) {
184
194
  return Math.max(0, Math.min(1, e));
185
195
  }
186
- function B(e) {
196
+ function P(e) {
187
197
  return e <= 0.04045 ? e / 12.92 : Math.pow((e + 0.055) / 1.055, 2.4);
188
198
  }
189
- function H(e) {
199
+ function G(e) {
190
200
  const t = h(e);
191
201
  return t <= 31308e-7 ? 12.92 * t : 1.055 * Math.pow(t, 1 / 2.4) - 0.055;
192
202
  }
193
203
  function oe({ r: e, g: t, b: r }) {
194
- const o = e / 255, l = t / 255, m = r / 255, w = B(o), _ = B(l), d = B(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, p = Math.cbrt(v), y = Math.cbrt(E), T = Math.cbrt(S), $ = 0.2104542553 * p + 0.793617785 * y - 0.0040720468 * T, O = 1.9779984951 * p - 2.428592205 * y + 0.4505937099 * T, R = 0.0259040371 * p + 0.7827717662 * y - 0.808675766 * T, C = Math.sqrt(O * O + R * R);
195
- let A = Math.atan2(R, O) * (180 / Math.PI);
196
- return A < 0 && (A += 360), { l: $, c: C, h: A };
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);
206
+ return x < 0 && (x += 360), { l: L, c: C, h: x };
197
207
  }
198
208
  function z(e, t, r, o = !1) {
199
- const l = r * Math.PI / 180, m = t * Math.cos(l), w = t * Math.sin(l), _ = 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, p = o ? h(v) : v;
200
- if (!o && (E < -1e-4 || E > 1.0001 || S < -1e-4 || S > 1.0001 || p < -1e-4 || p > 1.0001))
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))
201
211
  return null;
202
- const y = E * E * E, T = S * S * S, $ = p * p * p;
203
- let O = 4.0767416621 * y - 3.3077115913 * T + 0.2309699292 * $, R = -1.2684380046 * y + 2.6097574011 * T - 0.3413193965 * $, C = -0.0041960863 * y - 0.7034186147 * T + 1.707614701 * $;
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;
204
214
  if (o)
205
215
  O = h(O), R = h(R), C = h(C);
206
216
  else if (O < -1e-4 || O > 1.0001 || R < -1e-4 || R > 1.0001 || C < -1e-4 || C > 1.0001)
207
217
  return null;
208
- const A = h(H(O)), se = h(H(R)), ie = h(H(C));
218
+ const x = h(G(O)), se = h(G(R)), ie = h(G(C));
209
219
  return {
210
- r: Math.round(A * 255),
220
+ r: Math.round(x * 255),
211
221
  g: Math.round(se * 255),
212
222
  b: Math.round(ie * 255)
213
223
  };
214
224
  }
215
225
  function re(e, t, r) {
216
226
  let o = t;
217
- for (let l = 0; l < 8; l += 1) {
227
+ for (let u = 0; u < 8; u += 1) {
218
228
  const m = z(e, o, r);
219
229
  if (m)
220
230
  return m;
@@ -227,7 +237,7 @@ const Oe = "(prefers-color-scheme: dark)", Re = "(prefers-reduced-motion: reduce
227
237
  if (!t) return null;
228
238
  const r = te(t);
229
239
  if (!r) return null;
230
- const o = oe(r), l = {
240
+ const o = oe(r), u = {
231
241
  100: { lightness: 0.35, chroma: 0.45 },
232
242
  200: { lightness: 0.28, chroma: 0.5 },
233
243
  300: { lightness: 0.22, chroma: 0.6 },
@@ -244,23 +254,30 @@ const Oe = "(prefers-color-scheme: dark)", Re = "(prefers-reduced-motion: reduce
244
254
  const v = o.c * d;
245
255
  return Math.max(0, Math.min(0.4, v));
246
256
  };
247
- return Object.entries(l).forEach(([d, v]) => {
257
+ return Object.entries(u).forEach(([d, v]) => {
248
258
  const E = `--color-brand-${d}`;
249
259
  if (v.base) {
250
260
  m[E] = t;
251
261
  return;
252
262
  }
253
- const S = w(v.lightness), p = _(v.chroma), y = re(S, p, o.h);
263
+ const S = w(v.lightness), b = _(v.chroma), y = re(S, b, o.h);
254
264
  m[E] = ne(y);
255
265
  }), m;
256
266
  }
257
- const F = Y(() => ce(c.accentColor) ?? {}), ae = Y(() => F.value), N = {
258
- vars: {}
267
+ const F = V(() => ce(c.accentColor) ?? {}), ae = V(() => F.value), $ = {
268
+ vars: {},
269
+ enabled: !!c.exposeGlobalAccent
259
270
  };
260
- return s.push(N), L(
271
+ return s.push($), A(
272
+ () => c.exposeGlobalAccent,
273
+ (e) => {
274
+ $.enabled = !!e, p();
275
+ },
276
+ { immediate: !0 }
277
+ ), A(
261
278
  F,
262
279
  (e) => {
263
- e && Object.keys(e).length > 0 ? N.vars = { ...e } : N.vars = {}, g();
280
+ e && Object.keys(e).length > 0 ? $.vars = { ...e } : $.vars = {}, p();
264
281
  },
265
282
  { immediate: !0 }
266
283
  ), (e, t) => (J(), me("div", {
@@ -272,8 +289,8 @@ const Oe = "(prefers-color-scheme: dark)", Re = "(prefers-reduced-motion: reduce
272
289
  }
273
290
  }), De = (n, c) => {
274
291
  const s = n.__vccOpts || n;
275
- for (const [a, g] of c)
276
- s[a] = g;
292
+ for (const [a, p] of c)
293
+ s[a] = p;
277
294
  return s;
278
295
  }, Te = {
279
296
  __name: "ThemeSwitcher",
@@ -290,61 +307,61 @@ const Oe = "(prefers-color-scheme: dark)", Re = "(prefers-reduced-motion: reduce
290
307
  { value: "auto", label: "System" },
291
308
  { value: "light", label: "Light" },
292
309
  { value: "dark", label: "Dark" }
293
- ].reduce((f, u) => (f[u.value] = u.label, f), {}), g = j, k = n, P = c;
310
+ ].reduce((f, l) => (f[l.value] = l.label, f), {}), p = B, k = n, j = c;
294
311
  Z();
295
- const D = U(!1), I = G() ?? k.mode, i = U(
296
- g.includes(I) ? I : "auto"
312
+ const D = U(!1), I = Y() ?? k.mode, i = U(
313
+ p.includes(I) ? I : "auto"
297
314
  );
298
- return Y(
315
+ return V(
299
316
  () => a[i.value] ?? a.auto
300
- ), L(
317
+ ), A(
301
318
  () => k.mode,
302
319
  (f) => {
303
- g.includes(f) && f !== i.value && (i.value = f);
320
+ p.includes(f) && f !== i.value && (i.value = f);
304
321
  }
305
- ), L(
322
+ ), A(
306
323
  i,
307
324
  (f) => {
308
- if (!g.includes(f)) {
325
+ if (!p.includes(f)) {
309
326
  i.value = "auto";
310
327
  return;
311
328
  }
312
- D.value = !1, P("update:mode", f), Ee(f);
329
+ D.value = !1, j("update:mode", f), Ee(f);
313
330
  },
314
331
  { immediate: !0 }
315
- ), (f, u) => (J(), pe(b(ge), {
332
+ ), (f, l) => (J(), pe(g(ge), {
316
333
  open: D.value,
317
- "onUpdate:open": u[3] || (u[3] = (M) => D.value = M),
334
+ "onUpdate:open": l[3] || (l[3] = (M) => D.value = M),
318
335
  text: "Theme",
319
336
  "aria-label": "Select theme mode"
320
337
  }, {
321
338
  default: W(() => [
322
- x(b(ke), { title: "Theme" }, {
339
+ N(g(ke), { title: "Theme" }, {
323
340
  default: W(() => [
324
- x(b(V), {
341
+ N(g(H), {
325
342
  checked: i.value,
326
- "onUpdate:checked": u[0] || (u[0] = (M) => i.value = M),
343
+ "onUpdate:checked": l[0] || (l[0] = (M) => i.value = M),
327
344
  value: "auto",
328
- label: b(a).auto,
329
- "aria-label": `${b(a).auto} mode`
345
+ label: g(a).auto,
346
+ "aria-label": `${g(a).auto} mode`
330
347
  }, null, 8, ["checked", "label", "aria-label"]),
331
- u[4] || (u[4] = be("hr", {
348
+ l[4] || (l[4] = be("hr", {
332
349
  class: "theme-switcher-divider",
333
350
  role: "separator"
334
351
  }, null, -1)),
335
- x(b(V), {
352
+ N(g(H), {
336
353
  checked: i.value,
337
- "onUpdate:checked": u[1] || (u[1] = (M) => i.value = M),
354
+ "onUpdate:checked": l[1] || (l[1] = (M) => i.value = M),
338
355
  value: "light",
339
- label: b(a).light,
340
- "aria-label": `${b(a).light} mode`
356
+ label: g(a).light,
357
+ "aria-label": `${g(a).light} mode`
341
358
  }, null, 8, ["checked", "label", "aria-label"]),
342
- x(b(V), {
359
+ N(g(H), {
343
360
  checked: i.value,
344
- "onUpdate:checked": u[2] || (u[2] = (M) => i.value = M),
361
+ "onUpdate:checked": l[2] || (l[2] = (M) => i.value = M),
345
362
  value: "dark",
346
- label: b(a).dark,
347
- "aria-label": `${b(a).dark} mode`
363
+ label: g(a).dark,
364
+ "aria-label": `${g(a).dark} mode`
348
365
  }, null, 8, ["checked", "label", "aria-label"])
349
366
  ]),
350
367
  _: 1
@@ -355,7 +372,7 @@ const Oe = "(prefers-color-scheme: dark)", Re = "(prefers-reduced-motion: reduce
355
372
  }
356
373
  }, Le = /* @__PURE__ */ De(Te, [["__scopeId", "data-v-bcbc87cb"]]);
357
374
  export {
358
- Ae as Theme,
375
+ $e as Theme,
359
376
  Le as ThemeSwitcher
360
377
  };
361
378
  //# 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\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((entry) => entry.vars && Object.keys(entry.vars).length > 0);\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};\nglobalAccentStack.push(accentStackEntry);\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","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.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":"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"}
package/dist/theme.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- (function(g,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):(g=typeof globalThis<"u"?globalThis:g||self,t(g.theme={},g.Vue,g.whatInput,g.DropdownMenu))})(this,function(g,t,pe,N){"use strict";const v=["auto","light","dark"],q="gospore-theme-mode",F="(prefers-color-scheme: dark)";function j(){if(typeof document>"u")return null;const o=J(q);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:"",s=typeof window<"u"?window.location.protocol:"",i=X(a),k=s==="https:",M=["path=/","max-age=31536000","SameSite=Lax"];i&&M.push(`domain=${i}`),k&&M.push("Secure"),document.cookie=[`${encodeURIComponent(q)}=${encodeURIComponent(o)}`,...M].join("; ")}function Y(o){if(typeof document>"u")return;const a=typeof o=="string"&&v.includes(o)?o:j()??"auto";console.log("Applying theme mode:",a);const s=Z(a);document.documentElement.setAttribute("dark-mode",s)}function J(o){if(typeof document>"u"||!document.cookie)return null;const a=`${encodeURIComponent(o)}=`,s=document.cookie.split("; ");for(const i of s)if(i.startsWith(a))return decodeURIComponent(i.slice(a.length));return null}function X(o){if(!o||o==="localhost")return null;if(/^\d+(?:\.\d+){3}$/.test(o))return o;const s=o.split(".");return s.length<=1?null:s.length===2?o:s.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}},setup(o){const a=o,s=[],i=new Set;function k(){const e=document.documentElement;if(!e)return;i.forEach(c=>{e.style.removeProperty(c)}),i.clear();const n=[...s].reverse().find(c=>c.vars&&Object.keys(c.vars).length>0);n&&Object.entries(n.vars).forEach(([c,r])=>{e.style.setProperty(c,r),i.add(c)})}const M=window.matchMedia(ee),P=window.matchMedia(te),I=G();Y(I);const A=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){H(e);return}ce(()=>{H(e)})},{immediate:!0}),t.onBeforeUnmount(()=>{M.removeEventListener("change",w);const e=s.indexOf(U);e!==-1&&s.splice(e,1),k()});function h(){const e=G();A.value=e,l.value.darkMode=u(e)}function u(e){return e==="dark"?!0:e==="light"?!1:M.matches}function w(e){!e||A.value!=="auto"||(l.value.darkMode=e.matches)}function H(e){document.documentElement.setAttribute("dark-mode",e)}function ce(e){if(P.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 G(){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 ie({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 V(e){return e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)}function B(e){const n=p(e);return n<=.0031308?12.92*n:1.055*Math.pow(n,1/2.4)-.055}function se({r:e,g:n,b:c}){const r=e/255,d=n/255,m=c/255,y=V(r),T=V(d),f=V(m),E=.4122214708*y+.5363325363*T+.0514459929*f,S=.2119034982*y+.6806995451*T+.1073969566*f,O=.0883024619*y+.2817188376*T+.6299787005*f,b=Math.cbrt(E),_=Math.cbrt(S),C=Math.cbrt(O),L=.2104542553*b+.793617785*_-.0040720468*C,R=1.9779984951*b-2.428592205*_+.4505937099*C,D=.0259040371*b+.7827717662*_-.808675766*C,$=Math.sqrt(R*R+D*D);let x=Math.atan2(D,R)*(180/Math.PI);return x<0&&(x+=360),{l:L,c:$,h:x}}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,b=r?p(E):E;if(!r&&(S<-1e-4||S>1.0001||O<-1e-4||O>1.0001||b<-1e-4||b>1.0001))return null;const _=S*S*S,C=O*O*O,L=b*b*b;let R=4.0767416621*_-3.3077115913*C+.2309699292*L,D=-1.2684380046*_+2.6097574011*C-.3413193965*L,$=-.0041960863*_-.7034186147*C+1.707614701*L;if(r)R=p(R),D=p(D),$=p($);else if(R<-1e-4||R>1.0001||D<-1e-4||D>1.0001||$<-1e-4||$>1.0001)return null;const x=p(B(R)),fe=p(B(D)),me=p(B($));return{r:Math.round(x*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=se(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),b=T(E.chroma),_=le(O,b,r.h);m[S]=ie(_)}),m}const z=t.computed(()=>ue(a.accentColor)??{}),de=t.computed(()=>z.value),U={vars:{}};return s.push(U),t.watch(z,e=>{e&&Object.keys(e).length>0?U.vars={...e}:U.vars={},k()},{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 s=o.__vccOpts||o;for(const[i,k]of a)s[i]=k;return s})({__name:"ThemeSwitcher",props:{mode:{type:String,default:"auto",validator:o=>["auto","light","dark"].includes(o)}},emits:["update:mode"],setup(o,{emit:a}){const i=[{value:"auto",label:"System"},{value:"light",label:"Light"},{value:"dark",label:"Dark"}].reduce((h,u)=>(h[u.value]=u.label,h),{}),k=v,M=o,P=a;Y();const I=t.ref(!1),A=j()??M.mode,l=t.ref(k.includes(A)?A:"auto");return t.computed(()=>i[l.value]??i.auto),t.watch(()=>M.mode,h=>{k.includes(h)&&h!==l.value&&(l.value=h)}),t.watch(l,h=>{if(!k.includes(h)){l.value="auto";return}I.value=!1,P("update:mode",h),W(h)},{immediate:!0}),(h,u)=>(t.openBlock(),t.createBlock(t.unref(N.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(N.DropdownItemGroup),{title:"Theme"},{default:t.withCtx(()=>[t.createVNode(t.unref(N.DropdownItemRadio),{checked:l.value,"onUpdate:checked":u[0]||(u[0]=w=>l.value=w),value:"auto",label:t.unref(i).auto,"aria-label":`${t.unref(i).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(N.DropdownItemRadio),{checked:l.value,"onUpdate:checked":u[1]||(u[1]=w=>l.value=w),value:"light",label:t.unref(i).light,"aria-label":`${t.unref(i).light} mode`},null,8,["checked","label","aria-label"]),t.createVNode(t.unref(N.DropdownItemRadio),{checked:l.value,"onUpdate:checked":u[2]||(u[2]=w=>l.value=w),value:"dark",label:t.unref(i).dark,"aria-label":`${t.unref(i).dark} mode`},null,8,["checked","label","aria-label"])]),_:1})]),_:1},8,["open"]))}},[["__scopeId","data-v-bcbc87cb"]]);g.Theme=oe,g.ThemeSwitcher=re,Object.defineProperty(g,Symbol.toStringTag,{value:"Module"})});
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"})});
2
2
  //# sourceMappingURL=theme.umd.js.map