@trackunit/css-classname-utils 0.0.31 → 0.0.33

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/index.cjs.js CHANGED
@@ -14,7 +14,7 @@ var types = require('@typescript-eslint/types');
14
14
  */
15
15
  const TAILWIND_FUNCTIONS = [
16
16
  "cva",
17
- "cvaMerge",
17
+ "cx",
18
18
  "tw",
19
19
  "twx",
20
20
  "tws",
@@ -134,14 +134,15 @@ const extractFromArray = (node, parentContext) => {
134
134
  return locations;
135
135
  };
136
136
  // =============================================================================
137
- // CVA/CVAMerge Object Traversal
137
+ // CVA Object Traversal
138
138
  // =============================================================================
139
139
  /**
140
140
  * Recursively extract classname locations from a CVA options object.
141
141
  *
142
142
  * CVA structure:
143
143
  * ```
144
- * cva(baseClasses, {
144
+ * cva({
145
+ * base: baseClasses,
145
146
  * variants: {
146
147
  * variantName: {
147
148
  * variantValue: "classnames here",
@@ -169,6 +170,11 @@ const extractFromCvaObject = (node, functionName, currentPath = []) => {
169
170
  if (keyName === "defaultVariants") {
170
171
  continue;
171
172
  }
173
+ // Compound-variant objects mix selector values (`intent: "truncate"`) with
174
+ // classname fields (`class` / `className`). Only the latter are classnames.
175
+ if (currentPath[0] === "compoundVariants" && !isClassnameAttribute(keyName)) {
176
+ continue;
177
+ }
172
178
  // Recurse into nested objects (variants, compoundVariants entries, etc.)
173
179
  if (property.value.type === types.AST_NODE_TYPES.ObjectExpression) {
174
180
  locations.push(...extractFromCvaObject(property.value, functionName, propertyPath));
@@ -235,8 +241,8 @@ const getPropertyKeyName = (key) => {
235
241
  * Handles various argument patterns:
236
242
  * - String literals: twMerge("flex items-center")
237
243
  * - Template literals: twMerge(`flex ${condition && "hidden"}`)
238
- * - Arrays: cvaMerge(["flex", "items-center"], options)
239
- * - CVA options objects: cva(base, { variants: { ... } })
244
+ * - Arrays: cx(["flex", "items-center"], "gap-2")
245
+ * - CVA options objects: cva({ base, variants: { ... } })
240
246
  */
241
247
  const extractFromFunctionCall = (node) => {
242
248
  const calleeName = getCalleeName(node.callee);
@@ -244,7 +250,7 @@ const extractFromFunctionCall = (node) => {
244
250
  return [];
245
251
  }
246
252
  const locations = [];
247
- const isCvaStyle = calleeName === "cva" || calleeName === "cvaMerge";
253
+ const isCvaStyle = calleeName === "cva";
248
254
  node.arguments.forEach((arg, argIndex) => {
249
255
  const baseContext = {
250
256
  type: "function-call",
@@ -267,7 +273,7 @@ const extractFromFunctionCall = (node) => {
267
273
  locations.push(...extractFromArray(arg, baseContext));
268
274
  return;
269
275
  }
270
- // Handle CVA options object (typically second argument)
276
+ // Handle CVA options object (`cva({ base, variants, ... })`)
271
277
  if (isCvaStyle && arg.type === types.AST_NODE_TYPES.ObjectExpression) {
272
278
  locations.push(...extractFromCvaObject(arg, calleeName));
273
279
  }
@@ -389,7 +395,7 @@ const extractFromVariableDeclarator = (node) => {
389
395
  * Find all classname string locations in a CallExpression node.
390
396
  *
391
397
  * Use this in your ESLint rule's CallExpression handler to process
392
- * Tailwind utility function calls like twMerge, cvaMerge, etc.
398
+ * Tailwind utility function calls like twMerge, cva, etc.
393
399
  *
394
400
  * @example
395
401
  * ```typescript
package/index.esm.js CHANGED
@@ -12,7 +12,7 @@ import { AST_NODE_TYPES } from '@typescript-eslint/types';
12
12
  */
13
13
  const TAILWIND_FUNCTIONS = [
14
14
  "cva",
15
- "cvaMerge",
15
+ "cx",
16
16
  "tw",
17
17
  "twx",
18
18
  "tws",
@@ -132,14 +132,15 @@ const extractFromArray = (node, parentContext) => {
132
132
  return locations;
133
133
  };
134
134
  // =============================================================================
135
- // CVA/CVAMerge Object Traversal
135
+ // CVA Object Traversal
136
136
  // =============================================================================
137
137
  /**
138
138
  * Recursively extract classname locations from a CVA options object.
139
139
  *
140
140
  * CVA structure:
141
141
  * ```
142
- * cva(baseClasses, {
142
+ * cva({
143
+ * base: baseClasses,
143
144
  * variants: {
144
145
  * variantName: {
145
146
  * variantValue: "classnames here",
@@ -167,6 +168,11 @@ const extractFromCvaObject = (node, functionName, currentPath = []) => {
167
168
  if (keyName === "defaultVariants") {
168
169
  continue;
169
170
  }
171
+ // Compound-variant objects mix selector values (`intent: "truncate"`) with
172
+ // classname fields (`class` / `className`). Only the latter are classnames.
173
+ if (currentPath[0] === "compoundVariants" && !isClassnameAttribute(keyName)) {
174
+ continue;
175
+ }
170
176
  // Recurse into nested objects (variants, compoundVariants entries, etc.)
171
177
  if (property.value.type === AST_NODE_TYPES.ObjectExpression) {
172
178
  locations.push(...extractFromCvaObject(property.value, functionName, propertyPath));
@@ -233,8 +239,8 @@ const getPropertyKeyName = (key) => {
233
239
  * Handles various argument patterns:
234
240
  * - String literals: twMerge("flex items-center")
235
241
  * - Template literals: twMerge(`flex ${condition && "hidden"}`)
236
- * - Arrays: cvaMerge(["flex", "items-center"], options)
237
- * - CVA options objects: cva(base, { variants: { ... } })
242
+ * - Arrays: cx(["flex", "items-center"], "gap-2")
243
+ * - CVA options objects: cva({ base, variants: { ... } })
238
244
  */
239
245
  const extractFromFunctionCall = (node) => {
240
246
  const calleeName = getCalleeName(node.callee);
@@ -242,7 +248,7 @@ const extractFromFunctionCall = (node) => {
242
248
  return [];
243
249
  }
244
250
  const locations = [];
245
- const isCvaStyle = calleeName === "cva" || calleeName === "cvaMerge";
251
+ const isCvaStyle = calleeName === "cva";
246
252
  node.arguments.forEach((arg, argIndex) => {
247
253
  const baseContext = {
248
254
  type: "function-call",
@@ -265,7 +271,7 @@ const extractFromFunctionCall = (node) => {
265
271
  locations.push(...extractFromArray(arg, baseContext));
266
272
  return;
267
273
  }
268
- // Handle CVA options object (typically second argument)
274
+ // Handle CVA options object (`cva({ base, variants, ... })`)
269
275
  if (isCvaStyle && arg.type === AST_NODE_TYPES.ObjectExpression) {
270
276
  locations.push(...extractFromCvaObject(arg, calleeName));
271
277
  }
@@ -387,7 +393,7 @@ const extractFromVariableDeclarator = (node) => {
387
393
  * Find all classname string locations in a CallExpression node.
388
394
  *
389
395
  * Use this in your ESLint rule's CallExpression handler to process
390
- * Tailwind utility function calls like twMerge, cvaMerge, etc.
396
+ * Tailwind utility function calls like twMerge, cva, etc.
391
397
  *
392
398
  * @example
393
399
  * ```typescript
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/css-classname-utils",
3
- "version": "0.0.31",
3
+ "version": "0.0.33",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -16,7 +16,7 @@ import { TSESTree } from "@typescript-eslint/types";
16
16
  * This module provides a centralized way to detect classname usage patterns across:
17
17
  * - JSX `className` and `class` attributes
18
18
  * - Variables named with `...Class` or `...ClassName` suffixes
19
- * - Tailwind utility functions: `cvaMerge`, `twMerge`, `cva`, `tw`, `twx`, `tws`, `cn`, `clsx`, `classNames`, `twJoin`
19
+ * - Tailwind utility functions: `cva`, `cx`, `twMerge`, `tw`, `twx`, `tws`, `cn`, `clsx`, `classNames`, `twJoin`
20
20
  *
21
21
  * ## Core Concepts
22
22
  *
@@ -85,7 +85,7 @@ export type ClassnameLocation = {
85
85
  * Kept in sync with Prettier's Tailwind CSS plugin config by
86
86
  * `classname-config-sync.spec.ts`.
87
87
  */
88
- export declare const TAILWIND_FUNCTIONS: readonly ["cva", "cvaMerge", "tw", "twx", "tws", "twMerge", "twJoin", "cn", "clsx", "classNames"];
88
+ export declare const TAILWIND_FUNCTIONS: readonly ["cva", "cx", "tw", "twx", "tws", "twMerge", "twJoin", "cn", "clsx", "classNames"];
89
89
  export type TailwindFunction = (typeof TAILWIND_FUNCTIONS)[number];
90
90
  /**
91
91
  * Variable name suffixes that indicate a classname value.
@@ -119,7 +119,7 @@ export declare const getCalleeName: (callee: TSESTree.CallExpression["callee"])
119
119
  * Find all classname string locations in a CallExpression node.
120
120
  *
121
121
  * Use this in your ESLint rule's CallExpression handler to process
122
- * Tailwind utility function calls like twMerge, cvaMerge, etc.
122
+ * Tailwind utility function calls like twMerge, cva, etc.
123
123
  *
124
124
  * @example
125
125
  * ```typescript