Create custom react material ui icon from double svg d path - reactjs

I want to create a custom material ui icon from a svg file with two paths.
My code using
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import { green } from '#material-ui/core/colors';
import SvgIcon from '#material-ui/core/SvgIcon';
const useStyles = makeStyles((theme) => ({
root: {
'& > svg': {
margin: theme.spacing(2),
},
},
}));
function GradIcon(props) {
return (
<SvgIcon {...props}>
<path
d="M142.45,174.613c-4.645,0-11.495-0.514-17.779-2.926l-50.271-19.366H49.774v30.162c0,9.274,6.9,19.802,15.405,23.499
l60.872,26.496c8.505,3.691,22.312,3.707,30.826,0.036l61.536-26.574c8.508-3.671,15.41-14.183,15.41-23.457v-30.162h-27.175
l-44.547,18.78C156.742,173.365,149.756,174.613,142.45,174.613z"
/>
<path
d="M6.475,112.944l121.222,46.709c8.661,3.329,22.603,3.112,31.152-0.492l115.768-48.801v71.999l-7.151,23.866h20.682
l-7.399-24.114V107.45h-0.208c4.997-3.449,3.832-7.747-3.567-10.393L159.196,55.146c-8.74-3.117-22.859-2.985-31.545,0.277
L6.529,100.99C-2.157,104.258-2.178,109.612,6.475,112.944z"
/>
</SvgIcon>
);
}
export default function SvgIconsColor() {
const classes = useStyles();
return (
<div className={classes.root}>
<GradIcon />
</div>
);
}
like in the docs didn't work out. As I am fairly new to javascript and react I thought I'd ask on here.
Thanks

I solved it by creating a separate component with the following Layout like in this tutorial:
First I converted the image online to an svg.
Then I opened it within an editor and selected the whole svg part.
This part is posted within the component like below. Be sure to disable any unnecessary properties, and set the width and height to 24. The properties below should be enough. Don't delete parts. Just comment out and try till it fits your desired output.
import React from "react";
const IconName = () => {
return (
<svg xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
version="1.1"
viewBox="<viewBox>"
<path d="<path>"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
fill="<color>"
fill-rule="evenodd"
/>
</svg>
);
};
export default IconName;
Then just import the icon to the component you need it in.
The number of paths doesn't matter, just remember to include all the properties after the path.

Related

Why is the SvgIcon is not rendering in React MUI v5

I am trying to create a custom SVG component with material UI and typescript in rect that can be reused as an icon anywhere.
But, the icon is not rendering in the screen. I can't figure out why?
import { SvgIcon, SvgIconProps } from "#mui/material";
const ImgCompress: React.FunctionComponent<SvgIconProps> = (props) => {
return (
<SvgIcon
viewBox="0 0 512.000000 512.000000"
width="512.000000pt"
height="512.00000pt"
transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
stroke="none"
fill="#000000"
preserveAspectRatio="xMidYMid meet"
>
<path d="M15,19.16V15.07a4.27,4.27,0,0,0,6,0h0a4.27,4.27,0,0,0,0-6h0a4.27,4.27,0,0,0-6,0l-3,3-3,3a4.27,4.27,0,0,1-6,0h0a4.27,4.27,0,0,1,0-6h0A4.27,4.27,0,0,1,9,9" />
</SvgIcon>
);
};
export default ImgCompress;

SVG in React Component [duplicate]

