@@ -9,7 +9,9 @@ import ReactDOM from 'react-dom';
9
9
import objectAssign from 'react/lib/Object.assign' ;
10
10
import ReactTransitionGroup from 'react-addons-transition-group' ;
11
11
12
- import ReplaceChildComponent from './ReactCSSTransitionReplaceChild' ;
12
+ import emptyFunction from 'react/node_modules/fbjs/lib/emptyFunction' ;
13
+
14
+ import ReplaceChildComponent from 'react/lib/ReactCSSTransitionGroupChild' ;
13
15
14
16
const reactCSSTransitionReplaceChild = React . createFactory ( ReplaceChildComponent ) ;
15
17
@@ -53,7 +55,8 @@ export default class ReactCSSTransitionReplace extends React.Component {
53
55
transitionAppear : false ,
54
56
transitionEnter : true ,
55
57
transitionLeave : true ,
56
- transitionHeight : true
58
+ transitionHeight : true ,
59
+ component : 'span'
57
60
} ;
58
61
59
62
state = {
@@ -73,58 +76,23 @@ export default class ReactCSSTransitionReplace extends React.Component {
73
76
} ) ;
74
77
}
75
78
76
- const transitionHeight = nextProps . transitionHeight ;
77
- const currentHeight = transitionHeight ? ReactDOM . findDOMNode ( this . refs . container ) . offsetHeight : 'auto' ;
78
-
79
- // The child was removed, so animate out.
80
- if ( ! nextChild ) {
81
- return this . setState ( {
82
- height : currentHeight ,
83
- currentChild : null
84
- } , ( ) => transitionHeight && this . setState ( { height : 0 } ) ) ;
85
- }
86
-
87
- // The child was replaced or added, setting a nextChild will eventually animate it in.
88
79
this . setState ( {
89
- height : currentHeight ,
90
- currentChild : null ,
91
80
nextChild
92
81
} ) ;
93
82
}
94
83
95
84
componentDidUpdate ( ) {
96
- const nextChild = this . refs . nextChild ;
97
-
98
- // If there is a next child we'll be animating it in soon, so change to its height.
99
- if ( nextChild && nextChild . offsetHeight !== this . state . height ) {
100
- this . setState ( {
101
- height : nextChild . offsetHeight
102
- } ) ;
103
- }
104
- }
105
-
106
- _childLeft = ( ) => {
107
- // Swap the children after the current child left.
108
- this . setState ( {
109
- currentChild : this . state . nextChild ,
110
- nextChild : null
111
- } ) ;
112
- }
113
-
114
- _childEntered = ( ) => {
115
- // The height animation would have finished, so switch back to auto.
116
- if ( this . props . transitionHeight ) {
117
- this . setState ( {
118
- height : 'auto'
119
- } ) ;
85
+ if ( this . state . nextChild ) {
86
+ this . enterNext ( ) ;
87
+ this . leaveCurrent ( ) ;
120
88
}
121
89
}
122
90
123
- _wrapChild = ( child ) => {
91
+ _wrapChild = ( child , moreProps ) => {
124
92
// We need to provide this childFactory so that
125
93
// ReactCSSTransitionReplaceChild can receive updates to name,
126
94
// enter, and leave while it is leaving.
127
- return reactCSSTransitionReplaceChild ( {
95
+ return reactCSSTransitionReplaceChild ( objectAssign ( {
128
96
name : this . props . transitionName ,
129
97
appear : this . props . transitionAppear ,
130
98
enter : this . props . transitionEnter ,
@@ -134,43 +102,58 @@ export default class ReactCSSTransitionReplace extends React.Component {
134
102
leaveTimeout : this . props . transitionLeaveTimeout ,
135
103
onEntered : this . _childEntered ,
136
104
onLeft : this . _childLeft
137
- } , child ) ;
105
+ } , moreProps ) , child ) ;
138
106
}
139
107
140
- render ( ) {
141
- let { style, className = '' } = this . props ;
142
- let nextChildShadow ;
143
-
144
- if ( this . props . transitionHeight ) {
145
- if ( this . state . nextChild ) {
146
- nextChildShadow = (
147
- < div ref = "nextChild" style = { { position : 'absolute' , visibility : 'hidden' } } >
148
- { this . state . nextChild }
149
- </ div >
150
- ) ;
151
- }
108
+ enterNext ( ) {
109
+ this . refs . next . componentWillEnter ( this . _handleDoneEntering ) ;
110
+ }
152
111
153
- const animatingHeight = this . state . height !== 'auto' ;
112
+ _handleDoneEntering = ( ) => {
113
+ this . setState ( {
114
+ currentChild : this . state . nextChild ,
115
+ nextChild : null
116
+ } ) ;
117
+ }
154
118
155
- if ( animatingHeight ) {
156
- className = `${ className } ${ this . props . transitionName } -height` ;
157
- }
119
+ leaveCurrent ( ) {
120
+ this . refs . curr . componentWillLeave ( this . _handleDoneLeaving ) ;
121
+ }
122
+
123
+ render ( ) {
124
+ let { currentChild, nextChild } = this . state ;
125
+ let containerProps = this . props ;
126
+ const childrenToRender = [ ] ;
127
+
128
+ if ( currentChild ) {
129
+ childrenToRender . push ( this . _wrapChild ( currentChild , {
130
+ ref : 'curr' , key : 'curr'
131
+ } ) ) ;
132
+ }
158
133
159
- style = objectAssign ( style || { } , {
160
- overflow : animatingHeight ? 'hidden' : 'visible' ,
161
- height : this . state . height ,
134
+ if ( nextChild ) {
135
+ const style = objectAssign ( { } , this . props . style , {
136
+ position : 'relative' ,
137
+ overflow : 'hidden' ,
162
138
display : 'block'
163
139
} ) ;
140
+
141
+ containerProps = objectAssign ( { } , this . props , { style} ) ;
142
+
143
+ const nextChildStyle = objectAssign ( { } , nextChild . props . style , {
144
+ position : 'absolute' ,
145
+ left : 0 ,
146
+ top : 0
147
+ } ) ;
148
+
149
+ childrenToRender . push (
150
+ React . createElement ( 'span' , {
151
+ style : nextChildStyle ,
152
+ key : 'next'
153
+ } , this . _wrapChild ( nextChild , { ref : 'next' } ) )
154
+ ) ;
164
155
}
165
156
166
- return (
167
- < span >
168
- { nextChildShadow }
169
- < ReactTransitionGroup ref = "container" { ...this . props } childFactory = { this . _wrapChild }
170
- style = { style } className = { className } >
171
- { this . state . currentChild }
172
- </ ReactTransitionGroup >
173
- </ span >
174
- ) ;
157
+ return React . createElement ( this . props . component , containerProps , childrenToRender ) ;
175
158
}
176
159
}
0 commit comments