flexacore-ui-dev
Version:
Universal UI Framework for CDN, React, Angular, Vue, Svelte with TypeScript support
1 lines • 9.44 kB
JavaScript
!function(e,t){"use strict";class s{constructor(e,t,s){this.element=e,this.options=t,this.engine=s,this.initialized=!1,this.events=new Map,this.init()}init(){this.initialized=!0,this.setupEventListeners()}setupEventListeners(){}destroy(){this.initialized=!1,this.events.forEach((e,t)=>{this.element.removeEventListener(t,e)}),this.events.clear()}on(e,t){this.events.set(e,t),this.element.addEventListener(e,t)}emit(e,t={}){this.element.dispatchEvent(new CustomEvent(`fc-${e}`,{detail:{...t,component:this}}))}}class n extends s{setupEventListeners(){const e=t.querySelector(`[data-fc-modal-trigger="${this.element.id}"]`),s=this.element.querySelector("[data-fc-modal-close]");e&&this.on("click",t=>{t.target===e&&this.show()}),s&&this.on("click",e=>{e.target===s&&this.hide()}),this.on("click",e=>{e.target===this.element&&this.hide()})}show(){this.element.classList.add("fc-modal-active"),t.body.classList.add("fc-modal-open"),this.emit("show")}hide(){this.element.classList.remove("fc-modal-active"),t.body.classList.remove("fc-modal-open"),this.emit("hide")}}class i extends s{setupEventListeners(){const e=this.element.querySelector("[data-fc-dropdown-trigger]"),s=this.element.querySelector("[data-fc-dropdown-menu]");e&&s&&this.on("click",t=>{t.target===e&&(t.stopPropagation(),this.toggle())}),t.addEventListener("click",e=>{this.element.contains(e.target)||this.hide()})}toggle(){const e=this.element.querySelector("[data-fc-dropdown-menu]");e&&(e.classList.toggle("fc-dropdown-active"),this.emit("toggle",{active:e.classList.contains("fc-dropdown-active")}))}show(){const e=this.element.querySelector("[data-fc-dropdown-menu]");e&&(e.classList.add("fc-dropdown-active"),this.emit("show"))}hide(){const e=this.element.querySelector("[data-fc-dropdown-menu]");e&&(e.classList.remove("fc-dropdown-active"),this.emit("hide"))}}class o extends s{setupEventListeners(){const e=this.createTooltip();this.on("mouseenter",()=>{this.show(e)}),this.on("mouseleave",()=>{this.hide(e)})}createTooltip(){const e=t.createElement("div");return e.className="fc-tooltip",e.textContent=this.element.getAttribute("data-fc-tooltip"),t.body.appendChild(e),e}show(e){const t=this.element.getBoundingClientRect();e.style.left=t.left+t.width/2-e.offsetWidth/2+"px",e.style.top=t.top-e.offsetHeight-8+"px",e.classList.add("fc-tooltip-active"),this.emit("show")}hide(e){e.classList.remove("fc-tooltip-active"),this.emit("hide")}}class a extends s{setupEventListeners(){}show(e,t="info",s=3e3){const n=this.getToastContainer(),i=this.createToast(e,t);n.appendChild(i),setTimeout(()=>{i.classList.add("fc-toast-active")},100),setTimeout(()=>{this.hide(i)},s),this.emit("show",{message:e,type:t})}getToastContainer(){let e=t.getElementById("fc-toast-container");return e||(e=t.createElement("div"),e.id="fc-toast-container",e.className="fc-toast-container",t.body.appendChild(e)),e}createToast(e,s){const n=t.createElement("div");return n.className=`fc-toast fc-toast-${s}`,n.textContent=e,n}hide(e){e.classList.remove("fc-toast-active"),setTimeout(()=>{e.parentNode&&e.parentNode.removeChild(e)},300),this.emit("hide")}}class c extends s{setupEventListeners(){const e=this.element.querySelectorAll("[data-fc-tab]");this.element.querySelectorAll("[data-fc-tab-content]");e.forEach(e=>{e.addEventListener("click",()=>{const t=e.getAttribute("data-fc-tab");this.showTab(t)})}),e.length>0&&this.showTab(e[0].getAttribute("data-fc-tab"))}showTab(e){const t=this.element.querySelectorAll("[data-fc-tab]"),s=this.element.querySelectorAll("[data-fc-tab-content]");t.forEach(e=>{e.classList.remove("fc-tab-active")}),s.forEach(e=>{e.classList.remove("fc-tab-content-active")});const n=this.element.querySelector(`[data-fc-tab="${e}"]`),i=this.element.querySelector(`[data-fc-tab-content="${e}"]`);n&&n.classList.add("fc-tab-active"),i&&i.classList.add("fc-tab-content-active"),this.emit("tab-change",{target:e})}}class r extends s{setupEventListeners(){const e=this.element.querySelector('input[type="checkbox"]');e&&e.addEventListener("change",()=>{this.element.classList.toggle("fc-switch-active",e.checked),this.emit("change",{checked:e.checked})})}}class h extends s{setupEventListeners(){this.updateProgress()}updateProgress(){const e=this.element.getAttribute("data-fc-progress")||0,t=this.element.querySelector(".fc-progress-bar");t&&(t.style.width=`${e}%`)}setProgress(e){this.element.setAttribute("data-fc-progress",e),this.updateProgress(),this.emit("progress-change",{value:e})}}class l extends s{setupEventListeners(){const e=this.element.getAttribute("data-fc-skeleton")||"text";this.element.classList.add(`fc-skeleton-${e}`)}}class d extends s{setupEventListeners(){this.element.querySelectorAll("[data-fc-step]");const e=this.element.querySelector("[data-fc-stepper-next]"),t=this.element.querySelector("[data-fc-stepper-prev]");this.currentStep=0,e&&e.addEventListener("click",()=>{this.nextStep()}),t&&t.addEventListener("click",()=>{this.prevStep()}),this.showStep(0)}showStep(e){this.element.querySelectorAll("[data-fc-step]").forEach((t,s)=>{s===e?t.classList.add("fc-step-active"):t.classList.remove("fc-step-active")})}nextStep(){const e=this.element.querySelectorAll("[data-fc-step]");this.currentStep<e.length-1&&(this.currentStep++,this.showStep(this.currentStep),this.emit("step-change",{step:this.currentStep}))}prevStep(){this.currentStep>0&&(this.currentStep--,this.showStep(this.currentStep),this.emit("step-change",{step:this.currentStep}))}}class m extends s{setupEventListeners(){this.on("submit",e=>{e.preventDefault(),this.handleSubmit()})}handleSubmit(){const e=new FormData(this.element),t=Object.fromEntries(e);this.emit("submit",{data:t})}}class p{constructor(){this.name="component-manager",this.version="2.0.0",this.components=new Map,this.instances=new Map,this.engine=null,this.observer=null}init(e){this.engine=e,this.registerDefaultComponents(),this.initComponentSystem(),this.setupMutationObserver(),this.initExistingComponents(),this.engine.log("Component Manager Plugin initialized")}registerDefaultComponents(){this.registerComponent("modal",{name:"Modal",selector:"[data-fc-modal]",init:(e,t={})=>new n(e,t,this.engine)}),this.registerComponent("dropdown",{name:"Dropdown",selector:"[data-fc-dropdown]",init:(e,t={})=>new i(e,t,this.engine)}),this.registerComponent("tooltip",{name:"Tooltip",selector:"[data-fc-tooltip]",init:(e,t={})=>new o(e,t,this.engine)}),this.registerComponent("toast",{name:"Toast",selector:"[data-fc-toast]",init:(e,t={})=>new a(e,t,this.engine)}),this.registerComponent("tabs",{name:"Tabs",selector:"[data-fc-tabs]",init:(e,t={})=>new c(e,t,this.engine)}),this.registerComponent("switch",{name:"Switch",selector:"[data-fc-switch]",init:(e,t={})=>new r(e,t,this.engine)}),this.registerComponent("progress",{name:"Progress",selector:"[data-fc-progress]",init:(e,t={})=>new h(e,t,this.engine)}),this.registerComponent("skeleton",{name:"Skeleton",selector:"[data-fc-skeleton]",init:(e,t={})=>new l(e,t,this.engine)}),this.registerComponent("stepper",{name:"Stepper",selector:"[data-fc-stepper]",init:(e,t={})=>new d(e,t,this.engine)}),this.registerComponent("form",{name:"Form",selector:"[data-fc-form]",init:(e,t={})=>new m(e,t,this.engine)})}initComponentSystem(){this.createComponentContainer(),this.setupComponentEvents()}createComponentContainer(){if(!t.getElementById("fc-component-container")){const e=t.createElement("div");e.id="fc-component-container",e.style.display="none",t.body.appendChild(e)}}setupComponentEvents(){this.engine.on("component-init",e=>{this.engine.log(`Component "${e.name}" initialized`)}),this.engine.on("component-destroy",e=>{this.engine.log(`Component "${e.name}" destroyed`)})}setupMutationObserver(){this.observer=new MutationObserver(e=>{e.forEach(e=>{"childList"===e.type&&e.addedNodes.forEach(e=>{e.nodeType===Node.ELEMENT_NODE&&this.initComponentsInElement(e)})})}),this.observer.observe(t.body,{childList:!0,subtree:!0})}initExistingComponents(){this.initComponentsInElement(t.body)}initComponentsInElement(e){this.components.forEach((t,s)=>{(e.querySelectorAll?e.querySelectorAll(t.selector):e.matches&&e.matches(t.selector)?[e]:[]).forEach(e=>{if(!this.instances.has(e))try{const n=t.init(e,this.getComponentOptions(e));this.instances.set(e,{component:s,instance:n}),this.engine.emit("component-init",{name:s,element:e,instance:n})}catch(e){this.engine.error(`Failed to initialize component "${s}":`,e)}})})}getComponentOptions(e){const t={};return Array.from(e.attributes).forEach(e=>{if(e.name.startsWith("data-fc-")){const s=e.name.replace("data-fc-","");let n=e.value;try{n=JSON.parse(n)}catch(e){}t[s]=n}}),t}registerComponent(e,t){this.components.set(e,t),this.engine.log(`Component "${e}" registered`)}getComponent(e){return this.components.get(e)}getAllComponents(){return Array.from(this.components.entries())}getInstance(e){const t=this.instances.get(e);return t?t.instance:null}destroyComponent(e){const t=this.instances.get(e);t&&t.instance.destroy&&(t.instance.destroy(),this.instances.delete(e),this.engine.emit("component-destroy",{name:t.component,element:e}))}getAPI(){return{registerComponent:this.registerComponent.bind(this),getComponent:this.getComponent.bind(this),getAllComponents:this.getAllComponents.bind(this),getInstance:this.getInstance.bind(this),destroyComponent:this.destroyComponent.bind(this)}}}if(e.flexacore){const t=new p;e.flexacore.registerPlugin("component-manager",t),e.FCComponents=t.getAPI()}}(window,document);