# All files / src/transition CSSTransition.tsx

100% Statements 91/91
100% Branches 2/2
100% Functions 1/1
100% Lines 91/91

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    921x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    31x
    31x
    31x
    31x
    31x
    31x
    31x
    31x
    31x
    31x
    31x
     "use client";
    import { cnb } from "cnbuilder";
    import { Children, cloneElement, type ReactElement } from "react";
    import {
      type CSSTransitionComponentImplementation,
      type CSSTransitionHookOptions,
    } from "./types.js";
    import { useCSSTransition } from "./useCSSTransition.js";

    /**
     * @typeParam E - An HTMLElement type used for the ref required for the
     * transition.
     * @remarks \@since 4.0.0
     */
    export interface CSSTransitionProps<E extends HTMLElement>
      extends CSSTransitionHookOptions<E>,
        CSSTransitionComponentImplementation<E> {}

    /**
     * **Client Component**
     *
     * This is a component implementation of the {@link useCSSTransition} hook that
     * implements the `temporary` behavior. Since this component uses the
     * `React.cloneElement` to inject the `ref` and `className` into the `children`,
     * it is recommended to use the hook instead.
     *
     * @example
     * Simple Example
     * ```tsx
     * import { ReactElement, useState } from "react";
     * import { Button, CSSTransition } from "@react-md/core":
     *
     * // pretend global styles:
     * //
     * // .opacity--enter {
     * //   opacity: 0;
     * //   transition: opacity .3s;
     * // }
     * //
     * // .opacity--enter-active {
     * //   opacity: 1;
     * // }
     * //
     * // .opacity--exit {
     * //   opacity: 1;
     * // }
     * //
     * // .opacity--exit-active {
     * //   opacity: 0;
     * //   transition: opacity .3s;
     * // }
     *
     * function Example(): ReactElement {
     *   const [transitionIn, setTransitionIn] = useState(false);
     *
     *   return (
     *     <>
     *       <Button onClick={() => setTransitionIn(!transitionIn)}>
     *         Toggle
     *       </Button>
     *       <CSSTransition
     *         timeout={300}
     *         className="opacity"
     *         temporary
     *         transitionIn={transitionIn}
     *       >
     *         <div>
     *           This is some content that will animate!
     *         </div>
     *       </CSSTransition>
     *     </>
     *   );
     * }
     * ```
     *
     * @typeParam E - An HTMLElement type used for the ref required for the
     * transition.
     * @remarks \@since 4.0.0
     */
    export function CSSTransition<E extends HTMLElement>(
      props: CSSTransitionProps<E>
    ): ReactElement | null {
      const { children, className, ...options } = props;
      const child = Children.only(children);
      const { elementProps, rendered } = useCSSTransition({
        ...options,
        className: cnb(child.props.className, className),
      });

      return <>{rendered && cloneElement(children, elementProps)}</>;
    }