@mikey-pro/eslint-config-react 8.1.0 → 9.0.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 (4) hide show
  1. package/README.md +9 -2
  2. package/flat.js +3 -0
  3. package/index.js +269 -240
  4. package/package.json +30 -12
package/README.md CHANGED
@@ -18,9 +18,16 @@ A preset ESLint React configuration
18
18
  npm i -D mikey-pro @mikey-pro/eslint-config-react
19
19
  ```
20
20
 
21
- ### Configure
21
+ ### Configure (Flat ESLint v9+ Recommended)
22
22
 
23
- Extend to ESLint in `package.json`:
23
+ ```js
24
+ // eslint.config.js
25
+ import reactConfig from '@mikey-pro/eslint-config-react/flat';
26
+
27
+ export default reactConfig;
28
+ ```
29
+
30
+ ### Legacy Configuration (still supported)
24
31
 
25
32
  ```json
26
33
  {
package/flat.js ADDED
@@ -0,0 +1,3 @@
1
+ // Modern React ESLint 9 Flat Configuration for Mikey Pro
2
+
3
+ export { default } from './index.js';
package/index.js CHANGED
@@ -1,256 +1,285 @@
1
- import baseConfig from '@mikey-pro/eslint-config';
2
- import reactAppConfig from 'eslint-config-react-app-bump';
3
- import jestDomPlugin from 'eslint-plugin-jest-dom';
4
- import jsxA11yPlugin from 'eslint-plugin-jsx-a11y';
5
- import reactPlugin from 'eslint-plugin-react';
6
- import reactHooksPlugin from 'eslint-plugin-react-hooks';
7
- import reactPerformancePlugin from 'eslint-plugin-react-perf';
8
- import reactRefreshPlugin from 'eslint-plugin-react-refresh';
9
- import testingLibraryPlugin from 'eslint-plugin-testing-library';
1
+ // Modern React ESLint configuration for Mikey Pro
2
+ import { baseConfig } from '@mikey-pro/eslint-config/base-config.js';
3
+ import { baseOverrides } from '@mikey-pro/eslint-config/overrides.js';
4
+ import jsxA11y from 'eslint-plugin-jsx-a11y';
5
+ import react from 'eslint-plugin-react';
6
+ import reactHooks from 'eslint-plugin-react-hooks';
7
+ import reactPerf from 'eslint-plugin-react-perf';
8
+ import reactRefresh from 'eslint-plugin-react-refresh';
10
9
 
11
- const reactConfig = [
12
- ...baseConfig,
13
- {
14
- plugins: {
15
- react: reactPlugin,
16
- 'react-hooks': reactHooksPlugin,
17
- 'jsx-a11y': jsxA11yPlugin,
18
- 'react-perf': reactPerformancePlugin,
19
- 'testing-library': testingLibraryPlugin,
20
- 'jest-dom': jestDomPlugin,
21
- 'react-refresh': reactRefreshPlugin,
22
- },
23
- languageOptions: {
24
- parserOptions: {
25
- ...baseConfig.languageOptions.parserOptions,
26
- ecmaVersion: 'latest',
27
- sourceType: 'module',
28
- ecmaFeatures: {
29
- jsx: true,
30
- },
31
- babelOptions: {
32
- ...baseConfig.languageOptions.parserOptions.babelOptions,
33
- presets: [
34
- ...baseConfig.languageOptions.parserOptions.babelOptions.presets,
35
- [
36
- '@babel/preset-react',
37
- {
38
- runtime: 'automatic',
39
- },
40
- ],
41
- ],
42
- },
10
+ // React-specific configuration
11
+ const reactConfig = {
12
+ files: ['**/*.{js,jsx,ts,tsx}'],
13
+ languageOptions: {
14
+ ecmaVersion: 'latest',
15
+ parserOptions: {
16
+ ecmaFeatures: {
17
+ jsx: true,
43
18
  },
44
19
  },
45
- rules: {
46
- ...reactAppConfig.rules,
47
- ...baseConfig.rules,
48
-
49
- // Hooks
50
- 'react-hooks/rules-of-hooks': 'error',
51
- 'react-hooks/exhaustive-deps': [
52
- 'error',
53
- {
54
- additionalHooks: '(useAsync|useAsyncCallback|useMemoizedCallback)',
55
- enableDangerousAutofixThisMayCauseInfiniteLoops: false,
56
- },
57
- ],
58
-
59
- // Accessibility
60
- 'jsx-a11y/alt-text': 'error',
61
- 'jsx-a11y/anchor-has-content': 'error',
62
- 'jsx-a11y/aria-props': 'error',
63
- 'jsx-a11y/aria-role': 'error',
64
- 'jsx-a11y/role-has-required-aria-props': 'error',
65
-
66
- // Modern React
67
- 'react/hook-use-state': 'warn',
68
- 'react/jsx-no-leaked-render': 'warn',
69
- 'react/jsx-no-useless-fragment': 'warn',
70
- 'react/no-array-index-key': 'warn',
71
-
72
- // Performance
73
- 'react-perf/jsx-no-new-object-as-prop': 'warn',
74
- 'react-perf/jsx-no-new-array-as-prop': 'warn',
75
- 'react-perf/jsx-no-new-function-as-prop': 'warn',
76
-
77
- // Modern Patterns
78
- 'react/prefer-stateless-function': 'error',
79
- 'react/no-unused-prop-types': 'warn',
80
- 'react/no-unstable-nested-components': ['error', {
81
- allowAsProps: true,
82
- customValidators: ['memo', 'Suspense'],
83
- }],
84
- 'react/jsx-no-constructed-context-values': ['error', {
85
- allowObjectLiteral: false,
86
- checkFragmentShorthand: true,
87
- }],
88
-
89
- // Existing rules...
90
- 'react/display-name': ['warn', { ignoreTranspilerName: false }],
91
- 'react/function-component-definition': [
92
- 'off',
93
- { namedComponents: 'arrow-function' },
94
- ],
95
- 'react/jsx-curly-spacing': 'warn',
96
- 'react/jsx-key': ['warn', { checkFragmentShorthand: true }],
97
- 'react/jsx-no-bind': [
98
- 'error',
99
- {
100
- allowArrowFunctions: true,
101
- allowFunctions: false,
102
- allowBind: false,
103
- },
104
- ],
105
- 'react/jsx-no-comment-textnodes': 'warn',
106
- 'react/jsx-no-duplicate-props': 'warn',
107
- 'react/jsx-no-target-blank': 'warn',
108
- 'react/jsx-no-undef': 'warn',
109
- 'react/jsx-tag-spacing': ['warn', { beforeSelfClosing: 'always' }],
110
- 'react/jsx-uses-vars': 'warn',
111
- 'react/no-danger': 'warn',
112
- 'react/no-deprecated': 'warn',
113
- 'react/no-did-mount-set-state': 'warn',
114
- 'react/no-did-update-set-state': 'warn',
115
- 'react/no-find-dom-node': 'warn',
116
- 'react/no-is-mounted': 'warn',
117
- 'react/no-string-refs': 'warn',
118
- 'react/prefer-es6-class': 'warn',
119
- 'react/prefer-stateless-function': 'warn',
120
- 'react/require-render-return': 'warn',
121
- 'react/self-closing-comp': [
122
- 'error',
123
- {
124
- component: true,
125
- html: false,
126
- },
127
- ],
128
- 'react/state-in-constructor': 'off',
20
+ sourceType: 'module',
21
+ },
22
+ plugins: {
23
+ 'jsx-a11y': jsxA11y,
24
+ react,
25
+ 'react-hooks': reactHooks,
26
+ 'react-perf': reactPerf,
27
+ 'react-refresh': reactRefresh,
28
+ },
29
+ rules: {
30
+ // React rules
31
+ ...react.configs.recommended.rules,
32
+ ...react.configs['jsx-runtime'].rules,
33
+ ...reactHooks.configs.recommended.rules,
34
+ ...jsxA11y.configs.recommended.rules,
129
35
 
130
- // Testing Library
131
- 'testing-library/await-async-queries': 'error',
132
- 'testing-library/no-await-sync-queries': 'error',
133
- 'testing-library/prefer-screen-queries': 'warn',
134
- 'testing-library/no-node-access': 'error',
135
- 'testing-library/prefer-presence-queries': 'error',
136
- 'testing-library/prefer-user-event': 'error',
137
- 'testing-library/prefer-query-by-disappearance': 'error',
138
- 'testing-library/prefer-find-by': 'error',
139
-
140
- // Testing Best Practices
141
- 'jest-dom/prefer-checked': 'error',
142
- 'jest-dom/prefer-in-document': 'error',
143
- 'jest-dom/prefer-to-have-attribute': 'error',
144
- 'jest-dom/prefer-enabled-disabled': 'error',
145
- 'jest-dom/prefer-required': 'error',
146
-
147
- // Additional Performance
148
- 'react/no-object-type-as-default-prop': 'warn',
149
- 'react-perf/jsx-no-jsx-as-prop': ['error', {
150
- allowDestructuredProps: true,
151
- }],
152
-
153
- // Advanced React Performance
154
- 'react/jsx-handler-names': ['warn', {
36
+ // JSX A11y rules
37
+ 'jsx-a11y/alt-text': 'error',
38
+ 'jsx-a11y/anchor-has-content': 'error',
39
+ 'jsx-a11y/anchor-is-valid': 'error',
40
+ 'jsx-a11y/aria-activedescendant-has-tabindex': 'error',
41
+ 'jsx-a11y/aria-props': 'error',
42
+ 'jsx-a11y/aria-proptypes': 'error',
43
+ 'jsx-a11y/aria-role': 'error',
44
+ 'jsx-a11y/aria-unsupported-elements': 'error',
45
+ 'jsx-a11y/autocomplete-valid': 'error',
46
+ 'jsx-a11y/click-events-have-key-events': 'error',
47
+ 'jsx-a11y/control-has-associated-label': 'error',
48
+ 'jsx-a11y/heading-has-content': 'error',
49
+ 'jsx-a11y/html-has-lang': 'error',
50
+ 'jsx-a11y/iframe-has-title': 'error',
51
+ 'jsx-a11y/img-redundant-alt': 'error',
52
+ 'jsx-a11y/interactive-supports-focus': 'error',
53
+ 'jsx-a11y/label-has-associated-control': 'error',
54
+ 'jsx-a11y/lang': 'error',
55
+ 'jsx-a11y/media-has-caption': 'error',
56
+ 'jsx-a11y/mouse-events-have-key-events': 'error',
57
+ 'jsx-a11y/no-access-key': 'error',
58
+ 'jsx-a11y/no-aria-hidden-on-focusable': 'error',
59
+ 'jsx-a11y/no-autofocus': 'error',
60
+ 'jsx-a11y/no-distracting-elements': 'error',
61
+ 'jsx-a11y/no-interactive-element-to-noninteractive-role': 'error',
62
+ 'jsx-a11y/no-noninteractive-element-interactions': 'error',
63
+ 'jsx-a11y/no-noninteractive-element-to-interactive-role': 'error',
64
+ 'jsx-a11y/no-noninteractive-tabindex': 'error',
65
+ 'jsx-a11y/no-redundant-roles': 'error',
66
+ 'jsx-a11y/no-static-element-interactions': 'error',
67
+ 'jsx-a11y/role-has-required-aria-props': 'error',
68
+ 'jsx-a11y/role-supports-aria-props': 'error',
69
+ 'jsx-a11y/scope': 'error',
70
+ 'jsx-a11y/tabindex-no-positive': 'error',
71
+ // React Hooks rules
72
+ 'react-hooks/exhaustive-deps': 'warn',
73
+ 'react-hooks/rules-of-hooks': 'error',
74
+ // React Performance rules
75
+ 'react-perf/jsx-no-new-array-as-prop': 'warn',
76
+ 'react-perf/jsx-no-new-function-as-prop': 'warn',
77
+ 'react-perf/jsx-no-new-object-as-prop': 'warn',
78
+ // React Refresh rules
79
+ 'react-refresh/only-export-components': [
80
+ 'warn',
81
+ {
82
+ allowConstantExport: true,
83
+ allowExportNames: ['default'],
84
+ },
85
+ ],
86
+ // React-specific overrides
87
+ 'react/boolean-prop-naming': [
88
+ 'error',
89
+ {
90
+ message:
91
+ 'Boolean prop names should start with "is", "has", "should", "can", "will", or "did"',
92
+ propTypeNames: ['bool'],
93
+ rule: '^(is|has|should|can|will|did)[A-Z]([A-Za-z0-9]?)+',
94
+ },
95
+ ],
96
+ 'react/button-has-type': 'error',
97
+ 'react/function-component-definition': [
98
+ 'error',
99
+ {
100
+ namedComponents: 'arrow-function',
101
+ unnamedComponents: 'arrow-function',
102
+ },
103
+ ],
104
+ 'react/hook-use-state': 'error',
105
+ 'react/iframe-missing-sandbox': 'error',
106
+ 'react/jsx-boolean-value': ['error', 'never'],
107
+ 'react/jsx-curly-brace-presence': [
108
+ 'error',
109
+ {
110
+ children: 'never',
111
+ props: 'never',
112
+ },
113
+ ],
114
+ 'react/jsx-fragments': ['error', 'syntax'],
115
+ 'react/jsx-handler-names': [
116
+ 'error',
117
+ {
118
+ checkInlineFunction: true,
119
+ checkLocalVariables: true,
155
120
  eventHandlerPrefix: 'handle',
156
121
  eventHandlerPropPrefix: 'on',
157
- checkLocalVariables: true,
158
- }],
159
- 'react/jsx-no-script-url': 'error',
160
- 'react/jsx-no-useless-fragment': ['error', { allowExpressions: true }],
161
-
162
- // React 18+ Features
163
- 'react/prefer-read-only-props': 'warn',
164
- 'react/no-unused-class-component-methods': 'error',
165
- 'react/no-arrow-function-lifecycle': 'error',
166
-
167
- // Testing Best Practices
168
- 'testing-library/no-container': 'error',
169
- 'testing-library/no-node-access': ['error', { allowContainerFirstChild: true }],
170
- 'testing-library/prefer-explicit-assert': 'warn',
171
- 'jest-dom/prefer-focus': 'error',
122
+ },
123
+ ],
124
+ 'react/jsx-key': [
125
+ 'error',
126
+ {
127
+ checkFragmentShorthand: true,
128
+ checkKeyMustBeforeSpread: true,
129
+ warnOnDuplicates: true,
130
+ },
131
+ ],
132
+ 'react/jsx-no-bind': [
133
+ 'error',
134
+ {
135
+ allowArrowFunctions: true,
136
+ allowBind: false,
137
+ allowFunctions: false,
138
+ ignoreDOMComponents: true,
139
+ ignoreRefs: true,
140
+ },
141
+ ],
172
142
 
173
- // React 18.2+ Features
174
- 'react/hook-use-state': ['error', {
175
- allowDestructuredState: true,
176
- allowStatefulImports: false
177
- }],
178
- 'react/no-unstable-default-props': ['error', {
179
- forbidAllDefaults: true
180
- }],
181
- 'react/prefer-exact-props': 'error',
143
+ 'react/jsx-no-constructed-context-values': 'error',
144
+ 'react/jsx-no-leaked-render': 'error',
182
145
 
183
- // Enhanced Testing
184
- 'testing-library/no-render-in-lifecycle': 'error',
185
- 'testing-library/prefer-wait-for': 'error',
186
- 'testing-library/no-wait-for-empty-callback': 'error',
146
+ 'react/jsx-no-script-url': 'error',
147
+ 'react/jsx-no-target-blank': 'error',
148
+ 'react/jsx-no-undef': 'error',
149
+ 'react/jsx-no-useless-fragment': [
150
+ 'error',
151
+ {
152
+ allowExpressions: true,
153
+ },
154
+ ],
155
+ 'react/jsx-pascal-case': [
156
+ 'error',
157
+ {
158
+ allowAllCaps: true,
159
+ allowNamespace: true,
160
+ ignore: [],
161
+ },
162
+ ],
163
+ 'react/jsx-sort-props': [
164
+ 'error',
165
+ {
166
+ callbacksLast: true,
167
+ ignoreCase: true,
168
+ noSortAlphabetically: false,
169
+ reservedFirst: true,
170
+ shorthandFirst: true,
171
+ },
172
+ ],
173
+ 'react/no-array-index-key': 'warn',
174
+ 'react/no-danger': 'warn',
175
+ 'react/no-deprecated': 'error',
176
+ 'react/no-direct-mutation-state': 'error',
177
+ 'react/no-find-dom-node': 'error',
178
+ 'react/no-invalid-html-attribute': 'error',
179
+ 'react/no-is-mounted': 'error',
180
+ 'react/no-namespace': 'error',
181
+ 'react/no-object-type-as-default-prop': 'error',
182
+ 'react/no-render-return-value': 'error',
183
+ 'react/no-string-refs': 'error',
184
+ 'react/no-unescaped-entities': 'error',
185
+ 'react/no-unknown-property': 'error',
186
+ 'react/no-unsafe': 'error',
187
+ 'react/no-unstable-nested-components': 'error',
188
+ 'react/no-unused-class-component-methods': 'error',
189
+ 'react/no-unused-prop-types': 'error',
190
+ 'react/no-unused-state': 'error',
191
+ 'react/prefer-es6-class': 'error',
192
+ 'react/prefer-stateless-function': 'error',
193
+ 'react/prop-types': 'off', // Handled by TypeScript
194
+ 'react/react-in-jsx-scope': 'off', // Not needed with new JSX transform
195
+ 'react/require-default-props': 'off', // Handled by TypeScript
196
+ 'react/require-render-return': 'error',
197
+ 'react/self-closing-comp': 'error',
198
+ 'react/sort-comp': [
199
+ 'error',
200
+ {
201
+ order: [
202
+ 'static-methods',
203
+ 'instance-variables',
204
+ 'lifecycle',
205
+ '/^on.+$/',
206
+ 'everything-else',
207
+ 'render',
208
+ ],
209
+ },
210
+ ],
211
+ 'react/sort-default-props': 'error',
212
+ 'react/sort-prop-types': 'error',
187
213
 
188
- // Performance Guards
189
- 'react/forbid-dom-props': ['error', { forbid: ['style'] }],
190
- 'react-perf/jsx-no-new-function-as-prop': ['error', {
191
- allowInlineArrows: true,
192
- allowMethods: true
193
- }],
194
- 'react/jsx-no-constructed-context-values': ['error', {
195
- allowObjectLiteral: false
196
- }],
214
+ 'react/state-in-constructor': 'error',
197
215
 
198
- // Strict Mode Optimizations
199
- 'react/jsx-no-leaked-render': ['error', {
200
- validStrategies: ['ternary', 'coalescing', 'suspense']
201
- }],
216
+ 'react/static-property-placement': 'error',
217
+ 'react/style-prop-object': 'error',
218
+ 'react/void-dom-elements-no-children': 'error',
219
+ },
220
+ settings: {
221
+ 'import/resolver': {
222
+ typescript: {
223
+ alwaysTryTypes: true,
224
+ },
225
+ },
226
+ react: {
227
+ version: 'detect',
228
+ },
229
+ },
230
+ };
202
231
 
203
- // Advanced Testing
204
- 'testing-library/prefer-user-event': ['error', {
205
- allowedMethods: ['type', 'click', 'keyboard', 'upload']
206
- }],
207
- 'testing-library/render-result-naming-convention': ['error', {
208
- prefix: 'render'
209
- }],
232
+ // Export the complete React configuration
233
+ export default [
234
+ // Global ignores
235
+ {
236
+ ignores: [
237
+ '**/dist/**/*',
238
+ '**/vendor/**/*',
239
+ '**/node_modules/**/*',
240
+ '**/coverage/**/*',
241
+ '**/.next/**/*',
242
+ '**/.nuxt/**/*',
243
+ '**/.output/**/*',
244
+ '**/.vite/**/*',
245
+ '**/build/**/*',
246
+ '**/out/**/*',
247
+ '*.properties',
248
+ '*.cclibs',
249
+ '*.svg',
250
+ '*.png',
251
+ '*.jpg',
252
+ '*.jpeg',
253
+ '*.gif',
254
+ '*.ico',
255
+ '*.webp',
256
+ '*.aco',
257
+ '*.psd',
258
+ '*.ai',
259
+ '*.ase',
260
+ '*.sh',
261
+ '*.bat',
262
+ '*.cmd',
263
+ 'package-lock.json',
264
+ 'yarn.lock',
265
+ 'pnpm-lock.yaml',
266
+ 'LICENSE',
267
+ 'CNAME',
268
+ '*.min.js',
269
+ '*.min.css',
270
+ ],
271
+ },
210
272
 
211
- // Concurrent Mode
212
- 'react/no-unstable-nested-components': ['error', {
213
- allowAsProps: true,
214
- customValidators: ['memo', 'Suspense']
215
- }],
216
- 'react/jsx-no-constructed-context-values': ['error', {
217
- allowObjectLiteral: false,
218
- checkFragmentShorthand: true
219
- }],
273
+ // Base configuration
274
+ baseConfig,
220
275
 
221
- // Error Boundaries
222
- 'react/no-unstable-default-props': ['error', {
223
- forbidAllDefaults: true
224
- }],
225
- 'react/iframe-missing-sandbox': 'error',
226
- 'react/jsx-no-leaked-render': ['error', {
227
- validStrategies: ['ternary', 'coalescing', 'suspense']
228
- }],
276
+ // React-specific configuration
277
+ reactConfig,
229
278
 
230
- // Testing
231
- 'testing-library/no-global-regexp-flag-in-query': 'error',
232
- 'testing-library/prefer-query-matchers': 'error',
233
- 'testing-library/no-manual-cleanup': 'error'
234
- },
235
- settings: {
236
- ...baseConfig.settings,
237
- react: {
238
- version: 'detect',
239
- formComponents: ['Form'],
240
- linkComponents: ['Link', 'NavLink', 'RouterLink'],
241
- 'import/resolver': {
242
- typescript: {
243
- alwaysTryTypes: true,
244
- project: ['./tsconfig.json', './tsconfig.*.json']
245
- }
246
- },
247
- 'jsx-runtime': 'automatic'
248
- }
249
- }
250
- }
279
+ // File-specific overrides
280
+ ...baseOverrides,
251
281
  ];
252
282
 
253
- export default reactConfig;
254
- if (typeof module !== 'undefined' && module.exports) {
255
- module.exports = reactConfig;
256
- }
283
+ // Export individual components for advanced usage
284
+ export { baseConfig } from '@mikey-pro/eslint-config/base-config.js';
285
+ export { baseOverrides } from '@mikey-pro/eslint-config/overrides.js';
package/package.json CHANGED
@@ -1,23 +1,23 @@
1
1
  {
2
2
  "name": "@mikey-pro/eslint-config-react",
3
- "version": "8.1.0",
4
- "description": "Mikey Pro ESLint React configuration",
3
+ "version": "9.0.1",
4
+ "description": "Mikey Pro ESLint React configuration - Ultimate React coding style guide",
5
5
  "type": "module",
6
6
  "main": "index.js",
7
7
  "dependencies": {
8
- "@babel/preset-react": "^7.26.3",
9
- "@mikey-pro/eslint-config": "^8.1.0",
8
+ "@babel/preset-react": "^7.28.0",
9
+ "@mikey-pro/eslint-config": "^9.0.0",
10
10
  "eslint-config-react-app-bump": "^1.0.25",
11
11
  "eslint-plugin-jest-dom": "^5.5.0",
12
12
  "eslint-plugin-jsx-a11y": "^6.10.2",
13
- "eslint-plugin-react": "^7.37.4",
14
- "eslint-plugin-react-hooks": "^5.1.0",
13
+ "eslint-plugin-react": "^7.37.5",
14
+ "eslint-plugin-react-hooks": "^5.2.0",
15
15
  "eslint-plugin-react-perf": "^3.3.3",
16
- "eslint-plugin-react-refresh": "^0.4.19",
17
- "eslint-plugin-testing-library": "^7.1.1"
16
+ "eslint-plugin-react-refresh": "^0.4.20",
17
+ "eslint-plugin-testing-library": "^7.6.8"
18
18
  },
19
19
  "peerDependencies": {
20
- "@mikey-pro/eslint-config": "^8.1.0"
20
+ "@mikey-pro/eslint-config": "^9.0.0"
21
21
  },
22
22
  "peerDependenciesMeta": {
23
23
  "@types/react": {
@@ -29,6 +29,7 @@
29
29
  },
30
30
  "files": [
31
31
  "index.js",
32
+ "flat.js",
32
33
  "README.md",
33
34
  "LICENSE"
34
35
  ],
@@ -42,7 +43,7 @@
42
43
  },
43
44
  "license": "MIT",
44
45
  "keywords": [
45
- "@mikey-pro/eslint-config",
46
+ "@mikey-pro/eslint-config-react",
46
47
  "@mikey-pro",
47
48
  "mikey-pro",
48
49
  "mikey",
@@ -51,15 +52,32 @@
51
52
  "eslintconfig",
52
53
  "eslint",
53
54
  "config",
55
+ "react",
56
+ "jsx",
54
57
  "style-guide",
55
58
  "style",
56
- "guide"
59
+ "guide",
60
+ "eslint-9",
61
+ "flat-config"
57
62
  ],
58
63
  "author": "Mikl Wolfe <wolfe@mikl.io> (https://mikl.io)",
59
64
  "browserslist": [
60
65
  "defaults"
61
66
  ],
62
67
  "engines": {
63
- "node": ">=18.0.0"
68
+ "node": ">=18.0.0",
69
+ "npm": ">=9.0.0",
70
+ "pnpm": ">=8.0.0",
71
+ "yarn": ">=4.0.0"
72
+ },
73
+ "exports": {
74
+ ".": {
75
+ "import": "./index.js",
76
+ "require": "./index.js"
77
+ },
78
+ "./flat": {
79
+ "import": "./flat.js",
80
+ "require": "./flat.js"
81
+ }
64
82
  }
65
83
  }