Issue #2467Opened December 23, 2019by jcamejo0 reactions

[ISSUE] [SOLUTION PROPOSAL] Color picker remains open if the click happens on the canvas

Question

Hi @artf, i hope you are doing good.

I'm seeing some issues around the color picker, if one is open and afterwards a click is made on the canvas, the color picker will not close even if the option clickoutFiresChange of the plugin is set to true, this is because the event propagation is taken by the iframe of the canvas and is not passed through.

The only workaround that i have found is by adding a secondary event that can catch the click on the canvas, at the moment i'm using

component:selected

but i'm thinking for a better solution. Here is my proposal:

  getColorEl() {
    if (!this.colorEl) {
      const self = this;
      const ppfx = this.ppfx;
      var model = this.model;
      var em = this.em;

      var colorEl = $(`<div class="${this.ppfx}field-color-picker"></div>`);
      var cpStyle = colorEl.get(0).style;
      var elToAppend = this.em && this.em.config ? this.em.config.el : '';
      var colorPickerConfig =
        (this.em && this.em.getConfig && this.em.getConfig('colorPicker')) ||
        {};
      const getColor = color => {
        let cl =
          color.getAlpha() == 1 ? color.toHexString() : color.toRgbString();
        return cl.replace(/ /g, '');
      };

      let changed = 0;
      let previousColor;
      this.$el.find(`[data-colorp-c]`).append(colorEl);
      colorEl.spectrum({
        containerClassName: `${ppfx}one-bg ${ppfx}two-color`,
        appendTo: elToAppend || 'body',
        maxSelectionSize: 8,
        showPalette: true,
        showAlpha: true,
        chooseText: 'Ok',
        cancelText: '⨯',
        palette: [],

        // config expanded here so that the functions below are not overridden
        ...colorPickerConfig,

        move(color) {
          const cl = getColor(color);
          cpStyle.backgroundColor = cl;
          model.setValueFromInput(cl, 0);
        },
        change(color) {
          changed = 1;
          const cl = getColor(color);
          cpStyle.backgroundColor = cl;
          model.setValueFromInput(cl);
          self.noneColor = 0;
        },
        show(color) {
          changed = 0;
          previousColor = getColor(color);
        },
        hide(color) {
          if (!changed && previousColor) {
            if (self.noneColor) {
              previousColor = '';
            }
            cpStyle.backgroundColor = previousColor;
            colorEl.spectrum('set', previousColor);
            model.setValueFromInput(previousColor, 0);
          }
        }
      });

     // Added event
      if (em) {
        em.on('component:selected', () => {
          changed = 1;
          colorEl.spectrum('hide');
        });
      }
     // ++++++++++///

      this.colorEl = colorEl;
    }
    return this.colorEl;
  },

I was trying to add this action inside the picker callbacks but i can't was not managing to get the right context to do so.

What do you think? Should i try something different or can i submit a pull request?

Thanks a lot for this excellent library, i'm learning a lot diving into the source code.

Best regards,

Juan.

Answers (2)

artfDecember 25, 20190 reactions

The PR would be great 👍

NorthstarTechApril 1, 20200 reactions

@artf @jcamejo any update on this?

Related Questions and Answers

Continue research with similar issue discussions.

Paid Plugins That Match This Issue

Curated by issue keywords and label relevance to help you ship faster.

View all plugins

Loading paid plugin recommendations...

Browse Plugin Categories

Jump directly to plugin category pages on the marketplace.