How to register custom icons by reading a SVG file from path? - reactjs

I am building an application making use of #fluentui/react (version 8.34.7) and I am using create-react-app.
One of the things I would like to do is register custom icons which are in SVG format. Following the example here, I came up with the following code:
registerIcons({
icons: {
'hamburger-icon': (
<svg viewBox="0 0 16 16" role="presentation" focusable="false" aria-hidden="true">
<g>
<path d="M1 4.5v-1h14v1zm0 4v-1h14v1zm0 4v-1h14v1z"></path>
</g>
</svg>
)
}
});
and this works perfectly fine. I can reference hamburger-icon in my code and get the icon to display.
However, the issue with the code above is that I have to include svg file contents in my code. What I would like to do is read the SVG file contents and then use it in registerIcons method. I am not sure how I can do that.
If I do something like:
import Hamburger from 'assets/images/hamburger.svg';
I get a URL.
If I do something like:
import {ReactComponent as HamburgerIcon} from 'assets/images/hamburger.svg';
I get a React component whereas registerIcon method expects a React element.
Is it possible to simply specify a file path of an SVG file and register icon from that?

Well, it was ridiculously simple! All I had to do was this:
import {ReactComponent as HamburgerIcon} from 'assets/images/hamburger.svg';
registerIcons({
icons: {
'hamburger-icon': React.createElement(HamburgerIcon)
}
});
and all worked well.

Related

React Img Src Path not Working - How to Import Images

When you try to import any type of images inside React using the classical HTML it didn't work this is a big issue. So how to solve this problem?
<img src='./Image/Checked.png' height=50px width=50px/>
I spent a little bit of time researching this and I found 3 methods to solve this problem. This is why I made this Q&A style question. Hope to help other people like me out there to save some time.
Generally in HTML you will use this code
<img src='./Image/Checked.png' height=50px width=50px/>
But in React when you try to import assets like images you need a require tag. In the old versions it was enough to rewrite the code this way:
<img src={require('./Image/Checked.png')} height={50} width={50} />
The problem is that after a few updates the syntax changed a little bit and now for the images you need to use the default property to make it work. So with the new versions you actually have to use this code:
<img src={require('./Image/Checked.png').default} height={50} width={50} />
Another way to do the same think is to import the image and then use it this way:
import Image from './Image/Checked.png'
<img src={Image} height={50} width={50}/>
To finish in only case of svg images you can import them as React Component and use them this way:
import { ReactComponent as Image } from './Image/Checked.svg'
<Image />

Is there a way to copy the contents of a static file in Sveltekit into a string?

