react-ui-animate 2.0.0-rc.2 → 2.0.0-rc.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/.vscode/settings.json +3 -3
  2. package/LICENSE +21 -21
  3. package/README.md +115 -115
  4. package/dist/animation/index.d.ts +1 -0
  5. package/dist/animation/interpolation.d.ts +11 -2
  6. package/dist/animation/modules/AnimatedBlock.d.ts +8 -0
  7. package/dist/animation/modules/AnimatedImage.d.ts +8 -0
  8. package/dist/animation/modules/AnimatedInline.d.ts +8 -0
  9. package/dist/animation/modules/MountedBlock.d.ts +18 -0
  10. package/dist/animation/modules/ScrollableBlock.d.ts +21 -0
  11. package/dist/animation/modules/TransitionBlock.d.ts +17 -0
  12. package/dist/animation/modules/index.d.ts +6 -0
  13. package/dist/animation/useAnimatedValue.d.ts +8 -4
  14. package/dist/animation/useMountedValue.d.ts +5 -4
  15. package/dist/gestures/controllers/MouseMoveGesture.d.ts +2 -2
  16. package/dist/gestures/controllers/ScrollGesture.d.ts +2 -2
  17. package/dist/gestures/controllers/WheelGesture.d.ts +2 -2
  18. package/dist/gestures/controllers/index.d.ts +4 -4
  19. package/dist/gestures/eventAttacher.d.ts +1 -1
  20. package/dist/gestures/hooks/index.d.ts +5 -5
  21. package/dist/gestures/hooks/useDrag.d.ts +1 -1
  22. package/dist/gestures/hooks/useGesture.d.ts +1 -1
  23. package/dist/gestures/hooks/useMouseMove.d.ts +1 -1
  24. package/dist/gestures/hooks/useRecognizer.d.ts +1 -1
  25. package/dist/gestures/hooks/useScroll.d.ts +1 -1
  26. package/dist/gestures/hooks/useWheel.d.ts +1 -1
  27. package/dist/gestures/index.d.ts +2 -2
  28. package/dist/index.d.ts +1 -1
  29. package/dist/index.js +189 -152
  30. package/dist/index.js.map +1 -1
  31. package/package.json +48 -49
  32. package/rollup.config.js +18 -18
  33. package/src/animation/animationType.ts +17 -17
  34. package/src/animation/getInitialConfig.ts +61 -61
  35. package/src/animation/index.ts +10 -9
  36. package/src/animation/interpolation.ts +48 -24
  37. package/src/animation/modules/AnimatedBlock.ts +8 -0
  38. package/src/animation/modules/AnimatedImage.ts +8 -0
  39. package/src/animation/modules/AnimatedInline.ts +8 -0
  40. package/src/animation/modules/MountedBlock.tsx +25 -0
  41. package/src/animation/modules/ScrollableBlock.tsx +69 -0
  42. package/src/animation/modules/TransitionBlock.tsx +29 -0
  43. package/src/animation/modules/index.ts +6 -0
  44. package/src/animation/useAnimatedValue.ts +71 -62
  45. package/src/animation/useMountedValue.ts +67 -66
  46. package/src/gestures/controllers/DragGesture.ts +177 -177
  47. package/src/gestures/controllers/Gesture.ts +54 -54
  48. package/src/gestures/controllers/MouseMoveGesture.ts +111 -111
  49. package/src/gestures/controllers/ScrollGesture.ts +107 -107
  50. package/src/gestures/controllers/WheelGesture.ts +123 -123
  51. package/src/gestures/controllers/index.ts +4 -4
  52. package/src/gestures/eventAttacher.ts +67 -67
  53. package/src/gestures/hooks/index.ts +5 -5
  54. package/src/gestures/hooks/useDrag.ts +14 -14
  55. package/src/gestures/hooks/useGesture.ts +38 -38
  56. package/src/gestures/hooks/useMouseMove.ts +11 -11
  57. package/src/gestures/hooks/useRecognizer.ts +59 -59
  58. package/src/gestures/hooks/useScroll.ts +11 -11
  59. package/src/gestures/hooks/useWheel.ts +11 -11
  60. package/src/gestures/index.ts +2 -2
  61. package/src/gestures/math.ts +120 -120
  62. package/src/gestures/types.ts +49 -49
  63. package/src/gestures/withDefault.ts +3 -3
  64. package/src/hooks/index.ts +3 -3
  65. package/src/hooks/useMeasure.ts +133 -133
  66. package/src/hooks/useOutsideClick.ts +36 -36
  67. package/src/hooks/useWindowDimension.ts +59 -59
  68. package/src/index.ts +5 -5
  69. package/src/utils/delay.ts +9 -9
  70. package/src/utils/index.ts +2 -2
  71. package/src/utils/isDefined.ts +4 -4
  72. package/tsconfig.json +25 -25
  73. package/dist/animation/modules.d.ts +0 -55
  74. package/src/animation/modules.tsx +0 -105
