Skip to content

Commit 72c98fe

Browse files
committed
feat: add support for Flat Config
This change adds support for ESLint's new Flat config system. It maintains backwards compatibility with eslintrc style configs as well. To achieve this, we're now dynamically creating four configs: two are the original `recommended` and `strict`, and the other two are the new `flat/recommended` and `flat/strict`. The two `flat` ones are setup with the new config format, while the original two have the same options as before. Usage Legacy ```json { "extends": ["plugin:jsx-a11y/recommended"] } ``` Flat ```js import globals from 'globals'; import js from '@eslint/js'; import jsxA11y from 'eslint-plugin-jsx-a11y'; export default [ js.configs.recommended, jsxA11y.configs['flat/recommended'], { files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'], languageOptions: { ecmaVersion: 'latest', sourceType: 'module', globals: globals.browser, }, ignores: ['dist', 'eslint.config.js'], rules: { 'no-unused-vars': 'warn', 'jsx-a11y/anchor-ambiguous-text': 'warn', 'jsx-a11y/anchor-is-valid': 'warn', }, }, ]; ```
1 parent 5d14408 commit 72c98fe

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1198
-293
lines changed

.eslintignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
examples/

README.md

+92-2
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ yarn add eslint-plugin-jsx-a11y --dev
6060

6161
**Note:** If you installed ESLint globally (using the `-g` flag in npm, or the `global` prefix in yarn) then you must also install `eslint-plugin-jsx-a11y` globally.
6262

63-
## Usage
63+
<a id="usage"></a>
64+
65+
## Usage - Legacy Config (`.eslintrc`)
6466

6567
Add `jsx-a11y` to the plugins section of your `.eslintrc` configuration file. You can omit the `eslint-plugin-` prefix:
6668