This question already has answers here:
How to display svg icons(.svg files) in UI using React Component?
(16 answers)
Closed 12 months ago.
i've downloaded an svg image which i was intending in using it as a react component , but i paste the svg code to the functional component i get error markes within the tags , what i can do to fix this so ill be able to use the icon
import React from 'react'
const CardanoIcon = () => {
return (
<svg height="256" viewBox="0 0 256 256" width="256" xmlns="http://www.w3.org/2000/svg"><defs><style>
.cls-1 {
fill: #3468d1;
}
.cls-2 {
fill: #fff;
fill-rule: evenodd;
}
</style></defs><g data-name="cardano ada" id="cardano_ada"><g data-name="cardano ada" id="cardano_ada-2"><circle class="cls-1" cx="128" cy="128" data-name="Эллипс 6" id="Эллипс_6" r="128"/><path class="cls-2" d="M265.727,717.735a12.652,12.652,0,1,1-12.654,12.652A12.654,12.654,0,0,1,265.727,717.735Zm30.546,0a12.652,12.652,0,1,1-12.655,12.652A12.654,12.654,0,0,1,296.273,717.735Zm0,53.226a12.652,12.652,0,1,1-12.655,12.652A12.653,12.653,0,0,1,296.273,770.961Zm-30.546,0a12.652,12.652,0,1,1-12.654,12.652A12.653,12.653,0,0,1,265.727,770.961Zm-15.709-26.177a12.652,12.652,0,1,1-12.654,12.652A12.654,12.654,0,0,1,250.018,744.784Zm61.964,0a12.652,12.652,0,1,1-12.655,12.652A12.653,12.653,0,0,1,311.982,744.784Zm14.4-21.813a7.853,7.853,0,1,1-7.855,7.853A7.853,7.853,0,0,1,326.382,722.971Zm0,52.352a7.853,7.853,0,1,1-7.855,7.853A7.853,7.853,0,0,1,326.382,775.323Zm-90.764,0a7.853,7.853,0,1,1-7.854,7.853A7.854,7.854,0,0,1,235.618,775.323Zm0-52.352a7.853,7.853,0,1,1-7.854,7.853A7.854,7.854,0,0,1,235.618,722.971ZM281,696.794a7.853,7.853,0,1,1-7.855,7.853A7.853,7.853,0,0,1,281,696.794ZM281,801.5a7.853,7.853,0,1,1-7.855,7.853A7.853,7.853,0,0,1,281,801.5Zm33.6,7.853a6.544,6.544,0,1,1-6.546,6.544A6.544,6.544,0,0,1,314.6,809.353Zm-67.2,0a6.544,6.544,0,1,1-6.546,6.544A6.544,6.544,0,0,1,247.4,809.353Zm0-117.794a6.544,6.544,0,1,1-6.546,6.544A6.544,6.544,0,0,1,247.4,691.559Zm67.2,0a6.544,6.544,0,1,1-6.546,6.544A6.544,6.544,0,0,1,314.6,691.559Zm34.036,58.461a6.544,6.544,0,1,1-6.545,6.544A6.545,6.545,0,0,1,348.636,750.02Zm-135.273,0a6.544,6.544,0,1,1-6.545,6.544A6.544,6.544,0,0,1,213.363,750.02Zm-4.8-40.138a5.236,5.236,0,1,1-5.236,5.235A5.236,5.236,0,0,1,208.563,709.882Zm0,83.765a5.236,5.236,0,1,1-5.236,5.235A5.236,5.236,0,0,1,208.563,793.647Zm144.873,0a5.236,5.236,0,1,1-5.236,5.235A5.236,5.236,0,0,1,353.436,793.647Zm0-83.765a5.236,5.236,0,1,1-5.236,5.235A5.236,5.236,0,0,1,353.436,709.882ZM281,668a5.236,5.236,0,1,1-5.237,5.235A5.235,5.235,0,0,1,281,668Zm0,167.529a5.236,5.236,0,1,1-5.237,5.236A5.236,5.236,0,0,1,281,835.529Zm46.254-3.49a4.363,4.363,0,1,1-4.363,4.363A4.363,4.363,0,0,1,327.254,832.039Zm-92.509,0a4.363,4.363,0,1,1-4.363,4.363A4.363,4.363,0,0,1,234.745,832.039Zm0-158.8a4.363,4.363,0,1,1-4.363,4.363A4.363,4.363,0,0,1,234.745,673.235Zm92.509,0a4.363,4.363,0,1,1-4.363,4.363A4.363,4.363,0,0,1,327.254,673.235Zm45.382,79.4A4.363,4.363,0,1,1,368.273,757,4.363,4.363,0,0,1,372.636,752.637Zm-183.273,0A4.363,4.363,0,1,1,185,757,4.363,4.363,0,0,1,189.363,752.637Z" data-name="Эллипс 6 копия 29" id="Эллипс_6_копия_29" transform="translate(-152 -629)"/></g></g></svg>
)
}
export default CardanoIcon
create a file like an icon.svg and paste the SVG you have downloaded to that file then you can import SVG file in your component like this:
import icon from './icon.svg'
const CustomIcon = () => {
return (
<img src={icon} alt="icon" />
)
}
export default CustomIcon;
If you are using CRA (Create React App) for your React environment, I would suggest pulling out the contents of the <style> tag out into a separate .css file and then importing it into the React component.
So, your CardanoIcon.css would look as follows:
.cls-1 {
fill: #3468d1;
}
.cls-2 {
fill: #fff;
fill-rule: evenodd;
}
And your React component would look as follows - note the .css import on line 2. Also, note that you need to change class to className
import React from 'react';
import './CardanoIcon.css';
const CardanoIcon = () => (
<svg
height="256"
viewBox="0 0 256 256"
width="256"
xmlns="http://www.w3.org/2000/svg"
>
<defs></defs>
<g data-name="cardano ada" id="cardano_ada">
<g data-name="cardano ada" id="cardano_ada-2">
<circle
className="cls-1"
cx="128"
cy="128"
data-name="Эллипс 6"
id="Эллипс_6"
r="128"
/>
<path
className="cls-2"
d="M265.727,717.735a12.652,12.652,0,1,1-12.654,12.652A12.654,12.654,0,0,1,265.727,717.735Zm30.546,0a12.652,12.652,0,1,1-12.655,12.652A12.654,12.654,0,0,1,296.273,717.735Zm0,53.226a12.652,12.652,0,1,1-12.655,12.652A12.653,12.653,0,0,1,296.273,770.961Zm-30.546,0a12.652,12.652,0,1,1-12.654,12.652A12.653,12.653,0,0,1,265.727,770.961Zm-15.709-26.177a12.652,12.652,0,1,1-12.654,12.652A12.654,12.654,0,0,1,250.018,744.784Zm61.964,0a12.652,12.652,0,1,1-12.655,12.652A12.653,12.653,0,0,1,311.982,744.784Zm14.4-21.813a7.853,7.853,0,1,1-7.855,7.853A7.853,7.853,0,0,1,326.382,722.971Zm0,52.352a7.853,7.853,0,1,1-7.855,7.853A7.853,7.853,0,0,1,326.382,775.323Zm-90.764,0a7.853,7.853,0,1,1-7.854,7.853A7.854,7.854,0,0,1,235.618,775.323Zm0-52.352a7.853,7.853,0,1,1-7.854,7.853A7.854,7.854,0,0,1,235.618,722.971ZM281,696.794a7.853,7.853,0,1,1-7.855,7.853A7.853,7.853,0,0,1,281,696.794ZM281,801.5a7.853,7.853,0,1,1-7.855,7.853A7.853,7.853,0,0,1,281,801.5Zm33.6,7.853a6.544,6.544,0,1,1-6.546,6.544A6.544,6.544,0,0,1,314.6,809.353Zm-67.2,0a6.544,6.544,0,1,1-6.546,6.544A6.544,6.544,0,0,1,247.4,809.353Zm0-117.794a6.544,6.544,0,1,1-6.546,6.544A6.544,6.544,0,0,1,247.4,691.559Zm67.2,0a6.544,6.544,0,1,1-6.546,6.544A6.544,6.544,0,0,1,314.6,691.559Zm34.036,58.461a6.544,6.544,0,1,1-6.545,6.544A6.545,6.545,0,0,1,348.636,750.02Zm-135.273,0a6.544,6.544,0,1,1-6.545,6.544A6.544,6.544,0,0,1,213.363,750.02Zm-4.8-40.138a5.236,5.236,0,1,1-5.236,5.235A5.236,5.236,0,0,1,208.563,709.882Zm0,83.765a5.236,5.236,0,1,1-5.236,5.235A5.236,5.236,0,0,1,208.563,793.647Zm144.873,0a5.236,5.236,0,1,1-5.236,5.235A5.236,5.236,0,0,1,353.436,793.647Zm0-83.765a5.236,5.236,0,1,1-5.236,5.235A5.236,5.236,0,0,1,353.436,709.882ZM281,668a5.236,5.236,0,1,1-5.237,5.235A5.235,5.235,0,0,1,281,668Zm0,167.529a5.236,5.236,0,1,1-5.237,5.236A5.236,5.236,0,0,1,281,835.529Zm46.254-3.49a4.363,4.363,0,1,1-4.363,4.363A4.363,4.363,0,0,1,327.254,832.039Zm-92.509,0a4.363,4.363,0,1,1-4.363,4.363A4.363,4.363,0,0,1,234.745,832.039Zm0-158.8a4.363,4.363,0,1,1-4.363,4.363A4.363,4.363,0,0,1,234.745,673.235Zm92.509,0a4.363,4.363,0,1,1-4.363,4.363A4.363,4.363,0,0,1,327.254,673.235Zm45.382,79.4A4.363,4.363,0,1,1,368.273,757,4.363,4.363,0,0,1,372.636,752.637Zm-183.273,0A4.363,4.363,0,1,1,185,757,4.363,4.363,0,0,1,189.363,752.637Z"
data-name="Эллипс 6 копия 29"
id="Эллипс_6_копия_29"
transform="translate(-152 -629)"
/>
</g>
</g>
</svg>
);
export default CardanoIcon;

