How to code a simple linear gradient generator using ReactJS.
Tags: webdev, beginners, react, tutorial
Published: 2022-06-20 18:08:57


 This is what we are going to code.

![Linear gradient Generator](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qc3oywyf1j82dca6bvnb.png)
[Final code link](https://codesandbox.io/s/linear-gradient-o3bqvq?file=/src/App.js)
<br />
For styling our react app I am going to use [style-components](https://styled-components.com/). If you don't know or want a refresher refer to this awesome [article](https://www.smashingmagazine.com/2020/07/styled-components-react/).

Now let the fun begins........

```JavaScript
import React from "react";
import styled from "styled-components";

const GradientContainer = styled.div``;

const App = () => {
return (
// Here I will begin the code
}

export default App
```

This is the basic setup for our app. I am writing my code in the App component, you can write in whatever component you want.

Also, I am going to write all my styles inside GradientContainer. You can style your react app however you want.

First, let's code the structure of our app
```JavaScript
       <GradientContainer>
    <div className="gradient_container_header">
      <h1 className="gradient_container_header_heading">
        Gradient Generator
      </h1>
      <h3 className="gradient_container_header_subheading">
        Generate your gradient
      </h3>
    </div>
    <div className="gradient_container_main">
      <div className="gradient_container_main_color_box">

         // first ColorInput will go here
        <div className="gradient_conatiner_main_color_box_range">

        // first Range Input

        </div>
      </div>
      <div className="gradient_container_main_gradient_box">

       // Gradient Box will go here


      </div>
      <div className="gradient_container_main_color_box">

       // Second ColorInput will go here

        <div className="gradient_conatiner_main_color_box_range">

       // Second Range Input will go here


        </div>
      </div>
    </div>
    <div className="gradient_container_footer">
      <h3>In Deg</h3>

      // Third Range Input will go here


      <h3 className="gradient_container_footer_text">
        Code for the gradient that you have generated
      </h3>
      <h1 className="gradient_container_footer_code">

      // Code will go here


      </h1>
    </div>
  </GradientContainer>
```
Output
![Output of the above code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r3sb78gpd3sd1h7xj2qe.png)
 
Now let's understand the above structure line by line.

I created a div with className "gradient_container_header" which will act as a container for our header element.

Below this, the structure is a little bit complex and hard to understand but I will try my best to tell you as simple as possible.
First, let's understand what structure we are aiming for.
![Structure detail](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/low7wbjcafuze7nx90t8.png)

Here, you can see the mid part contain 3 component:- Color Picker and Range part || Gradient part || Color Picker and Range part

Therefore I created a div with className "gradient_container_main" which will act as a mid-part and inside that div, I have created three more div which will contain the three components, and with the help of flex-box we will achieve what we are aiming for.
 

Styling our structure.

```JavaScript
const GradientContainer = styled.div`
  .gradient_container_header {
    text-align: center;
    .gradient_container_header_heading {
      font-size: max(3vw, 20px);
    }
    .gradient_container_header_subheading {
      font-size: max(1.5vw, 10px);
      color: rgba(0, 0, 0, 0.5);
    }
  }

  /* To arrange the components side by side */
  .gradient_container_main {
    display: flex;
    justify-content: center;
    gap: 5em;
    
    .gradient_container_main_color_box {
      display: flex;
      flex-direction: column;
      gap: 5em;
      align-items: center;
      justify-content: center;

      /* To rotate the range input */
      .gradient_conatiner_main_color_box_range {
        height: max-content;
        transform: rotateZ(-90deg);
      }
    }
  }
  .gradient_container_footer {
    text-align: center;
  }
`;
```
Output
![Output of the above code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lh80qevm09tl3ih4h5yd.png)

## How to code color picker
![Linear gradient Generator](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qc3oywyf1j82dca6bvnb.png)

Here we are using a two color picker so instead of coding the color picker inside the app component (or whatever component you are currently working on ) it will be more convenient to make it a separate component and use that component wherever we want the color picker.

```JavaScript
import React from "react";
import styled from "styled-components";

const ColorInputStyle = styled.input``;
const ColorInput = (props) => (
  <ColorInputStyle
    type="color"
  />
);
export default ColorInput;
```

Now let's use this component inside the App

```JavaScript
    <GradientContainer>
    <div className="gradient_container_header">
      <h1 className="gradient_container_header_heading">
        Gradient Generator
      </h1>
      <h3 className="gradient_container_header_subheading">
        Generate your gradient
      </h3>
    </div>
    <div className="gradient_container_main">
      <div className="gradient_container_main_color_box">

         <ColorInput />
        <div className="gradient_conatiner_main_color_box_range">

        // first Range Input

        </div>
      </div>
      <div className="gradient_container_main_gradient_box">

       // Gradient Box will go here


      </div>
      <div className="gradient_container_main_color_box">

       <ColorInput />

        <div className="gradient_conatiner_main_color_box_range">

       // Second Range Input will go here


        </div>
      </div>
    </div>
    <div className="gradient_container_footer">
      <h3>In Deg</h3>

      // Third Range Input will go here


      <h3 className="gradient_container_footer_text">
        Code for the gradient that you have generated
      </h3>
      <h1 className="gradient_container_footer_code">

      // Code will go here


      </h1>
    </div>
  </GradientContainer>
```

Output
![Output of the code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6ul9zv3rxknda8qy5u34.png)
 

Now let's add some styling to our colorInput

```JavaScript
import React from "react";
import styled from "styled-components";

const ColorInputStyle = styled.input`
  border-radius: 50%;
  width: max(5vw, 50px);
  height: max(5vw, 50px);
`;
const ColorInput = (pros) => (
  <ColorInputStyle
    type="color"
  />
);
export default ColorInput;
```

Output
![Output of the above code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bt6q2qhqig3tjasrb2km.png)
 
Notice how the main color area is still square. The code to make it a circle is given below

```JavaScript
import React from "react";
import styled from "styled-components";

const ColorInputStyle = styled.input`
  border-radius: 50%;
  width: max(5vw, 50px);
  height: max(5vw, 50px);

  &::-webkit-color-swatch {
    border-radius: 50%;
  }
  &::-moz-color-swatch {
    border-radius: 50%;
  }
`;
const ColorInput = (pros) => (
  <ColorInputStyle
    type="color"
  />
);
export default ColorInput;
```
Output
![Output of the above code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g27q2ij72xxu0iis6s2t.png)
 

Now it's look perfect😍. 

## How to code range input

```JavaScript
import React from "react";
import styled from "styled-components";

const RangeInputStyle = styled.input``;
const RangeInput = (props) => (
  <RangeInputStyle
    type="range"
    min={0}
    max={100}
  />
);
export default RangeInput;
```

Now lets use this this inside our App component

```JavaScript
<GradientContainer>
      <div className="gradient_container_header">
        <h1 className="gradient_container_header_heading">
          Gradient Generator
        </h1>
        <h3 className="gradient_container_header_subheading">
          Generate your gradient
        </h3>
      </div>
      <div className="gradient_container_main">
        <div className="gradient_container_main_color_box">
          <ColorInput />

          <div className="gradient_conatiner_main_color_box_range">
            <RangeInput />
          </div>
        </div>
        <div className="gradient_container_main_gradient_box">
          // Gradient Box will go here
        </div>
        <div className="gradient_container_main_color_box">
          <ColorInput />

          <div className="gradient_conatiner_main_color_box_range">
            <RangeInput />
          </div>
        </div>
      </div>
      <div className="gradient_container_footer">
        <h3>In Deg</h3>

        <RangeInput />

        <h3 className="gradient_container_footer_text">
          Code for the gradient that you have generated
        </h3>
        <h1 className="gradient_container_footer_code">// Code will go here</h1>
      </div>
    </GradientContainer>
```

Output
![output of the above code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c94ou6jlvlbiyisuommy.png
)

## Let's code gradient box

For this, we need to create a box with some height and width and set the background to a linear gradient.

```JavaScript
import React from "react";
import styled from "styled-components";

const GradientBoxStyle = styled.div`
  width: max(20vw, 200px);
  height: max(30vw, 300px);
  background: linear-gradient(45deg, red, blue);
  margin: 3em auto;
  border-radius: 30px;
`;

const GradientBox = (props) => (
  <GradientBoxStyle
  />
);

export default GradientBox;

```

Let's use it inside the App component
```JavaScript
    <GradientContainer>
      <div className="gradient_container_header">
        <h1 className="gradient_container_header_heading">
          Gradient Generator
        </h1>
        <h3 className="gradient_container_header_subheading">
          Generate your gradient
        </h3>
      </div>
      <div className="gradient_container_main">
        <div className="gradient_container_main_color_box">
          <ColorInput />

          <div className="gradient_conatiner_main_color_box_range">
            <RangeInput />
          </div>
        </div>
        <div className="gradient_container_main_gradient_box">
          <GradientBox />
        </div>
        <div className="gradient_container_main_color_box">
          <ColorInput />

          <div className="gradient_conatiner_main_color_box_range">
            <RangeInput />
          </div>
        </div>
      </div>
      <div className="gradient_container_footer">
        <h3>In Deg</h3>

        <RangeInput />

        <h3 className="gradient_container_footer_text">
          Code for the gradient that you have generated
        </h3>
        <h1 className="gradient_container_footer_code">// Code will go here</h1>
      </div>
    </GradientContainer>
```
Output
![Output of the above code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dmgk4xrvym33gupwtbfm.png)

Now if I try to pick some color from the color picker nothing will happen the color of the gradient box will remain the same.
![Obviously](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qirzf83vpmyny206xjyp.gif)
because right now our gradient box has a static background. But we want to change the background of the gradient box to the color user picked which means we need to change the state of the app as the user changes the color of the color picker and the best way to deal with this scenario is to use useState hook (because I am using functional components)

What we need to do
1. Create a variable (using useState because we also need to change the state of our app) that will store the value of the color as the user changes the color of the color picker.
2. Pass that variable to the gradient box so that we can apply that color to the background.

Let's tackle the first part.

Create a useState hook that will store the color of the color picker.

```JavaScript
const App = () => {
  const [gradientValues, setGradientValues] = useState({
    color1: "#bb00ff"
  });
```
I have also given some default colors to this variable. This default color will be rendered when our app will be loaded for the first time.

Now let's tackle the second part.

Simply pass this variable as a prop to the GradientBox component.

```JavaScript
        <div className="gradient_container_main_gradient_box">
          <GradientBox 
          color1 = {gradientValues.color1}/>
        </div>
```

And in the GradientBox component

```JavaScript

import React from "react";
import styled from "styled-components";

const GradientBoxStyle = styled.div`
  width: max(20vw, 200px);
  height: max(30vw, 300px);
  background: linear-gradient(45deg, red, blue);
  margin: 3em auto;
  border-radius: 30px;
`;

const GradientBox = ({
  color1
}) => (
  <GradientBoxStyle 
  color1 = {color1}
  />
);

export default GradientBox;
```
Instead of using props, I destructured it using JavaScript object destructuring to use the direct value and also pass this value inside the style component so that I can access this variable inside my stylesheet.

Now set the background to the chosen color.

```JavaScript
import React from "react";
import styled from "styled-components";

const GradientBoxStyle = styled.div`
  width: max(20vw, 200px);
  height: max(30vw, 300px);

  background: ${({
    color1,
  }) =>
    `linear-gradient(45deg, ${color1}, red)`};
  
  margin: 3em auto;
  border-radius: 30px;
`;

const GradientBox = ({
  color1,
}) => (
  <GradientBoxStyle
    color1={color1}
  />
);

export default GradientBox;
```
Output

![Output of the above code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6lq2ccmi8hwhq87hh9ur.png)

But now if we still try to change the color of the gradient box by choosing color from color picker nothing will happen.

![WHY](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fw62tckcktrkzc8uc6up.gif)

Because we still haven't added the color-changing functionality. We didn't tell ours react app what will happen if someone changes the color of the color picker.

Now let's discuss what we need to do to add this functionality.

1. We need to keep listening for changes in the color input.
2. We need to get the value of the current color the user is on.

Let's tackle the first problem

We are going to use the onChange property to keep listening for any change in the ColorInput.
```JavaScript
const ColorInput = ({
  colorInputChangeHandler
 }) => (
  <ColorInputStyle
    type="color"
    onChange={(e) => colorInputChangeHandler(e)}
  />
);
export default ColorInput;
```
colorInputChangeHandler as the name itself suggests is going to tell ours react app what will happen if we change the color of the input. We are passing these functions as a prop. And also we need the current color the user is on therefore I am passing e, which will contain all the information related to ColorInput.

Now let's create this function and pass this function to the ColorInput component

```JavaScript
  const colorInputChangeHandler = (e) => {
    const color = e.target.value;
    setGradientValues({
      ...gradientValues,
      color1: color
    })
  };
```
Here I am storing the value of the current color to the color variable and updating the state with the value of the new color that the user selected.

"...gradientValue" is a spread operator if you don't know about it let me give you a brief intro to it.

...gradientValue will get all the previous values stored in the gravientValue. Then we can update whatever value we want without changing the object.

Consider this example
```JavaScript 
gradientValue = {
    color1: "color 1 value",
    color2: "color 2 value"
}

// without using spread operator
setGradientValue({
    color1: "color 1 change value"
})

console.log(gradientValue)
// output
/*
  gradientValue = {
        color1: "color 1 change value"
}

property color 2 is gone.
setGradientValue set { color1: "color 1 change value" } this object to the gradientValue
*/

// using spread operator
setGradientValue({
    ...gradientValue
    color1: "color 1 change value"
})

console.log(gradientValue)
// output
/*
  gradientValue = {
        color1: "color 1 change value",
        color2: "color 2 value"
}
```

Right now gradientValue contains only one value so you will not notice the difference but later we are going to add more property to it.

![output of the above code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ifv5ayv5evqrzmwxqtji.gif)

When you load the page the starting color in the gradient box is #bb00ff but the starting color in the color input is black. We need to fix that. This problem can be easily fixed by setting the value property of the color input to the current color of the gradient box.

Pass the current value of the color to the ColorInput

```JavaScript
<div className="gradient_container_main_color_box">
          <ColorInput
            colorValue={gradientValues.color1}
            colorInputChangeHandler={(e) => colorInputChangeHandler(e)}
          />
```
and in the ColorInput

```JavaScript
const ColorInput = ({ 
  colorValue, 
  colorInputChangeHandler }) => (
  <ColorInputStyle
    type="color"
    value={colorValue}
    onChange={(e) => colorInputChangeHandler(e)}
  />
);
```

Now when you load the page you will get

![output of the above code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n2ipblqtye62z1q0lxyq.png)

Now with the same logic let's add functionality to other color input

First let's create the variable to store the current color value

```JavaScript
  const [gradientValues, setGradientValues] = useState({
    color1: "#bb00ff",
    color2: "#00ffee",
  });
``` 
Pass all this value to the second ColorInput

```JavaScript
//Second color input
          <ColorInput
            colorValue={gradientValues.color2}
            colorInputChangeHandler={(e) => colorInputChangeHandler(e)}
          />
```

and also pass this value to the GradientBox

```JavaScript
          <GradientBox
            color1={gradientValues.color1}
            color2={gradientValues.color2}
          />
```
and in the GradientBox

```JavaScript
import React from "react";
import styled from "styled-components";

const GradientBoxStyle = styled.div`
  width: max(20vw, 200px);
  height: max(30vw, 300px);
  background: ${({
    color1,
    color2,
  }) =>
    `linear-gradient(45deg, ${color1}, ${color2})`};
  margin: 3em auto;
  border-radius: 30px;
`;

const GradientBox = ({
  color1,
  color2,
}) => (
  <GradientBoxStyle
    color1={color1}
    color2={color2}
  />
);

export default GradientBox;

```

Output

![output of the above code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q1ortyzdy537dp2e5d7u.png)


But there is a problem. Go on and try to change the color of the gradient box by changing the color of the second color input.

![above Problem](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/19jvnkpghfrxfeal849g.gif) 

On changing the value of the second color input, the value of the first color input changes.

![and why's that](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9p2ar72kw4ll5zmdbkit.gif)![output of the above code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/holqi84g795qnx4dc7gy.gif)

Because no matter what color input we are changing, we are calling the same function (colorInputChangeHandler) which is only changing the color of the color1.

```JavaScript
  const colorInputChangeHandler = (e) => {
    const color = e.target.value;
      setGradientValues({
        ...gradientValues,
        color1: color
      });
  };
``` 
There are two ways to solve the above problem
1. To create a new function and pass that in the second color input
2. We can use the name property of the input tag in HTML to identify which color input is currently active and change the value of color accordingly

I am going to follow the second approach. I don't want to create another function that performs the same thing. Because later we are going to add functionality to our range input and there are a total of 3 of them and I am not gonna create 3 separate functions for them.

Now let's add the name property to our color input

```JavaScript
const ColorInput = ({ colorValue, 
  colorInputChangeHandler, 
  inputName }) => (
  <ColorInputStyle
    type="color"
    value={colorValue}
    name={inputName}
    onChange={(e) => colorInputChangeHandler(e)}
  />
);
export default ColorInput;
```
Pass the inputName value to our colorInput

```JavaScript
<div className="gradient_container_main">
        <div className="gradient_container_main_color_box">
          <ColorInput
            colorValue={gradientValues.color1}
            inputName="color1"
            colorInputChangeHandler={(e) => colorInputChangeHandler(e)}
          />
          <div className="gradient_conatiner_main_color_box_range">
            <RangeInput
            />
          </div>
        </div>
        <div className="gradient_container_main_gradient_box">
          <GradientBox
            color1={gradientValues.color1}
            color2={gradientValues.color2}
          />
        </div>
        <div className="gradient_container_main_color_box">
          <ColorInput
            colorValue={gradientValues.color2}
            inputName="color2"
            colorInputChangeHandler={(e) => colorInputChangeHandler(e)}
          />
          <div className="gradient_conatiner_main_color_box_range">
            <RangeInput
            />
          </div>
        </div>
      </div>
```

Now using simple if and else statement we can check which color value we need to change.

```JavaScript
const colorInputChangeHandler = (e) => {
    const name = e.target.name;
    const color = e.target.value;
    if (name === "color1") {
      setGradientValues({
        ...gradientValues,
        color1: color
      });
    } else if (name === "color2") {
      setGradientValues({
        ...gradientValues,
        color2: color
      });
    }
  };
```

And finally the work of the color input is done.

![Celebrate](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b9am8wxx1l73ciivmfvx.gif)

##Adding functionality to range Input

Its functionality is the same as the Color Input.
1. Add some variables to keep track of the change made.
2. Add some props to our range input
3. Add a function that changes the state.
4. Pass that variable to the gradient box for changing the background.

Let's discuss these points one by one

What variable do we need?
For changing color 1 percentage, for changing color 2 percent, and for changing the angle of a linear gradient.
Let's add these variables to our state

```JavaScript
  const [gradientValues, setGradientValues] = useState({
    angle: 45,
    color1: "#bb00ff",
    color2: "#00ffee",
    color1Percentage: 50,
    color2Percentage: 50
  });
```

Let's add some props to our range input

```JavaScript
const RangeInput = ({
  start,
  end,
  rangeValue,
  rangeName,
  rangeInputChangeHandler
}) => (
  <RangeInputStyle
    type="range"
    min={start}
    max={end}
    value={rangeValue}
    name={rangeName}
    onChange={(e) => rangeInputChangeHandler(e)}
  />
);
export default RangeInput;
```
start and end will be the minimum and maximum values respectively. For example in color1Percentage start = 0 and end = 100 and in angle start = 0 and end = 360

name is provided to identify which range input is triggered (as we discuss in color input)

when the range is changed rangeInputChangeHandler will be triggered.

Let's add functionality to our range input.

```JavaScript
const rangeInputChangeHandler = (e) => {
    const value = e.target.value;
    const name = e.target.name;
    if (name === "angle") {
      setGradientValues({
        ...gradientValues,
        angle: value
      });
    } else if (name === "color1Percentage") {
      setGradientValues({
        ...gradientValues,
        color1Percentage: value
      });
    } else if (name === "color2Percentage") {
      setGradientValues({
        ...gradientValues,
        color2Percentage: value
      });
    }
  };
```
Pass all the value to range input and gradient box

```JavaScript
<GradientContainer>
      <div className="gradient_container_header">
        <h1 className="gradient_container_header_heading">
          Gradient Generator
        </h1>
        <h3 className="gradient_container_header_subheading">
          Generate your gradient
        </h3>
      </div>
      <div className="gradient_container_main">
        <div className="gradient_container_main_color_box">
          <ColorInput
            colorValue={gradientValues.color1}
            inputName="color1"
            colorInputChangeHandler={(e) => colorInputChangeHandler(e)}
          />
          <div className="gradient_conatiner_main_color_box_range">
            <RangeInput
              start={0}
              end={100}
              rangeName="color1Percentage"
              rangeValue={gradientValues.color1Percentage}
              rangeInputChangeHandler={(e) => rangeInputChangeHandler(e)}
            />
          </div>
        </div>
        <div className="gradient_container_main_gradient_box">
          <GradientBox
            color1={gradientValues.color1}
            color2={gradientValues.color2}
            angle={gradientValues.angle}
            color1Percentage={gradientValues.color1Percentage}
            color2Percentage={gradientValues.color2Percentage}
          />
        </div>
        <div className="gradient_container_main_color_box">
          <ColorInput
            colorValue={gradientValues.color2}
            inputName="color2"
            colorInputChangeHandler={(e) => colorInputChangeHandler(e)}
          />
          <div className="gradient_conatiner_main_color_box_range">
            <RangeInput
              start={0}
              end={100}
              rangeName="color2Percentage"
              rangeValue={gradientValues.color2Percentage}
              rangeInputChangeHandler={(e) => rangeInputChangeHandler(e)}
            />
          </div>
        </div>
      </div>
      <div className="gradient_container_footer">
        <h3>In Deg</h3>
        <RangeInput
          start={0}
          end={360}
          rangeValue={gradientValues.angle}
          rangeName="angle"
          rangeInputChangeHandler={(e) => rangeInputChangeHandler(e)}
        />
        <h3 className="gradient_container_footer_text">
          Code for the gradient that you have generated
        </h3>
        <h1 className="gradient_container_footer_code">
          Code will go here
        </h1>
      </div>
    </GradientContainer>
```

Use this value inside the GradientBox

```JavaScript
import React from "react";
import styled from "styled-components";

const GradientBoxStyle = styled.div`
  width: max(20vw, 200px);
  height: max(30vw, 300px);
  background: ${({
    angle,
    color1,
    color2,
    color1Percentage,
    color2Percentage
  }) =>
    `linear-gradient(${angle}deg, ${color1} ${color1Percentage}%, ${color2} ${color2Percentage}%)`};
  margin: 3em auto;
  border-radius: 30px;
`;

const GradientBox = ({
  color1,
  color2,
  angle,
  color1Percentage,
  color2Percentage
}) => (
  <GradientBoxStyle
    color1={color1}
    color2={color2}
    angle={angle}
    color1Percentage={color1Percentage}
    color2Percentage={color2Percentage}
  />
);

export default GradientBox;
```

##Finally display the linear gradient code
Using all the variable we created in the useState we can easily generate the code

```JavaScript
        <h1 className="gradient_container_footer_code">
          linear-gradient({gradientValues.angle}deg, {gradientValues.color1}{" "}
          {gradientValues.color1Percentage}%, {gradientValues.color2}{" "}
          {gradientValues.color2Percentage}%);
        </h1>
```
as the value changes the state will be updated.

and that's it. We got our linear gradient generator.