Product UIs need variants: primary vs danger buttons, compact vs comfortable tables. In React you model variants as props and map them to class names or style tokens—keep the mapping in one place so designers and engineers share vocabulary.
Variant maps
const variantClass: Record<'primary' | 'ghost', string> = {
primary: 'btn btn-primary',
ghost: 'btn btn-ghost',
};
function Button({ variant = 'primary', children }) {
return <button className={variantClass[variant]}>{children}</button>;
}
Boolean modifiers
Append modifier classes when flags are true: isActive && 'is-active'. For many flags, build an array and filter(Boolean).join(' ') to avoid double spaces.
Pitfalls
- Recreating style objects inline every render can break memoized children—extract stable objects or use classes.
- String concatenation typos silently fail—TypeScript unions for variant props catch mistakes early.
Self-check
- Why is a
Record<Variant, string>better than three nested ternaries? - How would you add a
size="sm" | "md"prop alongsidevariant?