ony3000 / prettier-plugin-classnames

A Prettier plugin that wraps verbose class name based on the `printWidth` option.
MIT License
94 stars 0 forks source link

[FAQ] Compatibility with `prettier-plugin-tailwindcss` #33

Open ony3000 opened 5 months ago

ony3000 commented 5 months ago

Can I use this plugin with prettier-plugin-tailwindcss?

Of course! However, there are a few notes.

  1. Languages that can be used with prettier-plugin-tailwindcss are limited to:

    • JavaScript
    • TypeScript
    • Vue (v0.3.0 or higher)
    • Astro (v0.6.0 or higher)
    • Angular, HTML, Svelte (v0.7.0 or higher)

    Support for other languages requires further development.

  2. You need to add prettier-plugin-merge to 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-tailwindcss will be used.

    {
     "plugins": [
       "prettier-plugin-classnames", // ignored
       "prettier-plugin-tailwindcss"
     ]
    }

    By reordering the two plugins, now only prettier-plugin-classnames is used.

    {
     "plugins": [
       "prettier-plugin-tailwindcss", // ignored
       "prettier-plugin-classnames"
     ]
    }

    I created prettier-plugin-merge to overcome this limitation of Prettier.

    prettier-plugin-merge uses 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-merge among the three plugins, but prettier-plugin-merge will use prettier-plugin-tailwindcss and prettier-plugin-classnames sequentially.

    So the class names will be sorted first and then wrapped.

ony3000 commented 5 months ago

I think it would be better to leave the issue open so that visitors can be more aware of how to use the plugin.

ghost commented 4 months ago

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.

ony3000 commented 4 months ago

@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:

ghost commented 4 months ago

@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.

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-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. 😅

Performance is fine, this is just a formatter after all. I was only pointing out that something is definitely happening there.

ony3000 commented 4 months ago

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.

ghost commented 4 months ago

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.

Yep, this worked. Thank you.

SergiySev commented 4 months ago

so, it doesn't work with SvelteKit, right?

ony3000 commented 4 months ago

@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.

lampewebdev commented 4 months ago

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

ony3000 commented 4 months ago

@lampewebdev As you can see in the first note, angular is also not currently supported. Further development is required.

yyijoo commented 3 months ago

@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.

Just to double check, are you saying formatting through this plugin doesn't work in SvelteKit, right?!

ony3000 commented 3 months ago

@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.

yyijoo commented 2 months ago

I see Thank you for your reply! @ony3000

ony3000 commented 1 month ago

Finally, v0.7.0 has been released.

@SergiySev @yyijoo svelte is now supported!

@lampewebdev angular is now also supported!