how to style motion icon in styled-component in React

Is it possible to style motion(framer-motion) icon in styled-components in React.
Here is my style.js file:
import { motion } from "framer-motion";
import { FaRegMoon } from "react-icons/fa";
export const MoonStyled = styled(motion.FaRegMoon)`
width: max-content;
height: max-content;
font-size: 40px;
`;
Here is my jsx file:
import { SunStyled } from "./styles/styles";
<SunStyled/>
I tried making it <motion.SunStyled/> but it doesn't work.
Is there anyway to get it worked?
Here is where the docs talk about this: https://www.framer.com/docs/component/#custom-components
This is the helpful statement that details how to forward a ref / make a custom component wrappable by motion:
const Component = React.forwardRef((props, ref) => (
<div ref={ref} />
))
const MotionComponent = motion(Component)
The icon component doesn't forward the ref to the actual dom svg, so that is why it is not wrappable by motion.
return (
<svg
stroke="currentColor"
fill="currentColor"
strokeWidth="0"
{...conf.attr}
{...attr}
{...svgProps}
className={className}
style={{ color: props.color || conf.color, ...conf.style, ...props.style}}
height={computedSize}
width={computedSize}
xmlns="http://www.w3.org/2000/svg"
>
{title && <title>{title}</title>}
{props.children}
</svg>
)
Even though they are spreading the props ref is the only prop that is not automatically passed.
source link
I wanted to test this on my own, so I made this example. It doesn't work for the above reason but feel free to see for yourself.
https://codesandbox.io/s/framer-motion-with-react-icons-rhqu6?file=/src/index.js

