@flint.fyi/jsx 0.0.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/LICENSE.md +20 -0
  2. package/lib/index.js +1 -2
  3. package/lib/plugin.d.ts +309 -1
  4. package/lib/plugin.js +12 -6
  5. package/lib/rules/accessKeys.d.ts +8 -1
  6. package/lib/rules/accessKeys.js +2 -3
  7. package/lib/rules/altTexts.d.ts +8 -1
  8. package/lib/rules/altTexts.js +6 -16
  9. package/lib/rules/anchorAmbiguousText.d.ts +8 -1
  10. package/lib/rules/anchorAmbiguousText.js +2 -5
  11. package/lib/rules/anchorContent.d.ts +8 -1
  12. package/lib/rules/anchorContent.js +2 -3
  13. package/lib/rules/anchorValidity.d.ts +8 -1
  14. package/lib/rules/anchorValidity.js +4 -5
  15. package/lib/rules/ariaActiveDescendantTabIndex.d.ts +8 -1
  16. package/lib/rules/ariaActiveDescendantTabIndex.js +4 -7
  17. package/lib/rules/ariaHiddenFocusables.d.ts +8 -1
  18. package/lib/rules/ariaHiddenFocusables.js +7 -9
  19. package/lib/rules/ariaPropTypes.d.ts +8 -1
  20. package/lib/rules/ariaPropTypes.js +6 -9
  21. package/lib/rules/ariaProps.d.ts +8 -1
  22. package/lib/rules/ariaProps.js +2 -3
  23. package/lib/rules/ariaRoleValidity.d.ts +8 -1
  24. package/lib/rules/ariaRoleValidity.js +3 -4
  25. package/lib/rules/ariaUnsupportedElements.d.ts +8 -1
  26. package/lib/rules/ariaUnsupportedElements.js +2 -3
  27. package/lib/rules/autoFocusProps.d.ts +8 -1
  28. package/lib/rules/autoFocusProps.js +4 -6
  29. package/lib/rules/autocomplete.d.ts +8 -1
  30. package/lib/rules/autocomplete.js +3 -4
  31. package/lib/rules/booleanValues.d.ts +8 -1
  32. package/lib/rules/booleanValues.js +2 -3
  33. package/lib/rules/bracedStatements.d.ts +8 -1
  34. package/lib/rules/bracedStatements.js +1 -2
  35. package/lib/rules/buttonTypes.d.ts +8 -1
  36. package/lib/rules/buttonTypes.js +3 -4
  37. package/lib/rules/childrenProps.d.ts +8 -1
  38. package/lib/rules/childrenProps.js +1 -2
  39. package/lib/rules/clickEventKeyEvents.d.ts +8 -1
  40. package/lib/rules/clickEventKeyEvents.js +2 -3
  41. package/lib/rules/commentTextNodes.d.ts +8 -1
  42. package/lib/rules/commentTextNodes.js +2 -3
  43. package/lib/rules/distractingElements.d.ts +8 -1
  44. package/lib/rules/distractingElements.js +2 -3
  45. package/lib/rules/elementChildrenValidity.d.ts +8 -1
  46. package/lib/rules/elementChildrenValidity.js +1 -2
  47. package/lib/rules/headingContents.d.ts +8 -1
  48. package/lib/rules/headingContents.js +5 -6
  49. package/lib/rules/htmlLangs.d.ts +8 -1
  50. package/lib/rules/htmlLangs.js +2 -3
  51. package/lib/rules/iframeTitles.d.ts +8 -1
  52. package/lib/rules/iframeTitles.js +3 -4
  53. package/lib/rules/interactiveElementRoles.d.ts +8 -1
  54. package/lib/rules/interactiveElementRoles.js +3 -4
  55. package/lib/rules/interactiveElementsFocusable.d.ts +8 -1
  56. package/lib/rules/interactiveElementsFocusable.js +7 -8
  57. package/lib/rules/labelAssociatedControls.d.ts +8 -1
  58. package/lib/rules/labelAssociatedControls.js +6 -7
  59. package/lib/rules/langValidity.d.ts +8 -1
  60. package/lib/rules/langValidity.js +1 -2
  61. package/lib/rules/mediaCaptions.d.ts +8 -1
  62. package/lib/rules/mediaCaptions.js +12 -13
  63. package/lib/rules/mouseEventKeyEvents.d.ts +8 -1
  64. package/lib/rules/mouseEventKeyEvents.js +2 -3
  65. package/lib/rules/nonInteractiveElementInteractions.d.ts +8 -1
  66. package/lib/rules/nonInteractiveElementInteractions.js +3 -4
  67. package/lib/rules/nonInteractiveElementRoles.d.ts +8 -1
  68. package/lib/rules/nonInteractiveElementRoles.js +3 -4
  69. package/lib/rules/nonInteractiveElementTabIndexes.d.ts +8 -1
  70. package/lib/rules/nonInteractiveElementTabIndexes.js +7 -8
  71. package/lib/rules/propDuplicates.d.ts +8 -1
  72. package/lib/rules/propDuplicates.js +2 -3
  73. package/lib/rules/roleRedundancies.d.ts +8 -1
  74. package/lib/rules/roleRedundancies.js +3 -4
  75. package/lib/rules/roleRequiredAriaProps.d.ts +8 -1
  76. package/lib/rules/roleRequiredAriaProps.js +3 -4
  77. package/lib/rules/roleSupportedAriaProps.d.ts +8 -1
  78. package/lib/rules/roleSupportedAriaProps.js +3 -4
  79. package/lib/rules/roleTags.d.ts +8 -1
  80. package/lib/rules/roleTags.js +2 -3
  81. package/lib/rules/ruleCreator.js +1 -2
  82. package/lib/rules/scopeProps.d.ts +8 -1
  83. package/lib/rules/scopeProps.js +2 -3
  84. package/lib/rules/staticElementInteractions.d.ts +8 -1
  85. package/lib/rules/staticElementInteractions.js +2 -3
  86. package/lib/rules/svgTitles.d.ts +8 -1
  87. package/lib/rules/svgTitles.js +5 -6
  88. package/lib/rules/tabIndexPositiveValues.d.ts +8 -1
  89. package/lib/rules/tabIndexPositiveValues.js +4 -5
  90. package/lib/rules/unescapedEntities.d.ts +8 -1
  91. package/lib/rules/unescapedEntities.js +1 -2
  92. package/lib/rules/unnecessaryFragments.d.ts +8 -1
  93. package/lib/rules/unnecessaryFragments.js +3 -4
  94. package/package.json +46 -51
  95. package/lib/jsx.d.ts +0 -8
  96. package/lib/jsx.js +0 -100