I am trying to build a web app with Sveltekit.
Currently I am working on a simple navigation which should include a text and an icon for each path. I want to generate this dynamically so I am doing this:
<script lang="ts">
export let currentRoute: string;
type Route = { icon: string; name: string; path: string };
const routes: Route[] = [
{ icon: '', name: 'Home', path: '/' },
{ icon: 'icons/servers.svg', name: 'Servers', path: '/servers' }
];
</script>
<nav>
<ul>
{#each routes as route}
<li class:active={currentRoute === route.path}>
<a href={route.path}>
<img src={route.icon} alt="" />
<p>{route.name}</p>
</a>
</li>
{/each}
</ul>
</nav>
This all works fine, but I actually want to change the color of the text and the svg when the corresponding li tag has the class active (which means it is the current route).
As I am using img I cannot change the color directly in css so my thought was to somehow read the static svg files via code and output them to keep everything dynamic.
So the question is: Is there a way to read the contents of each static svg file and just copy them into a variable to keep everything clean?
There are several ways to go around this.
svg as a component
One is to make all svg files components on their own, just name the file Server.svelte and keep the content of the file itself the same. Then include this component and use it as normal. This will inline the svg in your html and you can style it as normal.
I always have
<svg viewBox="0 0 24 24" height="1em" width="1em" fill="currentColor">
this ensures the icon scales with the surrounding text and takes it's color.
(if you don't want to rename the file to .svelte, you can use a plugin to import .svg files as well)
Refer to an included svg
Another technique is to write ```html
This requires you have somewhere else in your html the following
```html
<svg xmlns="http://www.w3.org/2000/svg" style="display: none" viewBox="0 0 24 24">
<defs>
<g id="myicon">
<path d="..." fill="currentColor" />
</g>
</defs>
</svg>
This will do more or less the same as the previous method. How you get all of this included is p to you. One idea would be to make an icons.svelte file with all the icons in it as defenition and include this at the top level. And another component Icon.svelte that sets up the xlink:href block for you so you can simply do <Icon id="myicon" /> in places where you need an icon

cannot create custom ant design icon component from a svg file

I have the icon I want to use in svg format stored in assets folder. I am importing that file and then create a component for the custom icon as shown below:
import dateIcon from "../../../assets/images/icons/calendar_blue.svg";
const calendarIcon = () => <img src={dateIcon} />;
And then when I want to use it as a suffix or prefix I use it as:
<Icon component={calendarIcon} />
I get a typescript error: "TypeScript error in "MYFILE".tsx(27,27):
')' expected. TS1005
You can't use SVG directly inside Icon. You have to convert it into jsx.
Convert the SVG Icon into the function.Use this website to convert SVG to function.
let's say function is Abc
Now use that function inside Icon <Icon component={Abc} />.
Your Icon is ready to use.If you still face any issue please comment.

React JSX - Filling an svg with an image

I am trying fill a simple circle SVG with an image in React. The sources I found have not been helpful, for they don't seem to apply to JSX.
Here is the code I currently have:
import React, {Component} from 'react';
import Anime from '../images/Anime.jpeg';
class Circle extends Component {
render() {
return (
<div>
<svg height="300" width="300">
<circle cx="150" cy="150" r="100" stroke="black" stroke-width="3" fill={Anime} />
</svg>
</div>
);
}
}
export default Circle;
My first instinct was to tweak the fill attribute by either replacing the original color ="red" with ={Anime} or =url("../images/Anime.jpeg"), but neither worked.
(I know the path to the Anime image is correct, after testing it by rendering <img src={Anime} alt={Anime}></img> inside the div.
I see people using <defs> and <pattern> tags, as such (referring to this post):
<svg id="graph" width="100%" height="400px">
<!-- pattern -->
<defs>
<pattern id="image" x="0%" y="0%" height="100%" width="100%"
viewBox="0 0 512 512">
<image x="0%" y="0%" width="512" height="512" xlink:href="https://cdn3.iconfinder.com/data/icons/people-professions/512/Baby-512.png"></image>
</pattern>
</defs>
<circle id="sd" class="medium" cx="5%" cy="40%" r="5%" fill="url(#image)" stroke="lightblue" stroke-width="0.5%" />
</svg>
But these tags don't seem to work in React / JSX; I keep getting this error when I try to use them: Namespace tags are not supported by default. React's JSX doesn't support namespace tags. You can turn on the 'throwIfNamespace' flag to bypass this warning.
Is there a way around this? I want to be able to fit the following picture into a simple circle svg with a thick black border around it.
I figured out a way and wanted to post / share it, in case anyone is here, looking at this post and wondering what the (one of the) solution(s) is!
Here is my final code:
import React, {Component} from 'react';
import AnimeCropped from '../images/AnimeCropped.png';
class Circle extends Component {
render() {
return (
<div>
<svg height="670" width="670">
<circle cx="350" cy="350" r="300" stroke="black" stroke-width="5" fill="none" />
<image className='img-circle' xlinkHref={AnimeCropped} x='75.5' y="15" height="670" width="670"/>
</svg>
</div>
);
}
}
export default Circle;
Essentially what I did was:
Crop the photo to be a circle. I could have followed cubrr's recommendation above and clip-path'ed it (which is a great idea!), but instead - I just found and used a photo cropping tool online. I then named the newly-cropped picture "AnimeCropped" and saved it in the same directory.
Imported the picture into the component file and rendered via a <image> tag after the <circle> tag. It wasn't mentioned in my original question above, but I also hypothesized that inserting the image inside the circle might solve the problem. As such:
<svg height="670" width="670">
<circle cx="350" cy="350" r="300" stroke="black" stroke-width="5" fill="none">
<img src={AnimeCropped} alt={AnimeCropped}/>
</circle>
</svg>
But this didn't work.
In my final code, you'll see that the <image> tag comes after the <circle> tag, so technically, it's not really inside the circle, but just overlaying on top of it. Also note that I had to use <image>, not <img>. I'll have to do a bit of research on this, but <img> was giving me an error message.
Also important: In React, xlink:href won't work, but xlinkHref will! This really tripped me off, but I found this helpful post.
Using classNames, I edited the size of the cropped picture in my App.css file.
Configured the x- and y- coordinates so that it somewhat fits perfectly in the middle of the circle.
That's it! Just wanted to post this for closure / help me review what I learned.

How to render svg image in React-Native?

Please try to help me!
I need to render svg image from my folder "project/assest/images/test.svg" on android and ios view.
I have tried :
Solution 1 : <Image source={imagePath}></Image>
Solution 2 :
import SvgUri from 'react-native-svg-uri';
<View>
<SvgUri
width="200"
height="200"
source={{uri:'http://thenewcode.com/assets/images/thumbnails/homer-simpson.svg'}}
/>
</View>
Solution 3 : First i should, convert svg file to png,jpeg then render simple image, but that very weired way on view
Please help, what did i wrong in this.
You can also try react-native-svg package for SVG
For Example --
import * as React from 'react';
import { SvgUri } from 'react-native-svg';
export default () => (
<SvgUri
width="100%"
height="100%"
uri="http://thenewcode.com/assets/images/thumbnails/homer-simpson.svg"
/>
);
You can try with this
<SvgUri width="200" height="200" source={require('./project/assest/images/test.svg')} />
May this will help you
here are two ways to use SVG in react-native.
one way is to translate the SVG to JSX use this site.
the other way is to use a font instead of SVG directly:
firstly, use SVG files to generate font. I use this site. it is fontello.
then I use react-native-vector-icons to generate icon.
for more details, you can see its API

Resources