Zkk
Zkk

Reputation: 751

How to control element with hover (display and hide) in dynamic way

I create a box/card with a checkbox hidden. So, if I hover this card, the checkbox displays. If the checkbox is checked it must be always visible. If checked is false, it turn back to default behavior.

I'm using a hover propriety to display my checkbox:

CSS using material ui:

  hideCheckbox: {
    display: 'none',
  },
  showCheckbox: {
    display: 'initial',
  },

My main class:

export class Item extends Component {

state = { 
  isHovering: true,
  checkboxChecked: false,
}

handleGetCardSelected = (id, checked) => { 
 //Here I set isHovering to display my checkbox
 //checkboxChecked is a control variable to always display the checkbox if it's checked

  if(checked){
    this.setState({
      isHovering: !this.state.isHovering,
      checkboxChecked: true,
    })

  } else {
    this.setState({
      checkboxChecked: false,
    })
  }
}

handleMouseHover = () => {
  if(!this.state.checkboxChecked){
    this.setState(this.toggleHoverState);
  }
}

toggleHoverState = (state) => {
  return {
    isHovering: !state.isHovering,
  };
}
return(
 <div 
   onMouseEnter={this.handleMouseHover} 
   onMouseLeave={this.handleMouseHover}
  >
   <div className={`
     ${this.state.isHovering && classes.hideCheckbox }
     ${this.state.checkboxChecked && classes.showCheckbox}
    `}>
      <CheckBoxCard handleGetCardSelected={this.handleGetCardSelected}/>
    </div>
  </div>

 <div 
   onMouseEnter={this.handleMouseHover} 
   onMouseLeave={this.handleMouseHover}
  >
   <div className={`
     ${this.state.isHovering && classes.hideCheckbox }
     ${this.state.checkboxChecked && classes.showCheckbox}
    `}>
      <CheckBoxCard handleGetCardSelected={this.handleGetCardSelected}/>
    </div>
  </div>

 <div 
   onMouseEnter={this.handleMouseHover} 
   onMouseLeave={this.handleMouseHover}
  >
   <div className={`
     ${this.state.isHovering && classes.hideCheckbox }
     ${this.state.checkboxChecked && classes.showCheckbox}
    `}>
      <CheckBoxCard handleGetCardSelected={this.handleGetCardSelected}/>
    </div>
  </div>
 )
 }

My CheckboxCard:

import React from 'react';
import { makeStyles, withStyles } from '@material-ui/core/styles';
import { Checkbox } from '@material-ui/core';
const GreenCheckbox = withStyles({
  root: {
    color: '#43a04754',
    '&$checked': {
      color: '#43a047',
    },
    '&:hover': {
      color: '#43a047',
      backgroundColor: 'initial',
    },
  },
  checked: {},
})(props => <Checkbox color="default" {...props} />);

export default function CheckBoxCard(props){
  const [state, setState] = React.useState({
    idItem: false,
  });

  const handleCheckbox = name => event => {
    setState({ ...state, [name]: event.target.checked });

    let id = name
    let checked = event.target.checked
    props.handleGetCardSelected(id, checked)
  };

  return(
    <GreenCheckbox
      checked={state.idItem}
      onChange={handleCheckbox('idItem')}
      value="idItem"
      inputProps={{
        'aria-label': 'primary checkbox',
      }}
    />
  );
}

By default, my checkbox is hidden because my state isHovering is true, so the css variable hideCheckbox ('display: none') is set.

If I hover the element, is called handleMouseHover and the checkbox is displayed!

If I checked my checkbox, it must be displayed always! I create a checkboxChecked for control it. If true i'm always displaying my checkbox! But isn't works perfectly, because checkboxChecked must be dynamic per element, not unique.

So, how it must be works?

-> All checkbox hidden (ok)
-> Hover card and checkbox appears (ok)
-> If checkbox is checked it must ignore hover and always be displayed

I uploaded my code at sandbox, pls click here to see how it works actually

How can I do that?

Upvotes: 1

Views: 1403

Answers (1)

Ashith
Ashith

Reputation: 309

Give CSS to box display none as default. maintain 2 state isHovered and isChecked for any of this state is true you can give display block class to it. It is better to split card to a sperate component so that an easily maintain the state easily.

working code is uploaded to sandbox: here

Upvotes: 2

Related Questions