"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.EuiFlyoutComponent = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
var _react = _interopRequireWildcard(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _services = require("../../services");
var _manager = require("./manager");
var _const = require("./manager/const");
var _focus_trap = require("../focus_trap");
var _i18n = require("../i18n");
var _resize_observer = require("../observer/resize_observer");
var _accessibility = require("../accessibility");
var _flyout_close_button = require("./_flyout_close_button");
var _flyout = require("./flyout.styles");
var _component_defaults = require("../provider/component_defaults");
var _const2 = require("./const");
var _hooks = require("./hooks");
var _flyout_menu = require("./flyout_menu");
var _flyout_overlay = require("./_flyout_overlay");
var _flyout_resize_button = require("./_flyout_resize_button");
var _use_flyout_resizable = require("./use_flyout_resizable");
var _use_flyout_z_index = require("./use_flyout_z_index");
var _flyout_parent_context = require("./flyout_parent_context");
var _use_flyout_menu = require("./use_flyout_menu");
var _react2 = require("@emotion/react");
var _excluded = ["className", "children", "as", "hideCloseButton", "flyoutMenuProps", "flyoutMenuDisplayMode", "closeButtonProps", "closeButtonPosition", "onClose", "ownFocus", "side", "size", "paddingSize", "maxWidth", "style", "hasChildBackground", "maskProps", "type", "outsideClickCloses", "pushMinBreakpoint", "pushAnimation", "hasAnimation", "focusTrapProps", "includeFixedHeadersInFocusTrap", "includeSelectorInFocusTrap", "aria-describedby", "aria-labelledby", "id", "resizable", "minWidth", "onResize", "onAnimationEnd", "container"];
/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License
 * 2.0 and the Server Side Public License, v 1; you may not use this file except
 * in compliance with, at your election, the Elastic License 2.0 or the Server
 * Side Public License, v 1.
 */
/* eslint-disable local/i18n */
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
/**
 * Resolves the container prop (element, getter, or selector string) to an
 * HTMLElement, or null if not found / invalid.
 */
var resolveContainer = function resolveContainer(raw) {
  if (raw == null) return null;
  if (typeof raw === 'string') {
    if (typeof document === 'undefined') return null;
    var el = document.querySelector(raw);
    return el instanceof HTMLElement ? el : null;
  }
  if (typeof raw === 'function') return raw();
  if (typeof HTMLElement === 'undefined') return null;
  return raw instanceof HTMLElement ? raw : null;
};
var defaultElement = 'div';
var EuiFlyoutComponent = exports.EuiFlyoutComponent = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) {
  var _maskProps$headerZind, _managerSessions, _managerState$layoutM, _managerState$current, _managerState$flyouts, _managerState$pushPad;
  var _usePropsWithComponen = (0, _component_defaults.usePropsWithComponentDefaults)('EuiFlyout', props),
    className = _usePropsWithComponen.className,
    children = _usePropsWithComponen.children,
    as = _usePropsWithComponen.as,
    _usePropsWithComponen2 = _usePropsWithComponen.hideCloseButton,
    hideCloseButton = _usePropsWithComponen2 === void 0 ? false : _usePropsWithComponen2,
    _flyoutMenuProps = _usePropsWithComponen.flyoutMenuProps,
    _usePropsWithComponen3 = _usePropsWithComponen.flyoutMenuDisplayMode,
    flyoutMenuDisplayMode = _usePropsWithComponen3 === void 0 ? _const2.DEFAULT_MENU_DISPLAY_MODE : _usePropsWithComponen3,
    closeButtonProps = _usePropsWithComponen.closeButtonProps,
    _usePropsWithComponen4 = _usePropsWithComponen.closeButtonPosition,
    closeButtonPosition = _usePropsWithComponen4 === void 0 ? 'inside' : _usePropsWithComponen4,
    onClose = _usePropsWithComponen.onClose,
    _usePropsWithComponen5 = _usePropsWithComponen.ownFocus,
    ownFocus = _usePropsWithComponen5 === void 0 ? true : _usePropsWithComponen5,
    _usePropsWithComponen6 = _usePropsWithComponen.side,
    side = _usePropsWithComponen6 === void 0 ? _const2.DEFAULT_SIDE : _usePropsWithComponen6,
    _usePropsWithComponen7 = _usePropsWithComponen.size,
    _size = _usePropsWithComponen7 === void 0 ? _const2.DEFAULT_SIZE : _usePropsWithComponen7,
    _usePropsWithComponen8 = _usePropsWithComponen.paddingSize,
    paddingSize = _usePropsWithComponen8 === void 0 ? _const2.DEFAULT_PADDING_SIZE : _usePropsWithComponen8,
    _usePropsWithComponen9 = _usePropsWithComponen.maxWidth,
    maxWidth = _usePropsWithComponen9 === void 0 ? false : _usePropsWithComponen9,
    style = _usePropsWithComponen.style,
    _usePropsWithComponen10 = _usePropsWithComponen.hasChildBackground,
    hasChildBackground = _usePropsWithComponen10 === void 0 ? false : _usePropsWithComponen10,
    maskProps = _usePropsWithComponen.maskProps,
    _usePropsWithComponen11 = _usePropsWithComponen.type,
    type = _usePropsWithComponen11 === void 0 ? _const2.DEFAULT_TYPE : _usePropsWithComponen11,
    outsideClickCloses = _usePropsWithComponen.outsideClickCloses,
    _usePropsWithComponen12 = _usePropsWithComponen.pushMinBreakpoint,
    pushMinBreakpoint = _usePropsWithComponen12 === void 0 ? _const2.DEFAULT_PUSH_MIN_BREAKPOINT : _usePropsWithComponen12,
    _pushAnimation = _usePropsWithComponen.pushAnimation,
    _hasAnimation = _usePropsWithComponen.hasAnimation,
    _focusTrapProps = _usePropsWithComponen.focusTrapProps,
    _usePropsWithComponen13 = _usePropsWithComponen.includeFixedHeadersInFocusTrap,
    includeFixedHeadersInFocusTrap = _usePropsWithComponen13 === void 0 ? true : _usePropsWithComponen13,
    includeSelectorInFocusTrap = _usePropsWithComponen.includeSelectorInFocusTrap,
    _ariaDescribedBy = _usePropsWithComponen['aria-describedby'],
    _ariaLabelledBy = _usePropsWithComponen['aria-labelledby'],
    id = _usePropsWithComponen.id,
    _usePropsWithComponen14 = _usePropsWithComponen.resizable,
    resizable = _usePropsWithComponen14 === void 0 ? false : _usePropsWithComponen14,
    minWidth = _usePropsWithComponen.minWidth,
    onResize = _usePropsWithComponen.onResize,
    onAnimationEnd = _usePropsWithComponen.onAnimationEnd,
    containerProp = _usePropsWithComponen.container,
    rest = (0, _objectWithoutProperties2.default)(_usePropsWithComponen, _excluded);
  var container = resolveContainer(containerProp);
  var hasAnimationDefault = type === 'overlay';
  var hasAnimation = _hasAnimation !== null && _hasAnimation !== void 0 ? _hasAnimation : hasAnimationDefault;
  var _useEuiThemeCSSVariab = (0, _services.useEuiThemeCSSVariables)(),
    setGlobalCSSVariables = _useEuiThemeCSSVariab.setGlobalCSSVariables;
  var Element = as || defaultElement;
  var maskRef = (0, _react.useRef)(null);

  // Ref for the main flyout element to pass to context
  var internalParentFlyoutRef = (0, _react.useRef)(null);

  // Observe the container's dimensions so the resize hook and
  // positioning styles stay aligned with its bounding rect.
  // When no container is provided, these remain inert (null/undefined).
  var containerDimensions = (0, _resize_observer.useResizeObserver)(container !== null && container !== void 0 ? container : null, 'width');
  var containerReferenceWidth = container ? containerDimensions.width || container.clientWidth : undefined;
  var isPushed = (0, _hooks.useIsPushed)({
    type: type,
    pushMinBreakpoint: pushMinBreakpoint,
    containerWidth: containerReferenceWidth
  });
  // When no explicit container is provided, push padding targets
  // document.body and global push-offset CSS vars are set. When a
  // container is provided, only that element receives padding.
  var shouldSetGlobalPushVars = container == null;
  if ('container' in props && ('maskProps' in props || 'includeFixedHeadersInFocusTrap' in props) && process.env.NODE_ENV === 'development') {
    if ('maskProps' in props) {
      console.warn('EuiFlyout: `maskProps` is deprecated. Prefer using the `container` prop to scope flyouts.');
    }
    if ('includeFixedHeadersInFocusTrap' in props) {
      console.warn('EuiFlyout: `includeFixedHeadersInFocusTrap` is deprecated. Prefer `includeSelectorInFocusTrap` when using `container`.');
    }
  }
  // Explicit viewport flyouts (container={null}) default to 'above' so
  // they render above fixed headers. Container-scoped and legacy flyouts
  // (no container prop) default to 'below'.
  var effectiveHeaderZindexLocation = (_maskProps$headerZind = maskProps === null || maskProps === void 0 ? void 0 : maskProps.headerZindexLocation) !== null && _maskProps$headerZind !== void 0 ? _maskProps$headerZind : containerProp === null ? 'above' : 'below';

  // Report the container element to the flyout manager for layout calculations.
  (0, _react.useEffect)(function () {
    var _flyoutManagerRef$cur;
    if (!container) return;
    (_flyoutManagerRef$cur = flyoutManagerRef.current) === null || _flyoutManagerRef$cur === void 0 || _flyoutManagerRef$cur.setContainerElement(container);
    return function () {
      var _flyoutManagerRef$cur2;
      if (((_flyoutManagerRef$cur2 = flyoutManagerRef.current) === null || _flyoutManagerRef$cur2 === void 0 || (_flyoutManagerRef$cur2 = _flyoutManagerRef$cur2.state) === null || _flyoutManagerRef$cur2 === void 0 ? void 0 : _flyoutManagerRef$cur2.containerElement) === container) {
        flyoutManagerRef.current.setContainerElement(null);
      }
    };
  }, [container]);

  // Performance: read context once and derive all manager-dependent values inline.
  var isInManagedContext = (0, _manager.useIsInManagedFlyout)();
  var flyoutId = (0, _manager.useFlyoutId)(id);
  var flyoutManager = (0, _manager.useFlyoutManager)();
  var managerState = flyoutManager === null || flyoutManager === void 0 ? void 0 : flyoutManager.state;
  var managerSessions = managerState === null || managerState === void 0 ? void 0 : managerState.sessions;
  var currentSession = managerSessions ? (_managerSessions = managerSessions[managerSessions.length - 1]) !== null && _managerSessions !== void 0 ? _managerSessions : null : null;
  var layoutMode = (_managerState$layoutM = managerState === null || managerState === void 0 ? void 0 : managerState.layoutMode) !== null && _managerState$layoutM !== void 0 ? _managerState$layoutM : _const.LAYOUT_MODE_SIDE_BY_SIDE;
  var isActiveManagedFlyout = (currentSession === null || currentSession === void 0 ? void 0 : currentSession.mainFlyoutId) === flyoutId || (currentSession === null || currentSession === void 0 ? void 0 : currentSession.childFlyoutId) === flyoutId;
  var currentZIndexRef = (0, _react.useRef)((_managerState$current = managerState === null || managerState === void 0 ? void 0 : managerState.currentZIndex) !== null && _managerState$current !== void 0 ? _managerState$current : 0);
  var _useEuiFlyoutMenu = (0, _use_flyout_menu.useEuiFlyoutMenu)({
      flyoutMenuProps: _flyoutMenuProps,
      flyoutMenuDisplayMode: flyoutMenuDisplayMode,
      ariaLabelledBy: _ariaLabelledBy
    }),
    flyoutMenuId = _useEuiFlyoutMenu.flyoutMenuId,
    flyoutMenuProps = _useEuiFlyoutMenu.flyoutMenuProps,
    shouldRenderMenu = _useEuiFlyoutMenu.shouldRenderMenu,
    ariaLabelledBy = _useEuiFlyoutMenu.ariaLabelledBy;
  (0, _react.useEffect)(function () {
    if (process.env.NODE_ENV === 'development' && _flyoutMenuProps && 'hideTitle' in _flyoutMenuProps) {
      console.warn('EuiFlyout: `flyoutMenuProps.hideTitle` is deprecated. Use `EuiFlyoutHeader` for visible titles instead.');
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // Use a ref to access the latest flyoutManager without triggering effect re-runs
  var flyoutManagerRef = (0, _react.useRef)(flyoutManager);
  (0, _react.useEffect)(function () {
    flyoutManagerRef.current = flyoutManager;
  }, [flyoutManager]);
  (0, _react.useEffect)(function () {
    // Keep track of unmanaged flyouts to properly calculate z-index
    // values for all flyouts
    if (!isInManagedContext) {
      var _flyoutManagerRef$cur3;
      (_flyoutManagerRef$cur3 = flyoutManagerRef.current) === null || _flyoutManagerRef$cur3 === void 0 || _flyoutManagerRef$cur3.addUnmanagedFlyout(flyoutId);
      return function () {
        var _flyoutManagerRef$cur4;
        return (_flyoutManagerRef$cur4 = flyoutManagerRef.current) === null || _flyoutManagerRef$cur4 === void 0 ? void 0 : _flyoutManagerRef$cur4.closeUnmanagedFlyout(flyoutId);
      };
    }
  }, [isInManagedContext, flyoutId]);

  // Derive flyout identity and sibling info from the single context read
  var flyoutIdentity = (0, _react.useMemo)(function () {
    if (!flyoutId || !currentSession) {
      return {
        isMainFlyout: false,
        siblingFlyoutId: null,
        hasValidSession: false
      };
    }
    var siblingFlyoutId = currentSession.mainFlyoutId === flyoutId ? currentSession.childFlyoutId : currentSession.mainFlyoutId;
    return {
      isMainFlyout: currentSession.mainFlyoutId === flyoutId,
      siblingFlyoutId: siblingFlyoutId,
      hasValidSession: true
    };
  }, [flyoutId, currentSession]);

  // Destructure for easier use
  var siblingFlyoutId = flyoutIdentity.siblingFlyoutId,
    isMainFlyout = flyoutIdentity.isMainFlyout;

  // Derive sibling flyout data from manager state (single read, no extra hooks)
  var siblingFlyout = siblingFlyoutId ? (_managerState$flyouts = managerState === null || managerState === void 0 ? void 0 : managerState.flyouts.find(function (f) {
    return f.flyoutId === siblingFlyoutId;
  })) !== null && _managerState$flyouts !== void 0 ? _managerState$flyouts : null : null;
  var _siblingFlyoutWidth = siblingFlyout === null || siblingFlyout === void 0 ? void 0 : siblingFlyout.width;
  var isSiblingFill = (siblingFlyout === null || siblingFlyout === void 0 ? void 0 : siblingFlyout.size) === 'fill';
  var siblingFlyoutMinWidth = siblingFlyout === null || siblingFlyout === void 0 ? void 0 : siblingFlyout.minWidth;
  var siblingFlyoutWidth = layoutMode === _const.LAYOUT_MODE_STACKED ? 0 : _siblingFlyoutWidth;

  // Track the container's bounding rect for positioning the flyout.
  var _useState = (0, _react.useState)(null),
    _useState2 = (0, _slicedToArray2.default)(_useState, 2),
    containerRect = _useState2[0],
    setContainerRect = _useState2[1];
  (0, _react.useLayoutEffect)(function () {
    if (!container) {
      setContainerRect(null);
      return;
    }
    setContainerRect(container.getBoundingClientRect());
  }, [container, containerDimensions.width]);
  (0, _react.useEffect)(function () {
    if (!container) return;
    var updateRect = function updateRect() {
      var next = container.getBoundingClientRect();
      setContainerRect(function (prev) {
        if (prev && prev.top === next.top && prev.left === next.left && prev.width === next.width && prev.height === next.height) {
          return prev;
        }
        return next;
      });
    };
    window.addEventListener('scroll', updateRect, {
      passive: true
    });
    window.addEventListener('resize', updateRect, {
      passive: true
    });
    return function () {
      window.removeEventListener('scroll', updateRect);
      window.removeEventListener('resize', updateRect);
    };
  }, [container]);
  // Prefer the manager's reference width when available so resize clamp
  // uses the same value as layout mode. When we have a container, cap by
  // its measured width so we never allow resize past the container (e.g. if
  // manager had viewport fallback or timing mismatch).
  var managerRefWidth = isInManagedContext && typeof (managerState === null || managerState === void 0 ? void 0 : managerState.referenceWidth) === 'number' && managerState.referenceWidth > 0 ? managerState.referenceWidth : undefined;
  var effectiveReferenceWidth = containerReferenceWidth != null && containerReferenceWidth > 0 ? managerRefWidth != null ? Math.min(managerRefWidth, containerReferenceWidth) : containerReferenceWidth : managerRefWidth !== null && managerRefWidth !== void 0 ? managerRefWidth : containerReferenceWidth;
  var _useEuiFlyoutResizabl = (0, _use_flyout_resizable.useEuiFlyoutResizable)({
      enabled: resizable,
      minWidth: minWidth,
      maxWidth: typeof maxWidth === 'number' ? maxWidth : undefined,
      // For fill siblings, clamp based on their minWidth rather than their
      // current measured width. Fill siblings dynamically adjust via CSS
      // (`calc(90% - mainWidth)`), so subtracting their current width from
      // the max creates a circular dependency where the main flyout can
      // never grow (max = 90% - (90% - main) = main). Using minWidth
      // breaks this cycle while ensuring the fill sibling never collapses
      // below its configured minimum.
      siblingFlyoutWidth: isSiblingFill ? siblingFlyoutMinWidth : siblingFlyoutWidth !== null && siblingFlyoutWidth !== void 0 ? siblingFlyoutWidth : undefined,
      referenceWidth: effectiveReferenceWidth,
      onResize: onResize,
      side: side,
      size: _size
    }),
    onMouseDownResizableButton = _useEuiFlyoutResizabl.onMouseDown,
    onKeyDownResizableButton = _useEuiFlyoutResizabl.onKeyDown,
    size = _useEuiFlyoutResizabl.size,
    setFlyoutRef = _useEuiFlyoutResizabl.setFlyoutRef;

  // Publish the main flyout's resolved width as a CSS custom property on
  // the document element so that the child (fill) flyout can track it
  // synchronously during drag resize, avoiding the 1-frame lag that
  // results from the async ResizeObserver → manager-state pipeline.
  (0, _react.useLayoutEffect)(function () {
    if (!isMainFlyout) return;

    // Only set when we have a computed percentage (during active resize)
    if (typeof size === 'string' && size.endsWith('%')) {
      document.documentElement.style.setProperty('--euiFlyoutMainWidth', size);
    }
    return function () {
      document.documentElement.style.removeProperty('--euiFlyoutMainWidth');
    };
  }, [isMainFlyout, size]);

  /**
   * Setting up the refs on the actual flyout element in order to
   * accommodate for the `isPushed` state by adding padding to the body equal to the width of the element
   */
  var _useState3 = (0, _react.useState)(null),
    _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
    resizeRef = _useState4[0],
    setResizeRef = _useState4[1];
  var setRef = (0, _services.useCombinedRefs)([setResizeRef, ref, internalParentFlyoutRef, setFlyoutRef]);
  var _useResizeObserver = (0, _resize_observer.useResizeObserver)(isPushed ? resizeRef : null, 'width'),
    width = _useResizeObserver.width;

  /**
   * Effect for adding push padding so the flyout has room. Targets the
   * container element when one is provided, otherwise document.body.
   * Uses useLayoutEffect so padding is applied before child render.
   */
  (0, _react.useLayoutEffect)(function () {
    if (!isPushed) {
      return;
    }
    var paddingTarget = container !== null && container !== void 0 ? container : document.body;
    var shouldApplyPadding = !isInManagedContext || isActiveManagedFlyout;
    var paddingSide = side === 'left' ? 'paddingInlineStart' : 'paddingInlineEnd';
    var cssVarName = "--euiPushFlyoutOffset".concat(side === 'left' ? 'InlineStart' : 'InlineEnd');
    var managerSide = side === 'left' ? 'left' : 'right';

    // Capture pre-existing inline padding so it can be restored on cleanup
    var previousPadding = paddingTarget.style[paddingSide];
    var paddingWidth = layoutMode === _const.LAYOUT_MODE_STACKED && isMainFlyout && _siblingFlyoutWidth ? _siblingFlyoutWidth : width;
    if (shouldApplyPadding) {
      paddingTarget.style[paddingSide] = "".concat(paddingWidth, "px");
      if (shouldSetGlobalPushVars) {
        setGlobalCSSVariables((0, _defineProperty2.default)({}, cssVarName, "".concat(paddingWidth, "px")));
      }
      if (isInManagedContext && flyoutManagerRef.current) {
        flyoutManagerRef.current.setPushPadding(managerSide, paddingWidth);
      }
    } else {
      paddingTarget.style[paddingSide] = previousPadding;
      if (shouldSetGlobalPushVars) {
        setGlobalCSSVariables((0, _defineProperty2.default)({}, cssVarName, null));
      }
      if (isInManagedContext && flyoutManagerRef.current) {
        flyoutManagerRef.current.setPushPadding(managerSide, 0);
      }
    }
    return function () {
      paddingTarget.style[paddingSide] = previousPadding;
      if (shouldSetGlobalPushVars) {
        setGlobalCSSVariables((0, _defineProperty2.default)({}, cssVarName, null));
      }
      if (isInManagedContext && flyoutManagerRef.current) {
        flyoutManagerRef.current.setPushPadding(managerSide, 0);
      }
    };
  }, [isPushed, isInManagedContext, isActiveManagedFlyout, setGlobalCSSVariables, side, width, layoutMode, isMainFlyout, _siblingFlyoutWidth, shouldSetGlobalPushVars, container]);

  /**
   * This class doesn't actually do anything by EUI, but is nice to add for consumers (JIC)
   */
  (0, _react.useEffect)(function () {
    document.body.classList.add('euiBody--hasFlyout');
    return function () {
      document.body.classList.remove('euiBody--hasFlyout');
    };
  }, []);
  var hasChildFlyout = (currentSession === null || currentSession === void 0 ? void 0 : currentSession.childFlyoutId) != null;
  var isChildFlyout = isInManagedContext && hasChildFlyout && (currentSession === null || currentSession === void 0 ? void 0 : currentSession.childFlyoutId) === id;
  var shouldCloseOnEscape = (0, _react.useMemo)(function () {
    // Regular flyout - always close on ESC
    if (!isInManagedContext) {
      return true;
    }

    // Managed flyout with no child - close on ESC
    if (!hasChildFlyout) {
      return true;
    }

    // Child flyout - close on ESC
    if (isChildFlyout) {
      return true;
    }

    // Main flyout with child flyout - don't close on ESC
    return false;
  }, [isInManagedContext, hasChildFlyout, isChildFlyout]);
  var handleClose = (0, _react.useCallback)(function (event) {
    onClose(event);
  }, [onClose]);

  /**
   * ESC key closes flyout based on flyout hierarchy rules
   */
  var onKeyDown = (0, _react.useCallback)(function (event) {
    if (!isPushed && event.key === _services.keys.ESCAPE && shouldCloseOnEscape) {
      event.preventDefault();
      handleClose(event);
    }
  }, [handleClose, isPushed, shouldCloseOnEscape]);
  var managedFlyoutIndex = currentZIndexRef.current;
  if (isInManagedContext && currentSession) {
    managedFlyoutIndex = currentSession.zIndex;
  }
  var _useEuiFlyoutZIndex = (0, _use_flyout_z_index.useEuiFlyoutZIndex)({
      headerZindexLocation: effectiveHeaderZindexLocation,
      isPushed: isPushed,
      managedFlyoutIndex: managedFlyoutIndex,
      isChildFlyout: isChildFlyout
    }),
    flyoutZIndex = _useEuiFlyoutZIndex.flyoutZIndex,
    maskZIndex = _useEuiFlyoutZIndex.maskZIndex;

  /**
   * Inline styles position the flyout inside the reference container's
   * bounding rect (document.body or a specific element) while remaining in
   * document.body with position: fixed.
   */
  var inlineStyles = (0, _react.useMemo)(function () {
    var composedStyles = (0, _flyout.composeFlyoutInlineStyles)(size, layoutMode, siblingFlyoutId, siblingFlyoutWidth || null, maxWidth, flyoutZIndex);

    // Constrain the flyout to the reference container's bounding rect.
    var containerPositionStyles = {};
    if (containerRect) {
      var containerMaxWidth = containerRect.width * 0.9;
      // Use clientWidth (excludes scrollbar) to match the coordinate
      // system of getBoundingClientRect() and CSS position: fixed.
      var viewportWidth = document.documentElement.clientWidth;
      var containerRightOffset = viewportWidth - containerRect.right;

      // Compute the container-relative width for this flyout.
      //
      // For `position: fixed` elements CSS resolves `%` values against
      // the viewport, not the container. The resize hook outputs
      // percentage strings relative to `_referenceWidth` (the container),
      // so we must convert them to pixel values here.
      //
      // Named sizes use their standard proportions (matching
      // `composeFlyoutSizing`). Percentage strings from the resize hook
      // are parsed and resolved against the container width. Numeric
      // values are used directly.
      var sizePercentMap = {
        s: 0.25,
        m: 0.5,
        l: 0.75,
        fill: 0.9
      };
      var containerRelativeWidth;
      if (typeof size === 'string') {
        var namedPct = sizePercentMap[size];
        if (namedPct !== undefined) {
          containerRelativeWidth = containerRect.width * namedPct;
        } else if (size.endsWith('%')) {
          // Percentage string from the resize hook — the value is
          // relative to `_referenceWidth` (container width). Parse it
          // and resolve against the container to get the correct pixels.
          var pct = parseFloat(size);
          if (!isNaN(pct)) {
            containerRelativeWidth = containerRect.width * (pct / 100);
          }
        }
      } else if (typeof size === 'number') {
        containerRelativeWidth = size;
      }

      // All container-scoped flyouts get top/height from the container rect.
      // Reset minInlineSize to 0 so that the CSS `min-inline-size` (which
      // resolves against the viewport for `position: fixed`) does not
      // prevent the container-relative width constraints from taking effect.
      containerPositionStyles = {
        top: containerRect.top,
        height: containerRect.height,
        minInlineSize: 0
      };
      if (isChildFlyout) {
        // Child flyouts position themselves relative to the main flyout.
        // In side-by-side mode, `siblingFlyoutWidth` is the main flyout's
        // pixel width; in stacked mode it's 0 (child sits on top).
        var siblingPx = siblingFlyoutWidth || 0;
        if (side === 'left') {
          containerPositionStyles.left = containerRect.left + siblingPx;
        } else {
          containerPositionStyles.right = containerRightOffset + siblingPx;
        }
        if (containerRelativeWidth !== undefined) {
          // Set `inlineSize` (logical property) so it properly overrides
          // `inlineSize` from composedStyles. We intentionally do NOT set
          // maxInlineSize — the CSS `max-inline-size` from the size class
          // provides the size-specific cap on initial render, and the
          // resize hook's clamp handles it after resize interactions.
          //
          // For fill-size children in side-by-side mode, subtract the
          // main flyout's width so the child takes only the remaining
          // available space. For non-fill children, do NOT subtract —
          // a fill-size main will shrink dynamically to accommodate.
          var fillDeduction = size === 'fill' && layoutMode === _const.LAYOUT_MODE_SIDE_BY_SIDE && siblingFlyoutWidth ? siblingFlyoutWidth : 0;
          containerPositionStyles.inlineSize = Math.min(Math.max(0, containerRelativeWidth - fillDeduction), containerMaxWidth);
        } else {
          containerPositionStyles.maxInlineSize = containerMaxWidth;
        }
      } else {
        // Main/standalone flyouts align to the container's edge.
        if (side === 'left') {
          containerPositionStyles.left = containerRect.left;
        } else {
          containerPositionStyles.right = containerRightOffset;
        }
        if (containerRelativeWidth !== undefined) {
          // For fill-size flyouts in side-by-side mode, subtract the
          // sibling's width so the main shrinks to accommodate the child.
          var _siblingPx = size === 'fill' && layoutMode === _const.LAYOUT_MODE_SIDE_BY_SIDE && siblingFlyoutWidth ? siblingFlyoutWidth : 0;
          containerPositionStyles.inlineSize = Math.min(Math.max(0, containerRelativeWidth - _siblingPx), containerMaxWidth);
        } else {
          containerPositionStyles.maxInlineSize = containerMaxWidth;
        }
      }
    }
    return _objectSpread(_objectSpread(_objectSpread({}, style), composedStyles), containerPositionStyles);
  }, [style, size, layoutMode, siblingFlyoutId, siblingFlyoutWidth, maxWidth, flyoutZIndex, containerRect, side, isChildFlyout]);
  var styles = (0, _services.useEuiMemoizedStyles)(_flyout.euiFlyoutStyles);
  var cssStyles = [styles.euiFlyout, styles.paddingSizes[paddingSize], (0, _const2.isEuiFlyoutSizeNamed)(size) && styles[size], maxWidth === false && styles.noMaxWidth, isPushed ? styles.push.push : styles.overlay.overlay, isPushed ? styles.push[side] : styles.overlay[side], !hasAnimation && styles.noAnimation, styles[side]];
  var classes = (0, _classnames.default)('euiFlyout', isChildFlyout && hasChildBackground && 'euiFlyout--hasChildBackground', className);
  var flyoutToggle = (0, _react.useRef)(document.activeElement);
  var _useState5 = (0, _react.useState)([]),
    _useState6 = (0, _slicedToArray2.default)(_useState5, 2),
    focusTrapShards = _useState6[0],
    setFocusTrapShards = _useState6[1];
  var isSideBySideChild = isChildFlyout && layoutMode === _const.LAYOUT_MODE_SIDE_BY_SIDE;
  // Side-by-side: main + child form a single modal unit; only main has aria-modal
  // to avoid competing dialog semantics. Stacked children are independent modals.
  var announcesAsModal = (0, _react.useMemo)(function () {
    return !isPushed && !isSideBySideChild;
  }, [isPushed, isSideBySideChild]);
  var focusTrapSelectors = (0, _react.useMemo)(function () {
    var selectors = [];
    if (includeSelectorInFocusTrap) {
      selectors = Array.isArray(includeSelectorInFocusTrap) ? includeSelectorInFocusTrap : [includeSelectorInFocusTrap];
    }
    if (includeFixedHeadersInFocusTrap) {
      selectors.push('.euiHeader[data-fixed-header]');
    }

    // Include parent in focus trap shards for side-by-side mode (unified navigation).
    // In stacked mode, parent is hidden behind child so shouldn't be navigable.
    if (isSideBySideChild) {
      selectors.push("[".concat(_const.PROPERTY_LEVEL, "=\"").concat(_const.LEVEL_MAIN, "\"]"));
    }
    return selectors;
  }, [includeSelectorInFocusTrap, includeFixedHeadersInFocusTrap, isSideBySideChild]);

  /**
   * Finds the shards to include in the focus trap by querying by `focusTrapSelectors`.
   *
   * @param shouldAutoFocus Whether to auto-focus the flyout wrapper when the focus trap is activated.
   * This is necessary because when a flyout is toggled from within a shard, the focus trap's `autoFocus`
   * feature doesn't work. This logic manually focuses the flyout as a workaround.
   */
  var findShards = (0, _react.useCallback)(function () {
    var shouldAutoFocus = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
    if (focusTrapSelectors.length > 0) {
      var shardsEls = focusTrapSelectors.flatMap(function (selector) {
        return Array.from(document.querySelectorAll(selector));
      });
      setFocusTrapShards(Array.from(shardsEls));
      if (shouldAutoFocus) {
        shardsEls.forEach(function (shard) {
          if (shard.contains(flyoutToggle.current)) {
            resizeRef === null || resizeRef === void 0 || resizeRef.focus();
          }
        });
      }
    } else {
      // Clear existing shards if necessary, e.g. switching to `false`
      setFocusTrapShards(function (shards) {
        return shards.length ? [] : shards;
      });
    }
  }, [focusTrapSelectors, resizeRef]);
  (0, _react.useEffect)(function () {
    // Auto-focus should only happen on initial flyout mount (or when the dependencies change)
    // because it snaps focus to the flyout wrapper, which steals it from subsequently focused elements.
    findShards(true);
    var unsubscribe = _services.focusTrapPubSub.subscribe(function () {
      return findShards();
    });
    return unsubscribe;
  }, [findShards]);
  var focusTrapProps = (0, _react.useMemo)(function () {
    return _objectSpread(_objectSpread({}, _focusTrapProps), {}, {
      shards: [].concat((0, _toConsumableArray2.default)(focusTrapShards), (0, _toConsumableArray2.default)((_focusTrapProps === null || _focusTrapProps === void 0 ? void 0 : _focusTrapProps.shards) || []))
    });
  }, [_focusTrapProps, focusTrapShards]);

  /*
   * Provide meaningful screen reader instructions/details
   */
  var hasOverlayMask = ownFocus && !isPushed;
  var descriptionId = (0, _services.useGeneratedHtmlId)();
  var ariaDescribedBy = (0, _classnames.default)(descriptionId, _ariaDescribedBy);
  var screenReaderDescription = (0, _react.useMemo)(function () {
    return (0, _react2.jsx)(_accessibility.EuiScreenReaderOnly, null, (0, _react2.jsx)("p", {
      id: descriptionId
    }, hasOverlayMask ? (0, _react2.jsx)(_i18n.EuiI18n, {
      token: "euiFlyout.screenReaderModalDialog",
      default: "You are in a modal dialog. Press Escape or tap/click outside the dialog on the shadowed overlay to close."
    }) : (0, _react2.jsx)(_i18n.EuiI18n, {
      token: "euiFlyout.screenReaderNoOverlayMaskDialog",
      default: "You are in a modal dialog. To close the dialog, press Escape."
    }), ' ', focusTrapShards.length > 0 && (0, _react2.jsx)(_i18n.EuiI18n, {
      token: "euiFlyout.screenReaderFocusTrapShards",
      default: "You can still continue tabbing through other global page landmarks."
    })));
  }, [hasOverlayMask, descriptionId, focusTrapShards.length]);

  /*
   * Trap focus even when `ownFocus={false}`, otherwise closing
   * the flyout won't return focus to the originating button.
   *
   * Set `clickOutsideDisables={true}` when `ownFocus={false}`
   * to allow non-keyboard users the ability to interact with
   * elements outside the flyout.
   *
   * Set `onClickOutside={onClose}` when `ownFocus` and `type` are the defaults,
   * or if `outsideClickCloses={true}` to close on clicks that target
   * (both mousedown and mouseup) the overlay mask.
   */
  var onClickOutside = (0, _react.useCallback)(function (event) {
    // Do not close the flyout for any external click
    if (outsideClickCloses === false) return undefined;
    if (hasOverlayMask) {
      // The overlay mask is present, so only clicks on the mask should close the flyout, regardless of outsideClickCloses
      if (event.target === maskRef.current) return handleClose(event);
    } else {
      // No overlay mask is present, so any outside clicks should close the flyout
      if (outsideClickCloses === true) return handleClose(event);
    }
    // Otherwise if ownFocus is false and outsideClickCloses is undefined, outside clicks should not close the flyout
    return undefined;
  }, [handleClose, hasOverlayMask, outsideClickCloses]);
  var maskCombinedRefs = (0, _services.useCombinedRefs)([maskProps === null || maskProps === void 0 ? void 0 : maskProps.maskRef, maskRef]);

  /**
   * For overlay flyouts in managed contexts, coordinate scroll locking with push flyout state.
   */
  var pushPadding = (_managerState$pushPad = managerState === null || managerState === void 0 ? void 0 : managerState.pushPadding) !== null && _managerState$pushPad !== void 0 ? _managerState$pushPad : {
    left: 0,
    right: 0
  };
  var hasPushPaddingInManager = pushPadding.left > 0 || pushPadding.right > 0;
  var shouldDeferScrollLock = !isPushed && isInManagedContext && hasPushPaddingInManager;
  var shouldUseScrollLock = hasOverlayMask && !shouldDeferScrollLock;
  return (0, _react2.jsx)(_flyout_overlay.EuiFlyoutOverlay, {
    hasOverlayMask: hasOverlayMask,
    isPushed: isPushed,
    maskZIndex: maskZIndex,
    headerZindexLocation: effectiveHeaderZindexLocation,
    containerRect: containerRect,
    maskProps: _objectSpread(_objectSpread({}, maskProps), {}, {
      maskRef: maskCombinedRefs,
      hasAnimation: hasAnimation
    })
  }, (0, _react2.jsx)(_services.EuiWindowEvent, {
    event: "keydown",
    handler: onKeyDown
  }), (0, _react2.jsx)(_focus_trap.EuiFocusTrap, (0, _extends2.default)({
    disabled: isPushed,
    scrollLock: shouldUseScrollLock,
    clickOutsideDisables: !ownFocus,
    onClickOutside: onClickOutside
  }, focusTrapProps), (0, _react2.jsx)(Element, (0, _extends2.default)({
    className: classes,
    css: cssStyles,
    style: inlineStyles,
    ref: setRef,
    id: id
  }, rest, {
    role: announcesAsModal ? 'dialog' : rest.role,
    "aria-modal": announcesAsModal ? true : undefined,
    tabIndex: !isPushed ? 0 : rest.tabIndex,
    "aria-describedby": !isPushed ? ariaDescribedBy : _ariaDescribedBy,
    "aria-labelledby": ariaLabelledBy,
    "data-autofocus": !isPushed || undefined,
    onAnimationEnd: onAnimationEnd
  }), !isPushed && screenReaderDescription, shouldRenderMenu ? (0, _react2.jsx)(_flyout_menu.EuiFlyoutMenu, (0, _extends2.default)({}, flyoutMenuProps, {
    titleId: flyoutMenuId
  })) : !hideCloseButton && (0, _react2.jsx)(_flyout_close_button.EuiFlyoutCloseButton, (0, _extends2.default)({}, closeButtonProps, {
    onClose: handleClose,
    closeButtonPosition: closeButtonPosition,
    side: side
  })), resizable && (0, _react2.jsx)(_flyout_resize_button.EuiFlyoutResizeButton, {
    type: type,
    side: side,
    ownFocus: ownFocus,
    isPushed: isPushed,
    onMouseDown: onMouseDownResizableButton,
    onTouchStart: onMouseDownResizableButton,
    onKeyDown: onKeyDownResizableButton
  }), (0, _react2.jsx)(_flyout_parent_context.EuiFlyoutParentProvider, null, children))));
}
// React.forwardRef interferes with the inferred element type
// Casting to ensure correct element prop type checking for `as`
// e.g., `href` is not on a `div`
);
// Recast to allow `displayName`
EuiFlyoutComponent.displayName = 'EuiFlyoutComponent';