prettier-plugin-tailwind-styled-components 0.0.3 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2020 Onesine
3
+ Copyright (c) 2025 DIMITRI BARBOT
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
18
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
21
+ SOFTWARE.
package/README.md CHANGED
@@ -2,62 +2,171 @@ A [Prettier](https://prettier.io/) plugin for Tailwind CSS v3.0+ and [Tailwind S
2
2
 
3
3
  ## Installation
4
4
 
5
- To get started, just install `prettier-plugin-tailwind-styled-components` as a dev-dependency:
5
+ To get started, just install `prettier-plugin-tailwindcss` and `prettier-plugin-tailwind-styled-components` as dev dependencies:
6
6
 
7
7
  ```sh
8
- npm install -D prettier prettier-plugin-tailwind-styled-components
8
+ npm install -D prettier prettier-plugin-tailwindcss prettier-plugin-tailwind-styled-components
9
9
  ```
10
10
 
11
- This plugin follows Prettier’s autoloading convention, so as long as you’ve got Prettier set up in your project, it’ll start working automatically as soon as it’s installed.
11
+ Then add these plugins to your [Prettier configuration](https://prettier.io/docs/en/configuration.html):
12
12
 
13
- _Note that plugin autoloading is not supported when using certain package managers, such as pnpm or Yarn PnP. In this case you may need to add the plugin to your Prettier config explicitly:_
13
+ ```json5
14
+ // .prettierrc
15
+ {
16
+ "plugins": [
17
+ "prettier-plugin-tailwindcss",
18
+ "prettier-plugin-tailwind-styled-components"
19
+ ]
20
+ }
21
+ ```
22
+
23
+ Make sure `prettier-plugin-tailwind-styled-components` comes after `prettier-plugin-tailwindcss` as it depends on it.
24
+
25
+ ## Upgrading to v0.5.x
14
26
 
15
- ```js
16
- // prettier.config.js
17
- module.exports = {
18
- plugins: [require('prettier-plugin-tailwind-styled-components')],
27
+ As of v0.5.x, this plugin now requires Prettier v3 and is ESM-only. This means it cannot be loaded via `require()`. For more information see our [upgrade guide](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/issues/207#issuecomment-1698071122).
28
+
29
+ ## Options
30
+
31
+ ### Specifying your Tailwind stylesheet path
32
+
33
+ When using Tailwind CSS v4 you must specify your CSS file entry point, which includes your theme, custom utilities, and other Tailwind configuration options. To do this, use the `tailwindStylesheet` option in your Prettier configuration.
34
+
35
+ Note that paths are resolved relative to the Prettier configuration file.
36
+
37
+ ```json5
38
+ // .prettierrc
39
+ {
40
+ "tailwindStylesheet": "./resources/css/app.css"
19
41
  }
20
42
  ```
21
43
 
22
- ## Resolving your Tailwind configuration
44
+ ### Specifying your Tailwind JavaScript config path
23
45
 
24
- To ensure that the class sorting is taking into consideration any of your project's Tailwind customizations, it needs access to your [Tailwind configuration file](https://tailwindcss.com/docs/configuration) (`tailwind.config.js`).
46
+ To ensure that the class sorting takes into consideration any of your project's Tailwind customizations, it needs access to your [Tailwind configuration file](https://tailwindcss.com/docs/configuration) (`tailwind.config.js`).
25
47
 
26
48
  By default the plugin will look for this file in the same directory as your Prettier configuration file. However, if your Tailwind configuration is somewhere else, you can specify this using the `tailwindConfig` option in your Prettier configuration.
27
49
 
28
50
  Note that paths are resolved relative to the Prettier configuration file.
29
51
 
30
- ```js
31
- // prettier.config.js
32
- module.exports = {
33
- tailwindConfig: './styles/tailwind.config.js',
52
+ ```json5
53
+ // .prettierrc
54
+ {
55
+ "tailwindConfig": "./styles/tailwind.config.js"
34
56
  }
35
57
  ```
36
58
 
37
59
  If a local configuration file cannot be found the plugin will fallback to the default Tailwind configuration.
38
60
 
61
+ ## Sorting classes in template literals
62
+
63
+ To sort classes in template literals as `tailwind-styled-components` you can use the `tailwindFunctions` option, which takes a list of function names:
64
+
65
+ ```json5
66
+ // .prettierrc
67
+ {
68
+ "tailwindFunctions": ["tw"]
69
+ }
70
+ ```
71
+
72
+ With this configuration, any classes in template literals tagged with `tw` will automatically be sorted:
73
+
74
+ ```jsx
75
+ import tw from "tailwind-styled-components";
76
+
77
+ export const Container = tw.div`
78
+ flex
79
+ flex-col
80
+ items-center
81
+ sm:flex-row
82
+ `;
83
+ ```
84
+
85
+ ## Preserving duplicate classes
86
+
87
+ This plugin automatically removes duplicate classes from your class lists. However, this can cause issues in some templating languages, like Fluid or Blade, where we can't distinguish between classes and the templating syntax.
88
+
89
+ If removing duplicate classes is causing issues in your project, you can use the `tailwindPreserveDuplicates` option to disable this behavior:
90
+
91
+ ```json5
92
+ // .prettierrc
93
+ {
94
+ "tailwindPreserveDuplicates": true
95
+ }
96
+ ```
97
+
98
+ With this configuration, anything we perceive as duplicate classes will be preserved:
99
+
100
+ ```jsx
101
+ import tw from "tailwind-styled-components";
102
+
103
+ export const Container = tw.div`
104
+ flex
105
+ flex-col
106
+ items-center
107
+ sm:flex-row
108
+ ${({ $isCompact }) => ($isCompact ? "grid-cols-3" : "grid-cols-5")}
109
+ ${({ $isDark }) => ($isDark ? "bg-black/50" : "bg-white/50")}
110
+ `;
111
+ ```
112
+
113
+ ## Specifying tailwind-styled-components import name
114
+
115
+ By default, this plugins searches for imports such as:
116
+
117
+ ```jsx
118
+ import tw from "tailwind-styled-components";
119
+ ```
120
+
121
+ However, you may want to create your own tailwind styled components library. In that case, your import statement could look like:
122
+
123
+ ```jsx
124
+ import tw from "@/lib/tailwindStyledComponents";
125
+ ```
126
+
127
+ To allow your own import statement to work with this plugin, you have to add this configuration to your prettier configuration file:
128
+
129
+ ```json5
130
+ // .prettierrc
131
+ {
132
+ "tailwindStyledComponentsImport": "@/lib/tailwindStyledComponents"
133
+ }
134
+ ```
135
+
39
136
  ## Compatibility with other Prettier plugins
40
137
 
41
138
  This plugin uses Prettier APIs that can only be used by one plugin at a time, making it incompatible with other Prettier plugins implemented the same way. To solve this we've added explicit per-plugin workarounds that enable compatibility with the following Prettier plugins:
42
139
 
140
+ - `@ianvs/prettier-plugin-sort-imports`
141
+ - `@prettier/plugin-pug`
142
+ - `@shopify/prettier-plugin-liquid`
43
143
  - `@trivago/prettier-plugin-sort-imports`
144
+ - `prettier-plugin-astro`
44
145
  - `prettier-plugin-css-order`
45
146
  - `prettier-plugin-import-sort`
46
147
  - `prettier-plugin-jsdoc`
148
+ - `prettier-plugin-multiline-arrays`
47
149
  - `prettier-plugin-organize-attributes`
48
150
  - `prettier-plugin-organize-imports`
49
151
  - `prettier-plugin-style-order`
152
+ - `prettier-plugin-svelte`
153
+ - `prettier-plugin-sort-imports`
50
154
 
51
- One limitation with this approach is that `prettier-plugin-tailwind-styled-components` *must* be loaded last, meaning Prettier auto-loading needs to be disabled. You can do this by setting the `pluginSearchDirs` option to `false` and then listing each of your Prettier plugins in the `plugins` array:
155
+ One limitation with this approach is that `prettier-plugin-tailwindcss` and `prettier-plugin-tailwind-styled-components` _must_ be loaded last.
52
156
 
53
157
  ```json5
54
158
  // .prettierrc
55
159
  {
56
160
  // ..
57
161
  "plugins": [
162
+ "prettier-plugin-svelte",
58
163
  "prettier-plugin-organize-imports",
164
+ "prettier-plugin-tailwindcss", // MUST come last
59
165
  "prettier-plugin-tailwind-styled-components" // MUST come last
60
- ],
61
- "pluginSearchDirs": false
166
+ ]
62
167
  }
63
168
  ```
169
+
170
+ ## Migrating from v0 version
171
+
172
+ This plugin now relies entirely on the `prettier-plugin-tailwindcss` plugin. You have to add it as a dev-dependency in your `package.json` and add it to your Prettier configuration file plugin section as specified in the [installation](#installation) section.
package/dist/index.mjs ADDED
@@ -0,0 +1,9 @@
1
+ import {createRequire as __global__createRequire__} from 'module'
2
+ import {dirname as __global__dirname__} from 'path'
3
+ import {fileURLToPath} from 'url'
4
+ const require=__global__createRequire__(import.meta.url)
5
+ const __filename=fileURLToPath(import.meta.url)
6
+ const __dirname=__global__dirname__(__filename)
7
+ var P=(r=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(r,{get:(t,s)=>(typeof require<"u"?require:t)[s]}):r)(function(r){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+r+'" is not supported')});import*as L from"prettier/plugins/acorn";import*as f from"prettier/plugins/babel";import*as O from"prettier/plugins/flow";import*as k from"prettier/plugins/meriyah";import*as S from"prettier/plugins/typescript";var T=(r,t)=>{let s=(e,a,o,l,i={})=>{if(typeof t=="function"){if(t(e,a,o,l,i)===!1)return}else if(e.type in t&&t[e.type](e,a,o,l,i)===!1)return;let n=Object.keys(e);for(let y=0;y<n.length;y++){let p=e[n[y]];if(Array.isArray(p))for(let u=0;u<p.length;u++)p[u]!==null&&s(p[u],e,n[y],u,{...i});else typeof(p==null?void 0:p.type)=="string"&&s(p,e,n[y],y,{...i})}};s(r)},q=r=>(r==null?void 0:r.type)==="TemplateLiteral"||(r==null?void 0:r.type)==="Template"&&typeof r.value=="string",m=r=>r.replace(/\r\n\t/g," ").replace(/\s+/g," ").trim(),B=(r,t)=>{var s,e;return(r.tag.type==="MemberExpression"&&((s=r.tag.object)==null?void 0:s.type)==="Identifier"&&r.tag.object.name===t||r.tag.type==="CallExpression"&&((e=r.tag.callee)==null?void 0:e.type)==="Identifier"&&r.tag.callee.name===t)&&q(r.quasi)},g=r=>r.endOfLine==="lf"?`
8
+ `:r.endOfLine==="cr"?"\r":r.endOfLine==="crlf"?`\r
9
+ `:"",w=r=>r.useTabs?" ":" ".repeat(r.tabWidth),h=(r,t)=>{let s=g(t),e=w(t);return r.startsWith(s)?r:`${s}${e}${r}`},d=(r,t,s)=>{let e=g(t);if(!r.endsWith(e)){if(s){let a=w(t);return`${r}${e}${a}`}return`${r}${e}`}return r},j=(r,t,s)=>{let e=g(t),a=w(t),o=r.split(" ");return s.splice(0,o.length).join(`${e}${a}`)},A=r=>/[\S]/g.exec(r),C=(r,t,s,e)=>{if(A(r)){let a=m(r);return a=j(a,t,s),a=h(a,t),a=d(a,t,e),a}if(e){let a=m(r);return a=d(a,t,e),a}return r},$=(r,t,s)=>{if(Array.isArray(r.quasis))for(let e=0;e<r.quasis.length;e++){let a=r.quasis[e];a.value&&(a.value.raw=C(a.value.raw,t,s.rawClassList,!a.tail),a.value.cooked=C(a.value.cooked,t,s.cookedClassList,!a.tail))}},x=r=>{if(Array.isArray(r.quasis)){let t=r.quasis.map(i=>{var n;return((n=i.value)==null?void 0:n.raw)||""}).join(""),s=r.quasis.map(i=>{var n;return((n=i.value)==null?void 0:n.cooked)||""}).join(""),a=m(t).split(" "),l=m(s).split(" ");return{rawClassList:a,cookedClassList:l}}return{rawClassList:[],cookedClassList:[]}},_=(r,t)=>e=>{if(!(!e.quasi||!e.tag)&&B(e,t)){let a=x(e.quasi);$(e.quasi,r,a)}},V=(r,t)=>{var o,l;if(!Array.isArray(r.body))return;let s=t.tailwindStyledComponentsImport||"tailwind-styled-components",a=(((o=r.body.find(i=>{var n;return i.type==="ImportDeclaration"&&((n=i.source)==null?void 0:n.value)===s}))==null?void 0:o.specifiers)||[]).find(i=>{var n;return i.type==="ImportDefaultSpecifier"||i.type==="ImportSpecifier"&&((n=i.imported)==null?void 0:n.name)==="default"});return(l=a==null?void 0:a.local)==null?void 0:l.name},I=async(r,t)=>{let s=V(r,t);s&&T(r,_(t,s))},b=(r,t)=>{var l;if(!t.plugins)return r;let s={...r},e="prettier-plugin-tailwindcss",a=null;try{a=P.resolve(e)}catch{return s}let o=t.plugins.find(i=>i.name===e||i.name===a);return o&&Object.assign(s,(l=o.parsers)==null?void 0:l.typescript),s},c=async r=>({...r,preprocess(t,s){let e=b(r,s);return e.preprocess?e.preprocess(t,s):t},async parse(t,s){let a=await b(r,s).parse(t,s);return await I(a,s),a}}),z={babel:c(f.parsers.babel),"babel-flow":c(f.parsers["babel-flow"]),flow:c(O.parsers.flow),typescript:c(S.parsers.typescript),"babel-ts":c(f.parsers["babel-ts"]),acorn:c(L.parsers.acorn),meriyah:c(k.parsers.meriyah),__js_expression:c(f.parsers.__js_expression)},v={},F={tailwindStyledComponentsImport:{type:"string",default:"tailwind-styled-components",category:"Tailwind Styled Components",description:"Tailwind styled components import"}};export{c as createParser,F as options,z as parsers,v as printers};
package/package.json CHANGED
@@ -1,9 +1,12 @@
1
1
  {
2
+ "type": "module",
2
3
  "name": "prettier-plugin-tailwind-styled-components",
3
- "version": "0.0.3",
4
+ "version": "1.0.0",
4
5
  "description": "A Prettier plugin for sorting and formatting Tailwind CSS classes when using Tailwind Styled-Components.",
5
6
  "license": "MIT",
6
- "main": "dist/index.js",
7
+ "main": "dist/index.mjs",
8
+ "module": "dist/index.mjs",
9
+ "types": "dist/index.d.ts",
7
10
  "files": [
8
11
  "dist"
9
12
  ],
@@ -19,87 +22,42 @@
19
22
  "tailwind-styled-components"
20
23
  ],
21
24
  "scripts": {
22
- "_pre": "rimraf dist",
25
+ "_pre": "rimraf dist && cpy 'node_modules/tailwindcss/lib/css/*' dist/css",
23
26
  "_esbuild": "node build.mjs",
24
27
  "prebuild": "yarn _pre",
25
28
  "build": "yarn _esbuild --minify",
26
29
  "predev": "yarn _pre",
27
30
  "dev": "yarn _esbuild --watch",
28
- "test": "jest",
29
- "prepublishOnly": "yarn build && npm test",
31
+ "test": "vitest",
32
+ "prepublishOnly": "yarn build",
30
33
  "format": "prettier \"src/**/*.js\" \"tests/test.js\" --write --print-width 100 --single-quote --no-semi --plugin-search-dir ./tests"
31
34
  },
32
35
  "devDependencies": {
33
- "@tailwindcss/line-clamp": "^0.4.2",
34
- "@trivago/prettier-plugin-sort-imports": "^3.4.0",
35
- "@types/react": "^18.0.26",
36
- "@types/react-dom": "^18.0.10",
37
- "@types/styled-components": "^5.1.26",
38
- "esbuild": "^0.18.0",
39
- "escalade": "^3.1.1",
40
- "import-fresh": "^3.3.0",
41
- "import-from": "^4.0.0",
42
- "import-sort-style-module": "^6.0.0",
43
- "jest": "^29.3.1",
44
- "object-hash": "^3.0.0",
45
- "prettier": "^2.8.8",
46
- "prettier-plugin-css-order": "^1.3.0",
47
- "prettier-plugin-import-sort": "^0.0.7",
48
- "prettier-plugin-jsdoc": "^0.4.2",
49
- "prettier-plugin-organize-attributes": "^0.0.5",
50
- "prettier-plugin-organize-imports": "^3.2.1",
51
- "prettier-plugin-style-order": "^0.2.2",
52
- "react": "^18.2.0",
53
- "react-dom": "^18.2.0",
54
- "rimraf": "^4.0.7",
55
- "styled-components": "^5.3.6",
36
+ "@types/node": "^22.13.14",
37
+ "cpy-cli": "^5.0.0",
38
+ "esbuild": "^0.25.1",
39
+ "eslint": "^9.23.0",
40
+ "eslint-config-prettier": "^10.1.1",
41
+ "prettier": "^3.5.3",
42
+ "prettier-plugin-tailwindcss": "0.6.11",
43
+ "rimraf": "^6.0.1",
56
44
  "tailwind-styled-components": "^2.2.0",
57
- "tailwindcss": "^3.2.4",
58
- "typescript": "^4.9.4"
45
+ "tailwindcss": "^4.0.17",
46
+ "ts-node": "^10.9.2",
47
+ "typescript": "^5.8.2",
48
+ "vitest": "^3.0.9"
59
49
  },
60
50
  "peerDependencies": {
61
- "@trivago/prettier-plugin-sort-imports": "*",
62
- "prettier": "^2.2 || ^3.0",
63
- "prettier-plugin-css-order": "*",
64
- "prettier-plugin-import-sort": "*",
65
- "prettier-plugin-jsdoc": "*",
66
- "prettier-plugin-organize-attributes": "*",
67
- "prettier-plugin-organize-imports": "*",
68
- "prettier-plugin-style-order": "*",
51
+ "prettier": "^3.0",
52
+ "prettier-plugin-tailwindcss": ">=0.6.11",
69
53
  "tailwind-styled-components": ">=2.2.0"
70
54
  },
71
- "peerDependenciesMeta": {
72
- "@trivago/prettier-plugin-sort-imports": {
73
- "optional": true
74
- },
75
- "prettier-plugin-css-order": {
76
- "optional": true
77
- },
78
- "prettier-plugin-import-sort": {
79
- "optional": true
80
- },
81
- "prettier-plugin-jsdoc": {
82
- "optional": true
83
- },
84
- "prettier-plugin-organize-attributes": {
85
- "optional": true
86
- },
87
- "prettier-plugin-organize-imports": {
88
- "optional": true
89
- },
90
- "prettier-plugin-style-order": {
91
- "optional": true
92
- }
93
- },
94
55
  "engines": {
95
- "node": ">=12.17.0"
56
+ "node": ">=14.21.3"
96
57
  },
97
58
  "importSort": {
98
59
  ".js, .jsx, .ts, .tsx": {
99
60
  "style": "module"
100
61
  }
101
- },
102
- "jest": {
103
- "testTimeout": 15000
104
62
  }
105
63
  }
package/CHANGELOG.md DELETED
@@ -1,26 +0,0 @@
1
- # Changelog
2
-
3
- All notable changes to this project will be documented in this file.
4
-
5
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
-
8
- ## [Unreleased]
9
-
10
- - Nothing yet!
11
-
12
- ## [0.0.2] - 2023-01-20
13
-
14
- ### Fixed
15
-
16
- - Fix issue with expression formatting
17
-
18
- ## [0.0.3] - 2023-07-20
19
-
20
- ### Fixed
21
-
22
- - Add Prettier v3 support
23
-
24
- [unreleased]: https://github.com/dimitribarbot/prettier-plugin-tailwind-styled-components/compare/v0.0.3...HEAD
25
- [0.0.3]: https://github.com/dimitribarbot/prettier-plugin-tailwind-styled-components/compare/v0.0.2...v0.0.3
26
- [0.0.2]: https://github.com/dimitribarbot/prettier-plugin-tailwind-styled-components/compare/21dc923c300729789a998bbedfbb2f54b7ef04a6...v0.0.2