@websolutespa/bom-mixer-hooks 1.9.1 → 1.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @websolutespa/bom-mixer-hooks
2
2
 
3
+ ## 1.9.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 4c2d7a6: Added: useScrollDirection
8
+
3
9
  ## 1.9.1
4
10
 
5
11
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -938,6 +938,8 @@ type Scroll = {
938
938
  };
939
939
  declare function useScroll(): Scroll;
940
940
 
941
+ declare function useScrollDirection(callback?: (top: number, left: number) => number): number;
942
+
941
943
  declare function useScrolled(callback?: (top: number, left: number) => boolean): boolean;
942
944
 
943
945
  declare function useScrollTo(offset?: number): (event: React.MouseEvent<HTMLElement>) => void;
@@ -1055,4 +1057,4 @@ type WindowSize = {
1055
1057
  };
1056
1058
  declare function useWindowSize(): WindowSize;
1057
1059
 
1058
- export { BodyScrollOptions, ClickOutGetContainer, ColorScheme, CurrentStateType, ElementStackItem, ExtraProvider, Filter, FilterMode, FilterParams, FilterValues, GeoLocationSensorState, IExtra, IFilter, IFilterOption, IGeolocationPositionError, ILabelContext, ILayoutContext, ILazyModulesContext, IMetaDataContext, IPageContext, IPageRoute, IPageRouteOptions, IPaginationInfo, IPaginationItem, IPaginationLegacyInfo, IPaginationOptions, IParams, IParamsEncoded, IParamsQs, IUseSearchParamsEncodedResult, IUseSearchParamsQsResult, IUseSearchParamsResult, IUseSearchParamsValueResult, KeyCode, KeyMod, KeyboardOptions, KeyboardResult, LabelProvider, LabelService, LayoutProvider, LazyModulesProvider, MetaDataProvider, PageProvider, SSRState, SizeResult, SizeType, Sorting, UIReducer, UIValue, UseFiltersResultType, UseKeyboard, UseKeyboardHandler, createElementWithId, createGenericContext, detectIsBrowser, filtersToParams, getCurrentPosition, getFilteredItems, getFilters, getMoreItems, getOwnerPaddingRight, getOwnerScrollbarWidth, getPagedItems, getPagedItemsLegacy, getPaginationInfo, getPaginationLegacyInfo, getPreferredColorScheme, getPreferredReducedMotion, getRealSize, getSearchParams, getSearchParamsEncoded, getSearchParamsQs, getUID, hasGeolocation, isElement, isPaginationInfo, isPaginationLegacyInfo, localCollectionDelete, localCollectionFetch, localCollectionGet, localCollectionPatch, localCollectionPost, localCollectionPut, parseLabel, parseParams, pushSearchParams, pushSearchParamsEncoded, pushSearchParamsEncodedSilently, pushSearchParamsQs, pushSearchParamsQsSilently, pushSearchParamsSilently, replaceSearchParams, replaceSearchParamsEncoded, replaceSearchParamsEncodedSilently, replaceSearchParamsQs, replaceSearchParamsQsSilently, replaceSearchParamsSilently, scrollToRelativeY, scrollToSelector, scrollToY, setFilters, updateSearchParams, updateSearchParamsEncoded, updateSearchParamsQs, useApi, useApiDelete, useApiFetch, useApiGet, useApiPatch, useApiPost, useApiPut, useAutosizeTextArea, useBodyScroll, useBreakpoint, useClickAnyWhere, useClickOut, useCollectionApi, useCollectionApiDelete, useCollectionApiGet, useCollectionApiPatch, useCollectionApiPost, useCollectionApiPut, useColorScheme, useCurrency, useCurrentState, useDateTimeFormat, useDebounce, useDebounceCallback, useDebugChangedProps, useDomObserver, useDrawer, useElementSize, useEventListener, useExtra, useFilters, useFocusTrap, useGeolocation, useIdle, useInfiniteLoader, useIntersectionObserver, useIsomorphicLayoutEffect, useKeyboard, useLabel, useLayout, useLazyModules, useMetaData, useModal, useMounted, useNumber, usePage, usePageLoading, usePagination, usePaginationLegacy, usePortal, usePrevious, useRealSize, useReducedMotion, useReducedMotionLocal, useResize, useSSR, useScroll, useScrollTo, useScrolled, useSearchParams, useSearchParamsEncoded, useSearchParamsQs, useSearchParamsValue, useSorting, useSyncedRef, useUI, useUnit, useUnmountEffect, useWindowSize };
1060
+ export { BodyScrollOptions, ClickOutGetContainer, ColorScheme, CurrentStateType, ElementStackItem, ExtraProvider, Filter, FilterMode, FilterParams, FilterValues, GeoLocationSensorState, IExtra, IFilter, IFilterOption, IGeolocationPositionError, ILabelContext, ILayoutContext, ILazyModulesContext, IMetaDataContext, IPageContext, IPageRoute, IPageRouteOptions, IPaginationInfo, IPaginationItem, IPaginationLegacyInfo, IPaginationOptions, IParams, IParamsEncoded, IParamsQs, IUseSearchParamsEncodedResult, IUseSearchParamsQsResult, IUseSearchParamsResult, IUseSearchParamsValueResult, KeyCode, KeyMod, KeyboardOptions, KeyboardResult, LabelProvider, LabelService, LayoutProvider, LazyModulesProvider, MetaDataProvider, PageProvider, SSRState, SizeResult, SizeType, Sorting, UIReducer, UIValue, UseFiltersResultType, UseKeyboard, UseKeyboardHandler, createElementWithId, createGenericContext, detectIsBrowser, filtersToParams, getCurrentPosition, getFilteredItems, getFilters, getMoreItems, getOwnerPaddingRight, getOwnerScrollbarWidth, getPagedItems, getPagedItemsLegacy, getPaginationInfo, getPaginationLegacyInfo, getPreferredColorScheme, getPreferredReducedMotion, getRealSize, getSearchParams, getSearchParamsEncoded, getSearchParamsQs, getUID, hasGeolocation, isElement, isPaginationInfo, isPaginationLegacyInfo, localCollectionDelete, localCollectionFetch, localCollectionGet, localCollectionPatch, localCollectionPost, localCollectionPut, parseLabel, parseParams, pushSearchParams, pushSearchParamsEncoded, pushSearchParamsEncodedSilently, pushSearchParamsQs, pushSearchParamsQsSilently, pushSearchParamsSilently, replaceSearchParams, replaceSearchParamsEncoded, replaceSearchParamsEncodedSilently, replaceSearchParamsQs, replaceSearchParamsQsSilently, replaceSearchParamsSilently, scrollToRelativeY, scrollToSelector, scrollToY, setFilters, updateSearchParams, updateSearchParamsEncoded, updateSearchParamsQs, useApi, useApiDelete, useApiFetch, useApiGet, useApiPatch, useApiPost, useApiPut, useAutosizeTextArea, useBodyScroll, useBreakpoint, useClickAnyWhere, useClickOut, useCollectionApi, useCollectionApiDelete, useCollectionApiGet, useCollectionApiPatch, useCollectionApiPost, useCollectionApiPut, useColorScheme, useCurrency, useCurrentState, useDateTimeFormat, useDebounce, useDebounceCallback, useDebugChangedProps, useDomObserver, useDrawer, useElementSize, useEventListener, useExtra, useFilters, useFocusTrap, useGeolocation, useIdle, useInfiniteLoader, useIntersectionObserver, useIsomorphicLayoutEffect, useKeyboard, useLabel, useLayout, useLazyModules, useMetaData, useModal, useMounted, useNumber, usePage, usePageLoading, usePagination, usePaginationLegacy, usePortal, usePrevious, useRealSize, useReducedMotion, useReducedMotionLocal, useResize, useSSR, useScroll, useScrollDirection, useScrollTo, useScrolled, useSearchParams, useSearchParamsEncoded, useSearchParamsQs, useSearchParamsValue, useSorting, useSyncedRef, useUI, useUnit, useUnmountEffect, useWindowSize };
package/dist/index.js CHANGED
@@ -189,6 +189,7 @@ __export(src_exports, {
189
189
  useResize: () => useResize,
190
190
  useSSR: () => useSSR,
191
191
  useScroll: () => useScroll,
192
+ useScrollDirection: () => useScrollDirection,
192
193
  useScrollTo: () => useScrollTo,
193
194
  useScrolled: () => useScrolled,
194
195
  useSearchParams: () => useSearchParams,
@@ -2116,13 +2117,42 @@ function useScroll() {
2116
2117
  return scroll;
2117
2118
  }
2118
2119
 
2119
- // src/useScrolled/useScrolled.ts
2120
+ // src/useScrollDirection/useScrollDirection.ts
2120
2121
  var import_react36 = require("react");
2122
+ var lastScrollTop = 0;
2121
2123
  var DEFAULT_CALLBACK = (top, left) => {
2124
+ const scrollTop = window.scrollY || document.documentElement.scrollTop;
2125
+ let direction = 0;
2126
+ if (scrollTop > lastScrollTop) {
2127
+ direction = 1;
2128
+ } else if (scrollTop < lastScrollTop) {
2129
+ direction = -1;
2130
+ }
2131
+ lastScrollTop = scrollTop <= 0 ? 0 : scrollTop;
2132
+ return direction;
2133
+ };
2134
+ function useScrollDirection(callback = DEFAULT_CALLBACK) {
2135
+ const [direction, setDirection] = (0, import_react36.useState)(0);
2136
+ const onScrolled = () => {
2137
+ const direction_ = callback(window.scrollY, window.scrollX);
2138
+ if (direction !== direction_) {
2139
+ setDirection(direction_);
2140
+ }
2141
+ };
2142
+ useEventListener("scroll", onScrolled);
2143
+ useIsomorphicLayoutEffect(() => {
2144
+ onScrolled();
2145
+ }, []);
2146
+ return direction;
2147
+ }
2148
+
2149
+ // src/useScrolled/useScrolled.ts
2150
+ var import_react37 = require("react");
2151
+ var DEFAULT_CALLBACK2 = (top, left) => {
2122
2152
  return top > 0;
2123
2153
  };
2124
- function useScrolled(callback = DEFAULT_CALLBACK) {
2125
- const [scrolled, setScrolled] = (0, import_react36.useState)(false);
2154
+ function useScrolled(callback = DEFAULT_CALLBACK2) {
2155
+ const [scrolled, setScrolled] = (0, import_react37.useState)(false);
2126
2156
  const onScrolled = () => {
2127
2157
  const scrolled_ = callback(window.scrollY, window.scrollX);
2128
2158
  if (scrolled !== scrolled_) {
@@ -2174,7 +2204,7 @@ function scrollToY(y = 0) {
2174
2204
 
2175
2205
  // src/useSearchParams/useSearchParams.ts
2176
2206
  var import_router3 = require("next/router");
2177
- var import_react37 = require("react");
2207
+ var import_react38 = require("react");
2178
2208
  function deserialize_(url) {
2179
2209
  const components = url.split("?");
2180
2210
  const search = components[1] || "";
@@ -2228,16 +2258,16 @@ function replaceSearchParamsSilently(router, params) {
2228
2258
  function useSearchParams() {
2229
2259
  const router = (0, import_router3.useRouter)();
2230
2260
  const params = getSearchParams2(router.asPath);
2231
- const pushParams = (0, import_react37.useCallback)((params2) => {
2261
+ const pushParams = (0, import_react38.useCallback)((params2) => {
2232
2262
  pushSearchParams(router, params2);
2233
2263
  }, [router]);
2234
- const pushParamsSilently = (0, import_react37.useCallback)((params2) => {
2264
+ const pushParamsSilently = (0, import_react38.useCallback)((params2) => {
2235
2265
  pushSearchParamsSilently(router, params2);
2236
2266
  }, [router]);
2237
- const replaceParams = (0, import_react37.useCallback)((params2) => {
2267
+ const replaceParams = (0, import_react38.useCallback)((params2) => {
2238
2268
  replaceSearchParams(router, params2);
2239
2269
  }, [router]);
2240
- const replaceParamsSilently = (0, import_react37.useCallback)((params2) => {
2270
+ const replaceParamsSilently = (0, import_react38.useCallback)((params2) => {
2241
2271
  replaceSearchParamsSilently(router, params2);
2242
2272
  }, [router]);
2243
2273
  return { params, pushParams, pushParamsSilently, replaceParams, replaceParamsSilently };
@@ -2245,16 +2275,16 @@ function useSearchParams() {
2245
2275
  function useSearchParamsValue(key) {
2246
2276
  const router = (0, import_router3.useRouter)();
2247
2277
  const params = getSearchParams2(router.asPath, key);
2248
- const pushParams = (0, import_react37.useCallback)((params2) => {
2278
+ const pushParams = (0, import_react38.useCallback)((params2) => {
2249
2279
  pushSearchParams(router, params2);
2250
2280
  }, [router]);
2251
- const pushParamsSilently = (0, import_react37.useCallback)((params2) => {
2281
+ const pushParamsSilently = (0, import_react38.useCallback)((params2) => {
2252
2282
  pushSearchParamsSilently(router, params2);
2253
2283
  }, [router]);
2254
- const replaceParams = (0, import_react37.useCallback)((params2) => {
2284
+ const replaceParams = (0, import_react38.useCallback)((params2) => {
2255
2285
  replaceSearchParams(router, params2);
2256
2286
  }, [router]);
2257
- const replaceParamsSilently = (0, import_react37.useCallback)((params2) => {
2287
+ const replaceParamsSilently = (0, import_react38.useCallback)((params2) => {
2258
2288
  replaceSearchParamsSilently(router, params2);
2259
2289
  }, [router]);
2260
2290
  return { params, pushParams, pushParamsSilently, replaceParams, replaceParamsSilently };
@@ -2263,7 +2293,7 @@ function useSearchParamsValue(key) {
2263
2293
  // src/useSearchParamsEncoded/useSearchParamsEncoded.ts
2264
2294
  var import_bom_core11 = require("@websolutespa/bom-core");
2265
2295
  var import_router4 = require("next/router");
2266
- var import_react38 = require("react");
2296
+ var import_react39 = require("react");
2267
2297
  var USE_ENCRYPTION = true;
2268
2298
  function stringToURLSearchParams(url) {
2269
2299
  return new URLSearchParams(url);
@@ -2355,16 +2385,16 @@ function replaceSearchParamsEncodedSilently(router, value, key) {
2355
2385
  function useSearchParamsEncoded(key) {
2356
2386
  const router = (0, import_router4.useRouter)();
2357
2387
  const params = getSearchParamsEncoded(router.asPath, key);
2358
- const pushParams = (0, import_react38.useCallback)((params2) => {
2388
+ const pushParams = (0, import_react39.useCallback)((params2) => {
2359
2389
  pushSearchParamsEncoded(router, params2, key);
2360
2390
  }, [key, router]);
2361
- const pushParamsSilently = (0, import_react38.useCallback)((params2) => {
2391
+ const pushParamsSilently = (0, import_react39.useCallback)((params2) => {
2362
2392
  pushSearchParamsEncodedSilently(router, params2, key);
2363
2393
  }, [key, router]);
2364
- const replaceParams = (0, import_react38.useCallback)((params2) => {
2394
+ const replaceParams = (0, import_react39.useCallback)((params2) => {
2365
2395
  replaceSearchParamsEncoded(router, params2, key);
2366
2396
  }, [key, router]);
2367
- const replaceParamsSilently = (0, import_react38.useCallback)((params2) => {
2397
+ const replaceParamsSilently = (0, import_react39.useCallback)((params2) => {
2368
2398
  replaceSearchParamsEncodedSilently(router, params2, key);
2369
2399
  }, [key, router]);
2370
2400
  return { params, pushParams, pushParamsSilently, replaceParams, replaceParamsSilently };
@@ -2373,7 +2403,7 @@ function useSearchParamsEncoded(key) {
2373
2403
  // src/useSearchParamsQs/useSearchParamsQs.ts
2374
2404
  var import_bom_core12 = require("@websolutespa/bom-core");
2375
2405
  var import_router5 = require("next/router");
2376
- var import_react39 = require("react");
2406
+ var import_react40 = require("react");
2377
2407
  function deserialize(encoded, key) {
2378
2408
  let decoded = {};
2379
2409
  if (encoded) {
@@ -2435,28 +2465,28 @@ function replaceSearchParamsQsSilently(router, value, key) {
2435
2465
  function useSearchParamsQs(key) {
2436
2466
  const router = (0, import_router5.useRouter)();
2437
2467
  const params = getSearchParamsQs(router.asPath, key);
2438
- const pushParams = (0, import_react39.useCallback)((params2) => {
2468
+ const pushParams = (0, import_react40.useCallback)((params2) => {
2439
2469
  pushSearchParamsQs(router, params2, key);
2440
2470
  }, [key, router]);
2441
- const pushParamsSilently = (0, import_react39.useCallback)((params2) => {
2471
+ const pushParamsSilently = (0, import_react40.useCallback)((params2) => {
2442
2472
  pushSearchParamsQsSilently(router, params2, key);
2443
2473
  }, [key, router]);
2444
- const replaceParams = (0, import_react39.useCallback)((params2) => {
2474
+ const replaceParams = (0, import_react40.useCallback)((params2) => {
2445
2475
  replaceSearchParamsQs(router, params2, key);
2446
2476
  }, [key, router]);
2447
- const replaceParamsSilently = (0, import_react39.useCallback)((params2) => {
2477
+ const replaceParamsSilently = (0, import_react40.useCallback)((params2) => {
2448
2478
  replaceSearchParamsQsSilently(router, params2, key);
2449
2479
  }, [key, router]);
2450
2480
  return { params, pushParamsSilently, pushParams, replaceParamsSilently, replaceParams };
2451
2481
  }
2452
2482
 
2453
2483
  // src/useSorting/useSorting.ts
2454
- var import_react40 = require("react");
2484
+ var import_react41 = require("react");
2455
2485
  function useSorting(items_, callback_, sort_) {
2456
- const [sort, setSort] = (0, import_react40.useState)(sort_);
2457
- const [items, setItems] = (0, import_react40.useState)(callback_(items_.slice(), sort));
2458
- const isInitialMount = (0, import_react40.useRef)(true);
2459
- (0, import_react40.useEffect)(() => {
2486
+ const [sort, setSort] = (0, import_react41.useState)(sort_);
2487
+ const [items, setItems] = (0, import_react41.useState)(callback_(items_.slice(), sort));
2488
+ const isInitialMount = (0, import_react41.useRef)(true);
2489
+ (0, import_react41.useEffect)(() => {
2460
2490
  if (isInitialMount.current) {
2461
2491
  isInitialMount.current = false;
2462
2492
  } else {
@@ -2472,11 +2502,11 @@ function useSorting(items_, callback_, sort_) {
2472
2502
  }
2473
2503
 
2474
2504
  // src/useSyncedRef/useSyncedRef.ts
2475
- var import_react41 = require("react");
2505
+ var import_react42 = require("react");
2476
2506
  function useSyncedRef(value) {
2477
- const ref = (0, import_react41.useRef)(value);
2507
+ const ref = (0, import_react42.useRef)(value);
2478
2508
  ref.current = value;
2479
- return (0, import_react41.useMemo)(() => Object.freeze({
2509
+ return (0, import_react42.useMemo)(() => Object.freeze({
2480
2510
  get current() {
2481
2511
  return ref.current;
2482
2512
  }
@@ -2489,10 +2519,10 @@ function useUnit(unit = "kilometer", locale) {
2489
2519
  }
2490
2520
 
2491
2521
  // src/useUnmountEffect/useUnmountEffect.ts
2492
- var import_react42 = require("react");
2522
+ var import_react43 = require("react");
2493
2523
  function useUnmountEffect(effect) {
2494
2524
  const effectRef = useSyncedRef(effect);
2495
- (0, import_react42.useEffect)(() => () => {
2525
+ (0, import_react43.useEffect)(() => () => {
2496
2526
  effectRef.current();
2497
2527
  }, []);
2498
2528
  }
@@ -2618,6 +2648,7 @@ function useUnmountEffect(effect) {
2618
2648
  useResize,
2619
2649
  useSSR,
2620
2650
  useScroll,
2651
+ useScrollDirection,
2621
2652
  useScrollTo,
2622
2653
  useScrolled,
2623
2654
  useSearchParams,
package/dist/index.mjs CHANGED
@@ -1962,13 +1962,42 @@ function useScroll() {
1962
1962
  return scroll;
1963
1963
  }
1964
1964
 
1965
- // src/useScrolled/useScrolled.ts
1965
+ // src/useScrollDirection/useScrollDirection.ts
1966
1966
  import { useState as useState22 } from "react";
1967
+ var lastScrollTop = 0;
1967
1968
  var DEFAULT_CALLBACK = (top, left) => {
1969
+ const scrollTop = window.scrollY || document.documentElement.scrollTop;
1970
+ let direction = 0;
1971
+ if (scrollTop > lastScrollTop) {
1972
+ direction = 1;
1973
+ } else if (scrollTop < lastScrollTop) {
1974
+ direction = -1;
1975
+ }
1976
+ lastScrollTop = scrollTop <= 0 ? 0 : scrollTop;
1977
+ return direction;
1978
+ };
1979
+ function useScrollDirection(callback = DEFAULT_CALLBACK) {
1980
+ const [direction, setDirection] = useState22(0);
1981
+ const onScrolled = () => {
1982
+ const direction_ = callback(window.scrollY, window.scrollX);
1983
+ if (direction !== direction_) {
1984
+ setDirection(direction_);
1985
+ }
1986
+ };
1987
+ useEventListener("scroll", onScrolled);
1988
+ useIsomorphicLayoutEffect(() => {
1989
+ onScrolled();
1990
+ }, []);
1991
+ return direction;
1992
+ }
1993
+
1994
+ // src/useScrolled/useScrolled.ts
1995
+ import { useState as useState23 } from "react";
1996
+ var DEFAULT_CALLBACK2 = (top, left) => {
1968
1997
  return top > 0;
1969
1998
  };
1970
- function useScrolled(callback = DEFAULT_CALLBACK) {
1971
- const [scrolled, setScrolled] = useState22(false);
1999
+ function useScrolled(callback = DEFAULT_CALLBACK2) {
2000
+ const [scrolled, setScrolled] = useState23(false);
1972
2001
  const onScrolled = () => {
1973
2002
  const scrolled_ = callback(window.scrollY, window.scrollX);
1974
2003
  if (scrolled !== scrolled_) {
@@ -2297,10 +2326,10 @@ function useSearchParamsQs(key) {
2297
2326
  }
2298
2327
 
2299
2328
  // src/useSorting/useSorting.ts
2300
- import { useEffect as useEffect26, useRef as useRef10, useState as useState23 } from "react";
2329
+ import { useEffect as useEffect26, useRef as useRef10, useState as useState24 } from "react";
2301
2330
  function useSorting(items_, callback_, sort_) {
2302
- const [sort, setSort] = useState23(sort_);
2303
- const [items, setItems] = useState23(callback_(items_.slice(), sort));
2331
+ const [sort, setSort] = useState24(sort_);
2332
+ const [items, setItems] = useState24(callback_(items_.slice(), sort));
2304
2333
  const isInitialMount = useRef10(true);
2305
2334
  useEffect26(() => {
2306
2335
  if (isInitialMount.current) {
@@ -2463,6 +2492,7 @@ export {
2463
2492
  useResize,
2464
2493
  useSSR,
2465
2494
  useScroll,
2495
+ useScrollDirection,
2466
2496
  useScrollTo,
2467
2497
  useScrolled,
2468
2498
  useSearchParams,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@websolutespa/bom-mixer-hooks",
3
- "version": "1.9.1",
3
+ "version": "1.9.2",
4
4
  "description": "Mixer Hooks module of the BOM Repository",
5
5
  "keywords": [
6
6
  "bom",
package/src/index.ts CHANGED
@@ -50,6 +50,7 @@ export * from './useReducedMotion/useReducedMotion';
50
50
  export * from './useReducedMotion/useReducedMotionLocal';
51
51
  export * from './useResize/useResize';
52
52
  export * from './useScroll/useScroll';
53
+ export * from './useScrollDirection/useScrollDirection';
53
54
  export * from './useScrolled/useScrolled';
54
55
  export * from './useScrollTo/useScrollTo';
55
56
  export * from './useSearchParams/useSearchParams';
@@ -0,0 +1,37 @@
1
+ import { useEventListener, useIsomorphicLayoutEffect } from '@websolutespa/bom-mixer-hooks';
2
+ import { useState } from 'react';
3
+
4
+ let lastScrollTop: number = 0;
5
+
6
+ const DEFAULT_CALLBACK = (top: number, left: number) => {
7
+ const scrollTop = window.scrollY || document.documentElement.scrollTop;
8
+ let direction = 0;
9
+ if (scrollTop > lastScrollTop) {
10
+ direction = 1;
11
+ } else if (scrollTop < lastScrollTop) {
12
+ direction = -1;
13
+ }
14
+ lastScrollTop = scrollTop <= 0 ? 0 : scrollTop;
15
+ return direction;
16
+ };
17
+
18
+ export function useScrollDirection(callback: (top: number, left: number) => number = DEFAULT_CALLBACK): number {
19
+ const [direction, setDirection] = useState<number>(0);
20
+
21
+ const onScrolled = () => {
22
+ const direction_ = callback(window.scrollY, window.scrollX);
23
+ if (direction !== direction_) {
24
+ setDirection(direction_);
25
+ }
26
+ };
27
+
28
+ useEventListener('scroll', onScrolled);
29
+
30
+ // Set size at the first client-side load
31
+ useIsomorphicLayoutEffect(() => {
32
+ onScrolled();
33
+ // eslint-disable-next-line react-hooks/exhaustive-deps
34
+ }, []);
35
+
36
+ return direction;
37
+ }