Color Picker
Forms & choicesBrick 0.1.12

Color Picker

Color Picker provides a finished Atom-backed control for editing, choosing, and submitting one opaque hexadecimal color. It supports editable text, the browser-native chooser, named presets, and optional floating content without application CSS.

Live example

Built from the published package

Interactive
Choose with confidence

Know when Color Picker is the right part

Use it when

Use Color Picker in settings, editors, and forms that need one #rrggbb value. Use Color Swatch when the interface only previews a color.

Choose another path when

Do not use this release for alpha, gradients, area picking, channels, eyedroppers, format conversion, contrast analysis, or persistent palette management. Those behaviors require an Atom-first capability or application specialist.

Installation and imports

tsx
import { ColorPicker } from "@flowstack-ui/brick/color-picker";
import { ColorSwatch } from "@flowstack-ui/brick/color-swatch";
import "@flowstack-ui/brick/styles.css";

For modular CSS, load the foundation and picker stylesheet. The picker stylesheet includes its Color Swatch dependency:

tsx
import "@flowstack-ui/brick/styles/core.css";
import "@flowstack-ui/brick/styles/color-picker.css";

Quick start

tsx
<ColorPicker.Root defaultValue="#5b5bd6" name="accent">
  <ColorPicker.Label>Accent color</ColorPicker.Label>
  <ColorPicker.Control>
    <ColorPicker.Input />
    <ColorPicker.NativeInput />
  </ColorPicker.Control>
  <ColorPicker.HiddenInput />
</ColorPicker.Root>

Visual recipes and states

Small, medium, and large controls use the shared 2rem, 2.5rem, and 3rem control geometry. Outline stays transparent with a strong border; Soft uses a subtle surface. Invalid uses danger treatment. Disabled blocks all interaction; read-only remains inspectable and can open its content while mutation stays blocked.

Examples

An inline picker omits Trigger and Content. A floating preset picker composes them as shown above. A controlled application passes value and onValueChange; it must update the authored value after accepting Atom's normalized callback.

Public contract

API

Start with the public parts and root options below. Components with multiple parts separate each area into its own named subsection.

PartImportant propsDefault
RootAtom props; `size: smmd
Labelnative label props-
Inputeditable text input props-
NativeInputnative color input propsaccessible name: Open native color chooser
Trigger / ContentAtom Popover propssideOffset: 8 on Content
SwatchTriggerrequired hexadecimal value-
HiddenInputnative hidden input propsRoot name/form/value
sizeColorPickerSize: sm, md, lgmd
variantColorPickerVariant: outline, softoutline

Root keeps Atom's value, defaultValue, onValueChange, open, defaultOpen, onOpenChange, disabled, read-only, invalid, required, name, form, and inputId contracts. Valid #rgb values normalize to lowercase #rrggbb. Native props, class names, styles, events, and refs pass through each part.

Public exports are ColorPicker, ColorPickerRoot, ColorPickerLabel, ColorPickerControl, ColorPickerInput, ColorPickerNativeInput, ColorPickerHiddenInput, ColorPickerTrigger, ColorPickerContent, ColorPickerSwatchTrigger, ColorPickerRootProps, ColorPickerLabelProps, ColorPickerControlProps, ColorPickerInputProps, ColorPickerNativeInputProps, ColorPickerHiddenInputProps, ColorPickerTriggerProps, ColorPickerContentProps, ColorPickerSwatchTriggerProps, ColorPickerSize, and ColorPickerVariant.

Floating presets

tsx
<ColorPicker.Root defaultValue="#5b5bd6" name="accent">
  <ColorPicker.Label>Accent color</ColorPicker.Label>
  <ColorPicker.Control>
    <ColorPicker.Input />
    <ColorPicker.Trigger aria-label="Choose an accent preset">
      <ColorSwatch.Root value="#5b5bd6" />
    </ColorPicker.Trigger>
  </ColorPicker.Control>
  <ColorPicker.Content aria-label="Accent presets">
    <ColorPicker.SwatchTrigger aria-label="Use indigo" value="#5b5bd6">
      <ColorSwatch.Root value="#5b5bd6" /> Indigo
    </ColorPicker.SwatchTrigger>
    <ColorPicker.SwatchTrigger aria-label="Use coral" value="#e5484d">
      <ColorSwatch.Root value="#e5484d" /> Coral
    </ColorPicker.SwatchTrigger>
  </ColorPicker.Content>
  <ColorPicker.HiddenInput />
</ColorPicker.Root>
Shared responsibility

Accessibility

Use Label or explicit names for both editable and native inputs. Presets are native buttons with aria-pressed; give each a meaningful name and do not communicate selection through color alone. Atom owns Escape, focus restoration, disabled/read-only mutation guards, and form reset. Brick preserves visible focus and forced-colors boundaries.

Responsive behavior

The component uses logical dimensions and content-sized controls. The control can wrap when the owning layout permits. Floating content is constrained to the dynamic viewport; the application or Block owns page-level responsive placement.

Stable visual contract

Styling and tokens

Customization

Prefer Root size and variant before overriding public variables. Use Color Swatch for every standard preview. Custom part classes may refine a product composition but must preserve Atom's slots, native names, selected state, focus, and viewport containment.

Tokens and CSS hooks

Stable hooks are .brick-color-picker and its __label, __control, __input, __native-input, __trigger, __content, and __swatch-trigger parts, plus Atom slots/state attributes and Root data-size/data-variant.

Public variables are --brick-color-picker-control-size, --brick-color-picker-gap, --brick-color-picker-background, --brick-color-picker-border-color, --brick-color-picker-focus-ring, --brick-color-picker-content-background, --brick-color-picker-content-border-color, --brick-color-picker-content-radius, and --brick-color-picker-content-shadow.

Advanced reference

Open these details only when you need to inspect DOM ownership, native forwarding, or lower-level composition.

Maintainer resources

Tests, playground evidence, source notes, and release history remain available without crowding the plug-and-play guide.