Styling Decision Tree
Tailwind class exists? → className="..."
Dynamic value? → style={{ width: ${x}% }}
Conditional styles? → cn("base", condition && "variant")
Static only? → className="..." (no cn() needed)
Library can't use class?→ style prop with var() constants
Critical Rules Never Use var() in className // ❌ NEVER: var() in className
// ✅ ALWAYS: Use Tailwind semantic classes
Never Use Hex Colors // ❌ NEVER: Hex colors in className
// ✅ ALWAYS: Use Tailwind color classes
The cn() Utility import { clsx } from "clsx"; import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); }
When to Use cn() // ✅ Conditional classes
// ✅ Merging with potential conflicts // className might override
// ✅ Multiple conditions
When NOT to Use cn() // ❌ Static classes - unnecessary wrapper
// ✅ Just use className directly
Style Constants for Charts/Libraries
When libraries don't accept className (like Recharts):
// ✅ Constants with var() - ONLY for library props const CHART_COLORS = { primary: "var(--color-primary)", secondary: "var(--color-secondary)", text: "var(--color-text)", gridLine: "var(--color-border)", };
// Usage with Recharts (can't use className)
Dynamic Values // ✅ style prop for truly dynamic values
// ✅ CSS custom properties for theming
Common Patterns Flexbox
Grid
Spacing // Padding
// All sides
// Horizontal, vertical
// Top, bottom
// Margin
// Center horizontally
Typography
Borders & Shadows
States
Responsive
Dark Mode
Arbitrary Values (Escape Hatch) // ✅ OK for one-off values not in design system
// ❌ Don't use for colors - use theme instead
// NO
← 返回排行榜