I am using the React-PDF library and wanting to add a banner across the page with a radial gradient, something simple. However, when I apply the CSS property I've been using in my app, it doesn't seem to accept it...
I have been attempting to use
backgroundColor: 'radial-gradient(105.71% 103.23% at 74.11% 75.76%, #0d0173 0%, #1704b8 100%)',
Loading the page then gets the error:
I can apply a single colour easily enough, like backgroundColor: '#0d0173';, but of course I want the radial background :-/
This is how I am using it:
const styles = {
container: {
backgroundColor: 'radial-gradient(105.71% 103.23% at 74.11% 75.76%, #0d0173 0%, #1704b8 100%)',
/* other css */
},
logo: { /* some logo css */ },
title: { /* some title css */ }
};
return (
<View style={styles.container}>
<Image style={styles.logo} src={logo} />
<Text style={styles.title}>Some text here</Text>
</View>
);
In CSS, the built-in gradients use background-image rather than background-color --- as the error message tells you, it's failing to parse the color, because a gradient defintion is not a color.
Unfortunately, the solve is not just to change to background-image, as it's not supported by React PDF.
Instead, you can use an embedded SVG element to achieve the same effect, something like:
<View style={styles.container}>
<Svg viewBox="0 0 10 10" width="100">
<Defs>
<RadialGradient id="radialGradient">
<Stop stop-color="#0d0173" />
<Stop offset="100%" stop-color="#1704b8"/>
</RadialGradient>
</Defs>
<Rect width="100%" height="100%" fill="url(#radialGradient)" />
</Svg>
</View>
I'm trying to put the svg text around the whatsapp fa icon, something like this
but unable to achieve desired result. this is what I'm getting so far.
I tried with the below code.
<a id='whatsapp'
style={{
bottom: '162px', right: '32px', fontSize: '3.3rem',
padding: '0.6rem', backgroundColor: '#70d470',
color: '#fff'
}}
href="https://wa.me/1232365326"
target="_blank" rel="noopener noreferrer"
className={`${visible ? "block whatsapp" : "none"}`}
>
<svg viewBox="0 0 100 100" width="100" height="100">
<defs>
<path id="circle"
d="
M 50, 50
m -37, 0
a 37,37 0 1,1 74,0
a 37,37 0 1,1 -74,0"/>
</defs>
<text font-size="8">
<textPath xlinkHref="#circle">
Need Appointment? Click me!
</textPath>
</text>
</svg>
<RiWhatsappFill/>
</a>
You could try using position: 'absolute' on the text, then aligning it manually.
Here's something that might work, give it a shot.
<a id='whatsapp'
style={{
bottom: '162px', right: '32px', fontSize: '3.3rem',
padding: '0.6rem', backgroundColor: '#70d470',
color: '#fff'
}}
href="https://wa.me/1232365326"
target="_blank" rel="noopener noreferrer"
className={`${visible ? "block whatsapp" : "none"}`}
>
<svg viewBox="0 0 100 100" width="100" height="100">
<defs>
<path id="circle"
d="
M 50, 50
m -37, 0
a 37,37 0 1,1 74,0
a 37,37 0 1,1 -74,0"/>
</defs>
<text style={{position: 'absolute', right: '32px', top: '2px'}} font-size="8">
<textPath xlinkHref="#circle">
Need Appointment? Click me!
</textPath>
</text>
</svg>
<RiWhatsappFill/>
</a>
I have links with their own SVGs coming from my backend via my API.
I want to overwrite the color when i'm in dark mode and set it to white.
Here is my component that display the SVG :
[...]
<button className="flex items-center fill">
{value.pictogram &&
pictogram(value.pictogram, {
fill: value.pictoFill,
})}
{!props.isMinimized && (
<span className="ml-3">{value.label}</span>
)}
</button>
[...]
export const pictogram: any = (key: string, props: any) => {
return pictogramToComponent[key] ? React.createElement(pictogramToComponent[key], props) : null;
};
And the SVG is like this in the DOM :
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 20 20" fill="#C1C1C1"><defs><clipPath id="clip-path-picto-hektor"><rect id="Bold_hyperlink-3" data-name="Bold / hyperlink-3" width="20" height="20" transform="translate(-1862 -1482)" fill="none"></rect></clipPath><clipPath id="clip-path-picto-hektor-2"><rect id="Rectangle_2" data-name="Rectangle 2" width="16" height="16" fill="#525254"></rect></clipPath></defs><g id="ico_Hektor" transform="translate(1862 1482)" opacity="0.3" clip-path="url(#clip-path-picto-hektor)"><g id="Groupe_4" data-name="Groupe 4" transform="translate(-1860 -1480)"><g id="Groupe_3" data-name="Groupe 3" transform="translate(0 0)" clip-path="url(#clip-path-picto-hektor-2)"><path id="Trac\xE9_2" data-name="Trac\xE9 2" d="M13.82,1.071Q12.046,0,8.019,0,4.064,0,2.4.961,0,2.289,0,5.8v4.434q0,3.474,2.4,4.8Q4.064,16,8.019,16a11.986,11.986,0,0,0,5.8-1.072Q16,13.635,16,10.235V5.8q0-3.436-2.18-4.73m.964,6.164a3.75,3.75,0,0,1-3.855,2.889A4.707,4.707,0,0,1,8,8.985a4.707,4.707,0,0,1-2.929,1.139A3.75,3.75,0,0,1,1.216,7.235a.059.059,0,0,1,.107-.049,2.291,2.291,0,0,0,2.022.957A7.284,7.284,0,0,0,6.45,6.8a.548.548,0,0,1,.46-.072L8,7.051l1.09-.319a.548.548,0,0,1,.46.072,7.283,7.283,0,0,0,3.105,1.34,2.292,2.292,0,0,0,2.022-.957.059.059,0,0,1,.106.049" transform="translate(0 0)" fill="#525254"></path></g></g></g></svg>
Any idea what should I change to change the color ?
I tried to add fill class and do this in my CSS :
.fill~svg,
.fill svg,
.fill~path,
.fill path,
.fill~circle,
.fill circle,
.fill~rect,
.fill rect,
.fill~line,
.fill line,
.fill~polyline,
.fill polyline,
.fill~polygon,
.fill polygon,
.fill~text,
.fill text,
.fill~tspan,
.fill tspan,
.fill~g,
.fill g {
fill: #ffffff !important;
}
But nothing change.
Try this:
svg #ico_Hektor {
opacity: 1 !important;
}
svg path {
fill: #000000 !important;
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 20 20" fill="#C1C1C1"><defs><clipPath id="clip-path-picto-hektor"><rect id="Bold_hyperlink-3" data-name="Bold / hyperlink-3" width="20" height="20" transform="translate(-1862 -1482)" fill="none"></rect></clipPath><clipPath id="clip-path-picto-hektor-2"><rect id="Rectangle_2" data-name="Rectangle 2" width="16" height="16" fill="#525254"></rect></clipPath></defs><g id="ico_Hektor" transform="translate(1862 1482)" opacity="0.3" clip-path="url(#clip-path-picto-hektor)"><g id="Groupe_4" data-name="Groupe 4" transform="translate(-1860 -1480)"><g id="Groupe_3" data-name="Groupe 3" transform="translate(0 0)" clip-path="url(#clip-path-picto-hektor-2)"><path id="Trac\xE9_2" data-name="Trac\xE9 2" d="M13.82,1.071Q12.046,0,8.019,0,4.064,0,2.4.961,0,2.289,0,5.8v4.434q0,3.474,2.4,4.8Q4.064,16,8.019,16a11.986,11.986,0,0,0,5.8-1.072Q16,13.635,16,10.235V5.8q0-3.436-2.18-4.73m.964,6.164a3.75,3.75,0,0,1-3.855,2.889A4.707,4.707,0,0,1,8,8.985a4.707,4.707,0,0,1-2.929,1.139A3.75,3.75,0,0,1,1.216,7.235a.059.059,0,0,1,.107-.049,2.291,2.291,0,0,0,2.022.957A7.284,7.284,0,0,0,6.45,6.8a.548.548,0,0,1,.46-.072L8,7.051l1.09-.319a.548.548,0,0,1,.46.072,7.283,7.283,0,0,0,3.105,1.34,2.292,2.292,0,0,0,2.022-.957.059.059,0,0,1,.106.049" transform="translate(0 0)" fill="#525254"></path></g></g></g></svg>
I want to implement a drop shadow for a line something like this:
What I did so far:
<View style=
{{
elevation: 5,
borderBottomWidth: 2,
bottom: 1,
}}
>
</View>
Use this code this might help you, Your can change the color as your theme.
cardContainer: {
borderBottomWidth: 1,
borderColor: #4d4d4d,
shadowColor: #4d4d4d,
shadowOffset: {
width: 0,
height: 8,
},
shadowOpacity: 0.8,
shadowRadius: 13.51,
elevation: 5,
}
import Svg, { LinearGradient, Defs, Stop, Rect } from 'react-native-svg'
<Svg height="100" width="100%" style={{ zIndex: 1, marginTop: -50 }}>
<Defs>
<LinearGradient id="grad" x1="0" y1="0" x2="0" y2="1">
<Stop offset="0" stopColor="#e6e6e6" stopOpacity="1" />
<Stop offset="1" stopColor="#e6e6e6" stopOpacity="0.01" />
</LinearGradient>
</Defs>
<Rect height="100" width="100%" fill="url(#grad)" />
</Svg>
I am creating React components that will render out various SVGs:
const Close = ({
fill, width, height, float,
}) => (
<svg width={ `${width}px` } height={ `${height}px` } viewBox="0 0 14.48 14.48" style={ { float: `${float}`, cursor: 'pointer' } }>
<title>x</title>
<g id="Layer_2" data-name="Layer 2">
<g id="Background">
<line style={ { fill: 'none', stroke: `${fill}`, strokeMiterlimit: 10 } } x1="14.13" y1="0.35" x2="0.35" y2="14.13" />
<line style={ { fill: 'none', stroke: `${fill}`, strokeMiterlimit: 10 } } x1="14.13" y1="14.13" x2="0.35" y2="0.35" />
</g>
</g>
</svg>
);
It's very convenient to be able to supply various attributed to this component to control dimensions, colour, etc...
What I don't have a good solution for, however, is handling the styles in a DRY manner. Note the line elements have the same value for style. I presently have them written inline because if I added an embedded stylesheet, then I would get class name collisions with other SVGs I render elsewhere on the page (our SVG software uses the same classes over and over).
<style scoped> has been removed from the spec: https://github.com/whatwg/html/issues/552
Shadow DOM is not yet supported by Edge: https://caniuse.com/#feat=shadowdomv1
Is there any other alternative for scoping styles?
To combine the best of both worlds, you could create an external styles file, as you would for CSS, but with exported style objects. You could then import it into any file that needs it.
As example, main file:
import React, { Component } from 'react';
import { render } from 'react-dom';
import * as Styles from './svgstyles';
class App extends Component {
render() {
return (
<div>
<svg width="100" height="200" viewBox="0 0 100 200">
<rect x="0" y="0" width="10" height="10" style={Styles.style1} />
<rect x="15" y="0" width="10" height="10" style={Styles.style2} />
<rect x="30" y="0" width="10" height="10" style={Styles.style3} />
<rect x="45" y="0" width="10" height="10" style={Styles.style4} />
<rect x="0" y="15" width="10" height="10" style={Styles.style4} />
<rect x="15" y="15" width="10" height="10" style={Styles.style3} />
<rect x="30" y="15" width="10" height="10" style={Styles.style2} />
<rect x="45" y="15" width="10" height="10" style={Styles.style1} />
</svg>
</div>
);
}
}
render(<App />, document.getElementById('root'));
And an external styles file:
export const style1 = {
stroke: 'red',
strokeWidth: "1",
fill: "blue",
}
export const style2 = {
stroke: 'red',
strokeWidth: "1",
fill: "green",
}
export const style3 = {
stroke: 'red',
strokeWidth: "1",
fill: "yellow",
}
export const style4 = {
...style3,
fill: "pink",
}
Live example here
If you just want to DRY up the code, you could create one style-object and reuse it:
const Close = ({
fill, width, height, float,
}) => {
const style = { fill: 'none', stroke: `${fill}`, strokeMiterlimit: 10 }
return (
<svg width={ `${width}px` } height={ `${height}px` } viewBox="0 0 14.48 14.48" style={ { float: `${float}`, cursor: 'pointer' } }>
<title>x</title>
<g id="Layer_2" data-name="Layer 2">
<g id="Background">
<line style={ style } x1="14.13" y1="0.35" x2="0.35" y2="14.13" />
<line style={ style } x1="14.13" y1="14.13" x2="0.35" y2="0.35" />
</g>
</g>
</svg>
);
}
This would also result in a small performance improvement since fewer objects would be created in each render cycle.
Actually, if I was in your place, Surely I use fonts instead of SVGs, but for your exact question, I prefer to use constant variables inside of my arrow function, just like below:
import React from 'react';
const Close = ({ fill, width, height, float }) => {
const constStyle = { fill: 'none', stroke: `${fill}`, strokeMiterlimit: 10 };
return (
<svg
width={`${width}px`}
height={`${height}px`}
viewBox="0 0 14.48 14.48"
style={{ float: `${float}`, cursor: 'pointer' }}
>
<title>x</title>
<g id="Layer_2" data-name="Layer 2">
<g id="Background">
<line style={constStyle} x1="14.13" y1="0.35" x2="0.35" y2="14.13" />
<line style={constStyle} x1="14.13" y1="14.13" x2="0.35" y2="0.35" />
</g>
</g>
</svg>
);
};
export default Close;
Even, I make the line dimension variables as props, but I don't know what is your case exactly.
Hope this answer helps you.