@directus/themes 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,106 +1,4 @@
1
- import * as _sinclair_typebox from '@sinclair/typebox';
2
- import { Static } from '@sinclair/typebox';
3
- import * as pinia from 'pinia';
4
- import * as vue from 'vue';
5
-
6
- /** CSS size, f.e. px, em, % */
7
- /** CSS font weight, f.e. 700, bold */
8
- /** CSS font family, f.e. 'Comic Sans, MS', 'Roboto' */
9
- declare const ThemeSchema: _sinclair_typebox.TObject<{
10
- name: _sinclair_typebox.TString;
11
- appearance: _sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"light">, _sinclair_typebox.TLiteral<"dark">]>;
12
- rules: _sinclair_typebox.TObject<{
13
- foreground: _sinclair_typebox.TString;
14
- }>;
15
- }>;
16
- type Theme = Static<typeof ThemeSchema>;
17
-
18
- declare const defineTheme: (theme: Theme) => {
19
- name: string;
20
- appearance: "light" | "dark";
21
- rules: {
22
- foreground: string;
23
- };
24
- };
25
-
26
- declare const useThemeStore: pinia.StoreDefinition<"themes", pinia._UnwrapAll<Pick<{
27
- themes: {
28
- dark: {
29
- name: string;
30
- appearance: "light" | "dark";
31
- rules: {
32
- foreground: string;
33
- };
34
- }[];
35
- light: {
36
- name: string;
37
- appearance: "light" | "dark";
38
- rules: {
39
- foreground: string;
40
- };
41
- }[];
42
- };
43
- registerTheme: (theme: Theme) => void;
44
- currentTheme: {
45
- dark: string;
46
- light: string;
47
- };
48
- currentAppearance: vue.Ref<"light" | "dark">;
49
- rules: vue.ComputedRef<{
50
- foreground: string;
51
- }>;
52
- }, "themes" | "currentTheme" | "currentAppearance">>, Pick<{
53
- themes: {
54
- dark: {
55
- name: string;
56
- appearance: "light" | "dark";
57
- rules: {
58
- foreground: string;
59
- };
60
- }[];
61
- light: {
62
- name: string;
63
- appearance: "light" | "dark";
64
- rules: {
65
- foreground: string;
66
- };
67
- }[];
68
- };
69
- registerTheme: (theme: Theme) => void;
70
- currentTheme: {
71
- dark: string;
72
- light: string;
73
- };
74
- currentAppearance: vue.Ref<"light" | "dark">;
75
- rules: vue.ComputedRef<{
76
- foreground: string;
77
- }>;
78
- }, "rules">, Pick<{
79
- themes: {
80
- dark: {
81
- name: string;
82
- appearance: "light" | "dark";
83
- rules: {
84
- foreground: string;
85
- };
86
- }[];
87
- light: {
88
- name: string;
89
- appearance: "light" | "dark";
90
- rules: {
91
- foreground: string;
92
- };
93
- }[];
94
- };
95
- registerTheme: (theme: Theme) => void;
96
- currentTheme: {
97
- dark: string;
98
- light: string;
99
- };
100
- currentAppearance: vue.Ref<"light" | "dark">;
101
- rules: vue.ComputedRef<{
102
- foreground: string;
103
- }>;
104
- }, "registerTheme">>;
105
-
106
- export { Theme, ThemeSchema, defineTheme, useThemeStore };
1
+ export { Definitions, ThemeSchema, TypeId, type Theme } from './schema.js';
2
+ export { useThemeStore } from './store.js';
3
+ export { default as ThemeProvider } from './theme-provider.vue';
4
+ export { useTheme } from './use-theme.js';
package/dist/index.js CHANGED
@@ -1,72 +1,405 @@
1
- // src/define-theme.ts
2
- var defineTheme = (theme) => theme;
3
-
4
- // src/schema.ts
5
- import { Type } from "@sinclair/typebox";
6
- var Color = Type.String();
7
- var ThemeSchema = Type.Object({
8
- name: Type.String(),
9
- appearance: Type.Union([Type.Literal("light"), Type.Literal("dark")]),
10
- rules: Type.Object({
11
- foreground: Color
1
+ import { Type as r } from "@sinclair/typebox";
2
+ import { defineStore as F, storeToRefs as j } from "pinia";
3
+ import { reactive as H, computed as v, unref as d, defineComponent as O, toRefs as w, openBlock as B, createBlock as T, Teleport as $, createTextVNode as D, toDisplayString as L } from "vue";
4
+ import { useHead as M } from "@unhead/vue";
5
+ import _ from "decamelize";
6
+ import { flatten as C } from "flat";
7
+ import { get as R, merge as y, mapKeys as I } from "lodash-es";
8
+ const k = {
9
+ Color: "Color",
10
+ FontFamily: "FontFamily"
11
+ }, e = r.Ref(r.String({ $id: k.Color })), b = r.Ref(r.String({ $id: k.FontFamily })), W = r.Object({
12
+ foreground: e,
13
+ foregroundSubdued: e,
14
+ foregroundAccent: e,
15
+ background: e,
16
+ primary: e,
17
+ primaryBackground: e,
18
+ primarySubdued: e,
19
+ primaryAccent: e,
20
+ secondary: e,
21
+ secondaryBackground: e,
22
+ secondarySubdued: e,
23
+ secondaryAccent: e,
24
+ success: e,
25
+ successBackground: e,
26
+ successSubdued: e,
27
+ successAccent: e,
28
+ warning: e,
29
+ warningBackground: e,
30
+ warningSubdued: e,
31
+ warningAccent: e,
32
+ danger: e,
33
+ dangerBackground: e,
34
+ dangerSubdued: e,
35
+ dangerAccent: e,
36
+ fontFamilyDisplay: b,
37
+ fontFamilySansSerif: b,
38
+ fontFamilySerif: b,
39
+ fontFamilyMonospace: b,
40
+ navigation: r.Object({
41
+ background: e,
42
+ project: r.Object({
43
+ background: e,
44
+ foreground: e
45
+ }),
46
+ modules: r.Object({
47
+ background: e,
48
+ button: r.Object({
49
+ foreground: e,
50
+ foregroundHover: e,
51
+ foregroundActive: e,
52
+ background: e,
53
+ backgroundHover: e,
54
+ backgroundActive: e
55
+ })
56
+ }),
57
+ list: r.Object({
58
+ icon: r.Object({
59
+ foreground: e,
60
+ foregroundHover: e,
61
+ foregroundActive: e
62
+ }),
63
+ foreground: e,
64
+ foregroundHover: e,
65
+ foregroundActive: e,
66
+ background: e,
67
+ backgroundHover: e,
68
+ backgroundActive: e
69
+ })
70
+ }),
71
+ header: r.Object({
72
+ background: e,
73
+ headline: r.Object({
74
+ foreground: e
75
+ }),
76
+ title: r.Object({
77
+ foreground: e,
78
+ fontFamily: b
79
+ })
80
+ }),
81
+ form: r.Object({
82
+ field: r.Object({
83
+ label: r.Object({
84
+ foreground: e
85
+ }),
86
+ input: r.Object({
87
+ background: e,
88
+ foreground: e,
89
+ foregroundSubdued: e
90
+ })
91
+ })
92
+ }),
93
+ sidebar: r.Object({
94
+ background: e,
95
+ foreground: e,
96
+ section: r.Object({
97
+ toggle: r.Object({
98
+ icon: r.Object({
99
+ foreground: e,
100
+ foregroundHover: e,
101
+ foregroundActive: e
102
+ }),
103
+ foreground: e,
104
+ foregroundHover: e,
105
+ foregroundActive: e,
106
+ background: e,
107
+ backgroundHover: e,
108
+ backgroundActive: e
109
+ })
110
+ })
12
111
  })
13
- });
14
-
15
- // src/store.ts
16
- import { defu } from "defu";
17
- import { defineStore } from "pinia";
18
- import { computed, reactive, ref, unref } from "vue";
19
-
20
- // src/themes/dark/default.ts
21
- var default_default = defineTheme({
22
- name: "Directus Default (Dark)",
112
+ }), N = r.Object({
113
+ name: r.String(),
114
+ appearance: r.Union([r.Literal("light"), r.Literal("dark")]),
115
+ rules: W
116
+ }), Z = { $defs: { [k.Color]: e, [k.FontFamily]: b } }, A = {
117
+ name: "Dark (Directus)",
23
118
  appearance: "dark",
24
119
  rules: {
25
- foreground: "#fff"
120
+ foreground: "#c9d1d9",
121
+ foregroundAccent: "#f0f6fc",
122
+ foregroundSubdued: "#666672",
123
+ background: "#0d1117",
124
+ primary: "var(--project-color)",
125
+ primaryBackground: "color-mix(in srgb, var(--theme--background), var(--theme--primary) 10%)",
126
+ primarySubdued: "color-mix(in srgb, var(--theme--background), var(--theme--primary) 50%)",
127
+ primaryAccent: "color-mix(in srgb, var(--theme--primary), #16151a 25%)",
128
+ secondary: "#ff99dd",
129
+ secondaryBackground: "color-mix(in srgb, var(--theme--background), var(--theme--secondary) 10%)",
130
+ secondarySubdued: "color-mix(in srgb, var(--theme--background), var(--theme--secondary) 50%)",
131
+ secondaryAccent: "color-mix(in srgb, var(--theme--secondary), #16151a 25%)",
132
+ success: "#2ecda7",
133
+ successBackground: "color-mix(in srgb, var(--theme--background), var(--theme--success) 10%)",
134
+ successSubdued: "color-mix(in srgb, var(--theme--background), var(--theme--success) 50%)",
135
+ successAccent: "color-mix(in srgb, var(--theme--success), #16151a 25%)",
136
+ warning: "#ffa439",
137
+ warningBackground: "color-mix(in srgb, var(--theme--background), var(--theme--warning) 10%)",
138
+ warningSubdued: "color-mix(in srgb, var(--theme--background), var(--theme--warning) 50%)",
139
+ warningAccent: "color-mix(in srgb, var(--theme--warning), #16151a 25%)",
140
+ danger: "#e35169",
141
+ dangerBackground: "color-mix(in srgb, var(--theme--background), var(--theme--danger) 10%)",
142
+ dangerSubdued: "color-mix(in srgb, var(--theme--background), var(--theme--danger) 50%)",
143
+ dangerAccent: "color-mix(in srgb, var(--theme--danger), #16151a 25%)",
144
+ fontFamilyDisplay: "var(--theme--font-family-sans-serif)",
145
+ fontFamilySansSerif: '"Inter", system-ui',
146
+ fontFamilySerif: '"Merriweather", serif',
147
+ fontFamilyMonospace: '"Fira Mono", monospace',
148
+ navigation: {
149
+ background: "#21262e",
150
+ project: {
151
+ background: "#30363d",
152
+ foreground: "var(--theme--foreground-accent)"
153
+ },
154
+ modules: {
155
+ background: "var(--theme--background)",
156
+ button: {
157
+ foreground: "var(--theme--foreground-subdued)",
158
+ foregroundHover: "#fff",
159
+ foregroundActive: "var(--theme--foreground-accent)",
160
+ background: "transparent",
161
+ backgroundHover: "transparent",
162
+ backgroundActive: "#21262e"
163
+ }
164
+ },
165
+ list: {
166
+ icon: {
167
+ foreground: "var(--theme--primary)",
168
+ foregroundHover: "var(--theme--navigation--list--icon--foreground)",
169
+ foregroundActive: "var(--theme--navigation--list--icon--foreground)"
170
+ },
171
+ foreground: "var(--theme--foreground-accent)",
172
+ foregroundHover: "var(--theme--navigation--list--foreground)",
173
+ foregroundActive: "var(--theme--navigation--list--foreground)",
174
+ background: "transparent",
175
+ backgroundHover: "#30363d",
176
+ backgroundActive: "#30363d"
177
+ }
178
+ },
179
+ header: {
180
+ background: "var(--theme--background)",
181
+ headline: {
182
+ foreground: "var(--theme--foreground-subdued)"
183
+ },
184
+ title: {
185
+ foreground: "var(--theme--foreground-accent)",
186
+ fontFamily: "var(--theme--font-family-display)"
187
+ }
188
+ },
189
+ form: {
190
+ field: {
191
+ label: {
192
+ foreground: "var(--theme--foreground-accent)"
193
+ },
194
+ input: {
195
+ background: "var(--theme--background)",
196
+ foreground: "var(--theme--foreground)",
197
+ foregroundSubdued: "var(--theme--foreground-subdued)"
198
+ }
199
+ }
200
+ },
201
+ sidebar: {
202
+ background: "#21262e",
203
+ foreground: "var(--theme--foreground-subdued)",
204
+ section: {
205
+ toggle: {
206
+ icon: {
207
+ foreground: "var(--theme--foreground-accent)",
208
+ foregroundHover: "var(--theme--sidebar--section--toggle--icon--foreground)",
209
+ foregroundActive: "var(--theme--sidebar--section--toggle--icon--foreground)"
210
+ },
211
+ foreground: "var(--theme--foreground-accent)",
212
+ foregroundHover: "var(--theme--sidebar--section--toggle--foreground)",
213
+ foregroundActive: "var(--theme--sidebar--section--toggle--foreground)",
214
+ background: "#30363d",
215
+ backgroundHover: "var(--theme--sidebar--section--toggle--background)",
216
+ backgroundActive: "var(--theme--sidebar--section--toggle--background)"
217
+ }
218
+ }
219
+ }
26
220
  }
27
- });
28
-
29
- // src/themes/light/default.ts
30
- var default_default2 = defineTheme({
31
- name: "Directus Default (Light)",
221
+ }, S = {
222
+ name: "Light (Directus)",
32
223
  appearance: "light",
33
224
  rules: {
34
- foreground: "#000"
225
+ foreground: "#4f5464",
226
+ foregroundAccent: "#172940",
227
+ foregroundSubdued: "#a2b5cd",
228
+ background: "#fff",
229
+ primary: "var(--project-color)",
230
+ primaryBackground: "color-mix(in srgb, var(--theme--background), var(--theme--primary) 10%)",
231
+ primarySubdued: "color-mix(in srgb, var(--theme--background), var(--theme--primary) 50%)",
232
+ primaryAccent: "color-mix(in srgb, var(--theme--primary), #2e3c43 25%)",
233
+ secondary: "#ff99dd",
234
+ secondaryBackground: "color-mix(in srgb, var(--theme--background), var(--theme--secondary) 10%)",
235
+ secondarySubdued: "color-mix(in srgb, var(--theme--background), var(--theme--secondary) 50%)",
236
+ secondaryAccent: "color-mix(in srgb, var(--theme--secondary), #2e3c43 25%)",
237
+ success: "#2ecda7",
238
+ successBackground: "color-mix(in srgb, var(--theme--background), var(--theme--success) 10%)",
239
+ successSubdued: "color-mix(in srgb, var(--theme--background), var(--theme--success) 50%)",
240
+ successAccent: "color-mix(in srgb, var(--theme--success), #2e3c43 25%)",
241
+ warning: "#ffa439",
242
+ warningBackground: "color-mix(in srgb, var(--theme--background), var(--theme--warning) 10%)",
243
+ warningSubdued: "color-mix(in srgb, var(--theme--background), var(--theme--warning) 50%)",
244
+ warningAccent: "color-mix(in srgb, var(--theme--warning), #2e3c43 25%)",
245
+ danger: "#e35169",
246
+ dangerBackground: "color-mix(in srgb, var(--theme--background), var(--theme--danger) 10%)",
247
+ dangerSubdued: "color-mix(in srgb, var(--theme--background), var(--theme--danger) 50%)",
248
+ dangerAccent: "color-mix(in srgb, var(--theme--danger), #2e3c43 25%)",
249
+ fontFamilyDisplay: "var(--theme--font-family-sans-serif)",
250
+ fontFamilySansSerif: '"Inter", system-ui',
251
+ fontFamilySerif: '"Merriweather", serif',
252
+ fontFamilyMonospace: '"Fira Mono", monospace',
253
+ navigation: {
254
+ background: "#f0f4f9",
255
+ project: {
256
+ background: "#e4eaf1",
257
+ foreground: "var(--theme--foreground-accent)"
258
+ },
259
+ modules: {
260
+ background: "#18222f",
261
+ button: {
262
+ foreground: "#8196b1",
263
+ foregroundHover: "#fff",
264
+ foregroundActive: "var(--theme--foreground-accent)",
265
+ background: "transparent",
266
+ backgroundHover: "transparent",
267
+ backgroundActive: "#f0f4f9"
268
+ }
269
+ },
270
+ list: {
271
+ icon: {
272
+ foreground: "var(--theme--primary)",
273
+ foregroundHover: "var(--theme--navigation--list--icon--foreground)",
274
+ foregroundActive: "var(--theme--navigation--list--icon--foreground)"
275
+ },
276
+ foreground: "var(--theme--foreground-accent)",
277
+ foregroundHover: "var(--theme--navigation--list--foreground)",
278
+ foregroundActive: "var(--theme--navigation--list--foreground)",
279
+ background: "transparent",
280
+ backgroundHover: "#e4eaf1",
281
+ backgroundActive: "#e4eaf1"
282
+ }
283
+ },
284
+ header: {
285
+ background: "var(--theme--background)",
286
+ headline: {
287
+ foreground: "var(--theme--foreground-subdued)"
288
+ },
289
+ title: {
290
+ foreground: "var(--theme--foreground-accent)",
291
+ fontFamily: "var(--theme--font-family-display)"
292
+ }
293
+ },
294
+ form: {
295
+ field: {
296
+ label: {
297
+ foreground: "var(--theme--foreground-accent)"
298
+ },
299
+ input: {
300
+ background: "var(--theme--background)",
301
+ foreground: "var(--theme--foreground)",
302
+ foregroundSubdued: "var(--theme--foreground-subdued)"
303
+ }
304
+ }
305
+ },
306
+ sidebar: {
307
+ background: "#f0f4f9",
308
+ foreground: "var(--theme--foreground-subdued)",
309
+ section: {
310
+ toggle: {
311
+ icon: {
312
+ foreground: "var(--theme--foreground-accent)",
313
+ foregroundHover: "var(--theme--sidebar--section--toggle--icon--foreground)",
314
+ foregroundActive: "var(--theme--sidebar--section--toggle--icon--foreground)"
315
+ },
316
+ foreground: "var(--theme--foreground-accent)",
317
+ foregroundHover: "var(--theme--sidebar--section--toggle--foreground)",
318
+ foregroundActive: "var(--theme--sidebar--section--toggle--foreground)",
319
+ background: "#e4eaf1",
320
+ backgroundHover: "var(--theme--sidebar--section--toggle--background)",
321
+ backgroundActive: "var(--theme--sidebar--section--toggle--background)"
322
+ }
323
+ }
324
+ }
35
325
  }
36
- });
37
-
38
- // src/store.ts
39
- var useThemeStore = defineStore("themes", () => {
40
- const currentAppearance = ref("light");
41
- const currentTheme = reactive({
42
- dark: default_default.name,
43
- light: default_default2.name
44
- });
45
- const themes = reactive({
46
- dark: [default_default],
47
- light: [default_default2]
326
+ }, V = [S], z = [A], E = F("🎨 Themes", () => {
327
+ const t = H({
328
+ light: V,
329
+ dark: z
48
330
  });
49
- const registerTheme = (theme) => {
50
- if (theme.appearance === "dark") {
51
- themes.dark.push(theme);
52
- } else {
53
- themes.light.push(theme);
54
- }
331
+ return { themes: t, registerTheme: (i) => {
332
+ i.appearance === "light" ? t.light.push(i) : t.dark.push(i);
333
+ } };
334
+ }), K = (t) => {
335
+ const s = [], i = (o, c = []) => {
336
+ for (const [a, n] of Object.entries(o))
337
+ typeof n == "object" && n !== null && ("type" in n && n.type === "object" && "properties" in n && i(n.properties, [...c, a]), "$ref" in n && n.$ref === k.FontFamily && s.push([...c, a]));
55
338
  };
56
- const defaultTheme = computed(() => {
57
- if (unref(currentAppearance) === "dark")
58
- return default_default;
59
- return default_default2;
60
- });
61
- const rules = computed(() => {
62
- const appearance = unref(currentAppearance);
63
- const theme = themes[appearance].find(({ name }) => name === currentTheme[unref(currentAppearance)]);
64
- return defu(theme?.rules, unref(defaultTheme).rules);
65
- });
66
- return { themes, registerTheme, currentTheme, currentAppearance, rules };
339
+ i(N.properties.rules.properties);
340
+ const m = v(() => {
341
+ const o = [];
342
+ for (const a of s)
343
+ o.push(R(d(t).rules, a).trim());
344
+ const c = /* @__PURE__ */ new Set();
345
+ for (const a of o)
346
+ a.split(",").forEach((g) => c.add(g));
347
+ return Array.from(c);
348
+ }), l = v(() => m.value.filter((o) => {
349
+ if (o.startsWith('"') && o.endsWith('"') && o.includes("var(") === !1) {
350
+ const c = ["Inter", "Merriweather", "Fira Mono"];
351
+ return !(c.includes(o) || c.map((a) => `"${a}"`).includes(o));
352
+ }
353
+ return !1;
354
+ }).map((o) => (o.startsWith('"') && o.endsWith('"') && (o = o.slice(1, -1)), o.replace(" ", "+"))));
355
+ return { fonts: m, googleFonts: l };
356
+ }, P = (t, s, i, m, l) => {
357
+ const { themes: o } = j(E());
358
+ return { theme: v(() => {
359
+ const a = d(t) ? d(i) : d(s), n = d(t) ? A : S, g = d(t) ? d(l) : d(m), h = d(o)[t ? "dark" : "light"].find((u) => u.name === a);
360
+ return h ? g ? y({}, n, h, { rules: g }) : y(n, h) : (a && a !== n.name && console.warn(`Theme "${a}" doesn't exist.`), g ? y({}, n, { rules: g }) : n);
361
+ }) };
362
+ }, ee = /* @__PURE__ */ O({
363
+ __name: "theme-provider",
364
+ props: {
365
+ darkMode: { type: Boolean },
366
+ themeLight: { default: S.name },
367
+ themeLightOverrides: { default: () => ({}) },
368
+ themeDark: { default: A.name },
369
+ themeDarkOverrides: { default: () => ({}) }
370
+ },
371
+ setup(t) {
372
+ const s = t, { darkMode: i, themeLight: m, themeDark: l, themeLightOverrides: o, themeDarkOverrides: c } = w(s), { theme: a } = P(i, m, l, o, c), n = v(() => {
373
+ const u = C(d(a).rules, { delimiter: "--" }), f = (p) => `--theme--${_(p, { separator: "-" })}`;
374
+ return I(u, (p, x) => f(x));
375
+ }), { googleFonts: g } = K(a);
376
+ M({
377
+ link: v(() => {
378
+ let u = "";
379
+ if (g.value.length > 0) {
380
+ const f = g.value.join("&family=");
381
+ u += `https://fonts.googleapis.com/css2?family=${f}`, u += `
382
+ `;
383
+ }
384
+ return u ? [
385
+ {
386
+ rel: "stylesheet",
387
+ href: u
388
+ }
389
+ ] : [];
390
+ })
391
+ });
392
+ const h = v(() => `:root {${Object.entries(d(n)).map(([f, p]) => `${f}: ${p};`).join(" ")}}`);
393
+ return (u, f) => (B(), T($, { to: "#theme" }, [
394
+ D(L(h.value), 1)
395
+ ]));
396
+ }
67
397
  });
68
398
  export {
69
- ThemeSchema,
70
- defineTheme,
71
- useThemeStore
399
+ Z as Definitions,
400
+ ee as ThemeProvider,
401
+ N as ThemeSchema,
402
+ k as TypeId,
403
+ P as useTheme,
404
+ E as useThemeStore
72
405
  };