1 | const prettierOptions = require('./.prettierrc')
|
2 |
|
3 | const RULES = {
|
4 | OFF: 0,
|
5 | WARNING: 1,
|
6 | ERROR: 2
|
7 | }
|
8 |
|
9 | const ACCESIBILITY_RULES = {
|
10 | 'jsx-a11y/accessible-emoji': RULES.WARNING,
|
11 | 'jsx-a11y/alt-text': RULES.WARNING,
|
12 | 'jsx-a11y/anchor-has-content': RULES.WARNING,
|
13 | 'jsx-a11y/anchor-is-valid': RULES.WARNING,
|
14 | 'jsx-a11y/aria-activedescendant-has-tabindex': RULES.WARNING,
|
15 | 'jsx-a11y/aria-props': RULES.WARNING,
|
16 | 'jsx-a11y/aria-proptypes': RULES.WARNING,
|
17 | 'jsx-a11y/aria-role': RULES.WARNING,
|
18 | 'jsx-a11y/aria-unsupported-elements': RULES.WARNING,
|
19 |
|
20 | 'jsx-a11y/click-events-have-key-events': RULES.WARNING,
|
21 | 'jsx-a11y/control-has-associated-label': [
|
22 | 'off',
|
23 | {
|
24 | ignoreElements: [
|
25 | 'audio',
|
26 | 'canvas',
|
27 | 'embed',
|
28 | 'input',
|
29 | 'textarea',
|
30 | 'tr',
|
31 | 'video'
|
32 | ],
|
33 | ignoreRoles: [
|
34 | 'grid',
|
35 | 'listbox',
|
36 | 'menu',
|
37 | 'menubar',
|
38 | 'radiogroup',
|
39 | 'row',
|
40 | 'tablist',
|
41 | 'toolbar',
|
42 | 'tree',
|
43 | 'treegrid'
|
44 | ],
|
45 | includeRoles: ['alert', 'dialog']
|
46 | }
|
47 | ],
|
48 | 'jsx-a11y/heading-has-content': RULES.WARNING,
|
49 | 'jsx-a11y/html-has-lang': RULES.WARNING,
|
50 | 'jsx-a11y/iframe-has-title': RULES.WARNING,
|
51 | 'jsx-a11y/img-redundant-alt': RULES.WARNING,
|
52 | 'jsx-a11y/interactive-supports-focus': [
|
53 | RULES.WARNING,
|
54 | {
|
55 | tabbable: [
|
56 | 'button',
|
57 | 'checkbox',
|
58 | 'link',
|
59 | 'searchbox',
|
60 | 'spinbutton',
|
61 | 'switch',
|
62 | 'textbox'
|
63 | ]
|
64 | }
|
65 | ],
|
66 | 'jsx-a11y/label-has-associated-control': RULES.WARNING,
|
67 | 'jsx-a11y/label-has-for': 'off',
|
68 | 'jsx-a11y/media-has-caption': RULES.WARNING,
|
69 | 'jsx-a11y/mouse-events-have-key-events': RULES.WARNING,
|
70 | 'jsx-a11y/no-access-key': RULES.WARNING,
|
71 | 'jsx-a11y/no-autofocus': RULES.WARNING,
|
72 | 'jsx-a11y/no-distracting-elements': RULES.WARNING,
|
73 | 'jsx-a11y/no-interactive-element-to-noninteractive-role': [
|
74 | RULES.WARNING,
|
75 | {
|
76 | tr: ['none', 'presentation']
|
77 | }
|
78 | ],
|
79 | 'jsx-a11y/no-noninteractive-element-interactions': [
|
80 | RULES.WARNING,
|
81 | {
|
82 | handlers: [
|
83 | 'onClick',
|
84 | 'onError',
|
85 | 'onLoad',
|
86 | 'onMouseDown',
|
87 | 'onMouseUp',
|
88 | 'onKeyPress',
|
89 | 'onKeyDown',
|
90 | 'onKeyUp'
|
91 | ],
|
92 | alert: ['onKeyUp', 'onKeyDown', 'onKeyPress'],
|
93 | body: ['onError', 'onLoad'],
|
94 | dialog: ['onKeyUp', 'onKeyDown', 'onKeyPress'],
|
95 | iframe: ['onError', 'onLoad'],
|
96 | img: ['onError', 'onLoad']
|
97 | }
|
98 | ],
|
99 | 'jsx-a11y/no-noninteractive-element-to-interactive-role': [
|
100 | RULES.WARNING,
|
101 | {
|
102 | ul: [
|
103 | 'listbox',
|
104 | 'menu',
|
105 | 'menubar',
|
106 | 'radiogroup',
|
107 | 'tablist',
|
108 | 'tree',
|
109 | 'treegrid'
|
110 | ],
|
111 | ol: [
|
112 | 'listbox',
|
113 | 'menu',
|
114 | 'menubar',
|
115 | 'radiogroup',
|
116 | 'tablist',
|
117 | 'tree',
|
118 | 'treegrid'
|
119 | ],
|
120 | li: ['menuitem', 'option', 'row', 'tab', 'treeitem'],
|
121 | table: ['grid'],
|
122 | td: ['gridcell']
|
123 | }
|
124 | ],
|
125 | 'jsx-a11y/no-noninteractive-tabindex': [
|
126 | RULES.WARNING,
|
127 | {
|
128 | tags: [],
|
129 | roles: ['tabpanel'],
|
130 | allowExpressionValues: true
|
131 | }
|
132 | ],
|
133 | 'jsx-a11y/no-onchange': RULES.WARNING,
|
134 | 'jsx-a11y/no-redundant-roles': RULES.WARNING,
|
135 | 'jsx-a11y/no-static-element-interactions': [
|
136 | RULES.WARNING,
|
137 | {
|
138 | allowExpressionValues: true,
|
139 | handlers: [
|
140 | 'onClick',
|
141 | 'onMouseDown',
|
142 | 'onMouseUp',
|
143 | 'onKeyPress',
|
144 | 'onKeyDown',
|
145 | 'onKeyUp'
|
146 | ]
|
147 | }
|
148 | ],
|
149 | 'jsx-a11y/role-has-required-aria-props': RULES.WARNING,
|
150 | 'jsx-a11y/role-supports-aria-props': RULES.WARNING,
|
151 | 'jsx-a11y/scope': RULES.WARNING,
|
152 | 'jsx-a11y/tabindex-no-positive': RULES.WARNING
|
153 | }
|
154 |
|
155 | const REACT_RULES = {
|
156 | 'react-hooks/exhaustive-deps': RULES.WARNING,
|
157 | 'react-hooks/rules-of-hooks': RULES.ERROR,
|
158 | 'react/default-props-match-prop-types': RULES.WARNING,
|
159 | 'react/jsx-handler-names': RULES.WARNING,
|
160 | 'react/jsx-no-duplicate-props': [RULES.WARNING, {ignoreCase: true}],
|
161 | 'react/jsx-no-undef': RULES.WARNING,
|
162 | 'react/jsx-pascal-case': [
|
163 | RULES.WARNING,
|
164 | {
|
165 | allowAllCaps: true,
|
166 | ignore: []
|
167 | }
|
168 | ],
|
169 | 'react/jsx-uses-react': RULES.OFF,
|
170 | 'react/jsx-uses-vars': RULES.WARNING,
|
171 | 'react/no-deprecated': RULES.WARNING,
|
172 | 'react/no-direct-mutation-state': RULES.ERROR,
|
173 | 'react/no-is-mounted': RULES.WARNING,
|
174 | 'react/no-multi-comp': [RULES.WARNING, {ignoreStateless: true}],
|
175 | 'react/no-unused-prop-types': RULES.WARNING,
|
176 | 'react/react-in-jsx-scope': RULES.OFF,
|
177 | 'react/require-render-return': RULES.WARNING
|
178 | }
|
179 |
|
180 | const TESTING_RULES = {
|
181 | 'chai-friendly/no-unused-expressions': [
|
182 | RULES.ERROR,
|
183 | {allowShortCircuit: true, allowTernary: true}
|
184 | ],
|
185 | 'no-only-tests/no-only-tests': RULES.ERROR
|
186 | }
|
187 |
|
188 | let resolvedBabelPresetSui = false
|
189 | try {
|
190 | require.resolve('babel-preset-sui')
|
191 | resolvedBabelPresetSui = true
|
192 | } catch {}
|
193 |
|
194 | const parser = resolvedBabelPresetSui ? '@babel/eslint-parser' : undefined
|
195 |
|
196 | module.exports = {
|
197 | env: {
|
198 | es6: true,
|
199 | mocha: true
|
200 | },
|
201 | globals: {
|
202 | 'cypress/globals': true,
|
203 | preval: 'readonly'
|
204 | },
|
205 | parser,
|
206 | parserOptions: {
|
207 | ecmaFeatures: {
|
208 | jsx: true
|
209 | },
|
210 | ecmaVersion: 12,
|
211 | babelOptions: {
|
212 | configFile: resolvedBabelPresetSui
|
213 | }
|
214 | },
|
215 | extends: [
|
216 | 'standard',
|
217 | 'standard-react',
|
218 | 'prettier',
|
219 | 'plugin:cypress/recommended',
|
220 | 'prettier/standard',
|
221 | 'prettier/react'
|
222 | ],
|
223 | plugins: [
|
224 | '@babel',
|
225 | 'chai-friendly',
|
226 | 'jsx-a11y',
|
227 | 'no-only-tests',
|
228 | 'prettier',
|
229 | 'react-hooks'
|
230 | ],
|
231 | rules: {
|
232 | ...ACCESIBILITY_RULES,
|
233 | ...REACT_RULES,
|
234 | ...TESTING_RULES,
|
235 | 'accessor-pairs': RULES.OFF,
|
236 | '@babel/no-unused-expressions': RULES.OFF,
|
237 | 'no-console': RULES.WARNING,
|
238 | 'no-debugger': RULES.ERROR,
|
239 | 'no-nested-ternary': RULES.WARNING,
|
240 | 'no-prototype-builtins': RULES.OFF,
|
241 | 'no-return-await': RULES.WARNING,
|
242 | 'no-unused-expressions': RULES.OFF,
|
243 | 'no-unused-vars': [
|
244 | RULES.ERROR,
|
245 | {args: 'none', ignoreRestSiblings: true, varsIgnorePattern: 'React'}
|
246 | ],
|
247 | 'no-var': RULES.WARNING,
|
248 | strict: RULES.OFF,
|
249 | 'prettier/prettier': [RULES.ERROR, prettierOptions]
|
250 | }
|
251 | }
|