How do you use Tailwind animate classes with React Hooks? - reactjs

For example - add animate-ping upon new message from a web-socket.

Tailwind just-in-time is likely to be the reason why you can't do that.
Basically, if animate-ping is not scraped in your files, adding it through Javascript or any other way later will simply not work, as the CSS file generated will not include animate-ping.
You should likely make your very own class in your CSS, even if it means using #apply directive of Tailwind. Adding Tailwind class later on in the DOM that were never parsed at build time will simply.. not works.

To conditionally show a class would be something like this:
function Notification() {
const [isNotification, setIsNotification] = useState(false);
return (
<div className={` ${isNotification ? "animate-ping" : null} h-2 w-2 m-5 bg-sky-400 rounded-full`}></div>
);
}

Related

How to use a dynamic background image URL with Tailwind CSS and React

In React, I'm unable to use a URL string in my Tailwind background image class:
1: Not working, getting error "can't resolve ${link}"
const link = "https://cdn.test.net/test.jpg";
<div className={`px-4 py-1 h-[22rem] lg:h-[28vw] bg-cover bg-center bg-[url('${link}')]`}></div
2: Working, but I need to use a variable inside my bg- class.
const link = "bg-[url('https://cdn.test.net/test.jpg')]";
<div className={`px-4 py-1 h-[22rem] lg:h-[28vw] bg-cover bg-center ${link}`}></div>
I still need to be able to use ${link} inside bg-[url('${link}')].
Here is how it looks for me
The given example should be working fine.
Working fine for me.
The CSS file generated by Tailwind will only include classes that it recognizes when it scans your code, which means that dynamically generated classes (e.g. bg-[url('${link}')]) will not be included.
If you only have a few different background images, you could add them to your tailwind.config.js and switch between them:
module.exports = {
theme: {
extend: {
backgroundImage: {
'first': "url('/img/first.jpg')",
'second': "url('/img/second.jpg')",
}
}
}
}
<div className={`bg-cover bg-center ${useFirst ? 'bg-first' : 'bg-second'}`}></div>
This would work, as long as you use the full utility class name, e.g. bg-first, in the code for Tailwind to find and include in the generated CSS.
If you need to reference completely arbitrary URL values, you can always use a style attribute instead of Tailwind classes. For example:
<div className="bg-cover bg-center" style={{backgroundImage: `url('${link}')`}}></div>

How to pass custom class name on react and use scss?

I am trying to create a react component that has the class name as props being passed,
I have managed sending the props part successfully, however when I try to set the scss for the updated class name, I could not find a way to fix that, all of your input is appreciated.
Code of the component
Code of injecting the custom style class
Styles of the Variation
Output
Output of the Variation Class
Output of the Stylesheet
not sure what I am missing to connect all of them.
Thanks in advance.
As mentioned by Phil, your SCSS should be using &.secondary as the selector.
As for the difference in your scss class IDs and them not matching when you pass ${variant} to the className, your issue is that you are passing a raw string as the variant to the className and are using CSS modules for your SCSS (this is what handles namespacing them/adding the unique characters). To fix this, you need to use the imported style rather than a raw string for the className.
The way I usually address this is with an enum as the prop for different variants, or if there are only two a boolean, and then apply the imported style accordingly. A quick example of this, using your code would be:
const SectionTitle: FC<SectionTitleProps> = ({ title, isSecondary = false }) => (
<h3
className={`${styles.SectionTitle}${isSecondary ? styles.secondary : ''}`}
...
>
...
</h3>
);
I also find the classnames library helpful for this. It allows you to achieve the above with something I find a bit more readable, such as:
<h3
className={classNames(styles.SectionTitle, { [styles.secondary]: isSecondary } )}
...
>
...
</h3>
EDIT: Also including an example using classnames with an enum for different variants:
enum TitleVarient {
Default,
Secondary,
Accent,
}
const SectionTitle: FC<SectionTitleProps> = ({
title,
variant = TitleVarient.Default,
}) => (
<h3
className={classNames(styles.SectionTitle, {
[styles.secondary]: variant === TitleVarient.Secondary,
[styles.accent]: variant === TitleVarient.Accent,
})}
...
>
...
</h3>
);

How can i dynamically change images as Background in TailwindCSS?

