3
3
A [ React] ( http://facebook.github.io/react/ ) component to animate replacing one element with another.
4
4
5
5
While [ ` ReactCSSTransitionGroup ` ] ( https://facebook.github.io/react/docs/animation.html ) does a great job
6
- of animating changes to a list of elements it does not allow removing an element, waiting for its leave
7
- transition to complete, and then adding a new element with its enter transition. This component is
8
- designed to do exactly that with an API closely following the
9
- [ ` ReactCSSTransitionGroup ` ] ( https://facebook.github.io/react/docs/animation.html ) API.
6
+ of animating changes to a list of components and can even be used to animate the replacement of one item
7
+ with another, proper handling of the container height in the latter case is not built in. This component
8
+ is designed to do exactly that with an API closely following that of ` ReactCSSTransitionGroup ` .
9
+
10
+ Using ` react-css-transition-replace ` provides two distinct benefits:
11
+
12
+ - It automatically handles the positioning of the animated components internally, and
13
+ - * allows changes in the height of container to be handled and animated with ease when
14
+ various content heights differ, even when absolute positioning is used.*
15
+
16
+ Animations are fully configurable with CSS, including having the entering component wait to enter until
17
+ the leaving component's animation completes. Following suit with the
18
+ [ React.js API] ( https://facebook.github.io/react/docs/animation.html#getting-started ) the one caveat is
19
+ that the transition duration must be specified in JavaScript as well as CSS.
10
20
11
21
12
22
## Installation
@@ -17,65 +27,123 @@ Install via `npm`:
17
27
npm install --save react-css-transition-replace
18
28
```
19
29
20
- ** Note:** This version requires ` React 0.14.0-rc1 ` , for ` React 0.13.x ` use version ` 0.1.4 ` of this library.
21
-
22
30
23
31
## Usage
24
32
25
- A ` ReactCSSTransitionReplace ` element can only have a single child. Other than that, the basic usage
26
- follows the exact same API as ` ReactCSSTransitionGroup ` :
33
+ A ` ReactCSSTransitionReplace ` component can only have a single child. Other than that, the basic usage
34
+ follows the exact same API as ` ReactCSSTransitionGroup ` . When the ` key ` of the child component changes, the
35
+ previous component is animated out and the new component animated in. During this process:
36
+
37
+ - The leaving component continues to be rendered as usual with ` static ` positioning.
38
+ - The entering component is positioned on top of the leaving component with ` absolute ` positioning.
39
+ - The height of the container is set to that of the leaving component, and then immediately to that of the
40
+ entering component, and the ` {animation-name}-height ` class is applied to it.
41
+
42
+ This provides many possibilities for animating the replacement as illustrated in the following examples.
43
+
44
+ ### Cross-fading two components
45
+
46
+ The ` ReactCSSTransitionReplace ` component is used exactly like its ` ReactCSSTransitionGroup ` counterpart:
27
47
28
48
``` javascript
29
49
import ReactCSSTransitionReplace from ' react-css-transition-replace' ;
30
50
31
51
render () {
32
52
return (
33
- < div>
34
- < ReactCSSTransitionReplace transitionName= " fade" >
35
- < SomeComponent / >
36
- < / ReactCSSTransitionReplace>
37
- < / div>
53
+ < ReactCSSTransitionReplace transitionName= " cross-fade"
54
+ transitionEnterTimeout= {1000 } transitionLeaveTimeout= {1000 }>
55
+ < SomeComponent key= " uniqueValue" / >
56
+ < / ReactCSSTransitionReplace>
38
57
);
39
58
}
40
59
```
41
60
42
- This will use the CSS styles below to apply transitions to the child elements that leave and enter.
43
- The entering element will only be added to the DOM flow once the leaving element has been removed.
61
+ To realize cross-fading of two components all that remains is to define the enter and leave opacity
62
+ transitions in the associated CSS classes:
44
63
45
64
``` css
46
- .fade-leave {
65
+ .cross- fade-leave {
47
66
opacity : 1 ;
48
67
}
49
- .fade-leave.fade-leave-active {
50
- opacity : 0.01 ;
51
- transition : opacity . 1s ease-in ;
68
+ .cross- fade-leave.cross- fade-leave-active {
69
+ opacity : 0 ;
70
+ transition : opacity 1s ease-in ;
52
71
}
53
72
54
- .fade-enter {
55
- opacity : 0.01 ;
73
+ .cross- fade-enter {
74
+ opacity : 0 ;
56
75
}
57
- .fade-enter.fade-enter-active {
76
+ .cross- fade-enter.cross- fade-enter-active {
58
77
opacity : 1 ;
59
- transition : opacity .2 s ease-in ;
78
+ transition : opacity 1 s ease-in ;
60
79
}
61
80
62
- .fade-height {
63
- transition : height .15 s ease-in-out ;
81
+ .cross- fade-height {
82
+ transition : height 1 s ease-in-out ;
64
83
}
65
84
```
66
85
67
- Note the additional ` .fade-height ` class. This will also animate the change in the container
68
- height based on the content transitioning out/in.
86
+ Note the additional ` .cross-fade-height ` class. This indicates how the container height is to be
87
+ animated if the heights of the entering and leaving components are not the same.
88
+
89
+ ### Fade out, then fade in
69
90
70
- It the ` .fade-height ` class is not specified the change in container height will not be animated.
71
- If this is the desired result the height transition can be disabled entirely by setting the
72
- ` transitionHeight ` prop to ` false ` :
91
+ To fade a component out and wait for its transition to complete before fading in the next, simply
92
+ add a delay to the ` enter ` transition.
93
+
94
+ ``` css
95
+ .fade-wait-leave {
96
+ opacity : 1 ;
97
+ }
98
+ .fade-wait-leave.fade-wait-leave-active {
99
+ opacity : 0 ;
100
+ transition : opacity .4s ease-in ;
101
+ }
73
102
103
+ .fade-wait-enter {
104
+ opacity : 0 ;
105
+ }
106
+ .fade-wait-enter.fade-wait-enter-active {
107
+ opacity : 1 ;
108
+ /* Delay the enter animation until the leave completes */
109
+ transition : opacity .4s ease-in .6s ;
110
+ }
111
+
112
+ .fade-wait-height {
113
+ transition : height .6s ease-in-out ;
114
+ }
74
115
```
75
- <ReactCSSTransitionReplace transitionName="fade" transitionHeight={false}>
116
+
117
+ * Note:* The ` transitionEnterTimeout ` specified in the JS must be long enough to allow for the delay and
118
+ the duration of the transition. In this case:
119
+
120
+ ``` javascript
121
+ < ReactCSSTransitionReplace transitionName= " fade-wait" transitionEnterTimeout= {1000 } transitionLeaveTimeout= {400 }>
76
122
```
77
123
78
- The ` transitionEnter ` , ` transitionLeave ` and ` transitionAppear ` props are also still available.
124
+
125
+ #### Disabling the height transition
126
+
127
+ If the ` .*-height ` class is not specified the change in container height will not be animated but rather
128
+ jump to the height of the entering component instantaneously. While this is probably not a very useful
129
+ scenario in practice, doing so does not break anything and still avoids absolute positioning related
130
+ height issues.
131
+
132
+
133
+ ## Tips
134
+
135
+ - In general animating ` block ` or ` inline-block ` level elements is more stable that ` inline ` elements. If the
136
+ height changes in random ways ensure that there isn't a ` span ` or other inline element used as the outer
137
+ element of the components being animated.
138
+ - The ` overflow ` of the container is set to ` 'hidden' ` automatically, which changes the behaviour of
139
+ [ collapsing margins] ( https://css-tricks.com/what-you-should-know-about-collapsing-margins/ ) from the default
140
+ ` 'visible' ` . This may cause a glitch in the height at the start or end of animations. To avoid this you can:
141
+ - Keep the overflow hidden permanently with custom styles/classes if there won't be adverse side-effects.
142
+ - Only use
143
+ [ Single-direction margin declarations] ( http://csswizardry.com/2012/06/single-direction-margin-declarations/ )
144
+ to avoid any collapsing margins.
145
+ - Turn this feature off by setting the ` overflowHidden={false} ` prop when hidden overflow is not needed,
146
+ for example when transitions are in place and content is of the same height.
79
147
80
148
81
149
## Contributing
0 commit comments