Skip to content

Commit efe853a

Browse files
committed
fix: improve props
1 parent 9711746 commit efe853a

File tree

5 files changed

+32
-22
lines changed

5 files changed

+32
-22
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ import { TransitionGroup } from 'react-transitioning'
126126

127127
```ts
128128
type TransitionProps = {
129-
children: (transitionState: TransitionState, activePhase: TransitionPhase) => React.ReactNode;
129+
children: React.ReactNode | ((transitionState: TransitionState, activePhase: TransitionPhase) => React.ReactNode);
130130
in?: boolean;
131131
appear?: boolean;
132132
enter?: boolean;

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-transitioning",
3-
"version": "1.0.2",
3+
"version": "1.0.3",
44
"description": "React components for easily implementing basic CSS animations and transitions",
55
"main": "dist/index.cjs.js",
66
"module": "dist/index.esm.js",

src/CSSTransition.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Children, cloneElement, useMemo } from 'react';
1+
import { cloneElement, isValidElement, useMemo } from 'react';
22
import { Transition, TransitionPhase, TransitionProps } from './Transition';
33

44
/**
@@ -67,18 +67,22 @@ type CSSTransitionChildProps = Pick<CSSTransitionProps, 'children' | 'classNames
6767
phase: TransitionPhase;
6868
};
6969

70-
const CSSTransitionChild = (props: CSSTransitionChildProps) => {
70+
function CSSTransitionChild(props: CSSTransitionChildProps) {
7171
const { children, classNames, phase } = props;
72-
const child = Children.only(children);
73-
const { className: childClassName } = child.props;
72+
73+
if (!isValidElement(children)) {
74+
return null;
75+
}
76+
77+
const { className: childClassName } = children.props;
7478

7579
const finalClassName = useMemo(
7680
() => joinClassNames(childClassName, makeClassName(phase, classNames)),
7781
[childClassName, classNames, phase],
7882
);
7983

80-
return cloneElement(child, { className: finalClassName });
81-
};
84+
return cloneElement(children, { className: finalClassName });
85+
}
8286

8387
/**
8488
* The `CSSTransition` component applies CSS transitions based on the phase of a transition lifecycle.

src/StyleTransition.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { cloneElement, Children, useMemo } from 'react';
1+
import { cloneElement, useMemo, isValidElement } from 'react';
22
import { TransitionPhase, TransitionProps, Transition } from './Transition';
33

44
/**
@@ -43,18 +43,22 @@ type StyleTransitionChildProps = Pick<StyleTransitionProps, 'children' | 'styles
4343
phase: TransitionPhase;
4444
};
4545

46-
const StyleTransitionChild = (props: StyleTransitionChildProps) => {
46+
function StyleTransitionChild(props: StyleTransitionChildProps) {
4747
const { children, styles, phase } = props;
48-
const child = Children.only(children);
49-
const { style: childStyle } = child.props;
48+
49+
if (!isValidElement(children)) {
50+
return null;
51+
}
52+
53+
const { style: childStyle } = children.props;
5054

5155
const finalStyle = useMemo(
5256
() => ({ ...childStyle, ...makePhaseStyle(phase, styles) }),
5357
[childStyle, styles, phase],
5458
);
5559

56-
return cloneElement(child, { style: finalStyle });
57-
};
60+
return cloneElement(children, { style: finalStyle });
61+
}
5862

5963
/**
6064
* The `StyleTransition` component allows you to animate the styles of a component across different

src/Transition.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState, useEffect, useRef, useMemo } from 'react';
1+
import { useState, useEffect, useMemo } from 'react';
22
import { useIsoEffect } from './useIsoEffect';
33

44
/**
@@ -101,7 +101,9 @@ export type TransitionProps = {
101101
* @param activePhase - The phase currently in progress (e.g., "appearActive", "enterDone").
102102
* @returns React nodes to render.
103103
*/
104-
children: (transitionState: TransitionState, activePhase: TransitionPhase) => React.ReactNode;
104+
children:
105+
| React.ReactNode
106+
| ((transitionState: TransitionState, activePhase: TransitionPhase) => React.ReactNode);
105107
};
106108

107109
const EVENT_MAP: {
@@ -136,7 +138,6 @@ export function Transition(props: TransitionProps) {
136138
addEndListener,
137139
} = props;
138140

139-
const tmRef = useRef<number>(0);
140141
let ignoreInPropChange = false;
141142

142143
// Make phase state
@@ -157,19 +158,20 @@ export function Transition(props: TransitionProps) {
157158
const [eventName, nextPhase, delay] = EVENT_MAP[phase];
158159
const { [eventName]: event } = props;
159160
event?.();
161+
let tm = 0;
160162
if (nextPhase) {
161163
if (delay) {
162164
if (addEndListener) {
163165
addEndListener(phase, () => setPhase(nextPhase));
164166
} else {
165-
tmRef.current = setTimeout(setPhase, duration, nextPhase);
167+
tm = setTimeout(setPhase, duration, nextPhase);
166168
}
167169
} else {
168-
tmRef.current = setTimeout(setPhase, 0, nextPhase);
170+
tm = setTimeout(setPhase, 0, nextPhase);
169171
}
170172
}
171173
return () => {
172-
clearTimeout(tmRef.current);
174+
clearTimeout(tm);
173175
};
174176
}, [phase, duration]);
175177

@@ -195,10 +197,10 @@ export function Transition(props: TransitionProps) {
195197
);
196198

197199
// Do not render anything
198-
if (!alwaysMounted && phase === TransitionPhase.EXIT_DONE) {
200+
if (!alwaysMounted && (exit ? phase === TransitionPhase.EXIT_DONE : !inProp)) {
199201
return null;
200202
}
201203

202204
// Render children
203-
return children(transitionState, phase);
205+
return typeof children === 'function' ? children(transitionState, phase) : children;
204206
}

0 commit comments

Comments
 (0)