/** * Generic category → visual token map. * * Maps a node-type category (free string, e.g. the backend * NodeType.Category choices) to a small token bundle the renderer can use. * Tokens are framework-agnostic (CSS custom-property friendly hex + a * Tailwind-ish class hint) so this stays in pure-TS land — no React here. * * Categories mirror the backend NodeType.Category text choices but the * map is open: unknown categories resolve to DEFAULT_CATEGORY_TOKEN. */ export interface CategoryToken { /** Stable category key. */ category: string; /** Human label. */ label: string; /** Accent color (hex) for borders/handles. */ color: string; /** Background tint (hex). */ background: string; /** Foreground/text color (hex). */ foreground: string; /** Icon hint (lucide-react icon name) — consumed by a later React epic. */ icon: string; } /** Fallback token for unknown categories. */ export const DEFAULT_CATEGORY_TOKEN: CategoryToken = { category: 'default', label: 'Node', color: '#64748b', // slate-500 background: '#f1f5f9', // slate-100 foreground: '#0f172a', // slate-900 icon: 'Box', }; /** * Built-in category tokens. Keys match backend NodeType.Category values. */ export const CATEGORY_TOKENS: Record = { trigger: { category: 'trigger', label: 'Trigger', color: '#16a34a', // green-600 background: '#dcfce7', // green-100 foreground: '#14532d', // green-900 icon: 'Zap', }, action: { category: 'action', label: 'Action', color: '#2563eb', // blue-600 background: '#dbeafe', // blue-100 foreground: '#1e3a8a', // blue-900 icon: 'Play', }, condition: { category: 'condition', label: 'Condition', color: '#d97706', // amber-600 background: '#fef3c7', // amber-100 foreground: '#78350f', // amber-900 icon: 'GitBranch', }, transform: { category: 'transform', label: 'Transform', color: '#7c3aed', // violet-600 background: '#ede9fe', // violet-100 foreground: '#4c1d95', // violet-900 icon: 'Shuffle', }, subworkflow: { category: 'subworkflow', label: 'Sub-workflow', color: '#0891b2', // cyan-600 background: '#cffafe', // cyan-100 foreground: '#164e63', // cyan-900 icon: 'Workflow', }, control: { category: 'control', label: 'Control', color: '#db2777', // pink-600 background: '#fce7f3', // pink-100 foreground: '#831843', // pink-900 icon: 'Settings2', }, }; /** Resolve a category token, falling back to the default. */ export function getCategoryToken(category: string | undefined): CategoryToken { if (!category) return DEFAULT_CATEGORY_TOKEN; return CATEGORY_TOKENS[category] ?? DEFAULT_CATEGORY_TOKEN; }