diff --git a/package.json b/package.json index 43c6a862..efd7ee0c 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "eslint-plugin-inclusive-language": "~2.2.0", "eslint-plugin-jsdoc": "~43.0.7", "eslint-plugin-jsonc": "~2.7.0", + "eslint-plugin-jsx-a11y": "~6.7.1", "eslint-plugin-mdx": "~2.0.5", "eslint-plugin-n": "~15.7.0", "eslint-plugin-node": "~11.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a599dad1..84f8d64d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -58,6 +58,9 @@ devDependencies: eslint-plugin-jsonc: specifier: ~2.7.0 version: 2.7.0(eslint@8.39.0) + eslint-plugin-jsx-a11y: + specifier: ~6.7.1 + version: 6.7.1(eslint@8.39.0) eslint-plugin-mdx: specifier: ~2.0.5 version: 2.0.5(eslint@8.39.0) @@ -1450,6 +1453,12 @@ packages: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: true + /aria-query@5.1.3: + resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} + dependencies: + deep-equal: 2.2.0 + dev: true + /array-buffer-byte-length@1.0.0: resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} dependencies: @@ -1521,6 +1530,10 @@ packages: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} dev: true + /ast-types-flow@0.0.7: + resolution: {integrity: sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==} + dev: true + /astral-regex@2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} @@ -1531,6 +1544,17 @@ packages: engines: {node: '>= 0.4'} dev: true + /axe-core@4.7.0: + resolution: {integrity: sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==} + engines: {node: '>=4'} + dev: true + + /axobject-query@3.1.1: + resolution: {integrity: sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==} + dependencies: + deep-equal: 2.2.0 + dev: true + /bail@2.0.2: resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} dev: true @@ -1866,6 +1890,10 @@ packages: type: 1.2.0 dev: true + /damerau-levenshtein@1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + dev: true + /dataloader@2.2.2: resolution: {integrity: sha512-8YnDaaf7N3k/q5HnTJVuzSyLETjoZjVmHc4AeKAzOvKHEFQKcn64OKBfzHYtE9zGjctNM7V9I0MfnUVLpi7M5g==} dev: true @@ -1913,6 +1941,28 @@ packages: type-detect: 4.0.8 dev: true + /deep-equal@2.2.0: + resolution: {integrity: sha512-RdpzE0Hv4lhowpIUKKMJfeH6C1pXdtT1/it80ubgWqwI3qpuxUBpC1S4hnHg+zjnuOoDkzUtUCEEkG+XG5l3Mw==} + dependencies: + call-bind: 1.0.2 + es-get-iterator: 1.1.3 + get-intrinsic: 1.2.0 + is-arguments: 1.1.1 + is-array-buffer: 3.0.2 + is-date-object: 1.0.5 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.2 + isarray: 2.0.5 + object-is: 1.1.5 + object-keys: 1.1.1 + object.assign: 4.1.4 + regexp.prototype.flags: 1.5.0 + side-channel: 1.0.4 + which-boxed-primitive: 1.0.2 + which-collection: 1.0.1 + which-typed-array: 1.1.9 + dev: true + /deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true @@ -1977,6 +2027,10 @@ packages: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} dev: true + /emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + dev: true + /entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -2028,6 +2082,20 @@ packages: which-typed-array: 1.1.9 dev: true + /es-get-iterator@1.1.3: + resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.0 + has-symbols: 1.0.3 + is-arguments: 1.1.1 + is-map: 2.0.2 + is-set: 2.0.2 + is-string: 1.0.7 + isarray: 2.0.5 + stop-iteration-iterator: 1.0.0 + dev: true + /es-set-tostringtag@2.0.1: resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} engines: {node: '>= 0.4'} @@ -2331,6 +2399,31 @@ packages: natural-compare: 1.4.0 dev: true + /eslint-plugin-jsx-a11y@6.7.1(eslint@8.39.0): + resolution: {integrity: sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + dependencies: + '@babel/runtime': 7.21.0 + aria-query: 5.1.3 + array-includes: 3.1.6 + array.prototype.flatmap: 1.3.1 + ast-types-flow: 0.0.7 + axe-core: 4.7.0 + axobject-query: 3.1.1 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + eslint: 8.39.0 + has: 1.0.3 + jsx-ast-utils: 3.3.3 + language-tags: 1.0.5 + minimatch: 3.1.2 + object.entries: 1.1.6 + object.fromentries: 2.0.6 + semver: 6.3.0 + dev: true + /eslint-plugin-markdown@3.0.0(eslint@8.39.0): resolution: {integrity: sha512-hRs5RUJGbeHDLfS7ELanT0e29Ocyssf/7kBM+p7KluY5AwngGkDf8Oyu4658/NZSGTTq05FZeWbkxXtbVyHPwg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -3165,6 +3258,14 @@ packages: is-decimal: 2.0.1 dev: true + /is-arguments@1.1.1: + resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + /is-array-buffer@3.0.2: resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} dependencies: @@ -3273,6 +3374,10 @@ packages: '@babel/runtime': 7.21.0 dev: true + /is-map@2.0.2: + resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} + dev: true + /is-negative-zero@2.0.2: resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} engines: {node: '>= 0.4'} @@ -3312,6 +3417,10 @@ packages: has-tostringtag: 1.0.0 dev: true + /is-set@2.0.2: + resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} + dev: true + /is-shared-array-buffer@1.0.2: resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} dependencies: @@ -3343,12 +3452,23 @@ packages: has-tostringtag: 1.0.0 dev: true + /is-weakmap@2.0.1: + resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} + dev: true + /is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: call-bind: 1.0.2 dev: true + /is-weakset@2.0.2: + resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.0 + dev: true + /is-wsl@2.2.0: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} @@ -3356,6 +3476,10 @@ packages: is-docker: 2.2.1 dev: true + /isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + dev: true + /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true @@ -3510,6 +3634,16 @@ packages: engines: {node: '>=6'} dev: true + /language-subtag-registry@0.3.22: + resolution: {integrity: sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==} + dev: true + + /language-tags@1.0.5: + resolution: {integrity: sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==} + dependencies: + language-subtag-registry: 0.3.22 + dev: true + /levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -4190,6 +4324,14 @@ packages: resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} dev: true + /object-is@1.1.5: + resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + dev: true + /object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} @@ -4859,6 +5001,13 @@ packages: resolution: {integrity: sha512-uUZI65yrV2Qva5gqE0+A7uVAvO40iPo6jGhs7s8keRfHCmtg+uB2X6EiLGCI9IgL1J17xGhvoOqSz79lzICPTA==} dev: true + /stop-iteration-iterator@1.0.0: + resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} + engines: {node: '>= 0.4'} + dependencies: + internal-slot: 1.0.5 + dev: true + /streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} @@ -5490,6 +5639,15 @@ packages: is-symbol: 1.0.4 dev: true + /which-collection@1.0.1: + resolution: {integrity: sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==} + dependencies: + is-map: 2.0.2 + is-set: 2.0.2 + is-weakmap: 2.0.1 + is-weakset: 2.0.2 + dev: true + /which-typed-array@1.1.9: resolution: {integrity: sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==} engines: {node: '>= 0.4'} diff --git a/scripts/generate-rule-files/src/plugins-map.ts b/scripts/generate-rule-files/src/plugins-map.ts index bf68a0c9..7238d7f1 100644 --- a/scripts/generate-rule-files/src/plugins-map.ts +++ b/scripts/generate-rule-files/src/plugins-map.ts @@ -39,6 +39,10 @@ export const PLUGIN_REGISTRY: Readonly> = { name: 'Jsonc', module: 'eslint-plugin-jsonc', }, + 'jsx-a11y': { + name: 'JsxA11y', + module: 'eslint-plugin-jsx-a11y', + }, mdx: { name: 'Mdx', module: 'eslint-plugin-mdx', diff --git a/src/config/extends/eslint-plugin-jsx-a11y.d.ts b/src/config/extends/eslint-plugin-jsx-a11y.d.ts new file mode 100644 index 00000000..d283fd9f --- /dev/null +++ b/src/config/extends/eslint-plugin-jsx-a11y.d.ts @@ -0,0 +1,8 @@ +/** + * Eslint JSX A11y extensions. + * + * @see [Eslint JSX A11y extensions](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y) + */ +export type JsxA11yExtensions = + | 'plugin:jsx-a11y/strict' + | 'plugin:jsx-a11y/recommended'; diff --git a/src/config/plugin.d.ts b/src/config/plugin.d.ts index dae721e0..68997d53 100644 --- a/src/config/plugin.d.ts +++ b/src/config/plugin.d.ts @@ -8,9 +8,11 @@ export type Plugin = LiteralUnion< | 'import' | 'inclusive-language' | 'jsdoc' + | 'jsx-a11y' | 'mdx' | 'prettier' | 'promise' + | 'react-hooks' | 'react' | 'sonarjs' | 'spellcheck' diff --git a/src/config/settings/index.d.ts b/src/config/settings/index.d.ts index bf7daafb..5df35fd7 100644 --- a/src/config/settings/index.d.ts +++ b/src/config/settings/index.d.ts @@ -1,5 +1,6 @@ import type { ImportSettings } from './import'; import type { JSDocSettings } from './jsdoc'; +import type { JsxA11ySettings } from './jsx-a11y'; import type { MdxSettings } from './mdx'; import type { NodeSettings } from './node'; import type { ReactSettings } from './react'; @@ -10,6 +11,7 @@ import type { ReactSettings } from './react'; export interface Settings extends ImportSettings, JSDocSettings, + JsxA11ySettings, MdxSettings, NodeSettings, ReactSettings, diff --git a/src/config/settings/jsx-a11y.d.ts b/src/config/settings/jsx-a11y.d.ts new file mode 100644 index 00000000..4622b686 --- /dev/null +++ b/src/config/settings/jsx-a11y.d.ts @@ -0,0 +1,10 @@ +/** + * JSX A11y settings. + * + * @see [JSX A11y settings](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y) + */ +export interface JsxA11ySettings extends Partial> { + 'jsx-a11y'?: { + components?: Record; + }; +} diff --git a/src/rules/index.d.ts b/src/rules/index.d.ts index 73e5ec1a..24157cc9 100644 --- a/src/rules/index.d.ts +++ b/src/rules/index.d.ts @@ -5,6 +5,7 @@ import type { GraphQLRules } from './graphql-eslint'; import type { ImportRules } from './import'; import type { JSDocRules } from './jsdoc'; import type { JsoncRules } from './jsonc'; +import type { JsxA11yRules } from './jsx-a11y'; import type { NRules } from './n'; import type { NodeRules } from './node'; import type { PromiseRules } from './promise'; @@ -33,6 +34,7 @@ export type Rules = Partial< ImportRules & JSDocRules & JsoncRules & + JsxA11yRules & NodeRules & NRules & PromiseRules & diff --git a/src/rules/jsx-a11y/accessible-emoji.d.ts b/src/rules/jsx-a11y/accessible-emoji.d.ts new file mode 100644 index 00000000..cddd88ea --- /dev/null +++ b/src/rules/jsx-a11y/accessible-emoji.d.ts @@ -0,0 +1,40 @@ +import type { RuleConfig } from '../rule-config'; + +/** + * Option. + */ +export interface AccessibleEmojiOption { + [k: string]: any; +} + +/** + * Options. + */ +export type AccessibleEmojiOptions = [AccessibleEmojiOption?]; + +/** + * Enforce emojis are wrapped in `` and provide screenreader access. + * + * @deprecated + * + * @see [accessible-emoji](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/accessible-emoji.md) + */ +export type AccessibleEmojiRuleConfig = RuleConfig; + +/** + * Enforce emojis are wrapped in `` and provide screenreader access. + * + * @deprecated + * + * @see [accessible-emoji](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/accessible-emoji.md) + */ +export interface AccessibleEmojiRule { + /** + * Enforce emojis are wrapped in `` and provide screenreader access. + * + * @deprecated + * + * @see [accessible-emoji](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/accessible-emoji.md) + */ + 'jsx-a11y/accessible-emoji': AccessibleEmojiRuleConfig; +} diff --git a/src/rules/jsx-a11y/alt-text.d.ts b/src/rules/jsx-a11y/alt-text.d.ts new file mode 100644 index 00000000..a6f9a37d --- /dev/null +++ b/src/rules/jsx-a11y/alt-text.d.ts @@ -0,0 +1,39 @@ +import type { RuleConfig } from '../rule-config'; + +/** + * Option. + */ +export interface AltTextOption { + elements?: string[]; + img?: string[]; + object?: string[]; + area?: string[]; + 'input[type="image"]'?: string[]; + [k: string]: any; +} + +/** + * Options. + */ +export type AltTextOptions = [AltTextOption?]; + +/** + * Enforce all elements that require alternative text have meaningful information to relay back to end user. + * + * @see [alt-text](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/alt-text.md) + */ +export type AltTextRuleConfig = RuleConfig; + +/** + * Enforce all elements that require alternative text have meaningful information to relay back to end user. + * + * @see [alt-text](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/alt-text.md) + */ +export interface AltTextRule { + /** + * Enforce all elements that require alternative text have meaningful information to relay back to end user. + * + * @see [alt-text](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/alt-text.md) + */ + 'jsx-a11y/alt-text': AltTextRuleConfig; +} diff --git a/src/rules/jsx-a11y/anchor-ambiguous-text.d.ts b/src/rules/jsx-a11y/anchor-ambiguous-text.d.ts new file mode 100644 index 00000000..4e566870 --- /dev/null +++ b/src/rules/jsx-a11y/anchor-ambiguous-text.d.ts @@ -0,0 +1,36 @@ +import type { RuleConfig } from '../rule-config'; + +/** + * Option. + */ +export interface AnchorAmbiguousTextOption { + words?: string[]; + [k: string]: any; +} + +/** + * Options. + */ +export type AnchorAmbiguousTextOptions = [AnchorAmbiguousTextOption?]; + +/** + * Enforce `` text to not exactly match "click here", "here", "link", or "a link". + * + * @see [anchor-ambiguous-text](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/anchor-ambiguous-text.md) + */ +export type AnchorAmbiguousTextRuleConfig = + RuleConfig; + +/** + * Enforce `` text to not exactly match "click here", "here", "link", or "a link". + * + * @see [anchor-ambiguous-text](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/anchor-ambiguous-text.md) + */ +export interface AnchorAmbiguousTextRule { + /** + * Enforce `` text to not exactly match "click here", "here", "link", or "a link". + * + * @see [anchor-ambiguous-text](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/anchor-ambiguous-text.md) + */ + 'jsx-a11y/anchor-ambiguous-text': AnchorAmbiguousTextRuleConfig; +} diff --git a/src/rules/jsx-a11y/anchor-has-content.d.ts b/src/rules/jsx-a11y/anchor-has-content.d.ts new file mode 100644 index 00000000..4dacd2cc --- /dev/null +++ b/src/rules/jsx-a11y/anchor-has-content.d.ts @@ -0,0 +1,35 @@ +import type { RuleConfig } from '../rule-config'; + +/** + * Option. + */ +export interface AnchorHasContentOption { + components?: string[]; + [k: string]: any; +} + +/** + * Options. + */ +export type AnchorHasContentOptions = [AnchorHasContentOption?]; + +/** + * Enforce all anchors to contain accessible content. + * + * @see [anchor-has-content](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/anchor-has-content.md) + */ +export type AnchorHasContentRuleConfig = RuleConfig; + +/** + * Enforce all anchors to contain accessible content. + * + * @see [anchor-has-content](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/anchor-has-content.md) + */ +export interface AnchorHasContentRule { + /** + * Enforce all anchors to contain accessible content. + * + * @see [anchor-has-content](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/anchor-has-content.md) + */ + 'jsx-a11y/anchor-has-content': AnchorHasContentRuleConfig; +} diff --git a/src/rules/jsx-a11y/anchor-is-valid.d.ts b/src/rules/jsx-a11y/anchor-is-valid.d.ts new file mode 100644 index 00000000..e6713f30 --- /dev/null +++ b/src/rules/jsx-a11y/anchor-is-valid.d.ts @@ -0,0 +1,43 @@ +import type { RuleConfig } from '../rule-config'; + +/** + * Option. + */ +export interface AnchorIsValidOption { + components?: string[]; + specialLink?: string[]; + /** + * @minItems 1 + */ + aspects?: [ + 'noHref' | 'invalidHref' | 'preferButton', + ...('noHref' | 'invalidHref' | 'preferButton')[], + ]; + [k: string]: any; +} + +/** + * Options. + */ +export type AnchorIsValidOptions = [AnchorIsValidOption?]; + +/** + * Enforce all anchors are valid, navigable elements. + * + * @see [anchor-is-valid](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/anchor-is-valid.md) + */ +export type AnchorIsValidRuleConfig = RuleConfig; + +/** + * Enforce all anchors are valid, navigable elements. + * + * @see [anchor-is-valid](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/anchor-is-valid.md) + */ +export interface AnchorIsValidRule { + /** + * Enforce all anchors are valid, navigable elements. + * + * @see [anchor-is-valid](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/anchor-is-valid.md) + */ + 'jsx-a11y/anchor-is-valid': AnchorIsValidRuleConfig; +} diff --git a/src/rules/jsx-a11y/aria-activedescendant-has-tabindex.d.ts b/src/rules/jsx-a11y/aria-activedescendant-has-tabindex.d.ts new file mode 100644 index 00000000..8ab523ef --- /dev/null +++ b/src/rules/jsx-a11y/aria-activedescendant-has-tabindex.d.ts @@ -0,0 +1,37 @@ +import type { RuleConfig } from '../rule-config'; + +/** + * Option. + */ +export interface AriaActivedescendantHasTabindexOption { + [k: string]: any; +} + +/** + * Options. + */ +export type AriaActivedescendantHasTabindexOptions = [ + AriaActivedescendantHasTabindexOption?, +]; + +/** + * Enforce elements with aria-activedescendant are tabbable. + * + * @see [aria-activedescendant-has-tabindex](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/aria-activedescendant-has-tabindex.md) + */ +export type AriaActivedescendantHasTabindexRuleConfig = + RuleConfig; + +/** + * Enforce elements with aria-activedescendant are tabbable. + * + * @see [aria-activedescendant-has-tabindex](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/aria-activedescendant-has-tabindex.md) + */ +export interface AriaActivedescendantHasTabindexRule { + /** + * Enforce elements with aria-activedescendant are tabbable. + * + * @see [aria-activedescendant-has-tabindex](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/aria-activedescendant-has-tabindex.md) + */ + 'jsx-a11y/aria-activedescendant-has-tabindex': AriaActivedescendantHasTabindexRuleConfig; +} diff --git a/src/rules/jsx-a11y/aria-props.d.ts b/src/rules/jsx-a11y/aria-props.d.ts new file mode 100644 index 00000000..1d6c979a --- /dev/null +++ b/src/rules/jsx-a11y/aria-props.d.ts @@ -0,0 +1,34 @@ +import type { RuleConfig } from '../rule-config'; + +/** + * Option. + */ +export interface AriaPropsOption { + [k: string]: any; +} + +/** + * Options. + */ +export type AriaPropsOptions = [AriaPropsOption?]; + +/** + * Enforce all `aria-*` props are valid. + * + * @see [aria-props](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/aria-props.md) + */ +export type AriaPropsRuleConfig = RuleConfig; + +/** + * Enforce all `aria-*` props are valid. + * + * @see [aria-props](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/aria-props.md) + */ +export interface AriaPropsRule { + /** + * Enforce all `aria-*` props are valid. + * + * @see [aria-props](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/aria-props.md) + */ + 'jsx-a11y/aria-props': AriaPropsRuleConfig; +} diff --git a/src/rules/jsx-a11y/aria-proptypes.d.ts b/src/rules/jsx-a11y/aria-proptypes.d.ts new file mode 100644 index 00000000..e67457c1 --- /dev/null +++ b/src/rules/jsx-a11y/aria-proptypes.d.ts @@ -0,0 +1,34 @@ +import type { RuleConfig } from '../rule-config'; + +/** + * Option. + */ +export interface AriaProptypesOption { + [k: string]: any; +} + +/** + * Options. + */ +export type AriaProptypesOptions = [AriaProptypesOption?]; + +/** + * Enforce ARIA state and property values are valid. + * + * @see [aria-proptypes](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/aria-proptypes.md) + */ +export type AriaProptypesRuleConfig = RuleConfig; + +/** + * Enforce ARIA state and property values are valid. + * + * @see [aria-proptypes](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/aria-proptypes.md) + */ +export interface AriaProptypesRule { + /** + * Enforce ARIA state and property values are valid. + * + * @see [aria-proptypes](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/aria-proptypes.md) + */ + 'jsx-a11y/aria-proptypes': AriaProptypesRuleConfig; +} diff --git a/src/rules/jsx-a11y/aria-role.d.ts b/src/rules/jsx-a11y/aria-role.d.ts new file mode 100644 index 00000000..1fe5e764 --- /dev/null +++ b/src/rules/jsx-a11y/aria-role.d.ts @@ -0,0 +1,36 @@ +import type { RuleConfig } from '../rule-config'; + +/** + * Option. + */ +export interface AriaRoleOption { + allowedInvalidRoles?: string[]; + ignoreNonDOM?: boolean; + [k: string]: any; +} + +/** + * Options. + */ +export type AriaRoleOptions = [AriaRoleOption?]; + +/** + * Enforce that elements with ARIA roles must use a valid, non-abstract ARIA role. + * + * @see [aria-role](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/aria-role.md) + */ +export type AriaRoleRuleConfig = RuleConfig; + +/** + * Enforce that elements with ARIA roles must use a valid, non-abstract ARIA role. + * + * @see [aria-role](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/aria-role.md) + */ +export interface AriaRoleRule { + /** + * Enforce that elements with ARIA roles must use a valid, non-abstract ARIA role. + * + * @see [aria-role](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/aria-role.md) + */ + 'jsx-a11y/aria-role': AriaRoleRuleConfig; +} diff --git a/src/rules/jsx-a11y/aria-unsupported-elements.d.ts b/src/rules/jsx-a11y/aria-unsupported-elements.d.ts new file mode 100644 index 00000000..ad78bd02 --- /dev/null +++ b/src/rules/jsx-a11y/aria-unsupported-elements.d.ts @@ -0,0 +1,35 @@ +import type { RuleConfig } from '../rule-config'; + +/** + * Option. + */ +export interface AriaUnsupportedElementsOption { + [k: string]: any; +} + +/** + * Options. + */ +export type AriaUnsupportedElementsOptions = [AriaUnsupportedElementsOption?]; + +/** + * Enforce that elements that do not support ARIA roles, states, and properties do not have those attributes. + * + * @see [aria-unsupported-elements](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/aria-unsupported-elements.md) + */ +export type AriaUnsupportedElementsRuleConfig = + RuleConfig; + +/** + * Enforce that elements that do not support ARIA roles, states, and properties do not have those attributes. + * + * @see [aria-unsupported-elements](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/aria-unsupported-elements.md) + */ +export interface AriaUnsupportedElementsRule { + /** + * Enforce that elements that do not support ARIA roles, states, and properties do not have those attributes. + * + * @see [aria-unsupported-elements](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/aria-unsupported-elements.md) + */ + 'jsx-a11y/aria-unsupported-elements': AriaUnsupportedElementsRuleConfig; +} diff --git a/src/rules/jsx-a11y/autocomplete-valid.d.ts b/src/rules/jsx-a11y/autocomplete-valid.d.ts new file mode 100644 index 00000000..33cc99bb --- /dev/null +++ b/src/rules/jsx-a11y/autocomplete-valid.d.ts @@ -0,0 +1,35 @@ +import type { RuleConfig } from '../rule-config'; + +/** + * Option. + */ +export interface AutocompleteValidOption { + inputComponents?: string[]; + [k: string]: any; +} + +/** + * Options. + */ +export type AutocompleteValidOptions = [AutocompleteValidOption?]; + +/** + * Enforce that autocomplete attributes are used correctly. + * + * @see [autocomplete-valid](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/autocomplete-valid.md) + */ +export type AutocompleteValidRuleConfig = RuleConfig; + +/** + * Enforce that autocomplete attributes are used correctly. + * + * @see [autocomplete-valid](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/autocomplete-valid.md) + */ +export interface AutocompleteValidRule { + /** + * Enforce that autocomplete attributes are used correctly. + * + * @see [autocomplete-valid](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/autocomplete-valid.md) + */ + 'jsx-a11y/autocomplete-valid': AutocompleteValidRuleConfig; +} diff --git a/src/rules/jsx-a11y/click-events-have-key-events.d.ts b/src/rules/jsx-a11y/click-events-have-key-events.d.ts new file mode 100644 index 00000000..86c21a30 --- /dev/null +++ b/src/rules/jsx-a11y/click-events-have-key-events.d.ts @@ -0,0 +1,35 @@ +import type { RuleConfig } from '../rule-config'; + +/** + * Option. + */ +export interface ClickEventsHaveKeyEventsOption { + [k: string]: any; +} + +/** + * Options. + */ +export type ClickEventsHaveKeyEventsOptions = [ClickEventsHaveKeyEventsOption?]; + +/** + * Enforce a clickable non-interactive element has at least one keyboard event listener. + * + * @see [click-events-have-key-events](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/click-events-have-key-events.md) + */ +export type ClickEventsHaveKeyEventsRuleConfig = + RuleConfig; + +/** + * Enforce a clickable non-interactive element has at least one keyboard event listener. + * + * @see [click-events-have-key-events](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/click-events-have-key-events.md) + */ +export interface ClickEventsHaveKeyEventsRule { + /** + * Enforce a clickable non-interactive element has at least one keyboard event listener. + * + * @see [click-events-have-key-events](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/click-events-have-key-events.md) + */ + 'jsx-a11y/click-events-have-key-events': ClickEventsHaveKeyEventsRuleConfig; +} diff --git a/src/rules/jsx-a11y/control-has-associated-label.d.ts b/src/rules/jsx-a11y/control-has-associated-label.d.ts new file mode 100644 index 00000000..847d102e --- /dev/null +++ b/src/rules/jsx-a11y/control-has-associated-label.d.ts @@ -0,0 +1,45 @@ +import type { RuleConfig } from '../rule-config'; + +/** + * Option. + */ +export interface ControlHasAssociatedLabelOption { + labelAttributes?: string[]; + controlComponents?: string[]; + ignoreElements?: string[]; + ignoreRoles?: string[]; + /** + * JSX tree depth limit to check for accessible label + */ + depth?: number; + [k: string]: any; +} + +/** + * Options. + */ +export type ControlHasAssociatedLabelOptions = [ + ControlHasAssociatedLabelOption?, +]; + +/** + * Enforce that a control (an interactive element) has a text label. + * + * @see [control-has-associated-label](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/control-has-associated-label.md) + */ +export type ControlHasAssociatedLabelRuleConfig = + RuleConfig; + +/** + * Enforce that a control (an interactive element) has a text label. + * + * @see [control-has-associated-label](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/control-has-associated-label.md) + */ +export interface ControlHasAssociatedLabelRule { + /** + * Enforce that a control (an interactive element) has a text label. + * + * @see [control-has-associated-label](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/control-has-associated-label.md) + */ + 'jsx-a11y/control-has-associated-label': ControlHasAssociatedLabelRuleConfig; +} diff --git a/src/rules/jsx-a11y/heading-has-content.d.ts b/src/rules/jsx-a11y/heading-has-content.d.ts new file mode 100644 index 00000000..a6f82db9 --- /dev/null +++ b/src/rules/jsx-a11y/heading-has-content.d.ts @@ -0,0 +1,35 @@ +import type { RuleConfig } from '../rule-config'; + +/** + * Option. + */ +export interface HeadingHasContentOption { + components?: string[]; + [k: string]: any; +} + +/** + * Options. + */ +export type HeadingHasContentOptions = [HeadingHasContentOption?]; + +/** + * Enforce heading (`h1`, `h2`, etc) elements contain accessible content. + * + * @see [heading-has-content](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/heading-has-content.md) + */ +export type HeadingHasContentRuleConfig = RuleConfig; + +/** + * Enforce heading (`h1`, `h2`, etc) elements contain accessible content. + * + * @see [heading-has-content](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/heading-has-content.md) + */ +export interface HeadingHasContentRule { + /** + * Enforce heading (`h1`, `h2`, etc) elements contain accessible content. + * + * @see [heading-has-content](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/heading-has-content.md) + */ + 'jsx-a11y/heading-has-content': HeadingHasContentRuleConfig; +} diff --git a/src/rules/jsx-a11y/html-has-lang.d.ts b/src/rules/jsx-a11y/html-has-lang.d.ts new file mode 100644 index 00000000..9818912f --- /dev/null +++ b/src/rules/jsx-a11y/html-has-lang.d.ts @@ -0,0 +1,34 @@ +import type { RuleConfig } from '../rule-config'; + +/** + * Option. + */ +export interface HtmlHasLangOption { + [k: string]: any; +} + +/** + * Options. + */ +export type HtmlHasLangOptions = [HtmlHasLangOption?]; + +/** + * Enforce `` element has `lang` prop. + * + * @see [html-has-lang](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/html-has-lang.md) + */ +export type HtmlHasLangRuleConfig = RuleConfig; + +/** + * Enforce `` element has `lang` prop. + * + * @see [html-has-lang](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/html-has-lang.md) + */ +export interface HtmlHasLangRule { + /** + * Enforce `` element has `lang` prop. + * + * @see [html-has-lang](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/html-has-lang.md) + */ + 'jsx-a11y/html-has-lang': HtmlHasLangRuleConfig; +} diff --git a/src/rules/jsx-a11y/iframe-has-title.d.ts b/src/rules/jsx-a11y/iframe-has-title.d.ts new file mode 100644 index 00000000..94349ce2 --- /dev/null +++ b/src/rules/jsx-a11y/iframe-has-title.d.ts @@ -0,0 +1,34 @@ +import type { RuleConfig } from '../rule-config'; + +/** + * Option. + */ +export interface IframeHasTitleOption { + [k: string]: any; +} + +/** + * Options. + */ +export type IframeHasTitleOptions = [IframeHasTitleOption?]; + +/** + * Enforce iframe elements have a title attribute. + * + * @see [iframe-has-title](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/iframe-has-title.md) + */ +export type IframeHasTitleRuleConfig = RuleConfig; + +/** + * Enforce iframe elements have a title attribute. + * + * @see [iframe-has-title](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/iframe-has-title.md) + */ +export interface IframeHasTitleRule { + /** + * Enforce iframe elements have a title attribute. + * + * @see [iframe-has-title](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/iframe-has-title.md) + */ + 'jsx-a11y/iframe-has-title': IframeHasTitleRuleConfig; +} diff --git a/src/rules/jsx-a11y/img-redundant-alt.d.ts b/src/rules/jsx-a11y/img-redundant-alt.d.ts new file mode 100644 index 00000000..33b23986 --- /dev/null +++ b/src/rules/jsx-a11y/img-redundant-alt.d.ts @@ -0,0 +1,36 @@ +import type { RuleConfig } from '../rule-config'; + +/** + * Option. + */ +export interface ImgRedundantAltOption { + components?: string[]; + words?: string[]; + [k: string]: any; +} + +/** + * Options. + */ +export type ImgRedundantAltOptions = [ImgRedundantAltOption?]; + +/** + * Enforce `` alt prop does not contain the word "image", "picture", or "photo". + * + * @see [img-redundant-alt](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/img-redundant-alt.md) + */ +export type ImgRedundantAltRuleConfig = RuleConfig; + +/** + * Enforce `` alt prop does not contain the word "image", "picture", or "photo". + * + * @see [img-redundant-alt](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/img-redundant-alt.md) + */ +export interface ImgRedundantAltRule { + /** + * Enforce `` alt prop does not contain the word "image", "picture", or "photo". + * + * @see [img-redundant-alt](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/img-redundant-alt.md) + */ + 'jsx-a11y/img-redundant-alt': ImgRedundantAltRuleConfig; +} diff --git a/src/rules/jsx-a11y/index.d.ts b/src/rules/jsx-a11y/index.d.ts new file mode 100644 index 00000000..5821becc --- /dev/null +++ b/src/rules/jsx-a11y/index.d.ts @@ -0,0 +1,82 @@ +import type { AccessibleEmojiRule } from './accessible-emoji'; +import type { AltTextRule } from './alt-text'; +import type { AnchorAmbiguousTextRule } from './anchor-ambiguous-text'; +import type { AnchorHasContentRule } from './anchor-has-content'; +import type { AnchorIsValidRule } from './anchor-is-valid'; +import type { AriaActivedescendantHasTabindexRule } from './aria-activedescendant-has-tabindex'; +import type { AriaPropsRule } from './aria-props'; +import type { AriaProptypesRule } from './aria-proptypes'; +import type { AriaRoleRule } from './aria-role'; +import type { AriaUnsupportedElementsRule } from './aria-unsupported-elements'; +import type { AutocompleteValidRule } from './autocomplete-valid'; +import type { ClickEventsHaveKeyEventsRule } from './click-events-have-key-events'; +import type { ControlHasAssociatedLabelRule } from './control-has-associated-label'; +import type { HeadingHasContentRule } from './heading-has-content'; +import type { HtmlHasLangRule } from './html-has-lang'; +import type { IframeHasTitleRule } from './iframe-has-title'; +import type { ImgRedundantAltRule } from './img-redundant-alt'; +import type { InteractiveSupportsFocusRule } from './interactive-supports-focus'; +import type { LabelHasAssociatedControlRule } from './label-has-associated-control'; +import type { LabelHasForRule } from './label-has-for'; +import type { LangRule } from './lang'; +import type { MediaHasCaptionRule } from './media-has-caption'; +import type { MouseEventsHaveKeyEventsRule } from './mouse-events-have-key-events'; +import type { NoAccessKeyRule } from './no-access-key'; +import type { NoAriaHiddenOnFocusableRule } from './no-aria-hidden-on-focusable'; +import type { NoAutofocusRule } from './no-autofocus'; +import type { NoDistractingElementsRule } from './no-distracting-elements'; +import type { NoInteractiveElementToNoninteractiveRoleRule } from './no-interactive-element-to-noninteractive-role'; +import type { NoNoninteractiveElementInteractionsRule } from './no-noninteractive-element-interactions'; +import type { NoNoninteractiveElementToInteractiveRoleRule } from './no-noninteractive-element-to-interactive-role'; +import type { NoNoninteractiveTabindexRule } from './no-noninteractive-tabindex'; +import type { NoOnchangeRule } from './no-onchange'; +import type { NoRedundantRolesRule } from './no-redundant-roles'; +import type { NoStaticElementInteractionsRule } from './no-static-element-interactions'; +import type { PreferTagOverRoleRule } from './prefer-tag-over-role'; +import type { RoleHasRequiredAriaPropsRule } from './role-has-required-aria-props'; +import type { RoleSupportsAriaPropsRule } from './role-supports-aria-props'; +import type { ScopeRule } from './scope'; +import type { TabindexNoPositiveRule } from './tabindex-no-positive'; + +/** + * All JsxA11y rules. + */ +export type JsxA11yRules = AccessibleEmojiRule & + AltTextRule & + AnchorAmbiguousTextRule & + AnchorHasContentRule & + AnchorIsValidRule & + AriaActivedescendantHasTabindexRule & + AriaPropsRule & + AriaProptypesRule & + AriaRoleRule & + AriaUnsupportedElementsRule & + AutocompleteValidRule & + ClickEventsHaveKeyEventsRule & + ControlHasAssociatedLabelRule & + HeadingHasContentRule & + HtmlHasLangRule & + IframeHasTitleRule & + ImgRedundantAltRule & + InteractiveSupportsFocusRule & + LabelHasAssociatedControlRule & + LabelHasForRule & + LangRule & + MediaHasCaptionRule & + MouseEventsHaveKeyEventsRule & + NoAccessKeyRule & + NoAriaHiddenOnFocusableRule & + NoAutofocusRule & + NoDistractingElementsRule & + NoInteractiveElementToNoninteractiveRoleRule & + NoNoninteractiveElementInteractionsRule & + NoNoninteractiveElementToInteractiveRoleRule & + NoNoninteractiveTabindexRule & + NoOnchangeRule & + NoRedundantRolesRule & + NoStaticElementInteractionsRule & + PreferTagOverRoleRule & + RoleHasRequiredAriaPropsRule & + RoleSupportsAriaPropsRule & + ScopeRule & + TabindexNoPositiveRule; diff --git a/src/rules/jsx-a11y/interactive-supports-focus.d.ts b/src/rules/jsx-a11y/interactive-supports-focus.d.ts new file mode 100644 index 00000000..ef2fadc2 --- /dev/null +++ b/src/rules/jsx-a11y/interactive-supports-focus.d.ts @@ -0,0 +1,74 @@ +import type { RuleConfig } from '../rule-config'; + +/** + * Option. + */ +export interface InteractiveSupportsFocusOption { + /** + * @minItems 0 + */ + tabbable?: ( + | 'button' + | 'checkbox' + | 'columnheader' + | 'combobox' + | 'grid' + | 'gridcell' + | 'link' + | 'listbox' + | 'menu' + | 'menubar' + | 'menuitem' + | 'menuitemcheckbox' + | 'menuitemradio' + | 'option' + | 'progressbar' + | 'radio' + | 'radiogroup' + | 'row' + | 'rowheader' + | 'scrollbar' + | 'searchbox' + | 'slider' + | 'spinbutton' + | 'switch' + | 'tab' + | 'tablist' + | 'textbox' + | 'tree' + | 'treegrid' + | 'treeitem' + | 'doc-backlink' + | 'doc-biblioref' + | 'doc-glossref' + | 'doc-noteref' + )[]; + [k: string]: any; +} + +/** + * Options. + */ +export type InteractiveSupportsFocusOptions = [InteractiveSupportsFocusOption?]; + +/** + * Enforce that elements with interactive handlers like `onClick` must be focusable. + * + * @see [interactive-supports-focus](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/interactive-supports-focus.md) + */ +export type InteractiveSupportsFocusRuleConfig = + RuleConfig; + +/** + * Enforce that elements with interactive handlers like `onClick` must be focusable. + * + * @see [interactive-supports-focus](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/interactive-supports-focus.md) + */ +export interface InteractiveSupportsFocusRule { + /** + * Enforce that elements with interactive handlers like `onClick` must be focusable. + * + * @see [interactive-supports-focus](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/interactive-supports-focus.md) + */ + 'jsx-a11y/interactive-supports-focus': InteractiveSupportsFocusRuleConfig; +} diff --git a/src/rules/jsx-a11y/label-has-associated-control.d.ts b/src/rules/jsx-a11y/label-has-associated-control.d.ts new file mode 100644 index 00000000..28f749d6 --- /dev/null +++ b/src/rules/jsx-a11y/label-has-associated-control.d.ts @@ -0,0 +1,48 @@ +import type { RuleConfig } from '../rule-config'; + +/** + * Option. + */ +export interface LabelHasAssociatedControlOption { + labelComponents?: string[]; + labelAttributes?: string[]; + controlComponents?: string[]; + /** + * Assert that the label has htmlFor, a nested label, both or either + */ + assert?: 'htmlFor' | 'nesting' | 'both' | 'either'; + /** + * JSX tree depth limit to check for accessible label + */ + depth?: number; + [k: string]: any; +} + +/** + * Options. + */ +export type LabelHasAssociatedControlOptions = [ + LabelHasAssociatedControlOption?, +]; + +/** + * Enforce that a `label` tag has a text label and an associated control. + * + * @see [label-has-associated-control](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/label-has-associated-control.md) + */ +export type LabelHasAssociatedControlRuleConfig = + RuleConfig; + +/** + * Enforce that a `label` tag has a text label and an associated control. + * + * @see [label-has-associated-control](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/label-has-associated-control.md) + */ +export interface LabelHasAssociatedControlRule { + /** + * Enforce that a `label` tag has a text label and an associated control. + * + * @see [label-has-associated-control](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/label-has-associated-control.md) + */ + 'jsx-a11y/label-has-associated-control': LabelHasAssociatedControlRuleConfig; +} diff --git a/src/rules/jsx-a11y/label-has-for.d.ts b/src/rules/jsx-a11y/label-has-for.d.ts new file mode 100644 index 00000000..8d011791 --- /dev/null +++ b/src/rules/jsx-a11y/label-has-for.d.ts @@ -0,0 +1,58 @@ +import type { RuleConfig } from '../rule-config'; + +/** + * Option. + */ +export interface LabelHasForOption { + components?: string[]; + required?: + | ('nesting' | 'id') + | { + /** + * @minItems 0 + */ + some: ('nesting' | 'id')[]; + [k: string]: any; + } + | { + /** + * @minItems 0 + */ + every: ('nesting' | 'id')[]; + [k: string]: any; + }; + allowChildren?: boolean; + [k: string]: any; +} + +/** + * Options. + */ +export type LabelHasForOptions = [LabelHasForOption?]; + +/** + * Enforce that `