Deen John
Deen John

Reputation: 3750

how to pass className to svg in styled components

I have been trying to style svg icon component via styled component and facing some issue but it's not working.The style i apply to close icon are not getting applied

import styled from 'styled-components'
import Close from './close.svg'

const CloseIcon = ({ className , ...props }) => <Close {...props} className={className} />

const styledCloseIcon = styled(CloseIcon)`
  &.ui.modal {
    .modal-icon-close {
      width: 14px;
      height: 24px;
      fill: black;
      top: 12px;
      right: 14px;
    }
  }
`
export default styledCloseIcon

close.svg

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
    <path d="M13.627 12.213l9.9 9.9-1.414 1.414-9.9-9.9-9.9 9.9L.9 22.113l9.9-9.9-9.9-9.9L2.314.9l9.9 9.9 9.899-9.9 1.414 1.415-9.9 9.9z"/>
</svg>

This close icon is being used in semantic ui react modal https://react.semantic-ui.com/modules/modal/#variations-close-icon


<Modal
      size='small'
      open={true}
      closeIcon={<Close className='modal-icon-close'/>}
      closeOnDimmerClick={false}
      className={classNames(className)}
      >

Upvotes: 2

Views: 11195

Answers (3)

Jar
Jar

Reputation: 2010

here's how I assign className to SVG file:

import { ReactComponent as MyImage } from '../assets/img/myimage.svg' 

<MyImage
    className='myClassName'
    fill='white'                            
/>

Index.css:

.hoverColor:hover {
    fill: yellow !important;
    opacity: 1 !important;
}

Upvotes: 0

Drew Reese
Drew Reese

Reputation: 202751

Issues

I think there are a couple of issues

  1. import Close from './close.svg'; isn't a valid react component
  2. Unnest the class in the styled component

Solution

First create a proper SVG react component

const CloseIcon = ({ className, ...props }) => (
  <svg
    xmlns="http://www.w3.org/2000/svg"
    viewBox="0 0 24 24"
    {...props}
    className={className}
  >
    <path d="M13.627 12.213l9.9 9.9-1.414 1.414-9.9-9.9-9.9 9.9L.9 22.113l9.9-9.9-9.9-9.9L2.314.9l9.9 9.9 9.899-9.9 1.414 1.415-9.9 9.9z" />
  </svg>
);

Second make modal-icon-close a top-level class in the styled component

const StyledCloseIcon = styled(CloseIcon)`
  &.modal-icon-close {
    width: 14px;
    height: 24px;
    fill: black;
    top: 12px;
    right: 14px;
  }
`;

Edit how to pass className to svg in styled-components

What doesn't make much sense to me is why internalize the classname and CSS and then require the correct classname prop to be passed anyway? You could simplify the component by also specifying the className prop using .attrs

const StyledCloseIcon = styled(CloseIcon).attrs(() => ({
  className: 'modal-icon-close',
}))`
  &.modal-icon-close {
    width: 14px;
    height: 24px;
    fill: black;
    top: 12px;
    right: 14px;
  }
`;

Or just simply eliminate the classname altogether

const StyledCloseIcon = styled(CloseIcon)`
    width: 14px;
    height: 24px;
    fill: black;
    top: 12px;
    right: 14px;
`;

Upvotes: 1

subashMahapatra
subashMahapatra

Reputation: 6837

When you call styled(CloseIcon) you are already styling the SVG because the custom component accepts className prop so styled-components can inject the className and only renders the SVG icon.

Try omitting all the nested class names and directly apply the styles.

Here is an example,

import React from "react";
import ReactDOM from "react-dom";

import styled from "styled-components";
import { ReactComponent as Close } from "./close.svg";

const CloseIcon = ({ className, ...props }) => (
  <Close {...props} className={className} />
);

const StyledCloseIcon = styled(CloseIcon)`
  width: 30px;
  height: 30px;
  fill: #ee4845;
`;

const App = () => {
  return (
    <div>
      <StyledCloseIcon />
    </div>
  );
};

Working demo in codesandbox

Upvotes: 4

Related Questions