scale and change the color of a svg on hover in React

I have the following custom Icon component:

import React from 'react';
import PropTypes from 'prop-types';

const Icon = (props: any) => {
  const styles = {
    svg: {
      display: 'inline-block',
      verticalAlign: 'middle',
    },
    path: {
       fill: props.color,
    },
  };

  return (

    <svg

      style={styles.svg}
      width={`${props.size}px`}
      height={`${props.size}px`}
      viewBox="0 0 1024 1024"
    >
       <path style={styles.path} d={props.icon} /> 
    </svg>
  );


};

Icon.propTypes = {
  icon: PropTypes.string.isRequired,
  size: PropTypes.number,
  color: PropTypes.string

};

Icon.defaultProps = {
  size: 16
};

export default Icon

In another component I instantiate it with the following statement:

<Icon
          icon={ICONS.TWITTER}
          color="#fff"
          size={30}
        />

How can I change the size and color on hover? Thanks in advance!

Upvotes: 6

Views: 27299

Answers (1)

Chris Jarling
Chris Jarling

Reputation: 375

Assuming you want to solve this using React, you need to make the component that is rendering your <Icon /> component and setting its props aware of wether the <Icon /> component is hovered or not.

This means that the parent component has to become stateful and the <Icon /> component needs to implement some kind of callback when the mouse enters and leaves it. For this, you could use the onMouseEnter and onMouseLeave functions (see the docs as well). These would then just set a boolean flag in the state of the parent component, and based on this, the props would change.

An implementation could look like this:

<Icon
  icon={ICONS.TWITTER}
  color={this.state.isHovered ? '#333' : '#fff'}
  size={this.state.isHovered ? 40 : 30}
  onMouseEnter={this.handleMouseEnter}
  onMouseLeave={this.handleMouseLeave}
/>

Where handleMouseEnter() could look like this:

handleMouseEnter = () => {
  this.setState({ isHovered: true })
}

and handleMouseLeave() would just do the opposite.

Note though, that this is a lot of work to implement something that browsers already do for you (the :hover state in CSS), so it is worth considering if you need the effect to be as dynamic as it now is, or if you could just live with a fixed increase in size and color change.
Also, onMouseEnter and onMouseLeave can cause some issues with touch devices.

Upvotes: 12

Related Questions