Skip to content

Commit 37b7e1d

Browse files
committed
feat: migrate app to Typescript
Also, apply minor optimisation on the custom hook and add ESLint
1 parent 778da08 commit 37b7e1d

File tree

9 files changed

+535
-2776
lines changed

9 files changed

+535
-2776
lines changed

.eslintcache

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"/Users/smakss/Development/SMAKSS/react-scroll-direction/src/hooks/index.ts":"1","/Users/smakss/Development/SMAKSS/react-scroll-direction/src/hooks/useDetectScroll.ts":"2"},{"size":64,"mtime":1684533639135,"results":"3","hashOfConfig":"4"},{"size":1493,"mtime":1684534510896,"results":"5","hashOfConfig":"4"},{"filePath":"6","messages":"7","suppressedMessages":"8","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"1v57251",{"filePath":"9","messages":"10","suppressedMessages":"11","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"/Users/smakss/Development/SMAKSS/react-scroll-direction/src/hooks/index.ts",[],[],"/Users/smakss/Development/SMAKSS/react-scroll-direction/src/hooks/useDetectScroll.ts",[],[]]

.eslintignore

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

.eslintrc.json

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
"env": {
3+
"browser": true,
4+
"es6": true
5+
},
6+
"extends": [
7+
"eslint:recommended",
8+
"plugin:@typescript-eslint/recommended",
9+
"plugin:prettier/recommended"
10+
],
11+
// Specifying Parser
12+
"parser": "@typescript-eslint/parser",
13+
"parserOptions": {
14+
"ecmaFeatures": {
15+
"jsx": true
16+
},
17+
"ecmaVersion": "latest",
18+
"sourceType": "module",
19+
"tsconfigRootDir": ".",
20+
"project": ["./tsconfig.json"]
21+
},
22+
// Configuring third-party plugins
23+
"plugins": ["@typescript-eslint"],
24+
// Resolve imports
25+
26+
"rules": {
27+
"linebreak-style": "off",
28+
// Configure prettier
29+
"prettier/prettier": [
30+
"error",
31+
{
32+
"printWidth": 80,
33+
"endOfLine": "lf",
34+
"singleQuote": false,
35+
"tabWidth": 2,
36+
"trailingComma": "es5"
37+
}
38+
],
39+
// Disallow the `any` type.
40+
"@typescript-eslint/no-explicit-any": "warn",
41+
"@typescript-eslint/ban-types": [
42+
"error",
43+
{
44+
"extendDefaults": true,
45+
"types": {
46+
"{}": false
47+
}
48+
}
49+
],
50+
"react-hooks/exhaustive-deps": "off",
51+
// Enforce the use of the shorthand syntax.
52+
"object-shorthand": "error",
53+
"no-console": "warn"
54+
}
55+
}

.github/dependabot.yml

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
version: 2
22
updates:
3-
- package-ecosystem: npm
4-
directory: "/"
5-
schedule:
6-
interval: daily
7-
open-pull-requests-limit: 10
3+
- package-ecosystem: npm
4+
directory: "/"
5+
schedule:
6+
interval: daily
7+
reviewers:
8+
- "SMAKSS"
9+
assignees:
10+
- "SMAKSS"
11+
labels:
12+
- "dependencies"
13+
open-pull-requests-limit: 10

package.json

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@
44
"url": "https://github.com/SMAKSS/react-scroll-direction/issues"
55
},
66
"description": "Detect scroll direction in react applications.",
7-
"dependencies": {
8-
"prop-types": "^15.8.1"
9-
},
107
"devDependencies": {
118
"@rollup/plugin-commonjs": "^25.0.0",
129
"@rollup/plugin-node-resolve": "^15.0.1",
10+
"@rollup/plugin-typescript": "^11.1.1",
11+
"@types/react": "^18.2.6",
12+
"@typescript-eslint/eslint-plugin": "^5.59.6",
13+
"@typescript-eslint/parser": "^5.59.6",
14+
"eslint": "^8.41.0",
15+
"eslint-config-prettier": "^8.8.0",
16+
"eslint-plugin-prettier": "^4.2.1",
17+
"prettier": "^2.8.8",
1318
"rollup": "^3.2.3",
14-
"ts-migrate": "^0.1.35",
1519
"typescript": "^5.0.4"
1620
},
1721
"exports": {
@@ -47,8 +51,10 @@
4751
"url": "git+https://github.com/SMAKSS/react-scroll-direction.git"
4852
},
4953
"scripts": {
50-
"generate": "rollup -c"
54+
"generate": "rollup -c",
55+
"lint": "tsc --noEmit && eslint src/**/*.ts --cache --max-warnings=0",
56+
"lint:fix": "eslint src/**/*.ts --fix"
5157
},
5258
"type": "module",
53-
"version": "1.0.5"
59+
"version": "1.1.0-beta"
5460
}

rollup.config.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import resolve from "@rollup/plugin-node-resolve";
22
import commonjs from "@rollup/plugin-commonjs";
3+
import typescript from "@rollup/plugin-typescript";
34
import packageJson from "./package.json" assert { type: "json" };
45

