How is SVG format images are set in React.Js? - reactjs

I have been working on my college website and to make things easier and time saving, I downloaded a template and completed half of the requirements of my project but I got some issues while finding new image formats like svg as I didn't learn about handling them earlier.
Can anyone tell me how to use use svg format images because they are written in xml...!!
I surfed through many websites still can't get out my problem ,please help me out.

The easiest way to use SVG images in react is by importing them and using them in the <img /> src.
import myLogo from '/path/to/image.svg'
const Button = () => {
return (
<button>
<img src={myLogo} alt="SVG logo image"/>
</button>
);
}
Setting them as background images and such with CSS:
.container {
background-image: url(/path/to/image.svg);
}
Converting into JSX:
Regular SVG tag:
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="2"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M11 19l-7-7 7-7m8 14l-7-7 7-7"
/>
</svg>
React:
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth={2}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M11 19l-7-7 7-7m8 14l-7-7 7-7"
/>
</svg>
SVG as a React Component
/path/to/LeftArrow.jsx
export const LeftArrow = () =>{
return(
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth={2}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M11 19l-7-7 7-7m8 14l-7-7 7-7"
/>
</svg>
)
};
import { LeftArrow } from './path/to/LeftArrow.jsx'
export const Button = () =>{
return(
<button>
<LeftArrow />
</button>
)
};
Use SVGR as data-url
This is what I do as it allows me to use SVGs as inline elements.
npm install svg-url-loader --save-dev
webpack.config.js
const webpack = require('webpack');
module.exports = {
entry: './src/index.js',
module: {
rules: [
{
test: /\.svg$/,
use: [
{
loader: 'svg-url-loader',
options: {
limit: 10240,
// make all svg images to work in IE
iesafe: true,
},
},
],
},
],
},
};
import myLogo from '/path/to/image.svg'
const Button = () => {
return (
<button>
<img src={myLogo} alt="SVG logo image"/>
</button>
);
};
This will compile it into a URL like:
<img src="wes49idjdur935jujd8907jdh.svg" alt="SVG logo image" />
Most of the time when using React, you're likely going to want to render SVGs conditionally. A common example would be the "hamburger" menu (which changes upon click). I went ahead and included an example of that:
Hamburger.jsx
import React from 'react';
export const Hamburger = () =>{
const [ isOpen, setisOpen ] = React.useState(false)
return(
<React.Fragment>
{ isOpen ? (
<button
onClick={()=>setisOpen(false)}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth={2}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M6 18L18 6M6 6l12 12"
/>
</svg>
</button>
):( <button
onClick={()=>setisOpen(true)}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth={2}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M4 6h16M4 12h16M4 18h16"
/>
</svg>
</button>
)
}
</React.Fragment>
)
};
Additional CSS to make the SVG appear properly:
svg {
height: 40px;
width: 40px;
}

Actually is very easy. You can configure webpack (or the bundler you are using) to import svgs directly as react components. You can use an img tag and add the route to the svg, it should render it directly as an image. An also you can rely on a library . All in all, even though they are written in xml, you can think about svg as images

Related

How to apply onClick event on Svg file on React?

I made a component for a Svg and I'm trying to apply onClick event so I change the state, but it doesnt work for some reason, I'm not sure what I'm doing wrong. I tried applying the onCLick on too , but it doesnt work either.
my code
import React, { useState } from "react";
import './style.scss'
const AverageSvg=() => {
const [active, setActive] = useState(false);
return (
<svg className="average" onClick={() => setActive(false)}
xmlns="http://www.w3.org/2000/svg"
width="170.539"
height="51.974"
viewBox="0 0 170.539 51.974"
>
<g data-name="The average" transform="translate(-1223 -2501)" >
<g className={active ? "clicked-fill" : "fill "}
// fill="none"
stroke="#707070"
strokeWidth="1"
data-name="Rectangle 60"
transform="translate(1223 2501)"
>
<rect
width="170.539"
height="51.974"
stroke="none"
rx="25.987"
></rect>
<rect
width="169.539"
height="50.974"
x="0.5"
y="0.5"
rx="25.487"
></rect>
</g>
<text className="text"
// fill="#464646"
data-name="The average"
fontFamily="ArialMT, Arial"
fontSize="17"
transform="translate(1261 2532)"
>
<tspan x="0" y="0" >
The average
</tspan>
</text>
</g>
</svg>
);
}
export default AverageSvg;
Have you tried wrapping the svg with another tag like a div or span and attaching the onClick on that wrapper ?
Also inside the setActive() you should pass true instead of false.
you can warp the SVG in another tag as Alexader says, also you can pass the event to the child element in the SVG tag directly and it will work. but you should be aware of the browser compatibility
check this link from MDN web Docs
https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/onclick
for example, this is an SVG delete icon
export const Delete = ({ ...props }) => {
return (
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" className={props?.className} >
<path onClick={props?.onClick} d="M7 21q-.825 0-1.412-.587Q5 19.825 5 19V6H4V4h5V3h6v1h5v2h-1v13q0 .825-.587 1.413Q17.825 21 17 21Zm2-4h2V8H9Zm4 0h2V8h-2Z" />
</svg>
)
}
when you call it just <Delete onClick={yourEvent} />
the onClick will apply on the <path/> tag

