Skip to content

Commit 3980a55

Browse files
committed
Fix vuejs#1808: Lint slots in attribute-hyphenation
1 parent 8f09420 commit 3980a55

File tree

3 files changed

+76
-2
lines changed

3 files changed

+76
-2
lines changed

docs/rules/attribute-hyphenation.md

+21-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ This rule enforces using hyphenated attribute names on custom components in Vue
3535
```json
3636
{
3737
"vue/attribute-hyphenation": ["error", "always" | "never", {
38-
"ignore": []
38+
"ignore": [],
39+
"includeSlots": false,
3940
}]
4041
}
4142
```
@@ -46,6 +47,7 @@ and all the [SVG attributes](https://developer.mozilla.org/en-US/docs/Web/SVG/At
4647
- `"always"` (default) ... Use hyphenated name.
4748
- `"never"` ... Don't use hyphenated name except the ones that are ignored.
4849
- `"ignore"` ... Array of ignored names
50+
- `"includeSlots"` ... Will lint attributes on slot elements when set to true
4951

5052
### `"always"`
5153

@@ -108,6 +110,24 @@ Don't use hyphenated name but allow custom attributes
108110

109111
</eslint-code-block>
110112

113+
### `"always", { "includeSlots": true }`
114+
115+
Use hyphenated names on slot elements
116+
117+
<eslint-code-block fix :rules="{'vue/attribute-hyphenation': ['error', 'always', { includeSlots: true }]}">
118+
119+
```vue
120+
<template>
121+
<!-- ✓ GOOD -->
122+
<MyComponent><slot my-prop="prop"></slot></MyComponent>
123+
124+
<!-- ✗ BAD -->
125+
<MyComponent><slot myProp="prop"></slot></MyComponent>
126+
</template>
127+
```
128+
129+
</eslint-code-block>
130+
111131
## :couple: Related Rules
112132

113133
- [vue/v-on-event-hyphenation](./v-on-event-hyphenation.md)

lib/rules/attribute-hyphenation.js

+19-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ module.exports = {
4040
},
4141
uniqueItems: true,
4242
additionalItems: false
43+
},
44+
includeSlots: {
45+
type: 'boolean'
4346
}
4447
},
4548
additionalProperties: false
@@ -100,13 +103,28 @@ module.exports = {
100103
return useHyphenated ? value.toLowerCase() === value : !/-/.test(value)
101104
}
102105

106+
/**
107+
* @param {VDirective | VAttribute} node
108+
*/
109+
function isConfiguredSlot(node) {
110+
return (
111+
optionsPayload &&
112+
optionsPayload.includeSlots &&
113+
node.parent.parent.name === 'slot'
114+
)
115+
}
116+
103117
// ----------------------------------------------------------------------
104118
// Public
105119
// ----------------------------------------------------------------------
106120

107121
return utils.defineTemplateBodyVisitor(context, {
108122
VAttribute(node) {
109-
if (!utils.isCustomComponent(node.parent.parent)) return
123+
if (
124+
!utils.isCustomComponent(node.parent.parent) &&
125+
!isConfiguredSlot(node)
126+
)
127+
return
110128

111129
const name = !node.directive
112130
? node.key.rawName

tests/lib/rules/attribute-hyphenation.js

+36
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,16 @@ ruleTester.run('attribute-hyphenation', rule, {
5656
filename: 'test.vue',
5757
code: '<template><my-component :[foo-bar]></my-component></template>',
5858
options: ['never']
59+
},
60+
{
61+
filename: 'test.vue',
62+
code: '<template><div><slot my-prop></slot></div></template>',
63+
options: ['always', { includeSlots: true }]
64+
},
65+
{
66+
filename: 'test.vue',
67+
code: '<template><div><slot myProp></slot></div></template>',
68+
options: ['never', { includeSlots: true }]
5969
}
6070
],
6171

@@ -252,6 +262,32 @@ ruleTester.run('attribute-hyphenation', rule, {
252262
line: 3
253263
}
254264
]
265+
},
266+
{
267+
filename: 'test.vue',
268+
code: '<template><div><slot my-prop="foo"></slot></div></template>',
269+
output: '<template><div><slot myProp="foo"></slot></div></template>',
270+
options: ['never', { includeSlots: true }],
271+
errors: [
272+
{
273+
message: "Attribute 'my-prop' can't be hyphenated.",
274+
type: 'VIdentifier',
275+
line: 1
276+
}
277+
]
278+
},
279+
{
280+
filename: 'test.vue',
281+
code: '<template><div><slot MyProp="Bar"></slot></div></template>',
282+
output: '<template><div><slot my-prop="Bar"></slot></div></template>',
283+
options: ['always', { includeSlots: true }],
284+
errors: [
285+
{
286+
message: "Attribute 'MyProp' must be hyphenated.",
287+
type: 'VIdentifier',
288+
line: 1
289+
}
290+
]
255291
}
256292
]
257293
})

0 commit comments

Comments
 (0)