// src/ui.js
(function(global) {
const { Component, Util, $ } = global;
const UI = {};
Component.register('Modal', container => {
container.modal = new bootstrap.Modal(container)
container.addEventListener('bind', e => {
e.detail ? container.modal.show() : container.modal.hide()
})
container.addEventListener('hide.bs.modal', () => {
document.activeElement?.blur()
container.dispatchEvent(new CustomEvent('change', { bubbles: false, detail: false }))
})
Util.copyFunction(container, container.modal, 'show', 'hide')
}, Util.makeDom(/*html*/`
`))
Component.register('Dialog', Component.getSetupFunction('Modal'), Util.makeDom(/*html*/`
`))
let _dialogCount = 0
UI.showDialog = function ({ title = '', message = '', buttons = ['{#Close#}'], type = 'body' }) {
const d = document.body.appendChild(document.createElement('Dialog'))
d.style.zIndex = 2000 + ++_dialogCount
Promise.resolve().then(() => {
Object.assign(d.state, { message, title, type, buttons })
d.show()
})
return new Promise((resolve) => {
d.addEventListener('change', e => {
_dialogCount--
resolve(d.result || 0)
d.remove()
})
})
}
UI.alert = function (message, options = {}) {
return UI.showDialog({ message, ...options })
}
UI.confirm = function (message, options = {}) {
return new Promise((resolve) => UI.showDialog({ message, buttons: ['{#Cancel#}', '{#Confirm#}'], ...options }).then(index => resolve(index >= 2)).catch(() => resolve(false)))
}
Component.register('Toast', container => {
container.toast = new bootstrap.Toast(container, { autohide: container.state.delay > 0 })
Util.copyFunction(container, container.toast, 'show', 'hide')
container.addEventListener('show.bs.toast', () => {
if (container.state.delay > 0) {
let timer
const startTimer = () => {
container.state.left = container.state.delay / 1000
timer = setInterval(() => {
if (!container.isConnected || --container.state.left <= 0) clearInterval(timer)
}, 1000)
}
startTimer()
container.addEventListener('mouseenter', () => { clearInterval(timer); container.state.left = undefined })
container.addEventListener('mouseleave', startTimer)
}
})
}, Util.makeDom(/*html*/`
`), Util.makeDom(/*html*/``))
UI.toast = function (message, options = {}) {
const delay = options.delay ?? 5000
const t = document.createElement('Toast')
t.state = { delay, left: delay ? delay / 1000 : undefined, type: options.type || 'primary', message, buttons: options.buttons || [] }
$(`[toast-container="${options.container || 'default'}"]`).appendChild(t)
Promise.resolve().then(() => t.show())
}
UI.toastConfirm = function (message, options = {}) {
return new Promise((resolve) => UI.toast(message, { buttons: ['{#Confirm#}'], ...options }).then(index => resolve(index === 1)).catch(() => resolve(false)))
}
global.UI = UI;
})(globalThis);