Skip to content

Commit a89424c

Browse files
authored
refactor: change to typescript (#26)
1 parent dc491ae commit a89424c

File tree

10 files changed

+3359
-4546
lines changed

10 files changed

+3359
-4546
lines changed

.babelrc

Lines changed: 0 additions & 3 deletions
This file was deleted.

.husky/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
_

.husky/pre-commit

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/sh
2+
. "$(dirname "$0")/_/husky.sh"
3+
4+
npm run pretty-quick

__test__/index.spec.js renamed to __test__/index.spec.tsx

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { render, cleanup, fireEvent } from '@testing-library/react';
33

44
import useUndo from '../index';
55

6-
const UndoComponent = React.memo(({ disabled }) => {
6+
const UndoComponent = ({ disabled }: { disabled: boolean }) => {
77
const [
88
countState,
99
{
@@ -62,18 +62,18 @@ const UndoComponent = React.memo(({ disabled }) => {
6262
</button>
6363
</div>
6464
);
65-
});
65+
};
6666

6767
const setup = (defaultDisabled = true) => {
6868
const { getByTestId } = render(<UndoComponent disabled={defaultDisabled} />);
6969

7070
const count = getByTestId('count');
71-
const unchangeButton = getByTestId('unchange');
72-
const incrementButton = getByTestId('increment');
73-
const decrementButton = getByTestId('decrement');
74-
const undoButton = getByTestId('undo');
75-
const redoButton = getByTestId('redo');
76-
const resetButton = getByTestId('reset');
71+
const unchangeButton = getByTestId('unchange') as HTMLButtonElement;
72+
const incrementButton = getByTestId('increment') as HTMLButtonElement;
73+
const decrementButton = getByTestId('decrement') as HTMLButtonElement;
74+
const undoButton = getByTestId('undo') as HTMLButtonElement;
75+
const redoButton = getByTestId('redo') as HTMLButtonElement;
76+
const resetButton = getByTestId('reset') as HTMLButtonElement;
7777

7878
return {
7979
count,
@@ -167,14 +167,7 @@ describe('use-undo', () => {
167167
});
168168

169169
it('present count should not be changed when canUndo or canRedo is false', () => {
170-
const {
171-
count,
172-
unchangeButton,
173-
incrementButton,
174-
decrementButton,
175-
undoButton,
176-
redoButton,
177-
} = setup(false);
170+
const { count, undoButton, redoButton } = setup(false);
178171

179172
expect(count.textContent).toBe('count: 0');
180173
expect(undoButton.disabled).toBe(false);

index.d.ts

Lines changed: 0 additions & 16 deletions
This file was deleted.

index.js renamed to index.ts

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,43 @@
11
import { useReducer, useCallback } from 'react';
22

3-
const UNDO = 'UNDO';
4-
const REDO = 'REDO';
5-
const SET = 'SET';
6-
const RESET = 'RESET';
3+
enum ActionType {
4+
Undo = 'UNDO',
5+
Redo = 'REDO',
6+
Set = 'SET',
7+
Reset = 'RESET',
8+
}
9+
10+
export interface Actions<T> {
11+
set: (newPresent: T) => void;
12+
reset: (newPresent: T) => void;
13+
undo: () => void;
14+
redo: () => void;
15+
canUndo: boolean;
16+
canRedo: boolean;
17+
}
18+
19+
interface Action<T> {
20+
type: ActionType;
21+
newPresent?: T;
22+
}
23+
24+
export interface State<T> {
25+
past: T[];
26+
present: T;
27+
future: T[];
28+
}
729

830
const initialState = {
931
past: [],
1032
present: null,
1133
future: [],
1234
};
1335

14-
const reducer = (state, action) => {
36+
const reducer = <T>(state: State<T>, action: Action<T>) => {
1537
const { past, present, future } = state;
1638

1739
switch (action.type) {
18-
case UNDO: {
40+
case ActionType.Undo: {
1941
const previous = past[past.length - 1];
2042
const newPast = past.slice(0, past.length - 1);
2143

@@ -26,7 +48,7 @@ const reducer = (state, action) => {
2648
};
2749
}
2850

29-
case REDO: {
51+
case ActionType.Redo: {
3052
const next = future[0];
3153
const newFuture = future.slice(1);
3254

@@ -37,7 +59,7 @@ const reducer = (state, action) => {
3759
};
3860
}
3961

40-
case SET: {
62+
case ActionType.Set: {
4163
const { newPresent } = action;
4264

4365
if (newPresent === present) {
@@ -50,7 +72,7 @@ const reducer = (state, action) => {
5072
};
5173
}
5274

53-
case RESET: {
75+
case ActionType.Reset: {
5476
const { newPresent } = action;
5577

5678
return {
@@ -62,30 +84,30 @@ const reducer = (state, action) => {
6284
}
6385
};
6486

65-
const useUndo = initialPresent => {
87+
const useUndo = <T>(initialPresent: T): [State<T>, Actions<T>] => {
6688
const [state, dispatch] = useReducer(reducer, {
6789
...initialState,
6890
present: initialPresent,
69-
});
91+
}) as [State<T>, React.Dispatch<Action<T>>];
7092

7193
const canUndo = state.past.length !== 0;
7294
const canRedo = state.future.length !== 0;
7395
const undo = useCallback(() => {
7496
if (canUndo) {
75-
dispatch({ type: UNDO });
97+
dispatch({ type: ActionType.Undo });
7698
}
7799
}, [canUndo]);
78100
const redo = useCallback(() => {
79101
if (canRedo) {
80-
dispatch({ type: REDO });
102+
dispatch({ type: ActionType.Redo });
81103
}
82104
}, [canRedo]);
83105
const set = useCallback(
84-
newPresent => dispatch({ type: SET, newPresent }),
106+
(newPresent: T) => dispatch({ type: ActionType.Set, newPresent }),
85107
[]
86108
);
87109
const reset = useCallback(
88-
newPresent => dispatch({ type: RESET, newPresent }),
110+
(newPresent: T) => dispatch({ type: ActionType.Reset, newPresent }),
89111
[]
90112
);
91113

jest.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = {
2+
preset: 'ts-jest',
3+
testEnvironment: 'jsdom',
4+
};

package.json

Lines changed: 26 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,66 +3,53 @@
33
"version": "1.0.3",
44
"description": "undo/redo functionality with React Hooks",
55
"license": "MIT",
6-
"author": "xxhomey19",
7-
"homepage": "https://github.com/xxhomey19/use-undo#readme",
6+
"author": "homerchen19",
7+
"homepage": "https://github.com/homerchen19/use-undo#readme",
88
"repository": {
99
"type": "git",
10-
"url": "git+https://github.com/xxhomey19/use-undo.git"
10+
"url": "git+https://github.com/homerchen19/use-undo.git"
1111
},
1212
"bugs": {
13-
"url": "https://github.com/xxhomey19/use-undo/issues"
13+
"url": "https://github.com/homerchen19/use-undo/issues"
1414
},
15+
"source": "index.ts",
1516
"main": "lib/use-undo.js",
1617
"umd:main": "lib/use-undo.umd.js",
1718
"module": "lib/use-undo.m.js",
19+
"types": "lib/index.d.ts",
1820
"scripts": {
19-
"build": "rimraf lib && microbundle -o lib/ --name use-undo --sourcemap false",
21+
"build": "rimraf lib && microbundle -o lib/ --name use-undo --sourcemap false --no-compress",
2022
"prepublishOnly": "yarn build",
2123
"preversion": "yarn test:cov",
2224
"test": "jest",
2325
"test:cov": "jest --coverage --runInBand --forceExit",
2426
"test:watch": "jest --watch",
25-
"pretty-quick": "pretty-quick"
27+
"pre-commit": "pretty-quick --staged",
28+
"pretty-quick": "pretty-quick",
29+
"prepare": "husky install"
2630
},
2731
"files": [
28-
"lib",
29-
"index.d.ts"
32+
"lib"
3033
],
3134
"devDependencies": {
32-
"@babel/core": "^7.5.5",
33-
"@babel/preset-env": "^7.5.5",
34-
"@babel/preset-react": "^7.0.0",
35-
"@testing-library/react": "^9.1.3",
36-
"babel-core": "^7.0.0-bridge.0",
37-
"babel-jest": "^24.9.0",
38-
"husky": "^3.0.4",
39-
"jest": "^24.9.0",
40-
"microbundle": "^0.11.0",
41-
"prettier": "^1.18.2",
42-
"pretty-quick": "^1.11.1",
43-
"react": "^16.9.0",
44-
"react-dom": "^16.9.0",
45-
"regenerator-runtime": "^0.13.3",
46-
"rimraf": "^3.0.0"
47-
},
48-
"jest": {
49-
"collectCoverageFrom": [
50-
"index.js"
51-
],
52-
"testPathIgnorePatterns": [
53-
"/node_modules/",
54-
"<rootDir>/lib"
55-
],
56-
"resetModules": true,
57-
"resetMocks": true
35+
"@testing-library/react": "^11.2.7",
36+
"@types/jest": "^26.0.23",
37+
"@types/node": "^15.6.1",
38+
"@types/react": "^17.0.8",
39+
"@types/react-dom": "^17.0.5",
40+
"husky": "^6.0.0",
41+
"jest": "^27.0.3",
42+
"microbundle": "^0.13.1",
43+
"prettier": "^2.3.0",
44+
"pretty-quick": "^3.1.0",
45+
"react": "^17.0.2",
46+
"react-dom": "^17.0.2",
47+
"rimraf": "^3.0.2",
48+
"ts-jest": "^27.0.1",
49+
"typescript": "^4.3.2"
5850
},
5951
"peerDependencies": {
6052
"react": "^16.8.6",
6153
"react-dom": "^16.8.6"
62-
},
63-
"husky": {
64-
"hooks": {
65-
"pre-commit": "pretty-quick --staged"
66-
}
6754
}
6855
}

tsconfig.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"compilerOptions": {
3+
"allowJs": false,
4+
"module": "ESNext",
5+
"target": "ESNext",
6+
"lib": ["dom", "esnext"],
7+
"esModuleInterop": true,
8+
"moduleResolution": "node",
9+
"outDir": "lib",
10+
"jsx": "react",
11+
"noUnusedLocals": true,
12+
"noUnusedParameters": true,
13+
"preserveConstEnums": true,
14+
"sourceMap": false,
15+
"strict": true
16+
},
17+
"exclude": ["node_modules", "lib"]
18+
}

0 commit comments

Comments
 (0)