-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
useResize.ts
77 lines (67 loc) · 2.02 KB
/
useResize.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import { MutableRefObject } from 'react'
import { onResize, each, useIsomorphicLayoutEffect } from '@react-spring/shared'
import { SpringProps, SpringValues } from '../types'
import { useSpring } from './useSpring'
export interface UseResizeOptions extends Omit<SpringProps, 'to' | 'from'> {
container?: MutableRefObject<HTMLElement | null | undefined>
}
/**
* A small abstraction around the `useSpring` hook. It returns a `SpringValues`
* object with the `width` and `height` of the element it's attached to & doesn't
* necessarily have to be attached to the window, by passing a `container` you
* can observe that element's size instead.
*
```jsx
import { useResize, animated } from '@react-spring/web'
function MyComponent() {
const { width } = useResize()
return (
<animated.div style={{ width }}>
Hello World
</animated.div>
)
}
```
*
* @param {UseResizeOptions} UseResizeOptions options for the useScroll hook.
* @param {MutableRefObject<HTMLElement>} UseResizeOptions.container the container to listen to scroll events on, defaults to the window.
*
* @returns {SpringValues<{width: number; height: number;}>} SpringValues the collection of values returned from the inner hook
*/
export const useResize = ({
container,
...springOptions
}: UseResizeOptions): SpringValues<{
width: number
height: number
}> => {
const [sizeValues, api] = useSpring(
() => ({
width: 0,
height: 0,
...springOptions,
}),
[]
)
useIsomorphicLayoutEffect(() => {
const cleanupScroll = onResize(
({ width, height }) => {
api.start({
width,
height,
immediate:
sizeValues.width.get() === 0 || sizeValues.height.get() === 0,
})
},
{ container: container?.current || undefined }
)
return () => {
/**
* Stop the springs on unmount.
*/
each(Object.values(sizeValues), value => value.stop())
cleanupScroll()
}
}, [])
return sizeValues
}