Skip to content

Commit f9e1eee

Browse files
MechJosh0michalsnik
authored andcommitted
Update attribute-hyphenation to allow a custom ignore list (#461)
* ignore phpstorm editor config * updated rule, tests, and markdown to include a custom list for ignoring attributes * dont do es6 destructuring assignment * cleaner code and do not overwrite default ignore list * Update attribute-hyphenation.js
1 parent 67e0f48 commit f9e1eee

File tree

4 files changed

+61
-12
lines changed

4 files changed

+61
-12
lines changed

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
.idea
12
/.nyc_output
23
/coverage
34
/tests/integrations/*/node_modules

Diff for: docs/rules/attribute-hyphenation.md

+19-5
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
# enforce attribute naming style in template (vue/attribute-hyphenation)
1+
# enforce attribute naming style on custom components in template (vue/attribute-hyphenation)
22

33
- :gear: This rule is included in `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
44
- :wrench: The `--fix` option on the [command line](http://eslint.org/docs/user-guide/command-line-interface#fix) can automatically fix some of the problems reported by this rule.
55

66
## :wrench: Options
77

8-
Default casing is set to `always`
8+
Default casing is set to `always` with `['data-', 'aria-', 'slot-scope']` set to be ignored
99

1010
```
11-
'vue/attribute-hyphenation': [2, 'always'|'never']
11+
'vue/attribute-hyphenation': [2, 'always'|'never', { 'ignore': ['custom-prop'] }]
1212
```
1313

14-
### `"always"` - Use hyphenated name. (It errors on upper case letters.)
14+
### `[2, "always"]` - Use hyphenated name. (It errors on upper case letters.)
1515

1616
:+1: Examples of **correct** code`:
1717

@@ -25,7 +25,7 @@ Default casing is set to `always`
2525
<MyComponent myProp="prop"/>
2626
```
2727

28-
### `"never"` - Don't use hyphenated name. (It errors on hyphens except `data-` and `aria-`.)
28+
### `[2, "never"]` - Don't use hyphenated name. (It errors on hyphens except `data-`, `aria-` and `slot-scope-`.)
2929

3030
:+1: Examples of **correct** code`:
3131

@@ -38,3 +38,17 @@ Default casing is set to `always`
3838
```html
3939
<MyComponent my-prop="prop"/>
4040
```
41+
42+
### `[2, "never", { 'ignore': ['custom-prop'] }]` - Don't use hyphenated name but allow custom attributes
43+
44+
:+1: Examples of **correct** code`:
45+
46+
```html
47+
<MyComponent myProp="prop" custom-prop="foo" data-id="1"/>
48+
```
49+
50+
:-1: Examples of **incorrect** code`:
51+
52+
```html
53+
<MyComponent my-prop="prop" custom-prop="foo" data-id="1"/>
54+
```

Diff for: lib/rules/attribute-hyphenation.js

+33-4
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,46 @@ const casing = require('../utils/casing')
1414
module.exports = {
1515
meta: {
1616
docs: {
17-
description: 'enforce attribute naming style in template',
17+
description: 'enforce attribute naming style on custom components in template',
1818
category: 'strongly-recommended',
1919
url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.5.0/docs/rules/attribute-hyphenation.md'
2020
},
2121
fixable: 'code',
2222
schema: [
2323
{
2424
enum: ['always', 'never']
25+
},
26+
{
27+
type: 'object',
28+
properties: {
29+
'ignore': {
30+
type: 'array',
31+
items: {
32+
allOf: [
33+
{ type: 'string' },
34+
{ not: { type: 'string', pattern: ':exit$' }},
35+
{ not: { type: 'string', pattern: '^\\s*$' }}
36+
]
37+
},
38+
uniqueItems: true,
39+
additionalItems: false
40+
}
41+
},
42+
additionalProperties: false
2543
}
2644
]
2745
},
2846

2947
create (context) {
3048
const sourceCode = context.getSourceCode()
31-
const options = context.options[0]
32-
const useHyphenated = options !== 'never'
49+
const option = context.options[0]
50+
const optionsPayload = context.options[1]
51+
const useHyphenated = option !== 'never'
52+
const ignoredAttributes = ['data-', 'aria-', 'slot-scope']
53+
54+
if (optionsPayload && optionsPayload.ignore) {
55+
ignoredAttributes.push(optionsPayload.ignore)
56+
}
3357

3458
const caseConverter = casing.getConverter(useHyphenated ? 'kebab-case' : 'camelCase')
3559

@@ -48,9 +72,14 @@ module.exports = {
4872
}
4973

5074
function isIgnoredAttribute (value) {
51-
if (value.indexOf('data-') !== -1 || value.indexOf('aria-') !== -1) {
75+
const isIgnored = ignoredAttributes.some(function (attr) {
76+
return value.indexOf(attr) !== -1
77+
})
78+
79+
if (isIgnored) {
5280
return true
5381
}
82+
5483
return useHyphenated ? value.toLowerCase() === value : !/-/.test(value)
5584
}
5685

Diff for: tests/lib/rules/attribute-hyphenation.js

+8-3
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,23 @@ ruleTester.run('attribute-hyphenation', rule, {
3030
},
3131
{
3232
filename: 'test.vue',
33-
code: '<template><div><custom data-id="foo" aria-test="bar" my-prop="prop"></custom></div></template>',
33+
code: '<template><div><custom data-id="foo" aria-test="bar" slot-scope="{ data }" my-prop="prop"></custom></div></template>',
3434
options: ['always']
3535
},
3636
{
3737
filename: 'test.vue',
38-
code: '<template><div><custom data-id="foo" aria-test="bar" myProp="prop"></custom></div></template>',
38+
code: '<template><div><custom data-id="foo" aria-test="bar" slot-scope="{ data }" myProp="prop"></custom></div></template>',
3939
options: ['never']
4040
},
4141
{
4242
filename: 'test.vue',
43-
code: '<template><div data-id="foo" aria-test="bar"><a onClick="" my-prop="prop"></a></div></template>',
43+
code: '<template><div data-id="foo" aria-test="bar" slot-scope="{ data }"><a onClick="" my-prop="prop"></a></div></template>',
4444
options: ['never']
45+
},
46+
{
47+
filename: 'test.vue',
48+
code: '<template><div data-id="foo" aria-test="bar" slot-scope="{ data }" custom-hypen="foo"><a onClick="" my-prop="prop"></a></div></template>',
49+
options: ['never', { 'ignore': ['custom-hypen'] }]
4550
}
4651
],
4752

0 commit comments

Comments
 (0)