@fluid-app/rep-core 0.1.13 → 0.1.15
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/chunk-CKQMccvm.cjs +28 -0
- package/dist/data-sources/DataAwareWidget.cjs +47 -56
- package/dist/data-sources/DataAwareWidget.cjs.map +1 -1
- package/dist/data-sources/DataAwareWidget.d.cts +27 -19
- package/dist/data-sources/DataAwareWidget.d.cts.map +1 -0
- package/dist/data-sources/DataAwareWidget.d.mts +38 -0
- package/dist/data-sources/DataAwareWidget.d.mts.map +1 -0
- package/dist/data-sources/DataAwareWidget.mjs +48 -0
- package/dist/data-sources/DataAwareWidget.mjs.map +1 -0
- package/dist/data-sources/ErrorState.cjs +18 -10
- package/dist/data-sources/ErrorState.cjs.map +1 -1
- package/dist/data-sources/ErrorState.d.cts +5 -3
- package/dist/data-sources/ErrorState.d.cts.map +1 -0
- package/dist/data-sources/ErrorState.d.mts +7 -0
- package/dist/data-sources/ErrorState.d.mts.map +1 -0
- package/dist/data-sources/ErrorState.mjs +18 -0
- package/dist/data-sources/ErrorState.mjs.map +1 -0
- package/dist/data-sources/context.cjs +22 -14
- package/dist/data-sources/context.cjs.map +1 -1
- package/dist/data-sources/context.d.cts +16 -10
- package/dist/data-sources/context.d.cts.map +1 -0
- package/dist/data-sources/context.d.mts +22 -0
- package/dist/data-sources/context.d.mts.map +1 -0
- package/dist/data-sources/context.mjs +21 -0
- package/dist/data-sources/context.mjs.map +1 -0
- package/dist/data-sources/fetchers/api.cjs +63 -10
- package/dist/data-sources/fetchers/api.cjs.map +1 -1
- package/dist/data-sources/fetchers/api.d.cts +4 -2
- package/dist/data-sources/fetchers/api.d.cts.map +1 -0
- package/dist/data-sources/fetchers/api.d.mts +10 -0
- package/dist/data-sources/fetchers/api.d.mts.map +1 -0
- package/dist/data-sources/fetchers/api.mjs +64 -0
- package/dist/data-sources/fetchers/api.mjs.map +1 -0
- package/dist/data-sources/fetchers/custom.cjs +106 -10
- package/dist/data-sources/fetchers/custom.cjs.map +1 -1
- package/dist/data-sources/fetchers/custom.d.cts +4 -2
- package/dist/data-sources/fetchers/custom.d.cts.map +1 -0
- package/dist/data-sources/fetchers/{custom.d.ts → custom.d.mts} +4 -2
- package/dist/data-sources/fetchers/custom.d.mts.map +1 -0
- package/dist/data-sources/fetchers/custom.mjs +107 -0
- package/dist/data-sources/fetchers/custom.mjs.map +1 -0
- package/dist/data-sources/fetchers/static.cjs +159 -14
- package/dist/data-sources/fetchers/static.cjs.map +1 -1
- package/dist/data-sources/fetchers/static.d.cts +12 -10
- package/dist/data-sources/fetchers/static.d.cts.map +1 -0
- package/dist/data-sources/fetchers/{static.d.ts → static.d.mts} +12 -10
- package/dist/data-sources/fetchers/static.d.mts.map +1 -0
- package/dist/data-sources/fetchers/static.mjs +158 -0
- package/dist/data-sources/fetchers/static.mjs.map +1 -0
- package/dist/data-sources/preview-context.cjs +15 -15
- package/dist/data-sources/preview-context.cjs.map +1 -1
- package/dist/data-sources/preview-context.d.cts +10 -6
- package/dist/data-sources/preview-context.d.cts.map +1 -0
- package/dist/data-sources/preview-context.d.mts +15 -0
- package/dist/data-sources/preview-context.d.mts.map +1 -0
- package/dist/data-sources/preview-context.mjs +18 -0
- package/dist/data-sources/preview-context.mjs.map +1 -0
- package/dist/data-sources/registry-context.cjs +51 -24
- package/dist/data-sources/registry-context.cjs.map +1 -1
- package/dist/data-sources/registry-context.d.cts +30 -22
- package/dist/data-sources/registry-context.d.cts.map +1 -0
- package/dist/data-sources/registry-context.d.mts +49 -0
- package/dist/data-sources/registry-context.d.mts.map +1 -0
- package/dist/data-sources/registry-context.mjs +49 -0
- package/dist/data-sources/registry-context.mjs.map +1 -0
- package/dist/data-sources/registry.cjs +29 -18
- package/dist/data-sources/registry.cjs.map +1 -1
- package/dist/data-sources/registry.d.cts +9 -7
- package/dist/data-sources/registry.d.cts.map +1 -0
- package/dist/data-sources/registry.d.mts +19 -0
- package/dist/data-sources/registry.d.mts.map +1 -0
- package/dist/data-sources/registry.mjs +29 -0
- package/dist/data-sources/registry.mjs.map +1 -0
- package/dist/data-sources/transformers.cjs +152 -10
- package/dist/data-sources/transformers.cjs.map +1 -1
- package/dist/data-sources/transformers.d.cts +4 -17
- package/dist/data-sources/transformers.d.cts.map +1 -0
- package/dist/data-sources/transformers.d.mts +10 -0
- package/dist/data-sources/transformers.d.mts.map +1 -0
- package/dist/data-sources/transformers.mjs +153 -0
- package/dist/data-sources/transformers.mjs.map +1 -0
- package/dist/data-sources/types.cjs +0 -4
- package/dist/data-sources/types.d.cts +2 -157
- package/dist/data-sources/types.d.mts +2 -0
- package/dist/data-sources/types.mjs +1 -0
- package/dist/data-sources/use-widget-data.cjs +109 -17
- package/dist/data-sources/use-widget-data.cjs.map +1 -1
- package/dist/data-sources/use-widget-data.d.cts +9 -8
- package/dist/data-sources/use-widget-data.d.cts.map +1 -0
- package/dist/data-sources/use-widget-data.d.mts +17 -0
- package/dist/data-sources/use-widget-data.d.mts.map +1 -0
- package/dist/data-sources/use-widget-data.mjs +109 -0
- package/dist/data-sources/use-widget-data.mjs.map +1 -0
- package/dist/index-Bxe_LIi8.d.cts +287 -0
- package/dist/index-Bxe_LIi8.d.cts.map +1 -0
- package/dist/index-CCAu2n19.d.mts +287 -0
- package/dist/index-CCAu2n19.d.mts.map +1 -0
- package/dist/registries/index.cjs +212 -127
- package/dist/registries/index.cjs.map +1 -1
- package/dist/registries/index.d.cts +146 -149
- package/dist/registries/index.d.cts.map +1 -0
- package/dist/registries/{index.d.ts → index.d.mts} +146 -149
- package/dist/registries/index.d.mts.map +1 -0
- package/dist/registries/index.mjs +229 -0
- package/dist/registries/index.mjs.map +1 -0
- package/dist/shell/AppShellLayout.cjs +47 -12
- package/dist/shell/AppShellLayout.cjs.map +1 -1
- package/dist/shell/AppShellLayout.d.cts +29 -19
- package/dist/shell/AppShellLayout.d.cts.map +1 -0
- package/dist/shell/AppShellLayout.d.mts +40 -0
- package/dist/shell/AppShellLayout.d.mts.map +1 -0
- package/dist/shell/AppShellLayout.mjs +46 -0
- package/dist/{chunk-45BCVWQK.cjs.map → shell/AppShellLayout.mjs.map} +1 -1
- package/dist/shell/ScreenHeader.cjs +44 -0
- package/dist/shell/ScreenHeader.cjs.map +1 -0
- package/dist/shell/ScreenHeader.d.cts +12 -0
- package/dist/shell/ScreenHeader.d.cts.map +1 -0
- package/dist/shell/ScreenHeader.d.mts +12 -0
- package/dist/shell/ScreenHeader.d.mts.map +1 -0
- package/dist/shell/ScreenHeader.mjs +42 -0
- package/dist/shell/ScreenHeader.mjs.map +1 -0
- package/dist/shell/ScreenHeaderContext.cjs +91 -0
- package/dist/shell/ScreenHeaderContext.cjs.map +1 -0
- package/dist/shell/ScreenHeaderContext.d.cts +36 -0
- package/dist/shell/ScreenHeaderContext.d.cts.map +1 -0
- package/dist/shell/ScreenHeaderContext.d.mts +36 -0
- package/dist/shell/ScreenHeaderContext.d.mts.map +1 -0
- package/dist/shell/ScreenHeaderContext.mjs +86 -0
- package/dist/shell/ScreenHeaderContext.mjs.map +1 -0
- package/dist/shell/ThemeModeContext.cjs +68 -18
- package/dist/shell/ThemeModeContext.cjs.map +1 -1
- package/dist/shell/ThemeModeContext.d.cts +23 -16
- package/dist/shell/ThemeModeContext.d.cts.map +1 -0
- package/dist/shell/ThemeModeContext.d.mts +34 -0
- package/dist/shell/ThemeModeContext.d.mts.map +1 -0
- package/dist/shell/ThemeModeContext.mjs +66 -0
- package/dist/shell/ThemeModeContext.mjs.map +1 -0
- package/dist/shell/index.cjs +43 -205
- package/dist/shell/index.d.cts +7 -43
- package/dist/shell/index.d.mts +7 -0
- package/dist/shell/index.mjs +7 -0
- package/dist/shell/sidebar.cjs +372 -87
- package/dist/shell/sidebar.cjs.map +1 -1
- package/dist/shell/sidebar.d.cts +38 -36
- package/dist/shell/sidebar.d.cts.map +1 -0
- package/dist/shell/{sidebar.d.ts → sidebar.d.mts} +38 -36
- package/dist/shell/sidebar.d.mts.map +1 -0
- package/dist/shell/sidebar.mjs +364 -0
- package/dist/{chunk-PFDBULOI.cjs.map → shell/sidebar.mjs.map} +1 -1
- package/dist/shell/use-mobile.cjs +49 -18
- package/dist/shell/use-mobile.cjs.map +1 -1
- package/dist/shell/use-mobile.d.cts +3 -1
- package/dist/shell/use-mobile.d.cts.map +1 -0
- package/dist/shell/{use-mobile.d.ts → use-mobile.d.mts} +3 -1
- package/dist/shell/use-mobile.d.mts.map +1 -0
- package/dist/shell/use-mobile.mjs +47 -0
- package/dist/shell/use-mobile.mjs.map +1 -0
- package/dist/theme/index.cjs +662 -549
- package/dist/theme/index.cjs.map +1 -1
- package/dist/theme/index.d.cts +32 -32
- package/dist/theme/index.d.cts.map +1 -0
- package/dist/theme/{index.d.ts → index.d.mts} +32 -32
- package/dist/theme/index.d.mts.map +1 -0
- package/dist/theme/index.mjs +727 -0
- package/dist/theme/index.mjs.map +1 -0
- package/dist/types/index.cjs +18 -72
- package/dist/types/index.d.cts +4 -268
- package/dist/types/index.d.mts +4 -0
- package/dist/types/index.mjs +2 -0
- package/dist/types-BIXtQlHB.d.cts +155 -0
- package/dist/types-BIXtQlHB.d.cts.map +1 -0
- package/dist/types-BXFX9bXp.cjs +303 -0
- package/dist/types-BXFX9bXp.cjs.map +1 -0
- package/dist/types-Bjmd7Fdx.mjs +208 -0
- package/dist/types-Bjmd7Fdx.mjs.map +1 -0
- package/dist/types-ByG6Xy3C.d.mts +85 -0
- package/dist/types-ByG6Xy3C.d.mts.map +1 -0
- package/dist/types-C5OFJy-O.d.mts +155 -0
- package/dist/types-C5OFJy-O.d.mts.map +1 -0
- package/dist/types-Ctu-Zio6.d.cts +85 -0
- package/dist/types-Ctu-Zio6.d.cts.map +1 -0
- package/dist/{widget-schema-D-ca3--K.d.ts → widget-schema--PY1uMWx.d.cts} +38 -41
- package/dist/widget-schema--PY1uMWx.d.cts.map +1 -0
- package/dist/{widget-schema-DvJdg1-B.d.cts → widget-schema-YkD5p3v4.d.mts} +38 -41
- package/dist/widget-schema-YkD5p3v4.d.mts.map +1 -0
- package/dist/widget-utils/index.cjs +96 -89
- package/dist/widget-utils/index.cjs.map +1 -1
- package/dist/widget-utils/index.d.cts +8 -6
- package/dist/widget-utils/index.d.cts.map +1 -0
- package/dist/widget-utils/{index.d.ts → index.d.mts} +8 -6
- package/dist/widget-utils/index.d.mts.map +1 -0
- package/dist/widget-utils/index.mjs +119 -0
- package/dist/widget-utils/index.mjs.map +1 -0
- package/package.json +4 -4
- package/dist/chunk-2SPTFZRC.js +0 -72
- package/dist/chunk-2SPTFZRC.js.map +0 -1
- package/dist/chunk-3I5Y3PEO.js +0 -23
- package/dist/chunk-3I5Y3PEO.js.map +0 -1
- package/dist/chunk-3ZRE7GX6.js +0 -620
- package/dist/chunk-3ZRE7GX6.js.map +0 -1
- package/dist/chunk-45BCVWQK.cjs +0 -38
- package/dist/chunk-46PUWB7C.cjs +0 -69
- package/dist/chunk-46PUWB7C.cjs.map +0 -1
- package/dist/chunk-5NYM4UTW.cjs +0 -58
- package/dist/chunk-5NYM4UTW.cjs.map +0 -1
- package/dist/chunk-B2NTWEDF.cjs +0 -130
- package/dist/chunk-B2NTWEDF.cjs.map +0 -1
- package/dist/chunk-GDY76JA6.cjs +0 -153
- package/dist/chunk-GDY76JA6.cjs.map +0 -1
- package/dist/chunk-HGVSPZEL.cjs +0 -119
- package/dist/chunk-HGVSPZEL.cjs.map +0 -1
- package/dist/chunk-HIDJYVKJ.js +0 -54
- package/dist/chunk-HIDJYVKJ.js.map +0 -1
- package/dist/chunk-KTXGU7OP.cjs +0 -136
- package/dist/chunk-KTXGU7OP.cjs.map +0 -1
- package/dist/chunk-KW5E2H5T.js +0 -128
- package/dist/chunk-KW5E2H5T.js.map +0 -1
- package/dist/chunk-LBLHDGMT.js +0 -25
- package/dist/chunk-LBLHDGMT.js.map +0 -1
- package/dist/chunk-MNVDL4FX.js +0 -134
- package/dist/chunk-MNVDL4FX.js.map +0 -1
- package/dist/chunk-MOTOSPAO.cjs +0 -15
- package/dist/chunk-MOTOSPAO.cjs.map +0 -1
- package/dist/chunk-N2K6W7FX.cjs +0 -169
- package/dist/chunk-N2K6W7FX.cjs.map +0 -1
- package/dist/chunk-PFDBULOI.cjs +0 -665
- package/dist/chunk-PVTQWD4I.js +0 -166
- package/dist/chunk-PVTQWD4I.js.map +0 -1
- package/dist/chunk-SJQPHJL4.cjs +0 -26
- package/dist/chunk-SJQPHJL4.cjs.map +0 -1
- package/dist/chunk-TML66UEU.js +0 -13
- package/dist/chunk-TML66UEU.js.map +0 -1
- package/dist/chunk-U3CQLX2Z.cjs +0 -28
- package/dist/chunk-U3CQLX2Z.cjs.map +0 -1
- package/dist/chunk-UUNEVOA5.js +0 -36
- package/dist/chunk-UUNEVOA5.js.map +0 -1
- package/dist/chunk-VRF7QEID.js +0 -67
- package/dist/chunk-VRF7QEID.js.map +0 -1
- package/dist/chunk-VSZWXSQA.js +0 -38
- package/dist/chunk-VSZWXSQA.js.map +0 -1
- package/dist/chunk-WYOHFNNW.js +0 -117
- package/dist/chunk-WYOHFNNW.js.map +0 -1
- package/dist/chunk-YKF5ZFF5.js +0 -136
- package/dist/chunk-YKF5ZFF5.js.map +0 -1
- package/dist/chunk-YXJMBVXO.cjs +0 -76
- package/dist/chunk-YXJMBVXO.cjs.map +0 -1
- package/dist/chunk-ZA4AE7KF.cjs +0 -42
- package/dist/chunk-ZA4AE7KF.cjs.map +0 -1
- package/dist/data-sources/DataAwareWidget.d.ts +0 -30
- package/dist/data-sources/DataAwareWidget.js +0 -57
- package/dist/data-sources/DataAwareWidget.js.map +0 -1
- package/dist/data-sources/ErrorState.d.ts +0 -5
- package/dist/data-sources/ErrorState.js +0 -3
- package/dist/data-sources/ErrorState.js.map +0 -1
- package/dist/data-sources/context.d.ts +0 -16
- package/dist/data-sources/context.js +0 -3
- package/dist/data-sources/context.js.map +0 -1
- package/dist/data-sources/fetchers/api.d.ts +0 -8
- package/dist/data-sources/fetchers/api.js +0 -3
- package/dist/data-sources/fetchers/api.js.map +0 -1
- package/dist/data-sources/fetchers/custom.js +0 -3
- package/dist/data-sources/fetchers/custom.js.map +0 -1
- package/dist/data-sources/fetchers/static.js +0 -3
- package/dist/data-sources/fetchers/static.js.map +0 -1
- package/dist/data-sources/preview-context.d.ts +0 -11
- package/dist/data-sources/preview-context.js +0 -18
- package/dist/data-sources/preview-context.js.map +0 -1
- package/dist/data-sources/registry-context.d.ts +0 -41
- package/dist/data-sources/registry-context.js +0 -9
- package/dist/data-sources/registry-context.js.map +0 -1
- package/dist/data-sources/registry.d.ts +0 -17
- package/dist/data-sources/registry.js +0 -7
- package/dist/data-sources/registry.js.map +0 -1
- package/dist/data-sources/transformers.d.ts +0 -23
- package/dist/data-sources/transformers.js +0 -3
- package/dist/data-sources/transformers.js.map +0 -1
- package/dist/data-sources/types.cjs.map +0 -1
- package/dist/data-sources/types.d.ts +0 -157
- package/dist/data-sources/types.js +0 -3
- package/dist/data-sources/types.js.map +0 -1
- package/dist/data-sources/use-widget-data.d.ts +0 -16
- package/dist/data-sources/use-widget-data.js +0 -10
- package/dist/data-sources/use-widget-data.js.map +0 -1
- package/dist/registries/index.js +0 -144
- package/dist/registries/index.js.map +0 -1
- package/dist/shareable-item-DkgWpwoU.d.cts +0 -21
- package/dist/shareable-item-DkgWpwoU.d.ts +0 -21
- package/dist/shell/AppShellLayout.d.ts +0 -30
- package/dist/shell/AppShellLayout.js +0 -5
- package/dist/shell/AppShellLayout.js.map +0 -1
- package/dist/shell/ThemeModeContext.d.ts +0 -27
- package/dist/shell/ThemeModeContext.js +0 -3
- package/dist/shell/ThemeModeContext.js.map +0 -1
- package/dist/shell/index.cjs.map +0 -1
- package/dist/shell/index.d.ts +0 -43
- package/dist/shell/index.js +0 -76
- package/dist/shell/index.js.map +0 -1
- package/dist/shell/sidebar.js +0 -4
- package/dist/shell/sidebar.js.map +0 -1
- package/dist/shell/use-mobile.js +0 -3
- package/dist/shell/use-mobile.js.map +0 -1
- package/dist/theme/index.js +0 -611
- package/dist/theme/index.js.map +0 -1
- package/dist/types/index.cjs.map +0 -1
- package/dist/types/index.d.ts +0 -268
- package/dist/types/index.js +0 -3
- package/dist/types/index.js.map +0 -1
- package/dist/types-CNIhy4JD.d.cts +0 -83
- package/dist/types-CNIhy4JD.d.ts +0 -83
- package/dist/widget-utils/index.js +0 -111
- package/dist/widget-utils/index.js.map +0 -1
package/dist/theme/index.cjs
CHANGED
|
@@ -1,617 +1,730 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"foreground",
|
|
15
|
-
"primary",
|
|
16
|
-
"secondary",
|
|
17
|
-
"accent",
|
|
18
|
-
"muted",
|
|
19
|
-
"destructive"
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_chunk = require("../chunk-CKQMccvm.cjs");
|
|
3
|
+
let colorjs_io = require("colorjs.io");
|
|
4
|
+
colorjs_io = require_chunk.__toESM(colorjs_io);
|
|
5
|
+
//#region src/theme/types.ts
|
|
6
|
+
const SEMANTIC_COLOR_NAMES = [
|
|
7
|
+
"background",
|
|
8
|
+
"foreground",
|
|
9
|
+
"primary",
|
|
10
|
+
"secondary",
|
|
11
|
+
"accent",
|
|
12
|
+
"muted",
|
|
13
|
+
"destructive"
|
|
20
14
|
];
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
15
|
+
const SHADE_STEPS = [
|
|
16
|
+
100,
|
|
17
|
+
200,
|
|
18
|
+
300,
|
|
19
|
+
400,
|
|
20
|
+
500,
|
|
21
|
+
600,
|
|
22
|
+
700,
|
|
23
|
+
800,
|
|
24
|
+
900
|
|
31
25
|
];
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
26
|
+
const FONT_SIZE_KEYS = [
|
|
27
|
+
"extraSmall",
|
|
28
|
+
"small",
|
|
29
|
+
"regular",
|
|
30
|
+
"large",
|
|
31
|
+
"extraLarge",
|
|
32
|
+
"giant"
|
|
39
33
|
];
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
34
|
+
const FONT_FAMILY_KEYS = ["header", "body"];
|
|
35
|
+
const RADIUS_KEYS = [
|
|
36
|
+
"small",
|
|
37
|
+
"medium",
|
|
38
|
+
"large",
|
|
39
|
+
"extraLarge"
|
|
40
|
+
];
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region src/theme/color-engine.ts
|
|
43
|
+
/**
|
|
44
|
+
* Attempt to convert any string into a Color using colorjs.io.
|
|
45
|
+
* If the string is exactly 6 characters it is assumed to be a bare hex value
|
|
46
|
+
* (e.g. "3b82f6") and a "#" prefix is added before parsing.
|
|
47
|
+
*
|
|
48
|
+
* @returns the parsed Color, or a neutral gray (`oklch(0.5 0 0)`) on failure
|
|
49
|
+
*/
|
|
44
50
|
function parseColor(value) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
if (value.length === 6) value = `#${value}`;
|
|
52
|
+
try {
|
|
53
|
+
return new colorjs_io.default(value);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.warn("[theme] Failed to parse color:", value, error);
|
|
56
|
+
return new colorjs_io.default("oklch", [
|
|
57
|
+
.5,
|
|
58
|
+
0,
|
|
59
|
+
0
|
|
60
|
+
]);
|
|
61
|
+
}
|
|
54
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Returns either the original foreground or a corrected lightness variant,
|
|
65
|
+
* whichever provides better contrast against `color`.
|
|
66
|
+
* Inversion triggers when the APCA contrast is below 50.
|
|
67
|
+
*/
|
|
55
68
|
function getForegroundColor(foreground, color) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
foreground.oklch.c || 0,
|
|
64
|
-
foreground.oklch.h || 0
|
|
65
|
-
]);
|
|
66
|
-
}
|
|
67
|
-
return foreground;
|
|
69
|
+
if (foreground.oklch.l == null || color.oklch.l == null) return foreground;
|
|
70
|
+
if (color.contrastAPCA(foreground) < 50) return new colorjs_io.default("oklch", [
|
|
71
|
+
color.oklch.l < .7 ? .95 : .15,
|
|
72
|
+
foreground.oklch.c || 0,
|
|
73
|
+
foreground.oklch.h || 0
|
|
74
|
+
]);
|
|
75
|
+
return foreground;
|
|
68
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* Generate a 100–900 shade ramp from a base color.
|
|
79
|
+
* Base anchors at 500. Light shades (100–400) step toward white,
|
|
80
|
+
* dark shades (600–900) step toward black. Dark steps use an asymmetric
|
|
81
|
+
* multiplier (1.6×, 1.875×, 3×, 4× of `darkStep`) for a more gradual
|
|
82
|
+
* initial descent. Chroma is nudged per step for perceptually natural ramps.
|
|
83
|
+
*/
|
|
69
84
|
function generateShades(base) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
85
|
+
const l = base.oklch.l ?? 0;
|
|
86
|
+
const c = base.oklch.c ?? 0;
|
|
87
|
+
const h = base.oklch.h ?? 0;
|
|
88
|
+
const safeMax = l >= .885 ? .995 : .97;
|
|
89
|
+
const safeMin = l <= .33 ? 0 : .21;
|
|
90
|
+
const lightStep = (safeMax - l) / 5;
|
|
91
|
+
const darkStep = -(l - safeMin) / 8;
|
|
92
|
+
const shade = (lDelta, cDelta) => {
|
|
93
|
+
return new colorjs_io.default("oklch", [
|
|
94
|
+
Math.max(0, Math.min(1, l + lDelta)),
|
|
95
|
+
c <= .001 ? c : Math.max(0, c + cDelta),
|
|
96
|
+
h
|
|
97
|
+
]);
|
|
98
|
+
};
|
|
99
|
+
return {
|
|
100
|
+
100: shade(5 * lightStep, -.00375),
|
|
101
|
+
200: shade(4 * lightStep, -.00375),
|
|
102
|
+
300: shade(3 * lightStep, -.00375),
|
|
103
|
+
400: shade(2 * lightStep, -.00375),
|
|
104
|
+
500: new colorjs_io.default("oklch", [
|
|
105
|
+
l,
|
|
106
|
+
c,
|
|
107
|
+
h
|
|
108
|
+
]),
|
|
109
|
+
600: shade(1.6 * darkStep, .025),
|
|
110
|
+
700: shade(1.875 * 2 * darkStep, .05),
|
|
111
|
+
800: shade(6 * darkStep, .075),
|
|
112
|
+
900: shade(8 * darkStep, .1)
|
|
113
|
+
};
|
|
95
114
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
115
|
+
const DARK_DERIVATION_CONFIG = {
|
|
116
|
+
background: {
|
|
117
|
+
baseLightness: .15,
|
|
118
|
+
fgLightness: .93
|
|
119
|
+
},
|
|
120
|
+
foreground: {
|
|
121
|
+
baseLightness: .93,
|
|
122
|
+
fgLightness: .15
|
|
123
|
+
},
|
|
124
|
+
muted: {
|
|
125
|
+
baseLightness: .22,
|
|
126
|
+
fgLightness: .75
|
|
127
|
+
},
|
|
128
|
+
primary: {
|
|
129
|
+
baseLightness: "invert",
|
|
130
|
+
fgLightness: .95,
|
|
131
|
+
chromaScale: .9
|
|
132
|
+
},
|
|
133
|
+
secondary: {
|
|
134
|
+
baseLightness: "invert",
|
|
135
|
+
fgLightness: .93,
|
|
136
|
+
chromaScale: .85
|
|
137
|
+
},
|
|
138
|
+
accent: {
|
|
139
|
+
baseLightness: "invert",
|
|
140
|
+
fgLightness: .95,
|
|
141
|
+
chromaScale: .9
|
|
142
|
+
},
|
|
143
|
+
destructive: {
|
|
144
|
+
baseLightness: "invert",
|
|
145
|
+
fgLightness: .95,
|
|
146
|
+
chromaScale: .95
|
|
147
|
+
}
|
|
108
148
|
};
|
|
149
|
+
/** Invert OKLCH lightness (1 - l), clamped to [0.35, 0.75] to avoid extremes. */
|
|
109
150
|
function invertLightness(l) {
|
|
110
|
-
|
|
111
|
-
|
|
151
|
+
const inverted = 1 - l;
|
|
152
|
+
return Math.max(.35, Math.min(.75, inverted));
|
|
112
153
|
}
|
|
154
|
+
/**
|
|
155
|
+
* Derive a dark-mode ThemeColorInput from its light-mode counterpart.
|
|
156
|
+
*/
|
|
113
157
|
function deriveDarkVariant(name, light) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
158
|
+
const config = DARK_DERIVATION_CONFIG[name];
|
|
159
|
+
const chromaScale = config.chromaScale ?? 1;
|
|
160
|
+
const baseLightness = config.baseLightness === "invert" ? invertLightness(light.base.oklch.l ?? 0) : config.baseLightness;
|
|
161
|
+
const fgLightness = config.fgLightness === "invert" ? invertLightness(light.foreground.oklch.l ?? 0) : config.fgLightness;
|
|
162
|
+
return {
|
|
163
|
+
base: new colorjs_io.default("oklch", [
|
|
164
|
+
baseLightness,
|
|
165
|
+
(light.base.oklch.c || 0) * chromaScale,
|
|
166
|
+
light.base.oklch.h || 0
|
|
167
|
+
]),
|
|
168
|
+
foreground: new colorjs_io.default("oklch", [
|
|
169
|
+
fgLightness,
|
|
170
|
+
(light.foreground.oklch.c || 0) * chromaScale,
|
|
171
|
+
light.foreground.oklch.h || 0
|
|
172
|
+
])
|
|
173
|
+
};
|
|
130
174
|
}
|
|
175
|
+
/**
|
|
176
|
+
* Merge auto-derived dark colors with any user-specified overrides.
|
|
177
|
+
* For each semantic color, if the user has fully overridden both base and
|
|
178
|
+
* foreground those are used; otherwise the missing channels are derived.
|
|
179
|
+
*/
|
|
131
180
|
function mergeDarkOverrides(def) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
return darkColors;
|
|
181
|
+
const darkColors = {};
|
|
182
|
+
for (const name of SEMANTIC_COLOR_NAMES) {
|
|
183
|
+
const lightInput = def.light[name];
|
|
184
|
+
const darkOverride = def.dark[name];
|
|
185
|
+
if (darkOverride?.base && darkOverride?.foreground) darkColors[name] = darkOverride;
|
|
186
|
+
else if (darkOverride) {
|
|
187
|
+
const base = darkOverride.base ?? deriveDarkVariant(name, lightInput).base;
|
|
188
|
+
darkColors[name] = {
|
|
189
|
+
base,
|
|
190
|
+
foreground: darkOverride.foreground ?? getForegroundColor(def.light.foreground.base, base)
|
|
191
|
+
};
|
|
192
|
+
} else darkColors[name] = deriveDarkVariant(name, lightInput);
|
|
193
|
+
}
|
|
194
|
+
return darkColors;
|
|
149
195
|
}
|
|
150
196
|
function resolveColorSet(colors) {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
}
|
|
165
|
-
return resolved;
|
|
197
|
+
const resolved = {};
|
|
198
|
+
for (const name of SEMANTIC_COLOR_NAMES) {
|
|
199
|
+
const input = colors[name];
|
|
200
|
+
const shades = generateShades(input.base);
|
|
201
|
+
const resolvedShades = {};
|
|
202
|
+
for (const step of SHADE_STEPS) resolvedShades[step] = shades[step];
|
|
203
|
+
resolved[name] = {
|
|
204
|
+
base: input.base.clone(),
|
|
205
|
+
foreground: input.foreground.clone(),
|
|
206
|
+
shades: resolvedShades
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
return resolved;
|
|
166
210
|
}
|
|
211
|
+
/**
|
|
212
|
+
* Resolve a ThemeDefinition into a complete ResolvedTheme.
|
|
213
|
+
* Dark mode colors are derived from light where not overridden.
|
|
214
|
+
*/
|
|
167
215
|
function resolveTheme(def) {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
216
|
+
return {
|
|
217
|
+
id: def.id,
|
|
218
|
+
name: def.name,
|
|
219
|
+
light: resolveColorSet(def.light),
|
|
220
|
+
dark: resolveColorSet(mergeDarkOverrides(def)),
|
|
221
|
+
fontSizes: { ...def.fontSizes },
|
|
222
|
+
fontFamilies: { ...def.fontFamilies },
|
|
223
|
+
spacing: def.spacing,
|
|
224
|
+
radii: { ...def.radii }
|
|
225
|
+
};
|
|
178
226
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
227
|
+
//#endregion
|
|
228
|
+
//#region src/theme/tailwind-overrides.ts
|
|
229
|
+
/**
|
|
230
|
+
* Specific overrides, otherwise all the overrides are generated using emitTailwindOverrides
|
|
231
|
+
*/
|
|
232
|
+
const OVERRIDES = {
|
|
233
|
+
"--color-gray-50": "var(--color-muted)",
|
|
234
|
+
"--color-gray-100": "var(--color-muted-600)",
|
|
235
|
+
"--color-gray-200": "var(--color-border)"
|
|
185
236
|
};
|
|
237
|
+
/**
|
|
238
|
+
* Returns the inverted shade for dark mode foreground colors.
|
|
239
|
+
* In dark mode, light shades (50, 100) should map to dark values (950, 900) and vice versa.
|
|
240
|
+
*/
|
|
186
241
|
function getInvertedStep(shade) {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
return SHADE_STEPS[invertedIndex] || 500;
|
|
242
|
+
const shadeIndex = SHADE_STEPS.indexOf(shade);
|
|
243
|
+
return SHADE_STEPS[SHADE_STEPS.length - 1 - shadeIndex] || 500;
|
|
190
244
|
}
|
|
245
|
+
/**
|
|
246
|
+
* Map semantic colors to Tailwind built-in color names.
|
|
247
|
+
*/
|
|
191
248
|
function emitTailwindOverrides(darkMode = false) {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
lines.push("--color-white: var(--color-background);");
|
|
226
|
-
lines.push("--color-black: var(--color-foreground);");
|
|
227
|
-
return lines;
|
|
249
|
+
const TAILWIND_COLOR_MAP = {
|
|
250
|
+
gray: "foreground",
|
|
251
|
+
red: "destructive",
|
|
252
|
+
blue: "primary",
|
|
253
|
+
green: "accent"
|
|
254
|
+
};
|
|
255
|
+
const TAILWIND_SHADES = [
|
|
256
|
+
50,
|
|
257
|
+
100,
|
|
258
|
+
200,
|
|
259
|
+
300,
|
|
260
|
+
400,
|
|
261
|
+
500,
|
|
262
|
+
600,
|
|
263
|
+
700,
|
|
264
|
+
800,
|
|
265
|
+
900,
|
|
266
|
+
950
|
|
267
|
+
];
|
|
268
|
+
const SHADE_REMAP = {
|
|
269
|
+
50: 100,
|
|
270
|
+
950: 900
|
|
271
|
+
};
|
|
272
|
+
const lines = [];
|
|
273
|
+
for (const [twName, semantic] of Object.entries(TAILWIND_COLOR_MAP)) for (const shade of TAILWIND_SHADES) {
|
|
274
|
+
const step = SHADE_REMAP[shade] ?? shade;
|
|
275
|
+
const override = OVERRIDES[`--color-${twName}-${shade}`];
|
|
276
|
+
lines.push(`--color-${twName}-${shade}: ${override ? override : `var(--color-${semantic}-${semantic === "foreground" && darkMode === true ? getInvertedStep(step) : step})`};`);
|
|
277
|
+
}
|
|
278
|
+
lines.push("--color-white: var(--color-background);");
|
|
279
|
+
lines.push("--color-black: var(--color-foreground);");
|
|
280
|
+
return lines;
|
|
228
281
|
}
|
|
229
|
-
|
|
230
|
-
|
|
282
|
+
//#endregion
|
|
283
|
+
//#region src/theme/css-generator.ts
|
|
231
284
|
function colorToCSS(color) {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
return "oklch(0.5 0 0)";
|
|
239
|
-
}
|
|
240
|
-
return result;
|
|
285
|
+
const result = color.toString({ format: "oklch" });
|
|
286
|
+
if (result.includes("NaN")) {
|
|
287
|
+
console.warn("[theme] colorToCSS produced NaN, using neutral fallback:", result);
|
|
288
|
+
return "oklch(0.5 0 0)";
|
|
289
|
+
}
|
|
290
|
+
return result;
|
|
241
291
|
}
|
|
242
292
|
function camelToKebab(str) {
|
|
243
|
-
|
|
293
|
+
return str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
244
294
|
}
|
|
295
|
+
/**
|
|
296
|
+
* Emit --color-{name}, --color-{name}-foreground, --color-{name}-{shade} vars.
|
|
297
|
+
* Uses --color- prefix to match rep-widgets/tailwind.config.ts.
|
|
298
|
+
*/
|
|
245
299
|
function emitColorVars(colors) {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
}
|
|
255
|
-
return lines;
|
|
300
|
+
const lines = [];
|
|
301
|
+
for (const name of SEMANTIC_COLOR_NAMES) {
|
|
302
|
+
const color = colors[name];
|
|
303
|
+
lines.push(`--color-${name}: ${colorToCSS(color.base)};`);
|
|
304
|
+
lines.push(`--color-${name}-foreground: ${colorToCSS(color.foreground)};`);
|
|
305
|
+
for (const step of SHADE_STEPS) lines.push(`--color-${name}-${step}: ${colorToCSS(color.shades[step])};`);
|
|
306
|
+
}
|
|
307
|
+
return lines;
|
|
256
308
|
}
|
|
309
|
+
/**
|
|
310
|
+
* Emit non-color CSS variables (font sizes, families, spacing, radii).
|
|
311
|
+
*/
|
|
257
312
|
function emitNonColorVars(theme) {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
}
|
|
265
|
-
lines.push(`--spacing: ${theme.spacing};`);
|
|
266
|
-
for (const key of RADIUS_KEYS) {
|
|
267
|
-
lines.push(`--radius-${camelToKebab(key)}: ${theme.radii[key]};`);
|
|
268
|
-
}
|
|
269
|
-
return lines;
|
|
313
|
+
const lines = [];
|
|
314
|
+
for (const key of FONT_SIZE_KEYS) lines.push(`--font-size-${camelToKebab(key)}: ${theme.fontSizes[key]};`);
|
|
315
|
+
for (const key of FONT_FAMILY_KEYS) lines.push(`--font-${key}: ${theme.fontFamilies[key]};`);
|
|
316
|
+
lines.push(`--spacing: ${theme.spacing};`);
|
|
317
|
+
for (const key of RADIUS_KEYS) lines.push(`--radius-${camelToKebab(key)}: ${theme.radii[key]};`);
|
|
318
|
+
return lines;
|
|
270
319
|
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
320
|
+
/**
|
|
321
|
+
* Static CSS alias variables that bridge theme var names to Tailwind/component conventions.
|
|
322
|
+
* These are always emitted and not mode-dependent.
|
|
323
|
+
*/
|
|
324
|
+
const globalCSSOverride = [
|
|
325
|
+
"--color-background-foreground: var(--color-foreground);",
|
|
326
|
+
"--color-foreground-foreground: var(--color-background);",
|
|
327
|
+
...SEMANTIC_COLOR_NAMES.map((value) => `--${value}: var(--color-${value});`),
|
|
328
|
+
...SEMANTIC_COLOR_NAMES.map((value) => `--${value}-foreground: var(--color-${value}-foreground);`),
|
|
329
|
+
"--sidebar-ring: var(--color-primary);",
|
|
330
|
+
"--sidebar-border: var(--color-border);",
|
|
331
|
+
"--sidebar-accent-foreground: var(--color-accent-foreground);",
|
|
332
|
+
"--sidebar-accent: var(--color-accent);",
|
|
333
|
+
"--sidebar-primary-foreground: var(--color-primary-foreground);",
|
|
334
|
+
"--sidebar-primary: var(--color-primary);",
|
|
335
|
+
"--sidebar-foreground: var(--color-muted-foreground);",
|
|
336
|
+
"--sidebar: var(--color-muted);",
|
|
337
|
+
"--border: var(--color-background-600);",
|
|
338
|
+
"--ring: var(--color-primary);",
|
|
339
|
+
"--popover: var(--color-background);",
|
|
340
|
+
"--popover-foreground: var(--color-foreground);",
|
|
341
|
+
"--card: var(--color-muted);",
|
|
342
|
+
"--card-foreground: var(--color-muted-foreground);",
|
|
343
|
+
"--radius-sm: var(--radius-small);",
|
|
344
|
+
"--radius-md: var(--radius-medium);",
|
|
345
|
+
"--radius-lg: var(--radius-large);",
|
|
346
|
+
"--radius-xl: var(--radius-extra-large);",
|
|
347
|
+
"--text-xs: var(--font-size-extra-small);",
|
|
348
|
+
"--text-sm: var(--font-size-small);",
|
|
349
|
+
"--text-base: var(--font-size-regular);",
|
|
350
|
+
"--text-lg: var(--font-size-large);",
|
|
351
|
+
"--text-xl: var(--font-size-extra-large);",
|
|
352
|
+
"--text-2xl: var(--font-size-giant);",
|
|
353
|
+
"--font-sans: var(--font-body);",
|
|
354
|
+
"--font-mono: var(--font-header);"
|
|
305
355
|
];
|
|
306
|
-
|
|
356
|
+
/**
|
|
357
|
+
* Overrides for global tailwindcss for specifically dark mode.
|
|
358
|
+
*/
|
|
359
|
+
const globalDarkCSSOverride = ["--border: var(--color-background-400);"];
|
|
360
|
+
/**
|
|
361
|
+
* Generate a complete CSS string for a resolved theme.
|
|
362
|
+
* Outputs 2–3 blocks: light default, dark explicit via `[data-theme-mode="dark"]`,
|
|
363
|
+
* and (unless `disableAutoTheme`) a `prefers-color-scheme: dark` media query block.
|
|
364
|
+
*/
|
|
307
365
|
function generateThemeCSS(theme, options = {}) {
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
366
|
+
const sel = `[data-theme="${theme.id}"]`;
|
|
367
|
+
const tw = options.mapTailwindColors ?? true;
|
|
368
|
+
const blocks = [];
|
|
369
|
+
blocks.push(`${sel} {`);
|
|
370
|
+
blocks.push(...globalCSSOverride);
|
|
371
|
+
blocks.push(...emitNonColorVars(theme));
|
|
372
|
+
blocks.push(...emitColorVars(theme.light));
|
|
373
|
+
if (tw) blocks.push(...emitTailwindOverrides());
|
|
374
|
+
blocks.push(`}`);
|
|
375
|
+
blocks.push(`${sel}[data-theme-mode="dark"] {`);
|
|
376
|
+
blocks.push(...globalDarkCSSOverride);
|
|
377
|
+
blocks.push(...emitColorVars(theme.dark));
|
|
378
|
+
if (tw) blocks.push(...emitTailwindOverrides(true));
|
|
379
|
+
blocks.push(`}`);
|
|
380
|
+
if (!options.disableAutoTheme) {
|
|
381
|
+
blocks.push(`@media (prefers-color-scheme: dark) {`);
|
|
382
|
+
blocks.push(`${sel}:not([data-theme-mode]) {`);
|
|
383
|
+
blocks.push(...globalDarkCSSOverride);
|
|
384
|
+
blocks.push(...emitColorVars(theme.dark).map((l) => `${l}`));
|
|
385
|
+
if (tw) blocks.push(...emitTailwindOverrides(true).map((l) => `${l}`));
|
|
386
|
+
blocks.push(`}`);
|
|
387
|
+
blocks.push(`}`);
|
|
388
|
+
}
|
|
389
|
+
return blocks.join("\n");
|
|
332
390
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
391
|
+
//#endregion
|
|
392
|
+
//#region src/theme/defaults.ts
|
|
393
|
+
const DEFAULT_FONT_SIZES = {
|
|
394
|
+
extraSmall: "0.75rem",
|
|
395
|
+
small: "0.875rem",
|
|
396
|
+
regular: "1rem",
|
|
397
|
+
large: "1.125rem",
|
|
398
|
+
extraLarge: "1.25rem",
|
|
399
|
+
giant: "1.5rem"
|
|
340
400
|
};
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
401
|
+
const DEFAULT_FONT_FAMILIES = {
|
|
402
|
+
header: "var(--font-inter)",
|
|
403
|
+
body: "var(--font-inter)"
|
|
344
404
|
};
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
405
|
+
const DEFAULT_SPACING = "0.25rem";
|
|
406
|
+
const DEFAULT_RADII = {
|
|
407
|
+
small: "0.25rem",
|
|
408
|
+
medium: "0.5rem",
|
|
409
|
+
large: "0.75rem",
|
|
410
|
+
extraLarge: "1rem"
|
|
351
411
|
};
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
412
|
+
const DEFAULT_COLORS = {
|
|
413
|
+
background: "#ffffff",
|
|
414
|
+
foreground: "#1a1a1a",
|
|
415
|
+
primary: "#3b82f6",
|
|
416
|
+
secondary: "#6b7280",
|
|
417
|
+
accent: "#10b981",
|
|
418
|
+
muted: "#f3f4f6",
|
|
419
|
+
destructive: "#ef4444",
|
|
420
|
+
mutedForeground: "#6b7280"
|
|
361
421
|
};
|
|
362
|
-
|
|
363
|
-
|
|
422
|
+
const DEFAULT_THEME_ID = "default";
|
|
423
|
+
const DEFAULT_THEME_NAME = "Default Theme";
|
|
424
|
+
/**
|
|
425
|
+
* Build a fresh ThemeDefinition populated with all defaults.
|
|
426
|
+
* Returns a new object each call because Color instances are mutable — do not cache the result.
|
|
427
|
+
*/
|
|
364
428
|
function getDefaultThemeDefinition() {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
429
|
+
const bg = new colorjs_io.default(DEFAULT_COLORS.background);
|
|
430
|
+
const fg = new colorjs_io.default(DEFAULT_COLORS.foreground);
|
|
431
|
+
const primary = new colorjs_io.default(DEFAULT_COLORS.primary);
|
|
432
|
+
const secondary = new colorjs_io.default(DEFAULT_COLORS.secondary);
|
|
433
|
+
const accent = new colorjs_io.default(DEFAULT_COLORS.accent);
|
|
434
|
+
const muted = new colorjs_io.default(DEFAULT_COLORS.muted);
|
|
435
|
+
const destructive = new colorjs_io.default(DEFAULT_COLORS.destructive);
|
|
436
|
+
const mutedFg = new colorjs_io.default(DEFAULT_COLORS.mutedForeground);
|
|
437
|
+
const darkBg = new colorjs_io.default("#0a0a0a");
|
|
438
|
+
const darkFg = new colorjs_io.default("#fafafa");
|
|
439
|
+
const darkMuted = new colorjs_io.default("#171717");
|
|
440
|
+
const darkMutedForeground = new colorjs_io.default("#dddddd");
|
|
441
|
+
return {
|
|
442
|
+
id: DEFAULT_THEME_ID,
|
|
443
|
+
name: DEFAULT_THEME_NAME,
|
|
444
|
+
light: {
|
|
445
|
+
background: {
|
|
446
|
+
base: bg,
|
|
447
|
+
foreground: fg
|
|
448
|
+
},
|
|
449
|
+
foreground: {
|
|
450
|
+
base: fg,
|
|
451
|
+
foreground: bg
|
|
452
|
+
},
|
|
453
|
+
primary: {
|
|
454
|
+
base: primary,
|
|
455
|
+
foreground: getForegroundColor(fg, primary)
|
|
456
|
+
},
|
|
457
|
+
secondary: {
|
|
458
|
+
base: secondary,
|
|
459
|
+
foreground: getForegroundColor(fg, secondary)
|
|
460
|
+
},
|
|
461
|
+
accent: {
|
|
462
|
+
base: accent,
|
|
463
|
+
foreground: getForegroundColor(fg, accent)
|
|
464
|
+
},
|
|
465
|
+
muted: {
|
|
466
|
+
base: muted,
|
|
467
|
+
foreground: mutedFg
|
|
468
|
+
},
|
|
469
|
+
destructive: {
|
|
470
|
+
base: destructive,
|
|
471
|
+
foreground: getForegroundColor(fg, destructive)
|
|
472
|
+
}
|
|
473
|
+
},
|
|
474
|
+
dark: {
|
|
475
|
+
background: {
|
|
476
|
+
base: darkBg,
|
|
477
|
+
foreground: darkFg
|
|
478
|
+
},
|
|
479
|
+
foreground: {
|
|
480
|
+
base: darkFg,
|
|
481
|
+
foreground: darkBg
|
|
482
|
+
},
|
|
483
|
+
muted: {
|
|
484
|
+
base: darkMuted,
|
|
485
|
+
foreground: darkMutedForeground
|
|
486
|
+
}
|
|
487
|
+
},
|
|
488
|
+
fontSizes: { ...DEFAULT_FONT_SIZES },
|
|
489
|
+
fontFamilies: { ...DEFAULT_FONT_FAMILIES },
|
|
490
|
+
spacing: DEFAULT_SPACING,
|
|
491
|
+
radii: { ...DEFAULT_RADII }
|
|
492
|
+
};
|
|
411
493
|
}
|
|
412
|
-
|
|
413
|
-
|
|
494
|
+
//#endregion
|
|
495
|
+
//#region src/theme/serialisation.ts
|
|
414
496
|
function colorToPlain(color) {
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
497
|
+
return {
|
|
498
|
+
l: color.oklch.l ?? 0,
|
|
499
|
+
c: color.oklch.c ?? 0,
|
|
500
|
+
h: color.oklch.h ?? 0
|
|
501
|
+
};
|
|
420
502
|
}
|
|
421
503
|
function plainToColor(plain) {
|
|
422
|
-
|
|
504
|
+
return new colorjs_io.default("oklch", [
|
|
505
|
+
plain.l,
|
|
506
|
+
plain.c,
|
|
507
|
+
plain.h
|
|
508
|
+
]);
|
|
423
509
|
}
|
|
510
|
+
/**
|
|
511
|
+
* Serialise a ThemeDefinition (with Color objects) to a plain JSON payload
|
|
512
|
+
* suitable for backend storage.
|
|
513
|
+
*/
|
|
424
514
|
function serialiseTheme(def) {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
...def.syncWithBrandColors ? { syncWithBrandColors: true } : {}
|
|
450
|
-
};
|
|
515
|
+
const light = {};
|
|
516
|
+
for (const name of SEMANTIC_COLOR_NAMES) light[name] = {
|
|
517
|
+
base: colorToPlain(def.light[name].base),
|
|
518
|
+
foreground: colorToPlain(def.light[name].foreground)
|
|
519
|
+
};
|
|
520
|
+
const dark = {};
|
|
521
|
+
for (const [name, value] of Object.entries(def.dark)) {
|
|
522
|
+
if (!value) continue;
|
|
523
|
+
dark[name] = {
|
|
524
|
+
...value.base ? { base: colorToPlain(value.base) } : {},
|
|
525
|
+
...value.foreground ? { foreground: colorToPlain(value.foreground) } : {}
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
return {
|
|
529
|
+
id: def.id,
|
|
530
|
+
name: def.name,
|
|
531
|
+
light,
|
|
532
|
+
dark,
|
|
533
|
+
fontSizes: { ...def.fontSizes },
|
|
534
|
+
fontFamilies: { ...def.fontFamilies },
|
|
535
|
+
spacing: def.spacing,
|
|
536
|
+
radii: { ...def.radii },
|
|
537
|
+
...def.syncWithBrandColors ? { syncWithBrandColors: true } : {}
|
|
538
|
+
};
|
|
451
539
|
}
|
|
540
|
+
/**
|
|
541
|
+
* Deserialise a backend payload into a ThemeDefinition with Color objects.
|
|
542
|
+
* Accepts `Record<string, unknown>` because API data is untyped at the boundary.
|
|
543
|
+
* Falls back to default colors for any missing light-mode entries.
|
|
544
|
+
*/
|
|
452
545
|
function deserialiseTheme(payload) {
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
radii: payload.radii ?? DEFAULT_RADII,
|
|
488
|
-
...payload.syncWithBrandColors === true ? { syncWithBrandColors: true } : {}
|
|
489
|
-
};
|
|
546
|
+
const lightRaw = payload.light ?? {};
|
|
547
|
+
const darkRaw = payload.dark ?? {};
|
|
548
|
+
const defaults = getDefaultThemeDefinition();
|
|
549
|
+
const light = {};
|
|
550
|
+
for (const name of SEMANTIC_COLOR_NAMES) {
|
|
551
|
+
const entry = lightRaw[name];
|
|
552
|
+
if (entry) light[name] = {
|
|
553
|
+
base: plainToColor(entry.base),
|
|
554
|
+
foreground: plainToColor(entry.foreground)
|
|
555
|
+
};
|
|
556
|
+
else {
|
|
557
|
+
console.warn(`[theme] deserialiseTheme: missing light color "${name}", using default`);
|
|
558
|
+
light[name] = defaults.light[name];
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
const dark = {};
|
|
562
|
+
for (const [name, value] of Object.entries(darkRaw)) {
|
|
563
|
+
if (!value) continue;
|
|
564
|
+
dark[name] = {
|
|
565
|
+
...value.base ? { base: plainToColor(value.base) } : {},
|
|
566
|
+
...value.foreground ? { foreground: plainToColor(value.foreground) } : {}
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
return {
|
|
570
|
+
id: payload.id,
|
|
571
|
+
name: payload.name,
|
|
572
|
+
light,
|
|
573
|
+
dark,
|
|
574
|
+
fontSizes: payload.fontSizes ?? DEFAULT_FONT_SIZES,
|
|
575
|
+
fontFamilies: payload.fontFamilies ?? DEFAULT_FONT_FAMILIES,
|
|
576
|
+
spacing: payload.spacing ?? "0.25rem",
|
|
577
|
+
radii: payload.radii ?? DEFAULT_RADII,
|
|
578
|
+
...payload.syncWithBrandColors === true ? { syncWithBrandColors: true } : {}
|
|
579
|
+
};
|
|
490
580
|
}
|
|
491
|
-
|
|
492
|
-
|
|
581
|
+
//#endregion
|
|
582
|
+
//#region src/theme/transforms.ts
|
|
583
|
+
/**
|
|
584
|
+
* Check if a theme config uses the new structured format (has a `light` key
|
|
585
|
+
* that is an object) vs the legacy flat format.
|
|
586
|
+
*/
|
|
493
587
|
function isNewThemeFormat(config) {
|
|
494
|
-
|
|
588
|
+
return config.light != null && typeof config.light === "object";
|
|
495
589
|
}
|
|
590
|
+
/**
|
|
591
|
+
* Convert a legacy flat config to a ThemeDefinition.
|
|
592
|
+
* Legacy format: { base: "#fff", text: "#000", primary: "oklch(0.6 0.2 250)", ... }
|
|
593
|
+
*/
|
|
496
594
|
function legacyConfigToDefinition(id, name, config) {
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
595
|
+
const bg = parseColor(config.base ?? config.background ?? DEFAULT_COLORS.background);
|
|
596
|
+
const fg = parseColor(config.text ?? config.foreground ?? DEFAULT_COLORS.foreground);
|
|
597
|
+
const primary = parseColor(config.primary ?? DEFAULT_COLORS.primary);
|
|
598
|
+
const secondary = parseColor(config.secondary ?? DEFAULT_COLORS.secondary);
|
|
599
|
+
const accent = parseColor(config.accent ?? DEFAULT_COLORS.accent);
|
|
600
|
+
const muted = parseColor(config.muted ?? DEFAULT_COLORS.muted);
|
|
601
|
+
const destructive = parseColor(config.destructive ?? DEFAULT_COLORS.destructive);
|
|
602
|
+
const mutedFg = parseColor(config.mutedForeground ?? DEFAULT_COLORS.mutedForeground);
|
|
603
|
+
return {
|
|
604
|
+
id: String(id),
|
|
605
|
+
name,
|
|
606
|
+
light: {
|
|
607
|
+
background: {
|
|
608
|
+
base: bg,
|
|
609
|
+
foreground: fg
|
|
610
|
+
},
|
|
611
|
+
foreground: {
|
|
612
|
+
base: fg,
|
|
613
|
+
foreground: bg
|
|
614
|
+
},
|
|
615
|
+
primary: {
|
|
616
|
+
base: primary,
|
|
617
|
+
foreground: getForegroundColor(fg, primary)
|
|
618
|
+
},
|
|
619
|
+
secondary: {
|
|
620
|
+
base: secondary,
|
|
621
|
+
foreground: getForegroundColor(fg, secondary)
|
|
622
|
+
},
|
|
623
|
+
accent: {
|
|
624
|
+
base: accent,
|
|
625
|
+
foreground: getForegroundColor(fg, accent)
|
|
626
|
+
},
|
|
627
|
+
muted: {
|
|
628
|
+
base: muted,
|
|
629
|
+
foreground: mutedFg
|
|
630
|
+
},
|
|
631
|
+
destructive: {
|
|
632
|
+
base: destructive,
|
|
633
|
+
foreground: getForegroundColor(fg, destructive)
|
|
634
|
+
}
|
|
635
|
+
},
|
|
636
|
+
dark: {},
|
|
637
|
+
fontSizes: {
|
|
638
|
+
extraSmall: config.extraSmall ?? DEFAULT_FONT_SIZES.extraSmall,
|
|
639
|
+
small: config.small ?? DEFAULT_FONT_SIZES.small,
|
|
640
|
+
regular: config.regular ?? DEFAULT_FONT_SIZES.regular,
|
|
641
|
+
large: config.large ?? DEFAULT_FONT_SIZES.large,
|
|
642
|
+
extraLarge: config.extraLarge ?? DEFAULT_FONT_SIZES.extraLarge,
|
|
643
|
+
giant: config.giant ?? DEFAULT_FONT_SIZES.giant
|
|
644
|
+
},
|
|
645
|
+
fontFamilies: {
|
|
646
|
+
header: config.headerFont ?? DEFAULT_FONT_FAMILIES.header,
|
|
647
|
+
body: config.bodyFont ?? DEFAULT_FONT_FAMILIES.body
|
|
648
|
+
},
|
|
649
|
+
spacing: config.globalSpacing ?? "0.25rem",
|
|
650
|
+
radii: {
|
|
651
|
+
small: config.radiusSmall ?? DEFAULT_RADII.small,
|
|
652
|
+
medium: config.radiusMedium ?? DEFAULT_RADII.medium,
|
|
653
|
+
large: config.radiusLarge ?? DEFAULT_RADII.large,
|
|
654
|
+
extraLarge: config.radiusExtraLarge ?? DEFAULT_RADII.extraLarge
|
|
655
|
+
}
|
|
656
|
+
};
|
|
558
657
|
}
|
|
658
|
+
/**
|
|
659
|
+
* Build a ThemeDefinition from a single API theme object.
|
|
660
|
+
* Handles both new structured format and legacy flat format.
|
|
661
|
+
*/
|
|
559
662
|
function buildThemeDefinition(theme) {
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
}
|
|
568
|
-
return legacyConfigToDefinition(
|
|
569
|
-
theme.id,
|
|
570
|
-
theme.name ?? "Untitled Theme",
|
|
571
|
-
config
|
|
572
|
-
);
|
|
663
|
+
const config = theme.config ?? {};
|
|
664
|
+
if (isNewThemeFormat(config)) return deserialiseTheme({
|
|
665
|
+
...config,
|
|
666
|
+
id: String(theme.id),
|
|
667
|
+
name: theme.name ?? "Untitled Theme"
|
|
668
|
+
});
|
|
669
|
+
return legacyConfigToDefinition(theme.id, theme.name ?? "Untitled Theme", config);
|
|
573
670
|
}
|
|
671
|
+
/**
|
|
672
|
+
* Transform raw API themes to ThemeDefinition[].
|
|
673
|
+
* Catches and logs errors per theme (graceful degradation).
|
|
674
|
+
*/
|
|
574
675
|
function transformThemes(themes) {
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
676
|
+
return themes.flatMap((theme) => {
|
|
677
|
+
try {
|
|
678
|
+
return [buildThemeDefinition(theme)];
|
|
679
|
+
} catch (error) {
|
|
680
|
+
console.error(`[theme] Failed to build theme id=${theme.id}:`, error);
|
|
681
|
+
return [];
|
|
682
|
+
}
|
|
683
|
+
});
|
|
583
684
|
}
|
|
685
|
+
/**
|
|
686
|
+
* Get the active theme ID from a list of raw API themes.
|
|
687
|
+
* Falls back to the first theme if none is marked active.
|
|
688
|
+
*/
|
|
584
689
|
function getActiveThemeId(themes) {
|
|
585
|
-
|
|
586
|
-
|
|
690
|
+
const active = themes.find((t) => t.active) ?? themes[0];
|
|
691
|
+
return active ? String(active.id) : void 0;
|
|
587
692
|
}
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
693
|
+
//#endregion
|
|
694
|
+
//#region src/theme/theme-applicator.ts
|
|
695
|
+
const STYLE_PREFIX = "theme-style-";
|
|
696
|
+
/**
|
|
697
|
+
* Inject or update a `<style>` element in `<head>` for the given theme.
|
|
698
|
+
* The element ID is deterministic (`theme-style-{themeId}`) so repeated calls
|
|
699
|
+
* for the same theme are idempotent — the existing element is updated in place.
|
|
700
|
+
* No-op when `document` is unavailable (SSR).
|
|
701
|
+
*/
|
|
591
702
|
function applyTheme(theme, options) {
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
703
|
+
if (typeof document === "undefined") return;
|
|
704
|
+
try {
|
|
705
|
+
const styleId = `${STYLE_PREFIX}${theme.id}`;
|
|
706
|
+
let el = document.getElementById(styleId);
|
|
707
|
+
if (!el) {
|
|
708
|
+
el = document.createElement("style");
|
|
709
|
+
el.id = styleId;
|
|
710
|
+
document.head.appendChild(el);
|
|
711
|
+
}
|
|
712
|
+
el.textContent = generateThemeCSS(theme, options);
|
|
713
|
+
} catch (error) {
|
|
714
|
+
console.error(`[theme] applyTheme failed for "${theme.id}":`, error);
|
|
715
|
+
}
|
|
605
716
|
}
|
|
717
|
+
/** Remove an injected theme stylesheet. No-op during SSR. */
|
|
606
718
|
function removeTheme(themeId) {
|
|
607
|
-
|
|
608
|
-
|
|
719
|
+
if (typeof document === "undefined") return;
|
|
720
|
+
document.getElementById(`${STYLE_PREFIX}${themeId}`)?.remove();
|
|
609
721
|
}
|
|
722
|
+
/** Remove all injected theme stylesheets. No-op during SSR. */
|
|
610
723
|
function removeAllThemes() {
|
|
611
|
-
|
|
612
|
-
|
|
724
|
+
if (typeof document === "undefined") return;
|
|
725
|
+
document.querySelectorAll(`style[id^="${STYLE_PREFIX}"]`).forEach((el) => el.remove());
|
|
613
726
|
}
|
|
614
|
-
|
|
727
|
+
//#endregion
|
|
615
728
|
exports.DEFAULT_COLORS = DEFAULT_COLORS;
|
|
616
729
|
exports.DEFAULT_FONT_FAMILIES = DEFAULT_FONT_FAMILIES;
|
|
617
730
|
exports.DEFAULT_FONT_SIZES = DEFAULT_FONT_SIZES;
|
|
@@ -640,5 +753,5 @@ exports.removeTheme = removeTheme;
|
|
|
640
753
|
exports.resolveTheme = resolveTheme;
|
|
641
754
|
exports.serialiseTheme = serialiseTheme;
|
|
642
755
|
exports.transformThemes = transformThemes;
|
|
643
|
-
|
|
756
|
+
|
|
644
757
|
//# sourceMappingURL=index.cjs.map
|