Hexi

Hexi

Record my life

Introduction to eslint-plugin-classname-arg-last

Prior Knowledge#

When using Tailwind CSS, combining class names is a common requirement. We often use a method called cn to manage classes efficiently and elegantly, which typically wraps the following two commonly used tools:

1. clsx#

  • A lighter, more performant alternative to classnames.
  • Supports combining classes in the form of strings, objects, arrays, etc.
  • Example:
    clsx('btn', { 'btn-primary': isPrimary }) // => 'btn btn-primary'
    

2. tailwind-merge (abbreviated as twMerge)#

  • Used to merge conflicting Tailwind CSS class names.
  • Handles conflicts like text-sm text-lg, retaining the last class with higher priority.
  • Example:
    twMerge('text-sm text-lg') // => 'text-lg'
    

3. cn Method Encapsulation#

Combining the above two libraries into a unified cn method:

import { clsx, type ClassValue } from 'clsx'
import { twMerge } from 'tailwind-merge'

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(...inputs))
}

4. Why should className be the last parameter?#

To ensure that user-provided styles can override default styles, it is recommended to place className last:

cn('default-class', className)

Because twMerge merges from left to right, classes that come later will take precedence. If the order is reversed, the component's default styles may override user intent.


What Did I Do?#

To maintain consistency in the practice of placing className at the end of parameters, I developed an ESLint plugin for static detection and automatic fixing with the help of Grok3, compatible with Eslint v7-v9.

Source:#

eslint-plugin-classname-arg-last

Example:#

// Error example
cn(className, 'text-sm')

// Correct usage
cn('text-sm', className)

Configuration:#

Add to .eslintrc.js:

module.exports = {
  // ...
  plugins: ['classname-arg-last'],
  rules: {
    'classname-arg-last/classname-arg-last': 'error',
  },
}

With this plugin, you can standardize practices during the development phase, reducing style conflicts caused by order issues.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.