/*!
 * (C) Ionic http://ionicframework.com - MIT License
 */
import { r as registerInstance, c as createEvent, e as config, j as printIonError, h, d as Host, g as getElement } from './index-C8IsBmNU.js';
import { g as getTimeGivenProgression } from './cubic-bezier-hHmYLOfE.js';
import { o as getPresentedOverlay, B as BACKDROP, n as focusFirstDescendant, q as focusLastDescendant, G as GESTURE } from './overlays-Bi5WpIkN.js';
import { G as GESTURE_CONTROLLER } from './gesture-controller-BTEOs1at.js';
import { b as getIonMode, a as isPlatform, c as getIonTheme, s as shouldUseCloseWatcher } from './ionic-global-2lDD9k7y.js';
import { o as isEndSide, i as inheritAriaAttributes, l as assert, e as clamp } from './helpers-Bsml3FcE.js';
import { m as menuController } from './index-BQI9hSZP.js';
import { h as hostContext, c as createColorClasses } from './theme-DiVJyqlX.js';
import { l as listSvg } from './list-Dhi5xtNS.js';
import { u as menuSharp, v as menuOutline } from './index-COG0_eom.js';
import './framework-delegate-D2mUP0WI.js';
import './focus-visible-vXpMhGrs.js';
import './animation-BNuoDl-O.js';

const ionicMenuMdCss = ":host{--width:304px;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--background:var(--ion-background-color, #fff);right:0;left:0;top:0;bottom:0;display:none;position:absolute;contain:strict}:host(.show-menu){display:block}.menu-inner{-webkit-transform:translateX(-9999px);transform:translateX(-9999px);display:-ms-flexbox;display:flex;position:absolute;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:justify;justify-content:space-between;width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);background:var(--background);contain:strict}:host(.menu-side-start) .menu-inner{--ion-safe-area-right:0px;top:0;bottom:0}:host(.menu-side-start) .menu-inner{inset-inline-start:0;inset-inline-end:auto}:host-context([dir=rtl]):host(.menu-side-start) .menu-inner,:host-context([dir=rtl]).menu-side-start .menu-inner{--ion-safe-area-right:unset;--ion-safe-area-left:0px}@supports selector(:dir(rtl)){:host(.menu-side-start:dir(rtl)) .menu-inner{--ion-safe-area-right:unset;--ion-safe-area-left:0px}}:host(.menu-side-end) .menu-inner{--ion-safe-area-left:0px;top:0;bottom:0}:host(.menu-side-end) .menu-inner{inset-inline-start:auto;inset-inline-end:0}:host-context([dir=rtl]):host(.menu-side-end) .menu-inner,:host-context([dir=rtl]).menu-side-end .menu-inner{--ion-safe-area-left:unset;--ion-safe-area-right:0px}@supports selector(:dir(rtl)){:host(.menu-side-end:dir(rtl)) .menu-inner{--ion-safe-area-left:unset;--ion-safe-area-right:0px}}ion-backdrop{display:none;opacity:0.01;z-index:-1}@media (max-width: 340px){.menu-inner{--width:264px}}:host(.menu-type-reveal){z-index:0}:host(.menu-type-reveal.show-menu) .menu-inner{-webkit-transform:translate3d(0,  0,  0);transform:translate3d(0,  0,  0)}:host(.menu-type-overlay){z-index:1000}:host(.menu-type-overlay) .show-backdrop{display:block;cursor:pointer}:host(.menu-pane-visible){-ms-flex:0 1 auto;flex:0 1 auto;width:var(--side-width, var(--width));min-width:var(--side-min-width, var(--min-width));max-width:var(--side-max-width, var(--max-width))}:host(.menu-pane-visible.split-pane-side){right:0;left:0;top:0;bottom:0;position:relative;-webkit-box-shadow:none;box-shadow:none;z-index:0}:host(.menu-pane-visible.split-pane-side.menu-enabled){display:-ms-flexbox;display:flex;-ms-flex-negative:0;flex-shrink:0}:host(.menu-pane-visible.split-pane-side){-ms-flex-order:-1;order:-1}:host(.menu-pane-visible.split-pane-side[side=end]){-ms-flex-order:1;order:1}:host(.menu-pane-visible) .menu-inner{right:0;left:0;width:auto;-webkit-transform:none;transform:none;-webkit-box-shadow:none;box-shadow:none}:host(.menu-pane-visible) ion-backdrop{display:hidden !important}:host(.menu-pane-visible.split-pane-side){-webkit-border-start:0;border-inline-start:0;-webkit-border-end:var(--border);border-inline-end:var(--border);border-top:0;border-bottom:0;min-width:var(--side-min-width);max-width:var(--side-max-width)}:host(.menu-pane-visible.split-pane-side[side=end]){-webkit-border-start:var(--border);border-inline-start:var(--border);-webkit-border-end:0;border-inline-end:0;border-top:0;border-bottom:0;min-width:var(--side-min-width);max-width:var(--side-max-width)}:host(.menu-type-overlay) .menu-inner{-webkit-box-shadow:4px 0px 16px rgba(0, 0, 0, 0.18);box-shadow:4px 0px 16px rgba(0, 0, 0, 0.18)}";

