Can CSS Grids be used in JSX Inline styles on Electron? - css

So I am creating an Electron app that allows the user to create an invoice and then produce a PDF of that invoice. I'm using a PDF npm package that allows me to pass in HTML. So I am using JSX to create the invoice dynamically then I am turning that JSX into an HTML string. Because I am doing it like this I cannot use typical css files to set styling. So I need to use JSX's inline styling. But for some reason I can't get it to work with CSS Grids. Am I doing anything wrong. I've tried researching it and can't really find any good information on what I'm trying to do.
let headerStyle = {
display: 'grid',
gridTemplateColumns: '3fr 1fr',
gridTemplateRows: 'auto auto',
}
let invoiceHeaderInfoStyle = {
gridColumn: '2 / 3',
gridRow: '1 / 2'
}
let invoiceHeaderCompanyInfoStyle = {
gridColumn: '1 / 2',
gridRow: '1 / 2'
}
let invoiceHeaderClientInfoStyle = {
gridColumnStart: '1',
gridColumnEnd: '2',
gridRow: '2 / 3'
}
return (<div>
<header style={headerStyle}>
<h1>Invoice</h1>
<section style={invoiceHeaderInfoStyle}>
<div className="invoiceHeaderInfoDetails">
<span>Invoice #:</span>
<span>{invoice.number}</span>
</div>
<div className="invoiceHeaderInfoDetails">
<span>Date:</span>
<span>{invoice.date}</span>
</div>
</section>
<section style={invoiceHeaderCompanyInfoStyle}>
<div><p>Company Name</p></div>
<div><p>Some City, KS</p></div>
<div><p>(555)555-5555</p></div>
<div><p>companyname#email.com</p></div>
</section>
<section style={invoiceHeaderClientInfoStyle}>
<div>{this.getFormattedAddressHeader()}</div>
</section>
</header>
</div>)

