Learn · Practical guides

Color in component libraries

A color palette only becomes useful when it's mapped to real components. Buttons, alerts, badges and chips all need consistent color roles so that users can quickly see what's primary, what's secondary and what's just background.

1.

Think in roles, not raw colors

Instead of assigning raw colors directly to components (button = #2563eb), define semantic roles and map palette values to them:

primaryblue-500
primary.hoverblue-600
background.defaultgray-50
text.primarygray-900
successgreen-500
warningamber-500
errorred-500

Your components consume roles instead of hex codes, making it easy to change themes later — light/dark or brand variations — and keep colors consistent across the whole library.

2.

A minimal Tailwind‑style base palette

The examples in this page are built from a simple palette: blue as the primary hue, gray as the neutral scale, and green/amber/red as semantic colors.

blue-400
blue-500
blue-600
blue-700
gray-50
gray-100
gray-200
gray-900
green-500
amber-500
red-500
3.

Buttons

Buttons are the most obvious place where primary/secondary roles show up.

Primary button — bg: blue-500, text: white, hover: blue-600

Secondary button — bg: white/gray-100, border: gray-200, text: gray-900

Ghost / tertiary — transparent, text: blue-600, hover: bg blue-50

4.

Alerts and banners

For each status, use a very light tint for the background, a slightly stronger shade for the border, the main semantic color for the icon, and neutrals for text.

Success · Warning · Error · Info alerts

✓
Success · Your changes have been saved.
⚠
Warning · Your trial expires in 3 days.
✕
Error · Could not connect to the server.
i
Info · A new version is available.
5.

Badges and chips

Badges are compact — color must work at small sizes. Three common variants: solid (high emphasis), subtle (low emphasis) and outline.

Solid · Subtle · Outline badges

SuccessSolidSubtleOutline
WarningSolidSubtleOutline
ErrorSolidSubtleOutline
6.

Chips, pills and toggles

Chips represent selections or filters. "Selected = some version of primary" is the consistent rule.

Unselected and selected chips

DesignEngineeringMarketingProduct

Toggle / switch — off: gray-200, on: blue-500, thumb: white

Off
On
7.

Inputs, text fields and forms

Inputs mostly use neutrals with an accent for focus and semantic colors for error/success.

Default · Focus · Error · Success input states

Default
Enter your email
Focus
Enter your email
Error
Enter your email
Please enter a valid email address.
Success
mikael@example.com
Looks good!
8.

Building a simple theme system

Using the palette above, a minimal theme object ties everything together. Each component binds to roles — not hex codes — so the entire library can be rebranded by changing the values in one place.

const theme = {
  bg: {
    default:  'gray-50',   // page background
    surface:  'gray-100',  // cards, panels
    inset:    'white',     // inputs, nested surfaces
  },
  text: {
    primary:  'gray-900',
    secondary:'gray-700',
    inverted: 'white',
  },
  border: {
    default:  'gray-200',
    strong:   'gray-300',
    focus:    'blue-500',
  },
  primary: {
    bg:       'blue-500',
    bgHover:  'blue-600',
    subtleBg: 'blue-50',
    text:     'white',
    outline:  'blue-500',
  },
  status: {
    success: { bg:'green-50',  border:'green-200',  icon:'green-500'  },
    warning: { bg:'amber-50',  border:'amber-200',  icon:'amber-500'  },
    error:   { bg:'red-50',    border:'red-200',    icon:'red-500'    },
    info:    { bg:'blue-50',   border:'blue-200',   icon:'blue-500'   },
  },
}

What each component binds to

  • Button — theme.primary.*
  • Alert — theme.status.* and theme.text.*
  • Card — theme.bg.surface, theme.border.default, theme.text.primary
  • Input — theme.border.default/focus, theme.text.primary, theme.bg.inset

Because everything is role‑based, you can swap blue-500 for any other hue to rebrand, plug in Radix or Material colors instead of Tailwind values, or extend with dark‑theme counterparts like bg.default.dark and text.primary.dark.

9.

Using Colorr as the source of truth

Colorr's collections give you a starting point for every role in the theme:

What you can do

  • Pick a primary hue from any collection — Tailwind, Material, Radix, Chakra, Open Color.
  • Choose neutral and semantic colors that complement it.
  • Map them into theme tokens like in the example above.
  • Reuse those tokens across your component library regardless of framework.