@youthfulhps/prettier-plugin-tailwindcss-normalizer 0.3.10 → 0.5.2

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/README.md CHANGED
@@ -5,31 +5,26 @@
5
5
 
6
6
  A Prettier plugin that automatically normalizes Tailwind CSS arbitrary values into standard utility classes, helping maintain consistent and optimized CSS across your project.
7
7
 
8
- > **⚠️ Important**: This plugin requires **Prettier v3.0.0 or higher**. It does not support Prettier v2.
8
+ **Requires Prettier v3.0.0 or higher** (Prettier v2 is not supported)
9
9
 
10
- ## Features
10
+ ## Features
11
11
 
12
- - **Automatic Normalization**: Converts arbitrary values like `p-[4px]` to standard classes like `p-1`
13
- - **Multi-Framework Support**: Works with HTML, React/JSX, Vue.js, and Angular
14
- - **Safe Transformation**: Only transforms class attributes, leaving comments, text, and other attributes untouched
15
- - **Comprehensive Mapping**: Supports padding, margin, sizing, typography, borders, shadows, and more
16
- - **Prettier v3+ Only**: Built specifically for Prettier v3.0.0 and above (v2 not supported)
12
+ - Converts arbitrary values like `p-[4px]` to standard classes like `p-1`
13
+ - Works with HTML, React/JSX, Vue.js, and Angular
14
+ - Only transforms class attributes, leaving comments, text, and other attributes untouched
15
+ - Supports padding, margin, sizing, typography, borders, shadows, and more
16
+ - Supports all Tailwind CSS variants (responsive, state, dark mode, group, peer, etc.)
17
17
 
18
- ## 🚀 Installation
19
-
20
- **Prerequisites**: Make sure you have Prettier v3.0.0 or higher installed.
18
+ ## Installation
21
19
 
22
20
  ```bash
23
- # Install Prettier v3+ (if not already installed)
24
21
  npm install --save-dev prettier@^3.0.0
25
-
26
- # Install the plugin
27
22
  npm install --save-dev @youthfulhps/prettier-plugin-tailwindcss-normalizer
28
23
  ```
29
24
 
30
- ## 📖 Usage
25
+ ## Usage
31
26
 
32
- ### 1. Configure Prettier
27
+ ### Basic Configuration
33
28
 
34
29
  Add the plugin to your Prettier configuration:
35
30
 
@@ -49,7 +44,7 @@ module.exports = {
49
44
  };
50
45
  ```
51
46
 
52
- ### 2. Run Prettier
47
+ ### Running Prettier
53
48
 
54
49
  ```bash
55
50
  # Format all files
@@ -59,35 +54,29 @@ npx prettier --write .
59
54
  npx prettier --write src/**/*.{tsx,jsx,html,vue}
60
55
  ```
61
56
 
62
- ## 🔗 Using with Other Prettier Tailwind Plugins
57
+ ## Using with Other Prettier Tailwind Plugins
63
58
 
64
- To use this plugin alongside other prettier tailwind plugins, you need to install and configure `prettier-plugin-merge`.
65
-
66
- ### Installation
59
+ To use this plugin alongside other prettier tailwind plugins (like `prettier-plugin-tailwindcss`), install and configure `prettier-plugin-merge`:
67
60
 
68
61
  ```bash
69
62
  npm install --save-dev prettier-plugin-merge
70
63
  ```
71
64
 
72
- ### Configuration
73
-
74
- In your `.prettierrc.js` file, add `prettier-plugin-merge` as the last item in the plugins array:
65
+ **`.prettierrc.js`**
75
66
 
76
67
  ```javascript
77
68
  module.exports = {
78
69
  plugins: [
79
70
  "@youthfulhps/prettier-plugin-tailwindcss-normalizer",
80
71
  "prettier-plugin-tailwindcss",
81
- "prettier-plugin-merge",
72
+ "prettier-plugin-merge", // Must be last
82
73
  ],
83
74
  };
84
75
  ```
85
76
 
86
- > **Note**: `prettier-plugin-merge` is a plugin that enables multiple prettier plugins to work together. When using with other tailwind-related plugins, it should always be placed last in the plugins array.
77
+ ## Examples
87
78
 
88
- ## 🎯 Examples
89
-
90
- ### Before
79
+ **Before:**
91
80
 
92
81
  ```jsx