const menuIosCss = ":host{--width:304px;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--background:var(--ion-background-color, #fff);right:0;left:0;top:0;bottom:0;display:none;position:absolute;contain:strict}:host(.show-menu){display:block}.menu-inner{-webkit-transform:translateX(-9999px);transform:translateX(-9999px);display:-ms-flexbox;display:flex;position:absolute;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:justify;justify-content:space-between;width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);background:var(--background);contain:strict}:host(.menu-side-start) .menu-inner{--ion-safe-area-right:0px;top:0;bottom:0}:host(.menu-side-start) .menu-inner{inset-inline-start:0;inset-inline-end:auto}:host-context([dir=rtl]):host(.menu-side-start) .menu-inner,:host-context([dir=rtl]).menu-side-start .menu-inner{--ion-safe-area-right:unset;--ion-safe-area-left:0px}@supports selector(:dir(rtl)){:host(.menu-side-start:dir(rtl)) .menu-inner{--ion-safe-area-right:unset;--ion-safe-area-left:0px}}:host(.menu-side-end) .menu-inner{--ion-safe-area-left:0px;top:0;bottom:0}:host(.menu-side-end) .menu-inner{inset-inline-start:auto;inset-inline-end:0}:host-context([dir=rtl]):host(.menu-side-end) .menu-inner,:host-context([dir=rtl]).menu-side-end .menu-inner{--ion-safe-area-left:unset;--ion-safe-area-right:0px}@supports selector(:dir(rtl)){:host(.menu-side-end:dir(rtl)) .menu-inner{--ion-safe-area-left:unset;--ion-safe-area-right:0px}}ion-backdrop{display:none;opacity:0.01;z-index:-1}@media (max-width: 340px){.menu-inner{--width:264px}}:host(.menu-type-reveal){z-index:0}:host(.menu-type-reveal.show-menu) .menu-inner{-webkit-transform:translate3d(0,  0,  0);transform:translate3d(0,  0,  0)}:host(.menu-type-overlay){z-index:1000}:host(.menu-type-overlay) .show-backdrop{display:block;cursor:pointer}:host(.menu-pane-visible){-ms-flex:0 1 auto;flex:0 1 auto;width:var(--side-width, var(--width));min-width:var(--side-min-width, var(--min-width));max-width:var(--side-max-width, var(--max-width))}:host(.menu-pane-visible.split-pane-side){right:0;left:0;top:0;bottom:0;position:relative;-webkit-box-shadow:none;box-shadow:none;z-index:0}:host(.menu-pane-visible.split-pane-side.menu-enabled){display:-ms-flexbox;display:flex;-ms-flex-negative:0;flex-shrink:0}:host(.menu-pane-visible.split-pane-side){-ms-flex-order:-1;order:-1}:host(.menu-pane-visible.split-pane-side[side=end]){-ms-flex-order:1;order:1}:host(.menu-pane-visible) .menu-inner{right:0;left:0;width:auto;-webkit-transform:none;transform:none;-webkit-box-shadow:none;box-shadow:none}:host(.menu-pane-visible) ion-backdrop{display:hidden !important}:host(.menu-pane-visible.split-pane-side){-webkit-border-start:0;border-inline-start:0;-webkit-border-end:var(--border);border-inline-end:var(--border);border-top:0;border-bottom:0;min-width:var(--side-min-width);max-width:var(--side-max-width)}:host(.menu-pane-visible.split-pane-side[side=end]){-webkit-border-start:var(--border);border-inline-start:var(--border);-webkit-border-end:0;border-inline-end:0;border-top:0;border-bottom:0;min-width:var(--side-min-width);max-width:var(--side-max-width)}:host(.menu-type-push){z-index:1000}:host(.menu-type-push) .show-backdrop{display:block}";

const menuMdCss = ":host{--width:304px;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--background:var(--ion-background-color, #fff);right:0;left:0;top:0;bottom:0;display:none;position:absolute;contain:strict}:host(.show-menu){display:block}.menu-inner{-webkit-transform:translateX(-9999px);transform:translateX(-9999px);display:-ms-flexbox;display:flex;position:absolute;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:justify;justify-content:space-between;width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);background:var(--background);contain:strict}:host(.menu-side-start) .menu-inner{--ion-safe-area-right:0px;top:0;bottom:0}:host(.menu-side-start) .menu-inner{inset-inline-start:0;inset-inline-end:auto}:host-context([dir=rtl]):host(.menu-side-start) .menu-inner,:host-context([dir=rtl]).menu-side-start .menu-inner{--ion-safe-area-right:unset;--ion-safe-area-left:0px}@supports selector(:dir(rtl)){:host(.menu-side-start:dir(rtl)) .menu-inner{--ion-safe-area-right:unset;--ion-safe-area-left:0px}}:host(.menu-side-end) .menu-inner{--ion-safe-area-left:0px;top:0;bottom:0}:host(.menu-side-end) .menu-inner{inset-inline-start:auto;inset-inline-end:0}:host-context([dir=rtl]):host(.menu-side-end) .menu-inner,:host-context([dir=rtl]).menu-side-end .menu-inner{--ion-safe-area-left:unset;--ion-safe-area-right:0px}@supports selector(:dir(rtl)){:host(.menu-side-end:dir(rtl)) .menu-inner{--ion-safe-area-left:unset;--ion-safe-area-right:0px}}ion-backdrop{display:none;opacity:0.01;z-index:-1}@media (max-width: 340px){.menu-inner{--width:264px}}:host(.menu-type-reveal){z-index:0}:host(.menu-type-reveal.show-menu) .menu-inner{-webkit-transform:translate3d(0,  0,  0);transform:translate3d(0,  0,  0)}:host(.menu-type-overlay){z-index:1000}:host(.menu-type-overlay) .show-backdrop{display:block;cursor:pointer}:host(.menu-pane-visible){-ms-flex:0 1 auto;flex:0 1 auto;width:var(--side-width, var(--width));min-width:var(--side-min-width, var(--min-width));max-width:var(--side-max-width, var(--max-width))}:host(.menu-pane-visible.split-pane-side){right:0;left:0;top:0;bottom:0;position:relative;-webkit-box-shadow:none;box-shadow:none;z-index:0}:host(.menu-pane-visible.split-pane-side.menu-enabled){display:-ms-flexbox;display:flex;-ms-flex-negative:0;flex-shrink:0}:host(.menu-pane-visible.split-pane-side){-ms-flex-order:-1;order:-1}:host(.menu-pane-visible.split-pane-side[side=end]){-ms-flex-order:1;order:1}:host(.menu-pane-visible) .menu-inner{right:0;left:0;width:auto;-webkit-transform:none;transform:none;-webkit-box-shadow:none;box-shadow:none}:host(.menu-pane-visible) ion-backdrop{display:hidden !important}:host(.menu-pane-visible.split-pane-side){-webkit-border-start:0;border-inline-start:0;-webkit-border-end:var(--border);border-inline-end:var(--border);border-top:0;border-bottom:0;min-width:var(--side-min-width);max-width:var(--side-max-width)}:host(.menu-pane-visible.split-pane-side[side=end]){-webkit-border-start:var(--border);border-inline-start:var(--border);-webkit-border-end:0;border-inline-end:0;border-top:0;border-bottom:0;min-width:var(--side-min-width);max-width:var(--side-max-width)}:host(.menu-type-overlay) .menu-inner{-webkit-box-shadow:4px 0px 16px rgba(0, 0, 0, 0.18);box-shadow:4px 0px 16px rgba(0, 0, 0, 0.18)}";

