import { jsx, jsxs } from 'react/jsx-runtime';
import { useContext, forwardRef, useState, useEffect, useRef, useId, useCallback, useLayoutEffect, useMemo } from 'react';
import { S as SvgClose } from './close-DZj38AEh.js';
import { T as Text } from './Text-J5YtSSXY.js';
import { B as Button } from './Button-Bnt8XUI7.js';
import { D as DrawerContext } from './DrawerContext-BSpnzXVZ.js';
import { c as childrenToString } from './childrenToString-Bz9MqbHb.js';
import { useTrackingId } from './useTrackingId.js';
import { c as cx } from './index-De1g9FRV.js';
import { u as useMergeRefs } from './useMergeRefs-Dfmtq9cI.js';
import { a as ToastProvider, b as ToasterPopover, c as ToasterContent } from './Toaster-Bq42x6Gx.js';
import { d as drillDownStyles, D as DrillDownContext } from './DrillDown.module-D1Bf9_yP.js';
import { u as useDrillDownContextState, a as useDialogTransitionStates, b as useKeyboardFocusables, c as useInitialFocus } from './useInitialFocus-BUxEDMEG.js';
import { r as registerLayer, u as unregisterLayer, a as useOnClickOutside } from './useOnClickOutside-Zw5vzxSq.js';
import { u as useDialogScrollLock } from './useDialogScrollLock-BW-aVboo.js';

import './Drawer.css';const drawer = "_drawer_s6o44_1";
const remove = "_remove_s6o44_39";
const small = "_small_s6o44_46";
const large = "_large_s6o44_50";
const xlarge = "_xlarge_s6o44_54";
const container = "_container_s6o44_58";
const header = "_header_s6o44_71";
const content = "_content_s6o44_95";
const sticky = "_sticky_s6o44_101";
const footer = "_footer_s6o44_112";
const styles = {
	"close-drawer": "_close-drawer_s6o44_1",
	"open-drawer": "_open-drawer_s6o44_1",
	"open-backdrop": "_open-backdrop_s6o44_1",
	"close-backdrop": "_close-backdrop_s6o44_1",
	drawer: drawer,
	remove: remove,
	small: small,
	large: large,
	xlarge: xlarge,
	container: container,
	header: header,
	"close-container": "_close-container_s6o44_87",
	content: content,
	sticky: sticky,
	footer: footer
};

function useDrawerContext() {
  const context = useContext(DrawerContext);
  if (!context) {
    throw new Error(
      "useDrawerContext must be used within a DrawerContextProvider"
    );
  }
  return context;
}

const DrawerCancelButton = forwardRef((props, ref) => {
  const { onClick, ...rest } = props;
  const { close } = useDrawerContext();
  const data = {
    children: childrenToString(props.children),
    appearance: props.appearance,
    size: props.size,
    type: props.type
  };
  const trackingId = useTrackingId({
    name: "DrawerCancelButton",
    data,
    hasOverride: !!props["data-tracking-id"]
  });
  const onClickHandler = (e) => {
    onClick?.(e);
    close();
  };
  return /* @__PURE__ */ jsx(
    Button,
    {
      "aria-label": "Close drawer",
      "data-anv": "drawer-cancel-button",
      "data-tracking-id": trackingId,
      onClick: onClickHandler,
      ref,
      ...rest
    }
  );
});
DrawerCancelButton.displayName = "DrawerCancelButton";

const DrawerHeader = forwardRef(
  (props, ref) => {
    const { className, children } = props;
    const { headerRef } = useDrawerContext();
    const data = {
      children: childrenToString(props.children)
    };
    const trackingId = useTrackingId({
      name: "DrawerHeader",
      data,
      hasOverride: !!props["data-tracking-id"]
    });
    const drawerHeaderClasses = cx(styles.header, className);
    return /* @__PURE__ */ jsxs(
      "header",
      {
        className: drawerHeaderClasses,
        "data-anv": "drawer-header",
        "data-tracking-id": trackingId,
        ref: useMergeRefs([ref, headerRef]),
        children: [
          /* @__PURE__ */ jsx(Text, { variant: "headline", el: "h1", children }),
          /* @__PURE__ */ jsx("span", { className: styles["close-container"], children: /* @__PURE__ */ jsx(
            DrawerCancelButton,
            {
              className: styles["close-button"],
              size: "small",
              appearance: "ghost",
              "aria-label": "Close drawer",
              "data-anv": "drawer-header-close-button",
              icon: SvgClose
            }
          ) })
        ]
      }
    );
  }
);
DrawerHeader.displayName = "DrawerHeader";