Why isn't fill working on my svg when using props?

I expect the svg to turn red but it isn't changing at all from the color #D8D8D8. I see the fill in the svg and if I turn this into a parameter I can use it then, but I'd rather just set the fill using React props so I can set a hover via my css:
The svg code (which I got my my Sketch export):
<svg width="57px" height="33px" viewBox="0 0 57 33" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Rectangle</title>
<g id="Design" stroke="none" stroke-width="1" fill-rule="evenodd">
<g id="Mobile-Copy-6" transform="translate(-196.000000, -69.000000)" fill="#D8D8D8">
<rect id="Rectangle" x="196" y="69" width="57" height="33"></rect>
</g>
</g>
</svg>
My react code:
import { ReactComponent as Logo } from "../../assets/rect.svg";
export const Example = () => {
return (
<div>
<Logo fill="#C94141" />
</div>
);
};
I used create-react-app with the typescript template and the Logo is identified as the type:
React.FunctionComponent<React.SVGProps<SVGSVGElement>
you need to create you Logo as a component with passing props to it which you want to keep dynamic. Try creating a component like:
export default ({ fill = '#D8D8D8' }) => (
<svg width="57px" height="33px" viewBox="0 0 57 33" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Rectangle</title>
<g id="Design" stroke="none" stroke-width="1" fill-rule="evenodd">
<g id="Mobile-Copy-6" transform="translate(-196.000000, -69.000000)" fill={fill}>
<rect id="Rectangle" x="196" y="69" width="57" height="33"></rect>
</g>
</g>
</svg>
);
and then use this component simply by
import Logo from "../../components/logo.js";
export const Example = () => {
return (
<div>
<Logo fill="#C94141" />
</div>
);
};

Error when using Custom Icon for Switch Component

When I try to use the custom icon prop I get this error:
index.js:1406 Warning: Failed prop type: Invalid prop icon supplied to ForwardRef(Switch), expected a ReactNode.
I have tried several things and I cannot make it work. Any ideas why it is not working?
<Switch
checked={formik.values.roleBasedAccess}
onChange={handleRoleBasedChange}
icon={HexagonSwitch}
value="roleBasedAccess"
/>
And the HexagonSwitch component:
import React from 'react';
const HexagonSwitch = () => {
return (
<svg width="24px" height="21px" viewBox="0 0 24 24">
<g id="Add-on/Guided-Workflow/Pieces/Status-Indicator/Complete" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polygon id="Polygon" fill="red" fill-rule="nonzero" points="12 3 20 7.5 20 16.5 12 21 4 16.5 4 7.5"></polygon>
</g>
</svg>
);
};
The "Failed prop type" message is telling you that it expects a node, but you are providing a component type.
Component Type: HexagonSwitch
Node (i.e. instance of the component type): <HexagonSwitch/>
Below is a working example.
import React from "react";
import Switch from "#material-ui/core/Switch";
const HexagonSwitch = () => {
return (
<svg width="24px" height="21px" viewBox="0 0 24 24">
<g
id="Add-on/Guided-Workflow/Pieces/Status-Indicator/Complete"
stroke="none"
strokeWidth="1"
fill="none"
fillRule="evenodd"
>
<polygon
id="Polygon"
fill="red"
fillRule="nonzero"
points="12 3 20 7.5 20 16.5 12 21 4 16.5 4 7.5"
/>
</g>
</svg>
);
};
export default function Switches() {
const [checked, setChecked] = React.useState(true);
return (
<div>
<Switch
checked={checked}
onChange={event => setChecked(event.target.checked)}
value="checkedA"
icon={<HexagonSwitch />}
checkedIcon={<HexagonSwitch />}
inputProps={{ "aria-label": "secondary checkbox" }}
/>
</div>
);
}

How to use a custom SVG file in material ui SVG ICON

