Skip to content

Commit

Permalink
Merge pull request #26 from Ashish-simpleCoder/feature/develop-hooks
Browse files Browse the repository at this point in the history
Add refs support in use-event-listener target params
  • Loading branch information
Ashish-simpleCoder authored Apr 17, 2024
2 parents 31105bb + 7e65ed2 commit 41fa3f0
Show file tree
Hide file tree
Showing 13 changed files with 50 additions and 15 deletions.
7 changes: 7 additions & 0 deletions .changeset/tiny-tables-switch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'classic-react-hooks': minor
---

- Add refs support in use-event-listener
- Update doc for use-event-listener
- Add new test case for testing refs in use-event-listener
2 changes: 1 addition & 1 deletion apps/doc/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default defineConfig({
},
{
text: 'API',
link: '/hooks/use-synced-ref',
link: '/getting-started/overview',
},
{
text: `v${version}`,
Expand Down
11 changes: 4 additions & 7 deletions apps/doc/hooks/use-event-listener.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,14 @@ type Handler = (event: Event) => void
### Usage
```ts
import { useRef } from 'react'
import { useEventListener } from 'classic-react-hooks'

export default function YourComponent() {
const ref = useRef()
useEventListener(
() => ref.current,
'click',
(e) => {
console.log(e)
}
)
useEventListener(ref, 'click', (e) => {
console.log(e)
})

return (
<div>
Expand Down
Binary file added apps/doc/public/android-chrome-192x192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/doc/public/android-chrome-512x512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/doc/public/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/doc/public/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/doc/public/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/doc/public/favicon.ico
Binary file not shown.
Binary file removed apps/doc/public/logo.ico
Binary file not shown.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"access": "public",
"provenance": true
},
"homepage": "https://github.com/Ashish-simpleCoder/classic-react-hooks",
"homepage": "https://classic-react-hooks.vercel.app",
"author": "Ashish-simpleCoder",
"license": "MIT",
"private": false,
Expand Down
25 changes: 24 additions & 1 deletion src/lib/use-event-listener/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { renderHook } from '@testing-library/react'
import { vi } from 'vitest'
import { useEventListener } from '.'

describe('use-outside-click', () => {
describe('use-event-listener', () => {
it('should render', () => {
renderHook(() => useEventListener(null, 'click', () => {}))
})
Expand Down Expand Up @@ -33,6 +33,29 @@ describe('use-outside-click', () => {
expect(removeSpy).toHaveBeenCalledTimes(2)
})

it('should work with refs', () => {
const div = document.createElement('div')
const addSpy = vi.spyOn(div, 'addEventListener')
const removeSpy = vi.spyOn(div, 'removeEventListener')

const ref = { current: div }

const { rerender, unmount } = renderHook(() => {
useEventListener(ref, 'resize', () => {}, { passive: true })
})

expect(addSpy).toHaveBeenCalledTimes(1)
expect(removeSpy).toHaveBeenCalledTimes(0)

rerender()
expect(addSpy).toHaveBeenCalledTimes(1)
expect(removeSpy).toHaveBeenCalledTimes(0)

unmount()
expect(addSpy).toHaveBeenCalledTimes(1)
expect(removeSpy).toHaveBeenCalledTimes(1)
})

it('should fire listener on event trigger with proper context', () => {
const div = document.createElement('div')
const listener = vi.fn()
Expand Down
18 changes: 13 additions & 5 deletions src/lib/use-event-listener/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect } from 'react'
import React, { RefObject, useEffect } from 'react'
import useSyncedRef from '../use-synced-ref'

type Target = null | EventTarget | (() => EventTarget | null)
type Target = null | EventTarget | RefObject<EventTarget> | (() => EventTarget | null)
type Options = boolean | AddEventListenerOptions
type Handler = (event: Event) => void

Expand All @@ -18,7 +18,7 @@ type Handler = (event: Event) => void
export default function YourComponent() {
const ref = useRef()
useEventListener(() => ref.current, 'click', (e) =>{
useEventListener(ref, 'click', (e) =>{
console.log(e)
})
Expand Down Expand Up @@ -71,11 +71,19 @@ export function useEventListener(
const options = listener.current.options

if (shouldInjectEvent) {
node.addEventListener(event, callback, options)
if ('current' in node) {
node.current?.addEventListener(event, callback, options)
} else {
node.addEventListener(event, callback, options)
}
}

return () => {
node.removeEventListener(event, callback, options)
if ('current' in node) {
node.current?.removeEventListener(event, callback, options)
} else {
node.removeEventListener(event, callback, options)
}
}
}, [event, target, shouldInjectEvent])
}

0 comments on commit 41fa3f0

Please sign in to comment.