Skip to content

Commit

Permalink
feat(max-attributes-per-line): singleline.allowFirstLine option (#1465)
Browse files Browse the repository at this point in the history
* feat(max-attributes-per-line): allow max attribues 0 for singleline

* feat(max-attributes-per-line): allowFirstLine option

* docs(max-attributes-per-line): updated options and added example
  • Loading branch information
privatenumber committed Apr 12, 2021
1 parent 62f577d commit 8bdb2a9
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 15 deletions.
26 changes: 24 additions & 2 deletions docs/rules/max-attributes-per-line.md
Expand Up @@ -57,7 +57,10 @@ There is a configurable number of attributes that are acceptable in one-line cas
```json
{
"vue/max-attributes-per-line": ["error", {
"singleline": 1,
"singleline": {
"max": 1,
"allowFirstLine": true
},
"multiline": {
"max": 1,
"allowFirstLine": false
Expand All @@ -66,7 +69,8 @@ There is a configurable number of attributes that are acceptable in one-line cas
}
```

- `singleline` (`number`) ... The number of maximum attributes per line when the opening tag is in a single line. Default is `1`.
- `singleline.max` (`number`) ... The number of maximum attributes per line when the opening tag is in a single line. Default is `1`.
- `singleline.allowFirstLine` (`boolean`) ... If `true`, it allows attributes on the same line as that tag name. Default is `true`.
- `multiline.max` (`number`) ... The max number of attributes per line when the opening tag is in multiple lines. Default is `1`. This can be `{ multiline: 1 }` instead of `{ multiline: { max: 1 }}` if you don't configure `allowFirstLine` property.
- `multiline.allowFirstLine` (`boolean`) ... If `true`, it allows attributes on the same line as that tag name. Default is `false`.

Expand All @@ -86,6 +90,24 @@ There is a configurable number of attributes that are acceptable in one-line cas

</eslint-code-block>

### `"singleline": 1, "allowFirstLine": false`

<eslint-code-block fix :rules="{'vue/max-attributes-per-line': ['error', {singleline: { allowFirstLine: false }}]}">

```vue
<template>
<!-- ✓ GOOD -->
<MyComponent
lorem="1"
/>
<!-- ✗ BAD -->
<MyComponent lorem="1" />
</template>
```

</eslint-code-block>

### `"multiline": 2`

<eslint-code-block fix :rules="{'vue/max-attributes-per-line': ['error', {multiline: 2}]}">
Expand Down
45 changes: 32 additions & 13 deletions lib/rules/max-attributes-per-line.js
Expand Up @@ -34,6 +34,9 @@ module.exports = {
max: {
type: 'number',
minimum: 1
},
allowFirstLine: {
type: 'boolean'
}
},
additionalProperties: false
Expand Down Expand Up @@ -72,7 +75,8 @@ module.exports = {
const configuration = parseOptions(context.options[0])
const multilineMaximum = configuration.multiline
const singlelinemMaximum = configuration.singleline
const canHaveFirstLine = configuration.allowFirstLine
const canHaveSinglelineFirstLine = configuration.singlelineAllowFirstLine
const canHaveMultilineFirstLine = configuration.multilineAllowFirstLine
const template =
context.parserServices.getTemplateBodyTokenStore &&
context.parserServices.getTemplateBodyTokenStore()
Expand All @@ -83,16 +87,22 @@ module.exports = {

if (!numberOfAttributes) return

if (
utils.isSingleLine(node) &&
numberOfAttributes > singlelinemMaximum
) {
showErrors(node.attributes.slice(singlelinemMaximum))
if (utils.isSingleLine(node)) {
if (
!canHaveSinglelineFirstLine &&
node.attributes[0].loc.start.line === node.loc.start.line
) {
showErrors([node.attributes[0]])
}

if (numberOfAttributes > singlelinemMaximum) {
showErrors(node.attributes.slice(singlelinemMaximum))
}
}

if (!utils.isSingleLine(node)) {
if (
!canHaveFirstLine &&
!canHaveMultilineFirstLine &&
node.attributes[0].loc.start.line === node.loc.start.line
) {
showErrors([node.attributes[0]])
Expand All @@ -114,27 +124,36 @@ module.exports = {
function parseOptions(options) {
const defaults = {
singleline: 1,
singlelineAllowFirstLine: true,
multiline: 1,
allowFirstLine: false
multilineAllowFirstLine: false
}

if (options) {
if (typeof options.singleline === 'number') {
defaults.singleline = options.singleline
} else if (options.singleline && options.singleline.max) {
defaults.singleline = options.singleline.max
} else if (typeof options.singleline === 'object') {
if (typeof options.singleline.max === 'number') {
defaults.singleline = options.singleline.max
}

if (typeof options.singleline.allowFirstLine === 'boolean') {
defaults.singlelineAllowFirstLine =
options.singleline.allowFirstLine
}
}

if (options.multiline) {
if (typeof options.multiline === 'number') {
defaults.multiline = options.multiline
} else if (typeof options.multiline === 'object') {
if (options.multiline.max) {
if (typeof options.multiline.max === 'number') {
defaults.multiline = options.multiline.max
}

if (options.multiline.allowFirstLine) {
defaults.allowFirstLine = options.multiline.allowFirstLine
if (typeof options.multiline.allowFirstLine === 'boolean') {
defaults.multilineAllowFirstLine =
options.multiline.allowFirstLine
}
}
}
Expand Down
13 changes: 13 additions & 0 deletions tests/lib/rules/max-attributes-per-line.js
Expand Up @@ -299,6 +299,19 @@ petname="Snoopy" extra="foo">
line: 3
}
]
},
{
code: `<template><component name="John Doe"></component></template>`,
options: [{ singleline: { allowFirstLine: false } }],
output: `<template><component
name="John Doe"></component></template>`,
errors: [
{
message: "'name' should be on a new line.",
type: 'VAttribute',
line: 1
}
]
}
]
})

0 comments on commit 8bdb2a9

Please sign in to comment.