Zudo Token Panel

Type to search...

to open search from anywhere

Custom color cluster

このページはまだ翻訳されていません。原文のまま表示しています。

Wire a non-default palette plus a semantic token table into the panel's Color tab.

The package ships zero baked-in color data. The host owns the palette template, the base roles, the semantic table, and the scheme registry. This recipe walks through wiring a fresh ColorClusterConfig for a new project.

For the authoritative shape and apply-time semantics, see Color cluster reference. Below is the minimum viable cluster that compiles against the public exports.

1. Define the cluster

Pick CSS variable names that match your stylesheet. The {n} placeholder in paletteCssVarTemplate is replaced with the palette index at apply time.

// src/lib/my-color-cluster.ts
import type {
  ColorClusterConfig,
  ColorScheme,
} from '@takazudo/zudo-design-token-panel';

const defaultDark: ColorScheme = {
  background: 0,
  foreground: 7,
  cursor: 7,
  selectionBg: 8,
  selectionFg: 0,
  palette: [
    '#1e1e2e', // p0 — base background
    '#f38ba8', // p1 — red
    '#a6e3a1', // p2 — green
    '#f9e2af', // p3 — yellow
    '#89b4fa', // p4 — blue
    '#cba6f7', // p5 — magenta
    '#94e2d5', // p6 — cyan
    '#cdd6f4', // p7 — base foreground
    '#45475a', // p8 — bright black
    '#f38ba8',
    '#a6e3a1',
    '#f9e2af',
    '#89b4fa',
    '#cba6f7',
    '#94e2d5',
    '#bac2de',
  ],
  shikiTheme: 'github-dark',
  // Overrides for individual semantics. Anything omitted falls back to
  // `cluster.semanticDefaults`.
  semantic: {
    primary: 4,
    accent: 5,
    danger: 1,
    success: 2,
    warning: 3,
    muted: 8,
  },
};

export const myColorCluster: ColorClusterConfig = {
  id: 'myapp',
  label: 'MyApp Brand',
  paletteSize: 16,
  paletteCssVarTemplate: '--myapp-p{n}',
  baseRoles: {
    background: '--myapp-color-bg',
    foreground: '--myapp-color-fg',
    cursor: '--myapp-color-cursor',
    selectionBg: '--myapp-color-selection-bg',
    selectionFg: '--myapp-color-selection-fg',
  },
  baseDefaults: {
    background: 0,
    foreground: 7,
    cursor: 7,
    selectionBg: 8,
    selectionFg: 0,
  },
  semanticDefaults: {
    primary: 4,
    accent: 5,
    danger: 1,
    success: 2,
    warning: 3,
    muted: 8,
  },
  semanticCssNames: {
    primary: '--myapp-color-primary',
    accent: '--myapp-color-accent',
    danger: '--myapp-color-danger',
    success: '--myapp-color-success',
    warning: '--myapp-color-warning',
    muted: '--myapp-color-muted',
  },
  defaultShikiTheme: 'github-dark',
  colorSchemes: {
    'Default Dark': defaultDark,
  },
  panelSettings: {
    colorScheme: 'Default Dark',
    // Single-mode site. See secondary-cluster-or-disable for the light/dark
    // pairing pattern.
    colorMode: false,
  },
};

ℹ️ Info

paletteSize must match every palette array. The validator (called automatically by the Astro adapter) throws when a ColorScheme.palette does not match paletteSize. Keep them in lockstep when you add or rename slots.

2. Plug it into configurePanel

Pass the cluster to configurePanel (the configure-once entry point) along with the rest of PanelConfig. The token manifest can stay minimal while you focus on color — the four arrays are required by the type but may be empty.

// src/lib/my-panel-config.ts
import type { PanelConfig } from '@takazudo/zudo-design-token-panel';
import { myColorCluster } from './my-color-cluster';

export const myPanelConfig: PanelConfig = {
  storagePrefix: 'myapp-design-token-panel',
  consoleNamespace: 'myapp',
  modalClassPrefix: 'myapp-design-token-panel-modal',
  schemaId: 'myapp-design-tokens/v1',
  exportFilenameBase: 'myapp-design-tokens',
  tokens: {
    spacing: [],
    typography: [],
    size: [],
    color: [],
  },
  colorCluster: myColorCluster,
};

See <code>configurePanel</code> reference for the full list of PanelConfig fields.

3. Match your stylesheet

The panel writes to :root using the names you declared. Your stylesheet needs to consume them — usually via fallback defaults so the page paints even before any user override:

/* src/styles/tokens.css */
:root {
  --myapp-p0: #1e1e2e;
  --myapp-p1: #f38ba8;
  /* …rest of the 16-tuple… */

  --myapp-color-bg: var(--myapp-p0);
  --myapp-color-fg: var(--myapp-p7);
  --myapp-color-primary: var(--myapp-p4);
  --myapp-color-accent: var(--myapp-p5);
  --myapp-color-danger: var(--myapp-p1);
  --myapp-color-success: var(--myapp-p2);
  --myapp-color-warning: var(--myapp-p3);
  --myapp-color-muted: var(--myapp-p8);
}

💡 Tip

The panel never reads these declarations — it only writes through document.documentElement.style.setProperty(...). Treat your stylesheet as the source of the defaults; treat the panel as a layer of inline overrides on top.

4. Add a second scheme (optional)

Schemes appear in the Color tab “Scheme…” dropdown. Add as many as you like; their order is the insertion order of colorSchemes.

const defaultLight: ColorScheme = {
  background: 0,
  foreground: 7,
  cursor: 7,
  selectionBg: 8,
  selectionFg: 0,
  palette: [
    '#fafafa', '#d20f39', '#40a02b', '#df8e1d',
    '#1e66f5', '#8839ef', '#179299', '#4c4f69',
    '#9ca0b0', '#d20f39', '#40a02b', '#df8e1d',
    '#1e66f5', '#8839ef', '#179299', '#5c5f77',
  ],
  shikiTheme: 'github-light',
};

// then, inside myColorCluster:
colorSchemes: {
  'Default Dark': defaultDark,
  'Default Light': defaultLight,
},

If you also want true light/dark switching driven by the page’s data-theme attribute, see the secondary cluster recipe and the Color cluster reference section on panelSettings.colorMode.

  • Color cluster reference — full type contract, JSON-serializability rule, and apply-time write order.
  • Panel CSS tokens — overriding the panel’s chrome colors (separate from your app’s color cluster).
  • Lazy color presets — keep a large preset library out of the SSR config blob.

Revision History