@memberjunction/react-runtime 5.48.0 → 5.50.0
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/.turbo/turbo-build.log +14 -14
- package/CHANGELOG.md +45 -0
- package/dist/324.runtime.umd.js +45 -39
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/runtime.umd.js +6879 -4351
- package/dist/utilities/component-library-theming.d.ts +6 -0
- package/dist/utilities/component-library-theming.d.ts.map +1 -0
- package/dist/utilities/component-library-theming.js +84 -0
- package/dist/utilities/component-library-theming.js.map +1 -0
- package/dist/utilities/component-styles.d.ts +1 -0
- package/dist/utilities/component-styles.d.ts.map +1 -1
- package/dist/utilities/component-styles.js +61 -1
- package/dist/utilities/component-styles.js.map +1 -1
- package/dist/utilities/index.d.ts +1 -0
- package/dist/utilities/index.d.ts.map +1 -1
- package/dist/utilities/index.js +1 -0
- package/dist/utilities/index.js.map +1 -1
- package/package.json +6 -6
- package/src/index.ts +8 -2
- package/src/utilities/component-library-theming.ts +127 -0
- package/src/utilities/component-styles.ts +103 -4
- package/src/utilities/index.ts +1 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ComponentStyles } from '@memberjunction/interactive-component-types';
|
|
2
|
+
export declare function buildAntdThemeConfig(styles: Partial<ComponentStyles> | undefined, antdLib: unknown): Record<string, unknown>;
|
|
3
|
+
export declare function wrapWithLibraryThemeProviders(React: {
|
|
4
|
+
createElement: (type: unknown, props: unknown, ...children: unknown[]) => unknown;
|
|
5
|
+
}, element: unknown, libraries: Record<string, unknown> | undefined, styles: Partial<ComponentStyles> | undefined): unknown;
|
|
6
|
+
//# sourceMappingURL=component-library-theming.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-library-theming.d.ts","sourceRoot":"","sources":["../../src/utilities/component-library-theming.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAuC9E,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,SAAS,EAC5C,OAAO,EAAE,OAAO,GACf,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAgCzB;AAcD,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE;IAAE,aAAa,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,QAAQ,EAAE,OAAO,EAAE,KAAK,OAAO,CAAA;CAAE,EAC5F,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC9C,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,SAAS,GAC3C,OAAO,CAaT"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { unwrapLibraryComponent } from './component-unwrapper.js';
|
|
2
|
+
function colorLuminance(color) {
|
|
3
|
+
if (!color)
|
|
4
|
+
return 1;
|
|
5
|
+
const s = String(color).trim();
|
|
6
|
+
let r, g, b;
|
|
7
|
+
const hex = /^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.exec(s);
|
|
8
|
+
if (hex) {
|
|
9
|
+
let h = hex[1];
|
|
10
|
+
if (h.length === 3)
|
|
11
|
+
h = h.split('').map((c) => c + c).join('');
|
|
12
|
+
const n = parseInt(h, 16);
|
|
13
|
+
r = (n >> 16) & 255;
|
|
14
|
+
g = (n >> 8) & 255;
|
|
15
|
+
b = n & 255;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
const m = /rgba?\(([^)]+)\)/i.exec(s);
|
|
19
|
+
if (!m)
|
|
20
|
+
return 1;
|
|
21
|
+
const p = m[1].split(',').map((x) => parseFloat(x));
|
|
22
|
+
r = p[0];
|
|
23
|
+
g = p[1];
|
|
24
|
+
b = p[2];
|
|
25
|
+
if ([r, g, b].some((v) => Number.isNaN(v)))
|
|
26
|
+
return 1;
|
|
27
|
+
}
|
|
28
|
+
return (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255;
|
|
29
|
+
}
|
|
30
|
+
function radiusToNumber(radius) {
|
|
31
|
+
const raw = typeof radius === 'string' ? radius : (radius && (radius.md || radius.sm || radius.lg));
|
|
32
|
+
if (!raw)
|
|
33
|
+
return undefined;
|
|
34
|
+
const n = parseInt(String(raw), 10);
|
|
35
|
+
return Number.isNaN(n) ? undefined : n;
|
|
36
|
+
}
|
|
37
|
+
export function buildAntdThemeConfig(styles, antdLib) {
|
|
38
|
+
const colors = (styles?.colors || {});
|
|
39
|
+
const themeNS = antdLib ? unwrapLibraryComponent(antdLib, 'theme') : undefined;
|
|
40
|
+
const isDark = colorLuminance(colors['background']) < 0.5;
|
|
41
|
+
const token = {
|
|
42
|
+
colorPrimary: colors['primary'],
|
|
43
|
+
colorInfo: colors['info'] || colors['primary'],
|
|
44
|
+
colorSuccess: colors['success'],
|
|
45
|
+
colorWarning: colors['warning'],
|
|
46
|
+
colorError: colors['error'],
|
|
47
|
+
colorBgContainer: colors['surface'],
|
|
48
|
+
colorBgElevated: colors['surface'],
|
|
49
|
+
colorBgLayout: colors['background'],
|
|
50
|
+
colorText: colors['text'],
|
|
51
|
+
colorTextSecondary: colors['textSecondary'],
|
|
52
|
+
colorBorder: colors['border'],
|
|
53
|
+
colorBorderSecondary: colors['borderLight'] || colors['border'],
|
|
54
|
+
fontFamily: styles?.typography?.fontFamily,
|
|
55
|
+
};
|
|
56
|
+
const radius = radiusToNumber(styles?.borders?.radius);
|
|
57
|
+
if (radius !== undefined)
|
|
58
|
+
token['borderRadius'] = radius;
|
|
59
|
+
for (const k of Object.keys(token)) {
|
|
60
|
+
if (token[k] == null)
|
|
61
|
+
delete token[k];
|
|
62
|
+
}
|
|
63
|
+
const config = { token };
|
|
64
|
+
const algorithm = themeNS && (isDark ? themeNS.darkAlgorithm : themeNS.defaultAlgorithm);
|
|
65
|
+
if (algorithm) {
|
|
66
|
+
config['algorithm'] = algorithm;
|
|
67
|
+
}
|
|
68
|
+
return config;
|
|
69
|
+
}
|
|
70
|
+
export function wrapWithLibraryThemeProviders(React, element, libraries, styles) {
|
|
71
|
+
const antdLib = libraries?.['antd'];
|
|
72
|
+
if (!antdLib)
|
|
73
|
+
return element;
|
|
74
|
+
const ConfigProvider = unwrapLibraryComponent(antdLib, 'ConfigProvider');
|
|
75
|
+
if (!ConfigProvider)
|
|
76
|
+
return element;
|
|
77
|
+
try {
|
|
78
|
+
return React.createElement(ConfigProvider, { theme: buildAntdThemeConfig(styles, antdLib) }, element);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return element;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=component-library-theming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-library-theming.js","sourceRoot":"","sources":["../../src/utilities/component-library-theming.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Auto-themes component libraries (Ant Design) from the MJ theme so\n * their built-in components inherit light/dark just like custom `styles.*` elements\n * do. Library components (antd `Table`, `Input`, `Select`, …) do not read `styles.*`\n * on their own — without their theme provider they render in the library's built-in\n * LIGHT theme even when the host is in dark mode. The host wraps the mounted React\n * tree once, and the provider's context flows to every library component below.\n *\n * TYPE-SAFETY NOTE (`unknown` usage): React and antd reach this module as UMD\n * globals loaded at runtime by the library loader — there are no compile-time\n * types for them in this package, and adding @types deps for runtime-loaded UMD\n * bundles would lie about the actual contract. `unknown` here is the narrow,\n * honest boundary type for those module surfaces (mirroring the existing\n * `unwrapLibraryComponent`); every access is funneled through the unwrapper or\n * an explicit shape check rather than blind property access. Do NOT widen these\n * to `any` — and do not treat this as precedent outside runtime-loaded UMD\n * boundaries (see the no-`any`/`unknown` rule in the root CLAUDE.md).\n * @module @memberjunction/react-runtime/utilities\n */\n\nimport { ComponentStyles } from '@memberjunction/interactive-component-types';\nimport { unwrapLibraryComponent } from './component-unwrapper';\n\n/** Relative luminance (0 = black, 1 = white) of a hex or rgb()/rgba() color; 1 if unparseable. */\nfunction colorLuminance(color: string | undefined): number {\n if (!color) return 1;\n const s = String(color).trim();\n let r: number, g: number, b: number;\n const hex = /^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.exec(s);\n if (hex) {\n let h = hex[1];\n if (h.length === 3) h = h.split('').map((c) => c + c).join('');\n const n = parseInt(h, 16);\n r = (n >> 16) & 255; g = (n >> 8) & 255; b = n & 255;\n } else {\n const m = /rgba?\\(([^)]+)\\)/i.exec(s);\n if (!m) return 1;\n const p = m[1].split(',').map((x) => parseFloat(x));\n r = p[0]; g = p[1]; b = p[2];\n if ([r, g, b].some((v) => Number.isNaN(v))) return 1;\n }\n return (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255;\n}\n\n/** Parse a radius token (e.g. '8px' or a size map) into a number for antd's borderRadius. */\nfunction radiusToNumber(radius: ComponentStyles['borders']['radius'] | undefined): number | undefined {\n const raw = typeof radius === 'string' ? radius : (radius && (radius.md || radius.sm || radius.lg));\n if (!raw) return undefined;\n const n = parseInt(String(raw), 10);\n return Number.isNaN(n) ? undefined : n;\n}\n\n/**\n * Builds an Ant Design v5 `ConfigProvider` `theme` config from ComponentStyles:\n * maps the MJ color/typography tokens onto antd seed/map tokens and selects antd's\n * dark algorithm when the theme's background is dark. `antdLib` is the loaded antd\n * module (used only to read its `theme` algorithm namespace). Unmapped tokens are\n * omitted so antd falls back to its own defaults.\n */\nexport function buildAntdThemeConfig(\n styles: Partial<ComponentStyles> | undefined,\n antdLib: unknown,\n): Record<string, unknown> {\n const colors = (styles?.colors || {}) as Record<string, string | undefined>;\n const themeNS = antdLib ? unwrapLibraryComponent(antdLib, 'theme') : undefined;\n const isDark = colorLuminance(colors['background']) < 0.5;\n\n const token: Record<string, unknown> = {\n colorPrimary: colors['primary'],\n colorInfo: colors['info'] || colors['primary'],\n colorSuccess: colors['success'],\n colorWarning: colors['warning'],\n colorError: colors['error'],\n colorBgContainer: colors['surface'],\n colorBgElevated: colors['surface'],\n colorBgLayout: colors['background'],\n colorText: colors['text'],\n colorTextSecondary: colors['textSecondary'],\n colorBorder: colors['border'],\n colorBorderSecondary: colors['borderLight'] || colors['border'],\n fontFamily: styles?.typography?.fontFamily,\n };\n const radius = radiusToNumber(styles?.borders?.radius);\n if (radius !== undefined) token['borderRadius'] = radius;\n for (const k of Object.keys(token)) {\n if (token[k] == null) delete token[k];\n }\n\n const config: Record<string, unknown> = { token };\n const algorithm = themeNS && (isDark ? themeNS.darkAlgorithm : themeNS.defaultAlgorithm);\n if (algorithm) {\n config['algorithm'] = algorithm;\n }\n return config;\n}\n\n/**\n * Wraps a React element in loaded component libraries' theme providers so their\n * built-in components inherit the MJ theme (including dark mode). Currently themes\n * Ant Design via `ConfigProvider` when the `antd` library is loaded; otherwise\n * returns the element unchanged. Because `ConfigProvider` supplies React context,\n * one wrap at the root themes every antd component in the subtree — including those\n * inside child components. `libraries` is keyed by global-variable name (e.g. `antd`).\n *\n * A generated component that also wraps its own `ConfigProvider` simply nests under\n * this one (antd merges nested configs), so this is safe alongside component-level\n * theming.\n */\nexport function wrapWithLibraryThemeProviders(\n React: { createElement: (type: unknown, props: unknown, ...children: unknown[]) => unknown },\n element: unknown,\n libraries: Record<string, unknown> | undefined,\n styles: Partial<ComponentStyles> | undefined,\n): unknown {\n const antdLib = libraries?.['antd'];\n if (!antdLib) return element;\n\n const ConfigProvider = unwrapLibraryComponent(antdLib, 'ConfigProvider');\n if (!ConfigProvider) return element;\n\n try {\n return React.createElement(ConfigProvider, { theme: buildAntdThemeConfig(styles, antdLib) }, element);\n } catch {\n // Never let theming wrap break rendering — fall back to the unwrapped element.\n return element;\n }\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ComponentStyles } from '@memberjunction/interactive-component-types';
|
|
2
2
|
export declare function SetupStyles(): ComponentStyles;
|
|
3
3
|
export declare const createDefaultComponentStyles: typeof SetupStyles;
|
|
4
|
+
export declare function BuildStylesFromTheme(root?: Element): ComponentStyles;
|
|
4
5
|
//# sourceMappingURL=component-styles.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component-styles.d.ts","sourceRoot":"","sources":["../../src/utilities/component-styles.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAO9E,wBAAgB,WAAW,IAAI,eAAe,
|
|
1
|
+
{"version":3,"file":"component-styles.d.ts","sourceRoot":"","sources":["../../src/utilities/component-styles.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAO9E,wBAAgB,WAAW,IAAI,eAAe,CAoH7C;AAGD,eAAO,MAAM,4BAA4B,oBAAc,CAAC;AA0DxD,wBAAgB,oBAAoB,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,eAAe,CA8BpE"}
|
|
@@ -3,6 +3,7 @@ export function SetupStyles() {
|
|
|
3
3
|
colors: {
|
|
4
4
|
primary: '#5B4FE9',
|
|
5
5
|
primaryHover: '#4940D4',
|
|
6
|
+
primaryActive: '#3E37B8',
|
|
6
7
|
primaryLight: '#E8E6FF',
|
|
7
8
|
secondary: '#64748B',
|
|
8
9
|
secondaryHover: '#475569',
|
|
@@ -21,6 +22,8 @@ export function SetupStyles() {
|
|
|
21
22
|
textSecondary: '#64748B',
|
|
22
23
|
textTertiary: '#94A3B8',
|
|
23
24
|
textInverse: '#FFFFFF',
|
|
25
|
+
link: '#5B4FE9',
|
|
26
|
+
linkHover: '#4940D4',
|
|
24
27
|
border: '#E2E8F0',
|
|
25
28
|
borderLight: '#F1F5F9',
|
|
26
29
|
borderFocus: '#5B4FE9',
|
|
@@ -87,8 +90,65 @@ export function SetupStyles() {
|
|
|
87
90
|
normal: '250ms ease-in-out',
|
|
88
91
|
slow: '350ms ease-in-out',
|
|
89
92
|
},
|
|
90
|
-
overflow: 'auto'
|
|
93
|
+
overflow: 'auto',
|
|
94
|
+
chartPalette: [
|
|
95
|
+
'#2196F3', '#4CAF50', '#FF9800', '#E91E63', '#9C27B0',
|
|
96
|
+
'#00BCD4', '#F44336', '#8BC34A', '#FF5722', '#3F51B5',
|
|
97
|
+
],
|
|
91
98
|
};
|
|
92
99
|
}
|
|
93
100
|
export const createDefaultComponentStyles = SetupStyles;
|
|
101
|
+
const THEME_COLOR_TOKEN_MAP = {
|
|
102
|
+
primary: '--mj-brand-primary',
|
|
103
|
+
primaryHover: '--mj-brand-primary-hover',
|
|
104
|
+
primaryActive: '--mj-brand-primary-active',
|
|
105
|
+
primaryLight: '--mj-brand-primary-light',
|
|
106
|
+
success: '--mj-status-success',
|
|
107
|
+
successLight: '--mj-status-success-bg',
|
|
108
|
+
warning: '--mj-status-warning',
|
|
109
|
+
warningLight: '--mj-status-warning-bg',
|
|
110
|
+
error: '--mj-status-error',
|
|
111
|
+
errorLight: '--mj-status-error-bg',
|
|
112
|
+
info: '--mj-status-info',
|
|
113
|
+
infoLight: '--mj-status-info-bg',
|
|
114
|
+
background: '--mj-bg-page',
|
|
115
|
+
surface: '--mj-bg-surface',
|
|
116
|
+
surfaceHover: '--mj-bg-surface-hover',
|
|
117
|
+
text: '--mj-text-primary',
|
|
118
|
+
textSecondary: '--mj-text-secondary',
|
|
119
|
+
textTertiary: '--mj-text-muted',
|
|
120
|
+
textInverse: '--mj-text-inverse',
|
|
121
|
+
link: '--mj-text-link',
|
|
122
|
+
linkHover: '--mj-text-link-hover',
|
|
123
|
+
border: '--mj-border-default',
|
|
124
|
+
borderLight: '--mj-border-subtle',
|
|
125
|
+
borderFocus: '--mj-border-focus',
|
|
126
|
+
};
|
|
127
|
+
const VIZ_TOKEN_COUNT = 10;
|
|
128
|
+
export function BuildStylesFromTheme(root) {
|
|
129
|
+
const base = SetupStyles();
|
|
130
|
+
const el = root ?? (typeof document !== 'undefined' ? document.documentElement : undefined);
|
|
131
|
+
if (!el || typeof getComputedStyle === 'undefined') {
|
|
132
|
+
return base;
|
|
133
|
+
}
|
|
134
|
+
const cs = getComputedStyle(el);
|
|
135
|
+
const read = (token) => cs.getPropertyValue(token).trim();
|
|
136
|
+
for (const [path, token] of Object.entries(THEME_COLOR_TOKEN_MAP)) {
|
|
137
|
+
const value = read(token);
|
|
138
|
+
if (value) {
|
|
139
|
+
base.colors[path] = value;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const palette = [];
|
|
143
|
+
for (let i = 1; i <= VIZ_TOKEN_COUNT; i++) {
|
|
144
|
+
const value = read(`--mj-viz-${i}`);
|
|
145
|
+
if (value) {
|
|
146
|
+
palette.push(value);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (palette.length > 0) {
|
|
150
|
+
base.chartPalette = palette;
|
|
151
|
+
}
|
|
152
|
+
return base;
|
|
153
|
+
}
|
|
94
154
|
//# sourceMappingURL=component-styles.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component-styles.js","sourceRoot":"","sources":["../../src/utilities/component-styles.ts"],"names":[],"mappings":"AAYA,MAAM,UAAU,WAAW;IAEzB,OAAO;QACL,MAAM,EAAE;YAEN,OAAO,EAAE,SAAS;YAClB,YAAY,EAAE,SAAS;YACvB,YAAY,EAAE,SAAS;YAGvB,SAAS,EAAE,SAAS;YACpB,cAAc,EAAE,SAAS;YAGzB,OAAO,EAAE,SAAS;YAClB,YAAY,EAAE,SAAS;YACvB,OAAO,EAAE,SAAS;YAClB,YAAY,EAAE,SAAS;YACvB,KAAK,EAAE,SAAS;YAChB,UAAU,EAAE,SAAS;YACrB,IAAI,EAAE,SAAS;YACf,SAAS,EAAE,SAAS;YAGpB,UAAU,EAAE,SAAS;YACrB,OAAO,EAAE,SAAS;YAClB,YAAY,EAAE,SAAS;YAGvB,IAAI,EAAE,SAAS;YACf,aAAa,EAAE,SAAS;YACxB,YAAY,EAAE,SAAS;YACvB,WAAW,EAAE,SAAS;YAGtB,MAAM,EAAE,SAAS;YACjB,WAAW,EAAE,SAAS;YACtB,WAAW,EAAE,SAAS;YAGtB,MAAM,EAAE,qBAAqB;YAC7B,YAAY,EAAE,oBAAoB;YAClC,WAAW,EAAE,qBAAqB;SACnC;QACD,OAAO,EAAE;YACP,EAAE,EAAE,KAAK;YACT,EAAE,EAAE,KAAK;YACT,EAAE,EAAE,MAAM;YACV,EAAE,EAAE,MAAM;YACV,EAAE,EAAE,MAAM;YACV,GAAG,EAAE,MAAM;YACX,IAAI,EAAE,MAAM;SACb;QACD,UAAU,EAAE;YACV,UAAU,EAAE,4EAA4E;YACxF,QAAQ,EAAE;gBACR,EAAE,EAAE,MAAM;gBACV,EAAE,EAAE,MAAM;gBACV,EAAE,EAAE,MAAM;gBACV,EAAE,EAAE,MAAM;gBACV,EAAE,EAAE,MAAM;gBACV,GAAG,EAAE,MAAM;gBACX,IAAI,EAAE,MAAM;aACb;YACD,UAAU,EAAE;gBACV,KAAK,EAAE,KAAK;gBACZ,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,KAAK;gBACb,QAAQ,EAAE,KAAK;gBACf,IAAI,EAAE,KAAK;aACZ;YACD,UAAU,EAAE;gBACV,KAAK,EAAE,MAAM;gBACb,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE,MAAM;aAChB;SACF;QACD,OAAO,EAAE;YACP,MAAM,EAAE;gBACN,EAAE,EAAE,KAAK;gBACT,EAAE,EAAE,KAAK;gBACT,EAAE,EAAE,MAAM;gBACV,EAAE,EAAE,MAAM;gBACV,IAAI,EAAE,QAAQ;aACf;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,KAAK;gBACX,MAAM,EAAE,KAAK;gBACb,KAAK,EAAE,KAAK;aACb;SACF;QACD,OAAO,EAAE;YACP,EAAE,EAAE,iCAAiC;YACrC,EAAE,EAAE,uEAAuE;YAC3E,EAAE,EAAE,yEAAyE;YAC7E,EAAE,EAAE,2EAA2E;YAC/E,KAAK,EAAE,uCAAuC;SAC/C;QACD,WAAW,EAAE;YACX,IAAI,EAAE,mBAAmB;YACzB,MAAM,EAAE,mBAAmB;YAC3B,IAAI,EAAE,mBAAmB;SAC1B;QACD,QAAQ,EAAE,MAAM;KACjB,CAAA;AACH,CAAC;AAGD,MAAM,CAAC,MAAM,4BAA4B,GAAG,WAAW,CAAC","sourcesContent":["/**\n * @fileoverview Default component styles for React runtime\n * @module @memberjunction/react-runtime/utilities\n */\n\nimport { ComponentStyles } from '@memberjunction/interactive-component-types';\n\n/**\n * Creates the default component styles for Skip components\n * These provide a modern, contemporary look and feel\n * Copied from skip-chat implementation\n */\nexport function SetupStyles(): ComponentStyles {\n // Return modern, contemporary styles for generated components\n return {\n colors: {\n // Primary colors - modern purple/blue gradient feel\n primary: '#5B4FE9',\n primaryHover: '#4940D4',\n primaryLight: '#E8E6FF',\n \n // Secondary colors - sophisticated gray\n secondary: '#64748B',\n secondaryHover: '#475569',\n \n // Status colors\n success: '#10B981',\n successLight: '#D1FAE5',\n warning: '#F59E0B',\n warningLight: '#FEF3C7',\n error: '#EF4444',\n errorLight: '#FEE2E2',\n info: '#3B82F6',\n infoLight: '#DBEAFE',\n \n // Base colors\n background: '#FFFFFF',\n surface: '#F8FAFC',\n surfaceHover: '#F1F5F9',\n \n // Text colors with better contrast\n text: '#1E293B',\n textSecondary: '#64748B',\n textTertiary: '#94A3B8',\n textInverse: '#FFFFFF',\n \n // Border colors\n border: '#E2E8F0',\n borderLight: '#F1F5F9',\n borderFocus: '#5B4FE9',\n \n // Shadows (as color strings for easy use)\n shadow: 'rgba(0, 0, 0, 0.05)',\n shadowMedium: 'rgba(0, 0, 0, 0.1)',\n shadowLarge: 'rgba(0, 0, 0, 0.15)',\n },\n spacing: {\n xs: '4px',\n sm: '8px',\n md: '16px',\n lg: '24px',\n xl: '32px',\n xxl: '48px',\n xxxl: '64px',\n },\n typography: {\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Inter\", \"Segoe UI\", Roboto, sans-serif',\n fontSize: {\n xs: '11px',\n sm: '12px',\n md: '14px',\n lg: '16px',\n xl: '20px',\n xxl: '24px',\n xxxl: '32px',\n },\n fontWeight: {\n light: '300',\n regular: '400',\n medium: '500',\n semibold: '600',\n bold: '700',\n },\n lineHeight: {\n tight: '1.25',\n normal: '1.5',\n relaxed: '1.75',\n },\n },\n borders: {\n radius: {\n sm: '6px',\n md: '8px',\n lg: '12px',\n xl: '16px',\n full: '9999px',\n },\n width: {\n thin: '1px',\n medium: '2px',\n thick: '3px',\n },\n },\n shadows: {\n sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',\n md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',\n lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',\n xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',\n inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)',\n },\n transitions: {\n fast: '150ms ease-in-out',\n normal: '250ms ease-in-out',\n slow: '350ms ease-in-out',\n },\n overflow: 'auto' // Default overflow style \n }\n}\n\n// Also export with the original name for backward compatibility\nexport const createDefaultComponentStyles = SetupStyles;"]}
|
|
1
|
+
{"version":3,"file":"component-styles.js","sourceRoot":"","sources":["../../src/utilities/component-styles.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Default component styles for React runtime\n * @module @memberjunction/react-runtime/utilities\n */\n\nimport { ComponentStyles } from '@memberjunction/interactive-component-types';\n\n/**\n * Creates the default component styles for Skip components\n * These provide a modern, contemporary look and feel\n * Copied from skip-chat implementation\n */\nexport function SetupStyles(): ComponentStyles {\n // Return modern, contemporary styles for generated components\n return {\n colors: {\n // Primary colors - modern purple/blue gradient feel\n primary: '#5B4FE9',\n primaryHover: '#4940D4',\n primaryActive: '#3E37B8',\n primaryLight: '#E8E6FF',\n\n // Secondary colors - sophisticated gray\n secondary: '#64748B',\n secondaryHover: '#475569',\n \n // Status colors\n success: '#10B981',\n successLight: '#D1FAE5',\n warning: '#F59E0B',\n warningLight: '#FEF3C7',\n error: '#EF4444',\n errorLight: '#FEE2E2',\n info: '#3B82F6',\n infoLight: '#DBEAFE',\n \n // Base colors\n background: '#FFFFFF',\n surface: '#F8FAFC',\n surfaceHover: '#F1F5F9',\n \n // Text colors with better contrast\n text: '#1E293B',\n textSecondary: '#64748B',\n textTertiary: '#94A3B8',\n textInverse: '#FFFFFF',\n\n // Link colors\n link: '#5B4FE9',\n linkHover: '#4940D4',\n\n // Border colors\n border: '#E2E8F0',\n borderLight: '#F1F5F9',\n borderFocus: '#5B4FE9',\n \n // Shadows (as color strings for easy use)\n shadow: 'rgba(0, 0, 0, 0.05)',\n shadowMedium: 'rgba(0, 0, 0, 0.1)',\n shadowLarge: 'rgba(0, 0, 0, 0.15)',\n },\n spacing: {\n xs: '4px',\n sm: '8px',\n md: '16px',\n lg: '24px',\n xl: '32px',\n xxl: '48px',\n xxxl: '64px',\n },\n typography: {\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Inter\", \"Segoe UI\", Roboto, sans-serif',\n fontSize: {\n xs: '11px',\n sm: '12px',\n md: '14px',\n lg: '16px',\n xl: '20px',\n xxl: '24px',\n xxxl: '32px',\n },\n fontWeight: {\n light: '300',\n regular: '400',\n medium: '500',\n semibold: '600',\n bold: '700',\n },\n lineHeight: {\n tight: '1.25',\n normal: '1.5',\n relaxed: '1.75',\n },\n },\n borders: {\n radius: {\n sm: '6px',\n md: '8px',\n lg: '12px',\n xl: '16px',\n full: '9999px',\n },\n width: {\n thin: '1px',\n medium: '2px',\n thick: '3px',\n },\n },\n shadows: {\n sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',\n md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',\n lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',\n xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',\n inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)',\n },\n transitions: {\n fast: '150ms ease-in-out',\n normal: '250ms ease-in-out',\n slow: '350ms ease-in-out',\n },\n overflow: 'auto', // Default overflow style\n // Default categorical palette for multi-series charts. Overridden per-theme\n // from the host's `--mj-viz-*` tokens by BuildStylesFromTheme().\n chartPalette: [\n '#2196F3', '#4CAF50', '#FF9800', '#E91E63', '#9C27B0',\n '#00BCD4', '#F44336', '#8BC34A', '#FF5722', '#3F51B5',\n ],\n }\n}\n\n// Also export with the original name for backward compatibility\nexport const createDefaultComponentStyles = SetupStyles;\n\n/**\n * The `--mj-*` semantic token → `ComponentStyles` mapping used by the theme bridge.\n * Keys are ComponentStyles color paths; values are the CSS custom property to read.\n * Only theme-defining tokens with a clear semantic equivalent are mapped; every\n * other field keeps its `SetupStyles()` default.\n */\nconst THEME_COLOR_TOKEN_MAP: Record<string, string> = {\n // Brand / primary + interactive states\n primary: '--mj-brand-primary',\n primaryHover: '--mj-brand-primary-hover',\n primaryActive: '--mj-brand-primary-active',\n primaryLight: '--mj-brand-primary-light',\n // Status\n success: '--mj-status-success',\n successLight: '--mj-status-success-bg',\n warning: '--mj-status-warning',\n warningLight: '--mj-status-warning-bg',\n error: '--mj-status-error',\n errorLight: '--mj-status-error-bg',\n info: '--mj-status-info',\n infoLight: '--mj-status-info-bg',\n // Surfaces (MJ: page = tinted, surface = elevated/white in light mode)\n background: '--mj-bg-page',\n surface: '--mj-bg-surface',\n surfaceHover: '--mj-bg-surface-hover',\n // Text\n text: '--mj-text-primary',\n textSecondary: '--mj-text-secondary',\n textTertiary: '--mj-text-muted',\n textInverse: '--mj-text-inverse',\n // Links\n link: '--mj-text-link',\n linkHover: '--mj-text-link-hover',\n // Borders / focus\n border: '--mj-border-default',\n borderLight: '--mj-border-subtle',\n borderFocus: '--mj-border-focus',\n};\n\n/** Number of `--mj-viz-N` categorical tokens the bridge probes for `chartPalette`. */\nconst VIZ_TOKEN_COUNT = 10;\n\n/**\n * Reads the live MJ theme (`--mj-*` custom properties on the document root) and\n * layers it over `SetupStyles()`, producing a `ComponentStyles` that follows the\n * host's active theme — including dark mode and interactive-state (hover/active/\n * focus) families — instead of the frozen default palette. This is the Phase 1\n * theme bridge that gives generated components shell↔content cohesion.\n *\n * DOM-guarded: in non-DOM environments (Node test harness, SSR) there is no\n * computed theme to read, so it returns `SetupStyles()` unchanged. Any individual\n * token that is absent falls back to its `SetupStyles()` default, so a page\n * without MJ tokens loaded also degrades cleanly.\n *\n * @param root optional element to read tokens from (defaults to document root).\n */\nexport function BuildStylesFromTheme(root?: Element): ComponentStyles {\n const base = SetupStyles();\n\n const el = root ?? (typeof document !== 'undefined' ? document.documentElement : undefined);\n if (!el || typeof getComputedStyle === 'undefined') {\n return base;\n }\n\n const cs = getComputedStyle(el);\n const read = (token: string): string => cs.getPropertyValue(token).trim();\n\n for (const [path, token] of Object.entries(THEME_COLOR_TOKEN_MAP)) {\n const value = read(token);\n if (value) {\n base.colors[path] = value;\n }\n }\n\n const palette: string[] = [];\n for (let i = 1; i <= VIZ_TOKEN_COUNT; i++) {\n const value = read(`--mj-viz-${i}`);\n if (value) {\n palette.push(value);\n }\n }\n if (palette.length > 0) {\n base.chartPalette = palette;\n }\n\n return base;\n}"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utilities/index.ts"],"names":[],"mappings":"AAKA,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utilities/index.ts"],"names":[],"mappings":"AAKA,cAAc,oBAAoB,CAAC;AACnC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC"}
|
package/dist/utilities/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utilities/index.ts"],"names":[],"mappings":"AAKA,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC","sourcesContent":["/**\n * @fileoverview Utilities module exports\n * @module @memberjunction/react-runtime/utilities\n */\n\nexport * from './component-styles';\nexport * from './standard-libraries';\nexport * from './library-loader';\nexport * from './library-registry';\nexport * from './library-dependency-resolver';\nexport * from './component-error-analyzer';\nexport * from './resource-manager';\nexport * from './cache-manager';\nexport * from './component-unwrapper';"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utilities/index.ts"],"names":[],"mappings":"AAKA,cAAc,oBAAoB,CAAC;AACnC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC","sourcesContent":["/**\n * @fileoverview Utilities module exports\n * @module @memberjunction/react-runtime/utilities\n */\n\nexport * from './component-styles';\nexport * from './component-library-theming';\nexport * from './standard-libraries';\nexport * from './library-loader';\nexport * from './library-registry';\nexport * from './library-dependency-resolver';\nexport * from './component-error-analyzer';\nexport * from './resource-manager';\nexport * from './cache-manager';\nexport * from './component-unwrapper';"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/react-runtime",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.50.0",
|
|
4
4
|
"description": "Platform-agnostic React component runtime for MemberJunction. Provides core compilation, registry, and execution capabilities for React components in any JavaScript environment.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
},
|
|
30
30
|
"homepage": "https://github.com/MemberJunction/MJ#readme",
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@memberjunction/core": "5.
|
|
33
|
-
"@memberjunction/global": "5.
|
|
34
|
-
"@memberjunction/interactive-component-types": "5.
|
|
35
|
-
"@memberjunction/core-entities": "5.
|
|
36
|
-
"@memberjunction/graphql-dataprovider": "5.
|
|
32
|
+
"@memberjunction/core": "5.50.0",
|
|
33
|
+
"@memberjunction/global": "5.50.0",
|
|
34
|
+
"@memberjunction/interactive-component-types": "5.50.0",
|
|
35
|
+
"@memberjunction/core-entities": "5.50.0",
|
|
36
|
+
"@memberjunction/graphql-dataprovider": "5.50.0",
|
|
37
37
|
"@babel/standalone": "^7.29.1",
|
|
38
38
|
"rxjs": "^7.8.2"
|
|
39
39
|
},
|
package/src/index.ts
CHANGED
|
@@ -86,11 +86,17 @@ export {
|
|
|
86
86
|
|
|
87
87
|
// Export utilities
|
|
88
88
|
|
|
89
|
-
export {
|
|
89
|
+
export {
|
|
90
90
|
SetupStyles,
|
|
91
|
-
createDefaultComponentStyles
|
|
91
|
+
createDefaultComponentStyles,
|
|
92
|
+
BuildStylesFromTheme
|
|
92
93
|
} from './utilities/component-styles';
|
|
93
94
|
|
|
95
|
+
export {
|
|
96
|
+
buildAntdThemeConfig,
|
|
97
|
+
wrapWithLibraryThemeProviders
|
|
98
|
+
} from './utilities/component-library-theming';
|
|
99
|
+
|
|
94
100
|
export {
|
|
95
101
|
StandardLibraries,
|
|
96
102
|
StandardLibraryManager,
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Auto-themes component libraries (Ant Design) from the MJ theme so
|
|
3
|
+
* their built-in components inherit light/dark just like custom `styles.*` elements
|
|
4
|
+
* do. Library components (antd `Table`, `Input`, `Select`, …) do not read `styles.*`
|
|
5
|
+
* on their own — without their theme provider they render in the library's built-in
|
|
6
|
+
* LIGHT theme even when the host is in dark mode. The host wraps the mounted React
|
|
7
|
+
* tree once, and the provider's context flows to every library component below.
|
|
8
|
+
*
|
|
9
|
+
* TYPE-SAFETY NOTE (`unknown` usage): React and antd reach this module as UMD
|
|
10
|
+
* globals loaded at runtime by the library loader — there are no compile-time
|
|
11
|
+
* types for them in this package, and adding @types deps for runtime-loaded UMD
|
|
12
|
+
* bundles would lie about the actual contract. `unknown` here is the narrow,
|
|
13
|
+
* honest boundary type for those module surfaces (mirroring the existing
|
|
14
|
+
* `unwrapLibraryComponent`); every access is funneled through the unwrapper or
|
|
15
|
+
* an explicit shape check rather than blind property access. Do NOT widen these
|
|
16
|
+
* to `any` — and do not treat this as precedent outside runtime-loaded UMD
|
|
17
|
+
* boundaries (see the no-`any`/`unknown` rule in the root CLAUDE.md).
|
|
18
|
+
* @module @memberjunction/react-runtime/utilities
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { ComponentStyles } from '@memberjunction/interactive-component-types';
|
|
22
|
+
import { unwrapLibraryComponent } from './component-unwrapper';
|
|
23
|
+
|
|
24
|
+
/** Relative luminance (0 = black, 1 = white) of a hex or rgb()/rgba() color; 1 if unparseable. */
|
|
25
|
+
function colorLuminance(color: string | undefined): number {
|
|
26
|
+
if (!color) return 1;
|
|
27
|
+
const s = String(color).trim();
|
|
28
|
+
let r: number, g: number, b: number;
|
|
29
|
+
const hex = /^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.exec(s);
|
|
30
|
+
if (hex) {
|
|
31
|
+
let h = hex[1];
|
|
32
|
+
if (h.length === 3) h = h.split('').map((c) => c + c).join('');
|
|
33
|
+
const n = parseInt(h, 16);
|
|
34
|
+
r = (n >> 16) & 255; g = (n >> 8) & 255; b = n & 255;
|
|
35
|
+
} else {
|
|
36
|
+
const m = /rgba?\(([^)]+)\)/i.exec(s);
|
|
37
|
+
if (!m) return 1;
|
|
38
|
+
const p = m[1].split(',').map((x) => parseFloat(x));
|
|
39
|
+
r = p[0]; g = p[1]; b = p[2];
|
|
40
|
+
if ([r, g, b].some((v) => Number.isNaN(v))) return 1;
|
|
41
|
+
}
|
|
42
|
+
return (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Parse a radius token (e.g. '8px' or a size map) into a number for antd's borderRadius. */
|
|
46
|
+
function radiusToNumber(radius: ComponentStyles['borders']['radius'] | undefined): number | undefined {
|
|
47
|
+
const raw = typeof radius === 'string' ? radius : (radius && (radius.md || radius.sm || radius.lg));
|
|
48
|
+
if (!raw) return undefined;
|
|
49
|
+
const n = parseInt(String(raw), 10);
|
|
50
|
+
return Number.isNaN(n) ? undefined : n;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Builds an Ant Design v5 `ConfigProvider` `theme` config from ComponentStyles:
|
|
55
|
+
* maps the MJ color/typography tokens onto antd seed/map tokens and selects antd's
|
|
56
|
+
* dark algorithm when the theme's background is dark. `antdLib` is the loaded antd
|
|
57
|
+
* module (used only to read its `theme` algorithm namespace). Unmapped tokens are
|
|
58
|
+
* omitted so antd falls back to its own defaults.
|
|
59
|
+
*/
|
|
60
|
+
export function buildAntdThemeConfig(
|
|
61
|
+
styles: Partial<ComponentStyles> | undefined,
|
|
62
|
+
antdLib: unknown,
|
|
63
|
+
): Record<string, unknown> {
|
|
64
|
+
const colors = (styles?.colors || {}) as Record<string, string | undefined>;
|
|
65
|
+
const themeNS = antdLib ? unwrapLibraryComponent(antdLib, 'theme') : undefined;
|
|
66
|
+
const isDark = colorLuminance(colors['background']) < 0.5;
|
|
67
|
+
|
|
68
|
+
const token: Record<string, unknown> = {
|
|
69
|
+
colorPrimary: colors['primary'],
|
|
70
|
+
colorInfo: colors['info'] || colors['primary'],
|
|
71
|
+
colorSuccess: colors['success'],
|
|
72
|
+
colorWarning: colors['warning'],
|
|
73
|
+
colorError: colors['error'],
|
|
74
|
+
colorBgContainer: colors['surface'],
|
|
75
|
+
colorBgElevated: colors['surface'],
|
|
76
|
+
colorBgLayout: colors['background'],
|
|
77
|
+
colorText: colors['text'],
|
|
78
|
+
colorTextSecondary: colors['textSecondary'],
|
|
79
|
+
colorBorder: colors['border'],
|
|
80
|
+
colorBorderSecondary: colors['borderLight'] || colors['border'],
|
|
81
|
+
fontFamily: styles?.typography?.fontFamily,
|
|
82
|
+
};
|
|
83
|
+
const radius = radiusToNumber(styles?.borders?.radius);
|
|
84
|
+
if (radius !== undefined) token['borderRadius'] = radius;
|
|
85
|
+
for (const k of Object.keys(token)) {
|
|
86
|
+
if (token[k] == null) delete token[k];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const config: Record<string, unknown> = { token };
|
|
90
|
+
const algorithm = themeNS && (isDark ? themeNS.darkAlgorithm : themeNS.defaultAlgorithm);
|
|
91
|
+
if (algorithm) {
|
|
92
|
+
config['algorithm'] = algorithm;
|
|
93
|
+
}
|
|
94
|
+
return config;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Wraps a React element in loaded component libraries' theme providers so their
|
|
99
|
+
* built-in components inherit the MJ theme (including dark mode). Currently themes
|
|
100
|
+
* Ant Design via `ConfigProvider` when the `antd` library is loaded; otherwise
|
|
101
|
+
* returns the element unchanged. Because `ConfigProvider` supplies React context,
|
|
102
|
+
* one wrap at the root themes every antd component in the subtree — including those
|
|
103
|
+
* inside child components. `libraries` is keyed by global-variable name (e.g. `antd`).
|
|
104
|
+
*
|
|
105
|
+
* A generated component that also wraps its own `ConfigProvider` simply nests under
|
|
106
|
+
* this one (antd merges nested configs), so this is safe alongside component-level
|
|
107
|
+
* theming.
|
|
108
|
+
*/
|
|
109
|
+
export function wrapWithLibraryThemeProviders(
|
|
110
|
+
React: { createElement: (type: unknown, props: unknown, ...children: unknown[]) => unknown },
|
|
111
|
+
element: unknown,
|
|
112
|
+
libraries: Record<string, unknown> | undefined,
|
|
113
|
+
styles: Partial<ComponentStyles> | undefined,
|
|
114
|
+
): unknown {
|
|
115
|
+
const antdLib = libraries?.['antd'];
|
|
116
|
+
if (!antdLib) return element;
|
|
117
|
+
|
|
118
|
+
const ConfigProvider = unwrapLibraryComponent(antdLib, 'ConfigProvider');
|
|
119
|
+
if (!ConfigProvider) return element;
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
return React.createElement(ConfigProvider, { theme: buildAntdThemeConfig(styles, antdLib) }, element);
|
|
123
|
+
} catch {
|
|
124
|
+
// Never let theming wrap break rendering — fall back to the unwrapped element.
|
|
125
|
+
return element;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -17,8 +17,9 @@ export function SetupStyles(): ComponentStyles {
|
|
|
17
17
|
// Primary colors - modern purple/blue gradient feel
|
|
18
18
|
primary: '#5B4FE9',
|
|
19
19
|
primaryHover: '#4940D4',
|
|
20
|
+
primaryActive: '#3E37B8',
|
|
20
21
|
primaryLight: '#E8E6FF',
|
|
21
|
-
|
|
22
|
+
|
|
22
23
|
// Secondary colors - sophisticated gray
|
|
23
24
|
secondary: '#64748B',
|
|
24
25
|
secondaryHover: '#475569',
|
|
@@ -43,7 +44,11 @@ export function SetupStyles(): ComponentStyles {
|
|
|
43
44
|
textSecondary: '#64748B',
|
|
44
45
|
textTertiary: '#94A3B8',
|
|
45
46
|
textInverse: '#FFFFFF',
|
|
46
|
-
|
|
47
|
+
|
|
48
|
+
// Link colors
|
|
49
|
+
link: '#5B4FE9',
|
|
50
|
+
linkHover: '#4940D4',
|
|
51
|
+
|
|
47
52
|
// Border colors
|
|
48
53
|
border: '#E2E8F0',
|
|
49
54
|
borderLight: '#F1F5F9',
|
|
@@ -113,9 +118,103 @@ export function SetupStyles(): ComponentStyles {
|
|
|
113
118
|
normal: '250ms ease-in-out',
|
|
114
119
|
slow: '350ms ease-in-out',
|
|
115
120
|
},
|
|
116
|
-
overflow: 'auto' // Default overflow style
|
|
121
|
+
overflow: 'auto', // Default overflow style
|
|
122
|
+
// Default categorical palette for multi-series charts. Overridden per-theme
|
|
123
|
+
// from the host's `--mj-viz-*` tokens by BuildStylesFromTheme().
|
|
124
|
+
chartPalette: [
|
|
125
|
+
'#2196F3', '#4CAF50', '#FF9800', '#E91E63', '#9C27B0',
|
|
126
|
+
'#00BCD4', '#F44336', '#8BC34A', '#FF5722', '#3F51B5',
|
|
127
|
+
],
|
|
117
128
|
}
|
|
118
129
|
}
|
|
119
130
|
|
|
120
131
|
// Also export with the original name for backward compatibility
|
|
121
|
-
export const createDefaultComponentStyles = SetupStyles;
|
|
132
|
+
export const createDefaultComponentStyles = SetupStyles;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* The `--mj-*` semantic token → `ComponentStyles` mapping used by the theme bridge.
|
|
136
|
+
* Keys are ComponentStyles color paths; values are the CSS custom property to read.
|
|
137
|
+
* Only theme-defining tokens with a clear semantic equivalent are mapped; every
|
|
138
|
+
* other field keeps its `SetupStyles()` default.
|
|
139
|
+
*/
|
|
140
|
+
const THEME_COLOR_TOKEN_MAP: Record<string, string> = {
|
|
141
|
+
// Brand / primary + interactive states
|
|
142
|
+
primary: '--mj-brand-primary',
|
|
143
|
+
primaryHover: '--mj-brand-primary-hover',
|
|
144
|
+
primaryActive: '--mj-brand-primary-active',
|
|
145
|
+
primaryLight: '--mj-brand-primary-light',
|
|
146
|
+
// Status
|
|
147
|
+
success: '--mj-status-success',
|
|
148
|
+
successLight: '--mj-status-success-bg',
|
|
149
|
+
warning: '--mj-status-warning',
|
|
150
|
+
warningLight: '--mj-status-warning-bg',
|
|
151
|
+
error: '--mj-status-error',
|
|
152
|
+
errorLight: '--mj-status-error-bg',
|
|
153
|
+
info: '--mj-status-info',
|
|
154
|
+
infoLight: '--mj-status-info-bg',
|
|
155
|
+
// Surfaces (MJ: page = tinted, surface = elevated/white in light mode)
|
|
156
|
+
background: '--mj-bg-page',
|
|
157
|
+
surface: '--mj-bg-surface',
|
|
158
|
+
surfaceHover: '--mj-bg-surface-hover',
|
|
159
|
+
// Text
|
|
160
|
+
text: '--mj-text-primary',
|
|
161
|
+
textSecondary: '--mj-text-secondary',
|
|
162
|
+
textTertiary: '--mj-text-muted',
|
|
163
|
+
textInverse: '--mj-text-inverse',
|
|
164
|
+
// Links
|
|
165
|
+
link: '--mj-text-link',
|
|
166
|
+
linkHover: '--mj-text-link-hover',
|
|
167
|
+
// Borders / focus
|
|
168
|
+
border: '--mj-border-default',
|
|
169
|
+
borderLight: '--mj-border-subtle',
|
|
170
|
+
borderFocus: '--mj-border-focus',
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
/** Number of `--mj-viz-N` categorical tokens the bridge probes for `chartPalette`. */
|
|
174
|
+
const VIZ_TOKEN_COUNT = 10;
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Reads the live MJ theme (`--mj-*` custom properties on the document root) and
|
|
178
|
+
* layers it over `SetupStyles()`, producing a `ComponentStyles` that follows the
|
|
179
|
+
* host's active theme — including dark mode and interactive-state (hover/active/
|
|
180
|
+
* focus) families — instead of the frozen default palette. This is the Phase 1
|
|
181
|
+
* theme bridge that gives generated components shell↔content cohesion.
|
|
182
|
+
*
|
|
183
|
+
* DOM-guarded: in non-DOM environments (Node test harness, SSR) there is no
|
|
184
|
+
* computed theme to read, so it returns `SetupStyles()` unchanged. Any individual
|
|
185
|
+
* token that is absent falls back to its `SetupStyles()` default, so a page
|
|
186
|
+
* without MJ tokens loaded also degrades cleanly.
|
|
187
|
+
*
|
|
188
|
+
* @param root optional element to read tokens from (defaults to document root).
|
|
189
|
+
*/
|
|
190
|
+
export function BuildStylesFromTheme(root?: Element): ComponentStyles {
|
|
191
|
+
const base = SetupStyles();
|
|
192
|
+
|
|
193
|
+
const el = root ?? (typeof document !== 'undefined' ? document.documentElement : undefined);
|
|
194
|
+
if (!el || typeof getComputedStyle === 'undefined') {
|
|
195
|
+
return base;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const cs = getComputedStyle(el);
|
|
199
|
+
const read = (token: string): string => cs.getPropertyValue(token).trim();
|
|
200
|
+
|
|
201
|
+
for (const [path, token] of Object.entries(THEME_COLOR_TOKEN_MAP)) {
|
|
202
|
+
const value = read(token);
|
|
203
|
+
if (value) {
|
|
204
|
+
base.colors[path] = value;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const palette: string[] = [];
|
|
209
|
+
for (let i = 1; i <= VIZ_TOKEN_COUNT; i++) {
|
|
210
|
+
const value = read(`--mj-viz-${i}`);
|
|
211
|
+
if (value) {
|
|
212
|
+
palette.push(value);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (palette.length > 0) {
|
|
216
|
+
base.chartPalette = palette;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return base;
|
|
220
|
+
}
|