You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CSSTransition.js 12 KiB

3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. "use strict";
  2. exports.__esModule = true;
  3. exports.default = void 0;
  4. var PropTypes = _interopRequireWildcard(require("prop-types"));
  5. var _addClass = _interopRequireDefault(require("dom-helpers/class/addClass"));
  6. var _removeClass = _interopRequireDefault(require("dom-helpers/class/removeClass"));
  7. var _react = _interopRequireDefault(require("react"));
  8. var _Transition = _interopRequireDefault(require("./Transition"));
  9. var _PropTypes = require("./utils/PropTypes");
  10. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  11. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
  12. function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
  13. function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
  14. var addClass = function addClass(node, classes) {
  15. return node && classes && classes.split(' ').forEach(function (c) {
  16. return (0, _addClass.default)(node, c);
  17. });
  18. };
  19. var removeClass = function removeClass(node, classes) {
  20. return node && classes && classes.split(' ').forEach(function (c) {
  21. return (0, _removeClass.default)(node, c);
  22. });
  23. };
  24. /**
  25. * A transition component inspired by the excellent
  26. * [ng-animate](http://www.nganimate.org/) library, you should use it if you're
  27. * using CSS transitions or animations. It's built upon the
  28. * [`Transition`](https://reactcommunity.org/react-transition-group/transition)
  29. * component, so it inherits all of its props.
  30. *
  31. * `CSSTransition` applies a pair of class names during the `appear`, `enter`,
  32. * and `exit` states of the transition. The first class is applied and then a
  33. * second `*-active` class in order to activate the CSSS transition. After the
  34. * transition, matching `*-done` class names are applied to persist the
  35. * transition state.
  36. *
  37. * ```jsx
  38. * function App() {
  39. * const [inProp, setInProp] = useState(false);
  40. * return (
  41. * <div>
  42. * <CSSTransition in={inProp} timeout={200} classNames="my-node">
  43. * <div>
  44. * {"I'll receive my-node-* classes"}
  45. * </div>
  46. * </CSSTransition>
  47. * <button type="button" onClick={() => setInProp(true)}>
  48. * Click to Enter
  49. * </button>
  50. * </div>
  51. * );
  52. * }
  53. * ```
  54. *
  55. * When the `in` prop is set to `true`, the child component will first receive
  56. * the class `example-enter`, then the `example-enter-active` will be added in
  57. * the next tick. `CSSTransition` [forces a
  58. * reflow](https://github.com/reactjs/react-transition-group/blob/5007303e729a74be66a21c3e2205e4916821524b/src/CSSTransition.js#L208-L215)
  59. * between before adding the `example-enter-active`. This is an important trick
  60. * because it allows us to transition between `example-enter` and
  61. * `example-enter-active` even though they were added immediately one after
  62. * another. Most notably, this is what makes it possible for us to animate
  63. * _appearance_.
  64. *
  65. * ```css
  66. * .my-node-enter {
  67. * opacity: 0;
  68. * }
  69. * .my-node-enter-active {
  70. * opacity: 1;
  71. * transition: opacity 200ms;
  72. * }
  73. * .my-node-exit {
  74. * opacity: 1;
  75. * }
  76. * .my-node-exit-active {
  77. * opacity: 0;
  78. * transition: opacity: 200ms;
  79. * }
  80. * ```
  81. *
  82. * `*-active` classes represent which styles you want to animate **to**.
  83. */
  84. var CSSTransition =
  85. /*#__PURE__*/
  86. function (_React$Component) {
  87. _inheritsLoose(CSSTransition, _React$Component);
  88. function CSSTransition() {
  89. var _this;
  90. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  91. args[_key] = arguments[_key];
  92. }
  93. _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;
  94. _this.onEnter = function (node, appearing) {
  95. var _this$getClassNames = _this.getClassNames(appearing ? 'appear' : 'enter'),
  96. className = _this$getClassNames.className;
  97. _this.removeClasses(node, 'exit');
  98. addClass(node, className);
  99. if (_this.props.onEnter) {
  100. _this.props.onEnter(node, appearing);
  101. }
  102. };
  103. _this.onEntering = function (node, appearing) {
  104. var _this$getClassNames2 = _this.getClassNames(appearing ? 'appear' : 'enter'),
  105. activeClassName = _this$getClassNames2.activeClassName;
  106. _this.reflowAndAddClass(node, activeClassName);
  107. if (_this.props.onEntering) {
  108. _this.props.onEntering(node, appearing);
  109. }
  110. };
  111. _this.onEntered = function (node, appearing) {
  112. var appearClassName = _this.getClassNames('appear').doneClassName;
  113. var enterClassName = _this.getClassNames('enter').doneClassName;
  114. var doneClassName = appearing ? appearClassName + " " + enterClassName : enterClassName;
  115. _this.removeClasses(node, appearing ? 'appear' : 'enter');
  116. addClass(node, doneClassName);
  117. if (_this.props.onEntered) {
  118. _this.props.onEntered(node, appearing);
  119. }
  120. };
  121. _this.onExit = function (node) {
  122. var _this$getClassNames3 = _this.getClassNames('exit'),
  123. className = _this$getClassNames3.className;
  124. _this.removeClasses(node, 'appear');
  125. _this.removeClasses(node, 'enter');
  126. addClass(node, className);
  127. if (_this.props.onExit) {
  128. _this.props.onExit(node);
  129. }
  130. };
  131. _this.onExiting = function (node) {
  132. var _this$getClassNames4 = _this.getClassNames('exit'),
  133. activeClassName = _this$getClassNames4.activeClassName;
  134. _this.reflowAndAddClass(node, activeClassName);
  135. if (_this.props.onExiting) {
  136. _this.props.onExiting(node);
  137. }
  138. };
  139. _this.onExited = function (node) {
  140. var _this$getClassNames5 = _this.getClassNames('exit'),
  141. doneClassName = _this$getClassNames5.doneClassName;
  142. _this.removeClasses(node, 'exit');
  143. addClass(node, doneClassName);
  144. if (_this.props.onExited) {
  145. _this.props.onExited(node);
  146. }
  147. };
  148. _this.getClassNames = function (type) {
  149. var classNames = _this.props.classNames;
  150. var isStringClassNames = typeof classNames === 'string';
  151. var prefix = isStringClassNames && classNames ? classNames + '-' : '';
  152. var className = isStringClassNames ? prefix + type : classNames[type];
  153. var activeClassName = isStringClassNames ? className + '-active' : classNames[type + 'Active'];
  154. var doneClassName = isStringClassNames ? className + '-done' : classNames[type + 'Done'];
  155. return {
  156. className: className,
  157. activeClassName: activeClassName,
  158. doneClassName: doneClassName
  159. };
  160. };
  161. return _this;
  162. }
  163. var _proto = CSSTransition.prototype;
  164. _proto.removeClasses = function removeClasses(node, type) {
  165. var _this$getClassNames6 = this.getClassNames(type),
  166. className = _this$getClassNames6.className,
  167. activeClassName = _this$getClassNames6.activeClassName,
  168. doneClassName = _this$getClassNames6.doneClassName;
  169. className && removeClass(node, className);
  170. activeClassName && removeClass(node, activeClassName);
  171. doneClassName && removeClass(node, doneClassName);
  172. };
  173. _proto.reflowAndAddClass = function reflowAndAddClass(node, className) {
  174. // This is for to force a repaint,
  175. // which is necessary in order to transition styles when adding a class name.
  176. if (className) {
  177. /* eslint-disable no-unused-expressions */
  178. node && node.scrollTop;
  179. /* eslint-enable no-unused-expressions */
  180. addClass(node, className);
  181. }
  182. };
  183. _proto.render = function render() {
  184. var props = _extends({}, this.props);
  185. delete props.classNames;
  186. return _react.default.createElement(_Transition.default, _extends({}, props, {
  187. onEnter: this.onEnter,
  188. onEntered: this.onEntered,
  189. onEntering: this.onEntering,
  190. onExit: this.onExit,
  191. onExiting: this.onExiting,
  192. onExited: this.onExited
  193. }));
  194. };
  195. return CSSTransition;
  196. }(_react.default.Component);
  197. CSSTransition.defaultProps = {
  198. classNames: ''
  199. };
  200. CSSTransition.propTypes = process.env.NODE_ENV !== "production" ? _extends({}, _Transition.default.propTypes, {
  201. /**
  202. * The animation classNames applied to the component as it enters, exits or
  203. * has finished the transition. A single name can be provided and it will be
  204. * suffixed for each stage: e.g.
  205. *
  206. * `classNames="fade"` applies `fade-enter`, `fade-enter-active`,
  207. * `fade-enter-done`, `fade-exit`, `fade-exit-active`, `fade-exit-done`,
  208. * `fade-appear`, `fade-appear-active`, and `fade-appear-done`.
  209. *
  210. * **Note**: `fade-appear-done` and `fade-enter-done` will _both_ be applied.
  211. * This allows you to define different behavior for when appearing is done and
  212. * when regular entering is done, using selectors like
  213. * `.fade-enter-done:not(.fade-appear-done)`. For example, you could apply an
  214. * epic entrance animation when element first appears in the DOM using
  215. * [Animate.css](https://daneden.github.io/animate.css/). Otherwise you can
  216. * simply use `fade-enter-done` for defining both cases.
  217. *
  218. * Each individual classNames can also be specified independently like:
  219. *
  220. * ```js
  221. * classNames={{
  222. * appear: 'my-appear',
  223. * appearActive: 'my-active-appear',
  224. * appearDone: 'my-done-appear',
  225. * enter: 'my-enter',
  226. * enterActive: 'my-active-enter',
  227. * enterDone: 'my-done-enter',
  228. * exit: 'my-exit',
  229. * exitActive: 'my-active-exit',
  230. * exitDone: 'my-done-exit',
  231. * }}
  232. * ```
  233. *
  234. * If you want to set these classes using CSS Modules:
  235. *
  236. * ```js
  237. * import styles from './styles.css';
  238. * ```
  239. *
  240. * you might want to use camelCase in your CSS file, that way could simply
  241. * spread them instead of listing them one by one:
  242. *
  243. * ```js
  244. * classNames={{ ...styles }}
  245. * ```
  246. *
  247. * @type {string | {
  248. * appear?: string,
  249. * appearActive?: string,
  250. * appearDone?: string,
  251. * enter?: string,
  252. * enterActive?: string,
  253. * enterDone?: string,
  254. * exit?: string,
  255. * exitActive?: string,
  256. * exitDone?: string,
  257. * }}
  258. */
  259. classNames: _PropTypes.classNamesShape,
  260. /**
  261. * A `<Transition>` callback fired immediately after the 'enter' or 'appear' class is
  262. * applied.
  263. *
  264. * @type Function(node: HtmlElement, isAppearing: bool)
  265. */
  266. onEnter: PropTypes.func,
  267. /**
  268. * A `<Transition>` callback fired immediately after the 'enter-active' or
  269. * 'appear-active' class is applied.
  270. *
  271. * @type Function(node: HtmlElement, isAppearing: bool)
  272. */
  273. onEntering: PropTypes.func,
  274. /**
  275. * A `<Transition>` callback fired immediately after the 'enter' or
  276. * 'appear' classes are **removed** and the `done` class is added to the DOM node.
  277. *
  278. * @type Function(node: HtmlElement, isAppearing: bool)
  279. */
  280. onEntered: PropTypes.func,
  281. /**
  282. * A `<Transition>` callback fired immediately after the 'exit' class is
  283. * applied.
  284. *
  285. * @type Function(node: HtmlElement)
  286. */
  287. onExit: PropTypes.func,
  288. /**
  289. * A `<Transition>` callback fired immediately after the 'exit-active' is applied.
  290. *
  291. * @type Function(node: HtmlElement)
  292. */
  293. onExiting: PropTypes.func,
  294. /**
  295. * A `<Transition>` callback fired immediately after the 'exit' classes
  296. * are **removed** and the `exit-done` class is added to the DOM node.
  297. *
  298. * @type Function(node: HtmlElement)
  299. */
  300. onExited: PropTypes.func
  301. }) : {};
  302. var _default = CSSTransition;
  303. exports.default = _default;
  304. module.exports = exports["default"];