UNPKG

@underpostnet/underpost

Version:
1,042 lines (1,004 loc) 83.3 kB
import { cap, getId, newInstance } from './CommonJs.js'; import { Draggable } from '@neodrag/vanilla'; import { append, s, prepend, setPath, getProxyPath, htmls, sa, getAllChildNodes, isActiveElement, } from './VanillaJs.js'; import { BtnIcon } from './BtnIcon.js'; import { Responsive } from './Responsive.js'; import { loggerFactory } from './Logger.js'; import { Css, ThemeEvents, Themes, ThemesScope, darkTheme, renderStyleTag, renderStatus, renderCssAttr, } from './Css.js'; import { setDocTitle } from './Router.js'; import { NotificationManager } from './NotificationManager.js'; import { EventsUI } from './EventsUI.js'; import { Translate } from './Translate.js'; import { Input } from './Input.js'; import { Validator } from './Validator.js'; import { DropDown } from './DropDown.js'; import { Keyboard } from './Keyboard.js'; import { Badge } from './Badge.js'; import { Worker } from './Worker.js'; const logger = loggerFactory(import.meta); const Modal = { Data: {}, Render: async function ( options = { id: '', barConfig: {}, title: '', html: '', handleType: 'bar', mode: '' /* slide-menu */, RouterInstance: {}, disableTools: [], observer: false, }, ) { if (options.heightBottomBar === undefined) options.heightBottomBar = 50; if (options.heightTopBar === undefined) options.heightTopBar = 50; let originHeightBottomBar = options.heightBottomBar ? newInstance(options.heightBottomBar) : 0; let originHeightTopBar = options.heightTopBar ? newInstance(options.heightTopBar) : 0; let width = 300; let height = 400; let top = 0; let left = 0; const topBottomBarEnable = options && options.barMode && options.barMode === 'top-bottom-bar'; if (!topBottomBarEnable) { options.heightTopBar = options.heightTopBar + options.heightBottomBar; options.heightBottomBar = 0; } let transition = `opacity 0.3s, box-shadow 0.3s, bottom 0.3s`; const originSlideMenuWidth = 320; const collapseSlideMenuWidth = 50; let slideMenuWidth = originSlideMenuWidth; const minWidth = width; const heightDefaultTopBar = 0; const heightDefaultBottomBar = 0; const idModal = options && 'id' in options ? options.id : getId(this.Data, 'modal-'); this.Data[idModal] = { options, onCloseListener: {}, onMenuListener: {}, onCollapseMenuListener: {}, onExtendMenuListener: {}, onDragEndListener: {}, onObserverListener: {}, onClickListener: {}, onExpandUiListener: {}, onBarUiOpen: {}, onBarUiClose: {}, onHome: {}, query: options.query ? `${window.location.search}` : undefined, }; const setCenterRestore = () => { const ResponsiveData = Responsive.getResponsiveData(); top = `${ResponsiveData.height / 2 - height / 2}px`; left = `${ResponsiveData.width / 2 - width / 2}px`; }; if (idModal !== 'main-body') setCenterRestore(); if (options && 'mode' in options) { this.Data[idModal][options.mode] = {}; switch (options.mode) { case 'view': if (options && options.slideMenu) s(`.btn-close-${options.slideMenu}`).click(); options.zIndexSync = true; options.style = { ...options.style, 'min-width': `${minWidth}px`, }; if (this.mobileModal()) { options.barConfig.buttons.restore.disabled = true; options.barConfig.buttons.minimize.disabled = true; options.dragDisabled = true; options.style.resize = 'none'; } Responsive.Event[`view-${idModal}`] = () => { if (!this.Data[idModal]) return delete Responsive.Event[`view-${idModal}`]; if (this.Data[idModal].slideMenu) s(`.${idModal}`).style.height = `${ window.innerHeight - (options.heightTopBar ? options.heightTopBar : heightDefaultTopBar) - (options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar) }px`; }; Responsive.Event[`view-${idModal}`](); // Router if (options.route) (() => { let path = window.location.pathname; if (path !== '/' && path[path.length - 1] === '/') path = path.slice(0, -1); const proxyPath = getProxyPath(); const newPath = `${proxyPath}${options.route}`; if (path !== newPath) { // console.warn('SET MODAL URI', newPath); setPath(`${newPath}`); // ${location.search} setDocTitle({ ...options.RouterInstance, route: options.route }); } })(); break; case 'slide-menu': case 'slide-menu-right': case 'slide-menu-left': (async () => { const { barConfig } = options; options.style = { position: 'absolute', height: `${ window.innerHeight - (options.heightTopBar ? options.heightTopBar : heightDefaultTopBar) - (options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar) }px`, width: `${slideMenuWidth}px`, // 'overflow-x': 'hidden', // overflow: 'visible', // required for tooltip 'z-index': 6, resize: 'none', top: `${options.heightTopBar ? options.heightTopBar : heightDefaultTopBar}px`, }; options.mode === 'slide-menu-right' ? (options.style.right = '0px') : (options.style.left = '0px'); const contentIconClass = 'abs center'; if (options.class) options.class += ' hide'; else options.class = 'hide'; options.dragDisabled = true; options.titleClass = 'hide'; top = '0px'; left = 'auto'; width = 'auto'; // barConfig.buttons.maximize.disabled = true; // barConfig.buttons.minimize.disabled = true; // barConfig.buttons.restore.disabled = true; // barConfig.buttons.menu.disabled = true; // barConfig.buttons.close.disabled = true; options.btnBarModalClass = 'hide'; Responsive.Event[`slide-menu-${idModal}`] = () => { for (const _idModal of Object.keys(this.Data)) { if (this.Data[_idModal].slideMenu && this.Data[_idModal].slideMenu.id === idModal) this.Data[_idModal].slideMenu.callBack(); } s(`.${idModal}`).style.height = `${ window.innerHeight - (options.heightTopBar ? options.heightTopBar : heightDefaultTopBar) - (options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar) }px`; if (s(`.main-body-top`)) { if (Modal.mobileModal()) { if (s(`.btn-menu-${idModal}`).classList.contains('hide') && collapseSlideMenuWidth !== slideMenuWidth) s(`.main-body-top`).classList.remove('hide'); if (s(`.btn-close-${idModal}`).classList.contains('hide')) s(`.main-body-top`).classList.add('hide'); } else if (!s(`.main-body-top`).classList.contains('hide')) s(`.main-body-top`).classList.add('hide'); } }; barConfig.buttons.menu.onClick = () => { this.Data[idModal][options.mode].width = slideMenuWidth; s(`.btn-menu-${idModal}`).classList.add('hide'); s(`.btn-close-${idModal}`).classList.remove('hide'); s(`.${idModal}`).style.width = `${this.Data[idModal][options.mode].width}px`; s(`.html-${idModal}`).style.display = 'block'; // s(`.title-modal-${idModal}`).style.display = 'block'; setTimeout(() => { s(`.main-body-btn-ui-menu-menu`).classList.add('hide'); s(`.main-body-btn-ui-menu-close`).classList.remove('hide'); if (s(`.btn-bar-center-icon-menu`)) { s(`.btn-bar-center-icon-close`).classList.remove('hide'); s(`.btn-bar-center-icon-menu`).classList.add('hide'); } }); setTimeout(() => { s(`.main-body-btn-container`).style[ true || (options.mode && options.mode.match('right')) ? 'right' : 'left' ] = options.mode && options.mode.match('right') ? `${slideMenuWidth}px` : '0px'; }); Responsive.Event[`slide-menu-${idModal}`](); }; barConfig.buttons.close.onClick = () => { this.Data[idModal][options.mode].width = 0; s(`.btn-close-${idModal}`).classList.add('hide'); s(`.btn-menu-${idModal}`).classList.remove('hide'); s(`.${idModal}`).style.width = `${this.Data[idModal][options.mode].width}px`; s(`.html-${idModal}`).style.display = 'none'; setTimeout(() => { s(`.main-body-btn-ui-menu-close`).classList.add('hide'); s(`.main-body-btn-ui-menu-menu`).classList.remove('hide'); if (s(`.btn-bar-center-icon-menu`)) { s(`.btn-bar-center-icon-menu`).classList.remove('hide'); s(`.btn-bar-center-icon-close`).classList.add('hide'); } }); // s(`.title-modal-${idModal}`).style.display = 'none'; setTimeout(() => { s(`.main-body-btn-container`).style[ true || (options.mode && options.mode.match('right')) ? 'right' : 'left' ] = `${0}px`; }); Responsive.Event[`slide-menu-${idModal}`](); }; transition += `, width 0.3s`; setTimeout(() => { append( 'body', html` <div class="abs main-body-btn-container hide" style="top: ${options.heightTopBar + 50}px; z-index: 9; ${true || (options.mode && options.mode.match('right')) ? 'right' : 'left'}: 50px; width: 50px; height: 100px; transition: .3s" > <div class="abs main-body-btn main-body-btn-menu" style="top: 50px; ${true || (options.mode && options.mode.match('right')) ? 'right' : 'left'}: 0px" > <div class="abs center"> <i class="fa-solid fa-xmark hide main-body-btn-ui-menu-close"></i> <i class="fa-solid fa-bars main-body-btn-ui-menu-menu"></i> </div> </div> <div class="abs main-body-btn main-body-btn-ui" style="top: 0px; ${true || (options.mode && options.mode.match('right')) ? 'right' : 'left'}: 0px" > <div class="abs center"> <i class="fas fa-caret-down main-body-btn-ui-open hide"></i> <i class="fas fa-caret-up main-body-btn-ui-close"></i> </div> </div> <div class="main-body-btn-container-custom"></div> </div> `, ); s(`.main-body-btn-menu`).onclick = () => { Modal.actionBtnCenter(); }; let _heightTopBar, _heightBottomBar, _topMenu; s(`.main-body-btn-ui`).onclick = () => { if (s(`.main-body-btn-ui-open`).classList.contains('hide')) { s(`.main-body-btn-ui-open`).classList.remove('hide'); s(`.main-body-btn-ui-close`).classList.add('hide'); _heightTopBar = newInstance(options.heightTopBar); _heightBottomBar = newInstance(options.heightBottomBar); _topMenu = newInstance(s(`.modal-menu`).style.top); options.heightTopBar = 0; options.heightBottomBar = 0; s(`.slide-menu-top-bar`).classList.add('hide'); s(`.bottom-bar`).classList.add('hide'); s(`.modal-menu`).style.top = '0px'; s(`.main-body-btn-container`).style.top = '50px'; s(`.main-body`).style.top = '0px'; for (const event of Object.keys(Modal.Data[idModal].onBarUiClose)) Modal.Data[idModal].onBarUiClose[event](); } else { s(`.main-body-btn-ui-close`).classList.remove('hide'); s(`.main-body-btn-ui-open`).classList.add('hide'); options.heightTopBar = _heightTopBar; options.heightBottomBar = _heightBottomBar; s(`.modal-menu`).style.top = _topMenu; s(`.main-body-btn-container`).style.top = `${options.heightTopBar + 50}px`; s(`.slide-menu-top-bar`).classList.remove('hide'); s(`.bottom-bar`).classList.remove('hide'); s(`.main-body`).style.top = `${options.heightTopBar}px`; for (const event of Object.keys(Modal.Data[idModal].onBarUiOpen)) Modal.Data[idModal].onBarUiOpen[event](); } Responsive.Event[`slide-menu-modal-menu`](); Object.keys(this.Data).map((_idModal) => { if (this.Data[_idModal].slideMenu) { if (s(`.btn-maximize-${_idModal}`)) s(`.btn-maximize-${_idModal}`).click(); } }); Responsive.Event[`view-${'main-body'}`](); if (Responsive.Event[`view-${'bottom-bar'}`]) Responsive.Event[`view-${'bottom-bar'}`](); if (Responsive.Event[`view-${'main-body-top'}`]) Responsive.Event[`view-${'main-body-top'}`](); for (const keyEvent of Object.keys(this.Data[idModal].onExpandUiListener)) { this.Data[idModal].onExpandUiListener[keyEvent]( !s(`.main-body-btn-ui-open`).classList.contains('hide'), ); } }; }); const inputSearchBoxId = `top-bar-search-box`; append( 'body', html` <div class="fix modal slide-menu-top-bar"> <div class="fl top-bar ${options.barClass ? options.barClass : ''}" style="height: ${originHeightTopBar}px;" > ${await BtnIcon.Render({ style: `height: 100%`, class: 'in fll main-btn-menu action-bar-box action-btn-close hide', label: html` <div class="${contentIconClass} action-btn-close-render"> <i class="fa-solid fa-xmark"></i> </div>`, })} ${await BtnIcon.Render({ style: `height: 100%`, class: `in fll main-btn-menu action-bar-box action-btn-app-icon ${ options?.disableTools?.includes('app-icon') ? 'hide' : '' }`, label: html` <div class="${contentIconClass} action-btn-app-icon-render"></div>`, })} <form class="in fll top-bar-search-box-container hover ${options?.disableTools?.includes('text-box') ? 'hide' : ''}" > ${await Input.Render({ id: inputSearchBoxId, placeholder: Modal.mobileModal() ? Translate.Render('search', '.top-bar-search-box') : undefined, // html`<i class="fa-solid fa-magnifying-glass"></i> ${Translate.Render('search')}`, placeholderIcon: html`<div class="in fll" style="width: ${originHeightTopBar}px; height: ${originHeightTopBar}px;" > <div class="abs center"><i class="fa-solid fa-magnifying-glass"></i></div> ${!Modal.mobileModal() ? html` <div class="inl wfm key-shortcut-container-info" style="${renderCssAttr({ style: { top: '10px', left: '60px' } })}" > ${await Badge.Render({ id: 'shortcut-key-info-search', text: 'Shift', classList: 'inl', style: { 'z-index': 1 }, })} ${await Badge.Render({ id: 'shortcut-key-info-search', text: '+', classList: 'inl', style: { 'z-index': 1, background: 'none', color: '#5f5f5f' }, })} ${await Badge.Render({ id: 'shortcut-key-info-search', text: 'k', classList: 'inl', style: { 'z-index': 1 }, })} </div>` : ''} </div>`, inputClass: 'in fll', // containerClass: '', })} </form> <div class="abs top-box-profile-container ${options?.disableTools?.includes('profile') ? 'hide' : ''}" > ${await BtnIcon.Render({ style: `height: 100%`, class: 'in fll session-in-log-in main-btn-menu action-bar-box action-btn-profile-log-in', label: html` <div class="${contentIconClass} action-btn-profile-log-in-render"></div>`, })} ${await BtnIcon.Render({ style: `height: 100%`, class: 'in fll session-in-log-out main-btn-menu action-bar-box action-btn-profile-log-out', label: html` <div class="${contentIconClass} action-btn-profile-log-out-render"> <i class="fas fa-user-plus"></i> </div>`, })} </div> </div> ${options?.slideMenuTopBarFix ? html`<div class="abs modal slide-menu-top-bar-fix" style="height: ${options.heightTopBar}px"> ${await options.slideMenuTopBarFix()} </div>` : ''} </div>`, ); EventsUI.onClick(`.action-btn-profile-log-in`, () => { s(`.main-btn-account`).click(); }); EventsUI.onClick(`.action-btn-profile-log-out`, () => { s(`.main-btn-sign-up`).click(); }); s(`.input-info-${inputSearchBoxId}`).style.textAlign = 'left'; htmls(`.input-info-${inputSearchBoxId}`, ''); const inputInfoNode = s(`.input-info-${inputSearchBoxId}`).cloneNode(true); s(`.input-info-${inputSearchBoxId}`).remove(); { const id = 'search-box-history'; const searchBoxHistoryId = id; const formDataInfoNode = [ { model: 'search-box', id: inputSearchBoxId, rules: [] /*{ type: 'isEmpty' }, { type: 'isEmail' }*/, }, ]; let hoverHistBox = false; let hoverInputBox = false; let currentKeyBoardSearchBoxIndex = 0; let results = []; let historySearchBox = []; const checkHistoryBoxTitleStatus = () => { if (s(`.search-box-result-title`) && s(`.search-box-result-title`).classList) { if (!s(`.${inputSearchBoxId}`).value.trim()) { s(`.search-box-result-title`).classList.add('hide'); s(`.search-box-recent-title`).classList.remove('hide'); } else { s(`.search-box-recent-title`).classList.add('hide'); s(`.search-box-result-title`).classList.remove('hide'); } } }; const checkShortcutContainerInfoEnabled = () => { if (Modal.mobileModal() || !s(`.key-shortcut-container-info`)) return; if (!s(`.${inputSearchBoxId}`).value) { s(`.key-shortcut-container-info`).classList.remove('hide'); } else s(`.key-shortcut-container-info`).classList.add('hide'); }; const renderSearchResult = async (results) => { htmls(`.html-${searchBoxHistoryId}`, ''); if (results.length === 0) { append( `.html-${searchBoxHistoryId}`, await BtnIcon.Render({ label: html`<i class="fas fa-exclamation-circle"></i> ${Translate.Render('no-result-found')}`, class: `wfa`, style: renderCssAttr({ style: { padding: '3px', margin: '2px', 'text-align': 'center', border: 'none', cursor: 'default', background: 'none !important', }, }), }), ); } let indexResult = -1; for (const result of results) { indexResult++; const indexRender = indexResult; append( `.html-${searchBoxHistoryId}`, await BtnIcon.Render({ label: `${ result.fontAwesomeIcon ? html`<i class="${result.fontAwesomeIcon.classList.toString()}"></i> ` : result.imgElement ? html`<img class="inl" src="${result.imgElement.src}" style="${renderCssAttr({ style: { width: '25px', height: '25px' } })}" />` : '' } ${Translate.Render(result.routerId)}`, class: `wfa search-result-btn-${result.routerId} ${ indexResult === currentKeyBoardSearchBoxIndex ? 'main-btn-menu-active' : '' } search-result-btn-${indexResult}`, style: renderCssAttr({ style: { padding: '3px', margin: '2px', 'text-align': 'left' }, }), }), ); s(`.search-result-btn-${result.routerId}`).onclick = () => { s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList.remove( `main-btn-menu-active`, ); currentKeyBoardSearchBoxIndex = indexRender; s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList.add( `main-btn-menu-active`, ); setSearchValue(`.search-result-btn-${result.routerId}`); }; } }; const getResultSearchBox = (validatorData) => { const { model, id } = validatorData; switch (model) { case 'search-box': { if ( s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex] && s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList ) s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList.remove( `main-btn-menu-active`, ); currentKeyBoardSearchBoxIndex = 0; if ( s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex] && s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList ) s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList.add( `main-btn-menu-active`, ); results = []; const routerInstance = Worker.RouterInstance.Routes(); for (const _routerId of Object.keys(routerInstance)) { const routerId = _routerId.slice(1); if (routerId) { if ( s(`.main-btn-${routerId}`) && (routerId.toLowerCase().match(s(`.${id}`).value.toLowerCase()) || (Translate.Data[routerId] && Object.keys(Translate.Data[routerId]).filter((keyLang) => Translate.Data[routerId][keyLang] .toLowerCase() .match(s(`.${id}`).value.toLowerCase()), ).length > 0)) ) { const fontAwesomeIcon = getAllChildNodes(s(`.main-btn-${routerId}`)).find((e) => { return ( e.classList && Array.from(e.classList).find((e) => e.match('fa-') && !e.match('fa-grip-vertical')) ); }); const imgElement = getAllChildNodes(s(`.main-btn-${routerId}`)).find((e) => { return ( typeof e.src === 'string' && e.src.match(routerId) && e.classList && Array.from(e.classList).find((e) => e.match('img-btn-square-menu')) ); }); if (imgElement || fontAwesomeIcon) { results.push({ routerId, fontAwesomeIcon: fontAwesomeIcon, imgElement, }); } } } } } break; default: break; } if (s(`.${inputSearchBoxId}`).value.trim()) renderSearchResult(results); else renderSearchResult(historySearchBox); }; const searchBoxCallBack = async (validatorData) => { const isSearchBoxActiveElement = isActiveElement(inputSearchBoxId); checkHistoryBoxTitleStatus(); checkShortcutContainerInfoEnabled(); if (!isSearchBoxActiveElement && !hoverHistBox && !hoverInputBox) { Modal.removeModal(searchBoxHistoryId); return; } setTimeout(() => getResultSearchBox(validatorData)); }; const getDefaultSearchBoxSelector = () => `.search-result-btn-${currentKeyBoardSearchBoxIndex}`; const updateSearchBoxValue = (selector) => { if (!selector) selector = getDefaultSearchBoxSelector(); if (s(selector).childNodes) { if ( s(selector).childNodes[s(selector).childNodes.length - 1] && s(selector).childNodes[s(selector).childNodes.length - 1].data && s(selector).childNodes[s(selector).childNodes.length - 1].data.trim() ) { s(`.${inputSearchBoxId}`).value = s(selector).childNodes[s(selector).childNodes.length - 1].data.trim(); } else if ( s(selector).childNodes[s(selector).childNodes.length - 2] && s(selector).childNodes[s(selector).childNodes.length - 2].outerText && s(selector).childNodes[s(selector).childNodes.length - 2].outerText.trim() ) { s(`.${inputSearchBoxId}`).value = s(selector).childNodes[s(selector).childNodes.length - 2].outerText.trim(); } } checkHistoryBoxTitleStatus(); checkShortcutContainerInfoEnabled(); }; const setSearchValue = (selector) => { if (!selector) selector = getDefaultSearchBoxSelector(); historySearchBox = historySearchBox.filter( (h) => h.routerId !== results[currentKeyBoardSearchBoxIndex].routerId, ); historySearchBox.unshift(results[currentKeyBoardSearchBoxIndex]); updateSearchBoxValue(selector); s(`.main-btn-${results[currentKeyBoardSearchBoxIndex].routerId}`).click(); Modal.removeModal(searchBoxHistoryId); }; const searchBoxHistoryOpen = async () => { if (!s(`.${id}`)) { const { barConfig } = await Themes[Css.currentTheme](); barConfig.buttons.maximize.disabled = true; barConfig.buttons.minimize.disabled = true; barConfig.buttons.restore.disabled = true; barConfig.buttons.menu.disabled = true; barConfig.buttons.close.disabled = false; await Modal.Render({ id, barConfig, title: html`<div class="search-box-recent-title"> ${renderViewTitle({ icon: html`<i class="fas fa-history mini-title"></i>`, text: Translate.Render('recent'), })} </div> <div class="search-box-result-title hide"> ${renderViewTitle({ icon: html`<i class="far fa-list-alt mini-title"></i>`, text: Translate.Render('results'), })} </div>`, html: () => html``, titleClass: 'mini-title', style: { resize: 'none', 'max-width': '450px', height: this.mobileModal() && window.innerWidth < 445 ? `${window.innerHeight - originHeightTopBar}px !important` : '300px !important', 'z-index': 7, }, dragDisabled: true, maximize: true, heightBottomBar: 0, heightTopBar: originHeightTopBar, barMode: options.barMode, }); const titleNode = s(`.title-modal-${id}`).cloneNode(true); s(`.title-modal-${id}`).remove(); s(`.btn-bar-modal-container-render-${id}`).classList.add('in'); s(`.btn-bar-modal-container-render-${id}`).classList.add('fll'); s(`.btn-bar-modal-container-render-${id}`).appendChild(titleNode); prepend(`.btn-bar-modal-container-${id}`, html`<div class="hide">${inputInfoNode.outerHTML}</div>`); s(`.top-bar-search-box-container`).onmouseover = () => { hoverInputBox = true; }; s(`.top-bar-search-box-container`).onmouseout = () => { hoverInputBox = false; }; s(`.${id}`).onmouseover = () => { hoverHistBox = true; }; s(`.${id}`).onmouseout = () => { hoverHistBox = false; s(`.${inputSearchBoxId}`).focus(); }; } }; s('.top-bar-search-box').oninput = () => { searchBoxHistoryOpen(); searchBoxCallBack(formDataInfoNode[0]); }; s('.top-bar-search-box').onfocus = () => { searchBoxHistoryOpen(); searchBoxCallBack(formDataInfoNode[0]); }; s('.top-bar-search-box').onblur = () => { if (!hoverHistBox && !hoverInputBox && !isActiveElement(inputSearchBoxId)) { Modal.removeModal(searchBoxHistoryId); } }; EventsUI.onClick(`.top-bar-search-box-container`, () => { searchBoxHistoryOpen(); searchBoxCallBack(formDataInfoNode[0]); }); const timePressDelay = 100; Keyboard.instanceMultiPressKey({ id: 'input-search-shortcut-ArrowUp', keys: ['ArrowUp'], eventCallBack: () => { if (s(`.${id}`)) { if ( s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex] && s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex - 1] ) { s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList.remove( `main-btn-menu-active`, ); currentKeyBoardSearchBoxIndex--; s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList.add( `main-btn-menu-active`, ); } else { if (s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex]) s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList.remove( `main-btn-menu-active`, ); currentKeyBoardSearchBoxIndex = s(`.html-${searchBoxHistoryId}`).childNodes.length - 1; if (s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex]) s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList.add( `main-btn-menu-active`, ); } updateSearchBoxValue(); } }, timePressDelay, }); Keyboard.instanceMultiPressKey({ id: 'input-search-shortcut-ArrowDown', keys: ['ArrowDown'], eventCallBack: () => { if (s(`.${id}`)) { if ( s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex] && s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex + 1] ) { s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList.remove( `main-btn-menu-active`, ); currentKeyBoardSearchBoxIndex++; s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList.add( `main-btn-menu-active`, ); } else { if (s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex]) s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList.remove( `main-btn-menu-active`, ); currentKeyBoardSearchBoxIndex = 0; if (s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex]) s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList.add( `main-btn-menu-active`, ); } updateSearchBoxValue(); } }, timePressDelay, }); s(`.top-bar-search-box-container`).onsubmit = (e) => { e.preventDefault(); setSearchValue(); }; } setTimeout(async () => { // clone and change position // s(`.btn-close-${idModal}`); // s(`.btn-menu-${idModal}`); if (originHeightBottomBar === 0) { const btnCloseNode = s(`.btn-close-${idModal}`).cloneNode(true); s(`.btn-close-${idModal}`).remove(); s(`.top-bar`).appendChild(btnCloseNode); s(`.btn-close-${idModal}`).onclick = btnCloseEvent; const btnMenuNode = s(`.btn-menu-${idModal}`).cloneNode(true); s(`.btn-menu-${idModal}`).remove(); s(`.top-bar`).appendChild(btnMenuNode); s(`.btn-menu-${idModal}`).onclick = btnMenuEvent; } // const titleNode = s(`.title-modal-${idModal}`).cloneNode(true); // s(`.title-modal-${idModal}`).remove(); // s(`.top-bar`).appendChild(titleNode); s(`.slide-menu-top-bar`).style.zIndex = 7; // s('body').removeChild(`.${idModal}`); // while (s(`.top-modal`).firstChild) s(`.top-modal`).removeChild(s(`.top-modal`).firstChild); { const { barConfig } = await Themes[Css.currentTheme](); barConfig.buttons.maximize.disabled = true; barConfig.buttons.minimize.disabled = true; barConfig.buttons.restore.disabled = true; barConfig.buttons.menu.disabled = true; barConfig.buttons.close.disabled = true; const id = 'main-body'; await Modal.Render({ id, barConfig, html: options.htmlMainBody ? options.htmlMainBody : () => html``, titleClass: 'hide', style: { // overflow: 'hidden', background: 'none', resize: 'none', 'min-width': `${minWidth}px`, width: '100%', // border: '3px solid red', }, dragDisabled: true, maximize: true, slideMenu: 'modal-menu', heightTopBar: originHeightTopBar, heightBottomBar: originHeightBottomBar, barMode: options.barMode, observer: true, }); const maxWidthInputSearchBox = 450; const paddingInputSearchBox = 5; const paddingRightSearchBox = 50; Responsive.Event[`view-${id}`] = () => { if (!this.Data[id] || !s(`.${id}`)) return delete Responsive.Event[`view-${id}`]; const widthInputSearchBox = window.innerWidth > maxWidthInputSearchBox ? maxWidthInputSearchBox : window.innerWidth; s(`.top-bar-search-box-container`).style.width = `${ widthInputSearchBox - originHeightTopBar - paddingRightSearchBox - 1 }px`; s(`.top-bar-search-box`).style.width = `${ widthInputSearchBox - originHeightTopBar * 2 - paddingRightSearchBox - paddingInputSearchBox * 2 /*padding input*/ - 10 /* right-margin */ }px`; s(`.top-bar-search-box`).style.top = `${ (originHeightTopBar - s(`.top-bar-search-box`).clientHeight) / 2 }px`; if (this.Data[id].slideMenu) s(`.${id}`).style.height = `${ window.innerHeight - (options.heightTopBar ? options.heightTopBar : heightDefaultTopBar) - (options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar) }px`; }; Responsive.Event[`view-${id}`](); Keyboard.instanceMultiPressKey({ id: 'input-search-shortcut-k', keys: [ ['Shift', 'k'], ['Alt', 'k'], ], eventCallBack: () => { if (s(`.top-bar-search-box`)) { s(`.top-bar-search-box`).blur(); s(`.top-bar-search-box`).focus(); s(`.top-bar-search-box`).select(); } }, }); } { const { barConfig } = await Themes[Css.currentTheme](); barConfig.buttons.maximize.disabled = true; barConfig.buttons.minimize.disabled = true; barConfig.buttons.restore.disabled = true; barConfig.buttons.menu.disabled = true; barConfig.buttons.close.disabled = true; const id = 'bottom-bar'; if (options && options.homeModals && !options.homeModals.includes(id)) options.homeModals.push(id); else options.homeModals = [id]; const html = async () => html` <style> .top-bar-search-box-container { height: 100%; overflow: hidden; } .bottom-bar { overflow: hidden; } .action-bar-box { margin: 0px; border: none; width: 50px; min-height: 50px; } </style> <div class="fl ${options.barClass ? options.barClass : ''}" style="height: ${originHeightBottomBar}px;" > ${await BtnIcon.Render({ style: `height: 100%`, class: `in fl${ options.mode === 'slide-menu-right' ? 'r' : 'l' } main-btn-menu action-bar-box action-btn-center ${ options?.disableTools?.includes('center') ? 'hide' : '' }`, label: html` <div class="${contentIconClass}"> <i class="far fa-square btn-bar-center-icon-square hide"></i> <span class="btn-bar-center-icon-close hide">${barConfig.buttons.close.label}</span> <span class="btn-bar-center-icon-menu">${barConfig.buttons.menu.label}</span> </div> `, })} ${await BtnIcon.Render({ style: `height: 100%`, class: `in flr main-btn-menu action-bar-box action-btn-lang ${ options?.disableTools?.includes('lang') ? 'hide' : '' }`, label: html` <div class="${contentIconClass} action-btn-lang-render"></div>`, })} ${await BtnIcon.Render({ style: `height: 100%`, class: `in flr main-btn-menu action-bar-box action-btn-theme ${ options?.disableTools?.includes('theme') ? 'hide' : '' }`, label: html` <div class="${contentIconClass} action-btn-theme-render"></div>`, })} ${await BtnIcon.Render({ style: `height: 100%`, class: `in flr main-btn-menu action-bar-box action-btn-home ${ options?.disableTools?.includes('navigator') ? 'hide' : '' }`, label: html` <div class="${contentIconClass}"><i class="fas fa-home"></i></div>`, })} ${await BtnIcon.Render({ style: `height: 100%`, class: `in flr main-btn-menu action-bar-box action-btn-right ${ options?.disableTools?.includes('navigator') ? 'hide' : '' }`, label: html` <div class="${contentIconClass}"><i class="fas fa-chevron-right"></i></div>`, })} ${await BtnIcon.Render({ style: `height: 100%`, class: `in flr main-btn-menu action-bar-box action-btn-left ${ options?.disableTools?.includes('navigator') ? 'hide' : '' }`, label: html`<div class="${contentIconClass}"><i class="fas fa-chevron-left"></i></div>`, })} </div> `; if (options.heightBottomBar === 0 && options.heightTopBar > 0) { append(`.slide-menu-top-bar`, html` <div class="in ${id}">${await html()}</div>`); } else { await Modal.Render({ id, barConfig, html, titleClass: 'hide', style: { resize: 'none', height: `${options.heightBottomBar}px`, 'min-width': `${minWidth}px`, 'z-index': 7, }, dragDisabled: true, maximize: true, barMode: options.barMode, }); Responsive.Event[`view-${id}`] = () => { if (!this.Data[id] || !s(`.${id}`)) return delete Responsive.Event[`view-${id}`]; // <div class="in fll right-offset-menu-bottom-bar" style="height: 100%"></div> // s(`.right-offset-menu-bottom-bar`).style.width = `${window.innerWidth - slideMenuWidth}px`; s(`.${id}`).style.top = `${ window.innerHeight - (options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar) }px`; }; Responsive.Event[`view-${id}`](); } EventsUI.onClick(`.action-btn-left`, (e) => { e.preventDefault(); window.history.back(); }); EventsUI.onClick(`.action-btn-center`, (e) => { e.preventDefault(); this.actionBtnCenter(); }); EventsUI.onClick(`.action-btn-right`, (e) => { e.preventDefault(); window.history.forward(); }); EventsUI.onClick(`.action-btn-home`, async () => { await Modal.onHomeRouterEvent(); Object.keys(this.Data[idModal].onHome).map((keyListener) => this.Data[idModal].onHome[keyListener]()); }); EventsUI.onClick(`.action-btn-app-icon`, () => Modal.onHomeRouterEvent()); Keyboard.instanceMultiPressKey({ id: 'input-shortcut-global-escape', keys: ['Escape'], eventCallBack: () => { if (s(`.btn-close-${this.currentTopModalId}`)) s(`.btn-close-${this.currentTopModalId}`).click(); }, }); } { ThemeEvents['action-btn-theme'] = () => { htmls( `.action-btn-theme-render`, html` ${darkTheme ? html` <i class="fas fa-moon"></i>` : html`<i class="far fa-sun"></i>`}`, ); }; ThemeEvents['action-btn-theme'](); EventsUI.onClick(`.action-btn-theme`, async () => { const themePair = ThemesScope.find((t) => t.theme === Css.currentTheme).themePair; const theme = themePair ? themePair : ThemesScope.find((t) => t.dark === !darkTheme).theme; if (s(`.dropdown-option-${theme}`)) DropDown.Tokens['settings-theme'].onClickEvents[`dropdown-option-${theme}`](); else awa