I'm sure you figured this out, but for others, you have to include style as JSX object:
import style from './app.css';
export default () => (
...
<div className={style.box}>A</div>
...
It's interesting the element style works in normal way, but references to classes have to be specified as JSX variables.

Related

Convey complex css in tailwindcss

Functional css make DX a pleasant, but I always wonder how do we convey some thing like
.item + item {
margin-top: 20px;
}
into our template using tailwindcss ?
You may write your own plugin for this
// tailwind.config.js
const plugin = require('tailwindcss/plugin')
module.exports = {
plugins: [
plugin( ({ addVariant, e }) => {
addVariant('item', ({ modifySelectors, separator }) => {
modifySelectors(
({ className }) => {
const eClassName = e(`item${separator}${className}`); // escaped class. This is like `item:bg-red-500` basically
return `[class^="item"] + .${eClassName}`; // this is your CSS selector
}
)
})
})
],
}
I chose this [class^="item"] selector (class starts with item) as it is allows not to have extra classes in HTML layout but it is up to you which you want to have
Use it as custom Tailwind variant like item:any-tailwind-class
<div class="item:mt-5 item:bg-red-500">1 - No `item` above - no CSS applied</div>
<div class="item:mt-5 item:text-yellow-500">2 - There is `item` above - CSS applied</div>
<div class="item:mt-5 item:bg-red-500 item:text-yellow-500">3</div>
<div class="item:mt-5 item:bg-red-500">4</div>
<div class="item:mt-5">5 - Has margin-top</div>
<div class="">6 - Nothing here</div>
<div class="item:bg-red-500">7- No `item` above - no color applied</div>
<div class="item">8 - This class starts with `item` so the next div should have styles</div>
<div class="item:mt-5 item:bg-red-500">9 - There is `item` above - CSS applied</div>
DEMO

How can I hide a link with inline conditional styling in react?

I'm building my portfolio right now and I would like to hide the download link of my projects when href is empty
<GridContainer>
{projects.map(({id, image, title, description, tags, source, visit, pdf}) =>
<BlogCard key={id}>
<div>
<Img src={image} style={{alignContent:"flex-start", display:"flex"}}/>
<br/>
<TitleContent>
<HeaderThree title>{title}</HeaderThree>
<Hr />
</TitleContent>
<CardInfo>{description}</CardInfo>
</div>
<div >
<br/>
<TitleContent>Technologies utilisées :</TitleContent>
<TagList>
{tags.map((tag, i) => (
<Tag key ={i}>{tag}</Tag>
))}
</TagList>
<UtilityList>
<ExternalLinks href={source}>Code</ExternalLinks>
<ExternalLinks href={pdf} download >PDF</ExternalLinks>
<ExternalLinks href={visit}>Live</ExternalLinks>
</UtilityList>
</div>
</BlogCard>
)}
</GridContainer>
The href is imported from :
export const projects = [
{
title: 'test',
description: "test",
image: 'test',
tags: ['PHP', 'MYSQL', 'HTML', 'CSS'],
source: 'https://google.com',
visit: 'https://google.com',
pdf:'#',
id: 0,
},
I import the css from styled-components like so:
export const ExternalLinks = styled.a`
color:#d4c0c0;
font-size: 1.6rem;
padding:1rem 1.5rem;
background: #6b3030;
border-radius: 15px;
transition: 0.5s;
&:hover{
background: #801414;
}
`;
The idea is to hide the PDF ExternalLinks only when pdf:'#' but I still don't know how to do that. Can you help me please ?
Tell me if you need some details about my code, and thanks for your help !
You could wrap the component effected in a condition checking that the value of href is not equal to "#".
{pdf !== "#" ? <ExternalLinks href={pdf}>PDF</ExternalLinks> : null }
You can use a ternary operator to conditionally render a particular element, in this case your ExternalLinks component and it'll not render, until the condition met.
{pdf.length > 1 ? <ExternalLinks href={pdf} download >PDF</ExternalLinks> : null}
You can alter this condition(pdf.length > 1) based on the data set you've.

How can I dynamically set style of a mapped element without using inline styling?

I'm coding a React function with parent component containing an array of objects:
let const ingredients = [
{name:"lettuce",color:"green"},
{name:"tomato",color:"red"}
]
...
In a child component, there is a map function that breaks down an array to single items to be displayed in a div.
What is the best practice for defining CSS styling for an object className:"name" to set backgroundColor: {ingredient.color};? I'm trying to avoid manual entry of the entire set of key/values of 'ingredients', to allow updating the object without breaking the code.
I'm currently using inline styling, which I have been advised against. Currently using:
let burg = props.toppings.map((item) => {
const divColor = {backgroundColor: item.color};
return (<div style={divColor}>{item.name}</div>)
Inline style is bad when you have other solution to do what you want. Here, you have a string that is the color (red, green, etc.) so you could write a css class for every color, but that is of course a really bad idea. Inline style is the good way to do it here.
I would suggest setting the class of the div instead of the style. That way you can change the look without resorting to inlining the style.
You could create a css class for lettuce with the background color green, instead of using the item.color you'd set class={ item.name }
You can use this way.
css can be more handy if you use scss
// css
.color-green {
color: green;
}
.color-red {
color: red;
}
import React from "react";
import "./styles.css";
const ingredients = [
{ name: "lettuce", color: "green" },
{ name: "tomato", color: "red" }
];
const Vegetable = ({ color, text }) => {
return (
<p>
this is <span className={`color-${color}`}>{text}</span> color{" "}
</p>
);
};
export default function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
{ingredients.map((item, index) => {
return <Vegetable key={index} color={item.color} text={item.name} />;
})}
</div>
);
}

Button with image using React Typescript

I am using React Typescript.
How do I add image to my button?
I tried doing it and there are no errors, but I am getting a blank button.
How do I style my button element using Emotion CSS here?
import React from "react";
function PostButton(props){
let style = {
width:24,
height:24,
src: "../images/abc.png"
};
return(
<button style={style} onClick={() => props.handleClick()}>{props.label}</button>
);
}
return (
<div style={style}>
<PostButton src={"../images/abc.png"} handleClick = {props.incrementScore}/>
</div>
);
}
src would be background:url(../images/abc.png)
Perhaps you're confusing the src prop that an img HTML element would have?
Perhaps you should include a nested img component inside your button.
Working example: https://stackblitz.com/edit/react-emotion-hello-u9qyaa
Damian's answer is technically correct however if you're using webpack you'll need to import the image like this:
import abc from "../images/abc.png";
And use it like this:
function PostButton(props){
let style = {
width:24,
height:24,
background: `url(${abc})`,
};
return(
<button style={style} onClick={() => props.handleClick()}>{props.label}</button>
);
}

ReactJS advanced custom styling

Using reactjs only, is it possible to do advanced styling similar to
#primary-nav .list-group-item.active {}
// or
#secondary-nav .list-group-item:hover>.background-item {}
in the first example I could do some rather simple javascript logic to figure out if the component is "active" but on the second example it's just so much simpler with css.
Is there a clear react+js solution for these situations that comes close to the simplicity of css?
className is applied exactly like a regular HTML class. So to correctly target .background-image like in
.list-group-item:hover>.background-item
Your jsx structure should look like
import './index.css'
const Component = () =>{
return(
<div className='list-group-item'>
<div className='background-item' />
<span>
<div className='background-item' /> /*Targeting nested items '>' */
</span>
</div>
)
}
You can use jss and clsx to have dynamic and conditional styles. Here is an example using MUI styles(hooks API), but you can use styled components, react-jss or implement you're own style's solution based on jss.
import { makeStyles } from '#material-ui/styles'
import clsx from 'clsx'
const styles = {
root:{
color: 'white',
'&:active':{
color: 'red'
}
},
hidden:{
opacity: 0
}
}
const useStyles = makeStyles(styles)
const Component = ({ open }) =>{
const classes = useStyles()
const rootStyle = clsx({
[classes.root] : true,
[classes.hidden] : !open
})
return <div classsName={rootStyle} />
}
jss also have lots of cool features like theming support, styles interpolation (a personal favorite), nested selectors, style's rules,etc. Definitely worth taking a look.
Notice that clsx doesn't require jss to work, it's just a helper to conditionally apply classes. You can use it like clsx({'foo' : true, 'bar': false})

Resources