"use client";
import { cnb } from "cnbuilder";
import { useState } from "react";
import { useEnsuredRef } from "../useEnsuredRef.js";
import { DISPLAY_NONE_CLASS } from "../utils/isElementVisible.js";
import { collapse } from "./collapseStyles.js";
import { useTransition } from "./useTransition.js";
import { getElementSizing, getTransitionTimeout } from "./utils.js";
const noop = ()=>{
// do nothing
};
/**
 * @since 2.0.0
 */ export const DEFAULT_COLLAPSE_TIMEOUT = {
    enter: 250,
    exit: 200
};
/**
 * This hook is used to create a transition to collapse and expand an element
 * **inline** with other content like an accordion by animating the
 * `max-height`, `padding-top`, and `padding-bottom` CSS properties. The default
 * behavior is to hide the element completely while collapsed, but providing the
 * `minHeight`, `minPaddingTop`, and `minPaddingBottom` options can make this
 * work like a "See More"/"Preview" type of element
 *
 * @example Simple Example
 * ```tsx
 * import { ReactElement, useState } from "react";
 * import { Button, Typography, useCollapseTransition } from "@react-md/core";
 *
 * function Example(): ReactElement {
 *   const [collapsed, setCollapsed] = useState(true);
 *   const { elementProps, rendered } =
 *     useCollapseTransition({
 *       transitionIn: !collapsed,
 *       // If the collapsible element should maintain state by not unmounting
 *       // while collapsed, uncomment this next line
 *       // temporary: false,
 *     });
 *
 *   return (
 *     <>
 *       <Button onClick={() => setCollapsed(!collapsed)}>
 *         Toggle
 *       </Button>
 *       {rendered && (
 *         <div {...elementProps}>
 *           <Typography>Stuff that should be collapsed</Typography>
 *           <div>Whatever content...</div>
 *         </div>
 *       )}
 *     </>
 *   );
 * }
 * ```
 *
 * @example See More Example
 * ```tsx
 * import { ReactElement, useState } from "react";
 * import { Button, IconRotator, Typography, useCollapseTransition } from "@react-md/core";
 * import { KeyboardArrowDownSVGIcon } from "@react-md/material-icons";
 *
 * import styles from "./Example.module.scss";
 * // pretend styles:
 * //
 * // .container {
 * //   padding: 1rem;
 * //   position: relative;
 * // }
 * //
 * // .button {
 * //   position: absolute;
 * //   right: 0;
 * //   top: 0;
 * // }
 *
 *
 * function Example(): ReactElement {
 *   const [collapsed, setCollapsed] = useState(true);
 *   const { elementProps } =
 *     useCollapseTransition({
 *       transitionIn: !collapsed,
 *       minHeight: 120,
 *       minPaddingTop: 16,
 *       className: styles.container,
 *     });
 *
 *   return (
 *     <div {...elementProps}>
 *       <Button
 *         aria-expanded={!collapsed}
 *         aria-label="Expand"
 *         onClick={() => setCollapsed(!collapsed)}
 *         buttonType="icon"
 *         className={styles.button}
 *       >
 *         <IconRotator rotated={!collapsed}>
 *           <KeyboardArrowDownSVGIcon />
 *         </IconRotator>
 *       </Button>
 *       <SomeComponentWithALotOfContent />
 *     </div>
 *   );
 * }
 * ```
 *
 * @typeParam E - An HTMLElement type used for the ref required for the
 * transition.
 * @since 4.0.0
 */ export function useCollapseTransition(options) {
    const { nodeRef: propNodeRef, style: propStyle, className, transitionIn, timeout = DEFAULT_COLLAPSE_TIMEOUT, minHeight = 0, minPaddingTop = 0, minPaddingBottom = 0, temporary = minHeight === 0 && minPaddingTop === 0 && minPaddingBottom === 0, appear = false, enter = true, exit = true, onEnter = noop, onEntering = noop, onEntered = noop, onExit = noop, onExiting = noop, onExited = noop } = options;
    const [nodeRef, refCallback] = useEnsuredRef(propNodeRef);
    const [style, setStyle] = useState(()=>{
        if (transitionIn) {
            return undefined;
        }
        return {
            maxHeight: minHeight,
            paddingTop: minPaddingTop,
            paddingBottom: minPaddingBottom
        };
    });
    const transitionTimeout = getTransitionTimeout({
        timeout,
        appear,
        enter,
        exit
    });
    const { appearing, rendered, ref, stage, transitionTo, disablePortal } = useTransition({
        nodeRef: refCallback,
        timeout,
        transitionIn,
        reflow: true,
        appear,
        enter,
        exit,
        temporary,
        onEnter (appearing) {
            onEnter(appearing);
            setStyle({
                maxHeight: minHeight,
                paddingTop: minPaddingTop,
                paddingBottom: minPaddingBottom
            });
        },
        onEntering (appearing) {
            onEntering(appearing);
            const { maxHeight, paddingTop, paddingBottom } = getElementSizing(nodeRef.current);
            const duration = appearing ? transitionTimeout.appear : transitionTimeout.enter;
            setStyle({
                maxHeight,
                paddingTop,
                paddingBottom,
                transitionDuration: `${duration}ms`
            });
        },
        onEntered (appearing) {
            onEntered(appearing);
            setStyle(undefined);
        },
        onExit () {
            onExit();
            const { maxHeight, paddingTop, paddingBottom } = getElementSizing(nodeRef.current);
            setStyle({
                maxHeight,
                paddingTop,
                paddingBottom,
                transitionDuration: `${transitionTimeout.exit}ms`
            });
        },
        onExiting () {
            onExiting();
            setStyle({
                maxHeight: minHeight,
                paddingTop: minPaddingTop,
                paddingBottom: minPaddingBottom,
                transitionDuration: `${transitionTimeout.exit}ms`
            });
        },
        onExited () {
            onExited();
            setStyle({
                maxHeight: minHeight,
                paddingTop: minPaddingTop,
                paddingBottom: minPaddingBottom
            });
        }
    });
    const entering = stage === "enter" || stage === "entering";
    const exiting = stage === "exit" || stage === "exiting";
    const collapsible = transitionTimeout.enter !== 0 || transitionTimeout.exit !== 0;
    const elementProps = {
        ref,
        style: {
            ...style,
            ...propStyle
        },
        className: cnb(className, collapsible && collapse({
            enter: entering,
            leave: exiting,
            disableOverflow: !transitionIn || !!style
        }), stage === "exited" && minHeight === 0 && minPaddingTop === 0 && minPaddingBottom === 0 && DISPLAY_NONE_CLASS) || undefined
    };
    return {
        ...elementProps,
        stage,
        rendered,
        appearing,
        elementProps,
        transitionTo,
        disablePortal
    };
}

//# sourceMappingURL=useCollapseTransition.js.map