"use client";
import { jsx } from "../../packages/jsx/src/jsx-runtime.js";
import { cloneElement } from "react";
import { TransitionGroup, CSSTransition } from "react-transition-group";
import { useCssId } from "../../hooks/useCssId.js";
import { getChildrenKey } from "../../utils/getChildrenKey.js";
import { TimingFunction } from "../../tokens/TimingFunction.js";
function Transition({
  layout = "block",
  effect = "fade",
  mode = "cross",
  duration = "400ms",
  disabled = false,
  className,
  children,
  ...props
}) {
  const transitionClass = `gds-Transition-${useCssId()}`;
  if (disabled) {
    return /* @__PURE__ */ jsx("div", { className, ...props, children });
  }
  const gridTemplateProperty = layout === "block" ? "grid-template-rows" : "grid-template-columns";
  const gridTemplatePropertyCamelCase = layout === "block" ? "gridTemplateRows" : "gridTemplateColumns";
  const shouldTransitionOpacity = effect !== "collapse";
  const shouldOverlayElements = effect !== "collapse";
  const totalDuration = typeof duration === "number" ? duration : parseInt(duration);
  const exitDuration = mode === "cross" ? totalDuration : totalDuration / 2;
  const enterDuration = exitDuration;
  const exitDelay = mode === "in-out" ? enterDuration : 0;
  const enterDelay = mode === "out-in" ? exitDuration : 0;
  return /* @__PURE__ */ jsx(
    "div",
    {
      className,
      sx: {
        display: "grid",
        // Force the entering element to wrap to a second column (if `block` layout) or a second row (if `inline` layout) in the following flex container
        // This is so we can easily overlay the elements on top of each other while maintaining a height that is the sum of the two elements' heights
        // (or a width that is the sum of the two elements' widths if `inline` layout)
        [gridTemplatePropertyCamelCase]: shouldOverlayElements ? "0.999fr" : void 0,
        // Putting all these styles here instead of on the child of `CSSTransition` below because changing `sx` values (e.g. if the `effect` is changed) changes the `className` of the element, which causes weird things to happen during the transition
        [`.${transitionClass}-exit`]: {
          order: -1,
          // Make sure the exiting element is rendered first, so we can render the entering element on top of it
          overflow: effect === "collapse" ? "clip" : void 0,
          [gridTemplatePropertyCamelCase]: "1fr",
          opacity: shouldTransitionOpacity ? 1 : void 0,
          transform: effect === "slide-left" || effect === "slide-right" ? "translateX(0)" : void 0,
          transition: `${gridTemplateProperty} ${totalDuration}ms ${TimingFunction.EASE_IN_OUT}, opacity ${exitDuration}ms ${TimingFunction.EASE_IN_OUT} ${exitDelay}ms, transform ${exitDuration}ms ${TimingFunction.EASE_IN_OUT} ${exitDelay}ms`,
          // The following two rules are needed to avoid weird visual bugs when quickly switching between 3+ states
          // Hide exiting elements other than the first one
          [`& ~ .${transitionClass}-exit`]: {
            display: "none"
          },
          // Disable the `gridTemplateProperty` transition if there are multiple exiting elements
          [`&:has(~ .${transitionClass}-exit)`]: {
            transitionDuration: `0ms, ${exitDuration}ms, ${exitDuration}ms`
          }
        },
        [`.${transitionClass}-exit-active`]: {
          [gridTemplatePropertyCamelCase]: "0fr",
          opacity: shouldTransitionOpacity ? 0 : void 0,
          transform: effect === "slide-left" ? "translateX(-50%)" : effect === "slide-right" ? "translateX(50%)" : void 0
        },
        [`.${transitionClass}-enter`]: {
          [layout === "block" ? "left" : "top"]: shouldOverlayElements ? "-100%" : void 0,
          // Render the entering element on top of the exiting one
          overflow: effect === "collapse" ? "clip" : void 0,
          [gridTemplatePropertyCamelCase]: "0fr",
          opacity: shouldTransitionOpacity ? 0 : void 0,
          transform: effect === "slide-left" ? "translateX(50%)" : effect === "slide-right" ? "translateX(-50%)" : void 0,
          transition: `${gridTemplateProperty} ${totalDuration}ms ${TimingFunction.EASE_IN_OUT}, opacity ${enterDuration}ms ${TimingFunction.EASE_IN_OUT} ${enterDelay}ms, transform ${enterDuration}ms ${TimingFunction.EASE_IN_OUT} ${enterDelay}ms`,
          // Disable the `gridTemplateProperty` transition if there are multiple exiting elements
          [`&:has(~ .${transitionClass}-exit ~ .${transitionClass}-exit)`]: {
            transitionDuration: `0ms, ${enterDuration}ms, ${enterDuration}ms`
          }
        },
        [`.${transitionClass}-enter-active`]: {
          [gridTemplatePropertyCamelCase]: "1fr",
          opacity: shouldTransitionOpacity ? 1 : void 0,
          transform: effect === "slide-left" || effect === "slide-right" ? "translateX(0)" : void 0
        }
      },
      ...props,
      children: /* @__PURE__ */ jsx(
        TransitionGroup,
        {
          childFactory: (child) => {
            if (!child.props.in) {
              return cloneElement(child, { inert: "" });
            }
            return child;
          },
          sx: {
            display: "flex",
            flexDirection: layout === "block" ? "column" : "row",
            flexWrap: "wrap"
          },
          children: /* @__PURE__ */ jsx(
            CSSTransition,
            {
              timeout: totalDuration,
              classNames: transitionClass,
              children: /* @__PURE__ */ jsx(
                "div",
                {
                  sx: {
                    display: "grid",
                    [layout === "block" ? "width" : "height"]: "100%"
                  },
                  children: /* @__PURE__ */ jsx("div", { children })
                }
              )
            },
            `gds-Transition-${getChildrenKey(children)}`
          )
        }
      )
    }
  );
}
export {
  Transition
};
