summaryrefslogtreecommitdiffstats
path: root/js/src/toast.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/toast.js')
-rw-r--r--js/src/toast.js225
1 files changed, 225 insertions, 0 deletions
diff --git a/js/src/toast.js b/js/src/toast.js
new file mode 100644
index 0000000..a7fe775
--- /dev/null
+++ b/js/src/toast.js
@@ -0,0 +1,225 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.2.3): toast.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+import { defineJQueryPlugin, reflow } from './util/index'
+import EventHandler from './dom/event-handler'
+import BaseComponent from './base-component'
+import { enableDismissTrigger } from './util/component-functions'
+
+/**
+ * Constants
+ */
+
+const NAME = 'toast'
+const DATA_KEY = 'bs.toast'
+const EVENT_KEY = `.${DATA_KEY}`
+
+const EVENT_MOUSEOVER = `mouseover${EVENT_KEY}`
+const EVENT_MOUSEOUT = `mouseout${EVENT_KEY}`
+const EVENT_FOCUSIN = `focusin${EVENT_KEY}`
+const EVENT_FOCUSOUT = `focusout${EVENT_KEY}`
+const EVENT_HIDE = `hide${EVENT_KEY}`
+const EVENT_HIDDEN = `hidden${EVENT_KEY}`
+const EVENT_SHOW = `show${EVENT_KEY}`
+const EVENT_SHOWN = `shown${EVENT_KEY}`
+
+const CLASS_NAME_FADE = 'fade'
+const CLASS_NAME_HIDE = 'hide' // @deprecated - kept here only for backwards compatibility
+const CLASS_NAME_SHOW = 'show'
+const CLASS_NAME_SHOWING = 'showing'
+
+const DefaultType = {
+ animation: 'boolean',
+ autohide: 'boolean',
+ delay: 'number'
+}
+
+const Default = {
+ animation: true,
+ autohide: true,
+ delay: 5000
+}
+
+/**
+ * Class definition
+ */
+
+class Toast extends BaseComponent {
+ constructor(element, config) {
+ super(element, config)
+
+ this._timeout = null
+ this._hasMouseInteraction = false
+ this._hasKeyboardInteraction = false
+ this._setListeners()
+ }
+
+ // Getters
+ static get Default() {
+ return Default
+ }
+
+ static get DefaultType() {
+ return DefaultType
+ }
+
+ static get NAME() {
+ return NAME
+ }
+
+ // Public
+ show() {
+ const showEvent = EventHandler.trigger(this._element, EVENT_SHOW)
+
+ if (showEvent.defaultPrevented) {
+ return
+ }
+
+ this._clearTimeout()
+
+ if (this._config.animation) {
+ this._element.classList.add(CLASS_NAME_FADE)
+ }
+
+ const complete = () => {
+ this._element.classList.remove(CLASS_NAME_SHOWING)
+ EventHandler.trigger(this._element, EVENT_SHOWN)
+
+ this._maybeScheduleHide()
+ }
+
+ this._element.classList.remove(CLASS_NAME_HIDE) // @deprecated
+ reflow(this._element)
+ this._element.classList.add(CLASS_NAME_SHOW, CLASS_NAME_SHOWING)
+
+ this._queueCallback(complete, this._element, this._config.animation)
+ }
+
+ hide() {
+ if (!this.isShown()) {
+ return
+ }
+
+ const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE)
+
+ if (hideEvent.defaultPrevented) {
+ return
+ }
+
+ const complete = () => {
+ this._element.classList.add(CLASS_NAME_HIDE) // @deprecated
+ this._element.classList.remove(CLASS_NAME_SHOWING, CLASS_NAME_SHOW)
+ EventHandler.trigger(this._element, EVENT_HIDDEN)
+ }
+
+ this._element.classList.add(CLASS_NAME_SHOWING)
+ this._queueCallback(complete, this._element, this._config.animation)
+ }
+
+ dispose() {
+ this._clearTimeout()
+
+ if (this.isShown()) {
+ this._element.classList.remove(CLASS_NAME_SHOW)
+ }
+
+ super.dispose()
+ }
+
+ isShown() {
+ return this._element.classList.contains(CLASS_NAME_SHOW)
+ }
+
+ // Private
+
+ _maybeScheduleHide() {
+ if (!this._config.autohide) {
+ return
+ }
+
+ if (this._hasMouseInteraction || this._hasKeyboardInteraction) {
+ return
+ }
+
+ this._timeout = setTimeout(() => {
+ this.hide()
+ }, this._config.delay)
+ }
+
+ _onInteraction(event, isInteracting) {
+ switch (event.type) {
+ case 'mouseover':
+ case 'mouseout': {
+ this._hasMouseInteraction = isInteracting
+ break
+ }
+
+ case 'focusin':
+ case 'focusout': {
+ this._hasKeyboardInteraction = isInteracting
+ break
+ }
+
+ default: {
+ break
+ }
+ }
+
+ if (isInteracting) {
+ this._clearTimeout()
+ return
+ }
+
+ const nextElement = event.relatedTarget
+ if (this._element === nextElement || this._element.contains(nextElement)) {
+ return
+ }
+
+ this._maybeScheduleHide()
+ }
+
+ _setListeners() {
+ EventHandler.on(this._element, EVENT_MOUSEOVER, event => this._onInteraction(event, true))
+ EventHandler.on(this._element, EVENT_MOUSEOUT, event => this._onInteraction(event, false))
+ EventHandler.on(this._element, EVENT_FOCUSIN, event => this._onInteraction(event, true))
+ EventHandler.on(this._element, EVENT_FOCUSOUT, event => this._onInteraction(event, false))
+ }
+
+ _clearTimeout() {
+ clearTimeout(this._timeout)
+ this._timeout = null
+ }
+
+ // Static
+ static jQueryInterface(config) {
+ return this.each(function () {
+ const data = Toast.getOrCreateInstance(this, config)
+
+ if (typeof config === 'string') {
+ if (typeof data[config] === 'undefined') {
+ throw new TypeError(`No method named "${config}"`)
+ }
+
+ data[config](this)
+ }
+ })
+ }
+}
+
+/**
+ * Data API implementation
+ */
+
+enableDismissTrigger(Toast)
+
+/**
+ * jQuery
+ */
+
+defineJQueryPlugin(Toast)
+
+export default Toast