diff --git a/.changeset/swift-ads-type.md b/.changeset/swift-ads-type.md new file mode 100644 index 000000000..e7394f1e3 --- /dev/null +++ b/.changeset/swift-ads-type.md @@ -0,0 +1,5 @@ +--- +"eslint-plugin-svelte": minor +--- + +feat(html-self-closing): add configuration presets diff --git a/.gitignore b/.gitignore index abaddc83f..7f4f50363 100644 --- a/.gitignore +++ b/.gitignore @@ -50,8 +50,8 @@ jspm_packages/ # Optional npm cache directory .npm -# Optional eslint cache -.eslintcache +# Optional eslint/stylelint cache, etc +.*cache # Microbundle cache .rpt2_cache/ diff --git a/docs/rules/html-self-closing.md b/docs/rules/html-self-closing.md index b60b8abae..95e8c1431 100644 --- a/docs/rules/html-self-closing.md +++ b/docs/rules/html-self-closing.md @@ -50,26 +50,43 @@ You can choose either two styles for elements without content ## :wrench: Options +presets: +```jsonc +{ + "svelte/html-self-closing": [ + "error", + "all", // or "html" or "none" + ] +} +``` + +config object: ```jsonc { "svelte/html-self-closing": [ "error", { - "void": "always", // or "always" or "ignore" + "void": "always", // or "never" or "ignore" "normal": "always", // or "never" or "ignore" "component": "always", // or "never" or "ignore" - "svelte": "always" // or "never" or "ignore" + "svelte": "always" // or "never" or "igore" } ] } ``` -- `void` (`"always"` by default)... Style of HTML void elements -- `component` (`"always"` by default)... Style of svelte components -- `svelte` (`"always"` by default)... Style of svelte special elements (``, ``) -- `normal` (`"always"` by default)... Style of other elements +presets: +- `all` - all elements should be self closing (unless they have children) +- `html` - html-compliant - only void elements and svelte special elements should be self closing +- `none` - no elements should be self closing + +config object: +- `void` (`"always"` in default preset)... Style of HTML void elements +- `component` (`"always"` in default preset)... Style of svelte components +- `svelte` (`"always"` in default preset)... Style of svelte special elements (``, ``) +- `normal` (`"always"` in default preset)... Style of other elements -Every option can be set to +Every config oject option can be set to - "always" (`
`) - "never" (`
`) - "ignore" (either `
` or `
`) diff --git a/package.json b/package.json index 709751d6a..53e6e5037 100644 --- a/package.json +++ b/package.json @@ -171,7 +171,7 @@ "access": "public" }, "typeCoverage": { - "atLeast": 98.62, + "atLeast": 98.63, "cache": true, "detail": true, "ignoreAsAssertion": true, diff --git a/src/rules/html-self-closing.ts b/src/rules/html-self-closing.ts index 6e10d65e2..186545c95 100644 --- a/src/rules/html-self-closing.ts +++ b/src/rules/html-self-closing.ts @@ -27,32 +27,66 @@ export default createRule("html-self-closing", { }, schema: [ { - type: "object", - properties: { - void: { - enum: ["never", "always", "ignore"], + anyOf: [ + { + properties: { + void: { + enum: ["never", "always", "ignore"], + }, + normal: { + enum: ["never", "always", "ignore"], + }, + component: { + enum: ["never", "always", "ignore"], + }, + svelte: { + enum: ["never", "always", "ignore"], + }, + }, + additionalProperties: false, }, - normal: { - enum: ["never", "always", "ignore"], + { + enum: ["all", "html", "none"], }, - component: { - enum: ["never", "always", "ignore"], - }, - svelte: { - enum: ["never", "always", "ignore"], - }, - }, - additionalProperties: false, + ], }, ], }, create(ctx) { - const options = { + let options = { void: "always", normal: "always", component: "always", svelte: "always", - ...ctx.options?.[0], + } + + const option = ctx.options?.[0] + switch (option) { + case "none": + options = { + void: "never", + normal: "never", + component: "never", + svelte: "never", + } + break + case "html": + options = { + void: "always", + normal: "never", + component: "never", + svelte: "always", + } + break + default: + if (typeof option !== "object" || option === null) break + + options = { + ...options, + ...option, + } + + break } /** diff --git a/tests/fixtures/rules/html-self-closing/invalid/presets/html/_config.json b/tests/fixtures/rules/html-self-closing/invalid/presets/html/_config.json new file mode 100644 index 000000000..19b1fd542 --- /dev/null +++ b/tests/fixtures/rules/html-self-closing/invalid/presets/html/_config.json @@ -0,0 +1,3 @@ +{ + "options": ["html"] +} diff --git a/tests/fixtures/rules/html-self-closing/invalid/presets/html/preset-html-errors.json b/tests/fixtures/rules/html-self-closing/invalid/presets/html/preset-html-errors.json new file mode 100644 index 000000000..ecd2cc2d7 --- /dev/null +++ b/tests/fixtures/rules/html-self-closing/invalid/presets/html/preset-html-errors.json @@ -0,0 +1,22 @@ +[ + { + "message": "Disallow self-closing on HTML elements.", + "line": 3, + "column": 3 + }, + { + "message": "Require self-closing on HTML void elements.", + "line": 4, + "column": 3 + }, + { + "message": "Disallow self-closing on Svelte custom components.", + "line": 5, + "column": 3 + }, + { + "message": "Require self-closing on Svelte special elements.", + "line": 8, + "column": 1 + } +] diff --git a/tests/fixtures/rules/html-self-closing/invalid/presets/html/preset-html-input.svelte b/tests/fixtures/rules/html-self-closing/invalid/presets/html/preset-html-input.svelte new file mode 100644 index 000000000..35dc286b6 --- /dev/null +++ b/tests/fixtures/rules/html-self-closing/invalid/presets/html/preset-html-input.svelte @@ -0,0 +1,8 @@ + +
+
+ + +
+ + diff --git a/tests/fixtures/rules/html-self-closing/invalid/presets/html/preset-html-output.svelte b/tests/fixtures/rules/html-self-closing/invalid/presets/html/preset-html-output.svelte new file mode 100644 index 000000000..c93424600 --- /dev/null +++ b/tests/fixtures/rules/html-self-closing/invalid/presets/html/preset-html-output.svelte @@ -0,0 +1,8 @@ + +
+
+ + +
+ + diff --git a/tests/fixtures/rules/html-self-closing/invalid/presets/none/_config.json b/tests/fixtures/rules/html-self-closing/invalid/presets/none/_config.json new file mode 100644 index 000000000..7e9785c01 --- /dev/null +++ b/tests/fixtures/rules/html-self-closing/invalid/presets/none/_config.json @@ -0,0 +1,3 @@ +{ + "options": ["none"] +} diff --git a/tests/fixtures/rules/html-self-closing/invalid/presets/none/preset-none-errors.json b/tests/fixtures/rules/html-self-closing/invalid/presets/none/preset-none-errors.json new file mode 100644 index 000000000..e3fcdeb40 --- /dev/null +++ b/tests/fixtures/rules/html-self-closing/invalid/presets/none/preset-none-errors.json @@ -0,0 +1,22 @@ +[ + { + "message": "Disallow self-closing on HTML elements.", + "line": 3, + "column": 3 + }, + { + "message": "Disallow self-closing on Svelte custom components.", + "line": 4, + "column": 3 + }, + { + "message": "Disallow self-closing on HTML void elements.", + "line": 5, + "column": 3 + }, + { + "message": "Disallow self-closing on Svelte special elements.", + "line": 8, + "column": 1 + } +] diff --git a/tests/fixtures/rules/html-self-closing/invalid/presets/none/preset-none-input.svelte b/tests/fixtures/rules/html-self-closing/invalid/presets/none/preset-none-input.svelte new file mode 100644 index 000000000..61675d719 --- /dev/null +++ b/tests/fixtures/rules/html-self-closing/invalid/presets/none/preset-none-input.svelte @@ -0,0 +1,8 @@ + +
+
+ + +
+ + diff --git a/tests/fixtures/rules/html-self-closing/invalid/presets/none/preset-none-output.svelte b/tests/fixtures/rules/html-self-closing/invalid/presets/none/preset-none-output.svelte new file mode 100644 index 000000000..42d0a6c5c --- /dev/null +++ b/tests/fixtures/rules/html-self-closing/invalid/presets/none/preset-none-output.svelte @@ -0,0 +1,8 @@ + +
+
+ + +
+ +