Files
flights_web_raw/node_modules/bootstrap.native/dist/components/toast/toast.mjs
T

328 lines
9.7 KiB
JavaScript

/*!
* Bootstrap Native Toast v5.1.10 (https://thednp.github.io/bootstrap.native/)
* Copyright 2026 © thednp
* Licensed under MIT (https://github.com/thednp/bootstrap.native/blob/master/LICENSE)
*/
"use strict";
import { Data, ObjectKeys, Timer, addClass, closest, createCustomEvent, dispatchEvent, emulateTransitionEnd, focusinEvent, focusoutEvent, getAttribute, getDocument, getInstance, hasClass, isElement, isString, mouseclickEvent, mouseenterEvent, mouseleaveEvent, normalizeOptions, querySelector, querySelectorAll, reflow, removeClass } from "@thednp/shorty";
import { addListener, removeListener } from "@thednp/event-listener";
//#region src/strings/fadeClass.ts
/**
* Global namespace for most components `fade` class.
*/
const fadeClass = "fade";
//#endregion
//#region src/strings/showClass.ts
/**
* Global namespace for most components `show` class.
*/
const showClass = "show";
//#endregion
//#region src/strings/dataBsDismiss.ts
/**
* Global namespace for most components `dismiss` option.
*/
const dataBsDismiss = "data-bs-dismiss";
//#endregion
//#region src/strings/dataBsToggle.ts
/**
* Global namespace for most components `toggle` option.
*/
const dataBsToggle = "data-bs-toggle";
//#endregion
//#region src/strings/toastString.ts
/** @type {string} */
const toastString = "toast";
//#endregion
//#region src/strings/toastComponent.ts
/** @type {string} */
const toastComponent = "Toast";
//#endregion
//#region src/strings/dataBsTarget.ts
/**
* Global namespace for most components `target` option.
*/
const dataBsTarget = "data-bs-target";
//#endregion
//#region src/strings/dataBsParent.ts
/**
* Global namespace for most components `parent` option.
*/
const dataBsParent = "data-bs-parent";
//#endregion
//#region src/strings/dataBsContainer.ts
/**
* Global namespace for most components `container` option.
*/
const dataBsContainer = "data-bs-container";
//#endregion
//#region src/util/getTargetElement.ts
/**
* Returns the `Element` that THIS one targets
* via `data-bs-target`, `href`, `data-bs-parent` or `data-bs-container`.
*
* @param element the target element
* @returns the query result
*/
const getTargetElement = (element) => {
const targetAttr = [
dataBsTarget,
dataBsParent,
dataBsContainer,
"href"
];
const doc = getDocument(element);
return targetAttr.map((att) => {
const attValue = getAttribute(element, att);
if (attValue) return att === "data-bs-parent" ? closest(element, attValue) : querySelector(attValue, doc);
return null;
}).filter((x) => x)[0];
};
//#endregion
//#region src/util/isDisabled.ts
/**
* Check if interactive element is disabled.
* @param target either a `<button>` or an `<a>`
* @returns whether the target is disabled
*/
const isDisabled = (target) => {
return hasClass(target, "disabled") || getAttribute(target, "disabled") === "true";
};
//#endregion
//#region src/version.ts
const Version = "5.1.10";
//#endregion
//#region src/components/base-component.ts
/** Returns a new `BaseComponent` instance. */
var BaseComponent = class {
/**
* @param target `Element` or selector string
* @param config component instance options
*/
constructor(target, config) {
let element;
try {
if (isElement(target)) element = target;
else if (isString(target)) {
element = querySelector(target);
if (!element) throw Error(`"${target}" is not a valid selector.`);
} else throw Error(`your target is not an instance of HTMLElement.`);
} catch (e) {
throw Error(`${this.name} Error: ${e.message}`);
}
const prevInstance = Data.get(element, this.name);
if (prevInstance) prevInstance._toggleEventListeners();
this.element = element;
this.options = this.defaults && ObjectKeys(this.defaults).length ? normalizeOptions(element, this.defaults, config || {}, "bs") : {};
Data.set(element, this.name, this);
}
get version() {
return Version;
}
get name() {
return "BaseComponent";
}
get defaults() {
return {};
}
/** just to have something to extend from */
_toggleEventListeners = () => {};
/** Removes component from target element. */
dispose() {
Data.remove(this.element, this.name);
ObjectKeys(this).forEach((prop) => {
delete this[prop];
});
}
};
//#endregion
//#region src/components/toast.ts
const toastSelector = `.${toastString}`;
const toastDismissSelector = `[${dataBsDismiss}="${toastString}"]`;
const toastToggleSelector = `[${dataBsToggle}="${toastString}"]`;
const showingClass = "showing";
/** @deprecated */
const hideClass = "hide";
const toastDefaults = {
animation: true,
autohide: true,
delay: 5e3
};
/**
* Static method which returns an existing `Toast` instance associated
* to a target `Element`.
*/
const getToastInstance = (element) => getInstance(element, toastComponent);
/**
* A `Toast` initialization callback.
*/
const toastInitCallback = (element) => new Toast(element);
const showToastEvent = createCustomEvent(`show.bs.${toastString}`);
const shownToastEvent = createCustomEvent(`shown.bs.${toastString}`);
const hideToastEvent = createCustomEvent(`hide.bs.${toastString}`);
const hiddenToastEvent = createCustomEvent(`hidden.bs.${toastString}`);
/**
* Executes after the toast is shown to the user.
*
* @param self the `Toast` instance
*/
const showToastComplete = (self) => {
const { element, options } = self;
removeClass(element, showingClass);
Timer.clear(element, showingClass);
dispatchEvent(element, shownToastEvent);
if (options.autohide) Timer.set(element, () => self.hide(), options.delay, toastString);
};
/**
* Executes after the toast is hidden to the user.
*
* @param self the `Toast` instance
*/
const hideToastComplete = (self) => {
const { element } = self;
removeClass(element, showingClass);
removeClass(element, showClass);
addClass(element, hideClass);
Timer.clear(element, toastString);
dispatchEvent(element, hiddenToastEvent);
};
/**
* Executes before hiding the toast.
*
* @param self the `Toast` instance
*/
const hideToast = (self) => {
const { element, options } = self;
addClass(element, showingClass);
if (options.animation) {
reflow(element);
emulateTransitionEnd(element, () => hideToastComplete(self));
} else hideToastComplete(self);
};
/**
* Executes before showing the toast.
*
* @param self the `Toast` instance
*/
const showToast = (self) => {
const { element, options } = self;
Timer.set(element, () => {
removeClass(element, hideClass);
reflow(element);
addClass(element, showClass);
addClass(element, showingClass);
if (options.animation) emulateTransitionEnd(element, () => showToastComplete(self));
else showToastComplete(self);
}, 17, showingClass);
};
/**
* Handles the `click` event listener for toast.
*
* @param e the `Event` object
*/
function toastClickHandler(e) {
const element = getTargetElement(this);
const self = element && getToastInstance(element);
if (isDisabled(this)) return;
if (!self) return;
if (this.tagName === "A") e.preventDefault();
self.relatedTarget = this;
self.show();
}
/**
* Executes when user interacts with the toast without closing it,
* usually by hovering or focusing it.
*
* @param e the `Toast` instance
*/
const interactiveToastHandler = (e) => {
const element = e.target;
const self = getToastInstance(element);
const { type, relatedTarget } = e;
if (!self || element === relatedTarget || element.contains(relatedTarget)) return;
if ([mouseenterEvent, focusinEvent].includes(type)) Timer.clear(element, toastString);
else Timer.set(element, () => self.hide(), self.options.delay, toastString);
};
/** Creates a new `Toast` instance. */
var Toast = class extends BaseComponent {
static selector = toastSelector;
static init = toastInitCallback;
static getInstance = getToastInstance;
/**
* @param target the target `.toast` element
* @param config the instance options
*/
constructor(target, config) {
super(target, config);
const { element, options } = this;
if (options.animation && !hasClass(element, "fade")) addClass(element, fadeClass);
else if (!options.animation && hasClass(element, "fade")) removeClass(element, fadeClass);
this.dismiss = querySelector(toastDismissSelector, element);
this.triggers = [...querySelectorAll(toastToggleSelector, getDocument(element))].filter((btn) => getTargetElement(btn) === element);
this._toggleEventListeners(true);
}
/**
* Returns component name string.
*/
get name() {
return toastComponent;
}
/**
* Returns component default options.
*/
get defaults() {
return toastDefaults;
}
/**
* Returns *true* when toast is visible.
*/
get isShown() {
return hasClass(this.element, showClass);
}
/** Shows the toast. */
show = () => {
const { element, isShown } = this;
if (!element || isShown) return;
dispatchEvent(element, showToastEvent);
if (!showToastEvent.defaultPrevented) showToast(this);
};
/** Hides the toast. */
hide = () => {
const { element, isShown } = this;
if (!element || !isShown) return;
dispatchEvent(element, hideToastEvent);
if (!hideToastEvent.defaultPrevented) hideToast(this);
};
/**
* Toggles on/off the `click` event listener.
*
* @param add when `true`, it will add the listener
*/
_toggleEventListeners = (add) => {
const action = add ? addListener : removeListener;
const { element, triggers, dismiss, options, hide } = this;
if (dismiss) action(dismiss, mouseclickEvent, hide);
if (options.autohide) [
focusinEvent,
focusoutEvent,
mouseenterEvent,
mouseleaveEvent
].forEach((e) => action(element, e, interactiveToastHandler));
if (triggers.length) triggers.forEach((btn) => {
action(btn, mouseclickEvent, toastClickHandler);
});
};
/** Removes the `Toast` component from the target element. */
dispose() {
const { element, isShown } = this;
this._toggleEventListeners();
Timer.clear(element, toastString);
if (isShown) removeClass(element, showClass);
super.dispose();
}
};
//#endregion
export { Toast as default };
//# sourceMappingURL=toast.mjs.map