feat(lint): noInvalidGridTemplateAreas
ADD
internal/compiler/lint/rules/css/noInvalidGridTemplateAreas.test.rjson
+filename: "filename.css"
+invalid: [
+ "
+ a { grid-template-areas: \"a a a\"
+ \"b b\"; }
+ "
+ "
+ a { grid-template-areas: \"a\" \"b b\"; }
+ "
+]
+valid: [
+ "
+ a { grid-template-areas: \"a a a\"
+ \"b b b\"; } "
+ "
+ a { grid-template-areas: none; }
+ "
+]

ADD
internal/compiler/lint/rules/css/noInvalidGridTemplateAreas.ts
+import {createVisitor, signals} from "@internal/compiler";
+import {descriptions} from "@internal/diagnostics";
+import {CSSString} from "@internal/ast";
+
+export default createVisitor({
+ name: "css/noInvalidGridTemplateAreas",
+ enter(path) {
+ const {node} = path;
+
+ if (
+ node.type === "CSSDeclaration" &&
+ node.name === "grid-template-areas" &&
+ node.value.length > 0
+ ) {
+ let length: null | number;
+ let incorrectNode: null | CSSString = null;
+ const correct = node.value.every((child) => {
+ if (child?.type === "CSSString") {
+ const childLength = child.value.split(" ").length;
+ if (length) {
+ const correct = childLength === length;
+ if (!correct) {
+ incorrectNode = child;
+ }
+ return correct;
+ } else {
+ length = childLength;
+ return true;
+ }
+ }
+ return true;
+ });
+ if (!correct) {
+ path.context.addNodeDiagnostic(
+ incorrectNode ?? node,
+ descriptions.LINT.CSS_NO_INVALID_GRID_TEMPLATE_AREAS,
+ );
+ }
+ }
+
+ return signals.retain;
+ },
+});

MODIFY
internal/compiler/lint/rules/index.ts
internal/compiler/lint/rules/index.ts
-/* GENERATED:START(hash:a89fe3228dc278f23598d2f5d0d0971ebc4040ef,id:main) Everything below is automatically generated. DO NOT MODIFY. Run `./rome run scripts/generated-files/lint-rules` to update. */
+/* GENERATED:START(hash:cbdd144ad35350b9a2f9b4864c8e217f28ce8a7c,id:main) Everything below is automatically generated. DO NOT MODIFY. Run `./rome run scripts/generated-files/lint-rules` to update. */
import noAriaUnsupportedElements from "./a11y/noAriaUnsupportedElements";
import noAutofocus from "./a11y/noAutofocus";
import noDistractingElements from "./a11y/noDistractingElements";
@@ -16,6 +16,7 @@ import useIframeTitle from "./a11y/useIframeTitle";
import useMediaCaption from "./a11y/useMediaCaption";
import useValidLang from "./a11y/useValidLang";
import noImportantInKeyframes from "./css/noImportantInKeyframes";
+import noInvalidGridTemplateAreas from "./css/noInvalidGridTemplateAreas";
import useClosingNonVoid from "./html/useClosingNonVoid";
import noArguments from "./js/noArguments";
import noAsyncPromiseExecutor from "./js/noAsyncPromiseExecutor";
@@ -138,6 +139,7 @@ lintTransforms.set("a11y/useIframeTitle", useIframeTitle);
lintTransforms.set("a11y/useMediaCaption", useMediaCaption);
lintTransforms.set("a11y/useValidLang", useValidLang);
lintTransforms.set("css/noImportantInKeyframes", noImportantInKeyframes);
+lintTransforms.set("css/noInvalidGridTemplateAreas", noInvalidGridTemplateAreas);
lintTransforms.set("html/useClosingNonVoid", useClosingNonVoid);
lintTransforms.set("js/noArguments", noArguments);
lintTransforms.set("js/noAsyncPromiseExecutor", noAsyncPromiseExecutor);
@@ -283,6 +285,7 @@ export const lintRuleNames: LintRuleName[] = [
"a11y/useMediaCaption",
"a11y/useValidLang",
"css/noImportantInKeyframes",
+ "css/noInvalidGridTemplateAreas",
"html/useClosingNonVoid",
"js/noArguments",
"js/noAsyncPromiseExecutor",
@@ -402,6 +405,7 @@ export type LintRuleName =
| "a11y/useMediaCaption"
| "a11y/useValidLang"
| "css/noImportantInKeyframes"
+ | "css/noInvalidGridTemplateAreas"
| "html/useClosingNonVoid"
| "js/noArguments"
| "js/noAsyncPromiseExecutor"

MODIFY
internal/compiler/lint/rules/tests.ts
internal/compiler/lint/rules/tests.ts
@@ -12,7 +12,7 @@ type Tests = Dict<{
cases: Test | Test[] | Test[][];
}>;
-/* GENERATED:START(hash:f6dacea8b47c0c2b4a91664233f25f3076faeafb,id:main) Everything below is automatically generated. DO NOT MODIFY. Run `./rome run scripts/generated-files/lint-rules` to update. */
+/* GENERATED:START(hash:379956f6eedd25af39a14faa3aaad5c35838a6a9,id:main) Everything below is automatically generated. DO NOT MODIFY. Run `./rome run scripts/generated-files/lint-rules` to update. */
// @ts-ignore
import noAriaUnsupportedElements from "./a11y/noAriaUnsupportedElements.test.rjson";
// @ts-ignore
@@ -48,6 +48,8 @@ import useValidLang from "./a11y/useValidLang.test.rjson";
// @ts-ignore
import noImportantInKeyframes from "./css/noImportantInKeyframes.test.rjson";
// @ts-ignore
+import noInvalidGridTemplateAreas from "./css/noInvalidGridTemplateAreas.test.rjson";
+// @ts-ignore
import useClosingNonVoid from "./html/useClosingNonVoid.test.rjson";
// @ts-ignore
import noArguments from "./js/noArguments.test.rjson";
@@ -305,6 +307,10 @@ export const tests: Tests = {
category: ["lint", "css", "noImportantInKeyframes"],
cases: noImportantInKeyframes,
},
+ "css/noInvalidGridTemplateAreas": {
+ category: ["lint", "css", "noInvalidGridTemplateAreas"],
+ cases: noInvalidGridTemplateAreas,
+ },
"html/useClosingNonVoid": {
category: ["lint", "html", "useClosingNonVoid"],
cases: useClosingNonVoid,

MODIFY
internal/diagnostics/categories.ts
internal/diagnostics/categories.ts
@@ -103,7 +103,7 @@ type DiagnosticCategoryString = StringConverter<DiagnosticCategory>;
type DiagnosticLintCategoryString = StringConverter<DiagnosticLintCategory>;
-/* GENERATED:START(hash:76e2abea0885f8ec89a6807c0ea8a62d46899879,id:main) Everything below is automatically generated. DO NOT MODIFY. Run `./rome run scripts/generated-files/lint-rules` to update. */
+/* GENERATED:START(hash:29617e7b360b4bd3bcfbacd81e8f7fa09ee42291,id:main) Everything below is automatically generated. DO NOT MODIFY. Run `./rome run scripts/generated-files/lint-rules` to update. */
export type DiagnosticLintCategory =
| ["lint", "a11y", "noAriaUnsupportedElements"]
| ["lint", "a11y", "noAutofocus"]
@@ -122,6 +122,7 @@ export type DiagnosticLintCategory =
| ["lint", "a11y", "useMediaCaption"]
| ["lint", "a11y", "useValidLang"]
| ["lint", "css", "noImportantInKeyframes"]
+ | ["lint", "css", "noInvalidGridTemplateAreas"]
| ["lint", "html", "useClosingNonVoid"]
| ["lint", "js", "noArguments"]
| ["lint", "js", "noAsyncPromiseExecutor"]
@@ -253,6 +254,11 @@ const lintCategoryNameMap: {
"lint/a11y/useMediaCaption": ["lint", "a11y", "useMediaCaption"],
"lint/a11y/useValidLang": ["lint", "a11y", "useValidLang"],
"lint/css/noImportantInKeyframes": ["lint", "css", "noImportantInKeyframes"],
+ "lint/css/noInvalidGridTemplateAreas": [
+ "lint",
+ "css",
+ "noInvalidGridTemplateAreas",
+ ],
"lint/html/useClosingNonVoid": ["lint", "html", "useClosingNonVoid"],
"lint/js/noArguments": ["lint", "js", "noArguments"],
"lint/js/noAsyncPromiseExecutor": ["lint", "js", "noAsyncPromiseExecutor"],

MODIFY
internal/diagnostics/descriptions/lint.ts
internal/diagnostics/descriptions/lint.ts
@@ -17,6 +17,10 @@ import {addEmphasis, createDiagnosticsCategory, orJoin} from "./index";
import {DIAGNOSTIC_CATEGORIES} from "../categories";
export const lint = createDiagnosticsCategory({
+ CSS_NO_INVALID_GRID_TEMPLATE_AREAS: {
+ category: DIAGNOSTIC_CATEGORIES["lint/css/noInvalidGridTemplateAreas"],
+ message: markup`All strings must have the same number of cell tokens`,
+ },
CSS_NO_IMPORTANT_IN_KEYFRAME: {
category: DIAGNOSTIC_CATEGORIES["lint/css/noImportantInKeyframes"],
message: markup`Using <emphasis>!important</emphasis> within keyframes declarations is completely ignored in some browsers.`,

MODIFY
website/src/docs/lint/rules/index.md
website/src/docs/lint/rules/index.md
@@ -11,7 +11,7 @@ eleventyNavigation:
# Rules
-<!-- GENERATED:START(hash:7dabac07385724d2e48a0352a8ecba14e6c4c199,id:main) Everything below is automatically generated. DO NOT MODIFY. Run `./rome run scripts/generated-files/lint-rules` to update. -->
+<!-- GENERATED:START(hash:7d439f5d88279866e2e455a537db46efca81646d,id:main) Everything below is automatically generated. DO NOT MODIFY. Run `./rome run scripts/generated-files/lint-rules` to update. -->
<section>
<h2>JavaScript</h2>
<p>Rule semantics and descriptions taken from <a href="https://eslint.org/">ESLint</a>. See individual rule docs for direct references.</p>
@@ -749,5 +749,12 @@ enforce style prop value is an object
</h3>
disallow `!important` in `@keyframe` rules
</div>
+<div class="rule">
+<h3 data-toc-exclude id="noInvalidGridTemplateAreas">
+ <a href="/docs/lint/rules/css/noInvalidGridTemplateAreas">noInvalidGridTemplateAreas</a>
+ <a class="header-anchor" href="#noInvalidGridTemplateAreas"></a>
+</h3>
+checks that `grid-template-areas` have valid names
+</div>
</section>
<!-- GENERATED:END(id:main) -->

feat(lint): noInvalidGridTemplateAreas (#1420)