@gainsight-hub/design-tokens 0.1.0 → 0.1.2

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.
@@ -0,0 +1,6 @@
1
+ // Auto-generated — do not edit manually.
2
+ export interface ThemeConfig {
3
+ themeId: string;
4
+ overrides: { light: Record<string, string>; dark: Record<string, string> };
5
+ }
6
+ export declare function applyThemeConfig(config: ThemeConfig, mode?: "light" | "dark"): void;
@@ -0,0 +1,37 @@
1
+ // Auto-generated — do not edit manually.
2
+ import manifest from "./theme-manifest.json";
3
+
4
+ const THEME_STYLE_ID = "__gs-theme-base";
5
+ const MODE_OVERRIDES_STYLE_ID = "__gs-mode-overrides";
6
+
7
+ function injectRootVars(styleId, vars) {
8
+ const entries = Object.entries(vars);
9
+ if (entries.length === 0) return;
10
+ const css = entries.map(([k, v]) => " " + k + ": " + v + ";").join("\n");
11
+ let el = document.getElementById(styleId);
12
+ if (!el) { el = document.createElement("style"); el.id = styleId; (document.head ?? document.documentElement).appendChild(el); }
13
+ el.textContent = ":root {\n" + css + "\n}";
14
+ }
15
+
16
+ function removeRootVars(styleId) {
17
+ document.getElementById(styleId)?.remove();
18
+ }
19
+
20
+ export function applyThemeConfig(config, mode = "light") {
21
+ if (mode === "dark") {
22
+ document.documentElement.setAttribute("data-theme", "dark");
23
+ document.documentElement.classList.add("dark");
24
+ } else {
25
+ document.documentElement.removeAttribute("data-theme");
26
+ document.documentElement.classList.remove("dark");
27
+ }
28
+ const themeId = config.themeId;
29
+ const theme = manifest.themes.find(t => t.id === themeId);
30
+ if (!theme) { console.warn("[design-tokens] theme \"" + themeId + "\" not found"); return; }
31
+ const themeVars = theme[mode] ?? {};
32
+ if (Object.keys(themeVars).length === 0) { removeRootVars(THEME_STYLE_ID); }
33
+ else { injectRootVars(THEME_STYLE_ID, themeVars); }
34
+ const overrideVars = config.overrides?.[mode] ?? {};
35
+ if (Object.keys(overrideVars).length === 0) { removeRootVars(MODE_OVERRIDES_STYLE_ID); }
36
+ else { injectRootVars(MODE_OVERRIDES_STYLE_ID, overrideVars); }
37
+ }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  // Auto-generated — do not edit manually.
2
2
  export * from "./tokens.js";
3
- export { applyThemeConfig } from "./applyTheme.js";
3
+ export { applyThemeConfig, type ThemeConfig, type ThemeMode, type ThemeEntry } from "./applyThemeConfig.js";
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  // Auto-generated — do not edit manually.
2
2
  export * from "./tokens.js";
