TransitionGroup.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
  2. import _extends from "@babel/runtime/helpers/esm/extends";
  3. import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized";
  4. import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose";
  5. import PropTypes from 'prop-types';
  6. import React from 'react';
  7. import TransitionGroupContext from './TransitionGroupContext';
  8. import { getChildMapping, getInitialChildMapping, getNextChildMapping } from './utils/ChildMapping';
  9. var values = Object.values || function (obj) {
  10. return Object.keys(obj).map(function (k) {
  11. return obj[k];
  12. });
  13. };
  14. var defaultProps = {
  15. component: 'div',
  16. childFactory: function childFactory(child) {
  17. return child;
  18. }
  19. };
  20. /**
  21. * The `<TransitionGroup>` component manages a set of transition components
  22. * (`<Transition>` and `<CSSTransition>`) in a list. Like with the transition
  23. * components, `<TransitionGroup>` is a state machine for managing the mounting
  24. * and unmounting of components over time.
  25. *
  26. * Consider the example below. As items are removed or added to the TodoList the
  27. * `in` prop is toggled automatically by the `<TransitionGroup>`.
  28. *
  29. * Note that `<TransitionGroup>` does not define any animation behavior!
  30. * Exactly _how_ a list item animates is up to the individual transition
  31. * component. This means you can mix and match animations across different list
  32. * items.
  33. */
  34. var TransitionGroup = /*#__PURE__*/function (_React$Component) {
  35. _inheritsLoose(TransitionGroup, _React$Component);
  36. function TransitionGroup(props, context) {
  37. var _this;
  38. _this = _React$Component.call(this, props, context) || this;
  39. var handleExited = _this.handleExited.bind(_assertThisInitialized(_this)); // Initial children should all be entering, dependent on appear
  40. _this.state = {
  41. contextValue: {
  42. isMounting: true
  43. },
  44. handleExited: handleExited,
  45. firstRender: true
  46. };
  47. return _this;
  48. }
  49. var _proto = TransitionGroup.prototype;
  50. _proto.componentDidMount = function componentDidMount() {
  51. this.mounted = true;
  52. this.setState({
  53. contextValue: {
  54. isMounting: false
  55. }
  56. });
  57. };
  58. _proto.componentWillUnmount = function componentWillUnmount() {
  59. this.mounted = false;
  60. };
  61. TransitionGroup.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, _ref) {
  62. var prevChildMapping = _ref.children,
  63. handleExited = _ref.handleExited,
  64. firstRender = _ref.firstRender;
  65. return {
  66. children: firstRender ? getInitialChildMapping(nextProps, handleExited) : getNextChildMapping(nextProps, prevChildMapping, handleExited),
  67. firstRender: false
  68. };
  69. } // node is `undefined` when user provided `nodeRef` prop
  70. ;
  71. _proto.handleExited = function handleExited(child, node) {
  72. var currentChildMapping = getChildMapping(this.props.children);
  73. if (child.key in currentChildMapping) return;
  74. if (child.props.onExited) {
  75. child.props.onExited(node);
  76. }
  77. if (this.mounted) {
  78. this.setState(function (state) {
  79. var children = _extends({}, state.children);
  80. delete children[child.key];
  81. return {
  82. children: children
  83. };
  84. });
  85. }
  86. };
  87. _proto.render = function render() {
  88. var _this$props = this.props,
  89. Component = _this$props.component,
  90. childFactory = _this$props.childFactory,
  91. props = _objectWithoutPropertiesLoose(_this$props, ["component", "childFactory"]);
  92. var contextValue = this.state.contextValue;
  93. var children = values(this.state.children).map(childFactory);
  94. delete props.appear;
  95. delete props.enter;
  96. delete props.exit;
  97. if (Component === null) {
  98. return /*#__PURE__*/React.createElement(TransitionGroupContext.Provider, {
  99. value: contextValue
  100. }, children);
  101. }
  102. return /*#__PURE__*/React.createElement(TransitionGroupContext.Provider, {
  103. value: contextValue
  104. }, /*#__PURE__*/React.createElement(Component, props, children));
  105. };
  106. return TransitionGroup;
  107. }(React.Component);
  108. TransitionGroup.propTypes = process.env.NODE_ENV !== "production" ? {
  109. /**
  110. * `<TransitionGroup>` renders a `<div>` by default. You can change this
  111. * behavior by providing a `component` prop.
  112. * If you use React v16+ and would like to avoid a wrapping `<div>` element
  113. * you can pass in `component={null}`. This is useful if the wrapping div
  114. * borks your css styles.
  115. */
  116. component: PropTypes.any,
  117. /**
  118. * A set of `<Transition>` components, that are toggled `in` and out as they
  119. * leave. the `<TransitionGroup>` will inject specific transition props, so
  120. * remember to spread them through if you are wrapping the `<Transition>` as
  121. * with our `<Fade>` example.
  122. *
  123. * While this component is meant for multiple `Transition` or `CSSTransition`
  124. * children, sometimes you may want to have a single transition child with
  125. * content that you want to be transitioned out and in when you change it
  126. * (e.g. routes, images etc.) In that case you can change the `key` prop of
  127. * the transition child as you change its content, this will cause
  128. * `TransitionGroup` to transition the child out and back in.
  129. */
  130. children: PropTypes.node,
  131. /**
  132. * A convenience prop that enables or disables appear animations
  133. * for all children. Note that specifying this will override any defaults set
  134. * on individual children Transitions.
  135. */
  136. appear: PropTypes.bool,
  137. /**
  138. * A convenience prop that enables or disables enter animations
  139. * for all children. Note that specifying this will override any defaults set
  140. * on individual children Transitions.
  141. */
  142. enter: PropTypes.bool,
  143. /**
  144. * A convenience prop that enables or disables exit animations
  145. * for all children. Note that specifying this will override any defaults set
  146. * on individual children Transitions.
  147. */
  148. exit: PropTypes.bool,
  149. /**
  150. * You may need to apply reactive updates to a child as it is exiting.
  151. * This is generally done by using `cloneElement` however in the case of an exiting
  152. * child the element has already been removed and not accessible to the consumer.
  153. *
  154. * If you do need to update a child as it leaves you can provide a `childFactory`
  155. * to wrap every child, even the ones that are leaving.
  156. *
  157. * @type Function(child: ReactElement) -> ReactElement
  158. */
  159. childFactory: PropTypes.func
  160. } : {};
  161. TransitionGroup.defaultProps = defaultProps;
  162. export default TransitionGroup;