From df1362f1a6c017d42ef3e77d0d4bd76e5a1ea0f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mois=C3=A9s=20Machuca=20Valverde?= Date: Tue, 12 Dec 2023 23:12:10 -0500 Subject: [PATCH] feat: update useEventListener Options (#81) Move the target parameter to the bind options and set default to window in useEventListener hook --- .changeset/five-rocks-bow.md | 6 +++++ .changeset/gentle-terms-mate.md | 5 ++++ .../hooks/use-event-listener/src/index.ts | 9 +++---- .../use-event-listener/tests/index.test.ts | 12 ++++----- .../hooks/use-scroll-position/src/index.ts | 11 ++++---- ...-scroll-position.test.ts => index.test.ts} | 26 +++++-------------- packages/hooks/use-window-size/src/index.ts | 4 +-- 7 files changed, 33 insertions(+), 40 deletions(-) create mode 100644 .changeset/five-rocks-bow.md create mode 100644 .changeset/gentle-terms-mate.md rename packages/hooks/use-scroll-position/tests/{use-scroll-position.test.ts => index.test.ts} (65%) diff --git a/.changeset/five-rocks-bow.md b/.changeset/five-rocks-bow.md new file mode 100644 index 0000000..577a558 --- /dev/null +++ b/.changeset/five-rocks-bow.md @@ -0,0 +1,6 @@ +--- +'@raddix/use-scroll-position': minor +'@raddix/use-window-size': minor +--- + +update the useEventListener hook with the new options diff --git a/.changeset/gentle-terms-mate.md b/.changeset/gentle-terms-mate.md new file mode 100644 index 0000000..49ebeea --- /dev/null +++ b/.changeset/gentle-terms-mate.md @@ -0,0 +1,5 @@ +--- +'@raddix/use-event-listener': major +--- + +Move the target parameter to the bind options and set default to window diff --git a/packages/hooks/use-event-listener/src/index.ts b/packages/hooks/use-event-listener/src/index.ts index 3ca78f8..c53513a 100644 --- a/packages/hooks/use-event-listener/src/index.ts +++ b/packages/hooks/use-event-listener/src/index.ts @@ -1,13 +1,13 @@ import { type RefObject, useEffect, useRef } from 'react'; -export const _window = typeof window !== 'undefined' ? window : null; -export const _document = typeof document !== 'undefined' ? document : null; +interface Options extends AddEventListenerOptions { + target?: RefObject | EventTarget; +} export const useEventListener = ( - target: RefObject | EventTarget | null, eventType: T, callback: (event: HTMLElementEventMap[T]) => void, - options?: boolean | AddEventListenerOptions + { target = globalThis, ...options }: Options = {} ): void => { const savedCallback = useRef(callback); @@ -16,7 +16,6 @@ export const useEventListener = ( }, [callback]); useEffect(() => { - if (target === null) return; const targetElement = 'current' in target ? target.current : target; if (!targetElement?.addEventListener) return; diff --git a/packages/hooks/use-event-listener/tests/index.test.ts b/packages/hooks/use-event-listener/tests/index.test.ts index 828ccfe..ef2b073 100644 --- a/packages/hooks/use-event-listener/tests/index.test.ts +++ b/packages/hooks/use-event-listener/tests/index.test.ts @@ -14,11 +14,9 @@ describe('useEventListener test:', () => { jest.clearAllMocks(); }); - it('should add event listener in document', () => { + it('should add event listener in window', () => { const callback = jest.fn(); - const { unmount } = renderHook(() => - useEventListener(document, 'click', callback) - ); + const { unmount } = renderHook(() => useEventListener('click', callback)); expect(callback).not.toHaveBeenCalled(); @@ -40,7 +38,7 @@ describe('useEventListener test:', () => { it('should add event listener in element', () => { const callback = jest.fn(); const { unmount } = renderHook(() => - useEventListener(container, 'click', callback) + useEventListener('click', callback, { target: container }) ); expect(callback).not.toHaveBeenCalled(); @@ -63,7 +61,7 @@ describe('useEventListener test:', () => { it('should add event listener to ref', () => { const callback = jest.fn(); const ref = { current: container }; - renderHook(() => useEventListener(ref, 'click', callback)); + renderHook(() => useEventListener('click', callback, { target: ref })); act(() => { document.body.click(); @@ -81,7 +79,7 @@ describe('useEventListener test:', () => { it('should not add event listener if the target does not have addEventListener', () => { const callback = jest.fn(); const ref = { current: null }; - renderHook(() => useEventListener(ref, 'click', callback)); + renderHook(() => useEventListener('click', callback, { target: ref })); act(() => { document.body.click(); diff --git a/packages/hooks/use-scroll-position/src/index.ts b/packages/hooks/use-scroll-position/src/index.ts index aed9439..e8a8928 100644 --- a/packages/hooks/use-scroll-position/src/index.ts +++ b/packages/hooks/use-scroll-position/src/index.ts @@ -1,5 +1,5 @@ import { type RefObject, useEffect, useState } from 'react'; -import { useEventListener, _document } from '@raddix/use-event-listener'; +import { useEventListener } from '@raddix/use-event-listener'; export interface ScrollPosition { x: number | null; @@ -7,11 +7,11 @@ export interface ScrollPosition { } export interface Options { - target?: RefObject | Document | null; + target?: RefObject | Document; } -export const useScroll = ({ - target = _document +export const useScrollPosition = ({ + target = globalThis.document }: Options = {}): ScrollPosition => { const [scrollPosition, setScrollPosition] = useState({ x: 0, @@ -19,7 +19,6 @@ export const useScroll = ({ }); const handle = () => { - if (!target) return; const targetElement = target instanceof Document ? document.documentElement : target.current; @@ -34,7 +33,7 @@ export const useScroll = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - useEventListener(target, 'scroll', handle, { passive: true }); + useEventListener('scroll', handle, { target, passive: true }); return scrollPosition; }; diff --git a/packages/hooks/use-scroll-position/tests/use-scroll-position.test.ts b/packages/hooks/use-scroll-position/tests/index.test.ts similarity index 65% rename from packages/hooks/use-scroll-position/tests/use-scroll-position.test.ts rename to packages/hooks/use-scroll-position/tests/index.test.ts index af66408..8ca1d7a 100644 --- a/packages/hooks/use-scroll-position/tests/use-scroll-position.test.ts +++ b/packages/hooks/use-scroll-position/tests/index.test.ts @@ -1,7 +1,7 @@ import { renderHook, act } from '@testing-library/react'; -import { useScroll } from '../src'; +import { useScrollPosition } from '../src'; -describe('useScroll test:', () => { +describe('useScrollPosition test:', () => { let container: HTMLDivElement; beforeEach(() => { @@ -15,14 +15,14 @@ describe('useScroll test:', () => { }); it('should initialize scroll position to (0, 0)', () => { - const { result } = renderHook(() => useScroll()); + const { result } = renderHook(() => useScrollPosition()); expect(result.current).toEqual({ x: 0, y: 0 }); }); it('should update scroll position on scroll event', () => { const { result } = renderHook(() => - useScroll({ target: { current: container } }) + useScrollPosition({ target: { current: container } }) ); expect(result.current).toEqual({ x: 0, y: 0 }); @@ -37,7 +37,7 @@ describe('useScroll test:', () => { }); it('should update scroll position on document scroll event', () => { - const { result } = renderHook(() => useScroll()); + const { result } = renderHook(() => useScrollPosition()); expect(result.current).toEqual({ x: 0, y: 0 }); @@ -50,23 +50,9 @@ describe('useScroll test:', () => { expect(result.current).toEqual({ x: 50, y: 100 }); }); - it('should not update scroll position if target is null', () => { - const { result } = renderHook(() => useScroll({ target: null })); - - expect(result.current).toEqual({ x: 0, y: 0 }); - - act(() => { - document.documentElement.scrollTop = 100; - document.documentElement.scrollLeft = 50; - document.dispatchEvent(new Event('scroll')); - }); - - expect(result.current).toEqual({ x: 0, y: 0 }); - }); - it('should not update the scroll position if the element does not exist', () => { const { result } = renderHook(() => - useScroll({ target: { current: null } }) + useScrollPosition({ target: { current: null } }) ); expect(result.current).toEqual({ x: null, y: null }); diff --git a/packages/hooks/use-window-size/src/index.ts b/packages/hooks/use-window-size/src/index.ts index e7ff60e..4128253 100644 --- a/packages/hooks/use-window-size/src/index.ts +++ b/packages/hooks/use-window-size/src/index.ts @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import { useEventListener, _window } from '@raddix/use-event-listener'; +import { useEventListener } from '@raddix/use-event-listener'; interface Size { width: number; @@ -23,7 +23,7 @@ export const useWindowSize = (): Size => { handleResize(); }, []); - useEventListener(_window, 'resize', handleResize); + useEventListener('resize', handleResize); return windowSize; };