hxf31891 / react-gradient-color-picker

An easy to use color/gradient picker for React.js
MIT License
146 stars 49 forks source link

Best way to implement custom presets? #80

Closed pjrundle closed 9 months ago

pjrundle commented 9 months ago

Hi, thanks for your work on this library ๐Ÿ™Œ

Question: is there a recommend way to implement custom preset pickers? Why I need them: I want to style them manually, plus also need more than 18 presets.

Basically just wondering if Iโ€™m missing something obvious - there doesn't seem to be an appropriate setter function for the current point?

Looking at what the hook exposes, it seems I would have to set each rgba value, rather than there being a setPointColor() etc type function?

I also considered doing manual transforms to the current value by taking the current point and splitting the string etc.

Just wondering if thereโ€™s a better way to do this.

Many thanks ๐Ÿ™Œ

hxf31891 commented 9 months ago

@pjrundle I actually just wrote a whole response to this before I realized what you meant. You are talking about using solid colors as presets to select individual colors in a gradient. Funnily enough I had never considered this functionality, even though it makes a lot of sense. Let me ponder it and see what I can come up with.

Will likely add a new function to the hook.

hxf31891 commented 9 months ago

@pjrundle In v3.0.7 the useColorPicker hook now exposes handleChange. I widely use this function within the picker but it previous was not exposed. In accepts a single color value i.e rgba(255,0,0,1) but not a gradient. When in gradient mode, the function will set the value of the selected point rather than update the entire gradient value.

Here is a very basic example of how you could implement custom presets using this function.

import React, { useState } from "react";
import ColorPicker, { useColorPicker } from "react-best-gradient-color-picker";

function PickerWithCustomPresets() {
  const [color, setColor] = useState(
    "linear-gradient(40deg, #f542f5 0%, blue 100%)"
  );
  const { handleChange } = useColorPicker(color, setColor);

  return (
    <>
      <ColorPicker
        value={color}
        hidePresets={true}
        onChange={(bv) => setColor(bv)}
      />
      <div style={{ display: "flex", flexWrap: "wrap", marginTop: 12 }}>
        {colors.map((c, idx) => (
          <Option key={`${c}-${idx}`} c={c} handleChange={handleChange} />
        ))}
      </div>
    </>
  );
}

export default PickerWithCustomPresets;

const Option = ({ c, handleChange }: any) => {
  return (
    <div
      style={{ width: "10%", height: 28, boxSizing: "border-box", padding: 3 }}
    >
      <div
        onClick={() => handleChange(c)}
        style={{
          background: c,
          height: "100%",
          width: "100%",
          borderRadius: 2,
        }}
      />
    </div>
  );
};

const colors = [
  "rgba(12,60,245,1)",
  "rgba(15,232,56,1)",
  "rgba(228,18,39,1)",
  "rgba(250,15,250,1)",
  "rgba(67,197,231,1)",
  "rgba(4,36,26,1)",
  "rgba(8,200,68,1)",
  "rgba(106,159,141,1)",
  "rgba(24,143,251,1)",
  "rgba(144,36,165,1)",
  "rgba(227,98,12,1)",
  "rgba(56,173,110,1)",
  "rgba(41,44,119,1)",
  "rgba(64,86,20,1)",
  "rgba(174,26,30,1)",
  "rgba(128,62,43,1)",
  "rgba(176,38,157,1)",
  "rgba(129,190,58,1)",
  "rgba(101,51,65,1)",
  "rgba(56,158,213,1)",
  "rgba(245,69,106,1)",
  "rgba(115,252,97,1)",
  "rgba(245,206,248,1)",
  "rgba(111,225,235,1)",
  "rgba(149,238,244,1)",
  "rgba(24,0,230,1)",
  "rgba(29,117,93,1)",
  "rgba(5,117,33,1)",
  "rgba(173,228,254,1)",
  "rgba(102,28,0,1)",
  "rgba(208,241,161,1)",
  "rgba(89,210,212,1)",
  "rgba(23,16,97,1)",
  "rgba(28,25,97,1)",
  "rgba(78,7,93,1)",
  "rgba(66,112,98,1)",
  "rgba(237,165,67,1)",
  "rgba(162,27,100,1)",
  "rgba(175,194,36,1)",
  "rgba(38,129,223,1)",
  "rgba(94,115,242,1)",
  "rgba(124,92,210,1)",
  "rgba(247,150,83,1)",
  "rgba(61,184,245,1)",
  "rgba(94,191,0,1)",
  "rgba(136,140,225,1)",
  "rgba(210,114,235,1)",
  "rgba(50,28,112,1)",
  "rgba(133,10,196,1)",
  "rgba(4,98,103,1)",
];

Hope this helps, let me know if you have any issues or questions.

pjrundle commented 8 months ago

@hxf31891 Thanks a lot for looking into this ๐Ÿ™Œ

I'll give it whirl probably next week in my project but the code above looks good to me ๐Ÿ™‡

Thanks again!