const DrawerFooter = forwardRef(
  (props, ref) => {
    const { className, children, sticky = false, ...rest } = props;
    const drawerFooterClasses = cx(styles.footer, className, {
      [styles["sticky"]]: sticky
    });
    return /* @__PURE__ */ jsx(
      "footer",
      {
        className: drawerFooterClasses,
        "data-anv": "drawer-footer",
        ref,
        ...rest,
        children
      }
    );
  }
);
DrawerFooter.displayName = "DrawerFooter";

const DrawerContent = forwardRef(
  (props, ref) => {
    const { children, className, sticky = false, ...rest } = props;
    const { headerRef } = useDrawerContext();
    const [headerHeight, setHeaderHeight] = useState(0);
    useEffect(() => {
      const headerElement = headerRef?.current;
      if (!sticky || !headerElement) return;
      const updateHeight = () => {
        setHeaderHeight(headerElement.offsetHeight || 0);
      };
      updateHeight();
      const resizeObserver = new ResizeObserver(updateHeight);
      resizeObserver.observe(headerElement);
      return () => resizeObserver.disconnect();
    }, [sticky, headerRef]);
    const contentClassNames = cx(styles["content"], className, {
      [styles["sticky"]]: sticky
    });
    const stickyStyle = sticky ? { top: `${headerHeight}px` } : void 0;
    return /* @__PURE__ */ jsx(
      "div",
      {
        className: contentClassNames,
        "data-anv": "drawer-content",
        ref,
        style: { ...stickyStyle, ...rest.style },
        ...rest,
        children
      }
    );
  }
);
DrawerContent.displayName = "DrawerContent";

