@gospore/theme 1.0.123 → 1.0.125

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,218 +1,350 @@
1
- import { ref as v, watch as M, onBeforeUnmount as O, provide as R, createElementBlock as T, openBlock as D, renderSlot as I, computed as A, createBlock as U, unref as l, withCtx as g, createVNode as k, createElementVNode as B } from "vue";
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";
2
2
  import "what-input";
3
- import { DropdownMenu as $, DropdownItemGroup as C, DropdownItemRadio as E } from "@gospore/dropdown-menu";
4
- const w = ["auto", "light", "dark"], b = "gospore-theme-mode", L = 60 * 60 * 24 * 365, x = "(prefers-color-scheme: dark)";
5
- function N() {
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() {
6
6
  if (typeof document > "u")
7
7
  return null;
8
- const e = V(b);
9
- return e && w.includes(e) ? e : null;
8
+ const n = we(X);
9
+ return n && j.includes(n) ? n : null;
10
10
  }
11
- function Y(e) {
12
- if (typeof document > "u" || !w.includes(e))
11
+ function Ee(n) {
12
+ if (typeof document > "u" || !j.includes(n))
13
13
  return;
14
- const t = typeof window < "u" ? window.location.hostname : "", r = typeof window < "u" ? window.location.protocol : "", n = G(t), i = r === "https:", u = [
14
+ const c = typeof window < "u" ? window.location.hostname : "", s = typeof window < "u" ? window.location.protocol : "", a = Se(c), g = s === "https:", k = [
15
15
  "path=/",
16
- `max-age=${L}`,
16
+ `max-age=${Me}`,
17
17
  "SameSite=Lax"
18
18
  ];
19
- n && u.push(`domain=${n}`), i && u.push("Secure"), document.cookie = [
20
- `${encodeURIComponent(b)}=${encodeURIComponent(e)}`,
21
- ...u
19
+ a && k.push(`domain=${a}`), g && k.push("Secure"), document.cookie = [
20
+ `${encodeURIComponent(X)}=${encodeURIComponent(n)}`,
21
+ ...k
22
22
  ].join("; ");
23
23
  }
24
- function S(e) {
24
+ function Z(n) {
25
25
  if (typeof document > "u")
26
26
  return;
27
- const t = typeof e == "string" && w.includes(e) ? e : N() ?? "auto";
28
- console.log("Applying theme mode:", t);
29
- const r = P(t);
30
- document.documentElement.setAttribute("dark-mode", r);
27
+ const c = typeof n == "string" && j.includes(n) ? n : G() ?? "auto";
28
+ console.log("Applying theme mode:", c);
29
+ const s = ye(c);
30
+ document.documentElement.setAttribute("dark-mode", s);
31
31
  }
32
- function V(e) {
32
+ function we(n) {
33
33
  if (typeof document > "u" || !document.cookie)
34
34
  return null;
35
- const t = `${encodeURIComponent(e)}=`, r = document.cookie.split("; ");
36
- for (const n of r)
37
- if (n.startsWith(t))
38
- return decodeURIComponent(n.slice(t.length));
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));
39
39
  return null;
40
40
  }
41
- function G(e) {
42
- if (!e || e === "localhost")
41
+ function Se(n) {
42
+ if (!n || n === "localhost")
43
43
  return null;
44
- if (/^\d+(?:\.\d+){3}$/.test(e))
45
- return e;
46
- const r = e.split(".");
47
- return r.length <= 1 ? null : r.length === 2 ? e : r.slice(-2).join(".");
44
+ if (/^\d+(?:\.\d+){3}$/.test(n))
45
+ return n;
46
+ const s = n.split(".");
47
+ return s.length <= 1 ? null : s.length === 2 ? n : s.slice(-2).join(".");
48
48
  }
49
- function P(e) {
50
- if (e === "dark")
49
+ function ye(n) {
50
+ if (n === "dark")
51
51
  return !0;
52
- if (e === "light" || typeof window > "u")
52
+ if (n === "light" || typeof window > "u")
53
53
  return !1;
54
54
  try {
55
- const t = typeof window.matchMedia == "function" ? window.matchMedia(x) : null;
56
- return t ? t.matches : !1;
55
+ const c = typeof window.matchMedia == "function" ? window.matchMedia(ve) : null;
56
+ return c ? c.matches : !1;
57
57
  } catch {
58
58
  return !1;
59
59
  }
60
60
  }
61
- const Q = { class: "theme" }, j = "(prefers-color-scheme: dark)", K = "(prefers-reduced-motion: reduce)", F = 200, Z = /* @__PURE__ */ Object.assign({
61
+ const Oe = "(prefers-color-scheme: dark)", Re = "(prefers-reduced-motion: reduce)", _e = 200, Ae = /* @__PURE__ */ Object.assign({
62
62
  name: "Theme"
63
63
  }, {
64
64
  __name: "Theme",
65
65
  props: {
66
66
  mode: {
67
67
  type: String,
68
- validator: (e) => ["auto", "light", "dark"].includes(e)
68
+ validator: (n) => ["auto", "light", "dark"].includes(n)
69
+ },
70
+ /**
71
+ * Optional hex accent color ("#RRGGBB" or "#RGB"). When provided,
72
+ * Theme derives the `--color-brand-*` palette and exposes the tokens on
73
+ * the root .theme element (and the global document for portals).
74
+ */
75
+ accentColor: {
76
+ type: String,
77
+ required: !1,
78
+ default: void 0
69
79
  }
70
80
  },
71
- setup(e) {
72
- const t = e, r = window.matchMedia(j), n = window.matchMedia(
73
- K
74
- ), i = d();
75
- S(i);
76
- const u = v(i), m = v({
77
- darkMode: h(i)
81
+ setup(n) {
82
+ const c = n, s = [], a = /* @__PURE__ */ new Set();
83
+ function g() {
84
+ const e = document.documentElement;
85
+ if (!e)
86
+ return;
87
+ a.forEach((r) => {
88
+ e.style.removeProperty(r);
89
+ }), a.clear();
90
+ const t = [...s].reverse().find((r) => r.vars && Object.keys(r.vars).length > 0);
91
+ t && Object.entries(t.vars).forEach(([r, o]) => {
92
+ e.style.setProperty(r, o), a.add(r);
93
+ });
94
+ }
95
+ const k = window.matchMedia(Oe), P = window.matchMedia(
96
+ Re
97
+ ), D = Q();
98
+ Z(D);
99
+ const I = U(D), i = U({
100
+ darkMode: u(D)
78
101
  });
79
- r.addEventListener("change", c), M(
80
- () => t.mode,
102
+ k.addEventListener("change", M), L(
103
+ () => c.mode,
81
104
  () => {
82
105
  f();
83
106
  },
84
107
  { immediate: !0 }
85
- ), M(
86
- () => m.value.darkMode,
87
- (o, p) => {
88
- if (p === void 0) {
89
- a(o);
108
+ ), L(
109
+ () => i.value.darkMode,
110
+ (e, t) => {
111
+ if (t === void 0) {
112
+ K(e);
90
113
  return;
91
114
  }
92
- s(() => {
93
- a(o);
115
+ ee(() => {
116
+ K(e);
94
117
  });
95
118
  },
96
119
  { immediate: !0 }
97
- ), O(() => {
98
- r.removeEventListener("change", c);
120
+ ), le(() => {
121
+ k.removeEventListener("change", M);
122
+ const e = s.indexOf(N);
123
+ e !== -1 && s.splice(e, 1), g();
99
124
  });
100
125
  function f() {
101
- const o = d();
102
- u.value = o, m.value.darkMode = h(o);
126
+ const e = Q();
127
+ I.value = e, i.value.darkMode = u(e);
103
128
  }
104
- function h(o) {
105
- return o === "dark" ? !0 : o === "light" ? !1 : r.matches;
129
+ function u(e) {
130
+ return e === "dark" ? !0 : e === "light" ? !1 : k.matches;
106
131
  }
107
- function c(o) {
108
- !o || u.value !== "auto" || (m.value.darkMode = o.matches);
132
+ function M(e) {
133
+ !e || I.value !== "auto" || (i.value.darkMode = e.matches);
109
134
  }
110
- function a(o) {
111
- document.documentElement.setAttribute("dark-mode", o);
135
+ function K(e) {
136
+ document.documentElement.setAttribute("dark-mode", e);
112
137
  }
113
- function s(o) {
114
- if (n.matches) {
115
- o();
138
+ function ee(e) {
139
+ if (P.matches) {
140
+ e();
116
141
  return;
117
142
  }
118
- const p = document.startViewTransition?.bind(document);
119
- if (p) {
120
- p(() => {
121
- o();
143
+ const t = document.startViewTransition?.bind(document);
144
+ if (t) {
145
+ t(() => {
146
+ e();
122
147
  });
123
148
  return;
124
149
  }
125
- o();
126
- const _ = document.documentElement;
127
- typeof _.animate == "function" && window.requestAnimationFrame(() => {
128
- _.animate([{ opacity: 0.85 }, { opacity: 1 }], {
129
- duration: F,
150
+ e();
151
+ const r = document.documentElement;
152
+ typeof r.animate == "function" && window.requestAnimationFrame(() => {
153
+ r.animate([{ opacity: 0.85 }, { opacity: 1 }], {
154
+ duration: _e,
130
155
  easing: "ease-in-out"
131
156
  });
132
157
  });
133
158
  }
134
- function d() {
135
- return t.mode ?? N() ?? "auto";
159
+ function Q() {
160
+ return c.mode ?? G() ?? "auto";
161
+ }
162
+ de("theme", i);
163
+ function q(e) {
164
+ if (!e) return null;
165
+ const t = e.trim().toLowerCase();
166
+ if (!/^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i.exec(t)) return null;
167
+ if (t.length === 4) {
168
+ const o = t[1], l = t[2], m = t[3];
169
+ return `#${o}${o}${l}${l}${m}${m}`;
170
+ }
171
+ return t;
172
+ }
173
+ function te(e) {
174
+ const t = q(e);
175
+ 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 };
178
+ }
179
+ function ne({ r: e, g: t, b: r }) {
180
+ const o = (l) => l.toString(16).padStart(2, "0");
181
+ return `#${o(e)}${o(t)}${o(r)}`;
182
+ }
183
+ function h(e) {
184
+ return Math.max(0, Math.min(1, e));
185
+ }
186
+ function B(e) {
187
+ return e <= 0.04045 ? e / 12.92 : Math.pow((e + 0.055) / 1.055, 2.4);
136
188
  }
137
- return R("theme", m), (o, p) => (D(), T("div", Q, [
138
- I(o.$slots, "default")
139
- ]));
189
+ function H(e) {
190
+ const t = h(e);
191
+ return t <= 31308e-7 ? 12.92 * t : 1.055 * Math.pow(t, 1 / 2.4) - 0.055;
192
+ }
193
+ 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 };
197
+ }
198
+ 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))
201
+ 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 * $;
204
+ if (o)
205
+ O = h(O), R = h(R), C = h(C);
206
+ else if (O < -1e-4 || O > 1.0001 || R < -1e-4 || R > 1.0001 || C < -1e-4 || C > 1.0001)
207
+ return null;
208
+ const A = h(H(O)), se = h(H(R)), ie = h(H(C));
209
+ return {
210
+ r: Math.round(A * 255),
211
+ g: Math.round(se * 255),
212
+ b: Math.round(ie * 255)
213
+ };
214
+ }
215
+ function re(e, t, r) {
216
+ let o = t;
217
+ for (let l = 0; l < 8; l += 1) {
218
+ const m = z(e, o, r);
219
+ if (m)
220
+ return m;
221
+ o *= 0.9;
222
+ }
223
+ return z(e, h(o), r, !0) || { r: 0, g: 0, b: 0 };
224
+ }
225
+ function ce(e) {
226
+ const t = q(e);
227
+ if (!t) return null;
228
+ const r = te(t);
229
+ if (!r) return null;
230
+ const o = oe(r), l = {
231
+ 100: { lightness: 0.35, chroma: 0.45 },
232
+ 200: { lightness: 0.28, chroma: 0.5 },
233
+ 300: { lightness: 0.22, chroma: 0.6 },
234
+ 400: { lightness: 0.16, chroma: 0.75 },
235
+ 500: { lightness: 0.08, chroma: 0.9 },
236
+ 600: { lightness: 0, chroma: 1, base: !0 },
237
+ 700: { lightness: -0.08, chroma: 1.05 },
238
+ 800: { lightness: -0.18, chroma: 1.1 },
239
+ 900: { lightness: -0.28, chroma: 1.15 },
240
+ 1e3: { lightness: -0.35, chroma: 1.2 }
241
+ }, m = {}, w = (d) => d === 0 ? o.l : d > 0 ? h(o.l + d * (1 - o.l)) : h(o.l * (1 + d)), _ = (d) => {
242
+ if (d === 1)
243
+ return o.c;
244
+ const v = o.c * d;
245
+ return Math.max(0, Math.min(0.4, v));
246
+ };
247
+ return Object.entries(l).forEach(([d, v]) => {
248
+ const E = `--color-brand-${d}`;
249
+ if (v.base) {
250
+ m[E] = t;
251
+ return;
252
+ }
253
+ const S = w(v.lightness), p = _(v.chroma), y = re(S, p, o.h);
254
+ m[E] = ne(y);
255
+ }), m;
256
+ }
257
+ const F = Y(() => ce(c.accentColor) ?? {}), ae = Y(() => F.value), N = {
258
+ vars: {}
259
+ };
260
+ return s.push(N), L(
261
+ F,
262
+ (e) => {
263
+ e && Object.keys(e).length > 0 ? N.vars = { ...e } : N.vars = {}, g();
264
+ },
265
+ { immediate: !0 }
266
+ ), (e, t) => (J(), me("div", {
267
+ class: "theme",
268
+ style: fe(ae.value)
269
+ }, [
270
+ he(e.$slots, "default")
271
+ ], 4));
140
272
  }
141
- }), H = (e, t) => {
142
- const r = e.__vccOpts || e;
143
- for (const [n, i] of t)
144
- r[n] = i;
145
- return r;
146
- }, q = {
273
+ }), De = (n, c) => {
274
+ const s = n.__vccOpts || n;
275
+ for (const [a, g] of c)
276
+ s[a] = g;
277
+ return s;
278
+ }, Te = {
147
279
  __name: "ThemeSwitcher",
148
280
  props: {
149
281
  mode: {
150
282
  type: String,
151
283
  default: "auto",
152
- validator: (e) => ["auto", "light", "dark"].includes(e)
284
+ validator: (n) => ["auto", "light", "dark"].includes(n)
153
285
  }
154
286
  },
155
287
  emits: ["update:mode"],
156
- setup(e, { emit: t }) {
157
- const n = [
288
+ setup(n, { emit: c }) {
289
+ const a = [
158
290
  { value: "auto", label: "System" },
159
291
  { value: "light", label: "Light" },
160
292
  { value: "dark", label: "Dark" }
161
- ].reduce((a, s) => (a[s.value] = s.label, a), {}), i = w, u = e, m = t;
162
- S();
163
- const f = v(!1), h = N() ?? u.mode, c = v(
164
- i.includes(h) ? h : "auto"
293
+ ].reduce((f, u) => (f[u.value] = u.label, f), {}), g = j, k = n, P = c;
294
+ Z();
295
+ const D = U(!1), I = G() ?? k.mode, i = U(
296
+ g.includes(I) ? I : "auto"
165
297
  );
166
- return A(
167
- () => n[c.value] ?? n.auto
168
- ), M(
169
- () => u.mode,
170
- (a) => {
171
- i.includes(a) && a !== c.value && (c.value = a);
298
+ return Y(
299
+ () => a[i.value] ?? a.auto
300
+ ), L(
301
+ () => k.mode,
302
+ (f) => {
303
+ g.includes(f) && f !== i.value && (i.value = f);
172
304
  }
173
- ), M(
174
- c,
175
- (a) => {
176
- if (!i.includes(a)) {
177
- c.value = "auto";
305
+ ), L(
306
+ i,
307
+ (f) => {
308
+ if (!g.includes(f)) {
309
+ i.value = "auto";
178
310
  return;
179
311
  }
180
- f.value = !1, m("update:mode", a), Y(a);
312
+ D.value = !1, P("update:mode", f), Ee(f);
181
313
  },
182
314
  { immediate: !0 }
183
- ), (a, s) => (D(), U(l($), {
184
- open: f.value,
185
- "onUpdate:open": s[3] || (s[3] = (d) => f.value = d),
315
+ ), (f, u) => (J(), pe(b(ge), {
316
+ open: D.value,
317
+ "onUpdate:open": u[3] || (u[3] = (M) => D.value = M),
186
318
  text: "Theme",
187
319
  "aria-label": "Select theme mode"
188
320
  }, {
189
- default: g(() => [
190
- k(l(C), { title: "Theme" }, {
191
- default: g(() => [
192
- k(l(E), {
193
- checked: c.value,
194
- "onUpdate:checked": s[0] || (s[0] = (d) => c.value = d),
321
+ default: W(() => [
322
+ x(b(ke), { title: "Theme" }, {
323
+ default: W(() => [
324
+ x(b(V), {
325
+ checked: i.value,
326
+ "onUpdate:checked": u[0] || (u[0] = (M) => i.value = M),
195
327
  value: "auto",
196
- label: l(n).auto,
197
- "aria-label": `${l(n).auto} mode`
328
+ label: b(a).auto,
329
+ "aria-label": `${b(a).auto} mode`
198
330
  }, null, 8, ["checked", "label", "aria-label"]),
199
- s[4] || (s[4] = B("hr", {
331
+ u[4] || (u[4] = be("hr", {
200
332
  class: "theme-switcher-divider",
201
333
  role: "separator"
202
334
  }, null, -1)),
203
- k(l(E), {
204
- checked: c.value,
205
- "onUpdate:checked": s[1] || (s[1] = (d) => c.value = d),
335
+ x(b(V), {
336
+ checked: i.value,
337
+ "onUpdate:checked": u[1] || (u[1] = (M) => i.value = M),
206
338
  value: "light",
207
- label: l(n).light,
208
- "aria-label": `${l(n).light} mode`
339
+ label: b(a).light,
340
+ "aria-label": `${b(a).light} mode`
209
341
  }, null, 8, ["checked", "label", "aria-label"]),
210
- k(l(E), {
211
- checked: c.value,
212
- "onUpdate:checked": s[2] || (s[2] = (d) => c.value = d),
342
+ x(b(V), {
343
+ checked: i.value,
344
+ "onUpdate:checked": u[2] || (u[2] = (M) => i.value = M),
213
345
  value: "dark",
214
- label: l(n).dark,
215
- "aria-label": `${l(n).dark} mode`
346
+ label: b(a).dark,
347
+ "aria-label": `${b(a).dark} mode`
216
348
  }, null, 8, ["checked", "label", "aria-label"])
217
349
  ]),
218
350
  _: 1
@@ -221,43 +353,9 @@ const Q = { class: "theme" }, j = "(prefers-color-scheme: dark)", K = "(prefers-
221
353
  _: 1
222
354
  }, 8, ["open"]));
223
355
  }
224
- }, ee = /* @__PURE__ */ H(q, [["__scopeId", "data-v-9b82a61c"]]), te = "hsl(225, 90%, 16%)", oe = "#061f80", y = "hsl(225, 94%, 35%)", ne = "#06c", re = "hsl(210, 100%, 50%)", se = "hsl(210, 100%, 93%)", ce = "hsl(225, 100%, 96%)", ae = "hsl(12, 91%, 46%)", ie = "hsl(11, 100%, 59%)", le = "hsl(40, 100%, 50%)", de = "hsl(46, 100%, 50%)", ue = "hsl(120, 100%, 25%)", me = "#36b37e", fe = "hsl(0, 0%, 0%)", he = "hsl(218, 76%, 15%)", pe = "hsla(0,0%,10%,.9)", ke = "hsla(0,0%,10%,.6)", ve = "hsl(218, 20%, 39%)", Me = "hsl(218, 17%, 44%)", we = "hsl(218, 14%, 49%)", Ee = "hsl(218, 14%, 54%)", Ne = "hsl(218, 13%, 59%)", _e = "hsl(218, 13%, 64%)", ge = "hsl(217, 13%, 69%)", De = "hsl(223, 12%, 89%)", be = "hsl(228, 14%, 93%)", Se = "hsl(210, 7%, 95%)", ye = "hsl(220, 16%, 96%)", Oe = "hsl(210, 25%, 98%)", Re = "hsl(0, 0%, 98%)", W = "hsl(0, 0%, 100%)", Te = y, Ie = y, Ae = W;
356
+ }, Le = /* @__PURE__ */ De(Te, [["__scopeId", "data-v-bcbc87cb"]]);
225
357
  export {
226
- ce as B100,
227
- se as B200,
228
- re as B300,
229
- ne as B400,
230
- y as B500,
231
- oe as B600,
232
- te as B900,
233
- me as G300,
234
- ue as G500,
235
- W as N0,
236
- Oe as N10,
237
- Ee as N100,
238
- fe as N1000,
239
- ye as N20,
240
- we as N200,
241
- Se as N25,
242
- be as N30,
243
- Me as N300,
244
- De as N40,
245
- ve as N400,
246
- Re as N5,
247
- ke as N500,
248
- ge as N70,
249
- _e as N80,
250
- pe as N800,
251
- Ne as N90,
252
- he as N900,
253
- ie as R300,
254
- ae as R400,
255
- Z as Theme,
256
- ee as ThemeSwitcher,
257
- de as Y200,
258
- le as Y300,
259
- Te as primary1,
260
- Ie as primary2,
261
- Ae as primary3
358
+ Ae as Theme,
359
+ Le as ThemeSwitcher
262
360
  };
263
361
  //# sourceMappingURL=theme.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"theme.es.js","sources":["../src/modeStorage.js","../src/Theme.vue","../src/ThemeSwitcher.vue","../src/colors.js"],"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\">\n <slot />\n </div>\n</template>\n\n<script setup>\nimport { provide, ref, watch, onBeforeUnmount } 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\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});\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</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\n</script>\n\n<style scoped lang=\"less\">\n.theme-switcher-divider {\n margin: 4px 0;\n background-color: var(--go-color-n20);\n}\n\n[dark-mode=\"true\"] {\n .theme-switcher-divider {\n background-color: var(--background-color-secondary-dark);\n }\n}\n</style>\n","// Blues\nexport const B900 = \"hsl(225, 90%, 16%)\";\n// @go-color-b700 = #000e7f;\nexport const B600 = \"#061f80\";\nexport const B500 = \"hsl(225, 94%, 35%)\";\n// @go-color-b550 = #131ff2;\n// @go-color-b500 = #001dff;\n// @go-color-b400 = #3333ff;\nexport const B400 = \"#06c\";\nexport const B300 = \"hsl(210, 100%, 50%)\";\nexport const B200 = \"hsl(210, 100%, 93%)\";\nexport const B100 = \"hsl(225, 100%, 96%)\";\n\n// Reds\nexport const R400 = \"hsl(12, 91%, 46%)\";\nexport const R300 = \"hsl(11, 100%, 59%)\";\n\n// Yellows\nexport const Y300 = \"hsl(40, 100%, 50%)\";\nexport const Y200 = \"hsl(46, 100%, 50%)\";\n\n// Greens\nexport const G500 = \"hsl(120, 100%, 25%)\";\nexport const G300 = \"#36b37e\";\n\n// Neutrals\nexport const N1000 = \"hsl(0, 0%, 0%)\";\nexport const N900 = \"hsl(218, 76%, 15%)\";\n// @go-color-n900 = hsl(218, 54%, 20%);\nexport const N800 = \"hsla(0,0%,10%,.9)\";\nexport const N500 = \"hsla(0,0%,10%,.6)\";\nexport const N400 = \"hsl(218, 20%, 39%)\";\nexport const N300 = \"hsl(218, 17%, 44%)\";\nexport const N200 = \"hsl(218, 14%, 49%)\";\nexport const N100 = \"hsl(218, 14%, 54%)\";\nexport const N90 = \"hsl(218, 13%, 59%)\";\nexport const N80 = \"hsl(218, 13%, 64%)\";\nexport const N70 = \"hsl(217, 13%, 69%)\";\nexport const N40 = \"hsl(223, 12%, 89%)\";\nexport const N30 = \"hsl(228, 14%, 93%)\";\nexport const N25 = \"hsl(210, 7%, 95%)\";\nexport const N20 = \"hsl(220, 16%, 96%)\";\nexport const N10 = \"hsl(210, 25%, 98%)\";\nexport const N5 = \"hsl(0, 0%, 98%)\";\nexport const N0 = \"hsl(0, 0%, 100%)\";\n\n// Primary color palette\nexport const primary1 = B500;\nexport const primary2 = B500;\nexport const primary3 = N0;\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","darkModeMedia","prefersReducedMotionMedia","PREFERS_REDUCED_MOTION_QUERY","initialMode","getEffectiveMode","currentMode","ref","theme","handleSystemPreferenceChange","watch","syncDarkMode","previousValue","setDocumentDarkModeAttribute","withThemeTransition","onBeforeUnmount","event","applyTheme","startViewTransition","element","THEME_TRANSITION_DURATION","provide","_openBlock","_createElementBlock","_hoisted_1","_renderSlot","_ctx","MODE_LABELS","map","option","VALID_MODES","emit","__emit","open","internalMode","computed","_createBlock","_unref","DropdownMenu","$event","_createVNode","DropdownItemGroup","DropdownItemRadio","_createElementVNode","B900","B600","B500","B400","B300","B200","B100","R400","R300","Y300","Y200","G500","G300","N1000","N900","N800","N500","N400","N300","N200","N100","N90","N80","N70","N40","N30","N25","N20","N10","N5","N0","primary1","primary2","primary3"],"mappings":";;;AAAA,MAAMA,IAAoB,CAAC,QAAQ,SAAS,MAAM,GAC5CC,IAAc,sBACdC,IAAsB,KAAK,KAAK,KAAK,KACrCC,IAAkB;AAEjB,SAASC,IAAiB;AAC7B,MAAI,OAAO,WAAa;AACpB,WAAO;AAEX,QAAMC,IAASC,EAAUL,CAAW;AACpC,SAAOI,KAAUL,EAAkB,SAASK,CAAM,IAAIA,IAAS;AACnE;AAEO,SAASE,EAAgBC,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,EAAgBH,CAAQ,GACjCI,IAASH,MAAa,UACtBI,IAAa;AAAA,IACf;AAAA,IACA,WAAWZ,CAAmB;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,EAAgBF,CAAY;AAC7C,WAAS,gBAAgB,aAAa,aAAaC,CAAQ;AAC/D;AAIA,SAASX,EAAUa,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,EAAgBH,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,EAAgBV,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,CAAe,IACjC;AACV,WAAOqB,IAAiBA,EAAe,UAAU;AAAA,EACrD,QAAgB;AACZ,WAAO;AAAA,EACX;AACJ;;;;;;;;;;;;AC5FA,UAAMC,IAAQC,GAURC,IAAgB,OAAO,WAAWxB,CAAe,GACjDyB,IAA4B,OAAO;AAAA,MACrCC;AAAA,IACJ,GAEMC,IAAcC,EAAgB;AACpC,IAAAhB,EAA0Be,CAAW;AAErC,UAAME,IAAcC,EAAIH,CAAW,GAE7BI,IAAQD,EAAI;AAAA,MACd,UAAUf,EAAgBY,CAAW;AAAA,IACzC,CAAC;AAED,IAAAH,EAAc,iBAAiB,UAAUQ,CAA4B,GAErEC;AAAA,MACI,MAAMX,EAAM;AAAA,MACZ,MAAM;AACF,QAAAY,EAAY;AAAA,MAChB;AAAA,MACA,EAAE,WAAW,GAAI;AAAA,IACrB,GAEAD;AAAA,MACI,MAAMF,EAAM,MAAM;AAAA,MAClB,CAACjB,GAAUqB,MAAkB;AACzB,YAAIA,MAAkB,QAAW;AAC7B,UAAAC,EAA6BtB,CAAQ;AACrC;AAAA,QACJ;AACA,QAAAuB,EAAoB,MAAM;AACtB,UAAAD,EAA6BtB,CAAQ;AAAA,QACzC,CAAC;AAAA,MACL;AAAA,MACA,EAAE,WAAW,GAAI;AAAA,IACrB,GAEAwB,EAAgB,MAAM;AAClB,MAAAd,EAAc,oBAAoB,UAAUQ,CAA4B;AAAA,IAC5E,CAAC;AAED,aAASE,IAAe;AACpB,YAAM7B,IAAOuB,EAAgB;AAC7B,MAAAC,EAAY,QAAQxB,GACpB0B,EAAM,MAAM,WAAWhB,EAAgBV,CAAI;AAAA,IAC/C;AAEA,aAASU,EAAgBV,GAAM;AAC3B,aAAIA,MAAS,SACF,KAEPA,MAAS,UACF,KAEJmB,EAAc;AAAA,IACzB;AAEA,aAASQ,EAA6BO,GAAO;AACzC,MAAI,CAACA,KAASV,EAAY,UAAU,WAGpCE,EAAM,MAAM,WAAWQ,EAAM;AAAA,IACjC;AAEA,aAASH,EAA6BtB,GAAU;AAC5C,eAAS,gBAAgB,aAAa,aAAaA,CAAQ;AAAA,IAC/D;AAEA,aAASuB,EAAoBG,GAAY;AACrC,UAAIf,EAA0B,SAAS;AACnC,QAAAe,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,aAASf,IAAmB;AACxB,aAAON,EAAM,QAAQrB,EAAc,KAAM;AAAA,IAC7C;AAEA,WAAA2C,EAAQ,SAASb,CAAK,cAzHlBc,EAAA,GAAAC,EAEK,OAFLC,GAEK;AAAA,MADDC,EAAOC,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,IAAcxD,GAEdyB,IAAQC,GAOR+B,IAAOC;AAEb,IAAA3C,EAAyB;AAEzB,UAAM4C,IAAO1B,EAAI,EAAK,GAChBH,IAAc1B,OAAoBqB,EAAM,MACxCmC,IAAe3B;AAAA,MACjBuB,EAAY,SAAS1B,CAAW,IAAIA,IAAc;AAAA,IACtD;AACc,WAAA+B;AAAA,MACV,MAAMR,EAAYO,EAAa,KAAK,KAAKP,EAAY;AAAA,IACzD,GAEAjB;AAAA,MACI,MAAMX,EAAM;AAAA,MACZ,CAACjB,MAAS;AACN,QAAIgD,EAAY,SAAShD,CAAI,KAAKA,MAASoD,EAAa,UACpDA,EAAa,QAAQpD;AAAA,MAE7B;AAAA,IACJ,GAEA4B;AAAA,MACIwB;AAAA,MACA,CAACpD,MAAS;AACN,YAAI,CAACgD,EAAY,SAAShD,CAAI,GAAG;AAC7B,UAAAoD,EAAa,QAAQ;AACrB;AAAA,QACJ;AACA,QAAAD,EAAK,QAAQ,IACbF,EAAK,eAAejD,CAAI,GACxBD,EAAgBC,CAAI;AAAA,MACxB;AAAA,MACA,EAAE,WAAW,GAAI;AAAA,IACrB,mBA/FIsD,EA0BeC,EAAAC,CAAA,GAAA;AAAA,MAzBH,MAAML,EAAA;AAAA,8CAAAA,EAAI,QAAAM;AAAA,MAClB,MAAK;AAAA,MACL,cAAW;AAAA;iBAEX,MAoBoB;AAAA,QApBpBC,EAoBoBH,EAAAI,CAAA,GAAA,EApBD,OAAM,QAAO,GAAA;AAAA,qBAC5B,MAKE;AAAA,YALFD,EAKEH,EAAAK,CAAA,GAAA;AAAA,cAJU,SAASR,EAAA;AAAA,yDAAAA,EAAY,QAAAK;AAAA,cAC7B,OAAM;AAAA,cACL,OAAOF,EAAAV,CAAA,EAAY;AAAA,cACnB,cAAU,GAAKU,EAAAV,CAAA,EAAY,IAAI;AAAA;4BAEpCgB,EAAsD,MAAA;AAAA,cAAlD,OAAM;AAAA,cAAyB,MAAK;AAAA;YACxCH,EAKEH,EAAAK,CAAA,GAAA;AAAA,cAJU,SAASR,EAAA;AAAA,yDAAAA,EAAY,QAAAK;AAAA,cAC7B,OAAM;AAAA,cACL,OAAOF,EAAAV,CAAA,EAAY;AAAA,cACnB,cAAU,GAAKU,EAAAV,CAAA,EAAY,KAAK;AAAA;YAErCa,EAKEH,EAAAK,CAAA,GAAA;AAAA,cAJU,SAASR,EAAA;AAAA,yDAAAA,EAAY,QAAAK;AAAA,cAC7B,OAAM;AAAA,cACL,OAAOF,EAAAV,CAAA,EAAY;AAAA,cACnB,cAAU,GAAKU,EAAAV,CAAA,EAAY,IAAI;AAAA;;;;;;;;kECvBnCiB,KAAO,sBAEPC,KAAO,WACPC,IAAO,sBAIPC,KAAO,QACPC,KAAO,uBACPC,KAAO,uBACPC,KAAO,uBAGPC,KAAO,qBACPC,KAAO,sBAGPC,KAAO,sBACPC,KAAO,sBAGPC,KAAO,uBACPC,KAAO,WAGPC,KAAQ,kBACRC,KAAO,sBAEPC,KAAO,qBACPC,KAAO,qBACPC,KAAO,sBACPC,KAAO,sBACPC,KAAO,sBACPC,KAAO,sBACPC,KAAM,sBACNC,KAAM,sBACNC,KAAM,sBACNC,KAAM,sBACNC,KAAM,sBACNC,KAAM,qBACNC,KAAM,sBACNC,KAAM,sBACNC,KAAK,mBACLC,IAAK,oBAGLC,KAAW7B,GACX8B,KAAW9B,GACX+B,KAAWH;"}
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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"}