const iosEasing = 'cubic-bezier(0.32,0.72,0,1)';
const mdEasing = 'cubic-bezier(0.0,0.0,0.2,1)';
const iosEasingReverse = 'cubic-bezier(1, 0, 0.68, 0.28)';
const mdEasingReverse = 'cubic-bezier(0.4, 0, 0.6, 1)';
const Menu = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
        this.ionWillOpen = createEvent(this, "ionWillOpen", 7);
        this.ionWillClose = createEvent(this, "ionWillClose", 7);
        this.ionDidOpen = createEvent(this, "ionDidOpen", 7);
        this.ionDidClose = createEvent(this, "ionDidClose", 7);
        this.ionMenuChange = createEvent(this, "ionMenuChange", 7);
        this.lastOnEnd = 0;
        this.blocker = GESTURE_CONTROLLER.createBlocker({ disableScroll: true });
        this.didLoad = false;
        /**
         * Flag used to determine if an open/close
         * operation was cancelled. For example, if
         * an app calls "menu.open" then disables the menu
         * part way through the animation, then this would
         * be considered a cancelled operation.
         */
        this.operationCancelled = false;
        this.isAnimating = false;
        this._isOpen = false;
        this.inheritedAttributes = {};
        this.handleFocus = (ev) => {
            /**
             * Overlays have their own focus trapping listener
             * so we do not want the two listeners to conflict
             * with each other. If the top-most overlay that is
             * open does not contain this ion-menu, then ion-menu's
             * focus trapping should not run.
             */
            const lastOverlay = getPresentedOverlay(document);
            if (lastOverlay && !lastOverlay.contains(this.el)) {
                return;
            }
            this.trapKeyboardFocus(ev, document);
        };
        /**
         * If true, then the menu should be
         * visible within a split pane.
         * If false, then the menu is hidden.
         * However, the menu-button/menu-toggle
         * components can be used to open the
         * menu.
         */
        this.isPaneVisible = false;
        this.isEndSide = false;
        /**
         * If `true`, the menu is disabled.
         */
        this.disabled = false;
        /**
         * Which side of the view the menu should be placed.
         */
        this.side = 'start';
        /**
         * If `true`, swiping the menu is enabled.
         */
        this.swipeGesture = true;
        /**
         * The edge threshold for dragging the menu open.
         * If a drag/swipe happens over this value, the menu is not triggered.
         */
        this.maxEdgeStart = 50;
    }
    typeChanged(type, oldType) {
        const contentEl = this.contentEl;
        if (contentEl) {
            if (oldType !== undefined) {
                contentEl.classList.remove(`menu-content-${oldType}`);
            }
            contentEl.classList.add(`menu-content-${type}`);
            contentEl.removeAttribute('style');
        }
        if (this.menuInnerEl) {
            // Remove effects of previous animations
            this.menuInnerEl.removeAttribute('style');
        }
        this.animation = undefined;
    }
    disabledChanged() {
        this.updateState();
        this.ionMenuChange.emit({
            disabled: this.disabled,
            open: this._isOpen,
        });
    }
    sideChanged() {
        this.isEndSide = isEndSide(this.side);
        /**
         * Menu direction animation is calculated based on the document direction.
         * If the document direction changes, we need to create a new animation.
         */
        this.animation = undefined;
    }
    swipeGestureChanged() {
        this.updateState();
    }
    async connectedCallback() {
        // TODO: connectedCallback is fired in CE build
        // before WC is defined. This needs to be fixed in Stencil.
        if (typeof customElements !== 'undefined' && customElements != null) {
            await customElements.whenDefined('ion-menu');
        }
        if (this.type === undefined) {
            this.type = config.get('menuType', 'overlay');
        }
        const content = this.contentId !== undefined ? document.getElementById(this.contentId) : null;
        if (content === null) {
            printIonError('[ion-menu] - Must have a "content" element to listen for drag events on.');
            return;
        }
        if (this.el.contains(content)) {
            printIonError(`[ion-menu] - The "contentId" should refer to the main view's ion-content, not the ion-content inside of the ion-menu.`);
        }
        this.contentEl = content;
        // add menu's content classes
        content.classList.add('menu-content');
        this.typeChanged(this.type, undefined);
        this.sideChanged();
        // register this menu with the app's menu controller
        menuController._register(this);
        this.menuChanged();
        this.gesture = (await import('./index-CfgBF1SE.js')).createGesture({
            el: document,
            gestureName: 'menu-swipe',
            gesturePriority: 30,
            threshold: 10,
            blurOnStart: true,
            canStart: (ev) => this.canStart(ev),
            onWillStart: () => this.onWillStart(),
            onStart: () => this.onStart(),
            onMove: (ev) => this.onMove(ev),
            onEnd: (ev) => this.onEnd(ev),
        });
        this.updateState();
    }
    componentWillLoad() {
        this.inheritedAttributes = inheritAriaAttributes(this.el);
    }
    async componentDidLoad() {
        this.didLoad = true;
        /**
         * A menu inside of a split pane is assumed
         * to be a side pane.
         *
         * When the menu is loaded it needs to
         * see if it should be considered visible inside
         * of the split pane. If the split pane is
         * hidden then the menu should be too.
         */
        const splitPane = this.el.closest('ion-split-pane');
        if (splitPane !== null) {
            this.isPaneVisible = await splitPane.isVisible();
        }
        this.menuChanged();
        this.updateState();
    }
    menuChanged() {
        /**
         * Inform dependent components such as ion-menu-button
         * that the menu is ready. Note that we only want to do this
         * once the menu has been rendered which is why we check for didLoad.
         */
        if (this.didLoad) {
            this.ionMenuChange.emit({ disabled: this.disabled, open: this._isOpen });
        }
    }
    async disconnectedCallback() {
        /**
         * The menu should be closed when it is
         * unmounted from the DOM.
         * This is an async call, so we need to wait for
         * this to finish otherwise contentEl
         * will not have MENU_CONTENT_OPEN removed.
         */
        await this.close(false);
        this.blocker.destroy();
        menuController._unregister(this);
        if (this.animation) {
            this.animation.destroy();
        }
        if (this.gesture) {
            this.gesture.destroy();
            this.gesture = undefined;
        }
        this.animation = undefined;
        this.contentEl = undefined;
    }
    onSplitPaneChanged(ev) {
        const closestSplitPane = this.el.closest('ion-split-pane');
        if (closestSplitPane !== null && closestSplitPane === ev.target) {
            this.isPaneVisible = ev.detail.visible;
            this.updateState();
        }
    }
    onBackdropClick(ev) {
        // TODO(FW-2832): type (CustomEvent triggers errors which should be sorted)
        if (this._isOpen && this.lastOnEnd < ev.timeStamp - 100) {
            const shouldClose = ev.composedPath ? !ev.composedPath().includes(this.menuInnerEl) : false;
            if (shouldClose) {
                ev.preventDefault();
                ev.stopPropagation();
                this.close(undefined, BACKDROP);
            }
        }
    }
    onKeydown(ev) {
        if (ev.key === 'Escape') {
            this.close(undefined, BACKDROP);
        }
    }
    /**
     * Returns `true` is the menu is open.
     */
    isOpen() {
        return Promise.resolve(this._isOpen);
    }
    /**
     * Returns `true` if the menu is active.
     *
     * A menu is active when it can be opened or closed, meaning it's enabled
     * and it's not part of a `ion-split-pane`.
     */
    isActive() {
        return Promise.resolve(this._isActive());
    }
    /**
     * Opens the menu. If the menu is already open or it can't be opened,
     * it returns `false`.
     *
     * @param animated If `true`, the menu will animate when opening.
     * If `false`, the menu will open instantly without animation.
     * Defaults to `true`.
     */
    open(animated = true) {
        return this.setOpen(true, animated);
    }
    /**
     * Closes the menu. If the menu is already closed or it can't be closed,
     * it returns `false`.
     *
     * @param animated If `true`, the menu will animate when closing. If `false`,
     * the menu will close instantly without animation. Defaults to `true`.
     * @param role The role of the element that is closing the menu.
     * This can be useful in a button handler for determining which button was
     * clicked to close the menu. Some examples include:
     * `"cancel"`, `"destructive"`, `"selected"`, and `"backdrop"`.
     */
    close(animated = true, role) {
        return this.setOpen(false, animated, role);
    }
    /**
     * Toggles the menu. If the menu is already open, it will try to close,
     * otherwise it will try to open it.
     * If the operation can't be completed successfully, it returns `false`.
     *
     * @param animated If `true`, the menu will animate when opening/closing.
     * If `false`, the menu will open/close instantly without animation.
     * Defaults to `true`.
     */
    toggle(animated = true) {
        return this.setOpen(!this._isOpen, animated);
    }
    /**
     * Opens or closes the menu.
     * If the operation can't be completed successfully, it returns `false`.
     *
     * @param shouldOpen If `true`, the menu will open. If `false`, the menu
     * will close.
     * @param animated If `true`, the menu will animate when opening/closing.
     * If `false`, the menu will open/close instantly without animation.
     * @param role The role of the element that is closing the menu.
     */
    setOpen(shouldOpen, animated = true, role) {
        var _a;
        // Blur the active element to prevent it from being kept focused inside an element that will be set with aria-hidden="true"
        (_a = document.activeElement) === null || _a === void 0 ? void 0 : _a.blur();
        return menuController._setOpen(this, shouldOpen, animated, role);
    }
    trapKeyboardFocus(ev, doc) {
        const target = ev.target;
        if (!target) {
            return;
        }
        /**
         * If the target is inside the menu contents, let the browser
         * focus as normal and keep a log of the last focused element.
         */
        if (this.el.contains(target)) {
            this.lastFocus = target;
        }
        else {
            /**
             * Otherwise, we are about to have focus go out of the menu.
             * Wrap the focus to either the first or last element.
             */
            const { el } = this;
            /**
             * Once we call `focusFirstDescendant`, another focus event
             * will fire, which will cause `lastFocus` to be updated
             * before we can run the code after that. We cache the value
             * here to avoid that.
             */
            focusFirstDescendant(el);
            /**
             * If the cached last focused element is the same as the now-
             * active element, that means the user was on the first element
             * already and pressed Shift + Tab, so we need to wrap to the
             * last descendant.
             */
            if (this.lastFocus === doc.activeElement) {
                focusLastDescendant(el);
            }
        }
    }
    async _setOpen(shouldOpen, animated = true, role) {
        // If the menu is disabled or it is currently being animated, let's do nothing
        if (!this._isActive() || this.isAnimating || shouldOpen === this._isOpen) {
            return false;
        }
        this.beforeAnimation(shouldOpen, role);
        await this.loadAnimation();
        await this.startAnimation(shouldOpen, animated);
        /**
         * If the animation was cancelled then
         * return false because the operation
         * did not succeed.
         */
        if (this.operationCancelled) {
            this.operationCancelled = false;
            return false;
        }
        this.afterAnimation(shouldOpen, role);
        return true;
    }
    async loadAnimation() {
        // Menu swipe animation takes the menu's inner width as parameter,
        // If `offsetWidth` changes, we need to create a new animation.
        const width = this.menuInnerEl.offsetWidth;
        /**
         * Menu direction animation is calculated based on the document direction.
         * If the document direction changes, we need to create a new animation.
         */
        const isEndSide$1 = isEndSide(this.side);
        if (width === this.width && this.animation !== undefined && isEndSide$1 === this.isEndSide) {
            return;
        }
        this.width = width;
        this.isEndSide = isEndSide$1;
        // Destroy existing animation
        if (this.animation) {
            this.animation.destroy();
            this.animation = undefined;
        }
        // Create new animation
        const animation = (this.animation = await menuController._createAnimation(this.type, this));
        if (!config.getBoolean('animated', true)) {
            animation.duration(0);
        }
        animation.fill('both');
    }
    async startAnimation(shouldOpen, animated) {
        const isReversed = !shouldOpen;
        const mode = getIonMode(this);
        const easing = mode === 'ios' ? iosEasing : mdEasing;
        const easingReverse = mode === 'ios' ? iosEasingReverse : mdEasingReverse;
        const ani = this.animation
            .direction(isReversed ? 'reverse' : 'normal')
            .easing(isReversed ? easingReverse : easing);
        if (animated) {
            await ani.play();
        }
        else {
            ani.play({ sync: true });
        }
        /**
         * We run this after the play invocation
         * instead of using ani.onFinish so that
         * multiple onFinish callbacks do not get
         * run if an animation is played, stopped,
         * and then played again.
         */
        if (ani.getDirection() === 'reverse') {
            ani.direction('normal');
        }
    }
    _isActive() {
        return !this.disabled && !this.isPaneVisible;
    }
    canSwipe() {
        return this.swipeGesture && !this.isAnimating && this._isActive();
    }
    canStart(detail) {
        // Do not allow swipe gesture if a modal is open
        const isModalPresented = !!document.querySelector('ion-modal.show-modal');
        if (isModalPresented || !this.canSwipe()) {
            return false;
        }
        if (this._isOpen) {
            return true;
        }
        else if (menuController._getOpenSync()) {
            return false;
        }
        return checkEdgeSide(window, detail.currentX, this.isEndSide, this.maxEdgeStart);
    }
    onWillStart() {
        this.beforeAnimation(!this._isOpen, GESTURE);
        return this.loadAnimation();
    }
    onStart() {
        if (!this.isAnimating || !this.animation) {
            assert(false, 'isAnimating has to be true');
            return;
        }
        // the cloned animation should not use an easing curve during seek
        this.animation.progressStart(true, this._isOpen ? 1 : 0);
    }
    onMove(detail) {
        if (!this.isAnimating || !this.animation) {
            assert(false, 'isAnimating has to be true');
            return;
        }
        const delta = computeDelta(detail.deltaX, this._isOpen, this.isEndSide);
        const stepValue = delta / this.width;
        this.animation.progressStep(this._isOpen ? 1 - stepValue : stepValue);
    }
    onEnd(detail) {
        if (!this.isAnimating || !this.animation) {
            assert(false, 'isAnimating has to be true');
            return;
        }
        const isOpen = this._isOpen;
        const isEndSide = this.isEndSide;
        const delta = computeDelta(detail.deltaX, isOpen, isEndSide);
        const width = this.width;
        const stepValue = delta / width;
        const velocity = detail.velocityX;
        const z = width / 2.0;
        const shouldCompleteRight = velocity >= 0 && (velocity > 0.2 || detail.deltaX > z);
        const shouldCompleteLeft = velocity <= 0 && (velocity < -0.2 || detail.deltaX < -z);
        const shouldComplete = isOpen
            ? isEndSide
                ? shouldCompleteRight
                : shouldCompleteLeft
            : isEndSide
                ? shouldCompleteLeft
                : shouldCompleteRight;
        let shouldOpen = !isOpen && shouldComplete;
        if (isOpen && !shouldComplete) {
            shouldOpen = true;
        }
        this.lastOnEnd = detail.currentTime;
        // Account for rounding errors in JS
        let newStepValue = shouldComplete ? 0.001 : -1e-3;
        /**
         * stepValue can sometimes return a negative
         * value, but you can't have a negative time value
         * for the cubic bezier curve (at least with web animations)
         */
        const adjustedStepValue = stepValue < 0 ? 0.01 : stepValue;
        /**
         * Animation will be reversed here, so need to
         * reverse the easing curve as well
         *
         * Additionally, we need to account for the time relative
         * to the new easing curve, as `stepValue` is going to be given
         * in terms of a linear curve.
         */
        newStepValue +=
            getTimeGivenProgression([0, 0], [0.4, 0], [0.6, 1], [1, 1], clamp(0, adjustedStepValue, 0.9999))[0] || 0;
        const playTo = this._isOpen ? !shouldComplete : shouldComplete;
        this.animation
            .easing('cubic-bezier(0.4, 0.0, 0.6, 1)')
            .onFinish(() => this.afterAnimation(shouldOpen, GESTURE), { oneTimeCallback: true })
            .progressEnd(playTo ? 1 : 0, this._isOpen ? 1 - newStepValue : newStepValue, 300);
    }
    beforeAnimation(shouldOpen, role) {
        assert(!this.isAnimating, '_before() should not be called while animating');
        /**
         * When the menu is presented on an Android device, TalkBack's focus rings
         * may appear in the wrong position due to the transition (specifically
         * `transform` styles). This occurs because the focus rings are initially
         * displayed at the starting position of the elements before the transition
         * begins. This workaround ensures the focus rings do not appear in the
         * incorrect location.
         *
         * If this solution is applied to iOS devices, then it leads to a bug where
         * the overlays cannot be accessed by screen readers. This is due to
         * VoiceOver not being able to update the accessibility tree when the
         * `aria-hidden` is removed.
         */
        if (isPlatform('android')) {
            this.el.setAttribute('aria-hidden', 'true');
        }
        // this places the menu into the correct location before it animates in
        // this css class doesn't actually kick off any animations
        this.el.classList.add(SHOW_MENU);
        /**
         * We add a tabindex here so that focus trapping
         * still works even if the menu does not have
         * any focusable elements slotted inside. The
         * focus trapping utility will fallback to focusing
         * the menu so focus does not leave when the menu
         * is open.
         */
        this.el.setAttribute('tabindex', '0');
        if (this.backdropEl) {
            this.backdropEl.classList.add(SHOW_BACKDROP);
        }
        // add css class and hide content behind menu from screen readers
        if (this.contentEl) {
            this.contentEl.classList.add(MENU_CONTENT_OPEN);
            /**
             * When the menu is open and overlaying the main
             * content, the main content should not be announced
             * by the screenreader as the menu is the main
             * focus. This is useful with screenreaders that have
             * "read from top" gestures that read the entire
             * page from top to bottom when activated.
             * This should be done before the animation starts
             * so that users cannot accidentally scroll
             * the content while dragging a menu open.
             */
            this.contentEl.setAttribute('aria-hidden', 'true');
        }
        this.blocker.block();
        this.isAnimating = true;
        if (shouldOpen) {
            this.ionWillOpen.emit();
        }
        else {
            this.ionWillClose.emit({ role });
        }
    }
    afterAnimation(isOpen, role) {
        var _a;
        // keep opening/closing the menu disabled for a touch more yet
        // only add listeners/css if it's enabled and isOpen
        // and only remove listeners/css if it's not open
        // emit opened/closed events
        this._isOpen = isOpen;
        this.isAnimating = false;
        if (!this._isOpen) {
            this.blocker.unblock();
        }
        if (isOpen) {
            /**
             * When the menu is presented on an Android device, TalkBack's focus rings
             * may appear in the wrong position due to the transition (specifically
             * `transform` styles). The menu is hidden from screen readers during the
             * transition to prevent this. Once the transition is complete, the menu
             * is shown again.
             */
            if (isPlatform('android')) {
                this.el.removeAttribute('aria-hidden');
            }
            // emit open event
            this.ionDidOpen.emit();
            /**
             * Move focus to the menu to prepare focus trapping, as long as
             * it isn't already focused. Use the host element instead of the
             * first descendant to avoid the scroll position jumping around.
             */
            const focusedMenu = (_a = document.activeElement) === null || _a === void 0 ? void 0 : _a.closest('ion-menu');
            if (focusedMenu !== this.el) {
                this.el.focus();
            }
            // start focus trapping
            document.addEventListener('focus', this.handleFocus, true);
        }
        else {
            this.el.removeAttribute('aria-hidden');
            // remove css classes and unhide content from screen readers
            this.el.classList.remove(SHOW_MENU);
            /**
             * Remove tabindex from the menu component
             * so that is cannot be tabbed to.
             */
            this.el.removeAttribute('tabindex');
            if (this.contentEl) {
                this.contentEl.classList.remove(MENU_CONTENT_OPEN);
                /**
                 * Remove aria-hidden so screen readers
                 * can announce the main content again
                 * now that the menu is not the main focus.
                 */
                this.contentEl.removeAttribute('aria-hidden');
            }
            if (this.backdropEl) {
                this.backdropEl.classList.remove(SHOW_BACKDROP);
            }
            if (this.animation) {
                this.animation.stop();
            }
            // emit close event
            this.ionDidClose.emit({ role });
            // undo focus trapping so multiple menus don't collide
            document.removeEventListener('focus', this.handleFocus, true);
        }
    }
    updateState() {
        const isActive = this._isActive();
        if (this.gesture) {
            this.gesture.enable(isActive && this.swipeGesture);
        }
        /**
         * If the menu is disabled but it is still open
         * then we should close the menu immediately.
         * Additionally, if the menu is in the process
         * of animating {open, close} and the menu is disabled
         * then it should still be closed immediately.
         */
        if (!isActive) {
            /**
             * It is possible to disable the menu while
             * it is mid-animation. When this happens, we
             * need to set the operationCancelled flag
             * so that this._setOpen knows to return false
             * and not run the "afterAnimation" callback.
             */
            if (this.isAnimating) {
                this.operationCancelled = true;
            }
            /**
             * If the menu is disabled then we should
             * forcibly close the menu even if it is open.
             */
            this.afterAnimation(false, GESTURE);
        }
    }
    render() {
        const { type, disabled, el, isPaneVisible, inheritedAttributes, side } = this;
        const theme = getIonTheme(this);
        /**
         * If the Close Watcher is enabled then
         * the ionBackButton listener in the menu controller
         * will handle closing the menu when Escape is pressed.
         */
        return (h(Host, { key: '77c64f0e339d5446f0e798d282935aace70da864', onKeyDown: shouldUseCloseWatcher() ? null : this.onKeydown, role: "navigation", "aria-label": inheritedAttributes['aria-label'] || 'menu', class: {
                [theme]: true,
                [`menu-type-${type}`]: true,
                'menu-enabled': !disabled,
                [`menu-side-${side}`]: true,
                'menu-pane-visible': isPaneVisible,
                'split-pane-side': hostContext('ion-split-pane', el),
            } }, h("div", { key: '6a2f346328fa682f8e9feae415427a0bfc34c958', class: "menu-inner", part: "container", ref: (el) => (this.menuInnerEl = el) }, h("slot", { key: 'd115caef9535f0a99becb1e7b6c28386f00bc4af' })), h("ion-backdrop", { key: '777937d2d456a4c1d22632fad6726c7db3647baf', ref: (el) => (this.backdropEl = el), class: "menu-backdrop", tappable: false, stopPropagation: false, part: "backdrop" })));
    }
    get el() { return getElement(this); }
    static get watchers() { return {
        "type": ["typeChanged"],
        "disabled": ["disabledChanged"],
        "side": ["sideChanged"],
        "swipeGesture": ["swipeGestureChanged"]
    }; }
};
const computeDelta = (deltaX, isOpen, isEndSide) => {
    return Math.max(0, isOpen !== isEndSide ? -deltaX : deltaX);
};
const checkEdgeSide = (win, posX, isEndSide, maxEdgeStart) => {
    if (isEndSide) {
        return posX >= win.innerWidth - maxEdgeStart;
    }
    else {
        return posX <= maxEdgeStart;
    }
};
const SHOW_MENU = 'show-menu';
const SHOW_BACKDROP = 'show-backdrop';
const MENU_CONTENT_OPEN = 'menu-content-open';
Menu.style = {
    ionic: ionicMenuMdCss,
    ios: menuIosCss,
    md: menuMdCss
};

