omgovich / react-colorful

🎨 A tiny (2,8 KB) color picker component for React and Preact apps
https://omgovich.github.io/react-colorful
MIT License
3.19k stars 100 forks source link

Hue resetting when dragging saturation to extreme #176

Open alundeen opened 2 years ago

alundeen commented 2 years ago

Hi, thanks for the great library!

I'm using it with Preact, and I noticed an issue where dragging the saturation slider all the way to a corner (#fff or #000) often resets the hue to 0 (red):

react-colorful-hue-issue

I can't seem to reproduce it with the React-based examples (like the library homepage), but it happens with a minimal Preact-based setup:

import { useState } from "preact/hooks";
import { HexColorPicker } from "react-colorful";

export default function App() {
    const [color, setColor] = useState("#aabbcc");

    return (
        <div>
            <HexColorPicker color={color} onChange={setColor} />
            <div>{color}</div>
        </div>
    );
}

I also noticed the hue slider wiggling around a bit as the saturation is changed.

Sometimes the issue happens immediately, sometimes I need to drag the hue slider a bit first. It may also take some wiggling back and forth of the saturation slider before it happens. Anecdotally, it seems to happen more frequently with the DevTools window open, so I wondered if it might be a timing issue.

I set up an example page/repo here: https://alundeen.github.io/react-colorful-hue-issue/ https://github.com/alundeen/react-colorful-hue-issue

I was wondering if this is something you've seen before? Thanks!

titoasty commented 2 years ago

I have the exact same problem. And much much worse with the devtools window open :( I've tried using vanilla-colorful instead, but onEventColorChanged is never called.

titoasty commented 2 years ago

@alundeen

I've found a temporary solution:

Use vanilla-colorful instead of react-colorful.

return (
    <rgb-color-picker ref={ref} color={color}></rgb-color-picker>
);

And to add the color changed event listener, simply do this:

useEffect(() => {
    const colorPicker = ref.current;
    if(!colorPicker) return;

    colorPicker.addEventListener('color-changed', (ev: any) => {
        setColor(ev.detail.value);
    })
}, []);

Hope it helps for now!