@@ -1,12 +1,11 @@
1
1
  import { ruleCreator } from "./ruleCreator.js";
2
2
  import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
3
-
4
3
  //#region src/rules/commentTextNodes.ts
5
4
  var commentTextNodes_default = ruleCreator.createRule(typescriptLanguage, {
6
5
  about: {
7
6
  description: "Reports JSX text nodes that contain comment syntax but are rendered as text.",
8
7
  id: "commentTextNodes",
9
- presets: ["logical"]
8
+ presets: ["logical", "logicalStrict"]
10
9
  },
11
10
  messages: { commentAsText: {
12
11
  primary: "This text looks like a comment but will be rendered as text in the JSX output.",
@@ -27,7 +26,7 @@ var commentTextNodes_default = ruleCreator.createRule(typescriptLanguage, {
27
26
  } } };
28
27
  }
29
28
  });
30
-
31
29
  //#endregion
32
30
  export { commentTextNodes_default as default };
31
+
33
32
  //# sourceMappingURL=commentTextNodes.js.map
@@ -1,3 +1,10 @@
1
- declare const _default: import("@flint.fyi/core").Rule<import("@flint.fyi/core").RuleAboutWithPresetsAndUrl<"logical" | "logicalStrict" | "stylistic">, object, object, "noDistractingElement", import("@flint.fyi/core").AnyOptionalSchema>;
1
+ declare const _default: import("@flint.fyi/core").Rule<{
2
+ readonly description: "Reports distracting elements like <marquee> and <blink>.";
3
+ readonly id: "distractingElements";
4
+ readonly presets: ["logical", "logicalStrict"];
5
+ } & {
6
+ presets?: ("logical" | "logicalStrict" | "stylistic")[];
7
+ url: string;
8
+ }, object, object, "noDistractingElement", import("@flint.fyi/core").AnyOptionalSchema>;
2
9
  export default _default;
3
10
  //# sourceMappingURL=distractingElements.d.ts.map
@@ -1,14 +1,13 @@
1
1
  import { ruleCreator } from "./ruleCreator.js";
2
2
  import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
3
3
  import { SyntaxKind } from "typescript";
4
-
5
4
  //#region src/rules/distractingElements.ts
6
5
  const distractingElements = new Set(["blink", "marquee"]);
7
6
  var distractingElements_default = ruleCreator.createRule(typescriptLanguage, {
8
7
  about: {
9
8
  description: "Reports distracting elements like <marquee> and <blink>.",
10
9
  id: "distractingElements",
11
- presets: ["logical"]
10
+ presets: ["logical", "logicalStrict"]
12
11
  },
13
12
  messages: { noDistractingElement: {
14
13
  primary: "The <{{ element }}> element is distracting and deprecated.",
@@ -35,7 +34,7 @@ var distractingElements_default = ruleCreator.createRule(typescriptLanguage, {
35
34
  } };
36
35
  }
37
36
  });
38
-
39
37
  //#endregion
40
38
  export { distractingElements_default as default };
39
+
41
40
  //# sourceMappingURL=distractingElements.js.map
@@ -1,3 +1,10 @@
1
- declare const _default: import("@flint.fyi/core").Rule<import("@flint.fyi/core").RuleAboutWithPresetsAndUrl<"logical" | "logicalStrict" | "stylistic">, object, object, "voidElementWithChildren", import("@flint.fyi/core").AnyOptionalSchema>;
1
+ declare const _default: import("@flint.fyi/core").Rule<{
2
+ readonly description: "Reports void DOM elements that have children, which is invalid HTML.";
3
+ readonly id: "elementChildrenValidity";
4
+ readonly presets: ["logical", "logicalStrict"];
5
+ } & {
6
+ presets?: ("logical" | "logicalStrict" | "stylistic")[];
7
+ url: string;
8
+ }, object, object, "voidElementWithChildren", import("@flint.fyi/core").AnyOptionalSchema>;
2
9
  export default _default;
3
10
  //# sourceMappingURL=elementChildrenValidity.d.ts.map
@@ -1,7 +1,6 @@
1
1
  import { ruleCreator } from "./ruleCreator.js";
2
2
  import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
3
3
  import { SyntaxKind } from "typescript";
4
-
5
4
  //#region src/rules/elementChildrenValidity.ts
6
5
  const voidElements = new Set([
7
6
  "area",
@@ -49,7 +48,7 @@ var elementChildrenValidity_default = ruleCreator.createRule(typescriptLanguage,
49
48
  } } };
50
49
  }
51
50
  });
52
-
53
51
  //#endregion
54
52
  export { elementChildrenValidity_default as default };
53
+
55
54
  //# sourceMappingURL=elementChildrenValidity.js.map
