@mjml-agent-editor/editor 0.4.1 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/editor/EmailEditor.tsx","../src/lib/save-baseline.ts","../src/lib/save-queue.ts","../src/lib/turn-follower.ts","../src/lib/shortcuts.ts","../src/components/ui/switch.tsx","../src/components/editor/ImagePicker.tsx","../src/components/editor/inspector/Inspector.tsx","../src/components/editor/ColorField.tsx","../src/components/editor/inspector/controls.tsx","../src/components/editor/inspector/values.ts","../src/components/editor/mjml-attributes.ts","../src/components/editor/ImageField.tsx","../src/components/editor/inspector/schema.ts","../src/components/editor/layers.ts","../src/components/editor/inspector/StructureSection.tsx","../src/components/editor/inspector/structure.ts","../src/components/editor/inspector/write.ts","../src/components/editor/blocks.ts","../src/components/editor/ids.ts","../src/components/editor/insert-block.ts","../src/components/editor/builtin-blocks.ts","../src/components/editor/table-type.ts","../src/components/editor/plugin-types.ts"],"sourcesContent":["\"use client\";\n\nimport grapesjs, { Component, Editor } from \"grapesjs\";\nimport GjsEditor, { Canvas, useEditorMaybe } from \"@grapesjs/react\";\nimport grapesjsMJML from \"grapesjs-mjml\";\nimport { useEffect, useRef, useState } from \"react\";\n\nimport { listSections, STARTER_MJML } from \"@mjml-agent-editor/core\";\nimport { useDocumentStore, useLabels, type CommentTarget, type EditorLabels } from \"../../index.js\";\nimport { refusal, saveToastId } from \"../../lib/refusal.js\";\nimport { createSaveBaseline } from \"../../lib/save-baseline.js\";\nimport { createSaveQueue } from \"../../lib/save-queue.js\";\nimport { createTurnFollower } from \"../../lib/turn-follower.js\";\nimport { opensBlockSearch } from \"../../lib/shortcuts.js\";\nimport { useAgentTurn } from \"../../stores.js\";\nimport { cn } from \"../../lib/utils\";\nimport { toast } from \"sonner\";\nimport { ChevronRight, Mail, MousePointerClick } from \"lucide-react\";\n\nimport { Button } from \"../ui/button\";\nimport { Spinner } from \"../ui/spinner\";\nimport { Switch } from \"../ui/switch\";\nimport { Input } from \"../ui/input\";\nimport { Search } from \"lucide-react\";\nimport CanvasComments from \"../comments/CanvasComments.js\";\nimport ImagePicker from \"./ImagePicker.js\";\nimport Inspector from \"./inspector/Inspector.js\";\nimport { registerBlocks, type SectionBlock } from \"./blocks.js\";\nimport { BUILTIN_BLOCKS, builtinBlock, CANVAS_CSS } from \"./builtin-blocks.js\";\nimport { addsBlock, insertBlock } from \"./insert-block.js\";\nimport { addIdClass, freshenCopiedIds, sectionIdOf } from \"./ids.js\";\nimport { badgeLabel, setupLayerNames } from \"./layers.js\";\nimport { fixPluginTypes } from \"./plugin-types.js\";\nimport { illegalAttributes, sourceForEditor } from \"./mjml-attributes.js\";\n\nexport type SaveStatus = \"idle\" | \"saving\" | \"saved\" | \"error\";\n\n/** Snapshot of editor state pushed to the header (device, undo, save, zoom, width). */\nexport type EditorState = {\n device: string;\n canUndo: boolean;\n canRedo: boolean;\n saveStatus: SaveStatus;\n zoom: number;\n contentWidth: string;\n /** True during an agent turn, until its result is loaded. */\n readOnly: boolean;\n};\n\nexport type EditorApi = {\n /** Current MJML source from the editor. */\n getMjml: () => string;\n /** Compiled email HTML (via grapesjs-mjml's mjml-get-code). */\n getCompiledHtml: () => string;\n /** Immediately saves the editor state to the DB. */\n flushSave: () => Promise<void>;\n /** Reloads the document from the DB (after agent changes). */\n reloadFromDb: () => Promise<void>;\n /** Highlights a section in the canvas while the agent edits it. */\n highlightSection: (sectionId: string, on: boolean) => void;\n /** Device manager control (used by the top header). */\n getDevices: () => { id: string; name: string }[];\n setDevice: (name: string) => void;\n undo: () => void;\n redo: () => void;\n /** Canvas zoom (percentage). */\n setZoom: (z: number) => void;\n /** Email body width (mj-body width attribute, e.g. \"600px\"). */\n setContentWidth: (w: string) => void;\n /** Subscribe to editor state changes (device/undo/save/zoom/width). Returns unsubscribe. */\n onEditorState: (cb: (s: EditorState) => void) => () => void;\n};\n\ntype Props = {\n docId: string;\n onReady: (api: EditorApi) => void;\n /** Bump to force the canvas comment layer to refetch (after agent turns). */\n commentsRefresh: number;\n /** Reports the number of open comments (for the header indicator). */\n onOpenCountChange: (n: number) => void;\n /**\n * Sections offered after the built-in blocks, read once when the editor starts. One that\n * `blockProblems` refuses is left out and reported in the console.\n */\n blocks?: readonly SectionBlock[];\n};\n\n// Element types that can receive a comment (besides a section).\nconst TYPE_LABEL: Record<string, string> = {\n \"mj-text\": \"Text\",\n \"mj-button\": \"Button\",\n \"mj-image\": \"Image\",\n \"mj-column\": \"Column\",\n};\n\nfunction tagOf(c: Component): string {\n return String(c.get(\"tagName\") || c.get(\"type\") || \"\");\n}\n\n// \"Sparkles\" icon (lucide Sparkles) used as a label in the GrapesJS toolbar.\nconst SPARKLES_SVG =\n '<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z\"/><path d=\"M20 3v4\"/><path d=\"M22 5h-4\"/><path d=\"M4 17v2\"/><path d=\"M5 18H3\"/></svg>';\n\n// \"Image up\" icon (lucide ImageUp), the toolbar button that opens the image picker.\nconst IMAGE_SVG =\n '<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10.3 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v10l-3.1-3.1a2 2 0 0 0-2.814.014L6 21\"/><path d=\"m14 19.5 3-3 3 3\"/><path d=\"M17 22v-5.5\"/><circle cx=\"9\" cy=\"9\" r=\"2\"/></svg>';\n\n// \"Layout template\" icon (lucide LayoutTemplate), the tile of a host's section without its own.\nconst SECTION_SVG =\n '<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect width=\"18\" height=\"7\" x=\"3\" y=\"3\" rx=\"1\"/><rect width=\"9\" height=\"7\" x=\"3\" y=\"14\" rx=\"1\"/><rect width=\"5\" height=\"7\" x=\"16\" y=\"14\" rx=\"1\"/></svg>';\n\nfunction isSection(c: Component): boolean {\n return tagOf(c) === \"mj-section\";\n}\n\nfunction isCommentable(c: Component): boolean {\n const t = tagOf(c);\n return t === \"mj-section\" || t in TYPE_LABEL;\n}\n\nfunction closestSection(c: Component | undefined): Component | null {\n let cur: Component | undefined = c;\n while (cur) {\n if (isSection(cur)) return cur;\n cur = cur.parent() ?? undefined;\n }\n return null;\n}\n\nfunction crumbName(c: Component, labels: EditorLabels): string {\n const t = tagOf(c);\n return labels.elementNames[t] ?? t.replace(/^mj-/, \"\");\n}\n\nfunction objectLabel(c: Component): string {\n const base = TYPE_LABEL[tagOf(c)] ?? tagOf(c);\n const text = String((c.getEl?.() as HTMLElement | undefined)?.textContent ?? \"\")\n .replace(/\\s+/g, \" \")\n .trim()\n .slice(0, 30);\n return text ? `${base}: “${text}”` : base;\n}\n\nconst RTE_FONTS = [\n \"Arial\",\n \"Helvetica\",\n \"Georgia\",\n \"Times New Roman\",\n \"Verdana\",\n \"Tahoma\",\n \"Trebuchet MS\",\n \"Courier New\",\n];\nconst RTE_SIZES = [11, 12, 13, 14, 16, 18, 20, 24, 28, 32, 40];\n\n// Wraps the current selection (in the canvas document) in a <span> with inline style.\nfunction wrapSelectionStyle(el: HTMLElement | undefined, style: Partial<CSSStyleDeclaration>) {\n const doc = el?.ownerDocument;\n const sel = doc?.getSelection?.();\n if (!doc || !sel || sel.rangeCount === 0 || sel.isCollapsed) return;\n const range = sel.getRangeAt(0);\n const span = doc.createElement(\"span\");\n Object.assign(span.style, style);\n try {\n span.appendChild(range.extractContents());\n range.insertNode(span);\n sel.removeAllRanges();\n const nr = doc.createRange();\n nr.selectNodeContents(span);\n sel.addRange(nr);\n } catch {\n /* ignore */\n }\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n// Extends the default GrapesJS RTE (mjml-compatible) with font/size/colors.\nfunction setupRichText(editor: Editor, labels: EditorLabels) {\n const rte = editor.RichTextEditor as any;\n if (!rte || rte.__customActions) return;\n rte.__customActions = true;\n const val = (action: any, sel: string) =>\n (action.btn?.querySelector(sel) as HTMLInputElement | HTMLSelectElement | null)?.value ?? \"\";\n\n rte.add(\"fontName\", {\n icon: `<select class=\"gjs-rte-select\" title=\"${labels.rteFont}\"><option value=\"\">${labels.rteFont}</option>${RTE_FONTS.map(\n (f) => `<option value=\"${f}\">${f}</option>`,\n ).join(\"\")}</select>`,\n event: \"change\",\n result: (r: any, action: any) => {\n const v = val(action, \"select\");\n if (v) r.exec(\"fontName\", v);\n },\n });\n\n rte.add(\"fontSize\", {\n icon: `<select class=\"gjs-rte-select\" title=\"${labels.rteSize}\"><option value=\"\">${labels.rteSize}</option>${RTE_SIZES.map(\n (s) => `<option value=\"${s}px\">${s}</option>`,\n ).join(\"\")}</select>`,\n event: \"change\",\n result: (r: any, action: any) => {\n const v = val(action, \"select\");\n if (v) wrapSelectionStyle(r.el, { fontSize: v });\n },\n });\n\n rte.add(\"forecolor\", {\n icon: `<input type=\"color\" class=\"gjs-rte-color\" title=\"${labels.rteTextColor}\" value=\"#000000\">`,\n event: \"change\",\n result: (r: any, action: any) => r.exec(\"foreColor\", val(action, \"input\")),\n });\n\n rte.add(\"hilitecolor\", {\n icon: `<input type=\"color\" class=\"gjs-rte-color\" title=\"${labels.rteBackgroundColor}\" value=\"#ffff00\">`,\n event: \"change\",\n result: (r: any, action: any) => r.exec(\"hiliteColor\", val(action, \"input\")),\n });\n}\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\nexport default function EmailEditor({\n docId,\n onReady,\n commentsRefresh,\n onOpenCountChange,\n blocks = [],\n}: Props) {\n // Injected by the host rather than imported, so the editor carries no database.\n const documents = useDocumentStore();\n const labels = useLabels();\n // Refs instead of state — GrapesJS lives outside React's lifecycle.\n const loadingRef = useRef(false);\n const saveStatusRef = useRef<SaveStatus>(\"idle\");\n const stateListeners = useRef(new Set<(s: EditorState) => void>());\n const [loading, setLoading] = useState(true);\n const [sidebarView, setSidebarView] = useState<SidebarView>(\"blocks\");\n const blockSearchRef = useRef<HTMLInputElement>(null);\n // Bound to the editor and its canvas, not the host page, whose own keys a host keeps.\n const onBlockSearchKey = (e: KeyboardEvent) => {\n if (readOnlyRef.current || !opensBlockSearch(e)) return;\n e.preventDefault();\n setSidebarView(\"blocks\");\n // The panel is hidden until the view switches, and a hidden input cannot take focus.\n requestAnimationFrame(() => blockSearchRef.current?.focus());\n };\n // Comment being composed (sparkles button) — opens the canvas popover.\n const [composeTarget, setComposeTarget] = useState<CommentTarget | null>(null);\n // Where the current selection came from — canvas click opens Settings,\n // selecting from the Layers tree does not (keeps you on Layers).\n const selectionSource = useRef<\"canvas\" | \"layers\" | \"other\">(\"other\");\n // Breadcrumb of the selected component's ancestry (Section › Column › …).\n const editorRef = useRef<Editor | null>(null);\n // Read only from a turn's start until the document it left is loaded, not just until it\n // ends: an edit made before that final reload would be replaced by it.\n const { running: turnRunning, locked: readOnly, setLocked } = useAgentTurn();\n const readOnlyRef = useRef(false);\n const applyReadOnly = useRef<(on: boolean) => Promise<void>>(async () => {});\n const [turn] = useState(createTurnFollower);\n useEffect(() => turn.turn(turnRunning), [turn, turnRunning]);\n useEffect(() => {\n turn.mount();\n return () => {\n turn.unmount();\n setLocked(false);\n };\n }, [turn, setLocked]);\n const [crumbs, setCrumbs] = useState<Component[]>([]);\n // The open picker: GrapesJS hands over how to apply a choice to the image being edited.\n const [picker, setPicker] = useState<{ current?: string; select: (url: string) => void } | null>(\n null,\n );\n\n const onEditor = async (editor: Editor) => {\n editorRef.current = editor;\n\n // Build the breadcrumb chain from a component up to (but excluding) mj-body.\n const buildCrumbs = (c: Component | undefined) => {\n const chain: Component[] = [];\n let cur: Component | undefined = c;\n while (cur) {\n const t = tagOf(cur);\n if (!t || t === \"mj-body\" || t === \"wrapper\" || t === \"Wrapper\") break;\n chain.unshift(cur);\n cur = cur.parent() ?? undefined;\n }\n setCrumbs(chain);\n };\n\n // GrapesJS find() by MJML tag is unreliable — walk the tree instead.\n const findByTag = (tag: string): Component | undefined => {\n let found: Component | undefined;\n editor.getWrapper()?.onAll((c) => {\n if (!found && (c.get(\"tagName\") === tag || c.get(\"type\") === tag)) found = c;\n });\n return found;\n };\n const bodyWidth = (): string => {\n const body = findByTag(\"mj-body\");\n return String((body?.getAttributes?.() as Record<string, unknown>)?.width ?? \"600px\");\n };\n const snapshot = (): EditorState => ({\n device: editor.getDevice(),\n canUndo: !readOnlyRef.current && editor.UndoManager.hasUndo(),\n canRedo: !readOnlyRef.current && editor.UndoManager.hasRedo(),\n saveStatus: saveStatusRef.current,\n zoom: Math.round((editor.Canvas.getZoom?.() as number | undefined) ?? 100),\n contentWidth: bodyWidth(),\n readOnly: readOnlyRef.current,\n });\n const notifyState = () => {\n const s = snapshot();\n stateListeners.current.forEach((l) => l(s));\n };\n const setSave = (s: SaveStatus) => {\n saveStatusRef.current = s;\n notifyState();\n };\n\n // Comment target for a component: its section + (if it's not the section\n // itself) the specific element. Assigns stable IDs (sec-/obj-) when needed.\n const targetOf = (c: Component | undefined): CommentTarget | null => {\n const section = closestSection(c);\n if (!section || !c) return null;\n const sectionId = addIdClass(section, \"sec\");\n if (isSection(c)) {\n return { sectionId, objectId: null, objectLabel: null };\n }\n const objectId = addIdClass(c, \"obj\");\n return { sectionId, objectId, objectLabel: objectLabel(c) };\n };\n\n // Gives the section a sec-<id> and adds a comment button to the toolbar of\n // every commentable element (section + text/button/image/column).\n const decorate = (c: Component) => {\n if (isSection(c)) addIdClass(c, \"sec\");\n if (!isCommentable(c)) return;\n const toolbar = [...((c.get(\"toolbar\") as { command?: string }[]) ?? [])];\n if (tagOf(c) === \"mj-image\" && !toolbar.some((t) => t.command === \"open-image-picker\")) {\n toolbar.push({\n command: \"open-image-picker\",\n label: IMAGE_SVG,\n attributes: { title: labels.chooseImage },\n } as never);\n c.set(\"toolbar\", toolbar as never);\n }\n // Comments are addressed by section; outside one (inside a hero) the button did nothing.\n if (closestSection(c) && !toolbar.some((t) => t.command === \"open-comments\")) {\n toolbar.push({\n command: \"open-comments\",\n label: SPARKLES_SVG,\n attributes: { title: labels.commentOnElement, \"data-role\": \"sparkles\" },\n } as never);\n c.set(\"toolbar\", toolbar as never);\n }\n };\n\n // What a double-click on an image does in GrapesJS, reachable from a button.\n editor.Commands.add(\"open-image-picker\", {\n run(ed: Editor) {\n const target = ed.getSelected();\n if (!target || tagOf(target) !== \"mj-image\") return;\n const am = ed.AssetManager;\n am.open({\n target,\n types: [\"image\"],\n select(asset: { getSrc: () => string }, complete?: boolean) {\n target.set({ src: asset.getSrc() });\n if (complete) am.close();\n },\n } as never);\n },\n });\n\n editor.Commands.add(\"open-comments\", {\n run(ed: Editor) {\n const target = targetOf(ed.getSelected() ?? undefined);\n if (target) setComposeTarget(target);\n },\n });\n\n setupRichText(editor, labels);\n fixPluginTypes(editor);\n registerBlocks(editor, blocks, labels.blockCategorySections, SECTION_SVG);\n setupLayerNames(editor, labels);\n\n // The email starts at mj-body: above it are the GrapesJS root and <mjml>, and mj-head,\n // none of which anyone edits here. Sections and columns start open, as they are the\n // structure the rows below them make sense in.\n const STRUCTURE = new Set([\"mj-wrapper\", \"mj-section\", \"mj-column\"]);\n const showBodyInLayers = () => {\n const body = findByTag(\"mj-body\");\n if (!body) return;\n editor.Layers.setRoot(body);\n body.onAll((c) => {\n if (STRUCTURE.has(tagOf(c))) editor.Layers.setOpen(c, true);\n });\n };\n // On each selection GrapesJS closes the rows it opened to show the last one, sections and\n // columns among them. Taken off its list, they stay open until the visitor closes them.\n // The list is internal, so a GrapesJS without it only brings the closing back.\n const keepStructureOpen = () => {\n const layers = editor.Layers as unknown as {\n model?: { get: (key: \"opened\") => Record<string, Component> | undefined };\n };\n const opened = layers.model?.get(\"opened\") ?? {};\n for (const [cid, c] of Object.entries(opened)) {\n if (STRUCTURE.has(tagOf(c))) delete opened[cid];\n }\n };\n\n editor.on(\"component:add\", (c: Component) => {\n // A load brings ids the store already uses; only copies made here are renamed.\n if (!loadingRef.current) freshenCopiedIds(editor.getWrapper(), c);\n decorate(c);\n });\n // Track selection origin: a mousedown inside the canvas iframe marks the\n // next selection as coming from the canvas (→ open Settings). Selecting via\n // the Layers tree leaves the source as \"layers\" (set by the sidebar).\n editor.on(\"load\", () => {\n const body = editor.Canvas.getBody();\n body?.addEventListener(\n \"mousedown\",\n () => {\n selectionSource.current = \"canvas\";\n },\n true,\n );\n // The host document only gets a copy of these, aimed at the iframe (see opensBlockSearch).\n editor.Canvas.getDocument()?.addEventListener(\"keydown\", onBlockSearchKey);\n // GrapesJS sets its configured root on load, which may come after the document did.\n showBodyInLayers();\n });\n // After GrapesJS's own listener, which was added when the editor was created.\n editor.on(\"component:selected\", (c: Component) => {\n keepStructureOpen();\n if (selectionSource.current === \"canvas\") setSidebarView(\"settings\");\n selectionSource.current = \"other\";\n buildCrumbs(c);\n });\n // With multi-select a deselection can leave something selected; follow what remains.\n editor.on(\"component:deselected\", () => {\n buildCrumbs(editor.getSelected());\n });\n\n // A save writes only when the canvas differs from what the store holds — the canvas is\n // the truth, not the events that changed it.\n const baseline = createSaveBaseline();\n\n const save = async () => {\n // An open rich-text editor holds its text until editing ends.\n const view = editor.getEditing()?.getView() as\n { syncContent?: () => Promise<void> } | undefined;\n await view?.syncContent?.();\n const mjml = editor.getHtml();\n if (!baseline.changed(mjml)) return;\n setSave(\"saving\");\n try {\n await documents.save(docId, { mjml, projectData: editor.getProjectData() });\n baseline.saved(mjml);\n setSave(\"saved\");\n } catch (e) {\n setSave(\"error\");\n toast.error(refusal(e) ?? labels.documentSaveFailed, { id: saveToastId(docId) });\n throw e;\n }\n };\n\n const queue = createSaveQueue(save, 1200);\n\n editor.on(\"update\", () => {\n notifyState();\n if (!loadingRef.current && !readOnlyRef.current) queue.schedule();\n });\n editor.on(\"change:device\", notifyState);\n\n // While a turn runs the agent writes the document, so the visitor cannot: edits made\n // meanwhile would be overwritten by the agent's next reload, or overwrite its work.\n const blocked = [\n \"core:undo\",\n \"core:redo\",\n \"core:paste\",\n \"core:component-delete\",\n \"tlb-delete\",\n \"tlb-clone\",\n \"tlb-move\",\n \"open-assets\",\n \"open-image-picker\",\n ];\n for (const id of blocked) {\n editor.on(`command:run:before:${id}`, ({ options }: { options: { abort?: boolean } }) => {\n if (readOnlyRef.current) options.abort = true;\n });\n }\n const lock = (on: boolean) => {\n if (!turn.mounted) return;\n readOnlyRef.current = on;\n setLocked(on);\n notifyState();\n };\n applyReadOnly.current = async (on) => {\n if (on) {\n lock(true);\n queue.cancel();\n editor.select([]);\n // Through GrapesJS, which otherwise keeps its asset command active and will not reopen.\n editor.AssetManager.close();\n setPicker(null);\n return;\n }\n try {\n await reload();\n } catch (e) {\n // Unlocking a stale canvas would let the next save overwrite what the agent wrote.\n console.error(e);\n toast.error(labels.documentLoadFailed, {\n id: `reload-${docId}`,\n duration: Infinity,\n action: { label: labels.retry, onClick: () => void applyReadOnly.current(false) },\n });\n return;\n }\n lock(false);\n // What a load repaired or added while the canvas was locked; nothing, if it is unchanged.\n queue.schedule();\n };\n\n // Only the agent writes during a turn, so the store differs from `baseline.stored` exactly when it\n // changed something. Otherwise the canvas is kept, including edits a failed save left unsaved.\n // Queued behind saves and earlier reloads, so a slow one never lands over a newer one.\n const reload = () =>\n queue.run(async () => {\n const fresh = await documents.get(docId);\n if (fresh.mjml !== baseline.stored) loadMjml(fresh.mjml);\n });\n\n const loadMjml = (mjml: string) => {\n // Loading reports changes of its own. What it adds — ids, the starter body — is still\n // written by the next save, which compares against what the store returned.\n loadingRef.current = true;\n let repaired = false;\n // What the load adds, the store needs: a comment pinned to a new id finds nothing else.\n // Read from the source, as the canvas gave each section its id as it was added.\n const adds = !mjml || listSections(mjml).some((s) => !s.sectionId);\n try {\n queue.cancel();\n baseline.load(mjml, null);\n const source = sourceForEditor(mjml || STARTER_MJML);\n repaired = source.repaired;\n editor.setComponents(source.mjml);\n // Attributes the sidebar used to write and MJML rejects. Rendering ignores them, so\n // removing them changes nothing visible, and leaving them fails every agent write.\n editor.getWrapper()?.onAll((c) => {\n const illegal = illegalAttributes(tagOf(c), c.getAttributes());\n if (illegal.length === 0) return;\n c.removeAttributes(illegal);\n repaired = true;\n });\n if (!repaired && !adds) baseline.load(mjml, editor.getHtml());\n showBodyInLayers();\n // What was loaded is where undo stops: undoing the load emptied the canvas, or put\n // back what an agent turn had replaced, and the next save stored that.\n editor.UndoManager.clear();\n } finally {\n loadingRef.current = false;\n }\n notifyState();\n // Written now rather than with the next edit: the agent reads the stored copy.\n if ((repaired || adds) && !readOnlyRef.current) queue.schedule();\n };\n\n // Highlight for the section the agent is editing. The canvas is an iframe with its\n // own document, so the host's stylesheet does not reach it and these rules have to be\n // injected. The colour is still read from the shared token rather than written out\n // again — the literal that used to live here was the pre-redesign violet and had\n // silently drifted from the brand for as long as the redesign had been in place.\n const ensureHighlightStyles = () => {\n const cdoc = editor.Canvas.getDocument();\n if (!cdoc || cdoc.getElementById(\"agent-edit-style\")) return;\n\n const accent =\n getComputedStyle(document.documentElement)\n .getPropertyValue(\"--mjml-editor-accent\")\n .trim() || \"#7c5cfc\";\n\n const style = cdoc.createElement(\"style\");\n style.id = \"agent-edit-style\";\n style.textContent = `\n @keyframes agentEditPulse {\n 0%, 100% { outline-color: color-mix(in srgb, ${accent} 25%, transparent); }\n 50% { outline-color: color-mix(in srgb, ${accent} 95%, transparent); }\n }\n .agent-editing {\n outline: 3px solid color-mix(in srgb, ${accent} 90%, transparent) !important;\n outline-offset: -3px;\n animation: agentEditPulse 1s ease-in-out infinite;\n transition: outline-color 0.2s;\n }`;\n cdoc.head.appendChild(style);\n };\n\n const sectionEl = (sectionId: string): HTMLElement | undefined => {\n // find() matches the rendered elements, where a section is not an mj-section.\n let comp: Component | undefined;\n editor.getWrapper()?.onAll((c) => {\n if (!comp && isSection(c) && sectionIdOf(c) === sectionId) comp = c;\n });\n return (comp?.getEl?.() as HTMLElement | undefined) ?? undefined;\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const compiledHtml = (): string => {\n try {\n // grapesjs-mjml compiles MJML → email HTML via this command ({ html, errors }).\n const res = editor.runCommand(\"mjml-code-to-html\") as { html?: string } | undefined;\n return res?.html ?? editor.getHtml();\n } catch {\n return editor.getHtml();\n }\n };\n\n turn.ready((on) => void applyReadOnly.current(on));\n try {\n // Queued, so the reload that ends a turn already running lands after this load.\n await queue.run(async () => loadMjml((await documents.get(docId)).mjml));\n } catch (e) {\n toast.error(labels.documentLoadFailed);\n console.error(e);\n } finally {\n setLoading(false);\n }\n\n onReady({\n getMjml: () => editor.getHtml(),\n getCompiledHtml: compiledHtml,\n flushSave: () => queue.flush(),\n reloadFromDb: reload,\n highlightSection: (sectionId, on) => {\n ensureHighlightStyles();\n const el = sectionEl(sectionId);\n if (!el) return;\n el.classList.toggle(\"agent-editing\", on);\n },\n getDevices: () =>\n editor.Devices.getDevices().map((d) => ({\n id: String(d.id),\n name: d.getName() || String(d.id),\n })),\n setDevice: (name) => {\n editor.setDevice(name);\n notifyState();\n },\n undo: () => {\n if (readOnlyRef.current) return;\n editor.UndoManager.undo();\n notifyState();\n },\n redo: () => {\n if (readOnlyRef.current) return;\n editor.UndoManager.redo();\n notifyState();\n },\n setZoom: (z) => {\n editor.Canvas.setZoom?.(Math.max(25, Math.min(200, z)));\n notifyState();\n },\n setContentWidth: (w) => {\n if (readOnlyRef.current) return;\n findByTag(\"mj-body\")?.addAttributes({ width: w });\n notifyState();\n },\n onEditorState: (cb) => {\n stateListeners.current.add(cb);\n cb(snapshot());\n return () => stateListeners.current.delete(cb);\n },\n });\n };\n\n return (\n <GjsEditor\n grapesjs={grapesjs}\n className=\"h-full\"\n options={{\n height: \"100%\",\n storageManager: false,\n // On by default: every visitor's browser would post the host's domain to\n // app.grapesjs.com and leave a session-storage entry, which a host would then have\n // to disclose and, for the entry, ask consent for.\n telemetry: false,\n // Font Awesome from cdnjs by default, a third party a host would have to name in its\n // privacy policy. Nothing we show uses it: GrapesJS draws its toolbar and layer icons\n // as SVG, and its icon-font panels and style manager are not rendered here.\n cssIcons: \"\",\n canvasCss: CANVAS_CSS,\n fromElement: false,\n panels: { defaults: [] },\n blockManager: { appendTo: \"#gjs-blocks\" },\n // The eye hides a layer by writing `display=\"none\"` into the MJML, which is illegal.\n // The root row is mj-body, which the sidebar reaches as \"Email settings\" instead.\n layerManager: { appendTo: \"#gjs-layers\", hidable: false, showWrapper: false },\n assetManager: {\n // Never inline files: mail clients block `data:` images (see ImageLibrary).\n embedAsBase64: false,\n // Our own dialog instead of GrapesJS's modal. GrapesJS still decides when it opens\n // and what a choice applies to; `select(url, true)` sets the image and closes.\n custom: {\n open: (props: {\n select: (asset: string, complete?: boolean) => void;\n // `current` is ours, passed by style properties that have no target component.\n options?: { target?: Component; current?: string };\n }) =>\n setPicker({\n current:\n props.options?.current ??\n (String(props.options?.target?.get(\"src\") ?? \"\") || undefined),\n select: (url) => props.select(url, true),\n }),\n close: () => setPicker(null),\n },\n },\n canvas: {\n customBadgeLabel: badgeLabel(labels),\n // A file or text dragged in from outside lands as `<img>` or `<div>`, which no MJML\n // validator accepts; drags from the palette are unaffected.\n allowExternalDrop: false,\n },\n deviceManager: {\n devices: [\n { id: \"desktop\", name: \"Desktop\", width: \"\" },\n { id: \"mobile\", name: \"Mobile\", width: \"375px\", widthMedia: \"480px\" },\n ],\n },\n plugins: [\n (editor: Editor) =>\n grapesjsMJML(editor, {\n blocks: BUILTIN_BLOCKS,\n block: builtinBlock(labels),\n }),\n ],\n }}\n onEditor={onEditor}\n >\n {/* Inert as well as covered, so the keyboard cannot reach the controls either. */}\n <div\n className=\"relative flex h-full min-h-0 flex-1\"\n inert={readOnly}\n onKeyDown={(e) => onBlockSearchKey(e.nativeEvent)}\n >\n {readOnly && (\n <div className=\"absolute inset-0 z-30 flex cursor-not-allowed items-start justify-center bg-white/20 pt-3\">\n <span className=\"flex items-center gap-2 rounded-full bg-panel px-3 py-1 text-xs text-panel-fg shadow\">\n <Spinner /> {labels.agentWorking}\n </span>\n </div>\n )}\n <LeftSidebar\n view={sidebarView}\n onViewChange={setSidebarView}\n markLayersSource={() => (selectionSource.current = \"layers\")}\n blockSearchRef={blockSearchRef}\n />\n <div className=\"flex min-w-0 flex-1 flex-col bg-surface-muted\">\n <div className=\"relative min-h-0 flex-1\">\n <Canvas className=\"h-full\" />\n {/* Canvas comment layer (pins + thread popovers) overlays the canvas. */}\n <CanvasComments\n docId={docId}\n composeTarget={composeTarget}\n onComposeConsumed={() => setComposeTarget(null)}\n refreshSignal={commentsRefresh}\n onOpenCountChange={onOpenCountChange}\n />\n <ImagePicker\n open={picker !== null}\n currentUrl={picker?.current}\n onSelect={(url) => {\n // An upload that finished after a turn locked the canvas is not applied.\n if (!readOnlyRef.current) picker?.select(url);\n setPicker(null);\n }}\n // Closed here as well as through GrapesJS: its close() is a no-op whenever it\n // does not consider its asset command active, which left the dialog stuck open.\n onClose={() => {\n setPicker(null);\n editorRef.current?.AssetManager.close();\n }}\n />\n {loading && (\n <div className=\"absolute inset-0 z-10 flex items-center justify-center gap-2 bg-white/70 text-sm text-zinc-500\">\n <Spinner /> {labels.loadingEditor}\n </div>\n )}\n </div>\n <Breadcrumb crumbs={crumbs} onSelect={(c) => editorRef.current?.select(c)} />\n </div>\n </div>\n </GjsEditor>\n );\n}\n\ntype SidebarView = \"blocks\" | \"settings\" | \"layers\";\n\n// Left sidebar (dark): Blocks / Settings / Layers. The block and layer managers are always\n// mounted (appendTo targets for GrapesJS) — visibility toggled via `hidden`.\nfunction LeftSidebar({\n view,\n onViewChange,\n markLayersSource,\n blockSearchRef,\n}: {\n view: SidebarView;\n onViewChange: (v: SidebarView) => void;\n markLayersSource: () => void;\n blockSearchRef: React.Ref<HTMLInputElement>;\n}) {\n const editor = useEditorMaybe();\n const labels = useLabels();\n const [layersExpanded, setLayersExpanded] = useState(false);\n const [blockSearch, setBlockSearch] = useState(\"\");\n const [noBlockMatches, setNoBlockMatches] = useState(false);\n\n // A tree walk: `find(\"mj-body\")` returns nothing, and falling back to the GrapesJS root\n // offered background fields that never reached the MJML.\n const selectBody = () => {\n let body: Component | undefined;\n editor?.getWrapper()?.onAll((c) => {\n if (!body && tagOf(c) === \"mj-body\") body = c;\n });\n if (body) editor?.select(body);\n };\n\n const toggleLayers = (expand: boolean) => {\n setLayersExpanded(expand);\n editor?.getWrapper()?.onAll((c) => c.set(\"open\", expand));\n };\n\n // GrapesJS's tiles only drag; Enter or Space on one adds its block (see insertBlock).\n const onTileKey = (e: React.KeyboardEvent) => {\n const tile = (e.target as HTMLElement).closest<HTMLElement>(\"[data-block]\");\n const block = tile && editor?.Blocks.get(tile.dataset.block ?? \"\");\n if (!editor || !block || !addsBlock(e)) return;\n e.preventDefault();\n // Focus stays on the tile, so the change in the canvas is said aloud (toasts are live).\n if (insertBlock(editor, block)) toast(labels.blockAdded(tile.textContent?.trim() ?? \"\"));\n };\n\n // Filter the GrapesJS-rendered blocks (DOM lives outside React) by label;\n // hide category groups that end up empty.\n const filterBlocks = (q: string) => {\n setBlockSearch(q);\n const root = document.getElementById(\"gjs-blocks\");\n if (!root) return;\n const term = q.trim().toLowerCase();\n root.querySelectorAll<HTMLElement>(\".gjs-block\").forEach((b) => {\n const label = (b.querySelector(\".gjs-block-label\")?.textContent ?? b.textContent ?? \"\")\n .toLowerCase()\n .trim();\n b.style.display = !term || label.includes(term) ? \"\" : \"none\";\n });\n root.querySelectorAll<HTMLElement>(\".gjs-block-category\").forEach((cat) => {\n const anyVisible = [...cat.querySelectorAll<HTMLElement>(\".gjs-block\")].some(\n (b) => b.style.display !== \"none\",\n );\n cat.style.display = anyVisible ? \"\" : \"none\";\n });\n setNoBlockMatches(\n [...root.querySelectorAll<HTMLElement>(\".gjs-block\")].every(\n (b) => b.style.display === \"none\",\n ),\n );\n };\n\n return (\n <div className=\"editor-dark flex w-64 shrink-0 flex-col border-r border-panel-border bg-panel text-panel-fg\">\n <div className=\"flex border-b border-panel-border\">\n {(\n [\n [\"blocks\", labels.tabBlocks],\n [\"settings\", labels.tabSettings],\n [\"layers\", labels.tabLayers],\n ] as const\n ).map(([value, label]) => (\n <button\n key={value}\n type=\"button\"\n onClick={() => onViewChange(value)}\n className={cn(\n \"relative flex-1 px-3 py-2.5 text-sm transition-colors\",\n \"after:absolute after:inset-x-0 after:-bottom-px after:h-0.5 after:transition-colors\",\n view === value\n ? \"font-medium text-panel-fg after:bg-brand\"\n : \"text-panel-muted-fg after:bg-transparent hover:text-panel-fg\",\n )}\n >\n {label}\n </button>\n ))}\n </div>\n\n {/* Blocks: search + categorized block palette */}\n <div className={cn(\"flex min-h-0 flex-1 flex-col\", view !== \"blocks\" && \"hidden\")}>\n <div className=\"relative border-b border-panel-border p-2\">\n <Search className=\"pointer-events-none absolute top-1/2 left-4 size-3.5 -translate-y-1/2 text-panel-muted-fg\" />\n <Input\n ref={blockSearchRef}\n value={blockSearch}\n onChange={(e) => filterBlocks(e.target.value)}\n placeholder={labels.searchBlocks}\n className=\"h-8 border-panel-border bg-panel-elevated pr-10 pl-7 text-sm text-panel-fg placeholder:text-panel-muted-fg\"\n />\n <kbd className=\"pointer-events-none absolute top-1/2 right-4 -translate-y-1/2 rounded border border-panel-border bg-panel px-1 py-0.5 font-mono text-[10px] text-panel-muted-fg\">\n /\n </kbd>\n </div>\n {noBlockMatches && (\n <p className=\"px-3 py-6 text-center text-xs text-panel-muted-fg\">\n {labels.noBlocksMatch}\n </p>\n )}\n <div id=\"gjs-blocks\" className=\"min-h-0 flex-1 overflow-y-auto\" onKeyDown={onTileKey} />\n </div>\n\n <div className={cn(\"min-h-0 flex-1 overflow-y-auto\", view !== \"settings\" && \"hidden\")}>\n <Inspector\n onEmailSettings={selectBody}\n empty={\n <div className=\"flex flex-col items-center gap-3 px-6 py-10 text-center\">\n <MousePointerClick className=\"size-6 text-panel-muted-fg\" />\n <p className=\"text-sm text-panel-muted-fg\">{labels.settingsEmpty}</p>\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n className=\"border-panel-border bg-panel-elevated text-panel-fg hover:bg-panel-hover hover:text-panel-fg\"\n onClick={selectBody}\n >\n <Mail />\n {labels.emailSettings}\n </Button>\n </div>\n }\n />\n </div>\n\n {/* Layers — with an expand/collapse-all switch. A pointer-down here marks\n the next selection as coming from the tree (→ do NOT open Settings). */}\n <div\n className={cn(\"flex min-h-0 flex-1 flex-col\", view !== \"layers\" && \"hidden\")}\n onMouseDownCapture={markLayersSource}\n >\n <label className=\"flex items-center justify-between gap-2 border-b border-panel-border px-3 py-2 text-xs text-panel-muted-fg\">\n <span>{labels.expandAll}</span>\n <Switch\n checked={layersExpanded}\n onCheckedChange={toggleLayers}\n className=\"data-[state=checked]:bg-brand data-[state=unchecked]:bg-panel-border\"\n />\n </label>\n <div\n id=\"gjs-layers\"\n className=\"min-h-0 flex-1 overflow-y-auto\"\n // A double-click renames a row in GrapesJS, but rows are named by their content.\n onDoubleClickCapture={(e) => {\n if ((e.target as HTMLElement).closest(\"[data-name]\")) e.stopPropagation();\n }}\n />\n </div>\n </div>\n );\n}\n\n// Breadcrumb under the canvas: the selected component's ancestry (clickable).\nfunction Breadcrumb({\n crumbs,\n onSelect,\n}: {\n crumbs: Component[];\n onSelect: (c: Component) => void;\n}) {\n const labels = useLabels();\n return (\n <div className=\"flex h-9 shrink-0 items-center gap-0.5 border-t border-border bg-surface px-3 text-xs text-muted-foreground\">\n {crumbs.length === 0 ? (\n <span className=\"text-muted-foreground/60\">{labels.selectAnElement}</span>\n ) : (\n crumbs.map((c, i) => (\n <span key={i} className=\"flex items-center gap-0.5\">\n {i > 0 && <ChevronRight className=\"size-3 opacity-40\" />}\n <button\n type=\"button\"\n onClick={() => onSelect(c)}\n className={cn(\n \"rounded px-1.5 py-0.5 hover:bg-muted hover:text-foreground\",\n i === crumbs.length - 1 && \"font-medium text-brand\",\n )}\n >\n {crumbName(c, labels)}\n </button>\n </span>\n ))\n )}\n </div>\n );\n}\n","/**\n * Whether the canvas holds a change the store does not have.\n *\n * Opening an email is not one. GrapesJS writes a document back in its own form — tags closed,\n * attributes quoted again — and reports changes of its own after a load, as an\n * image settles. Compared with the store alone, that rewrote emails nobody had touched.\n */\nexport function createSaveBaseline() {\n let stored = \"\";\n let loaded: string | null = null;\n return {\n /** The MJML the store holds, as far as this editor knows. */\n get stored() {\n return stored;\n },\n /** `canvas` is what the load serialises to, or null when it repaired something to write. */\n load(mjml: string, canvas: string | null) {\n stored = mjml;\n loaded = canvas;\n },\n saved(mjml: string) {\n stored = mjml;\n loaded = null;\n },\n changed(mjml: string) {\n return mjml !== stored && mjml !== loaded;\n },\n };\n}\n","/** Debounced autosave, and the flush a turn waits on. Whether to write is `save`'s call. */\nexport interface SaveQueue {\n /** Restarts the debounce. */\n schedule(): void;\n /** Drops a scheduled autosave. */\n cancel(): void;\n /** Runs `save` after any work under way; rejects if it fails. */\n flush(): Promise<void>;\n /** Runs `task` after any work under way, such as a reload that must not race a save. */\n run<T>(task: () => Promise<T>): Promise<T>;\n}\n\nexport function createSaveQueue(save: () => Promise<void>, delayMs: number): SaveQueue {\n let timer: ReturnType<typeof setTimeout> | null = null;\n // Work runs one after another, so an older write or read can never land after a newer one.\n let tail: Promise<unknown> = Promise.resolve();\n\n const cancel = () => {\n if (timer) clearTimeout(timer);\n timer = null;\n };\n\n const run = <T>(task: () => Promise<T>): Promise<T> => {\n const next = tail.then(task);\n tail = next.catch(() => {});\n return next;\n };\n\n return {\n schedule() {\n cancel();\n timer = setTimeout(() => void run(save).catch(() => {}), delayMs);\n },\n cancel,\n flush() {\n cancel();\n return run(save);\n },\n run,\n };\n}\n","/**\n * Passes the agent turn to a canvas that is ready only some time after it mounts.\n *\n * A turn can already be running by then: the chat re-attaches to one when the visitor comes\n * back mid-turn. Applied only on later changes, that turn left the canvas editable.\n */\nexport function createTurnFollower() {\n let running = false;\n let mounted = true;\n let apply: ((on: boolean) => unknown) | null = null;\n return {\n turn(on: boolean) {\n if (on === running) return;\n running = on;\n if (mounted) apply?.(on);\n },\n /**\n * Whether the canvas is still mounted. An unmounted one's late reload must not unlock\n * the shared state a canvas mounted since has locked.\n */\n get mounted() {\n return mounted;\n },\n // Both, as React mounts twice in development.\n mount() {\n mounted = true;\n },\n unmount() {\n mounted = false;\n },\n /** A turn already under way is applied at once; none means nothing to apply. */\n ready(fn: (on: boolean) => unknown) {\n apply = fn;\n if (running) fn(true);\n },\n };\n}\n","/**\n * Whether a key press should open the block search: a bare `/`, as on GitHub and YouTube.\n * Not ⌘K, which browsers on Windows and Linux keep for their own search bar.\n */\nexport function opensBlockSearch(\n e: Pick<KeyboardEvent, \"key\" | \"metaKey\" | \"ctrlKey\" | \"altKey\" | \"isComposing\" | \"target\">,\n): boolean {\n if (e.key !== \"/\" || e.metaKey || e.ctrlKey || e.altKey || e.isComposing) return false;\n // Typing a slash into a field, or into text being edited on the canvas, is just a slash.\n const target = e.target as { tagName?: string; isContentEditable?: boolean } | null;\n if (target?.isContentEditable) return false;\n // GrapesJS re-dispatches every key pressed in the canvas on its <iframe>, where the text\n // being edited is out of sight; the canvas document's own listener judges those.\n return ![\"INPUT\", \"TEXTAREA\", \"SELECT\", \"IFRAME\"].includes(target?.tagName ?? \"\");\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { Switch as SwitchPrimitive } from \"radix-ui\";\n\nimport { cn } from \"../../lib/utils\";\n\nfunction Switch({\n className,\n size = \"default\",\n ...props\n}: React.ComponentProps<typeof SwitchPrimitive.Root> & {\n size?: \"sm\" | \"default\";\n}) {\n return (\n <SwitchPrimitive.Root\n data-slot=\"switch\"\n data-size={size}\n className={cn(\n \"peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent transition-all outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=default]:h-[18.4px] data-[size=default]:w-[32px] data-[size=sm]:h-[14px] data-[size=sm]:w-[24px] dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:bg-primary data-unchecked:bg-input dark:data-unchecked:bg-input/80 data-disabled:cursor-not-allowed data-disabled:opacity-50\",\n className,\n )}\n {...props}\n >\n <SwitchPrimitive.Thumb\n data-slot=\"switch-thumb\"\n className=\"pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-checked:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-checked:translate-x-[calc(100%-2px)] dark:data-checked:bg-primary-foreground group-data-[size=default]/switch:data-unchecked:translate-x-0 group-data-[size=sm]/switch:data-unchecked:translate-x-0 dark:data-unchecked:bg-foreground\"\n />\n </SwitchPrimitive.Root>\n );\n}\n\nexport { Switch };\n","\"use client\";\n\n/**\n * The image picker, replacing GrapesJS's asset modal.\n *\n * GrapesJS's own modal could not be styled into the editor, and its \"click to upload\" area\n * was a transparent file input that did not open the file browser at all. This one is\n * opened by GrapesJS (`assetManager.custom`), so the canvas double-click, the toolbar button\n * and the sidebar all land here, and selecting goes back through GrapesJS to the image.\n */\n\nimport { useCallback, useEffect, useRef, useState, type DragEvent } from \"react\";\nimport { Check, ImageUp, Link2, Trash2 } from \"lucide-react\";\nimport { toast } from \"sonner\";\n\nimport { useImageLibrary, useLabels, type ImageAsset } from \"../../index.js\";\nimport { cn } from \"../../lib/utils\";\nimport { Button } from \"../ui/button\";\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from \"../ui/dialog\";\nimport { Input } from \"../ui/input\";\nimport { Spinner } from \"../ui/spinner\";\n\ntype Quota = { readonly used: number; readonly limit: number };\n\nexport default function ImagePicker({\n open,\n currentUrl,\n onSelect,\n onClose,\n}: {\n open: boolean;\n /** The image being replaced, marked in the gallery. */\n currentUrl?: string;\n onSelect: (url: string) => void;\n onClose: () => void;\n}) {\n const library = useImageLibrary();\n const labels = useLabels();\n const [images, setImages] = useState<readonly ImageAsset[]>([]);\n const [quota, setQuota] = useState<Quota>();\n const [loading, setLoading] = useState(false);\n const [pending, setPending] = useState(0);\n const [dragging, setDragging] = useState(false);\n const [url, setUrl] = useState(\"\");\n const [confirmId, setConfirmId] = useState<string | null>(null);\n const fileInput = useRef<HTMLInputElement>(null);\n // Bumped on every open and close. An upload still running when the picker closes, or\n // reopens for another image, must not apply its result to whatever is open now.\n const session = useRef(0);\n // Read through refs so neither a new `labels` object nor a new `onSelect` from a parent\n // render re-runs the open effect — that would wipe a half-typed URL.\n const latest = useRef({ labels, onSelect });\n latest.current = { labels, onSelect };\n // Opening, uploading and deleting each list the gallery; only the newest answer is shown.\n const lists = useRef(0);\n\n const refresh = useCallback(async () => {\n if (!library) return;\n const mine = ++lists.current;\n setLoading(true);\n try {\n const result = await library.list();\n if (mine !== lists.current) return;\n setImages(result.images);\n setQuota(result.quota);\n } catch (err) {\n console.error(err);\n if (mine === lists.current) toast.error(latest.current.labels.imagePickerLoadFailed);\n } finally {\n if (mine === lists.current) setLoading(false);\n }\n }, [library]);\n\n useEffect(() => {\n session.current += 1;\n if (!open) return;\n setUrl(\"\");\n setConfirmId(null);\n void refresh();\n // Once per opening; `refresh` reads the latest props through `latest`.\n }, [open]);\n // Nor after unmount, when the editor it would select into is gone.\n useEffect(() => () => void (session.current += 1), []);\n\n const accepts = (file: File) => matchesAccept(file, library?.accept);\n\n const full = quota !== undefined && quota.used >= quota.limit;\n\n const upload = async (files: FileList | null) => {\n const send = library?.upload?.bind(library);\n if (!send || !files?.length) return;\n const mine = session.current;\n // The input's `accept` covers browsing; a drop bypasses it, so check here too rather\n // than send a whole file only to have the host refuse it.\n const list = Array.from(files).filter((f) => {\n if (accepts(f)) return true;\n toast.error(labels.imagePickerUnsupported(f.name));\n return false;\n });\n if (!list.length) return;\n setPending((n) => n + list.length);\n // Settled rather than all: an upload that succeeded has already been stored and\n // counted by the host, so one failure must not hide it.\n // Async, so an adapter that throws rather than rejects still settles.\n const results = await Promise.allSettled(list.map(async (f) => send(f)));\n setPending((n) => n - list.length);\n for (const r of results) {\n if (r.status === \"rejected\") {\n console.error(r.reason);\n // The host's message is usually the actionable part (\"limit reached\", \"too large\").\n toast.error(r.reason instanceof Error ? r.reason.message : labels.imageUploadFailed);\n }\n }\n if (session.current !== mine) return;\n await refresh();\n // One file dropped while editing an image is meant for that image.\n const [only] = results;\n if (results.length === 1 && only?.status === \"fulfilled\" && session.current === mine) {\n latest.current.onSelect(only.value.url);\n }\n };\n\n const remove = async (image: ImageAsset) => {\n if (!library?.remove) return;\n // Two clicks rather than a confirm(): an image in use breaks every email showing it.\n if (confirmId !== image.id) {\n setConfirmId(image.id);\n return;\n }\n setConfirmId(null);\n try {\n await library.remove(image.id);\n await refresh();\n } catch (err) {\n console.error(err);\n toast.error(err instanceof Error ? err.message : labels.imageDeleteFailed);\n }\n };\n\n const onDrop = (e: DragEvent) => {\n e.preventDefault();\n setDragging(false);\n if (!full) void upload(e.dataTransfer.files);\n };\n\n return (\n <Dialog open={open} onOpenChange={(next) => !next && onClose()}>\n {/* A file dropped where nothing takes it would otherwise be opened by the browser in\n place of the editor: with no upload, or with the quota full. */}\n <DialogContent\n onDragOver={(e) => e.preventDefault()}\n onDrop={(e) => e.preventDefault()}\n className=\"editor-dark gap-0 overflow-hidden border border-panel-border bg-panel p-0 text-panel-fg ring-0 sm:max-w-3xl\"\n >\n <DialogHeader className=\"border-b border-panel-border px-5 py-4\">\n <DialogTitle>{labels.imagePickerTitle}</DialogTitle>\n {quota && (\n <DialogDescription className=\"text-panel-muted-fg\">\n {labels.imagePickerQuota(quota.used, quota.limit)}\n </DialogDescription>\n )}\n </DialogHeader>\n\n <div className=\"flex max-h-[70vh] flex-col gap-4 overflow-y-auto p-5\">\n {library?.upload &&\n (full ? (\n <p className=\"rounded-lg border border-panel-border bg-panel-elevated px-4 py-3 text-sm text-panel-muted-fg\">\n {labels.imagePickerQuotaFull}\n </p>\n ) : (\n <div\n onDragOver={(e) => {\n e.preventDefault();\n setDragging(true);\n }}\n onDragLeave={() => setDragging(false)}\n onDrop={onDrop}\n className={cn(\n \"flex flex-col items-center justify-center gap-3 rounded-xl border-2 border-dashed px-6 py-8 text-center transition-colors\",\n dragging ? \"border-brand bg-brand-soft\" : \"border-panel-border bg-panel-elevated\",\n )}\n >\n <ImageUp className=\"size-8 text-panel-muted-fg\" />\n <div className=\"flex flex-wrap items-center justify-center gap-2 text-sm text-panel-muted-fg\">\n <span>{labels.imagePickerDrop}</span>\n <Button\n type=\"button\"\n size=\"sm\"\n className=\"bg-brand text-brand-fg hover:bg-brand/90\"\n onClick={() => fileInput.current?.click()}\n >\n {labels.imagePickerBrowse}\n </Button>\n </div>\n <input\n ref={fileInput}\n type=\"file\"\n accept={library.accept ?? \"image/*\"}\n multiple\n hidden\n onChange={(e) => {\n void upload(e.target.files);\n e.target.value = \"\";\n }}\n />\n </div>\n ))}\n\n {library?.allowUrl !== false && (\n <form\n className=\"flex gap-2\"\n onSubmit={(e) => {\n e.preventDefault();\n const value = url.trim();\n if (value) onSelect(value);\n }}\n >\n <div className=\"relative flex-1\">\n <Link2 className=\"pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-panel-muted-fg\" />\n <Input\n value={url}\n onChange={(e) => setUrl(e.target.value)}\n placeholder={labels.imagePickerUrlPlaceholder}\n className=\"h-9 border-panel-border bg-panel-elevated pl-8 text-panel-fg placeholder:text-panel-muted-fg\"\n />\n </div>\n <Button\n type=\"submit\"\n size=\"lg\"\n variant=\"outline\"\n disabled={!url.trim()}\n className=\"border-panel-border bg-panel-elevated text-panel-fg hover:bg-panel-hover hover:text-panel-fg\"\n >\n {labels.imagePickerUseUrl}\n </Button>\n </form>\n )}\n\n {library && (\n <section>\n <h3 className=\"mb-2 text-xs font-medium tracking-wide text-panel-muted-fg uppercase\">\n {labels.imagePickerGallery}\n </h3>\n {loading && images.length === 0 && pending === 0 ? (\n <div className=\"flex justify-center py-8\">\n <Spinner />\n </div>\n ) : images.length === 0 && pending === 0 ? (\n <p className=\"py-6 text-center text-sm text-panel-muted-fg\">\n {labels.imagePickerEmpty}\n </p>\n ) : (\n <ul className=\"grid grid-cols-3 gap-3 sm:grid-cols-4\">\n {Array.from({ length: pending }, (_, i) => (\n <li\n key={`pending-${i}`}\n className=\"flex aspect-[4/3] items-center justify-center rounded-lg border border-panel-border bg-panel-elevated\"\n >\n <Spinner />\n </li>\n ))}\n {images.map((image) => {\n const selected = image.url === currentUrl;\n const confirming = confirmId === image.id;\n return (\n <li key={image.id} className=\"group relative\">\n <button\n type=\"button\"\n onClick={() => onSelect(image.url)}\n title={image.name}\n className={cn(\n \"block aspect-[4/3] w-full overflow-hidden rounded-lg border bg-black/25 transition outline-none focus-visible:ring-2 focus-visible:ring-brand\",\n selected\n ? \"border-brand ring-2 ring-brand\"\n : \"border-panel-border hover:border-panel-muted-fg\",\n )}\n >\n {/* Contained, not cropped: email images are mostly wide banners, and\n choosing one means seeing its whole composition. */}\n <img\n src={image.url}\n alt={image.name ?? \"\"}\n loading=\"lazy\"\n className=\"size-full object-contain\"\n />\n </button>\n {selected && (\n <span className=\"pointer-events-none absolute top-1.5 left-1.5 flex size-5 items-center justify-center rounded-full bg-brand text-brand-fg\">\n <Check className=\"size-3\" />\n </span>\n )}\n {image.name && (\n <span className=\"pointer-events-none absolute inset-x-0 bottom-0 truncate rounded-b-lg bg-black/60 px-2 py-1 text-[11px] text-white opacity-0 transition group-hover:opacity-100\">\n {image.name}\n </span>\n )}\n {library.remove && (\n <button\n type=\"button\"\n onClick={() => void remove(image)}\n onBlur={() => confirming && setConfirmId(null)}\n title={\n confirming\n ? labels.imagePickerConfirmDelete\n : labels.imagePickerDelete\n }\n aria-label={labels.imagePickerDelete}\n className={cn(\n \"absolute top-1.5 right-1.5 flex h-6 items-center gap-1 rounded-md px-1.5 text-xs text-white transition focus-visible:opacity-100\",\n confirming\n ? \"bg-red-600 opacity-100\"\n : \"bg-black/60 opacity-0 group-hover:opacity-100 hover:bg-black/80\",\n )}\n >\n <Trash2 className=\"size-3.5\" />\n {confirming && labels.imagePickerConfirmDelete}\n </button>\n )}\n </li>\n );\n })}\n </ul>\n )}\n </section>\n )}\n </div>\n </DialogContent>\n </Dialog>\n );\n}\n\n/** The subset of `<input accept>` a picker needs: MIME types, `type/*`, and `.ext`. */\nfunction matchesAccept(file: File, accept: string | undefined): boolean {\n if (!accept) return file.type.startsWith(\"image/\");\n return accept.split(\",\").some((raw) => {\n const rule = raw.trim().toLowerCase();\n if (rule.startsWith(\".\")) return file.name.toLowerCase().endsWith(rule);\n if (rule.endsWith(\"/*\")) return file.type.startsWith(rule.slice(0, -1));\n return file.type === rule;\n });\n}\n","\"use client\";\n\n/**\n * The Settings tab: the selected element's MJML attributes, grouped by what they are for.\n *\n * It reads `getAttributes()` and writes `addAttributes` / `removeAttributes`, never through\n * GrapesJS's Style Manager: its properties are global per CSS name, so a label, unit list or\n * option set could not differ by tag, and it reads a style mirror the plugin seeds with its\n * own defaults rather than the document's values. Only attributes the schema names are\n * written, so `css-class`, which carries the agent's `sec-*` and `obj-*` ids, never is.\n */\n\nimport { useEffect, useLayoutEffect, useReducer, useRef, useState, type ReactNode } from \"react\";\nimport type { Component, Editor } from \"grapesjs\";\nimport { useEditorMaybe } from \"@grapesjs/react\";\nimport { ArrowUp, ChevronRight, Copy, Monitor, Trash2, X } from \"lucide-react\";\n\nimport { useLabels } from \"../../../index.js\";\nimport type { EditorLabels } from \"../../../labels.js\";\nimport { useAgentTurn } from \"../../../stores.js\";\nimport { cn } from \"../../../lib/utils\";\nimport ColorField, { toHex } from \"../ColorField.js\";\nimport ImageField, { imageUrl } from \"../ImageField.js\";\nimport { BoxInput, LengthInput, Row, Segmented, Select, TextInput, Toggle } from \"./controls.js\";\nimport { layerName } from \"../layers.js\";\nimport { SCHEMA } from \"./schema.js\";\nimport StructureSection from \"./StructureSection.js\";\nimport type { Field, Group, Option } from \"./types.js\";\nimport { isSafeLink, isSafeNavbarLink, networkName, parseNetwork, SIDES } from \"./values.js\";\nimport { createWriter, type WriteOptions } from \"./write.js\";\n\nconst GROUPS: readonly Exclude<Group, \"advanced\">[] = [\"content\", \"layout\", \"spacing\", \"style\"];\n\n// Never listed under \"Other attributes\": the agent's ids, and GrapesJS's own bookkeeping.\nconst HIDDEN = new Set([\"css-class\", \"mj-class\", \"id\", \"style\"]);\n\nfunction tagOf(c: Component): string {\n return String(c.get(\"tagName\") || c.get(\"type\") || \"\");\n}\n\n/** Attributes as strings; GrapesJS keeps a few as booleans or numbers. */\nfunction attributesOf(c: Component): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [k, v] of Object.entries(c.getAttributes())) {\n if (v !== undefined && v !== null && v !== false) out[k] = String(v);\n }\n // mj-image keeps `src` as a model property, and the plugin writes that over the attribute.\n if (tagOf(c) === \"mj-image\") out.src = String(c.get(\"src\") ?? \"\");\n return out;\n}\n\n/**\n * Distinct colors already in the email, most frequent first, read when the picker opens.\n * Only values of color-bearing attributes: a bare `#[0-9a-f]+` also matches entities such as\n * `&#039;` and anchors such as `href=\"#top\"`.\n */\nfunction documentColors(editor: Editor): string[] {\n const counts = new Map<string, number>();\n const colorValue =\n /(?:color|background|border)[\\w-]*\\s*[:=]\\s*[\"']?[^\"';>{}]*?(#[0-9a-f]{3,8}\\b|rgba?\\([^)]*\\))/gi;\n for (const match of editor.getHtml().matchAll(colorValue)) {\n const hex = toHex(match[1]!, { opaque: true });\n if (hex) counts.set(hex, (counts.get(hex) ?? 0) + 1);\n }\n return [...counts.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 14)\n .map(([hex]) => hex);\n}\n\nexport default function Inspector({\n onEmailSettings,\n empty,\n}: {\n onEmailSettings: () => void;\n /** Shown when nothing is selected. */\n empty: ReactNode;\n}) {\n const editor = useEditorMaybe();\n const labels = useLabels();\n const { locked } = useAgentTurn();\n // Read when a write happens, not when its control rendered: a field held down as a turn\n // starts writes from a render before the lock, and its release comes as it unmounts.\n const lockedNow = useRef(locked);\n useLayoutEffect(() => {\n lockedNow.current = locked;\n });\n const [, refresh] = useReducer((n: number) => n + 1, 0);\n const root = useRef<HTMLDivElement>(null);\n const refocus = useRef(false);\n\n // GrapesJS owns the selection and the values; re-read them whenever either changes. No\n // Component is kept in state: an agent turn's reload replaces every one of them.\n useEffect(() => {\n if (!editor) return;\n const events = \"component:update change:device\";\n // A button here that changes the selection (parent, duplicate, delete, a link, Add) goes\n // with the old element's settings; focus moves to what replaces them, not to the page.\n const toggled = () => {\n if (root.current?.contains(document.activeElement)) refocus.current = true;\n refresh();\n };\n editor.on(events, refresh);\n editor.on(\"component:toggled\", toggled);\n return () => {\n editor.off(events, refresh);\n editor.off(\"component:toggled\", toggled);\n };\n }, [editor]);\n useEffect(() => {\n if (!refocus.current) return;\n refocus.current = false;\n root.current?.querySelector<HTMLElement>(\"[data-focus-target]\")?.focus();\n });\n\n if (!editor) return null;\n const selected = editor.getSelectedAll();\n const component = selected[0];\n return (\n <div ref={root}>\n {selected.length === 0 ? (\n <div data-focus-target tabIndex={-1} className=\"outline-none\">\n {empty}\n </div>\n ) : selected.length > 1 ? (\n <p\n data-focus-target\n tabIndex={-1}\n className=\"px-4 py-8 text-center text-xs text-panel-muted-fg outline-none\"\n >\n {labels.multipleSelected(selected.length)}\n </p>\n ) : (\n <ElementSettings\n key={component!.cid}\n editor={editor}\n component={component!}\n labels={labels}\n locked={locked}\n lockedNow={lockedNow}\n onEmailSettings={onEmailSettings}\n />\n )}\n </div>\n );\n}\n\nfunction ElementSettings({\n editor,\n component,\n labels,\n locked,\n lockedNow,\n onEmailSettings,\n}: {\n editor: Editor;\n component: Component;\n labels: EditorLabels;\n locked: boolean;\n lockedNow: { readonly current: boolean };\n onEmailSettings: () => void;\n}) {\n const [advancedOpen, setAdvancedOpen] = useState(false);\n const tag = tagOf(component);\n const fields = SCHEMA[tag] ?? [];\n const attributes = attributesOf(component);\n const visible = fields.filter((f) => !f.when || f.when(attributes));\n const t = (key: string) => labels.inspectorLabels[key] ?? key;\n const optionName = (o: Option) => labels.inspectorLabels[o.label] ?? o.label;\n\n // One writer per element (this component is keyed by it), so a drag's start survives renders.\n const [writer] = useState(() => createWriter(editor, component, () => lockedNow.current));\n const write = (attr: string, value: string, options?: WriteOptions) =>\n lockedNow.current ? Promise.resolve() : writer(attr, value, options);\n // A box writes its shorthand and drops the longhands, which would otherwise override it.\n const writeBox = (attr: string, shorthand: string, partial?: boolean) =>\n write(attr, shorthand, { remove: SIDES.map((s) => `${attr}-${s}`), partial });\n\n const chooseImage = (attr: string) => {\n if (attr === \"src\" && tag === \"mj-image\") return void editor.runCommand(\"open-image-picker\");\n const am = editor.AssetManager;\n am.open({\n types: [\"image\"],\n current: imageUrl(attributes[attr] ?? \"\") ?? undefined,\n select(asset: string | { getSrc: () => string }, complete?: boolean) {\n void write(attr, typeof asset === \"string\" ? asset : asset.getSrc());\n if (complete) am.close();\n },\n } as never);\n };\n\n const safeLink = (attr: string) => (link: string) => {\n if (tag === \"mj-navbar-link\" && attr === \"href\") {\n return isSafeNavbarLink(String(component.parent()?.getAttributes()[\"base-url\"] ?? \"\"), link);\n }\n if (tag === \"mj-navbar\" && attr === \"base-url\") {\n return component\n .components()\n .every((c: Component) => isSafeNavbarLink(link, String(c.getAttributes().href ?? \"\")));\n }\n return isSafeLink(link);\n };\n\n const control = (f: Field): ReactNode => {\n const value = attributes[f.attr] ?? \"\";\n const c = f.control;\n switch (c.type) {\n case \"text\":\n return (\n <TextInput\n value={value}\n placeholder={c.placeholder ?? f.default}\n onCommit={(v) => write(f.attr, v)}\n />\n );\n case \"link\":\n return (\n <TextInput\n value={value}\n placeholder=\"https://\"\n accept={safeLink(f.attr)}\n onCommit={(v) => write(f.attr, v)}\n />\n );\n case \"color\":\n return (\n <ColorField\n value={value}\n placeholder={f.default}\n documentColors={() => documentColors(editor)}\n labels={labels}\n onChange={(v, partial) => write(f.attr, v, { partial })}\n />\n );\n case \"image\":\n return (\n <ImageField\n value={value}\n labels={labels}\n onChoose={() => chooseImage(f.attr)}\n onClear={() => write(f.attr, \"\")}\n />\n );\n case \"length\":\n return (\n <LengthInput\n value={value}\n placeholder={f.default}\n units={c.units}\n negative={c.negative}\n labels={labels}\n onCommit={(v, partial) => write(f.attr, v, { partial })}\n />\n );\n case \"box\":\n return (\n <BoxInput\n attributes={attributes}\n attr={f.attr}\n placeholder={f.default}\n units={c.units}\n labels={labels}\n onCommit={(v, partial) => writeBox(f.attr, v, partial)}\n />\n );\n case \"segmented\":\n return (\n <Segmented\n value={value}\n fallback={f.default}\n options={c.options}\n name={optionName}\n onCommit={(v) => write(f.attr, v)}\n />\n );\n case \"select\":\n return (\n <Select\n value={value}\n fallback={f.default}\n options={c.options}\n name={optionName}\n onCommit={(v) => write(f.attr, v)}\n />\n );\n case \"toggle\":\n return (\n <Toggle\n checked={value === c.on}\n label={t(f.label)}\n onCommit={(on) => write(f.attr, on ? c.on : \"\")}\n />\n );\n case \"network\": {\n const { network, share } = parseNetwork(value);\n return (\n <div className=\"flex flex-col gap-1.5\">\n <Select\n value={network}\n options={c.networks}\n name={optionName}\n onCommit={(n) => write(f.attr, n ? networkName(n, share) : \"\")}\n />\n {network && network !== \"custom\" && (\n <Segmented\n value={share ? \"share\" : \"profile\"}\n options={[\n { value: \"profile\", label: labels.linkTypeProfile },\n { value: \"share\", label: labels.linkTypeShare },\n ]}\n name={(o) => o.label}\n onCommit={(v) => write(f.attr, networkName(network, v === \"share\"))}\n />\n )}\n </div>\n );\n }\n }\n };\n\n const own = (f: Field) =>\n f.control.type === \"box\"\n ? [f.attr, ...SIDES.map((s) => `${f.attr}-${s}`)].some((a) => attributes[a] !== undefined)\n : !!attributes[f.attr];\n const reset = (f: Field) => (f.control.type === \"box\" ? writeBox(f.attr, \"\") : write(f.attr, \"\"));\n const wide = (f: Field) =>\n [\"color\", \"image\", \"link\", \"text\", \"box\", \"network\"].includes(f.control.type);\n\n const row = (f: Field) => (\n <Row\n key={f.attr}\n label={t(f.label)}\n help={labels.inspectorLabels[`${f.label}.help`]}\n own={own(f)}\n wide={wide(f)}\n inline={f.control.type === \"toggle\"}\n labels={labels}\n onReset={() => void reset(f)}\n >\n {control(f)}\n </Row>\n );\n\n const named = new Set(\n fields.flatMap((f) =>\n f.control.type === \"box\" ? [f.attr, ...SIDES.map((s) => `${f.attr}-${s}`)] : [f.attr],\n ),\n );\n const others = Object.entries(attributes).filter(([k]) => !named.has(k) && !HIDDEN.has(k));\n const advanced = visible.filter((f) => f.group === \"advanced\");\n const advancedCount = advanced.length + others.length;\n\n return (\n <div className=\"pb-6\">\n <Header\n editor={editor}\n component={component}\n labels={labels}\n onEmailSettings={onEmailSettings}\n />\n {editor.getDevice() !== \"Desktop\" && (\n <p className=\"mx-3 mt-2 flex items-center gap-1.5 rounded-md bg-panel-elevated px-2 py-1.5 text-[11px] text-panel-muted-fg\">\n <Monitor className=\"size-3.5 shrink-0\" />\n {labels.allScreenSizes}\n </p>\n )}\n <StructureSection editor={editor} component={component} labels={labels} locked={locked} />\n {GROUPS.map((group) => {\n const inGroup = visible.filter((f) => f.group === group);\n if (inGroup.length === 0) return null;\n return (\n <section key={group} className=\"border-b border-panel-border/60 py-2\">\n <h3 className=\"px-3 pb-1 text-[10px] font-semibold tracking-wider text-panel-muted-fg/80 uppercase\">\n {groupName(group, labels)}\n </h3>\n {inGroup.map(row)}\n </section>\n );\n })}\n {advancedCount > 0 && (\n <section className=\"py-1\">\n <button\n type=\"button\"\n onClick={() => setAdvancedOpen((o) => !o)}\n aria-expanded={advancedOpen}\n className=\"flex w-full items-center gap-1 px-3 py-2 text-[10px] font-semibold tracking-wider text-panel-muted-fg/80 uppercase hover:text-panel-fg\"\n >\n <ChevronRight\n className={cn(\"size-3 transition-transform\", advancedOpen && \"rotate-90\")}\n />\n {labels.groupAdvanced}\n <span className=\"font-normal normal-case\">({advancedCount})</span>\n </button>\n {advancedOpen && (\n <>\n {advanced.map(row)}\n {others.length > 0 && (\n <div className=\"px-3 pt-2\">\n <p className=\"pb-1 text-[11px] text-panel-muted-fg\">{labels.otherAttributes}</p>\n <ul className=\"flex flex-col gap-1\">\n {others.map(([k, v]) => (\n <li\n key={k}\n className=\"flex items-center gap-2 rounded-md bg-panel-elevated px-2 py-1 font-mono text-[11px]\"\n >\n <span className=\"text-panel-muted-fg\">{k}</span>\n <span className=\"min-w-0 flex-1 truncate text-panel-fg\" title={v}>\n {v}\n </span>\n <button\n type=\"button\"\n onClick={() => void write(k, \"\")}\n title={labels.removeAttribute}\n aria-label={`${labels.removeAttribute}: ${k}`}\n className=\"text-panel-muted-fg hover:text-panel-fg\"\n >\n <X className=\"size-3\" />\n </button>\n </li>\n ))}\n </ul>\n </div>\n )}\n </>\n )}\n </section>\n )}\n </div>\n );\n}\n\nfunction groupName(group: Exclude<Group, \"advanced\">, labels: EditorLabels): string {\n return {\n content: labels.groupContent,\n layout: labels.groupLayout,\n spacing: labels.groupSpacing,\n style: labels.groupStyle,\n }[group];\n}\n\n/** What is selected, with the actions the canvas toolbar has, so the panel needs no hunt. */\nfunction Header({\n editor,\n component,\n labels,\n onEmailSettings,\n}: {\n editor: Editor;\n component: Component;\n labels: EditorLabels;\n onEmailSettings: () => void;\n}) {\n const tag = tagOf(component);\n const isBody = tag === \"mj-body\";\n const name = isBody\n ? labels.emailSettings\n : (labels.elementNames[tag] ?? tag.replace(/^mj-/, \"\"));\n // What it says, as Layers names it; a column's number is not something it says.\n const words = tag === \"mj-column\" ? \"\" : layerName(component, labels);\n const excerpt = words === name ? \"\" : words;\n const parent = component.parent();\n const action =\n \"flex size-7 items-center justify-center rounded-md text-panel-muted-fg hover:bg-panel-hover hover:text-panel-fg\";\n return (\n <div className=\"sticky top-0 z-10 flex items-center gap-2 border-b border-panel-border bg-panel px-3 py-2\">\n <div className=\"min-w-0 flex-1\">\n <p\n data-focus-target\n tabIndex={-1}\n className=\"truncate text-sm font-medium text-panel-fg outline-none\"\n >\n {name}\n </p>\n {excerpt && !isBody && (\n <p className=\"truncate text-[11px] text-panel-muted-fg\">“{excerpt}”</p>\n )}\n </div>\n {!isBody && parent && (\n <button\n type=\"button\"\n className={action}\n title={labels.selectParent}\n aria-label={labels.selectParent}\n onClick={() => (tagOf(parent) === \"mj-body\" ? onEmailSettings() : editor.select(parent))}\n >\n <ArrowUp className=\"size-3.5\" />\n </button>\n )}\n {!isBody && (\n <>\n <button\n type=\"button\"\n className={action}\n title={labels.duplicate}\n aria-label={labels.duplicate}\n onClick={() => editor.runCommand(\"tlb-clone\")}\n >\n <Copy className=\"size-3.5\" />\n </button>\n <button\n type=\"button\"\n className={action}\n title={labels.deleteElement}\n aria-label={labels.deleteElement}\n onClick={() => editor.runCommand(\"tlb-delete\")}\n >\n <Trash2 className=\"size-3.5\" />\n </button>\n </>\n )}\n </div>\n );\n}\n","\"use client\";\n\n/**\n * The color control in Settings. It keeps a text box — typing a hex is often the fastest\n * way — and opens a picker with the colors the email already uses, which is what keeps a\n * design consistent.\n */\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { HexAlphaColorPicker, HexColorPicker } from \"react-colorful\";\nimport { Pipette } from \"lucide-react\";\n\nimport type { EditorLabels } from \"../../labels.js\";\nimport { cn } from \"../../lib/utils\";\nimport { useFieldLabel } from \"./inspector/controls.js\";\nimport { NAMED_COLORS } from \"./mjml-attributes.js\";\nimport { Popover, PopoverAnchor, PopoverContent, PopoverTrigger } from \"../ui/popover\";\n\n/** Web-safe neutrals and a few saturated hues; emails rarely want more than this. */\nconst PRESETS = [\n \"#000000\",\n \"#374151\",\n \"#6b7280\",\n \"#d1d5db\",\n \"#f3f4f6\",\n \"#ffffff\",\n \"#dc2626\",\n \"#ea580c\",\n \"#ca8a04\",\n \"#16a34a\",\n \"#0284c7\",\n \"#4f46e5\",\n \"#9333ea\",\n \"#db2777\",\n];\n\n// Chrome's EyeDropper; absent elsewhere, and so is the button.\ntype EyeDropperCtor = new () => { open: () => Promise<{ sRGBHex: string }> };\nconst eyeDropper = (): EyeDropperCtor | undefined =>\n (globalThis as { EyeDropper?: EyeDropperCtor }).EyeDropper;\n\nexport default function ColorField({\n value,\n placeholder,\n documentColors,\n labels,\n onChange,\n}: {\n value: string;\n /** The property's default, shown when no value is set. */\n placeholder?: string;\n /** Read when the picker opens, so it reflects the email as it is now. */\n documentColors: () => string[];\n labels: EditorLabels;\n /** `partial` while dragging, so a drag is one undo step, not one per pixel. */\n onChange: (value: string, partial: boolean) => void;\n}) {\n const field = useFieldLabel();\n const [text, setText] = useState(value);\n const [open, setOpen] = useState(false);\n const [used, setUsed] = useState<string[]>([]);\n // Whether a pointer is down on the picker, and the value its drag left as a partial update.\n const pressed = useRef(false);\n const dragged = useRef<string | null>(null);\n const fieldRef = useRef<HTMLDivElement>(null);\n // The picker opens beside the panel the field sits in, level with the field. Anchored to\n // the field itself it covered the panel, since a property can be half the panel wide.\n const anchor = useRef({\n getBoundingClientRect: () => {\n const field = fieldRef.current?.getBoundingClientRect() ?? new DOMRect();\n const panel = fieldRef.current?.closest(\".editor-dark\")?.getBoundingClientRect();\n return new DOMRect(panel?.right ?? field.right, field.top, 0, field.height);\n },\n });\n\n useEffect(() => setText(value), [value]);\n const latestOnChange = useRef(onChange);\n latestOnChange.current = onChange;\n // A drag ends as a real change, with an undo step, when the pointer is released: GrapesJS\n // writes to whatever is selected at that moment, and nothing else can be selected while\n // the pointer is captured. The view going away mid-drag ends it too.\n const release = useCallback(() => {\n pressed.current = false;\n if (dragged.current !== null) latestOnChange.current(dragged.current, false);\n dragged.current = null;\n }, []);\n // On the document: when the captured element is removed mid-drag (the popover closing, or\n // the alpha slider appearing), the browser sends the release there rather than to it.\n useEffect(() => {\n document.addEventListener(\"lostpointercapture\", release);\n return () => {\n document.removeEventListener(\"lostpointercapture\", release);\n release();\n };\n }, [release]);\n\n const hex = toHex(value) ?? toHex(placeholder ?? \"\") ?? \"#000000\";\n // Translucent colors keep their alpha, and get the slider to change it.\n const translucent = hex.length === 9;\n // Unset, the swatch shows the default the email falls back to, as the text box does.\n const shown = value || placeholder || \"\";\n\n const commit = (next: string) => {\n dragged.current = null;\n const color = mjmlColor(next);\n // MJML would reject it, and with it every later write of the agent's; the field goes back.\n if (color === null) return setText(value);\n setText(color);\n onChange(color, false);\n };\n\n // react-colorful reports no drag end, and moves by arrow keys as well; those are whole changes.\n const drag = (picked: string) => {\n // The alpha picker reports `#rrggbbaa`, which MJML rejects.\n const next = mjmlColor(picked) ?? picked;\n setText(next);\n if (!pressed.current) return commit(next);\n dragged.current = next;\n onChange(next, true);\n };\n\n const pickFromScreen = async () => {\n const Ctor = eyeDropper();\n if (!Ctor) return;\n try {\n const { sRGBHex } = await new Ctor().open();\n commit(sRGBHex);\n } catch {\n // Escape cancels the eyedropper; nothing to do.\n }\n };\n\n return (\n <Popover\n open={open}\n onOpenChange={(next) => {\n if (next) setUsed(documentColors());\n // Closing by Escape or a click outside unmounts the hex input without a blur, so\n // a value typed there is committed here rather than lost.\n else if (text.trim() !== value) commit(text.trim());\n setOpen(next);\n }}\n >\n <PopoverAnchor virtualRef={anchor} />\n <div\n ref={fieldRef}\n className=\"flex h-8 w-full items-center gap-1.5 rounded-md border border-panel-border bg-panel-elevated pr-1.5 pl-2 focus-within:border-brand\"\n >\n <input\n value={text}\n placeholder={placeholder}\n spellCheck={false}\n {...field}\n onChange={(e) => setText(e.target.value)}\n onBlur={() => text !== value && commit(text.trim())}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") commit(text.trim());\n if (e.key === \"Escape\") setText(value);\n }}\n className=\"min-w-0 flex-1 bg-transparent font-mono text-xs text-panel-fg outline-none placeholder:text-panel-muted-fg\"\n />\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n title={labels.colorPickerOpen}\n aria-label={labels.colorPickerOpen}\n className=\"relative size-5 shrink-0 overflow-hidden rounded border border-white/20 outline-none focus-visible:ring-2 focus-visible:ring-brand\"\n >\n <Checkerboard />\n {mjmlColor(shown) && (\n <span className=\"absolute inset-0\" style={{ background: shown }} />\n )}\n </button>\n </PopoverTrigger>\n </div>\n <PopoverContent\n side=\"right\"\n align=\"start\"\n sideOffset={8}\n className=\"editor-dark flex w-52 flex-col gap-2.5 border border-panel-border bg-panel p-2.5 text-panel-fg\"\n >\n <div\n onPointerDownCapture={(e) => {\n pressed.current = true;\n // Captured, so a release over the canvas iframe still reaches this document. On the\n // target, not this wrapper: the mousedown react-colorful handles follows the capture.\n (e.target as Element).setPointerCapture(e.pointerId);\n }}\n >\n {translucent ? (\n <HexAlphaColorPicker color={hex} onChange={drag} className=\"color-field-picker\" />\n ) : (\n <HexColorPicker color={hex} onChange={drag} className=\"color-field-picker\" />\n )}\n </div>\n\n <div className=\"flex items-center gap-1.5\">\n <span\n className=\"size-6 shrink-0 rounded border border-white/20\"\n style={{ background: hex }}\n />\n <input\n value={text}\n spellCheck={false}\n {...field}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={(e) => e.key === \"Enter\" && commit(text.trim())}\n onBlur={() => text !== value && commit(text.trim())}\n className=\"h-6 min-w-0 flex-1 rounded border border-panel-border bg-panel-elevated px-1.5 font-mono text-[11px] outline-none focus:border-brand\"\n />\n {eyeDropper() && (\n <button\n type=\"button\"\n onClick={() => void pickFromScreen()}\n title={labels.colorPickerEyedropper}\n aria-label={labels.colorPickerEyedropper}\n className=\"flex size-6 shrink-0 items-center justify-center rounded border border-panel-border bg-panel-elevated text-panel-muted-fg hover:text-panel-fg\"\n >\n <Pipette className=\"size-3\" />\n </button>\n )}\n </div>\n\n {used.length > 0 && (\n <Swatches\n title={labels.colorPickerDocument}\n colors={used}\n current={hex}\n onPick={commit}\n />\n )}\n <Swatches\n title={labels.colorPickerPresets}\n colors={PRESETS}\n current={hex}\n onPick={commit}\n transparentLabel={labels.colorPickerTransparent}\n />\n </PopoverContent>\n </Popover>\n );\n}\n\nfunction Swatches({\n title,\n colors,\n current,\n onPick,\n transparentLabel,\n}: {\n title: string;\n colors: string[];\n current: string;\n onPick: (color: string) => void;\n /** Adds a \"transparent\" swatch at the end when given. */\n transparentLabel?: string;\n}) {\n return (\n <div>\n <p className=\"mb-1 text-[10px] font-medium tracking-wide text-panel-muted-fg uppercase\">\n {title}\n </p>\n <div className=\"grid grid-cols-8 gap-1\">\n {colors.map((color) => (\n <button\n key={color}\n type=\"button\"\n title={color}\n onClick={() => onPick(color)}\n className={cn(\n \"aspect-square rounded border border-white/15 outline-none hover:scale-110 focus-visible:ring-2 focus-visible:ring-brand\",\n color.toLowerCase() === current.toLowerCase() && \"ring-2 ring-brand\",\n )}\n style={{ background: color }}\n />\n ))}\n {transparentLabel && (\n <button\n type=\"button\"\n title={transparentLabel}\n onClick={() => onPick(\"transparent\")}\n className=\"relative aspect-square overflow-hidden rounded border border-white/15 outline-none hover:scale-110 focus-visible:ring-2 focus-visible:ring-brand\"\n >\n <Checkerboard />\n </button>\n )}\n </div>\n </div>\n );\n}\n\nfunction Checkerboard() {\n return (\n <span\n className=\"absolute inset-0\"\n style={{\n backgroundImage: \"repeating-conic-gradient(#9ca3af 0% 25%, #e5e7eb 0% 50%)\",\n backgroundSize: \"8px 8px\",\n }}\n />\n );\n}\n\n/**\n * A colour as MJML accepts it — `#rrggbb`, `rgba()` when translucent, or a name — or null for\n * anything MJML's Color type rejects. Empty stays empty: the attribute is removed.\n */\nexport function mjmlColor(value: string): string | null {\n const v = value.trim();\n if (v === \"\") return \"\";\n if (NAMED_COLORS.has(v.toLowerCase())) return v.toLowerCase();\n const hex = toHex(v);\n if (!hex) return null;\n if (hex.length === 7) return hex;\n const [r, g, b, a] = [1, 3, 5, 7].map((i) => parseInt(hex.slice(i, i + 2), 16));\n // MJML's pattern wants a digit before the point and at most three after it.\n return `rgba(${r},${g},${b},${Number((a! / 255).toFixed(2))})`;\n}\n\n/**\n * `#rgb`, `#rrggbb(aa)` and `rgb()/rgba()` to `#rrggbb`, or `#rrggbbaa` when translucent\n * unless `opaque` is set; anything else (names, `transparent`) to null.\n */\nexport function toHex(value: string, { opaque = false } = {}): string | null {\n const v = value.trim().toLowerCase();\n const short = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/.exec(v);\n if (short) return `#${short[1]}${short[1]}${short[2]}${short[2]}${short[3]}${short[3]}`;\n if (/^#[0-9a-f]{6}$/.test(v)) return v;\n if (/^#[0-9a-f]{8}$/.test(v)) return opaque || v.endsWith(\"ff\") ? v.slice(0, 7) : v;\n const rgb = /^rgba?\\(\\s*(\\d+)[\\s,]+(\\d+)[\\s,]+(\\d+)(?:[\\s,/]+([\\d.]+%?))?/.exec(v);\n if (rgb) {\n const channels = [rgb[1], rgb[2], rgb[3]].map((n) => Math.min(255, Number(n)));\n const alphaText = rgb[4];\n const alpha = alphaText?.endsWith(\"%\") ? parseFloat(alphaText) / 100 : Number(alphaText ?? 1);\n if (!opaque && alpha < 1) channels.push(Math.round(Math.max(0, alpha) * 255));\n return `#${channels.map((n) => n.toString(16).padStart(2, \"0\")).join(\"\")}`;\n }\n return null;\n}\n","\"use client\";\n\n/**\n * The inputs the Settings inspector is built from. Text-like inputs keep a draft and commit\n * on blur or Enter: every committed attribute re-renders the element through MJML, and one\n * undo step per keystroke is not an undo history anyone can use.\n */\n\nimport {\n createContext,\n useContext,\n useEffect,\n useId,\n useRef,\n useState,\n type KeyboardEvent,\n type ReactNode,\n} from \"react\";\nimport {\n AlignCenter,\n AlignJustify,\n AlignLeft,\n AlignRight,\n ChevronDown,\n ChevronUp,\n CircleHelp,\n Grid2x2,\n RotateCcw,\n} from \"lucide-react\";\n\nimport type { EditorLabels } from \"../../../labels.js\";\nimport { cn } from \"../../../lib/utils\";\nimport { Switch } from \"../../ui/switch\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"../../ui/tooltip\";\nimport type { Option, Unit } from \"./types.js\";\nimport { boxShorthand, parseLength, readBox, SIDES, type Sides } from \"./values.js\";\n\nconst FIELD =\n \"h-7 w-full min-w-0 rounded-md border border-panel-border bg-panel-elevated px-2 text-xs text-panel-fg outline-none placeholder:text-panel-muted-fg/70 focus:border-brand\";\n\n// The ids of the caption and the help of the Row a control sits in: the caption is not a\n// <label>, as it holds the reset button, so the control is named by reference.\nconst FieldLabel = createContext<{ label?: string; help?: string }>({});\n/** `aria-labelledby` and `aria-describedby` for a control inside a Row. */\nexport const useFieldLabel = () => {\n const { label, help } = useContext(FieldLabel);\n return { \"aria-labelledby\": label, \"aria-describedby\": help };\n};\n\n/** A label, the control, and — when the element sets its own value — a dot and a reset. */\nexport function Row({\n label,\n help,\n own,\n wide,\n inline,\n labels,\n onReset,\n children,\n}: {\n label: string;\n help?: string;\n own: boolean;\n /** Label above the control rather than beside it, for controls that need the width. */\n wide?: boolean;\n /** Label across the row and the control at its end, for a switch. */\n inline?: boolean;\n labels: EditorLabels;\n onReset: () => void;\n children: ReactNode;\n}) {\n const id = useId();\n const helpId = useId();\n const [helpOpen, setHelpOpen] = useState(false);\n const control = (\n <FieldLabel.Provider value={{ label: id, help: help ? helpId : undefined }}>\n {children}\n </FieldLabel.Provider>\n );\n const caption = (\n <span className=\"flex min-w-0 items-center gap-1.5 text-[11px] text-panel-muted-fg\">\n <span\n aria-hidden\n className={cn(\"size-1.5 shrink-0 rounded-full\", own ? \"bg-brand\" : \"bg-transparent\")}\n />\n <span id={id} className=\"truncate\">\n {label}\n </span>\n {/* On demand: shown under every field, the help doubled the panel's length. */}\n {help && (\n // Its own provider: a host need not wrap the editor in one, as only EditorHeader asked.\n // Opened by a tap as well: Radix opens a tooltip on hover and focus, not on touch.\n <TooltipProvider>\n <Tooltip open={helpOpen} onOpenChange={setHelpOpen}>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n aria-label={help}\n onClick={() => setHelpOpen((open) => !open)}\n className=\"-m-0.5 shrink-0 rounded p-0.5 text-panel-muted-fg/70 hover:text-panel-fg focus-visible:text-panel-fg\"\n >\n <CircleHelp className=\"size-3\" />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"top\" className=\"max-w-56 leading-snug\">\n {help}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n {own && (\n <button\n type=\"button\"\n onClick={onReset}\n title={labels.resetToDefault}\n aria-label={`${labels.resetToDefault}: ${label}`}\n className=\"ml-auto rounded p-0.5 text-panel-muted-fg opacity-0 group-hover/row:opacity-100 hover:text-panel-fg focus-visible:opacity-100\"\n >\n <RotateCcw className=\"size-3\" />\n </button>\n )}\n </span>\n );\n return (\n <div className=\"group/row px-3 py-1\">\n {wide ? (\n <div className=\"flex flex-col gap-1\">\n {caption}\n {control}\n </div>\n ) : inline ? (\n <div className=\"flex items-center justify-between gap-2\">\n {caption}\n {control}\n </div>\n ) : (\n <div className=\"grid grid-cols-[92px_minmax(0,1fr)] items-center gap-2\">\n {caption}\n {control}\n </div>\n )}\n {help && (\n <span id={helpId} hidden>\n {help}\n </span>\n )}\n </div>\n );\n}\n\n/** `source`: what the shown value is read from, when that can change while it does not. */\nfunction useDraft(value: string, commit: (next: string) => void, source: string = value) {\n const [draft, setDraft] = useState(value);\n useEffect(() => setDraft(value), [value, source]);\n const done = () => {\n if (draft.trim() !== value) commit(draft.trim());\n };\n const onKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") e.currentTarget.blur();\n if (e.key === \"Escape\") {\n setDraft(value);\n // Blurring after the reset commits nothing, since the draft equals the value again.\n requestAnimationFrame(() => (e.target as HTMLInputElement).blur());\n }\n };\n return { draft, setDraft, done, onKeyDown };\n}\n\nexport function TextInput({\n value,\n placeholder,\n accept,\n onCommit,\n}: {\n value: string;\n placeholder?: string;\n /** False for text the field must not write; it is kept, marked, for the visitor to fix. */\n accept?: (next: string) => boolean;\n onCommit: (next: string) => void;\n}) {\n const [invalid, setInvalid] = useState(false);\n const field = useFieldLabel();\n const { draft, setDraft, done, onKeyDown } = useDraft(value, (next) => {\n const ok = !accept || accept(next);\n setInvalid(!ok);\n if (ok) onCommit(next);\n });\n return (\n <input\n className={cn(FIELD, invalid && \"border-red-400\")}\n {...field}\n aria-invalid={invalid}\n value={draft}\n placeholder={placeholder}\n onChange={(e) => setDraft(e.target.value)}\n onBlur={done}\n onKeyDown={onKeyDown}\n />\n );\n}\n\nconst BARE_NUMBER = /^-?\\d*\\.?\\d+$/;\n\n/**\n * Typed text as the length to write: a bare number takes `unit` (the field's current one),\n * so typing `24` into a px field means 24px. Null for what the field cannot write, a negative\n * included unless MJML takes one there.\n */\nexport function normaliseLength(\n text: string,\n units: readonly Unit[],\n negative = false,\n unit: Unit = units[0]!,\n): string | null {\n if (text === \"\") return \"\";\n // Before parseLength, which reads a bare number as unitless where that is allowed.\n const parsed = BARE_NUMBER.test(text) ? { amount: text, unit } : parseLength(text, units);\n if (!parsed || (!negative && parsed.amount.startsWith(\"-\"))) return null;\n return `${parsed.amount}${parsed.unit}`;\n}\n\n/**\n * `amount` moved by `delta`, to two decimals, not below zero unless allowed. Unchanged where\n * the result would not be a plain decimal (`1e+22`, `Infinity`), which MJML rejects.\n */\nexport function stepAmount(amount: string, delta: number, negative = false): string {\n const moved = Math.round((Number(amount) + delta) * 100) / 100;\n const next = String(negative ? moved : Math.max(0, moved));\n return BARE_NUMBER.test(next) ? next : amount;\n}\n\n// A hold on a step button keeps stepping, after a pause long enough for a single click.\nconst REPEAT_AFTER_MS = 400;\nconst REPEAT_EVERY_MS = 60;\n\n/**\n * A number with its unit beside it, steppable by the arrows, the arrow keys (Shift for 10) or\n * holding a step button. A hold is shown as it goes and recorded as one change when released.\n * A value the field cannot read, such as one the agent wrote in another unit, shows whole and\n * is not stepped: stepping it from zero would throw it away.\n */\nexport function LengthInput({\n value,\n placeholder,\n units,\n negative = false,\n compact = false,\n labelledBy,\n labels,\n onCommit,\n}: {\n value: string;\n placeholder?: string;\n units: readonly Unit[];\n negative?: boolean;\n /** Too narrow for the arrows to stay: they show on hover and focus, the unit cannot change. */\n compact?: boolean;\n /** Ids naming the field, when the Row's caption alone does not. */\n labelledBy?: string;\n labels: EditorLabels;\n onCommit: (next: string, partial?: boolean) => void;\n}) {\n const fieldLabel = useFieldLabel();\n const own = parseLength(value, units);\n const fallback = parseLength(placeholder ?? \"\", units);\n // Picked while the field is empty; a value carries its own unit.\n const [picked, setPicked] = useState<Unit | null>(null);\n const unit = own?.unit ?? picked ?? fallback?.unit ?? units[0]!;\n const [invalid, setInvalid] = useState(false);\n // The latest, for a hold that outlives the render it began in: what it may write can change\n // under it, as when an agent turn locks the editor.\n const commit = useRef(onCommit);\n commit.current = onCommit;\n // Ends a hold still running: before any other edit of this field, and when it goes away.\n const endHold = useRef<(() => void) | null>(null);\n useEffect(() => () => endHold.current?.(), []);\n\n const { draft, setDraft, done, onKeyDown } = useDraft(\n own ? own.amount : value,\n (next) => {\n endHold.current?.();\n const normal = normaliseLength(next, units, negative, unit);\n setInvalid(normal === null);\n if (normal !== null) commit.current(normal);\n },\n value,\n );\n\n // Where a step starts: what is typed, else the default in the current unit, else zero.\n // Null for text the field cannot read.\n const from = (): { amount: string; unit: Unit } | null => {\n const text = draft.trim();\n if (BARE_NUMBER.test(text)) return { amount: text, unit };\n if (text === \"\") return { amount: fallback?.amount ?? \"0\", unit };\n return parseLength(text, units);\n };\n const stepOnce = (delta: number) => {\n endHold.current?.();\n const start = from();\n if (!start) return setInvalid(true);\n const amount = stepAmount(start.amount, delta, negative);\n setInvalid(false);\n setDraft(amount);\n commit.current(`${amount}${start.unit}`);\n };\n const onKey = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key !== \"ArrowUp\" && e.key !== \"ArrowDown\") return onKeyDown(e);\n e.preventDefault();\n stepOnce((e.key === \"ArrowUp\" ? 1 : -1) * (e.shiftKey ? 10 : 1));\n };\n\n const press = (direction: 1 | -1) => (e: React.PointerEvent<HTMLButtonElement>) => {\n // One hold at a time: a second finger, or the other arrow, waits for the first to end.\n if (e.button !== 0 || endHold.current) return;\n // Focus stays where it was; the press is not a click on the field.\n e.preventDefault();\n const start = from();\n if (!start) return setInvalid(true);\n const delta = direction * (e.shiftKey ? 10 : 1);\n let amount = stepAmount(start.amount, delta, negative);\n const show = () => {\n setInvalid(false);\n setDraft(amount);\n commit.current(`${amount}${start.unit}`, true);\n };\n show();\n let timer = window.setTimeout(function repeat() {\n amount = stepAmount(amount, delta, negative);\n show();\n timer = window.setTimeout(repeat, REPEAT_EVERY_MS);\n }, REPEAT_AFTER_MS);\n const button = e.currentTarget;\n // Captured, so a release over the canvas iframe still reaches the button; the window, the\n // blur and the cancel end it where capture is missing or the pointer is taken away.\n try {\n button.setPointerCapture(e.pointerId);\n } catch {\n // Not supported here; the window's listeners below end the hold.\n }\n const events = [\"pointerup\", \"pointercancel\", \"lostpointercapture\"] as const;\n const pointerId = e.pointerId;\n const end = () => {\n window.clearTimeout(timer);\n for (const type of events) button.removeEventListener(type, release);\n window.removeEventListener(\"pointerup\", release);\n window.removeEventListener(\"blur\", end);\n endHold.current = null;\n commit.current(`${amount}${start.unit}`);\n };\n // Only the pointer that pressed: another finger lifting elsewhere leaves the hold running.\n const release = (ev: Event) => {\n if (\n (ev as PointerEvent).pointerId === undefined ||\n (ev as PointerEvent).pointerId === pointerId\n )\n end();\n };\n endHold.current = end;\n for (const type of events) button.addEventListener(type, release);\n window.addEventListener(\"pointerup\", release);\n window.addEventListener(\"blur\", end);\n };\n // A click with no pointer behind it (`detail` 0) is the keyboard or assistive technology\n // pressing the button; a pointer's click follows the press, which already stepped.\n const click = (direction: 1 | -1) => (e: React.MouseEvent<HTMLButtonElement>) => {\n if (e.detail === 0) stepOnce(direction);\n };\n\n const pickUnit = () => {\n endHold.current?.();\n const next = units[(units.indexOf(unit) + 1) % units.length]!;\n const text = draft.trim();\n if (!BARE_NUMBER.test(text)) return setPicked(next);\n const normal = normaliseLength(text, units, negative, next);\n // A number the field refuses (a negative) is not written in another unit either.\n if (normal === null) return setInvalid(true);\n setPicked(next);\n commit.current(normal);\n };\n const unitName = (u: Unit) => u || labels.noUnit;\n // Only a value the field reads as a number has a unit to show beside it.\n const readable = draft.trim() === \"\" || BARE_NUMBER.test(draft.trim());\n\n const arrow =\n \"flex h-1/2 w-3.5 items-center justify-center text-panel-muted-fg hover:bg-panel-hover hover:text-panel-fg\";\n return (\n <div\n className={cn(\n \"group/length flex h-7 w-full min-w-0 items-center overflow-hidden rounded-md border border-panel-border bg-panel-elevated focus-within:border-brand\",\n invalid && \"border-red-400\",\n )}\n >\n <input\n className=\"h-full w-full min-w-0 flex-1 bg-transparent pl-2 font-mono text-xs text-panel-fg outline-none placeholder:text-panel-muted-fg/70\"\n value={draft}\n placeholder={fallback ? fallback.amount : placeholder}\n inputMode=\"decimal\"\n {...fieldLabel}\n aria-labelledby={labelledBy ?? fieldLabel[\"aria-labelledby\"]}\n aria-invalid={invalid}\n onChange={(e) => {\n endHold.current?.();\n setDraft(e.target.value);\n }}\n onBlur={done}\n onKeyDown={onKey}\n />\n {readable &&\n (units.length > 1 && !compact ? (\n <button\n type=\"button\"\n onClick={pickUnit}\n title={labels.changeUnit(unitName(unit))}\n aria-label={labels.changeUnit(unitName(unit))}\n className=\"shrink-0 rounded px-0.5 font-mono text-[10px] text-panel-muted-fg underline decoration-dotted underline-offset-2 hover:text-panel-fg\"\n >\n {unitName(unit)}\n </button>\n ) : (\n // Narrow, the unit gives its place to the arrows while they show; a unit is typed.\n <span\n aria-hidden\n className={cn(\n \"shrink-0 px-0.5 font-mono text-[10px] text-panel-muted-fg\",\n compact && \"group-focus-within/length:hidden group-hover/length:hidden\",\n )}\n >\n {unitName(unit)}\n </span>\n ))}\n <span\n className={cn(\n \"h-full shrink-0 flex-col border-l border-panel-border\",\n compact ? \"hidden group-focus-within/length:flex group-hover/length:flex\" : \"flex\",\n )}\n >\n <button\n type=\"button\"\n tabIndex={-1}\n aria-label={labels.increase}\n onPointerDown={press(1)}\n onClick={click(1)}\n className={arrow}\n >\n <ChevronUp className=\"size-2.5\" />\n </button>\n <button\n type=\"button\"\n tabIndex={-1}\n aria-label={labels.decrease}\n onPointerDown={press(-1)}\n onClick={click(-1)}\n className={arrow}\n >\n <ChevronDown className=\"size-2.5\" />\n </button>\n </span>\n </div>\n );\n}\n\n/** Vertical/horizontal pair, which is how emails are spaced, expanding to four sides. */\nexport function BoxInput({\n attributes,\n attr,\n placeholder,\n units,\n labels,\n onCommit,\n}: {\n attributes: Readonly<Record<string, string>>;\n attr: string;\n placeholder?: string;\n units: readonly Unit[];\n labels: EditorLabels;\n onCommit: (shorthand: string, partial?: boolean) => void;\n}) {\n const sides = readBox(attributes, attr);\n const defaults = readBox(placeholder ? { [attr]: placeholder } : {}, attr);\n const symmetric = sides[0] === sides[2] && sides[1] === sides[3];\n const [each, setEach] = useState(!symmetric);\n useEffect(() => {\n if (!symmetric) setEach(true);\n }, [symmetric]);\n\n const set = (indices: number[], v: string, partial?: boolean) => {\n // Sides left unset keep showing MJML's default; writing them as 0 would move them.\n const next = sides.map((s, i) => s || defaults[i]!) as Sides;\n for (const i of indices) next[i] = v || defaults[i]!;\n onCommit(next.every((s, i) => s === defaults[i]) ? \"\" : boxShorthand(next), partial);\n };\n\n const fieldLabel = useFieldLabel();\n const sideId = useId();\n const sideNames = [labels.sideTop, labels.sideRight, labels.sideBottom, labels.sideLeft];\n const pairs: [string, number[]][] = each\n ? SIDES.map((_, i) => [sideNames[i]!, [i]])\n : [\n [labels.sidesVertical, [0, 2]],\n [labels.sidesHorizontal, [1, 3]],\n ];\n\n return (\n <div className=\"flex items-start gap-1.5\">\n <div className={cn(\"grid flex-1 gap-1.5\", each ? \"grid-cols-4\" : \"grid-cols-2\")}>\n {pairs.map(([name, indices]) => (\n <label key={name} className=\"flex min-w-0 flex-col gap-0.5\" title={name}>\n <LengthInput\n value={sides[indices[0]!]!}\n placeholder={defaults[indices[0]!] || \"0\"}\n units={units}\n compact={each}\n labels={labels}\n labelledBy={[fieldLabel[\"aria-labelledby\"], `${sideId}-${indices[0]}`]\n .filter(Boolean)\n .join(\" \")}\n onCommit={(v, partial) => set(indices, v, partial)}\n />\n <span\n id={`${sideId}-${indices[0]}`}\n className=\"truncate text-center text-[10px] text-panel-muted-fg/80\"\n >\n {name}\n </span>\n </label>\n ))}\n </div>\n <button\n type=\"button\"\n onClick={() => setEach((v) => !v)}\n disabled={each && !symmetric}\n aria-pressed={each}\n title={labels.editEachSide}\n aria-label={labels.editEachSide}\n className={cn(\n \"flex size-7 shrink-0 items-center justify-center rounded-md border border-panel-border text-panel-muted-fg hover:text-panel-fg disabled:opacity-40\",\n each && \"border-brand text-panel-fg\",\n )}\n >\n <Grid2x2 className=\"size-3.5\" />\n </button>\n </div>\n );\n}\n\nconst ALIGN_ICONS: Record<string, ReactNode> = {\n left: <AlignLeft className=\"size-3.5\" />,\n center: <AlignCenter className=\"size-3.5\" />,\n right: <AlignRight className=\"size-3.5\" />,\n justify: <AlignJustify className=\"size-3.5\" />,\n};\n\nexport function Segmented({\n value,\n fallback,\n options,\n name,\n onCommit,\n}: {\n value: string;\n /** Shown as selected, unpressed, while nothing is set: MJML's default. */\n fallback?: string;\n options: readonly Option[];\n name: (option: Option) => string;\n onCommit: (next: string) => void;\n}) {\n const current = value || fallback;\n const iconsOnly = options.every((o) => o.value in ALIGN_ICONS);\n return (\n <div className=\"flex h-7 overflow-hidden rounded-md border border-panel-border bg-panel-elevated\">\n {options.map((o) => {\n const active = current === o.value;\n return (\n <button\n key={o.value}\n type=\"button\"\n aria-pressed={active}\n title={name(o)}\n aria-label={name(o)}\n onClick={() => o.value !== value && onCommit(o.value)}\n className={cn(\n \"flex min-w-0 flex-1 items-center justify-center px-1 text-[11px] text-panel-muted-fg transition-colors hover:text-panel-fg\",\n active &&\n (value\n ? \"bg-brand text-brand-fg hover:text-brand-fg\"\n : \"bg-panel-hover text-panel-fg\"),\n )}\n >\n {iconsOnly ? ALIGN_ICONS[o.value] : <span className=\"truncate\">{name(o)}</span>}\n </button>\n );\n })}\n </div>\n );\n}\n\nexport function Select({\n value,\n fallback,\n options,\n name,\n onCommit,\n}: {\n value: string;\n fallback?: string;\n options: readonly Option[];\n name: (option: Option) => string;\n onCommit: (next: string) => void;\n}) {\n // A value no option names (an agent's own font stack) stays visible and selected.\n const known = !value || options.some((o) => o.value === value);\n const fallbackOption = options.find((o) => o.value === fallback);\n const field = useFieldLabel();\n return (\n <select\n className={cn(FIELD, \"px-1.5\")}\n {...field}\n value={value || \"\"}\n onChange={(e) => onCommit(e.target.value)}\n >\n {/* Unset: MJML's default applies. */}\n <option value=\"\">{fallbackOption ? name(fallbackOption) : \"—\"}</option>\n {!known && <option value={value}>{value}</option>}\n {options.map((o) => (\n <option key={o.value} value={o.value}>\n {name(o)}\n </option>\n ))}\n </select>\n );\n}\n\nexport function Toggle({\n checked,\n label,\n onCommit,\n}: {\n checked: boolean;\n label: string;\n onCommit: (next: boolean) => void;\n}) {\n return (\n <Switch\n checked={checked}\n onCheckedChange={onCommit}\n aria-label={label}\n className=\"justify-self-end data-checked:bg-brand data-unchecked:bg-panel-border\"\n />\n );\n}\n","/** Reading and writing attribute values the way MJML spells them. */\n\nimport type { Unit } from \"./types.js\";\n\nexport const SIDES = [\"top\", \"right\", \"bottom\", \"left\"] as const;\nexport type Sides = [string, string, string, string];\n\n/** CSS shorthand order: one value for all, two for vertical/horizontal, three, or four. */\nexport function expandBox(value: string): Sides | null {\n const parts = value.trim().split(/\\s+/).filter(Boolean);\n if (parts.length === 0 || parts.length > 4) return null;\n const [t, r = t, b = t, l = r] = parts as [string, string?, string?, string?];\n return [t, r, b, l];\n}\n\n/**\n * Each side as MJML resolves it: a `-top`-style longhand wins over the shorthand, and a side\n * neither sets is empty. Agents write both forms, so reading only one showed wrong values.\n */\nexport function readBox(attributes: Readonly<Record<string, string>>, attr: string): Sides {\n const short = expandBox(attributes[attr] ?? \"\") ?? [\"\", \"\", \"\", \"\"];\n return SIDES.map((side, i) => attributes[`${attr}-${side}`] ?? short[i]!) as Sides;\n}\n\n/** The shortest shorthand for four sides; empty sides become `0`. */\nexport function boxShorthand(sides: Sides): string {\n const [t, r, b, l] = sides.map((s) => s.trim() || \"0\") as Sides;\n if (t === b && r === l) return t === r ? t : `${t} ${r}`;\n if (r === l) return `${t} ${r} ${b}`;\n return `${t} ${r} ${b} ${l}`;\n}\n\nexport type Length = { amount: string; unit: Unit };\n\n/** `\"20px\"` to `{ amount: \"20\", unit: \"px\" }`; null for anything that is not one length. */\nexport function parseLength(value: string, units: readonly Unit[]): Length | null {\n const match = /^(-?\\d*\\.?\\d+)\\s*(px|%|em)?$/.exec(value.trim());\n if (!match) return null;\n const unit = (match[2] ?? \"\") as Unit;\n return units.includes(unit) ? { amount: match[1]!, unit } : null;\n}\n\nconst NO_SHARE = \"-noshare\";\n\n/**\n * mj-social-element names a network and, without `-noshare`, makes the icon open a \"share\n * this page\" dialog instead of linking to the profile. Custom has no share variant.\n */\nexport function parseNetwork(name: string): { network: string; share: boolean } {\n return name.endsWith(NO_SHARE)\n ? { network: name.slice(0, -NO_SHARE.length), share: false }\n : { network: name, share: name !== \"custom\" && name !== \"\" };\n}\n\nexport function networkName(network: string, share: boolean): string {\n return share || network === \"custom\" ? network : `${network}${NO_SHARE}`;\n}\n\n// The agent backends refuse the same links, so the rule lives in core.\nexport { isSafeLink, isSafeNavbarLink } from \"@mjml-agent-editor/core\";\n","/**\n * The attributes MJML accepts on each tag the editor renders, copied from mjml 4.18's\n * `allowedAttributes` (a test keeps the copy in step with the installed package).\n *\n * The agent compiles the whole document strictly on every write, so one illegal attribute\n * anywhere — the sidebar used to write `title` and `display` — makes every later agent edit\n * fail on an element it never touched.\n */\n// prettier-ignore\nexport const ALLOWED_ATTRIBUTES: Readonly<Record<string, readonly string[]>> = {\n \"mj-body\": [\n \"background-color\", \"width\",\n ],\n \"mj-wrapper\": [\n \"background-color\", \"background-position\", \"background-position-x\",\n \"background-position-y\", \"background-repeat\", \"background-size\", \"background-url\",\n \"border\", \"border-bottom\", \"border-left\", \"border-radius\", \"border-right\", \"border-top\",\n \"direction\", \"full-width\", \"gap\", \"padding\", \"padding-bottom\", \"padding-left\",\n \"padding-right\", \"padding-top\", \"text-align\", \"text-padding\",\n ],\n \"mj-section\": [\n \"background-color\", \"background-position\", \"background-position-x\",\n \"background-position-y\", \"background-repeat\", \"background-size\", \"background-url\",\n \"border\", \"border-bottom\", \"border-left\", \"border-radius\", \"border-right\", \"border-top\",\n \"direction\", \"full-width\", \"padding\", \"padding-bottom\", \"padding-left\", \"padding-right\",\n \"padding-top\", \"text-align\", \"text-padding\",\n ],\n \"mj-column\": [\n \"background-color\", \"border\", \"border-bottom\", \"border-left\", \"border-radius\",\n \"border-right\", \"border-top\", \"direction\", \"inner-background-color\", \"inner-border\",\n \"inner-border-bottom\", \"inner-border-left\", \"inner-border-radius\", \"inner-border-right\",\n \"inner-border-top\", \"padding\", \"padding-bottom\", \"padding-left\", \"padding-right\",\n \"padding-top\", \"vertical-align\", \"width\",\n ],\n \"mj-group\": [\n \"background-color\", \"direction\", \"vertical-align\", \"width\",\n ],\n \"mj-text\": [\n \"align\", \"background-color\", \"color\", \"container-background-color\", \"font-family\",\n \"font-size\", \"font-style\", \"font-weight\", \"height\", \"letter-spacing\", \"line-height\",\n \"padding\", \"padding-bottom\", \"padding-left\", \"padding-right\", \"padding-top\",\n \"text-decoration\", \"text-transform\", \"vertical-align\",\n ],\n \"mj-button\": [\n \"align\", \"background-color\", \"border\", \"border-bottom\", \"border-left\", \"border-radius\",\n \"border-right\", \"border-top\", \"color\", \"container-background-color\", \"font-family\",\n \"font-size\", \"font-style\", \"font-weight\", \"height\", \"href\", \"inner-padding\",\n \"letter-spacing\", \"line-height\", \"name\", \"padding\", \"padding-bottom\", \"padding-left\",\n \"padding-right\", \"padding-top\", \"rel\", \"target\", \"text-align\", \"text-decoration\",\n \"text-transform\", \"title\", \"vertical-align\", \"width\",\n ],\n \"mj-image\": [\n \"align\", \"alt\", \"border\", \"border-bottom\", \"border-left\", \"border-radius\", \"border-right\",\n \"border-top\", \"container-background-color\", \"fluid-on-mobile\", \"font-size\", \"height\",\n \"href\", \"max-height\", \"name\", \"padding\", \"padding-bottom\", \"padding-left\", \"padding-right\",\n \"padding-top\", \"rel\", \"sizes\", \"src\", \"srcset\", \"target\", \"title\", \"usemap\", \"width\",\n ],\n \"mj-divider\": [\n \"align\", \"border-color\", \"border-style\", \"border-width\", \"container-background-color\",\n \"padding\", \"padding-bottom\", \"padding-left\", \"padding-right\", \"padding-top\", \"width\",\n ],\n \"mj-spacer\": [\n \"border\", \"border-bottom\", \"border-left\", \"border-right\", \"border-top\",\n \"container-background-color\", \"height\", \"padding\", \"padding-bottom\", \"padding-left\",\n \"padding-right\", \"padding-top\",\n ],\n \"mj-social\": [\n \"align\", \"border-radius\", \"color\", \"container-background-color\", \"font-family\",\n \"font-size\", \"font-style\", \"font-weight\", \"icon-height\", \"icon-padding\", \"icon-size\",\n \"inner-padding\", \"line-height\", \"mode\", \"padding\", \"padding-bottom\", \"padding-left\",\n \"padding-right\", \"padding-top\", \"table-layout\", \"text-decoration\", \"text-padding\",\n \"vertical-align\",\n ],\n \"mj-social-element\": [\n \"align\", \"alt\", \"background-color\", \"border-radius\", \"color\", \"font-family\", \"font-size\",\n \"font-style\", \"font-weight\", \"href\", \"icon-height\", \"icon-padding\", \"icon-position\",\n \"icon-size\", \"line-height\", \"name\", \"padding\", \"padding-bottom\", \"padding-left\",\n \"padding-right\", \"padding-top\", \"rel\", \"sizes\", \"src\", \"srcset\", \"target\",\n \"text-decoration\", \"text-padding\", \"title\", \"vertical-align\",\n ],\n \"mj-hero\": [\n \"background-color\", \"background-height\", \"background-position\", \"background-url\",\n \"background-width\", \"border-radius\", \"container-background-color\", \"height\",\n \"inner-background-color\", \"inner-padding\", \"inner-padding-bottom\", \"inner-padding-left\",\n \"inner-padding-right\", \"inner-padding-top\", \"mode\", \"padding\", \"padding-bottom\",\n \"padding-left\", \"padding-right\", \"padding-top\", \"vertical-align\",\n ],\n \"mj-navbar\": [\n \"align\", \"base-url\", \"hamburger\", \"ico-align\", \"ico-close\", \"ico-color\", \"ico-font-family\",\n \"ico-font-size\", \"ico-line-height\", \"ico-open\", \"ico-padding\", \"ico-padding-bottom\",\n \"ico-padding-left\", \"ico-padding-right\", \"ico-padding-top\", \"ico-text-decoration\",\n \"ico-text-transform\", \"padding\", \"padding-bottom\", \"padding-left\", \"padding-right\",\n \"padding-top\",\n ],\n \"mj-navbar-link\": [\n \"color\", \"font-family\", \"font-size\", \"font-style\", \"font-weight\", \"href\", \"letter-spacing\",\n \"line-height\", \"name\", \"padding\", \"padding-bottom\", \"padding-left\", \"padding-right\",\n \"padding-top\", \"rel\", \"target\", \"text-decoration\", \"text-transform\",\n ],\n};\n\n// Accepted on every tag by MJML's validator, plus GrapesJS's own `id` and `style` (the\n// plugin's style mirror), which it never serialises.\nconst ALWAYS_ALLOWED = new Set([\"mj-class\", \"css-class\", \"id\", \"style\"]);\n\n// A start tag, with quoted values read whole so a `>` inside one does not end it; and one\n// attribute in it, with its value, so a value's own text is never taken for an attribute.\nconst START_TAG = /<[a-z][^\\s/>]*(?:[^>\"']|\"[^\"]*\"|'[^']*')*>/gi;\nconst ATTRIBUTE = /\\s+([^\\s\"'>/=]+)(?:\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s\"'>]+))?/g;\n\n/**\n * The MJML without `data-gjs-*` attributes, which GrapesJS reads as properties of the element\n * rather than attributes: its layer name and icon among them, which it writes into the page\n * as markup. Strict MJML does not look inside a text's HTML, so the agent can write them too.\n * Only attributes are touched; text that mentions one is left as it is.\n */\nexport function withoutEditorProps(mjml: string): string {\n return mjml.replace(START_TAG, (tag) =>\n tag.replace(ATTRIBUTE, (attribute, name: string) =>\n name.toLowerCase().startsWith(\"data-gjs-\") ? \"\" : attribute,\n ),\n );\n}\n\n/**\n * The MJML with every self-closed `<mj-… />` written as an open and a close tag. GrapesJS\n * parses MJML as HTML, where `/>` does not close a custom element, so whatever follows an\n * `<mj-image />` was nested inside it: valid MJML in, MJML the agent's strict compile rejects\n * out.\n */\nexport function withClosedTags(mjml: string): string {\n return mjml.replace(START_TAG, (tag) => {\n const selfClosed = /^<(mj-[\\w-]+)([\\s\\S]*?)\\s*\\/>$/i.exec(tag);\n return selfClosed ? `<${selfClosed[1]}${selfClosed[2]}></${selfClosed[1]}>` : tag;\n });\n}\n\n// Comments are matched to be skipped: a table one mentions is not a table.\nconst TABLE =\n /<!--[\\s\\S]*?(?:-->|$)|(<mj-table\\b(?:[^>\"']|\"[^\"]*\"|'[^']*')*>)((?:<!--[\\s\\S]*?-->|(?!<!--)[\\s\\S])*?)(<\\/mj-table\\s*>)/gi;\n\n/**\n * The MJML with each mj-table's rows inside a `<template>`. Parsed as HTML, rows outside a\n * table are dropped and only their text kept; a template keeps them for the mj-table type.\n */\nexport function withTableRowsKept(mjml: string): string {\n return mjml.replace(TABLE, (match, open?: string, rows?: string, close?: string) =>\n open ? `${open}<template>${rows}</template>${close}` : match,\n );\n}\n\n/**\n * The MJML GrapesJS is given for a document, and whether it had to be repaired. Closing a\n * self-closed element or holding a table's rows is not a repair: it is the same MJML.\n */\nexport function sourceForEditor(mjml: string): { mjml: string; repaired: boolean } {\n const cleaned = withoutEditorProps(mjml);\n return { mjml: withTableRowsKept(withClosedTags(cleaned)), repaired: cleaned !== mjml };\n}\n\n/** The attributes MJML would reject on `tag`; none for a tag the table does not cover. */\nexport function illegalAttributes(tag: string, attributes: Record<string, unknown>): string[] {\n const allowed = ALLOWED_ATTRIBUTES[tag];\n if (!allowed) return [];\n return Object.keys(attributes).filter((a) => !ALWAYS_ALLOWED.has(a) && !allowed.includes(a));\n}\n\n/** The colour names MJML accepts, as mjml-core 4.18 lists them: CSS's, plus `inherit`. */\n// prettier-ignore\nexport const NAMED_COLORS: ReadonlySet<string> = new Set([\n \"aliceblue\", \"antiquewhite\", \"aqua\", \"aquamarine\", \"azure\", \"beige\", \"bisque\", \"black\",\n \"blanchedalmond\", \"blue\", \"blueviolet\", \"brown\", \"burlywood\", \"cadetblue\", \"chartreuse\",\n \"chocolate\", \"coral\", \"cornflowerblue\", \"cornsilk\", \"crimson\", \"cyan\", \"darkblue\", \"darkcyan\",\n \"darkgoldenrod\", \"darkgray\", \"darkgreen\", \"darkgrey\", \"darkkhaki\", \"darkmagenta\",\n \"darkolivegreen\", \"darkorange\", \"darkorchid\", \"darkred\", \"darksalmon\", \"darkseagreen\",\n \"darkslateblue\", \"darkslategray\", \"darkslategrey\", \"darkturquoise\", \"darkviolet\", \"deeppink\",\n \"deepskyblue\", \"dimgray\", \"dimgrey\", \"dodgerblue\", \"firebrick\", \"floralwhite\", \"forestgreen\",\n \"fuchsia\", \"gainsboro\", \"ghostwhite\", \"gold\", \"goldenrod\", \"gray\", \"green\", \"greenyellow\",\n \"grey\", \"honeydew\", \"hotpink\", \"indianred\", \"indigo\", \"inherit\", \"ivory\", \"khaki\", \"lavender\",\n \"lavenderblush\", \"lawngreen\", \"lemonchiffon\", \"lightblue\", \"lightcoral\", \"lightcyan\",\n \"lightgoldenrodyellow\", \"lightgray\", \"lightgreen\", \"lightgrey\", \"lightpink\", \"lightsalmon\",\n \"lightseagreen\", \"lightskyblue\", \"lightslategray\", \"lightslategrey\", \"lightsteelblue\",\n \"lightyellow\", \"lime\", \"limegreen\", \"linen\", \"magenta\", \"maroon\", \"mediumaquamarine\",\n \"mediumblue\", \"mediumorchid\", \"mediumpurple\", \"mediumseagreen\", \"mediumslateblue\",\n \"mediumspringgreen\", \"mediumturquoise\", \"mediumvioletred\", \"midnightblue\", \"mintcream\",\n \"mistyrose\", \"moccasin\", \"navajowhite\", \"navy\", \"oldlace\", \"olive\", \"olivedrab\", \"orange\",\n \"orangered\", \"orchid\", \"palegoldenrod\", \"palegreen\", \"paleturquoise\", \"palevioletred\",\n \"papayawhip\", \"peachpuff\", \"peru\", \"pink\", \"plum\", \"powderblue\", \"purple\", \"rebeccapurple\",\n \"red\", \"rosybrown\", \"royalblue\", \"saddlebrown\", \"salmon\", \"sandybrown\", \"seagreen\", \"seashell\",\n \"sienna\", \"silver\", \"skyblue\", \"slateblue\", \"slategray\", \"slategrey\", \"snow\", \"springgreen\",\n \"steelblue\", \"tan\", \"teal\", \"thistle\", \"tomato\", \"transparent\", \"turquoise\", \"violet\", \"wheat\",\n \"white\", \"whitesmoke\", \"yellow\", \"yellowgreen\",\n]);\n","\"use client\";\n\n/**\n * The control for image fields in Settings, such as a section's `background-url`: the image\n * itself, opening the same picker, with the gallery, as an `mj-image` does.\n */\n\nimport { ImageIcon, X } from \"lucide-react\";\n\nimport type { EditorLabels } from \"../../labels.js\";\n\nexport default function ImageField({\n value,\n labels,\n onChoose,\n onClear,\n}: {\n value: string;\n labels: EditorLabels;\n onChoose: () => void;\n onClear: () => void;\n}) {\n const url = imageUrl(value);\n return (\n <div className=\"relative\">\n <button\n type=\"button\"\n onClick={onChoose}\n title={labels.chooseImage}\n className=\"group relative block w-full overflow-hidden rounded-md border border-panel-border bg-panel-elevated outline-none focus-visible:ring-2 focus-visible:ring-brand\"\n >\n {url ? (\n <img src={url} alt=\"\" className=\"h-24 w-full bg-black/25 object-contain\" />\n ) : (\n <span className=\"flex h-16 flex-col items-center justify-center gap-1 text-xs text-panel-muted-fg\">\n <ImageIcon className=\"size-5\" />\n {labels.chooseImage}\n </span>\n )}\n {url && (\n <span className=\"absolute inset-0 flex items-center justify-center bg-black/50 text-xs font-medium text-white opacity-0 transition group-hover:opacity-100\">\n {labels.chooseImage}\n </span>\n )}\n </button>\n {value && (\n <button\n type=\"button\"\n onClick={onClear}\n title={labels.imageFieldRemove}\n aria-label={labels.imageFieldRemove}\n className=\"absolute top-1 right-1 flex size-5 items-center justify-center rounded bg-black/60 text-white hover:bg-black/80\"\n >\n <X className=\"size-3\" />\n </button>\n )}\n </div>\n );\n}\n\n/**\n * A bare URL (MJML attributes) or `url(\"…\")` (CSS) to the URL. Anything else — `none`, a\n * gradient or another CSS image function — to null, as there is no image to show.\n */\nexport function imageUrl(value: string): string | null {\n const v = value.trim();\n if (!v || v === \"none\") return null;\n const css = /^url\\(\\s*(['\"]?)(.*?)\\1\\s*\\)$/i.exec(v);\n if (css) return css[2] || null;\n return /^[a-z-]+\\(/i.test(v) ? null : v;\n}\n","/**\n * The fields the Settings tab offers per MJML tag, in display order.\n *\n * Every attribute, option and unit here must pass MJML's strict validation, which the agent\n * runs on the whole document at every write; `schema.test.ts` compiles each one.\n */\n\nimport type { Field, Option, Unit } from \"./types.js\";\n\nconst PX: readonly Unit[] = [\"px\"];\nconst PX_PCT: readonly Unit[] = [\"px\", \"%\"];\nconst LINE_HEIGHT: readonly Unit[] = [\"\", \"px\", \"%\"];\nconst LETTER_SPACING: readonly Unit[] = [\"px\", \"em\"];\n\nconst ALIGN: readonly Option[] = [\n { value: \"left\", label: \"alignLeft\" },\n { value: \"center\", label: \"alignCenter\" },\n { value: \"right\", label: \"alignRight\" },\n];\n\nconst VERTICAL_ALIGN: readonly Option[] = [\n { value: \"top\", label: \"alignTop\" },\n { value: \"middle\", label: \"alignMiddle\" },\n { value: \"bottom\", label: \"alignBottom\" },\n];\n\nconst FONTS: readonly Option[] = [\n { value: \"Ubuntu, Helvetica, Arial, sans-serif\", label: \"Ubuntu\" },\n { value: \"Arial, Helvetica, sans-serif\", label: \"Arial\" },\n { value: \"Helvetica, Arial, sans-serif\", label: \"Helvetica\" },\n { value: \"Verdana, Geneva, sans-serif\", label: \"Verdana\" },\n { value: \"Tahoma, Geneva, sans-serif\", label: \"Tahoma\" },\n { value: \"'Trebuchet MS', Helvetica, sans-serif\", label: \"Trebuchet MS\" },\n { value: \"Georgia, 'Times New Roman', serif\", label: \"Georgia\" },\n { value: \"'Times New Roman', Times, serif\", label: \"Times New Roman\" },\n { value: \"'Courier New', Courier, monospace\", label: \"Courier New\" },\n];\n\n// Keywords at both ends because MJML's own defaults are `normal`; agents' `400`/`700` show\n// as values the select does not list.\nconst WEIGHTS: readonly Option[] = [\n { value: \"normal\", label: \"weightRegular\" },\n { value: \"500\", label: \"weightMedium\" },\n { value: \"600\", label: \"weightSemibold\" },\n { value: \"bold\", label: \"weightBold\" },\n];\n\nconst TEXT_TRANSFORM: readonly Option[] = [\n { value: \"none\", label: \"caseNone\" },\n { value: \"uppercase\", label: \"caseUpper\" },\n { value: \"lowercase\", label: \"caseLower\" },\n { value: \"capitalize\", label: \"caseCapitalize\" },\n];\n\nconst TARGET: readonly Option[] = [\n { value: \"_blank\", label: \"targetNewTab\" },\n { value: \"_self\", label: \"targetSameTab\" },\n];\n\nconst BACKGROUND_POSITION: readonly Option[] = [\n { value: \"top left\", label: \"positionTopLeft\" },\n { value: \"top center\", label: \"positionTopCenter\" },\n { value: \"top right\", label: \"positionTopRight\" },\n { value: \"center left\", label: \"positionCenterLeft\" },\n { value: \"center center\", label: \"positionCenter\" },\n { value: \"center right\", label: \"positionCenterRight\" },\n { value: \"bottom left\", label: \"positionBottomLeft\" },\n { value: \"bottom center\", label: \"positionBottomCenter\" },\n { value: \"bottom right\", label: \"positionBottomRight\" },\n];\n\nexport const NETWORKS: readonly Option[] = [\n { value: \"facebook\", label: \"Facebook\" },\n { value: \"instagram\", label: \"Instagram\" },\n { value: \"x\", label: \"X\" },\n { value: \"linkedin\", label: \"LinkedIn\" },\n { value: \"youtube\", label: \"YouTube\" },\n { value: \"pinterest\", label: \"Pinterest\" },\n { value: \"github\", label: \"GitHub\" },\n { value: \"web\", label: \"networkWebsite\" },\n { value: \"snapchat\", label: \"Snapchat\" },\n { value: \"vimeo\", label: \"Vimeo\" },\n { value: \"medium\", label: \"Medium\" },\n { value: \"dribbble\", label: \"Dribbble\" },\n { value: \"soundcloud\", label: \"SoundCloud\" },\n { value: \"tumblr\", label: \"Tumblr\" },\n { value: \"xing\", label: \"Xing\" },\n { value: \"custom\", label: \"networkCustom\" },\n];\n\nconst hasBackgroundImage = (a: Readonly<Record<string, string>>) => !!a[\"background-url\"];\n\n/** Shared by mj-section and mj-wrapper, whose background and box attributes are the same. */\nconst SECTION_FIELDS: readonly Field[] = [\n {\n attr: \"full-width\",\n label: \"fullWidth\",\n group: \"layout\",\n control: { type: \"toggle\", on: \"full-width\" },\n },\n {\n attr: \"padding\",\n label: \"padding\",\n group: \"spacing\",\n control: { type: \"box\", units: PX_PCT },\n default: \"20px 0\",\n },\n {\n attr: \"background-color\",\n label: \"backgroundColor\",\n group: \"style\",\n control: { type: \"color\" },\n },\n { attr: \"background-url\", label: \"backgroundImage\", group: \"style\", control: { type: \"image\" } },\n {\n attr: \"background-size\",\n label: \"backgroundSize\",\n group: \"style\",\n control: {\n type: \"segmented\",\n options: [\n { value: \"cover\", label: \"sizeCover\" },\n { value: \"contain\", label: \"sizeContain\" },\n { value: \"auto\", label: \"sizeAuto\" },\n ],\n },\n default: \"auto\",\n when: hasBackgroundImage,\n },\n {\n attr: \"background-repeat\",\n label: \"backgroundRepeat\",\n group: \"style\",\n control: {\n type: \"segmented\",\n options: [\n { value: \"repeat\", label: \"repeatTile\" },\n { value: \"no-repeat\", label: \"repeatOnce\" },\n ],\n },\n default: \"repeat\",\n when: hasBackgroundImage,\n },\n {\n attr: \"background-position\",\n label: \"backgroundPosition\",\n group: \"style\",\n control: { type: \"select\", options: BACKGROUND_POSITION },\n default: \"top center\",\n when: hasBackgroundImage,\n },\n {\n attr: \"border-radius\",\n label: \"cornerRadius\",\n group: \"style\",\n control: { type: \"length\", units: PX_PCT },\n },\n];\n\n// prettier-ignore\nexport const SCHEMA: Readonly<Record<string, readonly Field[]>> = {\n \"mj-body\": [\n { attr: \"width\", label: \"contentWidth\", group: \"layout\", control: { type: \"length\", units: PX }, default: \"600px\" },\n { attr: \"background-color\", label: \"pageBackground\", group: \"style\", control: { type: \"color\" } },\n ],\n \"mj-wrapper\": [\n ...SECTION_FIELDS,\n { attr: \"gap\", label: \"gap\", group: \"advanced\", control: { type: \"length\", units: PX } },\n { attr: \"border\", label: \"border\", group: \"advanced\", control: { type: \"text\", placeholder: \"1px solid #cccccc\" } },\n ],\n \"mj-section\": [\n ...SECTION_FIELDS,\n { attr: \"text-align\", label: \"alignColumns\", group: \"advanced\", control: { type: \"segmented\", options: ALIGN }, default: \"center\" },\n { attr: \"direction\", label: \"reverseColumns\", group: \"advanced\", control: { type: \"toggle\", on: \"rtl\" } },\n { attr: \"border\", label: \"border\", group: \"advanced\", control: { type: \"text\", placeholder: \"1px solid #cccccc\" } },\n ],\n \"mj-column\": [\n { attr: \"vertical-align\", label: \"verticalAlign\", group: \"layout\", control: { type: \"segmented\", options: VERTICAL_ALIGN }, default: \"top\" },\n { attr: \"padding\", label: \"padding\", group: \"spacing\", control: { type: \"box\", units: PX_PCT } },\n { attr: \"background-color\", label: \"backgroundColor\", group: \"style\", control: { type: \"color\" } },\n { attr: \"border-radius\", label: \"cornerRadius\", group: \"style\", control: { type: \"length\", units: PX_PCT } },\n { attr: \"width\", label: \"width\", group: \"advanced\", control: { type: \"length\", units: PX_PCT } },\n { attr: \"inner-background-color\", label: \"innerBackground\", group: \"advanced\", control: { type: \"color\" } },\n { attr: \"inner-border-radius\", label: \"innerCornerRadius\", group: \"advanced\", control: { type: \"length\", units: PX_PCT } },\n { attr: \"border\", label: \"border\", group: \"advanced\", control: { type: \"text\", placeholder: \"1px solid #cccccc\" } },\n { attr: \"inner-border\", label: \"innerBorder\", group: \"advanced\", control: { type: \"text\", placeholder: \"1px solid #cccccc\" } },\n ],\n \"mj-text\": [\n {\n attr: \"align\",\n label: \"align\",\n group: \"layout\",\n control: { type: \"segmented\", options: [...ALIGN, { value: \"justify\", label: \"alignJustify\" }] },\n default: \"left\",\n },\n { attr: \"padding\", label: \"padding\", group: \"spacing\", control: { type: \"box\", units: PX_PCT }, default: \"10px 25px\" },\n { attr: \"font-family\", label: \"font\", group: \"style\", control: { type: \"select\", options: FONTS }, default: \"Ubuntu, Helvetica, Arial, sans-serif\" },\n { attr: \"font-size\", label: \"fontSize\", group: \"style\", control: { type: \"length\", units: PX }, default: \"13px\" },\n { attr: \"font-weight\", label: \"fontWeight\", group: \"style\", control: { type: \"select\", options: WEIGHTS } },\n { attr: \"color\", label: \"textColor\", group: \"style\", control: { type: \"color\" }, default: \"#000000\" },\n { attr: \"line-height\", label: \"lineHeight\", group: \"style\", control: { type: \"length\", units: LINE_HEIGHT }, default: \"1\" },\n { attr: \"container-background-color\", label: \"blockBackground\", group: \"style\", control: { type: \"color\" } },\n { attr: \"letter-spacing\", label: \"letterSpacing\", group: \"advanced\", control: { type: \"length\", units: LETTER_SPACING, negative: true } },\n { attr: \"text-transform\", label: \"textTransform\", group: \"advanced\", control: { type: \"select\", options: TEXT_TRANSFORM } },\n ],\n \"mj-button\": [\n { attr: \"href\", label: \"link\", group: \"content\", control: { type: \"link\" } },\n { attr: \"align\", label: \"align\", group: \"layout\", control: { type: \"segmented\", options: ALIGN }, default: \"center\" },\n { attr: \"inner-padding\", label: \"buttonPadding\", group: \"spacing\", control: { type: \"box\", units: PX_PCT }, default: \"10px 25px\" },\n { attr: \"padding\", label: \"spaceAround\", group: \"spacing\", control: { type: \"box\", units: PX_PCT }, default: \"10px 25px\" },\n { attr: \"background-color\", label: \"buttonColor\", group: \"style\", control: { type: \"color\" }, default: \"#414141\" },\n { attr: \"color\", label: \"textColor\", group: \"style\", control: { type: \"color\" }, default: \"#ffffff\" },\n { attr: \"font-size\", label: \"fontSize\", group: \"style\", control: { type: \"length\", units: PX }, default: \"13px\" },\n { attr: \"border-radius\", label: \"cornerRadius\", group: \"style\", control: { type: \"length\", units: PX_PCT }, default: \"3px\" },\n { attr: \"width\", label: \"width\", group: \"advanced\", control: { type: \"length\", units: PX_PCT } },\n { attr: \"font-family\", label: \"font\", group: \"advanced\", control: { type: \"select\", options: FONTS }, default: \"Ubuntu, Helvetica, Arial, sans-serif\" },\n { attr: \"font-weight\", label: \"fontWeight\", group: \"advanced\", control: { type: \"select\", options: WEIGHTS }, default: \"normal\" },\n { attr: \"target\", label: \"opensIn\", group: \"advanced\", control: { type: \"select\", options: TARGET }, default: \"_blank\" },\n { attr: \"title\", label: \"tooltip\", group: \"advanced\", control: { type: \"text\" } },\n { attr: \"rel\", label: \"rel\", group: \"advanced\", control: { type: \"text\", placeholder: \"noopener\" } },\n { attr: \"container-background-color\", label: \"blockBackground\", group: \"advanced\", control: { type: \"color\" } },\n { attr: \"border\", label: \"border\", group: \"advanced\", control: { type: \"text\", placeholder: \"1px solid #cccccc\" }, default: \"none\" },\n { attr: \"letter-spacing\", label: \"letterSpacing\", group: \"advanced\", control: { type: \"length\", units: LETTER_SPACING, negative: true } },\n { attr: \"text-transform\", label: \"textTransform\", group: \"advanced\", control: { type: \"select\", options: TEXT_TRANSFORM }, default: \"none\" },\n { attr: \"line-height\", label: \"lineHeight\", group: \"advanced\", control: { type: \"length\", units: LINE_HEIGHT }, default: \"120%\" },\n ],\n \"mj-image\": [\n { attr: \"src\", label: \"image\", group: \"content\", control: { type: \"image\" } },\n { attr: \"alt\", label: \"altText\", group: \"content\", control: { type: \"text\" } },\n { attr: \"href\", label: \"link\", group: \"content\", control: { type: \"link\" } },\n { attr: \"width\", label: \"width\", group: \"layout\", control: { type: \"length\", units: PX } },\n { attr: \"align\", label: \"align\", group: \"layout\", control: { type: \"segmented\", options: ALIGN }, default: \"center\" },\n { attr: \"fluid-on-mobile\", label: \"fluidOnMobile\", group: \"layout\", control: { type: \"toggle\", on: \"true\" } },\n { attr: \"padding\", label: \"padding\", group: \"spacing\", control: { type: \"box\", units: PX_PCT }, default: \"10px 25px\" },\n { attr: \"border-radius\", label: \"cornerRadius\", group: \"style\", control: { type: \"length\", units: PX_PCT } },\n { attr: \"target\", label: \"opensIn\", group: \"advanced\", control: { type: \"select\", options: TARGET }, default: \"_blank\" },\n { attr: \"title\", label: \"tooltip\", group: \"advanced\", control: { type: \"text\" } },\n { attr: \"rel\", label: \"rel\", group: \"advanced\", control: { type: \"text\", placeholder: \"noopener\" } },\n { attr: \"border\", label: \"border\", group: \"advanced\", control: { type: \"text\", placeholder: \"1px solid #cccccc\" }, default: \"0\" },\n { attr: \"container-background-color\", label: \"blockBackground\", group: \"advanced\", control: { type: \"color\" } },\n ],\n \"mj-divider\": [\n { attr: \"width\", label: \"width\", group: \"layout\", control: { type: \"length\", units: PX_PCT }, default: \"100%\" },\n { attr: \"align\", label: \"align\", group: \"layout\", control: { type: \"segmented\", options: ALIGN }, default: \"center\" },\n { attr: \"padding\", label: \"padding\", group: \"spacing\", control: { type: \"box\", units: PX_PCT }, default: \"10px 25px\" },\n { attr: \"border-color\", label: \"lineColor\", group: \"style\", control: { type: \"color\" }, default: \"#000000\" },\n { attr: \"border-width\", label: \"thickness\", group: \"style\", control: { type: \"length\", units: PX }, default: \"4px\" },\n {\n attr: \"border-style\",\n label: \"lineStyle\",\n group: \"style\",\n control: {\n type: \"segmented\",\n options: [\n { value: \"solid\", label: \"lineSolid\" },\n { value: \"dashed\", label: \"lineDashed\" },\n { value: \"dotted\", label: \"lineDotted\" },\n ],\n },\n default: \"solid\",\n },\n { attr: \"container-background-color\", label: \"blockBackground\", group: \"advanced\", control: { type: \"color\" } },\n ],\n \"mj-spacer\": [\n { attr: \"height\", label: \"height\", group: \"layout\", control: { type: \"length\", units: PX }, default: \"20px\" },\n { attr: \"container-background-color\", label: \"blockBackground\", group: \"advanced\", control: { type: \"color\" } },\n ],\n \"mj-social\": [\n {\n attr: \"mode\",\n label: \"socialMode\",\n group: \"layout\",\n control: {\n type: \"segmented\",\n options: [\n { value: \"horizontal\", label: \"modeHorizontal\" },\n { value: \"vertical\", label: \"modeVertical\" },\n ],\n },\n default: \"horizontal\",\n },\n { attr: \"align\", label: \"align\", group: \"layout\", control: { type: \"segmented\", options: ALIGN }, default: \"center\" },\n { attr: \"padding\", label: \"padding\", group: \"spacing\", control: { type: \"box\", units: PX_PCT }, default: \"10px 25px\" },\n { attr: \"inner-padding\", label: \"iconSpacing\", group: \"spacing\", control: { type: \"box\", units: PX_PCT } },\n { attr: \"icon-size\", label: \"iconSize\", group: \"style\", control: { type: \"length\", units: PX_PCT }, default: \"20px\" },\n // A single value: mj-social's border-radius is not a 4-side shorthand.\n { attr: \"border-radius\", label: \"cornerRadius\", group: \"style\", control: { type: \"length\", units: PX_PCT }, default: \"3px\" },\n { attr: \"font-family\", label: \"font\", group: \"advanced\", control: { type: \"select\", options: FONTS }, default: \"Ubuntu, Helvetica, Arial, sans-serif\" },\n { attr: \"font-size\", label: \"fontSize\", group: \"advanced\", control: { type: \"length\", units: PX }, default: \"13px\" },\n { attr: \"color\", label: \"textColor\", group: \"advanced\", control: { type: \"color\" }, default: \"#333333\" },\n { attr: \"line-height\", label: \"lineHeight\", group: \"advanced\", control: { type: \"length\", units: LINE_HEIGHT }, default: \"22px\" },\n { attr: \"container-background-color\", label: \"blockBackground\", group: \"advanced\", control: { type: \"color\" } },\n ],\n \"mj-social-element\": [\n { attr: \"name\", label: \"network\", group: \"content\", control: { type: \"network\", networks: NETWORKS } },\n { attr: \"href\", label: \"link\", group: \"content\", control: { type: \"link\" } },\n {\n attr: \"src\",\n label: \"customIcon\",\n group: \"content\",\n control: { type: \"image\" },\n when: (a) => (a.name ?? \"\").startsWith(\"custom\") || !!a.src,\n },\n { attr: \"alt\", label: \"altText\", group: \"content\", control: { type: \"text\" } },\n { attr: \"background-color\", label: \"iconColor\", group: \"style\", control: { type: \"color\" } },\n { attr: \"icon-size\", label: \"iconSize\", group: \"advanced\", control: { type: \"length\", units: PX_PCT } },\n { attr: \"border-radius\", label: \"cornerRadius\", group: \"advanced\", control: { type: \"length\", units: PX }, default: \"3px\" },\n { attr: \"padding\", label: \"padding\", group: \"advanced\", control: { type: \"box\", units: PX_PCT }, default: \"4px\" },\n { attr: \"icon-position\", label: \"iconPosition\", group: \"advanced\", control: { type: \"segmented\", options: [{ value: \"left\", label: \"alignLeft\" }, { value: \"right\", label: \"alignRight\" }] }, default: \"left\" },\n { attr: \"title\", label: \"tooltip\", group: \"advanced\", control: { type: \"text\" } },\n { attr: \"target\", label: \"opensIn\", group: \"advanced\", control: { type: \"select\", options: TARGET }, default: \"_blank\" },\n { attr: \"rel\", label: \"rel\", group: \"advanced\", control: { type: \"text\", placeholder: \"noopener\" } },\n ],\n \"mj-hero\": [\n { attr: \"background-url\", label: \"backgroundImage\", group: \"content\", control: { type: \"image\" } },\n {\n attr: \"mode\",\n label: \"heroMode\",\n group: \"content\",\n control: {\n type: \"segmented\",\n options: [\n { value: \"fixed-height\", label: \"heroFixed\" },\n { value: \"fluid-height\", label: \"heroFluid\" },\n ],\n },\n default: \"fixed-height\",\n },\n {\n attr: \"height\",\n label: \"height\",\n group: \"layout\",\n control: { type: \"length\", units: PX_PCT },\n default: \"0px\",\n when: (a) => (a.mode ?? \"fixed-height\") === \"fixed-height\",\n },\n {\n attr: \"background-width\",\n label: \"backgroundWidth\",\n group: \"layout\",\n control: { type: \"length\", units: PX_PCT },\n when: (a) => a.mode === \"fluid-height\",\n },\n {\n attr: \"background-height\",\n label: \"backgroundHeight\",\n group: \"layout\",\n control: { type: \"length\", units: PX_PCT },\n when: (a) => a.mode === \"fluid-height\",\n },\n { attr: \"vertical-align\", label: \"verticalAlign\", group: \"layout\", control: { type: \"segmented\", options: VERTICAL_ALIGN }, default: \"top\" },\n { attr: \"background-position\", label: \"backgroundPosition\", group: \"layout\", control: { type: \"select\", options: BACKGROUND_POSITION }, default: \"center center\" },\n { attr: \"padding\", label: \"padding\", group: \"spacing\", control: { type: \"box\", units: PX_PCT }, default: \"0px\" },\n { attr: \"background-color\", label: \"fallbackColor\", group: \"style\", control: { type: \"color\" }, default: \"#ffffff\" },\n { attr: \"border-radius\", label: \"cornerRadius\", group: \"style\", control: { type: \"length\", units: PX_PCT } },\n { attr: \"inner-padding\", label: \"contentPadding\", group: \"advanced\", control: { type: \"box\", units: PX_PCT } },\n { attr: \"inner-background-color\", label: \"contentBackground\", group: \"advanced\", control: { type: \"color\" } },\n ],\n \"mj-navbar\": [\n { attr: \"align\", label: \"align\", group: \"layout\", control: { type: \"segmented\", options: ALIGN }, default: \"center\" },\n { attr: \"hamburger\", label: \"hamburger\", group: \"layout\", control: { type: \"toggle\", on: \"hamburger\" } },\n { attr: \"padding\", label: \"padding\", group: \"spacing\", control: { type: \"box\", units: PX_PCT } },\n { attr: \"ico-color\", label: \"menuIconColor\", group: \"advanced\", control: { type: \"color\" }, default: \"#000000\", when: (a) => !!a.hamburger },\n { attr: \"ico-font-size\", label: \"menuIconSize\", group: \"advanced\", control: { type: \"length\", units: PX_PCT }, default: \"30px\", when: (a) => !!a.hamburger },\n { attr: \"ico-align\", label: \"menuIconAlign\", group: \"advanced\", control: { type: \"segmented\", options: ALIGN }, default: \"center\", when: (a) => !!a.hamburger },\n { attr: \"base-url\", label: \"baseUrl\", group: \"advanced\", control: { type: \"link\" } },\n ],\n \"mj-navbar-link\": [\n { attr: \"href\", label: \"link\", group: \"content\", control: { type: \"link\" } },\n { attr: \"padding\", label: \"padding\", group: \"spacing\", control: { type: \"box\", units: PX_PCT }, default: \"15px 10px\" },\n { attr: \"color\", label: \"textColor\", group: \"style\", control: { type: \"color\" }, default: \"#000000\" },\n { attr: \"font-family\", label: \"font\", group: \"style\", control: { type: \"select\", options: FONTS }, default: \"Ubuntu, Helvetica, Arial, sans-serif\" },\n { attr: \"font-size\", label: \"fontSize\", group: \"style\", control: { type: \"length\", units: PX }, default: \"13px\" },\n { attr: \"font-weight\", label: \"fontWeight\", group: \"style\", control: { type: \"select\", options: WEIGHTS }, default: \"normal\" },\n { attr: \"text-transform\", label: \"textTransform\", group: \"style\", control: { type: \"select\", options: TEXT_TRANSFORM }, default: \"uppercase\" },\n { attr: \"target\", label: \"opensIn\", group: \"advanced\", control: { type: \"select\", options: TARGET }, default: \"_blank\" },\n { attr: \"rel\", label: \"rel\", group: \"advanced\", control: { type: \"text\", placeholder: \"noopener\" } },\n { attr: \"letter-spacing\", label: \"letterSpacing\", group: \"advanced\", control: { type: \"length\", units: LETTER_SPACING, negative: true } },\n { attr: \"line-height\", label: \"lineHeight\", group: \"advanced\", control: { type: \"length\", units: LINE_HEIGHT }, default: \"22px\" },\n ],\n};\n","/**\n * The Layers tab: rows named by what they hold (\"Summer sale\", \"Shop now\") rather than by tag,\n * each with an icon for its kind. GrapesJS renders the tree; this only names the rows.\n */\n\nimport type { Component, Editor } from \"grapesjs\";\n\nimport type { EditorLabels } from \"../../labels.js\";\nimport { NETWORKS } from \"./inspector/schema.js\";\nimport { parseNetwork } from \"./inspector/values.js\";\n\nconst svg = (paths: string) =>\n `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">${paths}</svg>`;\n\n// Lucide icons, the set the rest of the editor uses.\nconst ICONS: Record<string, string> = {\n \"mj-wrapper\": svg(\n '<path d=\"M3 7V5a2 2 0 0 1 2-2h2\"/><path d=\"M17 3h2a2 2 0 0 1 2 2v2\"/><path d=\"M21 17v2a2 2 0 0 1-2 2h-2\"/><path d=\"M7 21H5a2 2 0 0 1-2-2v-2\"/><rect width=\"10\" height=\"10\" x=\"7\" y=\"7\" rx=\"1\"/>',\n ),\n \"mj-section\": svg('<rect width=\"20\" height=\"12\" x=\"2\" y=\"6\" rx=\"2\"/>'),\n \"mj-hero\": svg('<rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"/><path d=\"M3 9h18\"/>'),\n \"mj-group\": svg(\n '<rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"/><path d=\"M9 3v18\"/><path d=\"M15 3v18\"/>',\n ),\n \"mj-column\": svg('<rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"/><path d=\"M12 3v18\"/>'),\n \"mj-text\": svg('<path d=\"M4 7V4h16v3\"/><path d=\"M9 20h6\"/><path d=\"M12 4v16\"/>'),\n \"mj-image\": svg(\n '<rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"/><circle cx=\"9\" cy=\"9\" r=\"2\"/><path d=\"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21\"/>',\n ),\n \"mj-button\": svg('<rect width=\"20\" height=\"10\" x=\"2\" y=\"7\" rx=\"3\"/><path d=\"M8 12h8\"/>'),\n \"mj-divider\": svg('<path d=\"M5 12h14\"/>'),\n \"mj-spacer\": svg('<path d=\"M12 3v18\"/><path d=\"m8 17 4 4 4-4\"/><path d=\"m8 7 4-4 4 4\"/>'),\n \"mj-social\": svg(\n '<circle cx=\"18\" cy=\"5\" r=\"3\"/><circle cx=\"6\" cy=\"12\" r=\"3\"/><circle cx=\"18\" cy=\"19\" r=\"3\"/><path d=\"m8.59 13.51 6.83 3.98\"/><path d=\"m15.41 6.51-6.82 3.98\"/>',\n ),\n \"mj-social-element\": svg(\n '<circle cx=\"12\" cy=\"12\" r=\"4\"/><path d=\"M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-4 8\"/>',\n ),\n \"mj-navbar\": svg('<path d=\"M4 6h16\"/><path d=\"M4 12h16\"/><path d=\"M4 18h16\"/>'),\n \"mj-navbar-link\": svg(\n '<path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/>',\n ),\n \"mj-raw\": svg('<path d=\"m16 18 6-6-6-6\"/><path d=\"m8 6-6 6 6 6\"/>'),\n \"mj-table\": svg(\n '<rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"/><path d=\"M3 9h18\"/><path d=\"M3 15h18\"/><path d=\"M12 3v18\"/>',\n ),\n};\n\nfunction tagOf(c: Component): string {\n return String(c.get(\"tagName\") || c.get(\"type\") || \"\");\n}\n\n/**\n * The first line a reader sees of an element's content, most often its heading: tags dropped,\n * entities decoded. Without the line breaks a heading and its paragraph ran together.\n */\nexport function textOf(c: Component): string {\n // A template parses without running scripts or fetching images.\n const template = document.createElement(\"template\");\n template.innerHTML = c.getInnerHTML();\n template.content\n .querySelectorAll(\"br, p, div, li, tr, h1, h2, h3, h4, h5, h6\")\n .forEach((el) => el.after(\"\\n\"));\n const lines = (template.content.textContent ?? \"\").split(\"\\n\");\n const first = lines.map((l) => l.replace(/\\s+/g, \" \").trim()).find(Boolean) ?? \"\";\n return first.slice(0, 60);\n}\n\nfunction escapeHtml(s: string): string {\n return s.replace(/[&<>\"']/g, (ch) => `&#${ch.charCodeAt(0)};`);\n}\n\n/** A row's name: the element's own words where it has any, else what kind of element it is. */\nexport function layerName(c: Component, labels: EditorLabels): string {\n const tag = tagOf(c);\n const kind = labels.elementNames[tag] ?? tag.replace(/^mj-/, \"\");\n const attributes = c.getAttributes() as Record<string, string | undefined>;\n switch (tag) {\n case \"mj-text\":\n case \"mj-button\":\n case \"mj-navbar-link\":\n return textOf(c) || kind;\n case \"mj-image\":\n return attributes.alt?.trim() || kind;\n case \"mj-social-element\": {\n const { network } = parseNetwork(String(attributes.name ?? \"\"));\n const option = NETWORKS.find((o) => o.value === network && network !== \"custom\");\n return (\n textOf(c) || (option && (labels.inspectorLabels[option.label] ?? option.label)) || kind\n );\n }\n case \"mj-section\":\n case \"mj-wrapper\":\n case \"mj-hero\": {\n // A section is known by its first words: its heading, most often.\n let words = \"\";\n c.onAll((d) => {\n if (!words && d !== c && [\"mj-text\", \"mj-button\"].includes(tagOf(d))) words = textOf(d);\n });\n return words || kind;\n }\n case \"mj-column\": {\n const columns =\n c\n .parent()\n ?.components()\n .filter((s: Component) => tagOf(s) === \"mj-column\") ?? [];\n return columns.length > 1 ? `${kind} ${columns.indexOf(c) + 1}` : kind;\n }\n default:\n return kind;\n }\n}\n\n// Elements whose children are their content — a text's paragraphs, a button's words — and\n// not rows of their own.\nconst CONTENT = new Set([\"mj-text\", \"mj-button\", \"mj-navbar-link\", \"mj-social-element\", \"mj-raw\"]);\n\n/** The canvas badge, which keeps saying what kind of element is under the pointer. */\nexport function badgeLabel(labels: EditorLabels) {\n return (c: Component) => {\n const tag = tagOf(c);\n const icon = ICONS[tag] ? `<div class=\"gjs-badge__icon\">${ICONS[tag]}</div>` : \"\";\n const kind = labels.elementNames[tag] ?? tag.replace(/^mj-/, \"\");\n return `${icon}<div class=\"gjs-badge__name\">${escapeHtml(kind)}</div>`;\n };\n}\n\n/**\n * Names and icons for the mj-* types. The names live in the layers only: GrapesJS's own\n * renaming is turned off in the sidebar, as a name set there is not MJML and would be lost.\n */\nexport function setupLayerNames(editor: Editor, labels: EditorLabels) {\n // Not stored and not undoable: it is how the tree shows the element, not the element.\n const hideContent = (c: Component) =>\n c.onAll((d) => d !== c && d.set(\"layerable\", false, { avoidStore: true }));\n\n for (const type of editor.Components.getTypes()) {\n if (!type.id.startsWith(\"mj-\")) continue;\n editor.Components.addType(type.id, {\n model: {\n // Ours whatever the element says: GrapesJS writes it into the row's markup as it is.\n getIcon() {\n return ICONS[type.id] ?? \"\";\n },\n // GrapesJS writes the name into the row's markup unescaped, and it is document text.\n getName(this: Component) {\n return escapeHtml(layerName(this, labels));\n },\n ...(CONTENT.has(type.id) && {\n // Editing a text replaces its children, so they are hidden again as they arrive.\n init(this: Component) {\n hideContent(this);\n this.listenTo(this.components(), \"add reset\", () => hideContent(this));\n },\n }),\n },\n // Runs the plugin's own `init` as well.\n extendFn: [\"init\"],\n } as never);\n }\n\n // A name follows its content, and a section's follows its children, so after any change\n // every row is re-read, once per frame.\n let pending = false;\n editor.on(\"update component:add component:remove\", () => {\n if (pending) return;\n pending = true;\n requestAnimationFrame(() => {\n pending = false;\n editor.Layers.getRoot()?.onAll((c) => {\n const view = (c as { viewLayer?: { getInputName?: () => HTMLElement | null } }).viewLayer;\n const el = view?.getInputName?.();\n const name = layerName(c, labels);\n if (!el || el.textContent === name) return;\n el.textContent = name;\n el.parentElement?.setAttribute(\"title\", name);\n });\n });\n });\n}\n","\"use client\";\n\n/**\n * What an element holds, in its own settings: a section's column widths, and the links of a\n * navigation bar or social group, which are too small to pick out on the canvas.\n */\n\nimport type { Component, Editor } from \"grapesjs\";\nimport type { ReactNode } from \"react\";\nimport { AtSign, ChevronRight, Link2, Plus } from \"lucide-react\";\n\nimport type { EditorLabels } from \"../../../labels.js\";\nimport { cn } from \"../../../lib/utils\";\nimport { layerName } from \"../layers.js\";\nimport {\n addNavbarLink,\n addNetwork,\n COLUMN_RATIOS,\n columnsOf,\n currentRatio,\n setRatio,\n} from \"./structure.js\";\n\nfunction tagOf(c: Component): string {\n return String(c.get(\"tagName\") || c.get(\"type\") || \"\");\n}\n\nexport default function StructureSection({\n editor,\n component,\n labels,\n locked,\n}: {\n editor: Editor;\n component: Component;\n labels: EditorLabels;\n locked: boolean;\n}) {\n switch (tagOf(component)) {\n case \"mj-section\":\n return <ColumnWidths component={component} labels={labels} locked={locked} />;\n case \"mj-social\":\n return (\n <Children\n editor={editor}\n component={component}\n labels={labels}\n locked={locked}\n title={labels.socialNetworks}\n add={labels.addNetwork}\n icon={<AtSign className=\"size-3.5 shrink-0\" />}\n onAdd={() => editor.select(addNetwork(component))}\n />\n );\n case \"mj-navbar\":\n return (\n <Children\n editor={editor}\n component={component}\n labels={labels}\n locked={locked}\n title={labels.navbarLinks}\n add={labels.addLink}\n icon={<Link2 className=\"size-3.5 shrink-0\" />}\n onAdd={() => editor.select(addNavbarLink(component, labels.newLinkText))}\n />\n );\n default:\n return null;\n }\n}\n\nfunction Heading({ children }: { children: string }) {\n return (\n <h3 className=\"px-3 pb-1 text-[10px] font-semibold tracking-wider text-panel-muted-fg/80 uppercase\">\n {children}\n </h3>\n );\n}\n\nfunction ColumnWidths({\n component,\n labels,\n locked,\n}: {\n component: Component;\n labels: EditorLabels;\n locked: boolean;\n}) {\n const columns = columnsOf(component);\n const ratios = columns && COLUMN_RATIOS[columns.length];\n if (!columns || !ratios) return null;\n const current = currentRatio(columns);\n return (\n <section className=\"border-b border-panel-border/60 py-2\">\n <Heading>{labels.columnWidths}</Heading>\n <div className=\"flex gap-1.5 px-3 py-1\">\n {ratios.map((ratio) => {\n const name = labels.columnRatio(ratio.join(\":\"));\n const active = current?.join() === ratio.join();\n return (\n <button\n key={ratio.join()}\n type=\"button\"\n disabled={locked}\n aria-pressed={active}\n title={name}\n aria-label={name}\n onClick={() => !active && setRatio(columns, ratio)}\n className={cn(\n \"flex h-8 flex-1 items-center gap-0.5 rounded-md border px-1.5 transition-colors\",\n active\n ? \"border-brand bg-brand/15\"\n : \"border-panel-border bg-panel-elevated hover:border-panel-muted-fg\",\n )}\n >\n {ratio.map((part, i) => (\n <span\n key={i}\n style={{ flexGrow: part }}\n className={cn(\n \"h-4 basis-0 rounded-sm\",\n active ? \"bg-brand\" : \"bg-panel-muted-fg/50\",\n )}\n />\n ))}\n </button>\n );\n })}\n </div>\n </section>\n );\n}\n\nfunction Children({\n editor,\n component,\n labels,\n locked,\n title,\n add,\n icon,\n onAdd,\n}: {\n editor: Editor;\n component: Component;\n labels: EditorLabels;\n locked: boolean;\n title: string;\n add: string;\n icon: ReactNode;\n onAdd: () => void;\n}) {\n const children = component.components().models;\n return (\n <section className=\"border-b border-panel-border/60 py-2\">\n <Heading>{title}</Heading>\n <ul className=\"flex flex-col px-2\">\n {children.map((child) => (\n <li key={child.cid}>\n <button\n type=\"button\"\n onClick={() => editor.select(child)}\n className=\"group flex w-full items-center gap-2 rounded-md px-1.5 py-1 text-left text-xs text-panel-fg hover:bg-panel-hover\"\n >\n <span className=\"text-panel-muted-fg\">{icon}</span>\n <span className=\"min-w-0 flex-1 truncate\">{layerName(child, labels)}</span>\n <ChevronRight className=\"size-3 shrink-0 text-panel-muted-fg opacity-0 group-hover:opacity-100\" />\n </button>\n </li>\n ))}\n </ul>\n <button\n type=\"button\"\n disabled={locked}\n onClick={onAdd}\n className=\"mx-3 mt-1 flex items-center gap-1.5 rounded-md px-1 py-1 text-xs text-panel-muted-fg hover:text-panel-fg disabled:opacity-50\"\n >\n <Plus className=\"size-3.5\" />\n {add}\n </button>\n </section>\n );\n}\n","/** Changes to what an element holds rather than to its attributes: columns, links, networks. */\n\nimport type { Component } from \"grapesjs\";\n\nfunction tagOf(c: Component): string {\n return String(c.get(\"tagName\") || c.get(\"type\") || \"\");\n}\n\n/** Column proportions offered for a section of two or three columns; equal sets no widths. */\nexport const COLUMN_RATIOS: Readonly<Record<number, readonly (readonly number[])[]>> = {\n 2: [\n [1, 1],\n [1, 2],\n [2, 1],\n ],\n 3: [\n [1, 1, 1],\n [1, 2, 1],\n ],\n};\n\n/** A section's columns, when columns are all it holds; a column group is left alone. */\nexport function columnsOf(section: Component): Component[] | null {\n const children = section.components().models;\n return children.length > 0 && children.every((c) => tagOf(c) === \"mj-column\") ? children : null;\n}\n\n/** Percent widths for a ratio, to two decimals, or null where MJML's equal split does. */\nexport function ratioWidths(ratio: readonly number[]): string[] | null {\n if (ratio.every((r) => r === ratio[0])) return null;\n const total = ratio.reduce((a, b) => a + b, 0);\n return ratio.map((r) => `${Math.round((r / total) * 10000) / 100}%`);\n}\n\n/** The ratio the columns' widths already have, if it is one of the offered. */\nexport function currentRatio(columns: Component[]): readonly number[] | null {\n const widths = columns.map((c) => String(c.getAttributes().width ?? \"\"));\n return (\n COLUMN_RATIOS[columns.length]?.find((ratio) => {\n const want = ratioWidths(ratio);\n if (!want) return widths.every((w) => w === \"\");\n return widths.every(\n (w, i) => /%$/.test(w) && Math.abs(parseFloat(w) - parseFloat(want[i]!)) < 0.5,\n );\n }) ?? null\n );\n}\n\n/** Sets every column's width in one change, so it is one undo step. */\nexport function setRatio(columns: Component[], ratio: readonly number[]) {\n const widths = ratioWidths(ratio);\n columns.forEach((c, i) => {\n if (widths) c.addAttributes({ width: widths[i]! });\n else c.removeAttributes([\"width\"]);\n });\n}\n\n// Networks a new social link starts as, in order, each linking to the site until edited.\nconst PROFILE_URLS: Readonly<Record<string, string>> = {\n facebook: \"https://facebook.com/\",\n instagram: \"https://instagram.com/\",\n x: \"https://x.com/\",\n linkedin: \"https://linkedin.com/\",\n youtube: \"https://youtube.com/\",\n pinterest: \"https://pinterest.com/\",\n github: \"https://github.com/\",\n};\n\n/** Adds the first common network the group does not have yet, as a profile link. */\nexport function addNetwork(social: Component): Component {\n const present = new Set(\n social\n .components()\n .map((c: Component) => String(c.getAttributes().name ?? \"\").replace(/-noshare$/, \"\")),\n );\n const network = Object.keys(PROFILE_URLS).find((n) => !present.has(n)) ?? \"facebook\";\n // As markup: the plugin's types are recognised by tag, and a type alone renders a <div>.\n return social.append(\n `<mj-social-element name=\"${network}-noshare\" href=\"${PROFILE_URLS[network]}\"></mj-social-element>`,\n )[0]!;\n}\n\nexport function addNavbarLink(navbar: Component, text: string): Component {\n return navbar.append(`<mj-navbar-link>${escapeHtml(text)}</mj-navbar-link>`)[0]!;\n}\n\nfunction escapeHtml(s: string): string {\n return s.replace(/[&<>\"']/g, (ch) => `&#${ch.charCodeAt(0)};`);\n}\n","import type { Component, Editor } from \"grapesjs\";\n\nexport type WriteOptions = {\n /** A step of a drag: shown at once, recorded only when the drag ends. */\n partial?: boolean;\n /** Attributes to drop in the same change, such as longhands a shorthand replaces. */\n remove?: readonly string[];\n};\n\ntype Attributes = Record<string, unknown>;\n\nfunction same(a: Attributes, b: Attributes): boolean {\n const keys = Object.keys(a);\n return keys.length === Object.keys(b).length && keys.every((k) => k in b && a[k] === b[k]);\n}\n\n/**\n * Writes one element's MJML attributes. On mj-image `src` is a model property, which the\n * plugin writes over the attribute.\n *\n * Every write replaces the whole attribute set at once: the plugin mirrors attributes into a\n * style object and back, and a removal followed by an addition, made silently, came back\n * from that mirror with the removed attribute still in it.\n *\n * `blocked` is asked as the write lands, after any wait: an agent turn can lock the editor\n * while a text's typing is being synced.\n */\nexport function createWriter(\n editor: Editor,\n component: Component,\n blocked: () => boolean = () => false,\n) {\n const isImage = String(component.get(\"tagName\") || component.get(\"type\")) === \"mj-image\";\n // The attributes as MJML has them: without GrapesJS's `__p` marker and the plugin's style.\n const current = (): Attributes => {\n const { __p: _marker, style: _style, ...rest } = component.get(\"attributes\") as Attributes;\n return rest;\n };\n\n // The drag under way: its attribute and the attributes before its first step, which its\n // release is recorded as changing.\n let drag: { attr: string; start: Attributes } | null = null;\n\n // Records the attributes now as one change from `start`: the steps were silent, so the start\n // goes back silently first. None when they end where they began.\n const record = (start: Attributes, end: Attributes) => {\n component.setAttributes(start, { avoidStore: true });\n if (!same(end, start)) component.setAttributes(end);\n // A silent write leaves the `__p` marker on the attributes object, put there in place by\n // the plugin's mirror; a real change clears it, and when there was none it goes the same way.\n delete (component.get(\"attributes\") as Attributes).__p;\n };\n\n return async (attr: string, value: string, { partial, remove = [] }: WriteOptions = {}) => {\n // A write re-renders the element, which would drop text typed into it but not yet synced.\n if (editor.getEditing() === component) {\n const view = component.getView() as { syncContent?: () => Promise<void> } | undefined;\n await view?.syncContent?.();\n }\n if (blocked()) return;\n // Another field written mid-drag ends the drag first, so each keeps its own undo step.\n if (drag && drag.attr !== attr) {\n const { start } = drag;\n drag = null;\n record(start, current());\n }\n if (attr === \"src\" && isImage) return void component.set({ src: value });\n\n const next = current();\n for (const name of remove) delete next[name];\n if (value === \"\") delete next[attr];\n else next[attr] = value;\n\n if (partial) {\n drag ??= { attr, start: current() };\n component.setAttributes(next, { avoidStore: true });\n return;\n }\n const start = drag?.start ?? current();\n drag = null;\n record(start, next);\n };\n}\n","/**\n * Sections a host adds to the palette.\n *\n * A dropped block is ordinary MJML from then on, so it has to be MJML the agent's strict\n * compile accepts and the editor writes back unchanged: one bad block in the palette would\n * put an error into every email it is dropped in, and block every agent write to it.\n */\n\nimport grapesjs, { type Editor } from \"grapesjs\";\nimport grapesjsMJML from \"grapesjs-mjml\";\n\nimport { ID_RE } from \"./ids.js\";\nimport { tileAttributes } from \"./insert-block.js\";\nimport { isSafeLink, isSafeNavbarLink } from \"./inspector/values.js\";\nimport { withClosedTags } from \"./mjml-attributes.js\";\n\nexport type SectionBlock = {\n /** Unique, and not the id of a built-in block. */\n readonly id: string;\n /** Plain text. */\n readonly label: string;\n /** Exactly one `<mj-section>`, without `sec-*`/`obj-*` ids: those are added on drop. */\n readonly mjml: string;\n /** SVG markup for the tile, rendered as is. The palette paints it with `fill`, as it does\n * the built-in tiles, so draw with filled shapes. */\n readonly media?: string;\n};\n\n// Tags a dropped section may hold: what the editor keeps on a load and edits in Settings. Not\n// mj-table (its rows are kept, never edited), mj-hero (its content sits outside any\n// section, where the agent and comments cannot address it), accordion and carousel (the\n// editor can neither render nor edit them), mj-wrapper (it holds sections, and a block is\n// one) or mj-raw (HTML nobody edits here).\nconst EDITABLE_TAGS = new Set([\n \"mj-section\",\n \"mj-group\",\n \"mj-column\",\n \"mj-text\",\n \"mj-image\",\n \"mj-button\",\n \"mj-divider\",\n \"mj-spacer\",\n \"mj-social\",\n \"mj-social-element\",\n \"mj-navbar\",\n \"mj-navbar-link\",\n]);\n\n// The tags whose content is markup. Text anywhere else is dropped by MJML without an error.\nconst CONTENT_TAGS = new Set([\"mj-text\", \"mj-button\", \"mj-social-element\", \"mj-navbar-link\"]);\n\n// GrapesJS reads `data-gjs-*` as properties, which reach the page unescaped, and serialises\n// `__p` and `custom-name` from markup as they are.\nconst EDITOR_INTERNALS = /data-gjs-|__p\\b|custom-name/i;\n\n// Markup in a text that GrapesJS drops on a drop, so what was offered is not what lands.\nconst DROPPED_MARKUP = /<(?:script|style|link|meta|iframe|object|embed|form)\\b/i;\n\n// Mail clients block inline images, and the editor never inlines a file.\nconst INLINE_IMAGE =\n /\\b(?:src|srcset|background-url|icon)\\s*=\\s*(?:\"[^\"]*data:|'[^']*data:|data:)/i;\n\n// `<a/href=…>` is an href to a browser too.\nconst LINK_IN_MARKUP =\n /[\\s/\"'](?:xlink:)?(?:href|action|formaction)\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s>]+))/gi;\n\ntype MjmlNode = {\n tagName: string;\n attributes?: Record<string, string>;\n content?: string;\n children?: MjmlNode[];\n};\n\ntype MjmlError = { formattedMessage?: string; message?: string };\n\nlet validator: Editor | undefined;\n\n/** Why a block cannot be offered; empty when it can. */\nexport function blockProblems(\n mjml: string,\n editor: Editor = (validator ??= grapesjs.init({\n headless: true,\n storageManager: false,\n telemetry: false,\n plugins: [grapesjsMJML],\n })),\n): string[] {\n if (EDITOR_INTERNALS.test(mjml)) return [\"it contains GrapesJS's own attributes\"];\n if (INLINE_IMAGE.test(mjml)) return [\"it inlines an image as a data: URL\"];\n\n let tree: MjmlNode;\n try {\n tree = (\n editor.runCommand(\"mjml-code-to-html\", {\n mjml: `<mjml><mj-body>${withClosedTags(mjml)}</mj-body></mjml>`,\n validationLevel: \"strict\",\n }) as { json: MjmlNode }\n ).json;\n } catch (e) {\n const errors = (e as { errors?: MjmlError[] }).errors;\n if (!errors) throw e;\n return errors.map((error) => error.formattedMessage ?? error.message ?? String(error));\n }\n\n const problems: string[] = [];\n const top = tree.children?.find((c) => c.tagName === \"mj-body\")?.children ?? [];\n if (top.length !== 1 || top[0]!.tagName !== \"mj-section\") {\n problems.push(\"it is not exactly one mj-section\");\n }\n const visit = (node: MjmlNode, parent?: MjmlNode) => {\n const tag = node.tagName;\n const attributes = node.attributes ?? {};\n const content = node.content ?? \"\";\n if (!EDITABLE_TAGS.has(tag)) problems.push(`${tag} is not editable here`);\n const cssClass = attributes[\"css-class\"] ?? \"\";\n if (ID_RE.sec.test(cssClass) || ID_RE.obj.test(cssClass)) {\n problems.push(`${tag} carries a sec-* or obj-* id`);\n }\n // Defined in mj-head, which a block cannot bring.\n if (\"mj-class\" in attributes) problems.push(`${tag} uses mj-class`);\n const links = [attributes.href ?? \"\"];\n for (const match of content.matchAll(LINK_IN_MARKUP)) {\n links.push(match[1] ?? match[2] ?? match[3] ?? \"\");\n }\n const linked =\n tag === \"mj-navbar-link\"\n ? isSafeNavbarLink(parent?.attributes?.[\"base-url\"] ?? \"\", attributes.href ?? \"\")\n : true;\n if (!linked || !links.every(isSafeLink)) {\n problems.push(`${tag} has a link scheme mail must not carry`);\n }\n if (\n CONTENT_TAGS.has(tag) ? /<mj-/i.test(content) || DROPPED_MARKUP.test(content) : content.trim()\n ) {\n problems.push(`${tag} holds content the editor does not keep`);\n }\n node.children?.forEach((child) => visit(child, node));\n };\n top.forEach((node) => visit(node));\n return problems;\n}\n\nconst escapeHtml = (text: string) =>\n text.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\").replace(/\"/g, \"&quot;\");\n\n/** Adds the blocks that can be offered, and reports the rest to the developer. */\nexport function registerBlocks(\n editor: Editor,\n blocks: readonly SectionBlock[],\n category: string,\n media: string,\n) {\n for (const block of blocks) {\n const problems = editor.Blocks.get(block.id)\n ? [`the id is already taken`]\n : blockProblems(block.mjml, editor);\n if (problems.length > 0) {\n console.error(`Block \"${block.id}\" is left out of the palette: ${problems.join(\"; \")}`);\n continue;\n }\n editor.Blocks.add(block.id, {\n // GrapesJS writes the label into the tile as markup.\n label: escapeHtml(block.label),\n category,\n media: block.media ?? media,\n content: withClosedTags(block.mjml),\n attributes: tileAttributes(block.id),\n });\n }\n}\n","/**\n * The ids the agent addresses elements by: `sec-<id>` on a section and `obj-<id>` on an element\n * inside one, kept in `css-class` because the MJML validator rejects any other attribute.\n */\n\nimport type { Component } from \"grapesjs\";\n\n// A whole class token, as agent-core reads one: `promo-sec-a` is a host's class, not an id.\nexport const ID_RE = {\n sec: /(?:^|\\s)sec-([A-Za-z0-9_-]+)(?=\\s|$)/,\n obj: /(?:^|\\s)obj-([A-Za-z0-9_-]+)(?=\\s|$)/,\n} as const;\ntype Prefix = keyof typeof ID_RE;\n\nfunction idOf(c: Component, prefix: Prefix): string | null {\n return String(c.getAttributes()[\"css-class\"] ?? \"\").match(ID_RE[prefix])?.[1] ?? null;\n}\n\nconst newId = () => Math.random().toString(36).slice(2, 10);\n\nexport function sectionIdOf(c: Component): string | null {\n return idOf(c, \"sec\");\n}\n\nexport function addIdClass(c: Component, prefix: Prefix): string {\n const existing = idOf(c, prefix);\n if (existing) return existing;\n const cssClass = String(c.getAttributes()[\"css-class\"] ?? \"\");\n const id = newId();\n c.addAttributes({ \"css-class\": `${cssClass} ${prefix}-${id}`.trim() });\n return id;\n}\n\n/**\n * Gives an added subtree new ids wherever another element already has them. A duplicate or a\n * paste copies its original's `css-class`, and two sections answering to one `sec-*` make\n * comments and agent edits land on either.\n */\nexport function freshenCopiedIds(root: Component | undefined, added: Component) {\n const used = (prefix: Prefix, id: string, except: Component) => {\n let found = false;\n root?.onAll((o) => {\n if (o !== except && idOf(o, prefix) === id) found = true;\n });\n return found;\n };\n added.onAll((c) => {\n for (const prefix of [\"sec\", \"obj\"] as const) {\n const id = idOf(c, prefix);\n if (!id || !used(prefix, id, c)) continue;\n const cssClass = String(c.getAttributes()[\"css-class\"]);\n const fresh = cssClass.replace(ID_RE[prefix], (token) =>\n token.replace(`${prefix}-${id}`, `${prefix}-${newId()}`),\n );\n c.addAttributes({ \"css-class\": fresh });\n }\n });\n}\n","/** The palette from the keyboard: GrapesJS's tiles can only be dragged. */\n\nimport type { Block, Component, Editor } from \"grapesjs\";\n\n/** Enter or Space, once: not a held key's repeats, and not a shortcut with a modifier. */\nexport const addsBlock = (\n e: Pick<KeyboardEvent, \"key\" | \"repeat\" | \"ctrlKey\" | \"metaKey\" | \"altKey\">,\n) => (e.key === \"Enter\" || e.key === \" \") && !e.repeat && !e.ctrlKey && !e.metaKey && !e.altKey;\n\n/** Makes a tile focusable and names the block it adds; GrapesJS sets these on the tile. */\nexport const tileAttributes = (id: string) => ({ tabindex: \"0\", role: \"button\", \"data-block\": id });\n\nconst tagOf = (c: Component) => String(c.get(\"tagName\") ?? \"\");\n\nfunction closest(c: Component | undefined, tag: string): Component | undefined {\n for (let cur = c; cur; cur = cur.parent() ?? undefined) if (tagOf(cur) === tag) return cur;\n return undefined;\n}\n\n/** `c`'s ancestor, or itself, whose parent is `parent`. */\nfunction childOf(parent: Component, c: Component): Component {\n let cur = c;\n while (cur.parent() && cur.parent() !== parent) cur = cur.parent()!;\n return cur;\n}\n\n/**\n * Adds a block where a keyboard user means it: a section after the selected one, or last; an\n * element after the selected one or into the selected column, else in a section of its own.\n * Then selects it and, as a drop does, activates it (the image picker opens for an image).\n */\nexport function insertBlock(editor: Editor, block: Block): Component | undefined {\n const content = block.getContent();\n let body: Component | undefined;\n editor.getWrapper()?.onAll((c) => {\n if (!body && tagOf(c) === \"mj-body\") body = c;\n });\n if (typeof content !== \"string\" || !body) return undefined;\n\n const selected = editor.getSelected();\n const section = closest(selected, \"mj-section\");\n // Beside the selected section, so one inside an mj-wrapper stays in it.\n const sections = section?.parent() ?? body;\n const afterSection = section ? { at: section.index() + 1 } : {};\n const column = closest(selected, \"mj-column\");\n let added: Component | undefined;\n if (/^\\s*<mj-section\\b/i.test(content)) {\n added = sections.append(content, afterSection)[0];\n } else if (column && selected) {\n const at = selected === column ? {} : { at: childOf(column, selected).index() + 1 };\n added = column.append(content, at)[0];\n } else {\n const [wrapper] = sections.append(\n `<mj-section><mj-column>${content}</mj-column></mj-section>`,\n afterSection,\n );\n added = wrapper?.components().at(0)?.components().at(0);\n }\n if (!added) return undefined;\n\n editor.select(added);\n if (block.get(\"activate\")) added.getView()?.onActive(undefined as never);\n return added;\n}\n","/** The palette's own blocks: grapesjs-mjml's, with the content its defaults get wrong. */\n\nimport type { EditorLabels } from \"../../labels.js\";\nimport { tileAttributes } from \"./insert-block.js\";\n\n// Social and navigation children are only valid inside their parent; hero and wrapper are\n// banned from editable templates by agent-core (a hero gets no `sec-*` id, so the agent cannot\n// address it); raw HTML is out of place for the people this editor serves.\nexport const BUILTIN_BLOCKS = [\n \"mj-1-column\",\n \"mj-2-columns\",\n \"mj-3-columns\",\n \"mj-text\",\n \"mj-image\",\n \"mj-button\",\n \"mj-divider\",\n \"mj-spacer\",\n \"mj-social-group\",\n \"mj-navbar\",\n];\nconst LAYOUT_BLOCKS = new Set([\"mj-1-column\", \"mj-2-columns\", \"mj-3-columns\"]);\n\nconst CONTENT: Record<string, string> = {\n // The plugin's version links Google+ and shares the page: a bare network name makes the\n // icon open a \"share this link\" dialog, while `-noshare` links to the profile a footer\n // means. Without `alt` each link is an unnamed image to a screen reader.\n \"mj-social-group\": `<mj-social icon-size=\"24px\" mode=\"horizontal\">\n <mj-social-element name=\"facebook-noshare\" href=\"https://facebook.com/\" alt=\"Facebook\"></mj-social-element>\n <mj-social-element name=\"instagram-noshare\" href=\"https://instagram.com/\" alt=\"Instagram\"></mj-social-element>\n <mj-social-element name=\"x-noshare\" href=\"https://x.com/\" alt=\"X\"></mj-social-element>\n</mj-social>`,\n // The plugin's sample is a via.placeholder.com picture, stored in the email and loaded by\n // every reader's mail client. Dropping one opens the image picker instead.\n \"mj-image\": \"<mj-image></mj-image>\",\n};\n\n/** What grapesjs-mjml's `block` option returns for a built-in block. */\nexport function builtinBlock(labels: EditorLabels) {\n return (id: string) => ({\n label: labels.blockLabels[id] ?? id,\n // By id: a regex on the label broke as soon as a host translated it.\n category: LAYOUT_BLOCKS.has(id) ? labels.blockCategoryLayout : labels.blockCategoryContent,\n ...(id in CONTENT && { content: CONTENT[id] }),\n attributes: tileAttributes(id),\n });\n}\n\n/** Shows an image without a picture yet as a box to click, in the canvas only. */\nexport const CANVAS_CSS =\n 'img:not([src]), img[src=\"\"] { min-height: 120px; background: #f4f4f5; outline: 1px dashed #a1a1aa; outline-offset: -1px; }';\n","/**\n * An mj-table, which grapesjs-mjml has no type for. Its markup is kept as it was given and\n * never edited: parsed as HTML, rows outside a table were dropped and only their text kept,\n * so the first edit to an email with a table stored it flattened (see `withTableRowsKept`).\n */\n\nimport { isSafeLink } from \"@mjml-agent-editor/core\";\nimport type { Component, Editor } from \"grapesjs\";\n\n// What the agent's guard refuses too, and a nested template, whose content no query reaches.\nconst DROPPED =\n \"script, style, link, iframe, frame, object, embed, applet, base, meta, animate, set, svg, math, template\";\nconst LINK_ATTRIBUTES = new Set([\"href\", \"xlink:href\", \"action\", \"formaction\"]);\n\n/**\n * What GrapesJS's parser removes everywhere else, removed from the rows too: it never looks\n * inside a template. Scripts and embeds, `on…` handlers, links with another scheme.\n */\nfunction cleanRows(rows: DocumentFragment) {\n rows.querySelectorAll(DROPPED).forEach((el) => el.remove());\n rows.querySelectorAll(\"*\").forEach((el) => {\n for (const { name, value } of [...el.attributes]) {\n const lower = name.toLowerCase();\n const script = /^(java|vb)script:/i.test(value.replace(/[\\u0000-\\u0020]/g, \"\"));\n if (lower.startsWith(\"on\") || script || (LINK_ATTRIBUTES.has(lower) && !isSafeLink(value))) {\n el.removeAttribute(name);\n }\n }\n });\n}\n\n// A column's children are table rows in the canvas, as the plugin renders its own.\nconst ROW_STYLE = \"pointer-events: all; display: table; width: 100%;\";\n\n/**\n * The table as the canvas shows it: its rows and cells as text, aligned as written. Built from\n * an inert template rather than written as HTML, so nothing in the cells runs or loads.\n */\nexport function tablePreview(doc: Document, attributes: Record<string, unknown>, rows: string) {\n const attr = (name: string, fallback: string) => String(attributes[name] ?? fallback);\n const template = doc.createElement(\"template\");\n template.innerHTML = `<table>${rows}</table>`;\n\n const table = doc.createElement(\"table\");\n table.setAttribute(\"cellpadding\", String(parseInt(attr(\"cellpadding\", \"0\"), 10) || 0));\n table.setAttribute(\"cellspacing\", String(parseInt(attr(\"cellspacing\", \"0\"), 10) || 0));\n Object.assign(table.style, {\n width: attr(\"width\", \"100%\"),\n border: attr(\"border\", \"none\"),\n color: attr(\"color\", \"#000000\"),\n fontFamily: attr(\"font-family\", \"Ubuntu, Helvetica, Arial, sans-serif\"),\n fontSize: attr(\"font-size\", \"13px\"),\n lineHeight: attr(\"line-height\", \"22px\"),\n tableLayout: attr(\"table-layout\", \"auto\"),\n });\n for (const row of template.content.querySelectorAll(\"tr\")) {\n const tr = table.insertRow();\n for (const cell of row.querySelectorAll(\":scope > th, :scope > td\")) {\n const copy = doc.createElement(cell.tagName.toLowerCase());\n copy.textContent = cell.textContent;\n const align = cell.getAttribute(\"align\");\n if (align && /^(left|right|center)$/i.test(align)) copy.setAttribute(\"align\", align);\n tr.append(copy);\n }\n }\n\n const cell = doc.createElement(\"td\");\n cell.style.padding = attr(\"padding\", \"10px 25px\");\n cell.append(table);\n return cell;\n}\n\nexport function addTableType(editor: Editor) {\n const base = editor.Components.getType(\"default\")!.view.prototype as {\n updateAttributes: (...args: unknown[]) => void;\n };\n editor.Components.addType(\"mj-table\", {\n isComponent: (el: HTMLElement) => {\n if (el.tagName?.toLowerCase() !== \"mj-table\") return false;\n const rows = el.querySelector<HTMLTemplateElement>(\":scope > template\");\n if (rows) cleanRows(rows.content);\n return { type: \"mj-table\", content: rows?.innerHTML ?? \"\", components: [] };\n },\n model: { defaults: { tagName: \"mj-table\", droppable: false, editable: false } },\n view: {\n tagName: \"tr\",\n // GrapesJS clears the element's attributes, style among them, when the model's change.\n updateAttributes(this: { el: HTMLElement }, ...args: unknown[]) {\n base.updateAttributes.apply(this, args);\n this.el.style.cssText = ROW_STYLE;\n },\n updateContent(this: { el: HTMLElement; model: Component }) {\n const { el, model } = this;\n el.style.cssText = ROW_STYLE;\n el.replaceChildren(\n tablePreview(el.ownerDocument, model.getAttributes(), String(model.get(\"content\") ?? \"\")),\n );\n },\n },\n } as never);\n}\n","/** Corrections to how grapesjs-mjml's types read and write MJML. */\n\nimport type { Component, Editor } from \"grapesjs\";\n\nimport { addTableType } from \"./table-type.js\";\n\ntype AttrToHTML = (this: Component) => Record<string, unknown>;\n\n// What MJML accepts inside an mj-column. The plugin lets a column take anything, so a <p>\n// dragged out of a text landed in the column as an element no validator accepts.\nconst COLUMN_CHILDREN = new Set([\n \"mj-accordion\",\n \"mj-button\",\n \"mj-carousel\",\n \"mj-divider\",\n \"mj-image\",\n \"mj-navbar\",\n \"mj-raw\",\n \"mj-social\",\n \"mj-spacer\",\n \"mj-table\",\n \"mj-text\",\n]);\n\n/**\n * Applied to every mj-* type before a document loads.\n *\n * - No `style-default`s: the plugin's differ from MJML's in places. It stripped any attribute\n * equal to one on save (a navigation link's 25px padding came back as MJML's 15px) and\n * seeded each element with them, so every element looked as if it set them.\n * - Attribute values are escaped: the plugin writes them between double quotes as they are,\n * so a `\"` in a tooltip, or a font name the agent quoted, broke the tag and the document.\n * - GrapesJS's `__p`, which the plugin leaves on the attributes while a colour is dragged, is\n * never written: a save falling due mid-drag stored it.\n * - A column takes only what MJML allows in one.\n * - An mj-table keeps its rows.\n * - An image without a picture is saved without one.\n */\nexport function fixPluginTypes(editor: Editor) {\n addTableType(editor);\n for (const type of editor.Components.getTypes()) {\n // mj-table is ours and serialises through GrapesJS's own escaping; this would add a second.\n if (!type.id.startsWith(\"mj-\") || type.id === \"mj-table\") continue;\n const base = (type.model.prototype as { getAttrToHTML: AttrToHTML }).getAttrToHTML;\n editor.Components.addType(type.id, {\n model: {\n defaults: {\n \"style-default\": {},\n ...(type.id === \"mj-column\" && {\n droppable: (source: Component) => COLUMN_CHILDREN.has(String(source.get(\"tagName\"))),\n }),\n // GrapesJS's own is an SVG's markup, which the canvas wrote into `src` and saved.\n ...(type.id === \"mj-image\" && { src: \"\" }),\n },\n getAttrToHTML(this: Component) {\n const attributes = base.call(this);\n delete attributes.__p;\n for (const [name, value] of Object.entries(attributes)) {\n if (typeof value === \"string\") attributes[name] = value.replace(/\"/g, \"&quot;\");\n }\n return attributes;\n },\n },\n } as never);\n }\n}\n"],"mappings":"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","names":["grapesjs","useEditorMaybe","grapesjsMJML","useEffect","useRef","useState","toast","ChevronRight","jsx","useEffect","useRef","useState","ChevronRight","Trash2","X","useCallback","useEffect","useRef","useState","useEffect","useRef","useState","jsx","jsxs","useState","useEffect","useRef","jsx","jsxs","documentColors","useState","useRef","field","useEffect","useCallback","jsx","jsxs","Link2","tagOf","escapeHtml","jsx","jsxs","tagOf","Link2","start","jsx","jsxs","tagOf","useRef","useEffect","useState","ChevronRight","X","Trash2","tagOf","escapeHtml","CONTENT","isSafeLink","cell","jsx","jsxs","tagOf","useRef","useState","useEffect","toast","grapesjs","grapesjsMJML","useEditorMaybe","ChevronRight"]}
1
+ {"version":3,"sources":["../src/components/editor/EmailEditor.tsx","../src/lib/save-baseline.ts","../src/lib/save-queue.ts","../src/lib/turn-follower.ts","../src/lib/shortcuts.ts","../src/components/ui/switch.tsx","../src/components/editor/ImagePicker.tsx","../src/components/editor/inspector/Inspector.tsx","../src/components/editor/ColorField.tsx","../src/components/editor/inspector/controls.tsx","../src/components/editor/inspector/values.ts","../src/components/editor/mjml-attributes.ts","../src/components/editor/ImageField.tsx","../src/components/editor/inspector/schema.ts","../src/components/editor/layers.ts","../src/components/editor/inspector/StructureSection.tsx","../src/components/editor/inspector/structure.ts","../src/components/editor/inspector/write.ts","../src/components/editor/blocks.ts","../src/components/editor/ids.ts","../src/components/editor/insert-block.ts","../src/components/editor/builtin-blocks.ts","../src/components/editor/table-type.ts","../src/components/editor/plugin-types.ts"],"sourcesContent":["\"use client\";\n\nimport grapesjs, { Component, Editor } from \"grapesjs\";\nimport GjsEditor, { Canvas, useEditorMaybe } from \"@grapesjs/react\";\nimport grapesjsMJML from \"grapesjs-mjml\";\nimport { useEffect, useRef, useState } from \"react\";\n\nimport { listSections, STARTER_MJML } from \"@mjml-agent-editor/core\";\nimport { useDocumentStore, useLabels, type CommentTarget, type EditorLabels } from \"../../index.js\";\nimport { refusal, saveToastId } from \"../../lib/refusal.js\";\nimport { createSaveBaseline } from \"../../lib/save-baseline.js\";\nimport { createSaveQueue } from \"../../lib/save-queue.js\";\nimport { createTurnFollower } from \"../../lib/turn-follower.js\";\nimport { opensBlockSearch } from \"../../lib/shortcuts.js\";\nimport { useAgentTurn } from \"../../stores.js\";\nimport { cn } from \"../../lib/utils\";\nimport { toast } from \"sonner\";\nimport { ChevronRight, Mail, MousePointerClick } from \"lucide-react\";\n\nimport { Button } from \"../ui/button\";\nimport { Spinner } from \"../ui/spinner\";\nimport { Switch } from \"../ui/switch\";\nimport { Input } from \"../ui/input\";\nimport { Search } from \"lucide-react\";\nimport CanvasComments from \"../comments/CanvasComments.js\";\nimport ImagePicker from \"./ImagePicker.js\";\nimport Inspector from \"./inspector/Inspector.js\";\nimport { registerBlocks, type SectionBlock } from \"./blocks.js\";\nimport { BUILTIN_BLOCKS, builtinBlock, CANVAS_CSS } from \"./builtin-blocks.js\";\nimport { addsBlock, insertBlock } from \"./insert-block.js\";\nimport { addIdClass, freshenCopiedIds, sectionIdOf } from \"./ids.js\";\nimport { badgeLabel, setupLayerNames } from \"./layers.js\";\nimport { fixPluginTypes } from \"./plugin-types.js\";\nimport { illegalAttributes, sourceForEditor } from \"./mjml-attributes.js\";\n\nexport type SaveStatus = \"idle\" | \"saving\" | \"saved\" | \"error\";\n\n/** Snapshot of editor state pushed to the header (device, undo, save, zoom, width). */\nexport type EditorState = {\n device: string;\n canUndo: boolean;\n canRedo: boolean;\n saveStatus: SaveStatus;\n zoom: number;\n contentWidth: string;\n /** True during an agent turn, until its result is loaded. */\n readOnly: boolean;\n};\n\nexport type EditorApi = {\n /** Current MJML source from the editor. */\n getMjml: () => string;\n /** Compiled email HTML (via grapesjs-mjml's mjml-get-code). */\n getCompiledHtml: () => string;\n /** Immediately saves the editor state to the DB. */\n flushSave: () => Promise<void>;\n /** Reloads the document from the DB (after agent changes). */\n reloadFromDb: () => Promise<void>;\n /** Highlights a section in the canvas while the agent edits it. */\n highlightSection: (sectionId: string, on: boolean) => void;\n /** Device manager control (used by the top header). */\n getDevices: () => { id: string; name: string }[];\n setDevice: (name: string) => void;\n undo: () => void;\n redo: () => void;\n /** Canvas zoom (percentage). */\n setZoom: (z: number) => void;\n /** Email body width (mj-body width attribute, e.g. \"600px\"). */\n setContentWidth: (w: string) => void;\n /** Subscribe to editor state changes (device/undo/save/zoom/width). Returns unsubscribe. */\n onEditorState: (cb: (s: EditorState) => void) => () => void;\n};\n\ntype Props = {\n docId: string;\n onReady: (api: EditorApi) => void;\n /** Bump to force the canvas comment layer to refetch (after agent turns). */\n commentsRefresh: number;\n /** Reports the number of open comments (for the header indicator). */\n onOpenCountChange: (n: number) => void;\n /**\n * Sections offered after the built-in blocks, read once when the editor starts. One that\n * `blockProblems` refuses is left out and reported in the console.\n */\n blocks?: readonly SectionBlock[];\n};\n\n// Element types that can receive a comment (besides a section).\nconst TYPE_LABEL: Record<string, string> = {\n \"mj-text\": \"Text\",\n \"mj-button\": \"Button\",\n \"mj-image\": \"Image\",\n \"mj-column\": \"Column\",\n};\n\nfunction tagOf(c: Component): string {\n return String(c.get(\"tagName\") || c.get(\"type\") || \"\");\n}\n\n// \"Sparkles\" icon (lucide Sparkles) used as a label in the GrapesJS toolbar.\nconst SPARKLES_SVG =\n '<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z\"/><path d=\"M20 3v4\"/><path d=\"M22 5h-4\"/><path d=\"M4 17v2\"/><path d=\"M5 18H3\"/></svg>';\n\n// \"Image up\" icon (lucide ImageUp), the toolbar button that opens the image picker.\nconst IMAGE_SVG =\n '<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10.3 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v10l-3.1-3.1a2 2 0 0 0-2.814.014L6 21\"/><path d=\"m14 19.5 3-3 3 3\"/><path d=\"M17 22v-5.5\"/><circle cx=\"9\" cy=\"9\" r=\"2\"/></svg>';\n\n// \"Layout template\" icon (lucide LayoutTemplate), the tile of a host's section without its own.\nconst SECTION_SVG =\n '<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect width=\"18\" height=\"7\" x=\"3\" y=\"3\" rx=\"1\"/><rect width=\"9\" height=\"7\" x=\"3\" y=\"14\" rx=\"1\"/><rect width=\"5\" height=\"7\" x=\"16\" y=\"14\" rx=\"1\"/></svg>';\n\nfunction isSection(c: Component): boolean {\n return tagOf(c) === \"mj-section\";\n}\n\nfunction isCommentable(c: Component): boolean {\n const t = tagOf(c);\n return t === \"mj-section\" || t in TYPE_LABEL;\n}\n\nfunction closestSection(c: Component | undefined): Component | null {\n let cur: Component | undefined = c;\n while (cur) {\n if (isSection(cur)) return cur;\n cur = cur.parent() ?? undefined;\n }\n return null;\n}\n\nfunction crumbName(c: Component, labels: EditorLabels): string {\n const t = tagOf(c);\n return labels.elementNames[t] ?? t.replace(/^mj-/, \"\");\n}\n\nfunction objectLabel(c: Component): string {\n const base = TYPE_LABEL[tagOf(c)] ?? tagOf(c);\n const text = String((c.getEl?.() as HTMLElement | undefined)?.textContent ?? \"\")\n .replace(/\\s+/g, \" \")\n .trim()\n .slice(0, 30);\n return text ? `${base}: “${text}”` : base;\n}\n\nconst RTE_FONTS = [\n \"Arial\",\n \"Helvetica\",\n \"Georgia\",\n \"Times New Roman\",\n \"Verdana\",\n \"Tahoma\",\n \"Trebuchet MS\",\n \"Courier New\",\n];\nconst RTE_SIZES = [11, 12, 13, 14, 16, 18, 20, 24, 28, 32, 40];\n\n// Wraps the current selection (in the canvas document) in a <span> with inline style.\nfunction wrapSelectionStyle(el: HTMLElement | undefined, style: Partial<CSSStyleDeclaration>) {\n const doc = el?.ownerDocument;\n const sel = doc?.getSelection?.();\n if (!doc || !sel || sel.rangeCount === 0 || sel.isCollapsed) return;\n const range = sel.getRangeAt(0);\n const span = doc.createElement(\"span\");\n Object.assign(span.style, style);\n try {\n span.appendChild(range.extractContents());\n range.insertNode(span);\n sel.removeAllRanges();\n const nr = doc.createRange();\n nr.selectNodeContents(span);\n sel.addRange(nr);\n } catch {\n /* ignore */\n }\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n// Extends the default GrapesJS RTE (mjml-compatible) with font/size/colors.\nfunction setupRichText(editor: Editor, labels: EditorLabels) {\n const rte = editor.RichTextEditor as any;\n if (!rte || rte.__customActions) return;\n rte.__customActions = true;\n const val = (action: any, sel: string) =>\n (action.btn?.querySelector(sel) as HTMLInputElement | HTMLSelectElement | null)?.value ?? \"\";\n\n rte.add(\"fontName\", {\n icon: `<select class=\"gjs-rte-select\" title=\"${labels.rteFont}\"><option value=\"\">${labels.rteFont}</option>${RTE_FONTS.map(\n (f) => `<option value=\"${f}\">${f}</option>`,\n ).join(\"\")}</select>`,\n event: \"change\",\n result: (r: any, action: any) => {\n const v = val(action, \"select\");\n if (v) r.exec(\"fontName\", v);\n },\n });\n\n rte.add(\"fontSize\", {\n icon: `<select class=\"gjs-rte-select\" title=\"${labels.rteSize}\"><option value=\"\">${labels.rteSize}</option>${RTE_SIZES.map(\n (s) => `<option value=\"${s}px\">${s}</option>`,\n ).join(\"\")}</select>`,\n event: \"change\",\n result: (r: any, action: any) => {\n const v = val(action, \"select\");\n if (v) wrapSelectionStyle(r.el, { fontSize: v });\n },\n });\n\n rte.add(\"forecolor\", {\n icon: `<input type=\"color\" class=\"gjs-rte-color\" title=\"${labels.rteTextColor}\" value=\"#000000\">`,\n event: \"change\",\n result: (r: any, action: any) => r.exec(\"foreColor\", val(action, \"input\")),\n });\n\n rte.add(\"hilitecolor\", {\n icon: `<input type=\"color\" class=\"gjs-rte-color\" title=\"${labels.rteBackgroundColor}\" value=\"#ffff00\">`,\n event: \"change\",\n result: (r: any, action: any) => r.exec(\"hiliteColor\", val(action, \"input\")),\n });\n}\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\nexport default function EmailEditor({\n docId,\n onReady,\n commentsRefresh,\n onOpenCountChange,\n blocks = [],\n}: Props) {\n // Injected by the host rather than imported, so the editor carries no database.\n const documents = useDocumentStore();\n const labels = useLabels();\n // Refs instead of state — GrapesJS lives outside React's lifecycle.\n const loadingRef = useRef(false);\n const saveStatusRef = useRef<SaveStatus>(\"idle\");\n const stateListeners = useRef(new Set<(s: EditorState) => void>());\n const [loading, setLoading] = useState(true);\n const [sidebarView, setSidebarView] = useState<SidebarView>(\"blocks\");\n const blockSearchRef = useRef<HTMLInputElement>(null);\n // Bound to the editor and its canvas, not the host page, whose own keys a host keeps.\n const onBlockSearchKey = (e: KeyboardEvent) => {\n if (readOnlyRef.current || !opensBlockSearch(e)) return;\n e.preventDefault();\n setSidebarView(\"blocks\");\n // The panel is hidden until the view switches, and a hidden input cannot take focus.\n requestAnimationFrame(() => blockSearchRef.current?.focus());\n };\n // Comment being composed (sparkles button) — opens the canvas popover.\n const [composeTarget, setComposeTarget] = useState<CommentTarget | null>(null);\n // Where the current selection came from — canvas click opens Settings,\n // selecting from the Layers tree does not (keeps you on Layers).\n const selectionSource = useRef<\"canvas\" | \"layers\" | \"other\">(\"other\");\n // Breadcrumb of the selected component's ancestry (Section › Column › …).\n const editorRef = useRef<Editor | null>(null);\n // Read only from a turn's start until the document it left is loaded, not just until it\n // ends: an edit made before that final reload would be replaced by it.\n const { running: turnRunning, locked: readOnly, setLocked } = useAgentTurn();\n const readOnlyRef = useRef(false);\n const applyReadOnly = useRef<(on: boolean) => Promise<void>>(async () => {});\n const [turn] = useState(createTurnFollower);\n useEffect(() => turn.turn(turnRunning), [turn, turnRunning]);\n useEffect(() => {\n turn.mount();\n return () => {\n turn.unmount();\n setLocked(false);\n };\n }, [turn, setLocked]);\n // Chrome leaves the canvas deaf to the mouse wheel once the lock lifts, until a click.\n // Hiding the frame's overflow for one frame makes it rebuild the scroller.\n const wasLocked = useRef(false);\n useEffect(() => {\n if (readOnly) {\n wasLocked.current = true;\n return;\n }\n const root = wasLocked.current && editorRef.current?.Canvas.getDocument()?.documentElement;\n wasLocked.current = false;\n if (!root) return;\n const overflow = root.style.overflow;\n root.style.overflow = \"hidden\";\n void root.offsetHeight;\n const frame = requestAnimationFrame(() => (root.style.overflow = overflow));\n return () => {\n cancelAnimationFrame(frame);\n root.style.overflow = overflow;\n };\n }, [readOnly]);\n const [crumbs, setCrumbs] = useState<Component[]>([]);\n // The open picker: GrapesJS hands over how to apply a choice to the image being edited.\n const [picker, setPicker] = useState<{ current?: string; select: (url: string) => void } | null>(\n null,\n );\n\n const onEditor = async (editor: Editor) => {\n editorRef.current = editor;\n\n // Build the breadcrumb chain from a component up to (but excluding) mj-body.\n const buildCrumbs = (c: Component | undefined) => {\n const chain: Component[] = [];\n let cur: Component | undefined = c;\n while (cur) {\n const t = tagOf(cur);\n if (!t || t === \"mj-body\" || t === \"wrapper\" || t === \"Wrapper\") break;\n chain.unshift(cur);\n cur = cur.parent() ?? undefined;\n }\n setCrumbs(chain);\n };\n\n // GrapesJS find() by MJML tag is unreliable — walk the tree instead.\n const findByTag = (tag: string): Component | undefined => {\n let found: Component | undefined;\n editor.getWrapper()?.onAll((c) => {\n if (!found && (c.get(\"tagName\") === tag || c.get(\"type\") === tag)) found = c;\n });\n return found;\n };\n const bodyWidth = (): string => {\n const body = findByTag(\"mj-body\");\n return String((body?.getAttributes?.() as Record<string, unknown>)?.width ?? \"600px\");\n };\n const snapshot = (): EditorState => ({\n device: editor.getDevice(),\n canUndo: !readOnlyRef.current && editor.UndoManager.hasUndo(),\n canRedo: !readOnlyRef.current && editor.UndoManager.hasRedo(),\n saveStatus: saveStatusRef.current,\n zoom: Math.round((editor.Canvas.getZoom?.() as number | undefined) ?? 100),\n contentWidth: bodyWidth(),\n readOnly: readOnlyRef.current,\n });\n const notifyState = () => {\n const s = snapshot();\n stateListeners.current.forEach((l) => l(s));\n };\n const setSave = (s: SaveStatus) => {\n saveStatusRef.current = s;\n notifyState();\n };\n\n // Comment target for a component: its section + (if it's not the section\n // itself) the specific element. Assigns stable IDs (sec-/obj-) when needed.\n const targetOf = (c: Component | undefined): CommentTarget | null => {\n const section = closestSection(c);\n if (!section || !c) return null;\n const sectionId = addIdClass(section, \"sec\");\n if (isSection(c)) {\n return { sectionId, objectId: null, objectLabel: null };\n }\n const objectId = addIdClass(c, \"obj\");\n return { sectionId, objectId, objectLabel: objectLabel(c) };\n };\n\n // Gives the section a sec-<id> and adds a comment button to the toolbar of\n // every commentable element (section + text/button/image/column).\n const decorate = (c: Component) => {\n if (isSection(c)) addIdClass(c, \"sec\");\n if (!isCommentable(c)) return;\n const toolbar = [...((c.get(\"toolbar\") as { command?: string }[]) ?? [])];\n if (tagOf(c) === \"mj-image\" && !toolbar.some((t) => t.command === \"open-image-picker\")) {\n toolbar.push({\n command: \"open-image-picker\",\n label: IMAGE_SVG,\n attributes: { title: labels.chooseImage },\n } as never);\n c.set(\"toolbar\", toolbar as never);\n }\n // Comments are addressed by section; outside one (inside a hero) the button did nothing.\n if (closestSection(c) && !toolbar.some((t) => t.command === \"open-comments\")) {\n toolbar.push({\n command: \"open-comments\",\n label: SPARKLES_SVG,\n attributes: { title: labels.commentOnElement, \"data-role\": \"sparkles\" },\n } as never);\n c.set(\"toolbar\", toolbar as never);\n }\n };\n\n // What a double-click on an image does in GrapesJS, reachable from a button.\n editor.Commands.add(\"open-image-picker\", {\n run(ed: Editor) {\n const target = ed.getSelected();\n if (!target || tagOf(target) !== \"mj-image\") return;\n const am = ed.AssetManager;\n am.open({\n target,\n types: [\"image\"],\n select(asset: { getSrc: () => string }, complete?: boolean) {\n target.set({ src: asset.getSrc() });\n if (complete) am.close();\n },\n } as never);\n },\n });\n\n editor.Commands.add(\"open-comments\", {\n run(ed: Editor) {\n const target = targetOf(ed.getSelected() ?? undefined);\n if (target) setComposeTarget(target);\n },\n });\n\n setupRichText(editor, labels);\n fixPluginTypes(editor);\n registerBlocks(editor, blocks, labels.blockCategorySections, SECTION_SVG);\n setupLayerNames(editor, labels);\n\n // The email starts at mj-body: above it are the GrapesJS root and <mjml>, and mj-head,\n // none of which anyone edits here. Sections and columns start open, as they are the\n // structure the rows below them make sense in.\n const STRUCTURE = new Set([\"mj-wrapper\", \"mj-section\", \"mj-column\"]);\n const showBodyInLayers = () => {\n const body = findByTag(\"mj-body\");\n if (!body) return;\n editor.Layers.setRoot(body);\n body.onAll((c) => {\n if (STRUCTURE.has(tagOf(c))) editor.Layers.setOpen(c, true);\n });\n };\n // On each selection GrapesJS closes the rows it opened to show the last one, sections and\n // columns among them. Taken off its list, they stay open until the visitor closes them.\n // The list is internal, so a GrapesJS without it only brings the closing back.\n const keepStructureOpen = () => {\n const layers = editor.Layers as unknown as {\n model?: { get: (key: \"opened\") => Record<string, Component> | undefined };\n };\n const opened = layers.model?.get(\"opened\") ?? {};\n for (const [cid, c] of Object.entries(opened)) {\n if (STRUCTURE.has(tagOf(c))) delete opened[cid];\n }\n };\n\n editor.on(\"component:add\", (c: Component) => {\n // A load brings ids the store already uses; only copies made here are renamed.\n if (!loadingRef.current) freshenCopiedIds(editor.getWrapper(), c);\n decorate(c);\n });\n // Track selection origin: a mousedown inside the canvas iframe marks the\n // next selection as coming from the canvas (→ open Settings). Selecting via\n // the Layers tree leaves the source as \"layers\" (set by the sidebar).\n editor.on(\"load\", () => {\n const body = editor.Canvas.getBody();\n body?.addEventListener(\n \"mousedown\",\n () => {\n selectionSource.current = \"canvas\";\n },\n true,\n );\n // The host document only gets a copy of these, aimed at the iframe (see opensBlockSearch).\n editor.Canvas.getDocument()?.addEventListener(\"keydown\", onBlockSearchKey);\n // GrapesJS sets its configured root on load, which may come after the document did.\n showBodyInLayers();\n });\n // After GrapesJS's own listener, which was added when the editor was created.\n editor.on(\"component:selected\", (c: Component) => {\n keepStructureOpen();\n if (selectionSource.current === \"canvas\") setSidebarView(\"settings\");\n selectionSource.current = \"other\";\n buildCrumbs(c);\n });\n // With multi-select a deselection can leave something selected; follow what remains.\n editor.on(\"component:deselected\", () => {\n buildCrumbs(editor.getSelected());\n });\n\n // A save writes only when the canvas differs from what the store holds — the canvas is\n // the truth, not the events that changed it.\n const baseline = createSaveBaseline();\n\n const save = async () => {\n // An open rich-text editor holds its text until editing ends.\n const view = editor.getEditing()?.getView() as\n { syncContent?: () => Promise<void> } | undefined;\n await view?.syncContent?.();\n const mjml = editor.getHtml();\n if (!baseline.changed(mjml)) return;\n setSave(\"saving\");\n try {\n await documents.save(docId, { mjml, projectData: editor.getProjectData() });\n baseline.saved(mjml);\n setSave(\"saved\");\n } catch (e) {\n setSave(\"error\");\n toast.error(refusal(e) ?? labels.documentSaveFailed, { id: saveToastId(docId) });\n throw e;\n }\n };\n\n const queue = createSaveQueue(save, 1200);\n\n editor.on(\"update\", () => {\n notifyState();\n if (!loadingRef.current && !readOnlyRef.current) queue.schedule();\n });\n editor.on(\"change:device\", notifyState);\n\n // While a turn runs the agent writes the document, so the visitor cannot: edits made\n // meanwhile would be overwritten by the agent's next reload, or overwrite its work.\n const blocked = [\n \"core:undo\",\n \"core:redo\",\n \"core:paste\",\n \"core:component-delete\",\n \"tlb-delete\",\n \"tlb-clone\",\n \"tlb-move\",\n \"open-assets\",\n \"open-image-picker\",\n ];\n for (const id of blocked) {\n editor.on(`command:run:before:${id}`, ({ options }: { options: { abort?: boolean } }) => {\n if (readOnlyRef.current) options.abort = true;\n });\n }\n const lock = (on: boolean) => {\n if (!turn.mounted) return;\n readOnlyRef.current = on;\n setLocked(on);\n notifyState();\n };\n applyReadOnly.current = async (on) => {\n if (on) {\n lock(true);\n queue.cancel();\n editor.select([]);\n // Through GrapesJS, which otherwise keeps its asset command active and will not reopen.\n editor.AssetManager.close();\n setPicker(null);\n return;\n }\n try {\n await reload();\n } catch (e) {\n // Unlocking a stale canvas would let the next save overwrite what the agent wrote.\n console.error(e);\n toast.error(labels.documentLoadFailed, {\n id: `reload-${docId}`,\n duration: Infinity,\n action: { label: labels.retry, onClick: () => void applyReadOnly.current(false) },\n });\n return;\n }\n lock(false);\n // What a load repaired or added while the canvas was locked; nothing, if it is unchanged.\n queue.schedule();\n };\n\n // Only the agent writes during a turn, so the store differs from `baseline.stored` exactly when it\n // changed something. Otherwise the canvas is kept, including edits a failed save left unsaved.\n // Queued behind saves and earlier reloads, so a slow one never lands over a newer one.\n const reload = () =>\n queue.run(async () => {\n const fresh = await documents.get(docId);\n if (fresh.mjml !== baseline.stored) loadMjml(fresh.mjml);\n });\n\n const loadMjml = (mjml: string) => {\n // Loading reports changes of its own. What it adds — ids, the starter body — is still\n // written by the next save, which compares against what the store returned.\n loadingRef.current = true;\n let repaired = false;\n // What the load adds, the store needs: a comment pinned to a new id finds nothing else.\n // Read from the source, as the canvas gave each section its id as it was added.\n const adds = !mjml || listSections(mjml).some((s) => !s.sectionId);\n try {\n queue.cancel();\n baseline.load(mjml, null);\n const source = sourceForEditor(mjml || STARTER_MJML);\n repaired = source.repaired;\n editor.setComponents(source.mjml);\n // Attributes the sidebar used to write and MJML rejects. Rendering ignores them, so\n // removing them changes nothing visible, and leaving them fails every agent write.\n editor.getWrapper()?.onAll((c) => {\n const illegal = illegalAttributes(tagOf(c), c.getAttributes());\n if (illegal.length === 0) return;\n c.removeAttributes(illegal);\n repaired = true;\n });\n if (!repaired && !adds) baseline.load(mjml, editor.getHtml());\n showBodyInLayers();\n // What was loaded is where undo stops: undoing the load emptied the canvas, or put\n // back what an agent turn had replaced, and the next save stored that.\n editor.UndoManager.clear();\n } finally {\n loadingRef.current = false;\n }\n notifyState();\n // Written now rather than with the next edit: the agent reads the stored copy.\n if ((repaired || adds) && !readOnlyRef.current) queue.schedule();\n };\n\n // Highlight for the section the agent is editing. The canvas is an iframe with its\n // own document, so the host's stylesheet does not reach it and these rules have to be\n // injected. The colour is still read from the shared token rather than written out\n // again — the literal that used to live here was the pre-redesign violet and had\n // silently drifted from the brand for as long as the redesign had been in place.\n const ensureHighlightStyles = () => {\n const cdoc = editor.Canvas.getDocument();\n if (!cdoc || cdoc.getElementById(\"agent-edit-style\")) return;\n\n const accent =\n getComputedStyle(document.documentElement)\n .getPropertyValue(\"--mjml-editor-accent\")\n .trim() || \"#7c5cfc\";\n\n const style = cdoc.createElement(\"style\");\n style.id = \"agent-edit-style\";\n style.textContent = `\n @keyframes agentEditPulse {\n 0%, 100% { outline-color: color-mix(in srgb, ${accent} 25%, transparent); }\n 50% { outline-color: color-mix(in srgb, ${accent} 95%, transparent); }\n }\n .agent-editing {\n outline: 3px solid color-mix(in srgb, ${accent} 90%, transparent) !important;\n outline-offset: -3px;\n animation: agentEditPulse 1s ease-in-out infinite;\n transition: outline-color 0.2s;\n }`;\n cdoc.head.appendChild(style);\n };\n\n const sectionEl = (sectionId: string): HTMLElement | undefined => {\n // find() matches the rendered elements, where a section is not an mj-section.\n let comp: Component | undefined;\n editor.getWrapper()?.onAll((c) => {\n if (!comp && isSection(c) && sectionIdOf(c) === sectionId) comp = c;\n });\n return (comp?.getEl?.() as HTMLElement | undefined) ?? undefined;\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const compiledHtml = (): string => {\n try {\n // grapesjs-mjml compiles MJML → email HTML via this command ({ html, errors }).\n const res = editor.runCommand(\"mjml-code-to-html\") as { html?: string } | undefined;\n return res?.html ?? editor.getHtml();\n } catch {\n return editor.getHtml();\n }\n };\n\n turn.ready((on) => void applyReadOnly.current(on));\n try {\n // Queued, so the reload that ends a turn already running lands after this load.\n await queue.run(async () => loadMjml((await documents.get(docId)).mjml));\n } catch (e) {\n toast.error(labels.documentLoadFailed);\n console.error(e);\n } finally {\n setLoading(false);\n }\n\n onReady({\n getMjml: () => editor.getHtml(),\n getCompiledHtml: compiledHtml,\n flushSave: () => queue.flush(),\n reloadFromDb: reload,\n highlightSection: (sectionId, on) => {\n ensureHighlightStyles();\n const el = sectionEl(sectionId);\n if (!el) return;\n el.classList.toggle(\"agent-editing\", on);\n },\n getDevices: () =>\n editor.Devices.getDevices().map((d) => ({\n id: String(d.id),\n name: d.getName() || String(d.id),\n })),\n setDevice: (name) => {\n editor.setDevice(name);\n notifyState();\n },\n undo: () => {\n if (readOnlyRef.current) return;\n editor.UndoManager.undo();\n notifyState();\n },\n redo: () => {\n if (readOnlyRef.current) return;\n editor.UndoManager.redo();\n notifyState();\n },\n setZoom: (z) => {\n editor.Canvas.setZoom?.(Math.max(25, Math.min(200, z)));\n notifyState();\n },\n setContentWidth: (w) => {\n if (readOnlyRef.current) return;\n findByTag(\"mj-body\")?.addAttributes({ width: w });\n notifyState();\n },\n onEditorState: (cb) => {\n stateListeners.current.add(cb);\n cb(snapshot());\n return () => stateListeners.current.delete(cb);\n },\n });\n };\n\n return (\n <GjsEditor\n grapesjs={grapesjs}\n className=\"h-full\"\n options={{\n height: \"100%\",\n storageManager: false,\n // On by default: every visitor's browser would post the host's domain to\n // app.grapesjs.com and leave a session-storage entry, which a host would then have\n // to disclose and, for the entry, ask consent for.\n telemetry: false,\n // Font Awesome from cdnjs by default, a third party a host would have to name in its\n // privacy policy. Nothing we show uses it: GrapesJS draws its toolbar and layer icons\n // as SVG, and its icon-font panels and style manager are not rendered here.\n cssIcons: \"\",\n canvasCss: CANVAS_CSS,\n fromElement: false,\n panels: { defaults: [] },\n blockManager: { appendTo: \"#gjs-blocks\" },\n // The eye hides a layer by writing `display=\"none\"` into the MJML, which is illegal.\n // The root row is mj-body, which the sidebar reaches as \"Email settings\" instead.\n layerManager: { appendTo: \"#gjs-layers\", hidable: false, showWrapper: false },\n assetManager: {\n // Never inline files: mail clients block `data:` images (see ImageLibrary).\n embedAsBase64: false,\n // Our own dialog instead of GrapesJS's modal. GrapesJS still decides when it opens\n // and what a choice applies to; `select(url, true)` sets the image and closes.\n custom: {\n open: (props: {\n select: (asset: string, complete?: boolean) => void;\n // `current` is ours, passed by style properties that have no target component.\n options?: { target?: Component; current?: string };\n }) =>\n setPicker({\n current:\n props.options?.current ??\n (String(props.options?.target?.get(\"src\") ?? \"\") || undefined),\n select: (url) => props.select(url, true),\n }),\n close: () => setPicker(null),\n },\n },\n canvas: {\n customBadgeLabel: badgeLabel(labels),\n // A file or text dragged in from outside lands as `<img>` or `<div>`, which no MJML\n // validator accepts; drags from the palette are unaffected.\n allowExternalDrop: false,\n },\n deviceManager: {\n devices: [\n { id: \"desktop\", name: \"Desktop\", width: \"\" },\n { id: \"mobile\", name: \"Mobile\", width: \"375px\", widthMedia: \"480px\" },\n ],\n },\n plugins: [\n (editor: Editor) =>\n grapesjsMJML(editor, {\n blocks: BUILTIN_BLOCKS,\n block: builtinBlock(labels),\n }),\n ],\n }}\n onEditor={onEditor}\n >\n {/* Inert as well as covered, so the keyboard cannot reach the controls either. */}\n <div\n className=\"relative flex h-full min-h-0 flex-1\"\n inert={readOnly}\n onKeyDown={(e) => onBlockSearchKey(e.nativeEvent)}\n >\n {readOnly && (\n <div className=\"absolute inset-0 z-30 flex cursor-not-allowed items-start justify-center bg-white/20 pt-3\">\n <span className=\"flex items-center gap-2 rounded-full bg-panel px-3 py-1 text-xs text-panel-fg shadow\">\n <Spinner /> {labels.agentWorking}\n </span>\n </div>\n )}\n <LeftSidebar\n view={sidebarView}\n onViewChange={setSidebarView}\n markLayersSource={() => (selectionSource.current = \"layers\")}\n blockSearchRef={blockSearchRef}\n />\n <div className=\"flex min-w-0 flex-1 flex-col bg-surface-muted\">\n <div className=\"relative min-h-0 flex-1\">\n <Canvas className=\"h-full\" />\n {/* Canvas comment layer (pins + thread popovers) overlays the canvas. */}\n <CanvasComments\n docId={docId}\n composeTarget={composeTarget}\n onComposeConsumed={() => setComposeTarget(null)}\n refreshSignal={commentsRefresh}\n onOpenCountChange={onOpenCountChange}\n />\n <ImagePicker\n open={picker !== null}\n currentUrl={picker?.current}\n onSelect={(url) => {\n // An upload that finished after a turn locked the canvas is not applied.\n if (!readOnlyRef.current) picker?.select(url);\n setPicker(null);\n }}\n // Closed here as well as through GrapesJS: its close() is a no-op whenever it\n // does not consider its asset command active, which left the dialog stuck open.\n onClose={() => {\n setPicker(null);\n editorRef.current?.AssetManager.close();\n }}\n />\n {loading && (\n <div className=\"absolute inset-0 z-10 flex items-center justify-center gap-2 bg-white/70 text-sm text-zinc-500\">\n <Spinner /> {labels.loadingEditor}\n </div>\n )}\n </div>\n <Breadcrumb crumbs={crumbs} onSelect={(c) => editorRef.current?.select(c)} />\n </div>\n </div>\n </GjsEditor>\n );\n}\n\ntype SidebarView = \"blocks\" | \"settings\" | \"layers\";\n\n// Left sidebar (dark): Blocks / Settings / Layers. The block and layer managers are always\n// mounted (appendTo targets for GrapesJS) — visibility toggled via `hidden`.\nfunction LeftSidebar({\n view,\n onViewChange,\n markLayersSource,\n blockSearchRef,\n}: {\n view: SidebarView;\n onViewChange: (v: SidebarView) => void;\n markLayersSource: () => void;\n blockSearchRef: React.Ref<HTMLInputElement>;\n}) {\n const editor = useEditorMaybe();\n const labels = useLabels();\n const [layersExpanded, setLayersExpanded] = useState(false);\n const [blockSearch, setBlockSearch] = useState(\"\");\n const [noBlockMatches, setNoBlockMatches] = useState(false);\n\n // A tree walk: `find(\"mj-body\")` returns nothing, and falling back to the GrapesJS root\n // offered background fields that never reached the MJML.\n const selectBody = () => {\n let body: Component | undefined;\n editor?.getWrapper()?.onAll((c) => {\n if (!body && tagOf(c) === \"mj-body\") body = c;\n });\n if (body) editor?.select(body);\n };\n\n const toggleLayers = (expand: boolean) => {\n setLayersExpanded(expand);\n editor?.getWrapper()?.onAll((c) => c.set(\"open\", expand));\n };\n\n // GrapesJS's tiles only drag; Enter or Space on one adds its block (see insertBlock).\n const onTileKey = (e: React.KeyboardEvent) => {\n const tile = (e.target as HTMLElement).closest<HTMLElement>(\"[data-block]\");\n const block = tile && editor?.Blocks.get(tile.dataset.block ?? \"\");\n if (!editor || !block || !addsBlock(e)) return;\n e.preventDefault();\n // Focus stays on the tile, so the change in the canvas is said aloud (toasts are live).\n if (insertBlock(editor, block)) toast(labels.blockAdded(tile.textContent?.trim() ?? \"\"));\n };\n\n // Filter the GrapesJS-rendered blocks (DOM lives outside React) by label;\n // hide category groups that end up empty.\n const filterBlocks = (q: string) => {\n setBlockSearch(q);\n const root = document.getElementById(\"gjs-blocks\");\n if (!root) return;\n const term = q.trim().toLowerCase();\n root.querySelectorAll<HTMLElement>(\".gjs-block\").forEach((b) => {\n const label = (b.querySelector(\".gjs-block-label\")?.textContent ?? b.textContent ?? \"\")\n .toLowerCase()\n .trim();\n b.style.display = !term || label.includes(term) ? \"\" : \"none\";\n });\n root.querySelectorAll<HTMLElement>(\".gjs-block-category\").forEach((cat) => {\n const anyVisible = [...cat.querySelectorAll<HTMLElement>(\".gjs-block\")].some(\n (b) => b.style.display !== \"none\",\n );\n cat.style.display = anyVisible ? \"\" : \"none\";\n });\n setNoBlockMatches(\n [...root.querySelectorAll<HTMLElement>(\".gjs-block\")].every(\n (b) => b.style.display === \"none\",\n ),\n );\n };\n\n return (\n <div className=\"editor-dark flex w-64 shrink-0 flex-col border-r border-panel-border bg-panel text-panel-fg\">\n <div className=\"flex border-b border-panel-border\">\n {(\n [\n [\"blocks\", labels.tabBlocks],\n [\"settings\", labels.tabSettings],\n [\"layers\", labels.tabLayers],\n ] as const\n ).map(([value, label]) => (\n <button\n key={value}\n type=\"button\"\n onClick={() => onViewChange(value)}\n className={cn(\n \"relative flex-1 px-3 py-2.5 text-sm transition-colors\",\n \"after:absolute after:inset-x-0 after:-bottom-px after:h-0.5 after:transition-colors\",\n view === value\n ? \"font-medium text-panel-fg after:bg-brand\"\n : \"text-panel-muted-fg after:bg-transparent hover:text-panel-fg\",\n )}\n >\n {label}\n </button>\n ))}\n </div>\n\n {/* Blocks: search + categorized block palette */}\n <div className={cn(\"flex min-h-0 flex-1 flex-col\", view !== \"blocks\" && \"hidden\")}>\n <div className=\"relative border-b border-panel-border p-2\">\n <Search className=\"pointer-events-none absolute top-1/2 left-4 size-3.5 -translate-y-1/2 text-panel-muted-fg\" />\n <Input\n ref={blockSearchRef}\n value={blockSearch}\n onChange={(e) => filterBlocks(e.target.value)}\n placeholder={labels.searchBlocks}\n className=\"h-8 border-panel-border bg-panel-elevated pr-10 pl-7 text-sm text-panel-fg placeholder:text-panel-muted-fg\"\n />\n <kbd className=\"pointer-events-none absolute top-1/2 right-4 -translate-y-1/2 rounded border border-panel-border bg-panel px-1 py-0.5 font-mono text-[10px] text-panel-muted-fg\">\n /\n </kbd>\n </div>\n {noBlockMatches && (\n <p className=\"px-3 py-6 text-center text-xs text-panel-muted-fg\">\n {labels.noBlocksMatch}\n </p>\n )}\n <div id=\"gjs-blocks\" className=\"min-h-0 flex-1 overflow-y-auto\" onKeyDown={onTileKey} />\n </div>\n\n <div className={cn(\"min-h-0 flex-1 overflow-y-auto\", view !== \"settings\" && \"hidden\")}>\n <Inspector\n onEmailSettings={selectBody}\n empty={\n <div className=\"flex flex-col items-center gap-3 px-6 py-10 text-center\">\n <MousePointerClick className=\"size-6 text-panel-muted-fg\" />\n <p className=\"text-sm text-panel-muted-fg\">{labels.settingsEmpty}</p>\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n className=\"border-panel-border bg-panel-elevated text-panel-fg hover:bg-panel-hover hover:text-panel-fg\"\n onClick={selectBody}\n >\n <Mail />\n {labels.emailSettings}\n </Button>\n </div>\n }\n />\n </div>\n\n {/* Layers — with an expand/collapse-all switch. A pointer-down here marks\n the next selection as coming from the tree (→ do NOT open Settings). */}\n <div\n className={cn(\"flex min-h-0 flex-1 flex-col\", view !== \"layers\" && \"hidden\")}\n onMouseDownCapture={markLayersSource}\n >\n <label className=\"flex items-center justify-between gap-2 border-b border-panel-border px-3 py-2 text-xs text-panel-muted-fg\">\n <span>{labels.expandAll}</span>\n <Switch\n checked={layersExpanded}\n onCheckedChange={toggleLayers}\n className=\"data-[state=checked]:bg-brand data-[state=unchecked]:bg-panel-border\"\n />\n </label>\n <div\n id=\"gjs-layers\"\n className=\"min-h-0 flex-1 overflow-y-auto\"\n // A double-click renames a row in GrapesJS, but rows are named by their content.\n onDoubleClickCapture={(e) => {\n if ((e.target as HTMLElement).closest(\"[data-name]\")) e.stopPropagation();\n }}\n />\n </div>\n </div>\n );\n}\n\n// Breadcrumb under the canvas: the selected component's ancestry (clickable).\nfunction Breadcrumb({\n crumbs,\n onSelect,\n}: {\n crumbs: Component[];\n onSelect: (c: Component) => void;\n}) {\n const labels = useLabels();\n return (\n <div className=\"flex h-9 shrink-0 items-center gap-0.5 border-t border-border bg-surface px-3 text-xs text-muted-foreground\">\n {crumbs.length === 0 ? (\n <span className=\"text-muted-foreground/60\">{labels.selectAnElement}</span>\n ) : (\n crumbs.map((c, i) => (\n <span key={i} className=\"flex items-center gap-0.5\">\n {i > 0 && <ChevronRight className=\"size-3 opacity-40\" />}\n <button\n type=\"button\"\n onClick={() => onSelect(c)}\n className={cn(\n \"rounded px-1.5 py-0.5 hover:bg-muted hover:text-foreground\",\n i === crumbs.length - 1 && \"font-medium text-brand\",\n )}\n >\n {crumbName(c, labels)}\n </button>\n </span>\n ))\n )}\n </div>\n );\n}\n","/**\n * Whether the canvas holds a change the store does not have.\n *\n * Opening an email is not one. GrapesJS writes a document back in its own form — tags closed,\n * attributes quoted again — and reports changes of its own after a load, as an\n * image settles. Compared with the store alone, that rewrote emails nobody had touched.\n */\nexport function createSaveBaseline() {\n let stored = \"\";\n let loaded: string | null = null;\n return {\n /** The MJML the store holds, as far as this editor knows. */\n get stored() {\n return stored;\n },\n /** `canvas` is what the load serialises to, or null when it repaired something to write. */\n load(mjml: string, canvas: string | null) {\n stored = mjml;\n loaded = canvas;\n },\n saved(mjml: string) {\n stored = mjml;\n loaded = null;\n },\n changed(mjml: string) {\n return mjml !== stored && mjml !== loaded;\n },\n };\n}\n","/** Debounced autosave, and the flush a turn waits on. Whether to write is `save`'s call. */\nexport interface SaveQueue {\n /** Restarts the debounce. */\n schedule(): void;\n /** Drops a scheduled autosave. */\n cancel(): void;\n /** Runs `save` after any work under way; rejects if it fails. */\n flush(): Promise<void>;\n /** Runs `task` after any work under way, such as a reload that must not race a save. */\n run<T>(task: () => Promise<T>): Promise<T>;\n}\n\nexport function createSaveQueue(save: () => Promise<void>, delayMs: number): SaveQueue {\n let timer: ReturnType<typeof setTimeout> | null = null;\n // Work runs one after another, so an older write or read can never land after a newer one.\n let tail: Promise<unknown> = Promise.resolve();\n\n const cancel = () => {\n if (timer) clearTimeout(timer);\n timer = null;\n };\n\n const run = <T>(task: () => Promise<T>): Promise<T> => {\n const next = tail.then(task);\n tail = next.catch(() => {});\n return next;\n };\n\n return {\n schedule() {\n cancel();\n timer = setTimeout(() => void run(save).catch(() => {}), delayMs);\n },\n cancel,\n flush() {\n cancel();\n return run(save);\n },\n run,\n };\n}\n","/**\n * Passes the agent turn to a canvas that is ready only some time after it mounts.\n *\n * A turn can already be running by then: the chat re-attaches to one when the visitor comes\n * back mid-turn. Applied only on later changes, that turn left the canvas editable.\n */\nexport function createTurnFollower() {\n let running = false;\n let mounted = true;\n let apply: ((on: boolean) => unknown) | null = null;\n return {\n turn(on: boolean) {\n if (on === running) return;\n running = on;\n if (mounted) apply?.(on);\n },\n /**\n * Whether the canvas is still mounted. An unmounted one's late reload must not unlock\n * the shared state a canvas mounted since has locked.\n */\n get mounted() {\n return mounted;\n },\n // Both, as React mounts twice in development.\n mount() {\n mounted = true;\n },\n unmount() {\n mounted = false;\n },\n /** A turn already under way is applied at once; none means nothing to apply. */\n ready(fn: (on: boolean) => unknown) {\n apply = fn;\n if (running) fn(true);\n },\n };\n}\n","/**\n * Whether a key press should open the block search: a bare `/`, as on GitHub and YouTube.\n * Not ⌘K, which browsers on Windows and Linux keep for their own search bar.\n */\nexport function opensBlockSearch(\n e: Pick<KeyboardEvent, \"key\" | \"metaKey\" | \"ctrlKey\" | \"altKey\" | \"isComposing\" | \"target\">,\n): boolean {\n if (e.key !== \"/\" || e.metaKey || e.ctrlKey || e.altKey || e.isComposing) return false;\n // Typing a slash into a field, or into text being edited on the canvas, is just a slash.\n const target = e.target as { tagName?: string; isContentEditable?: boolean } | null;\n if (target?.isContentEditable) return false;\n // GrapesJS re-dispatches every key pressed in the canvas on its <iframe>, where the text\n // being edited is out of sight; the canvas document's own listener judges those.\n return ![\"INPUT\", \"TEXTAREA\", \"SELECT\", \"IFRAME\"].includes(target?.tagName ?? \"\");\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { Switch as SwitchPrimitive } from \"radix-ui\";\n\nimport { cn } from \"../../lib/utils\";\n\nfunction Switch({\n className,\n size = \"default\",\n ...props\n}: React.ComponentProps<typeof SwitchPrimitive.Root> & {\n size?: \"sm\" | \"default\";\n}) {\n return (\n <SwitchPrimitive.Root\n data-slot=\"switch\"\n data-size={size}\n className={cn(\n \"peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent transition-all outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=default]:h-[18.4px] data-[size=default]:w-[32px] data-[size=sm]:h-[14px] data-[size=sm]:w-[24px] dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:bg-primary data-unchecked:bg-input dark:data-unchecked:bg-input/80 data-disabled:cursor-not-allowed data-disabled:opacity-50\",\n className,\n )}\n {...props}\n >\n <SwitchPrimitive.Thumb\n data-slot=\"switch-thumb\"\n className=\"pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-checked:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-checked:translate-x-[calc(100%-2px)] dark:data-checked:bg-primary-foreground group-data-[size=default]/switch:data-unchecked:translate-x-0 group-data-[size=sm]/switch:data-unchecked:translate-x-0 dark:data-unchecked:bg-foreground\"\n />\n </SwitchPrimitive.Root>\n );\n}\n\nexport { Switch };\n","\"use client\";\n\n/**\n * The image picker, replacing GrapesJS's asset modal.\n *\n * GrapesJS's own modal could not be styled into the editor, and its \"click to upload\" area\n * was a transparent file input that did not open the file browser at all. This one is\n * opened by GrapesJS (`assetManager.custom`), so the canvas double-click, the toolbar button\n * and the sidebar all land here, and selecting goes back through GrapesJS to the image.\n */\n\nimport { useCallback, useEffect, useRef, useState, type DragEvent } from \"react\";\nimport { Check, ImageUp, Link2, Trash2 } from \"lucide-react\";\nimport { toast } from \"sonner\";\n\nimport { useImageLibrary, useLabels, type ImageAsset } from \"../../index.js\";\nimport { cn } from \"../../lib/utils\";\nimport { Button } from \"../ui/button\";\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from \"../ui/dialog\";\nimport { Input } from \"../ui/input\";\nimport { Spinner } from \"../ui/spinner\";\n\ntype Quota = { readonly used: number; readonly limit: number };\n\nexport default function ImagePicker({\n open,\n currentUrl,\n onSelect,\n onClose,\n}: {\n open: boolean;\n /** The image being replaced, marked in the gallery. */\n currentUrl?: string;\n onSelect: (url: string) => void;\n onClose: () => void;\n}) {\n const library = useImageLibrary();\n const labels = useLabels();\n const [images, setImages] = useState<readonly ImageAsset[]>([]);\n const [quota, setQuota] = useState<Quota>();\n const [loading, setLoading] = useState(false);\n const [pending, setPending] = useState(0);\n const [dragging, setDragging] = useState(false);\n const [url, setUrl] = useState(\"\");\n const [confirmId, setConfirmId] = useState<string | null>(null);\n const fileInput = useRef<HTMLInputElement>(null);\n // Bumped on every open and close. An upload still running when the picker closes, or\n // reopens for another image, must not apply its result to whatever is open now.\n const session = useRef(0);\n // Read through refs so neither a new `labels` object nor a new `onSelect` from a parent\n // render re-runs the open effect — that would wipe a half-typed URL.\n const latest = useRef({ labels, onSelect });\n latest.current = { labels, onSelect };\n // Opening, uploading and deleting each list the gallery; only the newest answer is shown.\n const lists = useRef(0);\n\n const refresh = useCallback(async () => {\n if (!library) return;\n const mine = ++lists.current;\n setLoading(true);\n try {\n const result = await library.list();\n if (mine !== lists.current) return;\n setImages(result.images);\n setQuota(result.quota);\n } catch (err) {\n console.error(err);\n if (mine === lists.current) toast.error(latest.current.labels.imagePickerLoadFailed);\n } finally {\n if (mine === lists.current) setLoading(false);\n }\n }, [library]);\n\n useEffect(() => {\n session.current += 1;\n if (!open) return;\n setUrl(\"\");\n setConfirmId(null);\n void refresh();\n // Once per opening; `refresh` reads the latest props through `latest`.\n }, [open]);\n // Nor after unmount, when the editor it would select into is gone.\n useEffect(() => () => void (session.current += 1), []);\n\n const accepts = (file: File) => matchesAccept(file, library?.accept);\n\n const full = quota !== undefined && quota.used >= quota.limit;\n\n const upload = async (files: FileList | null) => {\n const send = library?.upload?.bind(library);\n if (!send || !files?.length) return;\n const mine = session.current;\n // The input's `accept` covers browsing; a drop bypasses it, so check here too rather\n // than send a whole file only to have the host refuse it.\n const list = Array.from(files).filter((f) => {\n if (accepts(f)) return true;\n toast.error(labels.imagePickerUnsupported(f.name));\n return false;\n });\n if (!list.length) return;\n setPending((n) => n + list.length);\n // Settled rather than all: an upload that succeeded has already been stored and\n // counted by the host, so one failure must not hide it.\n // Async, so an adapter that throws rather than rejects still settles.\n const results = await Promise.allSettled(list.map(async (f) => send(f)));\n setPending((n) => n - list.length);\n for (const r of results) {\n if (r.status === \"rejected\") {\n console.error(r.reason);\n // The host's message is usually the actionable part (\"limit reached\", \"too large\").\n toast.error(r.reason instanceof Error ? r.reason.message : labels.imageUploadFailed);\n }\n }\n if (session.current !== mine) return;\n await refresh();\n // One file dropped while editing an image is meant for that image.\n const [only] = results;\n if (results.length === 1 && only?.status === \"fulfilled\" && session.current === mine) {\n latest.current.onSelect(only.value.url);\n }\n };\n\n const remove = async (image: ImageAsset) => {\n if (!library?.remove) return;\n // Two clicks rather than a confirm(): an image in use breaks every email showing it.\n if (confirmId !== image.id) {\n setConfirmId(image.id);\n return;\n }\n setConfirmId(null);\n try {\n await library.remove(image.id);\n await refresh();\n } catch (err) {\n console.error(err);\n toast.error(err instanceof Error ? err.message : labels.imageDeleteFailed);\n }\n };\n\n const onDrop = (e: DragEvent) => {\n e.preventDefault();\n setDragging(false);\n if (!full) void upload(e.dataTransfer.files);\n };\n\n return (\n <Dialog open={open} onOpenChange={(next) => !next && onClose()}>\n {/* A file dropped where nothing takes it would otherwise be opened by the browser in\n place of the editor: with no upload, or with the quota full. */}\n <DialogContent\n onDragOver={(e) => e.preventDefault()}\n onDrop={(e) => e.preventDefault()}\n className=\"editor-dark gap-0 overflow-hidden border border-panel-border bg-panel p-0 text-panel-fg ring-0 sm:max-w-3xl\"\n >\n <DialogHeader className=\"border-b border-panel-border px-5 py-4\">\n <DialogTitle>{labels.imagePickerTitle}</DialogTitle>\n {quota && (\n <DialogDescription className=\"text-panel-muted-fg\">\n {labels.imagePickerQuota(quota.used, quota.limit)}\n </DialogDescription>\n )}\n </DialogHeader>\n\n <div className=\"flex max-h-[70vh] flex-col gap-4 overflow-y-auto p-5\">\n {library?.upload &&\n (full ? (\n <p className=\"rounded-lg border border-panel-border bg-panel-elevated px-4 py-3 text-sm text-panel-muted-fg\">\n {labels.imagePickerQuotaFull}\n </p>\n ) : (\n <div\n onDragOver={(e) => {\n e.preventDefault();\n setDragging(true);\n }}\n onDragLeave={() => setDragging(false)}\n onDrop={onDrop}\n className={cn(\n \"flex flex-col items-center justify-center gap-3 rounded-xl border-2 border-dashed px-6 py-8 text-center transition-colors\",\n dragging ? \"border-brand bg-brand-soft\" : \"border-panel-border bg-panel-elevated\",\n )}\n >\n <ImageUp className=\"size-8 text-panel-muted-fg\" />\n <div className=\"flex flex-wrap items-center justify-center gap-2 text-sm text-panel-muted-fg\">\n <span>{labels.imagePickerDrop}</span>\n <Button\n type=\"button\"\n size=\"sm\"\n className=\"bg-brand text-brand-fg hover:bg-brand/90\"\n onClick={() => fileInput.current?.click()}\n >\n {labels.imagePickerBrowse}\n </Button>\n </div>\n <input\n ref={fileInput}\n type=\"file\"\n accept={library.accept ?? \"image/*\"}\n multiple\n hidden\n onChange={(e) => {\n void upload(e.target.files);\n e.target.value = \"\";\n }}\n />\n </div>\n ))}\n\n {library?.allowUrl !== false && (\n <form\n className=\"flex gap-2\"\n onSubmit={(e) => {\n e.preventDefault();\n const value = url.trim();\n if (value) onSelect(value);\n }}\n >\n <div className=\"relative flex-1\">\n <Link2 className=\"pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-panel-muted-fg\" />\n <Input\n value={url}\n onChange={(e) => setUrl(e.target.value)}\n placeholder={labels.imagePickerUrlPlaceholder}\n className=\"h-9 border-panel-border bg-panel-elevated pl-8 text-panel-fg placeholder:text-panel-muted-fg\"\n />\n </div>\n <Button\n type=\"submit\"\n size=\"lg\"\n variant=\"outline\"\n disabled={!url.trim()}\n className=\"border-panel-border bg-panel-elevated text-panel-fg hover:bg-panel-hover hover:text-panel-fg\"\n >\n {labels.imagePickerUseUrl}\n </Button>\n </form>\n )}\n\n {library && (\n <section>\n <h3 className=\"mb-2 text-xs font-medium tracking-wide text-panel-muted-fg uppercase\">\n {labels.imagePickerGallery}\n </h3>\n {loading && images.length === 0 && pending === 0 ? (\n <div className=\"flex justify-center py-8\">\n <Spinner />\n </div>\n ) : images.length === 0 && pending === 0 ? (\n <p className=\"py-6 text-center text-sm text-panel-muted-fg\">\n {labels.imagePickerEmpty}\n </p>\n ) : (\n <ul className=\"grid grid-cols-3 gap-3 sm:grid-cols-4\">\n {Array.from({ length: pending }, (_, i) => (\n <li\n key={`pending-${i}`}\n className=\"flex aspect-[4/3] items-center justify-center rounded-lg border border-panel-border bg-panel-elevated\"\n >\n <Spinner />\n </li>\n ))}\n {images.map((image) => {\n const selected = image.url === currentUrl;\n const confirming = confirmId === image.id;\n return (\n <li key={image.id} className=\"group relative\">\n <button\n type=\"button\"\n onClick={() => onSelect(image.url)}\n title={image.name}\n className={cn(\n \"block aspect-[4/3] w-full overflow-hidden rounded-lg border bg-black/25 transition outline-none focus-visible:ring-2 focus-visible:ring-brand\",\n selected\n ? \"border-brand ring-2 ring-brand\"\n : \"border-panel-border hover:border-panel-muted-fg\",\n )}\n >\n {/* Contained, not cropped: email images are mostly wide banners, and\n choosing one means seeing its whole composition. */}\n <img\n src={image.url}\n alt={image.name ?? \"\"}\n loading=\"lazy\"\n className=\"size-full object-contain\"\n />\n </button>\n {selected && (\n <span className=\"pointer-events-none absolute top-1.5 left-1.5 flex size-5 items-center justify-center rounded-full bg-brand text-brand-fg\">\n <Check className=\"size-3\" />\n </span>\n )}\n {image.name && (\n <span className=\"pointer-events-none absolute inset-x-0 bottom-0 truncate rounded-b-lg bg-black/60 px-2 py-1 text-[11px] text-white opacity-0 transition group-hover:opacity-100\">\n {image.name}\n </span>\n )}\n {library.remove && (\n <button\n type=\"button\"\n onClick={() => void remove(image)}\n onBlur={() => confirming && setConfirmId(null)}\n title={\n confirming\n ? labels.imagePickerConfirmDelete\n : labels.imagePickerDelete\n }\n aria-label={labels.imagePickerDelete}\n className={cn(\n \"absolute top-1.5 right-1.5 flex h-6 items-center gap-1 rounded-md px-1.5 text-xs text-white transition focus-visible:opacity-100\",\n confirming\n ? \"bg-red-600 opacity-100\"\n : \"bg-black/60 opacity-0 group-hover:opacity-100 hover:bg-black/80\",\n )}\n >\n <Trash2 className=\"size-3.5\" />\n {confirming && labels.imagePickerConfirmDelete}\n </button>\n )}\n </li>\n );\n })}\n </ul>\n )}\n </section>\n )}\n </div>\n </DialogContent>\n </Dialog>\n );\n}\n\n/** The subset of `<input accept>` a picker needs: MIME types, `type/*`, and `.ext`. */\nfunction matchesAccept(file: File, accept: string | undefined): boolean {\n if (!accept) return file.type.startsWith(\"image/\");\n return accept.split(\",\").some((raw) => {\n const rule = raw.trim().toLowerCase();\n if (rule.startsWith(\".\")) return file.name.toLowerCase().endsWith(rule);\n if (rule.endsWith(\"/*\")) return file.type.startsWith(rule.slice(0, -1));\n return file.type === rule;\n });\n}\n","\"use client\";\n\n/**\n * The Settings tab: the selected element's MJML attributes, grouped by what they are for.\n *\n * It reads `getAttributes()` and writes `addAttributes` / `removeAttributes`, never through\n * GrapesJS's Style Manager: its properties are global per CSS name, so a label, unit list or\n * option set could not differ by tag, and it reads a style mirror the plugin seeds with its\n * own defaults rather than the document's values. Only attributes the schema names are\n * written, so `css-class`, which carries the agent's `sec-*` and `obj-*` ids, never is.\n */\n\nimport { useEffect, useLayoutEffect, useReducer, useRef, useState, type ReactNode } from \"react\";\nimport type { Component, Editor } from \"grapesjs\";\nimport { useEditorMaybe } from \"@grapesjs/react\";\nimport { ArrowUp, ChevronRight, Copy, Monitor, Trash2, X } from \"lucide-react\";\n\nimport { useLabels } from \"../../../index.js\";\nimport type { EditorLabels } from \"../../../labels.js\";\nimport { useAgentTurn } from \"../../../stores.js\";\nimport { cn } from \"../../../lib/utils\";\nimport ColorField, { toHex } from \"../ColorField.js\";\nimport ImageField, { imageUrl } from \"../ImageField.js\";\nimport { BoxInput, LengthInput, Row, Segmented, Select, TextInput, Toggle } from \"./controls.js\";\nimport { layerName } from \"../layers.js\";\nimport { SCHEMA } from \"./schema.js\";\nimport StructureSection from \"./StructureSection.js\";\nimport type { Field, Group, Option } from \"./types.js\";\nimport { isSafeLink, isSafeNavbarLink, networkName, parseNetwork, SIDES } from \"./values.js\";\nimport { createWriter, type WriteOptions } from \"./write.js\";\n\nconst GROUPS: readonly Exclude<Group, \"advanced\">[] = [\"content\", \"layout\", \"spacing\", \"style\"];\n\n// Never listed under \"Other attributes\": the agent's ids, and GrapesJS's own bookkeeping.\nconst HIDDEN = new Set([\"css-class\", \"mj-class\", \"id\", \"style\"]);\n\nfunction tagOf(c: Component): string {\n return String(c.get(\"tagName\") || c.get(\"type\") || \"\");\n}\n\n/** Attributes as strings; GrapesJS keeps a few as booleans or numbers. */\nfunction attributesOf(c: Component): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [k, v] of Object.entries(c.getAttributes())) {\n if (v !== undefined && v !== null && v !== false) out[k] = String(v);\n }\n // mj-image keeps `src` as a model property, and the plugin writes that over the attribute.\n if (tagOf(c) === \"mj-image\") out.src = String(c.get(\"src\") ?? \"\");\n return out;\n}\n\n/**\n * Distinct colors already in the email, most frequent first, read when the picker opens.\n * Only values of color-bearing attributes: a bare `#[0-9a-f]+` also matches entities such as\n * `&#039;` and anchors such as `href=\"#top\"`.\n */\nfunction documentColors(editor: Editor): string[] {\n const counts = new Map<string, number>();\n const colorValue =\n /(?:color|background|border)[\\w-]*\\s*[:=]\\s*[\"']?[^\"';>{}]*?(#[0-9a-f]{3,8}\\b|rgba?\\([^)]*\\))/gi;\n for (const match of editor.getHtml().matchAll(colorValue)) {\n const hex = toHex(match[1]!, { opaque: true });\n if (hex) counts.set(hex, (counts.get(hex) ?? 0) + 1);\n }\n return [...counts.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 14)\n .map(([hex]) => hex);\n}\n\nexport default function Inspector({\n onEmailSettings,\n empty,\n}: {\n onEmailSettings: () => void;\n /** Shown when nothing is selected. */\n empty: ReactNode;\n}) {\n const editor = useEditorMaybe();\n const labels = useLabels();\n const { locked } = useAgentTurn();\n // Read when a write happens, not when its control rendered: a field held down as a turn\n // starts writes from a render before the lock, and its release comes as it unmounts.\n const lockedNow = useRef(locked);\n useLayoutEffect(() => {\n lockedNow.current = locked;\n });\n const [, refresh] = useReducer((n: number) => n + 1, 0);\n const root = useRef<HTMLDivElement>(null);\n const refocus = useRef(false);\n\n // GrapesJS owns the selection and the values; re-read them whenever either changes. No\n // Component is kept in state: an agent turn's reload replaces every one of them.\n useEffect(() => {\n if (!editor) return;\n const events = \"component:update change:device\";\n // A button here that changes the selection (parent, duplicate, delete, a link, Add) goes\n // with the old element's settings; focus moves to what replaces them, not to the page.\n const toggled = () => {\n if (root.current?.contains(document.activeElement)) refocus.current = true;\n refresh();\n };\n editor.on(events, refresh);\n editor.on(\"component:toggled\", toggled);\n return () => {\n editor.off(events, refresh);\n editor.off(\"component:toggled\", toggled);\n };\n }, [editor]);\n useEffect(() => {\n if (!refocus.current) return;\n refocus.current = false;\n root.current?.querySelector<HTMLElement>(\"[data-focus-target]\")?.focus();\n });\n\n if (!editor) return null;\n const selected = editor.getSelectedAll();\n const component = selected[0];\n return (\n <div ref={root}>\n {selected.length === 0 ? (\n <div data-focus-target tabIndex={-1} className=\"outline-none\">\n {empty}\n </div>\n ) : selected.length > 1 ? (\n <p\n data-focus-target\n tabIndex={-1}\n className=\"px-4 py-8 text-center text-xs text-panel-muted-fg outline-none\"\n >\n {labels.multipleSelected(selected.length)}\n </p>\n ) : (\n <ElementSettings\n key={component!.cid}\n editor={editor}\n component={component!}\n labels={labels}\n locked={locked}\n lockedNow={lockedNow}\n onEmailSettings={onEmailSettings}\n />\n )}\n </div>\n );\n}\n\nfunction ElementSettings({\n editor,\n component,\n labels,\n locked,\n lockedNow,\n onEmailSettings,\n}: {\n editor: Editor;\n component: Component;\n labels: EditorLabels;\n locked: boolean;\n lockedNow: { readonly current: boolean };\n onEmailSettings: () => void;\n}) {\n const [advancedOpen, setAdvancedOpen] = useState(false);\n const tag = tagOf(component);\n const fields = SCHEMA[tag] ?? [];\n const attributes = attributesOf(component);\n const visible = fields.filter((f) => !f.when || f.when(attributes));\n const t = (key: string) => labels.inspectorLabels[key] ?? key;\n const optionName = (o: Option) => labels.inspectorLabels[o.label] ?? o.label;\n\n // One writer per element (this component is keyed by it), so a drag's start survives renders.\n const [writer] = useState(() => createWriter(editor, component, () => lockedNow.current));\n const write = (attr: string, value: string, options?: WriteOptions) =>\n lockedNow.current ? Promise.resolve() : writer(attr, value, options);\n // A box writes its shorthand and drops the longhands, which would otherwise override it.\n const writeBox = (attr: string, shorthand: string, partial?: boolean) =>\n write(attr, shorthand, { remove: SIDES.map((s) => `${attr}-${s}`), partial });\n\n const chooseImage = (attr: string) => {\n if (attr === \"src\" && tag === \"mj-image\") return void editor.runCommand(\"open-image-picker\");\n const am = editor.AssetManager;\n am.open({\n types: [\"image\"],\n current: imageUrl(attributes[attr] ?? \"\") ?? undefined,\n select(asset: string | { getSrc: () => string }, complete?: boolean) {\n void write(attr, typeof asset === \"string\" ? asset : asset.getSrc());\n if (complete) am.close();\n },\n } as never);\n };\n\n const safeLink = (attr: string) => (link: string) => {\n if (tag === \"mj-navbar-link\" && attr === \"href\") {\n return isSafeNavbarLink(String(component.parent()?.getAttributes()[\"base-url\"] ?? \"\"), link);\n }\n if (tag === \"mj-navbar\" && attr === \"base-url\") {\n return component\n .components()\n .every((c: Component) => isSafeNavbarLink(link, String(c.getAttributes().href ?? \"\")));\n }\n return isSafeLink(link);\n };\n\n const control = (f: Field): ReactNode => {\n const value = attributes[f.attr] ?? \"\";\n const c = f.control;\n switch (c.type) {\n case \"text\":\n return (\n <TextInput\n value={value}\n placeholder={c.placeholder ?? f.default}\n onCommit={(v) => write(f.attr, v)}\n />\n );\n case \"link\":\n return (\n <TextInput\n value={value}\n placeholder=\"https://\"\n accept={safeLink(f.attr)}\n onCommit={(v) => write(f.attr, v)}\n />\n );\n case \"color\":\n return (\n <ColorField\n value={value}\n placeholder={f.default}\n documentColors={() => documentColors(editor)}\n labels={labels}\n onChange={(v, partial) => write(f.attr, v, { partial })}\n />\n );\n case \"image\":\n return (\n <ImageField\n value={value}\n labels={labels}\n onChoose={() => chooseImage(f.attr)}\n onClear={() => write(f.attr, \"\")}\n />\n );\n case \"length\":\n return (\n <LengthInput\n value={value}\n placeholder={f.default}\n units={c.units}\n negative={c.negative}\n labels={labels}\n onCommit={(v, partial) => write(f.attr, v, { partial })}\n />\n );\n case \"box\":\n return (\n <BoxInput\n attributes={attributes}\n attr={f.attr}\n placeholder={f.default}\n units={c.units}\n labels={labels}\n onCommit={(v, partial) => writeBox(f.attr, v, partial)}\n />\n );\n case \"segmented\":\n return (\n <Segmented\n value={value}\n fallback={f.default}\n options={c.options}\n name={optionName}\n onCommit={(v) => write(f.attr, v)}\n />\n );\n case \"select\":\n return (\n <Select\n value={value}\n fallback={f.default}\n options={c.options}\n name={optionName}\n onCommit={(v) => write(f.attr, v)}\n />\n );\n case \"toggle\":\n return (\n <Toggle\n checked={value === c.on}\n label={t(f.label)}\n onCommit={(on) => write(f.attr, on ? c.on : \"\")}\n />\n );\n case \"network\": {\n const { network, share } = parseNetwork(value);\n return (\n <div className=\"flex flex-col gap-1.5\">\n <Select\n value={network}\n options={c.networks}\n name={optionName}\n onCommit={(n) => write(f.attr, n ? networkName(n, share) : \"\")}\n />\n {network && network !== \"custom\" && (\n <Segmented\n value={share ? \"share\" : \"profile\"}\n options={[\n { value: \"profile\", label: labels.linkTypeProfile },\n { value: \"share\", label: labels.linkTypeShare },\n ]}\n name={(o) => o.label}\n onCommit={(v) => write(f.attr, networkName(network, v === \"share\"))}\n />\n )}\n </div>\n );\n }\n }\n };\n\n const own = (f: Field) =>\n f.control.type === \"box\"\n ? [f.attr, ...SIDES.map((s) => `${f.attr}-${s}`)].some((a) => attributes[a] !== undefined)\n : !!attributes[f.attr];\n const reset = (f: Field) => (f.control.type === \"box\" ? writeBox(f.attr, \"\") : write(f.attr, \"\"));\n const wide = (f: Field) =>\n [\"color\", \"image\", \"link\", \"text\", \"box\", \"network\"].includes(f.control.type);\n\n const row = (f: Field) => (\n <Row\n key={f.attr}\n label={t(f.label)}\n help={labels.inspectorLabels[`${f.label}.help`]}\n own={own(f)}\n wide={wide(f)}\n inline={f.control.type === \"toggle\"}\n labels={labels}\n onReset={() => void reset(f)}\n >\n {control(f)}\n </Row>\n );\n\n const named = new Set(\n fields.flatMap((f) =>\n f.control.type === \"box\" ? [f.attr, ...SIDES.map((s) => `${f.attr}-${s}`)] : [f.attr],\n ),\n );\n const others = Object.entries(attributes).filter(([k]) => !named.has(k) && !HIDDEN.has(k));\n const advanced = visible.filter((f) => f.group === \"advanced\");\n const advancedCount = advanced.length + others.length;\n\n return (\n <div className=\"pb-6\">\n <Header\n editor={editor}\n component={component}\n labels={labels}\n onEmailSettings={onEmailSettings}\n />\n {editor.getDevice() !== \"Desktop\" && (\n <p className=\"mx-3 mt-2 flex items-center gap-1.5 rounded-md bg-panel-elevated px-2 py-1.5 text-[11px] text-panel-muted-fg\">\n <Monitor className=\"size-3.5 shrink-0\" />\n {labels.allScreenSizes}\n </p>\n )}\n <StructureSection editor={editor} component={component} labels={labels} locked={locked} />\n {GROUPS.map((group) => {\n const inGroup = visible.filter((f) => f.group === group);\n if (inGroup.length === 0) return null;\n return (\n <section key={group} className=\"border-b border-panel-border/60 py-2\">\n <h3 className=\"px-3 pb-1 text-[10px] font-semibold tracking-wider text-panel-muted-fg/80 uppercase\">\n {groupName(group, labels)}\n </h3>\n {inGroup.map(row)}\n </section>\n );\n })}\n {advancedCount > 0 && (\n <section className=\"py-1\">\n <button\n type=\"button\"\n onClick={() => setAdvancedOpen((o) => !o)}\n aria-expanded={advancedOpen}\n className=\"flex w-full items-center gap-1 px-3 py-2 text-[10px] font-semibold tracking-wider text-panel-muted-fg/80 uppercase hover:text-panel-fg\"\n >\n <ChevronRight\n className={cn(\"size-3 transition-transform\", advancedOpen && \"rotate-90\")}\n />\n {labels.groupAdvanced}\n <span className=\"font-normal normal-case\">({advancedCount})</span>\n </button>\n {advancedOpen && (\n <>\n {advanced.map(row)}\n {others.length > 0 && (\n <div className=\"px-3 pt-2\">\n <p className=\"pb-1 text-[11px] text-panel-muted-fg\">{labels.otherAttributes}</p>\n <ul className=\"flex flex-col gap-1\">\n {others.map(([k, v]) => (\n <li\n key={k}\n className=\"flex items-center gap-2 rounded-md bg-panel-elevated px-2 py-1 font-mono text-[11px]\"\n >\n <span className=\"text-panel-muted-fg\">{k}</span>\n <span className=\"min-w-0 flex-1 truncate text-panel-fg\" title={v}>\n {v}\n </span>\n <button\n type=\"button\"\n onClick={() => void write(k, \"\")}\n title={labels.removeAttribute}\n aria-label={`${labels.removeAttribute}: ${k}`}\n className=\"text-panel-muted-fg hover:text-panel-fg\"\n >\n <X className=\"size-3\" />\n </button>\n </li>\n ))}\n </ul>\n </div>\n )}\n </>\n )}\n </section>\n )}\n </div>\n );\n}\n\nfunction groupName(group: Exclude<Group, \"advanced\">, labels: EditorLabels): string {\n return {\n content: labels.groupContent,\n layout: labels.groupLayout,\n spacing: labels.groupSpacing,\n style: labels.groupStyle,\n }[group];\n}\n\n/** What is selected, with the actions the canvas toolbar has, so the panel needs no hunt. */\nfunction Header({\n editor,\n component,\n labels,\n onEmailSettings,\n}: {\n editor: Editor;\n component: Component;\n labels: EditorLabels;\n onEmailSettings: () => void;\n}) {\n const tag = tagOf(component);\n const isBody = tag === \"mj-body\";\n const name = isBody\n ? labels.emailSettings\n : (labels.elementNames[tag] ?? tag.replace(/^mj-/, \"\"));\n // What it says, as Layers names it; a column's number is not something it says.\n const words = tag === \"mj-column\" ? \"\" : layerName(component, labels);\n const excerpt = words === name ? \"\" : words;\n const parent = component.parent();\n const action =\n \"flex size-7 items-center justify-center rounded-md text-panel-muted-fg hover:bg-panel-hover hover:text-panel-fg\";\n return (\n <div className=\"sticky top-0 z-10 flex items-center gap-2 border-b border-panel-border bg-panel px-3 py-2\">\n <div className=\"min-w-0 flex-1\">\n <p\n data-focus-target\n tabIndex={-1}\n className=\"truncate text-sm font-medium text-panel-fg outline-none\"\n >\n {name}\n </p>\n {excerpt && !isBody && (\n <p className=\"truncate text-[11px] text-panel-muted-fg\">“{excerpt}”</p>\n )}\n </div>\n {!isBody && parent && (\n <button\n type=\"button\"\n className={action}\n title={labels.selectParent}\n aria-label={labels.selectParent}\n onClick={() => (tagOf(parent) === \"mj-body\" ? onEmailSettings() : editor.select(parent))}\n >\n <ArrowUp className=\"size-3.5\" />\n </button>\n )}\n {!isBody && (\n <>\n <button\n type=\"button\"\n className={action}\n title={labels.duplicate}\n aria-label={labels.duplicate}\n onClick={() => editor.runCommand(\"tlb-clone\")}\n >\n <Copy className=\"size-3.5\" />\n </button>\n <button\n type=\"button\"\n className={action}\n title={labels.deleteElement}\n aria-label={labels.deleteElement}\n onClick={() => editor.runCommand(\"tlb-delete\")}\n >\n <Trash2 className=\"size-3.5\" />\n </button>\n </>\n )}\n </div>\n );\n}\n","\"use client\";\n\n/**\n * The color control in Settings. It keeps a text box — typing a hex is often the fastest\n * way — and opens a picker with the colors the email already uses, which is what keeps a\n * design consistent.\n */\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { HexAlphaColorPicker, HexColorPicker } from \"react-colorful\";\nimport { Pipette } from \"lucide-react\";\n\nimport type { EditorLabels } from \"../../labels.js\";\nimport { cn } from \"../../lib/utils\";\nimport { useFieldLabel } from \"./inspector/controls.js\";\nimport { NAMED_COLORS } from \"./mjml-attributes.js\";\nimport { Popover, PopoverAnchor, PopoverContent, PopoverTrigger } from \"../ui/popover\";\n\n/** Web-safe neutrals and a few saturated hues; emails rarely want more than this. */\nconst PRESETS = [\n \"#000000\",\n \"#374151\",\n \"#6b7280\",\n \"#d1d5db\",\n \"#f3f4f6\",\n \"#ffffff\",\n \"#dc2626\",\n \"#ea580c\",\n \"#ca8a04\",\n \"#16a34a\",\n \"#0284c7\",\n \"#4f46e5\",\n \"#9333ea\",\n \"#db2777\",\n];\n\n// Chrome's EyeDropper; absent elsewhere, and so is the button.\ntype EyeDropperCtor = new () => { open: () => Promise<{ sRGBHex: string }> };\nconst eyeDropper = (): EyeDropperCtor | undefined =>\n (globalThis as { EyeDropper?: EyeDropperCtor }).EyeDropper;\n\nexport default function ColorField({\n value,\n placeholder,\n documentColors,\n labels,\n onChange,\n}: {\n value: string;\n /** The property's default, shown when no value is set. */\n placeholder?: string;\n /** Read when the picker opens, so it reflects the email as it is now. */\n documentColors: () => string[];\n labels: EditorLabels;\n /** `partial` while dragging, so a drag is one undo step, not one per pixel. */\n onChange: (value: string, partial: boolean) => void;\n}) {\n const field = useFieldLabel();\n const [text, setText] = useState(value);\n const [open, setOpen] = useState(false);\n const [used, setUsed] = useState<string[]>([]);\n // Whether a pointer is down on the picker, and the value its drag left as a partial update.\n const pressed = useRef(false);\n const dragged = useRef<string | null>(null);\n const fieldRef = useRef<HTMLDivElement>(null);\n // The picker opens beside the panel the field sits in, level with the field. Anchored to\n // the field itself it covered the panel, since a property can be half the panel wide.\n const anchor = useRef({\n getBoundingClientRect: () => {\n const field = fieldRef.current?.getBoundingClientRect() ?? new DOMRect();\n const panel = fieldRef.current?.closest(\".editor-dark\")?.getBoundingClientRect();\n return new DOMRect(panel?.right ?? field.right, field.top, 0, field.height);\n },\n });\n\n useEffect(() => setText(value), [value]);\n const latestOnChange = useRef(onChange);\n latestOnChange.current = onChange;\n // A drag ends as a real change, with an undo step, when the pointer is released: GrapesJS\n // writes to whatever is selected at that moment, and nothing else can be selected while\n // the pointer is captured. The view going away mid-drag ends it too.\n const release = useCallback(() => {\n pressed.current = false;\n if (dragged.current !== null) latestOnChange.current(dragged.current, false);\n dragged.current = null;\n }, []);\n // On the document: when the captured element is removed mid-drag (the popover closing, or\n // the alpha slider appearing), the browser sends the release there rather than to it.\n useEffect(() => {\n document.addEventListener(\"lostpointercapture\", release);\n return () => {\n document.removeEventListener(\"lostpointercapture\", release);\n release();\n };\n }, [release]);\n\n const hex = toHex(value) ?? toHex(placeholder ?? \"\") ?? \"#000000\";\n // Translucent colors keep their alpha, and get the slider to change it.\n const translucent = hex.length === 9;\n // Unset, the swatch shows the default the email falls back to, as the text box does.\n const shown = value || placeholder || \"\";\n\n const commit = (next: string) => {\n dragged.current = null;\n const color = mjmlColor(next);\n // MJML would reject it, and with it every later write of the agent's; the field goes back.\n if (color === null) return setText(value);\n setText(color);\n onChange(color, false);\n };\n\n // react-colorful reports no drag end, and moves by arrow keys as well; those are whole changes.\n const drag = (picked: string) => {\n // The alpha picker reports `#rrggbbaa`, which MJML rejects.\n const next = mjmlColor(picked) ?? picked;\n setText(next);\n if (!pressed.current) return commit(next);\n dragged.current = next;\n onChange(next, true);\n };\n\n const pickFromScreen = async () => {\n const Ctor = eyeDropper();\n if (!Ctor) return;\n try {\n const { sRGBHex } = await new Ctor().open();\n commit(sRGBHex);\n } catch {\n // Escape cancels the eyedropper; nothing to do.\n }\n };\n\n return (\n <Popover\n open={open}\n onOpenChange={(next) => {\n if (next) setUsed(documentColors());\n // Closing by Escape or a click outside unmounts the hex input without a blur, so\n // a value typed there is committed here rather than lost.\n else if (text.trim() !== value) commit(text.trim());\n setOpen(next);\n }}\n >\n <PopoverAnchor virtualRef={anchor} />\n <div\n ref={fieldRef}\n className=\"flex h-8 w-full items-center gap-1.5 rounded-md border border-panel-border bg-panel-elevated pr-1.5 pl-2 focus-within:border-brand\"\n >\n <input\n value={text}\n placeholder={placeholder}\n spellCheck={false}\n {...field}\n onChange={(e) => setText(e.target.value)}\n onBlur={() => text !== value && commit(text.trim())}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") commit(text.trim());\n if (e.key === \"Escape\") setText(value);\n }}\n className=\"min-w-0 flex-1 bg-transparent font-mono text-xs text-panel-fg outline-none placeholder:text-panel-muted-fg\"\n />\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n title={labels.colorPickerOpen}\n aria-label={labels.colorPickerOpen}\n className=\"relative size-5 shrink-0 overflow-hidden rounded border border-white/20 outline-none focus-visible:ring-2 focus-visible:ring-brand\"\n >\n <Checkerboard />\n {mjmlColor(shown) && (\n <span className=\"absolute inset-0\" style={{ background: shown }} />\n )}\n </button>\n </PopoverTrigger>\n </div>\n <PopoverContent\n side=\"right\"\n align=\"start\"\n sideOffset={8}\n className=\"editor-dark flex w-52 flex-col gap-2.5 border border-panel-border bg-panel p-2.5 text-panel-fg\"\n >\n <div\n onPointerDownCapture={(e) => {\n pressed.current = true;\n // Captured, so a release over the canvas iframe still reaches this document. On the\n // target, not this wrapper: the mousedown react-colorful handles follows the capture.\n (e.target as Element).setPointerCapture(e.pointerId);\n }}\n >\n {translucent ? (\n <HexAlphaColorPicker color={hex} onChange={drag} className=\"color-field-picker\" />\n ) : (\n <HexColorPicker color={hex} onChange={drag} className=\"color-field-picker\" />\n )}\n </div>\n\n <div className=\"flex items-center gap-1.5\">\n <span\n className=\"size-6 shrink-0 rounded border border-white/20\"\n style={{ background: hex }}\n />\n <input\n value={text}\n spellCheck={false}\n {...field}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={(e) => e.key === \"Enter\" && commit(text.trim())}\n onBlur={() => text !== value && commit(text.trim())}\n className=\"h-6 min-w-0 flex-1 rounded border border-panel-border bg-panel-elevated px-1.5 font-mono text-[11px] outline-none focus:border-brand\"\n />\n {eyeDropper() && (\n <button\n type=\"button\"\n onClick={() => void pickFromScreen()}\n title={labels.colorPickerEyedropper}\n aria-label={labels.colorPickerEyedropper}\n className=\"flex size-6 shrink-0 items-center justify-center rounded border border-panel-border bg-panel-elevated text-panel-muted-fg hover:text-panel-fg\"\n >\n <Pipette className=\"size-3\" />\n </button>\n )}\n </div>\n\n {used.length > 0 && (\n <Swatches\n title={labels.colorPickerDocument}\n colors={used}\n current={hex}\n onPick={commit}\n />\n )}\n <Swatches\n title={labels.colorPickerPresets}\n colors={PRESETS}\n current={hex}\n onPick={commit}\n transparentLabel={labels.colorPickerTransparent}\n />\n </PopoverContent>\n </Popover>\n );\n}\n\nfunction Swatches({\n title,\n colors,\n current,\n onPick,\n transparentLabel,\n}: {\n title: string;\n colors: string[];\n current: string;\n onPick: (color: string) => void;\n /** Adds a \"transparent\" swatch at the end when given. */\n transparentLabel?: string;\n}) {\n return (\n <div>\n <p className=\"mb-1 text-[10px] font-medium tracking-wide text-panel-muted-fg uppercase\">\n {title}\n </p>\n <div className=\"grid grid-cols-8 gap-1\">\n {colors.map((color) => (\n <button\n key={color}\n type=\"button\"\n title={color}\n onClick={() => onPick(color)}\n className={cn(\n \"aspect-square rounded border border-white/15 outline-none hover:scale-110 focus-visible:ring-2 focus-visible:ring-brand\",\n color.toLowerCase() === current.toLowerCase() && \"ring-2 ring-brand\",\n )}\n style={{ background: color }}\n />\n ))}\n {transparentLabel && (\n <button\n type=\"button\"\n title={transparentLabel}\n onClick={() => onPick(\"transparent\")}\n className=\"relative aspect-square overflow-hidden rounded border border-white/15 outline-none hover:scale-110 focus-visible:ring-2 focus-visible:ring-brand\"\n >\n <Checkerboard />\n </button>\n )}\n </div>\n </div>\n );\n}\n\nfunction Checkerboard() {\n return (\n <span\n className=\"absolute inset-0\"\n style={{\n backgroundImage: \"repeating-conic-gradient(#9ca3af 0% 25%, #e5e7eb 0% 50%)\",\n backgroundSize: \"8px 8px\",\n }}\n />\n );\n}\n\n/**\n * A colour as MJML accepts it — `#rrggbb`, `rgba()` when translucent, or a name — or null for\n * anything MJML's Color type rejects. Empty stays empty: the attribute is removed.\n */\nexport function mjmlColor(value: string): string | null {\n const v = value.trim();\n if (v === \"\") return \"\";\n if (NAMED_COLORS.has(v.toLowerCase())) return v.toLowerCase();\n const hex = toHex(v);\n if (!hex) return null;\n if (hex.length === 7) return hex;\n const [r, g, b, a] = [1, 3, 5, 7].map((i) => parseInt(hex.slice(i, i + 2), 16));\n // MJML's pattern wants a digit before the point and at most three after it.\n return `rgba(${r},${g},${b},${Number((a! / 255).toFixed(2))})`;\n}\n\n/**\n * `#rgb`, `#rrggbb(aa)` and `rgb()/rgba()` to `#rrggbb`, or `#rrggbbaa` when translucent\n * unless `opaque` is set; anything else (names, `transparent`) to null.\n */\nexport function toHex(value: string, { opaque = false } = {}): string | null {\n const v = value.trim().toLowerCase();\n const short = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/.exec(v);\n if (short) return `#${short[1]}${short[1]}${short[2]}${short[2]}${short[3]}${short[3]}`;\n if (/^#[0-9a-f]{6}$/.test(v)) return v;\n if (/^#[0-9a-f]{8}$/.test(v)) return opaque || v.endsWith(\"ff\") ? v.slice(0, 7) : v;\n const rgb = /^rgba?\\(\\s*(\\d+)[\\s,]+(\\d+)[\\s,]+(\\d+)(?:[\\s,/]+([\\d.]+%?))?/.exec(v);\n if (rgb) {\n const channels = [rgb[1], rgb[2], rgb[3]].map((n) => Math.min(255, Number(n)));\n const alphaText = rgb[4];\n const alpha = alphaText?.endsWith(\"%\") ? parseFloat(alphaText) / 100 : Number(alphaText ?? 1);\n if (!opaque && alpha < 1) channels.push(Math.round(Math.max(0, alpha) * 255));\n return `#${channels.map((n) => n.toString(16).padStart(2, \"0\")).join(\"\")}`;\n }\n return null;\n}\n","\"use client\";\n\n/**\n * The inputs the Settings inspector is built from. Text-like inputs keep a draft and commit\n * on blur or Enter: every committed attribute re-renders the element through MJML, and one\n * undo step per keystroke is not an undo history anyone can use.\n */\n\nimport {\n createContext,\n useContext,\n useEffect,\n useId,\n useRef,\n useState,\n type KeyboardEvent,\n type ReactNode,\n} from \"react\";\nimport {\n AlignCenter,\n AlignJustify,\n AlignLeft,\n AlignRight,\n ChevronDown,\n ChevronUp,\n CircleHelp,\n Grid2x2,\n RotateCcw,\n} from \"lucide-react\";\n\nimport type { EditorLabels } from \"../../../labels.js\";\nimport { cn } from \"../../../lib/utils\";\nimport { Switch } from \"../../ui/switch\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"../../ui/tooltip\";\nimport type { Option, Unit } from \"./types.js\";\nimport { boxShorthand, parseLength, readBox, SIDES, type Sides } from \"./values.js\";\n\nconst FIELD =\n \"h-7 w-full min-w-0 rounded-md border border-panel-border bg-panel-elevated px-2 text-xs text-panel-fg outline-none placeholder:text-panel-muted-fg/70 focus:border-brand\";\n\n// The ids of the caption and the help of the Row a control sits in: the caption is not a\n// <label>, as it holds the reset button, so the control is named by reference.\nconst FieldLabel = createContext<{ label?: string; help?: string }>({});\n/** `aria-labelledby` and `aria-describedby` for a control inside a Row. */\nexport const useFieldLabel = () => {\n const { label, help } = useContext(FieldLabel);\n return { \"aria-labelledby\": label, \"aria-describedby\": help };\n};\n\n/** A label, the control, and — when the element sets its own value — a dot and a reset. */\nexport function Row({\n label,\n help,\n own,\n wide,\n inline,\n labels,\n onReset,\n children,\n}: {\n label: string;\n help?: string;\n own: boolean;\n /** Label above the control rather than beside it, for controls that need the width. */\n wide?: boolean;\n /** Label across the row and the control at its end, for a switch. */\n inline?: boolean;\n labels: EditorLabels;\n onReset: () => void;\n children: ReactNode;\n}) {\n const id = useId();\n const helpId = useId();\n const [helpOpen, setHelpOpen] = useState(false);\n const control = (\n <FieldLabel.Provider value={{ label: id, help: help ? helpId : undefined }}>\n {children}\n </FieldLabel.Provider>\n );\n const caption = (\n <span className=\"flex min-w-0 items-center gap-1.5 text-[11px] text-panel-muted-fg\">\n <span\n aria-hidden\n className={cn(\"size-1.5 shrink-0 rounded-full\", own ? \"bg-brand\" : \"bg-transparent\")}\n />\n <span id={id} className=\"truncate\">\n {label}\n </span>\n {/* On demand: shown under every field, the help doubled the panel's length. */}\n {help && (\n // Its own provider: a host need not wrap the editor in one, as only EditorHeader asked.\n // Opened by a tap as well: Radix opens a tooltip on hover and focus, not on touch.\n <TooltipProvider>\n <Tooltip open={helpOpen} onOpenChange={setHelpOpen}>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n aria-label={help}\n onClick={() => setHelpOpen((open) => !open)}\n className=\"-m-0.5 shrink-0 rounded p-0.5 text-panel-muted-fg/70 hover:text-panel-fg focus-visible:text-panel-fg\"\n >\n <CircleHelp className=\"size-3\" />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"top\" className=\"max-w-56 leading-snug\">\n {help}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n {own && (\n <button\n type=\"button\"\n onClick={onReset}\n title={labels.resetToDefault}\n aria-label={`${labels.resetToDefault}: ${label}`}\n className=\"ml-auto rounded p-0.5 text-panel-muted-fg opacity-0 group-hover/row:opacity-100 hover:text-panel-fg focus-visible:opacity-100\"\n >\n <RotateCcw className=\"size-3\" />\n </button>\n )}\n </span>\n );\n return (\n <div className=\"group/row px-3 py-1\">\n {wide ? (\n <div className=\"flex flex-col gap-1\">\n {caption}\n {control}\n </div>\n ) : inline ? (\n <div className=\"flex items-center justify-between gap-2\">\n {caption}\n {control}\n </div>\n ) : (\n <div className=\"grid grid-cols-[92px_minmax(0,1fr)] items-center gap-2\">\n {caption}\n {control}\n </div>\n )}\n {help && (\n <span id={helpId} hidden>\n {help}\n </span>\n )}\n </div>\n );\n}\n\n/** `source`: what the shown value is read from, when that can change while it does not. */\nfunction useDraft(value: string, commit: (next: string) => void, source: string = value) {\n const [draft, setDraft] = useState(value);\n useEffect(() => setDraft(value), [value, source]);\n const done = () => {\n if (draft.trim() !== value) commit(draft.trim());\n };\n const onKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") e.currentTarget.blur();\n if (e.key === \"Escape\") {\n setDraft(value);\n // Blurring after the reset commits nothing, since the draft equals the value again.\n requestAnimationFrame(() => (e.target as HTMLInputElement).blur());\n }\n };\n return { draft, setDraft, done, onKeyDown };\n}\n\nexport function TextInput({\n value,\n placeholder,\n accept,\n onCommit,\n}: {\n value: string;\n placeholder?: string;\n /** False for text the field must not write; it is kept, marked, for the visitor to fix. */\n accept?: (next: string) => boolean;\n onCommit: (next: string) => void;\n}) {\n const [invalid, setInvalid] = useState(false);\n const field = useFieldLabel();\n const { draft, setDraft, done, onKeyDown } = useDraft(value, (next) => {\n const ok = !accept || accept(next);\n setInvalid(!ok);\n if (ok) onCommit(next);\n });\n return (\n <input\n className={cn(FIELD, invalid && \"border-red-400\")}\n {...field}\n aria-invalid={invalid}\n value={draft}\n placeholder={placeholder}\n onChange={(e) => setDraft(e.target.value)}\n onBlur={done}\n onKeyDown={onKeyDown}\n />\n );\n}\n\nconst BARE_NUMBER = /^-?\\d*\\.?\\d+$/;\n\n/**\n * Typed text as the length to write: a bare number takes `unit` (the field's current one),\n * so typing `24` into a px field means 24px. Null for what the field cannot write, a negative\n * included unless MJML takes one there.\n */\nexport function normaliseLength(\n text: string,\n units: readonly Unit[],\n negative = false,\n unit: Unit = units[0]!,\n): string | null {\n if (text === \"\") return \"\";\n // Before parseLength, which reads a bare number as unitless where that is allowed.\n const parsed = BARE_NUMBER.test(text) ? { amount: text, unit } : parseLength(text, units);\n if (!parsed || (!negative && parsed.amount.startsWith(\"-\"))) return null;\n return `${parsed.amount}${parsed.unit}`;\n}\n\n/**\n * `amount` moved by `delta`, to two decimals, not below zero unless allowed. Unchanged where\n * the result would not be a plain decimal (`1e+22`, `Infinity`), which MJML rejects.\n */\nexport function stepAmount(amount: string, delta: number, negative = false): string {\n const moved = Math.round((Number(amount) + delta) * 100) / 100;\n const next = String(negative ? moved : Math.max(0, moved));\n return BARE_NUMBER.test(next) ? next : amount;\n}\n\n// A hold on a step button keeps stepping, after a pause long enough for a single click.\nconst REPEAT_AFTER_MS = 400;\nconst REPEAT_EVERY_MS = 60;\n\n/**\n * A number with its unit beside it, steppable by the arrows, the arrow keys (Shift for 10) or\n * holding a step button. A hold is shown as it goes and recorded as one change when released.\n * A value the field cannot read, such as one the agent wrote in another unit, shows whole and\n * is not stepped: stepping it from zero would throw it away.\n */\nexport function LengthInput({\n value,\n placeholder,\n units,\n negative = false,\n compact = false,\n labelledBy,\n labels,\n onCommit,\n}: {\n value: string;\n placeholder?: string;\n units: readonly Unit[];\n negative?: boolean;\n /** Too narrow for the arrows to stay: they show on hover and focus, the unit cannot change. */\n compact?: boolean;\n /** Ids naming the field, when the Row's caption alone does not. */\n labelledBy?: string;\n labels: EditorLabels;\n onCommit: (next: string, partial?: boolean) => void;\n}) {\n const fieldLabel = useFieldLabel();\n const own = parseLength(value, units);\n const fallback = parseLength(placeholder ?? \"\", units);\n // Picked while the field is empty; a value carries its own unit.\n const [picked, setPicked] = useState<Unit | null>(null);\n const unit = own?.unit ?? picked ?? fallback?.unit ?? units[0]!;\n const [invalid, setInvalid] = useState(false);\n // The latest, for a hold that outlives the render it began in: what it may write can change\n // under it, as when an agent turn locks the editor.\n const commit = useRef(onCommit);\n commit.current = onCommit;\n // Ends a hold still running: before any other edit of this field, and when it goes away.\n const endHold = useRef<(() => void) | null>(null);\n useEffect(() => () => endHold.current?.(), []);\n\n const { draft, setDraft, done, onKeyDown } = useDraft(\n own ? own.amount : value,\n (next) => {\n endHold.current?.();\n const normal = normaliseLength(next, units, negative, unit);\n setInvalid(normal === null);\n if (normal !== null) commit.current(normal);\n },\n value,\n );\n\n // Where a step starts: what is typed, else the default in the current unit, else zero.\n // Null for text the field cannot read.\n const from = (): { amount: string; unit: Unit } | null => {\n const text = draft.trim();\n if (BARE_NUMBER.test(text)) return { amount: text, unit };\n if (text === \"\") return { amount: fallback?.amount ?? \"0\", unit };\n return parseLength(text, units);\n };\n const stepOnce = (delta: number) => {\n endHold.current?.();\n const start = from();\n if (!start) return setInvalid(true);\n const amount = stepAmount(start.amount, delta, negative);\n setInvalid(false);\n setDraft(amount);\n commit.current(`${amount}${start.unit}`);\n };\n const onKey = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key !== \"ArrowUp\" && e.key !== \"ArrowDown\") return onKeyDown(e);\n e.preventDefault();\n stepOnce((e.key === \"ArrowUp\" ? 1 : -1) * (e.shiftKey ? 10 : 1));\n };\n\n const press = (direction: 1 | -1) => (e: React.PointerEvent<HTMLButtonElement>) => {\n // One hold at a time: a second finger, or the other arrow, waits for the first to end.\n if (e.button !== 0 || endHold.current) return;\n // Focus stays where it was; the press is not a click on the field.\n e.preventDefault();\n const start = from();\n if (!start) return setInvalid(true);\n const delta = direction * (e.shiftKey ? 10 : 1);\n let amount = stepAmount(start.amount, delta, negative);\n const show = () => {\n setInvalid(false);\n setDraft(amount);\n commit.current(`${amount}${start.unit}`, true);\n };\n show();\n let timer = window.setTimeout(function repeat() {\n amount = stepAmount(amount, delta, negative);\n show();\n timer = window.setTimeout(repeat, REPEAT_EVERY_MS);\n }, REPEAT_AFTER_MS);\n const button = e.currentTarget;\n // Captured, so a release over the canvas iframe still reaches the button; the window, the\n // blur and the cancel end it where capture is missing or the pointer is taken away.\n try {\n button.setPointerCapture(e.pointerId);\n } catch {\n // Not supported here; the window's listeners below end the hold.\n }\n const events = [\"pointerup\", \"pointercancel\", \"lostpointercapture\"] as const;\n const pointerId = e.pointerId;\n const end = () => {\n window.clearTimeout(timer);\n for (const type of events) button.removeEventListener(type, release);\n window.removeEventListener(\"pointerup\", release);\n window.removeEventListener(\"blur\", end);\n endHold.current = null;\n commit.current(`${amount}${start.unit}`);\n };\n // Only the pointer that pressed: another finger lifting elsewhere leaves the hold running.\n const release = (ev: Event) => {\n if (\n (ev as PointerEvent).pointerId === undefined ||\n (ev as PointerEvent).pointerId === pointerId\n )\n end();\n };\n endHold.current = end;\n for (const type of events) button.addEventListener(type, release);\n window.addEventListener(\"pointerup\", release);\n window.addEventListener(\"blur\", end);\n };\n // A click with no pointer behind it (`detail` 0) is the keyboard or assistive technology\n // pressing the button; a pointer's click follows the press, which already stepped.\n const click = (direction: 1 | -1) => (e: React.MouseEvent<HTMLButtonElement>) => {\n if (e.detail === 0) stepOnce(direction);\n };\n\n const pickUnit = () => {\n endHold.current?.();\n const next = units[(units.indexOf(unit) + 1) % units.length]!;\n const text = draft.trim();\n if (!BARE_NUMBER.test(text)) return setPicked(next);\n const normal = normaliseLength(text, units, negative, next);\n // A number the field refuses (a negative) is not written in another unit either.\n if (normal === null) return setInvalid(true);\n setPicked(next);\n commit.current(normal);\n };\n const unitName = (u: Unit) => u || labels.noUnit;\n // Only a value the field reads as a number has a unit to show beside it.\n const readable = draft.trim() === \"\" || BARE_NUMBER.test(draft.trim());\n\n const arrow =\n \"flex h-1/2 w-3.5 items-center justify-center text-panel-muted-fg hover:bg-panel-hover hover:text-panel-fg\";\n return (\n <div\n className={cn(\n \"group/length flex h-7 w-full min-w-0 items-center overflow-hidden rounded-md border border-panel-border bg-panel-elevated focus-within:border-brand\",\n invalid && \"border-red-400\",\n )}\n >\n <input\n className=\"h-full w-full min-w-0 flex-1 bg-transparent pl-2 font-mono text-xs text-panel-fg outline-none placeholder:text-panel-muted-fg/70\"\n value={draft}\n placeholder={fallback ? fallback.amount : placeholder}\n inputMode=\"decimal\"\n {...fieldLabel}\n aria-labelledby={labelledBy ?? fieldLabel[\"aria-labelledby\"]}\n aria-invalid={invalid}\n onChange={(e) => {\n endHold.current?.();\n setDraft(e.target.value);\n }}\n onBlur={done}\n onKeyDown={onKey}\n />\n {readable &&\n (units.length > 1 && !compact ? (\n <button\n type=\"button\"\n onClick={pickUnit}\n title={labels.changeUnit(unitName(unit))}\n aria-label={labels.changeUnit(unitName(unit))}\n className=\"shrink-0 rounded px-0.5 font-mono text-[10px] text-panel-muted-fg underline decoration-dotted underline-offset-2 hover:text-panel-fg\"\n >\n {unitName(unit)}\n </button>\n ) : (\n // Narrow, the unit gives its place to the arrows while they show; a unit is typed.\n <span\n aria-hidden\n className={cn(\n \"shrink-0 px-0.5 font-mono text-[10px] text-panel-muted-fg\",\n compact && \"group-focus-within/length:hidden group-hover/length:hidden\",\n )}\n >\n {unitName(unit)}\n </span>\n ))}\n <span\n className={cn(\n \"h-full shrink-0 flex-col border-l border-panel-border\",\n compact ? \"hidden group-focus-within/length:flex group-hover/length:flex\" : \"flex\",\n )}\n >\n <button\n type=\"button\"\n tabIndex={-1}\n aria-label={labels.increase}\n onPointerDown={press(1)}\n onClick={click(1)}\n className={arrow}\n >\n <ChevronUp className=\"size-2.5\" />\n </button>\n <button\n type=\"button\"\n tabIndex={-1}\n aria-label={labels.decrease}\n onPointerDown={press(-1)}\n onClick={click(-1)}\n className={arrow}\n >\n <ChevronDown className=\"size-2.5\" />\n </button>\n </span>\n </div>\n );\n}\n\n/** Vertical/horizontal pair, which is how emails are spaced, expanding to four sides. */\nexport function BoxInput({\n attributes,\n attr,\n placeholder,\n units,\n labels,\n onCommit,\n}: {\n attributes: Readonly<Record<string, string>>;\n attr: string;\n placeholder?: string;\n units: readonly Unit[];\n labels: EditorLabels;\n onCommit: (shorthand: string, partial?: boolean) => void;\n}) {\n const sides = readBox(attributes, attr);\n const defaults = readBox(placeholder ? { [attr]: placeholder } : {}, attr);\n const symmetric = sides[0] === sides[2] && sides[1] === sides[3];\n const [each, setEach] = useState(!symmetric);\n useEffect(() => {\n if (!symmetric) setEach(true);\n }, [symmetric]);\n\n const set = (indices: number[], v: string, partial?: boolean) => {\n // Sides left unset keep showing MJML's default; writing them as 0 would move them.\n const next = sides.map((s, i) => s || defaults[i]!) as Sides;\n for (const i of indices) next[i] = v || defaults[i]!;\n onCommit(next.every((s, i) => s === defaults[i]) ? \"\" : boxShorthand(next), partial);\n };\n\n const fieldLabel = useFieldLabel();\n const sideId = useId();\n const sideNames = [labels.sideTop, labels.sideRight, labels.sideBottom, labels.sideLeft];\n const pairs: [string, number[]][] = each\n ? SIDES.map((_, i) => [sideNames[i]!, [i]])\n : [\n [labels.sidesVertical, [0, 2]],\n [labels.sidesHorizontal, [1, 3]],\n ];\n\n return (\n <div className=\"flex items-start gap-1.5\">\n <div className={cn(\"grid flex-1 gap-1.5\", each ? \"grid-cols-4\" : \"grid-cols-2\")}>\n {pairs.map(([name, indices]) => (\n <label key={name} className=\"flex min-w-0 flex-col gap-0.5\" title={name}>\n <LengthInput\n value={sides[indices[0]!]!}\n placeholder={defaults[indices[0]!] || \"0\"}\n units={units}\n compact={each}\n labels={labels}\n labelledBy={[fieldLabel[\"aria-labelledby\"], `${sideId}-${indices[0]}`]\n .filter(Boolean)\n .join(\" \")}\n onCommit={(v, partial) => set(indices, v, partial)}\n />\n <span\n id={`${sideId}-${indices[0]}`}\n className=\"truncate text-center text-[10px] text-panel-muted-fg/80\"\n >\n {name}\n </span>\n </label>\n ))}\n </div>\n <button\n type=\"button\"\n onClick={() => setEach((v) => !v)}\n disabled={each && !symmetric}\n aria-pressed={each}\n title={labels.editEachSide}\n aria-label={labels.editEachSide}\n className={cn(\n \"flex size-7 shrink-0 items-center justify-center rounded-md border border-panel-border text-panel-muted-fg hover:text-panel-fg disabled:opacity-40\",\n each && \"border-brand text-panel-fg\",\n )}\n >\n <Grid2x2 className=\"size-3.5\" />\n </button>\n </div>\n );\n}\n\nconst ALIGN_ICONS: Record<string, ReactNode> = {\n left: <AlignLeft className=\"size-3.5\" />,\n center: <AlignCenter className=\"size-3.5\" />,\n right: <AlignRight className=\"size-3.5\" />,\n justify: <AlignJustify className=\"size-3.5\" />,\n};\n\nexport function Segmented({\n value,\n fallback,\n options,\n name,\n onCommit,\n}: {\n value: string;\n /** Shown as selected, unpressed, while nothing is set: MJML's default. */\n fallback?: string;\n options: readonly Option[];\n name: (option: Option) => string;\n onCommit: (next: string) => void;\n}) {\n const current = value || fallback;\n const iconsOnly = options.every((o) => o.value in ALIGN_ICONS);\n return (\n <div className=\"flex h-7 overflow-hidden rounded-md border border-panel-border bg-panel-elevated\">\n {options.map((o) => {\n const active = current === o.value;\n return (\n <button\n key={o.value}\n type=\"button\"\n aria-pressed={active}\n title={name(o)}\n aria-label={name(o)}\n onClick={() => o.value !== value && onCommit(o.value)}\n className={cn(\n \"flex min-w-0 flex-1 items-center justify-center px-1 text-[11px] text-panel-muted-fg transition-colors hover:text-panel-fg\",\n active &&\n (value\n ? \"bg-brand text-brand-fg hover:text-brand-fg\"\n : \"bg-panel-hover text-panel-fg\"),\n )}\n >\n {iconsOnly ? ALIGN_ICONS[o.value] : <span className=\"truncate\">{name(o)}</span>}\n </button>\n );\n })}\n </div>\n );\n}\n\nexport function Select({\n value,\n fallback,\n options,\n name,\n onCommit,\n}: {\n value: string;\n fallback?: string;\n options: readonly Option[];\n name: (option: Option) => string;\n onCommit: (next: string) => void;\n}) {\n // A value no option names (an agent's own font stack) stays visible and selected.\n const known = !value || options.some((o) => o.value === value);\n const fallbackOption = options.find((o) => o.value === fallback);\n const field = useFieldLabel();\n return (\n <select\n className={cn(FIELD, \"px-1.5\")}\n {...field}\n value={value || \"\"}\n onChange={(e) => onCommit(e.target.value)}\n >\n {/* Unset: MJML's default applies. */}\n <option value=\"\">{fallbackOption ? name(fallbackOption) : \"—\"}</option>\n {!known && <option value={value}>{value}</option>}\n {options.map((o) => (\n <option key={o.value} value={o.value}>\n {name(o)}\n </option>\n ))}\n </select>\n );\n}\n\nexport function Toggle({\n checked,\n label,\n onCommit,\n}: {\n checked: boolean;\n label: string;\n onCommit: (next: boolean) => void;\n}) {\n return (\n <Switch\n checked={checked}\n onCheckedChange={onCommit}\n aria-label={label}\n className=\"justify-self-end data-checked:bg-brand data-unchecked:bg-panel-border\"\n />\n );\n}\n","/** Reading and writing attribute values the way MJML spells them. */\n\nimport type { Unit } from \"./types.js\";\n\nexport const SIDES = [\"top\", \"right\", \"bottom\", \"left\"] as const;\nexport type Sides = [string, string, string, string];\n\n/** CSS shorthand order: one value for all, two for vertical/horizontal, three, or four. */\nexport function expandBox(value: string): Sides | null {\n const parts = value.trim().split(/\\s+/).filter(Boolean);\n if (parts.length === 0 || parts.length > 4) return null;\n const [t, r = t, b = t, l = r] = parts as [string, string?, string?, string?];\n return [t, r, b, l];\n}\n\n/**\n * Each side as MJML resolves it: a `-top`-style longhand wins over the shorthand, and a side\n * neither sets is empty. Agents write both forms, so reading only one showed wrong values.\n */\nexport function readBox(attributes: Readonly<Record<string, string>>, attr: string): Sides {\n const short = expandBox(attributes[attr] ?? \"\") ?? [\"\", \"\", \"\", \"\"];\n return SIDES.map((side, i) => attributes[`${attr}-${side}`] ?? short[i]!) as Sides;\n}\n\n/** The shortest shorthand for four sides; empty sides become `0`. */\nexport function boxShorthand(sides: Sides): string {\n const [t, r, b, l] = sides.map((s) => s.trim() || \"0\") as Sides;\n if (t === b && r === l) return t === r ? t : `${t} ${r}`;\n if (r === l) return `${t} ${r} ${b}`;\n return `${t} ${r} ${b} ${l}`;\n}\n\nexport type Length = { amount: string; unit: Unit };\n\n/** `\"20px\"` to `{ amount: \"20\", unit: \"px\" }`; null for anything that is not one length. */\nexport function parseLength(value: string, units: readonly Unit[]): Length | null {\n const match = /^(-?\\d*\\.?\\d+)\\s*(px|%|em)?$/.exec(value.trim());\n if (!match) return null;\n const unit = (match[2] ?? \"\") as Unit;\n return units.includes(unit) ? { amount: match[1]!, unit } : null;\n}\n\nconst NO_SHARE = \"-noshare\";\n\n/**\n * mj-social-element names a network and, without `-noshare`, makes the icon open a \"share\n * this page\" dialog instead of linking to the profile. Custom has no share variant.\n */\nexport function parseNetwork(name: string): { network: string; share: boolean } {\n return name.endsWith(NO_SHARE)\n ? { network: name.slice(0, -NO_SHARE.length), share: false }\n : { network: name, share: name !== \"custom\" && name !== \"\" };\n}\n\nexport function networkName(network: string, share: boolean): string {\n return share || network === \"custom\" ? network : `${network}${NO_SHARE}`;\n}\n\n// The agent backends refuse the same links, so the rule lives in core.\nexport { isSafeLink, isSafeNavbarLink } from \"@mjml-agent-editor/core\";\n","/**\n * The attributes MJML accepts on each tag the editor renders, copied from mjml 4.18's\n * `allowedAttributes` (a test keeps the copy in step with the installed package).\n *\n * The agent compiles the whole document strictly on every write, so one illegal attribute\n * anywhere — the sidebar used to write `title` and `display` — makes every later agent edit\n * fail on an element it never touched.\n */\n// prettier-ignore\nexport const ALLOWED_ATTRIBUTES: Readonly<Record<string, readonly string[]>> = {\n \"mj-body\": [\n \"background-color\", \"width\",\n ],\n \"mj-wrapper\": [\n \"background-color\", \"background-position\", \"background-position-x\",\n \"background-position-y\", \"background-repeat\", \"background-size\", \"background-url\",\n \"border\", \"border-bottom\", \"border-left\", \"border-radius\", \"border-right\", \"border-top\",\n \"direction\", \"full-width\", \"gap\", \"padding\", \"padding-bottom\", \"padding-left\",\n \"padding-right\", \"padding-top\", \"text-align\", \"text-padding\",\n ],\n \"mj-section\": [\n \"background-color\", \"background-position\", \"background-position-x\",\n \"background-position-y\", \"background-repeat\", \"background-size\", \"background-url\",\n \"border\", \"border-bottom\", \"border-left\", \"border-radius\", \"border-right\", \"border-top\",\n \"direction\", \"full-width\", \"padding\", \"padding-bottom\", \"padding-left\", \"padding-right\",\n \"padding-top\", \"text-align\", \"text-padding\",\n ],\n \"mj-column\": [\n \"background-color\", \"border\", \"border-bottom\", \"border-left\", \"border-radius\",\n \"border-right\", \"border-top\", \"direction\", \"inner-background-color\", \"inner-border\",\n \"inner-border-bottom\", \"inner-border-left\", \"inner-border-radius\", \"inner-border-right\",\n \"inner-border-top\", \"padding\", \"padding-bottom\", \"padding-left\", \"padding-right\",\n \"padding-top\", \"vertical-align\", \"width\",\n ],\n \"mj-group\": [\n \"background-color\", \"direction\", \"vertical-align\", \"width\",\n ],\n \"mj-text\": [\n \"align\", \"background-color\", \"color\", \"container-background-color\", \"font-family\",\n \"font-size\", \"font-style\", \"font-weight\", \"height\", \"letter-spacing\", \"line-height\",\n \"padding\", \"padding-bottom\", \"padding-left\", \"padding-right\", \"padding-top\",\n \"text-decoration\", \"text-transform\", \"vertical-align\",\n ],\n \"mj-button\": [\n \"align\", \"background-color\", \"border\", \"border-bottom\", \"border-left\", \"border-radius\",\n \"border-right\", \"border-top\", \"color\", \"container-background-color\", \"font-family\",\n \"font-size\", \"font-style\", \"font-weight\", \"height\", \"href\", \"inner-padding\",\n \"letter-spacing\", \"line-height\", \"name\", \"padding\", \"padding-bottom\", \"padding-left\",\n \"padding-right\", \"padding-top\", \"rel\", \"target\", \"text-align\", \"text-decoration\",\n \"text-transform\", \"title\", \"vertical-align\", \"width\",\n ],\n \"mj-image\": [\n \"align\", \"alt\", \"border\", \"border-bottom\", \"border-left\", \"border-radius\", \"border-right\",\n \"border-top\", \"container-background-color\", \"fluid-on-mobile\", \"font-size\", \"height\",\n \"href\", \"max-height\", \"name\", \"padding\", \"padding-bottom\", \"padding-left\", \"padding-right\",\n \"padding-top\", \"rel\", \"sizes\", \"src\", \"srcset\", \"target\", \"title\", \"usemap\", \"width\",\n ],\n \"mj-divider\": [\n \"align\", \"border-color\", \"border-style\", \"border-width\", \"container-background-color\",\n \"padding\", \"padding-bottom\", \"padding-left\", \"padding-right\", \"padding-top\", \"width\",\n ],\n \"mj-spacer\": [\n \"border\", \"border-bottom\", \"border-left\", \"border-right\", \"border-top\",\n \"container-background-color\", \"height\", \"padding\", \"padding-bottom\", \"padding-left\",\n \"padding-right\", \"padding-top\",\n ],\n \"mj-social\": [\n \"align\", \"border-radius\", \"color\", \"container-background-color\", \"font-family\",\n \"font-size\", \"font-style\", \"font-weight\", \"icon-height\", \"icon-padding\", \"icon-size\",\n \"inner-padding\", \"line-height\", \"mode\", \"padding\", \"padding-bottom\", \"padding-left\",\n \"padding-right\", \"padding-top\", \"table-layout\", \"text-decoration\", \"text-padding\",\n \"vertical-align\",\n ],\n \"mj-social-element\": [\n \"align\", \"alt\", \"background-color\", \"border-radius\", \"color\", \"font-family\", \"font-size\",\n \"font-style\", \"font-weight\", \"href\", \"icon-height\", \"icon-padding\", \"icon-position\",\n \"icon-size\", \"line-height\", \"name\", \"padding\", \"padding-bottom\", \"padding-left\",\n \"padding-right\", \"padding-top\", \"rel\", \"sizes\", \"src\", \"srcset\", \"target\",\n \"text-decoration\", \"text-padding\", \"title\", \"vertical-align\",\n ],\n \"mj-hero\": [\n \"background-color\", \"background-height\", \"background-position\", \"background-url\",\n \"background-width\", \"border-radius\", \"container-background-color\", \"height\",\n \"inner-background-color\", \"inner-padding\", \"inner-padding-bottom\", \"inner-padding-left\",\n \"inner-padding-right\", \"inner-padding-top\", \"mode\", \"padding\", \"padding-bottom\",\n \"padding-left\", \"padding-right\", \"padding-top\", \"vertical-align\",\n ],\n \"mj-navbar\": [\n \"align\", \"base-url\", \"hamburger\", \"ico-align\", \"ico-close\", \"ico-color\", \"ico-font-family\",\n \"ico-font-size\", \"ico-line-height\", \"ico-open\", \"ico-padding\", \"ico-padding-bottom\",\n \"ico-padding-left\", \"ico-padding-right\", \"ico-padding-top\", \"ico-text-decoration\",\n \"ico-text-transform\", \"padding\", \"padding-bottom\", \"padding-left\", \"padding-right\",\n \"padding-top\",\n ],\n \"mj-navbar-link\": [\n \"color\", \"font-family\", \"font-size\", \"font-style\", \"font-weight\", \"href\", \"letter-spacing\",\n \"line-height\", \"name\", \"padding\", \"padding-bottom\", \"padding-left\", \"padding-right\",\n \"padding-top\", \"rel\", \"target\", \"text-decoration\", \"text-transform\",\n ],\n};\n\n// Accepted on every tag by MJML's validator, plus GrapesJS's own `id` and `style` (the\n// plugin's style mirror), which it never serialises.\nconst ALWAYS_ALLOWED = new Set([\"mj-class\", \"css-class\", \"id\", \"style\"]);\n\n// A start tag, with quoted values read whole so a `>` inside one does not end it; and one\n// attribute in it, with its value, so a value's own text is never taken for an attribute.\nconst START_TAG = /<[a-z][^\\s/>]*(?:[^>\"']|\"[^\"]*\"|'[^']*')*>/gi;\nconst ATTRIBUTE = /\\s+([^\\s\"'>/=]+)(?:\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s\"'>]+))?/g;\n\n/**\n * The MJML without `data-gjs-*` attributes, which GrapesJS reads as properties of the element\n * rather than attributes: its layer name and icon among them, which it writes into the page\n * as markup. Strict MJML does not look inside a text's HTML, so the agent can write them too.\n * Only attributes are touched; text that mentions one is left as it is.\n */\nexport function withoutEditorProps(mjml: string): string {\n return mjml.replace(START_TAG, (tag) =>\n tag.replace(ATTRIBUTE, (attribute, name: string) =>\n name.toLowerCase().startsWith(\"data-gjs-\") ? \"\" : attribute,\n ),\n );\n}\n\n/**\n * The MJML with every self-closed `<mj-… />` written as an open and a close tag. GrapesJS\n * parses MJML as HTML, where `/>` does not close a custom element, so whatever follows an\n * `<mj-image />` was nested inside it: valid MJML in, MJML the agent's strict compile rejects\n * out.\n */\nexport function withClosedTags(mjml: string): string {\n return mjml.replace(START_TAG, (tag) => {\n const selfClosed = /^<(mj-[\\w-]+)([\\s\\S]*?)\\s*\\/>$/i.exec(tag);\n return selfClosed ? `<${selfClosed[1]}${selfClosed[2]}></${selfClosed[1]}>` : tag;\n });\n}\n\n// Comments are matched to be skipped: a table one mentions is not a table.\nconst TABLE =\n /<!--[\\s\\S]*?(?:-->|$)|(<mj-table\\b(?:[^>\"']|\"[^\"]*\"|'[^']*')*>)((?:<!--[\\s\\S]*?-->|(?!<!--)[\\s\\S])*?)(<\\/mj-table\\s*>)/gi;\n\n/**\n * The MJML with each mj-table's rows inside a `<template>`. Parsed as HTML, rows outside a\n * table are dropped and only their text kept; a template keeps them for the mj-table type.\n */\nexport function withTableRowsKept(mjml: string): string {\n return mjml.replace(TABLE, (match, open?: string, rows?: string, close?: string) =>\n open ? `${open}<template>${rows}</template>${close}` : match,\n );\n}\n\n/**\n * The MJML GrapesJS is given for a document, and whether it had to be repaired. Closing a\n * self-closed element or holding a table's rows is not a repair: it is the same MJML.\n */\nexport function sourceForEditor(mjml: string): { mjml: string; repaired: boolean } {\n const cleaned = withoutEditorProps(mjml);\n return { mjml: withTableRowsKept(withClosedTags(cleaned)), repaired: cleaned !== mjml };\n}\n\n/** The attributes MJML would reject on `tag`; none for a tag the table does not cover. */\nexport function illegalAttributes(tag: string, attributes: Record<string, unknown>): string[] {\n const allowed = ALLOWED_ATTRIBUTES[tag];\n if (!allowed) return [];\n return Object.keys(attributes).filter((a) => !ALWAYS_ALLOWED.has(a) && !allowed.includes(a));\n}\n\n/** The colour names MJML accepts, as mjml-core 4.18 lists them: CSS's, plus `inherit`. */\n// prettier-ignore\nexport const NAMED_COLORS: ReadonlySet<string> = new Set([\n \"aliceblue\", \"antiquewhite\", \"aqua\", \"aquamarine\", \"azure\", \"beige\", \"bisque\", \"black\",\n \"blanchedalmond\", \"blue\", \"blueviolet\", \"brown\", \"burlywood\", \"cadetblue\", \"chartreuse\",\n \"chocolate\", \"coral\", \"cornflowerblue\", \"cornsilk\", \"crimson\", \"cyan\", \"darkblue\", \"darkcyan\",\n \"darkgoldenrod\", \"darkgray\", \"darkgreen\", \"darkgrey\", \"darkkhaki\", \"darkmagenta\",\n \"darkolivegreen\", \"darkorange\", \"darkorchid\", \"darkred\", \"darksalmon\", \"darkseagreen\",\n \"darkslateblue\", \"darkslategray\", \"darkslategrey\", \"darkturquoise\", \"darkviolet\", \"deeppink\",\n \"deepskyblue\", \"dimgray\", \"dimgrey\", \"dodgerblue\", \"firebrick\", \"floralwhite\", \"forestgreen\",\n \"fuchsia\", \"gainsboro\", \"ghostwhite\", \"gold\", \"goldenrod\", \"gray\", \"green\", \"greenyellow\",\n \"grey\", \"honeydew\", \"hotpink\", \"indianred\", \"indigo\", \"inherit\", \"ivory\", \"khaki\", \"lavender\",\n \"lavenderblush\", \"lawngreen\", \"lemonchiffon\", \"lightblue\", \"lightcoral\", \"lightcyan\",\n \"lightgoldenrodyellow\", \"lightgray\", \"lightgreen\", \"lightgrey\", \"lightpink\", \"lightsalmon\",\n \"lightseagreen\", \"lightskyblue\", \"lightslategray\", \"lightslategrey\", \"lightsteelblue\",\n \"lightyellow\", \"lime\", \"limegreen\", \"linen\", \"magenta\", \"maroon\", \"mediumaquamarine\",\n \"mediumblue\", \"mediumorchid\", \"mediumpurple\", \"mediumseagreen\", \"mediumslateblue\",\n \"mediumspringgreen\", \"mediumturquoise\", \"mediumvioletred\", \"midnightblue\", \"mintcream\",\n \"mistyrose\", \"moccasin\", \"navajowhite\", \"navy\", \"oldlace\", \"olive\", \"olivedrab\", \"orange\",\n \"orangered\", \"orchid\", \"palegoldenrod\", \"palegreen\", \"paleturquoise\", \"palevioletred\",\n \"papayawhip\", \"peachpuff\", \"peru\", \"pink\", \"plum\", \"powderblue\", \"purple\", \"rebeccapurple\",\n \"red\", \"rosybrown\", \"royalblue\", \"saddlebrown\", \"salmon\", \"sandybrown\", \"seagreen\", \"seashell\",\n \"sienna\", \"silver\", \"skyblue\", \"slateblue\", \"slategray\", \"slategrey\", \"snow\", \"springgreen\",\n \"steelblue\", \"tan\", \"teal\", \"thistle\", \"tomato\", \"transparent\", \"turquoise\", \"violet\", \"wheat\",\n \"white\", \"whitesmoke\", \"yellow\", \"yellowgreen\",\n]);\n","\"use client\";\n\n/**\n * The control for image fields in Settings, such as a section's `background-url`: the image\n * itself, opening the same picker, with the gallery, as an `mj-image` does.\n */\n\nimport { ImageIcon, X } from \"lucide-react\";\n\nimport type { EditorLabels } from \"../../labels.js\";\n\nexport default function ImageField({\n value,\n labels,\n onChoose,\n onClear,\n}: {\n value: string;\n labels: EditorLabels;\n onChoose: () => void;\n onClear: () => void;\n}) {\n const url = imageUrl(value);\n return (\n <div className=\"relative\">\n <button\n type=\"button\"\n onClick={onChoose}\n title={labels.chooseImage}\n className=\"group relative block w-full overflow-hidden rounded-md border border-panel-border bg-panel-elevated outline-none focus-visible:ring-2 focus-visible:ring-brand\"\n >\n {url ? (\n <img src={url} alt=\"\" className=\"h-24 w-full bg-black/25 object-contain\" />\n ) : (\n <span className=\"flex h-16 flex-col items-center justify-center gap-1 text-xs text-panel-muted-fg\">\n <ImageIcon className=\"size-5\" />\n {labels.chooseImage}\n </span>\n )}\n {url && (\n <span className=\"absolute inset-0 flex items-center justify-center bg-black/50 text-xs font-medium text-white opacity-0 transition group-hover:opacity-100\">\n {labels.chooseImage}\n </span>\n )}\n </button>\n {value && (\n <button\n type=\"button\"\n onClick={onClear}\n title={labels.imageFieldRemove}\n aria-label={labels.imageFieldRemove}\n className=\"absolute top-1 right-1 flex size-5 items-center justify-center rounded bg-black/60 text-white hover:bg-black/80\"\n >\n <X className=\"size-3\" />\n </button>\n )}\n </div>\n );\n}\n\n/**\n * A bare URL (MJML attributes) or `url(\"…\")` (CSS) to the URL. Anything else — `none`, a\n * gradient or another CSS image function — to null, as there is no image to show.\n */\nexport function imageUrl(value: string): string | null {\n const v = value.trim();\n if (!v || v === \"none\") return null;\n const css = /^url\\(\\s*(['\"]?)(.*?)\\1\\s*\\)$/i.exec(v);\n if (css) return css[2] || null;\n return /^[a-z-]+\\(/i.test(v) ? null : v;\n}\n","/**\n * The fields the Settings tab offers per MJML tag, in display order.\n *\n * Every attribute, option and unit here must pass MJML's strict validation, which the agent\n * runs on the whole document at every write; `schema.test.ts` compiles each one.\n */\n\nimport type { Field, Option, Unit } from \"./types.js\";\n\nconst PX: readonly Unit[] = [\"px\"];\nconst PX_PCT: readonly Unit[] = [\"px\", \"%\"];\nconst LINE_HEIGHT: readonly Unit[] = [\"\", \"px\", \"%\"];\nconst LETTER_SPACING: readonly Unit[] = [\"px\", \"em\"];\n\nconst ALIGN: readonly Option[] = [\n { value: \"left\", label: \"alignLeft\" },\n { value: \"center\", label: \"alignCenter\" },\n { value: \"right\", label: \"alignRight\" },\n];\n\nconst VERTICAL_ALIGN: readonly Option[] = [\n { value: \"top\", label: \"alignTop\" },\n { value: \"middle\", label: \"alignMiddle\" },\n { value: \"bottom\", label: \"alignBottom\" },\n];\n\nconst FONTS: readonly Option[] = [\n { value: \"Ubuntu, Helvetica, Arial, sans-serif\", label: \"Ubuntu\" },\n { value: \"Arial, Helvetica, sans-serif\", label: \"Arial\" },\n { value: \"Helvetica, Arial, sans-serif\", label: \"Helvetica\" },\n { value: \"Verdana, Geneva, sans-serif\", label: \"Verdana\" },\n { value: \"Tahoma, Geneva, sans-serif\", label: \"Tahoma\" },\n { value: \"'Trebuchet MS', Helvetica, sans-serif\", label: \"Trebuchet MS\" },\n { value: \"Georgia, 'Times New Roman', serif\", label: \"Georgia\" },\n { value: \"'Times New Roman', Times, serif\", label: \"Times New Roman\" },\n { value: \"'Courier New', Courier, monospace\", label: \"Courier New\" },\n];\n\n// Keywords at both ends because MJML's own defaults are `normal`; agents' `400`/`700` show\n// as values the select does not list.\nconst WEIGHTS: readonly Option[] = [\n { value: \"normal\", label: \"weightRegular\" },\n { value: \"500\", label: \"weightMedium\" },\n { value: \"600\", label: \"weightSemibold\" },\n { value: \"bold\", label: \"weightBold\" },\n];\n\nconst TEXT_TRANSFORM: readonly Option[] = [\n { value: \"none\", label: \"caseNone\" },\n { value: \"uppercase\", label: \"caseUpper\" },\n { value: \"lowercase\", label: \"caseLower\" },\n { value: \"capitalize\", label: \"caseCapitalize\" },\n];\n\nconst TARGET: readonly Option[] = [\n { value: \"_blank\", label: \"targetNewTab\" },\n { value: \"_self\", label: \"targetSameTab\" },\n];\n\nconst BACKGROUND_POSITION: readonly Option[] = [\n { value: \"top left\", label: \"positionTopLeft\" },\n { value: \"top center\", label: \"positionTopCenter\" },\n { value: \"top right\", label: \"positionTopRight\" },\n { value: \"center left\", label: \"positionCenterLeft\" },\n { value: \"center center\", label: \"positionCenter\" },\n { value: \"center right\", label: \"positionCenterRight\" },\n { value: \"bottom left\", label: \"positionBottomLeft\" },\n { value: \"bottom center\", label: \"positionBottomCenter\" },\n { value: \"bottom right\", label: \"positionBottomRight\" },\n];\n\nexport const NETWORKS: readonly Option[] = [\n { value: \"facebook\", label: \"Facebook\" },\n { value: \"instagram\", label: \"Instagram\" },\n { value: \"x\", label: \"X\" },\n { value: \"linkedin\", label: \"LinkedIn\" },\n { value: \"youtube\", label: \"YouTube\" },\n { value: \"pinterest\", label: \"Pinterest\" },\n { value: \"github\", label: \"GitHub\" },\n { value: \"web\", label: \"networkWebsite\" },\n { value: \"snapchat\", label: \"Snapchat\" },\n { value: \"vimeo\", label: \"Vimeo\" },\n { value: \"medium\", label: \"Medium\" },\n { value: \"dribbble\", label: \"Dribbble\" },\n { value: \"soundcloud\", label: \"SoundCloud\" },\n { value: \"tumblr\", label: \"Tumblr\" },\n { value: \"xing\", label: \"Xing\" },\n { value: \"custom\", label: \"networkCustom\" },\n];\n\nconst hasBackgroundImage = (a: Readonly<Record<string, string>>) => !!a[\"background-url\"];\n\n/** Shared by mj-section and mj-wrapper, whose background and box attributes are the same. */\nconst SECTION_FIELDS: readonly Field[] = [\n {\n attr: \"full-width\",\n label: \"fullWidth\",\n group: \"layout\",\n control: { type: \"toggle\", on: \"full-width\" },\n },\n {\n attr: \"padding\",\n label: \"padding\",\n group: \"spacing\",\n control: { type: \"box\", units: PX_PCT },\n default: \"20px 0\",\n },\n {\n attr: \"background-color\",\n label: \"backgroundColor\",\n group: \"style\",\n control: { type: \"color\" },\n },\n { attr: \"background-url\", label: \"backgroundImage\", group: \"style\", control: { type: \"image\" } },\n {\n attr: \"background-size\",\n label: \"backgroundSize\",\n group: \"style\",\n control: {\n type: \"segmented\",\n options: [\n { value: \"cover\", label: \"sizeCover\" },\n { value: \"contain\", label: \"sizeContain\" },\n { value: \"auto\", label: \"sizeAuto\" },\n ],\n },\n default: \"auto\",\n when: hasBackgroundImage,\n },\n {\n attr: \"background-repeat\",\n label: \"backgroundRepeat\",\n group: \"style\",\n control: {\n type: \"segmented\",\n options: [\n { value: \"repeat\", label: \"repeatTile\" },\n { value: \"no-repeat\", label: \"repeatOnce\" },\n ],\n },\n default: \"repeat\",\n when: hasBackgroundImage,\n },\n {\n attr: \"background-position\",\n label: \"backgroundPosition\",\n group: \"style\",\n control: { type: \"select\", options: BACKGROUND_POSITION },\n default: \"top center\",\n when: hasBackgroundImage,\n },\n {\n attr: \"border-radius\",\n label: \"cornerRadius\",\n group: \"style\",\n control: { type: \"length\", units: PX_PCT },\n },\n];\n\n// prettier-ignore\nexport const SCHEMA: Readonly<Record<string, readonly Field[]>> = {\n \"mj-body\": [\n { attr: \"width\", label: \"contentWidth\", group: \"layout\", control: { type: \"length\", units: PX }, default: \"600px\" },\n { attr: \"background-color\", label: \"pageBackground\", group: \"style\", control: { type: \"color\" } },\n ],\n \"mj-wrapper\": [\n ...SECTION_FIELDS,\n { attr: \"gap\", label: \"gap\", group: \"advanced\", control: { type: \"length\", units: PX } },\n { attr: \"border\", label: \"border\", group: \"advanced\", control: { type: \"text\", placeholder: \"1px solid #cccccc\" } },\n ],\n \"mj-section\": [\n ...SECTION_FIELDS,\n { attr: \"text-align\", label: \"alignColumns\", group: \"advanced\", control: { type: \"segmented\", options: ALIGN }, default: \"center\" },\n { attr: \"direction\", label: \"reverseColumns\", group: \"advanced\", control: { type: \"toggle\", on: \"rtl\" } },\n { attr: \"border\", label: \"border\", group: \"advanced\", control: { type: \"text\", placeholder: \"1px solid #cccccc\" } },\n ],\n \"mj-column\": [\n { attr: \"vertical-align\", label: \"verticalAlign\", group: \"layout\", control: { type: \"segmented\", options: VERTICAL_ALIGN }, default: \"top\" },\n { attr: \"padding\", label: \"padding\", group: \"spacing\", control: { type: \"box\", units: PX_PCT } },\n { attr: \"background-color\", label: \"backgroundColor\", group: \"style\", control: { type: \"color\" } },\n { attr: \"border-radius\", label: \"cornerRadius\", group: \"style\", control: { type: \"length\", units: PX_PCT } },\n { attr: \"width\", label: \"width\", group: \"advanced\", control: { type: \"length\", units: PX_PCT } },\n { attr: \"inner-background-color\", label: \"innerBackground\", group: \"advanced\", control: { type: \"color\" } },\n { attr: \"inner-border-radius\", label: \"innerCornerRadius\", group: \"advanced\", control: { type: \"length\", units: PX_PCT } },\n { attr: \"border\", label: \"border\", group: \"advanced\", control: { type: \"text\", placeholder: \"1px solid #cccccc\" } },\n { attr: \"inner-border\", label: \"innerBorder\", group: \"advanced\", control: { type: \"text\", placeholder: \"1px solid #cccccc\" } },\n ],\n \"mj-text\": [\n {\n attr: \"align\",\n label: \"align\",\n group: \"layout\",\n control: { type: \"segmented\", options: [...ALIGN, { value: \"justify\", label: \"alignJustify\" }] },\n default: \"left\",\n },\n { attr: \"padding\", label: \"padding\", group: \"spacing\", control: { type: \"box\", units: PX_PCT }, default: \"10px 25px\" },\n { attr: \"font-family\", label: \"font\", group: \"style\", control: { type: \"select\", options: FONTS }, default: \"Ubuntu, Helvetica, Arial, sans-serif\" },\n { attr: \"font-size\", label: \"fontSize\", group: \"style\", control: { type: \"length\", units: PX }, default: \"13px\" },\n { attr: \"font-weight\", label: \"fontWeight\", group: \"style\", control: { type: \"select\", options: WEIGHTS } },\n { attr: \"color\", label: \"textColor\", group: \"style\", control: { type: \"color\" }, default: \"#000000\" },\n { attr: \"line-height\", label: \"lineHeight\", group: \"style\", control: { type: \"length\", units: LINE_HEIGHT }, default: \"1\" },\n { attr: \"container-background-color\", label: \"blockBackground\", group: \"style\", control: { type: \"color\" } },\n { attr: \"letter-spacing\", label: \"letterSpacing\", group: \"advanced\", control: { type: \"length\", units: LETTER_SPACING, negative: true } },\n { attr: \"text-transform\", label: \"textTransform\", group: \"advanced\", control: { type: \"select\", options: TEXT_TRANSFORM } },\n ],\n \"mj-button\": [\n { attr: \"href\", label: \"link\", group: \"content\", control: { type: \"link\" } },\n { attr: \"align\", label: \"align\", group: \"layout\", control: { type: \"segmented\", options: ALIGN }, default: \"center\" },\n { attr: \"inner-padding\", label: \"buttonPadding\", group: \"spacing\", control: { type: \"box\", units: PX_PCT }, default: \"10px 25px\" },\n { attr: \"padding\", label: \"spaceAround\", group: \"spacing\", control: { type: \"box\", units: PX_PCT }, default: \"10px 25px\" },\n { attr: \"background-color\", label: \"buttonColor\", group: \"style\", control: { type: \"color\" }, default: \"#414141\" },\n { attr: \"color\", label: \"textColor\", group: \"style\", control: { type: \"color\" }, default: \"#ffffff\" },\n { attr: \"font-size\", label: \"fontSize\", group: \"style\", control: { type: \"length\", units: PX }, default: \"13px\" },\n { attr: \"border-radius\", label: \"cornerRadius\", group: \"style\", control: { type: \"length\", units: PX_PCT }, default: \"3px\" },\n { attr: \"width\", label: \"width\", group: \"advanced\", control: { type: \"length\", units: PX_PCT } },\n { attr: \"font-family\", label: \"font\", group: \"advanced\", control: { type: \"select\", options: FONTS }, default: \"Ubuntu, Helvetica, Arial, sans-serif\" },\n { attr: \"font-weight\", label: \"fontWeight\", group: \"advanced\", control: { type: \"select\", options: WEIGHTS }, default: \"normal\" },\n { attr: \"target\", label: \"opensIn\", group: \"advanced\", control: { type: \"select\", options: TARGET }, default: \"_blank\" },\n { attr: \"title\", label: \"tooltip\", group: \"advanced\", control: { type: \"text\" } },\n { attr: \"rel\", label: \"rel\", group: \"advanced\", control: { type: \"text\", placeholder: \"noopener\" } },\n { attr: \"container-background-color\", label: \"blockBackground\", group: \"advanced\", control: { type: \"color\" } },\n { attr: \"border\", label: \"border\", group: \"advanced\", control: { type: \"text\", placeholder: \"1px solid #cccccc\" }, default: \"none\" },\n { attr: \"letter-spacing\", label: \"letterSpacing\", group: \"advanced\", control: { type: \"length\", units: LETTER_SPACING, negative: true } },\n { attr: \"text-transform\", label: \"textTransform\", group: \"advanced\", control: { type: \"select\", options: TEXT_TRANSFORM }, default: \"none\" },\n { attr: \"line-height\", label: \"lineHeight\", group: \"advanced\", control: { type: \"length\", units: LINE_HEIGHT }, default: \"120%\" },\n ],\n \"mj-image\": [\n { attr: \"src\", label: \"image\", group: \"content\", control: { type: \"image\" } },\n { attr: \"alt\", label: \"altText\", group: \"content\", control: { type: \"text\" } },\n { attr: \"href\", label: \"link\", group: \"content\", control: { type: \"link\" } },\n { attr: \"width\", label: \"width\", group: \"layout\", control: { type: \"length\", units: PX } },\n { attr: \"align\", label: \"align\", group: \"layout\", control: { type: \"segmented\", options: ALIGN }, default: \"center\" },\n { attr: \"fluid-on-mobile\", label: \"fluidOnMobile\", group: \"layout\", control: { type: \"toggle\", on: \"true\" } },\n { attr: \"padding\", label: \"padding\", group: \"spacing\", control: { type: \"box\", units: PX_PCT }, default: \"10px 25px\" },\n { attr: \"border-radius\", label: \"cornerRadius\", group: \"style\", control: { type: \"length\", units: PX_PCT } },\n { attr: \"target\", label: \"opensIn\", group: \"advanced\", control: { type: \"select\", options: TARGET }, default: \"_blank\" },\n { attr: \"title\", label: \"tooltip\", group: \"advanced\", control: { type: \"text\" } },\n { attr: \"rel\", label: \"rel\", group: \"advanced\", control: { type: \"text\", placeholder: \"noopener\" } },\n { attr: \"border\", label: \"border\", group: \"advanced\", control: { type: \"text\", placeholder: \"1px solid #cccccc\" }, default: \"0\" },\n { attr: \"container-background-color\", label: \"blockBackground\", group: \"advanced\", control: { type: \"color\" } },\n ],\n \"mj-divider\": [\n { attr: \"width\", label: \"width\", group: \"layout\", control: { type: \"length\", units: PX_PCT }, default: \"100%\" },\n { attr: \"align\", label: \"align\", group: \"layout\", control: { type: \"segmented\", options: ALIGN }, default: \"center\" },\n { attr: \"padding\", label: \"padding\", group: \"spacing\", control: { type: \"box\", units: PX_PCT }, default: \"10px 25px\" },\n { attr: \"border-color\", label: \"lineColor\", group: \"style\", control: { type: \"color\" }, default: \"#000000\" },\n { attr: \"border-width\", label: \"thickness\", group: \"style\", control: { type: \"length\", units: PX }, default: \"4px\" },\n {\n attr: \"border-style\",\n label: \"lineStyle\",\n group: \"style\",\n control: {\n type: \"segmented\",\n options: [\n { value: \"solid\", label: \"lineSolid\" },\n { value: \"dashed\", label: \"lineDashed\" },\n { value: \"dotted\", label: \"lineDotted\" },\n ],\n },\n default: \"solid\",\n },\n { attr: \"container-background-color\", label: \"blockBackground\", group: \"advanced\", control: { type: \"color\" } },\n ],\n \"mj-spacer\": [\n { attr: \"height\", label: \"height\", group: \"layout\", control: { type: \"length\", units: PX }, default: \"20px\" },\n { attr: \"container-background-color\", label: \"blockBackground\", group: \"advanced\", control: { type: \"color\" } },\n ],\n \"mj-social\": [\n {\n attr: \"mode\",\n label: \"socialMode\",\n group: \"layout\",\n control: {\n type: \"segmented\",\n options: [\n { value: \"horizontal\", label: \"modeHorizontal\" },\n { value: \"vertical\", label: \"modeVertical\" },\n ],\n },\n default: \"horizontal\",\n },\n { attr: \"align\", label: \"align\", group: \"layout\", control: { type: \"segmented\", options: ALIGN }, default: \"center\" },\n { attr: \"padding\", label: \"padding\", group: \"spacing\", control: { type: \"box\", units: PX_PCT }, default: \"10px 25px\" },\n { attr: \"inner-padding\", label: \"iconSpacing\", group: \"spacing\", control: { type: \"box\", units: PX_PCT } },\n { attr: \"icon-size\", label: \"iconSize\", group: \"style\", control: { type: \"length\", units: PX_PCT }, default: \"20px\" },\n // A single value: mj-social's border-radius is not a 4-side shorthand.\n { attr: \"border-radius\", label: \"cornerRadius\", group: \"style\", control: { type: \"length\", units: PX_PCT }, default: \"3px\" },\n { attr: \"font-family\", label: \"font\", group: \"advanced\", control: { type: \"select\", options: FONTS }, default: \"Ubuntu, Helvetica, Arial, sans-serif\" },\n { attr: \"font-size\", label: \"fontSize\", group: \"advanced\", control: { type: \"length\", units: PX }, default: \"13px\" },\n { attr: \"color\", label: \"textColor\", group: \"advanced\", control: { type: \"color\" }, default: \"#333333\" },\n { attr: \"line-height\", label: \"lineHeight\", group: \"advanced\", control: { type: \"length\", units: LINE_HEIGHT }, default: \"22px\" },\n { attr: \"container-background-color\", label: \"blockBackground\", group: \"advanced\", control: { type: \"color\" } },\n ],\n \"mj-social-element\": [\n { attr: \"name\", label: \"network\", group: \"content\", control: { type: \"network\", networks: NETWORKS } },\n { attr: \"href\", label: \"link\", group: \"content\", control: { type: \"link\" } },\n {\n attr: \"src\",\n label: \"customIcon\",\n group: \"content\",\n control: { type: \"image\" },\n when: (a) => (a.name ?? \"\").startsWith(\"custom\") || !!a.src,\n },\n { attr: \"alt\", label: \"altText\", group: \"content\", control: { type: \"text\" } },\n { attr: \"background-color\", label: \"iconColor\", group: \"style\", control: { type: \"color\" } },\n { attr: \"icon-size\", label: \"iconSize\", group: \"advanced\", control: { type: \"length\", units: PX_PCT } },\n { attr: \"border-radius\", label: \"cornerRadius\", group: \"advanced\", control: { type: \"length\", units: PX }, default: \"3px\" },\n { attr: \"padding\", label: \"padding\", group: \"advanced\", control: { type: \"box\", units: PX_PCT }, default: \"4px\" },\n { attr: \"icon-position\", label: \"iconPosition\", group: \"advanced\", control: { type: \"segmented\", options: [{ value: \"left\", label: \"alignLeft\" }, { value: \"right\", label: \"alignRight\" }] }, default: \"left\" },\n { attr: \"title\", label: \"tooltip\", group: \"advanced\", control: { type: \"text\" } },\n { attr: \"target\", label: \"opensIn\", group: \"advanced\", control: { type: \"select\", options: TARGET }, default: \"_blank\" },\n { attr: \"rel\", label: \"rel\", group: \"advanced\", control: { type: \"text\", placeholder: \"noopener\" } },\n ],\n \"mj-hero\": [\n { attr: \"background-url\", label: \"backgroundImage\", group: \"content\", control: { type: \"image\" } },\n {\n attr: \"mode\",\n label: \"heroMode\",\n group: \"content\",\n control: {\n type: \"segmented\",\n options: [\n { value: \"fixed-height\", label: \"heroFixed\" },\n { value: \"fluid-height\", label: \"heroFluid\" },\n ],\n },\n default: \"fixed-height\",\n },\n {\n attr: \"height\",\n label: \"height\",\n group: \"layout\",\n control: { type: \"length\", units: PX_PCT },\n default: \"0px\",\n when: (a) => (a.mode ?? \"fixed-height\") === \"fixed-height\",\n },\n {\n attr: \"background-width\",\n label: \"backgroundWidth\",\n group: \"layout\",\n control: { type: \"length\", units: PX_PCT },\n when: (a) => a.mode === \"fluid-height\",\n },\n {\n attr: \"background-height\",\n label: \"backgroundHeight\",\n group: \"layout\",\n control: { type: \"length\", units: PX_PCT },\n when: (a) => a.mode === \"fluid-height\",\n },\n { attr: \"vertical-align\", label: \"verticalAlign\", group: \"layout\", control: { type: \"segmented\", options: VERTICAL_ALIGN }, default: \"top\" },\n { attr: \"background-position\", label: \"backgroundPosition\", group: \"layout\", control: { type: \"select\", options: BACKGROUND_POSITION }, default: \"center center\" },\n { attr: \"padding\", label: \"padding\", group: \"spacing\", control: { type: \"box\", units: PX_PCT }, default: \"0px\" },\n { attr: \"background-color\", label: \"fallbackColor\", group: \"style\", control: { type: \"color\" }, default: \"#ffffff\" },\n { attr: \"border-radius\", label: \"cornerRadius\", group: \"style\", control: { type: \"length\", units: PX_PCT } },\n { attr: \"inner-padding\", label: \"contentPadding\", group: \"advanced\", control: { type: \"box\", units: PX_PCT } },\n { attr: \"inner-background-color\", label: \"contentBackground\", group: \"advanced\", control: { type: \"color\" } },\n ],\n \"mj-navbar\": [\n { attr: \"align\", label: \"align\", group: \"layout\", control: { type: \"segmented\", options: ALIGN }, default: \"center\" },\n { attr: \"hamburger\", label: \"hamburger\", group: \"layout\", control: { type: \"toggle\", on: \"hamburger\" } },\n { attr: \"padding\", label: \"padding\", group: \"spacing\", control: { type: \"box\", units: PX_PCT } },\n { attr: \"ico-color\", label: \"menuIconColor\", group: \"advanced\", control: { type: \"color\" }, default: \"#000000\", when: (a) => !!a.hamburger },\n { attr: \"ico-font-size\", label: \"menuIconSize\", group: \"advanced\", control: { type: \"length\", units: PX_PCT }, default: \"30px\", when: (a) => !!a.hamburger },\n { attr: \"ico-align\", label: \"menuIconAlign\", group: \"advanced\", control: { type: \"segmented\", options: ALIGN }, default: \"center\", when: (a) => !!a.hamburger },\n { attr: \"base-url\", label: \"baseUrl\", group: \"advanced\", control: { type: \"link\" } },\n ],\n \"mj-navbar-link\": [\n { attr: \"href\", label: \"link\", group: \"content\", control: { type: \"link\" } },\n { attr: \"padding\", label: \"padding\", group: \"spacing\", control: { type: \"box\", units: PX_PCT }, default: \"15px 10px\" },\n { attr: \"color\", label: \"textColor\", group: \"style\", control: { type: \"color\" }, default: \"#000000\" },\n { attr: \"font-family\", label: \"font\", group: \"style\", control: { type: \"select\", options: FONTS }, default: \"Ubuntu, Helvetica, Arial, sans-serif\" },\n { attr: \"font-size\", label: \"fontSize\", group: \"style\", control: { type: \"length\", units: PX }, default: \"13px\" },\n { attr: \"font-weight\", label: \"fontWeight\", group: \"style\", control: { type: \"select\", options: WEIGHTS }, default: \"normal\" },\n { attr: \"text-transform\", label: \"textTransform\", group: \"style\", control: { type: \"select\", options: TEXT_TRANSFORM }, default: \"uppercase\" },\n { attr: \"target\", label: \"opensIn\", group: \"advanced\", control: { type: \"select\", options: TARGET }, default: \"_blank\" },\n { attr: \"rel\", label: \"rel\", group: \"advanced\", control: { type: \"text\", placeholder: \"noopener\" } },\n { attr: \"letter-spacing\", label: \"letterSpacing\", group: \"advanced\", control: { type: \"length\", units: LETTER_SPACING, negative: true } },\n { attr: \"line-height\", label: \"lineHeight\", group: \"advanced\", control: { type: \"length\", units: LINE_HEIGHT }, default: \"22px\" },\n ],\n};\n","/**\n * The Layers tab: rows named by what they hold (\"Summer sale\", \"Shop now\") rather than by tag,\n * each with an icon for its kind. GrapesJS renders the tree; this only names the rows.\n */\n\nimport type { Component, Editor } from \"grapesjs\";\n\nimport type { EditorLabels } from \"../../labels.js\";\nimport { NETWORKS } from \"./inspector/schema.js\";\nimport { parseNetwork } from \"./inspector/values.js\";\n\nconst svg = (paths: string) =>\n `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">${paths}</svg>`;\n\n// Lucide icons, the set the rest of the editor uses.\nconst ICONS: Record<string, string> = {\n \"mj-wrapper\": svg(\n '<path d=\"M3 7V5a2 2 0 0 1 2-2h2\"/><path d=\"M17 3h2a2 2 0 0 1 2 2v2\"/><path d=\"M21 17v2a2 2 0 0 1-2 2h-2\"/><path d=\"M7 21H5a2 2 0 0 1-2-2v-2\"/><rect width=\"10\" height=\"10\" x=\"7\" y=\"7\" rx=\"1\"/>',\n ),\n \"mj-section\": svg('<rect width=\"20\" height=\"12\" x=\"2\" y=\"6\" rx=\"2\"/>'),\n \"mj-hero\": svg('<rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"/><path d=\"M3 9h18\"/>'),\n \"mj-group\": svg(\n '<rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"/><path d=\"M9 3v18\"/><path d=\"M15 3v18\"/>',\n ),\n \"mj-column\": svg('<rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"/><path d=\"M12 3v18\"/>'),\n \"mj-text\": svg('<path d=\"M4 7V4h16v3\"/><path d=\"M9 20h6\"/><path d=\"M12 4v16\"/>'),\n \"mj-image\": svg(\n '<rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"/><circle cx=\"9\" cy=\"9\" r=\"2\"/><path d=\"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21\"/>',\n ),\n \"mj-button\": svg('<rect width=\"20\" height=\"10\" x=\"2\" y=\"7\" rx=\"3\"/><path d=\"M8 12h8\"/>'),\n \"mj-divider\": svg('<path d=\"M5 12h14\"/>'),\n \"mj-spacer\": svg('<path d=\"M12 3v18\"/><path d=\"m8 17 4 4 4-4\"/><path d=\"m8 7 4-4 4 4\"/>'),\n \"mj-social\": svg(\n '<circle cx=\"18\" cy=\"5\" r=\"3\"/><circle cx=\"6\" cy=\"12\" r=\"3\"/><circle cx=\"18\" cy=\"19\" r=\"3\"/><path d=\"m8.59 13.51 6.83 3.98\"/><path d=\"m15.41 6.51-6.82 3.98\"/>',\n ),\n \"mj-social-element\": svg(\n '<circle cx=\"12\" cy=\"12\" r=\"4\"/><path d=\"M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-4 8\"/>',\n ),\n \"mj-navbar\": svg('<path d=\"M4 6h16\"/><path d=\"M4 12h16\"/><path d=\"M4 18h16\"/>'),\n \"mj-navbar-link\": svg(\n '<path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/>',\n ),\n \"mj-raw\": svg('<path d=\"m16 18 6-6-6-6\"/><path d=\"m8 6-6 6 6 6\"/>'),\n \"mj-table\": svg(\n '<rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"/><path d=\"M3 9h18\"/><path d=\"M3 15h18\"/><path d=\"M12 3v18\"/>',\n ),\n};\n\nfunction tagOf(c: Component): string {\n return String(c.get(\"tagName\") || c.get(\"type\") || \"\");\n}\n\n/**\n * The first line a reader sees of an element's content, most often its heading: tags dropped,\n * entities decoded. Without the line breaks a heading and its paragraph ran together.\n */\nexport function textOf(c: Component): string {\n // A template parses without running scripts or fetching images.\n const template = document.createElement(\"template\");\n template.innerHTML = c.getInnerHTML();\n template.content\n .querySelectorAll(\"br, p, div, li, tr, h1, h2, h3, h4, h5, h6\")\n .forEach((el) => el.after(\"\\n\"));\n const lines = (template.content.textContent ?? \"\").split(\"\\n\");\n const first = lines.map((l) => l.replace(/\\s+/g, \" \").trim()).find(Boolean) ?? \"\";\n return first.slice(0, 60);\n}\n\nfunction escapeHtml(s: string): string {\n return s.replace(/[&<>\"']/g, (ch) => `&#${ch.charCodeAt(0)};`);\n}\n\n/** A row's name: the element's own words where it has any, else what kind of element it is. */\nexport function layerName(c: Component, labels: EditorLabels): string {\n const tag = tagOf(c);\n const kind = labels.elementNames[tag] ?? tag.replace(/^mj-/, \"\");\n const attributes = c.getAttributes() as Record<string, string | undefined>;\n switch (tag) {\n case \"mj-text\":\n case \"mj-button\":\n case \"mj-navbar-link\":\n return textOf(c) || kind;\n case \"mj-image\":\n return attributes.alt?.trim() || kind;\n case \"mj-social-element\": {\n const { network } = parseNetwork(String(attributes.name ?? \"\"));\n const option = NETWORKS.find((o) => o.value === network && network !== \"custom\");\n return (\n textOf(c) || (option && (labels.inspectorLabels[option.label] ?? option.label)) || kind\n );\n }\n case \"mj-section\":\n case \"mj-wrapper\":\n case \"mj-hero\": {\n // A section is known by its first words: its heading, most often.\n let words = \"\";\n c.onAll((d) => {\n if (!words && d !== c && [\"mj-text\", \"mj-button\"].includes(tagOf(d))) words = textOf(d);\n });\n return words || kind;\n }\n case \"mj-column\": {\n const columns =\n c\n .parent()\n ?.components()\n .filter((s: Component) => tagOf(s) === \"mj-column\") ?? [];\n return columns.length > 1 ? `${kind} ${columns.indexOf(c) + 1}` : kind;\n }\n default:\n return kind;\n }\n}\n\n// Elements whose children are their content — a text's paragraphs, a button's words — and\n// not rows of their own.\nconst CONTENT = new Set([\"mj-text\", \"mj-button\", \"mj-navbar-link\", \"mj-social-element\", \"mj-raw\"]);\n\n/** The canvas badge, which keeps saying what kind of element is under the pointer. */\nexport function badgeLabel(labels: EditorLabels) {\n return (c: Component) => {\n const tag = tagOf(c);\n const icon = ICONS[tag] ? `<div class=\"gjs-badge__icon\">${ICONS[tag]}</div>` : \"\";\n const kind = labels.elementNames[tag] ?? tag.replace(/^mj-/, \"\");\n return `${icon}<div class=\"gjs-badge__name\">${escapeHtml(kind)}</div>`;\n };\n}\n\n/**\n * Names and icons for the mj-* types. The names live in the layers only: GrapesJS's own\n * renaming is turned off in the sidebar, as a name set there is not MJML and would be lost.\n */\nexport function setupLayerNames(editor: Editor, labels: EditorLabels) {\n // Not stored and not undoable: it is how the tree shows the element, not the element.\n const hideContent = (c: Component) =>\n c.onAll((d) => d !== c && d.set(\"layerable\", false, { avoidStore: true }));\n\n for (const type of editor.Components.getTypes()) {\n if (!type.id.startsWith(\"mj-\")) continue;\n editor.Components.addType(type.id, {\n model: {\n // Ours whatever the element says: GrapesJS writes it into the row's markup as it is.\n getIcon() {\n return ICONS[type.id] ?? \"\";\n },\n // GrapesJS writes the name into the row's markup unescaped, and it is document text.\n getName(this: Component) {\n return escapeHtml(layerName(this, labels));\n },\n ...(CONTENT.has(type.id) && {\n // Editing a text replaces its children, so they are hidden again as they arrive.\n init(this: Component) {\n hideContent(this);\n this.listenTo(this.components(), \"add reset\", () => hideContent(this));\n },\n }),\n },\n // Runs the plugin's own `init` as well.\n extendFn: [\"init\"],\n } as never);\n }\n\n // A name follows its content, and a section's follows its children, so after any change\n // every row is re-read, once per frame.\n let pending = false;\n editor.on(\"update component:add component:remove\", () => {\n if (pending) return;\n pending = true;\n requestAnimationFrame(() => {\n pending = false;\n editor.Layers.getRoot()?.onAll((c) => {\n const view = (c as { viewLayer?: { getInputName?: () => HTMLElement | null } }).viewLayer;\n const el = view?.getInputName?.();\n const name = layerName(c, labels);\n if (!el || el.textContent === name) return;\n el.textContent = name;\n el.parentElement?.setAttribute(\"title\", name);\n });\n });\n });\n}\n","\"use client\";\n\n/**\n * What an element holds, in its own settings: a section's column widths, and the links of a\n * navigation bar or social group, which are too small to pick out on the canvas.\n */\n\nimport type { Component, Editor } from \"grapesjs\";\nimport type { ReactNode } from \"react\";\nimport { AtSign, ChevronRight, Link2, Plus } from \"lucide-react\";\n\nimport type { EditorLabels } from \"../../../labels.js\";\nimport { cn } from \"../../../lib/utils\";\nimport { layerName } from \"../layers.js\";\nimport {\n addNavbarLink,\n addNetwork,\n COLUMN_RATIOS,\n columnsOf,\n currentRatio,\n setRatio,\n} from \"./structure.js\";\n\nfunction tagOf(c: Component): string {\n return String(c.get(\"tagName\") || c.get(\"type\") || \"\");\n}\n\nexport default function StructureSection({\n editor,\n component,\n labels,\n locked,\n}: {\n editor: Editor;\n component: Component;\n labels: EditorLabels;\n locked: boolean;\n}) {\n switch (tagOf(component)) {\n case \"mj-section\":\n return <ColumnWidths component={component} labels={labels} locked={locked} />;\n case \"mj-social\":\n return (\n <Children\n editor={editor}\n component={component}\n labels={labels}\n locked={locked}\n title={labels.socialNetworks}\n add={labels.addNetwork}\n icon={<AtSign className=\"size-3.5 shrink-0\" />}\n onAdd={() => editor.select(addNetwork(component))}\n />\n );\n case \"mj-navbar\":\n return (\n <Children\n editor={editor}\n component={component}\n labels={labels}\n locked={locked}\n title={labels.navbarLinks}\n add={labels.addLink}\n icon={<Link2 className=\"size-3.5 shrink-0\" />}\n onAdd={() => editor.select(addNavbarLink(component, labels.newLinkText))}\n />\n );\n default:\n return null;\n }\n}\n\nfunction Heading({ children }: { children: string }) {\n return (\n <h3 className=\"px-3 pb-1 text-[10px] font-semibold tracking-wider text-panel-muted-fg/80 uppercase\">\n {children}\n </h3>\n );\n}\n\nfunction ColumnWidths({\n component,\n labels,\n locked,\n}: {\n component: Component;\n labels: EditorLabels;\n locked: boolean;\n}) {\n const columns = columnsOf(component);\n const ratios = columns && COLUMN_RATIOS[columns.length];\n if (!columns || !ratios) return null;\n const current = currentRatio(columns);\n return (\n <section className=\"border-b border-panel-border/60 py-2\">\n <Heading>{labels.columnWidths}</Heading>\n <div className=\"flex gap-1.5 px-3 py-1\">\n {ratios.map((ratio) => {\n const name = labels.columnRatio(ratio.join(\":\"));\n const active = current?.join() === ratio.join();\n return (\n <button\n key={ratio.join()}\n type=\"button\"\n disabled={locked}\n aria-pressed={active}\n title={name}\n aria-label={name}\n onClick={() => !active && setRatio(columns, ratio)}\n className={cn(\n \"flex h-8 flex-1 items-center gap-0.5 rounded-md border px-1.5 transition-colors\",\n active\n ? \"border-brand bg-brand/15\"\n : \"border-panel-border bg-panel-elevated hover:border-panel-muted-fg\",\n )}\n >\n {ratio.map((part, i) => (\n <span\n key={i}\n style={{ flexGrow: part }}\n className={cn(\n \"h-4 basis-0 rounded-sm\",\n active ? \"bg-brand\" : \"bg-panel-muted-fg/50\",\n )}\n />\n ))}\n </button>\n );\n })}\n </div>\n </section>\n );\n}\n\nfunction Children({\n editor,\n component,\n labels,\n locked,\n title,\n add,\n icon,\n onAdd,\n}: {\n editor: Editor;\n component: Component;\n labels: EditorLabels;\n locked: boolean;\n title: string;\n add: string;\n icon: ReactNode;\n onAdd: () => void;\n}) {\n const children = component.components().models;\n return (\n <section className=\"border-b border-panel-border/60 py-2\">\n <Heading>{title}</Heading>\n <ul className=\"flex flex-col px-2\">\n {children.map((child) => (\n <li key={child.cid}>\n <button\n type=\"button\"\n onClick={() => editor.select(child)}\n className=\"group flex w-full items-center gap-2 rounded-md px-1.5 py-1 text-left text-xs text-panel-fg hover:bg-panel-hover\"\n >\n <span className=\"text-panel-muted-fg\">{icon}</span>\n <span className=\"min-w-0 flex-1 truncate\">{layerName(child, labels)}</span>\n <ChevronRight className=\"size-3 shrink-0 text-panel-muted-fg opacity-0 group-hover:opacity-100\" />\n </button>\n </li>\n ))}\n </ul>\n <button\n type=\"button\"\n disabled={locked}\n onClick={onAdd}\n className=\"mx-3 mt-1 flex items-center gap-1.5 rounded-md px-1 py-1 text-xs text-panel-muted-fg hover:text-panel-fg disabled:opacity-50\"\n >\n <Plus className=\"size-3.5\" />\n {add}\n </button>\n </section>\n );\n}\n","/** Changes to what an element holds rather than to its attributes: columns, links, networks. */\n\nimport type { Component } from \"grapesjs\";\n\nfunction tagOf(c: Component): string {\n return String(c.get(\"tagName\") || c.get(\"type\") || \"\");\n}\n\n/** Column proportions offered for a section of two or three columns; equal sets no widths. */\nexport const COLUMN_RATIOS: Readonly<Record<number, readonly (readonly number[])[]>> = {\n 2: [\n [1, 1],\n [1, 2],\n [2, 1],\n ],\n 3: [\n [1, 1, 1],\n [1, 2, 1],\n ],\n};\n\n/** A section's columns, when columns are all it holds; a column group is left alone. */\nexport function columnsOf(section: Component): Component[] | null {\n const children = section.components().models;\n return children.length > 0 && children.every((c) => tagOf(c) === \"mj-column\") ? children : null;\n}\n\n/** Percent widths for a ratio, to two decimals, or null where MJML's equal split does. */\nexport function ratioWidths(ratio: readonly number[]): string[] | null {\n if (ratio.every((r) => r === ratio[0])) return null;\n const total = ratio.reduce((a, b) => a + b, 0);\n return ratio.map((r) => `${Math.round((r / total) * 10000) / 100}%`);\n}\n\n/** The ratio the columns' widths already have, if it is one of the offered. */\nexport function currentRatio(columns: Component[]): readonly number[] | null {\n const widths = columns.map((c) => String(c.getAttributes().width ?? \"\"));\n return (\n COLUMN_RATIOS[columns.length]?.find((ratio) => {\n const want = ratioWidths(ratio);\n if (!want) return widths.every((w) => w === \"\");\n return widths.every(\n (w, i) => /%$/.test(w) && Math.abs(parseFloat(w) - parseFloat(want[i]!)) < 0.5,\n );\n }) ?? null\n );\n}\n\n/** Sets every column's width in one change, so it is one undo step. */\nexport function setRatio(columns: Component[], ratio: readonly number[]) {\n const widths = ratioWidths(ratio);\n columns.forEach((c, i) => {\n if (widths) c.addAttributes({ width: widths[i]! });\n else c.removeAttributes([\"width\"]);\n });\n}\n\n// Networks a new social link starts as, in order, each linking to the site until edited.\nconst PROFILE_URLS: Readonly<Record<string, string>> = {\n facebook: \"https://facebook.com/\",\n instagram: \"https://instagram.com/\",\n x: \"https://x.com/\",\n linkedin: \"https://linkedin.com/\",\n youtube: \"https://youtube.com/\",\n pinterest: \"https://pinterest.com/\",\n github: \"https://github.com/\",\n};\n\n/** Adds the first common network the group does not have yet, as a profile link. */\nexport function addNetwork(social: Component): Component {\n const present = new Set(\n social\n .components()\n .map((c: Component) => String(c.getAttributes().name ?? \"\").replace(/-noshare$/, \"\")),\n );\n const network = Object.keys(PROFILE_URLS).find((n) => !present.has(n)) ?? \"facebook\";\n // As markup: the plugin's types are recognised by tag, and a type alone renders a <div>.\n return social.append(\n `<mj-social-element name=\"${network}-noshare\" href=\"${PROFILE_URLS[network]}\"></mj-social-element>`,\n )[0]!;\n}\n\nexport function addNavbarLink(navbar: Component, text: string): Component {\n return navbar.append(`<mj-navbar-link>${escapeHtml(text)}</mj-navbar-link>`)[0]!;\n}\n\nfunction escapeHtml(s: string): string {\n return s.replace(/[&<>\"']/g, (ch) => `&#${ch.charCodeAt(0)};`);\n}\n","import type { Component, Editor } from \"grapesjs\";\n\nexport type WriteOptions = {\n /** A step of a drag: shown at once, recorded only when the drag ends. */\n partial?: boolean;\n /** Attributes to drop in the same change, such as longhands a shorthand replaces. */\n remove?: readonly string[];\n};\n\ntype Attributes = Record<string, unknown>;\n\nfunction same(a: Attributes, b: Attributes): boolean {\n const keys = Object.keys(a);\n return keys.length === Object.keys(b).length && keys.every((k) => k in b && a[k] === b[k]);\n}\n\n/**\n * Writes one element's MJML attributes. On mj-image `src` is a model property, which the\n * plugin writes over the attribute.\n *\n * Every write replaces the whole attribute set at once: the plugin mirrors attributes into a\n * style object and back, and a removal followed by an addition, made silently, came back\n * from that mirror with the removed attribute still in it.\n *\n * `blocked` is asked as the write lands, after any wait: an agent turn can lock the editor\n * while a text's typing is being synced.\n */\nexport function createWriter(\n editor: Editor,\n component: Component,\n blocked: () => boolean = () => false,\n) {\n const isImage = String(component.get(\"tagName\") || component.get(\"type\")) === \"mj-image\";\n // The attributes as MJML has them: without GrapesJS's `__p` marker and the plugin's style.\n const current = (): Attributes => {\n const { __p: _marker, style: _style, ...rest } = component.get(\"attributes\") as Attributes;\n return rest;\n };\n\n // The drag under way: its attribute and the attributes before its first step, which its\n // release is recorded as changing.\n let drag: { attr: string; start: Attributes } | null = null;\n\n // Records the attributes now as one change from `start`: the steps were silent, so the start\n // goes back silently first. None when they end where they began.\n const record = (start: Attributes, end: Attributes) => {\n component.setAttributes(start, { avoidStore: true });\n if (!same(end, start)) component.setAttributes(end);\n // A silent write leaves the `__p` marker on the attributes object, put there in place by\n // the plugin's mirror; a real change clears it, and when there was none it goes the same way.\n delete (component.get(\"attributes\") as Attributes).__p;\n };\n\n return async (attr: string, value: string, { partial, remove = [] }: WriteOptions = {}) => {\n // A write re-renders the element, which would drop text typed into it but not yet synced.\n if (editor.getEditing() === component) {\n const view = component.getView() as { syncContent?: () => Promise<void> } | undefined;\n await view?.syncContent?.();\n }\n if (blocked()) return;\n // Another field written mid-drag ends the drag first, so each keeps its own undo step.\n if (drag && drag.attr !== attr) {\n const { start } = drag;\n drag = null;\n record(start, current());\n }\n if (attr === \"src\" && isImage) return void component.set({ src: value });\n\n const next = current();\n for (const name of remove) delete next[name];\n if (value === \"\") delete next[attr];\n else next[attr] = value;\n\n if (partial) {\n drag ??= { attr, start: current() };\n component.setAttributes(next, { avoidStore: true });\n return;\n }\n const start = drag?.start ?? current();\n drag = null;\n record(start, next);\n };\n}\n","/**\n * Sections a host adds to the palette.\n *\n * A dropped block is ordinary MJML from then on, so it has to be MJML the agent's strict\n * compile accepts and the editor writes back unchanged: one bad block in the palette would\n * put an error into every email it is dropped in, and block every agent write to it.\n */\n\nimport grapesjs, { type Editor } from \"grapesjs\";\nimport grapesjsMJML from \"grapesjs-mjml\";\n\nimport { ID_RE } from \"./ids.js\";\nimport { tileAttributes } from \"./insert-block.js\";\nimport { isSafeLink, isSafeNavbarLink } from \"./inspector/values.js\";\nimport { withClosedTags } from \"./mjml-attributes.js\";\n\nexport type SectionBlock = {\n /** Unique, and not the id of a built-in block. */\n readonly id: string;\n /** Plain text. */\n readonly label: string;\n /** Exactly one `<mj-section>`, without `sec-*`/`obj-*` ids: those are added on drop. */\n readonly mjml: string;\n /** SVG markup for the tile, rendered as is. The palette paints it with `fill`, as it does\n * the built-in tiles, so draw with filled shapes. */\n readonly media?: string;\n};\n\n// Tags a dropped section may hold: what the editor keeps on a load and edits in Settings. Not\n// mj-table (its rows are kept, never edited), mj-hero (its content sits outside any\n// section, where the agent and comments cannot address it), accordion and carousel (the\n// editor can neither render nor edit them), mj-wrapper (it holds sections, and a block is\n// one) or mj-raw (HTML nobody edits here).\nconst EDITABLE_TAGS = new Set([\n \"mj-section\",\n \"mj-group\",\n \"mj-column\",\n \"mj-text\",\n \"mj-image\",\n \"mj-button\",\n \"mj-divider\",\n \"mj-spacer\",\n \"mj-social\",\n \"mj-social-element\",\n \"mj-navbar\",\n \"mj-navbar-link\",\n]);\n\n// The tags whose content is markup. Text anywhere else is dropped by MJML without an error.\nconst CONTENT_TAGS = new Set([\"mj-text\", \"mj-button\", \"mj-social-element\", \"mj-navbar-link\"]);\n\n// GrapesJS reads `data-gjs-*` as properties, which reach the page unescaped, and serialises\n// `__p` and `custom-name` from markup as they are.\nconst EDITOR_INTERNALS = /data-gjs-|__p\\b|custom-name/i;\n\n// Markup in a text that GrapesJS drops on a drop, so what was offered is not what lands.\nconst DROPPED_MARKUP = /<(?:script|style|link|meta|iframe|object|embed|form)\\b/i;\n\n// Mail clients block inline images, and the editor never inlines a file.\nconst INLINE_IMAGE =\n /\\b(?:src|srcset|background-url|icon)\\s*=\\s*(?:\"[^\"]*data:|'[^']*data:|data:)/i;\n\n// `<a/href=…>` is an href to a browser too.\nconst LINK_IN_MARKUP =\n /[\\s/\"'](?:xlink:)?(?:href|action|formaction)\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s>]+))/gi;\n\ntype MjmlNode = {\n tagName: string;\n attributes?: Record<string, string>;\n content?: string;\n children?: MjmlNode[];\n};\n\ntype MjmlError = { formattedMessage?: string; message?: string };\n\nlet validator: Editor | undefined;\n\n/** Why a block cannot be offered; empty when it can. */\nexport function blockProblems(\n mjml: string,\n editor: Editor = (validator ??= grapesjs.init({\n headless: true,\n storageManager: false,\n telemetry: false,\n plugins: [grapesjsMJML],\n })),\n): string[] {\n if (EDITOR_INTERNALS.test(mjml)) return [\"it contains GrapesJS's own attributes\"];\n if (INLINE_IMAGE.test(mjml)) return [\"it inlines an image as a data: URL\"];\n\n let tree: MjmlNode;\n try {\n tree = (\n editor.runCommand(\"mjml-code-to-html\", {\n mjml: `<mjml><mj-body>${withClosedTags(mjml)}</mj-body></mjml>`,\n validationLevel: \"strict\",\n }) as { json: MjmlNode }\n ).json;\n } catch (e) {\n const errors = (e as { errors?: MjmlError[] }).errors;\n if (!errors) throw e;\n return errors.map((error) => error.formattedMessage ?? error.message ?? String(error));\n }\n\n const problems: string[] = [];\n const top = tree.children?.find((c) => c.tagName === \"mj-body\")?.children ?? [];\n if (top.length !== 1 || top[0]!.tagName !== \"mj-section\") {\n problems.push(\"it is not exactly one mj-section\");\n }\n const visit = (node: MjmlNode, parent?: MjmlNode) => {\n const tag = node.tagName;\n const attributes = node.attributes ?? {};\n const content = node.content ?? \"\";\n if (!EDITABLE_TAGS.has(tag)) problems.push(`${tag} is not editable here`);\n const cssClass = attributes[\"css-class\"] ?? \"\";\n if (ID_RE.sec.test(cssClass) || ID_RE.obj.test(cssClass)) {\n problems.push(`${tag} carries a sec-* or obj-* id`);\n }\n // Defined in mj-head, which a block cannot bring.\n if (\"mj-class\" in attributes) problems.push(`${tag} uses mj-class`);\n const links = [attributes.href ?? \"\"];\n for (const match of content.matchAll(LINK_IN_MARKUP)) {\n links.push(match[1] ?? match[2] ?? match[3] ?? \"\");\n }\n const linked =\n tag === \"mj-navbar-link\"\n ? isSafeNavbarLink(parent?.attributes?.[\"base-url\"] ?? \"\", attributes.href ?? \"\")\n : true;\n if (!linked || !links.every(isSafeLink)) {\n problems.push(`${tag} has a link scheme mail must not carry`);\n }\n if (\n CONTENT_TAGS.has(tag) ? /<mj-/i.test(content) || DROPPED_MARKUP.test(content) : content.trim()\n ) {\n problems.push(`${tag} holds content the editor does not keep`);\n }\n node.children?.forEach((child) => visit(child, node));\n };\n top.forEach((node) => visit(node));\n return problems;\n}\n\nconst escapeHtml = (text: string) =>\n text.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\").replace(/\"/g, \"&quot;\");\n\n/** Adds the blocks that can be offered, and reports the rest to the developer. */\nexport function registerBlocks(\n editor: Editor,\n blocks: readonly SectionBlock[],\n category: string,\n media: string,\n) {\n for (const block of blocks) {\n const problems = editor.Blocks.get(block.id)\n ? [`the id is already taken`]\n : blockProblems(block.mjml, editor);\n if (problems.length > 0) {\n console.error(`Block \"${block.id}\" is left out of the palette: ${problems.join(\"; \")}`);\n continue;\n }\n editor.Blocks.add(block.id, {\n // GrapesJS writes the label into the tile as markup.\n label: escapeHtml(block.label),\n category,\n media: block.media ?? media,\n content: withClosedTags(block.mjml),\n attributes: tileAttributes(block.id),\n });\n }\n}\n","/**\n * The ids the agent addresses elements by: `sec-<id>` on a section and `obj-<id>` on an element\n * inside one, kept in `css-class` because the MJML validator rejects any other attribute.\n */\n\nimport type { Component } from \"grapesjs\";\n\n// A whole class token, as agent-core reads one: `promo-sec-a` is a host's class, not an id.\nexport const ID_RE = {\n sec: /(?:^|\\s)sec-([A-Za-z0-9_-]+)(?=\\s|$)/,\n obj: /(?:^|\\s)obj-([A-Za-z0-9_-]+)(?=\\s|$)/,\n} as const;\ntype Prefix = keyof typeof ID_RE;\n\nfunction idOf(c: Component, prefix: Prefix): string | null {\n return String(c.getAttributes()[\"css-class\"] ?? \"\").match(ID_RE[prefix])?.[1] ?? null;\n}\n\nconst newId = () => Math.random().toString(36).slice(2, 10);\n\nexport function sectionIdOf(c: Component): string | null {\n return idOf(c, \"sec\");\n}\n\nexport function addIdClass(c: Component, prefix: Prefix): string {\n const existing = idOf(c, prefix);\n if (existing) return existing;\n const cssClass = String(c.getAttributes()[\"css-class\"] ?? \"\");\n const id = newId();\n c.addAttributes({ \"css-class\": `${cssClass} ${prefix}-${id}`.trim() });\n return id;\n}\n\n/**\n * Gives an added subtree new ids wherever another element already has them. A duplicate or a\n * paste copies its original's `css-class`, and two sections answering to one `sec-*` make\n * comments and agent edits land on either.\n */\nexport function freshenCopiedIds(root: Component | undefined, added: Component) {\n const used = (prefix: Prefix, id: string, except: Component) => {\n let found = false;\n root?.onAll((o) => {\n if (o !== except && idOf(o, prefix) === id) found = true;\n });\n return found;\n };\n added.onAll((c) => {\n for (const prefix of [\"sec\", \"obj\"] as const) {\n const id = idOf(c, prefix);\n if (!id || !used(prefix, id, c)) continue;\n const cssClass = String(c.getAttributes()[\"css-class\"]);\n const fresh = cssClass.replace(ID_RE[prefix], (token) =>\n token.replace(`${prefix}-${id}`, `${prefix}-${newId()}`),\n );\n c.addAttributes({ \"css-class\": fresh });\n }\n });\n}\n","/** The palette from the keyboard: GrapesJS's tiles can only be dragged. */\n\nimport type { Block, Component, Editor } from \"grapesjs\";\n\n/** Enter or Space, once: not a held key's repeats, and not a shortcut with a modifier. */\nexport const addsBlock = (\n e: Pick<KeyboardEvent, \"key\" | \"repeat\" | \"ctrlKey\" | \"metaKey\" | \"altKey\">,\n) => (e.key === \"Enter\" || e.key === \" \") && !e.repeat && !e.ctrlKey && !e.metaKey && !e.altKey;\n\n/** Makes a tile focusable and names the block it adds; GrapesJS sets these on the tile. */\nexport const tileAttributes = (id: string) => ({ tabindex: \"0\", role: \"button\", \"data-block\": id });\n\nconst tagOf = (c: Component) => String(c.get(\"tagName\") ?? \"\");\n\nfunction closest(c: Component | undefined, tag: string): Component | undefined {\n for (let cur = c; cur; cur = cur.parent() ?? undefined) if (tagOf(cur) === tag) return cur;\n return undefined;\n}\n\n/** `c`'s ancestor, or itself, whose parent is `parent`. */\nfunction childOf(parent: Component, c: Component): Component {\n let cur = c;\n while (cur.parent() && cur.parent() !== parent) cur = cur.parent()!;\n return cur;\n}\n\n/**\n * Adds a block where a keyboard user means it: a section after the selected one, or last; an\n * element after the selected one or into the selected column, else in a section of its own.\n * Then selects it and, as a drop does, activates it (the image picker opens for an image).\n */\nexport function insertBlock(editor: Editor, block: Block): Component | undefined {\n const content = block.getContent();\n let body: Component | undefined;\n editor.getWrapper()?.onAll((c) => {\n if (!body && tagOf(c) === \"mj-body\") body = c;\n });\n if (typeof content !== \"string\" || !body) return undefined;\n\n const selected = editor.getSelected();\n const section = closest(selected, \"mj-section\");\n // Beside the selected section, so one inside an mj-wrapper stays in it.\n const sections = section?.parent() ?? body;\n const afterSection = section ? { at: section.index() + 1 } : {};\n const column = closest(selected, \"mj-column\");\n let added: Component | undefined;\n if (/^\\s*<mj-section\\b/i.test(content)) {\n added = sections.append(content, afterSection)[0];\n } else if (column && selected) {\n const at = selected === column ? {} : { at: childOf(column, selected).index() + 1 };\n added = column.append(content, at)[0];\n } else {\n const [wrapper] = sections.append(\n `<mj-section><mj-column>${content}</mj-column></mj-section>`,\n afterSection,\n );\n added = wrapper?.components().at(0)?.components().at(0);\n }\n if (!added) return undefined;\n\n editor.select(added);\n if (block.get(\"activate\")) added.getView()?.onActive(undefined as never);\n return added;\n}\n","/** The palette's own blocks: grapesjs-mjml's, with the content its defaults get wrong. */\n\nimport type { EditorLabels } from \"../../labels.js\";\nimport { tileAttributes } from \"./insert-block.js\";\n\n// Social and navigation children are only valid inside their parent; hero and wrapper are\n// banned from editable templates by agent-core (a hero gets no `sec-*` id, so the agent cannot\n// address it); raw HTML is out of place for the people this editor serves.\nexport const BUILTIN_BLOCKS = [\n \"mj-1-column\",\n \"mj-2-columns\",\n \"mj-3-columns\",\n \"mj-text\",\n \"mj-image\",\n \"mj-button\",\n \"mj-divider\",\n \"mj-spacer\",\n \"mj-social-group\",\n \"mj-navbar\",\n];\nconst LAYOUT_BLOCKS = new Set([\"mj-1-column\", \"mj-2-columns\", \"mj-3-columns\"]);\n\nconst CONTENT: Record<string, string> = {\n // The plugin's version links Google+ and shares the page: a bare network name makes the\n // icon open a \"share this link\" dialog, while `-noshare` links to the profile a footer\n // means. Without `alt` each link is an unnamed image to a screen reader.\n \"mj-social-group\": `<mj-social icon-size=\"24px\" mode=\"horizontal\">\n <mj-social-element name=\"facebook-noshare\" href=\"https://facebook.com/\" alt=\"Facebook\"></mj-social-element>\n <mj-social-element name=\"instagram-noshare\" href=\"https://instagram.com/\" alt=\"Instagram\"></mj-social-element>\n <mj-social-element name=\"x-noshare\" href=\"https://x.com/\" alt=\"X\"></mj-social-element>\n</mj-social>`,\n // The plugin's sample is a via.placeholder.com picture, stored in the email and loaded by\n // every reader's mail client. Dropping one opens the image picker instead.\n \"mj-image\": \"<mj-image></mj-image>\",\n};\n\n/** What grapesjs-mjml's `block` option returns for a built-in block. */\nexport function builtinBlock(labels: EditorLabels) {\n return (id: string) => ({\n label: labels.blockLabels[id] ?? id,\n // By id: a regex on the label broke as soon as a host translated it.\n category: LAYOUT_BLOCKS.has(id) ? labels.blockCategoryLayout : labels.blockCategoryContent,\n ...(id in CONTENT && { content: CONTENT[id] }),\n attributes: tileAttributes(id),\n });\n}\n\n/** Shows an image without a picture yet as a box to click, in the canvas only. */\nexport const CANVAS_CSS =\n 'img:not([src]), img[src=\"\"] { min-height: 120px; background: #f4f4f5; outline: 1px dashed #a1a1aa; outline-offset: -1px; }';\n","/**\n * An mj-table, which grapesjs-mjml has no type for. Its markup is kept as it was given and\n * never edited: parsed as HTML, rows outside a table were dropped and only their text kept,\n * so the first edit to an email with a table stored it flattened (see `withTableRowsKept`).\n */\n\nimport { isSafeLink } from \"@mjml-agent-editor/core\";\nimport type { Component, Editor } from \"grapesjs\";\n\n// What the agent's guard refuses too, and a nested template, whose content no query reaches.\nconst DROPPED =\n \"script, style, link, iframe, frame, object, embed, applet, base, meta, animate, set, svg, math, template\";\nconst LINK_ATTRIBUTES = new Set([\"href\", \"xlink:href\", \"action\", \"formaction\"]);\n\n/**\n * What GrapesJS's parser removes everywhere else, removed from the rows too: it never looks\n * inside a template. Scripts and embeds, `on…` handlers, links with another scheme.\n */\nfunction cleanRows(rows: DocumentFragment) {\n rows.querySelectorAll(DROPPED).forEach((el) => el.remove());\n rows.querySelectorAll(\"*\").forEach((el) => {\n for (const { name, value } of [...el.attributes]) {\n const lower = name.toLowerCase();\n const script = /^(java|vb)script:/i.test(value.replace(/[\\u0000-\\u0020]/g, \"\"));\n if (lower.startsWith(\"on\") || script || (LINK_ATTRIBUTES.has(lower) && !isSafeLink(value))) {\n el.removeAttribute(name);\n }\n }\n });\n}\n\n// A column's children are table rows in the canvas, as the plugin renders its own.\nconst ROW_STYLE = \"pointer-events: all; display: table; width: 100%;\";\n\n/**\n * The table as the canvas shows it: its rows and cells as text, aligned as written. Built from\n * an inert template rather than written as HTML, so nothing in the cells runs or loads.\n */\nexport function tablePreview(doc: Document, attributes: Record<string, unknown>, rows: string) {\n const attr = (name: string, fallback: string) => String(attributes[name] ?? fallback);\n const template = doc.createElement(\"template\");\n template.innerHTML = `<table>${rows}</table>`;\n\n const table = doc.createElement(\"table\");\n table.setAttribute(\"cellpadding\", String(parseInt(attr(\"cellpadding\", \"0\"), 10) || 0));\n table.setAttribute(\"cellspacing\", String(parseInt(attr(\"cellspacing\", \"0\"), 10) || 0));\n Object.assign(table.style, {\n width: attr(\"width\", \"100%\"),\n border: attr(\"border\", \"none\"),\n color: attr(\"color\", \"#000000\"),\n fontFamily: attr(\"font-family\", \"Ubuntu, Helvetica, Arial, sans-serif\"),\n fontSize: attr(\"font-size\", \"13px\"),\n lineHeight: attr(\"line-height\", \"22px\"),\n tableLayout: attr(\"table-layout\", \"auto\"),\n });\n for (const row of template.content.querySelectorAll(\"tr\")) {\n const tr = table.insertRow();\n for (const cell of row.querySelectorAll(\":scope > th, :scope > td\")) {\n const copy = doc.createElement(cell.tagName.toLowerCase());\n copy.textContent = cell.textContent;\n const align = cell.getAttribute(\"align\");\n if (align && /^(left|right|center)$/i.test(align)) copy.setAttribute(\"align\", align);\n tr.append(copy);\n }\n }\n\n const cell = doc.createElement(\"td\");\n cell.style.padding = attr(\"padding\", \"10px 25px\");\n cell.append(table);\n return cell;\n}\n\nexport function addTableType(editor: Editor) {\n const base = editor.Components.getType(\"default\")!.view.prototype as {\n updateAttributes: (...args: unknown[]) => void;\n };\n editor.Components.addType(\"mj-table\", {\n isComponent: (el: HTMLElement) => {\n if (el.tagName?.toLowerCase() !== \"mj-table\") return false;\n const rows = el.querySelector<HTMLTemplateElement>(\":scope > template\");\n if (rows) cleanRows(rows.content);\n return { type: \"mj-table\", content: rows?.innerHTML ?? \"\", components: [] };\n },\n model: { defaults: { tagName: \"mj-table\", droppable: false, editable: false } },\n view: {\n tagName: \"tr\",\n // GrapesJS clears the element's attributes, style among them, when the model's change.\n updateAttributes(this: { el: HTMLElement }, ...args: unknown[]) {\n base.updateAttributes.apply(this, args);\n this.el.style.cssText = ROW_STYLE;\n },\n updateContent(this: { el: HTMLElement; model: Component }) {\n const { el, model } = this;\n el.style.cssText = ROW_STYLE;\n el.replaceChildren(\n tablePreview(el.ownerDocument, model.getAttributes(), String(model.get(\"content\") ?? \"\")),\n );\n },\n },\n } as never);\n}\n","/** Corrections to how grapesjs-mjml's types read and write MJML. */\n\nimport type { Component, Editor } from \"grapesjs\";\n\nimport { addTableType } from \"./table-type.js\";\n\ntype AttrToHTML = (this: Component) => Record<string, unknown>;\n\n// What MJML accepts inside an mj-column. The plugin lets a column take anything, so a <p>\n// dragged out of a text landed in the column as an element no validator accepts.\nconst COLUMN_CHILDREN = new Set([\n \"mj-accordion\",\n \"mj-button\",\n \"mj-carousel\",\n \"mj-divider\",\n \"mj-image\",\n \"mj-navbar\",\n \"mj-raw\",\n \"mj-social\",\n \"mj-spacer\",\n \"mj-table\",\n \"mj-text\",\n]);\n\n/**\n * Applied to every mj-* type before a document loads.\n *\n * - No `style-default`s: the plugin's differ from MJML's in places. It stripped any attribute\n * equal to one on save (a navigation link's 25px padding came back as MJML's 15px) and\n * seeded each element with them, so every element looked as if it set them.\n * - Attribute values are escaped: the plugin writes them between double quotes as they are,\n * so a `\"` in a tooltip, or a font name the agent quoted, broke the tag and the document.\n * - GrapesJS's `__p`, which the plugin leaves on the attributes while a colour is dragged, is\n * never written: a save falling due mid-drag stored it.\n * - A column takes only what MJML allows in one.\n * - An mj-table keeps its rows.\n * - An image without a picture is saved without one.\n */\nexport function fixPluginTypes(editor: Editor) {\n addTableType(editor);\n for (const type of editor.Components.getTypes()) {\n // mj-table is ours and serialises through GrapesJS's own escaping; this would add a second.\n if (!type.id.startsWith(\"mj-\") || type.id === \"mj-table\") continue;\n const base = (type.model.prototype as { getAttrToHTML: AttrToHTML }).getAttrToHTML;\n editor.Components.addType(type.id, {\n model: {\n defaults: {\n \"style-default\": {},\n ...(type.id === \"mj-column\" && {\n droppable: (source: Component) => COLUMN_CHILDREN.has(String(source.get(\"tagName\"))),\n }),\n // GrapesJS's own is an SVG's markup, which the canvas wrote into `src` and saved.\n ...(type.id === \"mj-image\" && { src: \"\" }),\n },\n getAttrToHTML(this: Component) {\n const attributes = base.call(this);\n delete attributes.__p;\n for (const [name, value] of Object.entries(attributes)) {\n if (typeof value === \"string\") attributes[name] = value.replace(/\"/g, \"&quot;\");\n }\n return attributes;\n },\n },\n } as never);\n }\n}\n"],"mappings":"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","names":["grapesjs","useEditorMaybe","grapesjsMJML","useEffect","useRef","useState","toast","ChevronRight","jsx","useEffect","useRef","useState","ChevronRight","Trash2","X","useCallback","useEffect","useRef","useState","useEffect","useRef","useState","jsx","jsxs","useState","useEffect","useRef","jsx","jsxs","documentColors","useState","useRef","field","useEffect","useCallback","jsx","jsxs","Link2","tagOf","escapeHtml","jsx","jsxs","tagOf","Link2","start","jsx","jsxs","tagOf","useRef","useEffect","useState","ChevronRight","X","Trash2","tagOf","escapeHtml","CONTENT","isSafeLink","cell","jsx","jsxs","tagOf","useRef","useState","useEffect","toast","grapesjs","grapesjsMJML","useEditorMaybe","ChevronRight"]}