Dashboard sipadu mbip
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 11KB

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