UNPKG

5.51 kBJavaScriptView Raw
1import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
2import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
3import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
4import _typeof from "@babel/runtime/helpers/esm/typeof";
5
6/* eslint-disable react/default-props-match-prop-types, react/no-multi-comp, react/prop-types */
7import * as React from 'react';
8import { useRef } from 'react';
9import findDOMNode from "rc-util/es/Dom/findDOMNode";
10import { fillRef, supportRef } from "rc-util/es/ref";
11import classNames from 'classnames';
12import { getTransitionName, supportTransition } from './util/motion';
13import { STATUS_NONE, STEP_PREPARE, STEP_START } from './interface';
14import useStatus from './hooks/useStatus';
15import DomWrapper from './DomWrapper';
16import { isActive } from './hooks/useStepQueue';
17/**
18 * `transitionSupport` is used for none transition test case.
19 * Default we use browser transition event support check.
20 */
21
22export function genCSSMotion(config) {
23 var transitionSupport = config;
24
25 if (_typeof(config) === 'object') {
26 transitionSupport = config.transitionSupport;
27 }
28
29 function isSupportTransition(props) {
30 return !!(props.motionName && transitionSupport);
31 }
32
33 var CSSMotion = /*#__PURE__*/React.forwardRef(function (props, ref) {
34 var _props$visible = props.visible,
35 visible = _props$visible === void 0 ? true : _props$visible,
36 _props$removeOnLeave = props.removeOnLeave,
37 removeOnLeave = _props$removeOnLeave === void 0 ? true : _props$removeOnLeave,
38 forceRender = props.forceRender,
39 children = props.children,
40 motionName = props.motionName,
41 leavedClassName = props.leavedClassName,
42 eventProps = props.eventProps;
43 var supportMotion = isSupportTransition(props); // Ref to the react node, it may be a HTMLElement
44
45 var nodeRef = useRef(); // Ref to the dom wrapper in case ref can not pass to HTMLElement
46
47 var wrapperNodeRef = useRef();
48
49 function getDomElement() {
50 try {
51 // Here we're avoiding call for findDOMNode since it's deprecated
52 // in strict mode. We're calling it only when node ref is not
53 // an instance of DOM HTMLElement. Otherwise use
54 // findDOMNode as a final resort
55 return nodeRef.current instanceof HTMLElement ? nodeRef.current : findDOMNode(wrapperNodeRef.current);
56 } catch (e) {
57 // Only happen when `motionDeadline` trigger but element removed.
58 return null;
59 }
60 }
61
62 var _useStatus = useStatus(supportMotion, visible, getDomElement, props),
63 _useStatus2 = _slicedToArray(_useStatus, 4),
64 status = _useStatus2[0],
65 statusStep = _useStatus2[1],
66 statusStyle = _useStatus2[2],
67 mergedVisible = _useStatus2[3]; // Record whether content has rendered
68 // Will return null for un-rendered even when `removeOnLeave={false}`
69
70
71 var renderedRef = React.useRef(mergedVisible);
72
73 if (mergedVisible) {
74 renderedRef.current = true;
75 } // ====================== Refs ======================
76
77
78 var setNodeRef = React.useCallback(function (node) {
79 nodeRef.current = node;
80 fillRef(ref, node);
81 }, [ref]); // ===================== Render =====================
82
83 var motionChildren;
84
85 var mergedProps = _objectSpread(_objectSpread({}, eventProps), {}, {
86 visible: visible
87 });
88
89 if (!children) {
90 // No children
91 motionChildren = null;
92 } else if (status === STATUS_NONE || !isSupportTransition(props)) {
93 // Stable children
94 if (mergedVisible) {
95 motionChildren = children(_objectSpread({}, mergedProps), setNodeRef);
96 } else if (!removeOnLeave && renderedRef.current) {
97 motionChildren = children(_objectSpread(_objectSpread({}, mergedProps), {}, {
98 className: leavedClassName
99 }), setNodeRef);
100 } else if (forceRender) {
101 motionChildren = children(_objectSpread(_objectSpread({}, mergedProps), {}, {
102 style: {
103 display: 'none'
104 }
105 }), setNodeRef);
106 } else {
107 motionChildren = null;
108 }
109 } else {
110 var _classNames;
111
112 // In motion
113 var statusSuffix;
114
115 if (statusStep === STEP_PREPARE) {
116 statusSuffix = 'prepare';
117 } else if (isActive(statusStep)) {
118 statusSuffix = 'active';
119 } else if (statusStep === STEP_START) {
120 statusSuffix = 'start';
121 }
122
123 motionChildren = children(_objectSpread(_objectSpread({}, mergedProps), {}, {
124 className: classNames(getTransitionName(motionName, status), (_classNames = {}, _defineProperty(_classNames, getTransitionName(motionName, "".concat(status, "-").concat(statusSuffix)), statusSuffix), _defineProperty(_classNames, motionName, typeof motionName === 'string'), _classNames)),
125 style: statusStyle
126 }), setNodeRef);
127 } // Auto inject ref if child node not have `ref` props
128
129
130 if ( /*#__PURE__*/React.isValidElement(motionChildren) && supportRef(motionChildren)) {
131 var _motionChildren = motionChildren,
132 originNodeRef = _motionChildren.ref;
133
134 if (!originNodeRef) {
135 motionChildren = /*#__PURE__*/React.cloneElement(motionChildren, {
136 ref: setNodeRef
137 });
138 }
139 }
140
141 return /*#__PURE__*/React.createElement(DomWrapper, {
142 ref: wrapperNodeRef
143 }, motionChildren);
144 });
145 CSSMotion.displayName = 'CSSMotion';
146 return CSSMotion;
147}
148export default genCSSMotion(supportTransition);
\No newline at end of file