How we can reduce the number of svg icons inside React project? - javascript

I am working on a project which have around 100 icons inside the assets/icons folder. Some icons are quite similar such as trash(delete) icon with blue and red colour, and check icon with three different colour.
How we can pass the colour as props inside svg file. So that we can reduce the number of icon as much as possible.
Note : We don't want to make specific react component and pass the colour as props.
Here is an working example of my code. className="fill-red" will fill the colour in whole <svg /> . But how we can fill the colour in it's nested element like in <path/> or might be <rect/>
import { ReactComponent as Cross } from 'assets/icons/cross.svg';
import React from 'react';
const Alert = (props) => {
return (
<div>
<div className="flex items-start">
<Error className="mr-2 fill-red" />
{props.label}
</div>
</div>
);
};
export default Alert;
Here is my cross.svg
<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.205 4.71967C15.4978 5.01256 15.4978 5.48744 15.205 5.78033L11.023 9.96229L15.205 14.1443C15.4979 14.4372 15.4979 14.9121 15.205 15.205C14.9121 15.4978 14.4372 15.4978 14.1443 15.205L9.96233 11.0229L5.78033 15.205C5.48744 15.4978 5.01256 15.4978 4.71967 15.205C4.42678 14.9121 4.42678 14.4372 4.71967 14.1443L8.90167 9.96229L4.71971 5.78033C4.42682 5.48744 4.42682 5.01256 4.71971 4.71967C5.0126 4.42678 5.48748 4.42678 5.78037 4.71967L9.96233 8.90163L14.1443 4.71967C14.4372 4.42678 14.9121 4.42678 15.205 4.71967Z"/>
</svg>

Related

In an SVG map, how can I keep lines from doubling up on adjacent paths?

I'm drawing a simple US map with state borders drawn. Eventually there will be hover and click events. However, anywhere the states touch, the borders appear double thickness. On the assumption that there isn't something wrong with my shapes, how can I keep these lines from getting double thickness? Is there a CSS setting?
It's written in React, but I hope that's not relevant. In the end it's just path objects in a group in an svg.
export const USMap = (props: Props) => {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 959 593">
<title>Map of US States</title>
<g id="states">
{Object.entries(states).map(([abbreviation, state]) => (
<path key={abbreviation} d={state.dimensions} fill="#fff" stroke="#000" strokeWidth="1" />
))}
</g>
</svg>
);
};

React Template Literals don't work on SVG?

I have rendered an svg and morphed it using mouse position in vanilla javascript.
Here is an example(make sure to refresh the page since it doesnt start automatically for some reason): https://codesandbox.io/s/svg-shape-change-mouse-position-sjl0z
In vanilla js I did the following:
path.setAttribute("d", `M82 ${coords.y}L0 0H123V170H0L82 ${coords.y}Z`)
The problem:
I can't implement the same logic in React. Whenever I add the template literals
to the svg path it wont accept it.
Here is my code: https://codesandbox.io/s/react-svg-shape-morph-mouse-position-r7mx9?file=/src/App.js
This react code gives me an error:
let shape = useRef(null);
console.log("thiss: " + shape.current);
shape.current.setAttribute("d", `M82 ${y}L0 0H123V170H0L82 ${y}Z`);
return (
<div className="App">
<svg viewBox="0 0 100% 100%" preserveAspectRatio="xMidYMid meet">
<path ref={shape} d="M82 88L0 0H123V170H0L82 88Z" fill="lightblue" />
{/* <path d="M82 88L0 0H123V170H0L82 ${y}Z" fill="#F9B300" /> */}
</svg>
<h1>{`x: ${x}; y: ${y};`}</h1>
</div>
);
How can I link the mouse position to the svg path shape?
(ps. edited the question to include code snipets)

How can I use SVG in React Native?

