// src/editor.js import { $ as $2, isFunc as isFunc2, h as h2 } from "sigpro"; // src/sigpro-ui.js import { $, watch, h, mount, when, each, isFunc } from "sigpro"; var val = (val2) => typeof val2 === "function" ? val2() : val2; var cls = (...classes) => classes.filter(Boolean).join(" ").trim(); var c1 = (tag, cls2) => (p) => h(tag, { ...p, class: `${cls2} ${p?.class || ""}`.trim() }); var c2 = (tag, cls2) => (p, c) => h(tag, { ...p, class: `${cls2} ${p?.class || ""}`.trim() }, c); var ct = (tag, cls2, type) => (p) => h(tag, { type, ...p, class: `${cls2} ${p?.class || ""}`.trim() }); var Alert = c2("div", "alert"); var AvatarGroup = c2("div", "avatar-group -space-x-6"); var Badge = c2("span", "badge"); var Breadcrumbs = c2("div", "breadcrumbs"); var Button = c2("button", "btn"); var Card = c2("div", "card"); var CardTitle = c2("div", "card-title"); var CardBody = c2("div", "card-body"); var CardActions = c2("div", "card-actions"); var Carousel = c2("div", "carousel"); var CarouselItem = c2("div", "carousel-item"); var Chat = c2("div", "chat"); var ChatBubble = c2("div", "chat-bubble"); var ChatFooter = c2("div", "chat-footer"); var ChatHeader = c2("div", "chat-header"); var Checkbox = ct("input", "checkbox", "checkbox"); var Drawer = c2("div", "drawer"); var DrawerContent = c2("div", "drawer-content"); var DrawerSide = c2("div", "drawer-side"); var Divider = c1("div", "divider"); var Dropdown = c2("div", "dropdown"); var Kbd = c2("kbd", "kbd"); var List = c2("ul", "list"); var Loading = c2("span", "loading loading-spinner"); var Navbar = c2("div", "navbar"); var Progress = c1("progress", "progress"); var Radio = ct("input", "radio", "radio"); var Range = ct("input", "range", "range"); var Rating = c2("div", "rating"); var Skeleton = c1("div", "skeleton"); var SkeletonText = c1("span", "skeleton skeleton-text"); var Stack = c2("div", "stack"); var Stats = c2("div", "stats shadow"); var Steps = c2("ul", "steps"); var Swap = c2("label", "swap"); var SwapOn = c2("div", "swap-on"); var SwapOff = c2("div", "swap-off"); var Table = c2("table", "table"); var Textarea = c1("textarea", "textarea"); var Timeline = c2("ul", "timeline"); var Toggle = ct("input", "toggle", "checkbox"); // src/editor.js var Editor = (p) => { const { value, class: extraClass } = p; let editorRef = null; let savedRange = null; const isSource = $2(false); const source = $2(""); const count = $2(0); const refreshTick = $2(0); const showEmojis = $2(false); const emojis = ["\uD83D\uDE00", "\uD83D\uDE0A", "\uD83D\uDE09", "\uD83E\uDDD0", "\uD83D\uDE2E", "\uD83E\uDD14", "\uD83D\uDE05", "\uD83D\uDE02", "\uD83D\uDE0D", "\uD83D\uDE18", "\uD83E\uDD70", "\uD83D\uDC4D", "\uD83D\uDC4E", "\uD83D\uDC4C", "\uD83E\uDD1D", "\uD83E\uDD1E", "\uD83D\uDC4B", "\uD83D\uDC4F", "\uD83D\uDE4C", "\uD83D\uDE4F", "\uD83D\uDCAA", "☝️", "\uD83D\uDC47", "\uD83D\uDC48", "\uD83D\uDC49", "\uD83D\uDD95", "✅", "⚠️", "\uD83D\uDE80", "\uD83D\uDCE2", "✉️", "❤️"]; const saveSelection = () => { const sel = window.getSelection(); if (sel.getRangeAt && sel.rangeCount) savedRange = sel.getRangeAt(0); }; const restoreSelection = () => { if (savedRange) { const sel = window.getSelection(); sel.removeAllRanges(); sel.addRange(savedRange); } }; const triggerRefresh = () => { refreshTick(refreshTick() + 1); if (editorRef) count(editorRef.innerText.length); }; const notify = () => { if (!editorRef) return; const html = editorRef.innerHTML; if (isFunc2(value)) value(html); else p.onchange?.(html); triggerRefresh(); }; const exec = (cmd, val2 = null) => { if (!editorRef) return; editorRef.focus(); if (savedRange) restoreSelection(); document.execCommand(cmd, false, val2); savedRange = null; notify(); }; const openLightbox = (src) => { const overlay = document.createElement("div"); overlay.style = `position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.9);z-index:9999;display:flex;align-items:center;justify-content:center;cursor:zoom-out;`; const img = document.createElement("img"); img.src = src; img.style = `max-width:95%;max-height:95%;box-shadow:0 0 30px rgba(0,0,0,0.5);border-radius:4px;`; overlay.onclick = () => document.body.removeChild(overlay); overlay.appendChild(img); document.body.appendChild(overlay); }; const handleUpload = (file) => { if (!file) return; const reader = new FileReader; reader.onload = (re) => { if (file.type.startsWith("image/")) { const imgHtml = `
`; exec("insertHTML", imgHtml); } else { const linkHtml = `${file.name} `; exec("insertHTML", linkHtml); } }; reader.readAsDataURL(file); }; const queryState = (cmd, val2 = null) => { refreshTick(); if (!editorRef || isSource()) return false; try { if (cmd === "formatBlock") { let node = window.getSelection().getRangeAt(0).commonAncestorContainer; while (node && node !== editorRef) { if (node.nodeType === 1 && node.tagName === val2) return true; node = node.parentNode; } return false; } return document.queryCommandState(cmd); } catch (e) { return false; } }; const toolbar = h2("div", { class: "flex flex-wrap items-center gap-1 p-2 border-b border-base-300 bg-base-200 sticky top-0 z-20" }, [ h2("div", { class: "flex flex-wrap gap-1 flex-1 items-center" }, [ h2("button", { type: "button", class: () => `btn btn-ghost btn-xs ${queryState("bold") ? "btn-active bg-primary/20" : ""}`, onclick: () => exec("bold") }, h2("span", { class: "icon-[lucide--bold]" })), h2("button", { type: "button", class: () => `btn btn-ghost btn-xs ${queryState("italic") ? "btn-active bg-primary/20" : ""}`, onclick: () => exec("italic") }, h2("span", { class: "icon-[lucide--italic]" })), h2("button", { type: "button", class: () => `btn btn-ghost btn-xs ${queryState("underline") ? "btn-active bg-primary/20" : ""}`, onclick: () => exec("underline") }, h2("span", { class: "icon-[lucide--underline]" })), h2("input", { type: "color", class: "w-5 h-5 p-0 border-0 bg-transparent cursor-pointer", oninput: (e) => exec("foreColor", e.target.value) }), h2("span", { class: "w-px h-5 bg-base-300 mx-1" }), h2("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => exec("justifyLeft") }, h2("span", { class: "icon-[lucide--align-left]" })), h2("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => exec("justifyCenter") }, h2("span", { class: "icon-[lucide--align-center]" })), h2("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => exec("justifyRight") }, h2("span", { class: "icon-[lucide--align-right]" })), h2("span", { class: "w-px h-5 bg-base-300 mx-1" }), h2("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => exec("insertUnorderedList") }, h2("span", { class: "icon-[lucide--list]" })), h2("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => exec("insertOrderedList") }, h2("span", { class: "icon-[lucide--list-ordered]" })), h2("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => exec("outdent") }, h2("span", { class: "icon-[lucide--indent-decrease]" })), h2("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => exec("indent") }, h2("span", { class: "icon-[lucide--indent-increase]" })), h2("button", { type: "button", class: () => `btn btn-ghost btn-xs ${queryState("formatBlock", "BLOCKQUOTE") ? "btn-active" : ""}`, onclick: () => exec("formatBlock", queryState("formatBlock", "BLOCKQUOTE") ? "P" : "BLOCKQUOTE") }, h2("span", { class: "icon-[lucide--quote]" })), h2("span", { class: "w-px h-5 bg-base-300 mx-1" }), h2("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => { const url = window.prompt("URL:"); if (url) exec("createLink", url); } }, h2("span", { class: "icon-[lucide--link]" })), h2("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => { const input2 = document.createElement("input"); input2.type = "file"; input2.onchange = (e) => handleUpload(e.target.files[0]); input2.click(); } }, h2("span", { class: "icon-[lucide--paperclip]" })), h2("div", { class: "relative" }, [ h2("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: (e) => { e.stopPropagation(); saveSelection(); showEmojis(!showEmojis()); } }, h2("span", { class: "icon-[lucide--smile]" })), h2("div", { class: "absolute top-full left-0 mt-1 p-2 bg-base-100 border border-base-300 shadow-xl rounded-box w-52 z-50 flex flex-wrap gap-1", style: () => showEmojis() ? "display:flex" : "display:none" }, emojis.map((emo) => h2("span", { class: "cursor-pointer hover:bg-base-200 p-1 rounded text-lg", onclick: (e) => { e.stopPropagation(); exec("insertText", emo); showEmojis(false); } }, emo))) ]), h2("span", { class: "w-px h-5 bg-base-300 mx-1" }), h2("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => exec("undo") }, h2("span", { class: "icon-[lucide--undo-2]" })), h2("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => exec("redo") }, h2("span", { class: "icon-[lucide--redo-2]" })) ]), h2("button", { type: "button", class: () => `btn btn-ghost btn-xs ${isSource() ? "btn-active" : ""}`, onclick: () => { if (!isSource()) source(editorRef?.innerHTML || ""); else if (editorRef) { editorRef.innerHTML = source(); notify(); } isSource(!isSource()); } }, h2("span", { class: "icon-[lucide--code-2]" })) ]); if (typeof document !== "undefined" && !document.getElementById("editor-styles")) { const style = document.createElement("style"); style.id = "editor-styles"; style.textContent = ` [contenteditable="true"] div, [contenteditable="true"] p { margin: 0; padding: 0; } `; document.head.appendChild(style); } return h2("div", { class: cls("border border-base-300 rounded-box bg-base-100 overflow-hidden shadow-sm flex flex-col", extraClass) }, [ toolbar, h2("div", { class: "relative flex-1 flex flex-col", onclick: () => showEmojis(false) }, [ h2("div", { ref: (el) => { if (!editorRef && el) { editorRef = el; el.innerHTML = val(value) || ""; document.execCommand("defaultParagraphSeparator", false, "br"); el.addEventListener("click", (e) => { const container = e.target.closest(".resizable-img-container"); if (container) { const img = container.querySelector("img"); if (img) openLightbox(img.src); } }); } }, style: () => `min-height:22rem;${isSource() ? "display:none" : ""}`, class: "p-4 outline-none text-base-content leading-relaxed [&>div]:m-0 [&>p]:m-0 [&>div]:min-h-[1em] [&_.resizable-img-container]:hover:border-primary [&_blockquote]:border-l-4 [&_blockquote]:border-base-300 [&_blockquote]:pl-4 [&_blockquote]:italic [&_ul]:list-disc [&_ul]:pl-8 [&_ol]:list-decimal [&_ol]:pl-8", contenteditable: "true", oninput: notify, onkeydown: (e) => { if (e.key === "Tab") { e.preventDefault(); exec("indent"); } }, onkeyup: () => { triggerRefresh(); saveSelection(); }, onclick: (e) => { triggerRefresh(); saveSelection(); e.stopPropagation(); }, onmouseup: () => { notify(); saveSelection(); }, onpaste: (e) => { e.preventDefault(); const text = e.clipboardData.getData("text/plain"); exec("insertText", text); }, ondragover: (e) => e.preventDefault(), ondrop: (e) => { e.preventDefault(); handleUpload(e.dataTransfer.files[0]); } }), h2("textarea", { class: "w-full flex-1 min-h-[22rem] p-4 outline-none font-mono text-sm bg-base-200 border-0", style: () => isSource() ? "" : "display:none", value: source, oninput: (e) => { source(e.target.value); if (editorRef) editorRef.innerHTML = e.target.value; p.onchange?.(e.target.value); } }) ]), h2("div", { class: "px-3 py-1 border-t border-base-300 bg-base-100/50 text-[10px] text-right text-base-content/60 italic" }, [ h2("span", () => `${count()}`) ]) ]); }; export { Editor };