component-variants
Component Variants Pattern
Create matching light and dark variants of UI components using a systematic color token approach.
Pattern Overview
- Create paired components:
ComponentLightandComponentDark - Mirror the structure exactly between variants
- Map colors systematically using the token table below
- Export a unified component that renders both or accepts a
variantprop
Color Token Mapping
Basic Tokens
| Semantic Use | Light Mode | Dark Mode |
|---|---|---|
| Card background | bg-[#f8f8f8] |
bg-zinc-800 |
| Card border | border-zinc-200/80 |
border-zinc-700/80 |
| Content area | bg-white |
bg-zinc-900 |
| Primary text | text-zinc-900 |
text-zinc-100 |
| Secondary text | text-zinc-600 |
text-zinc-400 |
| Muted text | text-zinc-500 |
text-zinc-500 |
| Icon color | text-zinc-400 |
text-zinc-500 |
| Tag background | bg-zinc-100 |
bg-zinc-800 border border-zinc-700 |
| Tag text | text-zinc-600 |
text-zinc-400 |
| Accent background | bg-green-50 |
bg-green-900/50 |
| Accent text | text-green-700 |
text-green-400 |
| Shadow | shadow-zinc-200/50 |
shadow-black/30 |
| Hover background | hover:bg-zinc-100/50 |
hover:bg-zinc-700/30 |
Gradient & Nested Card Tokens
| Semantic Use | Light Mode | Dark Mode |
|---|---|---|
| Outer card gradient | bg-gradient-to-b from-[#e8e8ea] to-[#dcdce0] |
bg-gradient-to-b from-zinc-700 to-zinc-800 |
| Outer card border | border-white/60 |
border-zinc-600/40 |
| Outer card shadow | shadow-xl shadow-zinc-400/30 |
shadow-xl shadow-black/50 |
| Inner media border | border-white/40 |
border-zinc-600/30 |
Badge Tokens
| Semantic Use | Light Mode | Dark Mode |
|---|---|---|
| Success badge bg | bg-[#d4f5d4] |
bg-emerald-900/40 |
| Success badge text | text-zinc-700 |
text-emerald-400 |
Separator Tokens
| Semantic Use | Light Mode | Dark Mode |
|---|---|---|
| Dot separator | text-zinc-300 |
text-zinc-600 |
| Border separator | border-zinc-300 |
border-zinc-700 |
Implementation Template
// 1. Create the Light variant
function ComponentLight() {
return (
<div className="bg-[#f8f8f8] rounded-xl border border-zinc-200/80 shadow-lg shadow-zinc-200/50">
<div className="bg-white px-4 py-4">
<span className="text-zinc-900">Primary content</span>
<span className="text-zinc-500">Secondary content</span>
</div>
</div>
);
}
// 2. Create the Dark variant (mirror structure, swap tokens)
function ComponentDark() {
return (
<div className="bg-zinc-800 rounded-xl border border-zinc-700/80 shadow-lg shadow-black/30">
<div className="bg-zinc-900 px-4 py-4">
<span className="text-zinc-100">Primary content</span>
<span className="text-zinc-500">Secondary content</span>
</div>
</div>
);
}
// 3. Export unified component
export function Component({ variant = "light" }: { variant?: "light" | "dark" }) {
return variant === "dark" ? <ComponentDark /> : <ComponentLight />;
}
Helper Components Pattern
When components have repeated sub-elements, create paired helpers:
interface InfoRowProps {
icon: React.ReactNode;
label: string;
value: React.ReactNode;
}
function InfoRowLight({ icon, label, value }: InfoRowProps) {
return (
<div className="flex items-center gap-3 py-1">
<span className="text-zinc-400">{icon}</span>
<span className="text-zinc-500 text-sm w-32">{label}</span>
<div className="flex-1">{value}</div>
</div>
);
}
function InfoRowDark({ icon, label, value }: InfoRowProps) {
return (
<div className="flex items-center gap-3 py-1">
<span className="text-zinc-500">{icon}</span>
<span className="text-zinc-500 text-sm w-32">{label}</span>
<div className="flex-1">{value}</div>
</div>
);
}
Checklist
- Light and dark variants have identical structure
- All color classes mapped according to token table
- Text contrast meets accessibility guidelines
- Shadows appropriate for each theme
- Hover/focus states defined for both themes
More from ainergiz/design-inspirations
glassmorphism
Creates frosted glass UI elements with blur, transparency, and subtle borders. Use when building overlays, floating controls, tooltips, or any element that should appear elevated with a translucent background.
170image-carousel
Creates image carousels with hover-activated auto-advance, touch swipe support, and animated progress indicators. Use when building image galleries, product showcases, or any multi-image display with navigation.
6stacked-cards
Creates horizontally fanned/cascading card stacks with proper z-index ordering and hover lift animations. Use when building album browsers, card fans, stacked previews, or any overlapping card collection.
5nested-card
Creates cards with an outer gradient container and inner content card. Use when building premium card designs with depth, layered card layouts, or cards with image sections and content sections.
5expandable-card
Creates expandable/collapsible cards using CSS grid-rows animation with smooth transitions. Use when building accordions, expandable panels, collapsible sections, or show/hide card content.
5create-new-design
Scaffolds a new design in the design-inspirations repo with preview component, detail page, and main page entry. Use when creating a new design, adding a design inspiration, or scaffolding design files.
5