score:0

Accepted answer

with the help of useeffect we can perform actual setstate or in this case console.log(color), some time (in this case after 0.2 sec) after the user stops dragging the mouse in colorpicker or moving the slider in opacity or etc.

useeffect(() => {
    const timeoutid = settimeout(
      () => {
        if (color != null) {
          //do your things
          console.log(color);
        }
      },

      200
    );
    return () => cleartimeout(timeoutid);
  }, [color]);

codesandbox

score:1

try adding deferred prop in the colorpicker. with deferred set to true, change handler only fires when you click the set button to commit the change:

<colorpicker value={color} onchange={handlechange} deferred />

edit: if you really really want to listen to the mouseup event, you need to do some dirty work using plain js:

function mycolorpicker({ onchange }) {
  const [open, setopen] = usestate(false);
  const [, forcerender] = usereducer((x) => ++x, 0);
  const colorref = useref<color>();
  const handlechange = (newvalue: color) => {
    colorref.current = newvalue;
    forcerender();
  };

  react.useeffect(() => {
    let colorgradientel = null;
    let huesliderel = null;
    let alphasliderel = null;
    let inputels = [];
    const handlemouseup = () => onchange(colorref.current);

    if (open) {
      settimeout(() => {
        colorgradientel = document.queryselector(
          '[data-testid="hsvgradient-color"]'
        );
        huesliderel = document.queryselector('[data-testid="hueslider"]');
        alphasliderel = document.queryselector('[data-testid="alphaslider"]');
        inputels = [...document.queryselectorall("input")];
        const colorpickerpopoverel = document.queryselector(
          ".colorpicker-muipopover-root"
        );

        const observer = new mutationobserver((mutations) => {
          mutations.foreach((mutation) => {
            if (mutation.removednodes) {
              setopen(false);
            }
            observer.disconnect();
          });
        });

        observer.observe(colorpickerpopoverel!, { childlist: true });
        colorgradientel?.addeventlistener("mouseup", handlemouseup);
        huesliderel?.addeventlistener("mouseup", handlemouseup);
        alphasliderel?.addeventlistener("mouseup", handlemouseup);

        inputels.foreach((el) => {
          el.addeventlistener("change", handlemouseup);
        });
      }, 10);
    }

    return () => {
      colorgradientel?.removeeventlistener("mouseup", handlemouseup);
      huesliderel?.removeeventlistener("mouseup", handlemouseup);
      alphasliderel?.removeeventlistener("mouseup", handlemouseup);

      inputels.foreach((el) => {
        el.removeeventlistener("change", handlemouseup);
      });
    };
  }, [open]);

  return (
    <colorpicker
      onopen={() => setopen(true)}
      value={colorref.current}
      onchange={handlechange}
    />
  );
}

usage

mycolorpicker now only fires change handler when the user stops dragging the mouse:

<mycolorpicker onchange={handlechange} />

codesandbox demo


Related Query

More Query from same tag