I want to make a carousel, where the background is changing, i don't want to use the <img/> tag! I set the value as described in the documentation: https://tailwindcss.com/docs/background-image#arbitrary-values
My Code:
import React from 'react';
type CarouselProps = {
img: string;
};
const Carousel = ({ img }: CarouselProps) => {
return (
<div
className={`col-span-full bg-[url(${img})] bg-cover grid grid-cols-12 gap-6`}
> ...
</div>
);
};
When i set the String i pass to the Component hardcoded it works but when i use curly Braces and $ it doesn't. In addition i don't want to define my Background-Images in the tailwind.conf.js
The Error:
ERROR in ./src/index.css (./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[1].oneOf[5]
.use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].oneOf[5].use[2]!
./node_modules/source-map-loader/dist/cjs.js!./src/index.css) 9:36-70
i don't want to define my Background-Images in the tailwind.conf.js
Well you have to. What you're trying to do isn't supported.
The way Tailwind scans your source code for classes is intentionally
very simple — we don’t actually parse or execute any of your code in
the language it’s written in, we just use regular expressions to
extract every string that could possibly be a class name.
so tailwind has no idea what your React code actually means. So it's simply not going to work.
Tailwind does not support dynamic class names:
Don't construct class names dynamically
<div class="text-{{ error ? 'red' : 'green' }}-600"></div>
you should customise your theme to include the image url:
You can add your own background images by editing the
theme.backgroundImage section of your tailwind.config.js file:
tailwind.config.js
module.exports = {
theme: {
extend: {
backgroundImage: {
'hero-pattern': "url('/img/hero-pattern.svg')",
'footer-texture': "url('/img/footer-texture.png')",
}
}
}
}
The solution is to use the style attribute. Thanks for helping :)
<div
className="col-span-full bg- bg-cover grid grid-cols-12 gap-6"
style={{
backgroundImage: `url(${img})`,
}}
>

how to import css file in react when generating static html and inject imported css into html head tag?

I am trying to generate static html from react using renderToStaticMarkup method. The problem I am facing right now is that I am not able to import css into react component. I want to import css in my React components like css-modules (import styles from './style.css'). And then inject that loaded css into generated static html head. How can I accomplish that?
P.S. I can't use webpack due to some constraints. If there is any babel plugin availabe for this specific case, then please let me know.
Here is how I am generating static html from react component:
const reactElement = require('react').createElement;
const ReactDomServer = require('react-dom/server');
const renderHTML = Component => {
return ReactDomServer.renderToString(reactElement(Component))
}
You can pass a URL in as a prop and render a <link/> tag. Made an example here, not sure if that would meet your needs or if you need it to be a style tag.
This may be challenging without a lot of custom logic.
If you want to inline the CSS only for the initial render and then fetch the rest after the initial render, styled-components may be a better option because it supports exactly what you're trying to achieve without too much configuration: https://www.styled-components.com/docs/advanced#server-side-rendering
May be I am too late you can also create It like this way.
React.createElement("style", {},[ "body {background-color: powderblue;}
h1 {color: blue;}
p {color: red;}" ])
Output:
<style>
body {background-color: powderblue;}
h1 {color: blue;}
p {color: red;}
</style>
Since createElement take 3 params and last one is children we can put our vanila css inside it as a children. You can put any imported file in the form of string and it will convert to style tag

Webpack & Css-loader. How to create dynamic className for React?

The project has the following reference, which returns a string:
const left = slide.imageLeft; // introLeft
And further renders it inside React Component. But it returns as a string styles.imageLeft and since webpack doest convert it into corresponding bundled class like 914u923asdsajdlj1l23 the styles are not applied.
<div className={`styles.${left}`}> </div>
P.S I did try to eval, but it drops 2 errors.
There is an internal error in the React performance measurement code. Did not expect componentDidMount timer to start while render timer is still in progress for another instance.
And
ReferenceError: styles is not defined
Can you please suggest the possible ways to achieve dynamic class generation for css-loader.
You have to define the style within the render(), or within the component definition, like this
render: function(){
var myStyle = {
// your style rules go here
};
return(
<div style={myStyle}>
{this.props.children}
</div>
)
}
in a way, this is already dynamic, because all you have to do is to change to style and it'll make sure that the component will re-render on update

Resources