// Given a menu, return whether or not the menu toggle should be visible
const updateVisibility = async (menu) => {
    const menuEl = await menuController.get(menu);
    return !!(menuEl && (await menuEl.isActive()));
};

const menuButtonIonicCss = ":host{--background:transparent;--color-focused:currentColor;--border-radius:initial;--padding-top:0;--padding-bottom:0;color:var(--color);text-align:center;text-decoration:none;text-overflow:ellipsis;text-transform:none;white-space:nowrap;-webkit-font-kerning:none;font-kerning:none}.button-native{border-radius:var(--border-radius);color:inherit;font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-align:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;white-space:inherit;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:-ms-flexbox;display:flex;position:relative;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;min-height:inherit;border:0;outline:none;background:var(--background);line-height:1;cursor:pointer;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.button-inner{display:-ms-flexbox;display:flex;position:relative;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;min-height:inherit;z-index:1}ion-icon{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;pointer-events:none}:host(.menu-button-hidden){display:none}:host(.ion-focused) .button-native{color:var(--color-focused)}:host(.ion-focused) .button-native::after{background:var(--background-focused);opacity:var(--background-focused-opacity)}.button-native::after{right:0;left:0;top:0;bottom:0;position:absolute;content:\"\";opacity:0}@media (any-hover: hover){:host(:hover) .button-native{color:var(--color-hover)}:host(:hover) .button-native::after{background:var(--background-hover);opacity:var(--background-hover-opacity, 0)}}:host(.in-toolbar:not(.in-toolbar-color)){color:var(--ion-toolbar-color, var(--color))}:host{--background-focused:currentColor;--background-focused-opacity:0.12;--background-hover:currentColor;--background-hover-opacity:0.04;--border-radius:initial;--color:initial;--padding-start:0;--padding-end:0;position:relative;width:var(--token-scale-1000, 40px);height:var(--token-scale-1000, 40px);font-size:var(--token-font-size-600, 24px)}";

