Skip to content

Commit 3d22dbd

Browse files
feat: Support for Object syntax in custom callees beside classnames (francoismassart#185)
* feat: Classnames plugin handles key and value other way around * fix: Formatting * feat: Also added sorting orders test * feat: Also added support for other rules Co-authored-by: Francois Massart <francois.massart@gmail.com>
1 parent 1e2e521 commit 3d22dbd

10 files changed

+135
-12
lines changed

lib/rules/classnames-order.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,10 @@ module.exports = {
127127
});
128128
return;
129129
case 'ObjectExpression':
130+
const isUsedByClassNamesPlugin = node.callee && node.callee.name === 'classnames';
131+
130132
arg.properties.forEach((prop) => {
131-
sortNodeArgumentValue(node, prop.key);
133+
sortNodeArgumentValue(node, isUsedByClassNamesPlugin ? prop.key : prop.value);
132134
});
133135
return;
134136
case 'Literal':

lib/rules/enforces-negative-arbitrary-values.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,10 @@ module.exports = {
102102
});
103103
return;
104104
case 'ObjectExpression':
105+
const isUsedByClassNamesPlugin = node.callee && node.callee.name === 'classnames';
106+
105107
arg.properties.forEach((prop) => {
106-
parseForNegativeArbitraryClassNames(node, prop.key);
108+
parseForNegativeArbitraryClassNames(node, isUsedByClassNamesPlugin ? prop.key : prop.value);
107109
});
108110
return;
109111
case 'Literal':

lib/rules/enforces-shorthand.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,10 @@ module.exports = {
154154
});
155155
return;
156156
case 'ObjectExpression':
157+
const isUsedByClassNamesPlugin = node.callee && node.callee.name === 'classnames';
158+
157159
arg.properties.forEach((prop) => {
158-
parseForShorthandCandidates(node, prop.key);
160+
parseForShorthandCandidates(node, isUsedByClassNamesPlugin ? prop.key : prop.value);
159161
});
160162
return;
161163
case 'Literal':

lib/rules/no-arbitrary-value.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,10 @@ module.exports = {
101101
});
102102
return;
103103
case 'ObjectExpression':
104+
const isUsedByClassNamesPlugin = node.callee && node.callee.name === 'classnames';
105+
104106
arg.properties.forEach((prop) => {
105-
parseForArbitraryValues(node, prop.key);
107+
parseForArbitraryValues(node, isUsedByClassNamesPlugin ? prop.key : prop.value);
106108
});
107109
return;
108110
case 'Literal':

