Skip to content

Troubleshooting

When to use

Use this page when BerryPickr behaves unexpectedly and you need fast diagnosis from symptom to root cause.

Quick example

ts
controller.on('pluginError', ({ plugin, phase, error, transactionId }) => {
  console.error(`[${plugin}] ${phase}`, transactionId, error);
});

Options/Methods

Symptom -> Cause -> Fix

SymptomLikely causeFix
Picker never opensTarget selector does not resolve, or controller is disabledVerify target element exists and call controller.setDisabled(false)
setValue returns falseColor string cannot be parsedValidate format before calling; ensure supported syntax
mount.update throws about target/containerAttempted to change immutable mount optionsDestroy mount and remount with new target/container
Alpha controls missinglockAlpha is trueSet lockAlpha: false if alpha editing is required
Recent colors not persistingNo storage adapter or storage errorsProvide recentColors.storage and verify load/save logic
Plugin failures stop UI flowpluginErrorPolicy is 'throw'Switch to 'emit' for resilient runtime behavior
Styles not appliedMissing base stylesheet importImport @appberry/berrypickr/styles/base.css once in app bundle
Outside click does not closeNon-popover mode or closeOnOutsideClick: falseUse popover mode and enable outside close
Escape key does not closecloseOnEscape: false or wrong document contextEnable option and ensure listeners are attached to correct owner document

Diagnostic checklist

  1. Confirm resolved DOM context (target, container, iframe/shadow root ownership).
  2. Inspect controller.getState() for disabled, open, context, and formats.
  3. Verify event flow with change, commit, openChange, and pluginError listeners.
  4. Validate integration lifecycle cleanup (mount.destroy, controller.destroy).

Quick debug helper

ts
const unsubscribe = controller.subscribe((state) => {
  console.log({
    open: state.open,
    disabled: state.disabled,
    context: state.context,
    value: state.value?.to('hexa') ?? null,
    format: state.format,
    history: state.history
  });
});

// later
unsubscribe();

Gotchas

  • In iframes, target and container must come from iframe document to keep close/positioning behavior correct.
  • In shadow DOM, keep target and container in same shadow root.
  • Destroying controller before mount can leave detached UI artifacts if remove is false.