-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: new Hook
useReFocus
to run a callback when re-focus
- Loading branch information
Showing
4 changed files
with
195 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { Card } from '@/components' | ||
import { useReFocus } from '@shined/react-use' | ||
import { Toaster, toast } from 'react-hot-toast' | ||
|
||
export function App() { | ||
useReFocus( | ||
() => { | ||
toast.success('Refocused') | ||
}, | ||
{ wait: 6000 }, | ||
) | ||
|
||
return ( | ||
<Card> | ||
<div>This component will show a toast when the user refocuses on the window.</div> | ||
<Toaster /> | ||
</Card> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# useReFocus | ||
|
||
import { HooksType, NotReleased } from '@/components' | ||
|
||
<HooksType category="Utilities" lowLevel /> | ||
|
||
<NotReleased /> | ||
|
||
A React Hook that helps to run a function when the page is refocused. | ||
|
||
## Demo | ||
|
||
import { App } from './demo' | ||
|
||
<App /> | ||
|
||
## Usage | ||
|
||
import { RawCode } from '@/components' | ||
import source from '!!raw-loader!./demo' | ||
|
||
<RawCode>{source}</RawCode> | ||
|
||
## Source | ||
|
||
import { Source } from '@/components' | ||
|
||
<Source /> | ||
|
||
## API | ||
|
||
```tsx | ||
useReFocus(fn, options): void | ||
``` | ||
|
||
### Fn | ||
|
||
A function that will be called when the page is refocused. | ||
|
||
### Options | ||
|
||
```tsx | ||
interface UseReFocusOptions extends UseThrottledFnOptions { | ||
/** | ||
* Register focus event listener. | ||
*/ | ||
registerReFocus?: (callback: AnyFunc) => void | ||
} | ||
``` | ||
|
||
See [useThrottledFn](/reference/use-throttled-fn) for more information. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import { useEffectOnce } from '../use-effect-once' | ||
import { useLatest } from '../use-latest' | ||
import { useThrottledFn } from '../use-throttled-fn' | ||
|
||
import type { UseThrottledFnOptions } from '../use-throttled-fn' | ||
import type { AnyFunc } from '../utils/basic' | ||
|
||
interface UseReFocusOptions extends UseThrottledFnOptions { | ||
/** | ||
* Register focus event listener. | ||
*/ | ||
registerReFocus?: (callback: AnyFunc) => void | ||
} | ||
|
||
export function registerWebReFocus(callback: AnyFunc) { | ||
const focusState = { current: false } | ||
|
||
function handleFocus() { | ||
const nextState = true | ||
|
||
if (!focusState.current) { | ||
callback() | ||
focusState.current = nextState | ||
} | ||
} | ||
|
||
function handleBlur() { | ||
const nextState = false | ||
focusState.current = nextState | ||
} | ||
|
||
window.addEventListener('focus', handleFocus, { passive: true }) | ||
window.addEventListener('blur', handleBlur, { passive: true }) | ||
|
||
return () => { | ||
window.removeEventListener('focus', handleFocus) | ||
window.removeEventListener('blur', handleBlur) | ||
} | ||
} | ||
|
||
export function useReFocus(callback: AnyFunc, options: UseReFocusOptions = {}) { | ||
const { registerReFocus = registerWebReFocus, ...throttleOptions } = options | ||
|
||
const throttledFn = useThrottledFn(callback, { | ||
leading: true, | ||
trailing: false, | ||
...throttleOptions, | ||
}) | ||
|
||
const latest = useLatest({ throttledFn }) | ||
|
||
useEffectOnce(() => { | ||
return registerReFocus(() => latest.current.throttledFn()) | ||
}) | ||
} | ||
|
||
// biome-ignore lint/suspicious/noExplicitAny: ignore appState type | ||
export function createReactNativeReFocusRegister(appState: any) { | ||
return function registerReactNativeReFocus(callback: AnyFunc) { | ||
let state = appState.currentState | ||
|
||
const onAppStateChange = (nextAppState: string) => { | ||
if (state.match(/inactive|background/) && nextAppState === 'active') { | ||
callback() | ||
} | ||
|
||
state = nextAppState | ||
} | ||
|
||
const subscription = appState.addEventListener('change', onAppStateChange) | ||
|
||
return () => subscription.remove() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# useReFocus | ||
|
||
import { HooksType, NotReleased } from '@/components' | ||
|
||
<HooksType category="Utilities" lowLevel /> | ||
|
||
<NotReleased /> | ||
|
||
这是一个 React 钩子(Hook),用于在**重新**获得焦点时运行一个函数。 | ||
|
||
## 演示 Demo \{#demo} | ||
|
||
import { App } from './demo' | ||
|
||
<App /> | ||
|
||
## 用法 Usage \{#usage} | ||
|
||
import { RawCode } from '@/components' | ||
import source from '!!raw-loader!./demo' | ||
|
||
<RawCode>{source}</RawCode> | ||
|
||
## 源码 Source \{#source} | ||
|
||
import { Source } from '@/components' | ||
|
||
<Source /> | ||
|
||
## API \{#api} | ||
|
||
```tsx | ||
useReFocus(fn, options): void | ||
``` | ||
|
||
### 函数 Fn \{#fn} | ||
|
||
当重新获得焦点时将被调用的函数。 | ||
|
||
### 选项 Options \{#options} | ||
|
||
```tsx | ||
interface UseReFocusOptions extends UseThrottledFnOptions { | ||
/** | ||
* 注册焦点事件监听器。 | ||
*/ | ||
registerReFocus?: (callback: AnyFunc) => void | ||
} | ||
``` | ||
|
||
查看 [useThrottledFn](/reference/use-throttled-fn) 以了解更多信息。 |