3
- export { applyThemeConfig } from "./applyTheme.js";
3
+ export { applyThemeConfig } from "./applyThemeConfig.js";
@@ -2,19 +2,10 @@
2
2
  "themes": [
3
3
  {
4
4
  "id": "gainsight-light",
5
- "label": "Light",
6
- "description": "Gainsight design system — default light theme",
7
- "selector": null,
8
- "cssFile": null,
9
- "variables": {}
10
- },
11
- {
12
- "id": "dark",
13
- "label": "Dark",
14
- "description": "Gainsight design system — dark mode",
15
- "selector": "[data-theme=\"dark\"]",
16
- "cssFile": "@gainsight-hub/design-tokens/themes/dark.css",
17
- "variables": {
5
+ "label": "Gainsight Default",
6
+ "description": "Gainsight design system — default theme",
7
+ "light": {},
8
+ "dark": {
18
9
  "--theme-neutral-0": "#2B3346",
19
10
  "--theme-neutral-100": "#3B4254",
20
11
  "--theme-neutral-200": "#4F5663",
@@ -50,41 +41,11 @@
50
41
  "--color-skeleton-subtle": "#3B4254"
51
42
  }
52
43
  },
53
- {
54
- "id": "legacy",
55
- "label": "Legacy",
56
- "description": "Gainsight legacy defaults (pre design-system migration)",
57
- "selector": "[data-theme=\"legacy\"]",
58
- "cssFile": "@gainsight-hub/design-tokens/themes/legacy.css",
59
- "variables": {
60
- "--theme-brand-600": "oklch(from var(--theme-brand-700) calc(l + 0.037) c h)",
61
- "--theme-brand-500": "oklch(from var(--theme-brand-700) calc(l + 0.100) c h)",
62
- "--theme-brand-400": "oklch(from var(--theme-brand-700) calc(l + 0.185) c h)",
63
- "--theme-brand-300": "oklch(from var(--theme-brand-700) calc(l + 0.270) c h)",
64
- "--theme-brand-200": "oklch(from var(--theme-brand-700) calc(l + 0.353) c h)",
65
- "--theme-brand-100": "oklch(from var(--theme-brand-700) calc(l + 0.415) c h)",
66
- "--theme-brand-800": "oklch(from var(--theme-brand-700) calc(l - 0.087) c h)",
67
- "--theme-brand-900": "oklch(from var(--theme-brand-700) calc(l - 0.184) c h)",
68
- "--theme-brand-1000": "oklch(from var(--theme-brand-700) calc(l - 0.279) c h)",
69
- "--theme-neutral-0": "#FFFFFF",
70
- "--theme-neutral-100": "oklch(from var(--theme-neutral-1000) calc(l + 0.654) calc(c * 0.003) h)",
71
- "--theme-neutral-200": "oklch(from var(--theme-neutral-1000) calc(l + 0.624) calc(c * 0.003) h)",
72
- "--theme-neutral-300": "oklch(from var(--theme-neutral-1000) calc(l + 0.567) calc(c * 0.042) h)",
73
- "--theme-neutral-400": "oklch(from var(--theme-neutral-1000) calc(l + 0.482) calc(c * 0.087) h)",
74
- "--theme-neutral-500": "oklch(from var(--theme-neutral-1000) calc(l + 0.361) calc(c * 0.383) h)",
75
- "--theme-neutral-600": "oklch(from var(--theme-neutral-1000) calc(l + 0.291) calc(c * 0.626) h)",
76
- "--theme-neutral-700": "oklch(from var(--theme-neutral-1000) calc(l + 0.219) calc(c * 0.888) h)",
77
- "--theme-neutral-800": "oklch(from var(--theme-neutral-1000) calc(l + 0.139) calc(c * 1.011) h)",
78
- "--theme-neutral-900": "oklch(from var(--theme-neutral-1000) calc(l + 0.066) calc(c * 1.045) h)"
79
- }
80
- },
81
44
  {
82
45
  "id": "mui",
83
46
  "label": "Material UI",
84
47
  "description": "Material Design 3–inspired theme",
85
- "selector": "[data-theme=\"mui\"]",
86
- "cssFile": "@gainsight-hub/design-tokens/themes/mui.css",
87
- "variables": {
48
+ "light": {
88
49
  "--theme-brand-100": "#E3F2FD",
89
50
  "--theme-brand-200": "#BBDEFB",
90
51
  "--theme-brand-300": "#90CAF9",
@@ -119,15 +80,14 @@
119
80
  "--color-status-success-bold": "#2E7D32",
120
81
  "--color-status-danger-bold": "#D32F2F",
121
82
  "--color-status-information-bold": "#0288D1"
122
- }
83
+ },
84
+ "dark": {}
123
85
  },
124
86
  {
125
87
  "id": "antd",
126
88
  "label": "Ant Design",
127
89
  "description": "Ant Design 5.x–inspired theme",
128
- "selector": "[data-theme=\"antd\"]",
129
- "cssFile": "@gainsight-hub/design-tokens/themes/antd.css",
130
- "variables": {
90
+ "light": {
131
91
  "--theme-brand-100": "#E6F4FF",
132
92
  "--theme-brand-200": "#BAE0FF",
133
93
  "--theme-brand-300": "#91CAFF",
@@ -162,15 +122,14 @@
162
122
  "--color-status-success-bold": "#52C41A",
163
123
  "--color-status-danger-bold": "#FF4D4F",
164
124
  "--color-status-information-bold": "#1677FF"
165
- }
125
+ },
126
+ "dark": {}
166
127
  },
167
128
  {
168
129
  "id": "spectrum",
169
130
  "label": "Adobe Spectrum",
170
131
  "description": "Adobe Spectrum–inspired theme",
171
- "selector": "[data-theme=\"spectrum\"]",
172
- "cssFile": "@gainsight-hub/design-tokens/themes/spectrum.css",
173
- "variables": {
132
+ "light": {
174
133
  "--theme-brand-100": "#EAF1FB",
175
134
  "--theme-brand-200": "#CBE0F8",
176
135
  "--theme-brand-300": "#A8CCF2",
@@ -205,7 +164,8 @@
205
164
  "--color-status-success-bold": "#008854",
206
165
  "--color-status-danger-bold": "#D7373F",
207
166
  "--color-status-information-bold": "#0265DC"
208
- }
167
+ },
168
+ "dark": {}
209
169
  }
210
170
  ],
211
171
  "defaultTheme": "gainsight-light"
@@ -12,26 +12,26 @@
12
12
  */
13
13
  [data-theme="legacy"] {
14
14
  --theme-brand-700: var(--config--main-color-brand, #0C66E4);
15
- --theme-brand-600: oklch(from var(--theme-brand-700) calc(l + 0.037) c h);
16
- --theme-brand-500: oklch(from var(--theme-brand-700) calc(l + 0.100) c h);
17
- --theme-brand-400: oklch(from var(--theme-brand-700) calc(l + 0.185) c h);
18
- --theme-brand-300: oklch(from var(--theme-brand-700) calc(l + 0.270) c h);
19
- --theme-brand-200: oklch(from var(--theme-brand-700) calc(l + 0.353) c h);
20
- --theme-brand-100: oklch(from var(--theme-brand-700) calc(l + 0.415) c h);
21
- --theme-brand-800: oklch(from var(--theme-brand-700) calc(l - 0.087) c h);
22
- --theme-brand-900: oklch(from var(--theme-brand-700) calc(l - 0.184) c h);
23
- --theme-brand-1000: oklch(from var(--theme-brand-700) calc(l - 0.279) c h);
15
+ --theme-brand-600: oklch(from var(--theme-brand-700) calc(l + 0.0712) c h);
16
+ --theme-brand-500: oklch(from var(--theme-brand-700) calc(l + 0.1443) c h);
17
+ --theme-brand-400: oklch(from var(--theme-brand-700) calc(l + 0.2163) c h);
18
+ --theme-brand-300: oklch(from var(--theme-brand-700) calc(l + 0.2875) c h);
19
+ --theme-brand-200: oklch(from var(--theme-brand-700) calc(l + 0.3584) c h);
20
+ --theme-brand-100: oklch(from var(--theme-brand-700) calc(l + 0.4309) c h);
21
+ --theme-brand-800: oklch(from var(--theme-brand-700) calc(l - 0.0842) c h);
22
+ --theme-brand-900: oklch(from var(--theme-brand-700) calc(l - 0.1674) c h);
23
+ --theme-brand-1000: oklch(from var(--theme-brand-700) calc(l - 0.2511) c h);
24
24
  --theme-neutral-1000: var(--config--main-color-night, #2B3346);
25
25
  --theme-neutral-0: #FFFFFF;
26
- --theme-neutral-100: oklch(from var(--theme-neutral-1000) calc(l + 0.654) calc(c * 0.003) h);
27
- --theme-neutral-200: oklch(from var(--theme-neutral-1000) calc(l + 0.624) calc(c * 0.003) h);
28
- --theme-neutral-300: oklch(from var(--theme-neutral-1000) calc(l + 0.567) calc(c * 0.042) h);
29
- --theme-neutral-400: oklch(from var(--theme-neutral-1000) calc(l + 0.482) calc(c * 0.087) h);
30
- --theme-neutral-500: oklch(from var(--theme-neutral-1000) calc(l + 0.361) calc(c * 0.383) h);
31
- --theme-neutral-600: oklch(from var(--theme-neutral-1000) calc(l + 0.291) calc(c * 0.626) h);
32
- --theme-neutral-700: oklch(from var(--theme-neutral-1000) calc(l + 0.219) calc(c * 0.888) h);
33
- --theme-neutral-800: oklch(from var(--theme-neutral-1000) calc(l + 0.139) calc(c * 1.011) h);
34
- --theme-neutral-900: oklch(from var(--theme-neutral-1000) calc(l + 0.066) calc(c * 1.045) h);
26
+ --theme-neutral-100: oklch(from var(--theme-neutral-1000) calc(l + 0.6097) calc(c * 0.1115) h);
27
+ --theme-neutral-200: oklch(from var(--theme-neutral-1000) calc(l + 0.5423) calc(c * 0.1931) h);
28
+ --theme-neutral-300: oklch(from var(--theme-neutral-1000) calc(l + 0.4735) calc(c * 0.2806) h);
29
+ --theme-neutral-400: oklch(from var(--theme-neutral-1000) calc(l + 0.4066) calc(c * 0.3733) h);
30
+ --theme-neutral-500: oklch(from var(--theme-neutral-1000) calc(l + 0.3392) calc(c * 0.5034) h);
31
+ --theme-neutral-600: oklch(from var(--theme-neutral-1000) calc(l + 0.2719) calc(c * 0.5672) h);
32
+ --theme-neutral-700: oklch(from var(--theme-neutral-1000) calc(l + 0.2031) calc(c * 0.6802) h);
33
+ --theme-neutral-800: oklch(from var(--theme-neutral-1000) calc(l + 0.1357) calc(c * 0.8035) h);
34
+ --theme-neutral-900: oklch(from var(--theme-neutral-1000) calc(l + 0.0692) calc(c * 0.8940) h);
35
35
  --color-action-primary-default: var(--config--main-color-brand, #0C66E4);
36
36
  --color-action-destructive-default: var(--config--main-color-alert, #c92c2f);
37
37
  --color-surface-page: var(--config-body-background-color, #FAFAFA);
package/dist/themes.css CHANGED
@@ -1,7 +1,6 @@
1
1
  /* All design tokens + every theme override in one import.
2
2
  Use this unless you need to control which themes are loaded separately. */
3
3
  @import "./styles.css";
4
- @import "./themes/dark.css";
5
4
  @import "./themes/legacy.css";
6
5
  @import "./themes/mui.css";
7
6
  @import "./themes/antd.css";
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": "0.1.0",
3
- "generatedAt": "2026-05-05T08:27:58.298Z",
3
+ "generatedAt": "2026-05-18T10:51:54.522Z",
4
4
  "scales": {
5
5
  "brand": {
6
6
  "seedVar": "--theme-brand-700",
package/package.json CHANGED
@@ -1,26 +1,31 @@
1
1
  {
2
2
  "name": "@gainsight-hub/design-tokens",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Design tokens: CSS variables, JSON, TypeScript constants, and Tailwind preset.",
5
5
  "license": "UNLICENSED",
6
6
  "author": "Gainsight Design Systems",
7
7
  "type": "module",
8
+ "main": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
8
10
  "files": ["dist"],
9
11
  "sideEffects": ["**/*.css"],
10
12
  "exports": {
11
13
  ".": {
12
14
  "types": "./dist/index.d.ts",
13
- "import": "./dist/index.js"
15
+ "import": "./dist/index.js",
16
+ "require": "./dist/index.js",
17
+ "default": "./dist/index.js"
14
18
  },
15
19
  "./styles.css": "./dist/styles.css",
16
20
  "./themes.css": "./dist/themes.css",
17
- "./themes/*": "./dist/themes/*.css",
21
+ "./themes/*": "./dist/themes/*",
18
22
  "./tailwind": {
19
23
  "import": "./dist/tailwind.preset.mjs",
20
24
  "require": "./dist/tailwind.preset.cjs"
21
25
  },
22
26
  "./tokens.json": "./dist/tokens.json",
23
- "./token-catalog.json": "./dist/token-catalog.json"
27
+ "./token-catalog.json": "./dist/token-catalog.json",
28
+ "./theme-manifest.json": "./dist/theme-manifest.json"
24
29
  },
25
30
  "scripts": {
26
31
  "build": "node ./build.js",
@@ -1,14 +0,0 @@
1
- // Auto-generated — do not edit manually.
2
-
3
- /**
4
- * Switches the active theme at runtime. Lazy-loads the theme CSS on first use.
5
- * Import styles.css first to establish the default light theme.
6
- *
7
- * @param themeId Theme to activate ("gainsight-dark", "legacy", "theme-mui", …).
8
- * Pass "gainsight-light" to restore the default.
9
- * @param overrides Optional CSS variable overrides applied on top of the base theme.
10
- */
11
- export declare function applyThemeConfig(
12
- themeId: string,
13
- overrides?: Record<string, string>,
14
- ): Promise<void>;
@@ -1,66 +0,0 @@
1
- // Auto-generated — do not edit manually.
2
- const THEME_CSS_URLS = {
3
- "dark": new URL("./themes/dark.css", import.meta.url).href,
4
- "legacy": new URL("./themes/legacy.css", import.meta.url).href,
5
- "mui": new URL("./themes/mui.css", import.meta.url).href,
6
- "antd": new URL("./themes/antd.css", import.meta.url).href,
7
- "spectrum": new URL("./themes/spectrum.css", import.meta.url).href,
8
- };
9
-
10
- const STYLE_ID = "__gs-theme-overrides";
11
- const _loaded = new Set();
12
-
13
- function loadCss(url) {
14
- if (_loaded.has(url)) return Promise.resolve();
15
- return new Promise((resolve, reject) => {
16
- const link = document.createElement("link");
17
- link.rel = "stylesheet";
18
- link.href = url;
19
- link.onload = () => { _loaded.add(url); resolve(); };
20
- link.onerror = () => reject(new Error("Failed to load theme CSS: " + url));
21
- document.head.appendChild(link);
22
- });
23
- }
24
-
25
- function injectOverrides(overrides) {
26
- const css = Object.entries(overrides).map(([k, v]) => " " + k + ": " + v + ";").join("\n");
27
- let el = document.getElementById(STYLE_ID);
28
- if (!el) { el = document.createElement("style"); el.id = STYLE_ID; document.head.appendChild(el); }
29
- el.textContent = ":root {\n" + css + "\n}";
30
- }
31
-
32
- function removeOverrides() {
33
- document.getElementById(STYLE_ID)?.remove();
34
- }
35
-
36
- /**
37
- * Switches the active theme at runtime.
38
- *
39
- * @param {string} themeId - Theme to activate. Use "gainsight-light" to restore the default.
40
- * @param {Record<string,string>} [overrides] - Optional CSS variable overrides applied on top.
41
- * @returns {Promise<void>}
42
- *
43
- * @example
44
- * import { applyThemeConfig } from "@gainsight-hub/design-tokens";
45
- *
46
- * await applyThemeConfig("gainsight-dark");
47
- * await applyThemeConfig("gainsight-dark", { "--theme-brand-700": "#FF6600" });
48
- * await applyThemeConfig("gainsight-light"); // restore default
49
- */
50
- export async function applyThemeConfig(themeId, overrides = {}) {
51
- const cssUrl = THEME_CSS_URLS[themeId];
52
-
53
- if (!cssUrl) {
54
- // Default / light theme — remove any active theme attribute
55
- document.documentElement.removeAttribute("data-theme");
56
- } else {
57
- await loadCss(cssUrl);
58
- document.documentElement.setAttribute("data-theme", themeId);
59
- }
60
-
61
- if (Object.keys(overrides).length === 0) {
62
- removeOverrides();
63
- } else {
64
- injectOverrides(overrides);
65
- }
66
- }
@@ -1,47 +0,0 @@
1
- /* Auto-generated — do not edit manually. Source: themes/dark/index.js */
2
- /**
3
- * Gainsight design system — dark mode
4
- *
5
- * Usage:
6
- * import "@gainsight-hub/design-tokens/styles.css"; // must load first
7
- * import "@gainsight-hub/design-tokens/themes/dark.css";
8
- * document.documentElement.setAttribute("data-theme", "dark");
9
- *
10
- * Restore default theme:
11
- * document.documentElement.removeAttribute("data-theme");
12
- */
13
- [data-theme="dark"] {
14
- --theme-neutral-0: #2B3346;
15
- --theme-neutral-100: #3B4254;
16
- --theme-neutral-200: #4F5663;
17
- --theme-neutral-300: #696E7C;
18
- --theme-neutral-400: #7B808E;
19
- --theme-neutral-500: #8D919B;
20
- --theme-neutral-600: #B8BBC2;
21
- --theme-neutral-700: #DEDFE2;
22
- --theme-neutral-800: #F4F5F6;
23
- --theme-neutral-900: #FAFAFA;
24
- --theme-neutral-1000: #FFFFFF;
25
- --config-hero-color: #FFFFFF;
26
- --theme-brand-100: #1C2B41;
27
- --theme-brand-200: #09326C;
28
- --theme-brand-300: #0055CC;
29
- --theme-brand-400: #0C66E4;
30
- --theme-brand-500: #1D7AFC;
31
- --theme-brand-600: #388BFF;
32
- --theme-brand-700: #579DFF;
33
- --theme-brand-800: #85B8FF;
34
- --theme-brand-900: #CCE0FF;
35
- --theme-brand-1000: #E9F2FF;
36
- --color-status-success-bold: #4BCE7F;
37
- --color-status-information-bold: #579DFF;
38
- --color-status-danger-bold: #F86A68;
39
- --color-community-answered: #4BCE7F;
40
- --color-community-highlighted: #F5CD47;
41
- --color-community-pinned: #579DFF;
42
- --color-overlay-interactive-hover: rgba(255, 255, 255, 0.08);
43
- --color-overlay-interactive-pressed: rgba(255, 255, 255, 0.14);
44
- --color-overlay-backdrop: rgba(9, 30, 66, 0.72);
45
- --color-skeleton-default: #4F5663;
46
- --color-skeleton-subtle: #3B4254;
47
- }
@@ -1,2 +0,0 @@
1
- // CSS side-effect only — activates [data-theme="dark"] overrides, no exports.
2
- export {};