// 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);