@lvce-editor/eslint-plugin-virtual-dom 17.2.0 → 17.3.1
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/dist/index.js +546 -65
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -52,8 +52,19 @@ const getProperty = (node, name) => {
|
|
|
52
52
|
const hasProperty = (node, name) => {
|
|
53
53
|
return Boolean(getProperty(node, name));
|
|
54
54
|
};
|
|
55
|
+
const virtualDomElementNames = new Set(['A', 'Abbr', 'Article', 'Aside', 'Audio', 'Br', 'Button', 'Cite', 'Code', 'Col', 'ColGroup', 'Data', 'Dd', 'Del', 'Div', 'Dl', 'Dt', 'Figcaption', 'Figure', 'Footer', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'Header', 'Hr', 'I', 'Img', 'Input', 'Ins', 'Kbd', 'Label', 'Li', 'Nav', 'Ol', 'Option', 'P', 'Pre', 'Reference', 'Root', 'Search', 'Section', 'Select', 'Span', 'Table', 'TBody', 'Td', 'Text', 'TextArea', 'Tfoot', 'Th', 'THead', 'Time', 'Tr', 'Ul', 'Video']);
|
|
56
|
+
const getVirtualDomElementName = node => {
|
|
57
|
+
if (!isMemberExpressionNode(node) || node.computed || !isIdentifierNode(node.object) || !isIdentifierNode(node.property) || !node.object.name.endsWith('Elements') || !virtualDomElementNames.has(node.property.name)) {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
return node.property.name;
|
|
61
|
+
};
|
|
55
62
|
const isVirtualDomNode = node => {
|
|
56
|
-
|
|
63
|
+
if (!isObjectExpressionNode(node)) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
const typeProperty = getProperty(node, 'type');
|
|
67
|
+
return Boolean(typeProperty && (hasProperty(node, 'childCount') || getVirtualDomElementName(typeProperty.value)));
|
|
57
68
|
};
|
|
58
69
|
const isTextCall = node => {
|
|
59
70
|
return isCallExpressionNode(node) && isIdentifierNode(node.callee) && node.callee.name === 'text';
|
|
@@ -77,7 +88,67 @@ const isStringLiteral = node => {
|
|
|
77
88
|
return isLiteralNode(node) && typeof node.value === 'string';
|
|
78
89
|
};
|
|
79
90
|
|
|
80
|
-
const
|
|
91
|
+
const controlsRequiringDirectName = new Set(['Input', 'TextArea']);
|
|
92
|
+
const controlsAllowingChildren = new Set(['A', 'Button']);
|
|
93
|
+
const hasDirectName = node => {
|
|
94
|
+
return Boolean(getProperty(node, 'ariaLabel') || getProperty(node, 'ariaLabelledBy') || getProperty(node, 'title'));
|
|
95
|
+
};
|
|
96
|
+
const meta$p = {
|
|
97
|
+
docs: {
|
|
98
|
+
description: 'Require a statically determinable accessible name for virtual-dom controls'
|
|
99
|
+
},
|
|
100
|
+
messages: {
|
|
101
|
+
accessibleControlName: 'Add an accessible name to this virtual-dom `{{name}}` control.'
|
|
102
|
+
},
|
|
103
|
+
type: 'problem'
|
|
104
|
+
};
|
|
105
|
+
const create$p = context => {
|
|
106
|
+
return {
|
|
107
|
+
ObjectExpression(node) {
|
|
108
|
+
if (!isVirtualDomNode(node) || hasDirectName(node)) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const typeProperty = getProperty(node, 'type');
|
|
112
|
+
const elementName = typeProperty && getVirtualDomElementName(typeProperty.value);
|
|
113
|
+
if (!elementName) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (controlsRequiringDirectName.has(elementName)) {
|
|
117
|
+
context.report({
|
|
118
|
+
data: {
|
|
119
|
+
name: elementName
|
|
120
|
+
},
|
|
121
|
+
messageId: 'accessibleControlName',
|
|
122
|
+
node
|
|
123
|
+
});
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (!controlsAllowingChildren.has(elementName)) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const childCountProperty = getProperty(node, 'childCount');
|
|
130
|
+
const childCount = childCountProperty && getStaticNumberValue(childCountProperty.value);
|
|
131
|
+
if (childCount !== 0) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
context.report({
|
|
135
|
+
data: {
|
|
136
|
+
name: elementName
|
|
137
|
+
},
|
|
138
|
+
messageId: 'accessibleControlName',
|
|
139
|
+
node
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const accessibleControlName = {
|
|
146
|
+
__proto__: null,
|
|
147
|
+
create: create$p,
|
|
148
|
+
meta: meta$p
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
const meta$o = {
|
|
81
152
|
docs: {
|
|
82
153
|
description: 'Require an explicit role on clickable virtual-dom div nodes'
|
|
83
154
|
},
|
|
@@ -86,7 +157,7 @@ const meta$f = {
|
|
|
86
157
|
},
|
|
87
158
|
type: 'problem'
|
|
88
159
|
};
|
|
89
|
-
const create$
|
|
160
|
+
const create$o = context => {
|
|
90
161
|
return {
|
|
91
162
|
ObjectExpression(node) {
|
|
92
163
|
if (!isVirtualDomNode(node)) {
|
|
@@ -108,11 +179,11 @@ const create$f = context => {
|
|
|
108
179
|
|
|
109
180
|
const clickableDivNeedsRole = {
|
|
110
181
|
__proto__: null,
|
|
111
|
-
create: create$
|
|
112
|
-
meta: meta$
|
|
182
|
+
create: create$o,
|
|
183
|
+
meta: meta$o
|
|
113
184
|
};
|
|
114
185
|
|
|
115
|
-
const meta$
|
|
186
|
+
const meta$n = {
|
|
116
187
|
docs: {
|
|
117
188
|
description: 'Require static virtual-dom nodes created inside functions to be hoisted to module scope'
|
|
118
189
|
},
|
|
@@ -223,7 +294,7 @@ const isStaticExpression = (sourceCode, node) => {
|
|
|
223
294
|
return false;
|
|
224
295
|
}
|
|
225
296
|
};
|
|
226
|
-
const create$
|
|
297
|
+
const create$n = context => {
|
|
227
298
|
return {
|
|
228
299
|
ObjectExpression(node) {
|
|
229
300
|
if (!isVirtualDomElement(node)) {
|
|
@@ -248,11 +319,52 @@ const create$e = context => {
|
|
|
248
319
|
|
|
249
320
|
const hoistStaticNodes = {
|
|
250
321
|
__proto__: null,
|
|
251
|
-
create: create$
|
|
252
|
-
meta: meta$
|
|
322
|
+
create: create$n,
|
|
323
|
+
meta: meta$n
|
|
253
324
|
};
|
|
254
325
|
|
|
255
|
-
const meta$
|
|
326
|
+
const meta$m = {
|
|
327
|
+
docs: {
|
|
328
|
+
description: 'Disallow conditional spreads in virtual-dom arrays'
|
|
329
|
+
},
|
|
330
|
+
messages: {
|
|
331
|
+
noConditionalSpread: 'Move conditional virtual-dom children into a helper function and spread the helper result.'
|
|
332
|
+
},
|
|
333
|
+
type: 'suggestion'
|
|
334
|
+
};
|
|
335
|
+
const isConditionalSpread = node => {
|
|
336
|
+
return node?.type === 'SpreadElement' && node.argument.type === 'ConditionalExpression';
|
|
337
|
+
};
|
|
338
|
+
const isVirtualDomArray$1 = node => {
|
|
339
|
+
return isArrayExpressionNode(node) && node.elements.some(element => isVirtualDomNode(element) || isTextCall(element));
|
|
340
|
+
};
|
|
341
|
+
const addsVirtualDomChildren = spread => {
|
|
342
|
+
return isVirtualDomArray$1(spread.argument.consequent) || isVirtualDomArray$1(spread.argument.alternate);
|
|
343
|
+
};
|
|
344
|
+
const create$m = context => {
|
|
345
|
+
return {
|
|
346
|
+
ArrayExpression(node) {
|
|
347
|
+
const conditionalSpreads = node.elements.filter(isConditionalSpread);
|
|
348
|
+
if (!isVirtualDomArray$1(node) && !conditionalSpreads.some(addsVirtualDomChildren)) {
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
for (const spread of conditionalSpreads) {
|
|
352
|
+
context.report({
|
|
353
|
+
messageId: 'noConditionalSpread',
|
|
354
|
+
node: spread
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
const noConditionalSpread = {
|
|
362
|
+
__proto__: null,
|
|
363
|
+
create: create$m,
|
|
364
|
+
meta: meta$m
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
const meta$l = {
|
|
256
368
|
docs: {
|
|
257
369
|
description: 'Disallow empty ARIA values in virtual-dom nodes'
|
|
258
370
|
},
|
|
@@ -264,7 +376,7 @@ const meta$d = {
|
|
|
264
376
|
const isAriaProperty = name => {
|
|
265
377
|
return /^aria[A-Z]/.test(name);
|
|
266
378
|
};
|
|
267
|
-
const create$
|
|
379
|
+
const create$l = context => {
|
|
268
380
|
return {
|
|
269
381
|
ObjectExpression(node) {
|
|
270
382
|
if (!isVirtualDomNode(node)) {
|
|
@@ -289,11 +401,11 @@ const create$d = context => {
|
|
|
289
401
|
|
|
290
402
|
const noEmptyAria = {
|
|
291
403
|
__proto__: null,
|
|
292
|
-
create: create$
|
|
293
|
-
meta: meta$
|
|
404
|
+
create: create$l,
|
|
405
|
+
meta: meta$l
|
|
294
406
|
};
|
|
295
407
|
|
|
296
|
-
const meta$
|
|
408
|
+
const meta$k = {
|
|
297
409
|
docs: {
|
|
298
410
|
description: 'Disallow empty className values in virtual-dom nodes'
|
|
299
411
|
},
|
|
@@ -302,7 +414,7 @@ const meta$c = {
|
|
|
302
414
|
},
|
|
303
415
|
type: 'problem'
|
|
304
416
|
};
|
|
305
|
-
const create$
|
|
417
|
+
const create$k = context => {
|
|
306
418
|
return {
|
|
307
419
|
ObjectExpression(node) {
|
|
308
420
|
if (!isVirtualDomNode(node)) {
|
|
@@ -322,11 +434,11 @@ const create$c = context => {
|
|
|
322
434
|
|
|
323
435
|
const noEmptyClassName = {
|
|
324
436
|
__proto__: null,
|
|
325
|
-
create: create$
|
|
326
|
-
meta: meta$
|
|
437
|
+
create: create$k,
|
|
438
|
+
meta: meta$k
|
|
327
439
|
};
|
|
328
440
|
|
|
329
|
-
const meta$
|
|
441
|
+
const meta$j = {
|
|
330
442
|
docs: {
|
|
331
443
|
description: 'Disallow inline event handlers in virtual-dom nodes'
|
|
332
444
|
},
|
|
@@ -341,7 +453,7 @@ const isEventPropertyName = name => {
|
|
|
341
453
|
const isInlineEventHandler = node => {
|
|
342
454
|
return isStringLiteral(node) || isTemplateLiteralNode(node) || isArrowFunctionExpressionNode(node) || isFunctionExpressionNode(node);
|
|
343
455
|
};
|
|
344
|
-
const create$
|
|
456
|
+
const create$j = context => {
|
|
345
457
|
return {
|
|
346
458
|
ObjectExpression(node) {
|
|
347
459
|
if (!isVirtualDomNode(node)) {
|
|
@@ -366,11 +478,11 @@ const create$b = context => {
|
|
|
366
478
|
|
|
367
479
|
const noInlineEventHandlers = {
|
|
368
480
|
__proto__: null,
|
|
369
|
-
create: create$
|
|
370
|
-
meta: meta$
|
|
481
|
+
create: create$j,
|
|
482
|
+
meta: meta$j
|
|
371
483
|
};
|
|
372
484
|
|
|
373
|
-
const meta$
|
|
485
|
+
const meta$i = {
|
|
374
486
|
docs: {
|
|
375
487
|
description: 'Disallow inline style attributes in virtual-dom nodes'
|
|
376
488
|
},
|
|
@@ -379,7 +491,7 @@ const meta$a = {
|
|
|
379
491
|
},
|
|
380
492
|
type: 'problem'
|
|
381
493
|
};
|
|
382
|
-
const create$
|
|
494
|
+
const create$i = context => {
|
|
383
495
|
return {
|
|
384
496
|
ObjectExpression(node) {
|
|
385
497
|
if (!isVirtualDomNode(node)) {
|
|
@@ -399,11 +511,59 @@ const create$a = context => {
|
|
|
399
511
|
|
|
400
512
|
const noInlineStyle = {
|
|
401
513
|
__proto__: null,
|
|
402
|
-
create: create$
|
|
403
|
-
meta: meta$
|
|
514
|
+
create: create$i,
|
|
515
|
+
meta: meta$i
|
|
404
516
|
};
|
|
405
517
|
|
|
406
|
-
const
|
|
518
|
+
const ignoredProperties$1 = new Set(['childCount', 'type']);
|
|
519
|
+
const isOptionalExpression = node => {
|
|
520
|
+
return typeof node === 'object' && node !== null && ('type' in node && node.type === 'ChainExpression' || 'optional' in node && node.optional === true);
|
|
521
|
+
};
|
|
522
|
+
const isNullish = node => {
|
|
523
|
+
return isLiteralNode(node) && node.value === null || isIdentifierNode(node) && node.name === 'undefined' || isOptionalExpression(node);
|
|
524
|
+
};
|
|
525
|
+
const meta$h = {
|
|
526
|
+
docs: {
|
|
527
|
+
description: 'Disallow nullish virtual-dom attribute values'
|
|
528
|
+
},
|
|
529
|
+
messages: {
|
|
530
|
+
noNullishAttributeValue: 'Omit `{{name}}` instead of assigning a nullish value.'
|
|
531
|
+
},
|
|
532
|
+
type: 'problem'
|
|
533
|
+
};
|
|
534
|
+
const create$h = context => {
|
|
535
|
+
return {
|
|
536
|
+
ObjectExpression(node) {
|
|
537
|
+
if (!isVirtualDomNode(node)) {
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
540
|
+
for (const property of node.properties) {
|
|
541
|
+
if (!isPropertyNode(property)) {
|
|
542
|
+
continue;
|
|
543
|
+
}
|
|
544
|
+
const name = getStaticPropertyName(property);
|
|
545
|
+
if (!name || ignoredProperties$1.has(name) || !isNullish(property.value)) {
|
|
546
|
+
continue;
|
|
547
|
+
}
|
|
548
|
+
context.report({
|
|
549
|
+
data: {
|
|
550
|
+
name
|
|
551
|
+
},
|
|
552
|
+
messageId: 'noNullishAttributeValue',
|
|
553
|
+
node: property.value
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
};
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
const noNullishAttributeValues = {
|
|
561
|
+
__proto__: null,
|
|
562
|
+
create: create$h,
|
|
563
|
+
meta: meta$h
|
|
564
|
+
};
|
|
565
|
+
|
|
566
|
+
const meta$g = {
|
|
407
567
|
docs: {
|
|
408
568
|
description: 'Disallow object-like attribute values in virtual-dom nodes'
|
|
409
569
|
},
|
|
@@ -416,7 +576,7 @@ const ignoredProperties = new Set(['childCount', 'type']);
|
|
|
416
576
|
const isObjectLikeAttributeValue = node => {
|
|
417
577
|
return isObjectExpressionNode(node) || isArrayExpressionNode(node) || isArrowFunctionExpressionNode(node) || isFunctionExpressionNode(node);
|
|
418
578
|
};
|
|
419
|
-
const create$
|
|
579
|
+
const create$g = context => {
|
|
420
580
|
return {
|
|
421
581
|
ObjectExpression(node) {
|
|
422
582
|
if (!isVirtualDomNode(node)) {
|
|
@@ -441,11 +601,45 @@ const create$9 = context => {
|
|
|
441
601
|
|
|
442
602
|
const noObjectAttributeValues = {
|
|
443
603
|
__proto__: null,
|
|
444
|
-
create: create$
|
|
445
|
-
meta: meta$
|
|
604
|
+
create: create$g,
|
|
605
|
+
meta: meta$g
|
|
446
606
|
};
|
|
447
607
|
|
|
448
|
-
const meta$
|
|
608
|
+
const meta$f = {
|
|
609
|
+
docs: {
|
|
610
|
+
description: 'Disallow positive virtual-dom tabIndex values'
|
|
611
|
+
},
|
|
612
|
+
messages: {
|
|
613
|
+
noPositiveTabIndex: 'Use a `tabIndex` of 0 or -1 instead of a positive value.'
|
|
614
|
+
},
|
|
615
|
+
type: 'problem'
|
|
616
|
+
};
|
|
617
|
+
const create$f = context => {
|
|
618
|
+
return {
|
|
619
|
+
ObjectExpression(node) {
|
|
620
|
+
if (!isVirtualDomNode(node)) {
|
|
621
|
+
return;
|
|
622
|
+
}
|
|
623
|
+
const tabIndexProperty = getProperty(node, 'tabIndex');
|
|
624
|
+
const tabIndex = tabIndexProperty && getStaticNumberValue(tabIndexProperty.value);
|
|
625
|
+
if (!tabIndexProperty || tabIndex === undefined || tabIndex <= 0) {
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
context.report({
|
|
629
|
+
messageId: 'noPositiveTabIndex',
|
|
630
|
+
node: tabIndexProperty.value
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
};
|
|
634
|
+
};
|
|
635
|
+
|
|
636
|
+
const noPositiveTabIndex = {
|
|
637
|
+
__proto__: null,
|
|
638
|
+
create: create$f,
|
|
639
|
+
meta: meta$f
|
|
640
|
+
};
|
|
641
|
+
|
|
642
|
+
const meta$e = {
|
|
449
643
|
docs: {
|
|
450
644
|
description: 'Disallow raw string children in virtual-dom arrays'
|
|
451
645
|
},
|
|
@@ -457,7 +651,7 @@ const meta$8 = {
|
|
|
457
651
|
const isVirtualDomArray = node => {
|
|
458
652
|
return isArrayExpressionNode(node) && node.elements.some(element => isVirtualDomNode(element) || isTextCall(element));
|
|
459
653
|
};
|
|
460
|
-
const create$
|
|
654
|
+
const create$e = context => {
|
|
461
655
|
return {
|
|
462
656
|
ArrayExpression(node) {
|
|
463
657
|
if (!isVirtualDomArray(node)) {
|
|
@@ -478,11 +672,11 @@ const create$8 = context => {
|
|
|
478
672
|
|
|
479
673
|
const noRawTextChildren = {
|
|
480
674
|
__proto__: null,
|
|
481
|
-
create: create$
|
|
482
|
-
meta: meta$
|
|
675
|
+
create: create$e,
|
|
676
|
+
meta: meta$e
|
|
483
677
|
};
|
|
484
678
|
|
|
485
|
-
const meta$
|
|
679
|
+
const meta$d = {
|
|
486
680
|
docs: {
|
|
487
681
|
description: 'Require each virtual-dom event listener to call its dedicated handler'
|
|
488
682
|
},
|
|
@@ -491,7 +685,7 @@ const meta$7 = {
|
|
|
491
685
|
},
|
|
492
686
|
type: 'problem'
|
|
493
687
|
};
|
|
494
|
-
const create$
|
|
688
|
+
const create$d = context => {
|
|
495
689
|
return {
|
|
496
690
|
ObjectExpression(node) {
|
|
497
691
|
if (!isObjectExpressionNode(node)) {
|
|
@@ -521,16 +715,50 @@ const create$7 = context => {
|
|
|
521
715
|
|
|
522
716
|
const noSharedEventListenerHandlers = {
|
|
523
717
|
__proto__: null,
|
|
524
|
-
create: create$
|
|
525
|
-
meta: meta$
|
|
718
|
+
create: create$d,
|
|
719
|
+
meta: meta$d
|
|
526
720
|
};
|
|
527
721
|
|
|
528
|
-
const meta$
|
|
722
|
+
const meta$c = {
|
|
723
|
+
docs: {
|
|
724
|
+
description: 'Prefer constants for single literal virtual-dom class names'
|
|
725
|
+
},
|
|
726
|
+
messages: {
|
|
727
|
+
preferClassNameConstant: 'Use a `ClassNames.*` constant instead of a literal `className`.'
|
|
728
|
+
},
|
|
729
|
+
type: 'suggestion'
|
|
730
|
+
};
|
|
731
|
+
const create$c = context => {
|
|
732
|
+
return {
|
|
733
|
+
ObjectExpression(node) {
|
|
734
|
+
if (!isVirtualDomNode(node)) {
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
const classNameProperty = getProperty(node, 'className');
|
|
738
|
+
if (!classNameProperty || !isStringLiteral(classNameProperty.value) || classNameProperty.value.value === '' || /\s/.test(classNameProperty.value.value)) {
|
|
739
|
+
return;
|
|
740
|
+
}
|
|
741
|
+
context.report({
|
|
742
|
+
messageId: 'preferClassNameConstant',
|
|
743
|
+
node: classNameProperty.value
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
};
|
|
747
|
+
};
|
|
748
|
+
|
|
749
|
+
const preferClassNameConstants = {
|
|
750
|
+
__proto__: null,
|
|
751
|
+
create: create$c,
|
|
752
|
+
meta: meta$c
|
|
753
|
+
};
|
|
754
|
+
|
|
755
|
+
const meta$b = {
|
|
529
756
|
docs: {
|
|
530
757
|
description: 'Prefer virtual-dom constants over raw type, role, aria boolean, and tabIndex values'
|
|
531
758
|
},
|
|
532
759
|
messages: {
|
|
533
760
|
preferAriaBooleanConstant: 'Use an ARIA boolean constant instead of a raw string.',
|
|
761
|
+
preferEventListenerConstant: 'Use a named event listener constant instead of a raw numeric id.',
|
|
534
762
|
preferRoleConstant: 'Use `AriaRoles.*` instead of a raw role string.',
|
|
535
763
|
preferTabIndexConstant: 'Use `TabIndex.*` instead of a raw tabIndex number.',
|
|
536
764
|
preferTypeConstant: 'Use `VirtualDomElements.*` instead of a raw element type number.'
|
|
@@ -540,7 +768,7 @@ const meta$6 = {
|
|
|
540
768
|
const isAriaBooleanProperty = name => {
|
|
541
769
|
return /^aria[A-Z]/.test(name);
|
|
542
770
|
};
|
|
543
|
-
const create$
|
|
771
|
+
const create$b = context => {
|
|
544
772
|
return {
|
|
545
773
|
ObjectExpression(node) {
|
|
546
774
|
if (!isVirtualDomNode(node)) {
|
|
@@ -575,6 +803,13 @@ const create$6 = context => {
|
|
|
575
803
|
});
|
|
576
804
|
continue;
|
|
577
805
|
}
|
|
806
|
+
if (/^on[A-Z]/.test(name) && isNumericLiteral(property.value)) {
|
|
807
|
+
context.report({
|
|
808
|
+
messageId: 'preferEventListenerConstant',
|
|
809
|
+
node: property.value
|
|
810
|
+
});
|
|
811
|
+
continue;
|
|
812
|
+
}
|
|
578
813
|
if (isAriaBooleanProperty(name) && isStringLiteral(property.value) && (property.value.value === 'true' || property.value.value === 'false')) {
|
|
579
814
|
context.report({
|
|
580
815
|
messageId: 'preferAriaBooleanConstant',
|
|
@@ -588,11 +823,11 @@ const create$6 = context => {
|
|
|
588
823
|
|
|
589
824
|
const preferConstants = {
|
|
590
825
|
__proto__: null,
|
|
591
|
-
create: create$
|
|
592
|
-
meta: meta$
|
|
826
|
+
create: create$b,
|
|
827
|
+
meta: meta$b
|
|
593
828
|
};
|
|
594
829
|
|
|
595
|
-
const meta$
|
|
830
|
+
const meta$a = {
|
|
596
831
|
docs: {
|
|
597
832
|
description: 'Require Intl.DateTimeFormat instances to be created lazily'
|
|
598
833
|
},
|
|
@@ -607,7 +842,7 @@ const isFunctionNode = node => {
|
|
|
607
842
|
const isDateTimeFormat = node => {
|
|
608
843
|
return node.type === 'MemberExpression' && !node.computed && node.object.type === 'Identifier' && node.object.name === 'Intl' && node.property.type === 'Identifier' && node.property.name === 'DateTimeFormat';
|
|
609
844
|
};
|
|
610
|
-
const create$
|
|
845
|
+
const create$a = context => {
|
|
611
846
|
const isCreatedLazily = node => {
|
|
612
847
|
return context.sourceCode.getAncestors(node).some(isFunctionNode);
|
|
613
848
|
};
|
|
@@ -628,8 +863,8 @@ const create$5 = context => {
|
|
|
628
863
|
|
|
629
864
|
const preferLazyDateTimeFormat = {
|
|
630
865
|
__proto__: null,
|
|
631
|
-
create: create$
|
|
632
|
-
meta: meta$
|
|
866
|
+
create: create$a,
|
|
867
|
+
meta: meta$a
|
|
633
868
|
};
|
|
634
869
|
|
|
635
870
|
const isClassNameKey = node => {
|
|
@@ -677,7 +912,7 @@ const getParent = node => {
|
|
|
677
912
|
}
|
|
678
913
|
return undefined;
|
|
679
914
|
};
|
|
680
|
-
const meta$
|
|
915
|
+
const meta$9 = {
|
|
681
916
|
docs: {
|
|
682
917
|
description: 'Prefer mergeClassNames for composing virtual-dom className values'
|
|
683
918
|
},
|
|
@@ -686,7 +921,7 @@ const meta$4 = {
|
|
|
686
921
|
},
|
|
687
922
|
type: 'suggestion'
|
|
688
923
|
};
|
|
689
|
-
const create$
|
|
924
|
+
const create$9 = context => {
|
|
690
925
|
const reportNamespacedClassNameComposition = node => {
|
|
691
926
|
if (!isManualClassNameConcatenation(node) || !hasClassNamesReference(node)) {
|
|
692
927
|
return;
|
|
@@ -717,11 +952,11 @@ const create$4 = context => {
|
|
|
717
952
|
|
|
718
953
|
const preferMergeClassNames = {
|
|
719
954
|
__proto__: null,
|
|
720
|
-
create: create$
|
|
721
|
-
meta: meta$
|
|
955
|
+
create: create$9,
|
|
956
|
+
meta: meta$9
|
|
722
957
|
};
|
|
723
958
|
|
|
724
|
-
const meta$
|
|
959
|
+
const meta$8 = {
|
|
725
960
|
docs: {
|
|
726
961
|
description: 'Prefer destructuring state properties before use'
|
|
727
962
|
},
|
|
@@ -748,7 +983,7 @@ const isWriteExpression = node => {
|
|
|
748
983
|
}
|
|
749
984
|
return parent.type === 'UnaryExpression' && parent.operator === 'delete' && parent.argument === node;
|
|
750
985
|
};
|
|
751
|
-
const create$
|
|
986
|
+
const create$8 = context => {
|
|
752
987
|
return {
|
|
753
988
|
MemberExpression(node) {
|
|
754
989
|
if (node.computed) {
|
|
@@ -776,11 +1011,11 @@ const create$3 = context => {
|
|
|
776
1011
|
|
|
777
1012
|
const preferStateDestructuring = {
|
|
778
1013
|
__proto__: null,
|
|
779
|
-
create: create$
|
|
780
|
-
meta: meta$
|
|
1014
|
+
create: create$8,
|
|
1015
|
+
meta: meta$8
|
|
781
1016
|
};
|
|
782
1017
|
|
|
783
|
-
const meta$
|
|
1018
|
+
const meta$7 = {
|
|
784
1019
|
docs: {
|
|
785
1020
|
description: 'Require event listener options for handlers with specific browser event behavior'
|
|
786
1021
|
},
|
|
@@ -790,7 +1025,7 @@ const meta$2 = {
|
|
|
790
1025
|
type: 'problem'
|
|
791
1026
|
};
|
|
792
1027
|
const listenersRequiringPreventDefault = new Set(['handleDragOver', 'handleDrop']);
|
|
793
|
-
const create$
|
|
1028
|
+
const create$7 = context => {
|
|
794
1029
|
return {
|
|
795
1030
|
ObjectExpression(node) {
|
|
796
1031
|
if (!isObjectExpressionNode(node) || !getProperty(node, 'params')) {
|
|
@@ -817,11 +1052,44 @@ const create$2 = context => {
|
|
|
817
1052
|
|
|
818
1053
|
const requireEventListenerOptions = {
|
|
819
1054
|
__proto__: null,
|
|
820
|
-
create: create$
|
|
821
|
-
meta: meta$
|
|
1055
|
+
create: create$7,
|
|
1056
|
+
meta: meta$7
|
|
822
1057
|
};
|
|
823
1058
|
|
|
824
|
-
const meta$
|
|
1059
|
+
const meta$6 = {
|
|
1060
|
+
docs: {
|
|
1061
|
+
description: 'Require alt text on virtual-dom image nodes'
|
|
1062
|
+
},
|
|
1063
|
+
messages: {
|
|
1064
|
+
requireImageAlt: 'Add an `alt` attribute to this virtual-dom image.'
|
|
1065
|
+
},
|
|
1066
|
+
type: 'problem'
|
|
1067
|
+
};
|
|
1068
|
+
const create$6 = context => {
|
|
1069
|
+
return {
|
|
1070
|
+
ObjectExpression(node) {
|
|
1071
|
+
if (!isVirtualDomNode(node)) {
|
|
1072
|
+
return;
|
|
1073
|
+
}
|
|
1074
|
+
const typeProperty = getProperty(node, 'type');
|
|
1075
|
+
if (!typeProperty || getVirtualDomElementName(typeProperty.value) !== 'Img' || getProperty(node, 'alt')) {
|
|
1076
|
+
return;
|
|
1077
|
+
}
|
|
1078
|
+
context.report({
|
|
1079
|
+
messageId: 'requireImageAlt',
|
|
1080
|
+
node
|
|
1081
|
+
});
|
|
1082
|
+
}
|
|
1083
|
+
};
|
|
1084
|
+
};
|
|
1085
|
+
|
|
1086
|
+
const requireImageAlt = {
|
|
1087
|
+
__proto__: null,
|
|
1088
|
+
create: create$6,
|
|
1089
|
+
meta: meta$6
|
|
1090
|
+
};
|
|
1091
|
+
|
|
1092
|
+
const meta$5 = {
|
|
825
1093
|
docs: {
|
|
826
1094
|
description: 'Require secure attributes on virtual-dom links'
|
|
827
1095
|
},
|
|
@@ -835,7 +1103,7 @@ const hasStringPropertyValue = (node, name, value) => {
|
|
|
835
1103
|
const property = getProperty(node, name);
|
|
836
1104
|
return Boolean(property && isStringLiteral(property.value) && property.value.value === value);
|
|
837
1105
|
};
|
|
838
|
-
const create$
|
|
1106
|
+
const create$5 = context => {
|
|
839
1107
|
return {
|
|
840
1108
|
ObjectExpression(node) {
|
|
841
1109
|
if (!isVirtualDomNode(node)) {
|
|
@@ -864,11 +1132,97 @@ const create$1 = context => {
|
|
|
864
1132
|
|
|
865
1133
|
const secureLinks = {
|
|
866
1134
|
__proto__: null,
|
|
867
|
-
create: create$
|
|
868
|
-
meta: meta$
|
|
1135
|
+
create: create$5,
|
|
1136
|
+
meta: meta$5
|
|
869
1137
|
};
|
|
870
1138
|
|
|
871
|
-
const
|
|
1139
|
+
const validAriaProperties = new Set(['ariaActivedescendant', 'ariaAtomic', 'ariaAutoComplete', 'ariaBrailleLabel', 'ariaBrailleRoleDescription', 'ariaBusy', 'ariaChecked', 'ariaColCount', 'ariaColIndex', 'ariaColIndexText', 'ariaColSpan', 'ariaControls', 'ariaCurrent', 'ariaDescribedBy', 'ariaDescription', 'ariaDetails', 'ariaDisabled', 'ariaErrorMessage', 'ariaExpanded', 'ariaFlowTo', 'ariaHasPopup', 'ariaHidden', 'ariaInvalid', 'ariaKeyShortcuts', 'ariaLabel', 'ariaLabelledBy', 'ariaLevel', 'ariaLive', 'ariaModal', 'ariaMultiLine', 'ariaMultiSelectable', 'ariaOrientation', 'ariaOwns', 'ariaPlaceholder', 'ariaPosInSet', 'ariaPressed', 'ariaReadOnly', 'ariaRelevant', 'ariaRequired', 'ariaRoleDescription', 'ariaRowCount', 'ariaRowIndex', 'ariaRowIndexText', 'ariaRowSpan', 'ariaSelected', 'ariaSetSize', 'ariaSort', 'ariaValueMax', 'ariaValueMin', 'ariaValueNow', 'ariaValueText']);
|
|
1140
|
+
const meta$4 = {
|
|
1141
|
+
docs: {
|
|
1142
|
+
description: 'Validate virtual-dom ARIA property names'
|
|
1143
|
+
},
|
|
1144
|
+
messages: {
|
|
1145
|
+
validAriaProperty: '`{{name}}` is not a valid virtual-dom ARIA property.'
|
|
1146
|
+
},
|
|
1147
|
+
type: 'problem'
|
|
1148
|
+
};
|
|
1149
|
+
const create$4 = context => {
|
|
1150
|
+
return {
|
|
1151
|
+
ObjectExpression(node) {
|
|
1152
|
+
if (!isVirtualDomNode(node)) {
|
|
1153
|
+
return;
|
|
1154
|
+
}
|
|
1155
|
+
for (const property of node.properties) {
|
|
1156
|
+
if (!isPropertyNode(property)) {
|
|
1157
|
+
continue;
|
|
1158
|
+
}
|
|
1159
|
+
const name = getStaticPropertyName(property);
|
|
1160
|
+
if (!name?.startsWith('aria') || validAriaProperties.has(name)) {
|
|
1161
|
+
continue;
|
|
1162
|
+
}
|
|
1163
|
+
context.report({
|
|
1164
|
+
data: {
|
|
1165
|
+
name
|
|
1166
|
+
},
|
|
1167
|
+
messageId: 'validAriaProperty',
|
|
1168
|
+
node: property
|
|
1169
|
+
});
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
};
|
|
1173
|
+
};
|
|
1174
|
+
|
|
1175
|
+
const validAriaProperties$1 = {
|
|
1176
|
+
__proto__: null,
|
|
1177
|
+
create: create$4,
|
|
1178
|
+
meta: meta$4
|
|
1179
|
+
};
|
|
1180
|
+
|
|
1181
|
+
const allowedValues = new Map([['ariaAtomic', new Set(['false', 'true'])], ['ariaAutoComplete', new Set(['both', 'inline', 'list', 'none'])], ['ariaBusy', new Set(['false', 'true'])], ['ariaChecked', new Set(['false', 'mixed', 'true'])], ['ariaCurrent', new Set(['date', 'false', 'location', 'page', 'step', 'time', 'true'])], ['ariaDisabled', new Set(['false', 'true'])], ['ariaExpanded', new Set(['false', 'true'])], ['ariaHasPopup', new Set(['dialog', 'false', 'grid', 'listbox', 'menu', 'tree', 'true'])], ['ariaHidden', new Set(['false', 'true'])], ['ariaInvalid', new Set(['false', 'grammar', 'spelling', 'true'])], ['ariaLive', new Set(['assertive', 'off', 'polite'])], ['ariaModal', new Set(['false', 'true'])], ['ariaMultiLine', new Set(['false', 'true'])], ['ariaMultiSelectable', new Set(['false', 'true'])], ['ariaOrientation', new Set(['horizontal', 'undefined', 'vertical'])], ['ariaPressed', new Set(['false', 'mixed', 'true'])], ['ariaReadOnly', new Set(['false', 'true'])], ['ariaRelevant', new Set(['additions', 'additions removals', 'additions text', 'all', 'removals', 'removals additions', 'removals text', 'text', 'text additions', 'text removals'])], ['ariaRequired', new Set(['false', 'true'])], ['ariaSelected', new Set(['false', 'true'])], ['ariaSort', new Set(['ascending', 'descending', 'none', 'other'])]]);
|
|
1182
|
+
const meta$3 = {
|
|
1183
|
+
docs: {
|
|
1184
|
+
description: 'Validate literal virtual-dom ARIA values'
|
|
1185
|
+
},
|
|
1186
|
+
messages: {
|
|
1187
|
+
validAriaValue: '`{{value}}` is not a valid value for `{{name}}`.'
|
|
1188
|
+
},
|
|
1189
|
+
type: 'problem'
|
|
1190
|
+
};
|
|
1191
|
+
const create$3 = context => {
|
|
1192
|
+
return {
|
|
1193
|
+
ObjectExpression(node) {
|
|
1194
|
+
if (!isVirtualDomNode(node)) {
|
|
1195
|
+
return;
|
|
1196
|
+
}
|
|
1197
|
+
for (const property of node.properties) {
|
|
1198
|
+
if (!isPropertyNode(property)) {
|
|
1199
|
+
continue;
|
|
1200
|
+
}
|
|
1201
|
+
const name = getStaticPropertyName(property);
|
|
1202
|
+
const values = name && allowedValues.get(name);
|
|
1203
|
+
if (!name || !values || !isStringLiteral(property.value) || values.has(property.value.value)) {
|
|
1204
|
+
continue;
|
|
1205
|
+
}
|
|
1206
|
+
context.report({
|
|
1207
|
+
data: {
|
|
1208
|
+
name,
|
|
1209
|
+
value: property.value.value
|
|
1210
|
+
},
|
|
1211
|
+
messageId: 'validAriaValue',
|
|
1212
|
+
node: property.value
|
|
1213
|
+
});
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
};
|
|
1217
|
+
};
|
|
1218
|
+
|
|
1219
|
+
const validAriaValues = {
|
|
1220
|
+
__proto__: null,
|
|
1221
|
+
create: create$3,
|
|
1222
|
+
meta: meta$3
|
|
1223
|
+
};
|
|
1224
|
+
|
|
1225
|
+
const meta$2 = {
|
|
872
1226
|
docs: {
|
|
873
1227
|
description: 'Validate statically analyzable virtual-dom childCount values'
|
|
874
1228
|
},
|
|
@@ -943,7 +1297,7 @@ const hasImpossibleChildCount = (elements, index) => {
|
|
|
943
1297
|
}
|
|
944
1298
|
return false;
|
|
945
1299
|
};
|
|
946
|
-
const create = context => {
|
|
1300
|
+
const create$2 = context => {
|
|
947
1301
|
return {
|
|
948
1302
|
ArrayExpression(node) {
|
|
949
1303
|
if (!isArrayExpressionNode(node) || !node.elements.some(isVirtualDomNode) || !node.elements.every(isAnalyzableVirtualDomElement)) {
|
|
@@ -972,6 +1326,103 @@ const create = context => {
|
|
|
972
1326
|
};
|
|
973
1327
|
|
|
974
1328
|
const validChildCount = {
|
|
1329
|
+
__proto__: null,
|
|
1330
|
+
create: create$2,
|
|
1331
|
+
meta: meta$2
|
|
1332
|
+
};
|
|
1333
|
+
|
|
1334
|
+
const supportedEventProperties = new Set(['onBeforeInput', 'onBlur', 'onChange', 'onClick', 'onContextMenu', 'onDblClick', 'onDragEnd', 'onDragEnter', 'onDragLeave', 'onDragOver', 'onDragStart', 'onDrop', 'onFocus', 'onFocusIn', 'onFocusOut', 'onInput', 'onKeyDown', 'onKeyUp', 'onMouseDown', 'onMouseMove', 'onMouseOut', 'onMouseOver', 'onMouseUp', 'onPointerDown', 'onPointerMove', 'onPointerOut', 'onPointerOver', 'onScroll', 'onSelectionChange', 'onSubmit', 'onWheel']);
|
|
1335
|
+
const meta$1 = {
|
|
1336
|
+
docs: {
|
|
1337
|
+
description: 'Require virtual-dom event properties supported by the renderer'
|
|
1338
|
+
},
|
|
1339
|
+
messages: {
|
|
1340
|
+
validEventProperty: '`{{name}}` is not a supported virtual-dom event property.'
|
|
1341
|
+
},
|
|
1342
|
+
type: 'problem'
|
|
1343
|
+
};
|
|
1344
|
+
const create$1 = context => {
|
|
1345
|
+
return {
|
|
1346
|
+
ObjectExpression(node) {
|
|
1347
|
+
if (!isVirtualDomNode(node)) {
|
|
1348
|
+
return;
|
|
1349
|
+
}
|
|
1350
|
+
for (const property of node.properties) {
|
|
1351
|
+
if (!isPropertyNode(property)) {
|
|
1352
|
+
continue;
|
|
1353
|
+
}
|
|
1354
|
+
const name = getStaticPropertyName(property);
|
|
1355
|
+
if (!name?.startsWith('on') || supportedEventProperties.has(name)) {
|
|
1356
|
+
continue;
|
|
1357
|
+
}
|
|
1358
|
+
context.report({
|
|
1359
|
+
data: {
|
|
1360
|
+
name
|
|
1361
|
+
},
|
|
1362
|
+
messageId: 'validEventProperty',
|
|
1363
|
+
node: property
|
|
1364
|
+
});
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
};
|
|
1368
|
+
};
|
|
1369
|
+
|
|
1370
|
+
const validEventProperties = {
|
|
1371
|
+
__proto__: null,
|
|
1372
|
+
create: create$1,
|
|
1373
|
+
meta: meta$1
|
|
1374
|
+
};
|
|
1375
|
+
|
|
1376
|
+
const voidElements = new Set(['Br', 'Col', 'Hr', 'Img', 'Input']);
|
|
1377
|
+
const meta = {
|
|
1378
|
+
docs: {
|
|
1379
|
+
description: 'Require canonical virtual-dom node shapes'
|
|
1380
|
+
},
|
|
1381
|
+
messages: {
|
|
1382
|
+
elementTextProperty: 'Use a `text(...)` child instead of a `text` property on an element node.',
|
|
1383
|
+
missingChildCount: 'Add an explicit `childCount` to this virtual-dom node.',
|
|
1384
|
+
voidElementChildren: '`VirtualDomElements.{{name}}` must have a `childCount` of 0.'
|
|
1385
|
+
},
|
|
1386
|
+
type: 'problem'
|
|
1387
|
+
};
|
|
1388
|
+
const create = context => {
|
|
1389
|
+
return {
|
|
1390
|
+
ObjectExpression(node) {
|
|
1391
|
+
if (!isObjectExpressionNode(node)) {
|
|
1392
|
+
return;
|
|
1393
|
+
}
|
|
1394
|
+
const typeProperty = getProperty(node, 'type');
|
|
1395
|
+
const elementName = typeProperty && getVirtualDomElementName(typeProperty.value);
|
|
1396
|
+
if (!typeProperty || !elementName) {
|
|
1397
|
+
return;
|
|
1398
|
+
}
|
|
1399
|
+
const childCountProperty = getProperty(node, 'childCount');
|
|
1400
|
+
if (!childCountProperty) {
|
|
1401
|
+
context.report({
|
|
1402
|
+
messageId: 'missingChildCount',
|
|
1403
|
+
node
|
|
1404
|
+
});
|
|
1405
|
+
} else if (voidElements.has(elementName) && getStaticNumberValue(childCountProperty.value) !== 0) {
|
|
1406
|
+
context.report({
|
|
1407
|
+
data: {
|
|
1408
|
+
name: elementName
|
|
1409
|
+
},
|
|
1410
|
+
messageId: 'voidElementChildren',
|
|
1411
|
+
node: childCountProperty
|
|
1412
|
+
});
|
|
1413
|
+
}
|
|
1414
|
+
const textProperty = getProperty(node, 'text');
|
|
1415
|
+
if (textProperty && elementName !== 'Text') {
|
|
1416
|
+
context.report({
|
|
1417
|
+
messageId: 'elementTextProperty',
|
|
1418
|
+
node: textProperty
|
|
1419
|
+
});
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
};
|
|
1423
|
+
};
|
|
1424
|
+
|
|
1425
|
+
const validNodeShape = {
|
|
975
1426
|
__proto__: null,
|
|
976
1427
|
create,
|
|
977
1428
|
meta
|
|
@@ -984,22 +1435,32 @@ const plugin = {
|
|
|
984
1435
|
version: '0.0.1'
|
|
985
1436
|
},
|
|
986
1437
|
rules: {
|
|
1438
|
+
'accessible-control-name': accessibleControlName,
|
|
987
1439
|
'clickable-div-needs-role': clickableDivNeedsRole,
|
|
988
1440
|
'hoist-static-nodes': hoistStaticNodes,
|
|
1441
|
+
'no-conditional-spread': noConditionalSpread,
|
|
989
1442
|
'no-empty-aria': noEmptyAria,
|
|
990
1443
|
'no-empty-class-name': noEmptyClassName,
|
|
991
1444
|
'no-inline-event-handlers': noInlineEventHandlers,
|
|
992
1445
|
'no-inline-style': noInlineStyle,
|
|
1446
|
+
'no-nullish-attribute-values': noNullishAttributeValues,
|
|
993
1447
|
'no-object-attribute-values': noObjectAttributeValues,
|
|
1448
|
+
'no-positive-tab-index': noPositiveTabIndex,
|
|
994
1449
|
'no-raw-text-children': noRawTextChildren,
|
|
995
1450
|
'no-shared-event-listener-handlers': noSharedEventListenerHandlers,
|
|
1451
|
+
'prefer-class-name-constants': preferClassNameConstants,
|
|
996
1452
|
'prefer-constants': preferConstants,
|
|
997
1453
|
'prefer-lazy-date-time-format': preferLazyDateTimeFormat,
|
|
998
1454
|
'prefer-merge-class-names': preferMergeClassNames,
|
|
999
1455
|
'prefer-state-destructuring': preferStateDestructuring,
|
|
1000
1456
|
'require-event-listener-options': requireEventListenerOptions,
|
|
1457
|
+
'require-image-alt': requireImageAlt,
|
|
1001
1458
|
'secure-links': secureLinks,
|
|
1002
|
-
'valid-
|
|
1459
|
+
'valid-aria-properties': validAriaProperties$1,
|
|
1460
|
+
'valid-aria-values': validAriaValues,
|
|
1461
|
+
'valid-child-count': validChildCount,
|
|
1462
|
+
'valid-event-properties': validEventProperties,
|
|
1463
|
+
'valid-node-shape': validNodeShape
|
|
1003
1464
|
}
|
|
1004
1465
|
};
|
|
1005
1466
|
const recommended = [{
|
|
@@ -1010,6 +1471,7 @@ const recommended = [{
|
|
|
1010
1471
|
rules: {
|
|
1011
1472
|
'virtual-dom/clickable-div-needs-role': 'error',
|
|
1012
1473
|
'virtual-dom/hoist-static-nodes': 'error',
|
|
1474
|
+
'virtual-dom/no-conditional-spread': 'error',
|
|
1013
1475
|
'virtual-dom/no-empty-aria': 'error',
|
|
1014
1476
|
'virtual-dom/no-empty-class-name': 'error',
|
|
1015
1477
|
'virtual-dom/no-inline-event-handlers': 'error',
|
|
@@ -1031,5 +1493,24 @@ const recommended = [{
|
|
|
1031
1493
|
'virtual-dom/hoist-static-nodes': 'off'
|
|
1032
1494
|
}
|
|
1033
1495
|
}];
|
|
1496
|
+
const strict = [...recommended, {
|
|
1497
|
+
files: ['**/*.{js,mjs,cjs,ts,mts,cts}'],
|
|
1498
|
+
rules: {
|
|
1499
|
+
'virtual-dom/accessible-control-name': 'error',
|
|
1500
|
+
'virtual-dom/no-nullish-attribute-values': 'error',
|
|
1501
|
+
'virtual-dom/no-positive-tab-index': 'error',
|
|
1502
|
+
'virtual-dom/prefer-class-name-constants': 'error',
|
|
1503
|
+
'virtual-dom/require-image-alt': 'error',
|
|
1504
|
+
'virtual-dom/valid-aria-properties': 'error',
|
|
1505
|
+
'virtual-dom/valid-aria-values': 'error',
|
|
1506
|
+
'virtual-dom/valid-event-properties': 'error',
|
|
1507
|
+
'virtual-dom/valid-node-shape': 'error'
|
|
1508
|
+
}
|
|
1509
|
+
}, {
|
|
1510
|
+
files: ['**/test/**/*.{js,mjs,cjs,ts,mts,cts}', '**/tests/**/*.{js,mjs,cjs,ts,mts,cts}', '**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts}'],
|
|
1511
|
+
rules: {
|
|
1512
|
+
'virtual-dom/prefer-class-name-constants': 'off'
|
|
1513
|
+
}
|
|
1514
|
+
}];
|
|
1034
1515
|
|
|
1035
|
-
export { recommended as default };
|
|
1516
|
+
export { recommended as default, strict };
|