1
1
import type { TSESTree } from '@typescript-eslint/types'
2
2
3
+ import { minimatch } from 'minimatch'
3
4
import path from 'node:path'
4
5
5
6
import type { SortingNode } from '../typings'
@@ -28,6 +29,7 @@ type Options<T extends string[]> = [
28
29
customGroups : { [ key in T [ number ] ] : string [ ] | string }
29
30
type : 'alphabetical' | 'line-length' | 'natural'
30
31
groups : ( Group < T > [ ] | Group < T > ) [ ]
32
+ ignorePattern : string [ ]
31
33
order : 'desc' | 'asc'
32
34
ignoreCase : boolean
33
35
} > ,
@@ -67,6 +69,12 @@ export default createEslintRule<Options<string[]>, MESSAGE_ID>({
67
69
type : 'boolean' ,
68
70
default : true ,
69
71
} ,
72
+ ignorePattern : {
73
+ items : {
74
+ type : 'string' ,
75
+ } ,
76
+ type : 'array' ,
77
+ } ,
70
78
} ,
71
79
additionalProperties : false ,
72
80
} ,
@@ -92,108 +100,124 @@ export default createEslintRule<Options<string[]>, MESSAGE_ID>({
92
100
if ( node . openingElement . attributes . length > 1 ) {
93
101
let options = complete ( context . options . at ( 0 ) , {
94
102
type : 'alphabetical' ,
103
+ ignorePattern : [ ] ,
95
104
ignoreCase : true ,
96
105
customGroups : { } ,
97
106
order : 'asc' ,
98
107
groups : [ ] ,
99
108
} as const )
100
109
101
- let parts : SortingNode [ ] [ ] = node . openingElement . attributes . reduce (
102
- (
103
- accumulator : SortingNode [ ] [ ] ,
104
- attribute : TSESTree . JSXSpreadAttribute | TSESTree . JSXAttribute ,
105
- ) => {
106
- if ( attribute . type === 'JSXSpreadAttribute' ) {
107
- accumulator . push ( [ ] )
108
- return accumulator
109
- }
110
-
111
- let name =
112
- attribute . name . type === 'JSXNamespacedName'
113
- ? `${ attribute . name . namespace . name } :${ attribute . name . name . name } `
114
- : attribute . name . name
115
-
116
- let { getGroup, defineGroup, setCustomGroups } = useGroups (
117
- options . groups ,
118
- )
119
-
120
- setCustomGroups ( options . customGroups , name )
110
+ let shouldIgnore = false
111
+ if ( options . ignorePattern . length ) {
112
+ let tagName = context . sourceCode . text . slice (
113
+ ...node . openingElement . name . range ,
114
+ )
115
+ shouldIgnore = options . ignorePattern . some ( pattern =>
116
+ minimatch ( tagName , pattern ) ,
117
+ )
118
+ }
121
119
122
- if ( attribute . value === null ) {
123
- defineGroup ( 'shorthand' )
124
- }
120
+ if ( ! shouldIgnore && node . openingElement . attributes . length > 1 ) {
121
+ let parts : SortingNode [ ] [ ] = node . openingElement . attributes . reduce (
122
+ (
123
+ accumulator : SortingNode [ ] [ ] ,
124
+ attribute : TSESTree . JSXSpreadAttribute | TSESTree . JSXAttribute ,
125
+ ) => {
126
+ if ( attribute . type === 'JSXSpreadAttribute' ) {
127
+ accumulator . push ( [ ] )
128
+ return accumulator
129
+ }
130
+
131
+ let name =
132
+ attribute . name . type === 'JSXNamespacedName'
133
+ ? `${ attribute . name . namespace . name } :${ attribute . name . name . name } `
134
+ : attribute . name . name
135
+
136
+ let { getGroup, defineGroup, setCustomGroups } = useGroups (
137
+ options . groups ,
138
+ )
139
+
140
+ setCustomGroups ( options . customGroups , name )
141
+
142
+ if ( attribute . value === null ) {
143
+ defineGroup ( 'shorthand' )
144
+ }
145
+
146
+ if ( attribute . loc . start . line !== attribute . loc . end . line ) {
147
+ defineGroup ( 'multiline' )
148
+ }
149
+
150
+ let jsxNode = {
151
+ size : rangeToDiff ( attribute . range ) ,
152
+ group : getGroup ( ) ,
153
+ node : attribute ,
154
+ name,
155
+ }
156
+
157
+ accumulator . at ( - 1 ) ! . push ( jsxNode )
125
158
126
- if ( attribute . loc . start . line !== attribute . loc . end . line ) {
127
- defineGroup ( 'multiline' )
128
- }
159
+ return accumulator
160
+ } ,
161
+ [ [ ] ] ,
162
+ )
163
+
164
+ for ( let nodes of parts ) {
165
+ pairwise ( nodes , ( left , right ) => {
166
+ let leftNum = getGroupNumber ( options . groups , left )
167
+ let rightNum = getGroupNumber ( options . groups , right )
168
+
169
+ if (
170
+ leftNum > rightNum ||
171
+ ( leftNum === rightNum &&
172
+ isPositive ( compare ( left , right , options ) ) )
173
+ ) {
174
+ context . report ( {
175
+ messageId : 'unexpectedJSXPropsOrder' ,
176
+ data : {
177
+ left : left . name ,
178
+ right : right . name ,
179
+ } ,
180
+ node : right . node ,
181
+ fix : fixer => {
182
+ let grouped : {
183
+ [ key : string ] : SortingNode [ ]
184
+ } = { }
185
+
186
+ for ( let currentNode of nodes ) {
187
+ let groupNum = getGroupNumber (
188
+ options . groups ,
189
+ currentNode ,
190
+ )
129
191
130
- let jsxNode = {
131
- size : rangeToDiff ( attribute . range ) ,
132
- group : getGroup ( ) ,
133
- node : attribute ,
134
- name,
135
- }
192
+ if ( ! ( groupNum in grouped ) ) {
193
+ grouped [ groupNum ] = [ currentNode ]
194
+ } else {
195
+ grouped [ groupNum ] = sortNodes (
196
+ [ ...grouped [ groupNum ] , currentNode ] ,
197
+ options ,
198
+ )
199
+ }
200
+ }
136
201
137
- accumulator . at ( - 1 ) ! . push ( jsxNode )
202
+ let sortedNodes : SortingNode [ ] = [ ]
138
203
139
- return accumulator
140
- } ,
141
- [ [ ] ] ,
142
- )
143
-
144
- for ( let nodes of parts ) {
145
- pairwise ( nodes , ( left , right ) => {
146
- let leftNum = getGroupNumber ( options . groups , left )
147
- let rightNum = getGroupNumber ( options . groups , right )
148
-
149
- if (
150
- leftNum > rightNum ||
151
- ( leftNum === rightNum &&
152
- isPositive ( compare ( left , right , options ) ) )
153
- ) {
154
- context . report ( {
155
- messageId : 'unexpectedJSXPropsOrder' ,
156
- data : {
157
- left : left . name ,
158
- right : right . name ,
159
- } ,
160
- node : right . node ,
161
- fix : fixer => {
162
- let grouped : {
163
- [ key : string ] : SortingNode [ ]
164
- } = { }
165
-
166
- for ( let currentNode of nodes ) {
167
- let groupNum = getGroupNumber ( options . groups , currentNode )
168
-
169
- if ( ! ( groupNum in grouped ) ) {
170
- grouped [ groupNum ] = [ currentNode ]
171
- } else {
172
- grouped [ groupNum ] = sortNodes (
173
- [ ...grouped [ groupNum ] , currentNode ] ,
174
- options ,
175
- )
204
+ for ( let group of Object . keys ( grouped ) . sort (
205
+ ( a , b ) => Number ( a ) - Number ( b ) ,
206
+ ) ) {
207
+ sortedNodes . push ( ...sortNodes ( grouped [ group ] , options ) )
176
208
}
177
- }
178
-
179
- let sortedNodes : SortingNode [ ] = [ ]
180
-
181
- for ( let group of Object . keys ( grouped ) . sort (
182
- ( a , b ) => Number ( a ) - Number ( b ) ,
183
- ) ) {
184
- sortedNodes . push ( ...sortNodes ( grouped [ group ] , options ) )
185
- }
186
-
187
- return makeFixes (
188
- fixer ,
189
- nodes ,
190
- sortedNodes ,
191
- context . sourceCode ,
192
- )
193
- } ,
194
- } )
195
- }
196
- } )
209
+
210
+ return makeFixes (
211
+ fixer ,
212
+ nodes ,
213
+ sortedNodes ,
214
+ context . sourceCode ,
215
+ )
216
+ } ,
217
+ } )
218
+ }
219
+ } )
220
+ }
197
221
}
198
222
}
199
223
} ,
0 commit comments