const menuButtonIosCss = ":host{--background:transparent;--color-focused:currentColor;--border-radius:initial;--padding-top:0;--padding-bottom:0;color:var(--color);text-align:center;text-decoration:none;text-overflow:ellipsis;text-transform:none;white-space:nowrap;-webkit-font-kerning:none;font-kerning:none}.button-native{border-radius:var(--border-radius);color:inherit;font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-align:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;white-space:inherit;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:-ms-flexbox;display:flex;position:relative;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;min-height:inherit;border:0;outline:none;background:var(--background);line-height:1;cursor:pointer;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.button-inner{display:-ms-flexbox;display:flex;position:relative;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;min-height:inherit;z-index:1}ion-icon{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;pointer-events:none}:host(.menu-button-hidden){display:none}:host(.ion-focused) .button-native{color:var(--color-focused)}:host(.ion-focused) .button-native::after{background:var(--background-focused);opacity:var(--background-focused-opacity)}.button-native::after{right:0;left:0;top:0;bottom:0;position:absolute;content:\"\";opacity:0}@media (any-hover: hover){:host(:hover) .button-native{color:var(--color-hover)}:host(:hover) .button-native::after{background:var(--background-hover);opacity:var(--background-hover-opacity, 0)}}:host(.in-toolbar:not(.in-toolbar-color)){color:var(--ion-toolbar-color, var(--color))}:host(.menu-button-disabled){cursor:default;opacity:0.5;pointer-events:none}:host(.ion-color) .button-native{color:var(--ion-color-base)}:host{--background-focused:currentColor;--background-focused-opacity:0.1;--border-radius:4px;--color:var(--ion-color-primary, #0054e9);--padding-start:5px;--padding-end:5px;min-height:32px;font-size:clamp(31px, 1.9375rem, 38.13px)}:host(.ion-activated){opacity:0.4}@media (any-hover: hover){:host(:hover){opacity:0.6}}";