const Drawer = Object.assign(
  forwardRef(function DrawerInner(props, ref) {
    const {
      className,
      open = false,
      children,
      onClose,
      // onCancel is destructured so that it is not passed to the dialog in ...rest
      onCancel,
      onKeyDown,
      disableCloseOnEscape = false,
      onClickOutside,
      disableCloseOnClickOutside = false,
      size = "medium",
      enableScrollChaining,
      onOpenAnimationStart,
      onOpenAnimationComplete,
      onCloseAnimationStart,
      onCloseAnimationComplete,
      initialFocusResolver,
      defaultDrillDownIndex,
      onDrillDownContextChange,
      ...rest
    } = props;
    const elRef = useRef(null);
    const contentRef = useRef(null);
    const toasterRef = useRef(null);
    const headerRef = useRef(null);
    const combinedRef = useMergeRefs([elRef, ref]);
    const drillDownContextValue = useDrillDownContextState({
      defaultDrillDownIndex
    });
    const id = useId();
    const { state, isOpenOrOpening } = useDialogTransitionStates(elRef, open, {
      onOpenAnimationStart: useCallback(() => {
        onOpenAnimationStart?.();
      }, [onOpenAnimationStart]),
      onOpenAnimationComplete: useCallback(() => {
        onOpenAnimationComplete?.();
      }, [onOpenAnimationComplete]),
      onCloseAnimationStart: useCallback(() => {
        onCloseAnimationStart?.();
      }, [onCloseAnimationStart]),
      onCloseAnimationComplete: useCallback(() => {
        onCloseAnimationComplete?.();
      }, [onCloseAnimationComplete])
    });
    const previousOpenRef = useRef(open);
    useLayoutEffect(() => {
      if (open && !previousOpenRef.current) {
        drillDownContextValue.setHostTrigger?.(
          document.activeElement instanceof HTMLElement ? document.activeElement : null
        );
      }
    }, [open, drillDownContextValue]);
    useEffect(() => {
      previousOpenRef.current = open;
    }, [open]);
    useEffect(() => {
      if (state === "closing") {
        drillDownContextValue.onHostClose?.();
      }
    }, [state, drillDownContextValue]);
    useEffect(() => {
      if (state === "closed") {
        drillDownContextValue.onHostClosed?.();
      }
    }, [state, drillDownContextValue]);
    const drillDownContextProviderValue = useMemo(
      () => ({
        ...drillDownContextValue,
        hostIsInteractive: state !== "closing" && state !== "closed"
      }),
      [drillDownContextValue, state]
    );
    useLayoutEffect(() => {
      onDrillDownContextChange?.(drillDownContextProviderValue);
    }, [drillDownContextProviderValue]);
    const classNames = cx([styles.drawer, drillDownStyles.drawer], className, {
      [styles.remove]: state === "closing",
      [styles[size]]: true
    });
    const { focusables } = useKeyboardFocusables(contentRef, {
      observeChange: false
    });
    const firstFocusable = focusables?.[0];
    const lastFocusable = focusables?.[focusables.length - 1];
    useDialogScrollLock({
      open: isOpenOrOpening,
      id,
      enableScrollChaining,
      elementRef: elRef
    });
    useEffect(() => {
      if (open) {
        registerLayer(id);
      } else {
        unregisterLayer(id);
      }
      return () => {
        unregisterLayer(id);
      };
    }, [open, id]);
    const computeFocus = useCallback((focusables2) => {
      return focusables2.find(
        (focusable) => focusable.dataset.anv !== "drawer-header-close-button"
      ) || focusables2[0];
    }, []);
    useInitialFocus(elRef, {
      computeFocus: initialFocusResolver || computeFocus
    });
    const onCancelHandler = (e) => {
      e.preventDefault();
      if (disableCloseOnEscape) return;
      onClose?.();
    };
    useOnClickOutside({
      onClickOutsideBegin: (e) => {
        if (!open) return;
        onClickOutside?.(e);
      },
      targets: [
        contentRef.current,
        toasterRef.current
      ],
      onClickOutside: () => {
        if (disableCloseOnClickOutside || !open) return;
        onClose?.();
      },
      layerId: id
    });
    const onKeyDownHandler = (e) => {
      onKeyDown?.(e);
      if (e.code === "Tab") {
        if (e.shiftKey && e.target === firstFocusable) {
          e.preventDefault();
          lastFocusable?.focus();
          return;
        }
        if (e.target === lastFocusable && !e.shiftKey) {
          e.preventDefault();
          firstFocusable?.focus();
          return;
        }
      }
    };
    const contextValue = useMemo(() => {
      return { close: () => onClose?.(), headerRef, state };
    }, [onClose, state]);
    return (
      // dialog element does seem to be interactive on MDN guideline
      /* @__PURE__ */ jsxs(
        "dialog",
        {
          className: classNames,
          "data-anv": "drawer",
          "data-anv-scroll-chaining": enableScrollChaining,
          "data-anv-transition-state": state,
          ref: combinedRef,
          onCancel: onCancelHandler,
          onKeyDown: onKeyDownHandler,
          ...rest,
          children: [
            /* @__PURE__ */ jsx(ToastProvider, { isDialogToaster: isOpenOrOpening, children: /* @__PURE__ */ jsx(ToasterPopover, { children: /* @__PURE__ */ jsx(ToasterContent, { id: "drawer-toaster", ref: toasterRef }) }) }),
            /* @__PURE__ */ jsx(DrillDownContext.Provider, { value: drillDownContextProviderValue, children: /* @__PURE__ */ jsx(DrawerContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
              "section",
              {
                ref: contentRef,
                className: styles.container,
                "data-open": isOpenOrOpening,
                children
              }
            ) }) })
          ]
        }
      )
    );
  }),
  {
    /**
     * Header component for the drawer that displays a title and close button.
     *
     * Features:
     * - Displays the drawer title as a headline
     * - Includes an accessible close button
     * - Sticky positioning at the top of the drawer
     * - Proper semantic HTML structure
     * - Accessible with proper ARIA attributes
     * - Consistent styling with the design system
     * - Automatic close functionality
     * - Automatic tracking ID generation for analytics
     *
     * @example
     * <Drawer.Header>Settings</Drawer.Header>
     */
    Header: DrawerHeader,
    /**
     * Footer component for the drawer that displays action buttons and controls.
     *
     * Features:
     * - Flexible layout for action buttons and controls
     * - Optional sticky positioning at the bottom
     * - Proper semantic HTML structure
     * - Accessible with proper ARIA attributes
     * - Consistent styling with the design system
     * - Supports all standard footer element props
     * - Responsive design that adapts to content
     *
     * @example
     * <Drawer.Footer sticky>
     *   <Button onClick={handleSave}>Save</Button>
     *   <Drawer.CancelButton>Cancel</Drawer.CancelButton>
     * </Drawer.Footer>
     */
    Footer: DrawerFooter,
    /**
     * Content container for the drawer that holds the main content area.
     *
     * Features:
     * - Flexible content area with proper spacing
     * - Scrollable content when needed
     * - Proper semantic HTML structure
     * - Accessible with proper ARIA attributes
     * - Consistent styling with the design system
     * - Supports all standard div element props
     * - Responsive design that adapts to content
     * - Proper focus management
     *
     * @example
     * <Drawer.Content>
     *   <p>This is the main content of the drawer.</p>
     *   <p>It can contain any type of content.</p>
     * </Drawer.Content>
     */
    Content: DrawerContent,
    /**
     * A button component that automatically closes the drawer when clicked.
     *
     * Features:
     * - Automatically closes the drawer when clicked
     * - Extends Button component functionality
     * - Accessible with proper ARIA attributes
     * - Consistent styling with the design system
     * - Supports all standard button props
     * - Proper focus management
     * - Can be used anywhere within the drawer context
     * - Automatic tracking ID generation for analytics
     *
     * @example
     * <Drawer.CancelButton appearance="ghost" size="small">
     *   Cancel
     * </Drawer.CancelButton>
     */
    CancelButton: DrawerCancelButton
  }
);
Drawer.displayName = "Drawer";

export { Drawer as D };
//# sourceMappingURL=Drawer-iewBy1DW.js.map
