UNPKG

2.22 kBJavaScriptView Raw
1'use client';
2
3import * as React from 'react';
4/**
5 * Allows child elements to be transitioned in and out.
6 *
7 * Demos:
8 *
9 * - [Transitions](https://mui.com/base-ui/react-transitions/#hooks)
10 *
11 * API:
12 *
13 * - [useTransitionTrigger API](https://mui.com/base-ui/react-transitions/hooks-api/#use-transition-trigger)
14 */
15export function useTransitionTrigger(requestEnter) {
16 const [exitTransitionFinished, setExitTransitionFinished] = React.useState(true);
17 const hasPendingExitTransition = React.useRef(false);
18 const registeredTransitions = React.useRef(0);
19 const [hasTransition, setHasTransition] = React.useState(false);
20 const previousRequestEnter = React.useRef(requestEnter);
21 React.useEffect(() => {
22 if (!requestEnter &&
23 // checking registeredTransitions.current instead of hasTransition to avoid this effect re-firing whenever hasTransition changes
24 registeredTransitions.current > 0 &&
25 // prevents waiting for a pending transition right after mounting
26 previousRequestEnter.current !== requestEnter) {
27 hasPendingExitTransition.current = true;
28 setExitTransitionFinished(false);
29 }
30 previousRequestEnter.current = requestEnter;
31 }, [requestEnter]);
32 const handleExited = React.useCallback(() => {
33 hasPendingExitTransition.current = false;
34 setExitTransitionFinished(true);
35 }, []);
36 const registerTransition = React.useCallback(() => {
37 registeredTransitions.current += 1;
38 setHasTransition(true);
39 return () => {
40 registeredTransitions.current -= 1;
41 if (registeredTransitions.current === 0) {
42 setHasTransition(false);
43 }
44 };
45 }, []);
46 let hasExited;
47 if (!hasTransition) {
48 // If there are no transitions registered, the `exited` state is opposite of `requestEnter` immediately.
49 hasExited = !requestEnter;
50 } else if (requestEnter) {
51 hasExited = false;
52 } else {
53 hasExited = !hasPendingExitTransition.current && exitTransitionFinished;
54 }
55 const contextValue = React.useMemo(() => ({
56 requestedEnter: requestEnter,
57 onExited: handleExited,
58 registerTransition,
59 hasExited
60 }), [handleExited, requestEnter, registerTransition, hasExited]);
61 return {
62 contextValue,
63 hasExited
64 };
65}
\No newline at end of file