Automatically add clsx for className
in React and have the same fun without importing and writing it.
It is important to note that this library supports the use of Typescript
projects. No other library of its kind has been found to do this.
Before doing so, make sure that clsx is installed or another available
className
handler exists for your project.
npm
npm i --save-dev babel-plugin-clsx
yarn
yarn add --save-dev babel-plugin-clsx
pnpm
pnpm add --save-dev babel-plugin-clsx
Add the babel configuration
{
"plugins": ["clsx"]
}
Your code
<div className={['c1', 'c2']} />;
<div className={{ c1: true, c2: true }} />;
After compilation
import _clsx from 'clsx';
<div className={_clsx('c1', 'c2')} />;
<div className={_clsx({ c1: true, c2: true })} />;
options.[ static
| strict
| importSource
| importName
]
interface Options {
/**
* @default true
*/
static?: boolean;
/**
* @default true
*/
strict?: boolean;
/**
* @default 'clsx'
*/
importSource?: string;
/**
* @default 'default'
*/
importName?: string;
}
By default, static mode is enabled, in which only array
and object
are converted, effectively avoiding duplicate processing of className
. Of course, although it is not recommended to do so, you can still turn off this option, and after that, it will be up to you to handle or ignore unnecessary transformations.
Add the babel configuration
{
"plugins": [
[
"clsx",
{
"static": false
}
]
]
}
Your code
const className = ['c1', 'c2'];
<div className={className} />;
After compilation
import _clsx from 'clsx';
const className = ['c1', 'c2'];
<div className={_clsx(className)} />;
In an existing project, there may be a lot of code like this, and if you turn off static mode, there will be a lot of duplication.
Your code
import classNames from 'clsx';
// π This will repeat the process
const className = classNames('c1', 'c2');
<div className={className} />;
// π This does not repeat the process
<div className={classNames('c1', 'c2')} />;
After compilation
import _clsx from 'clsx';
import classNames from 'clsx';
// π This will repeat the process
const className = classNames('c1', 'c2');
<div className={_clsx(className)} />;
// π This does not repeat the process
<div className={classNames('c1', 'c2')} />;
Strict mode is turned on by default, and you can turn it off if you want to add clsx to any attribute suffixed by className
.
Add the babel configuration
{
"plugins": [
[
"clsx",
{
"strict": false
}
]
]
}
Your code
<Component
className={['c1', 'c2']}
headerClassName={['c1', 'c2']}
footerClassName={['c1', 'c2']}
/>
After compilation
import _clsx from 'clsx';
<Component
className={_clsx('c1', 'c2')}
headerClassName={_clsx('c1', 'c2')}
footerClassName={_clsx('c1', 'c2')}
/>;
clsx is the supported library by default, and if you have your choice, you can replace it with importSource
.
Add the babel configuration
{
"plugins": [
[
"clsx",
{
"importSource": "classnames"
}
]
]
}
Your code
<div className={['c1', 'c2']} />
After compilation
import _clsx from 'classnames';
<div className={_clsx('c1', 'c2')} />;
If your custom import source does not have a default export available, you can specify the import name with importName
.
Add the babel configuration
{
"plugins": [
[
"clsx",
{
"importSource": "@/utils",
"importName": "classNames"
}
]
]
}
Your code
<div className={['c1', 'c2']} />
After compilation
import { classNames as _clsx } from '@/utils';
<div className={_clsx('c1', 'c2')} />;
If you feel that there is an unnecessary transformation, you can add a comment so that it is ignored during the transformation.
You can ignore the conversion of this line by adding a comment above.
Your code
<div className={['c1', 'c2']} />;
<div
// @clsx-ignore
className={['c1', 'c2']}
/>;
After compilation
import _clsx from 'clsx';
<div className={_clsx('c1', 'c2')} />;
<div className={['c1', 'c2']} />;
You can omit the conversion of the entire file by adding a comment at the top of the file.
Your code
// @clsx-ignore-global
<div className={['c1', 'c2']} />;
<div className={['c1', 'c2']} />;
After compilation
<div className={['c1', 'c2']} />;
<div className={['c1', 'c2']} />;
Support Typescript
with jsxImportSource.
You only need to make minor changes to tsconfig.json
to support the use of the plugin in Typescript
projects.
Only react17+
and Typescript4.7+
are supported due to the use of advanced syntax.
preserve
{
"compilerOptions": {
"jsx": "preserve",
"jsxImportSource": "babel-plugin-clsx/jsx",
"isolatedModules": true
}
}
react-jsx
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "babel-plugin-clsx/jsx"
}
}
react-jsxdev
{
"compilerOptions": {
"jsx": "react-jsxdev",
"jsxImportSource": "babel-plugin-clsx/jsx"
}
}
react-native
{
"compilerOptions": {
"jsx": "react-native",
"jsxImportSource": "babel-plugin-clsx/jsx",
"isolatedModules": true
}
}
One thing to note is that
babel-plugin-clsx/jsx
only supports type inference, which preventsTypescript
from throwing errors.