/*!
 * (C) Gasco https://gasco-web-component.herokuapp.com/ - MIT License
 */
import { r as registerInstance, c as createEvent, e as writeTask, h, H as Host, a as getElement } from './index-211ca8fb.js';
import { c as config } from './config-47f2ca98.js';
import { f as findGascoContent, p as printGascoContentErrorMsg } from './index-5274ca93.js';
import { C as CoreDelegate, a as attachComponent, d as deepReady, b as detachComponent } from './index-dc2d220f.js';
import { r as raf } from './helpers-4b2cb009.js';
import { K as KEYBOARD_DID_OPEN, m as mdLeaveAnimation, c as createSwipeToCloseGesture, a as mdEnterAnimation, b as createSheetGesture } from './swipe-to-close-e313c3cd.js';
import { p as printGascoWarning } from './index-8cafebf1.js';
import { B as BACKDROP, a as prepareOverlay, b as present, f as activeAnimations, d as dismiss, e as eventMethod } from './overlays-e2fa6ae2.js';
import { g as getClassMap } from './theme-c4ea3043.js';
import './index-b54e5fe6.js';
import './gesture-controller-77b7bda7.js';
import './cubic-bezier-9ae16910.js';

const gascoModalMdCss = ":host{--width:100%;--max-width:644px;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--gasco-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:flex;position:fixed;align-items:center;justify-content:center;outline:none;contain:strict}.modal-wrapper,gasco-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);max-width:var(--max-width);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;margin-left:auto;margin-right:auto;position:absolute;width:36px;height:5px;transform:translateZ(0);background:var(--gasco-color-step-350, #c0c0be);z-index:11}@supports (margin-inline-start: 0) or (-webkit-margin-start: 0){.modal-handle{margin-left:unset;margin-right:unset;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto}}:host(.modal-sheet){--height:calc(100% - (var(--gasco-safe-area-top) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}.modal-native{text-align:center;display:flex;flex-direction:column;flex:1 1;padding:1rem}.modal-native .modal-button-close{align-self:flex-end;border-radius:50%;padding:0;width:30px;height:30px;border:none;cursor:pointer}.modal-native h2{font-weight:600;font-size:28px;line-height:36px;color:#072531;margin:14px 0}.modal-native h2.default{align-self:flex-start;margin:0 0 12px 0}.modal-native p{font-weight:600;font-size:16px;line-height:20px;color:#4D4D4D;margin:0}.modal-native p.default{align-self:flex-start;text-align:left}.modal-native hr{width:85%;margin:28px 0;align-self:center;background:#CCCCCC}.modal-native .modal-button-group{display:flex;justify-content:center;gap:1rem}@media only screen and (max-width: 768px){::slotted([slot=start]){width:50px;height:50px}.modal-native h2{font-size:20px;line-height:28px}.modal-native h2.default{align-self:flex-start;margin:0 0 12px 0}.modal-native p{font-weight:400;font-size:16px;line-height:24px}.modal-native p.default{align-self:flex-start;text-align:left}.modal-native hr{width:85%}}@media only screen and (max-width: 480px){::slotted([slot=start]){width:40px;height:40px}.modal-native h2{font-size:16px;line-height:20px}.modal-native h2.default{align-self:flex-start;margin:0 0 12px 0}.modal-native p{font-size:14px;line-height:20px}.modal-native p.default{align-self:flex-start;text-align:left}.modal-native hr{width:85%}.modal-native .modal-button-group{flex-wrap:wrap;gap:10px;padding:0 1rem}}:host{--border-radius:8px;--box-shadow:0px 6px 12px rgba(171, 190, 209, 0.3);--backdrop-opacity:var(--gasco-backdrop-opacity, 0.32)}.modal-wrapper{transform:translate3d(0,  40px,  0);opacity:0.01;margin:0 1rem}";

