UNPKG

on-codemerge

Version:

A WYSIWYG editor for on-codemerge is a user-friendly interface that allows users to edit and view their code in real time, exactly as it will appear in the final product

179 lines (178 loc) 7.46 kB
/*! on-codemerge v1.3.1 @author Pavel Kuzmin @license MIT @homepage https://s00d.github.io/on-codemerge/ @repository git+https://github.com/s00d/on-codemerge.git Copyright (c) 2026 Pavel Kuzmin - Built on 2026-07-02T13:39:17.947Z */ var w = Object.defineProperty; var v = (l, e, t) => e in l ? w(l, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : l[e] = t; var c = (l, e, t) => v(l, typeof e != "symbol" ? e + "" : e, t); import { PopupManager as f } from "../../../core/ui/PopupManager.mjs"; import u from "../../../icons/desktop.svg.mjs"; import y from "../../../icons/mobile.svg.mjs"; import C from "../../../icons/responsive.svg.mjs"; import x from "../../../icons/tablet.svg.mjs"; import { createContainer as r, createSpan as p, createButton as k } from "../../../utils/helpers.mjs"; import { SetViewportCommand as V } from "../commands/SetViewportCommand.mjs"; class I { constructor(e) { c(this, "editor"); c(this, "popup"); c(this, "viewportChangeHandlers", []); c(this, "activeViewport"); c(this, "viewports", []); var o, n; this.editor = e; const i = this.editor.getPlugins().get("responsive"); this.activeViewport = ((n = (o = i == null ? void 0 : i.viewportManager) == null ? void 0 : o.getCurrentViewport) == null ? void 0 : n.call(o)) || "responsive", this.viewports = [ { name: "mobile", icon: y, label: e.t("Mobile"), size: "320px", description: e.t("Smartphone view"), hotkey: "Ctrl+1" }, { name: "tablet", icon: x, label: e.t("Tablet"), size: "768px", description: e.t("Tablet view"), hotkey: "Ctrl+2" }, { name: "desktop", icon: u, label: e.t("Desktop"), size: "1024px", description: e.t("Standard desktop"), hotkey: "Ctrl+3" }, { name: "largeDesktop", icon: u, label: e.t("Large Desktop"), size: "1440px", description: e.t("Large desktop view"), hotkey: "Ctrl+4" }, { name: "ultraWide", icon: u, label: e.t("Ultra Wide"), size: "1920px", description: e.t("Ultra wide screen"), hotkey: "Ctrl+5" }, { name: "responsive", icon: C, label: e.t("Responsive"), size: "Fluid", description: e.t("Fluid width"), hotkey: "Ctrl+0" } ], this.popup = new f(e, { title: e.t("Responsive View"), className: "responsive-menu", closeOnClickOutside: !0, items: [ { type: "custom", id: "responsive-content", content: () => this.createContent() } ] }), this.setupHotkeys(); } createContent() { const e = r("p-6 space-y-6"), t = r("flex items-center justify-between"), i = p("text-lg font-semibold", this.editor.t("Select Viewport")), o = this.viewports.find((a) => a.name === this.activeViewport), n = p( "text-sm text-gray-500", `${o == null ? void 0 : o.label} (${o == null ? void 0 : o.size})` ); t.appendChild(i), t.appendChild(n), e.appendChild(t); const s = r("grid grid-cols-2 gap-4"); this.viewports.forEach((a) => { const h = this.createViewportButton(a); s.appendChild(h); }), e.appendChild(s); const d = this.createInfoPanel(); return e.appendChild(d), this.setupEventListeners(s), e; } createViewportButton(e) { const t = e.name === this.activeViewport, i = k("", () => { this.setActiveViewport(e.name), this.popup.hide(); }); i.className = `viewport-btn w-full p-4 border-2 rounded-lg transition-all duration-200 ${t ? "border-blue-500 bg-blue-50 shadow-md" : "border-gray-200 hover:border-blue-300 hover:shadow-sm"}`, i.dataset.viewport = e.name; const o = r("flex flex-col items-center gap-3"), n = r("relative"), s = r("text-2xl"); s.innerHTML = e.icon; const d = r( `w-16 h-10 border-2 border-gray-300 rounded ${e.name === "responsive" ? "w-20" : "w-16"}` ); d.style.background = "linear-gradient(45deg, #f0f0f0 25%, transparent 25%), linear-gradient(-45deg, #f0f0f0 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #f0f0f0 75%), linear-gradient(-45deg, transparent 75%, #f0f0f0 75%)", d.style.backgroundSize = "4px 4px", d.style.backgroundPosition = "0 0, 0 2px, 2px -2px, -2px 0px", n.appendChild(s), n.appendChild(d); const a = r("text-center"), h = p("block text-sm font-medium text-gray-900", e.label), m = p("block text-xs text-gray-500 mt-1", e.size), g = p("block text-xs text-gray-400 mt-1", e.description), b = p("block text-xs text-blue-500 mt-1 font-mono", e.hotkey); return a.appendChild(h), a.appendChild(m), a.appendChild(g), a.appendChild(b), o.appendChild(n), o.appendChild(a), i.appendChild(o), i; } createInfoPanel() { const e = r("mt-6 p-4 bg-gray-50 rounded-lg border"), t = p("block text-sm font-medium text-gray-900 mb-2", this.editor.t("Tips")), i = [ this.editor.t("• Use hotkeys for quick switching"), this.editor.t("• Responsive mode allows manual resizing"), this.editor.t("• Viewport state is saved automatically"), this.editor.t("• Tables adapt automatically to viewport size") ], o = r("space-y-1"); return i.forEach((n) => { const s = p("block text-xs text-gray-600", n); o.appendChild(s); }), e.appendChild(t), e.appendChild(o), e; } setupEventListeners(e) { e.querySelectorAll(".viewport-btn").forEach((t) => { t.addEventListener("click", () => { const i = t.dataset.viewport; this.setActiveViewport(i), this.popup.hide(); }); }), this.editor.getDOMContext().addEventListener("keydown", (t) => { var i; t.key === "Escape" && ((i = this.popup) == null || i.hide()); }); } setupHotkeys() { this.editor.getDOMContext().addEventListener("keydown", (e) => { if (e.ctrlKey && !e.shiftKey && !e.altKey) { const t = e.key, i = { 1: "mobile", 2: "tablet", 3: "desktop", 4: "largeDesktop", 5: "ultraWide", 0: "responsive" }; i[t] && (e.preventDefault(), this.setActiveViewport(i[t])); } }); } setActiveViewport(e) { this.activeViewport = e, this.notifyViewportChange(e); const t = new V(this.editor); t.setViewport(e), t.execute(), this.popup && this.editor.getDOMContext().querySelectorAll(".viewport-btn").forEach((o) => { const n = o, s = n.dataset.viewport === e; n.className = `viewport-btn w-full p-4 border-2 rounded-lg transition-all duration-200 ${s ? "border-blue-500 bg-blue-50 shadow-md" : "border-gray-200 hover:border-blue-300 hover:shadow-sm"}`; }); } show() { var i, o; const t = this.editor.getPlugins().get("responsive"); this.activeViewport = ((o = (i = t == null ? void 0 : t.viewportManager) == null ? void 0 : i.getCurrentViewport) == null ? void 0 : o.call(i)) || "responsive", this.popup.show(); } onViewportChange(e) { this.viewportChangeHandlers.push(e); } notifyViewportChange(e) { this.viewportChangeHandlers.forEach((t) => t(e)); } getActiveViewport() { return this.activeViewport; } destroy() { this.popup.destroy(), this.viewportChangeHandlers = [], this.viewports = [], this.editor = null, this.popup = null; } } export { I as ResponsiveMenu };