Kiazim Khutaba
Kiazim Khutaba

Reputation: 323

onClick event handler not work as expected when attached to SVG Icon in React

I use SVG Icons as React components in my current project and faced with next problem:

When I click on icon, that has attached onClick event handler - sometimes handler works, sometimes not. I observed, that this depends where mouse pointer currently placed - if it placed on svg element to which handler attached - it works, otherwise - if mouse pointer placed on svg child path element - handler not works.

This is example of my Icon Component:


import React from 'react';

const IconTrash = ({ onClick, style, ...rest }) => {
    return (
        <svg width="1em" height="1em" viewBox="0 0 16 16" className="bi bi-trash" fill="currentColor"
             xmlns="http://www.w3.org/2000/svg"
             onClick={onClick}
             style={{ ...style, cursor: 'pointer'}}
             {...rest}
        >
            <path
                d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z"/>
            <path fillRule="evenodd"
                  d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4L4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z"/>
        </svg>
    );
};

export default IconTrash;

As temporary solution I decided attach onClick handler to all elements, but I think this is not good.

So, how to call handler, independently where mouse pointer appeared on svg or on it child?

Upvotes: 2

Views: 2567

Answers (2)

Ricardo
Ricardo

Reputation: 1356

I had the same problem.

I used to have that problem when doing this (WRONG WAY):

<div className="flex flex-row">
  <VscNewFolder
    onClick={createNewFolder}
    className="w-5 h-5 mr-2 text-gray-400 transform hover:scale-110 hover:bg-gray-700 rounded-sm"
  />
</div>

I can fix that by

  • Wrapping the icon in a div
  • Set the icon's pointerEvents="none"

Ending looking something like this: (RIGHT WAY)

<div className="flex flex-row">
  <div onClick={createNewFolder}
    className="w-5 h-5 mr-2 text-gray-400 transform hover:scale-110 hover:bg-gray-700 rounded-sm">
    <VscNewFolder
    pointerEvents="none"
    className="w-full h-full"
    />
  </div>                  
</div>

Upvotes: 5

dannyxnda
dannyxnda

Reputation: 1014

I think the best way to solve it is wrapping <svg> in another tag (button, span, ...) and add onClick event to the wrapper. Anyway, an svg contains all its children and I don't know how can your situation occur.

If you pass onClick to svg and its children, when you click the children, it will trigger both on them and svg.

Upvotes: 0

Related Questions