1 | 'use client';
|
2 |
|
3 | import * as React from 'react';
|
4 | import PropTypes from 'prop-types';
|
5 | import { Transition } from 'react-transition-group';
|
6 | import chainPropTypes from '@mui/utils/chainPropTypes';
|
7 | import HTMLElementType from '@mui/utils/HTMLElementType';
|
8 | import elementAcceptingRef from '@mui/utils/elementAcceptingRef';
|
9 | import getReactElementRef from '@mui/utils/getReactElementRef';
|
10 | import debounce from "../utils/debounce.js";
|
11 | import useForkRef from "../utils/useForkRef.js";
|
12 | import { useTheme } from "../zero-styled/index.js";
|
13 | import { reflow, getTransitionProps } from "../transitions/utils.js";
|
14 | import { ownerWindow } from "../utils/index.js";
|
15 |
|
16 |
|
17 |
|
18 | import { jsx as _jsx } from "react/jsx-runtime";
|
19 | function getTranslateValue(direction, node, resolvedContainer) {
|
20 | const rect = node.getBoundingClientRect();
|
21 | const containerRect = resolvedContainer && resolvedContainer.getBoundingClientRect();
|
22 | const containerWindow = ownerWindow(node);
|
23 | let transform;
|
24 | if (node.fakeTransform) {
|
25 | transform = node.fakeTransform;
|
26 | } else {
|
27 | const computedStyle = containerWindow.getComputedStyle(node);
|
28 | transform = computedStyle.getPropertyValue('-webkit-transform') || computedStyle.getPropertyValue('transform');
|
29 | }
|
30 | let offsetX = 0;
|
31 | let offsetY = 0;
|
32 | if (transform && transform !== 'none' && typeof transform === 'string') {
|
33 | const transformValues = transform.split('(')[1].split(')')[0].split(',');
|
34 | offsetX = parseInt(transformValues[4], 10);
|
35 | offsetY = parseInt(transformValues[5], 10);
|
36 | }
|
37 | if (direction === 'left') {
|
38 | if (containerRect) {
|
39 | return `translateX(${containerRect.right + offsetX - rect.left}px)`;
|
40 | }
|
41 | return `translateX(${containerWindow.innerWidth + offsetX - rect.left}px)`;
|
42 | }
|
43 | if (direction === 'right') {
|
44 | if (containerRect) {
|
45 | return `translateX(-${rect.right - containerRect.left - offsetX}px)`;
|
46 | }
|
47 | return `translateX(-${rect.left + rect.width - offsetX}px)`;
|
48 | }
|
49 | if (direction === 'up') {
|
50 | if (containerRect) {
|
51 | return `translateY(${containerRect.bottom + offsetY - rect.top}px)`;
|
52 | }
|
53 | return `translateY(${containerWindow.innerHeight + offsetY - rect.top}px)`;
|
54 | }
|
55 |
|
56 |
|
57 | if (containerRect) {
|
58 | return `translateY(-${rect.top - containerRect.top + rect.height - offsetY}px)`;
|
59 | }
|
60 | return `translateY(-${rect.top + rect.height - offsetY}px)`;
|
61 | }
|
62 | function resolveContainer(containerPropProp) {
|
63 | return typeof containerPropProp === 'function' ? containerPropProp() : containerPropProp;
|
64 | }
|
65 | export function setTranslateValue(direction, node, containerProp) {
|
66 | const resolvedContainer = resolveContainer(containerProp);
|
67 | const transform = getTranslateValue(direction, node, resolvedContainer);
|
68 | if (transform) {
|
69 | node.style.webkitTransform = transform;
|
70 | node.style.transform = transform;
|
71 | }
|
72 | }
|
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 | const Slide = React.forwardRef(function Slide(props, ref) {
|
79 | const theme = useTheme();
|
80 | const defaultEasing = {
|
81 | enter: theme.transitions.easing.easeOut,
|
82 | exit: theme.transitions.easing.sharp
|
83 | };
|
84 | const defaultTimeout = {
|
85 | enter: theme.transitions.duration.enteringScreen,
|
86 | exit: theme.transitions.duration.leavingScreen
|
87 | };
|
88 | const {
|
89 | addEndListener,
|
90 | appear = true,
|
91 | children,
|
92 | container: containerProp,
|
93 | direction = 'down',
|
94 | easing: easingProp = defaultEasing,
|
95 | in: inProp,
|
96 | onEnter,
|
97 | onEntered,
|
98 | onEntering,
|
99 | onExit,
|
100 | onExited,
|
101 | onExiting,
|
102 | style,
|
103 | timeout = defaultTimeout,
|
104 |
|
105 | TransitionComponent = Transition,
|
106 | ...other
|
107 | } = props;
|
108 | const childrenRef = React.useRef(null);
|
109 | const handleRef = useForkRef(getReactElementRef(children), childrenRef, ref);
|
110 | const normalizedTransitionCallback = callback => isAppearing => {
|
111 | if (callback) {
|
112 |
|
113 | if (isAppearing === undefined) {
|
114 | callback(childrenRef.current);
|
115 | } else {
|
116 | callback(childrenRef.current, isAppearing);
|
117 | }
|
118 | }
|
119 | };
|
120 | const handleEnter = normalizedTransitionCallback((node, isAppearing) => {
|
121 | setTranslateValue(direction, node, containerProp);
|
122 | reflow(node);
|
123 | if (onEnter) {
|
124 | onEnter(node, isAppearing);
|
125 | }
|
126 | });
|
127 | const handleEntering = normalizedTransitionCallback((node, isAppearing) => {
|
128 | const transitionProps = getTransitionProps({
|
129 | timeout,
|
130 | style,
|
131 | easing: easingProp
|
132 | }, {
|
133 | mode: 'enter'
|
134 | });
|
135 | node.style.webkitTransition = theme.transitions.create('-webkit-transform', {
|
136 | ...transitionProps
|
137 | });
|
138 | node.style.transition = theme.transitions.create('transform', {
|
139 | ...transitionProps
|
140 | });
|
141 | node.style.webkitTransform = 'none';
|
142 | node.style.transform = 'none';
|
143 | if (onEntering) {
|
144 | onEntering(node, isAppearing);
|
145 | }
|
146 | });
|
147 | const handleEntered = normalizedTransitionCallback(onEntered);
|
148 | const handleExiting = normalizedTransitionCallback(onExiting);
|
149 | const handleExit = normalizedTransitionCallback(node => {
|
150 | const transitionProps = getTransitionProps({
|
151 | timeout,
|
152 | style,
|
153 | easing: easingProp
|
154 | }, {
|
155 | mode: 'exit'
|
156 | });
|
157 | node.style.webkitTransition = theme.transitions.create('-webkit-transform', transitionProps);
|
158 | node.style.transition = theme.transitions.create('transform', transitionProps);
|
159 | setTranslateValue(direction, node, containerProp);
|
160 | if (onExit) {
|
161 | onExit(node);
|
162 | }
|
163 | });
|
164 | const handleExited = normalizedTransitionCallback(node => {
|
165 |
|
166 | node.style.webkitTransition = '';
|
167 | node.style.transition = '';
|
168 | if (onExited) {
|
169 | onExited(node);
|
170 | }
|
171 | });
|
172 | const handleAddEndListener = next => {
|
173 | if (addEndListener) {
|
174 |
|
175 | addEndListener(childrenRef.current, next);
|
176 | }
|
177 | };
|
178 | const updatePosition = React.useCallback(() => {
|
179 | if (childrenRef.current) {
|
180 | setTranslateValue(direction, childrenRef.current, containerProp);
|
181 | }
|
182 | }, [direction, containerProp]);
|
183 | React.useEffect(() => {
|
184 |
|
185 | if (inProp || direction === 'down' || direction === 'right') {
|
186 | return undefined;
|
187 | }
|
188 | const handleResize = debounce(() => {
|
189 | if (childrenRef.current) {
|
190 | setTranslateValue(direction, childrenRef.current, containerProp);
|
191 | }
|
192 | });
|
193 | const containerWindow = ownerWindow(childrenRef.current);
|
194 | containerWindow.addEventListener('resize', handleResize);
|
195 | return () => {
|
196 | handleResize.clear();
|
197 | containerWindow.removeEventListener('resize', handleResize);
|
198 | };
|
199 | }, [direction, inProp, containerProp]);
|
200 | React.useEffect(() => {
|
201 | if (!inProp) {
|
202 |
|
203 |
|
204 | updatePosition();
|
205 | }
|
206 | }, [inProp, updatePosition]);
|
207 | return _jsx(TransitionComponent, {
|
208 | nodeRef: childrenRef,
|
209 | onEnter: handleEnter,
|
210 | onEntered: handleEntered,
|
211 | onEntering: handleEntering,
|
212 | onExit: handleExit,
|
213 | onExited: handleExited,
|
214 | onExiting: handleExiting,
|
215 | addEndListener: handleAddEndListener,
|
216 | appear: appear,
|
217 | in: inProp,
|
218 | timeout: timeout,
|
219 | ...other,
|
220 | children: (state, childProps) => {
|
221 | return React.cloneElement(children, {
|
222 | ref: handleRef,
|
223 | style: {
|
224 | visibility: state === 'exited' && !inProp ? 'hidden' : undefined,
|
225 | ...style,
|
226 | ...children.props.style
|
227 | },
|
228 | ...childProps
|
229 | });
|
230 | }
|
231 | });
|
232 | });
|
233 | process.env.NODE_ENV !== "production" ? Slide.propTypes = {
|
234 |
|
235 |
|
236 |
|
237 |
|
238 | |
239 |
|
240 |
|
241 |
|
242 |
|
243 | addEndListener: PropTypes.func,
|
244 | |
245 |
|
246 |
|
247 |
|
248 |
|
249 | appear: PropTypes.bool,
|
250 | |
251 |
|
252 |
|
253 | children: elementAcceptingRef.isRequired,
|
254 | |
255 |
|
256 |
|
257 |
|
258 | container: chainPropTypes(PropTypes.oneOfType([HTMLElementType, PropTypes.func]), props => {
|
259 | if (props.open) {
|
260 | const resolvedContainer = resolveContainer(props.container);
|
261 | if (resolvedContainer && resolvedContainer.nodeType === 1) {
|
262 | const box = resolvedContainer.getBoundingClientRect();
|
263 | if (process.env.NODE_ENV !== 'test' && box.top === 0 && box.left === 0 && box.right === 0 && box.bottom === 0) {
|
264 | return new Error(['MUI: The `container` prop provided to the component is invalid.', 'The anchor element should be part of the document layout.', "Make sure the element is present in the document or that it's not display none."].join('\n'));
|
265 | }
|
266 | } else if (!resolvedContainer || typeof resolvedContainer.getBoundingClientRect !== 'function' || resolvedContainer.contextElement != null && resolvedContainer.contextElement.nodeType !== 1) {
|
267 | return new Error(['MUI: The `container` prop provided to the component is invalid.', 'It should be an HTML element instance.'].join('\n'));
|
268 | }
|
269 | }
|
270 | return null;
|
271 | }),
|
272 | |
273 |
|
274 |
|
275 |
|
276 | direction: PropTypes.oneOf(['down', 'left', 'right', 'up']),
|
277 | |
278 |
|
279 |
|
280 |
|
281 |
|
282 |
|
283 |
|
284 |
|
285 | easing: PropTypes.oneOfType([PropTypes.shape({
|
286 | enter: PropTypes.string,
|
287 | exit: PropTypes.string
|
288 | }), PropTypes.string]),
|
289 | |
290 |
|
291 |
|
292 | in: PropTypes.bool,
|
293 | |
294 |
|
295 |
|
296 | onEnter: PropTypes.func,
|
297 | |
298 |
|
299 |
|
300 | onEntered: PropTypes.func,
|
301 | |
302 |
|
303 |
|
304 | onEntering: PropTypes.func,
|
305 | |
306 |
|
307 |
|
308 | onExit: PropTypes.func,
|
309 | |
310 |
|
311 |
|
312 | onExited: PropTypes.func,
|
313 | |
314 |
|
315 |
|
316 | onExiting: PropTypes.func,
|
317 | |
318 |
|
319 |
|
320 | style: PropTypes.object,
|
321 | |
322 |
|
323 |
|
324 |
|
325 |
|
326 |
|
327 |
|
328 |
|
329 | timeout: PropTypes.oneOfType([PropTypes.number, PropTypes.shape({
|
330 | appear: PropTypes.number,
|
331 | enter: PropTypes.number,
|
332 | exit: PropTypes.number
|
333 | })])
|
334 | } : void 0;
|
335 | export default Slide; |
\ | No newline at end of file |