Skip to content

Commit 1c79cda

Browse files
committed
Merge branch 'master' of github.com:vuejs/eslint-plugin-vue into feature/np-negated-condition
2 parents 6f3ef44 + 72b186c commit 1c79cda

16 files changed

+656
-47
lines changed

.changeset/beige-teams-camp.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'eslint-plugin-vue': minor
3+
---
4+
5+
Added `ignoreParents` option to [`vue/no-deprecated-slot-attribute`](https://eslint.vuejs.org/rules/no-deprecated-slot-attribute.html)

.changeset/eight-camels-refuse.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"eslint-plugin-vue": patch
3+
---
4+
5+
Resolved TypeScript compatibility issues introduced by eslint-typegen

.changeset/true-pumas-open.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'eslint-plugin-vue': minor
3+
---
4+
5+
Added new [`vue/no-negated-condition`](https://eslint.vuejs.org/rules/no-negated-condition.html) rule

docs/rules/index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ The following rules extend the rules provided by ESLint itself and apply them to
328328
| [vue/no-implicit-coercion] | Disallow shorthand type conversions in `<template>` | :wrench::bulb: | :hammer: |
329329
| [vue/no-irregular-whitespace] | disallow irregular whitespace in `.vue` files | | :warning: |
330330
| [vue/no-loss-of-precision] | Disallow literal numbers that lose precision in `<template>` | | :warning: |
331+
| [vue/no-negated-condition] | Disallow negated conditions in `<template>` | | :hammer: |
331332
| [vue/no-restricted-syntax] | Disallow specified syntax in `<template>` | | :hammer: |
332333
| [vue/no-sparse-arrays] | Disallow sparse arrays in `<template>` | | :warning: |
333334
| [vue/no-useless-concat] | Disallow unnecessary concatenation of literals or template literals in `<template>` | | :hammer: |
@@ -484,6 +485,7 @@ The following rules extend the rules provided by ESLint itself and apply them to
484485
[vue/no-multiple-template-root]: ./no-multiple-template-root.md
485486
[vue/no-mutating-props]: ./no-mutating-props.md
486487
[vue/no-negated-v-if-condition]: ./no-negated-v-if-condition.md
488+
[vue/no-negated-condition]: ./no-negated-condition.md
487489
[vue/no-parsing-error]: ./no-parsing-error.md
488490
[vue/no-potential-component-option-typo]: ./no-potential-component-option-typo.md
489491
[vue/no-ref-as-operand]: ./no-ref-as-operand.md

docs/rules/no-deprecated-slot-attribute.md

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,18 @@ This rule reports deprecated `slot` attribute in Vue.js v2.6.0+.
4343
```json
4444
{
4545
"vue/no-deprecated-slot-attribute": ["error", {
46-
"ignore": ["my-component"]
46+
"ignore": ["my-component"],
47+
"ignoreParents": ["my-web-component"],
4748
}]
4849
}
4950
```
5051

5152
- `"ignore"` (`string[]`) An array of tags or regular expression patterns (e.g. `/^custom-/`) that ignore these rules. This option will check both kebab-case and PascalCase versions of the given tag names. Default is empty.
53+
- `"ignoreParents"` (`string[]`) An array of tags or regular expression patterns (e.g. `/^custom-/`) for parents that ignore these rules. This option is especially useful for [Web-Components](https://developer.mozilla.org/en-US/docs/Web/API/Web_components). Default is empty.
5254

5355
### `"ignore": ["my-component"]`
5456

55-
<eslint-code-block fix :rules="{'vue/no-dupe-keys': ['error', {ignore: ['my-component']}]}">
57+
<eslint-code-block fix :rules="{'vue/no-deprecated-slot-attribute': ['error', {ignore: ['my-component']}]}">
5658

5759
```vue
5860
<template>
@@ -81,9 +83,41 @@ This rule reports deprecated `slot` attribute in Vue.js v2.6.0+.
8183

8284
</eslint-code-block>
8385

86+
### `"ignoreParents": ["my-web-component"]`
87+
88+
<eslint-code-block fix :rules="{'vue/no-deprecated-slot-attribute': ['error', {ignoreParents: ['my-web-component']}]}">
89+
90+
```vue
91+
<template>
92+
<my-web-component>
93+
<!-- ✓ GOOD -->
94+
<template v-slot:name>
95+
{{ props.title }}
96+
</template>
97+
</my-web-component>
98+
99+
<my-web-component>
100+
<!-- ✓ GOOD -->
101+
<my-component slot="name">
102+
{{ props.title }}
103+
</my-component>
104+
</my-web-component>
105+
106+
<other-component>
107+
<!-- ✗ BAD -->
108+
<my-component slot="name">
109+
{{ props.title }}
110+
</my-component>
111+
</other-component>
112+
</template>
113+
```
114+
115+
</eslint-code-block>
116+
84117
## :books: Further Reading
85118

86119
- [API - slot](https://v2.vuejs.org/v2/api/#slot-deprecated)
120+
- [Web - slot](https://developer.mozilla.org/en-US/docs/Web/API/Element/slot)
87121

88122
## :rocket: Version
89123

docs/rules/no-negated-condition.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
pageClass: rule-details
3+
sidebarDepth: 0
4+
title: vue/no-negated-condition
5+
description: Disallow negated conditions in `<template>`
6+
---
7+
8+
# vue/no-negated-condition
9+
10+
> Disallow negated conditions in `<template>`
11+
12+
- :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> _**This rule has not been released yet.**_ </badge>
13+
14+
## :book: Rule Details
15+
16+
This rule is the same rule as core [no-negated-condition] rule but it applies to the expressions in `<template>`.
17+
18+
## :couple: Related Rules
19+
20+
- [unicorn/no-negated-condition](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-negated-condition.md)
21+
22+
## :books: Further Reading
23+
24+
- [no-negated-condition]
25+
26+
[no-negated-condition]: https://eslint.org/docs/rules/no-negated-condition
27+
28+
## :mag: Implementation
29+
30+
- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-negated-condition.js)
31+
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-negated-condition.js)
32+
33+
<sup>Taken with ❤️ [from ESLint core](https://eslint.org/docs/latest/rules/no-negated-condition)</sup>

lib/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ const plugin = {
142142
'no-multiple-template-root': require('./rules/no-multiple-template-root'),
143143
'no-mutating-props': require('./rules/no-mutating-props'),
144144
'no-negated-v-if-condition': require('./rules/no-negated-v-if-condition'),
145+
'no-negated-condition': require('./rules/no-negated-condition'),
145146
'no-parsing-error': require('./rules/no-parsing-error'),
146147
'no-potential-component-option-typo': require('./rules/no-potential-component-option-typo'),
147148
'no-ref-as-operand': require('./rules/no-ref-as-operand'),

lib/rules/no-deprecated-slot-attribute.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ module.exports = {
2525
type: 'array',
2626
items: { type: 'string' },
2727
uniqueItems: true
28+
},
29+
ignoreParents: {
30+
type: 'array',
31+
items: { type: 'string' },
32+
uniqueItems: true
2833
}
2934
},
3035
additionalProperties: false

lib/rules/no-negated-condition.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* @author Wayne Zhang
3+
* See LICENSE file in root directory for full license.
4+
*/
5+
'use strict'
6+
7+
const { wrapCoreRule } = require('../utils')
8+
9+
// eslint-disable-next-line internal/no-invalid-meta
10+
module.exports = wrapCoreRule('no-negated-condition', {
11+
applyDocument: true
12+
})

lib/rules/syntaxes/slot-attribute.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,18 @@
77
const canConvertToVSlot = require('./utils/can-convert-to-v-slot')
88
const regexp = require('../../utils/regexp')
99
const casing = require('../../utils/casing')
10+
const { isVElement } = require('../../utils')
1011

1112
module.exports = {
1213
deprecated: '2.6.0',
1314
supported: '<3.0.0',
1415
/** @param {RuleContext} context @returns {TemplateListener} */
1516
createTemplateBodyVisitor(context) {
16-
/** @type {{ ignore: string[] }} */
17+
/** @type {{ ignore: string[], ignoreParents: string[] }} */
1718
const options = context.options[0] || {}
18-
const { ignore = [] } = options
19+
const { ignore = [], ignoreParents = [] } = options
1920
const isAnyIgnored = regexp.toRegExpGroupMatcher(ignore)
21+
const isParentIgnored = regexp.toRegExpGroupMatcher(ignoreParents)
2022

2123
const sourceCode = context.getSourceCode()
2224
const tokenStore =
@@ -123,7 +125,8 @@ module.exports = {
123125
* @returns {void}
124126
*/
125127
function reportSlot(slotAttr) {
126-
const componentName = slotAttr.parent.parent.rawName
128+
const component = slotAttr.parent.parent
129+
const componentName = component.rawName
127130

128131
if (
129132
isAnyIgnored(
@@ -135,6 +138,12 @@ module.exports = {
135138
return
136139
}
137140

141+
const parent = component.parent
142+
const parentName = isVElement(parent) ? parent.rawName : null
143+
if (parentName && isParentIgnored(parentName)) {
144+
return
145+
}
146+
138147
context.report({
139148
node: slotAttr.key,
140149
messageId: 'forbiddenSlotAttribute',

0 commit comments

Comments
 (0)