const menuButtonMdCss = ":host{--background:transparent;--color-focused:currentColor;--border-radius:initial;--padding-top:0;--padding-bottom:0;color:var(--color);text-align:center;text-decoration:none;text-overflow:ellipsis;text-transform:none;white-space:nowrap;-webkit-font-kerning:none;font-kerning:none}.button-native{border-radius:var(--border-radius);color:inherit;font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-align:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;white-space:inherit;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:-ms-flexbox;display:flex;position:relative;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;min-height:inherit;border:0;outline:none;background:var(--background);line-height:1;cursor:pointer;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.button-inner{display:-ms-flexbox;display:flex;position:relative;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;min-height:inherit;z-index:1}ion-icon{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;pointer-events:none}:host(.menu-button-hidden){display:none}:host(.ion-focused) .button-native{color:var(--color-focused)}:host(.ion-focused) .button-native::after{background:var(--background-focused);opacity:var(--background-focused-opacity)}.button-native::after{right:0;left:0;top:0;bottom:0;position:absolute;content:\"\";opacity:0}@media (any-hover: hover){:host(:hover) .button-native{color:var(--color-hover)}:host(:hover) .button-native::after{background:var(--background-hover);opacity:var(--background-hover-opacity, 0)}}:host(.in-toolbar:not(.in-toolbar-color)){color:var(--ion-toolbar-color, var(--color))}:host(.menu-button-disabled){cursor:default;opacity:0.5;pointer-events:none}:host(.ion-color) .button-native{color:var(--ion-color-base)}:host{--background-focused:currentColor;--background-focused-opacity:0.12;--background-hover:currentColor;--background-hover-opacity:0.04;--border-radius:50%;--color:initial;--padding-start:8px;--padding-end:8px;width:3rem;height:3rem;font-size:1.5rem}:host(.ion-color.ion-focused)::after{background:var(--ion-color-base)}@media (any-hover: hover){:host(.ion-color:hover) .button-native::after{background:var(--ion-color-base)}}";

