Skip to content

BerryPickr

BerryPickr Handbook

Ship reliable color tooling with a headless controller and optional UI mount.

Use one controller surface across app builders, design systems, and framework wrappers without rewriting state logic.

Installpnpm add berrypickr

Choose Your Path

Start

New to BerryPickr

Get a controller mounted, committed, and bound to real UI state in minutes.

Open New to BerryPickr

Core

Understand the model

Learn contexts, transaction IDs, and event semantics before scaling integrations.

Open Understand the model

When to use

Use BerryPickr when you need one consistent color state engine across:

  • App builders and dashboard products
  • Design system tooling with custom UI skinning
  • Framework integrations (React, Vue, Svelte)
  • Accessibility-conscious color workflows with commit control

Quick example

ts
import { createBerryPickrController, mountBerryPickrUI, createCssVarBinding } from '@appberry/berrypickr';
import '@appberry/berrypickr/styles/base.css';

const controller = createBerryPickrController({
  defaultValue: '#486dff',
  formats: ['hex', 'rgba', 'hsla'],
  history: { limit: 120 }
});

const mount = mountBerryPickrUI(controller, {
  target: '#brand-color-trigger',
  mode: 'popover'
});

createCssVarBinding({
  controller,
  target: ':root',
  variable: '--brand-color',
  format: 'hexa',
  event: 'commit'
});

controller.on('commit', ({ transactionId, value }) => {
  console.log(transactionId, value?.to('hexa'));
});

mount.show();

Live Playground

Interactive Playground

Live Controller + UI Mount

Toggle mount mode, edit options, and inspect emitted events.

Tip: change the options JSON and recreate to test different controller configurations.

Event log

Plugin Live Demos

The plugin demos cover:

  • lifecycle setup and teardown behavior
  • telemetry differences between onChange and onCommit
  • failure handling with pluginErrorPolicy: 'emit' vs 'throw'

What BerryPickr gives you

  • A headless controller with explicit commit and history semantics
  • Optional UI mount that can be swapped or themed without replacing state logic
  • Typed events with instanceId, transactionId, and timestamps for tracing
  • Binding helpers for CSS custom properties and inline style outputs
  • First-party framework adapters for React, Vue, and Svelte
  • Plugin hooks with controlled error behavior (emit or throw)
  • Utility exports for contrast analysis and controller orchestration