I am trying to use a chip with SVG delete icon,
The icon code is
const icon = (props) => {
return (
<SvgIcon>
<img src={'ic_check.svg'} style={{width: '20px'}} width={'20px'}/>
</SvgIcon>
)
};
The content of SVG file
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<rect width="20" height="20" x="2" y="2" fill="#6FB934" rx="10"/>
<path fill="#FFF" fill-rule="nonzero" d="M9.5 15.475L6.025 12l-1.183 1.175L9.5 17.833l10-10-1.175-1.175z"/>
<path d="M0 0h24v24H0z"/>
</g>
</svg>
and the chip finally is
<Chip
label={ViewUtils.NOT_EXPIRED}
className={classes.chip}
onDelete={() => {}}
deleteIcon={<icon/>}/>
But this is not working and I checked for the path and it is correct as I can render same svg in img tag.
Nayan SvgIcon takes a svg path that you can further style. But in your case your svg is already styled. It doesn't take svg file directory path which actually lose SvgIcon API purpose.
You just need to remove SvgIcon from img tag:
<Chip
label={ViewUtils.NOT_EXPIRED}
className={classes.chip}
onDelete={() => {console.log('You Deleted this icon')}}
deleteIcon={icon}
/>
and Make you svg as const or import from assets file directory I haven't tried that,
const icon = <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<rect width="20" height="20" x="2" y="2" fill="#6FB934" rx="10"/>
<path fill="#FFF" fill-rule="nonzero" d="M9.5 15.475L6.025 12l-1.183 1.175L9.5 17.833l10-10-1.175-1.175z"/>
<path d="M0 0h24v24H0z"/>
</g>
</svg>
There is a reason why we can't make <icon/> component. If we make it as component as following:
const Icon = (props) => {
return (
<SvgIcon>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
>
<g fill="none" fill-rule="evenodd">
<rect width="20" height="20" x="2" y="2" fill="#6FB934" rx="10" />
<path
fill="#FFF"
fill-rule="nonzero"
d="M9.5 15.475L6.025 12l-1.183 1.175L9.5 17.833l10-10-1.175-1.175z"
/>
<path d="M0 0h24v24H0z" />
</g>
</svg>
</SvgIcon>
)
};
It works like a charm but onDelete doesn't get fired on this component.I've reported this issue as well on material UI. In first case onDelete gets called every time. Feel free to ask any question.
EDITED Fixed the above issue for Icon as Component rather than const. here is the codesandbox link for working example:
https://codesandbox.io/s/98842r4yy4
I am using React and typescript, created a component and added the tags from HTML and it worked normally.
export const IconTable: React.FC = () => {
return (
<svg width="130" height="130" viewBox="0 0 1024 1024">
<path d="M505.947 123.597a23.096 23.096 0 0 0-16.99-7.477h-6.837c-17.929 0-32.631 13.468-34.198 "/>
</svg>
);

How to attach onClick events to preview template in react-dropzone-component?

I am trying to use react-dropzone-component in reactjs, Everything works fine but after image is uploaded i want to add the onclick events to preview Template
Below is the config
const djsConfig = { addRemoveLinks: true, params: {
userId: this.props.userId }, previewTemplate:
<div class="dz-preview dz-file-preview" >
<div class="dz-image"><img data-dz-thumbnail /></div>
<div class="dz-details">
<div class="dz-size"><span data-dz-size></span></div>
<div class="dz-filename"><span data-dz-name></span></div>
</div>
<div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div>
<div class="dz-error-message"><span data-dz-errormessage></span></div>
<div class="dz-success-mark">
<svg width="54px" height="54px" viewBox="0 0 54 54" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<title>Check</title>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<path d="M23.5,31.8431458 L17.5852419,25.9283877 C16.0248253,24.3679711 13.4910294,24.366835
11.9289322,25.9289322 C10.3700136,27.4878508 10.3665912,30.0234455 11.9283877,31.5852419 L20.4147581,40.0716123 C20.5133999,40.1702541 20.6159315,40.2626649 20.7218615,40.3488435 C22.2835669,41.8725651 24.794234,41.8626202 26.3461564,40.3106978 L43.3106978,23.3461564 C44.8771021,21.7797521 44.8758057,19.2483887 43.3137085,17.6862915
C41.7547899,16.1273729 39.2176035,16.1255422 37.6538436,17.6893022
L23.5,31.8431458 Z M27,53 C41.3594035,53 53,41.3594035 53,27
C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27
C1,41.3594035 12.6405965,53 27,53 Z" id="Oval-2"
stroke-opacity="0.198794158" stroke="#747474"
fill-opacity="0.816519475" fill="#FFFFFF"
sketch:type="MSShapeGroup"></path>
</g>
</svg>
</div>
<div class="dz-error-mark">
<svg width="54px" height="54px" viewBox="0 0 54 54" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<title>Error</title>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="Check-+-Oval-2" sketch:type="MSLayerGroup" stroke="#747474"
stroke-opacity="0.198794158" fill="#FFFFFF"
fill-opacity="0.816519475">
<path d="M32.6568542,29 L38.3106978,23.3461564 C39.8771021,21.7797521 39.8758057,19.2483887
38.3137085,17.6862915 C36.7547899,16.1273729 34.2176035,16.1255422 32.6538436,17.6893022 L27,23.3431458 L21.3461564,17.6893022 C19.7823965,16.1255422 17.2452101,16.1273729 15.6862915,17.6862915
C14.1241943,19.2483887 14.1228979,21.7797521 15.6893022,23.3461564
L21.3431458,29 L15.6893022,34.6538436 C14.1228979,36.2202479
14.1241943,38.7516113 15.6862915,40.3137085 C17.2452101,41.8726271 19.7823965,41.8744578 21.3461564,40.3106978 L27,34.6568542 L32.6538436,40.3106978 C34.2176035,41.8744578 36.7547899,41.8726271
38.3137085,40.3137085 C39.8758057,38.7516113 39.8771021,36.2202479 38.3106978,34.6538436 L32.6568542,29 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1
1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z" id="Oval-2"
sketch:type="MSShapeGroup"></path>
</g>
</g>
</svg>
</div>
</div> };
is there any way i can do it?

Resources