2

I have created a react checkbox component I am struggling to make it so that I can call different background colors to the box once it checked. I want to be able to have a primary, secondary and info attributes.

I just don't know how to add this functionality to the checkbox component. I want different colors, types and size for the checkbox I would like to change background colors based on what type checkbox it is - so if primary = blue, success = green and so on.

class Checkbox extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      checked: true,

    };
    this.onChange = this.onChange.bind(this);
  }


  onChange = () => {
    this.setState({
      checked: !this.state.checked
    });

  }


  render() {
    return ( 
     <div className="checkbox" onClick={this.onChange}>
      <div className="checkbox-box"> {
        this.state.checked &&
        <span className="checkbox-box-mark">
        <svg 
          viewBox = "0 0 64 64"
          xmlns = "http://www.w3.org/2000/svg"
        >
        <path 
          d="M21.33,57.82,0,36.53l5.87-5.87L21.33,46.09,58.13,9.36,64,15.23,21.33,57.82"/>
        </svg>
        </span>
      } 
      </div>  
      <div className="checkbox-label">checkbox</div> 
      </div>   
    );
  }
}
export default Checkbox

2 Answers 2

1

A simple way of doing this is to set up a styles object in your Checkbox component to define primary and success, and info styles and add a style attribute to the parent div that updates its style based on the type (passed in through props) when the box is checked.

So there are three key things:

1) We pass in a type property to the component. In the component we assign that value to a new type property in state.

2) We set up a styles object that contains the background colours for each different checkbox type

3) We assign a colour object from the styles object if checked is true.

Let's break down how that works:

style={checked ? { width: '50px', ...styles[type] } : { width: '50px' }}

The style attribute accepts an object. In the case where checked is false we want to return an object that defines the width, but if checked is true we want to return an object with the width definition and the colour definition from styles. In the above line I've used a ternary operation that translates as:

if (checked) use the combined width object and styles[type] object (else) just use the object with the width definition`.

const { Component } = React;

// App.js

function App() {
  return (
    <div className="App">
      <Checkbox type="primary" />
      <Checkbox type="success" />
      <Checkbox type="info" />
    </div>
  );
}

// Checkbox.js


// Style definitions
const styles = {
  primary: { backgroundColor: 'blue' },
  success: { backgroundColor: 'green' },
  info: { backgroundColor: 'cyan' }
}

class Checkbox extends Component {

  constructor(props) {
    super(props);

    // Set a new type property in state and assign the
    // props value of type to it
    this.state = { type: props.type, checked: false };
    this.onChange = this.onChange.bind(this);
  }

  onChange = () => {
    this.setState({ checked: !this.state.checked });
  }

  render() {
  
    // Destructure the type and checked properties from state
    const { type, checked } = this.state;
  
    return (
      <div className="checkbox" onClick={this.onChange}>
        {/* If the box is checked set a width of 50px and apply the styles for that type */}
        {/* Otherwise just set a width of 50px */}
        <div
          className="checkbox-box"
          style={checked ? { width: '50px', ...styles[type] } : { width: '50px' }}
        >
          <span className="checkbox-box-mark" >
            <svg viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
              <path d="M21.33,57.82,0,36.53l5.87-5.87L21.33,46.09,58.13,9.36,64,15.23,21.33,57.82"/>
            </svg>
          </span>
        </div>
      </div>
    );
  }

}

ReactDOM.render(<App />, document.querySelector("#root"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"/>

Further reading
Sign up to request clarification or add additional context in comments.

2 Comments

Hi Andy, thanks for the help - I am quite new to this and its way over my head at the moment. I see it working but dont understand why its working and how I can make mine work like yours.
@Fulano, I've added some additional commentary to the answer. Hope it helps.
0

this is quite easy: 1. define your component type ("primary", etc) as a component state property 2. Remember to call setState when you want to change this property. 3. render all other dependent properties in a render method using conditional rendering: https://reactjs.org/docs/conditional-rendering.html

If still not clear, I let me know :)

4 Comments

Hi Denis, Thanks for the suggestion. I don't get the SetState - I keep on banging my head agains the wall.
Hi Fulano, you can check how it works here: codepen.io/luvram/pen/MyKvOE (result is in the lower window part)
And here how you should set css properties: create classes with set of properties (background color, size, etc, and then set corresponding class): upmostly.com/tutorials/changing-the-background-color-in-react
Hi Denis, I get what the setState is doing there but how can I call my component like this: <Checkbox type='primary' > </Checkbox> The type primary here would be a className and that class will be blue and red if I call "warning" and so on. I think a need a function for that but dont know where to put it or the logic for it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.