Convert imported CSS module class for style attribute - reactjs

I want to import a style from CSS module file and assign it to style attribute, instead of writing it directly as inline style. The following code:
import styles from "./Calculator.module.css"
const Calculator = () => {
return (
// ...
<Card style={styles.darkmode} />
// ...
);
};
Gives a The style prop expects a mapping from style properties to values, not a string error, because styles.darkmode is just a name, not a JSON object. How could I convert the class name to a valid JSON object?
I've also read this question, but in that case, he got the JSON object itself, not just the name.

CSS modules return unique class names. You should be using className, instead of style:
<Card className={styles.darkmode} />

Related

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 change property of Instantiated component in react?

Given the following code:
export const AdmButton = ({icon,title,iconSize}) =>{
return({icon} {title})
buttondata.map((el, index) => {
<AdmButton title={el.title} icon={el.icon} iconSize="3em"/>
})
export const buttondata=[{
title:'calc',
icon: <ImIcons.ImCalculator size="2em"/>,
},*/.../*
]
The AdmButton is by iteration created as many times as objects in buttondata. The object contains as icon the component from react-icons, in the example ImIcons.ImCalculator is being used. Now, this component has a property called size which I'd like to change depending the place the button is shown, but I don't find a way to refer to size (or another property) when the component is being called via object property. What's the right way to modify or overwrite a Property of a given component iterated this way?
Instead of being a hard-coded component, the icon property in your object can be a function which generates a component. And that function can accept an argument:
icon: (size) => <ImIcons.ImCalculator size={size} />
Then in your AdmButton component you can invoke that function with the parameter:
return({icon(iconSize)} {title})
So each iteration when mapping will pass the parameter along and instantiate the icon on the fly.
Side note: Your call to .map() is missing the return in the callback, and as such currently won't render anything. Either include a return or remove the curly braces to make use of an implicit return.

Passing css module as prop using babel-plugin-react-css-modules

I'm using babel-plugin-react-css-modules and need to pass classes via props to React components, as such:
import "./style.css"
// Works
<div styleName="a" />
// Does not work
<CustomComponent styleNameOverride="b" />
Inside CustomComponent, I take the prop and apply it where needed.
When it's not passed to styleName directly, the class name is not hashed. Is there a way I can achieve this with this plug-in, i.e. get the hashed class name and pass it as a prop?
I found a solution to this. By passing in the attributeNames option when configuring the plugin, I could specify the names of props that I want to be transformed, and what I want them to be transformed to.
{
"plugins": [
["#dr.pogodin/react-css-modules", {
attributeNames: {
altStyleName: "altClassName",
}
}]
]
}

Strict Null Check Typescript Error on a JSX Element

I am creating a React component with Typescript which has a div JSX element with a 'style' attribute. One of the values is background color, and I'm pulling that value from a Mobx State Tree, like this:
style={{backgroundColor: css.primaryColor}}
However, this creates an error that the value might be undefined.
Normally when calling from the Mobx tree in TS, I set the path equal to a variable, then add an if statement to satisfy this null check, like this:
const { store } = this.props
const currentBot = store.bots.current
if (currentBot) {
do something
}
So in the render function, I tried creating a variable called css, from which I can reference the different keys on the object (primaryColor in the above example). This didn't work, because css could still be undefined, so I also tried adding an OR operator with a default hexcode.
const { store } = this.props
const currentBot = store.bots.current
let css
if (currentBot) {
css = currentBot.theme.css
}
...
<div
style={{backgroundColor: css.primaryColor || '#707070'}}
/>
I'm still getting 'Object is possibly undefined' on the 'css' in the style attribute in VSCode.
How can I satisfy that null check? Do I need to put the entire return statement inside of an if statement?
If the intention is to just remove the error, add ! after the variable which you know is not null to quell this error.This tells the Typescript that the object is not null.
e.g.
<div
style={{backgroundColor: css!.primaryColor || '#707070'}}
/>
If you wish to learn how to use inline styles with Typescript, see the following links-
https://medium.com/#zvona/react-native-and-typescript-meets-styles-b727ecf7e677
https://blog.blueberry.io/how-we-handle-inline-styles-with-typescript-and-react-2c257e039f2b

Resources