@dbcdk/react-components 0.0.173 → 0.0.175
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/client.cjs +14 -0
- package/dist/client.d.ts +2 -0
- package/dist/client.js +2 -0
- package/dist/components/app-header/AppHeader.module.css +2 -2
- package/dist/components/button/Button.d.ts +3 -1
- package/dist/components/button/Button.module.css +26 -0
- package/dist/components/color-scheme-button/ColorSchemeButton.cjs +78 -0
- package/dist/components/color-scheme-button/ColorSchemeButton.d.ts +8 -0
- package/dist/components/color-scheme-button/ColorSchemeButton.js +75 -0
- package/dist/components/filter-field/FilterField.module.css +2 -2
- package/dist/components/forms/file-upload/FileUpload.module.css +3 -3
- package/dist/components/forms/form-select/FormSelect.d.ts +1 -1
- package/dist/components/forms/form-select/FormSelect.module.css +20 -1
- package/dist/components/forms/input/Input.cjs +1 -1
- package/dist/components/forms/input/Input.d.ts +1 -1
- package/dist/components/forms/input/Input.js +1 -1
- package/dist/components/forms/input/Input.module.css +40 -8
- package/dist/components/forms/text-area/Textarea.module.css +2 -1
- package/dist/components/forms/typeahead/Typeahead.cjs +1 -0
- package/dist/components/forms/typeahead/Typeahead.js +1 -0
- package/dist/components/hyperlink/Hyperlink.cjs +2 -1
- package/dist/components/hyperlink/Hyperlink.d.ts +2 -1
- package/dist/components/hyperlink/Hyperlink.js +2 -1
- package/dist/components/hyperlink/Hyperlink.module.css +16 -0
- package/dist/components/nav-bar/NavBar.cjs +1 -0
- package/dist/components/nav-bar/NavBar.js +1 -0
- package/dist/components/nav-bar/NavBar.module.css +10 -10
- package/dist/components/page-layout/PageLayout.module.css +1 -1
- package/dist/components/popover/Popover.cjs +4 -2
- package/dist/components/popover/Popover.d.ts +2 -0
- package/dist/components/popover/Popover.js +4 -2
- package/dist/components/popover/Popover.module.css +5 -0
- package/dist/components/theme-button/ThemeButton.cjs +30 -23
- package/dist/components/theme-button/ThemeButton.d.ts +9 -3
- package/dist/components/theme-button/ThemeButton.js +31 -24
- package/dist/components/theme-script/ThemeScript.cjs +50 -12
- package/dist/components/theme-script/ThemeScript.d.ts +35 -12
- package/dist/components/theme-script/ThemeScript.js +51 -13
- package/dist/hooks/useColorScheme.cjs +74 -0
- package/dist/hooks/useColorScheme.d.ts +6 -0
- package/dist/hooks/useColorScheme.js +72 -0
- package/dist/hooks/useTheme.cjs +116 -50
- package/dist/hooks/useTheme.d.ts +17 -5
- package/dist/hooks/useTheme.js +117 -51
- package/dist/index.cjs +14 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/styles/themes/dbc/colors.css +14 -2
- package/dist/styles/themes/filmstriben/theme.css +108 -0
- package/dist/styles/themes/types.cjs +8 -0
- package/dist/styles/themes/types.d.ts +24 -16
- package/dist/styles/themes/types.js +6 -0
- package/dist/themes/filmstriben.css +4 -0
- package/dist/utils/color-scheme.constants.cjs +11 -0
- package/dist/utils/color-scheme.constants.d.ts +4 -0
- package/dist/utils/color-scheme.constants.js +7 -0
- package/dist/utils/theme.constants.cjs +3 -7
- package/dist/utils/theme.constants.d.ts +2 -4
- package/dist/utils/theme.constants.js +3 -6
- package/package.json +1 -1
- package/dist/styles/themes/filmstriben-budget/theme.css +0 -22
- package/dist/themes/filmstriben-budget.css +0 -3
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useEffect, useSyncExternalStore } from 'react';
|
|
3
|
+
import { isColorScheme, COLOR_SCHEME_STORAGE_KEY } from '../utils/color-scheme.constants';
|
|
4
|
+
import { readCookie, writeCookie } from '../utils/cookie.utils';
|
|
5
|
+
import { readLocalStorage, writeLocalStorage } from '../utils/localStorage.utils';
|
|
6
|
+
|
|
7
|
+
function persistColorScheme(id) {
|
|
8
|
+
writeLocalStorage(COLOR_SCHEME_STORAGE_KEY, id);
|
|
9
|
+
writeCookie(COLOR_SCHEME_STORAGE_KEY, id);
|
|
10
|
+
}
|
|
11
|
+
function getDomColorScheme() {
|
|
12
|
+
return document.documentElement.dataset.theme;
|
|
13
|
+
}
|
|
14
|
+
function applyColorScheme(id) {
|
|
15
|
+
document.documentElement.dataset.theme = id;
|
|
16
|
+
}
|
|
17
|
+
let currentColorScheme = null;
|
|
18
|
+
let resolved = false;
|
|
19
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
20
|
+
function notify() {
|
|
21
|
+
listeners.forEach((listener) => listener());
|
|
22
|
+
}
|
|
23
|
+
function subscribe(listener) {
|
|
24
|
+
listeners.add(listener);
|
|
25
|
+
return () => {
|
|
26
|
+
listeners.delete(listener);
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function getSnapshot() {
|
|
30
|
+
return currentColorScheme;
|
|
31
|
+
}
|
|
32
|
+
function getServerSnapshot() {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
function resolveInitialColorScheme(initialColorScheme) {
|
|
36
|
+
const fromDomAttribute = getDomColorScheme();
|
|
37
|
+
let resolvedColorScheme = isColorScheme(fromDomAttribute) ? fromDomAttribute : initialColorScheme;
|
|
38
|
+
const fromCookie = readCookie(COLOR_SCHEME_STORAGE_KEY);
|
|
39
|
+
if (isColorScheme(fromCookie)) {
|
|
40
|
+
resolvedColorScheme = fromCookie;
|
|
41
|
+
} else {
|
|
42
|
+
const fromStorage = readLocalStorage(COLOR_SCHEME_STORAGE_KEY);
|
|
43
|
+
if (isColorScheme(fromStorage)) resolvedColorScheme = fromStorage;
|
|
44
|
+
}
|
|
45
|
+
return resolvedColorScheme;
|
|
46
|
+
}
|
|
47
|
+
function ensureResolved(initialColorScheme) {
|
|
48
|
+
if (resolved) return;
|
|
49
|
+
resolved = true;
|
|
50
|
+
const value = resolveInitialColorScheme(initialColorScheme);
|
|
51
|
+
applyColorScheme(value);
|
|
52
|
+
persistColorScheme(value);
|
|
53
|
+
currentColorScheme = value;
|
|
54
|
+
notify();
|
|
55
|
+
}
|
|
56
|
+
function switchColorScheme(id) {
|
|
57
|
+
applyColorScheme(id);
|
|
58
|
+
persistColorScheme(id);
|
|
59
|
+
currentColorScheme = id;
|
|
60
|
+
resolved = true;
|
|
61
|
+
notify();
|
|
62
|
+
return id;
|
|
63
|
+
}
|
|
64
|
+
function useColorScheme(initialColorScheme = "system") {
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
ensureResolved(initialColorScheme);
|
|
67
|
+
}, [initialColorScheme]);
|
|
68
|
+
const colorScheme = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
69
|
+
return { colorScheme, switchColorScheme };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export { useColorScheme };
|
package/dist/hooks/useTheme.cjs
CHANGED
|
@@ -2,34 +2,59 @@
|
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var react = require('react');
|
|
5
|
+
var cookie_utils = require('../utils/cookie.utils');
|
|
6
|
+
var localStorage_utils = require('../utils/localStorage.utils');
|
|
5
7
|
var theme_constants = require('../utils/theme.constants');
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
function persistTheme(id) {
|
|
12
|
-
try {
|
|
13
|
-
localStorage.setItem(theme_constants.THEME_STORAGE_KEY, id);
|
|
14
|
-
} catch {
|
|
15
|
-
console.error("Failed to access localStorage");
|
|
16
|
-
}
|
|
17
|
-
try {
|
|
18
|
-
document.cookie = `${theme_constants.THEME_STORAGE_KEY}=${encodeURIComponent(
|
|
19
|
-
id
|
|
20
|
-
)}; Path=/; Max-Age=${60 * 60 * 24 * 365}`;
|
|
21
|
-
} catch {
|
|
22
|
-
console.error("Failed to set theme cookie");
|
|
23
|
-
}
|
|
9
|
+
const PRELOAD_ID_PREFIX = "dbc-theme-preload-";
|
|
10
|
+
function persistTheme(storageKey, id) {
|
|
11
|
+
localStorage_utils.writeLocalStorage(storageKey, id);
|
|
12
|
+
cookie_utils.writeCookie(storageKey, id);
|
|
24
13
|
}
|
|
25
14
|
function getDomTheme() {
|
|
26
|
-
return document.documentElement.dataset.
|
|
15
|
+
return document.documentElement.dataset.productTheme;
|
|
27
16
|
}
|
|
28
17
|
function applyTheme(id) {
|
|
29
|
-
document.documentElement.dataset.
|
|
18
|
+
document.documentElement.dataset.productTheme = id;
|
|
19
|
+
}
|
|
20
|
+
function findLink(linkId) {
|
|
21
|
+
return document.getElementById(linkId);
|
|
22
|
+
}
|
|
23
|
+
function findPreloadLink(id) {
|
|
24
|
+
return document.getElementById(`${PRELOAD_ID_PREFIX}${id}`);
|
|
25
|
+
}
|
|
26
|
+
function ensureStylesheet(id, href, linkId, onReady) {
|
|
27
|
+
var _a;
|
|
28
|
+
if (!href) {
|
|
29
|
+
onReady();
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const active = findLink(linkId);
|
|
33
|
+
if (active && active.getAttribute("href") === href && active.rel === "stylesheet") {
|
|
34
|
+
onReady();
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const preload = findPreloadLink(id);
|
|
38
|
+
const link = (_a = active != null ? active : preload) != null ? _a : document.createElement("link");
|
|
39
|
+
const wasConnected = link.isConnected;
|
|
40
|
+
link.id = linkId;
|
|
41
|
+
link.rel = "stylesheet";
|
|
42
|
+
link.removeAttribute("as");
|
|
43
|
+
link.href = href;
|
|
44
|
+
if (preload && preload !== link) preload.remove();
|
|
45
|
+
let settled = false;
|
|
46
|
+
const finish = () => {
|
|
47
|
+
if (settled) return;
|
|
48
|
+
settled = true;
|
|
49
|
+
onReady();
|
|
50
|
+
};
|
|
51
|
+
link.addEventListener("load", finish, { once: true });
|
|
52
|
+
link.addEventListener("error", finish, { once: true });
|
|
53
|
+
if (!wasConnected) document.head.appendChild(link);
|
|
30
54
|
}
|
|
31
55
|
let currentTheme = null;
|
|
32
56
|
let resolved = false;
|
|
57
|
+
let preloadScheduled = false;
|
|
33
58
|
const listeners = /* @__PURE__ */ new Set();
|
|
34
59
|
function notify() {
|
|
35
60
|
listeners.forEach((listener) => listener());
|
|
@@ -46,44 +71,85 @@ function getSnapshot() {
|
|
|
46
71
|
function getServerSnapshot() {
|
|
47
72
|
return null;
|
|
48
73
|
}
|
|
49
|
-
function resolveInitialTheme(
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
const fromCookie =
|
|
53
|
-
if (
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const fromStorage = localStorage.getItem(theme_constants.THEME_STORAGE_KEY);
|
|
58
|
-
if (theme_constants.isThemeVariant(fromStorage)) resolvedTheme = fromStorage;
|
|
59
|
-
} catch {
|
|
60
|
-
console.error("Failed to access localStorage");
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return resolvedTheme;
|
|
74
|
+
function resolveInitialTheme(storageKey, defaultTheme) {
|
|
75
|
+
const fromDom = getDomTheme();
|
|
76
|
+
if (fromDom) return fromDom;
|
|
77
|
+
const fromCookie = cookie_utils.readCookie(storageKey);
|
|
78
|
+
if (fromCookie) return fromCookie;
|
|
79
|
+
const fromStorage = localStorage_utils.readLocalStorage(storageKey);
|
|
80
|
+
if (fromStorage) return fromStorage;
|
|
81
|
+
return defaultTheme;
|
|
64
82
|
}
|
|
65
|
-
function ensureResolved(
|
|
83
|
+
function ensureResolved(hrefs, defaultTheme, storageKey, linkId) {
|
|
66
84
|
if (resolved) return;
|
|
67
85
|
resolved = true;
|
|
68
|
-
const value = resolveInitialTheme(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
86
|
+
const value = resolveInitialTheme(storageKey, defaultTheme);
|
|
87
|
+
const finish = () => {
|
|
88
|
+
applyTheme(value);
|
|
89
|
+
persistTheme(storageKey, value);
|
|
90
|
+
currentTheme = value;
|
|
91
|
+
notify();
|
|
92
|
+
};
|
|
93
|
+
if (value === defaultTheme) {
|
|
94
|
+
finish();
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
ensureStylesheet(value, hrefs[value], linkId, finish);
|
|
73
98
|
}
|
|
74
|
-
function
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
99
|
+
function schedulePreload(hrefs, defaultTheme) {
|
|
100
|
+
if (preloadScheduled) return;
|
|
101
|
+
preloadScheduled = true;
|
|
102
|
+
const run = () => {
|
|
103
|
+
var _a;
|
|
104
|
+
for (const [id, href] of Object.entries(hrefs)) {
|
|
105
|
+
if (id === defaultTheme || !href) continue;
|
|
106
|
+
if (((_a = findLink(theme_constants.THEME_LINK_ID)) == null ? void 0 : _a.getAttribute("href")) === href) continue;
|
|
107
|
+
if (findPreloadLink(id)) continue;
|
|
108
|
+
const link = document.createElement("link");
|
|
109
|
+
link.id = `${PRELOAD_ID_PREFIX}${id}`;
|
|
110
|
+
link.rel = "preload";
|
|
111
|
+
link.as = "style";
|
|
112
|
+
link.href = href;
|
|
113
|
+
document.head.appendChild(link);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
const requestIdle = window.requestIdleCallback;
|
|
117
|
+
if (typeof requestIdle === "function") {
|
|
118
|
+
requestIdle(run);
|
|
119
|
+
} else {
|
|
120
|
+
setTimeout(run, 1);
|
|
121
|
+
}
|
|
81
122
|
}
|
|
82
|
-
function
|
|
123
|
+
function switchThemeInternal(hrefs, defaultTheme, storageKey, linkId, id) {
|
|
124
|
+
const finish = () => {
|
|
125
|
+
applyTheme(id);
|
|
126
|
+
persistTheme(storageKey, id);
|
|
127
|
+
currentTheme = id;
|
|
128
|
+
resolved = true;
|
|
129
|
+
notify();
|
|
130
|
+
};
|
|
131
|
+
if (id === defaultTheme) {
|
|
132
|
+
finish();
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
ensureStylesheet(id, hrefs[id], linkId, finish);
|
|
136
|
+
}
|
|
137
|
+
function useTheme(options) {
|
|
138
|
+
const {
|
|
139
|
+
defaultTheme,
|
|
140
|
+
hrefs = {},
|
|
141
|
+
linkId = theme_constants.THEME_LINK_ID,
|
|
142
|
+
preloadOthers = true,
|
|
143
|
+
storageKey = theme_constants.THEME_STORAGE_KEY
|
|
144
|
+
} = options;
|
|
83
145
|
react.useEffect(() => {
|
|
84
|
-
ensureResolved(
|
|
85
|
-
|
|
146
|
+
ensureResolved(hrefs, defaultTheme, storageKey, linkId);
|
|
147
|
+
if (preloadOthers) schedulePreload(hrefs, defaultTheme);
|
|
148
|
+
}, []);
|
|
86
149
|
const theme = react.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
150
|
+
function switchTheme(id) {
|
|
151
|
+
switchThemeInternal(hrefs, defaultTheme, storageKey, linkId, id);
|
|
152
|
+
}
|
|
87
153
|
return { theme, switchTheme };
|
|
88
154
|
}
|
|
89
155
|
|
package/dist/hooks/useTheme.d.ts
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export type {
|
|
3
|
-
export
|
|
4
|
-
theme
|
|
5
|
-
|
|
1
|
+
import type { ThemeHrefs, ThemeId } from '../styles/themes/types';
|
|
2
|
+
export type { ThemeHrefs, ThemeId };
|
|
3
|
+
export interface UseThemeOptions {
|
|
4
|
+
/** The theme the app already loads via a normal static import — never
|
|
5
|
+
* fetched/linked dynamically, just applied via the attribute. */
|
|
6
|
+
defaultTheme: ThemeId;
|
|
7
|
+
/** Per-theme CSS URL, for any theme not already loaded some other way. */
|
|
8
|
+
hrefs?: ThemeHrefs;
|
|
9
|
+
/** DOM id for the `<link>` element used for the currently active non-default theme. */
|
|
10
|
+
linkId?: string;
|
|
11
|
+
/** Warm the browser cache for every other theme at idle time. Default true. */
|
|
12
|
+
preloadOthers?: boolean;
|
|
13
|
+
storageKey?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function useTheme(options: UseThemeOptions): {
|
|
16
|
+
theme: ThemeId | null;
|
|
17
|
+
switchTheme: (id: ThemeId) => void;
|
|
6
18
|
};
|
package/dist/hooks/useTheme.js
CHANGED
|
@@ -1,33 +1,58 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { useEffect, useSyncExternalStore } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { readCookie, writeCookie } from '../utils/cookie.utils';
|
|
4
|
+
import { readLocalStorage, writeLocalStorage } from '../utils/localStorage.utils';
|
|
5
|
+
import { THEME_STORAGE_KEY, THEME_LINK_ID } from '../utils/theme.constants';
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
function persistTheme(id) {
|
|
10
|
-
try {
|
|
11
|
-
localStorage.setItem(THEME_STORAGE_KEY, id);
|
|
12
|
-
} catch {
|
|
13
|
-
console.error("Failed to access localStorage");
|
|
14
|
-
}
|
|
15
|
-
try {
|
|
16
|
-
document.cookie = `${THEME_STORAGE_KEY}=${encodeURIComponent(
|
|
17
|
-
id
|
|
18
|
-
)}; Path=/; Max-Age=${60 * 60 * 24 * 365}`;
|
|
19
|
-
} catch {
|
|
20
|
-
console.error("Failed to set theme cookie");
|
|
21
|
-
}
|
|
7
|
+
const PRELOAD_ID_PREFIX = "dbc-theme-preload-";
|
|
8
|
+
function persistTheme(storageKey, id) {
|
|
9
|
+
writeLocalStorage(storageKey, id);
|
|
10
|
+
writeCookie(storageKey, id);
|
|
22
11
|
}
|
|
23
12
|
function getDomTheme() {
|
|
24
|
-
return document.documentElement.dataset.
|
|
13
|
+
return document.documentElement.dataset.productTheme;
|
|
25
14
|
}
|
|
26
15
|
function applyTheme(id) {
|
|
27
|
-
document.documentElement.dataset.
|
|
16
|
+
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);
|
|
28
52
|
}
|
|
29
53
|
let currentTheme = null;
|
|
30
54
|
let resolved = false;
|
|
55
|
+
let preloadScheduled = false;
|
|
31
56
|
const listeners = /* @__PURE__ */ new Set();
|
|
32
57
|
function notify() {
|
|
33
58
|
listeners.forEach((listener) => listener());
|
|
@@ -44,44 +69,85 @@ function getSnapshot() {
|
|
|
44
69
|
function getServerSnapshot() {
|
|
45
70
|
return null;
|
|
46
71
|
}
|
|
47
|
-
function resolveInitialTheme(
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
const fromCookie =
|
|
51
|
-
if (
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const fromStorage = localStorage.getItem(THEME_STORAGE_KEY);
|
|
56
|
-
if (isThemeVariant(fromStorage)) resolvedTheme = fromStorage;
|
|
57
|
-
} catch {
|
|
58
|
-
console.error("Failed to access localStorage");
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
return resolvedTheme;
|
|
72
|
+
function resolveInitialTheme(storageKey, defaultTheme) {
|
|
73
|
+
const fromDom = getDomTheme();
|
|
74
|
+
if (fromDom) return fromDom;
|
|
75
|
+
const fromCookie = readCookie(storageKey);
|
|
76
|
+
if (fromCookie) return fromCookie;
|
|
77
|
+
const fromStorage = readLocalStorage(storageKey);
|
|
78
|
+
if (fromStorage) return fromStorage;
|
|
79
|
+
return defaultTheme;
|
|
62
80
|
}
|
|
63
|
-
function ensureResolved(
|
|
81
|
+
function ensureResolved(hrefs, defaultTheme, storageKey, linkId) {
|
|
64
82
|
if (resolved) return;
|
|
65
83
|
resolved = true;
|
|
66
|
-
const value = resolveInitialTheme(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
84
|
+
const value = resolveInitialTheme(storageKey, defaultTheme);
|
|
85
|
+
const finish = () => {
|
|
86
|
+
applyTheme(value);
|
|
87
|
+
persistTheme(storageKey, value);
|
|
88
|
+
currentTheme = value;
|
|
89
|
+
notify();
|
|
90
|
+
};
|
|
91
|
+
if (value === defaultTheme) {
|
|
92
|
+
finish();
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
ensureStylesheet(value, hrefs[value], linkId, finish);
|
|
71
96
|
}
|
|
72
|
-
function
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
97
|
+
function schedulePreload(hrefs, defaultTheme) {
|
|
98
|
+
if (preloadScheduled) return;
|
|
99
|
+
preloadScheduled = true;
|
|
100
|
+
const run = () => {
|
|
101
|
+
var _a;
|
|
102
|
+
for (const [id, href] of Object.entries(hrefs)) {
|
|
103
|
+
if (id === defaultTheme || !href) continue;
|
|
104
|
+
if (((_a = findLink(THEME_LINK_ID)) == null ? void 0 : _a.getAttribute("href")) === href) continue;
|
|
105
|
+
if (findPreloadLink(id)) continue;
|
|
106
|
+
const link = document.createElement("link");
|
|
107
|
+
link.id = `${PRELOAD_ID_PREFIX}${id}`;
|
|
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
|
+
}
|
|
79
120
|
}
|
|
80
|
-
function
|
|
121
|
+
function switchThemeInternal(hrefs, defaultTheme, storageKey, linkId, id) {
|
|
122
|
+
const finish = () => {
|
|
123
|
+
applyTheme(id);
|
|
124
|
+
persistTheme(storageKey, id);
|
|
125
|
+
currentTheme = id;
|
|
126
|
+
resolved = true;
|
|
127
|
+
notify();
|
|
128
|
+
};
|
|
129
|
+
if (id === defaultTheme) {
|
|
130
|
+
finish();
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
ensureStylesheet(id, hrefs[id], linkId, finish);
|
|
134
|
+
}
|
|
135
|
+
function useTheme(options) {
|
|
136
|
+
const {
|
|
137
|
+
defaultTheme,
|
|
138
|
+
hrefs = {},
|
|
139
|
+
linkId = THEME_LINK_ID,
|
|
140
|
+
preloadOthers = true,
|
|
141
|
+
storageKey = THEME_STORAGE_KEY
|
|
142
|
+
} = options;
|
|
81
143
|
useEffect(() => {
|
|
82
|
-
ensureResolved(
|
|
83
|
-
|
|
144
|
+
ensureResolved(hrefs, defaultTheme, storageKey, linkId);
|
|
145
|
+
if (preloadOthers) schedulePreload(hrefs, defaultTheme);
|
|
146
|
+
}, []);
|
|
84
147
|
const theme = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
148
|
+
function switchTheme(id) {
|
|
149
|
+
switchThemeInternal(hrefs, defaultTheme, storageKey, linkId, id);
|
|
150
|
+
}
|
|
85
151
|
return { theme, switchTheme };
|
|
86
152
|
}
|
|
87
153
|
|
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var colorScheme_constants = require('./utils/color-scheme.constants');
|
|
3
4
|
var ThemeScript = require('./components/theme-script/ThemeScript');
|
|
4
5
|
var theme_constants = require('./utils/theme.constants');
|
|
6
|
+
var types = require('./styles/themes/types');
|
|
5
7
|
var Icon = require('./components/icon/Icon');
|
|
6
8
|
var UserDisplay = require('./components/user-display/UserDisplay');
|
|
7
9
|
var Headline = require('./components/headline/Headline');
|
|
@@ -46,6 +48,12 @@ var CheckboxGroup = require('./components/forms/checkbox-group/CheckboxGroup');
|
|
|
46
48
|
|
|
47
49
|
|
|
48
50
|
|
|
51
|
+
Object.keys(colorScheme_constants).forEach(function (k) {
|
|
52
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
53
|
+
enumerable: true,
|
|
54
|
+
get: function () { return colorScheme_constants[k]; }
|
|
55
|
+
});
|
|
56
|
+
});
|
|
49
57
|
Object.keys(ThemeScript).forEach(function (k) {
|
|
50
58
|
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
51
59
|
enumerable: true,
|
|
@@ -58,6 +66,12 @@ Object.keys(theme_constants).forEach(function (k) {
|
|
|
58
66
|
get: function () { return theme_constants[k]; }
|
|
59
67
|
});
|
|
60
68
|
});
|
|
69
|
+
Object.keys(types).forEach(function (k) {
|
|
70
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
71
|
+
enumerable: true,
|
|
72
|
+
get: function () { return types[k]; }
|
|
73
|
+
});
|
|
74
|
+
});
|
|
61
75
|
Object.keys(Icon).forEach(function (k) {
|
|
62
76
|
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
63
77
|
enumerable: true,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
export * from './utils/color-scheme.constants';
|
|
1
2
|
export * from './components/theme-script/ThemeScript';
|
|
2
3
|
export * from './utils/theme.constants';
|
|
4
|
+
export * from './styles/themes/types';
|
|
3
5
|
export * from './components/icon/Icon';
|
|
4
6
|
export * from './components/user-display/UserDisplay';
|
|
5
7
|
export * from './components/headline/Headline';
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
export * from './utils/color-scheme.constants';
|
|
1
2
|
export * from './components/theme-script/ThemeScript';
|
|
2
3
|
export * from './utils/theme.constants';
|
|
4
|
+
export * from './styles/themes/types';
|
|
3
5
|
export * from './components/icon/Icon';
|
|
4
6
|
export * from './components/user-display/UserDisplay';
|
|
5
7
|
export * from './components/headline/Headline';
|
|
@@ -215,6 +215,7 @@ html {
|
|
|
215
215
|
/* Focus */
|
|
216
216
|
--color-focus-ring: var(--dbc-blue-300);
|
|
217
217
|
--focus-ring: 0 0 0 3px light-dark(rgba(12, 62, 227, 0.25), rgba(59, 130, 246, 0.35));
|
|
218
|
+
--color-field-focus: var(--color-brand);
|
|
218
219
|
|
|
219
220
|
/* Syntax (JSON viewer) */
|
|
220
221
|
--color-syntax-accent: var(--dbc-blue-300);
|
|
@@ -240,11 +241,22 @@ html {
|
|
|
240
241
|
--button-fg-primary: var(--color-fg-on-brand);
|
|
241
242
|
|
|
242
243
|
/* Product / logo lockup — generic defaults; apps with a custom identity
|
|
243
|
-
override these tokens only (see e.g. filmstriben
|
|
244
|
-
--color-logo: var(--color-
|
|
244
|
+
override these tokens only (see e.g. filmstriben/theme.css) */
|
|
245
|
+
--color-logo: var(--color-fg-default);
|
|
245
246
|
--color-logo-bg: color-mix(in srgb, var(--color-logo) 10%, var(--color-bg-surface));
|
|
246
247
|
--color-logo-fg: var(--color-fg-default);
|
|
247
248
|
|
|
249
|
+
/* Navbar */
|
|
250
|
+
--color-navbar-bg: var(--color-bg-surface);
|
|
251
|
+
--color-navbar-fg: var(--color-fg-default);
|
|
252
|
+
--color-navbar-fg-muted: var(--color-fg-muted);
|
|
253
|
+
--color-navbar-border: var(--color-border-default);
|
|
254
|
+
/* Active nav-link accent — deliberately its own token, not --color-logo:
|
|
255
|
+
the two happen to agree in some themes (filmstriben: both yellow) but
|
|
256
|
+
not others (dbc: logo is neutral fg-default, but the active link should
|
|
257
|
+
still read as brand-colored, not the same shade as inactive text) */
|
|
258
|
+
--color-navbar-brand: var(--color-brand);
|
|
259
|
+
|
|
248
260
|
/* Tables */
|
|
249
261
|
--table-header-bg: light-dark(#f3f4f6, #1b2533);
|
|
250
262
|
--table-row-bg: light-dark(#ffffff, #111827);
|