@gtcx/theme 0.1.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/dist/config-provider.d.ts +40 -0
- package/dist/config-provider.d.ts.map +1 -0
- package/dist/create-theme.d.ts +61 -0
- package/dist/create-theme.d.ts.map +1 -0
- package/dist/index.cjs +167 -0
- package/dist/index.d.cts +58 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +228 -0
- package/dist/index.mjs +210 -0
- package/dist/platform-themes.d.ts +33 -0
- package/dist/platform-themes.d.ts.map +1 -0
- package/dist/use-gtcx-theme.d.ts +23 -0
- package/dist/use-gtcx-theme.d.ts.map +1 -0
- package/package.json +42 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module config-provider
|
|
3
|
+
*
|
|
4
|
+
* Root provider for GTCX theming. Wraps Ant Design's `ConfigProvider` with
|
|
5
|
+
* GTCX tokens and ensures all descendants receive the correct theme.
|
|
6
|
+
*
|
|
7
|
+
* Per ADR-0002: All styling flows from GTCX tokens via ConfigProvider.
|
|
8
|
+
* Platform apps should wrap their root with this provider.
|
|
9
|
+
*/
|
|
10
|
+
import { ConfigProvider } from 'antd';
|
|
11
|
+
import React from 'react';
|
|
12
|
+
import { type ThemeMode, type ThemeDensity, type TokensOverride } from './create-theme';
|
|
13
|
+
export interface GtcxConfigProviderProps {
|
|
14
|
+
/** Light or dark mode. Defaults to `'light'`. */
|
|
15
|
+
mode?: ThemeMode;
|
|
16
|
+
/** Comfortable or compact density. Defaults to `'comfortable'`. */
|
|
17
|
+
density?: ThemeDensity;
|
|
18
|
+
/** Deep-merged token overrides. Must be a stable reference or memoized. */
|
|
19
|
+
tokensOverride?: TokensOverride;
|
|
20
|
+
/** Layout direction. Defaults to `'ltr'`. */
|
|
21
|
+
direction?: 'ltr' | 'rtl';
|
|
22
|
+
/** Ant Design locale object for i18n. */
|
|
23
|
+
locale?: React.ComponentProps<typeof ConfigProvider>['locale'];
|
|
24
|
+
children: React.ReactNode;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Root GTCX theme provider.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```tsx
|
|
31
|
+
* <GtcxConfigProvider mode="dark" density="compact">
|
|
32
|
+
* <App />
|
|
33
|
+
* </GtcxConfigProvider>
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare function GtcxConfigProvider({ mode, density, tokensOverride, direction, locale, children, }: GtcxConfigProviderProps): React.ReactElement;
|
|
37
|
+
export declare namespace GtcxConfigProvider {
|
|
38
|
+
var displayName: string;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=config-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-provider.d.ts","sourceRoot":"","sources":["../src/config-provider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,cAAc,EAAO,MAAM,MAAM,CAAC;AAC3C,OAAO,KAAyC,MAAM,OAAO,CAAC;AAE9D,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,cAAc,EACpB,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,uBAAuB;IACtC,iDAAiD;IACjD,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,mEAAmE;IACnE,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,2EAA2E;IAC3E,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,6CAA6C;IAC7C,SAAS,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAC1B,yCAAyC;IACzC,MAAM,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC/D,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,IAAc,EACd,OAAuB,EACvB,cAAc,EACd,SAAiB,EACjB,MAAM,EACN,QAAQ,GACT,EAAE,uBAAuB,GAAG,KAAK,CAAC,YAAY,CA2B9C;yBAlCe,kBAAkB"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module create-theme
|
|
3
|
+
*
|
|
4
|
+
* Creates Ant Design v5 {@link ThemeConfig} objects from GTCX semantic tokens.
|
|
5
|
+
* This is the single bridge between the GTCX token system and Ant Design's
|
|
6
|
+
* theming engine.
|
|
7
|
+
*
|
|
8
|
+
* Key design decisions:
|
|
9
|
+
* - Deep merges `tokensOverride` so nested objects (like `colors.primary`)
|
|
10
|
+
* don't blow away sibling keys.
|
|
11
|
+
* - Maps ~80% of Ant Design's seed, alias, and component tokens.
|
|
12
|
+
* - Supports light/dark modes via `theme.darkAlgorithm`.
|
|
13
|
+
* - Supports compact density via `theme.compactAlgorithm`.
|
|
14
|
+
*/
|
|
15
|
+
import { type SemanticColors, type SemanticSpacing, type SemanticTypography, type SemanticRadii, type SemanticShadows, type SemanticLayout } from '@gtcx/tokens';
|
|
16
|
+
import type { ThemeConfig } from 'antd';
|
|
17
|
+
export type ThemeMode = 'light' | 'dark';
|
|
18
|
+
export type ThemeDensity = 'comfortable' | 'compact';
|
|
19
|
+
type Widen<T> = T extends string ? string : T extends number ? number : T extends boolean ? boolean : T;
|
|
20
|
+
type DeepPartial<T> = {
|
|
21
|
+
[K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : Widen<T[K]>;
|
|
22
|
+
};
|
|
23
|
+
export interface TokensOverride {
|
|
24
|
+
colors?: DeepPartial<SemanticColors>;
|
|
25
|
+
spacing?: DeepPartial<SemanticSpacing>;
|
|
26
|
+
typography?: DeepPartial<SemanticTypography>;
|
|
27
|
+
radii?: DeepPartial<SemanticRadii>;
|
|
28
|
+
shadows?: DeepPartial<SemanticShadows>;
|
|
29
|
+
layout?: DeepPartial<SemanticLayout>;
|
|
30
|
+
}
|
|
31
|
+
export interface CreateAntdThemeOptions {
|
|
32
|
+
/** Light or dark mode. Defaults to `'light'`. */
|
|
33
|
+
mode?: ThemeMode;
|
|
34
|
+
/** Comfortable (default) or compact density. */
|
|
35
|
+
density?: ThemeDensity;
|
|
36
|
+
/** Deep-merged overrides for semantic tokens. */
|
|
37
|
+
tokensOverride?: TokensOverride;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Creates an Ant Design {@link ThemeConfig} from GTCX semantic tokens.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* // Light mode (default)
|
|
45
|
+
* const theme = createAntdTheme();
|
|
46
|
+
*
|
|
47
|
+
* // Dark mode
|
|
48
|
+
* const dark = createAntdTheme({ mode: 'dark' });
|
|
49
|
+
*
|
|
50
|
+
* // Compact density
|
|
51
|
+
* const compact = createAntdTheme({ density: 'compact' });
|
|
52
|
+
*
|
|
53
|
+
* // Override specific tokens without losing siblings
|
|
54
|
+
* const custom = createAntdTheme({
|
|
55
|
+
* tokensOverride: { colors: { primary: '#ff0000' } },
|
|
56
|
+
* });
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export declare function createAntdTheme(options?: CreateAntdThemeOptions): ThemeConfig;
|
|
60
|
+
export {};
|
|
61
|
+
//# sourceMappingURL=create-theme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-theme.d.ts","sourceRoot":"","sources":["../src/create-theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAWL,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,cAAc,EACpB,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AAMxC,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AACzC,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,SAAS,CAAC;AAErD,KAAK,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,GAC5B,MAAM,GACN,CAAC,SAAS,MAAM,GACd,MAAM,GACN,CAAC,SAAS,OAAO,GACf,OAAO,GACP,CAAC,CAAC;AACV,KAAK,WAAW,CAAC,CAAC,IAAI;KACnB,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CACvE,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,WAAW,CAAC,cAAc,CAAC,CAAC;IACrC,OAAO,CAAC,EAAE,WAAW,CAAC,eAAe,CAAC,CAAC;IACvC,UAAU,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,CAAC;IAC7C,KAAK,CAAC,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC;IACnC,OAAO,CAAC,EAAE,WAAW,CAAC,eAAe,CAAC,CAAC;IACvC,MAAM,CAAC,EAAE,WAAW,CAAC,cAAc,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,sBAAsB;IACrC,iDAAiD;IACjD,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,gDAAgD;IAChD,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,iDAAiD;IACjD,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAsDD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAE,sBAA2B,GAAG,WAAW,CA6LjF"}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
GtcxConfigProvider: () => GtcxConfigProvider,
|
|
24
|
+
createAntdTheme: () => createAntdTheme,
|
|
25
|
+
getAntThemeForPlatform: () => getAntThemeForPlatform,
|
|
26
|
+
getPlatformTheme: () => getPlatformTheme,
|
|
27
|
+
platformThemes: () => platformThemes
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(index_exports);
|
|
30
|
+
|
|
31
|
+
// src/createAntdTheme.ts
|
|
32
|
+
var import_tokens = require("@gtcx/tokens");
|
|
33
|
+
function createAntdTheme(options = {}) {
|
|
34
|
+
const { mode = "light" } = options;
|
|
35
|
+
const tokens = { ...import_tokens.semanticTokens, ...options.tokensOverride };
|
|
36
|
+
const baseTheme = {
|
|
37
|
+
token: {
|
|
38
|
+
colorPrimary: tokens.colors.primary,
|
|
39
|
+
colorSuccess: tokens.colors.success,
|
|
40
|
+
colorWarning: tokens.colors.warning,
|
|
41
|
+
colorError: tokens.colors.error,
|
|
42
|
+
colorInfo: tokens.colors.info,
|
|
43
|
+
colorLink: tokens.colors.link,
|
|
44
|
+
colorLinkHover: tokens.colors.linkHover,
|
|
45
|
+
colorText: tokens.colors.textPrimary,
|
|
46
|
+
colorTextSecondary: tokens.colors.textSecondary,
|
|
47
|
+
colorTextTertiary: tokens.colors.textMuted,
|
|
48
|
+
colorBgContainer: tokens.colors.bgSurface,
|
|
49
|
+
colorBgLayout: tokens.colors.bgPage,
|
|
50
|
+
colorBorder: tokens.colors.border,
|
|
51
|
+
colorBorderSecondary: tokens.colors.borderLight,
|
|
52
|
+
borderRadius: tokens.radii.component,
|
|
53
|
+
fontFamily: tokens.typography.fontFamily,
|
|
54
|
+
fontFamilyCode: tokens.typography.fontFamilyCode,
|
|
55
|
+
fontSize: tokens.typography.body.md.fontSize,
|
|
56
|
+
lineHeight: tokens.typography.body.md.lineHeight,
|
|
57
|
+
boxShadow: tokens.shadows.card,
|
|
58
|
+
boxShadowSecondary: tokens.shadows.dropdown
|
|
59
|
+
},
|
|
60
|
+
components: {
|
|
61
|
+
Layout: {
|
|
62
|
+
headerBg: tokens.colors.bgHeader,
|
|
63
|
+
headerHeight: tokens.layout.headerHeight,
|
|
64
|
+
siderBg: tokens.colors.bgSidebar,
|
|
65
|
+
bodyBg: tokens.colors.bgPage
|
|
66
|
+
},
|
|
67
|
+
Menu: {
|
|
68
|
+
itemBg: "transparent",
|
|
69
|
+
itemSelectedBg: tokens.colors.primaryBg,
|
|
70
|
+
itemSelectedColor: tokens.colors.primary,
|
|
71
|
+
itemHoverBg: tokens.colors.bgSurfaceHover,
|
|
72
|
+
itemHeight: 36,
|
|
73
|
+
itemMarginInline: 8,
|
|
74
|
+
itemPaddingInline: 12,
|
|
75
|
+
itemBorderRadius: 6,
|
|
76
|
+
groupTitleColor: tokens.colors.textMuted,
|
|
77
|
+
groupTitleFontSize: 11,
|
|
78
|
+
groupTitleLineHeight: 16
|
|
79
|
+
},
|
|
80
|
+
Button: {
|
|
81
|
+
borderRadius: tokens.radii.button
|
|
82
|
+
},
|
|
83
|
+
Card: {
|
|
84
|
+
borderRadiusLG: tokens.radii.card
|
|
85
|
+
},
|
|
86
|
+
Input: {
|
|
87
|
+
borderRadius: tokens.radii.input
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
if (mode === "dark") {
|
|
92
|
+
return {
|
|
93
|
+
...baseTheme,
|
|
94
|
+
algorithm: void 0
|
|
95
|
+
// TODO: implement dark mode algorithm
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return baseTheme;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// src/GtcxConfigProvider.tsx
|
|
102
|
+
var import_react = require("react");
|
|
103
|
+
var import_antd = require("antd");
|
|
104
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
105
|
+
function GtcxConfigProvider({
|
|
106
|
+
mode = "light",
|
|
107
|
+
tokensOverride,
|
|
108
|
+
direction = "ltr",
|
|
109
|
+
children
|
|
110
|
+
}) {
|
|
111
|
+
const theme = (0, import_react.useMemo)(
|
|
112
|
+
() => createAntdTheme({ mode, tokensOverride }),
|
|
113
|
+
[mode, tokensOverride]
|
|
114
|
+
);
|
|
115
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_antd.ConfigProvider, { theme, direction, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_antd.App, { children }) });
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// src/platform-themes.ts
|
|
119
|
+
var import_tokens2 = require("@gtcx/tokens");
|
|
120
|
+
var platformThemes = {
|
|
121
|
+
crx: {
|
|
122
|
+
platform: "crx",
|
|
123
|
+
colors: import_tokens2.platformColors.crx,
|
|
124
|
+
spacing: import_tokens2.platformSpacing.crx
|
|
125
|
+
},
|
|
126
|
+
sgx: {
|
|
127
|
+
platform: "sgx",
|
|
128
|
+
colors: import_tokens2.platformColors.sgx,
|
|
129
|
+
spacing: import_tokens2.platformSpacing.sgx
|
|
130
|
+
},
|
|
131
|
+
agx: {
|
|
132
|
+
platform: "agx",
|
|
133
|
+
colors: import_tokens2.platformColors.agx,
|
|
134
|
+
spacing: import_tokens2.platformSpacing.agx
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
var getPlatformTheme = (platform) => platformThemes[platform];
|
|
138
|
+
function getAntThemeForPlatform(platform) {
|
|
139
|
+
const theme = platformThemes[platform];
|
|
140
|
+
return {
|
|
141
|
+
token: {
|
|
142
|
+
colorPrimary: theme.colors.primary,
|
|
143
|
+
colorInfo: import_tokens2.colorPrimitives.info[500],
|
|
144
|
+
colorSuccess: import_tokens2.colorPrimitives.success[500],
|
|
145
|
+
colorWarning: import_tokens2.colorPrimitives.warning[500],
|
|
146
|
+
colorError: import_tokens2.colorPrimitives.error[500],
|
|
147
|
+
borderRadius: 8,
|
|
148
|
+
fontFamily: "Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif"
|
|
149
|
+
},
|
|
150
|
+
components: {
|
|
151
|
+
Button: {
|
|
152
|
+
paddingInline: theme.spacing.basePadding
|
|
153
|
+
},
|
|
154
|
+
Card: {
|
|
155
|
+
paddingLG: theme.spacing.basePadding + 8
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
161
|
+
0 && (module.exports = {
|
|
162
|
+
GtcxConfigProvider,
|
|
163
|
+
createAntdTheme,
|
|
164
|
+
getAntThemeForPlatform,
|
|
165
|
+
getPlatformTheme,
|
|
166
|
+
platformThemes
|
|
167
|
+
});
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ThemeConfig } from 'antd';
|
|
2
|
+
import { semanticTokens, Platform } from '@gtcx/tokens';
|
|
3
|
+
export { Platform } from '@gtcx/tokens';
|
|
4
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
type ThemeMode = 'light' | 'dark';
|
|
8
|
+
interface CreateAntdThemeOptions {
|
|
9
|
+
mode?: ThemeMode;
|
|
10
|
+
tokensOverride?: Partial<typeof semanticTokens>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Creates an Ant Design theme config from GTCX semantic tokens.
|
|
14
|
+
* Follows ADR-0002: use ConfigProvider as primary customization mechanism.
|
|
15
|
+
*/
|
|
16
|
+
declare function createAntdTheme(options?: CreateAntdThemeOptions): ThemeConfig;
|
|
17
|
+
|
|
18
|
+
interface GtcxConfigProviderProps {
|
|
19
|
+
mode?: ThemeMode;
|
|
20
|
+
tokensOverride?: Partial<typeof semanticTokens>;
|
|
21
|
+
direction?: 'ltr' | 'rtl';
|
|
22
|
+
children: React.ReactNode;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Root provider for GTCX theming.
|
|
26
|
+
* Wraps Ant Design ConfigProvider with GTCX tokens.
|
|
27
|
+
*
|
|
28
|
+
* Per ADR-0002: All styling flows from GTCX tokens via ConfigProvider.
|
|
29
|
+
* Platform apps should wrap their root with this provider.
|
|
30
|
+
*/
|
|
31
|
+
declare function GtcxConfigProvider({ mode, tokensOverride, direction, children, }: GtcxConfigProviderProps): react_jsx_runtime.JSX.Element;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Platform-specific Ant Design theme generators for CRX, SGX, and AGX.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
interface PlatformTheme {
|
|
38
|
+
platform: Platform;
|
|
39
|
+
colors: {
|
|
40
|
+
primary: string;
|
|
41
|
+
secondary: string;
|
|
42
|
+
accent: string;
|
|
43
|
+
gradient: string;
|
|
44
|
+
};
|
|
45
|
+
spacing: {
|
|
46
|
+
density: string;
|
|
47
|
+
basePadding: number;
|
|
48
|
+
baseGap: number;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
declare const platformThemes: Record<Platform, PlatformTheme>;
|
|
52
|
+
declare const getPlatformTheme: (platform: Platform) => PlatformTheme;
|
|
53
|
+
/**
|
|
54
|
+
* Generate an Ant Design theme config for a specific platform.
|
|
55
|
+
*/
|
|
56
|
+
declare function getAntThemeForPlatform(platform: Platform): ThemeConfig;
|
|
57
|
+
|
|
58
|
+
export { type CreateAntdThemeOptions, GtcxConfigProvider, type GtcxConfigProviderProps, type PlatformTheme, type ThemeMode, createAntdTheme, getAntThemeForPlatform, getPlatformTheme, platformThemes };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { createAntdTheme } from './create-theme';
|
|
2
|
+
export type { ThemeMode, ThemeDensity, CreateAntdThemeOptions, TokensOverride, } from './create-theme';
|
|
3
|
+
export { GtcxConfigProvider } from './config-provider';
|
|
4
|
+
export type { GtcxConfigProviderProps } from './config-provider';
|
|
5
|
+
export { useGtcxTheme } from './use-gtcx-theme';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,YAAY,EACV,SAAS,EACT,YAAY,EACZ,sBAAsB,EACtB,cAAc,GACf,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,YAAY,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAEjE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
GtcxConfigProvider: () => GtcxConfigProvider,
|
|
24
|
+
createAntdTheme: () => createAntdTheme,
|
|
25
|
+
useGtcxTheme: () => useGtcxTheme
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(index_exports);
|
|
28
|
+
|
|
29
|
+
// src/create-theme.ts
|
|
30
|
+
var import_tokens = require("@gtcx/tokens");
|
|
31
|
+
var import_antd = require("antd");
|
|
32
|
+
function deepMerge(base, override) {
|
|
33
|
+
if (typeof base !== "object" || base === null || typeof override !== "object" || override === null) {
|
|
34
|
+
return override ?? base;
|
|
35
|
+
}
|
|
36
|
+
const result = { ...base };
|
|
37
|
+
for (const key of Object.keys(override)) {
|
|
38
|
+
const overrideVal = override[key];
|
|
39
|
+
const baseVal = base[key];
|
|
40
|
+
if (overrideVal !== null && overrideVal !== void 0 && typeof overrideVal === "object" && !Array.isArray(overrideVal) && typeof baseVal === "object" && baseVal !== null && !Array.isArray(baseVal)) {
|
|
41
|
+
result[key] = deepMerge(baseVal, overrideVal);
|
|
42
|
+
} else if (overrideVal !== void 0) {
|
|
43
|
+
result[key] = overrideVal;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
function createAntdTheme(options = {}) {
|
|
49
|
+
const { mode = "light", density = "comfortable" } = options;
|
|
50
|
+
const base = {
|
|
51
|
+
colors: { ...import_tokens.semanticColors },
|
|
52
|
+
spacing: { ...import_tokens.semanticSpacing },
|
|
53
|
+
typography: { ...import_tokens.semanticTypography },
|
|
54
|
+
radii: { ...import_tokens.semanticRadii },
|
|
55
|
+
shadows: { ...import_tokens.semanticShadows },
|
|
56
|
+
layout: { ...import_tokens.semanticLayout }
|
|
57
|
+
};
|
|
58
|
+
const tokens = options.tokensOverride ? {
|
|
59
|
+
colors: options.tokensOverride.colors ? deepMerge(base.colors, options.tokensOverride.colors) : base.colors,
|
|
60
|
+
spacing: options.tokensOverride.spacing ? deepMerge(base.spacing, options.tokensOverride.spacing) : base.spacing,
|
|
61
|
+
typography: options.tokensOverride.typography ? deepMerge(base.typography, options.tokensOverride.typography) : base.typography,
|
|
62
|
+
radii: options.tokensOverride.radii ? deepMerge(base.radii, options.tokensOverride.radii) : base.radii,
|
|
63
|
+
shadows: options.tokensOverride.shadows ? deepMerge(base.shadows, options.tokensOverride.shadows) : base.shadows,
|
|
64
|
+
layout: options.tokensOverride.layout ? deepMerge(base.layout, options.tokensOverride.layout) : base.layout
|
|
65
|
+
} : base;
|
|
66
|
+
const colors = mode === "dark" ? { ...tokens.colors, ...import_tokens.darkSemanticColors } : tokens.colors;
|
|
67
|
+
const algorithms = [];
|
|
68
|
+
if (mode === "dark") {
|
|
69
|
+
algorithms.push(import_antd.theme.darkAlgorithm);
|
|
70
|
+
}
|
|
71
|
+
if (density === "compact") {
|
|
72
|
+
algorithms.push(import_antd.theme.compactAlgorithm);
|
|
73
|
+
}
|
|
74
|
+
const config = {
|
|
75
|
+
// Algorithm
|
|
76
|
+
...algorithms.length === 1 ? { algorithm: algorithms[0] } : algorithms.length > 1 ? { algorithm: algorithms } : {},
|
|
77
|
+
// Seed + alias tokens
|
|
78
|
+
token: {
|
|
79
|
+
// Colors — seed
|
|
80
|
+
colorPrimary: colors.primary,
|
|
81
|
+
colorSuccess: colors.success,
|
|
82
|
+
colorWarning: colors.warning,
|
|
83
|
+
colorError: colors.error,
|
|
84
|
+
colorInfo: colors.info,
|
|
85
|
+
colorLink: colors.link,
|
|
86
|
+
colorLinkHover: colors.linkHover,
|
|
87
|
+
// Colors — text
|
|
88
|
+
colorText: colors.textPrimary,
|
|
89
|
+
colorTextSecondary: colors.textSecondary,
|
|
90
|
+
colorTextTertiary: colors.textTertiary,
|
|
91
|
+
colorTextQuaternary: colors.textMuted,
|
|
92
|
+
// Colors — backgrounds
|
|
93
|
+
colorBgBase: colors.bgPage,
|
|
94
|
+
colorBgContainer: colors.bgSurface,
|
|
95
|
+
colorBgLayout: colors.bgPage,
|
|
96
|
+
colorBgElevated: colors.bgSurface,
|
|
97
|
+
// Colors — borders
|
|
98
|
+
colorBorder: colors.border,
|
|
99
|
+
colorBorderSecondary: colors.borderLight,
|
|
100
|
+
// Typography
|
|
101
|
+
fontFamily: tokens.typography.fontFamily,
|
|
102
|
+
fontFamilyCode: tokens.typography.fontFamilyCode,
|
|
103
|
+
fontSize: tokens.typography.body.md.fontSize,
|
|
104
|
+
lineHeight: tokens.typography.body.md.lineHeight,
|
|
105
|
+
// Border radius — seed
|
|
106
|
+
borderRadius: tokens.radii.component,
|
|
107
|
+
// Shadows
|
|
108
|
+
boxShadow: tokens.shadows.card,
|
|
109
|
+
boxShadowSecondary: tokens.shadows.dropdown,
|
|
110
|
+
boxShadowTertiary: tokens.shadows.modal,
|
|
111
|
+
// Focus
|
|
112
|
+
controlOutlineWidth: import_tokens.focusPrimitives.ringWidth,
|
|
113
|
+
// Opacity
|
|
114
|
+
opacityLoading: import_tokens.opacityPrimitives.loading,
|
|
115
|
+
// Spacing — Ant Design seed tokens
|
|
116
|
+
sizeUnit: 4,
|
|
117
|
+
sizeStep: 4,
|
|
118
|
+
// Motion
|
|
119
|
+
motionUnit: 0.1,
|
|
120
|
+
// Z-index
|
|
121
|
+
zIndexBase: 0,
|
|
122
|
+
zIndexPopupBase: 1e3,
|
|
123
|
+
// Control height
|
|
124
|
+
controlHeight: 36
|
|
125
|
+
},
|
|
126
|
+
// Component-level token overrides
|
|
127
|
+
components: {
|
|
128
|
+
Layout: {
|
|
129
|
+
headerBg: colors.bgHeader,
|
|
130
|
+
headerHeight: tokens.layout.headerHeight,
|
|
131
|
+
siderBg: colors.bgSidebar,
|
|
132
|
+
bodyBg: colors.bgPage
|
|
133
|
+
},
|
|
134
|
+
Menu: {
|
|
135
|
+
itemBg: "transparent",
|
|
136
|
+
itemSelectedBg: colors.primaryBg,
|
|
137
|
+
itemSelectedColor: colors.primary,
|
|
138
|
+
itemHoverBg: colors.bgSurfaceHover,
|
|
139
|
+
itemHeight: 36,
|
|
140
|
+
itemMarginInline: 8,
|
|
141
|
+
itemPaddingInline: 12,
|
|
142
|
+
itemBorderRadius: import_tokens.borderRadiusPrimitives.md,
|
|
143
|
+
groupTitleColor: colors.textMuted,
|
|
144
|
+
groupTitleFontSize: tokens.typography.caption.fontSize - 1,
|
|
145
|
+
groupTitleLineHeight: 16
|
|
146
|
+
},
|
|
147
|
+
Button: {
|
|
148
|
+
borderRadius: tokens.radii.button,
|
|
149
|
+
paddingInline: tokens.spacing.component.button.paddingX,
|
|
150
|
+
fontWeight: tokens.typography.button.md.fontWeight
|
|
151
|
+
},
|
|
152
|
+
Card: {
|
|
153
|
+
borderRadiusLG: tokens.radii.card,
|
|
154
|
+
paddingLG: tokens.spacing.component.card.padding
|
|
155
|
+
},
|
|
156
|
+
Input: {
|
|
157
|
+
borderRadius: tokens.radii.input,
|
|
158
|
+
paddingInline: tokens.spacing.component.input.paddingX
|
|
159
|
+
},
|
|
160
|
+
Table: {
|
|
161
|
+
cellPaddingBlock: tokens.spacing.component.table.cellPadding,
|
|
162
|
+
cellPaddingInline: tokens.spacing.component.table.cellPadding,
|
|
163
|
+
headerBg: colors.bgSurfaceHover,
|
|
164
|
+
headerColor: colors.textSecondary,
|
|
165
|
+
borderColor: colors.borderLight,
|
|
166
|
+
rowHoverBg: colors.bgSurfaceHover
|
|
167
|
+
},
|
|
168
|
+
Modal: {
|
|
169
|
+
paddingLG: tokens.spacing.component.modal.padding,
|
|
170
|
+
borderRadiusLG: tokens.radii.card
|
|
171
|
+
},
|
|
172
|
+
Form: {
|
|
173
|
+
itemMarginBottom: tokens.spacing.component.form.fieldGap,
|
|
174
|
+
labelFontSize: tokens.typography.body.sm.fontSize
|
|
175
|
+
},
|
|
176
|
+
Typography: {
|
|
177
|
+
fontFamilyCode: tokens.typography.fontFamilyCode
|
|
178
|
+
},
|
|
179
|
+
Tag: {
|
|
180
|
+
borderRadiusSM: tokens.radii.tag
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
return config;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// src/config-provider.tsx
|
|
188
|
+
var import_antd2 = require("antd");
|
|
189
|
+
var import_react = require("react");
|
|
190
|
+
function GtcxConfigProvider({
|
|
191
|
+
mode = "light",
|
|
192
|
+
density = "comfortable",
|
|
193
|
+
tokensOverride,
|
|
194
|
+
direction = "ltr",
|
|
195
|
+
locale,
|
|
196
|
+
children
|
|
197
|
+
}) {
|
|
198
|
+
const overrideRef = (0, import_react.useRef)(tokensOverride);
|
|
199
|
+
const overrideJson = JSON.stringify(tokensOverride);
|
|
200
|
+
const prevJson = (0, import_react.useRef)(overrideJson);
|
|
201
|
+
if (overrideJson !== prevJson.current) {
|
|
202
|
+
overrideRef.current = tokensOverride;
|
|
203
|
+
prevJson.current = overrideJson;
|
|
204
|
+
}
|
|
205
|
+
const theme = (0, import_react.useMemo)(
|
|
206
|
+
() => createAntdTheme({ mode, density, tokensOverride: overrideRef.current }),
|
|
207
|
+
[mode, density, overrideJson]
|
|
208
|
+
);
|
|
209
|
+
return (0, import_react.createElement)(
|
|
210
|
+
import_antd2.ConfigProvider,
|
|
211
|
+
{ theme, direction, locale },
|
|
212
|
+
(0, import_react.createElement)(import_antd2.App, null, children)
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
GtcxConfigProvider.displayName = "GtcxConfigProvider";
|
|
216
|
+
|
|
217
|
+
// src/use-gtcx-theme.ts
|
|
218
|
+
var import_antd3 = require("antd");
|
|
219
|
+
function useGtcxTheme() {
|
|
220
|
+
const { token } = import_antd3.theme.useToken();
|
|
221
|
+
return { token };
|
|
222
|
+
}
|
|
223
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
224
|
+
0 && (module.exports = {
|
|
225
|
+
GtcxConfigProvider,
|
|
226
|
+
createAntdTheme,
|
|
227
|
+
useGtcxTheme
|
|
228
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
// src/create-theme.ts
|
|
2
|
+
import {
|
|
3
|
+
semanticColors,
|
|
4
|
+
semanticSpacing,
|
|
5
|
+
semanticTypography,
|
|
6
|
+
semanticRadii,
|
|
7
|
+
semanticShadows,
|
|
8
|
+
semanticLayout,
|
|
9
|
+
darkSemanticColors,
|
|
10
|
+
borderRadiusPrimitives,
|
|
11
|
+
opacityPrimitives,
|
|
12
|
+
focusPrimitives
|
|
13
|
+
} from "@gtcx/tokens";
|
|
14
|
+
import { theme as antdTheme } from "antd";
|
|
15
|
+
function deepMerge(base, override) {
|
|
16
|
+
if (typeof base !== "object" || base === null || typeof override !== "object" || override === null) {
|
|
17
|
+
return override ?? base;
|
|
18
|
+
}
|
|
19
|
+
const result = { ...base };
|
|
20
|
+
for (const key of Object.keys(override)) {
|
|
21
|
+
const overrideVal = override[key];
|
|
22
|
+
const baseVal = base[key];
|
|
23
|
+
if (overrideVal !== null && overrideVal !== void 0 && typeof overrideVal === "object" && !Array.isArray(overrideVal) && typeof baseVal === "object" && baseVal !== null && !Array.isArray(baseVal)) {
|
|
24
|
+
result[key] = deepMerge(baseVal, overrideVal);
|
|
25
|
+
} else if (overrideVal !== void 0) {
|
|
26
|
+
result[key] = overrideVal;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
function createAntdTheme(options = {}) {
|
|
32
|
+
const { mode = "light", density = "comfortable" } = options;
|
|
33
|
+
const base = {
|
|
34
|
+
colors: { ...semanticColors },
|
|
35
|
+
spacing: { ...semanticSpacing },
|
|
36
|
+
typography: { ...semanticTypography },
|
|
37
|
+
radii: { ...semanticRadii },
|
|
38
|
+
shadows: { ...semanticShadows },
|
|
39
|
+
layout: { ...semanticLayout }
|
|
40
|
+
};
|
|
41
|
+
const tokens = options.tokensOverride ? {
|
|
42
|
+
colors: options.tokensOverride.colors ? deepMerge(base.colors, options.tokensOverride.colors) : base.colors,
|
|
43
|
+
spacing: options.tokensOverride.spacing ? deepMerge(base.spacing, options.tokensOverride.spacing) : base.spacing,
|
|
44
|
+
typography: options.tokensOverride.typography ? deepMerge(base.typography, options.tokensOverride.typography) : base.typography,
|
|
45
|
+
radii: options.tokensOverride.radii ? deepMerge(base.radii, options.tokensOverride.radii) : base.radii,
|
|
46
|
+
shadows: options.tokensOverride.shadows ? deepMerge(base.shadows, options.tokensOverride.shadows) : base.shadows,
|
|
47
|
+
layout: options.tokensOverride.layout ? deepMerge(base.layout, options.tokensOverride.layout) : base.layout
|
|
48
|
+
} : base;
|
|
49
|
+
const colors = mode === "dark" ? { ...tokens.colors, ...darkSemanticColors } : tokens.colors;
|
|
50
|
+
const algorithms = [];
|
|
51
|
+
if (mode === "dark") {
|
|
52
|
+
algorithms.push(antdTheme.darkAlgorithm);
|
|
53
|
+
}
|
|
54
|
+
if (density === "compact") {
|
|
55
|
+
algorithms.push(antdTheme.compactAlgorithm);
|
|
56
|
+
}
|
|
57
|
+
const config = {
|
|
58
|
+
// Algorithm
|
|
59
|
+
...algorithms.length === 1 ? { algorithm: algorithms[0] } : algorithms.length > 1 ? { algorithm: algorithms } : {},
|
|
60
|
+
// Seed + alias tokens
|
|
61
|
+
token: {
|
|
62
|
+
// Colors — seed
|
|
63
|
+
colorPrimary: colors.primary,
|
|
64
|
+
colorSuccess: colors.success,
|
|
65
|
+
colorWarning: colors.warning,
|
|
66
|
+
colorError: colors.error,
|
|
67
|
+
colorInfo: colors.info,
|
|
68
|
+
colorLink: colors.link,
|
|
69
|
+
colorLinkHover: colors.linkHover,
|
|
70
|
+
// Colors — text
|
|
71
|
+
colorText: colors.textPrimary,
|
|
72
|
+
colorTextSecondary: colors.textSecondary,
|
|
73
|
+
colorTextTertiary: colors.textTertiary,
|
|
74
|
+
colorTextQuaternary: colors.textMuted,
|
|
75
|
+
// Colors — backgrounds
|
|
76
|
+
colorBgBase: colors.bgPage,
|
|
77
|
+
colorBgContainer: colors.bgSurface,
|
|
78
|
+
colorBgLayout: colors.bgPage,
|
|
79
|
+
colorBgElevated: colors.bgSurface,
|
|
80
|
+
// Colors — borders
|
|
81
|
+
colorBorder: colors.border,
|
|
82
|
+
colorBorderSecondary: colors.borderLight,
|
|
83
|
+
// Typography
|
|
84
|
+
fontFamily: tokens.typography.fontFamily,
|
|
85
|
+
fontFamilyCode: tokens.typography.fontFamilyCode,
|
|
86
|
+
fontSize: tokens.typography.body.md.fontSize,
|
|
87
|
+
lineHeight: tokens.typography.body.md.lineHeight,
|
|
88
|
+
// Border radius — seed
|
|
89
|
+
borderRadius: tokens.radii.component,
|
|
90
|
+
// Shadows
|
|
91
|
+
boxShadow: tokens.shadows.card,
|
|
92
|
+
boxShadowSecondary: tokens.shadows.dropdown,
|
|
93
|
+
boxShadowTertiary: tokens.shadows.modal,
|
|
94
|
+
// Focus
|
|
95
|
+
controlOutlineWidth: focusPrimitives.ringWidth,
|
|
96
|
+
// Opacity
|
|
97
|
+
opacityLoading: opacityPrimitives.loading,
|
|
98
|
+
// Spacing — Ant Design seed tokens
|
|
99
|
+
sizeUnit: 4,
|
|
100
|
+
sizeStep: 4,
|
|
101
|
+
// Motion
|
|
102
|
+
motionUnit: 0.1,
|
|
103
|
+
// Z-index
|
|
104
|
+
zIndexBase: 0,
|
|
105
|
+
zIndexPopupBase: 1e3,
|
|
106
|
+
// Control height
|
|
107
|
+
controlHeight: 36
|
|
108
|
+
},
|
|
109
|
+
// Component-level token overrides
|
|
110
|
+
components: {
|
|
111
|
+
Layout: {
|
|
112
|
+
headerBg: colors.bgHeader,
|
|
113
|
+
headerHeight: tokens.layout.headerHeight,
|
|
114
|
+
siderBg: colors.bgSidebar,
|
|
115
|
+
bodyBg: colors.bgPage
|
|
116
|
+
},
|
|
117
|
+
Menu: {
|
|
118
|
+
itemBg: "transparent",
|
|
119
|
+
itemSelectedBg: colors.primaryBg,
|
|
120
|
+
itemSelectedColor: colors.primary,
|
|
121
|
+
itemHoverBg: colors.bgSurfaceHover,
|
|
122
|
+
itemHeight: 36,
|
|
123
|
+
itemMarginInline: 8,
|
|
124
|
+
itemPaddingInline: 12,
|
|
125
|
+
itemBorderRadius: borderRadiusPrimitives.md,
|
|
126
|
+
groupTitleColor: colors.textMuted,
|
|
127
|
+
groupTitleFontSize: tokens.typography.caption.fontSize - 1,
|
|
128
|
+
groupTitleLineHeight: 16
|
|
129
|
+
},
|
|
130
|
+
Button: {
|
|
131
|
+
borderRadius: tokens.radii.button,
|
|
132
|
+
paddingInline: tokens.spacing.component.button.paddingX,
|
|
133
|
+
fontWeight: tokens.typography.button.md.fontWeight
|
|
134
|
+
},
|
|
135
|
+
Card: {
|
|
136
|
+
borderRadiusLG: tokens.radii.card,
|
|
137
|
+
paddingLG: tokens.spacing.component.card.padding
|
|
138
|
+
},
|
|
139
|
+
Input: {
|
|
140
|
+
borderRadius: tokens.radii.input,
|
|
141
|
+
paddingInline: tokens.spacing.component.input.paddingX
|
|
142
|
+
},
|
|
143
|
+
Table: {
|
|
144
|
+
cellPaddingBlock: tokens.spacing.component.table.cellPadding,
|
|
145
|
+
cellPaddingInline: tokens.spacing.component.table.cellPadding,
|
|
146
|
+
headerBg: colors.bgSurfaceHover,
|
|
147
|
+
headerColor: colors.textSecondary,
|
|
148
|
+
borderColor: colors.borderLight,
|
|
149
|
+
rowHoverBg: colors.bgSurfaceHover
|
|
150
|
+
},
|
|
151
|
+
Modal: {
|
|
152
|
+
paddingLG: tokens.spacing.component.modal.padding,
|
|
153
|
+
borderRadiusLG: tokens.radii.card
|
|
154
|
+
},
|
|
155
|
+
Form: {
|
|
156
|
+
itemMarginBottom: tokens.spacing.component.form.fieldGap,
|
|
157
|
+
labelFontSize: tokens.typography.body.sm.fontSize
|
|
158
|
+
},
|
|
159
|
+
Typography: {
|
|
160
|
+
fontFamilyCode: tokens.typography.fontFamilyCode
|
|
161
|
+
},
|
|
162
|
+
Tag: {
|
|
163
|
+
borderRadiusSM: tokens.radii.tag
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
return config;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// src/config-provider.tsx
|
|
171
|
+
import { ConfigProvider, App } from "antd";
|
|
172
|
+
import { useMemo, useRef, createElement } from "react";
|
|
173
|
+
function GtcxConfigProvider({
|
|
174
|
+
mode = "light",
|
|
175
|
+
density = "comfortable",
|
|
176
|
+
tokensOverride,
|
|
177
|
+
direction = "ltr",
|
|
178
|
+
locale,
|
|
179
|
+
children
|
|
180
|
+
}) {
|
|
181
|
+
const overrideRef = useRef(tokensOverride);
|
|
182
|
+
const overrideJson = JSON.stringify(tokensOverride);
|
|
183
|
+
const prevJson = useRef(overrideJson);
|
|
184
|
+
if (overrideJson !== prevJson.current) {
|
|
185
|
+
overrideRef.current = tokensOverride;
|
|
186
|
+
prevJson.current = overrideJson;
|
|
187
|
+
}
|
|
188
|
+
const theme = useMemo(
|
|
189
|
+
() => createAntdTheme({ mode, density, tokensOverride: overrideRef.current }),
|
|
190
|
+
[mode, density, overrideJson]
|
|
191
|
+
);
|
|
192
|
+
return createElement(
|
|
193
|
+
ConfigProvider,
|
|
194
|
+
{ theme, direction, locale },
|
|
195
|
+
createElement(App, null, children)
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
GtcxConfigProvider.displayName = "GtcxConfigProvider";
|
|
199
|
+
|
|
200
|
+
// src/use-gtcx-theme.ts
|
|
201
|
+
import { theme as antdTheme2 } from "antd";
|
|
202
|
+
function useGtcxTheme() {
|
|
203
|
+
const { token } = antdTheme2.useToken();
|
|
204
|
+
return { token };
|
|
205
|
+
}
|
|
206
|
+
export {
|
|
207
|
+
GtcxConfigProvider,
|
|
208
|
+
createAntdTheme,
|
|
209
|
+
useGtcxTheme
|
|
210
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module platform-themes
|
|
3
|
+
*
|
|
4
|
+
* Pre-built theme configs for each GTCX exchange platform.
|
|
5
|
+
* These compose platform-specific token overrides with the base
|
|
6
|
+
* semantic theme to produce ready-to-use Ant Design ThemeConfig objects.
|
|
7
|
+
*/
|
|
8
|
+
import { type Platform } from '@gtcx/tokens';
|
|
9
|
+
import type { ThemeConfig } from 'antd';
|
|
10
|
+
export interface PlatformTheme {
|
|
11
|
+
platform: Platform;
|
|
12
|
+
colors: {
|
|
13
|
+
primary: string;
|
|
14
|
+
secondary: string;
|
|
15
|
+
accent: string;
|
|
16
|
+
gradient: string;
|
|
17
|
+
};
|
|
18
|
+
spacing: {
|
|
19
|
+
density: string;
|
|
20
|
+
basePadding: number;
|
|
21
|
+
baseGap: number;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export declare const platformThemes: Record<Platform, PlatformTheme>;
|
|
25
|
+
/** Get the platform theme descriptor for a given platform. */
|
|
26
|
+
export declare const getPlatformTheme: (platform: Platform) => PlatformTheme;
|
|
27
|
+
/**
|
|
28
|
+
* Generate an Ant Design theme config for a specific platform.
|
|
29
|
+
*
|
|
30
|
+
* Uses semantic token references instead of hardcoded values.
|
|
31
|
+
*/
|
|
32
|
+
export declare function getAntThemeForPlatform(platform: Platform): ThemeConfig;
|
|
33
|
+
//# sourceMappingURL=platform-themes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform-themes.d.ts","sourceRoot":"","sources":["../src/platform-themes.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAML,KAAK,QAAQ,EACd,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AAExC,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,OAAO,EAAE;QACP,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,QAAQ,EAAE,aAAa,CAgB1D,CAAC;AAEF,8DAA8D;AAC9D,eAAO,MAAM,gBAAgB,GAAI,UAAU,QAAQ,KAAG,aAAyC,CAAC;AAEhG;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,GAAG,WAAW,CAqBtE"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module use-gtcx-theme
|
|
3
|
+
*
|
|
4
|
+
* React hook for accessing the resolved Ant Design theme token
|
|
5
|
+
* within the GTCX context. Thin wrapper around `antd`'s `theme.useToken()`.
|
|
6
|
+
*/
|
|
7
|
+
import type { GlobalToken } from 'antd/es/theme/interface';
|
|
8
|
+
/**
|
|
9
|
+
* Access the resolved Ant Design theme token from the nearest
|
|
10
|
+
* `GtcxConfigProvider` (or `ConfigProvider`).
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* function MyComponent() {
|
|
15
|
+
* const { token } = useGtcxTheme();
|
|
16
|
+
* return <div style={{ color: token.colorPrimary }}>Themed</div>;
|
|
17
|
+
* }
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare function useGtcxTheme(): {
|
|
21
|
+
token: GlobalToken;
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=use-gtcx-theme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-gtcx-theme.d.ts","sourceRoot":"","sources":["../src/use-gtcx-theme.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,IAAI;IAAE,KAAK,EAAE,WAAW,CAAA;CAAE,CAGrD"}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gtcx/theme",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "GTCX Ant Design theme integration — maps tokens to ThemeConfig, provides GtcxConfigProvider",
|
|
5
|
+
"main": "dist/index.cjs",
|
|
6
|
+
"module": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"require": "./dist/index.cjs"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"sideEffects": false,
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsup && tsc --emitDeclarationOnly --declaration --outDir dist",
|
|
18
|
+
"dev": "tsup src/index.ts --format esm,cjs --dts --watch",
|
|
19
|
+
"lint": "eslint src/",
|
|
20
|
+
"typecheck": "tsc --noEmit",
|
|
21
|
+
"test": "vitest run"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@gtcx/tokens": "workspace:*",
|
|
25
|
+
"antd": "^5.12.0"
|
|
26
|
+
},
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"react": "^18.0.0 || ^19.0.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/react": "^18.0.0",
|
|
32
|
+
"tsup": "^8.0.0",
|
|
33
|
+
"typescript": "^5.0.0"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"dist",
|
|
37
|
+
"README.md"
|
|
38
|
+
],
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
}
|
|
42
|
+
}
|