eslint-plugin-vuetify 2.2.0 → 2.4.0

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 CHANGED
@@ -48,6 +48,7 @@ These rules will help you avoid deprecated components, props, and classes. They
48
48
  - Prevent the use of classes that have been removed from Vuetify ([`no-deprecated-classes`])
49
49
  - Prevent the use of the old theme class syntax ([`no-deprecated-colors`])
50
50
  - Prevent the use of deprecated import paths ([`no-deprecated-imports`])
51
+ - Ensure icon buttons have a variant defined ([`icon-button-variant`])
51
52
 
52
53
  ### Grid system
53
54
 
@@ -63,6 +64,7 @@ These rules are designed to help migrate to the new grid system in Vuetify v2. T
63
64
  [`no-deprecated-classes`]: ./docs/rules/no-deprecated-classes.md
64
65
  [`no-deprecated-colors`]: ./docs/rules/no-deprecated-colors.md
65
66
  [`no-deprecated-imports`]: ./docs/rules/no-deprecated-imports.md
67
+ [`icon-button-variant`]: ./docs/rules/icon-button-variant.md
66
68
 
67
69
 
68
70
  ## 💪 Supporting Vuetify
@@ -0,0 +1,49 @@
1
+ 'use strict';
2
+
3
+ const {
4
+ classify,
5
+ getAttributes
6
+ } = require('../util/helpers');
7
+
8
+ // ------------------------------------------------------------------------------
9
+ // Rule Definition
10
+ // ------------------------------------------------------------------------------
11
+
12
+ module.exports = {
13
+ meta: {
14
+ docs: {
15
+ description: 'Ensure icon buttons have a variant defined.',
16
+ category: 'recommended'
17
+ },
18
+ fixable: 'code',
19
+ schema: [{
20
+ type: 'string'
21
+ }],
22
+ messages: {
23
+ needsVariant: 'Icon buttons should have {{ a }} defined.'
24
+ }
25
+ },
26
+ create(context) {
27
+ return context.parserServices.defineTemplateBodyVisitor({
28
+ VElement(element) {
29
+ const tag = classify(element.rawName);
30
+ if (tag !== 'VBtn') return;
31
+ const attributes = getAttributes(element);
32
+ const iconAttribute = attributes.find(attr => attr.name === 'icon');
33
+ if (!iconAttribute) return;
34
+ if (attributes.some(attr => attr.name === 'variant')) return;
35
+ const variant = `variant="${context.options[0] || 'text'}"`;
36
+ context.report({
37
+ node: iconAttribute.node,
38
+ messageId: 'needsVariant',
39
+ data: {
40
+ a: variant
41
+ },
42
+ fix(fixer) {
43
+ return fixer.insertTextAfter(iconAttribute.node, ' ' + variant);
44
+ }
45
+ });
46
+ }
47
+ });
48
+ }
49
+ };
@@ -11,13 +11,7 @@ const replacements = new Map([[/^rounded-(r|l|tr|tl|br|bl)(-.*)?$/, ([side, rest
11
11
  bl: 'bs'
12
12
  }[side];
13
13
  return `rounded-${side}${rest || ''}`;
14
- }], [/^border-([rl])(.*)$/, ([side, rest]) => {
15
- side = {
16
- r: 'e',
17
- l: 's'
18
- }[side];
19
- return `border-${side}${rest}`;
20
- }], [/^text-xs-(left|right|center|justify)$/, ([align]) => `text-${align}`], [/hidden-(xs|sm|md|lg|xl)-only/, ([breakpoint]) => `hidden-${breakpoint}`], ['scroll-y', 'overflow-y-auto'], ['hide-overflow', 'overflow-hidden'], ['show-overflow', 'overflow-visible'], ['no-wrap', 'text-no-wrap'], ['ellipsis', 'text-truncate'], ['left', 'float-left'], ['right', 'float-right'], ['display-4', 'text-h1'], ['display-3', 'text-h2'], ['display-2', 'text-h3'], ['display-1', 'text-h4'], ['headline', 'text-h5'], ['title', 'text-h6'], ['subtitle-1', 'text-subtitle-1'], ['subtitle-2', 'text-subtitle-2'], ['body-1', 'text-body-1'], ['body-2', 'text-body-2'], ['caption', 'text-caption'], ['caption', 'text-caption'], ['overline', 'text-overline'], [/^transition-(fast-out-slow-in|linear-out-slow-in|fast-out-linear-in|ease-in-out|fast-in-fast-out|swing)$/, false]]);
14
+ }], [/^text-xs-(left|right|center|justify)$/, ([align]) => `text-${align}`], [/^hidden-(xs|sm|md|lg|xl)-only$/, ([breakpoint]) => `hidden-${breakpoint}`], ['scroll-y', 'overflow-y-auto'], ['hide-overflow', 'overflow-hidden'], ['show-overflow', 'overflow-visible'], ['no-wrap', 'text-no-wrap'], ['ellipsis', 'text-truncate'], ['left', 'float-left'], ['right', 'float-right'], ['display-4', 'text-h1'], ['display-3', 'text-h2'], ['display-2', 'text-h3'], ['display-1', 'text-h4'], ['headline', 'text-h5'], ['title', 'text-h6'], ['subtitle-1', 'text-subtitle-1'], ['subtitle-2', 'text-subtitle-2'], ['body-1', 'text-body-1'], ['body-2', 'text-body-2'], ['caption', 'text-caption'], ['caption', 'text-caption'], ['overline', 'text-overline'], [/^transition-(fast-out-slow-in|linear-out-slow-in|fast-out-linear-in|ease-in-out|fast-in-fast-out|swing)$/, false]]);
21
15
 