const MenuButton = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
        this.inheritedAttributes = {};
        this.visible = false;
        /**
         * If `true`, the user cannot interact with the menu button.
         */
        this.disabled = false;
        /**
         * Automatically hides the menu button when the corresponding menu is not active
         */
        this.autoHide = true;
        /**
         * The type of the button.
         */
        this.type = 'button';
        this.onClick = async () => {
            return menuController.toggle(this.menu);
        };
    }
    componentWillLoad() {
        this.inheritedAttributes = inheritAriaAttributes(this.el);
    }
    componentDidLoad() {
        this.visibilityChanged();
    }
    async visibilityChanged() {
        this.visible = await updateVisibility(this.menu);
    }
    get menuIcon() {
        // Determine the theme and map to default icons
        const theme = getIonTheme(this);
        const defaultIcons = {
            ios: menuOutline,
            ionic: listSvg,
            md: menuSharp,
        };
        // Get the default icon based on the theme, falling back to 'md' icon if necessary
        const defaultIcon = defaultIcons[theme] || defaultIcons.md;
        // Return the configured menu icon or the default icon
        return config.get('menuIcon', defaultIcon);
    }
    render() {
        const { color, disabled, inheritedAttributes, menuIcon } = this;
        const theme = getIonTheme(this);
        const hidden = this.autoHide && !this.visible;
        const attrs = {
            type: this.type,
        };
        const ariaLabel = inheritedAttributes['aria-label'] || 'menu';
        return (h(Host, { key: '03935c67ec2448862cb0f2b4e643946438e1e566', onClick: this.onClick, "aria-disabled": disabled ? 'true' : null, "aria-hidden": hidden ? 'true' : null, class: createColorClasses(color, {
                [theme]: true,
                button: true, // ion-buttons target .button
                'menu-button-hidden': hidden,
                'menu-button-disabled': disabled,
                'in-toolbar': hostContext('ion-toolbar', this.el),
                'in-toolbar-color': hostContext('ion-toolbar[color]', this.el),
                'ion-activatable': true,
                'ion-focusable': true,
            }) }, h("button", Object.assign({ key: 'e877eed6a614918eaaf7e041ba725331e27797a5' }, attrs, { disabled: disabled, class: "button-native", part: "native", "aria-label": ariaLabel }), h("span", { key: 'dca1c233c1da70ad7cd8f511713a0b18caa1666d', class: "button-inner" }, h("slot", { key: '7b663519d50fa74c5a287d4e0fc896406f48e759' }, h("ion-icon", { key: '42d30513e68b6c3830ec8a42e7d08abd55aad33b', part: "icon", icon: menuIcon, lazy: false, "aria-hidden": "true" }))), theme === 'md' && h("ion-ripple-effect", { key: '6b8c422244d078255fed90abe147a1701cbd6b92', type: "unbounded" }))));
    }
    get el() { return getElement(this); }
};
MenuButton.style = {
    ionic: menuButtonIonicCss,
    ios: menuButtonIosCss,
    md: menuButtonMdCss
};

const menuToggleCss = ":host(.menu-toggle-hidden){display:none}";

const MenuToggle = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
        this.visible = false;
        /**
         * Automatically hides the content when the corresponding menu is not active.
         *
         * By default, it's `true`. Change it to `false` in order to
         * keep `ion-menu-toggle` always visible regardless the state of the menu.
         */
        this.autoHide = true;
        this.onClick = () => {
            return menuController.toggle(this.menu);
        };
    }
    connectedCallback() {
        this.visibilityChanged();
    }
    async visibilityChanged() {
        this.visible = await updateVisibility(this.menu);
    }
    render() {
        const theme = getIonTheme(this);
        const hidden = this.autoHide && !this.visible;
        return (h(Host, { key: '971acbed9c17a29b559281e20f8b3d53aa5a1fde', onClick: this.onClick, "aria-hidden": hidden ? 'true' : null, class: {
                [theme]: true,
                'menu-toggle-hidden': hidden,
            } }, h("slot", { key: 'c6ba836a3380866148420953f5ef4a86ad9b6b85' })));
    }
};
MenuToggle.style = menuToggleCss;

export { Menu as ion_menu, MenuButton as ion_menu_button, MenuToggle as ion_menu_toggle };
