EastDesire/jscolor

Container option breaking on resize

Kirsdarkenvaar opened this issue · 9 comments

First of all, thank you for making an awesome color picker!

I'm using it on a project where the picker is shown on a sliding panel, so it's bound to a node in the sliding panel's DOM. It appears to be working well, except that when I use the browser's emulator to change devices/sizes, the color picker appears to get disconnected from its node container and just jumps off screen to the right. Screenshots attached -- the second was taken right after stretching the right border by a few pixels.

1

2

Is there a way for the picker to handle resize events?

@Kirsdarkenvaar, this seems to be caused by smartPosition feature. You might need to turn it off by setting option smartPosition: false. Let me know whether it helped, please.

Unfortunately I already had it disabled. Here's the full initialization code for your reference:

import "@eastdesire/jscolor";

this.colorPicker = new JSColor(this.colorPickerElement, {
preset: "large",
alphaChannel: true,
backgroundColor: "none",
borderWidth: 0,
container: this.colorPickerElement,
hideOnLeave: false,
palette: [
"#000000",
"#7d7d7d",
"#870014",
"#ec1c23",
"#ff7e26",
"#fef100",
"#22b14b",
"#00a1e7",
"#3f47cc",
"#a349a4",
"#FFFFFF",
"#c3c3c3",
"#b87957",
"#feaec9",
"#ffc80d",
"#eee3af",
"#b5e61d",
"#99d9ea",
"#7092be",
"#c8bfe7",
],
paletteCols: 10,
paletteHeight: 27,
paletteSpacing: 6,
onInput: this.onColorPickerInput,
previewElement: null,
random: true,
shadow: false,
smartPosition: false,
zIndex: "inherit",
});

this.colorPicker.show();

That all looks OK, except that 'container' element should not be the same as targetElement (the first argument in JSColor() constructor). Container should be some relatively/absolutely positioned element in that sliding panel, and it should contain targetElement somewhere in it.
Not sure if that's the cause of this issue though.

Custom container is an experimental feature and hasn't been thoroughly tested.

I've tried repositioning the element as you suggested, but it made no difference sadly. One thing I did notice though is that when I stretch the border, three properties change on their own:

  1. position goes from relative to fixed
  2. left goes from 0 to a higher value
  3. top goes from 0 to a higher value

If I manually reset those three to the original settings (relative/0/0), the picker goes back to its correct position.

1

2

3

Thanks for the detailed info, @Kirsdarkenvaar.

This seems to be a deeper issue. It's quite difficult to make custom container work in all scenarios. We probably won't get it fixed easily.

You might try to comment out the following code in jscolor.js, but obviously that's not a real solution.

				// If the target element or one of its parent nodes has fixed position,
				// then use fixed positioning instead
				var compStyle = jsc.getCompStyle(elm);
				if (compStyle.position && compStyle.position.toLowerCase() === 'fixed') {
					this.fixed = true;
				}

Try commenting out: // this.fixed = true;

(That code was there for a reason though, so it can't be simply removed in official build.)

That didn't work unfortunately. I went ahead and forked the project and did some digging, and found where the problem lies. In drawPicker() you have this code:

			// The redrawPosition() method needs picker.owner to be set, that's why we call it here,
			// after setting the owner
			if (THIS.container === window.document.body) {
				jsc.redrawPosition();
			} else {
				jsc._drawPosition(THIS, 0, 0, 'relative', false);
			}

However in onWindowResize() you have this:

	onWindowResize: function (e) {
		jsc.redrawPosition();
	},

Changing it to this to mirror the drawPicker() code fixes the problem:

	onWindowResize: function (e) {

		if (jsc.picker.owner.container === window.document.body) {
			jsc.redrawPosition();
		} else {
			jsc._drawPosition(jsc.picker.owner.container, 0, 0, 'relative', false);
		}
	},

Presumably the same check should be performed in onWindowScroll as well.

(Sorry for not sending a pull request, I still suck at using GitHub.)

Good spot, @Kirsdarkenvaar! I made appropriate changes and did some smoke testing locally.
Could you please test it too in your environment?
The updated script is attached.
Thank you!
jscolor-2.4.9-pre1.js.zip

Seems to work on my end. Thank you!

Fixed in version 2.4.9