93
82
  <div className="p-[16px] m-[8px] bg-blue-500">
@@ -95,7 +84,7 @@ module.exports = {
95
84
  </div>
96
85
  ```
97
86
 
98
- ### After
87
+ **After:**
99
88
 
100
89
  ```jsx
101
90
  <div className="p-4 m-2 bg-blue-500">
@@ -103,86 +92,131 @@ module.exports = {
103
92
  </div>
104
93
  ```
105
94
 
106
- ## 🛡️ Safety Features
107
-
108
- The plugin is designed to be safe and only transforms class-related attributes:
109
-
110
- ### ✅ What Gets Transformed
111
-
112
- - `className` attributes in JSX/TSX
113
- - `class` attributes in HTML
114
- - `:class` and `v-bind:class` in Vue
115
- - `[class]` in Angular
116
- - String literals in template literals
117
- - Function calls like `clsx()`, `classnames()`, `cn()`
95
+ **With Variants:**
118
96
 
119
- ### ❌ What Stays Untouched
97
+ ```jsx
98
+ // Before
99
+ <div className="md:p-[16px] hover:m-[8px] dark:bg-[#1f2937]">
100
+ Content
101
+ </div>
120
102
 
121
- - Comments and documentation
122
- - Regular text content
123
- - Other HTML attributes (`title`, `data-*`, etc.)
124
- - JavaScript strings and variables
125
- - CSS in `<style>` tags
103
+ // After
104
+ <div className="md:p-4 hover:m-2 dark:bg-[#1f2937]">
105
+ Content
106
+ </div>
107
+ ```
126
108
 
127
- ## 📋 Supported Mappings
109
+ ## Supported Mappings
128
110
 
129
111
  ### Spacing
130
112
 
131
- - **Padding**: `p-[4px]` → `p-1`, `px-[16px]` → `px-4`
132
- - **Margin**: `m-[8px]` → `m-2`, `my-[12px]` → `my-3`
133
- - **Gap**: `gap-[8px]` → `gap-2`, `gap-x-[16px]` → `gap-x-4`
113
+ - Padding: `p-[4px]` → `p-1`, `px-[16px]` → `px-4`
114
+ - Margin: `m-[8px]` → `m-2`, `my-[12px]` → `my-3`
115
+ - Gap: `gap-[8px]` → `gap-2`, `gap-x-[16px]` → `gap-x-4`
134
116
 
135
117
  ### Sizing
136
118
 
137
- - **Width**: `w-[100px]` → `w-25`, `w-[200px]` → `w-50`
138
- - **Height**: `h-[50px]` → `h-12.5`, `h-[100px]` → `h-25`
119
+ - Width: `w-[100px]` → `w-25`, `w-[200px]` → `w-50`
120
+ - Height: `h-[50px]` → `h-12.5`, `h-[100px]` → `h-25`
139
121
 
140
122
  ### Typography
141
123
 
142
- - **Font Size**: `text-[14px]` → `text-sm`, `text-[18px]` → `text-lg`
124
+ - Font Size: `text-[14px]` → `text-sm`, `text-[18px]` → `text-lg`
125
+ - Letter Spacing: `tracking-[-0.05em]` → `tracking-tighter`
143
126
 
144
127
  ### Layout
145
128
 
146
- - **Border Radius**: `rounded-[4px]` → `rounded`, `rounded-[6px]` → `rounded-md`
147
- - **Border Width**: `border-[1px]` → `border`, `border-[2px]` → `border-2`
129
+ - Border Radius: `rounded-[4px]` → `rounded`, `rounded-[6px]` → `rounded-md`
130
+ - Border Width: `border-[1px]` → `border`, `border-[2px]` → `border-2`
148
131
 
149
132
  ### Effects
150
133
 
151
- - **Box Shadow**: `shadow-[0_1px_3px_rgba(0,0,0,0.1)]` → `shadow-sm`
152
- - **Opacity**: `opacity-[0.5]` → `opacity-50`
134
+ - Box Shadow: `shadow-[0_1px_3px_rgba(0,0,0,0.1)]` → `shadow-sm`
135
+ - Opacity: `opacity-[0.5]` → `opacity-50`
153
136
 
154
- ## 🔧 Configuration
137
+ ### Transforms
155
138
 
156
- The plugin works out of the box with default settings. No additional configuration is required.
139
+ - Rotate: `rotate-[-180deg]` `-rotate-180`
140
+ - Translate: `translate-x-[-100%]` → `-translate-x-full`
157
141
 
158
- > **Note**: This plugin is optimized for Prettier v3+ and takes advantage of the new plugin architecture. If you're using Prettier v2, please upgrade to v3 or use an alternative solution.
142
+ ## Configuration
159
143
 
160
- ## 🧪 Testing
144
+ ### Custom Spacing Unit
161
145
 
162
- The plugin includes comprehensive tests covering:
146
+ By default, Tailwind uses **4px** as the base spacing unit (e.g., `p-1` = 4px, `p-2` = 8px). If you've customized your Tailwind spacing scale, configure the `customSpacingUnit` option:
163
147
 
164
- - Various file formats (HTML, JSX, TSX, Vue)
165
- - Edge cases and complex scenarios
166
- - Safety features and non-transformation cases
167
- - Different Tailwind CSS patterns
148
+ **`.prettierrc.js`**
168
149
 
169
- Run tests:
150
+ ```javascript
151
+ module.exports = {
152
+ plugins: ["@youthfulhps/prettier-plugin-tailwindcss-normalizer"],
153
+ customSpacingUnit: 8, // Change to match your Tailwind spacing scale
154
+ };
155
+ ```
170
156
 
171
- ```bash
172
- npm test
157
+ **Example with `customSpacingUnit: 8`:**
158
+
159
+ ```jsx
160
+ // Before
161
+ <div className="p-[8px] m-[16px] gap-[24px]">Content</div>
162
+
163
+ // After
164
+ <div className="p-1 m-2 gap-3">Content</div>
173
165
  ```
174
166
 
175
- ## 📁 File Support
167
+ See the [examples/custom-spacing](./examples/custom-spacing) directory for a complete working example.
168
+
169
+ ## Supported Variants
170
+
171
+ The plugin supports all Tailwind CSS variants:
172
+
173
+ - **Responsive**: `sm:`, `md:`, `lg:`, `xl:`, `2xl:`
174
+ - **State**: `hover:`, `focus:`, `active:`, `disabled:`, etc.
175
+ - **Dark Mode**: `dark:`
176
+ - **Group/Peer**: `group-hover:`, `peer-checked:`, etc.
177
+ - **Pseudo-elements**: `before:`, `after:`, `placeholder:`, etc.
178
+ - **ARIA**: `aria-checked:`, `aria-disabled:`, etc.
179
+ - **Data Attributes**: `data-[status=active]:`
180
+ - **Arbitrary**: `[&:nth-child(3)]:`, `has-[input:focus]:`, etc.
176
181
 
177
- | Format | Extension | Support |
178
- | --------- | ----------------- | ------- |
179
- | HTML | `.html` | ✅ |
180
- | React JSX | `.jsx` | ✅ |
181
- | React TSX | `.tsx` | ✅ |
182
- | Vue | `.vue` | ✅ |
183
- | Angular | `.component.html` | ✅ |
182
+ ## Safety Features
183
+
184
+ The plugin only transforms class-related attributes:
185
+
186
+ **Transformed:**
187
+
188
+ - `className` attributes in JSX/TSX
189
+ - `class` attributes in HTML
190
+ - `:class` and `v-bind:class` in Vue
191
+ - `[class]` in Angular
192
+ - String literals in template literals
193
+ - Function calls like `clsx()`, `classnames()`, `cn()`
184
194
 
185
- ## 🤝 Contributing
195
+ **Untouched:**
196
+
197
+ - Comments and documentation
198
+ - Regular text content
199
+ - Other HTML attributes
200
+ - JavaScript strings and variables
201
+ - CSS in `<style>` tags
202
+
203
+ ## File Support
204
+
205
+ | Format | Extension |
206
+ | --------- | ----------------- |
207
+ | HTML | `.html` |
208
+ | React JSX | `.jsx` |
209
+ | React TSX | `.tsx` |
210
+ | Vue | `.vue` |
211
+ | Angular | `.component.html` |
212
+
213
+ ## Testing
214
+
215
+ ```bash
216
+ npm test
217
+ ```
218
+
219
+ ## Contributing
186
220
 
187
221
  Contributions are welcome! Please feel free to submit a Pull Request.
188
222
 
@@ -192,17 +226,11 @@ Contributions are welcome! Please feel free to submit a Pull Request.
192
226
  4. Push to the branch (`git push origin feature/amazing-feature`)
193
227
  5. Open a Pull Request
194
228
 
195
- ## 📄 License
229
+ ## License
196
230
 
197
231
  This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
198
232
 
199
- ## 🙏 Acknowledgments
200
-
201
- - Built for the Prettier ecosystem
202
- - Inspired by Tailwind CSS best practices
203
- - Thanks to all contributors and users
204
-
205
- ## 📞 Support
233
+ ## Support
206
234
 
207
235
  If you encounter any issues or have questions:
208
236
 
@@ -212,15 +240,8 @@ If you encounter any issues or have questions:
212
240
 
213
241
  ### Common Issues
214
242
 
215
- **Q: The plugin doesn't work with Prettier v2**
243
+ **Q: The plugin doesn't work with Prettier v2**
216
244
  A: This plugin requires Prettier v3.0.0 or higher. Please upgrade your Prettier version.
217
245
 
218
- **Q: How do I check my Prettier version?**
246
+ **Q: How do I check my Prettier version?**
219
247
  A: Run `npx prettier --version` to check your current Prettier version.
220
-
221
- **Q: Can I use this with Prettier v2?**
222
- A: No, this plugin is built specifically for Prettier v3+ and will not work with v2.
223
-
224
- ---
225
-
226
- **Made with ❤️ for the developer community**
package/dist/index.d.ts CHANGED
@@ -3,5 +3,5 @@ declare const parsers: Record<string, CompatParser>, languages: {
3
3
  name: string;
4
4
  parsers: string[];
5
5
  extensions: string[];
6
- }[] | undefined;
7
- export { parsers, languages };
6
+ }[] | undefined, options: Record<string, any> | undefined;
7
+ export { parsers, languages, options };
package/dist/index.js CHANGED
@@ -1,13 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.languages = exports.parsers = void 0;
3
+ exports.options = exports.languages = exports.parsers = void 0;
4
4
  const ast_transformer_1 = require("./ast-transformer");
5
5
  const version_utils_1 = require("./utils/version-utils");
6
+ const normalizer_1 = require("./normalizer");
6
7
  function createParser(parserName, fileType) {
7
8
  const baseParser = (0, version_utils_1.safeLoadParser)(parserName, fileType);
8
9
  return {
9
10
  ...baseParser,
10
11
  preprocess: (text, options) => {
12
+ const pluginOptions = {
13
+ customSpacingUnit: options.customSpacingUnit,
14
+ };
15
+ (0, normalizer_1.setPluginOptions)(pluginOptions);
11
16
  return (0, ast_transformer_1.transformByFileType)(text, options.filepath || `file.${fileType}`);
12
17
  },
13
18
  };
@@ -62,7 +67,16 @@ const plugin = {
62
67
  astFormat: "estree",
63
68
  },
64
69
  },
70
+ options: {
71
+ customSpacingUnit: {
72
+ type: "int",
73
+ category: "Tailwind",
74
+ default: 4,
75
+ description: "Custom spacing unit in pixels (default: 4). Tailwind uses 4px as the base unit (e.g., p-1 = 4px). Change this if you've customized Tailwind's spacing scale.",
76
+ },
77
+ },
65
78
  };