@@ -1,61 +1,61 @@
1
- import { Easing, UseTransitionConfig } from '@raidipesh78/re-motion';
2
- export type InitialConfigType =
3
- | 'linear'
4
- | 'easein'
5
- | 'easeout'
6
- | 'easeinout'
7
- | 'ease'
8
- | 'power1'
9
- | 'power2'
10
- | 'power3'
11
- | 'power4'
12
- | 'elastic'
13
- | 'stiff'
14
- | 'wooble'
15
- | 'bounce';
16
-
17
- export const getInitialConfig = (
18
- animationType?: InitialConfigType
19
- ): UseTransitionConfig => {
20
- switch (animationType) {
21
- case 'elastic':
22
- return { mass: 1, friction: 18, tension: 250 };
23
-
24
- case 'stiff':
25
- return { mass: 1, friction: 18, tension: 350 };
26
-
27
- case 'wooble':
28
- return { mass: 1, friction: 8, tension: 250 };
29
-
30
- case 'bounce':
31
- return { duration: 500, easing: Easing.bounce };
32
-
33
- case 'power1':
34
- return { duration: 500, easing: Easing.bezier(0.17, 0.42, 0.51, 0.97) };
35
-
36
- case 'power2':
37
- return { duration: 500, easing: Easing.bezier(0.07, 0.11, 0.13, 1) };
38
-
39
- case 'power3':
40
- return { duration: 500, easing: Easing.bezier(0.09, 0.7, 0.16, 1.04) };
41
-
42
- case 'power4':
43
- return { duration: 500, easing: Easing.bezier(0.05, 0.54, 0, 1.03) };
44
-
45
- case 'linear':
46
- return { duration: 500, easing: Easing.linear };
47
-
48
- case 'easein':
49
- return { duration: 500, easing: Easing.in(Easing.ease) };
50
-
51
- case 'easeout':
52
- return { duration: 500, easing: Easing.out(Easing.ease) };
53
-
54
- case 'easeinout':
55
- return { duration: 500, easing: Easing.inOut(Easing.ease) };
56
-
57
- case 'ease':
58
- default:
59
- return { mass: 1, friction: 26, tension: 170 };
60
- }
61
- };
1
+ import { Easing, UseTransitionConfig } from '@raidipesh78/re-motion';
2
+ export type InitialConfigType =
3
+ | 'linear'
4
+ | 'easein'
5
+ | 'easeout'
6
+ | 'easeinout'
7
+ | 'ease'
8
+ | 'power1'
9
+ | 'power2'
10
+ | 'power3'
11
+ | 'power4'
12
+ | 'elastic'
13
+ | 'stiff'
14
+ | 'wooble'
15
+ | 'bounce';
16
+
17
+ export const getInitialConfig = (
18
+ animationType?: InitialConfigType
19
+ ): UseTransitionConfig => {
20
+ switch (animationType) {
21
+ case 'elastic':
22
+ return { mass: 1, friction: 18, tension: 250 };
23
+
24
+ case 'stiff':
25
+ return { mass: 1, friction: 18, tension: 350 };
26
+
27
+ case 'wooble':
28
+ return { mass: 1, friction: 8, tension: 250 };
29
+
30
+ case 'bounce':
31
+ return { duration: 500, easing: Easing.bounce };
32
+
33
+ case 'power1':
34
+ return { duration: 500, easing: Easing.bezier(0.17, 0.42, 0.51, 0.97) };
35
+
36
+ case 'power2':
37
+ return { duration: 500, easing: Easing.bezier(0.07, 0.11, 0.13, 1) };
38
+
39
+ case 'power3':
40
+ return { duration: 500, easing: Easing.bezier(0.09, 0.7, 0.16, 1.04) };
41
+
42
+ case 'power4':
43
+ return { duration: 500, easing: Easing.bezier(0.05, 0.54, 0, 1.03) };
44
+
45
+ case 'linear':
46
+ return { duration: 500, easing: Easing.linear };
47
+
48
+ case 'easein':
49
+ return { duration: 500, easing: Easing.in(Easing.ease) };
50
+
51
+ case 'easeout':
52
+ return { duration: 500, easing: Easing.out(Easing.ease) };
53
+
54
+ case 'easeinout':
55
+ return { duration: 500, easing: Easing.inOut(Easing.ease) };
56
+
57
+ case 'ease':
58
+ default:
59
+ return { mass: 1, friction: 34, tension: 290 };
60
+ }
61
+ };
@@ -1,9 +1,10 @@
1
- export * from './interpolation';
2
- export * from './modules';
3
- export {
4
- useAnimatedValue,
5
- ValueType,
6
- UseAnimatedValueConfig,
7
- } from './useAnimatedValue';
8
- export { useMountedValue } from './useMountedValue';
9
- export * from './animationType';
1
+ export * from './interpolation';
2
+ export * from './modules';
3
+ export {
4
+ useAnimatedValue,
5
+ ValueType,
6
+ UseAnimatedValueConfig,
7
+ } from './useAnimatedValue';
8
+ export { useMountedValue } from './useMountedValue';
9
+ export * from './animationType';
10
+ export * from './modules';
@@ -1,24 +1,48 @@
1
- import {
2
- interpolate,
3
- ExtrapolateConfig,
4
- TransitionValue,
5
- } from '@raidipesh78/re-motion';
6
- export { interpolate } from '@raidipesh78/re-motion';
7
-
8
- /**
9
- * bInterpolate functions maps input range [0, 1] to given [minOutput, maxOutput]
10
- * sorthand function to interpolate input range [0, 1]
11
- * @param value - number | TransitionValue
12
- * @param minOutput - number | string
13
- * @param maxOutput - number | string
14
- * @param extrapolateConfig - "clamp" | "identity" | "extend"
15
- * @returns - number | TransitionValue
16
- */
17
- export function bInterpolate(
18
- value: number | TransitionValue,
19
- minOutput: number | string,
20
- maxOutput: number | string,
21
- extrapolateConfig?: ExtrapolateConfig
22
- ) {
23
- return interpolate(value, [0, 1], [minOutput, maxOutput], extrapolateConfig);
24
- }
1
+ import { ExtrapolateConfig, TransitionValue } from '@raidipesh78/re-motion';
2
+ import { ValueType } from './useAnimatedValue';
3
+ import { interpolate as internalInterpolate } from '@raidipesh78/re-motion';
4
+
5
+ /**
6
+ * interpolate functions maps input range to given output range
7
+ * @param value - number | TransitionValue
8
+ * @param inputRange - Array<number>
9
+ * @param outputRange - Array<number | string>
10
+ * @param extrapolateConfig - "clamp" | "identity" | "extend"
11
+ * @returns - number | TransitionValue
12
+ */
13
+ export function interpolate(
14
+ value: number | TransitionValue | ValueType,
15
+ inputRange: Array<number>,
16
+ outputRange: Array<number | string>,
17
+ extrapolateConfig?: ExtrapolateConfig
18
+ ) {
19
+ return internalInterpolate(
20
+ value as any,
21
+ inputRange,
22
+ outputRange,
23
+ extrapolateConfig
24
+ );
25
+ }
26
+
27
+ /**
28
+ * bInterpolate functions maps input range [0, 1] to given [minOutput, maxOutput]
29
+ * sorthand function to interpolate input range [0, 1]
30
+ * @param value - number | TransitionValue
31
+ * @param minOutput - number | string
32
+ * @param maxOutput - number | string
33
+ * @param extrapolateConfig - "clamp" | "identity" | "extend"
34
+ * @returns - number | TransitionValue
35
+ */
36
+ export function bInterpolate(
37
+ value: number | TransitionValue | ValueType,
38
+ minOutput: number | string,
39
+ maxOutput: number | string,
40
+ extrapolateConfig?: ExtrapolateConfig
41
+ ) {
42
+ return internalInterpolate(
43
+ value as any,
44
+ [0, 1],
45
+ [minOutput, maxOutput],
46
+ extrapolateConfig
47
+ );
48
+ }
@@ -0,0 +1,8 @@
1
+ import { makeAnimatedComponent } from '@raidipesh78/re-motion';
2
+
3
+ /**
4
+ * AnimatedBlock - A higher order component built upon `div` element
5
+ * which can accept `AnimatedValue`. It also exposes some extra style properties like
6
+ * translateX, translateY, rotateX, rotateY, scaleX, etc.
7
+ */
8
+ export const AnimatedBlock = makeAnimatedComponent('div');
@@ -0,0 +1,8 @@
1
+ import { makeAnimatedComponent } from '@raidipesh78/re-motion';
2
+
3
+ /**
4
+ * AnimatedImage - A higher order component built upon `img` element
5
+ * which can accept `AnimatedValue`. It also exposes some extra style properties like
6
+ * translateX, translateY, rotateX, rotateY, scaleX, etc.
7
+ */
8
+ export const AnimatedImage = makeAnimatedComponent('img');
@@ -0,0 +1,8 @@
1
+ import { makeAnimatedComponent } from '@raidipesh78/re-motion';
2
+
3
+ /**
4
+ * AnimatedInline - A higher order component built upon `span` element
5
+ * which can accept `AnimatedValue`. It also exposes some extra style properties like
6
+ * translateX, translateY, rotateX, rotateY, scaleX, etc.
7
+ */
8
+ export const AnimatedInline = makeAnimatedComponent('span');
@@ -0,0 +1,25 @@
1
+ import * as React from 'react';
2
+ import { TransitionValue } from '@raidipesh78/re-motion';
3
+ import { useMountedValue, UseMountedValueConfig } from '../useMountedValue';
4
+
5
+ interface MountedBlockProps {
6
+ state: boolean;
7
+ children: (animation: { value: TransitionValue }) => React.ReactNode;
8
+ config: UseMountedValueConfig;
9
+ }
10
+
11
+ /**
12
+ * MountedBlock - Higher order component which handles mounting and unmounting of a component.
13
+ * @prop { boolean } state - Boolean indicating the component should mount or unmount.
14
+ * @prop { function } children - Child as a function with `AnimatedValue` on `.value` property.
15
+ * @prop { UseMountedValueConfig } config - Animation configuration.
16
+ */
17
+ export const MountedBlock = ({
18
+ state,
19
+ children,
20
+ config,
21
+ }: MountedBlockProps) => {
22
+ const open = useMountedValue(state, config);
23
+
24
+ return <>{open((animation, mounted) => mounted && children(animation))}</>;
25
+ };
@@ -0,0 +1,69 @@
1
+ import * as React from 'react';
2
+ import {
3
+ useAnimatedValue,
4
+ UseAnimatedValueConfig,
5
+ ValueType,
6
+ } from '../useAnimatedValue';
7
+
8
+ interface ScrollableBlockProps {
9
+ children?: (animation: { value: ValueType }) => React.ReactNode;
10
+ direction?: 'single' | 'both';
11
+ threshold?: number;
12
+ animationConfig?: UseAnimatedValueConfig;
13
+ }
14
+
15
+ /**
16
+ * ScrollableBlock - Higher order component to handle the entrance or exit animation
17
+ * of a component when it enters or exit the viewport. Accepts child as a function with
18
+ * `AnimatedValue` as its first argument which can be interpolated on input range [0, 1]
19
+ * @prop { function } children - child as a function with `AnimatedValue` as its first argument.
20
+ * @prop { 'single' | 'both' } direction - single applies animation on enter once, both applies on enter and exit.
21
+ * @prop { number } threshold - should be in range 0 to 1 which equivalent to `IntersectionObserver` threshold.
22
+ * @prop { UseAnimatedValueConfig } animationConfig - Animation config
23
+ */
24
+ export const ScrollableBlock = (props: ScrollableBlockProps) => {
25
+ const {
26
+ children,
27
+ direction = 'single',
28
+ animationConfig,
29
+ threshold = 0.2,
30
+ } = props;
31
+ const scrollableBlockRef = React.useRef<HTMLDivElement>(null);
32
+ const animation = useAnimatedValue(0, animationConfig); // 0: not intersecting | 1: intersecting
33
+
34
+ React.useEffect(() => {
35
+ const _scrollableBlock = scrollableBlockRef.current;
36
+
37
+ const observer = new IntersectionObserver(
38
+ function ([entry]) {
39
+ const { isIntersecting } = entry;
40
+
41
+ if (isIntersecting) {
42
+ animation.value = 1;
43
+ } else {
44
+ if (direction === 'both') animation.value = 0;
45
+ }
46
+ },
47
+ {
48
+ root: null, // FOR VIEWPORT ONLY
49
+ threshold,
50
+ }
51
+ );
52
+
53
+ if (_scrollableBlock) {
54
+ observer.observe(_scrollableBlock);
55
+ }
56
+
57
+ return () => {
58
+ if (_scrollableBlock) {
59
+ observer.unobserve(_scrollableBlock);
60
+ }
61
+ };
62
+ }, []);
63
+
64
+ return (
65
+ <div ref={scrollableBlockRef}>
66
+ {children && children({ value: animation.value })}
67
+ </div>
68
+ );
69
+ };
@@ -0,0 +1,29 @@
1
+ import * as React from 'react';
2
+ import { bin } from '../../gestures/math';
3
+ import {
4
+ useAnimatedValue,
5
+ UseAnimatedValueConfig,
6
+ ValueType,
7
+ } from '../useAnimatedValue';
8
+
9
+ interface TransitionBlockProps {
10
+ state: boolean;
11
+ children: (animation: { value: ValueType }) => React.ReactNode;
12
+ config?: UseAnimatedValueConfig;
13
+ }
14
+
15
+ /**
16
+ * TransitionBlock - Higher order component which animates on state change.
17
+ * @prop { boolean } state - Boolean indicating the current state of animation, usually `false = 0 and true = 1`.
18
+ * @prop { function } children - Child as a function with `AnimatedValue` on `.value` property.
19
+ * @prop { UseAnimatedValueConfig } config - Animation configuration.
20
+ */
21
+ export const TransitionBlock = ({
22
+ state,
23
+ children,
24
+ config,
25
+ }: TransitionBlockProps) => {
26
+ const amv = useAnimatedValue(bin(state), config);
27
+
28
+ return <>{children({ value: amv.value })}</>;
29
+ };
@@ -0,0 +1,6 @@
1
+ export * from './AnimatedBlock';
2
+ export * from './AnimatedInline';
3
+ export * from './AnimatedImage';
4
+ export * from './MountedBlock';
5
+ export * from './ScrollableBlock';
6
+ export * from './TransitionBlock';
@@ -1,62 +1,71 @@
1
- import { useTransition, UseTransitionConfig } from '@raidipesh78/re-motion';
2
-
3
- // useAnimatedValue value type
4
- type AnimatedValueType = number | string;
5
- export interface UseAnimatedValueConfig extends UseTransitionConfig {}
6
-
7
- type Length = number | string;
8
- type AssignValue = {
9
- toValue: Length;
10
- config?: UseAnimatedValueConfig;
11
- };
12
- export type ValueType =
13
- | Length
14
- | AssignValue
15
- | ((update: (next: AssignValue) => Promise<any>) => void);
16
-
17
- /**
18
- * useAnimatedValue for animated transitions
19
- */
20
- export function useAnimatedValue(
21
- initialValue: AnimatedValueType,
22
- config?: UseAnimatedValueConfig
23
- ) {
24
- const [animation, setAnimation] = useTransition(initialValue, config);
25
-
26
- const targetObject: {
27
- value: any;
28
- currentValue: number | string;
29
- } = {
30
- value: animation,
31
- currentValue: animation.get(),
32
- };
33
-
34
- return new Proxy(targetObject, {
35
- set: function (_, key, value: ValueType) {
36
- if (key === 'value') {
37
- if (typeof value === 'number' || typeof value === 'string') {
38
- setAnimation({ toValue: value });
39
- } else if (typeof value === 'object' || typeof value === 'function') {
40
- setAnimation(value);
41
- }
42
-
43
- return true;
44
- }
45
-
46
- throw new Error('You cannot set any other property to animation node.');
47
- },
48
- get: function (_, key) {
49
- if (key === 'value') {
50
- return animation;
51
- }
52
-
53
- if (key === 'currentValue') {
54
- return animation.get();
55
- }
56
-
57
- throw new Error(
58
- 'You cannot access any other property from animation node.'
59
- );
60
- },
61
- });
62
- }
1
+ import { useTransition, UseTransitionConfig } from '@raidipesh78/re-motion';
2
+ import { AnimationConfigUtils } from './animationType';
3
+
4
+ // useAnimatedValue value type
5
+ type Length = number | string;
6
+ type AnimatedValueType = Length;
7
+
8
+ export interface UseAnimatedValueConfig extends UseTransitionConfig {}
9
+
10
+ type AssignValue = {
11
+ toValue: Length;
12
+ config?: UseAnimatedValueConfig;
13
+ };
14
+ export type ValueType =
15
+ | Length
16
+ | AssignValue
17
+ | ((update: (next: AssignValue) => Promise<any>) => void);
18
+
19
+ /**
20
+ * `useAnimatedValue` returns an animation value with `.value` and `.currentValue` property which is
21
+ * initialized when passed to argument (`initialValue`). The retured value persist until the lifetime of
22
+ * a component. It doesnot cast any re-renders which can is very good for performance optimization.
23
+ * @param { string | number } initialValue - Initial value
24
+ * @param { UseAnimatedValueConfig } config - Animation configuration object.
25
+ */
26
+ export function useAnimatedValue(
27
+ initialValue: AnimatedValueType,
28
+ config?: UseAnimatedValueConfig
29
+ ) {
30
+ const [animation, setAnimation] = useTransition(initialValue, {
31
+ ...AnimationConfigUtils.EASE,
32
+ ...config,
33
+ });
34
+
35
+ const targetObject: {
36
+ value: ValueType;
37
+ currentValue: number | string;
38
+ } = {
39
+ value: animation as any,
40
+ currentValue: animation.get(),
41
+ };
42
+
43
+ return new Proxy(targetObject, {
44
+ set: function (_, key, value: ValueType) {
45
+ if (key === 'value') {
46
+ if (typeof value === 'number' || typeof value === 'string') {
47
+ setAnimation({ toValue: value });
48
+ } else if (typeof value === 'object' || typeof value === 'function') {
49
+ setAnimation(value);
50
+ }
51
+
52
+ return true;
53
+ }
54
+
55
+ throw new Error('You cannot set any other property to animation node.');
56
+ },
57
+ get: function (_, key) {
58
+ if (key === 'value') {
59
+ return animation;
60
+ }
61
+
62
+ if (key === 'currentValue') {
63
+ return animation.get();
64
+ }
65
+
66
+ throw new Error(
67
+ 'You cannot access any other property from animation node.'
68
+ );
69
+ },
70
+ });
71
+ }
@@ -1,66 +1,67 @@
1
- import * as React from 'react';
2
- import {
3
- useTransition,
4
- TransitionValue,
5
- UseMountConfig,
6
- } from '@raidipesh78/re-motion';
7
-
8
- export interface UseMountedValueConfig extends UseMountConfig {}
9
-
10
- /**
11
- * useMountedValue handles mounting and unmounting of a component
12
- * @param state - boolean
13
- * @param config - useTransitionConfig
14
- * @returns mountedValueFunction with a callback with argument ( { value: animationNode }, mounted )
15
- */
16
- export function useMountedValue(state: boolean, config: UseMountedValueConfig) {
17
- const initial = React.useRef(true);
18
- const [mounted, setMounted] = React.useState(state);
19
- const {
20
- from,
21
- enter,
22
- exit,
23
- config: innerConfig,
24
- enterConfig,
25
- exitConfig,
26
- } = React.useRef(config).current;
27
- const [animation, setAnimation] = useTransition(from, innerConfig);
28
-
29
- React.useEffect(() => {
30
- if (state) {
31
- initial.current = true;
32
- setMounted(true);
33
- } else {
34
- initial.current = false;
35
- setAnimation(
36
- {
37
- toValue: exit,
38
- config: exitConfig,
39
- },
40
- function ({ finished }) {
41
- if (finished) {
42
- setMounted(false);
43
- }
44
- }
45
- );
46
- }
47
- }, [state]);
48
-
49
- React.useEffect(() => {
50
- if (mounted && initial.current) {
51
- setAnimation({
52
- toValue: enter,
53
- config: enterConfig,
54
- });
55
- }
56
- }, [mounted, initial.current]);
57
-
58
- return function (
59
- callback: (
60
- { value: animation }: { value: TransitionValue },
61
- mounted: boolean
62
- ) => React.ReactNode
63
- ) {
64
- return callback({ value: animation }, mounted);
65
- };
66
- }
1
+ import * as React from 'react';
2
+ import {
3
+ useTransition,
4
+ TransitionValue,
5
+ UseMountConfig,
6
+ } from '@raidipesh78/re-motion';
7
+
8
+ export interface UseMountedValueConfig extends UseMountConfig {}
9
+
10
+ /**
11
+ * `useMountedValue` handles mounting and unmounting of a component which captures current state
12
+ * passed as an arugment (`state`) and exposes the shadow state which handles the mount and unmount
13
+ * of a component.
14
+ * @param { boolean } state - Boolean indicating the component should mount or unmount.
15
+ * @param { UseMountedValueConfig } config - Animation configuration.
16
+ */
17
+ export function useMountedValue(state: boolean, config: UseMountedValueConfig) {
18
+ const initial = React.useRef(true);
19
+ const [mounted, setMounted] = React.useState(state);
20
+ const {
21
+ from,
22
+ enter,
23
+ exit,
24
+ config: innerConfig,
25
+ enterConfig,
26
+ exitConfig,
27
+ } = React.useRef(config).current;
28
+ const [animation, setAnimation] = useTransition(from, innerConfig);
29
+
30
+ React.useEffect(() => {
31
+ if (state) {
32
+ initial.current = true;
33
+ setMounted(true);
34
+ } else {
35
+ initial.current = false;
36
+ setAnimation(
37
+ {
38
+ toValue: exit,
39
+ config: exitConfig,
40
+ },
41
+ function ({ finished }) {
42
+ if (finished) {
43
+ setMounted(false);
44
+ }
45
+ }
46
+ );
47
+ }
48
+ }, [state]);
49
+
50
+ React.useEffect(() => {
51
+ if (mounted && initial.current) {
52
+ setAnimation({
53
+ toValue: enter,
54
+ config: enterConfig,
55
+ });
56
+ }
57
+ }, [mounted, initial.current]);
58
+
59
+ return function (
60
+ callback: (
61
+ { value: animation }: { value: TransitionValue },
62
+ mounted: boolean
63
+ ) => React.ReactNode
64
+ ) {
65
+ return callback({ value: animation }, mounted);
66
+ };
67
+ }