prettier-plugin-classnames
                                
                                 prettier-plugin-classnames copied to clipboard
                                
                                    prettier-plugin-classnames copied to clipboard
                            
                            
                            
                        [FAQ] Compatibility with `prettier-plugin-tailwindcss`
Can I use this plugin with prettier-plugin-tailwindcss?
Of course! However, there are a few notes.
- 
Languages that can be used with prettier-plugin-tailwindcssare limited to:- JavaScript
- TypeScript
- Vue (v0.3.0or higher)
- Astro (v0.6.0or higher)
- Angular, HTML, Svelte (v0.7.0or higher)
 Support for other languages requires further development. 
- 
You need to add prettier-plugin-mergeto your Prettier configuration.This is because if two or more plugins are configured to format a particular language, Prettier will only use the last of those plugins. So, for example, if you configure it like this, only prettier-plugin-tailwindcsswill be used.{ "plugins": [ "prettier-plugin-classnames", // ignored "prettier-plugin-tailwindcss" ] }By reordering the two plugins, now only prettier-plugin-classnamesis used.{ "plugins": [ "prettier-plugin-tailwindcss", // ignored "prettier-plugin-classnames" ] }I created prettier-plugin-mergeto overcome this limitation of Prettier.prettier-plugin-mergeuses the plugins listed before it sequentially to format and merge them.So, to allow Prettier to use prettier-plugin-merge, change the configuration as follows:{ "plugins": [ "prettier-plugin-tailwindcss", "prettier-plugin-classnames", "prettier-plugin-merge" ] }Now Prettier will only use prettier-plugin-mergeamong the three plugins, butprettier-plugin-mergewill useprettier-plugin-tailwindcssandprettier-plugin-classnamessequentially.So the class names will be sorted first and then wrapped. 
I think it would be better to leave the issue open so that visitors can be more aware of how to use the plugin.
Hi @ony3000
Your plugin doesn't work for me. I put the following in my .prettierrc:
{
  "plugins": [
    "prettier-plugin-tailwindcss",
    "prettier-plugin-classnames",
    "prettier-plugin-merge"
  ]
}
I then ran prettier . --write and all my files were reported unchanged. The only thing I noticed was that for some reason it took prettier 227ms to process my 75 LoC App.tsx, while normally (with prettier-plugin-tailwindcss only) it takes around 100ms.
@dprkh Have you checked the Ending Position option? When this option is set to default(relative), line breaks are performed only for class names without considering the length of the code. Therefore, if the class name is short enough, the plugin may appear to not work because it remains a single-line class name.
If class names that are longer than the printWidth do not wrap, please report the issue with more detailed information and I will investigate.
Since prettier-plugin-merge sequentially uses the plugins listed before it, it could theoretically take more time than if only prettier-plugin-tailwindcss was used. But maybe the logic of this plugin is not optimized. :sweat_smile:
@dprkh Have you checked the Ending Position option? When this option is set to default(
relative), line breaks are performed only for class names without considering the length of the code. Therefore, if the class name is short enough, the plugin may appear to not work because it remains a single-line class name.If class names that are longer than the
printWidthdo not wrap, please report the issue with more detailed information and I will investigate.
I've tried adding --ending-position=relative when running prettier . --write and it did not seem to have changed anything. I'm not sure what the default printWidth is, but I have a fairly long class name right here, so I would expect this line and a couple of others to have been broken down. You can also find my .prettierrc and package.json for review.
Since
prettier-plugin-mergesequentially uses the plugins listed before it, it could theoretically take more time than if onlyprettier-plugin-tailwindcsswas used. But maybe the logic of this plugin is not optimized. 😅
Performance is fine, this is just a formatter after all. I was only pointing out that something is definitely happening there.
Ah! The name that this plugin considers to be the default attribute for jsx (and tsx) is className.
So, in your case the customAttributes: ["class"] setting (--custom-attributes=class if you are using the CLI method) should be added.
Ah! The name that this plugin considers to be the default attribute for jsx (and tsx) is
className.So, in your case the
customAttributes: ["class"]setting (--custom-attributes=classif you are using the CLI method) should be added.
Yep, this worked. Thank you.
so, it doesn't work with SvelteKit, right?
@SergiySev For now, yes. In this case, you can still configure Prettier as follows:
{
  "plugins": [
    "prettier-plugin-svelte",
    "prettier-plugin-tailwindcss",
    "prettier-plugin-classnames",
    "prettier-plugin-merge"
  ]
}
However, among the above plugins, only prettier-plugin-svelte and prettier-plugin-tailwindcss support svelte formatting, so Prettier will use prettier-plugin-tailwindcss.
There is logic inside prettier-plugin-tailwindcss that enables compatibility with prettier-plugin-svelte, so class name sorting works.
I'm using this plugin and the merge plugin with angular with the following config:
/** @type {import("prettier").Config} */
const config = {
  plugins: [
    "prettier-plugin-tailwindcss",
    "prettier-plugin-classnames",
    "prettier-plugin-merge",
  ],
  customAttributes: ["class", "className", "style"],
  endingPosition: "absolute-with-indent",
  printWidth: 80,
  overrides: [
    {
      files: "*.html",
      options: {
        parser: "angular",
      },
    },
  ],
};
export default config;
and I have the following html snippet:
    <button
      type="submit"
      class="w-full rounded-lg bg-blue-700 px-5 py-2.5 text-center text-sm font-medium text-white hover:bg-blue-800 focus:outline-none focus:ring-4 focus:ring-blue-300 sm:w-auto dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
    >
      Submit
    </button>
When I run prettier with:
 npx prettier --write .
The class name does not get formated
@lampewebdev As you can see in the first note, angular is also not currently supported. Further development is required.
@SergiySev For now, yes. In this case, you can still configure Prettier as follows:
{ "plugins": [ "prettier-plugin-svelte", "prettier-plugin-tailwindcss", "prettier-plugin-classnames", "prettier-plugin-merge" ] }However, among the above plugins, only
prettier-plugin-svelteandprettier-plugin-tailwindcsssupport svelte formatting, so Prettier will useprettier-plugin-tailwindcss.There is logic inside
prettier-plugin-tailwindcssthat enables compatibility withprettier-plugin-svelte, so class name sorting works.
Just to double check, are you saying formatting through this plugin doesn't work in SvelteKit, right?!
@yyijoo Strictly speaking, this plugin can work on components written in *.js (or *.ts) files even in SvelteKit projects.
But I haven't used SvelteKit, so I don't know if such a use case exists.
It's true that it doesn't currently work with *.svelte files, and I plan to include svelte support in the v0.7.0 release.
I see Thank you for your reply! @ony3000
Finally, v0.7.0 has been released.
@SergiySev @yyijoo svelte is now supported!
@lampewebdev angular is now also supported!
Hi, Can we be compatible with the prettier-plugin-multiline-arrays plugin?
@u3u I looked at prettier-plugin-multiline-arrays, and it appears to support five different parsers.
The intersection of prettier-plugin-multiline-arrays, this plugin, and prettier-plugin-merge is babel and typescript, so it is expected to be compatible with JavaScript and TypeScript.
@ony3000 Thank you! That's enough!
Thanks for this plugin @ony3000. But the biggest pain still exists even with prettier-plugin-merge: the Format on save option in many editors takes the classNames back to a single line.
I know we can format with npx prettier --write ., but having your code change back to a previous state when saving or working on it is a HUGE PAIN.
I believe you've been using this. So how did you work around it?
@udohjeremiah I mainly use VS Code. The format on save option is of course enabled and works fine.
Please try cloning the next-tailwind-template repository and check, and if the "pain" is reproduced, please report the issue.
Thanks for this plugin @ony3000. But the biggest pain still exists even with
prettier-plugin-merge: the Format on save option in many editors takes the classNames back to a single line.I know we can format with
npx prettier --write ., but having your code change back to a previous state when saving or working on it is a HUGE PAIN.
Put the same settings to your VS Code settings.json
prettier.config.mjs
/** @type {import('prettier').Config} */
export default {
  plugins: [
    'prettier-plugin-astro',
    'prettier-plugin-tailwindcss',
    'prettier-plugin-classnames',
    'prettier-plugin-merge',
  ],
  singleQuote: true,
  tabWidth: 2,
  useTabs: false,
  trailingComma: 'es5',
  printWidth: 80,
  tailwindConfig: './tailwind.config.mjs',
};
VS Code settings.json
{
  "prettier.singleQuote": true,
  "prettier.tabWidth": 2,
  "prettier.useTabs": false,
  "prettier.trailingComma": "es5",
  "prettier.printWidth": 80,
  "prettier.plugins": [
    "prettier-plugin-astro",
    "prettier-plugin-tailwindcss",
    "prettier-plugin-classnames",
    "prettier-plugin-merge"
  ]
}
Modify to your needs accordingly. Sometimes it's also a good idea to restart VS Code when changing these settings.
Thanks for this plugin @ony3000. But the biggest pain still exists even with
prettier-plugin-merge: the Format on save option in many editors takes the classNames back to a single line. I know we can format withnpx prettier --write ., but having your code change back to a previous state when saving or working on it is a HUGE PAIN.Put the same settings to your VS Code settings.json
prettier.config.mjs
/** @type {import('prettier').Config} */ export default { plugins: [ 'prettier-plugin-astro', 'prettier-plugin-tailwindcss', 'prettier-plugin-classnames', 'prettier-plugin-merge', ], singleQuote: true, tabWidth: 2, useTabs: false, trailingComma: 'es5', printWidth: 80, tailwindConfig: './tailwind.config.mjs', };VS Code settings.json
{ "prettier.singleQuote": true, "prettier.tabWidth": 2, "prettier.useTabs": false, "prettier.trailingComma": "es5", "prettier.printWidth": 80, "prettier.plugins": [ "prettier-plugin-astro", "prettier-plugin-tailwindcss", "prettier-plugin-classnames", "prettier-plugin-merge" ] }Modify to your needs accordingly. Sometimes it's also a good idea to restart VS Code when changing these settings.
Does not work for me :( I get Unknown Configuration Setting  for "prettier.plugins":  in VSCode.
@n3ssi3 I didn't check carefully when the above comment was written. Now that I look back, it looks like there is no plugins property in the Prettier settings in VS Code.
And I don't think there's any need for a duplicate Prettier configuration.
Edit: this is now fixed 🙌
I understand too late that the merge plugin will impact everything before it by design which may or may not be desireable. Should the merge plugin be more specific in usage? The following breaks for me and I have a hard time pointing at the specific cause, even though those aren't all handling related code lines
/** @type {import("prettier").Config} */
module.exports = {
  endingPosition: 'absolute-with-indent',
  importOrder: [...],
  importOrderTypeScriptVersion: '5.0.0',
  plugins:
    // NOTE Order matters, the merge plugin ensures they are run sequentially
    [
      '@ianvs/prettier-plugin-sort-imports',
      'prettier-plugin-tailwindcss',
      'prettier-plugin-classnames',
      'prettier-plugin-merge',
    ],
  proseWrap: 'always',
  singleQuote: true,
  tailwindConfig: './tailwind.config.ts',
  tailwindFunctions: ['twJoin', 'twMerge'],
};
In addition to the following undesired changes in Markdown content
 Some Markdown content.
 ```tsx
-<Komponent />
+<Komponent />;
 ```
And even though --file-info seems to infer the appropriate parser, Prettier errors on some HTML:
[error] path/to/some.html: SyntaxError: ';' expected. (3:16)
[error]   1 | <!doctype html>
[error]   2 | <html>
[error] > 3 |   <head>
[error]     |                ^
[error]   4 |     <title>Some Title</title>
[error]   5 |     <script>
[error]   6 |       /** @license React v17.0.1
[error]   1 | <!doctype html>
[error]   2 | <html>
[error] > 3 |   <head>
[error]     |                ^
[error]   4 |     <title>Some Title</title>
[error]   5 |     <script>
[error]   6 |       /** @license React v17.0.1
Similar results happened with the original prettier-plugin-sort-imports plugin and I seem to reproduce by commenting plugins one by one and the classnames plugin seems to be the culprit. What am I missing?
@angrybacon Well, this is the first time I've seen this type of problem, so I'll have to investigate it to figure out the cause.
Please report the issue by attaching the versions of Prettier and plugins, your Prettier configuration, and an example of the code that is causing the problem, and I will look into it.
Thank you for being so responsive 🙏 Unfortunately I could not reproduce my 2 issues with the exact same version numbers I use in my project so I'm not sure where to look now
I've added the sandbox and details anyway in case you can think of something relevant https://github.com/ony3000/prettier-plugin-classnames/issues/80