66
- const { parsers, languages } = plugin;
79
+ const { parsers, languages, options } = plugin;
67
80
  exports.parsers = parsers;
68
81
  exports.languages = languages;
82
+ exports.options = options;
@@ -1,3 +1,5 @@
1
+ import { PluginOptions } from "./types";
2
+ export declare function setPluginOptions(options?: PluginOptions): void;
1
3
  export declare function normalizeClassAttribute(content: string): string;
2
4
  export declare function normalizeClassNames(classNames: string): string;
3
5
  export declare function normalizeClassName(className: string): string;
@@ -1,9 +1,24 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setPluginOptions = setPluginOptions;
3
4
  exports.normalizeClassAttribute = normalizeClassAttribute;
4
5
  exports.normalizeClassNames = normalizeClassNames;
5
6
  exports.normalizeClassName = normalizeClassName;
6
7
  const mappings_1 = require("./mappings");
8
+ const spacing_generator_1 = require("./utils/spacing-generator");
9
+ let currentMappings = mappings_1.TAILWIND_MAPPINGS;
10
+ function setPluginOptions(options = {}) {
11
+ if (options.customSpacingUnit && options.customSpacingUnit !== 4) {
12
+ const customSpacingMappings = (0, spacing_generator_1.generateSpacingMappings)(options.customSpacingUnit);
13
+ currentMappings = {
14
+ ...mappings_1.TAILWIND_MAPPINGS,
15
+ ...customSpacingMappings,
16
+ };
17
+ }
18
+ else {
19
+ currentMappings = mappings_1.TAILWIND_MAPPINGS;
20
+ }
21
+ }
7
22
  function normalizeClassAttribute(content) {
8
23
  let result = content;
9
24
  const classAttributeRegex = /class\s*=\s*["']([^"']*?)["']/g;
@@ -62,18 +77,90 @@ function normalizeClassNames(classNames) {
62
77
  return classes.map((className) => normalizeClassName(className)).join(" ");
63
78
  }
64
79
  function normalizeClassName(className) {
80
+ let variantPrefix = "";
81
+ let pos = 0;
82
+ while (pos < className.length) {
83
+ if (className[pos] === "[") {
84
+ const bracketEnd = className.indexOf("]:", pos);
85
+ if (bracketEnd === -1)
86
+ break;
87
+ variantPrefix += className.substring(pos, bracketEnd + 2);
88
+ pos = bracketEnd + 2;
89
+ }
90
+ else {
91
+ const colonPos = className.indexOf(":", pos);
92
+ if (colonPos === -1)
93
+ break;
94
+ const beforeColon = className.substring(pos, colonPos);
95
+ if (beforeColon.includes("[")) {
96
+ const bracketEnd = className.indexOf("]:", pos);
97
+ if (bracketEnd === -1)
98
+ break;
99
+ variantPrefix += className.substring(pos, bracketEnd + 2);
100
+ pos = bracketEnd + 2;
101
+ }
102
+ else {
103
+ variantPrefix += className.substring(pos, colonPos + 1);
104
+ pos = colonPos + 1;
105
+ }
106
+ }
107
+ if (pos >= className.length)
108
+ break;
109
+ if (className[pos] === " ")
110
+ break;
111
+ const nextChar = className[pos];
112
+ if (!/[a-z0-9_\-\[\]]/.test(nextChar)) {
113
+ break;
114
+ }
115
+ }
116
+ const classWithoutVariant = className.substring(variantPrefix.length);
117
+ if (!variantPrefix) {
118
+ return normalizeClassNameWithoutVariant(className);
119
+ }
120
+ const normalizedClass = normalizeClassNameWithoutVariant(classWithoutVariant);
121
+ if (normalizedClass === classWithoutVariant) {
122
+ return className;
123
+ }
124
+ return variantPrefix + normalizedClass;
125
+ }
126
+ function normalizeClassNameWithoutVariant(className) {
65
127
  const negativeArbitraryValueRegex = /^-([a-z:-]+)\[([^\]]+)\]$/;
66
128
  const negativeArbitraryMatch = className.match(negativeArbitraryValueRegex);
67
129
  if (negativeArbitraryMatch) {
68
130
  const [, prefixWithDash, value] = negativeArbitraryMatch;
69
131
  const prefix = prefixWithDash.replace(/-$/, "");
132
+ const negativeAllowedPrefixes = [
133
+ "m",
134
+ "mx",
135
+ "my",
136
+ "mt",
137
+ "mr",
138
+ "mb",
139
+ "ml",
140
+ "ms",
141
+ "me",
142
+ "top",
143
+ "right",
144
+ "bottom",
145
+ "left",
146
+ "inset",
147
+ "inset-x",
148
+ "inset-y",
149
+ "gap",
150
+ "gap-x",
151
+ "gap-y",
152
+ "space-x",
153
+ "space-y",
154
+ ];
155
+ if (!negativeAllowedPrefixes.includes(prefix)) {
156
+ return className;
157
+ }
70
158
  if (value === "0px" || value === "0") {
71
159
  const mapping = findStandardMapping(prefix, value);
72
- return mapping || className;
160
+ return mapping ? `-${mapping}` : className;
73
161
  }
74
- const negativeValue = `-${value}`;
75
- const mapping = findStandardMapping(prefix, negativeValue);
76
- return mapping || className;
162
+ const mapping = findStandardMapping(prefix, value);
163
+ return mapping ? `-${mapping}` : className;
77
164
  }
78
165
  const arbitraryValueRegex = /^([a-z:-]+)\[([^\]]+)\]$/;
