Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/258 scrolldir is always down #266

Merged
merged 5 commits into from
Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"es6": true
},
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
// Specifying Parser
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
Expand All @@ -15,12 +14,9 @@
"tsconfigRootDir": ".",
"project": ["./tsconfig.json"]
},
// Configuring third-party plugins
"plugins": ["@typescript-eslint"],
// Resolve imports
"plugins": ["@typescript-eslint", "react-hooks"],
"rules": {
"linebreak-style": "off",
// Disallow the `any` type.
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/ban-types": [
"error",
Expand All @@ -31,8 +27,8 @@
}
}
],
"react-hooks/exhaustive-deps": "off",
// Enforce the use of the shorthand syntax.
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
"object-shorthand": "error",
"no-console": "warn"
}
Expand Down
34 changes: 34 additions & 0 deletions .github/workflows/semantic-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Semantic Release

on:
push:
branches:
- master
workflow_dispatch:

jobs:
release:
name: Create Release
runs-on: ubuntu-latest
permissions:
contents: write
issues: write
pull-requests: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 'lts/*'

- name: Install dependencies
run: npm install

- name: Semantic Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npx semantic-release
24 changes: 13 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,22 @@
},
"description": "Enhance your React apps with advanced scroll detection using @smakss/react-scroll-direction. This powerful hook not only detects scroll direction but also provides scroll position information. Ideal for React, Remix, Next.js, and Gatsby projects, it comes with adjustable sensitivity and supports ES Modules.",
"devDependencies": {
"@commitlint/cli": "^18.6.0",
"@commitlint/config-conventional": "^18.6.0",
"@commitlint/cli": "^19.2.1",
"@commitlint/config-conventional": "^19.1.0",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-typescript": "^11.1.6",
"@types/react": "^18.2.55",
"@typescript-eslint/eslint-plugin": "^7.0.1",
"@typescript-eslint/parser": "^7.0.1",
"eslint": "^8.56.0",
"@types/react": "^18.2.74",
"@typescript-eslint/eslint-plugin": "^7.5.0",
"@typescript-eslint/parser": "^7.5.0",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
"husky": "^9.0.10",
"eslint-plugin-react-hooks": "^4.6.0",
"husky": "^9.0.11",
"lint-staged": "^15.2.2",
"prettier": "^3.2.5",
"rollup": "^4.10.0",
"typescript": "^5.3.3"
"rollup": "^4.14.0",
"typescript": "^5.4.4"
},
"engines": {
"node": ">=18.0.0"
Expand Down Expand Up @@ -74,9 +75,10 @@
"lint": "eslint --cache --cache-location ./node_modules/.cache/.eslintcache --ext js,jsx,ts,tsx --max-warnings=0 .",
"lint:fix": "eslint src/**/*.ts --fix",
"setup": "yarn && husky install",
"typecheck": "tsc -b ."
"typecheck": "tsc -b .",
"update:deps": "rm -rf node_modules yarn.lock && ncu -u && yarn"
},
"type": "module",
"types": "./dist/index.d.ts",
"version": "4.0.4"
"version": "4.1.0"
}
76 changes: 65 additions & 11 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,93 @@
import { useState, useEffect, useCallback } from 'react';
import { useState, useEffect, useCallback, useRef } from 'react';

/** Enumeration for axis values */
export enum Axis {
/**
* The x-axis represents the horizontal direction.
*/
X = 'x',
/**
* The y-axis represents the vertical direction.
*/
Y = 'y'
}

/** Enumeration for direction values */
export enum Direction {
/**
* The up direction represents the scroll direction moving towards the top.
*/
Up = 'up',
/**
* The down direction represents the scroll direction moving towards the bottom.
*/
Down = 'down',
/**
* The left direction represents the scroll direction moving towards the left.
*/
Left = 'left',
/**
* The right direction represents the scroll direction moving towards the right.
*/
Right = 'right',
/**
* The still direction represents the scroll direction when the user is not scrolling.
*/
Still = 'still'
}

type ScrollPosition = {
/**
* The top position represents the distance from the top edge of the page.
*/
top: number;
/**
* The bottom position represents the distance from the bottom edge of the page.
*/
bottom: number;
/**
* The left position represents the distance from the left edge of the page.
*/
left: number;
/**
* The right position represents the distance from the right edge of the page.
*/
right: number;
};

/** Type declaration for the returned scroll information */
type ScrollInfo = {
/**
* The scrollDir represents the current scroll direction.
*/
scrollDir: Direction;
/**
* The scrollPosition represents the current scroll position.
*/
scrollPosition: ScrollPosition;
};

/** Type declaration for scroll properties */
type ScrollProps = {
/**
* The thr represents the threshold value for scroll detection.
*/
thr?: number;
/**
* The axis represents the scroll axis (x or y).
*/
axis?: Axis;
/**
* The scrollUp represents the scroll direction when moving up.
*/
scrollUp?: Direction;
/**
* The scrollDown represents the scroll direction when moving down.
*/
scrollDown?: Direction;
/**
* The still represents the scroll direction when the user is not scrolling.
*/
still?: Direction;
};

Expand Down Expand Up @@ -87,18 +141,18 @@ function useDetectScroll(props: ScrollProps = {}): ScrollInfo {
});

const threshold = Math.max(0, thr);
let ticking = false;
let lastScroll = 0;
const ticking = useRef(false);
const lastScroll = useRef(0);

/** Function to update scroll direction */
const updateScrollDir = useCallback(() => {
const scroll = axis === Axis.Y ? window.scrollY : window.scrollX;

if (Math.abs(scroll - lastScroll) >= threshold) {
setScrollDir(scroll > lastScroll ? scrollDown : scrollUp);
lastScroll = Math.max(0, scroll);
if (Math.abs(scroll - lastScroll.current) >= threshold) {
setScrollDir(scroll > lastScroll.current ? scrollDown : scrollUp);
lastScroll.current = Math.max(0, scroll);
}
ticking = false;
ticking.current = false;
}, [axis, threshold, scrollDown, scrollUp]);

useEffect(() => {
Expand All @@ -125,20 +179,20 @@ function useDetectScroll(props: ScrollProps = {}): ScrollInfo {
}, []);

useEffect(() => {
lastScroll = axis === Axis.Y ? window.scrollY : window.scrollX;
lastScroll.current = axis === Axis.Y ? window.scrollY : window.scrollX;

/** Function to handle onScroll event */
const onScroll = () => {
if (!ticking) {
if (!ticking.current) {
window.requestAnimationFrame(updateScrollDir);
ticking = true;
ticking.current = true;
}
};

window.addEventListener('scroll', onScroll);

return () => window.removeEventListener('scroll', onScroll);
}, [updateScrollDir]);
}, [axis, updateScrollDir]);

return { scrollDir, scrollPosition };
}
Expand Down
Loading
Loading