Tips for adding style to a group of SVG elements:

I currently have an array of .svg icons, each with unique properties that I need to customize:

<svg width="24" height="24" viewBox="0 0 24 24"> ... </svg>
import styled from 'styled-components';

import Github from 'assets/github.svg';
import Facebook from 'assets/facebook.svg';
import Twitter from 'assets/twitter.svg';
...

const icons = [
  <Github />,
  <Facebook />,
  <Twitter />,
  ...
];

My goal is to style all icons consistently without redundant code and utilize CSS-in-JS.

Although my current solution works, there are some drawbacks:

// Effective but not using CSS-in-JS like styled-components
// Making future updates challenging
const iconStyle = {
  width: 50,
  height: 50
};

const SocialBar = () => (
  <IconBar as={FlexBox}>
    {icons.map((icon, key) => (
      <div key={key}>{React.cloneElement(icon, iconStyle)}</div>
    ))}
  </IconBar>
);
// Functional but dealing with excessive amount of icons
const SocialBar = () => (
  <IconBar as={FlexBox}>
    <Github style={iconStyle} />
    <Facebook style={iconStyle} />
    ...
  </IconBar>
);

Attempting to style the svg component directly may not yield the desired results:

// Does not override the existing width="24" height="24" properties
const StyledIcon = styled(Github)`
  width: 50;
  height: 50;
`;

Answer №1

To customize SVG elements, wrap them within a parent element and apply CSS styles using styled-components. It may be necessary to manually transfer SVG code into a JavaScript file for easier manipulation. Check out this example demonstrating how to work with SVGs in React:

For a live example and code sandbox, click here: https://codesandbox.io/s/styled-svg-component-f6cu2?fontsize=14


The Icon component accepts a styled component generated className and any children nested inside it.

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

const Icon = ({ className, children }) => (
  <i className={className}>{children}</i>
);

Icon.propTypes = {
  className: PropTypes.string.isRequired,
  children: PropTypes.node.isRequired
};

export default Icon;

The following code styles the Icon component with its children using styled components:

import styled from "styled-components";
import Icon from "./Icon";

const StyledIcon = styled(Icon)`
  margin: 0 20px;
  svg {
    fill: ${({ fill }) => fill || "#03a9f3"};
    height: ${({ dimension }) => dimension || "50px"};
    width: ${({ dimension }) => dimension || "50px"};
  }
`;

export default StyledIcon;

Answer №2

Here's a method to accomplish the task.

//Github.js
import React from "react";
export default function Github({size, dimensions}) {
    return (
        <svg width={dimensions} height={size} viewBox="0 0 24 24"> ...  </svg>
    );
}

Next, implement it wherever necessary.

<Github size={24} dimensions={24} />

Answer №3

Not entirely clear on your request in relation to the existing code samples provided. Are you attempting to avoid utilizing React.cloneElement? Transform the array of icons into functions instead of a jsx element. Utilize the map method to convert it into jsx and apply styles to each individual icon.

const icons = [
  Github,
  Facebook,
  Twitter,
]

buildIcons() {
  const style = {
    //..
  }
  return icons.map((icon, idx) => (
    <icon style={style} key={idx}/>
  ))

}

Using the index as the key is functional, yet if there's an alternative unique property for each icon, that would be preferred.

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

What is the reason behind Typescript flagging a potential undefined value when checking for array length using a greater than comparison but not with an

