tailwindlabs/prettier-plugin-tailwindcss

The plugin does not work for classes declared in <script setup> as variables.

rudachenkoev opened this issue · 1 comments

What version of prettier-plugin-tailwindcss are you using?

^0.5.13

What version of Tailwind CSS are you using?

^3.4.1

What version of Node.js are you using?

18.13.0

What package manager are you using?

npm

What operating system are you using?

macOS

Reproduction URL

<script setup lang="ts">
const defaultClasses = {
  field: 'relative',
  fieldInput:
    'absolute top-1/2 left-1/2 -translate-y-1/2 -translate-x-1/2 appearance-none bg-neutral-50 peer border rounded cursor-pointer disabled:opacity-50 disabled:cursor-default transition',
}
</script>

<template>
  <div :class="defaultClasses.field">
    <input type="checkbox" :class="defaultClasses.fieldInput" />
  </div>
</template>

Describe your issue

I am using Vue 3 and Composition API. The plugin does not work for classes declared in <script setup> as variables, by example defaultClasses.fieldInput.

Expected result: peer absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 cursor-pointer appearance-none rounded border bg-neutral-50 transition disabled:cursor-default disabled:opacity-50

Hi! Per the readme, this plugin only supports sorting classes in three places:

  • Attributes like class="p-2 sm:p-4" — you can customize which attributes we look at by setting tailwindAttributes in your prettier config. By default we support class, ngClass, className, and a few others.
  • Function calls like clsx("p-2 sm:p-4") — customizable with the tailwindFunctions setting. None by default.
  • Tagged template literals — also customizable with the tailwindFunctions setting. None by default:
let x = tw`p-2 sm:p-4`

In your case I suggest using tagged template literals. We provide an "identity" function called tw in our readme that does not change the string. After adding the appropriate types to it you'd end up with something like this — and you can always pull the tw function out into a separate file and import it if you want to reuse it across multiple components:

<script setup lang="ts">
const tw = (strings: string[], ...values: any[]) => String.raw({ raw: strings }, ...values)

const defaultClasses = {
  field: tw`relative`,
  fieldInput: tw`absolute top-1/2 left-1/2 -translate-y-1/2 -translate-x-1/2 appearance-none bg-neutral-50 peer border rounded cursor-pointer disabled:opacity-50 disabled:cursor-default transition`,
}
</script>

<template>
  <div :class="defaultClasses.field">
    <input type="checkbox" :class="defaultClasses.fieldInput" />
  </div>
</template>

Hope that helps! ✨