@gainsight-hub/design-tokens
v0.1.1
Published
Design tokens: CSS variables, JSON, TypeScript constants, and Tailwind preset.
Readme
@gainsight-hub/design-tokens
Design tokens for the Gainsight Community Hub — CSS custom properties, TypeScript constants, JSON, and a Tailwind v3 preset.
Install
npm install @gainsight-hub/design-tokensQuick start
Import styles.css once at your app entry point. That's it for most apps.
// main.js / main.ts
import "@gainsight-hub/design-tokens/styles.css";Then use tokens anywhere via CSS custom properties:
.button {
background: var(--color-action-primary-default);
color: var(--color-content-inverse);
border-radius: var(--button-radius);
}CSS custom properties
Base (light theme)
Defines all tokens as CSS custom properties on :root. This is the default light theme.
import "@gainsight-hub/design-tokens/styles.css";All themes bundled
Includes the base tokens plus all theme overrides in a single file. Use this if you want to switch themes at runtime without loading additional stylesheets.
import "@gainsight-hub/design-tokens/themes.css";Individual themes
Load only the theme you need on top of styles.css:
import "@gainsight-hub/design-tokens/styles.css";
import "@gainsight-hub/design-tokens/themes/dark.css";Available themes:
| Import path | Description |
|---|---|
| @gainsight-hub/design-tokens/themes/dark.css | Gainsight dark mode |
| @gainsight-hub/design-tokens/themes/legacy.css | Legacy variable aliases |
| @gainsight-hub/design-tokens/themes/mui.css | Material UI overrides |
| @gainsight-hub/design-tokens/themes/antd.css | Ant Design overrides |
| @gainsight-hub/design-tokens/themes/spectrum.css | Adobe Spectrum overrides |
Theme switching at runtime
All CSS custom properties can be scoped and overridden at any level:
/* Scope to a data attribute */
[data-theme="dark"] {
--color-surface-page: #161618;
--color-content-default: #f4f5f7;
}
/* Scope to a tenant / white-label */
[data-tenant="acme"] {
--color-action-primary-default: #e63946;
--button-primary-background-default: #e63946;
}TypeScript / JavaScript
Import typed token constants directly. All exports are fully typed via the bundled tokens.d.ts.
import {
ColorActionPrimaryDefault,
ColorSurfacePage,
RadiusFull,
} from "@gainsight-hub/design-tokens";
// Use in JS logic — e.g. canvas drawing, charting libs
ctx.fillStyle = ColorActionPrimaryDefault; // "#0C66E4"Tailwind v3
Step 1 — Import the CSS variables
The Tailwind preset generates utility classes that reference CSS custom properties. Import styles.css so those variables are defined on the page.
// main.js / main.ts
import "@gainsight-hub/design-tokens/styles.css";Step 2 — Add the preset to your Tailwind config
ESM (Vite, Next.js, modern setups):
// tailwind.config.js
import preset from "@gainsight-hub/design-tokens/tailwind";
export default {
content: ["./src/**/*.{html,js,ts,jsx,tsx}"],
presets: [preset],
};CJS (older Tailwind v3 configs):
// tailwind.config.cjs
const preset = require("@gainsight-hub/design-tokens/tailwind");
module.exports = {
content: ["./src/**/*.{html,js,ts,jsx,tsx}"],
presets: [preset],
};Step 3 — Use token-based utility classes
<!-- Colors -->
<div class="bg-action-primary text-content-inverse">Primary button</div>
<div class="bg-surface-default text-content-default">Card</div>
<div class="bg-status-success-bold text-content-inverse">Success badge</div>
<!-- Spacing -->
<div class="p-spacing-200 gap-spacing-100">Layout</div>
<!-- Border radius -->
<div class="rounded-radius-100">Small</div>
<div class="rounded-radius-full">Pill / avatar</div>
<!-- Typography -->
<p class="text-sm leading-normal font-medium">Body text</p>
<!-- Shadows -->
<div class="shadow-elevation-1">Raised card</div>Color token naming — the -default suffix collapses into the base class:
| Tailwind class | CSS variable |
|---|---|
| bg-action-primary | var(--color-action-primary-default) |
| bg-action-primary-hover | var(--color-action-primary-hover) |
| bg-surface-page | var(--color-surface-page) |
| text-content-subtle | var(--color-content-subtle) |
| border-line-default | var(--color-line-default) |
Why import both
styles.cssand the preset?styles.cssdefines the CSS custom property values. The preset generates utility classes that reference those variables withvar(--token-name). The preset alone produces no colors — it needs the variables defined on the page. This separation enables runtime theming: change a CSS variable at any scope and every Tailwind class using that token updates automatically, with no rebuild.
Component tokens (CSS Modules)
For component internals, use CSS Modules with var() directly:
/* Button.module.css */
.root {
background: var(--button-primary-background-default);
color: var(--button-primary-label-default);
border-radius: var(--button-radius);
padding: var(--space-100) var(--space-200);
}
.root:hover {
background: var(--button-primary-background-hover);
}// Button.tsx
import styles from "./Button.module.css";
export function Button({ children }: { children: React.ReactNode }) {
return <button className={styles.root}>{children}</button>;
}JSON
Raw token values as nested JSON. Useful for tooling, build scripts, or non-web targets (e.g. React Native, Figma plugins).
import tokens from "@gainsight-hub/design-tokens/tokens.json" with { type: "json" };
const primary = tokens.color.action.primary.default.value; // "#0C66E4"
const gutter = tokens.space.layout.gutter.value; // "12px"Token catalog
Structured catalog with resolved values, descriptions, alias chains, and legacy mappings. Used by the design portal and design tooling.
import catalog from "@gainsight-hub/design-tokens/token-catalog.json" with { type: "json" };
// 224 tokens with cssVar, path, type, value, description, references, legacyMapping
catalog.all.forEach(token => console.log(token.cssVar, token.value));Runtime theme switching
Switch the active theme at runtime — no page reload required. applyThemeConfig lazy-loads the theme CSS on first use via import.meta.url, so only the themes you actually activate are fetched.
import "@gainsight-hub/design-tokens/styles.css"; // load base tokens first
import { applyThemeConfig } from "@gainsight-hub/design-tokens";
// Switch to dark mode
await applyThemeConfig("gainsight-dark");
// Dark mode + custom brand color override
await applyThemeConfig("gainsight-dark", { "--theme-brand-700": "#FF6600" });
// Restore default light theme
await applyThemeConfig("gainsight-light");Available theme IDs: gainsight-light (default), dark, legacy, mui, antd, spectrum.
Available exports
| Import | Description |
|---|---|
| @gainsight-hub/design-tokens | applyThemeConfig + TypeScript/JS named constants |
| @gainsight-hub/design-tokens/styles.css | CSS custom properties — base light theme |
| @gainsight-hub/design-tokens/themes.css | CSS custom properties — all themes bundled |
| @gainsight-hub/design-tokens/themes/* | Individual theme overrides (load on top of styles.css) |
| @gainsight-hub/design-tokens/tailwind | Tailwind v3 preset (ESM + CJS) |
| @gainsight-hub/design-tokens/tokens.json | Nested JSON — raw token values |
| @gainsight-hub/design-tokens/token-catalog.json | Full catalog with resolved values, descriptions, alias chains |
Package structure
packages/design-tokens/
├── src/ Token source files (Style Dictionary format)
│ ├── primitive/ Raw scales — color, space, radius, font, shadow
│ ├── semantic/ Semantic roles — action, surface, content, line, status
│ └── component/ Component tokens — button, card, feed, navigation, widget
├── config/ Style Dictionary config and custom formats
│ └── themes/ Theme override definitions
├── migration/ Legacy variable mapping tools
├── build.js Build entry point
└── dist/ Published output (generated, do not edit)
├── index.js Root entry — applyThemeConfig + token constants
├── index.d.ts TypeScript declarations for root entry
├── applyTheme.js Runtime theme switcher (lazy CSS loading)
├── applyTheme.d.ts TypeScript declarations for applyThemeConfig
├── tokens.js JS named constants
├── tokens.d.ts TypeScript declarations for token constants
├── styles.css CSS custom properties (base light theme)
├── themes.css All themes combined (styles.css + all theme overrides)
├── tokens.json Nested JSON
├── token-catalog.json Full token catalog
├── tailwind.preset.mjs Tailwind preset (ESM)
├── tailwind.preset.cjs Tailwind preset (CJS)
└── themes/ Individual theme CSS filesBuilding and publishing
# Build from the monorepo root
turbo run build --filter=@gainsight-hub/design-tokens
# Publish
npm publish --access public -w packages/design-tokens