Skip to content

Commit 4aa214b

Browse files
committed
feat: add icon-button-variant rule
1 parent b9cd3ad commit 4aa214b

File tree

4 files changed

+109
-0
lines changed

4 files changed

+109
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ These rules will help you avoid deprecated components, props, and classes. They
4848
- Prevent the use of classes that have been removed from Vuetify ([`no-deprecated-classes`])
4949
- Prevent the use of the old theme class syntax ([`no-deprecated-colors`])
5050
- Prevent the use of deprecated import paths ([`no-deprecated-imports`])
51+
- Ensure icon buttons have a variant defined ([`icon-button-variant`])
5152

5253
### Grid system
5354

@@ -63,6 +64,7 @@ These rules are designed to help migrate to the new grid system in Vuetify v2. T
6364
[`no-deprecated-classes`]: ./docs/rules/no-deprecated-classes.md
6465
[`no-deprecated-colors`]: ./docs/rules/no-deprecated-colors.md
6566
[`no-deprecated-imports`]: ./docs/rules/no-deprecated-imports.md
67+
[`icon-button-variant`]: ./docs/rules/icon-button-variant.md
6668

6769

6870
## 💪 Supporting Vuetify

docs/rules/icon-button-variant.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Ensure icon buttons have a variant defined (icon-button-variant)
2+
3+
:wrench: This rule is fixable with `eslint --fix`
4+
5+
## Rule Details
6+
7+
Buttons in Vuetify 3 no longer have a different variant applied automatically.
8+
9+
Examples of **incorrect** code for this rule:
10+
11+
```html
12+
<v-btn icon />
13+
<v-btn icon="search" />
14+
```
15+
16+
Examples of **correct** code for this rule:
17+
18+
```js
19+
<v-btn icon variant="text" />
20+
<v-btn icon="search" variant="text" />
21+
```
22+
23+
### Options
24+
25+
A different variant other than `text` can be assigned:
26+
27+
```js
28+
{
29+
'vuetify/icon-button-variant': ['error', 'plain']
30+
}
31+
```

src/rules/icon-button-variant.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
'use strict'
2+
3+
const { classify, getAttributes } = require('../util/helpers')
4+
5+
// ------------------------------------------------------------------------------
6+
// Rule Definition
7+
// ------------------------------------------------------------------------------
8+
9+
module.exports = {
10+
meta: {
11+
docs: {
12+
description: 'Ensure icon buttons have a variant defined.',
13+
category: 'recommended',
14+
},
15+
fixable: 'code',
16+
schema: [
17+
{ type: 'string' },
18+
],
19+
messages: {
20+
needsVariant: 'Icon buttons should have {{ a }} defined.',
21+
},
22+
},
23+
24+
create (context) {
25+
return context.parserServices.defineTemplateBodyVisitor({
26+
VElement (element) {
27+
const tag = classify(element.rawName)
28+
if (tag !== 'VBtn') return
29+
30+
const attributes = getAttributes(element)
31+
const iconAttribute = attributes.find(attr => attr.name === 'icon')
32+
if (!iconAttribute) return
33+
if (attributes.some(attr => attr.name === 'variant')) return
34+
35+
const variant = `variant="${context.options[0] || 'text'}"`
36+
37+
context.report({
38+
node: iconAttribute.node,
39+
messageId: 'needsVariant',
40+
data: { a: variant },
41+
fix (fixer) {
42+
return fixer.insertTextAfter(iconAttribute.node, ' ' + variant)
43+
},
44+
})
45+
},
46+
})
47+
},
48+
}

tests/rules/icon-button-variant.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
const RuleTester = require('eslint').RuleTester
2+
const rule = require('../../src/rules/icon-button-variant')
3+
4+
const tester = new RuleTester({
5+
parser: require.resolve('vue-eslint-parser'),
6+
parserOptions: { ecmaVersion: 2015 },
7+
})
8+
9+
tester.run('icon-button-variant', rule, {
10+
valid: [
11+
'<template><v-btn /></template>',
12+
'<template><v-btn variant="text" /></template>',
13+
'<template><v-btn icon variant="text" /></template>',
14+
'<template><v-btn icon="foo" variant="text" /></template>',
15+
],
16+
invalid: [
17+
{
18+
code: '<template><v-btn icon /></template>',
19+
output: '<template><v-btn icon variant="text" /></template>',
20+
errors: [{ messageId: 'needsVariant' }],
21+
},
22+
{
23+
code: '<template><v-btn icon="foo" /></template>',
24+
output: '<template><v-btn icon="foo" variant="text" /></template>',
25+
errors: [{ messageId: 'needsVariant' }],
26+
},
27+
],
28+
})

0 commit comments

Comments
 (0)