eslint-plugin-vuetify 2.0.0-beta.0 → 2.0.0-beta.2
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/README.md +2 -0
- package/lib/configs/base.js +1 -0
- package/lib/rules/grid-unknown-attributes.js +1 -1
- package/lib/rules/no-deprecated-classes.js +2 -2
- package/lib/rules/no-deprecated-components.js +1 -0
- package/lib/rules/no-deprecated-events.js +209 -0
- package/lib/rules/no-deprecated-props.js +45 -32
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -42,6 +42,7 @@ These rules will help you avoid deprecated components, props, and classes. They
|
|
|
42
42
|
|
|
43
43
|
- Prevent the use of components that have been removed from Vuetify ([`no-deprecated-components`])
|
|
44
44
|
- Prevent the use of props that have been removed from Vuetify ([`no-deprecated-props`])
|
|
45
|
+
- Prevent the use of events that have been removed from Vuetify ([`no-deprecated-events`])
|
|
45
46
|
- Prevent the use of classes that have been removed from Vuetify ([`no-deprecated-classes`])
|
|
46
47
|
- Prevent the use of the old theme class syntax ([`no-deprecated-colors`])
|
|
47
48
|
|
|
@@ -55,6 +56,7 @@ These rules are designed to help migrate to the new grid system in Vuetify v2. T
|
|
|
55
56
|
[`grid-unknown-attributes`]: ./docs/rules/grid-unknown-attributes.md
|
|
56
57
|
[`no-deprecated-components`]: ./docs/rules/no-deprecated-components.md
|
|
57
58
|
[`no-deprecated-props`]: ./docs/rules/no-deprecated-props.md
|
|
59
|
+
[`no-deprecated-events`]: ./docs/rules/no-deprecated-events.md
|
|
58
60
|
[`no-deprecated-classes`]: ./docs/rules/no-deprecated-classes.md
|
|
59
61
|
[`no-deprecated-colors`]: ./docs/rules/no-deprecated-colors.md
|
|
60
62
|
|
package/lib/configs/base.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
/** @type {Map<RegExp, (args: string[]) => string> | Map<string, string>} */
|
|
4
|
-
const replacements = new Map([[/^rounded-(r|l|tr|tl|br|bl)(
|
|
4
|
+
const replacements = new Map([[/^rounded-(r|l|tr|tl|br|bl)(-.*)?$/, ([side, rest]) => {
|
|
5
5
|
side = {
|
|
6
6
|
r: 'e',
|
|
7
7
|
l: 's',
|
|
@@ -10,7 +10,7 @@ const replacements = new Map([[/^rounded-(r|l|tr|tl|br|bl)(.*)$/, ([side, rest])
|
|
|
10
10
|
br: 'be',
|
|
11
11
|
bl: 'bs'
|
|
12
12
|
}[side];
|
|
13
|
-
return `rounded-${side}${rest}`;
|
|
13
|
+
return `rounded-${side}${rest || ''}`;
|
|
14
14
|
}], [/^border-([rl])(.*)$/, ([side, rest]) => {
|
|
15
15
|
side = {
|
|
16
16
|
r: 'e',
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
hyphenate,
|
|
5
|
+
classify
|
|
6
|
+
} = require('../util/helpers');
|
|
7
|
+
const model = {
|
|
8
|
+
input: 'update:modelValue'
|
|
9
|
+
};
|
|
10
|
+
const inputs = {
|
|
11
|
+
...model,
|
|
12
|
+
'click:appendOuter': 'click:append',
|
|
13
|
+
'update:error': false
|
|
14
|
+
};
|
|
15
|
+
const combobox = {
|
|
16
|
+
...inputs,
|
|
17
|
+
'update:searchInput': 'update:search',
|
|
18
|
+
'update:listIndex': false
|
|
19
|
+
};
|
|
20
|
+
const replacements = {
|
|
21
|
+
VTextField: inputs,
|
|
22
|
+
VTextarea: inputs,
|
|
23
|
+
VFileInput: inputs,
|
|
24
|
+
VCombobox: {
|
|
25
|
+
...combobox,
|
|
26
|
+
change: false
|
|
27
|
+
},
|
|
28
|
+
VAutocomplete: {
|
|
29
|
+
...combobox,
|
|
30
|
+
change: 'update:modelValue'
|
|
31
|
+
},
|
|
32
|
+
VSelect: {
|
|
33
|
+
...combobox,
|
|
34
|
+
change: 'update:modelValue'
|
|
35
|
+
},
|
|
36
|
+
VAlert: model,
|
|
37
|
+
VTabs: {
|
|
38
|
+
...model,
|
|
39
|
+
'call:slider': false,
|
|
40
|
+
change: 'update:modelValue',
|
|
41
|
+
next: false,
|
|
42
|
+
prev: false
|
|
43
|
+
},
|
|
44
|
+
VTab: {
|
|
45
|
+
change: 'group:selected'
|
|
46
|
+
},
|
|
47
|
+
VBottomNavigation: {
|
|
48
|
+
change: 'update:modelValue',
|
|
49
|
+
'update:inputValue': false
|
|
50
|
+
},
|
|
51
|
+
VBtn: {
|
|
52
|
+
change: 'group:selected'
|
|
53
|
+
},
|
|
54
|
+
VBtnToggle: {
|
|
55
|
+
change: 'update:modelValue'
|
|
56
|
+
},
|
|
57
|
+
VCarousel: {
|
|
58
|
+
change: 'update:modelValue'
|
|
59
|
+
},
|
|
60
|
+
VCheckbox: {
|
|
61
|
+
change: 'update:modelValue',
|
|
62
|
+
'update:error': false
|
|
63
|
+
},
|
|
64
|
+
VChip: {
|
|
65
|
+
...model,
|
|
66
|
+
'update:active': 'update:modelValue'
|
|
67
|
+
},
|
|
68
|
+
VChipGroup: {
|
|
69
|
+
change: 'update:modelValue'
|
|
70
|
+
},
|
|
71
|
+
VColorPicker: {
|
|
72
|
+
...model,
|
|
73
|
+
'update:color': 'update:modelValue'
|
|
74
|
+
},
|
|
75
|
+
VDialog: {
|
|
76
|
+
...model,
|
|
77
|
+
'update:returnValue': false
|
|
78
|
+
},
|
|
79
|
+
VExpansionPanels: {
|
|
80
|
+
change: 'update:modelValue'
|
|
81
|
+
},
|
|
82
|
+
VExpansionPanel: {
|
|
83
|
+
change: 'group:selected'
|
|
84
|
+
},
|
|
85
|
+
VForm: {
|
|
86
|
+
input: 'update:modelValue'
|
|
87
|
+
},
|
|
88
|
+
VHover: model,
|
|
89
|
+
VItemGroup: {
|
|
90
|
+
change: 'update:modelValue'
|
|
91
|
+
},
|
|
92
|
+
VMenu: {
|
|
93
|
+
...model,
|
|
94
|
+
'update:returnValue': false
|
|
95
|
+
},
|
|
96
|
+
VNavigationDrawer: {
|
|
97
|
+
...model,
|
|
98
|
+
'update:miniVariant': false
|
|
99
|
+
},
|
|
100
|
+
VPagination: {
|
|
101
|
+
...model,
|
|
102
|
+
previous: 'prev'
|
|
103
|
+
},
|
|
104
|
+
VProgressLinear: {
|
|
105
|
+
change: 'update:modelValue'
|
|
106
|
+
},
|
|
107
|
+
VRadioGroup: {
|
|
108
|
+
change: 'update:modelValue',
|
|
109
|
+
'update:error': false
|
|
110
|
+
},
|
|
111
|
+
VRadio: {
|
|
112
|
+
change: 'update:modelValue',
|
|
113
|
+
'update:error': false
|
|
114
|
+
},
|
|
115
|
+
VRangeSlider: {
|
|
116
|
+
...model,
|
|
117
|
+
change: false,
|
|
118
|
+
'update:error': false,
|
|
119
|
+
start: false,
|
|
120
|
+
end: false
|
|
121
|
+
},
|
|
122
|
+
VRating: model,
|
|
123
|
+
VSlider: {
|
|
124
|
+
...model,
|
|
125
|
+
change: false,
|
|
126
|
+
'update:error': false,
|
|
127
|
+
start: false,
|
|
128
|
+
end: false
|
|
129
|
+
},
|
|
130
|
+
VSlideGroup: {
|
|
131
|
+
change: 'update:modelValue',
|
|
132
|
+
next: false,
|
|
133
|
+
prev: false
|
|
134
|
+
},
|
|
135
|
+
VSnackbar: model,
|
|
136
|
+
VSwitch: {
|
|
137
|
+
change: 'update:modelValue',
|
|
138
|
+
'update:error': false
|
|
139
|
+
},
|
|
140
|
+
VWindow: {
|
|
141
|
+
change: 'update:modelValue'
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
// ------------------------------------------------------------------------------
|
|
146
|
+
// Rule Definition
|
|
147
|
+
// ------------------------------------------------------------------------------
|
|
148
|
+
|
|
149
|
+
module.exports = {
|
|
150
|
+
meta: {
|
|
151
|
+
docs: {
|
|
152
|
+
description: 'Prevent the use of removed and deprecated events.',
|
|
153
|
+
category: 'recommended'
|
|
154
|
+
},
|
|
155
|
+
fixable: 'code',
|
|
156
|
+
schema: [],
|
|
157
|
+
messages: {
|
|
158
|
+
replacedWith: `{{ tag }}: @{{ a }} has been replaced with @{{ b }}`,
|
|
159
|
+
removed: `{{ tag }}: @{{ name }} has been removed`
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
create(context) {
|
|
163
|
+
return context.parserServices.defineTemplateBodyVisitor({
|
|
164
|
+
VAttribute(attr) {
|
|
165
|
+
if (!(attr.directive && attr.key.name.name === 'on' && attr.key.argument?.type === 'VIdentifier')) return;
|
|
166
|
+
const tag = classify(attr.parent.parent.rawName);
|
|
167
|
+
if (!Object.keys(replacements).includes(tag)) return;
|
|
168
|
+
const eventNameNode = attr.key.argument;
|
|
169
|
+
const eventName = hyphenate(eventNameNode.rawName);
|
|
170
|
+
Object.entries(replacements[tag]).forEach(([test, replace]) => {
|
|
171
|
+
if (hyphenate(test) === eventName) {
|
|
172
|
+
if (replace === false) {
|
|
173
|
+
context.report({
|
|
174
|
+
messageId: 'removed',
|
|
175
|
+
data: {
|
|
176
|
+
tag,
|
|
177
|
+
name: eventName
|
|
178
|
+
},
|
|
179
|
+
node: eventNameNode
|
|
180
|
+
});
|
|
181
|
+
} else if (typeof replace === 'string') {
|
|
182
|
+
context.report({
|
|
183
|
+
messageId: 'replacedWith',
|
|
184
|
+
data: {
|
|
185
|
+
tag,
|
|
186
|
+
a: eventName,
|
|
187
|
+
b: replace
|
|
188
|
+
},
|
|
189
|
+
node: eventNameNode,
|
|
190
|
+
fix(fixer) {
|
|
191
|
+
return fixer.replaceText(eventNameNode, hyphenate(replace));
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
} else if (typeof replace === 'object' && 'custom' in replace) {
|
|
195
|
+
context.report({
|
|
196
|
+
messageId: 'replacedWith',
|
|
197
|
+
data: {
|
|
198
|
+
a: eventName,
|
|
199
|
+
b: replace.custom
|
|
200
|
+
},
|
|
201
|
+
node: eventNameNode
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
};
|
|
@@ -107,13 +107,11 @@ const link = {
|
|
|
107
107
|
const overlay = {
|
|
108
108
|
hideOverlay: {
|
|
109
109
|
name: 'scrim',
|
|
110
|
+
bind: true,
|
|
110
111
|
value: false
|
|
111
112
|
},
|
|
112
113
|
internalActivator: false,
|
|
113
|
-
overlayColor:
|
|
114
|
-
name: 'scrim',
|
|
115
|
-
value: value => value
|
|
116
|
-
},
|
|
114
|
+
overlayColor: 'scrim',
|
|
117
115
|
overlayOpacity: false,
|
|
118
116
|
value: 'model-value',
|
|
119
117
|
returnValue: false
|
|
@@ -148,7 +146,7 @@ const replacements = {
|
|
|
148
146
|
value: value => ({
|
|
149
147
|
right: 'end',
|
|
150
148
|
left: 'start'
|
|
151
|
-
})[value]
|
|
149
|
+
})[value] || value
|
|
152
150
|
},
|
|
153
151
|
outline: {
|
|
154
152
|
name: 'variant',
|
|
@@ -202,10 +200,11 @@ const replacements = {
|
|
|
202
200
|
app: false,
|
|
203
201
|
fixed: false,
|
|
204
202
|
hideOnScroll: false,
|
|
205
|
-
inputValue:
|
|
203
|
+
inputValue: false,
|
|
206
204
|
scrollTarget: false,
|
|
207
205
|
scrollThreshold: false,
|
|
208
206
|
width: false,
|
|
207
|
+
value: 'model-value',
|
|
209
208
|
...size
|
|
210
209
|
},
|
|
211
210
|
VBreadcrumbs: {
|
|
@@ -225,7 +224,7 @@ const replacements = {
|
|
|
225
224
|
},
|
|
226
225
|
depressed: {
|
|
227
226
|
name: 'variant',
|
|
228
|
-
value: '
|
|
227
|
+
value: 'flat'
|
|
229
228
|
},
|
|
230
229
|
fab: false,
|
|
231
230
|
flat: {
|
|
@@ -354,7 +353,7 @@ const replacements = {
|
|
|
354
353
|
},
|
|
355
354
|
VChip: {
|
|
356
355
|
active: false,
|
|
357
|
-
close: '
|
|
356
|
+
close: 'closable',
|
|
358
357
|
inputValue: 'model-value',
|
|
359
358
|
outline: {
|
|
360
359
|
name: 'variant',
|
|
@@ -420,14 +419,17 @@ const replacements = {
|
|
|
420
419
|
allowOverflow: false,
|
|
421
420
|
auto: false,
|
|
422
421
|
bottom: {
|
|
423
|
-
|
|
422
|
+
name: 'location',
|
|
423
|
+
value: 'bottom'
|
|
424
424
|
},
|
|
425
425
|
closeOnClick: {
|
|
426
426
|
name: 'persistent',
|
|
427
|
-
|
|
427
|
+
bind: true,
|
|
428
|
+
value: value => value ? `!(${value})` : false
|
|
428
429
|
},
|
|
429
430
|
left: {
|
|
430
|
-
|
|
431
|
+
name: 'location',
|
|
432
|
+
value: 'left'
|
|
431
433
|
},
|
|
432
434
|
nudgeBottom: {
|
|
433
435
|
custom: 'offset'
|
|
@@ -447,12 +449,14 @@ const replacements = {
|
|
|
447
449
|
positionX: false,
|
|
448
450
|
positionY: false,
|
|
449
451
|
right: {
|
|
450
|
-
|
|
452
|
+
name: 'location',
|
|
453
|
+
value: 'right'
|
|
451
454
|
},
|
|
452
455
|
rounded: false,
|
|
453
456
|
tile: false,
|
|
454
457
|
top: {
|
|
455
|
-
|
|
458
|
+
name: 'location',
|
|
459
|
+
value: 'top'
|
|
456
460
|
},
|
|
457
461
|
value: 'model-value',
|
|
458
462
|
...overlay
|
|
@@ -476,7 +480,8 @@ const replacements = {
|
|
|
476
480
|
dense: false,
|
|
477
481
|
disabled: false,
|
|
478
482
|
left: 'start',
|
|
479
|
-
right: 'end'
|
|
483
|
+
right: 'end',
|
|
484
|
+
...sizes
|
|
480
485
|
},
|
|
481
486
|
VImg: {
|
|
482
487
|
contain: {
|
|
@@ -553,15 +558,13 @@ const replacements = {
|
|
|
553
558
|
height: false,
|
|
554
559
|
hideOverlay: {
|
|
555
560
|
name: 'scrim',
|
|
561
|
+
bind: true,
|
|
556
562
|
value: false
|
|
557
563
|
},
|
|
558
564
|
miniVariant: 'rail',
|
|
559
565
|
miniVariantWidth: 'rail-width',
|
|
560
566
|
mobileBreakPoint: false,
|
|
561
|
-
overlayColor:
|
|
562
|
-
name: 'scrim',
|
|
563
|
-
value: value => value
|
|
564
|
-
},
|
|
567
|
+
overlayColor: 'scrim',
|
|
565
568
|
overlayOpacity: false,
|
|
566
569
|
right: {
|
|
567
570
|
name: 'location',
|
|
@@ -572,10 +575,7 @@ const replacements = {
|
|
|
572
575
|
value: 'model-value'
|
|
573
576
|
},
|
|
574
577
|
VOverlay: {
|
|
575
|
-
color:
|
|
576
|
-
name: 'scrim',
|
|
577
|
-
value: value => value
|
|
578
|
-
},
|
|
578
|
+
color: 'scrim',
|
|
579
579
|
opacity: false,
|
|
580
580
|
value: 'model-value'
|
|
581
581
|
},
|
|
@@ -599,6 +599,7 @@ const replacements = {
|
|
|
599
599
|
value: 'model-value'
|
|
600
600
|
},
|
|
601
601
|
VRadio: {
|
|
602
|
+
inputValue: 'model-value',
|
|
602
603
|
activeClass: 'false',
|
|
603
604
|
offIcon: 'false-icon',
|
|
604
605
|
onIcon: 'true-icon',
|
|
@@ -698,7 +699,8 @@ const replacements = {
|
|
|
698
699
|
value: 'model-value'
|
|
699
700
|
},
|
|
700
701
|
VSwitch: {
|
|
701
|
-
...inputs
|
|
702
|
+
...inputs,
|
|
703
|
+
value: undefined
|
|
702
704
|
},
|
|
703
705
|
VSystemBar: {
|
|
704
706
|
app: false,
|
|
@@ -754,14 +756,16 @@ const replacements = {
|
|
|
754
756
|
VTooltip: {
|
|
755
757
|
allowOverflow: false,
|
|
756
758
|
bottom: {
|
|
757
|
-
|
|
759
|
+
name: 'location',
|
|
760
|
+
value: 'bottom'
|
|
758
761
|
},
|
|
759
762
|
closeOnClick: {
|
|
760
763
|
name: 'persistent',
|
|
761
764
|
value: true
|
|
762
765
|
},
|
|
763
766
|
left: {
|
|
764
|
-
|
|
767
|
+
name: 'location',
|
|
768
|
+
value: 'left'
|
|
765
769
|
},
|
|
766
770
|
nudgeBottom: {
|
|
767
771
|
custom: 'offset'
|
|
@@ -778,10 +782,12 @@ const replacements = {
|
|
|
778
782
|
positionX: false,
|
|
779
783
|
positionY: false,
|
|
780
784
|
right: {
|
|
781
|
-
|
|
785
|
+
name: 'location',
|
|
786
|
+
value: 'right'
|
|
782
787
|
},
|
|
783
788
|
top: {
|
|
784
|
-
|
|
789
|
+
name: 'location',
|
|
790
|
+
value: 'top'
|
|
785
791
|
},
|
|
786
792
|
value: 'model-value',
|
|
787
793
|
...overlay
|
|
@@ -826,7 +832,7 @@ module.exports = {
|
|
|
826
832
|
const tag = classify(attr.parent.parent.rawName);
|
|
827
833
|
if (!Object.keys(replacements).includes(tag)) return;
|
|
828
834
|
const propName = attr.directive ? hyphenate(attr.key.argument.rawName) : hyphenate(attr.key.rawName);
|
|
829
|
-
const propNameNode = attr.directive ? attr.key.argument : attr;
|
|
835
|
+
const propNameNode = attr.directive ? attr.key.argument : attr.key;
|
|
830
836
|
Object.entries(replacements[tag]).forEach(([test, replace]) => {
|
|
831
837
|
if (hyphenate(test) === propName) {
|
|
832
838
|
if (replace === false) {
|
|
@@ -850,7 +856,7 @@ module.exports = {
|
|
|
850
856
|
}
|
|
851
857
|
});
|
|
852
858
|
} else if (typeof replace === 'object' && 'name' in replace && 'value' in replace) {
|
|
853
|
-
const value = typeof replace.value === 'function' ? replace.value(attr.value?.value) : replace.value;
|
|
859
|
+
const value = typeof replace.value === 'function' ? replace.value(attr.directive ? context.getSourceCode().getText(attr.value.expression) : attr.value?.value) : replace.value;
|
|
854
860
|
if (value == null) return;
|
|
855
861
|
context.report({
|
|
856
862
|
messageId: 'replacedWith',
|
|
@@ -861,10 +867,17 @@ module.exports = {
|
|
|
861
867
|
node: propNameNode,
|
|
862
868
|
fix(fixer) {
|
|
863
869
|
if (attr.directive) {
|
|
864
|
-
|
|
865
|
-
|
|
870
|
+
if (replace.bind) {
|
|
871
|
+
if (value === 'true' || value === '!(false)') {
|
|
872
|
+
return fixer.replaceText(attr, replace.name);
|
|
873
|
+
}
|
|
874
|
+
return [fixer.replaceText(propNameNode, replace.name), fixer.replaceText(attr.value, `"${value}"`)];
|
|
875
|
+
} else {
|
|
876
|
+
const expression = context.getSourceCode().getText(attr.value.expression);
|
|
877
|
+
return [fixer.replaceText(propNameNode, replace.name), fixer.replaceText(attr.value, `"${expression} && '${value}'"`)];
|
|
878
|
+
}
|
|
866
879
|
} else {
|
|
867
|
-
return fixer.replaceText(attr, `${replace.name}="${value}"`);
|
|
880
|
+
return fixer.replaceText(attr, `${replace.bind ? ':' : ''}${replace.name}="${value}"`);
|
|
868
881
|
}
|
|
869
882
|
}
|
|
870
883
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-vuetify",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.2",
|
|
4
4
|
"description": "An eslint plugin for Vuetify",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"author": "Kael Watts-Deuchar <kaelwd@gmail.com>",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"nyc": "^15.1.0",
|
|
37
37
|
"rimraf": "^3.0.2",
|
|
38
38
|
"vue": "^3.2.41",
|
|
39
|
-
"vuetify": "^3.0.0
|
|
39
|
+
"vuetify": "^3.0.0"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"eslint": "^8.0.0",
|