1
- import type { TSESTree } from '@typescript-eslint/utils'
1
+ import { type TSESTree } from '@typescript-eslint/utils'
2
2
import { type Rule , createRule } from '../utils'
3
3
import { isInPandaFunction , isPandaAttribute , isPandaProp , isRecipeVariant } from '../utils/helpers'
4
4
import {
@@ -17,48 +17,69 @@ const rule: Rule = createRule({
17
17
meta : {
18
18
docs : {
19
19
description :
20
- "Ensure user doesn 't use dynamic styling at any point. \nPrefer to use static styles, leverage css variables or recipes for known dynamic styles." ,
20
+ "Ensure users don 't use dynamic styling. Prefer static styles, leverage CSS variables, or recipes for known dynamic styles." ,
21
21
} ,
22
22
messages : {
23
- dynamic : 'Remove dynamic value. Prefer static styles' ,
24
- dynamicProperty : 'Remove dynamic property. Prefer static style property' ,
25
- dynamicRecipeVariant : 'Remove dynamic variant. Prefer static variant definition' ,
23
+ dynamic : 'Remove dynamic value. Prefer static styles. ' ,
24
+ dynamicProperty : 'Remove dynamic property. Prefer static style property. ' ,
25
+ dynamicRecipeVariant : 'Remove dynamic variant. Prefer static variant definition. ' ,
26
26
} ,
27
- type : 'suggestion ' ,
27
+ type : 'problem ' ,
28
28
schema : [ ] ,
29
29
} ,
30
30
defaultOptions : [ ] ,
31
31
create ( context ) {
32
+ // Helper function to determine if a node represents a static value
33
+ function isStaticValue ( node : TSESTree . Node | null | undefined ) : boolean {
34
+ if ( ! node ) return false
35
+ if ( isLiteral ( node ) ) return true
36
+ if ( isTemplateLiteral ( node ) && node . expressions . length === 0 ) return true
37
+ if ( isObjectExpression ( node ) ) return true // Conditions are acceptable
38
+ return false
39
+ }
40
+
41
+ // Function to check array elements for dynamic values
42
+ function checkArrayElements ( array : TSESTree . ArrayExpression ) {
43
+ array . elements . forEach ( ( element ) => {
44
+ if ( ! element ) return
45
+ if ( isStaticValue ( element ) ) return
46
+
47
+ context . report ( {
48
+ node : element ,
49
+ messageId : 'dynamic' ,
50
+ } )
51
+ } )
52
+ }
53
+
32
54
return {
33
- JSXAttribute ( node ) {
55
+ // JSX Attributes
56
+ JSXAttribute ( node : TSESTree . JSXAttribute ) {
34
57
if ( ! node . value ) return
35
- if ( isLiteral ( node . value ) ) return
36
- if ( isJSXExpressionContainer ( node . value ) && isLiteral ( node . value . expression ) ) return
37
-
38
- // For syntax like: <Circle property={`value that could be multiline`} />
39
- if (
40
- isJSXExpressionContainer ( node . value ) &&
41
- isTemplateLiteral ( node . value . expression ) &&
42
- node . value . expression . expressions . length === 0
43
- )
44
- return
45
58
46
- // Don't warn for objects. Those are conditions
47
- if ( isObjectExpression ( node . value . expression ) ) return
59
+ if ( isLiteral ( node . value ) ) return
60
+ // Check if it's a Panda prop early to avoid unnecessary processing
48
61
if ( ! isPandaProp ( node , context ) ) return
49
62
50
- if ( isArrayExpression ( node . value . expression ) ) {
51
- return checkArrayElements ( node . value . expression , context )
63
+ if ( isJSXExpressionContainer ( node . value ) ) {
64
+ const expr = node . value . expression
65
+
66
+ if ( isStaticValue ( expr ) ) return
67
+
68
+ if ( isArrayExpression ( expr ) ) {
69
+ checkArrayElements ( expr )
70
+ return
71
+ }
52
72
}
53
73
74
+ // Report dynamic value usage
54
75
context . report ( {
55
76
node : node . value ,
56
77
messageId : 'dynamic' ,
57
78
} )
58
79
} ,
59
80
60
- // Dynamic properties
61
- 'Property[computed=true]' ( node : TSESTree . Property ) {
81
+ // Dynamic properties with computed keys
82
+ 'Property[computed=true]' : ( node : TSESTree . Property ) => {
62
83
if ( ! isInPandaFunction ( node , context ) ) return
63
84
64
85
context . report ( {
@@ -67,22 +88,22 @@ const rule: Rule = createRule({
67
88
} )
68
89
} ,
69
90
70
- Property ( node ) {
91
+ // Object Properties
92
+ Property ( node : TSESTree . Property ) {
71
93
if ( ! isIdentifier ( node . key ) ) return
72
- if ( isLiteral ( node . value ) ) return
73
-
74
- // For syntax like: { property: `value that could be multiline` }
75
- if ( isTemplateLiteral ( node . value ) && node . value . expressions . length === 0 ) return
76
-
77
- // Don't warn for objects. Those are conditions
78
- if ( isObjectExpression ( node . value ) ) return
79
94
95
+ // Check if it's a Panda attribute early to avoid unnecessary processing
80
96
if ( ! isPandaAttribute ( node , context ) ) return
97
+ if ( isRecipeVariant ( node , context ) ) return
98
+
99
+ if ( isStaticValue ( node . value ) ) return
81
100
82
101
if ( isArrayExpression ( node . value ) ) {
83
- return checkArrayElements ( node . value , context )
102
+ checkArrayElements ( node . value )
103
+ return
84
104
}
85
105
106
+ // Report dynamic value usage
86
107
context . report ( {
87
108
node : node . value ,
88
109
messageId : 'dynamic' ,
@@ -92,17 +113,4 @@ const rule: Rule = createRule({
92
113
} ,
93
114
} )
94
115
95
- function checkArrayElements ( array : TSESTree . ArrayExpression , context : Parameters < ( typeof rule ) [ 'create' ] > [ 0 ] ) {
96
- array . elements . forEach ( ( node ) => {
97
- if ( ! node ) return
98
- if ( isLiteral ( node ) ) return
99
- if ( isTemplateLiteral ( node ) && node . expressions . length === 0 ) return
100
-
101
- context . report ( {
102
- node : node ,
103
- messageId : 'dynamic' ,
104
- } )
105
- } )
106
- }
107
-
108
116
export default rule
0 commit comments