The following code compiles just fine but the icon doesn't show up:
Icon.jsx
component:
import React from 'react';
import { css } from 'emotion';
import ArrowRight from "./arrow-right.svg";
export const iconTypes = {
arrowRight: 'ARROW_RIGHT',
// arrowLeft: 'ARROW_LEFT',
}
const iconSrc = {
ARROW_RIGHT: ArrowRight,
// ARROW_LEFT: ArrowLeft,
}
export default function Icon({ type }) {
return (
<div>
<img src={iconSrc[type]}/>
</div>
)
};
In the browser the request looks like this:
http://localhost:9001/%22data:image/svg+xml,%3Csvg%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20width='512'%20height='512'%20viewBox='0%200%20512%20512'%3E%20%3Ctitle%3E%3C/title%3E%20%3Cg%20id='icomoon-ignore'%3E%20%3C/g%3E%20%3Cpath%20d='M310.627%20438.627l160-160c12.497-12.496%2012.497-32.758%200-45.255l-160-160c-12.497-12.496-32.758-12.496-45.255%200s-12.497%2032.758%200%2045.255l105.373%20105.373h-306.745c-17.673%200-32%2014.327-32%2032s14.327%2032%2032%2032h306.745l-105.373%20105.373c-6.248%206.248-9.372%2014.438-9.372%2022.627s3.124%2016.379%209.372%2022.627c12.497%2012.497%2032.758%2012.497%2045.255%200z'%3E%3C/path%3E%20%3C/svg%3E%22
Icon.jsx
story:
import { action } from "@storybook/addon-actions";
import Icon from "../components/Icon/Index";
import { iconTypes } from "../components/Icon/Index";
storiesOf("Icon", module)
.add("with text", () => (
<Icon type={iconTypes.arrowRight}>
</Icon>
));
When I fill the src
with a http
path (for ex: "https://s.cdpn.io/3/kiwi.svg") it works just fine.
When I open the svg file directly in the browser it also opens fine.
Any help would be appreciated.
It is much better to use the svg inline rather than as image. It is also easier to parameterise (e.g. the size):
Icon.jsx
import React from 'react';
export const iconTypes = {
arrowRight: 'ARROW_RIGHT',
arrowLeft: 'ARROW_LEFT',
}
export default function Icon({ type = iconTypes.arrowRight, size = 512 }) {
return (
<svg
width={size}
height={size}
viewBox='0 0 512 512'>
{type === iconTypes.arrowRight &&
<path d='M310.627 438.627l160-160c12.497-12.496 12.497-32.758 0-45.255l-160-160c-12.497-12.496-32.758-12.496-45.255 0s-12.497 32.758 0 45.255l105.373 105.373h-306.745c-17.673 0-32 14.327-32 32s14.327 32 32 32h306.745l-105.373 105.373c-6.248 6.248-9.372 14.438-9.372 22.627s3.124 16.379 9.372 22.627c12.497 12.497 32.758 12.497 45.255 0z' />
}
{type === iconTypes.arrowLeft &&
<path d="..." />
}
</svg>
)
};
Note: you should leave the viewBox
prop hardcoded 512
to make the scale work properly.
I think the best way to show default icon in your application is sprite them and use them with their class name. With that, you can cache and have a better performance.
<Icon name="plus" size={10} />
there are many free tools to sprite your image.
Can you use the SVG as a background style on a class and just switch them out depending on what icon you need?
For good performance you can just base64 encode the SVG and paste the contents in a background style in your CSS. http://b64.io/ this is a good site for encoding SVGs
E.g.
.kiwi {
background-image: url("data:image/svg+xml;base64,PD94b...");
}
Any questions, shout!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With