Skip to content

Commit

Permalink
Merge pull request #30 from Ashish-simpleCoder/feature/develop-hooks
Browse files Browse the repository at this point in the history
Update docs and fix logic issues
  • Loading branch information
Ashish-simpleCoder authored Apr 22, 2024
2 parents 24713cd + 34866b5 commit ac5cc67
Show file tree
Hide file tree
Showing 18 changed files with 134 additions and 43 deletions.
3 changes: 2 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ dist
coverage
node_modules
public
apps/doc/.vitepress/cache
apps/doc/.vitepress/cache
.changeset
10 changes: 0 additions & 10 deletions .size-limit.json

This file was deleted.

48 changes: 48 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Contributing Guide

Hi! We are really excited that you are interested in contributing to classic-react-hooks. Before submitting your contribution, please make sure to take a moment and read through the following guide:

## Repo Setup

The package manager used to install and link dependencies must be [pnpm](https://pnpm.io/). NodeJS version should be v18.14.2 or higher

1. Run `pnpm install` in root folder

2. Run `pnpm run build` to build the package

3. Run `pnpm run test` to run the test cases

4. Run `pnpm run format` to format all of the coding with prettier

## Pull Request Guidelines

- Checkout a topic branch from a base branch, e.g. `main`, and merge back against that branch.

- If adding a new feature:

- Add accompanying test case.
- Provide a convincing reason to add this feature. Ideally, you should open a suggestion issue first and have it approved before working on it.

- If fixing bug:

- If you are resolving a special issue, add `(fix #xxxx[,#xxxx])` (#xxxx is the issue id) in your PR title for a better release log, e.g. `fix: update entities encoding/decoding (fix #3899)`.
- Provide a detailed description of the bug in the PR. Live demo preferred.
- Add appropriate test coverage if applicable.

- It's OK to have multiple small commits as you work on the PR - GitHub can automatically squash them before merging.

- Make sure tests pass!

- Use `pnpm format` to format files according to the project guidelines.

## Documenation Guidelines

- To make contribute in the documentation, go to apps/doc directory

1. Run `pnpm install` to install all of the dependencies

2. Run `pnpm docs:dev` for development of doc

3. Run `pnpm docs:build` for building the prodution version of doc

4. Run `pnpm docs:preview` to see the preview of doc
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 🚀 classic-react-hooks

#### A simple and minimal library of `custom react hooks`.
#### A simple and awesome collection of `custom react hooks`.

<br />

Expand Down Expand Up @@ -63,3 +63,7 @@ $ yarn add classic-react-hooks
- use-synced-effect
- use-on-mount-effect
- use-counter

## Contribution

See [Contributing Guide](https://github.com/Ashish-simpleCoder/classic-react-hooks/blob/main/CONTRIBUTING.md).
2 changes: 1 addition & 1 deletion apps/doc/hooks/use-debounced-fn.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ outline: deep

### Returns

- It returns a function which debouced version of passed cb.
- It returns a function which is debouced version of passed callback.

### Usage

Expand Down
2 changes: 1 addition & 1 deletion apps/doc/hooks/use-interval-effect.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ outline: deep

# use-interval-effect

- A hooks which fires the provided callback every time when the given delay is passed, just like the setInterval.
- A hooks which fires the provided callback every time when the given delay is passed, just like the `setInterval`.

### Parameters

Expand Down
10 changes: 5 additions & 5 deletions apps/doc/hooks/use-local-storage.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ outline: deep

- A hook for managing the states with `local-storage`
- It automatically updates the state in `local-storage`
- `useState` with local storage power.
- It is `useState` with local storage power.

### Parameters

| Parameter | Type | Required | Default Value | Description |
| ------------ | :----: | :------: | :-----------: | ------------------------------------------------------ |
| key | string || - | key for getting from local-storage |
| defaultValue | any || - | A initial value when item is not present local-storage |
| Parameter | Type | Required | Default Value | Description |
| ------------ | :----: | :------: | :-----------: | ---------------------------------------------------- |
| key | string || - | key for getting an item from local-storage |
| defaultValue | any || - | A initial value when item is not found local-storage |

### Returns

Expand Down
2 changes: 1 addition & 1 deletion apps/doc/hooks/use-on-mount-effect.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ outline: deep

| Parameter | Type | Required | Default Value | Description |
| --------- | :------: | :------: | :-----------: | ------------------------------------- |
| cb | Function || - | Function to fire after initial mount. |
| cb | Function || - | Callback to fire after initial mount. |

### Usage

Expand Down
10 changes: 3 additions & 7 deletions apps/doc/hooks/use-outside-click.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,9 @@ import { useOutsideClick } from 'classic-react-hooks'

export default function YourComponent() {
const modalRef = useRef(null)
useOutsideClick(
() => modalRef.current,
(e) => {
console.log('clicked outside on modal. Target = ', e.target)
},
true
)
useOutsideClick(modalRef, (e) => {
console.log('clicked outside on modal. Target = ', e.target)
})

return (
<div>
Expand Down
2 changes: 1 addition & 1 deletion apps/doc/hooks/use-synced-effect.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ outline: deep

| Parameter | Type | Required | Default Value | Description |
| --------- | :------: | :------: | :-----------: | ----------------------------------------------- |
| cb | Function || - | Function to fire when dependencies get changed. |
| cb | Function || - | Callback to fire when dependencies get changed. |
| deps | Array || [] | Dependencies. |

### Usage
Expand Down
2 changes: 1 addition & 1 deletion apps/doc/hooks/use-timeout-effect.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ outline: deep

# use-timeout-effect

- A hooks which fires the provided callback only once when the given delay is passed, just like the setTimeout.
- A hooks which fires the provided callback only once when the given delay is passed, just like the `setTimeout`.

### Parameters

Expand Down
12 changes: 11 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,15 @@
"tabWidth": 3,
"jsxSingleQuote": true,
"trailingComma": "es5"
}
},
"size-limit": [
{
"path": "dist/index.mjs",
"limit": "10 KB"
},
{
"path": "dist/index.js",
"limit": "10 KB"
}
]
}
22 changes: 22 additions & 0 deletions src/lib/use-outside-click/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,28 @@ describe('use-outside-click', () => {
expect(addSpy).toHaveBeenCalledTimes(1)
expect(removeSpy).toHaveBeenCalledTimes(1)
})
it('should work with refs', () => {
const div = document.createElement('div')
const addSpy = vi.spyOn(document, 'addEventListener')
const removeSpy = vi.spyOn(document, 'removeEventListener')

const ref = { current: div }

const { rerender, unmount } = renderHook(() => {
useOutsideClick(ref, () => {})
})

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 when clicked outside of target element', () => {
const div = document.createElement('div')
Expand Down
12 changes: 8 additions & 4 deletions src/lib/use-outside-click/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
'use client'
import React, { useCallback } from 'react'
import React, { RefObject, useCallback } from 'react'
import { useEventListener } from '../use-event-listener'
import useSyncedRef from '../use-synced-ref'

type Target = null | EventTarget | (() => EventTarget | null)
type Target = null | EventTarget | RefObject<EventTarget> | (() => EventTarget | null)

/**
* @description
Expand Down Expand Up @@ -41,9 +41,13 @@ export default function useOutsideClick(

const eventCb = useCallback((event: DocumentEventMap['click']) => {
const node = (typeof target == 'function' ? target() : target) ?? document
if (event.target == node) return
if (event.target == node || ('current' in node && event.target == node.current)) return

if (node && (node as Node).contains(event.target as Node)) {
if (
node &&
((node as Node).contains(event.target as Node) ||
('current' in node && (node.current as Node).contains(event.target as Node)))
) {
return
}
paramsRef.current.handler(event)
Expand Down
17 changes: 12 additions & 5 deletions src/lib/use-synced-effect/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import { vi } from 'vitest'
import useSyncedEffect from '.'

describe('use-on-mount-effect', () => {
beforeEach(() => {
vi.useFakeTimers()
})

it('should not run callback on initial the mount', () => {
const fn = vi.fn()
renderHook(() => useSyncedEffect(fn, []))
Expand All @@ -18,15 +22,17 @@ describe('use-on-mount-effect', () => {
const fn = vi.fn()
let skill = 'js'

const { rerender } = renderHook((props: Array<any>) => useSyncedEffect(fn, props ?? [skill]))
const { rerender } = renderHook(() => useSyncedEffect(fn, [skill]))
expect(fn).toHaveBeenCalledTimes(0)

vi.runAllTimers()

skill = 'react'
rerender([skill])
rerender()
expect(fn).toHaveBeenCalledTimes(1)

skill = 'typescript'
rerender([skill])
rerender()
expect(fn).toHaveBeenCalledTimes(2)
})

Expand All @@ -35,10 +41,11 @@ describe('use-on-mount-effect', () => {
const fn = vi.fn(() => cleanupFn)
let skill = 'js'

const { rerender, unmount } = renderHook((props: Array<any>) => useSyncedEffect(fn, props ?? [skill]))
const { rerender, unmount } = renderHook(() => useSyncedEffect(fn, [skill]))
vi.runAllTimers()

skill = 'react'
rerender([skill])
rerender()
expect(fn).toHaveBeenCalledTimes(1)

unmount()
Expand Down
13 changes: 11 additions & 2 deletions src/lib/use-synced-effect/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,20 @@ export default function useSyncedEffect(cb: EffectCallback, deps?: DependencyLis
const cleanup = useRef<void | (() => void)>()

useEffect(() => {
let timeoutId: NodeJS.Timeout
if (isInitialLoad.current) {
isInitialLoad.current = false
// handling React.StrictMode double time firing
timeoutId = setTimeout(() => {
isInitialLoad.current = false
})
} else {
cleanup.current = cb()
}
return cleanup.current
return () => {
if (timeoutId) {
clearTimeout(timeoutId)
}
cleanup.current?.()
}
}, deps ?? DEP)
}
2 changes: 1 addition & 1 deletion src/lib/use-timeout-effect/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe('use-timeout-effect', () => {
renderHook(() => useTimoeoutEffect(fn))

expect(fn).toHaveBeenCalledTimes(0)
vi.advanceTimersByTime(0)
vi.advanceTimersByTime(100)
expect(fn).toHaveBeenCalledTimes(1)
})

Expand Down
2 changes: 1 addition & 1 deletion src/lib/use-timeout-effect/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import useSyncedRef from '../use-synced-ref'
)
}
*/
export default function useTimeoutEffect(cb: () => void, timeout = 0) {
export default function useTimeoutEffect(cb: () => void, timeout = 100) {
let paramsRef = useSyncedRef({
cb,
timeout,
Expand Down

0 comments on commit ac5cc67

Please sign in to comment.