56
export default [
67
{
7-
input: "src/index.js",
8+
input: "src/index.ts",
89
output: [
910
{
1011
file: packageJson.main,
@@ -17,7 +18,7 @@ export default [
1718
sourcemap: true,
1819
},
1920
],
20-
plugins: [resolve(), commonjs()],
21+
plugins: [resolve(), commonjs(), typescript()],
2122
external: [
2223
...Object.keys(packageJson.devDependencies || {}),
2324
...Object.keys(packageJson.peerDependencies || {}),

src/hooks/useDetectScroll.ts

Lines changed: 40 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,52 @@
1-
// @ts-expect-error TS(2307): Cannot find module 'react' or its corresponding ty... Remove this comment to see the full error message
2-
import { useState, useEffect } from "react";
3-
// @ts-expect-error TS(7016): Could not find a declaration file for module 'prop... Remove this comment to see the full error message
4-
import PropTypes from "prop-types";
1+
import { useState, useEffect, useCallback } from "react";
52

6-
function useDetectScroll(props: any) {
3+
enum Axis {
4+
X = "x",
5+
Y = "y",
6+
}
7+
8+
enum Direction {
9+
Up = "up",
10+
Down = "down",
11+
Left = "left",
12+
Right = "right",
13+
Still = "still",
14+
}
15+
16+
type ScrollProps = {
17+
thr?: number;
18+
axis?: Axis;
19+
scrollUp?: string;
20+
scrollDown?: string;
21+
still?: string;
22+
};
23+
24+
function useDetectScroll(props: ScrollProps) {
725
const {
826
thr = 0,
9-
axis = "y",
10-
scrollUp = axis === "y" ? "up" : "left",
11-
scrollDown = axis === "y" ? "down" : "right",
12-
still = "still",
27+
axis = Axis.Y,
28+
scrollUp = axis === Axis.Y ? Direction.Up : Direction.Left,
29+
scrollDown = axis === Axis.Y ? Direction.Down : Direction.Right,
30+
still = Direction.Still,
1331
} = props;
14-
const [scrollDir, setScrollDir] = useState(still);
1532

16-
useEffect(() => {
17-
const threshold = thr > 0 ? thr : 0;
18-
let ticking = false;
19-
let lastScroll: any = undefined;
20-
21-
axis === "y"
22-
? (lastScroll = window.pageYOffset)
23-
: (lastScroll = window.pageXOffset);
33+
const [scrollDir, setScrollDir] = useState(still);
2434

25-
const updateScrollDir = () => {
26-
let scroll = undefined;
35+
const threshold = Math.max(0, thr);
36+
let ticking = false;
37+
let lastScroll: number = axis === Axis.Y ? window.scrollY : window.scrollX;
2738

28-
axis === "y"
29-
? (scroll = window.pageYOffset)
30-
: (scroll = window.pageXOffset);
39+
const updateScrollDir = useCallback(() => {
40+
const scroll = axis === Axis.Y ? window.scrollY : window.scrollX;
3141

32-
if (Math.abs(scroll - lastScroll) < threshold) {
33-
ticking = false;
34-
return;
35-
}
42+
if (Math.abs(scroll - lastScroll) >= threshold) {
3643
setScrollDir(scroll > lastScroll ? scrollDown : scrollUp);
37-
lastScroll = scroll > 0 ? scrollY : 0;
38-
ticking = false;
39-
};
44+
lastScroll = Math.max(0, scroll);
45+
}
46+
ticking = false;
47+
}, [axis, threshold, scrollDown, scrollUp]);
4048

49+
useEffect(() => {
4150
const onScroll = () => {
4251
if (!ticking) {
4352
window.requestAnimationFrame(updateScrollDir);
@@ -48,17 +57,9 @@ function useDetectScroll(props: any) {
4857
window.addEventListener("scroll", onScroll);
4958

5059
return () => window.removeEventListener("scroll", onScroll);
51-
}, [scrollDir]);
60+
}, [updateScrollDir]);
5261

5362
return [scrollDir];
5463
}
5564

5665
export default useDetectScroll;
57-
58-
useDetectScroll.propTypes = {
59-
thr: PropTypes.number,
60-
axis: PropTypes.string,
61-
scrollUp: PropTypes.string,
62-
scrollDown: PropTypes.string,
63-
still: PropTypes.string,
64-
};

src/tsconfig.json renamed to tsconfig.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
1212

1313
/* Language and Environment */
14-
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
14+
"target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
1515
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
1616
// "jsx": "preserve", /* Specify what JSX code is generated. */
1717
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
@@ -25,9 +25,9 @@
2525
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
2626

2727
/* Modules */
28-
"module": "commonjs", /* Specify what module code is generated. */
28+
"module": "esnext" /* Specify what module code is generated. */,
2929
// "rootDir": "./", /* Specify the root folder within your source files. */
30-
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
30+
"moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */,
3131
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
3232
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
3333
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
@@ -77,12 +77,12 @@
7777
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
7878
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
7979
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
80-
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
80+
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
8181
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
82-
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
82+
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
8383

8484
/* Type Checking */
85-
"strict": true, /* Enable all strict type-checking options. */
85+
"strict": true /* Enable all strict type-checking options. */,
8686
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
8787
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
8888
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
@@ -104,6 +104,6 @@
104104

105105
/* Completeness */
106106
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
107-
"skipLibCheck": true /* Skip type checking all .d.ts files. */
107+
"skipLibCheck": true /* Skip type checking all .d.ts files. */
108108
}
109109
}

0 commit comments

Comments
 (0)