Skip to content

Commit e900a9b

Browse files
authored
fix: fix warnings in strict mode (#97)
1 parent 44dc346 commit e900a9b

File tree

3 files changed

+105
-3
lines changed

3 files changed

+105
-3
lines changed

src/ImperativeTransition.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import useIsomorphicEffect from '@restart/hooks/useIsomorphicEffect';
44
import React, { useRef, cloneElement, useState } from 'react';
55
import { TransitionComponent, TransitionProps } from './types';
66
import NoopTransition from './NoopTransition';
7+
import RTGTransition from './RTGTransition';
78

89
export interface TransitionFunctionOptions {
910
in: boolean;
@@ -118,12 +119,12 @@ export default function ImperativeTransition({
118119
}
119120

120121
export function renderTransition(
121-
Component: TransitionComponent | undefined,
122+
component: TransitionComponent | undefined,
122123
runTransition: TransitionHandler | undefined,
123124
props: TransitionProps & Omit<ImperativeTransitionProps, 'transition'>,
124125
) {
125-
if (Component) {
126-
return <Component {...props} />;
126+
if (component) {
127+
return <RTGTransition {...props} component={component} />;
127128
}
128129
if (runTransition) {
129130
return <ImperativeTransition {...props} transition={runTransition} />;

src/RTGTransition.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import * as React from 'react';
2+
import useRTGTransitionProps, {
3+
TransitionProps,
4+
} from './useRTGTransitionProps';
5+
6+
export type RTGTransitionProps = TransitionProps & {
7+
component: React.ElementType;
8+
};
9+
10+
// Normalizes Transition callbacks when nodeRef is used.
11+
const RTGTransition = React.forwardRef<any, RTGTransitionProps>(
12+
({ component: Component, ...props }, ref) => {
13+
const transitionProps = useRTGTransitionProps(props);
14+
15+
return <Component ref={ref} {...transitionProps} />;
16+
},
17+
);
18+
19+
export default RTGTransition;

src/useRTGTransitionProps.ts

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { cloneElement, useCallback, useRef } from 'react';
2+
import useMergedRefs from '@restart/hooks/useMergedRefs';
3+
import {
4+
TransitionProps as RTGTransitionProps,
5+
TransitionStatus,
6+
} from 'react-transition-group/Transition';
7+
8+
export type TransitionProps = RTGTransitionProps & {
9+
children:
10+
| React.ReactElement
11+
| ((
12+
status: TransitionStatus,
13+
props: Record<string, unknown>,
14+
) => React.ReactNode);
15+
};
16+
17+
/**
18+
* Normalizes RTG transition callbacks with nodeRef to better support
19+
* strict mode.
20+
*
21+
* @param props Transition props.
22+
* @returns Normalized transition props.
23+
*/
24+
export default function useRTGTransitionProps({
25+
onEnter,
26+
onEntering,
27+
onEntered,
28+
onExit,
29+
onExiting,
30+
onExited,
31+
addEndListener,
32+
children,
33+
...props
34+
}: TransitionProps) {
35+
const nodeRef = useRef<HTMLElement>(null);
36+
const mergedRef = useMergedRefs(
37+
nodeRef,
38+
typeof children === 'function' ? null : (children as any).ref,
39+
);
40+
41+
const normalize =
42+
(callback?: (node: HTMLElement, param: any) => void) => (param: any) => {
43+
if (callback && nodeRef.current) {
44+
callback(nodeRef.current, param);
45+
}
46+
};
47+
48+
/* eslint-disable react-hooks/exhaustive-deps */
49+
const handleEnter = useCallback(normalize(onEnter), [onEnter]);
50+
const handleEntering = useCallback(normalize(onEntering), [onEntering]);
51+
const handleEntered = useCallback(normalize(onEntered), [onEntered]);
52+
const handleExit = useCallback(normalize(onExit), [onExit]);
53+
const handleExiting = useCallback(normalize(onExiting), [onExiting]);
54+
const handleExited = useCallback(normalize(onExited), [onExited]);
55+
const handleAddEndListener = useCallback(normalize(addEndListener), [
56+
addEndListener,
57+
]);
58+
/* eslint-enable react-hooks/exhaustive-deps */
59+
60+
return {
61+
...props,
62+
nodeRef,
63+
onEnter: handleEnter,
64+
onEntering: handleEntering,
65+
onEntered: handleEntered,
66+
onExit: handleExit,
67+
onExiting: handleExiting,
68+
onExited: handleExited,
69+
addEndListener: handleAddEndListener,
70+
children:
71+
typeof children === 'function'
72+
? (((status: TransitionStatus, innerProps: Record<string, unknown>) =>
73+
// TODO: Types for RTG missing innerProps, so need to cast.
74+
children(status, {
75+
...innerProps,
76+
ref: mergedRef,
77+
})) as any)
78+
: cloneElement(children as React.ReactElement, {
79+
ref: mergedRef,
80+
}),
81+
};
82+
}

0 commit comments

Comments
 (0)