Skip to content

Commit e940b12

Browse files
Merge pull request #62 from commitd/sh/pagination
Add usePagination hook
2 parents 9df968e + abb7092 commit e940b12

23 files changed

+5535
-5987
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
}

.github/workflows/ci.yaml

+7-7
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ concurrency:
1313
cancel-in-progress: true
1414

1515
env:
16-
NODE_VERSION: 14
16+
NODE_VERSION: 18
1717

1818
jobs:
1919
build:
20-
runs-on: ubuntu-18.04
20+
runs-on: ubuntu-latest
2121
steps:
2222
- name: Checkout Commit
2323
uses: actions/checkout@v3
@@ -39,7 +39,7 @@ jobs:
3939
path: dist
4040
retention-days: 1
4141
static-analysis:
42-
runs-on: ubuntu-18.04
42+
runs-on: ubuntu-latest
4343
needs: build
4444
steps:
4545
- name: Checkout Commit
@@ -59,7 +59,7 @@ jobs:
5959
run: |
6060
yarn run lint
6161
unit-test-scan:
62-
runs-on: ubuntu-18.04
62+
runs-on: ubuntu-latest
6363
needs: build
6464
steps:
6565
- name: Checkout Commit
@@ -84,7 +84,7 @@ jobs:
8484
SONAR_TOKEN: ${{ secrets.SONAR_CLOUD_TOKEN }}
8585
build-storybook:
8686
if: github.event_name == 'pull_request'
87-
runs-on: ubuntu-18.04
87+
runs-on: ubuntu-latest
8888
needs: build
8989
steps:
9090
- name: Checkout Commit
@@ -101,7 +101,7 @@ jobs:
101101
run: yarn run build-storybook --quiet
102102
release:
103103
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/beta'
104-
runs-on: ubuntu-18.04
104+
runs-on: ubuntu-latest
105105
needs: [static-analysis, unit-test-scan]
106106
steps:
107107
- name: Checkout Commit
@@ -131,7 +131,7 @@ jobs:
131131
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
132132
run: npx semantic-release
133133
publish-storybook:
134-
runs-on: ubuntu-18.04
134+
runs-on: ubuntu-latest
135135
needs: release
136136
steps:
137137
- name: Checkout Commit

package.json

