ranui
Version:
A framework-agnostic Web Components UI library built on native custom elements, with TypeScript types, light/dark theming, SSR and PWA support.
3 lines (2 loc) • 13.4 kB
JavaScript
const M=require("./rolldown-runtime-DGqZhkpL.cjs"),n=require("./builder-Cb6jFd2B.cjs"),o=require("./utils-D2N_KPUb.cjs");require("./icon-CJdX6ZRY.cjs");var R=":host{display:block}:host([hidden]){display:none}.ran-mermaid{position:relative;padding:var(--ran-mermaid-padding, 0)}.ran-mermaid-diagram{display:flex;justify-content:center;overflow-x:auto}.ran-mermaid-diagram svg{max-width:100%;height:auto}.ran-mermaid-toolbar{position:absolute;top:var(--ran-mermaid-toolbar-top, 8px);right:var(--ran-mermaid-toolbar-right, 8px);display:none;gap:var(--ran-mermaid-toolbar-gap, 4px);padding:var(--ran-mermaid-toolbar-padding, var(--ran-space-1, 4px));border-radius:var(--ran-radius-md, 8px);background:var(--ran-mermaid-toolbar-background, var(--ran-color-bg-elevated, #fff));box-shadow:var(--ran-mermaid-toolbar-shadow, var(--ran-shadow-menu, 0 2px 8px rgba(0, 0, 0, .12)));opacity:0;transition:opacity .15s ease;pointer-events:none}.ran-mermaid.has-controls .ran-mermaid-toolbar{display:flex}.ran-mermaid:hover .ran-mermaid-toolbar,.ran-mermaid-toolbar:focus-within{opacity:1;pointer-events:auto}.ran-mermaid-btn{display:inline-flex;align-items:center;justify-content:center;width:var(--ran-mermaid-button-size, var(--ran-size-5, 28px));height:var(--ran-mermaid-button-size, var(--ran-size-5, 28px));padding:0;border:none;border-radius:var(--ran-radius-sm, 6px);background:transparent;color:var(--ran-mermaid-button-color, var(--ran-color-text-secondary, #666));cursor:pointer}.ran-mermaid-btn:hover{background:var(--ran-mermaid-button-hover-background, var(--ran-color-bg-muted, rgba(0, 0, 0, .06)));color:var(--ran-mermaid-button-hover-color, var(--ran-color-text, #222))}.ran-mermaid-btn:focus-visible{outline:var(--ran-mermaid-button-focus-outline, 2px solid var(--ran-color-primary, #1890ff));outline-offset:var(--ran-mermaid-button-focus-outline-offset, 1px)}.ran-mermaid-menu{position:absolute;top:var(--ran-mermaid-menu-top, 44px);right:var(--ran-mermaid-toolbar-right, 8px);display:flex;flex-direction:column;min-width:132px;padding:var(--ran-mermaid-menu-padding, var(--ran-space-1, 4px));border-radius:var(--ran-radius-md, 8px);background:var(--ran-mermaid-toolbar-background, var(--ran-color-bg-elevated, #fff));box-shadow:var(--ran-mermaid-toolbar-shadow, var(--ran-shadow-menu, 0 2px 8px rgba(0, 0, 0, .12)));z-index:1}.ran-mermaid-menu-item{padding:var(--ran-mermaid-menu-item-padding-block, var(--ran-space-2, 8px)) var(--ran-mermaid-menu-item-padding-inline, var(--ran-space-3, 12px));border:none;border-radius:var(--ran-radius-sm, 6px);background:transparent;color:var(--ran-mermaid-menu-item-color, var(--ran-color-text, #222));text-align:left;font-size:var(--ran-mermaid-menu-item-font-size, var(--ran-text-label-2, 13px));font-weight:var(--ran-mermaid-menu-item-font-weight, var(--ran-text-label-weight, 500));cursor:pointer}.ran-mermaid-menu-item:hover{background:var(--ran-mermaid-button-hover-background, var(--ran-color-bg-muted, rgba(0, 0, 0, .06)))}.ran-mermaid-error{margin:0;padding:var(--ran-mermaid-error-padding, var(--ran-space-3, 12px));color:var(--ran-mermaid-error-color, #c0392b);white-space:pre-wrap;font-size:var(--ran-mermaid-error-font-size, var(--ran-text-label-2, 13px));font-weight:var(--ran-mermaid-error-font-weight, var(--ran-text-label-weight, 500))}",D=M.__exportAll({Mermaid:()=>b,default:()=>b}),A=0,b=class extends o.RanElement{_events=new o.EventManager;_shadowDom;_wrap;_diagram;_toolbar;_themeObserver;_copyResetTimer;_fullscreenClose;_downloadMenu;static get observedAttributes(){return["code","theme","copy","download","fullscreen","sheet"]}constructor(){super(),this._shadowDom=o.ensureShadowRoot(this,R);const e=n.createRef(),t=n.createRef();this._wrap=n.Div().class("ran-mermaid").part("mermaid").children(n.Div().class("ran-mermaid-diagram").ref(e).part("diagram"),n.Div().class("ran-mermaid-toolbar").ref(t).part("toolbar")).build(),this._shadowDom.appendChild(this._wrap),this._diagram=o.shadowPart(e,"diagram"),this._toolbar=o.shadowPart(t,"toolbar")}get code(){const e=o.getStringAttribute(this,"code");return e?decodeURIComponent(e):(this.textContent||"").trim()}set code(e){o.setStringAttribute(this,"code",encodeURIComponent(e))}get theme(){return o.getStringAttribute(this,"theme")||"auto"}set theme(e){o.setStringAttribute(this,"theme",e)}get sheet(){return o.getStringAttribute(this,"sheet")}set sheet(e){o.setStringAttribute(this,"sheet",e)}get copyable(){return this.hasAttribute("copy")}set copyable(e){o.setBooleanAttribute(this,"copy",e)}get downloadable(){return this.hasAttribute("download")}set downloadable(e){o.setBooleanAttribute(this,"download",e)}get fullscreenable(){return this.hasAttribute("fullscreen")}set fullscreenable(e){o.setBooleanAttribute(this,"fullscreen",e)}label(e,t){return o.getStringAttribute(this,`label-${e}`)||t}resolveTheme(){const e=this.theme;if(e==="dark")return"dark";if(e==="light")return"default";const t=document.documentElement;return t.classList.contains("dark")||t.getAttribute("data-ran-theme")==="dark"?"dark":"default"}emit(e,t){this.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0}))}handlerExternalCss=()=>{o.syncSheetAttribute(this,this._shadowDom,"sheet",null,this.sheet)};render(){const e=this.code;if(!e)return;const t=`ran-mermaid-${A++}`;Promise.resolve().then(()=>require("./mermaid.core-DKMReV6x.cjs")).then(async({default:a})=>{a.initialize({startOnLoad:!1,securityLevel:"loose",theme:this.resolveTheme(),fontFamily:"inherit"});try{const{svg:r}=await a.render(t,e);this._diagram.innerHTML=r,this.buildToolbar(),this.emit("render",{ok:!0})}catch(r){document.getElementById(`d${t}`)?.remove(),document.getElementById(t)?.remove(),this.showError(String(r?.message||r))}}).catch(a=>this.showError(a.message))}showError(e){this._diagram.innerHTML="";const t=n.View("pre").class("ran-mermaid-error").part("error").build();t.textContent=e,this._diagram.appendChild(t),this._toolbar.innerHTML="",this._wrap.classList.remove("has-controls"),this.emit("error",{message:e})}iconButton(e,t,a){const r=n.View("button").class("ran-mermaid-btn").part("button").attr("type","button").attr("aria-label",t).attr("title",t).children(n.View("r-icon").attr("name",e).attr("size","16").attr("color","currentColor")).build();return this._events.on(r,"click",a),r}buildToolbar(){this._toolbar.innerHTML="";const e=[];this.copyable&&e.push(this.iconButton("copy",this.label("copy","Copy source"),this.copySource)),this.downloadable&&e.push(this.iconButton("download",this.label("download","Download"),this.onDownload)),this.fullscreenable&&e.push(this.iconButton("fullscreen",this.label("fullscreen","Fullscreen"),this.openFullscreen)),e.forEach(t=>this._toolbar.appendChild(t)),this._wrap.classList.toggle("has-controls",e.length>0)}copySource=()=>{const e=this.code;!e||!navigator.clipboard||navigator.clipboard.writeText(e).then(()=>{this.emit("copied",{kind:"source"});const t=this._toolbar.querySelector('r-icon[name="copy"]');t&&(t.setAttribute("name","check"),window.clearTimeout(this._copyResetTimer),this._copyResetTimer=window.setTimeout(()=>t.setAttribute("name","copy"),1200))})};currentSvg(){return this._diagram.querySelector("svg")}downloadFormats(){const e=o.getStringAttribute(this,"download").trim();return(e?e.split(/\s+/):["svg","png","source"]).filter(t=>t==="svg"||t==="png"||t==="source")}onDownload=()=>{const e=this.downloadFormats();e.length<=1?this.triggerDownload(e[0]||"svg"):this.toggleDownloadMenu()};triggerDownload(e){e==="png"?this.downloadPng():e==="source"?this.downloadSource():this.downloadRawSvg()}saveBlob(e,t){const a=URL.createObjectURL(e),r=document.createElement("a");r.href=a,r.download=t,r.click(),URL.revokeObjectURL(a)}downloadRawSvg(){const e=this.currentSvg();if(!e)return;const t=new XMLSerializer().serializeToString(e);this.saveBlob(new Blob([`<?xml version="1.0" encoding="UTF-8"?>
${t}`],{type:"image/svg+xml;charset=utf-8"}),"diagram.svg"),this.emit("download",{format:"svg"})}downloadSource(){const e=this.code;e&&(this.saveBlob(new Blob([e],{type:"text/plain;charset=utf-8"}),"diagram.mmd"),this.emit("download",{format:"source"}))}downloadPng(){const e=this.currentSvg();if(!e)return;const t=e.getBoundingClientRect(),a=Math.max(1,Math.round((t.width||800)*2)),r=Math.max(1,Math.round((t.height||600)*2)),m=new XMLSerializer().serializeToString(e),s=URL.createObjectURL(new Blob([m],{type:"image/svg+xml;charset=utf-8"})),l=new Image;l.onload=()=>{try{const d=document.createElement("canvas");d.width=a,d.height=r;const c=d.getContext("2d");c&&(c.fillStyle=this.resolveTheme()==="dark"?"#1a1a1a":"#ffffff",c.fillRect(0,0,a,r),c.drawImage(l,0,0,a,r)),d.toBlob(h=>{URL.revokeObjectURL(s),h?(this.saveBlob(h,"diagram.png"),this.emit("download",{format:"png"})):this.emit("error",{message:"PNG export failed"})},"image/png")}catch{URL.revokeObjectURL(s),this.emit("error",{message:"PNG export failed (diagram may use HTML labels)"})}},l.onerror=()=>{URL.revokeObjectURL(s),this.emit("error",{message:"PNG export failed"})},l.src=s}toggleDownloadMenu(){if(this._downloadMenu){this.closeDownloadMenu();return}const e=n.Div().class("ran-mermaid-menu").part("menu").build(),t={svg:this.label("download-svg","SVG"),png:this.label("download-png","PNG"),source:this.label("download-source","Source (.mmd)")};this.downloadFormats().forEach(a=>{const r=n.View("button").class("ran-mermaid-menu-item").attr("type","button").build();r.textContent=t[a]||a,this._events.on(r,"click",()=>{this.triggerDownload(a),this.closeDownloadMenu()}),e.appendChild(r)}),this._wrap.appendChild(e),this._downloadMenu=e}closeDownloadMenu=()=>{this._downloadMenu?.remove(),this._downloadMenu=void 0};openFullscreen=()=>{const e=this.currentSvg();e&&Promise.resolve().then(()=>require("./modal-CIYBc0MH.cjs")).then(t=>t.modal_exports).then(()=>{const t=document.createElement("r-modal");t.setAttribute("title",this.label("diagram","Diagram")),t.setAttribute("hide-header",""),t.setAttribute("closable",""),t.setAttribute("maskClosable","true"),t.setAttribute("closeOnEsc","true"),t.style.setProperty("--ran-modal-dialog-width","min(1280px, 94vw)"),t.style.setProperty("--ran-modal-dialog-max-width","94vw");const a=n.Div().build();a.style.cssText="position:relative;width:100%;height:82vh;overflow:hidden;";const r=n.Div().build();r.style.cssText="width:100%;height:100%;display:flex;align-items:center;justify-content:center;cursor:grab;touch-action:none;";const m=n.Div().build();m.style.cssText="transform-origin:center center;transition:transform .05s linear;",m.appendChild(e.cloneNode(!0)),r.appendChild(m),a.appendChild(r);let s=1,l=0,d=0,c=!1,h=0,x=0;const g=()=>{m.style.transform=`translate(${l}px, ${d}px) scale(${s})`},v=i=>{s=Math.min(8,Math.max(.4,s*i)),g()},L=()=>{s=1,l=0,d=0,g()},y=new AbortController,u=y.signal;r.addEventListener("wheel",i=>{i.preventDefault(),v(i.deltaY<0?1.1:1/1.1)},{signal:u,passive:!1}),r.addEventListener("pointerdown",i=>{c=!0,h=i.clientX-l,x=i.clientY-d,r.style.cursor="grabbing",r.setPointerCapture?.(i.pointerId)},{signal:u}),r.addEventListener("pointermove",i=>{c&&(l=i.clientX-h,d=i.clientY-x,g())},{signal:u});const _=()=>{c=!1,r.style.cursor="grab"};r.addEventListener("pointerup",_,{signal:u}),r.addEventListener("pointercancel",_,{signal:u});const p=n.Div().build();p.style.cssText="position:absolute;bottom:12px;left:50%;transform:translateX(-50%);display:flex;gap:4px;padding:4px;border-radius:8px;background:var(--ran-color-bg-elevated,#fff);box-shadow:0 2px 8px rgba(0,0,0,.15);";const f=(i,S,k)=>{const w=n.View("button").attr("type","button").attr("aria-label",S).attr("title",S).children(n.View("r-icon").attr("name",i).attr("size","18").attr("color","currentColor")).build();return w.style.cssText="display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;border-radius:6px;background:transparent;color:var(--ran-color-text-secondary,#666);cursor:pointer;",w.addEventListener("click",k,{signal:u}),w};p.appendChild(f("zoom-out",this.label("zoom-out","Zoom out"),()=>v(1/1.2))),p.appendChild(f("refresh",this.label("reset","Reset"),L)),p.appendChild(f("zoom-in",this.label("zoom-in","Zoom in"),()=>v(1.2))),a.appendChild(p),t.appendChild(a),document.body.appendChild(t),t.setAttribute("open",""),this.emit("fullscreenchange",{open:!0});const C=()=>{y.abort(),t.remove(),this._fullscreenClose=void 0,this.emit("fullscreenchange",{open:!1})};t.addEventListener("afterclose",C,{once:!0}),this._fullscreenClose=C})};connectedCallback(){this.handlerExternalCss(),this.render(),this._events.on(this._wrap,"mouseleave",this.closeDownloadMenu),this.theme==="auto"&&!this._themeObserver&&(this._themeObserver=new MutationObserver(()=>this.render()),this._themeObserver.observe(document.documentElement,{attributes:!0,attributeFilter:["class","data-ran-theme"]}))}disconnectedCallback(){this._events.abort(),this._themeObserver?.disconnect(),this._themeObserver=void 0,window.clearTimeout(this._copyResetTimer),this.closeDownloadMenu(),this._fullscreenClose?.()}attributeChangedCallback(e,t,a){t!==a&&(e==="code"||e==="theme"?this.render():e==="copy"||e==="download"||e==="fullscreen"?this.buildToolbar():e==="sheet"&&this.handlerExternalCss())}};o.defineSSR("r-mermaid",b);Object.defineProperty(exports,"Mermaid",{enumerable:!0,get:function(){return b}});Object.defineProperty(exports,"mermaid_exports",{enumerable:!0,get:function(){return D}});