UNPKG

@sunnysideup/npm-page-favourites-bookmarker

Version:
134 lines (122 loc) 3.08 kB
export class Overlay { /** * @param {{ * getList:()=>Array<{url:string,title:string,ts:number}>, * onRemove:(url:string)=>void, * onReorder:(from:number,to:number)=>void, * onClose:()=>void, * onSync:()=>Promise<void>, * onShare:()=>Promise<void>, * shareLink?: string, * emailLink?: string, * userIsLoggedIn: boolean, * loginUrl?: string, * templates:{ * overlayBar:Function, * overlayShell:Function, * overlayRow:Function * overlayNoBookmarks:Function * } * htmlClasses Record<string, string>, * phrases Record<string, string>, * }} opts */ constructor (opts) { this.opts = opts this.el = null this.listEl = null } #isShown = false isShown () { return this.#isShown } toggle () { if (this.#isShown) { this.hide() } else { this.show() } } show () { if (!this.#isShown) { this.mount() } } hide () { this.unmount() } getEl () { return this.el } unmount () { document.removeEventListener('keydown', this.#escListener) this.el?.remove() this.el = this.listEl = null this.#escListener = null this.#isShown = false } mount () { const { wrap, list } = this.opts.templates.overlayShell( { htmlClasses: this.opts.htmlClasses, phrases: this.opts.phrases } ) const hasBookmarks = this.opts.getList().length > 0 const bar = this.opts.templates.overlayBar({ onClose: this.opts.onClose, onSync: this.opts.onSync, onShare: this.opts.onShare, hasBookmarks, userIsLoggedIn: this.opts.userIsLoggedIn, loginUrl: this.opts.loginUrl, shareLink: this.opts.shareLink, emailLink: this.opts.emailLink, htmlClasses: this.opts.htmlClasses, phrases: this.opts.phrases }) wrap.prepend(bar) document.body.appendChild(wrap) this.el = wrap this.listEl = list this.#renderList() this.#escListener = e => { if (e.code === 'Escape') { this.hide() } } document.addEventListener('keydown', this.#escListener) this.#isShown = true } update () { this.#renderList() } #renderList () { // once mounted, it should not be falsy if (!this.listEl) return this.listEl.innerHTML = '' const frag = document.createDocumentFragment() const rowList = this.opts.getList() if (rowList.length === 0) { const row = this.opts.templates.overlayNoBookmarks({ htmlClasses: this.opts.htmlClasses, phrases: this.opts.phrases }) frag.appendChild(row) } else { rowList.forEach((item, i) => { const row = this.opts.templates.overlayRow({ item, index: i, onRemove: this.opts.onRemove, onReorder: this.opts.onReorder, htmlClasses: this.opts.htmlClasses, phrases: this.opts.phrases }) frag.appendChild(row) }) } this.listEl.appendChild(frag) } #escListener = null }