Start
New to BerryPickr
Get a controller mounted, committed, and bound to real UI state in minutes.
Open New to BerryPickrBerryPickr Handbook
Use one controller surface across app builders, design systems, and framework wrappers without rewriting state logic.
pnpm add berrypickrStart
Get a controller mounted, committed, and bound to real UI state in minutes.
Open New to BerryPickrCore
Learn contexts, transaction IDs, and event semantics before scaling integrations.
Open Understand the modelBuild
Dive into controller methods, mount options, bindings, and plugin lifecycles.
Open Build custom workflowsUse BerryPickr when you need one consistent color state engine across:
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();Interactive Playground
Toggle mount mode, edit options, and inspect emitted events.
Tip: change the options JSON and recreate to test different controller configurations.
The plugin demos cover:
onChange and onCommitpluginErrorPolicy: 'emit' vs 'throw'controller with explicit commit and history semanticsmount that can be swapped or themed without replacing state logicinstanceId, transactionId, and timestamps for tracingemit or throw)