+32-28
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@
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",
32-
"storybook": "start-storybook -p 6006 -h 0.0.0.0",
33-
"build-storybook": "build-storybook",
32+
"storybook": "NODE_OPTIONS=--openssl-legacy-provider start-storybook -p 6006 -h 0.0.0.0",
33+
"build-storybook": "NODE_OPTIONS=--openssl-legacy-provider build-storybook",
3434
"format": "prettier --write '**/{src,test,stories}/**/{*.js,*.ts,*.tsx,*.json,*.md,*.mdx}'",
3535
"format:check": "prettier --check '**/{src,test,stories}/**/{*.js,*.ts,*.tsx,*.json,*.md,*.mdx}'",
36-
"deploy-storybook": "storybook-to-ghpages",
36+
"deploy-storybook": "NODE_OPTIONS=--openssl-legacy-provider storybook-to-ghpages",
3737
"generate": "plop --plopfile ./generators/plopfile.js",
3838
"prepare": "husky install",
3939
"semantic-release": "semantic-release"
@@ -93,47 +93,51 @@
9393
},
9494
"devDependencies": {
9595
"@babel/core": "^7.12.3",
96-
"@commitlint/cli": "^16.2.3",
97-
"@commitlint/config-conventional": "^16.2.1",
96+
"@commitlint/cli": "^17.4.2",
97+
"@commitlint/config-conventional": "^17.4.2",
9898
"@committed/components": "^7.0.2",
9999
"@fontsource/dosis": "^4.5.7",
100100
"@fontsource/inter": "^4.5.7",
101101
"@size-limit/preset-small-lib": "^8.1.1",
102-
"@storybook/addon-essentials": "^6.4.22",
103-
"@storybook/react": "^6.4.22",
102+
"@storybook/addon-essentials": "^6.5.15",
103+
"@storybook/react": "^6.5.15",
104104
"@storybook/storybook-deployer": "^2.8.11",
105105
"@testing-library/jest-dom": "^5.11.5",
106-
"@testing-library/react": "^11.1.0",
107-
"@testing-library/react-hooks": "^3.4.2",
108-
"@testing-library/user-event": "^12.1.10",
109-
"@types/react": "^16.9.53",
110-
"@types/react-dom": "^16.9.8",
111-
"@typescript-eslint/eslint-plugin": "^4.7.0",
112-
"@typescript-eslint/parser": "^4.7.0",
113-
"babel-loader": "^8.1.0",
106+
"@testing-library/react": "^13.4.0",
107+
"@testing-library/react-hooks": "^8.0.1",
108+
"@testing-library/user-event": "^14.4.3",
109+
"@types/react": "^18.0.26",
110+
"@types/react-dom": "^18.0.10",
111+
"@typescript-eslint/eslint-plugin": "^5.48.1",
112+
"@typescript-eslint/parser": "^5.48.1",
113+
"babel-loader": "^9.1.2",
114114
"commitizen": "^4.2.4",
115115
"cz-conventional-changelog": "^3.3.0",
116-
"eslint-config-prettier": "^6.14.0",
117-
"eslint-config-react-app": "^6.0.0",
118-
"eslint-plugin-prettier": "^3.1.4",
119-
"eslint-plugin-react-hooks": "^4.4.0",
120-
"eslint-plugin-security": "^1.4.0",
121-
"eslint-plugin-storybook": "^0.5.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",
125129
"plop": "^2.7.4",
126130
"prettier": "^2.1.2",
127131
"prettier-plugin-organize-imports": "^2.3.4",
128132
"pretty-quick": "^3.1.0",
129-
"react": "^17.0.1",
130-
"react-dom": "^17.0.1",
131-
"react-is": "^17.0.1",
132-
"react-test-renderer": "^17.0.1",
133+
"react": "^18.2.0",
134+
"react-dom": "^18.2.0",
135+
"react-is": "^18.2.0",
136+
"react-test-renderer": "^18.2.0",
133137
"shx": "^0.3.2",
134138
"size-limit": "^8.1.1",
135-
"storybook-dark-mode": "^1.0.9",
136-
"swr": "^0.3.8",
139+
"storybook-dark-mode": "^2.0.5",
140+
"swr": "^2.0.0",
137141
"tsdx": "^0.14.1",
138142
"tslib": "^2.4.0",
139143
"typescript": "^4.6.4"

src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export * from './useKeyboard'
1111
export * from './useLocalState'
1212
export * from './useMergedRefs'
1313
export * from './useModal'
14+
export * from './usePagination'
1415
export * from './usePoll'
1516
export * from './useTimeout'
1617
export * from './useTitle'

src/useBoolean/useBoolean.ts

+3-5
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,9 +8,7 @@ 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(
12-
startState = false
13-
): [
11+
export function useBoolean(startState = false): [
1412
boolean,
1513
{
1614
toggle: () => void
@@ -20,7 +18,7 @@ export function useBoolean(
2018
] {
2119
const [value, setValue] = useState(startState)
2220

23-
const functions = React.useMemo(
21+
const functions = useMemo(
2422
() => ({
2523
toggle: (): void => setValue((state) => !state),
2624
setTrue: (): void => setValue(true),

src/useClipboard/useClipboard.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,8 @@ 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(
11-
timeout = 2000
12-
): {
13-
copy: (valueToCopy: string) => void
10+
export function useClipboard(timeout = 2000): {
11+
copy: (valueToCopy: string) => Promise<void>
1412
reset: () => void
1513
error: Error | undefined
1614
copied: boolean
@@ -36,7 +34,9 @@ export function useClipboard(
3634
return navigator.clipboard
3735
.writeText(valueToCopy)
3836
.then(() => handleCopyResult(true))
39-
.catch((err) => setError(err))
37+
.catch((err) => {
38+
if (err instanceof Error) setError(err)
39+
})
4040
} else {
4141
setError(new Error('useClipboard: clipboard is not supported'))
4242
}

0 commit comments

Comments
 (0)