diff --git a/docs/rules/max-attributes-per-line.md b/docs/rules/max-attributes-per-line.md
index 69bd77949..dac9d2d72 100644
--- a/docs/rules/max-attributes-per-line.md
+++ b/docs/rules/max-attributes-per-line.md
@@ -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
@@ -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`.
@@ -86,6 +90,24 @@ There is a configurable number of attributes that are acceptable in one-line cas
+### `"singleline": 1, "allowFirstLine": false`
+
+
+
+```vue
+
+
+
+
+
+
+
+```
+
+
+
### `"multiline": 2`
diff --git a/lib/rules/max-attributes-per-line.js b/lib/rules/max-attributes-per-line.js
index e379df47f..d50a78d6d 100644
--- a/lib/rules/max-attributes-per-line.js
+++ b/lib/rules/max-attributes-per-line.js
@@ -34,6 +34,9 @@ module.exports = {
max: {
type: 'number',
minimum: 1
+ },
+ allowFirstLine: {
+ type: 'boolean'
}
},
additionalProperties: false
@@ -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()
@@ -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]])
@@ -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
}
}
}
diff --git a/tests/lib/rules/max-attributes-per-line.js b/tests/lib/rules/max-attributes-per-line.js
index fa7210027..aedc6d6d8 100644
--- a/tests/lib/rules/max-attributes-per-line.js
+++ b/tests/lib/rules/max-attributes-per-line.js
@@ -299,6 +299,19 @@ petname="Snoopy" extra="foo">
line: 3
}
]
+ },
+ {
+ code: ``,
+ options: [{ singleline: { allowFirstLine: false } }],
+ output: ``,
+ errors: [
+ {
+ message: "'name' should be on a new line.",
+ type: 'VAttribute',
+ line: 1
+ }
+ ]
}
]
})