grapesjs-tailwind-iconify
Version:
Enhanced fork of grapesjs-tailwind with Custom Components Manager and Iconify integration
2 lines (1 loc) • 3.52 kB
JavaScript
!function(o,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(o="undefined"!=typeof globalThis?globalThis:o||self).CustomComponentManager=t()}(this,(function(){"use strict";return class{constructor(o,t={}){this.editor=o,this.options={defaultCategory:"Custom",cdnEndpoints:[],localComponents:[],jsonSources:[],...t},this.loadedComponents=new Map,this.init()}init(){this.loadAllComponents()}async loadAllComponents(){this.options.localComponents.length>0&&this.loadLocalComponents(this.options.localComponents),this.options.jsonSources.length>0&&await this.loadJSONComponents(this.options.jsonSources),this.options.cdnEndpoints.length>0&&await this.loadCDNComponents(this.options.cdnEndpoints)}loadLocalComponents(o){o.forEach((o=>{this.registerComponent(o)}))}async loadJSONComponents(o){for(const e of o)try{let o;if("string"==typeof e){const t=await fetch(e);o=await t.json()}else o=e;(Array.isArray(o)?o:[o]).forEach((o=>{this.registerComponent(o)}))}catch(t){console.error(`Failed to load JSON components from ${e}:`,t)}}async loadCDNComponents(o){for(const e of o)try{if(await this.loadScript(e),window.customTailwindComponents){window.customTailwindComponents.forEach((o=>{this.registerComponent(o)})),delete window.customTailwindComponents}}catch(t){console.error(`Failed to load CDN components from ${e}:`,t)}}loadScript(o){return new Promise(((t,e)=>{const n=document.createElement("script");n.src=o,n.onload=t,n.onerror=e,document.head.appendChild(n)}))}registerComponent(o){try{if(!this.validateComponent(o))return void console.warn("Invalid component structure:",o);o.id||(o.id=this.generateComponentId(o.label||"custom-component")),o.category||(o.category=this.options.defaultCategory),this.editor.BlockManager.add(o.id,{label:o.label||o.id,content:o.content||o.html||"",category:o.category,attributes:{class:o.class||"custom-block",title:o.description||o.label||o.id},media:o.media||o.icon||o.preview||this.generateSVGIcon(o.label)}),this.loadedComponents.set(o.id,o),console.log(`✅ Registered component: ${o.id}`)}catch(t){console.error("Failed to register component:",o,t)}}validateComponent(o){return o&&(o.content||o.html)&&(o.label||o.id)}generateComponentId(o){const t=o.toLowerCase().replace(/[^a-z0-9]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"");let e=1,n=`custom-${t}`;for(;this.loadedComponents.has(n);)n=`custom-${t}-${e}`,e++;return n}generateSVGIcon(o="□"){return`\n <svg width="100%" height="100%" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <rect x="2" y="2" width="20" height="20" rx="4" fill="#f3f4f6" stroke="#d1d5db" stroke-width="1"/>\n <text x="12" y="16" text-anchor="middle" fill="#6b7280" font-size="10" font-family="Arial, sans-serif">\n ${o.charAt(0).toUpperCase()}\n </text>\n </svg>\n `}addComponent(o){this.registerComponent(o)}addComponents(o){o.forEach((o=>{this.registerComponent(o)}))}removeComponent(o){this.editor.BlockManager.remove(o),this.loadedComponents.delete(o),console.log(`🗑️ Removed component: ${o}`)}getComponent(o){return this.loadedComponents.get(o)}getAllComponents(){return Array.from(this.loadedComponents.values())}async loadFromURL(o){try{const t=await fetch(o),e=await t.json(),n=Array.isArray(e)?e:[e];return this.addComponents(n),n.length}catch(t){throw console.error(`Failed to load components from URL ${o}:`,t),t}}exportComponents(){return JSON.stringify(this.getAllComponents(),null,2)}}}));