I am trying to use bootstrap icons in react native and I can't find any useful methods on how to render an SVG in react-native. Does anyone know how to?
To Add SVGs in react native you can use react-native-svg
Install:
yarn add react-native-svg
Example:
import Svg, {
Circle,
Ellipse,
G,
Text,
TSpan,
TextPath,
Path,
Polygon,
Polyline,
Line,
Rect,
Use,
Image,
Symbol,
Defs,
LinearGradient,
RadialGradient,
Stop,
ClipPath,
Pattern,
Mask,
} from 'react-native-svg';
/* Use this if you are using Expo
import * as Svg from 'react-native-svg';
const { Circle, Rect } = Svg;
*/
import React from 'react';
import { View, StyleSheet } from 'react-native';
export default class SvgExample extends React.Component {
render() {
return (
<View
style={[
StyleSheet.absoluteFill,
{ alignItems: 'center', justifyContent: 'center' },
]}
>
<Svg height="50%" width="50%" viewBox="0 0 100 100">
<Circle
cx="50"
cy="50"
r="45"
stroke="blue"
strokeWidth="2.5"
fill="green"
/>
<Rect
x="15"
y="15"
width="70"
height="70"
stroke="red"
strokeWidth="2"
fill="yellow"
/>
</Svg>
</View>
);
}
}
Or you want to import an svg to your app use: react-native-svg-transformer
Example:
import Logo from "./logo.svg";
<Logo width={120} height={40} />
But if you want an icon library you can use : react-native-vector-icons
Also here is the directory: React Native Vector Icons directory
I just found out an easy way to solve this problem that works for me.
I'm using Expo and I have react-native-svg installed. Note that this is different from importing SvgUri from react-native-svg-uri. That is a different library.
import { SvgUri } from "react-native-svg";
<SvgUri
uri="https://example.com/uploads/apple.svg"
width="40%"
height="40%"
/>
Recommond Parcel
const logo = new URL('logo.svg', import.meta.url);
export function Logo() {return <img src={logo} alt="logo" />}

How do I use SVGs for background images on buttons in React

First timer on stack overflow so I'll try my best.
I'm trying to dynamically add SVGs as background images for my buttons.
Created react app using create-react-app.
I have 3~ files in question: poland.svg, Flag.jsx and exampleComponent.jsx
exampleComponent.jsx
import React from 'react';
import Flag from './Flag.jsx';
const exampleComponent = (props) => {
const backgroundImage = {
backgroundImage: `url(${Flag(props.nation)})`
}
return(
<button style={backgroundImage}>
<div />
</button>
)
}
export default exampleComponent;
Flag.jsx
import Poland from './poland.svg';
import US from './us.svg';
const Flag = (nation) => {
let path = "";
if (nation === "Poland") path = Poland;
else if (nation === "US") path = US;
return path;
}
export default Flag;
poland.svg
<svg
height="100%"
width="100%"
>
<defs />
<rect fill="#ffffff" width="100%" height="50%" />
<rect transform="translate(0, 50px)" fill="#ff0000" width="100%" height="50%" />
</svg>
I'm getting the file path /static/media/poland.49b43928.svg
When I inspect the element in chrome the correct file path is shown but the SVG isn't being loaded!
IM STILL A NOOB! so please be harsh! ;D
Update! So the file was being sent in XML format.. I wish I knew more to explain the details but all I did to fix this was add:
xmlns="http://www.w3.org/2000/svg"
to the svg tags like so:
<svg
height="100%"
width="100%"
xmlns="http://www.w3.org/2000/svg"
>
<defs />
<rect fill="#ffffff" width="100%" height="50%" />
<rect transform="translate(0, 50px)" fill="#ff0000" width="100%" height="50%" />
</svg>
If the svg files are similar, there may be a problem with matching the
<use xlink ID:href="#xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"/>,
where xxxxxxxx-xxxx-xxxx-xxxx-xxxx-xxxxxxxxxx is the ID, it must be unique for each file.
See the link, it may help
https://github.com/SilverFox70/svg-react-loader

SVG rect goes to new position when wrapped in div with React

I am new to React, and I am having trouble with some formatting issues.
I have one react component, an SVG that is the background element. On it, I am trying to render several points, with annotations when you hover.
I am able to get the points to show when I simply return the point directly, but I need to wrap it in a div so I can add some text.
Working, rendering the point in the right place:
class InfoPoint extends Component {
render() {
return (
<rect x="10" y="93" width="15" height="12" rx="2" ry="2" fill="red" ></rect>
);
}
}
Not working, I cannot find the element when I wrap it in the div:
class InfoPoint extends Component {
render() {
return (
<div className="point">
<rect x="10" y="93" width="15" height="12" rx="2" ry="2" fill="red" ></rect>
</div>
);
}
}
<rect> elements must be inside an <svg> element. And <div> elements are invalid inside a <svg> element. You can't indiscriminately mix HTML and SVG elements together.

Categories

Resources