npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@appberry/berrypickr

v2.0.0

Published

Modern, framework-agnostic color picker for evergreen browsers.

Downloads

82

Readme

BerryPickr

BerryPickr is a headless-first color picker plugin with an optional default UI mount. It gives you one typed color state engine (controller) that you can use with:

  • the built-in UI mount (mountBerryPickrUI)
  • your own custom UI
  • plugin hooks for side effects (analytics, telemetry, policy checks)
  • framework adapters for React, Vue, and Svelte

Install

pnpm add @appberry/berrypickr

Why BerryPickr

  • Headless controller API with explicit commit flow (setValue vs commit)
  • Built-in undo/redo and configurable history
  • Context-aware values: default, hover, active, focus, disabled
  • Plugin lifecycle hooks: setup, onChange, onCommit, teardown
  • Safe plugin failure control with pluginErrorPolicy: 'emit' | 'throw'
  • Optional UI mount with popover mode and runtime updates
  • Binding helpers for CSS variables and inline styles
  • WCAG contrast helpers (getContrastRatio, analyzeContrast)
  • Official adapter entry points: @appberry/berrypickr/react, @appberry/berrypickr/vue, @appberry/berrypickr/svelte

Quick Start

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

const telemetryPlugin: BerryPickrPlugin = {
  name: 'telemetry',
  onCommit(event) {
    console.log('commit', event.transactionId, event.value?.to('hexa'));
  }
};

const controller = createBerryPickrController({
  defaultValue: '#486DFF',
  formats: ['hex', 'rgba', 'hsla'],
  history: { limit: 200 },
  plugins: [telemetryPlugin],
  pluginErrorPolicy: 'emit'
});

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

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

controller.on('change', ({ value, source, transactionId }) => {
  console.log(source, transactionId, value?.to('rgba'));
});

// Update UI options without remounting.
mount.update({
  closeOnOutsideClick: false
});

Minimum lifecycle you should wire in production:

  • mount.destroy({ remove: true }) when host view unmounts
  • controller.destroy() to release plugin teardown/listeners

Styling

BerryPickr ships with two CSS assets:

  • @appberry/berrypickr/styles/base.css (required structure + interactions)
  • @appberry/berrypickr/styles/skin-template.css (starter theme tokens)

Use CSS variables on .bp-app to skin without rewriting component structure:

.bp-app {
  --bp-surface: #f6f8ff;
  --bp-text: #1a2445;
  --bp-muted: #5d6888;
  --bp-border: rgba(30, 52, 107, 0.16);
  --bp-shadow: 0 22px 40px rgba(40, 66, 143, 0.25);
  --bp-accent: #2f67d1;
  --bp-danger: #be3f57;
  --bp-focus: rgba(47, 103, 209, 0.38);
  --bp-radius: 16px;
}

Recommended practice:

  • Override tokens first; avoid structural CSS overrides unless necessary
  • Keep focus ring token (--bp-focus) high-contrast in every theme
  • Re-run keyboard and contrast checks after theme changes

Accessibility

BerryPickr includes keyboard-first interactions and ARIA labeling hooks:

  • Escape-to-close in popover mode (closeOnEscape)
  • Keyboard interaction for palette and sliders
  • Localizable i18n labels for dialog, toggle, controls, and actions
  • E2E coverage in this repo (Playwright + axe)
mountBerryPickrUI(controller, {
  target: '#color-trigger',
  closeOnEscape: true,
  i18n: {
    dialog: 'Brand color dialog',
    toggle: 'Open brand color dialog',
    palette: 'Color palette',
    hue: 'Hue slider',
    alpha: 'Opacity slider'
  }
});

Accessibility checklist before release:

  • Verify keyboard-only access to all visible controls
  • Ensure visible focus states in your final skin
  • Confirm translated i18n labels match product terminology
  • Validate contrast for text/button labels in your theme

Documentation