Skip to content

Commit c0f9fb9

Browse files
committed
update typeScript and fix bug speed
1 parent 3319399 commit c0f9fb9

32 files changed

+295
-106
lines changed

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
"build": "vite build",
99
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
1010
"preview": "vite preview",
11-
"format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,css,scss,md}\""
11+
"format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,css,scss,md}\"",
12+
"typecheck": "tsc --noEmit"
1213
},
1314
"dependencies": {
1415
"react": "^18.3.1",

src/App.jsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,15 @@ const App = () => {
3737
}, [player, runAlgorithm, resetAll, algorithmState]);
3838

3939
// refactor - use CSS instead of JS logic (hint: media queries, dvh units)
40-
const barWidth = window.screen.width / array.length;
4140
disableScroll();
4241

4342
const step = getCurrentStep();
43+
console.log(step);
4444

4545
return (
4646
<section>
4747
<span className="title-algorithm">{selectedAlgorithm} Sort</span>
48-
<BarContainer {...step} barWidth={barWidth} />
48+
<BarContainer {...step} />
4949
<Player
5050
selectAlgorithm={selectAlgorithm}
5151
goToNextStep={() => player.setPlayerState('forward')}

src/actions/useClickOutside.ts

+12-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
11
import { useEffect } from 'react';
22

3-
const useClickOutside = (callback, targetClass) => {
3+
type useClickOutsideProps = {
4+
callback: () => void;
5+
targetClass: string;
6+
};
7+
8+
const useClickOutside = ({
9+
callback,
10+
targetClass,
11+
}: useClickOutsideProps): void => {
412
useEffect(() => {
5-
const handleClickOutside = (event) => {
6-
if (!event.target.closest(`.${targetClass}`)) {
13+
const handleClickOutside = (event: MouseEvent): void => {
14+
const target = event.target as HTMLElement | null;
15+
if (target && !target.closest(`.${targetClass}`)) {
716
callback();
817
}
918
};

src/components/Bar/Bar.jsx renamed to src/components/Bar/Bar.tsx

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
11
import './Bar.css';
22

3-
const Bar = ({ width, height, isActive, isCompare, isPivot }) => {
3+
type BarProps = {
4+
width: number;
5+
height: number;
6+
isActive: boolean | null;
7+
isCompare: boolean | null;
8+
isPivot: boolean | null;
9+
};
10+
11+
const Bar: React.FC<BarProps> = ({
12+
width,
13+
height,
14+
isActive,
15+
isCompare,
16+
isPivot,
17+
}) => {
418
const barStyles = {
519
height: `${height}px`,
620
width: `${width}px`,

src/components/BarContainer/BarContainer.jsx renamed to src/components/BarContainer/BarContainer.tsx

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
import Bar from '../Bar/Bar';
2+
import { Tracking } from '../../types';
23

34
import './BarContainer.css';
45

5-
const Array = ({ barWidth, array, tracking }) => {
6+
type BarContainerProps = {
7+
array: number[];
8+
tracking: Tracking;
9+
};
10+
11+
const BarContainer: React.FC<BarContainerProps> = ({ array, tracking }) => {
612
const { activeIndex, compareIndex, pivotIndex } = tracking;
713

14+
//Calculate width each column in array
15+
const barWidth = window.screen.width / array.length;
16+
817
return (
918
<div className="arr">
1019
{array.map((heightPx, index) => (
@@ -21,4 +30,4 @@ const Array = ({ barWidth, array, tracking }) => {
2130
);
2231
};
2332

24-
export default Array;
33+
export default BarContainer;

src/components/Button/Button.jsx

-30
This file was deleted.

src/components/Button/Button.tsx

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import React, { ReactNode } from 'react';
2+
3+
import './Button.css';
4+
5+
type ButtonProps = {
6+
onClick?: () => void;
7+
onMouseDown?: (event: React.MouseEvent<HTMLButtonElement>) => void;
8+
onMouseUp?: (event: React.MouseEvent<HTMLButtonElement>) => void;
9+
onMouseLeave?: (event: React.MouseEvent<HTMLButtonElement>) => void;
10+
onTouchCancel?: (event: React.TouchEvent<HTMLButtonElement>) => void;
11+
onTouchStart?: (event: React.TouchEvent<HTMLButtonElement>) => void;
12+
onTouchEnd?: (event: React.TouchEvent<HTMLButtonElement>) => void;
13+
children?: ReactNode;
14+
className?: string;
15+
};
16+
17+
const Button: React.FC<ButtonProps> = ({
18+
onClick,
19+
onMouseDown,
20+
onMouseUp,
21+
onMouseLeave,
22+
onTouchCancel,
23+
onTouchStart,
24+
onTouchEnd,
25+
children,
26+
className,
27+
}) => {
28+
return (
29+
<button
30+
className={`button ${className}`}
31+
onMouseDown={onMouseDown}
32+
onMouseUp={onMouseUp}
33+
onMouseLeave={onMouseLeave}
34+
onClick={onClick}
35+
onTouchEnd={onTouchEnd}
36+
onTouchCancel={onTouchCancel}
37+
onTouchStart={onTouchStart}
38+
>
39+
{children}
40+
</button>
41+
);
42+
};
43+
44+
export default Button;

src/components/DropDown/DropDown.jsx renamed to src/components/DropDown/DropDown.tsx

+28-12
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,40 @@
1-
import './DropDown.css';
2-
import { useState } from 'react';
1+
import { useCallback, useState } from 'react';
32
import useClickOutside from '../../actions/useClickOutside';
4-
import DropDownIcon from '../icon/DropDownIcon';
53
import { algorithms } from '../../constants';
64
import { capitalizeFirstLetter } from '../../utils/capitalizeFirstLetter';
5+
import DropDownIcon from '../icon/DropDownIcon';
6+
7+
import './DropDown.css';
78

8-
const DropDown = ({ onSelect, selectedAlgorithm }) => {
9+
type DropDowmProps = {
10+
selectAlgorithm: (select: string) => void;
11+
selectedAlgorithm: string;
12+
};
13+
14+
const DropDown: React.FC<DropDowmProps> = ({
15+
selectAlgorithm,
16+
selectedAlgorithm,
17+
}) => {
918
const [isOpen, setIsOpen] = useState(false);
1019

1120
const toggleDropDown = () => {
12-
setIsOpen(!isOpen);
21+
setIsOpen((prev) => !prev);
1322
};
1423

15-
const handleSelect = (algorithm) => {
16-
onSelect(algorithm);
17-
setIsOpen(false);
18-
};
19-
useClickOutside(() => {
20-
if (isOpen) setIsOpen(false);
21-
}, 'dropdown');
24+
const handleSelect = useCallback(
25+
(algorithm: string) => {
26+
selectAlgorithm(algorithm);
27+
setIsOpen(false);
28+
},
29+
[selectAlgorithm, setIsOpen],
30+
);
31+
32+
useClickOutside({
33+
callback: (): void => {
34+
if (isOpen) setIsOpen(false);
35+
},
36+
targetClass: 'dropdown',
37+
});
2238

2339
return (
2440
<div className={`dropdown ${isOpen ? 'open' : ''}`}>

src/components/InputRange/InputRange.jsx

-16
This file was deleted.
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import './InputRange.css';
2+
3+
type InputRangeType = {
4+
speed: number;
5+
setSpeed: (speed: number) => void;
6+
};
7+
8+
const InputRange: React.FC<InputRangeType> = ({ speed, setSpeed }) => {
9+
return (
10+
<input
11+
type="range"
12+
id="speed"
13+
value={speed}
14+
min={10}
15+
max={20}
16+
step={0.1}
17+
onChange={(e) => setSpeed(parseFloat(e.target.value))}
18+
/>
19+
);
20+
};
21+
22+
export default InputRange;

src/components/Player/Player.tsx

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useCallback, useRef } from 'react';
1+
import { useCallback, useRef } from 'react';
22
import { speedOptions } from '../../constants';
33
import ResetIcon from '../icon/ResetIcon';
44
import NextStepIcon from '../icon/NextStepIcon';
@@ -8,7 +8,8 @@ import InputRange from '../InputRange/InputRange';
88
import Button from '../Button/Button';
99
import PauseIcon from '../icon/PauseIcon';
1010
import DropDown from '../DropDown/DropDown';
11-
import { AlgorithmState, PlayerState } from '../../types';
11+
import { AlgorithmState } from '../../types';
12+
import { PlayerState } from '../../hooks';
1213

1314
import './Player.css';
1415

@@ -37,7 +38,7 @@ const Player: React.FC<PlayerProps> = ({
3738
algorithmState,
3839
playerState,
3940
}) => {
40-
const intervalRef = useRef<NodeJS.Timeout | null>(null);
41+
const intervalRef = useRef<number | null>(null);
4142

4243
const startInterval = (action: () => void) => {
4344
if (intervalRef.current === null) {
@@ -82,7 +83,7 @@ const Player: React.FC<PlayerProps> = ({
8283
<div className="player-container">
8384
<div className="controls">
8485
<DropDown
85-
onSelect={selectAlgorithm}
86+
selectAlgorithm={selectAlgorithm}
8687
selectedAlgorithm={selectedAlgorithm}
8788
/>
8889
<div className="step-buttons">

src/components/icon/DropDownIcon.tsx

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import React from 'react';
2-
31
const DropDownIcon = () => {
42
return (
53
<svg

src/components/icon/NextStepIcon.tsx

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import React from 'react';
21
const NextStepIcon = () => {
32
return (
43
<div>

src/components/icon/PauseIcon.tsx

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import React from 'react';
2-
31
const PauseIcon = () => {
42
return (
53
<svg

src/components/icon/PlayIcon.tsx

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import React from 'react';
2-
31
const PlayIcon = () => {
42
return (
53
<svg

src/components/icon/PreviousStepIcon.tsx

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import React from 'react';
2-
31
export const PreviousStepIcon = () => {
42
return (
53
<svg

src/components/icon/ResetIcon.tsx

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import React from 'react';
2-
31
const ResetIcon = () => {
42
return (
53
<svg

src/components/icon/ResumePlay.tsx

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import React from 'react';
2-
31
const ResumePlay = () => {
42
return (
53
<svg

src/constants/index.js

-3
This file was deleted.

src/constants/index.ts

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export const speedOptions: number[] = [1, 2, 3, 4, 5];
2+
3+
export const algorithms: string[] = [
4+
'selection',
5+
'bubble',
6+
'quick',
7+
'insertion',
8+
];

src/hooks/useHistory.ts

+12-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
import { useCallback, useEffect, useRef, useState } from 'react';
22

3-
export const useHistory = () => {
4-
const [history, setHistory] = useState([]);
3+
type HistoryRef<T> = {
4+
updateHistory: (newState: T) => void;
5+
incrementTrack: () => void;
6+
decrementTrack: () => void;
7+
isHistoryEnd: () => boolean;
8+
};
9+
10+
export const useHistory = <T>() => {
11+
const [history, setHistory] = useState<T[]>([]);
512
const [currentTrack, setCurrentTrack] = useState(0);
6-
console.log(history);
13+
714
const incrementTrack = useCallback(() => {
815
setCurrentTrack((prevTrack) => prevTrack + 1);
916
}, [setCurrentTrack]);
@@ -17,7 +24,7 @@ export const useHistory = () => {
1724
}, [currentTrack, history]);
1825

1926
const updateHistory = useCallback(
20-
(newState) => {
27+
(newState: T) => {
2128
setHistory((prevHistory) => {
2229
setCurrentTrack(prevHistory.length);
2330
return [...prevHistory, newState];
@@ -35,7 +42,7 @@ export const useHistory = () => {
3542
return history[currentTrack];
3643
}, [history, currentTrack]);
3744

38-
const historyRef = useRef({
45+
const historyRef = useRef<HistoryRef<T>>({
3946
updateHistory,
4047
incrementTrack,
4148
decrementTrack,

0 commit comments

Comments
 (0)