79
166
  const arbitraryMatch = className.match(arbitraryValueRegex);
@@ -86,8 +173,42 @@ function normalizeClassName(className) {
86
173
  const mapping = findStandardMapping(prefix, positiveValue);
87
174
  return mapping || className;
88
175
  }
89
- const mapping = findStandardMapping(prefix, value);
90
- return mapping || className;
176
+ const negativeMapping = findStandardMapping(prefix, value);
177
+ if (negativeMapping) {
178
+ return negativeMapping;
179
+ }
180
+ const negativeAllowedPrefixes = [
181
+ "m",
182
+ "mx",
183
+ "my",
184
+ "mt",
185
+ "mr",
186
+ "mb",
187
+ "ml",
188
+ "ms",
189
+ "me",
190
+ "top",
191
+ "right",
192
+ "bottom",
193
+ "left",
194
+ "inset",
195
+ "inset-x",
196
+ "inset-y",
197
+ "gap",
198
+ "gap-x",
199
+ "gap-y",
200
+ "space-x",
201
+ "space-y",
202
+ "rotate",
203
+ "translate-x",
204
+ "translate-y",
205
+ ];
206
+ if (negativeAllowedPrefixes.includes(prefix)) {
207
+ const positiveValue = value.substring(1);
208
+ const mapping = findStandardMapping(prefix, positiveValue);
209
+ return mapping ? `-${mapping}` : className;
210
+ }
211
+ return className;
91
212
  }
