Skip to content

Commit 889c192

Browse files
authored
feat(require-toggle-inside-transition): add additionalDirectives option (#2535) (#2537)
1 parent 354c0de commit 889c192

File tree

3 files changed

+115
-6
lines changed

3 files changed

+115
-6
lines changed

docs/rules/require-toggle-inside-transition.md

+28-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,34 @@ This rule reports elements inside `<transition>` that do not control the display
3333

3434
## :wrench: Options
3535

36-
Nothing.
36+
```json
37+
{
38+
"vue/require-toggle-inside-transition": ["error", {
39+
"additionalDirectives": []
40+
}]
41+
}
42+
```
43+
44+
- `additionalDirectives` (`string[]`) ... Custom directives which will satisfy this rule in addition to `v-show` and `v-if`. Should be added without the `v-` prefix.
45+
46+
### `additionalDirectives: ["dialog"]`
47+
48+
<eslint-code-block :rules="{'vue/require-toggle-inside-transition': ['error', {additionalDirectives: ['dialog']}]}">
49+
50+
```vue
51+
<template>
52+
<!-- ✓ GOOD -->
53+
<transition><div v-if="show" /></transition>
54+
<transition><div v-show="show" /></transition>
55+
<transition><dialog v-dialog="show" /></transition>
56+
57+
<!-- ✗ BAD -->
58+
<transition><div /></transition>
59+
<transition><div v-custom="show" /></transition>
60+
<template>
61+
```
62+
63+
</eslint-code-block>
3764

3865
## :books: Further Reading
3966

lib/rules/require-toggle-inside-transition.js

+48-5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,25 @@ function isValidBindAppear(vBindAppear) {
2020
return true
2121
}
2222

23+
/**
24+
* @param {string[]} directives
25+
*/
26+
function createDirectiveList(directives) {
27+
let str = ''
28+
29+
for (const [index, directive] of directives.entries()) {
30+
if (index === 0) {
31+
str += `\`v-${directive}\``
32+
} else if (index < directives.length - 1) {
33+
str += `, \`v-${directive}\``
34+
} else {
35+
str += ` or \`v-${directive}\``
36+
}
37+
}
38+
39+
return str
40+
}
41+
2342
module.exports = {
2443
meta: {
2544
type: 'problem',
@@ -30,14 +49,34 @@ module.exports = {
3049
url: 'https://eslint.vuejs.org/rules/require-toggle-inside-transition.html'
3150
},
3251
fixable: null,
33-
schema: [],
52+
schema: [
53+
{
54+
type: 'object',
55+
properties: {
56+
additionalDirectives: {
57+
type: 'array',
58+
items: {
59+
type: 'string'
60+
},
61+
uniqueItems: true
62+
}
63+
},
64+
additionalProperties: false
65+
}
66+
],
3467
messages: {
3568
expected:
36-
'The element inside `<transition>` is expected to have a `v-if` or `v-show` directive.'
69+
'The element inside `<transition>` is expected to have a {{allowedDirectives}} directive.'
3770
}
3871
},
3972
/** @param {RuleContext} context */
4073
create(context) {
74+
/** @type {Array<string>} */
75+
const additionalDirectives =
76+
(context.options[0] && context.options[0].additionalDirectives) || []
77+
const allowedDirectives = ['if', 'show', ...additionalDirectives]
78+
const allowedDirectivesString = createDirectiveList(allowedDirectives)
79+
4180
/**
4281
* Check if the given element has display control.
4382
* @param {VElement} element The element node to check.
@@ -59,14 +98,18 @@ module.exports = {
5998

6099
if (
61100
element.name !== 'slot' &&
62-
!utils.hasDirective(element, 'if') &&
63-
!utils.hasDirective(element, 'show') &&
101+
!allowedDirectives.some((directive) =>
102+
utils.hasDirective(element, directive)
103+
) &&
64104
!utils.hasDirective(element, 'bind', 'key')
65105
) {
66106
context.report({
67107
node: element.startTag,
68108
loc: element.startTag.loc,
69-
messageId: 'expected'
109+
messageId: 'expected',
110+
data: {
111+
allowedDirectives: allowedDirectivesString
112+
}
70113
})
71114
}
72115
}

tests/lib/rules/require-toggle-inside-transition.js

+39
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,15 @@ tester.run('require-toggle-inside-transition', rule, {
7777
{
7878
filename: 'test.vue',
7979
code: '<template><transition :appear="true"><div /></transition></template>'
80+
},
81+
{
82+
filename: 'test.vue',
83+
code: '<template><transition><dialog v-dialog="show" /></transition></template>',
84+
options: [
85+
{
86+
additionalDirectives: ['dialog']
87+
}
88+
]
8089
}
8190
],
8291
invalid: [
@@ -132,6 +141,36 @@ tester.run('require-toggle-inside-transition', rule, {
132141
filename: 'test.vue',
133142
code: '<template><transition @appear="isLoaded"><div /></transition></template>',
134143
errors: [{ messageId: 'expected' }]
144+
},
145+
{
146+
filename: 'test.vue',
147+
code: '<template><transition><dialog v-dialog="show" /></transition></template>',
148+
options: [
149+
{
150+
additionalDirectives: []
151+
}
152+
],
153+
errors: [
154+
{
155+
messageId: 'expected',
156+
data: { allowedDirectives: '`v-if` or `v-show`' }
157+
}
158+
]
159+
},
160+
{
161+
filename: 'test.vue',
162+
code: '<template><transition><div v-custom="show" /></transition></template>',
163+
options: [
164+
{
165+
additionalDirectives: ['dialog']
166+
}
167+
],
168+
errors: [
169+
{
170+
messageId: 'expected',
171+
data: { allowedDirectives: '`v-if`, `v-show` or `v-dialog`' }
172+
}
173+
]
135174
}
136175
]
137176
})

0 commit comments

Comments
 (0)