File tree Expand file tree Collapse file tree 7 files changed +131
-14
lines changed Expand file tree Collapse file tree 7 files changed +131
-14
lines changed Original file line number Diff line number Diff line change
1
+ export * from './useActiveElement/useActiveElement' ;
1
2
export * from './useAsync/useAsync' ;
2
3
export * from './useBattery/useBattery' ;
3
4
export * from './useBoolean/useBoolean' ;
@@ -96,6 +97,7 @@ export * from './useToggle/useToggle';
96
97
export * from './useUnmount/useUnmount' ;
97
98
export * from './useWebSocket/useWebSocket' ;
98
99
export * from './useWindowEvent/useWindowEvent' ;
100
+ export * from './useWindowFocus/useWindowFocus' ;
99
101
export * from './useWindowScroll/useWindowScroll' ;
100
102
export * from './useWindowSize/useWindowSize' ;
101
103
export * from './useWizard/useWizard' ;
Original file line number Diff line number Diff line change
1
+ import { useActiveElement } from './useActiveElement' ;
2
+
3
+ const Demo = ( ) => {
4
+ const activeElement = useActiveElement ( ) ;
5
+ const activeElementId = activeElement ?. dataset ?. id ?? 'null' ;
6
+
7
+ return (
8
+ < >
9
+ < div style = { { display : 'grid' , gridTemplateColumns : '1fr 1fr' , gap : '5px' } } >
10
+ { Array . from ( { length : 6 } , ( _ , i ) => i + 1 ) . map ( ( id ) => (
11
+ < input key = { id } type = 'text' data-id = { String ( id ) } placeholder = { String ( id ) } />
12
+ ) ) }
13
+ </ div >
14
+
15
+ < p >
16
+ current active element: < code > { activeElementId } </ code >
17
+ </ p >
18
+ </ >
19
+ ) ;
20
+ } ;
21
+
22
+ export default Demo ;
Original file line number Diff line number Diff line change
1
+ import { useEffect , useState } from 'react' ;
2
+
3
+ import { useMutationObserver } from '../useMutationObserver/useMutationObserver' ;
4
+
5
+ /**
6
+ * @name useActiveElement
7
+ * @description - Hook that returns the active element
8
+ * @category Elements
9
+ *
10
+ * @returns {ActiveElement | null } The active element
11
+ *
12
+ * @example
13
+ * const activeElement = useActiveElement();
14
+ */
15
+ export const useActiveElement = < ActiveElement extends HTMLElement > ( ) => {
16
+ const [ activeElement , setActiveElement ] = useState < ActiveElement | null > ( null ) ;
17
+
18
+ useEffect ( ( ) => {
19
+ const onActiveElementChange = ( ) =>
20
+ setActiveElement ( document ?. activeElement as ActiveElement | null ) ;
21
+
22
+ window . addEventListener ( 'focus' , onActiveElementChange , true ) ;
23
+ window . addEventListener ( 'blur' , onActiveElementChange , true ) ;
24
+ return ( ) => {
25
+ window . removeEventListener ( 'focus' , onActiveElementChange ) ;
26
+ window . removeEventListener ( 'blur' , onActiveElementChange ) ;
27
+ } ;
28
+ } ) ;
29
+
30
+ useMutationObserver (
31
+ document as any ,
32
+ ( mutations ) => {
33
+ mutations
34
+ . filter ( ( mutation ) => mutation . removedNodes . length )
35
+ . map ( ( mutation ) => Array . from ( mutation . removedNodes ) )
36
+ . flat ( )
37
+ . forEach ( ( node ) => {
38
+ if ( node === activeElement )
39
+ setActiveElement ( document ?. activeElement as ActiveElement | null ) ;
40
+ } ) ;
41
+ } ,
42
+ {
43
+ childList : true ,
44
+ subtree : true
45
+ }
46
+ ) ;
47
+
48
+ return activeElement ;
49
+ } ;
Original file line number Diff line number Diff line change
1
+ import { useEffect , useState } from 'react' ;
2
+
1
3
import { useDidUpdate } from '../useDidUpdate/useDidUpdate' ;
4
+ import { useTimer } from '../useTimer/useTimer' ;
2
5
3
6
import { useDocumentVisibility } from './useDocumentVisibility' ;
4
7
8
+ const START_MESSAGE = '💡 Minimize the page or switch tab then return' ;
9
+
5
10
const Demo = ( ) => {
11
+ const [ message , setMessage ] = useState ( START_MESSAGE ) ;
6
12
const documentVisibility = useDocumentVisibility ( ) ;
7
13
8
- useDidUpdate ( ( ) => {
9
- console . log ( `Current document visibility state: ${ documentVisibility } ` ) ;
14
+ const timer = useTimer ( 3000 , ( ) => {
15
+ setMessage ( START_MESSAGE ) ;
16
+ } ) ;
10
17
18
+ useDidUpdate ( ( ) => {
11
19
if ( documentVisibility === 'visible' ) {
12
- alert ( `Current document visibility state: ${ documentVisibility } ` ) ;
20
+ setMessage ( '🎉 Welcome back!' ) ;
21
+ timer . start ( ) ;
13
22
}
14
23
} , [ documentVisibility ] ) ;
15
24
16
- return (
17
- < div >
18
- < p >
19
- Switch to another tab and then return here
20
- < br />
21
- < br />
22
- Visibility status: < code > { documentVisibility } </ code >
23
- </ p >
24
- </ div >
25
- ) ;
25
+ return < p > { message } </ p > ;
26
26
} ;
27
27
28
28
export default Demo ;
Original file line number Diff line number Diff line change
1
+ import { useWindowFocus } from './useWindowFocus' ;
2
+
3
+ const Demo = ( ) => {
4
+ const windowFocused = useWindowFocus ( ) ;
5
+
6
+ return (
7
+ < p >
8
+ { windowFocused && '💡 Click somewhere outside of the document to unfocus.' }
9
+ { ! windowFocused && 'ℹ Tab is unfocused' }
10
+ </ p >
11
+ ) ;
12
+ } ;
13
+
14
+ export default Demo ;
Original file line number Diff line number Diff line change
1
+ import { useEffect , useState } from 'react' ;
2
+
3
+ /**
4
+ * @name useWindowFocus
5
+ * @description - Hook that provides the current focus state of the window
6
+ * @category Elements
7
+ *
8
+ * @returns {boolean } The current focus state of the window
9
+ *
10
+ * @example
11
+ * const focused = useWindowFocus();
12
+ */
13
+ export const useWindowFocus = ( ) => {
14
+ const [ focused , setFocused ] = useState ( false ) ;
15
+
16
+ useEffect ( ( ) => {
17
+ const onFocus = ( ) => setFocused ( true ) ;
18
+ const onBlur = ( ) => setFocused ( false ) ;
19
+
20
+ window . addEventListener ( 'focus' , onFocus ) ;
21
+ window . addEventListener ( 'blur' , onBlur ) ;
22
+
23
+ return ( ) => {
24
+ window . removeEventListener ( 'focus' , onFocus ) ;
25
+ window . removeEventListener ( 'blur' , onBlur ) ;
26
+ } ;
27
+ } ) ;
28
+
29
+ return focused ;
30
+ } ;
Original file line number Diff line number Diff line change @@ -19,7 +19,7 @@ export interface UseWindowSizeReturn {
19
19
/**
20
20
* @name useWindowSize
21
21
* @description - Hook that manages a window size
22
- * @category Browser
22
+ * @category Elements
23
23
*
24
24
* @param {number } [params.initialWidth=Number.POSITIVE_INFINITY] The initial window width
25
25
* @param {number } [params.initialHeight=Number.POSITIVE_INFINITY] The initial window height
You can’t perform that action at this time.
0 commit comments