92
213
  const mapping = findStandardMapping(prefix, value);
93
214
  return mapping || className;
@@ -96,13 +217,39 @@ function normalizeClassName(className) {
96
217
  const negativePxMatch = className.match(negativePxSuffixRegex);
97
218
  if (negativePxMatch) {
98
219
  const [, prefix, numValue] = negativePxMatch;
220
+ const negativeAllowedPrefixes = [
221
+ "m",
222
+ "mx",
223
+ "my",
224
+ "mt",
225
+ "mr",
226
+ "mb",
227
+ "ml",
228
+ "ms",
229
+ "me",
230
+ "top",
231
+ "right",
232
+ "bottom",
233
+ "left",
234
+ "inset",
235
+ "inset-x",
236
+ "inset-y",
237
+ "gap",
238
+ "gap-x",
239
+ "gap-y",
240
+ "space-x",
241
+ "space-y",
242
+ ];
243
+ if (!negativeAllowedPrefixes.includes(prefix)) {
244
+ return className;
245
+ }
99
246
  if (numValue === "0") {
100
247
  const mapping = findStandardMapping(prefix, "0px");
101
- return mapping || className;
248
+ return mapping ? `-${mapping}` : className;
102
249
  }
103
- const negativePixelValue = `-${numValue}px`;
104
- const mapping = findStandardMapping(prefix, negativePixelValue);
105
- return mapping || className;
250
+ const pixelValue = `${numValue}px`;
251
+ const mapping = findStandardMapping(prefix, pixelValue);
252
+ return mapping ? `-${mapping}` : className;
106
253
  }
107
254
  const pxSuffixRegex = /^([a-z:-]+)-(\d+)px$/;
108
255
  const pxMatch = className.match(pxSuffixRegex);
@@ -115,7 +262,7 @@ function normalizeClassName(className) {
115
262
  return className;
116
263
  }
117
264
  function findStandardMapping(prefix, value) {
118
- const mappings = mappings_1.TAILWIND_MAPPINGS[prefix];
265
+ const mappings = currentMappings[prefix];
119
266
  if (!mappings) {
120
267
  return null;
121
268
  }
package/dist/types.d.ts CHANGED
@@ -1,4 +1,7 @@
1
1
  export type ValueMapping = Record<string, string>;
2
+ export interface PluginOptions {
3
+ customSpacingUnit?: number;
4
+ }
2
5
  export type TailwindMapping = {
3
6
  p?: ValueMapping;
4
7
  px?: ValueMapping;
@@ -0,0 +1,2 @@
1
+ import { ValueMapping } from "../types";
2
+ export declare function generateSpacingMappings(customUnit?: number): Record<string, ValueMapping>;
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateSpacingMappings = generateSpacingMappings;
4
+ function generateSpacingMappings(customUnit = 4) {
5
+ const spacingPrefixes = [
6
+ "p",
7
+ "px",
8
+ "py",
9
+ "pt",
10
+ "pr",
11
+ "pb",
12
+ "pl",
13
+ "ps",
14
+ "pe",
15
+ "m",
16
+ "mx",
17
+ "my",
18
+ "mt",
19
+ "mr",
20
+ "mb",
21
+ "ml",
22
+ "ms",
23
+ "me",
24
+ "gap",
25
+ "gap-x",
26
+ "gap-y",
27
+ "space-x",
28
+ "space-y",
29
+ "w",
30
+ "h",
31
+ "size",
32
+ "min-w",
33
+ "max-w",
34
+ "min-h",
35
+ "max-h",
36
+ "top",
37
+ "right",
38
+ "bottom",
39
+ "left",
40
+ "scroll-m",
41
+ "scroll-p",
42
+ ];
43
+ const standardScales = [
44
+ { scale: "0", multiplier: 0 },
45
+ { scale: "0.5", multiplier: 0.5 },
46
+ { scale: "1", multiplier: 1 },
47
+ { scale: "1.5", multiplier: 1.5 },
48
+ { scale: "2", multiplier: 2 },
49
+ { scale: "2.5", multiplier: 2.5 },
50
+ { scale: "3", multiplier: 3 },
51
+ { scale: "3.5", multiplier: 3.5 },
52
+ { scale: "4", multiplier: 4 },
53
+ { scale: "5", multiplier: 5 },
54
+ { scale: "6", multiplier: 6 },
55
+ { scale: "7", multiplier: 7 },
56
+ { scale: "8", multiplier: 8 },
57
+ { scale: "9", multiplier: 9 },
58
+ { scale: "10", multiplier: 10 },
59
+ { scale: "11", multiplier: 11 },
60
+ { scale: "12", multiplier: 12 },
61
+ { scale: "14", multiplier: 14 },
62
+ { scale: "16", multiplier: 16 },
63
+ { scale: "20", multiplier: 20 },
64
+ { scale: "24", multiplier: 24 },
65
+ { scale: "28", multiplier: 28 },
66
+ { scale: "32", multiplier: 32 },
67
+ { scale: "36", multiplier: 36 },
68
+ { scale: "40", multiplier: 40 },
69
+ { scale: "44", multiplier: 44 },
70
+ { scale: "48", multiplier: 48 },
71
+ { scale: "52", multiplier: 52 },
72
+ { scale: "56", multiplier: 56 },
73
+ { scale: "60", multiplier: 60 },
74
+ { scale: "64", multiplier: 64 },
75
+ { scale: "72", multiplier: 72 },
76
+ { scale: "80", multiplier: 80 },
77
+ { scale: "96", multiplier: 96 },
78
+ ];
79
+ const fractionalPrefixes = ["py", "my"];
80
+ const result = {};
81
+ spacingPrefixes.forEach((prefix) => {
82
+ const mapping = {};
83
+ const supportsFractional = fractionalPrefixes.includes(prefix);
84
+ const supportsNegative = [
85
+ "m",
86
+ "mx",
87
+ "my",
88
+ "mt",
89
+ "mr",
90
+ "mb",
91
+ "ml",
92
+ "ms",
93
+ "me",
94
+ "top",
95
+ "right",
96
+ "bottom",
97
+ "left",
98
+ ].includes(prefix);
99
+ standardScales.forEach(({ scale, multiplier }) => {
100
+ if (!supportsFractional && scale.includes(".")) {
101
+ return;
102
+ }
103
+ const pixelValue = multiplier * customUnit;
104
+ const pixelKey = `${pixelValue}px`;
105
+ mapping[pixelKey] = `${prefix}-${scale}`;
106
+ if (supportsNegative && scale !== "0") {
107
+ const negativePixelValue = -pixelValue;
108
+ const negativePixelKey = `${negativePixelValue}px`;
109
+ mapping[negativePixelKey] = `-${prefix}-${scale}`;
110
+ }
111
+ });
112
+ mapping["1px"] = `${prefix}-px`;
113
+ result[prefix] = mapping;
114
+ });
115
+ return result;
116
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@youthfulhps/prettier-plugin-tailwindcss-normalizer",
3
- "version": "0.3.10",
3
+ "version": "0.5.2",
4
4
  "description": "A Prettier plugin that normalizes Tailwind CSS arbitrary values into standard utility classes.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",