# All files Collapse.tsx

0% Statements 0/85
0% Branches 0/1
0% Functions 0/1
0% Lines 0/85

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

     "use client";
    import { cnb } from "cnbuilder";
    import type { ReactElement } from "react";
    import { Children, cloneElement } from "react";
    import type {
      CollapseElementProps,
      CollapseTransitionHookOptions,
    } from "./useCollapseTransition.js";
    import { useCollapseTransition } from "./useCollapseTransition.js";

    /**
     * @typeParam E - An HTMLElement type used for the ref required for the
     * transition.
     *
     * @remarks
     * \@since 2.0.0
     * \@since 4.0.0 Updated for the new CSS Transition API.
     */
    export interface CollapseProps<E extends HTMLElement>
      extends Omit<CollapseTransitionHookOptions<E>, "transitionIn"> {
      /**
       * The child element that should have a `ref` and the `style`, `className` and
       * `hidden` props cloned into using the `cloneElement` API. If the child is a
       * custom component, you **must** use `React.forwardRef` and pass the `ref`
       * and the other props for the transition to work correctly.
       */
      children: ReactElement<CollapseElementProps<E>>;

      /**
       * Boolean if the element should be collapsed.
       *
       * @see {@link CollapseTransitionHookOptions.transitionIn}
       */
      collapsed: boolean;
    }

    /**
     * **Client Component**
     *
     * This is a component implementation of the {@link useCollapseTransition} 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
     * function Example(): ReactElement {
     *   const [collapsed, setCollapsed] = useState(true);
     *
     *   return (
     *     <>
     *       <Button onClick={() => setCollapsed(!collapsed)}>
     *         Toggle
     *       </Button>
     *       <Collapse collapsed={collapsed}>
     *         <div>
     *           Some content that should only be visible while not collapsed.
     *         </div>
     *       </Collapse>
     *     </>
     *   );
     * }
     * ```
     *
     * @see {@link useCollapseTransition} for additional examples
     * @typeParam E - An HTMLElement type used for the ref required for the
     * transition.
     * @remarks
     * \@since 2.0.0
     * \@since 4.0.0 Updated for the new CSS Transition API.
     */
    export function Collapse<E extends HTMLElement>(
      props: CollapseProps<E>
    ): ReactElement {
      const { children, collapsed, className, ...options } = props;
      const child = Children.only(children);
      const { elementProps, rendered } = useCollapseTransition({
        ...options,
        className: cnb(child.props.className, className),
        transitionIn: !collapsed,
      });

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