@@ -109,6 +111,94 @@ Add `plugin:jsx-a11y/recommended` or `plugin:jsx-a11y/strict` in `extends`:
109111
}
110112
```
111113

114+
## Usage - Flat Config (`eslint.config.js`)
115+
116+
The default export of `eslint-plugin-jsx-a11y` is a plugin object.
117+
118+
```js
119+
const jsxA11y = require('eslint-plugin-jsx-a11y');
120+
121+
module.exports = [
122+
123+
{
124+
files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],
125+
plugins: {
126+
'jsx-a11y': jsxA11y,
127+
},
128+
languageOptions: {
129+
parserOptions: {
130+
ecmaFeatures: {
131+
jsx: true,
132+
},
133+
},
134+
},
135+
rules: {
136+
// ... any rules you want
137+
'jsx-a11y/alt-text': 'error',
138+
},
139+
// ... others are omitted for brevity
140+
},
141+
142+
];
143+
```
144+
145+
### Shareable Configs
146+
147+
There are two shareable configs, provided by the plugin.
148+
149+
- `flat/strict`
150+
- `flat/recommended`
151+
152+
#### CJS
153+
154+
```js
155+
const jsxA11y = require('eslint-plugin-jsx-a11y');
156+
157+
export default [
158+
jsxA11y.configs['flat/recommended'],
159+
{
160+
// Your additional configs and overrides
161+
},
162+
];
163+
```
164+
165+
#### ESM
166+
167+
```js
168+
import jsxA11y from 'eslint-plugin-jsx-a11y';
169+
170+
export default [
171+
jsxA11y.configs['flat/recommended'],
172+
{
173+
// Your additional configs and overrides
174+
},
175+
];
176+
```
177+
178+
**Note**: Our shareable config do configure `files` or [`languageOptions.globals`](https://eslint.org/docs/latest/user-guide/configuring/configuration-files-new#configuration-objects).
179+
For most of the cases, you probably want to configure some of these properties yourself.
180+
181+
```js
182+
const jsxA11yRecommended = require('eslint-plugin-jsx-a11y');
183+
const globals = require('globals');
184+
185+
module.exports = [
186+
187+
{
188+
files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],
189+
...jsxA11y.configs['flat/recommended'],
190+
languageOptions: {
191+
...jsxA11y.configs['flat/recommended'].languageOptions,
192+
globals: {
193+
...globals.serviceworker,
194+
...globals.browser,
195+
},
196+
},
197+
},
198+
199+
];
200+
```
201+
112202
#### Component Mapping
113203

114204
To enable your custom components to be checked as DOM elements, you can set global settings in your configuration file by mapping each custom component name to a DOM element type.
@@ -124,7 +214,7 @@ For example, if you set the `polymorphicPropName` setting to `as` then this elem
124214

125215
will be evaluated as an `h3`. If no `polymorphicPropName` is set, then the component will be evaluated as `Box`.
126216

127-
⚠️ Polymorphic components can make code harder to maintain; please use this feature with caution.
217+
⚠️ Polymorphic components can make code harder to maintain; please use this feature with caution.
128218

129219
## Supported Rules
130220

examples/flat-cjs/.gitignore

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
node_modules
11+
dist
12+
dist-ssr
13+
*.local
14+
15+
# Editor directories and files
16+
.vscode/*
17+
!.vscode/extensions.json
18+
.idea
19+
.DS_Store
20+
*.suo
21+
*.ntvs*
22+
*.njsproj
23+
*.sln
24+
*.sw?

examples/flat-cjs/README.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# React + Vite
2+
3+
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4+
5+
Currently, two official plugins are available:
6+
7+
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
8+
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh

examples/flat-cjs/eslint.config.cjs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const globals = require('globals');
2+
const js = require('@eslint/js');
3+
const jsxA11y = require('eslint-plugin-jsx-a11y');
4+
5+
module.exports = [
6+
js.configs.recommended,
7+
jsxA11y.configs['flat/recommended'],
8+
{
9+
files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],
10+
languageOptions: {
11+
ecmaVersion: 'latest',
12+
sourceType: 'module',
13+
globals: globals.browser,
14+
},
15+
ignores: ['dist', 'eslint.config.cjs'],
16+
rules: {
17+
'no-unused-vars': 'warn',
18+
'jsx-a11y/anchor-ambiguous-text': 'warn',
19+
'jsx-a11y/anchor-is-valid': 'warn',
20+
},
21+
},
22+
];

examples/flat-cjs/index.html

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Vite + React</title>
8+
</head>
9+
<body>
10+
<div id="root"></div>
11+
<script type="module" src="/src/main.jsx"></script>
12+
</body>
13+
</html>

examples/flat-cjs/package.json

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "flat-cjs",
3+
"private": true,
4+
"version": "0.0.0",
5+
"type": "module",
6+
"scripts": {
7+
"dev": "vite",
8+
"build": "vite build",
9+
"lint": "cross-env ESLINT_USE_FLAT_CONFIG=true eslint . --report-unused-disable-directives",
10+
"preview": "vite preview"
11+
},
12+
"dependencies": {
13+
"react": "^18.2.0",
14+
"react-dom": "^18.2.0"
15+
},
16+
"devDependencies": {
17+
"@eslint/js": "^9.5.0",
18+
"@types/react": "^18.2.66",
19+
"@types/react-dom": "^18.2.22",
20+
"@vitejs/plugin-react": "^4.2.1",
21+
"cross-env": "^7.0.3",
22+
"eslint": "^8.57.0",
23+
"eslint-plugin-jsx-a11y": "file:../..",
24+
"globals": "^15.6.0",
25+
"vite": "^5.2.0"
26+
}
27+
}

examples/flat-cjs/public/vite.svg

+1
Loading

examples/flat-cjs/src/App.css

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#root {
2+
max-width: 1280px;
3+
margin: 0 auto;
4+
padding: 2rem;
5+
text-align: center;
6+
}
7+
8+
.logo {
9+
height: 6em;
10+
padding: 1.5em;
11+
will-change: filter;
12+
transition: filter 300ms;
13+
}
14+
.logo:hover {
15+
filter: drop-shadow(0 0 2em #646cffaa);
16+
}
17+
.logo.react:hover {
18+
filter: drop-shadow(0 0 2em #61dafbaa);
19+
}
20+
21+
@keyframes logo-spin {
22+
from {
23+
transform: rotate(0deg);
24+
}
25+
to {
26+
transform: rotate(360deg);
27+
}
28+
}
29+
30+
@media (prefers-reduced-motion: no-preference) {
31+
a:nth-of-type(2) .logo {
32+
animation: logo-spin infinite 20s linear;
33+
}
34+
}
35+
36+
.card {
37+
padding: 2em;
38+
}
39+
40+
.read-the-docs {
41+
color: #888;
42+
}

examples/flat-cjs/src/App.jsx

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { useState } from 'react';
2+
import reactLogo from './assets/react.svg';
3+
import viteLogo from '/vite.svg';
4+
import './App.css';
5+
6+
function App() {
7+
const [count, setCount] = useState(0);
8+
9+
return (
10+
<>
11+
<div>
12+
<a href="https://vitejs.dev" target="_blank">
13+
<img src={viteLogo} className="logo" alt="Vite logo" />
14+
</a>
15+
<a href="https://react.dev" target="_blank">
16+
<img src={reactLogo} className="logo react" alt="React logo" />
17+
</a>
18+
<a>click here</a>
19+
</div>
20+
<h1>Vite + React</h1>
21+
<div className="card">
22+
<button onClick={() => setCount((count) => count + 1)}>
23+
count is {count}
24+
</button>
25+
<p>
26+
Edit <code>src/App.jsx</code> and save to test HMR
27+
</p>
28+
</div>
29+
<p className="read-the-docs">
30+
Click on the Vite and React logos to learn more
31+
</p>
32+
</>
33+
);
34+
}
35+
36+
export default App;
+1
Loading

examples/flat-cjs/src/index.css

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
:root {
2+
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
3+
line-height: 1.5;
4+
font-weight: 400;
5+
6+
color-scheme: light dark;
7+
color: rgba(255, 255, 255, 0.87);
8+
background-color: #242424;
9+
10+
font-synthesis: none;
11+
text-rendering: optimizeLegibility;
12+
-webkit-font-smoothing: antialiased;
13+
-moz-osx-font-smoothing: grayscale;
14+
}
15+
16+
a {
17+
font-weight: 500;
18+
color: #646cff;
19+
text-decoration: inherit;
20+
}
21+
a:hover {
22+
color: #535bf2;
23+
}
24+
25+
body {
26+
margin: 0;
27+
display: flex;
28+
place-items: center;
29+
min-width: 320px;
30+
min-height: 100vh;
31+
}
32+
33+
h1 {
34+
font-size: 3.2em;
35+
line-height: 1.1;
36+
}
37+
38+
button {
39+
border-radius: 8px;
40+
border: 1px solid transparent;
41+
padding: 0.6em 1.2em;
42+
font-size: 1em;
43+
font-weight: 500;
44+
font-family: inherit;
45+
background-color: #1a1a1a;
46+
cursor: pointer;
47+
transition: border-color 0.25s;
48+
}
49+
button:hover {
50+
border-color: #646cff;
51+
}
52+
button:focus,
53+
button:focus-visible {
54+
outline: 4px auto -webkit-focus-ring-color;
55+
}
56+
57+
@media (prefers-color-scheme: light) {
58+
:root {
59+
color: #213547;
60+
background-color: #ffffff;
61+
}
62+
a:hover {
63+
color: #747bff;
64+
}
65+
button {
66+
background-color: #f9f9f9;
67+
}
68+
}

examples/flat-cjs/src/main.jsx

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import React from 'react'
2+
import ReactDOM from 'react-dom/client'
3+
import App from './App.jsx'
4+
import './index.css'
5+
6+
ReactDOM.createRoot(document.getElementById('root')).render(
7+
<React.StrictMode>
8+
<App />
9+
</React.StrictMode>,
10+
)

examples/flat-cjs/vite.config.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { defineConfig } from 'vite'
2+
import react from '@vitejs/plugin-react'
3+
4+
// https://vitejs.dev/config/
5+
export default defineConfig({
6+
plugins: [react()],
7+
})

0 commit comments

Comments
 (0)