Consider the following excerpt from a React component: const AccountInformation = (props: { readonly accountData: AccountData | undefined | null }) => { const hasMultipleAccounts: boolean = props.accountData?.customerAccounts?.length === 1 ? false : t ...

Invalid JSON cannot be defined

I'm encountering the error mentioned above in this React component. Despite my best efforts in reviewing it, everything appears to be correct, so I'm puzzled as to why the error is occurring. I am utilizing next.js 13.3.0. Uncaught SyntaxError: ...

Button in HTML not functioning as expected

I have 3 different files that are crucial for my webpage to function properly: index.html: <html> <head> </head> <body> <h1>Webpage</h1> <p id = "text">Hello world!</p> <button oncl ...

The edit functionality in jqGrid does not function properly if custom search parameters are designated

Using the Guriddo jqGrid JS version 5.2.0 implemented here: @license Guriddo jqGrid JS - v5.2.0 - 2016-11-27 Copyright(c) 2008, Tony Tomov, [email protected] The code block below showcases an entire self-contained implementation of jqGrid. It inclu ...

Issue with host-context scss rules not appearing in final production version

I am facing an issue in my Angular project where the scss rules that define how components should look when within the context of another component are not being applied when I build for production and put it live. Here is an example: :host-context(my-tabl ...

Generate a new array of objects by cloning an existing array of objects with placeholder values

I am looking to transform an array of objects into another array of objects in order to generate a graph. Below is the array I am using to determine the position of each object within the new object. let uniqueSkills = ['Using', 'Analyzing ...

Tips for distinguishing between the different values

Greetings! I am currently utilizing this code snippet to retrieve values from a Java class. Upon getting the data from Java, it triggers an alert displaying two values separated by spaces. My next goal is to split the values into two separate entities an ...

When selecting an option in the burger menu, the dropdown does not react properly

I am facing an issue with the burger menu where one of the options should trigger a dropdown, but the content is not adjusting properly. The dropdown menu should push the other content downward, but currently, it overlaps. I have included the code for th ...

Is it possible to use "/path/{?}" in a path when working with Node.js?

I am new to node.js and I'm working on creating a route that will verify the authorization of all users when the specified endpoint begins with /api. I've learned that an optional value can be indicated using ? like {_id?}, but is it possible to ...

What could be causing the unexpected behavior of req.query in NEXT.js?

In the latest version of NextJS App Router, I have the following code located in the file app\api\products\route.tsx import { initMongoose } from "@/lib/mongoose"; import Product from "@/models/products"; import { NextApi ...

What is the method to close the picker when using type="datetime-local"?

Currently, I am utilizing Vue with the "datetime-local" type for input. While I can successfully select the date and time, my goal is to have the picker close automatically after a selection has been made. I've experimented with adding an onchange ev ...

I am working on an HTML form that is designed vertically, but I am unsure of how to arrange two text fields side by side on the same line

I'm struggling with formatting my HTML form to have two text fields on the same line instead of stacked vertically. In the example below, I want the Size, Width, and Height fields to be aligned horizontally rather than one below the other. <form c ...

Aligning Description Item components horizontally in antdLearn how to easily horizontally align Description

Currently, I am utilizing the `antd` Description components. In this scenario, when there is no `title` for the items, the value should be aligned to the left. You can see an example of this alignment in the image below: https://i.sstatic.net/Ah70f.png I ...

Avoiding duplication of prints in EJS template files

In my EJS code, I have created a loop to fetch the total amount of items from the database. Here is my current code: <h2>Summary</h2> <% if(typeof items.cart!=="undefined"){ var amount = 0; %> <% i ...

Steps to insert a Drop-Down Sub-Menu

I'm just about finished with my navigation panel. Any tips on how to add a sub-menu? I currently have one in the Product page. Below is the HTML code containing the sub-menus: <nav> <ul> <li><a href="">HOME</a>&l ...

Objects of equal nature combine and sift through

I am looking to categorize objects based on their status ID and also retrieve data and CSR counts for each item. Each StatusName has multiple items: [ { "StatusId": 2, "StatusName": "ordered", " ...

Can you explain the significance of this error message that occurs when attempting to execute a node.js script connected to a MySQL database?

const mysql = require('mysql'); const inquirer = require('inquirer'); const connection = mysql.createConnection({ host: "localhost", port: 8889, user: "root", password: "root", database: "bamazon" }) connection.conn ...

Using jQuery to dynamically load custom post type data in WordPress upon clicking

Let me explain my current project setup. I have developed a custom post type called "People" and have created several individual posts within it. At the moment, I have successfully implemented a modal using JavaScript with static content. Instead of disp ...

Container element refusing to grow in size while the footer remains fixed on the screen

Description: I recently encountered an issue with the layout of my website. I have a main content div (#main) and a container div (.display), which should expand automatically with content to push the footer down. Initially, I struggled to get this workin ...

Updating state in Redux from a different componentorModifying state

I'm currently learning about redux and I'm facing an issue with accessing the stored state (id) in my components. Specifically, I have a Footer component with a button that is supposed to modify the state in the Layout component. However, I am un ...