From 7d08da6f8869dfc0d02fe8565ffcc56e637cfd2a Mon Sep 17 00:00:00 2001
From: 0xA1337 <0xa1337@proton.me>
Date: 2025年6月13日 12:36:56 +0900
Subject: [PATCH 1/3] feat(attributes-order): add sortByLineLength option
---
docs/rules/attributes-order.md | 76 ++++++++-
lib/rules/attributes-order.js | 24 ++-
tests/lib/rules/attributes-order.js | 242 ++++++++++++++++++++++++++++
3 files changed, 338 insertions(+), 4 deletions(-)
diff --git a/docs/rules/attributes-order.md b/docs/rules/attributes-order.md
index 74b3abaf6..7b44ccc5e 100644
--- a/docs/rules/attributes-order.md
+++ b/docs/rules/attributes-order.md
@@ -143,7 +143,8 @@ Note that `v-bind="object"` syntax is considered to be the same as the next or p
"EVENTS",
"CONTENT"
],
- "alphabetical": false
+ "alphabetical": false,
+ "sortLineLength": false
}]
}
```
@@ -201,6 +202,79 @@ Note that `v-bind="object"` syntax is considered to be the same as the next or p
+### `"sortLineLength": true`
+
+
+
+```vue
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+
+
+### `"alphabetical": true` with `"sortLineLength": true`
+
+When `alphabetical` and `sortLineLength` are both set to `true`, attributes within the same group are sorted primarily by their line length, and then alphabetically as a tie-breaker for attributes with the same length. This provides a clean, predictable attribute order that enhances readability.
+
+
+
+```vue
+
+
+
+
+
+
+
+```
+
+
+
### Custom orders
#### `['LIST_RENDERING', 'CONDITIONALS', 'RENDER_MODIFIERS', 'GLOBAL', 'UNIQUE', 'TWO_WAY_BINDING', 'DEFINITION', 'OTHER_DIRECTIVES', 'OTHER_ATTR', 'EVENTS', 'CONTENT']`
diff --git a/lib/rules/attributes-order.js b/lib/rules/attributes-order.js
index 50c9b452c..8fe461004 100644
--- a/lib/rules/attributes-order.js
+++ b/lib/rules/attributes-order.js
@@ -271,6 +271,9 @@ function create(context) {
const alphabetical = Boolean(
context.options[0] && context.options[0].alphabetical
)
+ const sortLineLength = Boolean(
+ context.options[0] && context.options[0].sortLineLength
+ )
/** @type { { [key: string]: number } } */
const attributePosition = {}
@@ -347,9 +350,23 @@ function create(context) {
const { attr, position } = attributeAndPositions[index]
let valid = previousPosition <= position - if (valid && alphabetical && previousPosition === position) { - valid = isAlphabetical(previousNode, attr, sourceCode) + if (valid && previousPosition === position) { + let sortedByLength = false + if (sortLineLength) { + const prevText = sourceCode.getText(previousNode) + const currText = sourceCode.getText(attr) + + if (prevText.length !== currText.length) { + valid = prevText.length < currText.length + sortedByLength = true + } + } + + if (alphabetical && !sortedByLength) { + valid = isAlphabetical(previousNode, attr, sourceCode) + } } + if (valid) { previousNode = attr previousPosition = position @@ -450,7 +467,8 @@ module.exports = { uniqueItems: true, additionalItems: false }, - alphabetical: { type: 'boolean' } + alphabetical: { type: 'boolean' }, + sortLineLength: { type: 'boolean' } }, additionalProperties: false } diff --git a/tests/lib/rules/attributes-order.js b/tests/lib/rules/attributes-order.js index 79ab47627..ba0c4be1e 100644 --- a/tests/lib/rules/attributes-order.js +++ b/tests/lib/rules/attributes-order.js @@ -617,6 +617,71 @@ tester.run('attributes-order', rule, { alphabetical: false } ] + }, + { + filename: 'test.vue', + code: ` +
+