@dbcdk/react-components 0.0.175 → 0.0.177
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -18
- package/dist/components/menu/Menu.module.css +2 -4
- package/dist/components/theme-button/ThemeButton.cjs +4 -15
- package/dist/components/theme-button/ThemeButton.d.ts +3 -4
- package/dist/components/theme-button/ThemeButton.js +4 -15
- package/dist/components/theme-script/ThemeScript.cjs +23 -16
- package/dist/components/theme-script/ThemeScript.d.ts +2 -6
- package/dist/components/theme-script/ThemeScript.js +24 -17
- package/dist/hooks/usePersistentState.cjs +6 -1
- package/dist/hooks/usePersistentState.d.ts +1 -1
- package/dist/hooks/usePersistentState.js +6 -1
- package/dist/hooks/useTheme.cjs +33 -96
- package/dist/hooks/useTheme.d.ts +3 -10
- package/dist/hooks/useTheme.js +34 -97
- package/dist/styles/themes/apply-product-theme.cjs +20 -0
- package/dist/styles/themes/apply-product-theme.d.ts +3 -0
- package/dist/styles/themes/apply-product-theme.js +18 -0
- package/dist/styles/themes/dbc/colors.css +1 -1
- package/dist/styles/themes/product-theme-tokens.cjs +39 -0
- package/dist/styles/themes/product-theme-tokens.d.ts +3 -0
- package/dist/styles/themes/product-theme-tokens.js +37 -0
- package/dist/styles/themes/product-themes.cjs +143 -0
- package/dist/styles/themes/product-themes.d.ts +11 -0
- package/dist/styles/themes/product-themes.js +140 -0
- package/dist/styles/themes/types.cjs +3 -2
- package/dist/styles/themes/types.d.ts +1 -13
- package/dist/styles/themes/types.js +3 -2
- package/dist/utils/sessionStorage.utils.cjs +53 -0
- package/dist/utils/sessionStorage.utils.d.ts +19 -0
- package/dist/utils/sessionStorage.utils.js +49 -0
- package/package.json +1 -1
- package/dist/styles/themes/filmstriben/theme.css +0 -108
- package/dist/themes/filmstriben.css +0 -4
- package/dist/types/assets.d.cjs +0 -2
- package/dist/types/assets.d.js +0 -1
package/dist/hooks/useTheme.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { useEffect, useSyncExternalStore } from 'react';
|
|
3
|
+
import { applyProductTheme } from '../styles/themes/apply-product-theme';
|
|
3
4
|
import { readCookie, writeCookie } from '../utils/cookie.utils';
|
|
4
5
|
import { readLocalStorage, writeLocalStorage } from '../utils/localStorage.utils';
|
|
5
|
-
import { THEME_STORAGE_KEY
|
|
6
|
+
import { THEME_STORAGE_KEY } from '../utils/theme.constants';
|
|
6
7
|
|
|
7
|
-
const PRELOAD_ID_PREFIX = "dbc-theme-preload-";
|
|
8
8
|
function persistTheme(storageKey, id) {
|
|
9
9
|
writeLocalStorage(storageKey, id);
|
|
10
10
|
writeCookie(storageKey, id);
|
|
@@ -12,47 +12,16 @@ function persistTheme(storageKey, id) {
|
|
|
12
12
|
function getDomTheme() {
|
|
13
13
|
return document.documentElement.dataset.productTheme;
|
|
14
14
|
}
|
|
15
|
+
function getDomColorScheme() {
|
|
16
|
+
return document.documentElement.dataset.theme;
|
|
17
|
+
}
|
|
15
18
|
function applyTheme(id) {
|
|
16
19
|
document.documentElement.dataset.productTheme = id;
|
|
17
|
-
|
|
18
|
-
function findLink(linkId) {
|
|
19
|
-
return document.getElementById(linkId);
|
|
20
|
-
}
|
|
21
|
-
function findPreloadLink(id) {
|
|
22
|
-
return document.getElementById(`${PRELOAD_ID_PREFIX}${id}`);
|
|
23
|
-
}
|
|
24
|
-
function ensureStylesheet(id, href, linkId, onReady) {
|
|
25
|
-
var _a;
|
|
26
|
-
if (!href) {
|
|
27
|
-
onReady();
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
const active = findLink(linkId);
|
|
31
|
-
if (active && active.getAttribute("href") === href && active.rel === "stylesheet") {
|
|
32
|
-
onReady();
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
const preload = findPreloadLink(id);
|
|
36
|
-
const link = (_a = active != null ? active : preload) != null ? _a : document.createElement("link");
|
|
37
|
-
const wasConnected = link.isConnected;
|
|
38
|
-
link.id = linkId;
|
|
39
|
-
link.rel = "stylesheet";
|
|
40
|
-
link.removeAttribute("as");
|
|
41
|
-
link.href = href;
|
|
42
|
-
if (preload && preload !== link) preload.remove();
|
|
43
|
-
let settled = false;
|
|
44
|
-
const finish = () => {
|
|
45
|
-
if (settled) return;
|
|
46
|
-
settled = true;
|
|
47
|
-
onReady();
|
|
48
|
-
};
|
|
49
|
-
link.addEventListener("load", finish, { once: true });
|
|
50
|
-
link.addEventListener("error", finish, { once: true });
|
|
51
|
-
if (!wasConnected) document.head.appendChild(link);
|
|
20
|
+
applyProductTheme(id, getDomColorScheme());
|
|
52
21
|
}
|
|
53
22
|
let currentTheme = null;
|
|
54
23
|
let resolved = false;
|
|
55
|
-
let
|
|
24
|
+
let observerAttached = false;
|
|
56
25
|
const listeners = /* @__PURE__ */ new Set();
|
|
57
26
|
function notify() {
|
|
58
27
|
listeners.forEach((listener) => listener());
|
|
@@ -78,75 +47,43 @@ function resolveInitialTheme(storageKey, defaultTheme) {
|
|
|
78
47
|
if (fromStorage) return fromStorage;
|
|
79
48
|
return defaultTheme;
|
|
80
49
|
}
|
|
81
|
-
function ensureResolved(
|
|
50
|
+
function ensureResolved(defaultTheme, storageKey) {
|
|
82
51
|
if (resolved) return;
|
|
83
52
|
resolved = true;
|
|
84
53
|
const value = resolveInitialTheme(storageKey, defaultTheme);
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
notify();
|
|
90
|
-
};
|
|
91
|
-
if (value === defaultTheme) {
|
|
92
|
-
finish();
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
ensureStylesheet(value, hrefs[value], linkId, finish);
|
|
54
|
+
applyTheme(value);
|
|
55
|
+
persistTheme(storageKey, value);
|
|
56
|
+
currentTheme = value;
|
|
57
|
+
notify();
|
|
96
58
|
}
|
|
97
|
-
function
|
|
98
|
-
if (
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
link.rel = "preload";
|
|
109
|
-
link.as = "style";
|
|
110
|
-
link.href = href;
|
|
111
|
-
document.head.appendChild(link);
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
const requestIdle = window.requestIdleCallback;
|
|
115
|
-
if (typeof requestIdle === "function") {
|
|
116
|
-
requestIdle(run);
|
|
117
|
-
} else {
|
|
118
|
-
setTimeout(run, 1);
|
|
119
|
-
}
|
|
59
|
+
function ensureColorSchemeObserver() {
|
|
60
|
+
if (observerAttached) return;
|
|
61
|
+
observerAttached = true;
|
|
62
|
+
const observer = new MutationObserver(() => {
|
|
63
|
+
if (!currentTheme) return;
|
|
64
|
+
applyProductTheme(currentTheme, getDomColorScheme());
|
|
65
|
+
});
|
|
66
|
+
observer.observe(document.documentElement, {
|
|
67
|
+
attributes: true,
|
|
68
|
+
attributeFilter: ["data-theme"]
|
|
69
|
+
});
|
|
120
70
|
}
|
|
121
|
-
function switchThemeInternal(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
notify();
|
|
128
|
-
};
|
|
129
|
-
if (id === defaultTheme) {
|
|
130
|
-
finish();
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
ensureStylesheet(id, hrefs[id], linkId, finish);
|
|
71
|
+
function switchThemeInternal(storageKey, id) {
|
|
72
|
+
applyTheme(id);
|
|
73
|
+
persistTheme(storageKey, id);
|
|
74
|
+
currentTheme = id;
|
|
75
|
+
resolved = true;
|
|
76
|
+
notify();
|
|
134
77
|
}
|
|
135
78
|
function useTheme(options) {
|
|
136
|
-
const {
|
|
137
|
-
defaultTheme,
|
|
138
|
-
hrefs = {},
|
|
139
|
-
linkId = THEME_LINK_ID,
|
|
140
|
-
preloadOthers = true,
|
|
141
|
-
storageKey = THEME_STORAGE_KEY
|
|
142
|
-
} = options;
|
|
79
|
+
const { defaultTheme, storageKey = THEME_STORAGE_KEY } = options;
|
|
143
80
|
useEffect(() => {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}, []);
|
|
81
|
+
ensureColorSchemeObserver();
|
|
82
|
+
ensureResolved(defaultTheme, storageKey);
|
|
83
|
+
}, [defaultTheme, storageKey]);
|
|
147
84
|
const theme = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
148
85
|
function switchTheme(id) {
|
|
149
|
-
switchThemeInternal(
|
|
86
|
+
switchThemeInternal(storageKey, id);
|
|
150
87
|
}
|
|
151
88
|
return { theme, switchTheme };
|
|
152
89
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var productThemeTokens = require('./product-theme-tokens');
|
|
4
|
+
var productThemes = require('./product-themes');
|
|
5
|
+
|
|
6
|
+
function clearProductThemeTokens(target) {
|
|
7
|
+
for (const token of productThemeTokens.PRODUCT_THEME_TOKEN_NAMES) {
|
|
8
|
+
target.style.removeProperty(token);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
function applyProductTheme(themeId, colorScheme, target = document.documentElement) {
|
|
12
|
+
clearProductThemeTokens(target);
|
|
13
|
+
const tokens = productThemes.getProductThemeTokens(themeId, colorScheme);
|
|
14
|
+
for (const [token, value] of Object.entries(tokens)) {
|
|
15
|
+
if (!value) continue;
|
|
16
|
+
target.style.setProperty(token, value);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
exports.applyProductTheme = applyProductTheme;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { PRODUCT_THEME_TOKEN_NAMES } from './product-theme-tokens';
|
|
2
|
+
import { getProductThemeTokens } from './product-themes';
|
|
3
|
+
|
|
4
|
+
function clearProductThemeTokens(target) {
|
|
5
|
+
for (const token of PRODUCT_THEME_TOKEN_NAMES) {
|
|
6
|
+
target.style.removeProperty(token);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
function applyProductTheme(themeId, colorScheme, target = document.documentElement) {
|
|
10
|
+
clearProductThemeTokens(target);
|
|
11
|
+
const tokens = getProductThemeTokens(themeId, colorScheme);
|
|
12
|
+
for (const [token, value] of Object.entries(tokens)) {
|
|
13
|
+
if (!value) continue;
|
|
14
|
+
target.style.setProperty(token, value);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { applyProductTheme };
|
|
@@ -241,7 +241,7 @@ html {
|
|
|
241
241
|
--button-fg-primary: var(--color-fg-on-brand);
|
|
242
242
|
|
|
243
243
|
/* Product / logo lockup — generic defaults; apps with a custom identity
|
|
244
|
-
override these tokens only
|
|
244
|
+
override these tokens only via the product-theme token registry. */
|
|
245
245
|
--color-logo: var(--color-fg-default);
|
|
246
246
|
--color-logo-bg: color-mix(in srgb, var(--color-logo) 10%, var(--color-bg-surface));
|
|
247
247
|
--color-logo-fg: var(--color-fg-default);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const PRODUCT_THEME_TOKEN_NAMES = [
|
|
4
|
+
"--color-brand",
|
|
5
|
+
"--color-brand-hover",
|
|
6
|
+
"--color-brand-strong",
|
|
7
|
+
"--color-fg-on-brand",
|
|
8
|
+
"--color-border-selected",
|
|
9
|
+
"--color-link",
|
|
10
|
+
"--color-link-hover",
|
|
11
|
+
"--color-bg-selected",
|
|
12
|
+
"--color-bg-selected-hover",
|
|
13
|
+
"--color-chart-primary",
|
|
14
|
+
"--color-chart-brand",
|
|
15
|
+
"--color-navbar-bg",
|
|
16
|
+
"--color-navbar-fg",
|
|
17
|
+
"--color-navbar-fg-muted",
|
|
18
|
+
"--color-navbar-border",
|
|
19
|
+
"--color-navbar-brand",
|
|
20
|
+
"--color-logo",
|
|
21
|
+
"--color-logo-bg",
|
|
22
|
+
"--color-logo-fg",
|
|
23
|
+
"--color-field-focus",
|
|
24
|
+
"--color-focus-ring",
|
|
25
|
+
"--focus-ring",
|
|
26
|
+
"--color-bg-page",
|
|
27
|
+
"--color-bg-surface",
|
|
28
|
+
"--color-bg-surface-subtle",
|
|
29
|
+
"--color-bg-surface-strong",
|
|
30
|
+
"--color-bg-inverse",
|
|
31
|
+
"--color-bg-toolbar",
|
|
32
|
+
"--color-bg-toolbar-hover",
|
|
33
|
+
"--table-header-bg",
|
|
34
|
+
"--table-row-bg",
|
|
35
|
+
"--table-row-bg-alt",
|
|
36
|
+
"--table-row-bg-hover"
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
exports.PRODUCT_THEME_TOKEN_NAMES = PRODUCT_THEME_TOKEN_NAMES;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const PRODUCT_THEME_TOKEN_NAMES: readonly ["--color-brand", "--color-brand-hover", "--color-brand-strong", "--color-fg-on-brand", "--color-border-selected", "--color-link", "--color-link-hover", "--color-bg-selected", "--color-bg-selected-hover", "--color-chart-primary", "--color-chart-brand", "--color-navbar-bg", "--color-navbar-fg", "--color-navbar-fg-muted", "--color-navbar-border", "--color-navbar-brand", "--color-logo", "--color-logo-bg", "--color-logo-fg", "--color-field-focus", "--color-focus-ring", "--focus-ring", "--color-bg-page", "--color-bg-surface", "--color-bg-surface-subtle", "--color-bg-surface-strong", "--color-bg-inverse", "--color-bg-toolbar", "--color-bg-toolbar-hover", "--table-header-bg", "--table-row-bg", "--table-row-bg-alt", "--table-row-bg-hover"];
|
|
2
|
+
export type ProductThemeTokenName = (typeof PRODUCT_THEME_TOKEN_NAMES)[number];
|
|
3
|
+
export type ProductThemeTokens = Partial<Record<ProductThemeTokenName, string>>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const PRODUCT_THEME_TOKEN_NAMES = [
|
|
2
|
+
"--color-brand",
|
|
3
|
+
"--color-brand-hover",
|
|
4
|
+
"--color-brand-strong",
|
|
5
|
+
"--color-fg-on-brand",
|
|
6
|
+
"--color-border-selected",
|
|
7
|
+
"--color-link",
|
|
8
|
+
"--color-link-hover",
|
|
9
|
+
"--color-bg-selected",
|
|
10
|
+
"--color-bg-selected-hover",
|
|
11
|
+
"--color-chart-primary",
|
|
12
|
+
"--color-chart-brand",
|
|
13
|
+
"--color-navbar-bg",
|
|
14
|
+
"--color-navbar-fg",
|
|
15
|
+
"--color-navbar-fg-muted",
|
|
16
|
+
"--color-navbar-border",
|
|
17
|
+
"--color-navbar-brand",
|
|
18
|
+
"--color-logo",
|
|
19
|
+
"--color-logo-bg",
|
|
20
|
+
"--color-logo-fg",
|
|
21
|
+
"--color-field-focus",
|
|
22
|
+
"--color-focus-ring",
|
|
23
|
+
"--focus-ring",
|
|
24
|
+
"--color-bg-page",
|
|
25
|
+
"--color-bg-surface",
|
|
26
|
+
"--color-bg-surface-subtle",
|
|
27
|
+
"--color-bg-surface-strong",
|
|
28
|
+
"--color-bg-inverse",
|
|
29
|
+
"--color-bg-toolbar",
|
|
30
|
+
"--color-bg-toolbar-hover",
|
|
31
|
+
"--table-header-bg",
|
|
32
|
+
"--table-row-bg",
|
|
33
|
+
"--table-row-bg-alt",
|
|
34
|
+
"--table-row-bg-hover"
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
export { PRODUCT_THEME_TOKEN_NAMES };
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const PRODUCT_THEMES = {
|
|
4
|
+
dbc: {
|
|
5
|
+
label: "DBC"
|
|
6
|
+
},
|
|
7
|
+
filmstriben: {
|
|
8
|
+
label: "Filmstriben",
|
|
9
|
+
base: {
|
|
10
|
+
"--color-navbar-bg": "#212529",
|
|
11
|
+
"--color-navbar-fg": "#ffffff",
|
|
12
|
+
"--color-navbar-fg-muted": "rgba(255, 255, 255, 0.9)",
|
|
13
|
+
"--color-navbar-border": "color-mix(in srgb, var(--color-navbar-fg) 25%, transparent)",
|
|
14
|
+
"--color-navbar-brand": "#ffc107",
|
|
15
|
+
"--color-logo": "#ffc107",
|
|
16
|
+
"--color-logo-bg": "color-mix(in srgb, var(--color-logo) 10%, var(--color-bg-surface))",
|
|
17
|
+
"--color-logo-fg": "#212529"
|
|
18
|
+
},
|
|
19
|
+
light: {
|
|
20
|
+
"--color-brand": "var(--dbc-blue-500)",
|
|
21
|
+
"--color-brand-hover": "var(--dbc-blue-600)",
|
|
22
|
+
"--color-brand-strong": "var(--dbc-blue-600)",
|
|
23
|
+
"--color-fg-on-brand": "#ffffff",
|
|
24
|
+
"--color-border-selected": "var(--color-brand)",
|
|
25
|
+
"--color-field-focus": "var(--dbc-blue-500)",
|
|
26
|
+
"--color-focus-ring": "var(--dbc-blue-300)",
|
|
27
|
+
"--focus-ring": "0 0 0 3px rgba(12, 62, 227, 0.25)",
|
|
28
|
+
"--color-link": "var(--dbc-blue-500)",
|
|
29
|
+
"--color-link-hover": "var(--dbc-blue-600)",
|
|
30
|
+
"--color-bg-selected": "var(--dbc-blue-100)",
|
|
31
|
+
"--color-bg-selected-hover": "var(--dbc-blue-150)",
|
|
32
|
+
"--color-chart-primary": "color-mix(in srgb, var(--color-brand) 75%, rgb(255 255 255 / 0))"
|
|
33
|
+
},
|
|
34
|
+
dark: {
|
|
35
|
+
"--color-bg-page": "#212529",
|
|
36
|
+
"--color-bg-surface": "#212529",
|
|
37
|
+
"--color-bg-surface-subtle": "#2a2f34",
|
|
38
|
+
"--color-bg-surface-strong": "#161a1d",
|
|
39
|
+
"--color-bg-inverse": "#34393f",
|
|
40
|
+
"--color-bg-toolbar": "#2a2f34",
|
|
41
|
+
"--color-bg-toolbar-hover": "#343a40",
|
|
42
|
+
"--table-header-bg": "#2a2f34",
|
|
43
|
+
"--table-row-bg": "#212529",
|
|
44
|
+
"--table-row-bg-alt": "#1c2024",
|
|
45
|
+
"--table-row-bg-hover": "#2a2f34",
|
|
46
|
+
"--color-brand": "#ffc107",
|
|
47
|
+
"--color-brand-hover": "#ffca2c",
|
|
48
|
+
"--color-brand-strong": "#ffcd39",
|
|
49
|
+
"--color-fg-on-brand": "#212529",
|
|
50
|
+
"--color-border-selected": "var(--color-brand)",
|
|
51
|
+
"--color-field-focus": "var(--dbc-blue-300)",
|
|
52
|
+
"--color-focus-ring": "#ffc107",
|
|
53
|
+
"--focus-ring": "0 0 0 3px color-mix(in srgb, #ffc107 35%, transparent)",
|
|
54
|
+
"--color-bg-selected": "#4a3a06",
|
|
55
|
+
"--color-bg-selected-hover": "#5b4707",
|
|
56
|
+
"--color-chart-primary": "color-mix(in srgb, var(--color-brand) 75%, rgb(255 255 255 / 0))"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
valentines: {
|
|
60
|
+
label: "Valentines",
|
|
61
|
+
light: {
|
|
62
|
+
"--color-navbar-bg": "linear-gradient(90deg, #fff1f5 0%, #ffe4ec 52%, #f5ecff 100%)",
|
|
63
|
+
"--color-navbar-fg": "#3f1d2e",
|
|
64
|
+
"--color-navbar-fg-muted": "color-mix(in srgb, #3f1d2e 72%, white)",
|
|
65
|
+
"--color-navbar-border": "color-mix(in srgb, #e11d48 18%, transparent)",
|
|
66
|
+
"--color-navbar-brand": "#e11d48",
|
|
67
|
+
"--color-logo": "#e11d48",
|
|
68
|
+
"--color-logo-bg": "color-mix(in srgb, #e11d48 16%, white)",
|
|
69
|
+
"--color-logo-fg": "#ffffff",
|
|
70
|
+
"--color-bg-page": "#fff5f8",
|
|
71
|
+
"--color-bg-surface": "#fff0f5",
|
|
72
|
+
"--color-bg-surface-subtle": "#fff8fb",
|
|
73
|
+
"--color-bg-surface-strong": "#ffe2eb",
|
|
74
|
+
"--color-bg-inverse": "#3f1d2e",
|
|
75
|
+
"--color-bg-toolbar": "#ffdce8",
|
|
76
|
+
"--color-bg-toolbar-hover": "#ffcddd",
|
|
77
|
+
"--table-header-bg": "#ffe2eb",
|
|
78
|
+
"--table-row-bg": "#fff0f5",
|
|
79
|
+
"--table-row-bg-alt": "#fff7fa",
|
|
80
|
+
"--table-row-bg-hover": "#ffe8f0",
|
|
81
|
+
"--color-brand": "#e11d48",
|
|
82
|
+
"--color-brand-hover": "#be123c",
|
|
83
|
+
"--color-brand-strong": "#9f1239",
|
|
84
|
+
"--color-fg-on-brand": "#ffffff",
|
|
85
|
+
"--color-border-selected": "var(--color-brand)",
|
|
86
|
+
"--color-field-focus": "#4c1d95",
|
|
87
|
+
"--color-focus-ring": "#4c1d95",
|
|
88
|
+
"--focus-ring": "0 0 0 3px color-mix(in srgb, #4c1d95 28%, transparent)",
|
|
89
|
+
"--color-link": "#4c1d95",
|
|
90
|
+
"--color-link-hover": "color-mix(in srgb, #4c1d95 86%, black)",
|
|
91
|
+
"--color-bg-selected": "#ffe4ec",
|
|
92
|
+
"--color-bg-selected-hover": "#ffd3e0",
|
|
93
|
+
"--color-chart-primary": "color-mix(in srgb, var(--color-brand) 78%, rgb(255 255 255 / 0))",
|
|
94
|
+
"--color-chart-brand": "color-mix(in srgb, #4c1d95 76%, rgb(255 255 255 / 0))"
|
|
95
|
+
},
|
|
96
|
+
dark: {
|
|
97
|
+
"--color-navbar-bg": "linear-gradient(90deg, #4c1d95 0%, #7e22ce 35%, #be185d 100%)",
|
|
98
|
+
"--color-navbar-fg": "#fff7fb",
|
|
99
|
+
"--color-navbar-fg-muted": "rgba(255, 247, 251, 0.82)",
|
|
100
|
+
"--color-navbar-border": "rgba(255, 247, 251, 0.18)",
|
|
101
|
+
"--color-navbar-brand": "#ffd6e7",
|
|
102
|
+
"--color-logo": "#ffd6e7",
|
|
103
|
+
"--color-logo-bg": "color-mix(in srgb, #ffd6e7 18%, var(--color-bg-surface))",
|
|
104
|
+
"--color-logo-fg": "#4c1d95",
|
|
105
|
+
"--color-bg-page": "#241326",
|
|
106
|
+
"--color-bg-surface": "#241326",
|
|
107
|
+
"--color-bg-surface-subtle": "#301836",
|
|
108
|
+
"--color-bg-surface-strong": "#1a0d1d",
|
|
109
|
+
"--color-bg-inverse": "#fdf2f8",
|
|
110
|
+
"--color-bg-toolbar": "#301836",
|
|
111
|
+
"--color-bg-toolbar-hover": "#43204b",
|
|
112
|
+
"--table-header-bg": "#301836",
|
|
113
|
+
"--table-row-bg": "#241326",
|
|
114
|
+
"--table-row-bg-alt": "#2a142f",
|
|
115
|
+
"--table-row-bg-hover": "#301836",
|
|
116
|
+
"--color-brand": "#fb7185",
|
|
117
|
+
"--color-brand-hover": "#f43f5e",
|
|
118
|
+
"--color-brand-strong": "#e11d48",
|
|
119
|
+
"--color-fg-on-brand": "#2c1022",
|
|
120
|
+
"--color-border-selected": "var(--color-brand)",
|
|
121
|
+
"--color-field-focus": "#c4b5fd",
|
|
122
|
+
"--color-focus-ring": "#f9a8d4",
|
|
123
|
+
"--focus-ring": "0 0 0 3px color-mix(in srgb, #f9a8d4 36%, transparent)",
|
|
124
|
+
"--color-link": "#f9a8d4",
|
|
125
|
+
"--color-link-hover": "#fbcfe8",
|
|
126
|
+
"--color-bg-selected": "#4a1730",
|
|
127
|
+
"--color-bg-selected-hover": "#5a1c3a",
|
|
128
|
+
"--color-chart-primary": "color-mix(in srgb, var(--color-brand) 78%, rgb(255 255 255 / 0))",
|
|
129
|
+
"--color-chart-brand": "color-mix(in srgb, #c4b5fd 76%, rgb(255 255 255 / 0))"
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
function getProductThemeTokens(themeId, colorScheme) {
|
|
134
|
+
const definition = PRODUCT_THEMES[themeId];
|
|
135
|
+
if (!definition) return {};
|
|
136
|
+
return {
|
|
137
|
+
...definition.base,
|
|
138
|
+
...colorScheme === "dark" ? definition.dark : definition.light
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
exports.PRODUCT_THEMES = PRODUCT_THEMES;
|
|
143
|
+
exports.getProductThemeTokens = getProductThemeTokens;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ColorScheme } from '../../utils/color-scheme.constants';
|
|
2
|
+
import type { ProductThemeTokens } from './product-theme-tokens';
|
|
3
|
+
import type { ThemeId } from './types';
|
|
4
|
+
export interface ProductThemeDefinition {
|
|
5
|
+
label: string;
|
|
6
|
+
base?: ProductThemeTokens;
|
|
7
|
+
light?: ProductThemeTokens;
|
|
8
|
+
dark?: ProductThemeTokens;
|
|
9
|
+
}
|
|
10
|
+
export declare const PRODUCT_THEMES: Record<ThemeId, ProductThemeDefinition>;
|
|
11
|
+
export declare function getProductThemeTokens(themeId: ThemeId, colorScheme: ColorScheme | undefined): ProductThemeTokens;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
const PRODUCT_THEMES = {
|
|
2
|
+
dbc: {
|
|
3
|
+
label: "DBC"
|
|
4
|
+
},
|
|
5
|
+
filmstriben: {
|
|
6
|
+
label: "Filmstriben",
|
|
7
|
+
base: {
|
|
8
|
+
"--color-navbar-bg": "#212529",
|
|
9
|
+
"--color-navbar-fg": "#ffffff",
|
|
10
|
+
"--color-navbar-fg-muted": "rgba(255, 255, 255, 0.9)",
|
|
11
|
+
"--color-navbar-border": "color-mix(in srgb, var(--color-navbar-fg) 25%, transparent)",
|
|
12
|
+
"--color-navbar-brand": "#ffc107",
|
|
13
|
+
"--color-logo": "#ffc107",
|
|
14
|
+
"--color-logo-bg": "color-mix(in srgb, var(--color-logo) 10%, var(--color-bg-surface))",
|
|
15
|
+
"--color-logo-fg": "#212529"
|
|
16
|
+
},
|
|
17
|
+
light: {
|
|
18
|
+
"--color-brand": "var(--dbc-blue-500)",
|
|
19
|
+
"--color-brand-hover": "var(--dbc-blue-600)",
|
|
20
|
+
"--color-brand-strong": "var(--dbc-blue-600)",
|
|
21
|
+
"--color-fg-on-brand": "#ffffff",
|
|
22
|
+
"--color-border-selected": "var(--color-brand)",
|
|
23
|
+
"--color-field-focus": "var(--dbc-blue-500)",
|
|
24
|
+
"--color-focus-ring": "var(--dbc-blue-300)",
|
|
25
|
+
"--focus-ring": "0 0 0 3px rgba(12, 62, 227, 0.25)",
|
|
26
|
+
"--color-link": "var(--dbc-blue-500)",
|
|
27
|
+
"--color-link-hover": "var(--dbc-blue-600)",
|
|
28
|
+
"--color-bg-selected": "var(--dbc-blue-100)",
|
|
29
|
+
"--color-bg-selected-hover": "var(--dbc-blue-150)",
|
|
30
|
+
"--color-chart-primary": "color-mix(in srgb, var(--color-brand) 75%, rgb(255 255 255 / 0))"
|
|
31
|
+
},
|
|
32
|
+
dark: {
|
|
33
|
+
"--color-bg-page": "#212529",
|
|
34
|
+
"--color-bg-surface": "#212529",
|
|
35
|
+
"--color-bg-surface-subtle": "#2a2f34",
|
|
36
|
+
"--color-bg-surface-strong": "#161a1d",
|
|
37
|
+
"--color-bg-inverse": "#34393f",
|
|
38
|
+
"--color-bg-toolbar": "#2a2f34",
|
|
39
|
+
"--color-bg-toolbar-hover": "#343a40",
|
|
40
|
+
"--table-header-bg": "#2a2f34",
|
|
41
|
+
"--table-row-bg": "#212529",
|
|
42
|
+
"--table-row-bg-alt": "#1c2024",
|
|
43
|
+
"--table-row-bg-hover": "#2a2f34",
|
|
44
|
+
"--color-brand": "#ffc107",
|
|
45
|
+
"--color-brand-hover": "#ffca2c",
|
|
46
|
+
"--color-brand-strong": "#ffcd39",
|
|
47
|
+
"--color-fg-on-brand": "#212529",
|
|
48
|
+
"--color-border-selected": "var(--color-brand)",
|
|
49
|
+
"--color-field-focus": "var(--dbc-blue-300)",
|
|
50
|
+
"--color-focus-ring": "#ffc107",
|
|
51
|
+
"--focus-ring": "0 0 0 3px color-mix(in srgb, #ffc107 35%, transparent)",
|
|
52
|
+
"--color-bg-selected": "#4a3a06",
|
|
53
|
+
"--color-bg-selected-hover": "#5b4707",
|
|
54
|
+
"--color-chart-primary": "color-mix(in srgb, var(--color-brand) 75%, rgb(255 255 255 / 0))"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
valentines: {
|
|
58
|
+
label: "Valentines",
|
|
59
|
+
light: {
|
|
60
|
+
"--color-navbar-bg": "linear-gradient(90deg, #fff1f5 0%, #ffe4ec 52%, #f5ecff 100%)",
|
|
61
|
+
"--color-navbar-fg": "#3f1d2e",
|
|
62
|
+
"--color-navbar-fg-muted": "color-mix(in srgb, #3f1d2e 72%, white)",
|
|
63
|
+
"--color-navbar-border": "color-mix(in srgb, #e11d48 18%, transparent)",
|
|
64
|
+
"--color-navbar-brand": "#e11d48",
|
|
65
|
+
"--color-logo": "#e11d48",
|
|
66
|
+
"--color-logo-bg": "color-mix(in srgb, #e11d48 16%, white)",
|
|
67
|
+
"--color-logo-fg": "#ffffff",
|
|
68
|
+
"--color-bg-page": "#fff5f8",
|
|
69
|
+
"--color-bg-surface": "#fff0f5",
|
|
70
|
+
"--color-bg-surface-subtle": "#fff8fb",
|
|
71
|
+
"--color-bg-surface-strong": "#ffe2eb",
|
|
72
|
+
"--color-bg-inverse": "#3f1d2e",
|
|
73
|
+
"--color-bg-toolbar": "#ffdce8",
|
|
74
|
+
"--color-bg-toolbar-hover": "#ffcddd",
|
|
75
|
+
"--table-header-bg": "#ffe2eb",
|
|
76
|
+
"--table-row-bg": "#fff0f5",
|
|
77
|
+
"--table-row-bg-alt": "#fff7fa",
|
|
78
|
+
"--table-row-bg-hover": "#ffe8f0",
|
|
79
|
+
"--color-brand": "#e11d48",
|
|
80
|
+
"--color-brand-hover": "#be123c",
|
|
81
|
+
"--color-brand-strong": "#9f1239",
|
|
82
|
+
"--color-fg-on-brand": "#ffffff",
|
|
83
|
+
"--color-border-selected": "var(--color-brand)",
|
|
84
|
+
"--color-field-focus": "#4c1d95",
|
|
85
|
+
"--color-focus-ring": "#4c1d95",
|
|
86
|
+
"--focus-ring": "0 0 0 3px color-mix(in srgb, #4c1d95 28%, transparent)",
|
|
87
|
+
"--color-link": "#4c1d95",
|
|
88
|
+
"--color-link-hover": "color-mix(in srgb, #4c1d95 86%, black)",
|
|
89
|
+
"--color-bg-selected": "#ffe4ec",
|
|
90
|
+
"--color-bg-selected-hover": "#ffd3e0",
|
|
91
|
+
"--color-chart-primary": "color-mix(in srgb, var(--color-brand) 78%, rgb(255 255 255 / 0))",
|
|
92
|
+
"--color-chart-brand": "color-mix(in srgb, #4c1d95 76%, rgb(255 255 255 / 0))"
|
|
93
|
+
},
|
|
94
|
+
dark: {
|
|
95
|
+
"--color-navbar-bg": "linear-gradient(90deg, #4c1d95 0%, #7e22ce 35%, #be185d 100%)",
|
|
96
|
+
"--color-navbar-fg": "#fff7fb",
|
|
97
|
+
"--color-navbar-fg-muted": "rgba(255, 247, 251, 0.82)",
|
|
98
|
+
"--color-navbar-border": "rgba(255, 247, 251, 0.18)",
|
|
99
|
+
"--color-navbar-brand": "#ffd6e7",
|
|
100
|
+
"--color-logo": "#ffd6e7",
|
|
101
|
+
"--color-logo-bg": "color-mix(in srgb, #ffd6e7 18%, var(--color-bg-surface))",
|
|
102
|
+
"--color-logo-fg": "#4c1d95",
|
|
103
|
+
"--color-bg-page": "#241326",
|
|
104
|
+
"--color-bg-surface": "#241326",
|
|
105
|
+
"--color-bg-surface-subtle": "#301836",
|
|
106
|
+
"--color-bg-surface-strong": "#1a0d1d",
|
|
107
|
+
"--color-bg-inverse": "#fdf2f8",
|
|
108
|
+
"--color-bg-toolbar": "#301836",
|
|
109
|
+
"--color-bg-toolbar-hover": "#43204b",
|
|
110
|
+
"--table-header-bg": "#301836",
|
|
111
|
+
"--table-row-bg": "#241326",
|
|
112
|
+
"--table-row-bg-alt": "#2a142f",
|
|
113
|
+
"--table-row-bg-hover": "#301836",
|
|
114
|
+
"--color-brand": "#fb7185",
|
|
115
|
+
"--color-brand-hover": "#f43f5e",
|
|
116
|
+
"--color-brand-strong": "#e11d48",
|
|
117
|
+
"--color-fg-on-brand": "#2c1022",
|
|
118
|
+
"--color-border-selected": "var(--color-brand)",
|
|
119
|
+
"--color-field-focus": "#c4b5fd",
|
|
120
|
+
"--color-focus-ring": "#f9a8d4",
|
|
121
|
+
"--focus-ring": "0 0 0 3px color-mix(in srgb, #f9a8d4 36%, transparent)",
|
|
122
|
+
"--color-link": "#f9a8d4",
|
|
123
|
+
"--color-link-hover": "#fbcfe8",
|
|
124
|
+
"--color-bg-selected": "#4a1730",
|
|
125
|
+
"--color-bg-selected-hover": "#5a1c3a",
|
|
126
|
+
"--color-chart-primary": "color-mix(in srgb, var(--color-brand) 78%, rgb(255 255 255 / 0))",
|
|
127
|
+
"--color-chart-brand": "color-mix(in srgb, #c4b5fd 76%, rgb(255 255 255 / 0))"
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
function getProductThemeTokens(themeId, colorScheme) {
|
|
132
|
+
const definition = PRODUCT_THEMES[themeId];
|
|
133
|
+
if (!definition) return {};
|
|
134
|
+
return {
|
|
135
|
+
...definition.base,
|
|
136
|
+
...colorScheme === "dark" ? definition.dark : definition.light
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export { PRODUCT_THEMES, getProductThemeTokens };
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const THEME_IDS = ["dbc", "filmstriben"];
|
|
3
|
+
const THEME_IDS = ["dbc", "filmstriben", "valentines"];
|
|
4
4
|
const THEME_LABELS = {
|
|
5
5
|
dbc: "DBC",
|
|
6
|
-
filmstriben: "Filmstriben"
|
|
6
|
+
filmstriben: "Filmstriben",
|
|
7
|
+
valentines: "Valentines"
|
|
7
8
|
};
|
|
8
9
|
|
|
9
10
|
exports.THEME_IDS = THEME_IDS;
|
|
@@ -7,18 +7,6 @@
|
|
|
7
7
|
* TypeScript-only enforcement; add an id here (and to `THEME_LABELS`)
|
|
8
8
|
* whenever a new theme folder is added.
|
|
9
9
|
*/
|
|
10
|
-
export declare const THEME_IDS: readonly ["dbc", "filmstriben"];
|
|
10
|
+
export declare const THEME_IDS: readonly ["dbc", "filmstriben", "valentines"];
|
|
11
11
|
export type ThemeId = (typeof THEME_IDS)[number];
|
|
12
12
|
export declare const THEME_LABELS: Record<ThemeId, string>;
|
|
13
|
-
/**
|
|
14
|
-
* Per-theme override for where to fetch its CSS from at runtime. Only
|
|
15
|
-
* needed for a theme whose CSS isn't already loaded some other way by the
|
|
16
|
-
* app — omit an id (or leave its value `''`/unset) for a theme that's
|
|
17
|
-
* already bundled statically alongside whatever the app already imports.
|
|
18
|
-
*
|
|
19
|
-
* This is the only piece of theme data `ThemeScript`/`useTheme` actually
|
|
20
|
-
* need at runtime (which id to inject a `<link>` for, and its URL) — they
|
|
21
|
-
* don't need the full enumerated id list or labels, only whichever UI
|
|
22
|
-
* renders the switcher (`ThemeButton`/`ThemeMenuSection`) does.
|
|
23
|
-
*/
|
|
24
|
-
export type ThemeHrefs = Partial<Record<ThemeId, string>>;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
const THEME_IDS = ["dbc", "filmstriben"];
|
|
1
|
+
const THEME_IDS = ["dbc", "filmstriben", "valentines"];
|
|
2
2
|
const THEME_LABELS = {
|
|
3
3
|
dbc: "DBC",
|
|
4
|
-
filmstriben: "Filmstriben"
|
|
4
|
+
filmstriben: "Filmstriben",
|
|
5
|
+
valentines: "Valentines"
|
|
5
6
|
};
|
|
6
7
|
|
|
7
8
|
export { THEME_IDS, THEME_LABELS };
|