/** * Globals Panel — left-side panel with Colors & Typography token lists * * Two tabs: Colors | Typography * Each shows a scrollable list of tokens with inline editors. */ import { useState } from 'react' import { Button } from '@/components/ui/button' import { ScrollArea } from '@/components/ui/scroll-area' import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs' import { Palette, Type, Plus } from 'lucide-react' import { GlobalStyles, GlobalColor, GlobalTypography } from '../config' import { ColorEditor } from './color-editor' import { TypographyEditor } from './typography-editor' interface GlobalsPanelProps { settings: GlobalStyles onChange: (updated: GlobalStyles) => void } /** Generate a unique slug from a name */ function slugify(name: string): string { return name .toLowerCase() .replace(/[^a-z0-9]+/g, '-') .replace(/^-|-$/g, '') || `token-${Date.now()}` } export function GlobalsPanel({ settings, onChange }: GlobalsPanelProps) { const [activeTab, setActiveTab] = useState<'colors' | 'typography'>('colors') /* ── Color helpers ──────────────────────────────────────── */ const updateColor = (index: number, updated: GlobalColor) => { const next = [...settings.colors] next[index] = updated onChange({ ...settings, colors: next }) } const addColor = () => { const newColor: GlobalColor = { id: slugify(`custom-${settings.colors.length + 1}`), name: `Custom ${settings.colors.length + 1}`, value: '#6366f1', isDefault: false, } onChange({ ...settings, colors: [...settings.colors, newColor] }) } const deleteColor = (index: number) => { const next = settings.colors.filter((_: GlobalColor, i: number) => i !== index) onChange({ ...settings, colors: next }) } /* ── Typography helpers ─────────────────────────────────── */ const updateTypography = (index: number, updated: GlobalTypography) => { const next = [...settings.typography] next[index] = updated onChange({ ...settings, typography: next }) } const addTypography = () => { const newTypo: GlobalTypography = { id: slugify(`custom-font-${settings.typography.length + 1}`), name: `Custom Font ${settings.typography.length + 1}`, fontFamily: '', fontWeight: '400', fontSize: '', lineHeight: '', letterSpacing: '', textTransform: 'none', isDefault: false, } onChange({ ...settings, typography: [...settings.typography, newTypo] }) } const deleteTypography = (index: number) => { const next = settings.typography.filter((_: GlobalTypography, i: number) => i !== index) onChange({ ...settings, typography: next }) } return (