{description}
12 | 13 | {children} 14 |32 |45 |33 | Exposes simple components useful for defining entering and exiting 34 | transitions. React Transition Group is not an animation library 35 | like{' '} 36 | 37 | React-Motion 38 | 39 | , it does not animate styles by itself. Instead it exposes 40 | transition stages, manages classes and group elements and 41 | manipulates the DOM in useful ways, making the implementation of 42 | actual visual transitions much easier. 43 |
44 |
50 |
51 | {`
52 | # npm
53 | npm install react-transition-group --save
54 |
55 | # yarn
56 | yarn add react-transition-group
57 | `.trim()}
58 |
59 |
60 |
61 | 63 | Since react-transition-group is fairly small, the overhead of 64 | including the library in your application is negligible. However, 65 | in situations where it may be useful to benefit from an external 66 | CDN when bundling, link to the following CDN:{' '} 67 | 68 | https://unpkg.com/react-transition-group/dist/react-transition-group.js 69 | 70 |
71 |
28 | In some situations, like visual snapshot testing, it's helpful to
29 | disable transitions so they don't complicate the test, or introduce
30 | abitrary waits. To make this easier react-transition-group
{' '}
31 | exposes a way to globally toggle transitions. When set,{' '}
32 | all transitions, when toggled, will immediately switch
33 | to their entered or exited states as appropriate.
34 |
36 |
37 | {`
38 | import { config } from 'react-transition-group'
39 |
40 | config.disabled = true
41 | `.trim()}
42 |
43 |
44 | 45 |53 |46 | Note: This does not automatically disable 47 | animations. It only disabled waits in
52 |Transition
. You may 48 | also have to disable animation as appropriate for the library. 49 | example:{' '} 50 | Mocking in Velocity.js 51 |
29 | People often want to animate route transitions, which can result in
30 | delightful UX when used in moderation. The first instinct might be to
31 | use wrap all routes in TransitionGroup
, but that approach
32 | requires hacks and falls apart easily when used with trickier components
33 | of React Router like Redirect
. You should use{' '}
34 | CSSTransition
for each route and manage their{' '}
35 | in
prop on their own.
36 |
38 | The main challenge is the exit transition because React
39 | Router changes to a new route instantly, so we need to keep the old
40 | route around long enough to transition out of it. Fortunately,{' '}
41 | Route
42 | 's children
prop also accepts a function, which
43 | should not be confused with the render
prop! Unlike the{' '}
44 | render
prop, children
function runs whether
45 | the route is matched or not. React Router passes the object containing a{' '}
46 | match
object, which exists if the route matches, otherwise
47 | it's null
. This enables us to manage the in
{' '}
48 | prop of CSSTransition
based on the presence of{' '}
49 | match
.
50 |
52 | Exit transitions will cause the content of routes to linger until they 53 | disappear, which might pose some styling challenges. Make sure that 54 | routes don't affect each other's layout, for example you can remove them 55 | from the flow of the document by using absolute or fixed positioning. 56 |
57 |58 |67 |59 | Note: When using React Transition Group with React Router, make 60 | sure to avoid using the
66 |Switch
component because it only 61 | executes the first matchingRoute
. This would make the 62 | exit transition impossible to achieve because the exiting route will 63 | no longer match the current URL and thechildren
function 64 | won't execute. 65 |
{`<${p.replace('./', '')}>`}
81 | ))
82 | .reduce((acc, el, i) => {
83 | acc.push(el);
84 | if (i < metadata.composes.length - 1) {
85 | acc.push(', ');
86 | }
87 | return acc;
88 | }, [])}{' '}
89 | unless otherwise noted.
90 |
91 | >
92 | )}
93 | {name}
113 |
114 | {typeInfo}
124 | )}
125 | {defaultValue.value.trim()}
130 | 158 | {displayObj(renderObject(type.value))} 159 |160 | ); 161 | 162 | return name; 163 | case 'union': 164 | return type.value.reduce((current, val, i, list) => { 165 | val = typeof val === 'string' ? { name: val } : val; 166 | let item = this.renderType({ type: val }); 167 | 168 | if (React.isValidElement(item)) { 169 | item = React.cloneElement(item, { key: i }); 170 | } 171 | 172 | current = current.concat(item); 173 | 174 | return i === list.length - 1 ? current : current.concat(' | '); 175 | }, []); 176 | case 'array': 177 | case 'Array': { 178 | let child = this.renderType({ type: type.value }); 179 | 180 | return ( 181 | 182 | {'Array<'} 183 | {child} 184 | {'>'} 185 | 186 | ); 187 | } 188 | case 'enum': 189 | return this.renderEnum(type); 190 | case 'custom': 191 | return cleanDocletValue(doclets.type || name); 192 | default: 193 | return name; 194 | } 195 | } 196 | 197 | renderEnum(enumType) { 198 | const enumValues = enumType.value || []; 199 | return
{enumValues.join(' | ')}
;
200 | }
201 | }
202 |
203 | ComponentTemplate.propTypes = propTypes;
204 |
205 | function getDisplayTypeName(typeName) {
206 | if (typeName === 'func') {
207 | return 'function';
208 | } else if (typeName === 'bool') {
209 | return 'boolean';
210 | } else if (typeName === 'object') {
211 | return 'Object';
212 | }
213 |
214 | return typeName;
215 | }
216 |
217 | function renderObject(props) {
218 | return transform(
219 | props,
220 | (obj, val, key) => {
221 | obj[val.required ? key : key + '?'] = simpleType(val);
222 | },
223 | {}
224 | );
225 | }
226 |
227 | function simpleType(prop) {
228 | let type = prop.type || {};
229 | let name = getDisplayTypeName(type.name);
230 | let doclets = prop.doclets || {};
231 |
232 | switch (name) {
233 | case 'node':
234 | return 'any';
235 | case 'function':
236 | return 'Function';
237 | case 'elementType':
238 | return 'ReactClass