Skip to Content
DocumentationComponentsColor PickerNext Gen

Color picker

The color picker allows users to choose colors using a visual RGBA color space, hex and RGB inputs, an opacity slider, and optional brand kit integration.

Loading...

Overview

Resources

Loading...

Loading...

Loading...

Loading...

Install

yarn add @camp/color-picker

Usage

Set up ThemeProvider

The color picker components require a styled-components ThemeProvider to be set up in your application. See the Styled Components & ThemeProvider guide for more details on setting up the ThemeProvider.

Color state with ColorPickerProvider

The color picker uses a React context (ColorPickerProvider) to manage color state. Wrap your color picker components with ColorPickerProvider and pass a color value and onChange handler.

import { ColorPicker, ColorPickerProvider } from '@camp/color-picker'; import { useState } from 'react'; const MyColorPicker = () => { const [color, setColor] = useState({ r: 59, g: 130, b: 246, a: 1 }); return ( <ColorPickerProvider value={color} onChange={setColor}> <ColorPicker /> </ColorPickerProvider> ); };

Color values are represented as RGBA objects with r, g, b (0–255) and a (0–1) properties. You can also pass hex strings (e.g. "#3b82f6") as the color prop.

Inline color input with ColorPickerInputRow

For compact layouts, use ColorPickerInputRow which combines a swatch button, hex input, and alpha input into a single row. Clicking the swatch opens a popover with the full color picker.

ColorPickerInputRow manages its own ColorPickerProvider by default, so you can use it standalone with either controlled or uncontrolled state.

import { ColorPickerInputRow } from '@camp/color-picker'; import { useState } from 'react'; // Controlled const ControlledInput = () => { const [color, setColor] = useState({ r: 59, g: 130, b: 246, a: 1 }); return <ColorPickerInputRow value={color} onChange={setColor} />; }; // Uncontrolled (component manages its own state) const UncontrolledInput = () => { return ( <ColorPickerInputRow defaultColor={{ r: 59, g: 130, b: 246, a: 1 }} onChange={(color) => console.log('Color changed:', color)} /> ); };

Standalone swatch

Use the Swatch component to display a color preview that optionally opens a popover with the color picker.

import { Swatch, ColorPickerProvider } from '@camp/color-picker'; import { useState } from 'react'; const SwatchExample = () => { const [color, setColor] = useState({ r: 59, g: 130, b: 246, a: 1 }); return ( <ColorPickerProvider value={color} onChange={setColor}> <Swatch isPopover /> </ColorPickerProvider> ); };

Brand kit integration

When users work with brand colors, pass a brands array to the Swatch or ColorPickerInputRow components. This renders a brand kit picker within the popover, allowing users to select from brand-specific colors organized by brand.

import { ColorPickerInputRow } from '@camp/color-picker'; import { useState } from 'react'; const brands = [ { brandkitName: 'Brand A', isPrimary: true, colors: { primary: '#3b82f6', lightBackground: '#ffffff', darkBackground: '#000000', accents: ['#ef4444', '#10b981', '#f59e0b'], }, }, { brandkitName: 'Brand B', isPrimary: false, colors: { primary: '#8b5cf6', lightBackground: '#f9fafb', darkBackground: '#111827', accents: ['#ec4899', '#06b6d4', '#84cc16'], }, }, ]; const BrandColorPicker = () => { const [color, setColor] = useState({ r: 59, g: 130, b: 246, a: 1 }); return ( <ColorPickerInputRow value={color} onChange={setColor} brands={brands} onBrandColorAdd={(brandkitName, hexColor) => { console.log(`Added ${hexColor} to ${brandkitName}`); }} /> ); };

Best practices

  • Use ColorPickerInputRow for most form scenarios where color selection is part of a larger form — it provides a compact layout with a swatch, hex, and alpha input in a single row
  • Use the standalone ColorPicker component when you need the full color picker embedded directly in the page without a popover
  • Use Swatch with isPopover when you only need a color preview that opens the picker on click
  • Wrap components with ColorPickerProvider when using ColorPicker or Swatch directly — ColorPickerInputRow handles this automatically
  • Pass brands data when users need to select from pre-defined brand colors in addition to choosing custom colors
  • Use controlled state (color + onChange) when the parent component needs to react to color changes in real time
  • Use uncontrolled state (defaultColor + onChange) when the component can manage its own state independently

Content guidelines

✅ DO

  • Use the ColorPickerInputRow for inline color selection in forms
  • Show brand colors when the user is working within a branded context (campaigns, landing pages)
  • Provide the full color picker when precise color control is needed (RGB, hex, opacity)

🚫 DON’T

  • Don’t use the full ColorPicker component in tight spaces — use ColorPickerInputRow instead
  • Don’t show the brand kit picker if no brand colors are configured
  • Don’t use Swatch without ColorPickerProvider context — the swatch needs color state to display the current color

Variations

Default color picker

The base ColorPicker component provides an RGBA color space selector, hex input, RGB channel inputs, and an alpha (opacity) input.

import { ColorPicker, ColorPickerProvider } from '@camp/color-picker'; import { useState } from 'react'; const MyColorPicker = () => { const [color, setColor] = useState({ r: 59, g: 130, b: 246, a: 1 }); return ( <ColorPickerProvider value={color} onChange={setColor}> <ColorPicker /> </ColorPickerProvider> ); };

Swatch with popover

The Swatch component renders a clickable color preview. When isPopover is true (the default), clicking the swatch opens a popover containing the full color picker.