22
16
  // ------------------------------------------------------------------------------
23
17
  // Rule Definition
@@ -89,9 +89,6 @@ const select = {
89
89
  cacheItems: false,
90
90
  deletableChips: 'closable-chips',
91
91
  disableLookup: false,
92
- itemColor: {
93
- custom: 'item-props.color'
94
- },
95
92
  itemDisabled: {
96
93
  custom: 'item-props.disabled'
97
94
  },
@@ -197,6 +194,7 @@ const replacements = {
197
194
  ...size
198
195
  },
199
196
  VBadge: {
197
+ value: 'model-value',
200
198
  avatar: false,
201
199
  mode: false,
202
200
  origin: false,
@@ -315,10 +313,7 @@ const replacements = {
315
313
  VCard: {
316
314
  activeClass: false,
317
315
  loaderHeight: false,
318
- outlined: {
319
- name: 'variant',
320
- value: 'outlined'
321
- },
316
+ outlined: 'border',
322
317
  raised: {
323
318
  name: 'elevation',
324
319
  value: 8
@@ -481,7 +476,10 @@ const replacements = {
481
476
  ...inputs
482
477
  },
483
478
  VDialog: {
484
- ...overlay
479
+ ...overlay,
480
+ tile: {
481
+ custom: 'apply border-radius changes to the root element of the `v-dialog`\'s content'
482
+ }
485
483
  },
486
484
  VMenu: {
487
485
  allowOverflow: false,
@@ -551,7 +549,6 @@ const replacements = {
551
549
  name: 'size',
552
550
  value: 'small'
553
551
  },
554
- disabled: false,
555
552
  left: 'start',
556
553
  right: 'end',
557
554
  ...sizes,
@@ -1015,7 +1012,7 @@ module.exports = {
1015
1012
  return [fixer.replaceText(propNameNode, replace.name), fixer.replaceText(attr.value, `"${value}"`)];
1016
1013
  } else {
1017
1014
  const expression = context.getSourceCode().getText(attr.value.expression);
1018
- return [fixer.replaceText(propNameNode, replace.name), fixer.replaceText(attr.value, `"${expression} && '${value}'"`)];
1015
+ return [fixer.replaceText(propNameNode, replace.name), fixer.replaceText(attr.value, `"${expression} ? '${value}' : undefined"`)];
1019
1016
  }
1020
1017
  } else {
1021
1018
  return fixer.replaceText(attr, `${replace.bind ? ':' : ''}${replace.name}="${value}"`);
@@ -149,6 +149,23 @@ const groups = [{
149
149
  }
150
150
  });
151
151
  }
152
+ }, {
153
+ components: ['VSnackbar'],
154
+ slots: ['action'],
155
+ handler(context, node, directive, param) {
156
+ context.report({
157
+ node: directive,
158
+ messageId: 'renamed',
159
+ data: {
160
+ component: node.parent.name,
161
+ slot: directive.key.argument.name,
162
+ newSlot: 'actions'
163
+ },
164
+ fix(fixer) {
165
+ return fixer.replaceText(directive.key.argument, 'action');
166
+ }
167
+ });
168
+ }
152
169
  }];
153
170
 
154
171
  // ------------------------------------------------------------------------------
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-vuetify",
3
- "version": "2.2.0",
3
+ "version": "2.4.0",
4
4
  "description": "An eslint plugin for Vuetify",
5
5
  "main": "lib/index.js",
6
6
  "author": "Kael Watts-Deuchar <kaelwd@gmail.com>",