component-variants

v2026.09.25

Creates light and dark mode component variants with consistent color token mapping. Use when building dual-theme components, creating light/dark UI pairs, or implementing theme-aware designs.

GitHub
Install command
npx skhub add ainergiz/component-variants
Markdown
SKILL.md

Component Variants Pattern

Create matching light and dark variants of UI components using a systematic color token approach.

Pattern Overview

  1. Create paired components: ComponentLight and ComponentDark
  2. Mirror the structure exactly between variants
  3. Map colors systematically using the token table below
  4. Export a unified component that renders both or accepts a variant prop

Color Token Mapping

Basic Tokens

Semantic UseLight ModeDark Mode
Card backgroundbg-[#f8f8f8]bg-zinc-800
Card borderborder-zinc-200/80border-zinc-700/80
Content areabg-whitebg-zinc-900
Primary texttext-zinc-900text-zinc-100
Secondary texttext-zinc-600text-zinc-400
Muted texttext-zinc-500text-zinc-500
Icon colortext-zinc-400text-zinc-500
Tag backgroundbg-zinc-100bg-zinc-800 border border-zinc-700
Tag texttext-zinc-600text-zinc-400
Accent backgroundbg-green-50bg-green-900/50
Accent texttext-green-700text-green-400
Shadowshadow-zinc-200/50shadow-black/30
Hover backgroundhover:bg-zinc-100/50hover:bg-zinc-700/30

Gradient & Nested Card Tokens

Semantic UseLight ModeDark Mode
Outer card gradientbg-gradient-to-b from-[#e8e8ea] to-[#dcdce0]bg-gradient-to-b from-zinc-700 to-zinc-800
Outer card borderborder-white/60border-zinc-600/40
Outer card shadowshadow-xl shadow-zinc-400/30shadow-xl shadow-black/50
Inner media borderborder-white/40border-zinc-600/30

Badge Tokens

Semantic UseLight ModeDark Mode
Success badge bgbg-[#d4f5d4]bg-emerald-900/40
Success badge texttext-zinc-700text-emerald-400

Separator Tokens

Semantic UseLight ModeDark Mode
Dot separatortext-zinc-300text-zinc-600
Border separatorborder-zinc-300border-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
Discovery
Tags

No tags published for this skill.

Version
Latest version metadata

Version

v2026.09.25

Published

Sep 25, 2026

Category

Uncategorized

License

Not specified

Source path

.claude/skills/component-variants

Default branch

main

Latest commit

697155e

Tree SHA

4d00112