import { Swatch, ColorPickerProvider } from '@camp/color-picker'; import { useState } from 'react'; const SwatchPopover = () => { const [color, setColor] = useState({ r: 59, g: 130, b: 246, a: 1 }); return ( <ColorPickerProvider value={color} onChange={setColor}> <Swatch isPopover /> </ColorPickerProvider> ); };

Swatch without popover

Set isPopover={false} to use the swatch as a simple button that fires an onClick callback rather than opening a popover.

import { Swatch, ColorPickerProvider } from '@camp/color-picker'; <ColorPickerProvider value={color} onChange={setColor}> <Swatch isPopover={false} onClick={() => console.log('Swatch clicked')} /> </ColorPickerProvider>;

Disabled swatch

Pass disabled to prevent interaction with the swatch.

import { Swatch, ColorPickerProvider } from '@camp/color-picker'; <ColorPickerProvider value={color} onChange={setColor}> <Swatch isPopover disabled /> </ColorPickerProvider>;

Swatch with brand colors

Pass a brands array to display a brand kit color picker within the popover. Users can switch between brands, toggle grid/list view, and select from brand-specific colors.

import { Swatch, ColorPickerProvider } from '@camp/color-picker'; const brands = [ { brandkitName: 'Brand A', isPrimary: true, colors: { primary: '#3b82f6', lightBackground: '#ffffff', darkBackground: '#000000', accents: ['#ef4444', '#10b981', '#f59e0b'], }, }, ]; <ColorPickerProvider value={color} onChange={setColor}> <Swatch isPopover brands={brands} /> </ColorPickerProvider>;

Add color to brand kit

Use the onBrandColorAdd callback to allow users to save the currently selected color into one of their brand kits. When provided, an “Add” button appears in the brand color section. The callback receives the brand name and the hex color string so you can persist the change.

import { Swatch, ColorPickerProvider } from '@camp/color-picker'; import { useState, useCallback } from 'react'; const BrandColorAddExample = () => { const [color, setColor] = useState({ r: 59, g: 130, b: 246, a: 1 }); const [brands, setBrands] = useState([ { brandkitName: 'Brand A', isPrimary: true, colors: { primary: '#3b82f6', lightBackground: '#ffffff', darkBackground: '#000000', accents: ['#ef4444', '#10b981'], }, }, { brandkitName: 'Brand B', isPrimary: false, colors: { primary: '#8b5cf6', lightBackground: '#f9fafb', darkBackground: '#111827', accents: ['#ec4899', '#06b6d4'], }, }, ]); const handleBrandColorAdd = useCallback((brandkitName, hexColor) => { setBrands((prevBrands) => prevBrands.map((brand) => brand.brandkitName === brandkitName ? { ...brand, colors: { ...brand.colors, accents: [...brand.colors.accents, hexColor], }, } : brand, ), ); }, []); return ( <ColorPickerProvider value={color} onChange={setColor}> <Swatch isPopover brands={brands} onBrandColorAdd={handleBrandColorAdd} /> </ColorPickerProvider> ); };

How it works:

  • The onBrandColorAdd callback is called with (brandkitName: string, color: string) when the user clicks the add button
  • The brandkitName identifies which brand kit the color should be added to
  • The color is a hex string (e.g. "#3b82f6") of the currently selected color
  • Update your brands state to append the new color to the selected brand’s accents array — the picker will re-render with the new color visible

ColorPickerInputRow

A compact input row combining a swatch, hex input, and alpha input. Manages its own ColorPickerProvider by default.

import { ColorPickerInputRow } from '@camp/color-picker'; import { useState } from 'react'; const InputRow = () => { const [color, setColor] = useState({ r: 59, g: 130, b: 246, a: 1 }); return <ColorPickerInputRow value={color} onChange={setColor} />; };

ColorPickerInputRow with brands

Pass brands to render the brand kit picker in the input row’s popover.

import { ColorPickerInputRow } from '@camp/color-picker'; <ColorPickerInputRow value={color} onChange={setColor} brands={brands} onBrandColorAdd={(brandkitName, hexColor) => { console.log(`Added ${hexColor} to ${brandkitName}`); }} />;

Toggle theming

Prop: themed
Type: boolean
Default value: true

The themed prop controls whether the color picker adapts to the current theme context (light/dark). All three components (ColorPicker, Swatch, ColorPickerInputRow) support this prop.

When to use themed:

  • If you need light mode only, use themed={false}. Useful in standard application areas that only support light mode.
  • If you need light and dark mode support, themed is not required as it defaults to true.
import { ColorPicker, ColorPickerProvider } from '@camp/color-picker'; <ColorPickerProvider value={color} onChange={setColor}> <ColorPicker themed={false} /> </ColorPickerProvider>;

Accessibility

Keyboard support

  • Move focus to each input using the tab key, or shift + tab to move backwards
  • To open the color picker popover (on a Swatch), press enter or space
  • Use arrow keys to move around the color space in the RGBA picker
  • Use the tab key to move focus between the hex input, RGB inputs, and alpha input
  • Use arrow keys to adjust the opacity slider
  • esc will close the color picker popover and return focus to the swatch trigger
  • The swatch button is focusable and shows a visible focus ring when focused

Screen reader support

  • The swatch renders as a button element with proper focus management
  • Hex, RGB, and alpha inputs have associated labels for screen reader identification
  • The popover uses proper ARIA attributes for accessible disclosure
Last updated on