最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React : Openclose react-colorful picker - Stack Overflow

programmeradmin8浏览0评论

I'm using react-colorful to get colors HEX code. I would want to show this ponent when the color's box is clicked, and hide it when clicked outside of it, kinda like the color picker Chrome is using (ex <input type="color" /> )

How to do so ?

=/src/App.js:308-322

import React, { useState } from "react";
import { HexColorPicker } from "react-colorful";
import "./styles.css";

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

  const handleChange = (e) => {
    setColor(e.target.value);
  };

  return (
    <div className="App">
      <HexColorPicker color={color} onChange={setColor} />

      //Click on this box to show the picker <div className="value" style={{ borderLeftColor: color }}>
        Current color is {color}
      </div>
      <input value={color} onChange={handleChange} />
      <div className="buttons">
        <button onClick={() => setColor("#c6ad23")}>Choose gold</button>
        <button onClick={() => setColor("#556b2f")}>Choose green</button>
        <button onClick={() => setColor("#207bd7")}>Choose blue</button>
      </div>
    </div>
  );
}

I'm using react-colorful to get colors HEX code. I would want to show this ponent when the color's box is clicked, and hide it when clicked outside of it, kinda like the color picker Chrome is using (ex <input type="color" /> )

How to do so ?

https://codesandbox.io/s/react-colorful-demo-forked-wwxq2?file=/src/App.js:308-322

import React, { useState } from "react";
import { HexColorPicker } from "react-colorful";
import "./styles.css";

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

  const handleChange = (e) => {
    setColor(e.target.value);
  };

  return (
    <div className="App">
      <HexColorPicker color={color} onChange={setColor} />

      //Click on this box to show the picker <div className="value" style={{ borderLeftColor: color }}>
        Current color is {color}
      </div>
      <input value={color} onChange={handleChange} />
      <div className="buttons">
        <button onClick={() => setColor("#c6ad23")}>Choose gold</button>
        <button onClick={() => setColor("#556b2f")}>Choose green</button>
        <button onClick={() => setColor("#207bd7")}>Choose blue</button>
      </div>
    </div>
  );
}
Share Improve this question edited May 4, 2021 at 9:23 AlyaKra asked May 4, 2021 at 9:18 AlyaKraAlyaKra 56610 silver badges26 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 3

At first, you should have to declare a state which tracks whether the color box is open or not like

const [open, setopen] = useState(false);

Now add an event handler on the div of the box which toggles the state from false to true and true to false.

const openBox = () => {
    setopen(!open);
  }

Now in your return statement, add a conditional to open or close colorBox. if clicked on that div which holds the onClick method.

<div className="App">
      {open &&<HexColorPicker color={color} onChange={setColor} />
      }
      

      <div onClick={() => openBox()}className="value" style={{ borderLeftColor: color }}>
        Current color is {color}
      </div>

Now if you click on the div which contains the onClick method, it will open the colorBox and on pressing again it will close it.

You can use the following example (from https://codesandbox.io/s/opmco found in Code Recipes)

import React, { useCallback, useRef, useState } from "react";
import { HexColorPicker } from "react-colorful";

import useClickOutside from "./useClickOutside";

export const PopoverPicker = ({ color, onChange }) => {
  const popover = useRef();
  const [isOpen, toggle] = useState(false);

  const close = useCallback(() => toggle(false), []);
  useClickOutside(popover, close);

  return (
    <div className="picker">
      <div
        className="swatch"
        style={{ backgroundColor: color }}
        onClick={() => toggle(true)}
      />

      {isOpen && (
        <div className="popover" ref={popover}>
          <HexColorPicker color={color} onChange={onChange} />
        </div>
      )}
    </div>
  );
};

useClickOutside.js

import { useEffect } from "react";

// Improved version of https://usehooks./useOnClickOutside/
const useClickOutside = (ref, handler) => {
  useEffect(() => {
    let startedInside = false;
    let startedWhenMounted = false;

    const listener = (event) => {
      // Do nothing if `mousedown` or `touchstart` started inside ref element
      if (startedInside || !startedWhenMounted) return;
      // Do nothing if clicking ref's element or descendent elements
      if (!ref.current || ref.current.contains(event.target)) return;

      handler(event);
    };

    const validateEventStart = (event) => {
      startedWhenMounted = ref.current;
      startedInside = ref.current && ref.current.contains(event.target);
    };

    document.addEventListener("mousedown", validateEventStart);
    document.addEventListener("touchstart", validateEventStart);
    document.addEventListener("click", listener);

    return () => {
      document.removeEventListener("mousedown", validateEventStart);
      document.removeEventListener("touchstart", validateEventStart);
      document.removeEventListener("click", listener);
    };
  }, [ref, handler]);
};

export default useClickOutside;
发布评论

评论列表(0)

  1. 暂无评论