Skip to content

Commit d69db95

Browse files
committed
feat(require-toggle-inside-transition): add additionalDirectives option (#2535)
1 parent 0fbe35e commit d69db95

File tree

3 files changed

+115
-6
lines changed

3 files changed

+115
-6
lines changed

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

Lines changed: 28 additions & 1 deletion
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

Lines changed: 48 additions & 5 deletions
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

Lines changed: 39 additions & 0 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy