I am implementing a simple Emoji-Rating system. There are 5 Emojis on the screen, when the user hovers over their appearance changes. It is done by the :hover
pseudo-class.
And what I wanted is also that when the user clicks on one of the emojis it stays as it was when hovered.
But anytime I click on on it and the cursor gets off, it snaps back to ita original look.
Here is the Form in ReactJs:
<form className='ratingForm' onSubmit={(event) => handleSubmit(event)}>
<div className='inputs'>
<div className='inputWrapper'>
<div id="angry-emoji-wrapper" className='emoji-wrapper angry'>
<EmojiAngry passedProp={getChildProps} value={0} />
</div>
<label className='inpLabel' htmlFor="0">Very Bad</label>
</div>
<div className='inputWrapper'>
<div id="frown-emoji-wrapper" className='emoji-wrapper frown'>
<EmojiFrown passedProp={getChildProps} value={1} />
</div>
<label className='inpLabel' htmlFor="1">Bad</label>
</div>
<div className='inputWrapper'>
<div id='neutral-emoji-wrapper' className='emoji-wrapper neutral'>
<EmojiNeutral passedProp={getChildProps} value={2} />
</div>
<label className='inpLabel' htmlFor="2">Average</label>
</div>
<div className='inputWrapper'>
<div id='smile-emoji-wrapper' className='emoji-wrapper smile'>
<EmojiSmile passedProp={getChildProps} value={3} />
</div>
<label className='inpLabel' htmlFor="3">Good</label>
</div>
<div className='inputWrapper'>
<div id='laughing-emoji-wrapper' className='emoji-wrapper laugh'>
<EmojiLaughing passedProp={getChildProps} value={4} />
</div>
<label className='inpLabel' htmlFor="4">Very Good</label>
</div>
</div>
<button className='btn btn-success' type="submit">Submit</button>
</form>
One of the Emoji components using react-icons npm package:
import { BsEmojiAngryFill } from 'react-icons/bs';
export default function EmojiAngry(props) {
function handleClick() {
props.passedProp(props.value);
}
return (
<BsEmojiAngryFill onClick={handleClick} />
)
}
And here is the CSS for it:
/*==================================EMOJI===================================*/
svg {
width: 70px;
height: 50px;
color: rgb(201, 201, 201);
}
/*ANGRY*/
#angry-emoji-wrapper.emoji-wrapper.angry:hover>svg,
#angry-emoji-wrapper.emoji-wrapper.angry:focus>svg {
color: #de332b !important;
transform: scale(1.2) !important;
transition: all .1s ease-in-out !important;
cursor: pointer !important;
}
I have tried using tabIndex={0}
but all I achieved was an outline that kept changing size depending on the emoji's current scale.
I have tried writing different css, so not like just separate the hover and focuse with comas.
And also I have tried using the :active
pseudo as well but nothing.
Looks like I managed to solve it by adding a new class based on whether the emoji is clicked or not and then use that in css.
Looks like this (not exactly its just a part of it)
const [selectedEmoji, setSelectedEmoji] = useState(null);
function getChildProps(value) {
setRating(value);
setSelectedEmoji(value);
console.log(value)
}
<div className={`inputWrapper`}>
<div id="angry-emoji-wrapper" className={`emoji-wrapper angry ${selectedEmoji === 0 ? 'selected' : ''}`}>
<EmojiAngry passedProp={getChildProps} value={0} />
</div>
<label className='inpLabel' htmlFor="0">Very Bad</label>
</div>
The component itself has not changed. And this is the CSS:
/*==================================EMOJI===================================*/
svg {
width: 70px;
height: 50px;
color: rgb(201, 201, 201);
}
/*ANGRY*/
#angry-emoji-wrapper.emoji-wrapper.angry:hover>svg,
#angry-emoji-wrapper.emoji-wrapper.angry:focus>svg,
#angry-emoji-wrapper.emoji-wrapper.angry.selected>svg {
color: #de332b !important;
transform: scale(1.2) !important;
transition: all .1s ease-in-out !important;
cursor: pointer !important;
}