Skip to content

Commit 4559514

Browse files
committed
feat(react): add more configurations
1 parent 0d7c0b4 commit 4559514

File tree

1 file changed

+172
-19
lines changed

1 file changed

+172
-19
lines changed

src/configs/react.ts

Lines changed: 172 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,197 @@
1-
import type { FlatESLintConfigItem, OptionsHasTypeScript, OptionsOverrides } from '../types'
1+
import globals from 'globals'
2+
import type { FlatESLintConfigItem, OptionsHasTypeScript, OptionsOverrides, OptionsStylistic } from '../types'
23
import { GLOB_JSX, GLOB_TSX } from '../globs'
34
import { parserTs, pluginReact, pluginReactHooks } from '../plugins'
45
import { OFF } from './../flags'
56

6-
export function react(options: OptionsHasTypeScript & OptionsOverrides = {}): FlatESLintConfigItem[] {
7+
export function react(options: OptionsHasTypeScript & OptionsOverrides & OptionsStylistic = {}): FlatESLintConfigItem[] {
78
const {
89
overrides = {},
10+
stylistic = true,
911
} = options
12+
13+
const {
14+
indent = 4,
15+
} = typeof stylistic === 'boolean' ? {} : stylistic
16+
17+
const extensions = [GLOB_JSX, ...[options.typescript ? GLOB_TSX : '']]
18+
1019
return [
1120
{
12-
files: [GLOB_JSX, GLOB_TSX],
21+
name: 'coderwyd:react:setup',
22+
plugins: {
23+
'react': pluginReact,
24+
'react-hooks': pluginReactHooks,
25+
},
26+
settings: {
27+
'import/extensions': extensions,
28+
'import/resolver': {
29+
node: { extensions },
30+
},
31+
'react': {
32+
version: 'detect',
33+
},
34+
},
35+
},
36+
{
37+
files: [GLOB_JSX, ...[options.typescript ? GLOB_TSX : '']],
1338
languageOptions: {
39+
globals: globals.browser,
1440
parserOptions: {
1541
ecmaFeatures: {
1642
jsx: true,
1743
},
18-
parser: options.typescript ? parserTs as any : null,
19-
sourceType: 'module',
44+
// for @typescript/eslint-parser
45+
jsxPragma: undefined,
46+
// FIXME: @typescript-eslint v6 throws deprecation warnings
47+
// See https://github.com/jsx-eslint/eslint-plugin-react/issues/3602
48+
// Remove this when they support typescript 5.2
49+
suppressDeprecatedPropertyWarnings: true,
2050
},
2151
},
22-
name: 'coderwyd:react',
23-
plugins: {
24-
'react': pluginReact,
25-
'react-hooks': pluginReactHooks,
26-
},
52+
name: 'coderwyd:react:rules',
2753
rules: {
28-
'style/jsx-quotes': ['error', 'prefer-double'],
54+
...pluginReact.configs.recommended.rules as any,
55+
...pluginReactHooks.configs.recommended.rules as any,
2956

30-
...pluginReact.configs.recommended.rules,
31-
'react/react-in-jsx-scope': OFF,
57+
'node/prefer-global/process': OFF,
3258

33-
...pluginReactHooks.configs.recommended.rules,
59+
'react/display-name': ['off', { ignoreTranspilerName: false }],
60+
'react/iframe-missing-sandbox': 'warn',
61+
'react/jsx-curly-brace-presence': ['error', { children: 'never', props: 'never' }],
62+
'react/no-unknown-property': ['error', {
63+
ignore: [
64+
// SVG
65+
'clip-path',
66+
'clip-rule',
67+
'fill-opacity',
68+
'fill-rule',
69+
'stroke-dasharray',
70+
'stroke-dashoffset',
71+
'stroke-linecap',
72+
'stroke-linejoin',
73+
'stroke-miterlimit',
74+
'stroke-opacity',
75+
'stroke-width',
76+
],
77+
}],
78+
'react/no-unused-class-component-methods': 'error',
79+
'react/no-unused-state': 'error',
80+
'react/prop-types': 'off',
81+
'react/react-in-jsx-scope': 'off',
82+
83+
...stylistic
84+
? {
85+
'react/jsx-boolean-value': ['error', 'never', { always: [] }],
86+
'react/jsx-closing-bracket-location': ['error', 'tag-aligned'],
87+
'react/jsx-curly-newline': ['error', {
88+
multiline: 'consistent',
89+
singleline: 'consistent',
90+
}],
91+
'react/jsx-curly-spacing': ['error', 'never', { allowMultiline: true }],
92+
'react/jsx-first-prop-new-line': ['error', 'multiline-multiprop'],
93+
'react/jsx-fragments': ['error', 'syntax'],
94+
'react/jsx-indent': ['error', indent, { checkAttributes: false, indentLogicalExpressions: true }],
95+
'react/jsx-indent-props': ['error', indent],
96+
'react/jsx-max-props-per-line': ['error', { maximum: 1, when: 'multiline' }],
97+
'react/jsx-no-useless-fragment': 'error',
98+
'react/jsx-props-no-multi-spaces': 'error',
99+
'react/jsx-tag-spacing': ['error', {
100+
afterOpening: 'never',
101+
beforeClosing: 'never',
102+
beforeSelfClosing: 'always',
103+
closingSlash: 'never',
104+
}],
105+
'react/jsx-wrap-multilines': ['error', {
106+
arrow: 'parens-new-line',
107+
assignment: 'parens-new-line',
108+
condition: 'parens-new-line',
109+
declaration: 'parens-new-line',
110+
logical: 'parens-new-line',
111+
prop: 'parens-new-line',
112+
return: 'parens-new-line',
113+
}],
114+
'react/sort-comp': ['error', {
115+
groups: {
116+
lifecycle: [
117+
'displayName',
118+
'propTypes',
119+
'contextTypes',
120+
'childContextTypes',
121+
'mixins',
122+
'statics',
123+
'defaultProps',
124+
'constructor',
125+
'getDefaultProps',
126+
'getInitialState',
127+
'state',
128+
'getChildContext',
129+
'getDerivedStateFromProps',
130+
'componentWillMount',
131+
'UNSAFE_componentWillMount',
132+
'componentDidMount',
133+
'componentWillReceiveProps',
134+
'UNSAFE_componentWillReceiveProps',
135+
'shouldComponentUpdate',
136+
'componentWillUpdate',
137+
'UNSAFE_componentWillUpdate',
138+
'getSnapshotBeforeUpdate',
139+
'componentDidUpdate',
140+
'componentDidCatch',
141+
'componentWillUnmount',
142+
],
143+
rendering: [
144+
'/^render.+$/',
145+
'render',
146+
],
147+
},
148+
order: [
149+
'static-variables',
150+
'static-methods',
151+
'instance-variables',
152+
'lifecycle',
153+
'/^handle.+$/',
154+
'/^on.+$/',
155+
'getters',
156+
'setters',
157+
'/^(get|set)(?!(InitialState$|DefaultProps$|ChildContext$)).+$/',
158+
'instance-methods',
159+
'everything-else',
160+
'rendering',
161+
],
162+
}],
163+
'react/style-prop-object': 'error',
164+
'style/indent': ['error', indent, {
165+
SwitchCase: 1,
166+
VariableDeclarator: 1,
167+
// from: https://github.com/airbnb/javascript/blob/master/packages/eslint-config-airbnb-base/rules/style.js
168+
ignoredNodes: [
169+
'JSXElement',
170+
'JSXElement :not(JSXExpressionContainer, JSXExpressionContainer *)',
171+
'JSXAttribute',
172+
'JSXIdentifier',
173+
'JSXNamespacedName',
174+
'JSXMemberExpression',
175+
'JSXSpreadAttribute',
176+
'JSXOpeningElement',
177+
'JSXClosingElement',
178+
'JSXFragment',
179+
'JSXOpeningFragment',
180+
'JSXClosingFragment',
181+
'JSXText',
182+
'JSXEmptyExpression',
183+
'JSXSpreadChild',
184+
],
185+
offsetTernaryExpressions: true,
186+
outerIIFEBody: 1,
187+
}],
188+
'style/jsx-quotes': ['error', 'prefer-double'],
189+
}
190+
: {},
34191

35192
...overrides,
36193
},
37-
settings: {
38-
react: {
39-
version: 'detect',
40-
},
41-
},
194+
42195
},
43196
]
44197
}

0 commit comments

Comments
 (0)