tiny-essentials
Version:
Collection of small, essential scripts designed to be used across various projects. These simple utilities are crafted for speed, ease of use, and versatility.
1 lines • 5.58 kB
JavaScript
(()=>{"use strict";var t={d:(e,n)=>{for(var o in n)t.o(n,o)&&!t.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:n[o]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};t.d(e,{TinyNotifyCenter:()=>o});class n{static getTemplate(){return'\n<div class="notify-overlay hidden">\n <div class="notify-center" id="notifCenter">\n <div class="header">\n <div>Notifications</div>\n <div class="options">\n <button class="clear-all" type="button">\n <svg\n xmlns="http://www.w3.org/2000/svg"\n viewBox="0 0 24 24"\n width="24"\n height="24"\n fill="currentColor"\n >\n <path\n d="M21.6 2.4a1 1 0 0 0-1.4 0L13 9.6l-1.3-1.3a1 1 0 0 0-1.4 0L3 15.6a1 1 0 0 0 0 1.4l4 4a1 1 0 0 0 1.4 0l7.3-7.3a1 1 0 0 0 0-1.4l-1.3-1.3 7.2-7.2a1 1 0 0 0 0-1.4zM6 17l3.5-3.5 1.5 1.5L7.5 18.5 6 17z"\n />\n </svg>\n </button>\n <button class="close">×</button>\n </div>\n </div>\n <div class="list"></div>\n </div>\n</div>\n\n<button class="notify-bell" aria-label="Open notifications">\n <svg\n xmlns="http://www.w3.org/2000/svg"\n width="20"\n height="20"\n fill="currentColor"\n viewBox="0 0 24 24"\n >\n <path\n d="M12 2C10.3 2 9 3.3 9 5v1.1C6.7 7.2 5 9.4 5 12v5l-1 1v1h16v-1l-1-1v-5c0-2.6-1.7-4.8-4-5.9V5c0-1.7-1.3-3-3-3zm0 20c1.1 0 2-.9 2-2h-4c0 1.1.9 2 2 2z"\n />\n </svg>\n <span class="badge" id="notifBadge">0</span>\n</button>\n '}static insertTemplate(t="afterbegin"){document.body.insertAdjacentHTML(t,n.getTemplate())}#t;#e;#n;#o;#s;#i=0;#a=99;#l=300;#r=!1;#c=new WeakMap;#d(t){if(this.#c.delete(t),!(t instanceof HTMLElement))throw new Error("Invalid HTMLElement to clear.");t.classList.add("removing"),setTimeout((()=>{this.markAsRead(t),t.remove()}),this.#l)}#m(t){this.#i=Math.max(0,t),this.#n.setAttribute("data-value",String(this.#i)),this.#n.textContent=this.#i>this.#a?`${this.#a}+`:String(this.#i)}constructor(t={}){const{center:e=document.getElementById("notifCenter"),badge:n=document.getElementById("notifBadge"),button:o=document.querySelector(".notify-bell"),overlay:s=document.querySelector(".notify-overlay")}=t;if(!(e instanceof HTMLElement))throw new Error(`NotificationCenter: "center" must be an HTMLElement. Got: ${e}`);if(!(s instanceof HTMLElement))throw new Error(`NotificationCenter: "overlay" must be an HTMLElement. Got: ${s}`);if(!(n instanceof HTMLElement))throw new Error(`NotificationCenter: "badge" must be an HTMLElement. Got: ${n}`);if(!(o instanceof HTMLElement))throw new Error(`NotificationCenter: "button" must be an HTMLElement. Got: ${o}`);const i=e?.querySelector(".clear-all"),a=e?.querySelector(".list")??null;if(!(a instanceof HTMLElement))throw new Error(`NotificationCenter: ".list" inside center must be an HTMLElement. Got: ${a}`);this.#t=e,this.#e=a,this.#n=n,this.#o=o,this.#s=s,this.#o.addEventListener("click",(()=>this.toggle())),this.#t.querySelector(".close")?.addEventListener("click",(()=>this.close())),i&&i.addEventListener("click",(()=>this.clear())),this.#s.addEventListener("click",(t=>{t.target===this.#s&&this.close()}))}setMarkAllAsReadOnClose(t){if("boolean"!=typeof t)throw new TypeError("Expected boolean for markAllAsReadOnClose, got "+typeof t);this.#r=t}setRemoveDelay(t){if("number"!=typeof t)throw new Error('NotificationCenter: "ms" must be an number.');this.#l=t}getItemMode(t){const e=this.getItem(t);return e?this.#c.get(e):null}getItem(t){const e=this.#e.children.item(t);if(!(e instanceof HTMLElement))throw new Error(`NotificationCenter: "item" must be an HTMLElement. Got: ${e}`);return e}hasItem(t){return t>=0&&t<this.#e.children.length}markAsRead(t){const e=t instanceof HTMLElement?t:this.getItem(t);e.classList.contains("unread")&&(e.classList.remove("unread"),this.#m(this.#i-1))}add(t,e="text"){const n=document.createElement("div");n.className="item unread";let o=null,s=null,i=null,a=null;if("object"==typeof t&&null!==t?(o=t.title,s=t.message,i=t.avatar,a=t.onClick):s=t,i){const t=document.createElement("div");t.className="avatar",t.style.backgroundImage=`url("${i}")`,n.appendChild(t)}const l=document.createElement("div");if(l.className="content",o){const t=document.createElement("div");t.className="title",t.textContent=o,l.appendChild(t)}const r=document.createElement("div");r.className="message","html"===e?r.innerHTML=s:r.textContent=s,l.appendChild(r),"function"==typeof a&&(n.classList.add("clickable"),n.addEventListener("click",(t=>{t.target instanceof HTMLElement&&!t.target.closest(".notify-close")&&a(t)})));const c=document.createElement("button");c.className="notify-close",c.setAttribute("type","button"),c.innerHTML="×",c.addEventListener("click",(t=>{t.stopPropagation(),this.#d(n)})),n.append(l,c),this.#e.prepend(n),this.#c.set(n,e),this.#m(this.#i+1)}remove(t){const e=this.getItem(t);this.#d(e)}clear(){let t=!0;for(;t;){t=!1;const e=Array.from(this.#e.children);for(const n of e)n instanceof HTMLElement&&!n.classList.contains("removing")&&(this.#d(n),t=!0)}}open(){this.#s.classList.remove("hidden"),this.#t.classList.add("open")}close(){if(this.#s.classList.add("hidden"),this.#t.classList.remove("open"),this.#r){const t=this.#e.querySelectorAll(".item.unread");for(const e of t)e instanceof HTMLElement&&this.markAsRead(e)}}toggle(){this.#t.classList.contains("open")?this.close():this.open()}recount(){const t=this.#e.querySelectorAll(".item.unread").length;this.#m(t)}get count(){return this.#i}}const o=n;window.TinyNotifyCenter=e.TinyNotifyCenter})();