const GascoModal = class {
  constructor(hostRef) {
    registerInstance(this, hostRef);
    this.didPresent = createEvent(this, "gascoModalDidPresent", 7);
    this.willPresent = createEvent(this, "gascoModalWillPresent", 7);
    this.willDismiss = createEvent(this, "gascoModalWillDismiss", 7);
    this.didDismiss = createEvent(this, "gascoModalDidDismiss", 7);
    this.accepted = createEvent(this, "gascoModalAccepted", 7);
    this.gascoBreakpointDidChange = createEvent(this, "gascoBreakpointDidChange", 7);
    this.didPresentShorthand = createEvent(this, "didPresent", 7);
    this.willPresentShorthand = createEvent(this, "willPresent", 7);
    this.willDismissShorthand = createEvent(this, "willDismiss", 7);
    this.didDismissShorthand = createEvent(this, "didDismiss", 7);
    this.acceptedShorthand = createEvent(this, "accepted", 7);
    this.modalIndex = modalIds++;
    this.coreDelegate = CoreDelegate();
    this.isSheetModal = false;
    this.inline = false;
    // Whether or not modal is being dismissed via gesture
    this.gestureAnimationDismissing = false;
    this.presented = false;
    /** @internal */
    this.hasController = false;
    /**
     * If `true`, the keyboard will be automatically dismissed when the overlay is presented.
     */
    this.keyboardClose = true;
    /**
     * A decimal value between 0 and 1 that indicates the
     * point after which the backdrop will begin to fade in
     * when using a sheet modal. Prior to this point, the
     * backdrop will be hidden and the content underneath
     * the sheet can be interacted with. This value is exclusive
     * meaning the backdrop will become active after the value
     * specified.
     */
    this.backdropBreakpoint = 0;
    /**
     * If `true`, the modal will be dismissed when the backdrop is clicked.
     */
    this.backdropDismiss = true;
    /**
     * If `true`, a backdrop will be displayed behind the modal.
     * This property controls whether or not the backdrop
     * darkens the screen when the modal is presented.
     * It does not control whether or not the backdrop
     * is active or present in the DOM.
     */
    this.showBackdrop = true;
    /**
     * If `true`, the modal will animate.
     */
    this.animated = true;
    /**
     * If `"default"`, the modal will default.
     * For default `"default"`.
     */
    this.type = 'default';
    /**
     * If `true`, the modal can be swiped to dismiss. Only applies in iOS mode.
     * @deprecated - To prevent modals from dismissing, use canDismiss instead.
     */
    this.swipeToClose = false;
    /**
     * If `true`, the modal will open. If `false`, the modal will close.
     * Use this if you need finer grained control over presentation, otherwise
     * just use the modalController or the `trigger` property.
     * Note: `isOpen` will not automatically be set back to `false` when
     * the modal dismisses. You will need to do that in your code.
     */
    this.isOpen = false;
    this.configureTriggerInteraction = () => {
      const { trigger, el, destroyTriggerInteraction } = this;
      if (destroyTriggerInteraction) {
        destroyTriggerInteraction();
      }
      const triggerEl = trigger !== undefined ? document.getElementById(trigger) : null;
      if (!triggerEl) {
        return;
      }
      const configureTriggerInteraction = (trigEl, modalEl) => {
        const openModal = () => {
          modalEl.present();
        };
        trigEl.addEventListener('click', openModal);
        return () => {
          trigEl.removeEventListener('click', openModal);
        };
      };
      this.destroyTriggerInteraction = configureTriggerInteraction(triggerEl, el);
    };
    /**
     * Dismiss the modal overlay after it has been presented.
     *
     * @param role The role of the element that is dismissing the modal. For example, 'cancel' or 'backdrop'.
     */
    this.handleDismiss = async (role) => {
      return await this.dismiss(role);
    };
    this.onBackdropTap = () => {
      this.dismiss(undefined, BACKDROP);
    };
    this.onLifecycle = (modalEvent) => {
      const el = this.usersElement;
      const name = LIFECYCLE_MAP[modalEvent.type];
      if (el && name) {
        const ev = new CustomEvent(name, {
          bubbles: false,
          cancelable: false,
          detail: modalEvent.detail,
        });
        el.dispatchEvent(ev);
      }
    };
  }
  onIsOpenChange(newValue, oldValue) {
    if (newValue === true && oldValue === false) {
      this.present();
    }
    else if (newValue === false && oldValue === true) {
      this.dismiss();
    }
  }
  onTriggerChange() {
    this.configureTriggerInteraction();
  }
  async swipeToCloseChanged(enable) {
    if (this.gesture) {
      this.gesture.enable(enable);
    }
    else if (enable) {
      await this.initSwipeToClose();
    }
  }
  breakpointsChanged(breakpoints) {
    if (breakpoints !== undefined) {
      this.sortedBreakpoints = breakpoints.sort((a, b) => a - b);
    }
  }
  connectedCallback() {
    prepareOverlay(this.el);
  }
  componentWillLoad() {
    const { breakpoints, initialBreakpoint, swipeToClose } = this;
    /**
     * If user has custom ID set then we should
     * not assign the default incrementing ID.
     */
    this.modalId = this.el.hasAttribute('id') ? this.el.getAttribute('id') : `gasco-modal-${this.modalIndex}`;
    const isSheetModal = (this.isSheetModal = breakpoints !== undefined && initialBreakpoint !== undefined);
    if (isSheetModal) {
      this.currentBreakpoint = this.initialBreakpoint;
    }
    if (breakpoints !== undefined && initialBreakpoint !== undefined && !breakpoints.includes(initialBreakpoint)) {
      printGascoWarning('Your breakpoints array must include the initialBreakpoint value.');
    }
    if (swipeToClose) {
      printGascoWarning('swipeToClose has been deprecated in favor of canDismiss.\n\nIf you want a card modal to be swipeable, set canDismiss to `true`. In the next major release of Gasco, swipeToClose will be removed, and all card modals will be swipeable by default.');
    }
  }
  componentDidLoad() {
    /**
     * If modal was rendered with isOpen="true"
     * then we should open modal immediately.
     */
    if (this.isOpen === true) {
      raf(() => this.present());
    }
    this.breakpointsChanged(this.breakpoints);
    this.configureTriggerInteraction();
  }
  /**
   * Determines whether or not an overlay
   * is being used inline or via a controller/JS
   * and returns the correct delegate.
   * By default, subsequent calls to getDelegate
   * will use a cached version of the delegate.
   * This is useful for calling dismiss after
   * present so that the correct delegate is given.
   */
  getDelegate(force = false) {
    if (this.workingDelegate && !force) {
      return {
        delegate: this.workingDelegate,
        inline: this.inline,
      };
    }
    /**
     * If using overlay inline
     * we potentially need to use the coreDelegate
     * so that this works in vanilla JS apps.
     * If a developer has presented this component
     * via a controller, then we can assume
     * the component is already in the
     * correct place.
     */
    const parentEl = this.el.parentNode;
    const inline = (this.inline = parentEl !== null && !this.hasController);
    const delegate = (this.workingDelegate = inline ? this.delegate || this.coreDelegate : this.delegate);
    return { inline, delegate };
  }
  /**
   * Determines whether or not the
   * modal is allowed to dismiss based
   * on the state of the canDismiss prop.
   */
  async checkCanDismiss() {
    const { canDismiss } = this;
    /**
     * TODO (FW-937) - Remove the following check in
     * the next major release of Ionic.
     */
    if (canDismiss === undefined) {
      return true;
    }
    if (typeof canDismiss === 'function') {
      return canDismiss();
    }
    return canDismiss;
  }
  /**
   * Present the modal overlay after it has been created.
   */
  async present() {
    if (this.presented) {
      return;
    }
    /**
     * When using an inline modal
     * and dismissing a modal it is possible to
     * quickly present the modal while it is
     * dismissing. We need to await any current
     * transition to allow the dismiss to finish
     * before presenting again.
     */
    if (this.currentTransition !== undefined) {
      await this.currentTransition;
    }
    /**
     * If the modal is presented multiple times (inline modals), we
     * need to reset the current breakpoint to the initial breakpoint.
     */
    this.currentBreakpoint = this.initialBreakpoint;
    const data = Object.assign(Object.assign({}, this.componentProps), { modal: this.el });
    const { inline, delegate } = this.getDelegate(true);
    this.usersElement = await attachComponent(delegate, this.el, this.component, data, inline);
    await deepReady(this.usersElement);
    writeTask(() => this.el.classList.add('show-modal'));
    this.currentTransition = present(this, 'modalEnter', mdEnterAnimation, {
      presentingEl: this.presentingElement,
      currentBreakpoint: this.initialBreakpoint,
      backdropBreakpoint: this.backdropBreakpoint,
    });
    /**
     * TODO (FW-937) - In the next major release of Gasco, all card modals
     * will be swipeable by default. canDismiss will be used to determine if the
     * modal can be dismissed. This check should change to check the presence of
     * presentingElement instead.
     *
     * If we did not do this check, then not using swipeToClose would mean you could
     * not run canDismiss on swipe as there would be no swipe gesture created.
     */
    const hasCardModal = this.swipeToClose || (this.canDismiss !== undefined && this.presentingElement !== undefined);
    await this.currentTransition;
    if (this.isSheetModal) {
      this.initSheetGesture();
    }
    else if (hasCardModal) {
      await this.initSwipeToClose();
    }
    /* tslint:disable-next-line */
    if (typeof window !== 'undefined') {
      this.keyboardOpenCallback = () => {
        if (this.gesture) {
          /**
           * When the native keyboard is opened and the webview
           * is resized, the gesture implementation will become unresponsive
           * and enter a free-scroll mode.
           *
           * When the keyboard is opened, we disable the gesture for
           * a single frame and re-enable once the contents have repositioned
           * from the keyboard placement.
           */
          this.gesture.enable(false);
          raf(() => {
            if (this.gesture) {
              this.gesture.enable(true);
            }
          });
        }
      };
      window.addEventListener(KEYBOARD_DID_OPEN, this.keyboardOpenCallback);
    }
    this.currentTransition = undefined;
  }
  initSwipeToClose() {
    const { el } = this;
    // All of the elements needed for the swipe gesture
    // should be in the DOM and referenced by now, except
    // for the presenting el
    const animationBuilder = this.leaveAnimation || config.get('modalLeave', mdLeaveAnimation);
    const ani = (this.animation = animationBuilder(el, { presentingEl: this.presentingElement }));
    const contentEl = findGascoContent(el);
    if (!contentEl) {
      printGascoContentErrorMsg(el);
      return;
    }
    this.gesture = createSwipeToCloseGesture(el, ani, () => {
      /**
       * While the gesture animation is finishing
       * it is possible for a user to tap the backdrop.
       * This would result in the dismiss animation
       * being played again. Typically this is avoided
       * by setting `presented = false` on the overlay
       * component; however, we cannot do that here as
       * that would prevent the element from being
       * removed from the DOM.
       */
      this.gestureAnimationDismissing = true;
      this.animation.onFinish(async () => {
        await this.dismiss(undefined, 'gesture');
        this.gestureAnimationDismissing = false;
      });
    });
    this.gesture.enable(true);
  }
  initSheetGesture() {
    const { wrapperEl, initialBreakpoint, backdropBreakpoint } = this;
    if (!wrapperEl || initialBreakpoint === undefined) {
      return;
    }
    const animationBuilder = this.enterAnimation || config.get('modalEnter', mdEnterAnimation);
    const ani = (this.animation = animationBuilder(this.el, {
      presentingEl: this.presentingElement,
      currentBreakpoint: initialBreakpoint,
      backdropBreakpoint,
    }));
    ani.progressStart(true, 1);
    const { gesture, moveSheetToBreakpoint } = createSheetGesture(this.el, this.backdropEl, wrapperEl, initialBreakpoint, backdropBreakpoint, ani, this.sortedBreakpoints, () => { var _a; return (_a = this.currentBreakpoint) !== null && _a !== void 0 ? _a : 0; }, () => this.sheetOnDismiss(), (breakpoint) => {
      if (this.currentBreakpoint !== breakpoint) {
        this.currentBreakpoint = breakpoint;
        this.gascoBreakpointDidChange.emit({ breakpoint });
      }
    });
    this.gesture = gesture;
    this.moveSheetToBreakpoint = moveSheetToBreakpoint;
    this.gesture.enable(true);
  }
  sheetOnDismiss() {
    /**
     * While the gesture animation is finishing
     * it is possible for a user to tap the backdrop.
     * This would result in the dismiss animation
     * being played again. Typically this is avoided
     * by setting `presented = false` on the overlay
     * component; however, we cannot do that here as
     * that would prevent the element from being
     * removed from the DOM.
     */
    this.gestureAnimationDismissing = true;
    this.animation.onFinish(async () => {
      this.currentBreakpoint = 0;
      this.gascoBreakpointDidChange.emit({ breakpoint: this.currentBreakpoint });
      await this.dismiss(undefined, 'gesture');
      this.gestureAnimationDismissing = false;
    });
  }
  /**
   * Dismiss the modal overlay after it has been presented.
   *
   * @param data Any data to emit in the dismiss events.
   * @param role The role of the element that is dismissing the modal. For example, 'cancel' or 'backdrop'.
   */
  async dismiss(data, role) {
    if (this.gestureAnimationDismissing && role !== 'gesture') {
      return false;
    }
    /**
     * If a canDismiss handler is responsible
     * for calling the dismiss method, we should
     * not run the canDismiss check again.
     */
    if (role !== 'handler' && !(await this.checkCanDismiss())) {
      return false;
    }
    /* tslint:disable-next-line */
    if (typeof window !== 'undefined' && this.keyboardOpenCallback) {
      window.removeEventListener(KEYBOARD_DID_OPEN, this.keyboardOpenCallback);
    }
    /**
     * When using an inline modal
     * and presenting a modal it is possible to
     * quickly dismiss the modal while it is
     * presenting. We need to await any current
     * transition to allow the present to finish
     * before dismissing again.
     */
    if (this.currentTransition !== undefined) {
      await this.currentTransition;
    }
    const enteringAnimation = activeAnimations.get(this) || [];
    this.currentTransition = dismiss(this, data, role, 'modalLeave', mdLeaveAnimation, {
      presentingEl: this.presentingElement,
      currentBreakpoint: this.currentBreakpoint || this.initialBreakpoint,
      backdropBreakpoint: this.backdropBreakpoint,
    });
    const dismissed = await this.currentTransition;
    if (dismissed) {
      const { delegate } = this.getDelegate();
      await detachComponent(delegate, this.usersElement);
      writeTask(() => this.el.classList.remove('show-modal'));
      if (this.animation) {
        this.animation.destroy();
      }
      if (this.gesture) {
        this.gesture.destroy();
      }
      enteringAnimation.forEach((ani) => ani.destroy());
    }
    this.currentBreakpoint = undefined;
    this.currentTransition = undefined;
    this.animation = undefined;
    return dismissed;
  }
  /**
   * Returns a promise that resolves when the modal did dismiss.
   */
  onDidDismiss() {
    return eventMethod(this.el, 'gascoModalDidDismiss');
  }
  /**
   * Returns a promise that resolves when the modal will dismiss.
   */
  onWillDismiss() {
    return eventMethod(this.el, 'gascoModalWillDismiss');
  }
  /**
   * Move a sheet style modal to a specific breakpoint. The breakpoint value must
   * be a value defined in your `breakpoints` array.
   */
  async setCurrentBreakpoint(breakpoint) {
    if (!this.isSheetModal) {
      printGascoWarning('setCurrentBreakpoint is only supported on sheet modals.');
      return;
    }
    if (!this.breakpoints.includes(breakpoint)) {
      printGascoWarning(`Attempted to set invalid breakpoint value ${breakpoint}. Please double check that the breakpoint value is part of your defined breakpoints.`);
      return;
    }
    const { currentBreakpoint, moveSheetToBreakpoint, canDismiss, breakpoints } = this;
    if (currentBreakpoint === breakpoint) {
      return;
    }
    if (moveSheetToBreakpoint) {
      moveSheetToBreakpoint({
        breakpoint,
        breakpointOffset: 1 - currentBreakpoint,
        canDismiss: canDismiss !== undefined && canDismiss !== true && breakpoints[0] === 0,
      });
    }
  }
  /**
   * Returns the current breakpoint of a sheet style modal
   */
  async getCurrentBreakpoint() {
    return this.currentBreakpoint;
  }
  render() {
    const { handle, isSheetModal, htmlAttributes } = this;
    const finalSize = this.size === undefined && false ? 'small' : this.size;
    const showHandle = handle !== false && isSheetModal;
    const { modalId, accepted } = this;
    return (h(Host, Object.assign({ "no-router": true, "aria-modal": "true", tabindex: "-1" }, htmlAttributes, { style: {
        zIndex: `${20000 + this.overlayIndex}`,
      }, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { 'modal-card': true, 'overlay-hidden': true, 'modal-sheet': isSheetModal, 'modal-default': !isSheetModal, [`modal-${finalSize}`]: finalSize !== undefined }), id: modalId, onGascoBackdropTap: this.onBackdropTap, onGascoModalDidPresent: this.onLifecycle, onGascoModalWillPresent: this.onLifecycle, onGascoModalWillDismiss: this.onLifecycle, onGascoModalDidDismiss: this.onLifecycle, onGascoModalAccepted: this.onLifecycle }), h("gasco-backdrop", { ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), h("div", { role: "dialog", class: "modal-wrapper gasco-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }, showHandle && h("div", { class: "modal-handle", part: "handle" }), h("div", { class: "modal-native" }, h("button", { type: "button", part: "button", tabIndex: 0, onClick: this.handleDismiss.bind('cancel'), class: "modal-button-close focusable activatable" }, h("svg", { width: "24", height: "25", viewBox: "0 0 24 25", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, h("path", { d: "M19 6.86843L17.59 5.45844L12 11.0484L6.41 5.45844L5 6.86843L10.59 12.4584L5 18.0484L6.41 19.4584L12 13.8684L17.59 19.4584L19 18.0484L13.41 12.4584L19 6.86843Z", fill: "#999999" }))), this.type !== 'default' && (h("div", { class: "modal-header" }, h("slot", { name: "start" }))), this.modalTitle && h("h2", { class: this.type === 'default' && 'default' }, this.modalTitle), this.modalBody && h("p", { class: this.type === 'default' && 'default' }, this.modalBody), this.modalTitle && this.modalBody && this.type !== 'default' && h("hr", null), h("div", { class: "modal-button-group" }, this.type === 'basic' && [
      h("gasco-button", { fill: "outline", onClick: this.handleDismiss.bind('cancel') }, "No, cancelar"),
      h("gasco-button", { fill: "solid", color: "primary", onClick: () => accepted.emit(true) }, "Si, aceptar")
    ], this.type === 'simple' && (h("gasco-button", { color: "primary", onClick: this.handleDismiss.bind('cancel') }, "Entendido")))))));
  }
  get el() { return getElement(this); }
  static get watchers() { return {
    "isOpen": ["onIsOpenChange"],
    "trigger": ["onTriggerChange"],
    "swipeToClose": ["swipeToCloseChanged"]
  }; }
};
const LIFECYCLE_MAP = {
  gascoModalDidPresent: 'gascoViewDidEnter',
  gascoModalWillPresent: 'gascoViewWillEnter',
  gascoModalWillDismiss: 'gascoViewWillLeave',
  gascoModalDidDismiss: 'gascoViewDidLeave',
  gascoModalAccepted: 'gascoViewWillUpdate',
};
let modalIds = 0;
GascoModal.style = gascoModalMdCss;

export { GascoModal as gasco_modal };