@@ -1,3 +1,10 @@
1
- declare const _default: import("@flint.fyi/core").Rule<import("@flint.fyi/core").RuleAboutWithPresetsAndUrl<"logical" | "logicalStrict" | "stylistic">, object, object, "emptyHeading", import("@flint.fyi/core").AnyOptionalSchema>;
1
+ declare const _default: import("@flint.fyi/core").Rule<{
2
+ readonly description: "Reports heading elements without accessible content.";
3
+ readonly id: "headingContents";
4
+ readonly presets: ["logical", "logicalStrict"];
5
+ } & {
6
+ presets?: ("logical" | "logicalStrict" | "stylistic")[];
7
+ url: string;
8
+ }, object, object, "emptyHeading", import("@flint.fyi/core").AnyOptionalSchema>;
2
9
  export default _default;
3
10
  //# sourceMappingURL=headingContents.d.ts.map
@@ -1,7 +1,6 @@
1
1
  import { ruleCreator } from "./ruleCreator.js";
2
2
  import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
3
3
  import { SyntaxKind } from "typescript";
4
-
5
4
  //#region src/rules/headingContents.ts
6
5
  const headingElements = new Set([
7
6
  "h1",
@@ -15,7 +14,7 @@ var headingContents_default = ruleCreator.createRule(typescriptLanguage, {
15
14
  about: {
16
15
  description: "Reports heading elements without accessible content.",
17
16
  id: "headingContents",
18
- presets: ["logical"]
17
+ presets: ["logical", "logicalStrict"]
19
18
  },
20
19
  messages: { emptyHeading: {
21
20
  primary: "This heading element is missing accessible content.",
@@ -28,14 +27,14 @@ var headingContents_default = ruleCreator.createRule(typescriptLanguage, {
28
27
  } },
29
28
  setup(context) {
30
29
  function checkHeading(node, { sourceFile }) {
31
- const tagName = node.kind == SyntaxKind.JsxElement ? node.openingElement.tagName : node.tagName;
30
+ const tagName = node.kind === SyntaxKind.JsxElement ? node.openingElement.tagName : node.tagName;
32
31
  if (tagName.kind !== SyntaxKind.Identifier || !headingElements.has(tagName.text.toLowerCase())) return;
33
- if ((node.kind == SyntaxKind.JsxElement ? node.openingElement.attributes : node.attributes).properties.some((property) => {
32
+ if ((node.kind === SyntaxKind.JsxElement ? node.openingElement.attributes : node.attributes).properties.some((property) => {
34
33
  if (property.kind !== SyntaxKind.JsxAttribute || property.name.kind !== SyntaxKind.Identifier) return false;
35
34
  return (property.name.text === "aria-label" || property.name.text === "aria-labelledby") && !!property.initializer;
36
35
  })) return;
37
36
  if (node.kind === SyntaxKind.JsxElement && node.children.some((child) => {
38
- if (child.kind === SyntaxKind.JsxText) return child.text.trim().length > 0;
37
+ if (child.kind === SyntaxKind.JsxText) return !!child.text.trim().length;
39
38
  return child.kind === SyntaxKind.JsxElement || child.kind === SyntaxKind.JsxSelfClosingElement || child.kind === SyntaxKind.JsxExpression;
40
39
  })) return;
41
40
  context.report({
@@ -49,7 +48,7 @@ var headingContents_default = ruleCreator.createRule(typescriptLanguage, {
49
48
  } };
50
49
  }
51
50
  });
52
-
53
51
  //#endregion
54
52
  export { headingContents_default as default };
53
+
55
54
  //# sourceMappingURL=headingContents.js.map
@@ -1,3 +1,10 @@
1
- declare const _default: import("@flint.fyi/core").Rule<import("@flint.fyi/core").RuleAboutWithPresetsAndUrl<"logical" | "logicalStrict" | "stylistic">, object, object, "missingLang", import("@flint.fyi/core").AnyOptionalSchema>;
1
+ declare const _default: import("@flint.fyi/core").Rule<{
2
+ readonly description: "Reports <html> elements without a lang prop.";
3
+ readonly id: "htmlLangs";
4
+ readonly presets: ["logical", "logicalStrict"];
5
+ } & {
6
+ presets?: ("logical" | "logicalStrict" | "stylistic")[];
7
+ url: string;
8
+ }, object, object, "missingLang", import("@flint.fyi/core").AnyOptionalSchema>;
2
9
  export default _default;
3
10
  //# sourceMappingURL=htmlLangs.d.ts.map
@@ -1,13 +1,12 @@
1
1
  import { ruleCreator } from "./ruleCreator.js";
2
2
  import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
3
3
  import { SyntaxKind } from "typescript";
4
-
5
4
  //#region src/rules/htmlLangs.ts
6
5
  var htmlLangs_default = ruleCreator.createRule(typescriptLanguage, {
7
6
  about: {
8
7
  description: "Reports <html> elements without a lang prop.",
9
8
  id: "htmlLangs",
10
- presets: ["logical"]
9
+ presets: ["logical", "logicalStrict"]
11
10
  },
12
11
  messages: { missingLang: {
13
12
  primary: "This <html> element is missing a `lang` prop.",
@@ -27,7 +26,7 @@ var htmlLangs_default = ruleCreator.createRule(typescriptLanguage, {
27
26
  } } };
28
27
  }
29
28
  });
30
-
31
29
  //#endregion
32
30
  export { htmlLangs_default as default };
31
+
33
32
  //# sourceMappingURL=htmlLangs.js.map
@@ -1,3 +1,10 @@
1
- declare const _default: import("@flint.fyi/core").Rule<import("@flint.fyi/core").RuleAboutWithPresetsAndUrl<"logical" | "logicalStrict" | "stylistic">, object, object, "missingTitle", import("@flint.fyi/core").AnyOptionalSchema>;
1
+ declare const _default: import("@flint.fyi/core").Rule<{
2
+ readonly description: "Reports <iframe> elements without a title prop.";
3
+ readonly id: "iframeTitles";
4
+ readonly presets: ["logical", "logicalStrict"];
5
+ } & {
6
+ presets?: ("logical" | "logicalStrict" | "stylistic")[];
7
+ url: string;
8
+ }, object, object, "missingTitle", import("@flint.fyi/core").AnyOptionalSchema>;
2
9
  export default _default;
3
10
  //# sourceMappingURL=iframeTitles.d.ts.map
@@ -1,13 +1,12 @@
1
1
  import { ruleCreator } from "./ruleCreator.js";
2
2
  import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
3
3
  import { SyntaxKind } from "typescript";
4
-
5
4
  //#region src/rules/iframeTitles.ts
6
5
  var iframeTitles_default = ruleCreator.createRule(typescriptLanguage, {
7
6
  about: {
8
7
  description: "Reports <iframe> elements without a title prop.",
9
8
  id: "iframeTitles",
10
- presets: ["logical"]
9
+ presets: ["logical", "logicalStrict"]
11
10
  },
12
11
  messages: { missingTitle: {
13
12
  primary: "This <iframe> element is missing a `title` prop.",
@@ -24,7 +23,7 @@ var iframeTitles_default = ruleCreator.createRule(typescriptLanguage, {
24
23
  const titleAttribute = attributes.properties.find((property) => {
25
24
  return property.kind === SyntaxKind.JsxAttribute && property.name.kind === SyntaxKind.Identifier && property.name.text.toLowerCase() === "title";
26
25
  });
27
- if (!titleAttribute || titleAttribute.kind !== SyntaxKind.JsxAttribute) {
26
+ if (titleAttribute?.kind !== SyntaxKind.JsxAttribute) {
28
27
  context.report({
29
28
  message: "missingTitle",
30
29
  range: getTSNodeRange(tagName, sourceFile)
@@ -58,7 +57,7 @@ var iframeTitles_default = ruleCreator.createRule(typescriptLanguage, {
58
57
  } };
59
58
  }
60
59
  });
61
-
62
60
  //#endregion
63
61
  export { iframeTitles_default as default };
62
+
64
63
  //# sourceMappingURL=iframeTitles.js.map
@@ -1,3 +1,10 @@
1
- declare const _default: import("@flint.fyi/core").Rule<import("@flint.fyi/core").RuleAboutWithPresetsAndUrl<"logical" | "logicalStrict" | "stylistic">, object, object, "invalidRole", import("@flint.fyi/core").AnyOptionalSchema>;
1
+ declare const _default: import("@flint.fyi/core").Rule<{
2
+ readonly description: "Reports interactive elements with non-interactive ARIA roles.";
3
+ readonly id: "interactiveElementRoles";
4
+ readonly presets: ["logical", "logicalStrict"];
5
+ } & {
6
+ presets?: ("logical" | "logicalStrict" | "stylistic")[];
7
+ url: string;
8
+ }, object, object, "invalidRole", import("@flint.fyi/core").AnyOptionalSchema>;
2
9
  export default _default;
3
10
  //# sourceMappingURL=interactiveElementRoles.d.ts.map
@@ -1,7 +1,6 @@
1
1
  import { ruleCreator } from "./ruleCreator.js";
2
2
  import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
3
3
  import { SyntaxKind } from "typescript";
4
-
5
4
  //#region src/rules/interactiveElementRoles.ts
6
5
  const interactiveElements = new Set([
7
6
  "a",
@@ -54,7 +53,7 @@ var interactiveElementRoles_default = ruleCreator.createRule(typescriptLanguage,
54
53
  about: {
55
54
  description: "Reports interactive elements with non-interactive ARIA roles.",
56
55
  id: "interactiveElementRoles",
57
- presets: ["logical"]
56
+ presets: ["logical", "logicalStrict"]
58
57
  },
59
58
  messages: { invalidRole: {
60
59
  primary: "Interactive element <{{ element }}> should not have the non-interactive role `'{{ role }}'`.",
@@ -71,7 +70,7 @@ var interactiveElementRoles_default = ruleCreator.createRule(typescriptLanguage,
71
70
  const elementName = element.tagName.text.toLowerCase();
72
71
  if (!interactiveElements.has(elementName)) return;
73
72
  const roleProperty = element.attributes.properties.find((property) => property.kind === SyntaxKind.JsxAttribute && property.name.kind === SyntaxKind.Identifier && property.name.text === "role");
74
- if (!roleProperty || roleProperty.kind !== SyntaxKind.JsxAttribute || !roleProperty.initializer || roleProperty.initializer.kind !== SyntaxKind.StringLiteral) return;
73
+ if (roleProperty?.kind !== SyntaxKind.JsxAttribute || roleProperty.initializer?.kind !== SyntaxKind.StringLiteral) return;
75
74
  const role = roleProperty.initializer.text;
76
75
  if (nonInteractiveRoles.has(role)) context.report({
77
76
  data: {
@@ -88,7 +87,7 @@ var interactiveElementRoles_default = ruleCreator.createRule(typescriptLanguage,
88
87
  } };
89
88
  }
90
89
  });
91
-
92
90
  //#endregion
93
91
  export { interactiveElementRoles_default as default };
92
+
94
93
  //# sourceMappingURL=interactiveElementRoles.js.map
@@ -1,3 +1,10 @@
1
- declare const _default: import("@flint.fyi/core").Rule<import("@flint.fyi/core").RuleAboutWithPresetsAndUrl<"logical" | "logicalStrict" | "stylistic">, object, object, "notFocusable", import("@flint.fyi/core").AnyOptionalSchema>;
1
+ declare const _default: import("@flint.fyi/core").Rule<{
2
+ readonly description: "Reports interactive elements that are not focusable via keyboard.";
3
+ readonly id: "interactiveElementsFocusable";
4
+ readonly presets: ["logical", "logicalStrict"];
5
+ } & {
6
+ presets?: ("logical" | "logicalStrict" | "stylistic")[];
7
+ url: string;
8
+ }, object, object, "notFocusable", import("@flint.fyi/core").AnyOptionalSchema>;
2
9
  export default _default;
3
10
  //# sourceMappingURL=interactiveElementsFocusable.d.ts.map
@@ -1,7 +1,6 @@
1
1
  import { ruleCreator } from "./ruleCreator.js";
2
2
  import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
3
3
  import { SyntaxKind } from "typescript";
4
-
5
4
  //#region src/rules/interactiveElementsFocusable.ts
6
5
  const interactiveHandlers = [
7
6
  "onClick",
@@ -95,7 +94,7 @@ var interactiveElementsFocusable_default = ruleCreator.createRule(typescriptLang
95
94
  about: {
96
95
  description: "Reports interactive elements that are not focusable via keyboard.",
97
96
  id: "interactiveElementsFocusable",
98
- presets: ["logical"]
97
+ presets: ["logical", "logicalStrict"]
99
98
  },
100
99
  messages: { notFocusable: {
101
100
  primary: "The '{{ role }}' role makes this element interactive, so it should also be focusable.",
@@ -116,17 +115,17 @@ var interactiveElementsFocusable_default = ruleCreator.createRule(typescriptLang
116
115
  if (!tabIndex?.initializer) return;
117
116
  if (tabIndex.initializer.kind === SyntaxKind.JsxExpression) {
118
117
  const expression = tabIndex.initializer.expression;
119
- if (expression && expression.kind === SyntaxKind.NumericLiteral) return Number(expression.text);
118
+ if (expression?.kind === SyntaxKind.NumericLiteral) return Number(expression.text);
120
119
  }
121
120
  if (tabIndex.initializer.kind === SyntaxKind.StringLiteral) return Number(tabIndex.initializer.text);
122
121
  }
123
122
  function getRoleValue(node) {
124
123
  const role = node.attributes.properties.find((property) => property.kind === SyntaxKind.JsxAttribute && property.name.kind === SyntaxKind.Identifier && property.name.text === "role");
125
- if (role && role.kind === SyntaxKind.JsxAttribute && role.initializer && role.initializer.kind === SyntaxKind.StringLiteral) return role.initializer.text;
124
+ if (role?.kind === SyntaxKind.JsxAttribute && role.initializer?.kind === SyntaxKind.StringLiteral) return role.initializer.text;
126
125
  }
127
126
  function isAriaHidden(node) {
128
127
  const ariaHidden = node.attributes.properties.find((property) => property.kind === SyntaxKind.JsxAttribute && property.name.kind === SyntaxKind.Identifier && property.name.text === "aria-hidden");
129
- if (!ariaHidden || ariaHidden.kind !== SyntaxKind.JsxAttribute || !ariaHidden.initializer) return false;
128
+ if (ariaHidden?.kind !== SyntaxKind.JsxAttribute || !ariaHidden.initializer) return false;
130
129
  if (ariaHidden.initializer.kind === SyntaxKind.JsxExpression) return ariaHidden.initializer.expression?.kind === SyntaxKind.TrueKeyword;
131
130
  if (ariaHidden.initializer.kind === SyntaxKind.StringLiteral) return ariaHidden.initializer.text === "true";
132
131
  return false;
@@ -136,7 +135,7 @@ var interactiveElementsFocusable_default = ruleCreator.createRule(typescriptLang
136
135
  }
137
136
  function isDisabled(node) {
138
137
  const disabledProperty = node.attributes.properties.find((property) => property.kind === SyntaxKind.JsxAttribute && property.name.kind === SyntaxKind.Identifier && property.name.text === "disabled");
139
- if (!disabledProperty || disabledProperty.kind !== SyntaxKind.JsxAttribute) return false;
138
+ if (disabledProperty?.kind !== SyntaxKind.JsxAttribute) return false;
140
139
  if (!disabledProperty.initializer) return true;
141
140
  if (disabledProperty.initializer.kind === SyntaxKind.JsxExpression) return disabledProperty.initializer.expression?.kind === SyntaxKind.TrueKeyword;
142
141
  return false;
@@ -157,7 +156,7 @@ var interactiveElementsFocusable_default = ruleCreator.createRule(typescriptLang
157
156
  context.report({
158
157
  data: { role: displayRole },
159
158
  message: "notFocusable",
160
- range: getTSNodeRange(roleProperty && roleProperty.kind === SyntaxKind.JsxAttribute ? roleProperty : node.tagName, sourceFile)
159
+ range: getTSNodeRange(roleProperty?.kind === SyntaxKind.JsxAttribute ? roleProperty : node.tagName, sourceFile)
161
160
  });
162
161
  }
163
162
  }
@@ -167,7 +166,7 @@ var interactiveElementsFocusable_default = ruleCreator.createRule(typescriptLang
167
166
  } };
168
167
  }
169
168
  });
170
-
171
169
  //#endregion
172
170
  export { interactiveElementsFocusable_default as default };
171
+
173
172
  //# sourceMappingURL=interactiveElementsFocusable.js.map
@@ -1,3 +1,10 @@
1
- declare const _default: import("@flint.fyi/core").Rule<import("@flint.fyi/core").RuleAboutWithPresetsAndUrl<"logical" | "logicalStrict" | "stylistic">, object, object, "missingAssociatedControl", import("@flint.fyi/core").AnyOptionalSchema>;
1
+ declare const _default: import("@flint.fyi/core").Rule<{
2
+ readonly description: "Reports <label> elements without an associated control element.";
3
+ readonly id: "labelAssociatedControls";
4
+ readonly presets: ["logical", "logicalStrict"];
5
+ } & {
6
+ presets?: ("logical" | "logicalStrict" | "stylistic")[];
7
+ url: string;
8
+ }, object, object, "missingAssociatedControl", import("@flint.fyi/core").AnyOptionalSchema>;
2
9
  export default _default;
3
10
  //# sourceMappingURL=labelAssociatedControls.d.ts.map
@@ -1,7 +1,6 @@
1
1
  import { ruleCreator } from "./ruleCreator.js";
2
2
  import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
3
3
  import { SyntaxKind } from "typescript";
4
-
5
4
  //#region src/rules/labelAssociatedControls.ts
6
5
  const controlElements = new Set([
7
6
  "input",
@@ -15,7 +14,7 @@ var labelAssociatedControls_default = ruleCreator.createRule(typescriptLanguage,
15
14
  about: {
16
15
  description: "Reports <label> elements without an associated control element.",
17
16
  id: "labelAssociatedControls",
18
- presets: ["logical"]
17
+ presets: ["logical", "logicalStrict"]
19
18
  },
20
19
  messages: { missingAssociatedControl: {
21
20
  primary: "This <label> element is missing an associated control element.",
@@ -41,7 +40,7 @@ var labelAssociatedControls_default = ruleCreator.createRule(typescriptLanguage,
41
40
  }
42
41
  function hasNestedControl(children) {
43
42
  return children.some((child) => {
44
- if (child.kind == SyntaxKind.JsxElement) {
43
+ if (child.kind === SyntaxKind.JsxElement) {
45
44
  const { tagName } = child.openingElement;
46
45
  return tagName.kind === SyntaxKind.Identifier && controlElements.has(tagName.text.toLowerCase()) || hasNestedControl(child.children);
47
46
  }
@@ -50,10 +49,10 @@ var labelAssociatedControls_default = ruleCreator.createRule(typescriptLanguage,
50
49
  });
51
50
  }
52
51
  function checkLabel(node, { sourceFile }) {
53
- if (node.kind == SyntaxKind.JsxElement && hasNestedControl(node.children)) return;
54
- const tagName = node.kind == SyntaxKind.JsxElement ? node.openingElement.tagName : node.tagName;
52
+ if (node.kind === SyntaxKind.JsxElement && hasNestedControl(node.children)) return;
53
+ const tagName = node.kind === SyntaxKind.JsxElement ? node.openingElement.tagName : node.tagName;
55
54
  if (tagName.kind !== SyntaxKind.Identifier || tagName.text.toLowerCase() !== "label") return;
56
- if (hasHtmlForAttribute(node.kind == SyntaxKind.JsxElement ? node.openingElement.attributes : node.attributes)) return;
55
+ if (hasHtmlForAttribute(node.kind === SyntaxKind.JsxElement ? node.openingElement.attributes : node.attributes)) return;
57
56
  context.report({
58
57
  message: "missingAssociatedControl",
59
58
  range: getTSNodeRange(tagName, sourceFile)
@@ -65,7 +64,7 @@ var labelAssociatedControls_default = ruleCreator.createRule(typescriptLanguage,
65
64
  } };
66
65
  }
67
66
  });
68
-
69
67
  //#endregion
70
68
  export { labelAssociatedControls_default as default };
69
+
71
70
  //# sourceMappingURL=labelAssociatedControls.js.map
@@ -1,3 +1,10 @@
1
- declare const _default: import("@flint.fyi/core").Rule<import("@flint.fyi/core").RuleAboutWithPresetsAndUrl<"logical" | "logicalStrict" | "stylistic">, object, object, "invalidLang", import("@flint.fyi/core").AnyOptionalSchema>;
1
+ declare const _default: import("@flint.fyi/core").Rule<{
2
+ readonly description: "Reports invalid lang attribute values.";
3
+ readonly id: "langValidity";
4
+ readonly presets: ["logical", "logicalStrict"];
5
+ } & {
6
+ presets?: ("logical" | "logicalStrict" | "stylistic")[];
7
+ url: string;
8
+ }, object, object, "invalidLang", import("@flint.fyi/core").AnyOptionalSchema>;
2
9
  export default _default;
3
10
  //# sourceMappingURL=langValidity.d.ts.map
@@ -2,7 +2,6 @@ import { ruleCreator } from "./ruleCreator.js";
2
2
  import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
3
3
  import { SyntaxKind } from "typescript";
4
4
  import languageTags from "language-tags";
5
-
6
5
  //#region src/rules/langValidity.ts
7
6
  var langValidity_default = ruleCreator.createRule(typescriptLanguage, {
8
7
  about: {
@@ -38,7 +37,7 @@ var langValidity_default = ruleCreator.createRule(typescriptLanguage, {
38
37
  } };
39
38
  }
40
39
  });
41
-
42
40
  //#endregion
43
41
  export { langValidity_default as default };
42
+
44
43
  //# sourceMappingURL=langValidity.js.map
@@ -1,3 +1,10 @@
1
- declare const _default: import("@flint.fyi/core").Rule<import("@flint.fyi/core").RuleAboutWithPresetsAndUrl<"logical" | "logicalStrict" | "stylistic">, object, object, "missingCaptions", import("@flint.fyi/core").AnyOptionalSchema>;
1
+ declare const _default: import("@flint.fyi/core").Rule<{
2
+ readonly description: "Reports media elements without captions.";
3
+ readonly id: "mediaCaptions";
4
+ readonly presets: ["logical", "logicalStrict"];
5
+ } & {
6
+ presets?: ("logical" | "logicalStrict" | "stylistic")[];
7
+ url: string;
8
+ }, object, object, "missingCaptions", import("@flint.fyi/core").AnyOptionalSchema>;
2
9
  export default _default;
3
10
  //# sourceMappingURL=mediaCaptions.d.ts.map
@@ -1,13 +1,12 @@
1
1
  import { ruleCreator } from "./ruleCreator.js";
2
2
  import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
3
3
  import { SyntaxKind } from "typescript";
4
-
5
4
  //#region src/rules/mediaCaptions.ts
6
5
  var mediaCaptions_default = ruleCreator.createRule(typescriptLanguage, {
7
6
  about: {
8
7
  description: "Reports media elements without captions.",
9
8
  id: "mediaCaptions",
10
- presets: ["logical"]
9
+ presets: ["logical", "logicalStrict"]
11
10
  },
12
11
  messages: { missingCaptions: {
13
12
  primary: "This media element is missing <track> element captions.",
@@ -20,12 +19,12 @@ var mediaCaptions_default = ruleCreator.createRule(typescriptLanguage, {
20
19
  } },
21
20
  setup(context) {
22
21
  function checkMediaElement(node, { sourceFile }) {
23
- const tagName = node.kind == SyntaxKind.JsxElement ? node.openingElement.tagName : node.tagName;
24
- if (tagName.kind != SyntaxKind.Identifier) return;
22
+ const tagName = node.kind === SyntaxKind.JsxElement ? node.openingElement.tagName : node.tagName;
23
+ if (tagName.kind !== SyntaxKind.Identifier) return;
25
24
  const elementName = tagName.text.toLowerCase();
26
25
  if (elementName !== "audio" && elementName !== "video") return;
27
- if ((node.kind == SyntaxKind.JsxElement ? node.openingElement.attributes : node.attributes).properties.some((properties) => properties.kind == SyntaxKind.JsxAttribute && properties.name.kind == SyntaxKind.Identifier && properties.name.text === "muted")) return;
28
- if (node.kind == SyntaxKind.JsxElement && node.children.some(isCaptionsTrack)) return;
26
+ if ((node.kind === SyntaxKind.JsxElement ? node.openingElement.attributes : node.attributes).properties.some((properties) => properties.kind === SyntaxKind.JsxAttribute && properties.name.kind === SyntaxKind.Identifier && properties.name.text === "muted")) return;
27
+ if (node.kind === SyntaxKind.JsxElement && node.children.some(isCaptionsTrack)) return;
29
28
  context.report({
30
29
  message: "missingCaptions",
31
30
  range: getTSNodeRange(tagName, sourceFile)
@@ -38,16 +37,16 @@ var mediaCaptions_default = ruleCreator.createRule(typescriptLanguage, {
38
37
  }
39
38
  });
40
39
  function isCaptionsTrack(node) {
41
- if (node.kind != SyntaxKind.JsxElement && node.kind != SyntaxKind.JsxSelfClosingElement) return false;
42
- const childTagName = node.kind == SyntaxKind.JsxElement ? node.openingElement.tagName : node.tagName;
43
- if (childTagName.kind != SyntaxKind.Identifier || childTagName.text !== "track") return false;
44
- return (node.kind == SyntaxKind.JsxElement ? node.openingElement.attributes : node.attributes).properties.some((property) => {
45
- if (property.kind != SyntaxKind.JsxAttribute || property.name.kind != SyntaxKind.Identifier || property.name.text !== "kind") return false;
46
- if (property.initializer?.kind == SyntaxKind.StringLiteral) return property.initializer.text === "captions";
40
+ if (node.kind !== SyntaxKind.JsxElement && node.kind !== SyntaxKind.JsxSelfClosingElement) return false;
41
+ const childTagName = node.kind === SyntaxKind.JsxElement ? node.openingElement.tagName : node.tagName;
42
+ if (childTagName.kind !== SyntaxKind.Identifier || childTagName.text !== "track") return false;
43
+ return (node.kind === SyntaxKind.JsxElement ? node.openingElement.attributes : node.attributes).properties.some((property) => {
44
+ if (property.kind !== SyntaxKind.JsxAttribute || property.name.kind !== SyntaxKind.Identifier || property.name.text !== "kind") return false;
45
+ if (property.initializer?.kind === SyntaxKind.StringLiteral) return property.initializer.text === "captions";
47
46
  return false;
48
47
  });
49
48
  }
50
-
51
49
  //#endregion
52
50
  export { mediaCaptions_default as default };
51
+
53
52
  //# sourceMappingURL=mediaCaptions.js.map
@@ -1,3 +1,10 @@
1
- declare const _default: import("@flint.fyi/core").Rule<import("@flint.fyi/core").RuleAboutWithPresetsAndUrl<"logical" | "logicalStrict" | "stylistic">, object, object, "missingKeyEvent", import("@flint.fyi/core").AnyOptionalSchema>;
1
+ declare const _default: import("@flint.fyi/core").Rule<{
2
+ readonly description: "Reports mouse events without corresponding keyboard events.";
3
+ readonly id: "mouseEventKeyEvents";
4
+ readonly presets: ["logical", "logicalStrict"];
5
+ } & {
6
+ presets?: ("logical" | "logicalStrict" | "stylistic")[];
7
+ url: string;
8
+ }, object, object, "missingKeyEvent", import("@flint.fyi/core").AnyOptionalSchema>;
2
9
  export default _default;
3
10
  //# sourceMappingURL=mouseEventKeyEvents.d.ts.map
@@ -1,14 +1,13 @@
1
1
  import { ruleCreator } from "./ruleCreator.js";
2
2
  import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
3
3
  import { SyntaxKind } from "typescript";
4
-
5
4
  //#region src/rules/mouseEventKeyEvents.ts
6
5
  const mouseNamesToKeyboardNames = new Map([["onMouseOut", "onBlur"], ["onMouseOver", "onFocus"]]);
7
6
  var mouseEventKeyEvents_default = ruleCreator.createRule(typescriptLanguage, {
8
7
  about: {
9
8
  description: "Reports mouse events without corresponding keyboard events.",
10
9
  id: "mouseEventKeyEvents",
11
- presets: ["logical"]
10
+ presets: ["logical", "logicalStrict"]
12
11
  },
13
12
  messages: { missingKeyEvent: {
14
13
  primary: "`{{ mouseEvent }}` is missing an accompanying `{{ keyEvent }}` for keyboard accessibility.",
@@ -44,7 +43,7 @@ var mouseEventKeyEvents_default = ruleCreator.createRule(typescriptLanguage, {
44
43
  } };
45
44
  }
46
45
  });
47
-
48
46
  //#endregion
49
47
  export { mouseEventKeyEvents_default as default };
48
+
50
49
  //# sourceMappingURL=mouseEventKeyEvents.js.map
@@ -1,3 +1,10 @@
1
- declare const _default: import("@flint.fyi/core").Rule<import("@flint.fyi/core").RuleAboutWithPresetsAndUrl<"logical" | "logicalStrict" | "stylistic">, object, object, "invalidHandler", import("@flint.fyi/core").AnyOptionalSchema>;
1
+ declare const _default: import("@flint.fyi/core").Rule<{
2
+ readonly description: "Reports non-interactive elements with interactive event handlers.";
3
+ readonly id: "nonInteractiveElementInteractions";
4
+ readonly presets: ["logical", "logicalStrict"];
5
+ } & {
6
+ presets?: ("logical" | "logicalStrict" | "stylistic")[];
7
+ url: string;
8
+ }, object, object, "invalidHandler", import("@flint.fyi/core").AnyOptionalSchema>;
2
9
  export default _default;
3
10
  //# sourceMappingURL=nonInteractiveElementInteractions.d.ts.map
@@ -1,7 +1,6 @@
1
1
  import { ruleCreator } from "./ruleCreator.js";
2
2
  import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
3
3
  import { SyntaxKind } from "typescript";
4
-
5
4
  //#region src/rules/nonInteractiveElementInteractions.ts
6
5
  const interactiveHandlers = [
7
6
  "onClick",
@@ -53,7 +52,7 @@ var nonInteractiveElementInteractions_default = ruleCreator.createRule(typescrip
53
52
  about: {
54
53
  description: "Reports non-interactive elements with interactive event handlers.",
55
54
  id: "nonInteractiveElementInteractions",
56
- presets: ["logical"]
55
+ presets: ["logical", "logicalStrict"]
57
56
  },
58
57
  messages: { invalidHandler: {
59
58
  primary: "`<{{ element }}>` elements are non-interactive and so should not have interactive event handlers.",
@@ -75,7 +74,7 @@ var nonInteractiveElementInteractions_default = ruleCreator.createRule(typescrip
75
74
  if (elementName !== element.tagName.text || !nonInteractiveElements.has(elementName)) return;
76
75
  let hasInteractiveHandler = false;
77
76
  for (const property of element.attributes.properties) if (property.kind === SyntaxKind.JsxAttribute && property.name.kind === SyntaxKind.Identifier) {
78
- if (property.name.text === "role" && property.initializer && property.initializer.kind === SyntaxKind.StringLiteral && !nonInteractiveRoles.has(property.initializer.text)) return;
77
+ if (property.name.text === "role" && property.initializer?.kind === SyntaxKind.StringLiteral && !nonInteractiveRoles.has(property.initializer.text)) return;
79
78
  if (interactiveHandlers.includes(property.name.text)) hasInteractiveHandler = true;
80
79
  }
81
80
  if (hasInteractiveHandler) context.report({
@@ -90,7 +89,7 @@ var nonInteractiveElementInteractions_default = ruleCreator.createRule(typescrip
90
89
  } };
91
90
  }
92
91
  });
93
-
94
92
  //#endregion
95
93
  export { nonInteractiveElementInteractions_default as default };
94
+
96
95
  //# sourceMappingURL=nonInteractiveElementInteractions.js.map
@@ -1,3 +1,10 @@
1
- declare const _default: import("@flint.fyi/core").Rule<import("@flint.fyi/core").RuleAboutWithPresetsAndUrl<"logical" | "logicalStrict" | "stylistic">, object, object, "invalidRole", import("@flint.fyi/core").AnyOptionalSchema>;
1
+ declare const _default: import("@flint.fyi/core").Rule<{
2
+ readonly description: "Reports non-interactive elements with interactive ARIA roles.";
3
+ readonly id: "nonInteractiveElementRoles";
4
+ readonly presets: ["logical", "logicalStrict"];
5
+ } & {
6
+ presets?: ("logical" | "logicalStrict" | "stylistic")[];
7
+ url: string;
8
+ }, object, object, "invalidRole", import("@flint.fyi/core").AnyOptionalSchema>;
2
9
  export default _default;
3
10
  //# sourceMappingURL=nonInteractiveElementRoles.d.ts.map