how can I apply a class name to an SVG element within styled components

I've been attempting to style an SVG icon component using styled-components, but I'm encountering some issues as the styles I apply to the close icon are not taking effect.

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 utilized in a Semantic UI React modal


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

Answer №1

By using styled(CloseIcon), you are automatically applying styles to the SVG as the custom component accepts the className prop. This allows styled-components to add the necessary styles and only display the SVG icon.

Instead of using nested class names, try applying styles directly.

For 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>
  );
};

Check out the working demo on codesandbox

Answer №2

Challenges

I have identified a few challenges

  1. import Close from './close.svg'; is not recognized as a valid react component
  2. Need to refactor the class structure in the styled component

Resolution

First step is to 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>
);

Next, ensure modal-icon-close is 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;
  }
`;

https://codesandbox.io/s/upbeat-pine-j6b1f?fontsize=14&hidenavigation=1&module=%2Fsrc%2FApp.js&theme=dark

It seems redundant to internalize the classname and CSS, only to require the correct classname prop to be passed. Simplify the component by 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;
  }
`;

Alternatively, consider eliminating the classname altogether

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

Answer №3

This is the way I set a class name for an SVG file:

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

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

styles.css:

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Just dipping my toes into the world of backend development and diving into the intric

Hi everyone, I've been working on coding for a little over a year now and have mainly focused on frontend technologies like JavaScript, various frameworks, CSS, and HTML. Just yesterday, I encountered the notorious CORS issue with the Spotify API. Ev ...

Retrieve the most recently added item in the Material-ui Autocomplete component

Currently, I am incorporating the material-ui Autocomplete component with multiple selection feature. In one specific scenario, I require the ability to retrieve only the value of a newly added item. Despite utilizing the onChange listener, the event pro ...

What could be causing my dropdown links to malfunction on the desktop version?

I've been developing a responsive website and encountering an issue. In desktop view, the icon on the far right (known as "dropdown-btn") is supposed to activate a dropdown menu with contact links. However, for some unknown reason, the links are not f ...

Dividing the code into a function and invoking it does not produce the desired outcome

Everything seemed to be working perfectly until I attempted to encapsulate the code into a function and call it within my expression. Unfortunately, this approach did not yield the desired results. Functional code: render: function() { return ( ...

Excluding Gitlab's node_modules from the .gitignore: How to modify and upload a module?

I've added node_modules to .gitignore but now I need to update a module (Searchbar from reactnativeelements). What's the best and cleanest way to push this change to my GitLab repository? Creating a separate folder for the complete module and upd ...

Error in Typescript: The type 'string' cannot be assigned to the type '"allName" | `allName.${number}.nestedArray`' within the react hook form

Currently, I am tackling the react hook form with typescript and facing a challenge with my data structure which involves arrays within an array. To address this, I decided to implement the useFieldArray functionality. allName: [ { name: "us ...

Select the radio button by hovering the mouse over it

Is there a way to check my radio buttons when hovering over them without having to click? I want to display photos based on the selected radio button. I attempted this using JQuery, but I am still learning and consider myself a beginner. ...

Applying CSS Filters can sometimes interfere with the functionality of 3D

While playing around with CSS transforms, I discovered that filters flatten the transforms just like setting transform-style: flat. var toggleFilter = function() { var div = document.getElementById("cube") if (div.className == "cube") { d ...

React Router will not remount the component when using this.context.router.push

We have implemented a click handler that utilizes react router 2.0 to update the URL with this.context.router.push(). Here is the code snippet: selectRelatedJob(slug) { JobActionCreators.fetchJobPage(slug); JobsActionCreators.getRelatedJobs({'sl& ...

What is the most efficient method for saving Redux state into local state using React JS?

In my application, I have a reducer called tables which includes a state named mainTables. I am utilizing the react-dnd library to manage the positioning of these tables. const initialState = { channel: null, errors: null, mainTables: [], takeaways: [ ...

Encountering type errors in React+Typescript while dynamically setting values in the change handler

I am currently working on dynamically generating a form based on an array of objects. The objective is to allow users to create accounts dynamically by clicking the Add User button and then submit the complete state object of users to the backend. Encoun ...

React component state change in reverse

As I work on a simple login form component, I encountered an issue where clicking on the form should make it disappear and only display my JSON data. However, due to my limited experience with React state management, I seem to be achieving the opposite eff ...

emulate the removal of a material-ui Chip

I'm looking to create a test that removes a material-ui Chip component from my InputTag component. Does anyone have any suggestions on how to make this happen? Here is what I have tried so far: import React from 'react'; import InputTag fro ...

Guidelines for automating button click using selenium in Python

<div class="wrapper"> <button class="w-full h-14 pt-2 pb-1 px-3 bg-accent text-dark-1 rounded-full md:rounded select-none cursor-pointer md:hover:shadow-big focus:outline-none md:focus:bg-accent-2 md:focus:shadow-small "> ...

TypeScript: Unable to fetch the property type from a different type

Currently, I'm using create-react-app with its TypeScript template. However, I encountered an issue while attempting to retrieve the type of the property 'pending' in 'GenericAsyncThunk', similar to how it's done in the redux- ...

Issue with state not being updated upon clicking "Save" button

After setting multiple items in the TransferList component provided by Material-UI, I am encountering an issue when trying to update a state upon clicking "Save". The problem is that the state does not update immediately after clicking "Save"; it requires ...

When React first fetches data and users move to chat with each other, the state value does not update

Recently, I started learning about React and Node.js as I dive into building a chat application. When a user is clicked for one-on-one chat, I retrieve records from the database using backend Node.js and also incorporate socket.io. In my Chat.js file: imp ...

Error: Cannot use Object.fromEntries as a function

I encountered an issue with some older iPhones, specifically iPhone 7 and iPhone 10. https://i.sstatic.net/gX32N.png I have been unsuccessful in finding a solution to this problem. The libraries I am utilizing "@chakra-ui/react": "^1.4.1 ...

Converting a List of Maps from Immutable.js into a List of Lists and utilizing it as the dataset for Google Charts

I am currently working on implementing the Google Charts library to visualize some time series data. Right now, I have dummy data stored in a separate file from my application. In this file, I have an Immutable List structured like this: le ...

Is it possible for a div to extend beyond the previous div's boundaries using CSS?

When viewing a website like GameFAQs, you may notice that there are two divs positioned next to each other - the main content and an aside (such as a poll). As you resize the window, the aside sometimes moves down below the main content without leaving any ...