import { n as __exportAll } from "./chunk-B-1-B7_t.js";
import { n as cn } from "./utils-DXzSsU1e.js";
import { t as FieldFrame_default } from "./field-frame-DhCOWcMP.js";
import { Fragment, Teleport, Transition, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, mergeModels, nextTick, normalizeClass, normalizeStyle, onBeforeUnmount, openBlock, ref, renderList, toDisplayString, unref, useModel, watch, withCtx, withKeys, withModifiers } from "vue";
import { Bold, Braces, Code, Columns2, Eraser, Eye, Heading, Image, Italic, Link, List, ListOrdered, Minus, PanelLeft, Quote, Redo2, Strikethrough, Table, Undo2 } from "@lucide/vue";
//#region src/components/compositions/elements/editor/MarkdownEditor.vue?vue&type=script&setup=true&lang.ts
var _hoisted_1 = ["onKeydown"];
var _hoisted_2 = ["innerHTML"];
var _hoisted_3 = {
	key: 1,
	class: "text-sm text-muted-foreground"
};
var _hoisted_4 = ["disabled"];
var _hoisted_5 = ["disabled"];
var _hoisted_6 = ["disabled"];
var _hoisted_7 = ["disabled"];
var _hoisted_8 = ["disabled"];
var _hoisted_9 = ["disabled"];
var _hoisted_10 = ["disabled"];
var _hoisted_11 = ["disabled"];
var _hoisted_12 = ["disabled"];
var _hoisted_13 = ["disabled"];
var _hoisted_14 = ["disabled"];
var _hoisted_15 = ["disabled"];
var _hoisted_16 = ["disabled"];
var _hoisted_17 = ["disabled"];
var _hoisted_18 = { class: "ml-auto flex items-center gap-px pl-2" };
var _hoisted_19 = [
	"id",
	"name",
	"placeholder",
	"readonly",
	"disabled",
	"required",
	"value",
	"data-element-name"
];
var _hoisted_20 = ["innerHTML"];
var _hoisted_21 = ["innerHTML"];
var _hoisted_22 = ["innerHTML"];
var _hoisted_23 = ["data-testid", "onClick"];
var MINI_W = 140;
var MINI_H = 90;
var CONTENT_W = 600;
var MarkdownEditor_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
	__name: "MarkdownEditor",
	props: /* @__PURE__ */ mergeModels({
		modelValue: {},
		id: {},
		name: {},
		label: {},
		hideLabel: { type: Boolean },
		placeholder: {},
		required: { type: Boolean },
		readonly: { type: Boolean },
		disabled: { type: Boolean },
		helpText: {},
		errors: { default: () => [] },
		rows: { default: 16 },
		seamless: { type: Boolean },
		miniPreview: { type: Boolean }
	}, {
		"modelValue": {},
		"modelModifiers": {}
	}),
	emits: ["update:modelValue"],
	setup(__props) {
		/**
		* MarkdownEditor — markdown composer with toolbar, split-pane preview,
		* list auto-continuation, and an optional seamless mode.
		*
		* Standard mode: toolbar + side-by-side editor/preview (viewMode toggle).
		* Seamless mode (`seamless` prop): renders a live preview when unfocused;
		*   clicking the preview surface activates the editor. The toolbar gains a
		*   hold-to-peek button (and Ctrl/⌘+P keyboard shortcut) that temporarily
		*   shows the preview while the button is held.
		*
		* Keyboard shortcuts (when textarea is focused):
		*   Ctrl/⌘ + B    — bold
		*   Ctrl/⌘ + I    — italic
		*   Ctrl/⌘ + K    — link
		*   Ctrl/⌘ + `    — inline code
		*   Ctrl/⌘ + P    — hold-to-peek preview (seamless mode only)
		*   Enter          — continue the current list item (ul/ol)
		*   Enter (empty list item) — exit the list
		*/
		const props = __props;
		const model = useModel(__props, "modelValue");
		const viewMode = ref("split");
		/** Whether the editor pane is active (seamless mode only). */
		const isEditing = ref(false);
		/** Whether the user is holding the peek button / Ctrl+P (seamless only). */
		const isPeeking = ref(false);
		/** Ref to the entire editor container; used for focusout-to-close logic. */
		const containerRef = ref(null);
		function enterEditMode() {
			if (props.disabled || props.readonly) return;
			isEditing.value = true;
			nextTick(() => textareaRef.value?.focus());
		}
		function onContainerFocusOut(_event) {
			if (!props.seamless) return;
			setTimeout(() => {
				if (!isEditing.value) return;
				const active = document.activeElement;
				const insideEditor = containerRef.value?.contains(active);
				const insideMenu = headingMenuRef.value?.contains(active);
				if (!insideEditor && !insideMenu) {
					isEditing.value = false;
					isPeeking.value = false;
				}
			}, 0);
		}
		/** Called on the toolbar div's mousedown in seamless mode.
		*  Prevents focus from leaving the textarea when toolbar buttons are clicked. */
		function onToolbarMousedown(event) {
			if (props.seamless) event.preventDefault();
		}
		/** Hold-to-peek: pointer pressed on the Peek button. */
		function startPeek() {
			if (!props.miniPreview) containerRef.value?.focus();
			isPeeking.value = true;
		}
		/** Hold-to-peek: pointer released / left the Peek button. */
		function endPeek() {
			isPeeking.value = false;
			nextTick(() => textareaRef.value?.focus());
		}
		const MINI_SCALE = MINI_W / CONTENT_W;
		/** Normalised scroll ratio [0–1] driven by the textarea's scrollTop. */
		const miniScrollRatio = ref(0);
		/** Ref to the unscaled inner content div inside the mini thumbnail. */
		const miniInnerRef = ref(null);
		/** Actual rendered height of the mini inner content (updated via ResizeObserver). */
		const miniInnerHeight = ref(0);
		/** Ref to the full-size expanded preview div shown while peeking. */
		const fullPreviewRef = ref(null);
		watch(miniScrollRatio, (ratio) => {
			const el = fullPreviewRef.value;
			if (!el) return;
			el.scrollTop = ratio * Math.max(0, el.scrollHeight - el.clientHeight);
		});
		function onTextareaScroll(event) {
			if (!props.miniPreview) return;
			const ta = event.target;
			miniScrollRatio.value = ta.scrollTop / Math.max(ta.scrollHeight - ta.clientHeight, 1);
		}
		const showMiniPreview = computed(() => props.seamless && props.miniPreview && isEditing.value);
		/** CSS transform applied to the unscaled inner content to scale + scroll-sync it. */
		const miniInnerTransform = computed(() => {
			const visibleH = MINI_H / MINI_SCALE;
			const scrollable = Math.max(0, miniInnerHeight.value - visibleH);
			return `translateY(-${miniScrollRatio.value * scrollable}px) scale(${MINI_SCALE})`;
		});
		function onMiniEnter(el, done) {
			const div = el;
			div.style.transform = "scale(0.85) translate(4px, -4px)";
			div.style.transition = "none";
			requestAnimationFrame(() => {
				div.style.transition = "transform 0.2s ease";
				div.style.transform = "scale(1) translate(0, 0)";
				setTimeout(done, 200);
			});
		}
		function onMiniLeave(el, done) {
			const div = el;
			div.style.transition = "opacity 0.15s ease, transform 0.15s ease";
			div.style.opacity = "0";
			div.style.transform = "scale(1.08) translate(4px, -3px)";
			setTimeout(done, 150);
		}
		function onPeekEnter(_el, done) {
			done();
		}
		function onPeekLeave(_el, done) {
			done();
		}
		const showHeadingMenu = ref(false);
		const headingBtnRef = ref(null);
		const headingMenuRef = ref(null);
		/** Fixed viewport position of the dropdown (updated on open). */
		const headingMenuPos = ref({
			top: 0,
			left: 0
		});
		function openHeadingMenu() {
			const rect = headingBtnRef.value?.getBoundingClientRect();
			if (rect) headingMenuPos.value = {
				top: rect.bottom + 2,
				left: rect.left
			};
			showHeadingMenu.value = true;
		}
		function closeHeadingMenu() {
			showHeadingMenu.value = false;
		}
		function toggleHeadingMenu() {
			if (showHeadingMenu.value) closeHeadingMenu();
			else openHeadingMenu();
		}
		/** Close when clicking outside both the trigger button and the teleported menu. */
		function onHeadingMenuDocClick(event) {
			const target = event.target;
			if (headingBtnRef.value?.contains(target) || headingMenuRef.value?.contains(target)) return;
			closeHeadingMenu();
		}
		watch(showHeadingMenu, (open) => {
			if (open) document.addEventListener("click", onHeadingMenuDocClick, { capture: true });
			else document.removeEventListener("click", onHeadingMenuDocClick, { capture: true });
		});
		onBeforeUnmount(() => {
			document.removeEventListener("click", onHeadingMenuDocClick, { capture: true });
		});
		const textareaRef = ref(null);
		const editorMinHeight = computed(() => `${props.rows * 1.5}rem`);
		/** Wrap the current selection (or a placeholder) with before/after markers. */
		function wrapSelection(before, after = "", placeholder = "text") {
			const ta = textareaRef.value;
			if (!ta || props.disabled || props.readonly) return;
			const start = ta.selectionStart;
			const end = ta.selectionEnd;
			const selected = ta.value.slice(start, end) || placeholder;
			model.value = ta.value.slice(0, start) + before + selected + after + ta.value.slice(end);
			nextTick(() => {
				ta.focus();
				ta.setSelectionRange(start + before.length, start + before.length + selected.length);
			});
		}
		/** Prefix the line at the current cursor position. */
		function insertAtLineStart(prefix) {
			const ta = textareaRef.value;
			if (!ta || props.disabled || props.readonly) return;
			const start = ta.selectionStart;
			const lineStart = ta.value.lastIndexOf("\n", start - 1) + 1;
			model.value = ta.value.slice(0, lineStart) + prefix + ta.value.slice(lineStart);
			nextTick(() => {
				ta.focus();
				ta.setSelectionRange(start + prefix.length, start + prefix.length);
			});
		}
		/** Insert a block at the cursor with surrounding newline guards. */
		function insertBlock(block) {
			const ta = textareaRef.value;
			if (!ta || props.disabled || props.readonly) return;
			const start = ta.selectionStart;
			const before = start > 0 && ta.value[start - 1] !== "\n" ? "\n" : "";
			model.value = ta.value.slice(0, start) + before + block + "\n" + ta.value.slice(start);
			nextTick(() => {
				ta.focus();
				const pos = start + before.length + block.length + 1;
				ta.setSelectionRange(pos, pos);
			});
		}
		function onUndo() {
			textareaRef.value?.focus();
			document.execCommand("undo");
		}
		function onRedo() {
			textareaRef.value?.focus();
			document.execCommand("redo");
		}
		function onClear() {
			if (!props.disabled && !props.readonly) {
				model.value = "";
				nextTick(() => textareaRef.value?.focus());
			}
		}
		function onHeading(level) {
			insertAtLineStart("#".repeat(level) + " ");
			showHeadingMenu.value = false;
		}
		function onBold() {
			wrapSelection("**", "**", "bold text");
		}
		function onItalic() {
			wrapSelection("*", "*", "italic text");
		}
		function onStrikethrough() {
			wrapSelection("~~", "~~", "strikethrough");
		}
		function onBlockquote() {
			insertAtLineStart("> ");
		}
		function onOrderedList() {
			insertAtLineStart("1. ");
		}
		function onUnorderedList() {
			insertAtLineStart("- ");
		}
		function onTable() {
			insertBlock("| Column 1 | Column 2 | Column 3 |\n| --- | --- | --- |\n| Cell 1 | Cell 2 | Cell 3 |");
		}
		function onHR() {
			insertBlock("---");
		}
		function onLink() {
			wrapSelection("[", "](url)", "link text");
		}
		function onImage() {
			insertBlock("![alt text](image-url)");
		}
		function onCode() {
			wrapSelection("`", "`", "code");
		}
		function onCodeFence() {
			insertBlock("```\ncode here\n```");
		}
		function onKeydown(event) {
			const ta = textareaRef.value;
			if (!ta) return;
			if (event.ctrlKey || event.metaKey) {
				switch (event.key.toLowerCase()) {
					case "b":
						event.preventDefault();
						onBold();
						return;
					case "i":
						event.preventDefault();
						onItalic();
						return;
					case "k":
						event.preventDefault();
						onLink();
						return;
					case "`":
						event.preventDefault();
						onCode();
						return;
					case "p":
						if (props.seamless && !event.repeat) {
							event.preventDefault();
							if (!props.miniPreview) containerRef.value?.focus();
							isPeeking.value = true;
							const cleanup = () => {
								isPeeking.value = false;
								nextTick(() => textareaRef.value?.focus());
								window.removeEventListener("keyup", cleanup);
							};
							window.addEventListener("keyup", cleanup);
						}
						return;
				}
				return;
			}
			if (event.key === "Enter" && !event.shiftKey) {
				const cursor = ta.selectionStart;
				const lineStart = ta.value.lastIndexOf("\n", cursor - 1) + 1;
				const line = ta.value.slice(lineStart, cursor);
				const ulMatch = line.match(/^([-*+]) (.*)$/);
				if (ulMatch) {
					event.preventDefault();
					const prefix = ulMatch[1] + " ";
					if (!ulMatch[2].trim()) {
						model.value = ta.value.slice(0, lineStart) + "\n" + ta.value.slice(cursor);
						nextTick(() => ta.setSelectionRange(lineStart + 1, lineStart + 1));
					} else {
						const insertion = "\n" + prefix;
						model.value = ta.value.slice(0, cursor) + insertion + ta.value.slice(cursor);
						nextTick(() => ta.setSelectionRange(cursor + insertion.length, cursor + insertion.length));
					}
					return;
				}
				const olMatch = line.match(/^(\d+)\. (.*)$/);
				if (olMatch) {
					event.preventDefault();
					const num = Number.parseInt(olMatch[1], 10);
					if (!olMatch[2].trim()) {
						model.value = ta.value.slice(0, lineStart) + "\n" + ta.value.slice(cursor);
						nextTick(() => ta.setSelectionRange(lineStart + 1, lineStart + 1));
					} else {
						const insertion = `
${num + 1}. `;
						model.value = ta.value.slice(0, cursor) + insertion + ta.value.slice(cursor);
						nextTick(() => ta.setSelectionRange(cursor + insertion.length, cursor + insertion.length));
					}
					return;
				}
			}
		}
		function onInput(event) {
			model.value = event.target?.value ?? "";
		}
		const previewHtml = computed(() => renderMarkdown(model.value ?? ""));
		function escapeHtml(s) {
			return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
		}
		function inlineMarkdown(escaped) {
			return escaped.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, "<img src=\"$2\" alt=\"$1\" class=\"max-w-full rounded\" />").replace(/\[([^\]]+)\]\(([^)]+)\)/g, "<a href=\"$2\" rel=\"noopener noreferrer\" class=\"text-primary underline underline-offset-2\">$1</a>").replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>").replace(/\*(.+?)\*/g, "<em>$1</em>").replace(/~~(.+?)~~/g, "<del>$1</del>").replace(/`([^`]+)`/g, "<code class=\"rounded bg-muted px-1 py-0.5 font-mono text-[0.85em]\">$1</code>");
		}
		const HEADING_SIZES = {
			1: "text-3xl font-bold mt-6 mb-3",
			2: "text-2xl font-bold mt-5 mb-2",
			3: "text-xl font-semibold mt-4 mb-2",
			4: "text-lg font-semibold mt-3 mb-1",
			5: "text-base font-medium mt-2 mb-1",
			6: "text-sm font-medium mt-2 mb-1"
		};
		function isBlockStart(line) {
			return /^(#{1,6}\s|>\s|[-*+]\s|\d+\.\s|```|(-{3,}|\*{3,}|_{3,})\s*$|\|)/.test(line);
		}
		function renderMarkdown(input) {
			if (!input.trim()) return "";
			const lines = input.split("\n");
			const out = [];
			let i = 0;
			while (i < lines.length) {
				const line = lines[i] ?? "";
				if (line.startsWith("```")) {
					const lang = line.slice(3).trim();
					const codeLines = [];
					i++;
					while (i < lines.length && !(lines[i] ?? "").startsWith("```")) {
						codeLines.push(lines[i] ?? "");
						i++;
					}
					out.push(`<pre class="my-4 overflow-x-auto rounded-md bg-muted px-4 py-3 text-sm font-mono">${lang ? `<code class="language-${escapeHtml(lang)}">` : "<code>"}${escapeHtml(codeLines.join("\n"))}</code></pre>`);
					i++;
					continue;
				}
				if (/^(-{3,}|\*{3,}|_{3,})\s*$/.test(line)) {
					out.push("<hr class=\"my-6 border-border\" />");
					i++;
					continue;
				}
				const headingMatch = line.match(/^(#{1,6})\s+(.*)$/);
				if (headingMatch) {
					const lvl = headingMatch[1].length;
					const text = headingMatch[2].trim();
					if (text) out.push(`<h${lvl} class="${HEADING_SIZES[lvl] ?? ""} leading-tight">${inlineMarkdown(escapeHtml(text))}</h${lvl}>`);
					i++;
					continue;
				}
				if (line.startsWith("> ")) {
					const bqLines = [];
					while (i < lines.length && (lines[i] ?? "").startsWith("> ")) {
						bqLines.push((lines[i] ?? "").slice(2));
						i++;
					}
					out.push(`<blockquote class="my-3 border-l-4 border-muted-foreground/30 pl-4 italic text-muted-foreground">${inlineMarkdown(escapeHtml(bqLines.join("\n")))}</blockquote>`);
					continue;
				}
				if (/^[-*+]\s/.test(line)) {
					const items = [];
					while (i < lines.length && /^[-*+]\s/.test(lines[i] ?? "")) {
						items.push(`<li class="leading-relaxed">${inlineMarkdown(escapeHtml((lines[i] ?? "").replace(/^[-*+]\s/, "")))}</li>`);
						i++;
					}
					out.push(`<ul class="my-3 list-disc space-y-1 pl-6">${items.join("")}</ul>`);
					continue;
				}
				if (/^\d+\.\s/.test(line)) {
					const items = [];
					while (i < lines.length && /^\d+\.\s/.test(lines[i] ?? "")) {
						items.push(`<li class="leading-relaxed">${inlineMarkdown(escapeHtml((lines[i] ?? "").replace(/^\d+\.\s/, "")))}</li>`);
						i++;
					}
					out.push(`<ol class="my-3 list-decimal space-y-1 pl-6">${items.join("")}</ol>`);
					continue;
				}
				if (line.includes("|") && /^\|[\s:|-]+\|/.test(lines[i + 1] ?? "")) {
					const headers = line.split("|").slice(1, -1).map((h) => `<th class="border border-border bg-muted/50 px-3 py-2 text-left font-semibold">${inlineMarkdown(escapeHtml(h.trim()))}</th>`);
					i += 2;
					const rows = [];
					while (i < lines.length && (lines[i] ?? "").includes("|") && !/^\|[\s:|-]+\|/.test(lines[i] ?? "")) {
						const cells = (lines[i] ?? "").split("|").slice(1, -1).map((c) => `<td class="border border-border px-3 py-2">${inlineMarkdown(escapeHtml(c.trim()))}</td>`);
						rows.push(`<tr class="even:bg-muted/20">${cells.join("")}</tr>`);
						i++;
					}
					out.push(`<div class="my-4 overflow-x-auto rounded-md border"><table class="w-full border-collapse text-sm"><thead><tr>${headers.join("")}</tr></thead><tbody>${rows.join("")}</tbody></table></div>`);
					continue;
				}
				if (!line.trim()) {
					i++;
					continue;
				}
				const paraLines = [];
				while (i < lines.length && (lines[i] ?? "").trim() && !isBlockStart(lines[i] ?? "")) {
					paraLines.push(lines[i] ?? "");
					i++;
				}
				if (paraLines.length) out.push(`<p class="my-2 leading-relaxed">${inlineMarkdown(escapeHtml(paraLines.join(" ")))}</p>`);
				else i++;
			}
			return out.join("\n");
		}
		watch([miniInnerRef, previewHtml], () => {
			const el = miniInnerRef.value;
			if (el) miniInnerHeight.value = el.scrollHeight;
		}, { flush: "post" });
		/** Whether the source textarea should be rendered. */
		const showSource = computed(() => {
			if (props.seamless) {
				if (props.miniPreview) return isEditing.value;
				return isEditing.value && !isPeeking.value;
			}
			return viewMode.value !== "preview";
		});
		/** Whether the standalone preview pane should be rendered. */
		const showPreview = computed(() => {
			if (props.seamless) {
				if (props.miniPreview) return false;
				return !isEditing.value || isPeeking.value;
			}
			return viewMode.value !== "edit";
		});
		const sourceWidthClass = computed(() => {
			if (props.seamless) return "w-full";
			return viewMode.value === "split" ? "w-1/2 border-r" : "w-full";
		});
		const previewWidthClass = computed(() => {
			if (props.seamless) return "w-full";
			return viewMode.value === "split" ? "w-1/2 border-l" : "w-full";
		});
		return (_ctx, _cache) => {
			return openBlock(), createElementBlock(Fragment, null, [createVNode(unref(FieldFrame_default), {
				label: __props.label,
				required: __props.required,
				"hide-label": __props.hideLabel,
				for: __props.id,
				"help-text": __props.helpText,
				errors: __props.errors,
				"data-testid": "markdown-editor"
			}, {
				default: withCtx(() => [props.seamless && !isEditing.value ? (openBlock(), createElementBlock("div", {
					key: 0,
					role: "button",
					tabindex: "0",
					style: normalizeStyle({ minHeight: editorMinHeight.value }),
					class: normalizeClass(unref(cn)("group relative cursor-text rounded-md px-4 py-3 transition-all", "ring-1 ring-transparent hover:ring-ring/30", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", props.disabled ? "pointer-events-none opacity-50" : "")),
					"data-testid": "markdown-editor-preview-surface",
					onClick: enterEditMode,
					onKeydown: [withKeys(withModifiers(enterEditMode, ["prevent"]), ["enter"]), withKeys(withModifiers(enterEditMode, ["prevent"]), ["space"])]
				}, [previewHtml.value ? (openBlock(), createElementBlock("div", {
					key: 0,
					class: "prose prose-sm max-w-none text-sm dark:prose-invert",
					"data-testid": "markdown-editor-preview",
					innerHTML: previewHtml.value
				}, null, 8, _hoisted_2)) : (openBlock(), createElementBlock("p", _hoisted_3, toDisplayString(__props.placeholder ?? "Write markdown here…"), 1)), _cache[4] || (_cache[4] = createElementVNode("span", { class: "absolute bottom-2 right-2 rounded-sm bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100" }, " Click to edit ", -1))], 46, _hoisted_1)) : createCommentVNode("", true), !props.seamless || isEditing.value ? (openBlock(), createElementBlock("div", {
					key: 1,
					ref_key: "containerRef",
					ref: containerRef,
					tabindex: "-1",
					class: "flex flex-col rounded-md border focus-visible:outline-none",
					onFocusout: onContainerFocusOut
				}, [createElementVNode("div", {
					class: "flex shrink-0 items-center gap-px overflow-x-auto border-b bg-muted/20 px-1.5 py-1",
					"data-testid": "markdown-editor-toolbar",
					onMousedown: onToolbarMousedown
				}, [
					createElementVNode("button", {
						type: "button",
						class: "flex h-7 w-7 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-40",
						title: "Undo",
						"data-testid": "markdown-editor-undo",
						onClick: onUndo
					}, [createVNode(unref(Undo2), { class: "h-3.5 w-3.5" })]),
					createElementVNode("button", {
						type: "button",
						class: "flex h-7 w-7 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-40",
						title: "Redo",
						"data-testid": "markdown-editor-redo",
						onClick: onRedo
					}, [createVNode(unref(Redo2), { class: "h-3.5 w-3.5" })]),
					createElementVNode("button", {
						type: "button",
						class: "flex h-7 w-7 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-40",
						title: "Clear",
						disabled: __props.disabled || __props.readonly,
						"data-testid": "markdown-editor-clear",
						onClick: onClear
					}, [createVNode(unref(Eraser), { class: "h-3.5 w-3.5" })], 8, _hoisted_4),
					_cache[5] || (_cache[5] = createElementVNode("div", { class: "mx-1 h-5 w-px shrink-0 bg-border" }, null, -1)),
					createElementVNode("button", {
						ref_key: "headingBtnRef",
						ref: headingBtnRef,
						type: "button",
						class: normalizeClass(["flex h-7 w-7 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-40", showHeadingMenu.value ? "bg-accent text-accent-foreground" : ""]),
						title: "Heading",
						disabled: __props.disabled || __props.readonly,
						"data-testid": "markdown-editor-heading",
						onClick: toggleHeadingMenu
					}, [createVNode(unref(Heading), { class: "h-3.5 w-3.5" })], 10, _hoisted_5),
					createElementVNode("button", {
						type: "button",
						class: "flex h-7 w-7 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-40",
						title: "Bold (Ctrl+B)",
						disabled: __props.disabled || __props.readonly,
						"data-testid": "markdown-editor-bold",
						onClick: onBold
					}, [createVNode(unref(Bold), { class: "h-3.5 w-3.5" })], 8, _hoisted_6),
					createElementVNode("button", {
						type: "button",
						class: "flex h-7 w-7 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-40",
						title: "Italic (Ctrl+I)",
						disabled: __props.disabled || __props.readonly,
						"data-testid": "markdown-editor-italic",
						onClick: onItalic
					}, [createVNode(unref(Italic), { class: "h-3.5 w-3.5" })], 8, _hoisted_7),
					createElementVNode("button", {
						type: "button",
						class: "flex h-7 w-7 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-40",
						title: "Strikethrough",
						disabled: __props.disabled || __props.readonly,
						"data-testid": "markdown-editor-strikethrough",
						onClick: onStrikethrough
					}, [createVNode(unref(Strikethrough), { class: "h-3.5 w-3.5" })], 8, _hoisted_8),
					createElementVNode("button", {
						type: "button",
						class: "flex h-7 w-7 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-40",
						title: "Blockquote",
						disabled: __props.disabled || __props.readonly,
						"data-testid": "markdown-editor-blockquote",
						onClick: onBlockquote
					}, [createVNode(unref(Quote), { class: "h-3.5 w-3.5" })], 8, _hoisted_9),
					_cache[6] || (_cache[6] = createElementVNode("div", { class: "mx-1 h-5 w-px shrink-0 bg-border" }, null, -1)),
					createElementVNode("button", {
						type: "button",
						class: "flex h-7 w-7 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-40",
						title: "Ordered list",
						disabled: __props.disabled || __props.readonly,
						"data-testid": "markdown-editor-ordered-list",
						onClick: onOrderedList
					}, [createVNode(unref(ListOrdered), { class: "h-3.5 w-3.5" })], 8, _hoisted_10),
					createElementVNode("button", {
						type: "button",
						class: "flex h-7 w-7 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-40",
						title: "Unordered list",
						disabled: __props.disabled || __props.readonly,
						"data-testid": "markdown-editor-unordered-list",
						onClick: onUnorderedList
					}, [createVNode(unref(List), { class: "h-3.5 w-3.5" })], 8, _hoisted_11),
					createElementVNode("button", {
						type: "button",
						class: "flex h-7 w-7 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-40",
						title: "Table",
						disabled: __props.disabled || __props.readonly,
						"data-testid": "markdown-editor-table",
						onClick: onTable
					}, [createVNode(unref(Table), { class: "h-3.5 w-3.5" })], 8, _hoisted_12),
					createElementVNode("button", {
						type: "button",
						class: "flex h-7 w-7 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-40",
						title: "Horizontal rule",
						disabled: __props.disabled || __props.readonly,
						"data-testid": "markdown-editor-hr",
						onClick: onHR
					}, [createVNode(unref(Minus), { class: "h-3.5 w-3.5" })], 8, _hoisted_13),
					_cache[7] || (_cache[7] = createElementVNode("div", { class: "mx-1 h-5 w-px shrink-0 bg-border" }, null, -1)),
					createElementVNode("button", {
						type: "button",
						class: "flex h-7 w-7 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-40",
						title: "Link (Ctrl+K)",
						disabled: __props.disabled || __props.readonly,
						"data-testid": "markdown-editor-link",
						onClick: onLink
					}, [createVNode(unref(Link), { class: "h-3.5 w-3.5" })], 8, _hoisted_14),
					createElementVNode("button", {
						type: "button",
						class: "flex h-7 w-7 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-40",
						title: "Image",
						disabled: __props.disabled || __props.readonly,
						"data-testid": "markdown-editor-image",
						onClick: onImage
					}, [createVNode(unref(Image), { class: "h-3.5 w-3.5" })], 8, _hoisted_15),
					createElementVNode("button", {
						type: "button",
						class: "flex h-7 w-7 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-40",
						title: "Inline code (Ctrl+`)",
						disabled: __props.disabled || __props.readonly,
						"data-testid": "markdown-editor-code",
						onClick: onCode
					}, [createVNode(unref(Code), { class: "h-3.5 w-3.5" })], 8, _hoisted_16),
					createElementVNode("button", {
						type: "button",
						class: "flex h-7 w-7 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-40",
						title: "Code block",
						disabled: __props.disabled || __props.readonly,
						"data-testid": "markdown-editor-code-fence",
						onClick: onCodeFence
					}, [createVNode(unref(Braces), { class: "h-3.5 w-3.5" })], 8, _hoisted_17),
					createElementVNode("div", _hoisted_18, [props.seamless ? (openBlock(), createElementBlock("button", {
						key: 0,
						type: "button",
						class: normalizeClass(["flex h-7 w-7 items-center justify-center rounded transition-colors", isPeeking.value ? "bg-accent text-accent-foreground" : "text-muted-foreground hover:bg-accent/60 hover:text-accent-foreground"]),
						title: "Hold to preview (Ctrl+P)",
						"data-testid": "markdown-editor-peek",
						onPointerdown: withModifiers(startPeek, ["stop"]),
						onPointerup: withModifiers(endPeek, ["stop"]),
						onPointerleave: withModifiers(endPeek, ["stop"])
					}, [createVNode(unref(Eye), { class: "h-3.5 w-3.5" })], 34)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
						createElementVNode("button", {
							type: "button",
							class: normalizeClass(["flex h-7 w-7 items-center justify-center rounded transition-colors", viewMode.value === "edit" ? "bg-accent text-accent-foreground" : "text-muted-foreground hover:bg-accent/60 hover:text-accent-foreground"]),
							title: "Edit only",
							"data-testid": "markdown-editor-view-edit",
							onClick: _cache[0] || (_cache[0] = ($event) => viewMode.value = "edit")
						}, [createVNode(unref(PanelLeft), { class: "h-3.5 w-3.5" })], 2),
						createElementVNode("button", {
							type: "button",
							class: normalizeClass(["flex h-7 w-7 items-center justify-center rounded transition-colors", viewMode.value === "split" ? "bg-accent text-accent-foreground" : "text-muted-foreground hover:bg-accent/60 hover:text-accent-foreground"]),
							title: "Split view",
							"data-testid": "markdown-editor-view-split",
							onClick: _cache[1] || (_cache[1] = ($event) => viewMode.value = "split")
						}, [createVNode(unref(Columns2), { class: "h-3.5 w-3.5" })], 2),
						createElementVNode("button", {
							type: "button",
							class: normalizeClass(["flex h-7 w-7 items-center justify-center rounded transition-colors", viewMode.value === "preview" ? "bg-accent text-accent-foreground" : "text-muted-foreground hover:bg-accent/60 hover:text-accent-foreground"]),
							title: "Preview only",
							"data-testid": "markdown-editor-view-preview",
							onClick: _cache[2] || (_cache[2] = ($event) => viewMode.value = "preview")
						}, [createVNode(unref(Eye), { class: "h-3.5 w-3.5" })], 2)
					], 64))])
				], 32), createElementVNode("div", {
					class: "relative flex overflow-hidden rounded-b-md",
					style: normalizeStyle({ minHeight: editorMinHeight.value })
				}, [
					showSource.value ? (openBlock(), createElementBlock("textarea", {
						key: 0,
						id: __props.id,
						ref_key: "textareaRef",
						ref: textareaRef,
						name: __props.name ?? void 0,
						placeholder: __props.placeholder ?? "Write markdown here...",
						readonly: __props.readonly,
						disabled: __props.disabled,
						required: __props.required,
						value: model.value ?? "",
						"data-element-name": __props.name ?? void 0,
						"data-testid": "markdown-editor-source",
						class: normalizeClass(unref(cn)("flex-1 resize-none bg-background px-4 py-3 font-mono text-sm leading-relaxed focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50", sourceWidthClass.value, __props.errors.length ? "border-destructive ring-destructive" : "")),
						onInput,
						onKeydown,
						onScroll: onTextareaScroll
					}, null, 42, _hoisted_19)) : createCommentVNode("", true),
					showPreview.value ? (openBlock(), createElementBlock("div", {
						key: 1,
						"data-testid": "markdown-editor-preview",
						class: normalizeClass(unref(cn)("flex-1 overflow-y-auto px-6 py-4 text-sm prose prose-sm max-w-none dark:prose-invert", previewWidthClass.value)),
						innerHTML: previewHtml.value
					}, null, 10, _hoisted_20)) : createCommentVNode("", true),
					createVNode(Transition, {
						css: false,
						onEnter: onMiniEnter,
						onLeave: onMiniLeave
					}, {
						default: withCtx(() => [showMiniPreview.value && !isPeeking.value ? (openBlock(), createElementBlock("div", {
							key: 0,
							class: "pointer-events-none absolute overflow-hidden rounded-md border bg-background shadow-md",
							style: normalizeStyle({
								top: "8px",
								right: "8px",
								width: `${MINI_W}px`,
								height: `${MINI_H}px`,
								zIndex: 10,
								opacity: "0.85"
							}),
							"data-testid": "markdown-editor-mini-preview"
						}, [createElementVNode("div", {
							ref_key: "miniInnerRef",
							ref: miniInnerRef,
							class: "prose prose-sm pointer-events-none absolute left-0 top-0 max-w-none dark:prose-invert",
							style: normalizeStyle({
								transform: miniInnerTransform.value,
								transformOrigin: "0 0",
								width: `${CONTENT_W}px`,
								padding: "0.75rem",
								fontSize: "0.625rem",
								lineHeight: "1.4"
							}),
							innerHTML: previewHtml.value
						}, null, 12, _hoisted_21)], 4)) : createCommentVNode("", true)]),
						_: 1
					}),
					createVNode(Transition, {
						css: false,
						onEnter: onPeekEnter,
						onLeave: onPeekLeave
					}, {
						default: withCtx(() => [showMiniPreview.value && isPeeking.value ? (openBlock(), createElementBlock("div", {
							key: 0,
							ref_key: "fullPreviewRef",
							ref: fullPreviewRef,
							class: "prose prose-sm absolute inset-0 max-w-none overflow-y-auto bg-background px-6 py-4 text-sm dark:prose-invert",
							style: {
								"z-index": "20",
								"pointer-events": "none"
							},
							"data-testid": "markdown-editor-peek-preview",
							innerHTML: previewHtml.value
						}, null, 8, _hoisted_22)) : createCommentVNode("", true)]),
						_: 1
					})
				], 4)], 544)) : createCommentVNode("", true)]),
				_: 1
			}, 8, [
				"label",
				"required",
				"hide-label",
				"for",
				"help-text",
				"errors"
			]), (openBlock(), createBlock(Teleport, { to: "body" }, [showHeadingMenu.value ? (openBlock(), createElementBlock("div", {
				key: 0,
				ref_key: "headingMenuRef",
				ref: headingMenuRef,
				style: normalizeStyle({
					position: "fixed",
					top: `${headingMenuPos.value.top}px`,
					left: `${headingMenuPos.value.left}px`,
					zIndex: 9999
				}),
				class: "flex min-w-[5rem] flex-col gap-px rounded-md border bg-popover p-1 shadow-md",
				"data-testid": "markdown-editor-heading-menu",
				onMousedown: _cache[3] || (_cache[3] = withModifiers(() => {}, ["prevent"]))
			}, [(openBlock(), createElementBlock(Fragment, null, renderList([
				1,
				2,
				3,
				4,
				5,
				6
			], (lvl) => {
				return createElementVNode("button", {
					key: lvl,
					type: "button",
					class: normalizeClass(["flex h-7 w-full items-center rounded px-2.5 text-sm hover:bg-accent", lvl <= 2 ? "font-bold" : lvl <= 4 ? "font-semibold" : "font-medium text-muted-foreground"]),
					"data-testid": `markdown-editor-heading-${lvl}`,
					onClick: ($event) => onHeading(lvl)
				}, " H" + toDisplayString(lvl), 11, _hoisted_23);
			}), 64))], 36)) : createCommentVNode("", true)]))], 64);
		};
	}
});
//#endregion
//#region src/components/compositions/elements/editor/MarkdownEditor.vue
var MarkdownEditor_exports = /* @__PURE__ */ __exportAll({ default: () => MarkdownEditor_default });
var MarkdownEditor_default = MarkdownEditor_vue_vue_type_script_setup_true_lang_default;
//#endregion
export { MarkdownEditor_exports as n, MarkdownEditor_default as t };

//# sourceMappingURL=MarkdownEditor-Dfeic9Ce.js.map