From d48f6449f2aae2196500985d23c555e12bd5b8c0 Mon Sep 17 00:00:00 2001 From: Stephen Darnell Date: Tue, 27 Feb 2024 16:30:22 +0000 Subject: [PATCH 1/4] feat: Add prefer option to prefer-class-directive This the prefer option can be 'empty' or 'always' with 'empty' being the default. 'always' matches the current behaviour, always insisting on directives 'empty' only prefers directives when one class is empty. --- docs/rules/prefer-class-directive.md | 20 +++++++++++++++++-- src/rules/prefer-class-directive.ts | 16 ++++++++++++++- .../invalid/_config.json | 3 +++ .../prefer-class-directive/valid/_config.json | 3 +++ .../valid/empty/_config.json | 3 +++ .../valid/empty/ignore-test05-input.svelte | 10 ++++++++++ 6 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 tests/fixtures/rules/prefer-class-directive/invalid/_config.json create mode 100644 tests/fixtures/rules/prefer-class-directive/valid/_config.json create mode 100644 tests/fixtures/rules/prefer-class-directive/valid/empty/_config.json create mode 100644 tests/fixtures/rules/prefer-class-directive/valid/empty/ignore-test05-input.svelte diff --git a/docs/rules/prefer-class-directive.md b/docs/rules/prefer-class-directive.md index f026296fa..404c4a1c8 100644 --- a/docs/rules/prefer-class-directive.md +++ b/docs/rules/prefer-class-directive.md @@ -22,13 +22,16 @@ This rule aims to replace a class with ternary operator with the class directive ```svelte + + ``` @@ -40,7 +43,20 @@ You cannot enforce this style by using [prettier-plugin-svelte]. That is, this r ## :wrench: Options -Nothing. +```json +{ + "svelte/html-quotes": [ + "error", + { + "prefer": "empty" // or "always" + } + ] +} +``` + +- `prefer` ... Whether to apply this rule always or just when there's an empty string. Default is `"empty"`. + - `"empty"` ... Requires class directives only if one of the strings is empty. + - `"always"` ... Requires class directives always rather than interpolation. ## :couple: Related Rules diff --git a/src/rules/prefer-class-directive.ts b/src/rules/prefer-class-directive.ts index acd877265..b14a44571 100644 --- a/src/rules/prefer-class-directive.ts +++ b/src/rules/prefer-class-directive.ts @@ -14,7 +14,15 @@ export default createRule('prefer-class-directive', { conflictWithPrettier: false }, fixable: 'code', - schema: [], + schema: [ + { + type: 'object', + properties: { + prefer: { enum: ['always', 'empty'] } + }, + additionalProperties: false + } + ], messages: { unexpected: 'Unexpected class using the ternary operator.' }, @@ -22,6 +30,7 @@ export default createRule('prefer-class-directive', { }, create(context) { const sourceCode = getSourceCode(context); + const preferEmpty = context.options[0]?.prefer !== 'always'; type Expr = { not?: true; @@ -301,6 +310,7 @@ export default createRule('prefer-class-directive', { const prevIsWord = !startsWithNonWord(attr, index + 1); const nextIsWord = !endsWithNonWord(attr, index - 1); let canTransform = true; + let foundEmpty = false; for (const className of map.values()) { if (className) { if (!/^[\w-]*$/u.test(className.trim())) { @@ -317,6 +327,7 @@ export default createRule('prefer-class-directive', { break; } } else { + foundEmpty = true; if (prevIsWord && nextIsWord) { // The previous and next may be connected. canTransform = false; @@ -324,6 +335,9 @@ export default createRule('prefer-class-directive', { } } } + if (preferEmpty && !foundEmpty) { + return; + } if (!canTransform) { return; } diff --git a/tests/fixtures/rules/prefer-class-directive/invalid/_config.json b/tests/fixtures/rules/prefer-class-directive/invalid/_config.json new file mode 100644 index 000000000..78d5d8817 --- /dev/null +++ b/tests/fixtures/rules/prefer-class-directive/invalid/_config.json @@ -0,0 +1,3 @@ +{ + "options": [{ "prefer": "always" }] +} diff --git a/tests/fixtures/rules/prefer-class-directive/valid/_config.json b/tests/fixtures/rules/prefer-class-directive/valid/_config.json new file mode 100644 index 000000000..78d5d8817 --- /dev/null +++ b/tests/fixtures/rules/prefer-class-directive/valid/_config.json @@ -0,0 +1,3 @@ +{ + "options": [{ "prefer": "always" }] +} diff --git a/tests/fixtures/rules/prefer-class-directive/valid/empty/_config.json b/tests/fixtures/rules/prefer-class-directive/valid/empty/_config.json new file mode 100644 index 000000000..0a335cc5a --- /dev/null +++ b/tests/fixtures/rules/prefer-class-directive/valid/empty/_config.json @@ -0,0 +1,3 @@ +{ + "options": [{ "prefer": "empty" }] +} diff --git a/tests/fixtures/rules/prefer-class-directive/valid/empty/ignore-test05-input.svelte b/tests/fixtures/rules/prefer-class-directive/valid/empty/ignore-test05-input.svelte new file mode 100644 index 000000000..3e768870b --- /dev/null +++ b/tests/fixtures/rules/prefer-class-directive/valid/empty/ignore-test05-input.svelte @@ -0,0 +1,10 @@ + + + + + + From 125964c75e95d95986a396b7c257e541d03a54d7 Mon Sep 17 00:00:00 2001 From: Stephen Darnell Date: Tue, 27 Feb 2024 16:47:39 +0000 Subject: [PATCH 2/4] Add changeset and prettier fixup on .md file. --- .changeset/popular-hotels-invent.md | 5 +++++ docs/rules/prefer-class-directive.md | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 .changeset/popular-hotels-invent.md diff --git a/.changeset/popular-hotels-invent.md b/.changeset/popular-hotels-invent.md new file mode 100644 index 000000000..f68821fe7 --- /dev/null +++ b/.changeset/popular-hotels-invent.md @@ -0,0 +1,5 @@ +--- +"eslint-plugin-svelte": minor +--- + +Added prefer option to prefer-class-directive rule ('always' or 'empty'). The default is now 'empty' which is a slight relaxation of the rule. diff --git a/docs/rules/prefer-class-directive.md b/docs/rules/prefer-class-directive.md index 404c4a1c8..bee8d0997 100644 --- a/docs/rules/prefer-class-directive.md +++ b/docs/rules/prefer-class-directive.md @@ -27,7 +27,7 @@ This rule aims to replace a class with ternary operator with the class directive - + @@ -55,8 +55,8 @@ You cannot enforce this style by using [prettier-plugin-svelte]. That is, this r ``` - `prefer` ... Whether to apply this rule always or just when there's an empty string. Default is `"empty"`. - - `"empty"` ... Requires class directives only if one of the strings is empty. - - `"always"` ... Requires class directives always rather than interpolation. + - `"empty"` ... Requires class directives only if one of the strings is empty. + - `"always"` ... Requires class directives always rather than interpolation. ## :couple: Related Rules From e896d7af3b9c17ea6d1197e38f36fe0a9a8ce61f Mon Sep 17 00:00:00 2001 From: Stephen Darnell Date: Tue, 27 Feb 2024 19:43:02 +0000 Subject: [PATCH 3/4] Fix lint issues --- .../rules/prefer-class-directive/invalid/_config.json | 2 +- .../rules/prefer-class-directive/valid/_config.json | 2 +- .../rules/prefer-class-directive/valid/empty/_config.json | 2 +- .../valid/empty/ignore-test05-input.svelte | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/fixtures/rules/prefer-class-directive/invalid/_config.json b/tests/fixtures/rules/prefer-class-directive/invalid/_config.json index 78d5d8817..e04cbf0cf 100644 --- a/tests/fixtures/rules/prefer-class-directive/invalid/_config.json +++ b/tests/fixtures/rules/prefer-class-directive/invalid/_config.json @@ -1,3 +1,3 @@ { - "options": [{ "prefer": "always" }] + "options": [{ "prefer": "always" }] } diff --git a/tests/fixtures/rules/prefer-class-directive/valid/_config.json b/tests/fixtures/rules/prefer-class-directive/valid/_config.json index 78d5d8817..e04cbf0cf 100644 --- a/tests/fixtures/rules/prefer-class-directive/valid/_config.json +++ b/tests/fixtures/rules/prefer-class-directive/valid/_config.json @@ -1,3 +1,3 @@ { - "options": [{ "prefer": "always" }] + "options": [{ "prefer": "always" }] } diff --git a/tests/fixtures/rules/prefer-class-directive/valid/empty/_config.json b/tests/fixtures/rules/prefer-class-directive/valid/empty/_config.json index 0a335cc5a..33a273416 100644 --- a/tests/fixtures/rules/prefer-class-directive/valid/empty/_config.json +++ b/tests/fixtures/rules/prefer-class-directive/valid/empty/_config.json @@ -1,3 +1,3 @@ { - "options": [{ "prefer": "empty" }] + "options": [{ "prefer": "empty" }] } diff --git a/tests/fixtures/rules/prefer-class-directive/valid/empty/ignore-test05-input.svelte b/tests/fixtures/rules/prefer-class-directive/valid/empty/ignore-test05-input.svelte index 3e768870b..c149c438e 100644 --- a/tests/fixtures/rules/prefer-class-directive/valid/empty/ignore-test05-input.svelte +++ b/tests/fixtures/rules/prefer-class-directive/valid/empty/ignore-test05-input.svelte @@ -4,7 +4,7 @@ let danger = false; - - - + + + From e74d997de0f36250970e650b66229dd086c1b097 Mon Sep 17 00:00:00 2001 From: Stephen Darnell Date: Wed, 28 Feb 2024 16:41:08 +0000 Subject: [PATCH 4/4] fix: Add invalid test for empty setting, and fix markdown example Also now considers the trimmed class name when looking for empty strings. --- docs/rules/prefer-class-directive.md | 2 +- src/rules/prefer-class-directive.ts | 10 +++++----- .../invalid/empty/test01-errors.yaml | 20 +++++++++++++++++++ .../invalid/empty/test01-input.svelte | 13 ++++++++++++ .../invalid/empty/test01-output.svelte | 13 ++++++++++++ 5 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 tests/fixtures/rules/prefer-class-directive/invalid/empty/test01-errors.yaml create mode 100644 tests/fixtures/rules/prefer-class-directive/invalid/empty/test01-input.svelte create mode 100644 tests/fixtures/rules/prefer-class-directive/invalid/empty/test01-output.svelte diff --git a/docs/rules/prefer-class-directive.md b/docs/rules/prefer-class-directive.md index bee8d0997..1841be9e3 100644 --- a/docs/rules/prefer-class-directive.md +++ b/docs/rules/prefer-class-directive.md @@ -22,7 +22,7 @@ This rule aims to replace a class with ternary operator with the class directive ```svelte diff --git a/src/rules/prefer-class-directive.ts b/src/rules/prefer-class-directive.ts index b14a44571..7e4897e61 100644 --- a/src/rules/prefer-class-directive.ts +++ b/src/rules/prefer-class-directive.ts @@ -307,10 +307,14 @@ export default createRule('prefer-class-directive', { // It's too complicated. return; } + if (preferEmpty && [...map.values()].every((x) => x.trim())) { + // We prefer directives when there's an empty string, but they're all not empty + return; + } + const prevIsWord = !startsWithNonWord(attr, index + 1); const nextIsWord = !endsWithNonWord(attr, index - 1); let canTransform = true; - let foundEmpty = false; for (const className of map.values()) { if (className) { if (!/^[\w-]*$/u.test(className.trim())) { @@ -327,7 +331,6 @@ export default createRule('prefer-class-directive', { break; } } else { - foundEmpty = true; if (prevIsWord && nextIsWord) { // The previous and next may be connected. canTransform = false; @@ -335,9 +338,6 @@ export default createRule('prefer-class-directive', { } } } - if (preferEmpty && !foundEmpty) { - return; - } if (!canTransform) { return; } diff --git a/tests/fixtures/rules/prefer-class-directive/invalid/empty/test01-errors.yaml b/tests/fixtures/rules/prefer-class-directive/invalid/empty/test01-errors.yaml new file mode 100644 index 000000000..f8153d158 --- /dev/null +++ b/tests/fixtures/rules/prefer-class-directive/invalid/empty/test01-errors.yaml @@ -0,0 +1,20 @@ +- message: Unexpected class using the ternary operator. + line: 6 + column: 15 + suggestions: null +- message: Unexpected class using the ternary operator. + line: 7 + column: 18 + suggestions: null +- message: Unexpected class using the ternary operator. + line: 8 + column: 17 + suggestions: null +- message: Unexpected class using the ternary operator. + line: 10 + column: 20 + suggestions: null +- message: Unexpected class using the ternary operator. + line: 11 + column: 20 + suggestions: null diff --git a/tests/fixtures/rules/prefer-class-directive/invalid/empty/test01-input.svelte b/tests/fixtures/rules/prefer-class-directive/invalid/empty/test01-input.svelte new file mode 100644 index 000000000..09c60d75a --- /dev/null +++ b/tests/fixtures/rules/prefer-class-directive/invalid/empty/test01-input.svelte @@ -0,0 +1,13 @@ + + + + + + +
foo
+
foo
+ + diff --git a/tests/fixtures/rules/prefer-class-directive/invalid/empty/test01-output.svelte b/tests/fixtures/rules/prefer-class-directive/invalid/empty/test01-output.svelte new file mode 100644 index 000000000..3d6470290 --- /dev/null +++ b/tests/fixtures/rules/prefer-class-directive/invalid/empty/test01-output.svelte @@ -0,0 +1,13 @@ + + + + + + +
1}>foo
+
foo
+ +