can't change color of these icons from react icons library

no matter what I do, I can't change color of these 2 react icons, I am not sure if they are set to be not changeable. I used other icons before, haven't had this issue yet, Thank you!
import React from "react";
import "./styles.css";
import { GrSubtractCircle, GrAddCircle } from "react-icons/gr";
export default function App() {
return (
<div className="App">
<GrAddCircle id="try"/>
</div>
);
}
css
#try{
color: green;
}
svg{
color: aqua;
}
There is a problem with the stroke attribute in path in svg its defaulted to "#000" which means it will always be black color it should be "currentColor"
as a work around this problem with this particular element in this library
i did the following
import React from "react";
import { GrAddCircle } from "./Icons";
function App() {
return (
<div className="App">
<GrAddCircle
color="red"
title="folder icon"
className="additional-class-name"
/>
</div>
);
}
export default App;
then in src i created folder called Icons to work as my own custom Icons
then inside the folder i created index.js
import React from "react";
export const GrAddCircle = ({ color, size, title, className }) => {
return (
<svg
stroke="currentColor"
fill="currentColor"
strokeWidth="0"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
height={ size ? size : "1rem" }
width={ size ? size : "1rem" }
style={{ color }}
className={ className ? className : '' }
>
{ title ? <title>{title}</title> : null }
<path
fill="none"
stroke="currentColor"
strokeWidth="2"
d="M12,22 C17.5228475,22 22,17.5228475 22,12 C22,6.4771525 17.5228475,2 12,2 C6.4771525,2 2,6.4771525 2,12 C2,17.5228475 6.4771525,22 12,22 Z M12,18 L12,6 M6,12 L18,12"
></path>
</svg>
);
};
this way you can create your own custom icons based on react-icons and import it from Icons frolder directly
now the element will have the property size (width, height attributes), title, className and color. you can add more custom props if you want.

Render React SVG component as backgroundImage

I am trying to render a React Component that returns an <svg> as a backgroundImage of a <div>.
Currently I am using ReactDOMServer with renderToStaticMarkup or renderToString but nothing shows up:
const SvgComponent = () => {
return (
<svg xmlns='http://www.w3.org/2000/svg'><rect fill='red' x='0' y='0' /></svg>
)
}
const ParentComponent = () => {
return (
<div
className={classes.banner}
style={{
backgroundImage: `url("data:image/svg+xml;utf8, ${ReactDOMServer.renderToStaticMarkup(<SvgComponent />)} ")`
}}
>
</div>
)
}
Would the package jsx-to-string the way to do it?
You have to use encodeURIComponent() to URI encode the SVG data because React will not render the SVG data if it is not URI encoded. So,
const svgString = encodeURIComponent(renderToStaticMarkup(<SvgComponent />));
Also, set the width and height in <rect> of SVG like,
<rect fill="red" width={100} height={100} />
So final code should look like,
import ReactDOM from "react-dom";
import { renderToStaticMarkup } from "react-dom/server";
import React from "react";
const SvgComponent = () => {
return (
<svg xmlns="http://www.w3.org/2000/svg">
<rect fill="red" width={100} height={100} />
</svg>
);
};
const ParentComponent = () => {
const svgString = encodeURIComponent(renderToStaticMarkup(<SvgComponent />));
return (
<div
style={{
backgroundImage: `url('data:image/svg+xml;utf8, ${svgString}')`,
width:500,
height:500
}}
>
</div>
)
}
ReactDOM.render(<ParentComponent />, document.getElementById("root"));
I have setup the same in CodeSandbox,
ReactDOMServer.renderToStaticMarkup uses double quotes in the markup, so it returns
<svg xmlns="http://www.w3.org/2000/svg"><rect fill="red" width="10" height="10"></rect></svg>
And because you also used double quotes in url("...") it gives invalid markup.
So just use single quotes in url('...') and it should work.
Note: This will probably break if react changes how renderToStaticMarkup is implemented!

Resources