Is it possible to use a custom class name generator for styled components in MaterialUI? - reactjs

I'm using an unejected create-react-app project with MaterialUI and trying to replace JSS with Styled Components. It's working fine, but the class names generated are not human readable.
I read that you can use a babel plugin to do that, but I can't change the Babel config without ejecting the project. I know that you can supply a custom class name generator function to StylesProvider to generate JSS class names. Is there a similar mechanism for Styled Components that would allow me to change the class names without ejecting my project?

Basically import like this, with macro:
import styled from "styled-components/macro";
It has the same functionality of the plugin, take a look in the documentation:
https://www.styled-components.com/docs/tooling#babel-macro
example here:
https://codesandbox.io/s/nostalgic-sea-8m3q1?fontsize=14

Related

Sending props to a React-component that uses Tailwind and is imported from a Node module does not change the styling

I have a several React projects where I import some UI-components from a private NPM-package.
This UI-components package is also built using React and styled with Tailwind 3.
The projects where I import the UI-components is using Tailwind 2 and Rollup. I have the abillity to change most of this if it would help.
The CSS of this UI-components package is imported in my projects index.ts file.
(I have access to this NPM package and can change to code there as well)
One of these components is a wrapper-component. That takes in a prop called classes.
import { Wrapper } from 'our-ui-package/components/wrapper';
<Wrapper classes="pt-[30px]">
<Some-children-here />
</Wrapper>
Here I want to be able to send inn Tailwind-classes like pt-3 or even better: send in arbitrary values like pt-[30px].
Now this does not work, as the CSS for the UI-component is created when the NPM-package is build.
Is there any way I can combine the CSS from the UI-components package, as well as add any extra CSS I want to generate by sending these props to the wrapper (or any other component I make that accepts classes as props)?
Appreciate any help. Thank you so much.
Summary:
Importing components that are styled with Tailwind from a NPM-package, and send inn extra Tailwind-classes as props to said compontents, hoping the styling would update.
This does not happen, as the CSS is generated in the NPM-package is already generated when the package is built.

How to combine multiple classNames in React?

I'm writing a small React app with Create-React-App. For simple styling tweaks I use tachyons-css. Due to frequent reappearing CSS styling issues I recently switched from classic CSS styling to CSS modules (also valid question for SCSS). Now I wonder if there is a way to still use both - CSS modules and tachyons styling - even though it is not possible anymore to just add an additional "classic" className to the CSS module styles object.
Before using CSS modules I used to define a class and tachyons styling (padding5 in this example) by having multiple classNames.
For example:
<ExampleComponent className="examplecomponentstyle pa5"/>
When using CSS modules the CSS class definition will now look like this:
<ExampleComponent className={styles.examplecomponentstyle}/>
How can this syntax now be combined with the previous usage of the tachyons styling? Is there something like this that could work?:
<ExampleComponent className={styles.examplecomponentstyle & "pa5"}/>
Thanks a lot!
UPDATE from 05-Sep-19:
The clsx package is exactly doing what I was trying to achieve. After installing clsx
npm install --save clsx
the ExampleComponent can then e.g. be styled using clsx like this:
<ExampleComponent className={clsx(styles.examplecomponentstyle, "pa5 bg-yellow")}/>
UPDATE from 17-May-20:
As Sandip pointed out the ClassNames package can as well as the clsx package be used to achieve the same behaviour. The number of weekly downloads of both packages even indicates that ClassNames is much more frequently used than CLSX (~5.2 mio vs ~1.6 mio weekly downloads as of May 17 2020). This link on github discusses the performance differences between the two packages.
Without any package:
className={[styles.examplecomponentstyle, "pa5"].join(" ")};
Like you already mentioned, the package clsx is pretty good:
className={clsx(styles.examplecomponentstyle, "pa5 bg-yellow")}
When using CSS modules, you can combine classes like this
import styles from "./styles.module.css";
import "./index.css";
...
<div className={`${style.header} ${style.headerLight} container`}>
...

React tree-shakable component library with Rollup and Sass

I have a requirement which I'm not sure if can be achieved with Rollup (or with Webpack?)
I've written a React component library. Each component imports it's stylesheet. Something like
import "./button.scss"
export default function Button() {
...
}
Now, these scss files use sass variables of all sorts that I would like to define in a global file.
I want the consumer of my library to be able to import Button as so:
import { Button } from "mylib" or even better:
import Button from "mylib/button"
and have only the code required by Button be added to my library.
I can't for the life of me figure/google out how to achieve this.
Is there a good reference to a tree-shakable React component library that uses sass and sass variables?
Bonus question:
I have some third party css that only some of the component require.
So, if each of the component's scss files imports:
#import "~some-third-party-css-lib.css"
Will Rollup duplicate that css? Or is there some kind of deduping mechanism?
Thanks!
From what I know now (Feb 2020) the only options to achieve good tree-shaking results for a component library are:
When using css modules
You need to rely on the consumer of your library to handle the (s)css imports (Create React App for example is doing this pretty well)
Make sure to not transpile/bundle the css in your package and that the import paths are correct
Make the consumers import each component separately (import Button from "mylib/button"). This is because css imports are considered side-effects by most bundlers and it's petty hard (maybe even impossible) to tell which classes are actually used. So if you have an index in your library that re-exports all components, this causes ALL css to be imported and probably bundled.
When using a css-in-js system with a runtime
also make sure that you do not pre-bundle/export the css in the library build-step but rather have that leave that to the consuming app.
This has some implications that should be considered.
The consumer of your components must ship a css-in-js runtime alongside their app
If the consumer is trying to do server-side pre-rendering in some sort that might require custom additional steps depending of the css-in-js library you're using
Conclusion
As of now I don't know a solution that supports full tree-shaking (including css) while also not imposing additional complexity to the consuming app. But I'm currently still investigating this topic and will post updates here if I find something interesting.
Look at the library tailwindcss. It automatically purges the unused css variables.

Change script injection order for styled-components

I'm using styled-components in my reactjs app and I'm on a very frustrating situation, where my component defined styles get overridden by my global styles (that I import in the index.js file). I can solve this issue by using !important in those rules, but this is very far from ideal.
So, how can I make the styled-component script to inject the style dynamic tags AFTER the global injections? Is this configurable?

Debugging styled components with Create React App

I've installed Styled Components into my Create React App, and everything works fine, but by default, it looks as though the class name it appends to the element isn't based off of the styled component name (ie. MyButton should create an element with the class MyButton-134as23f).
In the Styled Components documentation, it says to install the babel-plugin-styled-components, and then configure the .babelrc file, however, from what I understand, we don't have access to that file until we eject from the app.
So how can I debug styled components while I am developing an app within Create React App?
I was able to find an answer to this:
Because Create React App is a zero-config application, the only way to add anything to the .babelrc file is to eject from React.
Obviously, I wanted to keep all of my tooling, and came across babel-plugin-macro. It's essentially a way for users to run libraries at compile time, without having to configure their Babel file beforehand.
So after installing it to my devDependencies, I then changed the import path to import styled from 'styled-components/macro, and all of the Babel plugin features that you would normally need to eject for came standard with Styled Components.
Let me know if you have any questions or trouble with my answer.
Hope this helps!

Resources