lib/util/ast.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,15 @@ function parseNodeRecursive(node, arg, cb, skipConditional = false, isolate = fa
209209
return;
210210
case 'ObjectExpression':
211211
arg.properties.forEach((prop) => {
212-
parseNodeRecursive(node, prop.key, cb, skipConditional, forceIsolation);
212+
const isUsedByClassNamesPlugin = node.callee && node.callee.name === 'classnames';
213+
214+
parseNodeRecursive(
215+
node,
216+
isUsedByClassNamesPlugin ? prop.key : prop.value,
217+
cb,
218+
skipConditional,
219+
forceIsolation
220+
);
213221
});
214222
return;
215223
case 'Literal':

tests/lib/rules/classnames-order.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,20 @@ ruleTester.run("classnames-order", rule, {
507507
],
508508
errors: errors,
509509
},
510+
{
511+
code: `cva({
512+
primary: ["absolute bottom-0 w-full h-[70px] flex flex-col"],
513+
})`,
514+
output: `cva({
515+
primary: ["absolute bottom-0 flex h-[70px] w-full flex-col"],
516+
})`,
517+
options: [
518+
{
519+
callees: ["cva"],
520+
},
521+
],
522+
errors: errors,
523+
},
510524
{
511525
code: `<div className={clsx(\`absolute bottom-0 w-full h-[270px] flex flex-col\`)}>clsx</div>`,
512526
output: `<div className={clsx(\`absolute bottom-0 flex h-[270px] w-full flex-col\`)}>clsx</div>`,

tests/lib/rules/enforces-shorthand.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,5 +491,19 @@ ruleTester.run("shorthands", rule, {
491491
`,
492492
errors: [generateError(["p-2", "pl-2", "pr-2"], "p-2")],
493493
},
494+
{
495+
code: `cva({
496+
primary: ["border-l-0 border-r-0"],
497+
});`,
498+
output: `cva({
499+
primary: ["border-x-0"],
500+
});`,
501+
options: [
502+
{
503+
callees: ["cva"],
504+
},
505+
],
506+
errors: [generateError(["border-l-0", "border-r-0"], "border-x-0")],
507+
},
494508
],
495509
});

tests/lib/rules/no-arbitrary-value.js

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,11 @@ ruleTester.run("no-arbitrary-value", rule, {
9393
{
9494
code: `
9595
<nav
96-
className={cns("flex relative flex-row rounded-lg select-none", {
96+
className={classnames("flex relative flex-row rounded-lg select-none", {
9797
"bg-gray-200 p-1": !size,
9898
"bg-gray-100 p-[3px]": size === "sm",
9999
})}
100100
/>`,
101-
options: [
102-
{
103-
callees: ["cns"],
104-
},
105-
],
106101
errors: generateErrors("p-[3px]"),
107102
},
108103
{
@@ -116,6 +111,18 @@ ruleTester.run("no-arbitrary-value", rule, {
116111
);`,
117112
errors: generateErrors("text-[length:var(--font-size)] rounded-[2em] p-[4vw] leading-[1]"),
118113
},
114+
{
115+
code: `
116+
cva({
117+
primary: ["[mask-type:luminance] container flex bg-[rgba(10,20,30,0.5)] w-12 sm:w-6 lg:w-4"],
118+
});`,
119+
options: [
120+
{
121+
callees: ["cva"],
122+
},
123+
],
124+
errors: generateErrors("[mask-type:luminance] bg-[rgba(10,20,30,0.5)]"),
125+
},
119126
{
120127
code: `<div className={ctl('w-[10px]')}>Skip class attribute</div>`,
121128
options: skipClassAttributeOptions,

tests/lib/rules/no-contradicting-classname.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,18 @@ ruleTester.run("no-contradicting-classname", rule, {
618618
</div>`,
619619
errors: generateErrors("-outline-offset-2 outline-offset-4"),
620620
},
621+
{
622+
code: `
623+
cva({
624+
primary: ["px-2 px-4"],
625+
});`,
626+
options: [
627+
{
628+
callees: ["cva"],
629+
},
630+
],
631+
errors: generateErrors(["px-2 px-4"]),
632+
},
621633
{
622634
code: `
623635
<div className={\`stroke-white stroke-none \${ctl('-outline-offset-2 outline-offset-4')}\`}>

tests/lib/rules/no-custom-classname.js

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -785,7 +785,7 @@ ruleTester.run("no-custom-classname", rule, {
785785
{
786786
code: `
787787
<div class="grid-flow-dense mix-blend-plus-lighter border-separate border-spacing-4">
788-
grid-flow-dense, mix-blend-plus-lighter
788+
grid-flow-dense, mix-blend-plus-lighter
789789
</div>`,
790790
},
791791
{
@@ -820,6 +820,35 @@ ruleTester.run("no-custom-classname", rule, {
820820
},
821821
],
822822
},
823+
{
824+
code: `
825+
cva({
826+
variants: {
827+
variant: {
828+
primary: ["sm:w-6 w-8 container w-12 flex lg:w-4"],
829+
primary: ["sm:w-6 w-8 container w-12 flex lg:w-4"],
830+
},
831+
},
832+
});
833+
`,
834+
options: [
835+
{
836+
callees: ["cva"],
837+
},
838+
],
839+
},
840+
{
841+
code: `
842+
cva({
843+
primary: ["sm:w-6 w-8 container w-12 flex lg:w-4"],
844+
});
845+
`,
846+
options: [
847+
{
848+
callees: ["cva"],
849+
},
850+
],
851+
},
823852
],
824853

825854
invalid: [
@@ -1088,5 +1117,36 @@ ruleTester.run("no-custom-classname", rule, {
10881117
],
10891118
errors: generateErrors("bg-404 lg:text-unknown text-color-not-found"),
10901119
},
1120+
{
1121+
code: `
1122+
cva({
1123+
variants: {
1124+
variant: {
1125+
primary: ["sm:w-6 w-8 container w-12 flex lg:w-4 hello"],
1126+
primary: ["sm:w-6 w-8 container w-12 flex lg:w-4 world"],
1127+
},
1128+
},
1129+
});
1130+
`,
1131+
options: [
1132+
{
1133+
callees: ["cva"],
1134+
},
1135+
],
1136+
errors: generateErrors("hello world"),
1137+
},
1138+
{
1139+
code: `
1140+
cva({
1141+
primary: ["sm:w-6 w-8 container w-12 flex lg:w-4 hello"],
1142+
});
1143+
`,
1144+
options: [
1145+
{
1146+
callees: ["cva"],
1147+
},
1148+
],
1149+
errors: generateErrors("hello"),
1150+
},
10911151
],
10921152
});

0 commit comments

Comments
 (0)