Skip to content

Commit dd74853

Browse files
committed
build: fixes linting
now matches the current settings in components
1 parent 96a1355 commit dd74853

File tree

8 files changed

+466
-304
lines changed

8 files changed

+466
-304
lines changed

.eslintrc.js

+63-96
Original file line numberDiff line numberDiff line change
@@ -1,117 +1,84 @@
11
module.exports = {
2+
parser: '@typescript-eslint/parser',
3+
parserOptions: {
4+
sourceType: 'module',
5+
project: './tsconfig.json',
6+
},
27
env: {
38
browser: true,
4-
es6: true,
59
node: true,
6-
jest: true,
710
},
8-
ignorePatterns: ['setupTests.tsx', '*.test.ts*', '*.stories.tsx'],
11+
plugins: ['import'],
912
extends: [
10-
// non-ts recommended rules
1113
'eslint:recommended',
12-
// remove non-ts rules covered by typescript-eslint
13-
'plugin:@typescript-eslint/eslint-recommended',
14-
// ts recommended rules
15-
// can be slow
14+
'plugin:import/errors',
15+
'plugin:import/warnings',
16+
'plugin:import/typescript',
17+
'plugin:react/recommended',
18+
'plugin:react-hooks/recommended',
19+
'plugin:jsx-a11y/recommended',
20+
'plugin:jest/recommended',
21+
'plugin:jest/style',
22+
'plugin:jest-dom/recommended',
1623
'plugin:@typescript-eslint/recommended',
17-
// ts recommended rules that require tsconfig.json to be specified in parserOptions.project
18-
// can be slow
1924
'plugin:@typescript-eslint/recommended-requiring-type-checking',
20-
'prettier/@typescript-eslint',
21-
22-
'plugin:react/recommended',
23-
'plugin:security/recommended',
24-
// remove rules covered by prettier
25-
'prettier/@typescript-eslint',
26-
'plugin:prettier/recommended',
25+
'prettier',
26+
'plugin:storybook/recommended',
2727
],
28-
globals: {
29-
Atomics: 'readonly',
30-
SharedArrayBuffer: 'readonly',
31-
},
32-
parser: '@typescript-eslint/parser',
33-
parserOptions: {
34-
ecmaFeatures: {
35-
jsx: true,
36-
modules: true,
28+
settings: {
29+
react: {
30+
// to indicate latest version
31+
// https://github.com/yannickcr/eslint-plugin-react/blob/b8e91a571bc6b58cc3c78e9e62e8b60ecb45e233/lib/util/version.js#L48
32+
version: '999.999.999',
33+
},
34+
'import/parsers': {
35+
'@typescript-eslint/parser': ['.ts', '.tsx'],
36+
},
37+
'import/resolver': {
38+
typescript: {
39+
alwaysTryTypes: true,
40+
},
3741
},
38-
ecmaVersion: 2018,
39-
sourceType: 'module',
40-
project: ['./tsconfig.json'],
4142
},
42-
plugins: ['react', '@typescript-eslint'],
4343
rules: {
44-
'@typescript-eslint/ban-ts-ignore': 'off',
45-
'@typescript-eslint/ban-types': 'warn',
46-
'@typescript-eslint/interface-name-prefix': 'off',
47-
'@typescript-eslint/naming-convention': [
48-
'warn',
49-
{
50-
selector: 'function',
51-
format: ['camelCase', 'PascalCase'],
52-
},
53-
],
54-
'@typescript-eslint/no-base-to-string': 'warn',
55-
'@typescript-eslint/no-empty-function': 'warn',
44+
'import/default': 'off',
45+
'import/no-default-export': 'off',
46+
'react/display-name': 'off',
47+
'import/no-named-as-default-member': 'warn',
48+
// see for rational https://basarat.gitbook.io/typescript/main-1/defaultisbad
49+
'import/no-default-export': 'error',
50+
'@typescript-eslint/restrict-template-expressions': 'off',
51+
'@typescript-eslint/ban-ts-comment': 'warn',
5652
'@typescript-eslint/no-explicit-any': 'warn',
57-
'@typescript-eslint/no-floating-promises': 'error',
58-
'@typescript-eslint/no-implied-eval': 'warn',
59-
'@typescript-eslint/no-inferrable-types': 'warn',
60-
'@typescript-eslint/no-misused-promises': 'error',
61-
'@typescript-eslint/no-non-null-assertion': 'warn',
62-
'@typescript-eslint/no-throw-literal': 'warn',
63-
'@typescript-eslint/no-unnecessary-boolean-literal-compare': 'warn',
64-
'@typescript-eslint/no-unnecessary-condition': 'warn',
65-
'@typescript-eslint/no-unnecessary-qualifier': 'warn',
66-
'@typescript-eslint/no-unnecessary-type-arguments': 'warn',
67-
'@typescript-eslint/no-unnecessary-type-assertion': 'warn',
6853
'@typescript-eslint/no-unsafe-assignment': 'warn',
6954
'@typescript-eslint/no-unsafe-call': 'warn',
7055
'@typescript-eslint/no-unsafe-member-access': 'warn',
7156
'@typescript-eslint/no-unsafe-return': 'warn',
72-
'@typescript-eslint/no-unused-vars-experimental': 'off',
73-
'@typescript-eslint/prefer-nullish-coalescing': 'warn',
74-
'@typescript-eslint/prefer-readonly': 'warn',
75-
// Ideally this would be on, but it has too many false positives. Should apply to arrays but seems to apply to everything, potentially a bug
76-
'@typescript-eslint/prefer-readonly-parameter-types': 'off',
77-
'@typescript-eslint/prefer-reduce-type-parameter': 'warn',
78-
'@typescript-eslint/prefer-regexp-exec': 'warn',
79-
'@typescript-eslint/promise-function-async': 'error',
80-
'@typescript-eslint/promise-function-async': 'error',
81-
'@typescript-eslint/require-array-sort-compare': 'warn',
82-
// require-await is incompatible with promise-function-async
83-
'@typescript-eslint/require-await': 'off',
84-
'@typescript-eslint/restrict-plus-operands': 'warn',
85-
'@typescript-eslint/restrict-template-expressions': [
86-
'warn',
87-
{
88-
allowNumber: true,
89-
allowBoolean: true,
90-
allowNullable: false,
57+
'@typescript-eslint/no-this-alias': 'warn',
58+
},
59+
overrides: [
60+
{
61+
// required because of https://github.com/yannickcr/eslint-plugin-react/issues/2353
62+
// otherwise get missing prop-types error in tsx files
63+
files: ['**/*.tsx'],
64+
rules: {
65+
'react/prop-types': 'off',
9166
},
92-
],
93-
'@typescript-eslint/strict-boolean-expressions': 'warn',
94-
'@typescript-eslint/switch-exhaustiveness-check': 'warn',
95-
// TODO: We use this in mocks in .spec.ts, perhaps syntax is incorrect?
96-
'@typescript-eslint/unbound-method': 'off',
97-
'react/jsx-pascal-case': [
98-
'warn',
99-
{
100-
ignore: [
101-
'h1',
102-
'h2',
103-
'h3',
104-
'h4',
105-
'h5',
106-
'h6',
107-
'd1',
108-
'd2',
109-
'd3',
110-
'd4',
111-
'd5',
112-
'd6',
113-
],
67+
},
68+
{
69+
// allow node_module mocks to have default exports
70+
files: ['__mocks__/**/*'],
71+
rules: {
72+
'import/no-default-export': 'off',
11473
},
115-
],
116-
},
74+
},
75+
],
76+
ignorePatterns: [
77+
'dist',
78+
'docs',
79+
'example',
80+
'node_modules',
81+
'**/*.stories.tsx',
82+
'**/*.test.ts',
83+
],
11784
}

package.json

+11-7
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"start": "microbundle watch",
2727
"build": "yarn clean ; microbundle",
2828
"test": "tsdx test",
29-
"lint": "tsdx lint",
29+
"lint": "eslint \"./src/**/*.ts\"",
3030
"size": "size-limit",
3131
"analyze": "size-limit --why",
3232
"storybook": "NODE_OPTIONS=--openssl-legacy-provider start-storybook -p 6006 -h 0.0.0.0",
@@ -113,12 +113,16 @@
113113
"babel-loader": "^9.1.2",
114114
"commitizen": "^4.2.4",
115115
"cz-conventional-changelog": "^3.3.0",
116-
"eslint-config-prettier": "^8.6.0",
117-
"eslint-config-react-app": "^7.0.1",
118-
"eslint-plugin-prettier": "^4.2.1",
119-
"eslint-plugin-react-hooks": "^4.4.0",
120-
"eslint-plugin-security": "^1.4.0",
121-
"eslint-plugin-storybook": "^0.6.10",
116+
"eslint": "^7.29.0",
117+
"eslint-config-prettier": "^8.1.0",
118+
"eslint-import-resolver-typescript": "^2.4.0",
119+
"eslint-plugin-import": "^2.22.1",
120+
"eslint-plugin-jest": "^24.3.4",
121+
"eslint-plugin-jest-dom": "^3.7.0",
122+
"eslint-plugin-jsx-a11y": "^6.4.1",
123+
"eslint-plugin-react": "^7.23.1",
124+
"eslint-plugin-react-hooks": "^4.2.0",
125+
"eslint-plugin-storybook": "^0.6.4",
122126
"husky": "^7.0.4",
123127
"jest-sonar-reporter": "^2.0.0",
124128
"microbundle": "^0.15.0",

src/useBoolean/useBoolean.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState } from 'react'
1+
import { useMemo, useState } from 'react'
22

33
/**
44
* Utility hook for boolean state
@@ -8,7 +8,9 @@ import React, { useState } from 'react'
88
* Use with caution, attaching to buttons can cause unintended consequences from double clicks.
99
* @params startState (optional) starting value
1010
*/
11-
export function useBoolean(startState = false): [
11+
export function useBoolean(
12+
startState = false
13+
): [
1214
boolean,
1315
{
1416
toggle: () => void
@@ -18,7 +20,7 @@ export function useBoolean(startState = false): [
1820
] {
1921
const [value, setValue] = useState(startState)
2022

21-
const functions = React.useMemo(
23+
const functions = useMemo(
2224
() => ({
2325
toggle: (): void => setValue((state) => !state),
2426
setTrue: (): void => setValue(true),

src/useClipboard/useClipboard.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import { useState } from 'react'
77
*
88
* @param {number | undefined} timeout set to change the default timeout for notification of copy
99
*/
10-
export function useClipboard(timeout = 2000): {
11-
copy: (valueToCopy: string) => void
10+
export function useClipboard(
11+
timeout = 2000
12+
): {
13+
copy: (valueToCopy: string) => Promise<void>
1214
reset: () => void
1315
error: Error | undefined
1416
copied: boolean
@@ -34,7 +36,9 @@ export function useClipboard(timeout = 2000): {
3436
return navigator.clipboard
3537
.writeText(valueToCopy)
3638
.then(() => handleCopyResult(true))
37-
.catch((err) => setError(err))
39+
.catch((err) => {
40+
if (err instanceof Error) setError(err)
41+
})
3842
} else {
3943
setError(new Error('useClipboard: clipboard is not supported'))
4044
}

src/useFavicon/useFavicon.ts

-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ export function useFavicon(href: string, options: FaviconOptions = {}): void {
8080
useLayoutEffect(() => {
8181
const imageType = href.toLowerCase().split('.').pop()
8282
if (isImageType(imageType)) {
83-
// eslint-disable-next-line security/detect-object-injection
8483
const type = ImageTypes[imageType]
8584
setFavIcon(document, { type, href })
8685
} else {

src/useLocalState/useLocalState.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { Dispatch } from 'react'
1+
import { Dispatch, useCallback, useEffect, useRef, useState } from 'react'
22

33
/**
44
* Serialize the value to a string
@@ -39,7 +39,7 @@ export function useLocalState<T>(
3939
deserialize: Deserializer<T>
4040
} = { serialize: JSON.stringify, deserialize: JSON.parse }
4141
): [T, Dispatch<T>, () => void] {
42-
const [state, setState] = React.useState<T>(() => {
42+
const [state, setState] = useState<T>(() => {
4343
const valueInLocalStorage = window.localStorage.getItem(key)
4444
if (valueInLocalStorage != null) {
4545
try {
@@ -55,9 +55,9 @@ export function useLocalState<T>(
5555
}
5656
})
5757

58-
const prevKeyRef = React.useRef(key)
58+
const prevKeyRef = useRef(key)
5959

60-
React.useEffect(() => {
60+
useEffect(() => {
6161
const prevKey = prevKeyRef.current
6262
if (prevKey !== key) {
6363
window.localStorage.removeItem(prevKey)
@@ -70,7 +70,7 @@ export function useLocalState<T>(
7070
}
7171
}, [key, state, serialize])
7272

73-
const clear = React.useCallback(() => {
73+
const clear = useCallback(() => {
7474
window.localStorage.removeItem(key)
7575
}, [key])
7676

src/usePagination/usePagination.ts

+8-7
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,11 @@ export function usePagination({
5050
endIndex,
5151
isNextDisabled,
5252
isPreviousDisabled,
53-
} = useMemo(
54-
() => getDerivedData(totalItems, pageSize, page),
55-
[page, pageSize, totalItems]
56-
)
53+
} = useMemo(() => getDerivedData(totalItems, pageSize, page), [
54+
page,
55+
pageSize,
56+
totalItems,
57+
])
5758

5859
const setTotalItems = useCallback((newTotalItems: number) => {
5960
setTotalItemsInternal(Math.max(0, newTotalItems))
@@ -67,16 +68,16 @@ export function usePagination({
6768
(newPage: number) => {
6869
setPageInternal(Math.max(1, Math.min(newPage, totalPages)))
6970
},
70-
[page, totalPages]
71+
[totalPages]
7172
)
7273

7374
const setNextPage = useCallback(() => {
7475
setPage(page + 1)
75-
}, [page])
76+
}, [page, setPage])
7677

7778
const setPreviousPage = useCallback(() => {
7879
setPage(page - 1)
79-
}, [page])
80+
}, [page, setPage])
8081

8182
useEffect(() => {
8283
setPageInternal((page) => Math.max(1, Math.min(page, totalPages)))

0 commit comments

Comments
 (0)