UNPKG

vue-libre-editor

Version:
1,286 lines 119 kB
import { h, ref, reactive, onMounted, onUnmounted, watch, computed, resolveComponent, createElementBlock, openBlock, normalizeStyle, createElementVNode, createCommentVNode, createStaticVNode, withDirectives, withKeys, vModelText, Fragment, renderList, normalizeClass, createVNode, vModelCheckbox, nextTick } from "vue"; /** * @license lucide-vue-next v0.511.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(); const toCamelCase = (string) => string.replace( /^([A-Z])|[\s-_]+(\w)/g, (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase() ); const toPascalCase = (string) => { const camelCase = toCamelCase(string); return camelCase.charAt(0).toUpperCase() + camelCase.slice(1); }; const mergeClasses = (...classes) => classes.filter((className, index, array) => { return Boolean(className) && className.trim() !== "" && array.indexOf(className) === index; }).join(" ").trim(); /** * @license lucide-vue-next v0.511.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ var defaultAttributes = { xmlns: "http://www.w3.org/2000/svg", width: 24, height: 24, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": 2, "stroke-linecap": "round", "stroke-linejoin": "round" }; /** * @license lucide-vue-next v0.511.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const Icon = ({ size, strokeWidth = 2, absoluteStrokeWidth, color, iconNode, name, class: classes, ...props }, { slots }) => { return h( "svg", { ...defaultAttributes, width: size || defaultAttributes.width, height: size || defaultAttributes.height, stroke: color || defaultAttributes.stroke, "stroke-width": absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth, class: mergeClasses( "lucide", ...name ? [`lucide-${toKebabCase(toPascalCase(name))}-icon`, `lucide-${toKebabCase(name)}`] : ["lucide-icon"] ), ...props }, [...iconNode.map((child) => h(...child)), ...slots.default ? [slots.default()] : []] ); }; /** * @license lucide-vue-next v0.511.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const createLucideIcon = (iconName, iconNode) => (props, { slots }) => h( Icon, { ...props, iconNode, name: iconName }, slots ); /** * @license lucide-vue-next v0.511.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const AlignCenter = createLucideIcon("align-center", [ ["path", { d: "M17 12H7", key: "16if0g" }], ["path", { d: "M19 18H5", key: "18s9l3" }], ["path", { d: "M21 6H3", key: "1jwq7v" }] ]); /** * @license lucide-vue-next v0.511.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const AlignJustify = createLucideIcon("align-justify", [ ["path", { d: "M3 12h18", key: "1i2n21" }], ["path", { d: "M3 18h18", key: "1h113x" }], ["path", { d: "M3 6h18", key: "d0wm0j" }] ]); /** * @license lucide-vue-next v0.511.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const AlignLeft = createLucideIcon("align-left", [ ["path", { d: "M15 12H3", key: "6jk70r" }], ["path", { d: "M17 18H3", key: "1amg6g" }], ["path", { d: "M21 6H3", key: "1jwq7v" }] ]); /** * @license lucide-vue-next v0.511.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const AlignRight = createLucideIcon("align-right", [ ["path", { d: "M21 12H9", key: "dn1m92" }], ["path", { d: "M21 18H7", key: "1ygte8" }], ["path", { d: "M21 6H3", key: "1jwq7v" }] ]); /** * @license lucide-vue-next v0.511.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const Bold = createLucideIcon("bold", [ [ "path", { d: "M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8", key: "mg9rjx" } ] ]); /** * @license lucide-vue-next v0.511.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const Combine = createLucideIcon("combine", [ ["path", { d: "M10 18H5a3 3 0 0 1-3-3v-1", key: "ru65g8" }], ["path", { d: "M14 2a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2", key: "e30een" }], ["path", { d: "M20 2a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2", key: "2ahx8o" }], ["path", { d: "m7 21 3-3-3-3", key: "127cv2" }], ["rect", { x: "14", y: "14", width: "8", height: "8", rx: "2", key: "1b0bso" }], ["rect", { x: "2", y: "2", width: "8", height: "8", rx: "2", key: "1x09vl" }] ]); /** * @license lucide-vue-next v0.511.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const Image$1 = createLucideIcon("image", [ ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2", key: "1m3agn" }], ["circle", { cx: "9", cy: "9", r: "2", key: "af1f0g" }], ["path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21", key: "1xmnt7" }] ]); /** * @license lucide-vue-next v0.511.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const IndentDecrease = createLucideIcon("indent-decrease", [ ["path", { d: "M21 12H11", key: "wd7e0v" }], ["path", { d: "M21 18H11", key: "4wu86t" }], ["path", { d: "M21 6H11", key: "6dy1d6" }], ["path", { d: "m7 8-4 4 4 4", key: "o5hrat" }] ]); /** * @license lucide-vue-next v0.511.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const IndentIncrease = createLucideIcon("indent-increase", [ ["path", { d: "M21 12H11", key: "wd7e0v" }], ["path", { d: "M21 18H11", key: "4wu86t" }], ["path", { d: "M21 6H11", key: "6dy1d6" }], ["path", { d: "m3 8 4 4-4 4", key: "1a3j6y" }] ]); /** * @license lucide-vue-next v0.511.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const Italic = createLucideIcon("italic", [ ["line", { x1: "19", x2: "10", y1: "4", y2: "4", key: "15jd3p" }], ["line", { x1: "14", x2: "5", y1: "20", y2: "20", key: "bu0au3" }], ["line", { x1: "15", x2: "9", y1: "4", y2: "20", key: "uljnxc" }] ]); /** * @license lucide-vue-next v0.511.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const Link = createLucideIcon("link", [ ["path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71", key: "1cjeqo" }], ["path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71", key: "19qd67" }] ]); /** * @license lucide-vue-next v0.511.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const Paintbrush = createLucideIcon("paintbrush", [ ["path", { d: "m14.622 17.897-10.68-2.913", key: "vj2p1u" }], [ "path", { d: "M18.376 2.622a1 1 0 1 1 3.002 3.002L17.36 9.643a.5.5 0 0 0 0 .707l.944.944a2.41 2.41 0 0 1 0 3.408l-.944.944a.5.5 0 0 1-.707 0L8.354 7.348a.5.5 0 0 1 0-.707l.944-.944a2.41 2.41 0 0 1 3.408 0l.944.944a.5.5 0 0 0 .707 0z", key: "18tc5c" } ], [ "path", { d: "M9 8c-1.804 2.71-3.97 3.46-6.583 3.948a.507.507 0 0 0-.302.819l7.32 8.883a1 1 0 0 0 1.185.204C12.735 20.405 16 16.792 16 15", key: "ytzfxy" } ] ]); /** * @license lucide-vue-next v0.511.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const Redo = createLucideIcon("redo", [ ["path", { d: "M21 7v6h-6", key: "3ptur4" }], ["path", { d: "M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3l3 2.7", key: "1kgawr" }] ]); /** * @license lucide-vue-next v0.511.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const Settings = createLucideIcon("settings", [ [ "path", { d: "M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z", key: "1qme2f" } ], ["circle", { cx: "12", cy: "12", r: "3", key: "1v7zrd" }] ]); /** * @license lucide-vue-next v0.511.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const SquareSplitVertical = createLucideIcon("square-split-vertical", [ ["path", { d: "M5 8V5c0-1 1-2 2-2h10c1 0 2 1 2 2v3", key: "1pi83i" }], ["path", { d: "M19 16v3c0 1-1 2-2 2H7c-1 0-2-1-2-2v-3", key: "ido5k7" }], ["line", { x1: "4", x2: "20", y1: "12", y2: "12", key: "1e0a9i" }] ]); /** * @license lucide-vue-next v0.511.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const Strikethrough = createLucideIcon("strikethrough", [ ["path", { d: "M16 4H9a3 3 0 0 0-2.83 4", key: "43sutm" }], ["path", { d: "M14 12a4 4 0 0 1 0 8H6", key: "nlfj13" }], ["line", { x1: "4", x2: "20", y1: "12", y2: "12", key: "1e0a9i" }] ]); /** * @license lucide-vue-next v0.511.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const Table = createLucideIcon("table", [ ["path", { d: "M12 3v18", key: "108xh3" }], ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }], ["path", { d: "M3 9h18", key: "1pudct" }], ["path", { d: "M3 15h18", key: "5xshup" }] ]); /** * @license lucide-vue-next v0.511.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const Underline = createLucideIcon("underline", [ ["path", { d: "M6 4v6a6 6 0 0 0 12 0V4", key: "9kb039" }], ["line", { x1: "4", x2: "20", y1: "20", y2: "20", key: "nun2al" }] ]); /** * @license lucide-vue-next v0.511.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const Undo = createLucideIcon("undo", [ ["path", { d: "M3 7v6h6", key: "1v2h90" }], ["path", { d: "M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13", key: "1r6uu6" }] ]); /** * @license lucide-vue-next v0.511.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const X = createLucideIcon("x", [ ["path", { d: "M18 6 6 18", key: "1bl5f8" }], ["path", { d: "m6 6 12 12", key: "d8bk6v" }] ]); const _export_sfc = (sfc, props) => { const target = sfc.__vccOpts || sfc; for (const [key, val] of props) { target[key] = val; } return target; }; const _sfc_main$6 = { components: { Bold, Italic, Underline, Strikethrough, AlignLeft, AlignCenter, AlignRight, AlignJustify, Outdent: IndentDecrease, Indent: IndentIncrease, ImageIcon: Image$1, Link, Undo, Redo, X, Table, Settings, SplitSquareVertical: SquareSplitVertical, Combine, Paintbrush }, props: { editor: { type: Object, default: null }, theme: { type: Object, default: () => ({ headerBgColor: "#f3f4f6", headerFgColor: "#111827", contentBgColor: "#ffffff", contentFgColor: "#111827", edgeColor: "#d1d5db", activeButtonBg: "#e5e7eb", activeButtonFg: "#2563eb" }) }, selectedElement: { type: Object, default: null }, selectedCell: { type: Object, default: null } }, emits: ["execute-command", "insert-image", "insert-table", "insert-link", "edit-table", "split-cell", "merge-cells", "cell-color"], setup(props, { emit }) { const showColorPicker = ref(false); const showBgColorPicker = ref(false); const textColor = ref("#000000"); const bgColor = ref("#ffffff"); const textColorPickerRef = ref(null); const bgColorPickerRef = ref(null); const commandStates = reactive({ bold: false, italic: false, underline: false, strikeThrough: false, justifyLeft: false, justifyCenter: false, justifyRight: false, justifyFull: false }); const updateCommandStates = () => { try { commandStates.bold = document.queryCommandState("bold"); commandStates.italic = document.queryCommandState("italic"); commandStates.underline = document.queryCommandState("underline"); commandStates.strikeThrough = document.queryCommandState("strikeThrough"); commandStates.justifyLeft = document.queryCommandState("justifyLeft"); commandStates.justifyCenter = document.queryCommandState("justifyCenter"); commandStates.justifyRight = document.queryCommandState("justifyRight"); commandStates.justifyFull = document.queryCommandState("justifyFull"); } catch (e) { console.warn("Error updating command states:", e); } }; onMounted(() => { document.addEventListener("selectionchange", updateCommandStates); document.addEventListener("click", handleClickOutside); updateCommandStates(); }); onUnmounted(() => { document.removeEventListener("selectionchange", updateCommandStates); document.removeEventListener("click", handleClickOutside); }); watch(() => props.theme, () => { updateCommandStates(); }, { deep: true }); const colors = [ "#000000", "#434343", "#666666", "#999999", "#b7b7b7", "#d9d9d9", "#efefef", "#f3f3f3", "#ffffff", "#980000", "#ff0000", "#ff9900", "#ffff00", "#00ff00", "#00ffff", "#4a86e8", "#0000ff", "#9900ff", "#ff00ff", "#e6b8af", "#f4cccc", "#fce5cd", "#fff2cc", "#d9ead3", "#d0e0e3", "#c9daf8", "#cfe2f3", "#d9d2e9", "#ead1dc" ]; const activeButtonBg = computed(() => { if (props.theme.activeButtonBg) { return props.theme.activeButtonBg; } const isDark = isColorDark(props.theme.headerBgColor); if (isDark) { return lightenColor(props.theme.headerBgColor, 20); } else { return darkenColor(props.theme.headerBgColor, 10); } }); const activeIconColor = computed(() => { if (props.theme.activeButtonFg) { return props.theme.activeButtonFg; } return "#2563eb"; }); const toolbarStyle = computed(() => ({ backgroundColor: props.theme.headerBgColor, color: props.theme.headerFgColor, borderBottom: `1px solid ${props.theme.edgeColor}` })); const buttonStyle = computed(() => ({ backgroundColor: "transparent", borderColor: props.theme.edgeColor, color: props.theme.headerFgColor, transition: "all 0.2s ease" })); const activeButtonStyle = computed(() => { return { backgroundColor: activeButtonBg.value, borderColor: props.theme.edgeColor, color: props.theme.headerFgColor, boxShadow: "0 1px 2px rgba(0, 0, 0, 0.1)" }; }); const selectStyle = computed(() => ({ backgroundColor: props.theme.contentBgColor, color: props.theme.contentFgColor, borderColor: props.theme.edgeColor })); const dropdownStyle = computed(() => ({ backgroundColor: props.theme.contentBgColor, color: props.theme.contentFgColor, borderColor: props.theme.edgeColor })); const inputStyle = computed(() => ({ backgroundColor: props.theme.contentBgColor, color: props.theme.contentFgColor, borderColor: props.theme.edgeColor })); const applyButtonStyle = computed(() => ({ backgroundColor: "#2563eb", color: "#ffffff" })); const isColorDark = (hexColor) => { const r = parseInt(hexColor.substring(1, 3), 16); const g = parseInt(hexColor.substring(3, 5), 16); const b = parseInt(hexColor.substring(5, 7), 16); const brightness = (r * 299 + g * 587 + b * 114) / 1e3; return brightness < 128; }; const lightenColor = (hexColor, amount) => { let r = parseInt(hexColor.substring(1, 3), 16); let g = parseInt(hexColor.substring(3, 5), 16); let b = parseInt(hexColor.substring(5, 7), 16); r = Math.min(255, r + amount); g = Math.min(255, g + amount); b = Math.min(255, b + amount); return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`; }; const darkenColor = (hexColor, amount) => { let r = parseInt(hexColor.substring(1, 3), 16); let g = parseInt(hexColor.substring(3, 5), 16); let b = parseInt(hexColor.substring(5, 7), 16); r = Math.max(0, r - amount); g = Math.max(0, g - amount); b = Math.max(0, b - amount); return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`; }; const handleClickOutside = (event) => { if (showColorPicker.value && textColorPickerRef.value && !textColorPickerRef.value.contains(event.target)) { showColorPicker.value = false; } if (showBgColorPicker.value && bgColorPickerRef.value && !bgColorPickerRef.value.contains(event.target)) { showBgColorPicker.value = false; } }; const toggleTextColorPicker = (event) => { event.stopPropagation(); showColorPicker.value = !showColorPicker.value; if (showColorPicker.value) { showBgColorPicker.value = false; } }; const toggleBgColorPicker = (event) => { event.stopPropagation(); showBgColorPicker.value = !showBgColorPicker.value; if (showBgColorPicker.value) { showColorPicker.value = false; } }; const executeCommand = (command, value = null) => { emit("execute-command", command, value); setTimeout(updateCommandStates, 10); }; const changeTextColor = (color) => { textColor.value = color; executeCommand("foreColor", color); showColorPicker.value = false; }; const applyTextColor = () => { executeCommand("foreColor", textColor.value); showColorPicker.value = false; }; const changeBackgroundColor = (color) => { bgColor.value = color; executeCommand("hiliteColor", color); showBgColorPicker.value = false; }; const applyBgColor = () => { executeCommand("hiliteColor", bgColor.value); showBgColorPicker.value = false; }; const changeFontSize = (size) => { const selection = window.getSelection(); if (selection.rangeCount > 0) { const range = selection.getRangeAt(0); if (!selection.isCollapsed) { const content = range.extractContents(); const span = document.createElement("span"); span.style.fontSize = `${size}px`; span.appendChild(content); range.insertNode(span); selection.removeAllRanges(); selection.addRange(range); emit("execute-command", "insertHTML", span.outerHTML); } else { emit("execute-command", "insertHTML", `<span style="font-size: ${size}px">&nbsp;</span>`); } updateCommandStates(); } }; return { commandStates, showColorPicker, showBgColorPicker, textColor, bgColor, colors, changeTextColor, applyTextColor, changeBackgroundColor, applyBgColor, changeFontSize, textColorPickerRef, bgColorPickerRef, toggleTextColorPicker, toggleBgColorPicker, toolbarStyle, buttonStyle, selectStyle, dropdownStyle, inputStyle, applyButtonStyle, activeButtonStyle, activeButtonBg, activeIconColor, executeCommand }; } }; const _hoisted_1$6 = { class: "relative", ref: "textColorPickerRef" }; const _hoisted_2$6 = { class: "mb-2" }; const _hoisted_3$6 = { class: "grid grid-cols-5 gap-1" }; const _hoisted_4$5 = ["onClick"]; const _hoisted_5$5 = { class: "mt-2 flex justify-end" }; const _hoisted_6$3 = { class: "relative", ref: "bgColorPickerRef" }; const _hoisted_7$2 = { class: "mb-2" }; const _hoisted_8$2 = { class: "grid grid-cols-5 gap-1" }; const _hoisted_9$2 = ["onClick"]; const _hoisted_10$1 = { class: "mt-2 flex justify-end" }; const _hoisted_11$1 = { key: 0, class: "flex items-center" }; const _hoisted_12$1 = { key: 1, class: "flex items-center" }; function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) { const _component_Bold = resolveComponent("Bold"); const _component_Italic = resolveComponent("Italic"); const _component_Underline = resolveComponent("Underline"); const _component_Strikethrough = resolveComponent("Strikethrough"); const _component_AlignLeft = resolveComponent("AlignLeft"); const _component_AlignCenter = resolveComponent("AlignCenter"); const _component_AlignRight = resolveComponent("AlignRight"); const _component_AlignJustify = resolveComponent("AlignJustify"); const _component_Outdent = resolveComponent("Outdent"); const _component_Indent = resolveComponent("Indent"); const _component_ImageIcon = resolveComponent("ImageIcon"); const _component_Table = resolveComponent("Table"); const _component_Settings = resolveComponent("Settings"); const _component_Paintbrush = resolveComponent("Paintbrush"); const _component_Link = resolveComponent("Link"); const _component_Undo = resolveComponent("Undo"); const _component_Redo = resolveComponent("Redo"); const _component_X = resolveComponent("X"); return openBlock(), createElementBlock("div", { class: "editor-toolbar flex flex-wrap gap-1 p-2", style: normalizeStyle($setup.toolbarStyle) }, [ createElementVNode("select", { class: "h-8 px-2 border rounded text-sm", style: normalizeStyle($setup.selectStyle), onChange: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("execute-command", "fontName", $event.target.value)) }, _cache[28] || (_cache[28] = [ createStaticVNode('<option value="" disabled selected data-v-f4d6928b>Font</option><option value="Arial" data-v-f4d6928b>Arial</option><option value="Helvetica" data-v-f4d6928b>Helvetica</option><option value="Times New Roman" data-v-f4d6928b>Times New Roman</option><option value="Courier New" data-v-f4d6928b>Courier New</option><option value="Georgia" data-v-f4d6928b>Georgia</option><option value="Verdana" data-v-f4d6928b>Verdana</option><option value="Impact" data-v-f4d6928b>Impact</option>', 8) ]), 36), createElementVNode("select", { class: "h-8 px-2 border rounded text-sm", style: normalizeStyle($setup.selectStyle), onChange: _cache[1] || (_cache[1] = ($event) => $setup.changeFontSize($event.target.value)) }, _cache[29] || (_cache[29] = [ createStaticVNode('<option value="" disabled selected data-v-f4d6928b>Size</option><option value="8" data-v-f4d6928b>8px</option><option value="10" data-v-f4d6928b>10px</option><option value="12" data-v-f4d6928b>12px</option><option value="14" data-v-f4d6928b>14px</option><option value="16" data-v-f4d6928b>16px</option><option value="18" data-v-f4d6928b>18px</option><option value="20" data-v-f4d6928b>20px</option><option value="24" data-v-f4d6928b>24px</option><option value="28" data-v-f4d6928b>28px</option><option value="32" data-v-f4d6928b>32px</option><option value="36" data-v-f4d6928b>36px</option><option value="48" data-v-f4d6928b>48px</option><option value="72" data-v-f4d6928b>72px</option>', 14) ]), 36), createElementVNode("div", _hoisted_1$6, [ createElementVNode("button", { class: "p-1 rounded flex items-center", style: normalizeStyle($setup.buttonStyle), onClick: _cache[2] || (_cache[2] = (...args) => $setup.toggleTextColorPicker && $setup.toggleTextColorPicker(...args)), title: "Text Color" }, [ createElementVNode("span", { class: "w-4 h-4 border rounded-sm", style: normalizeStyle({ backgroundColor: $setup.textColor, borderColor: $props.theme.edgeColor }) }, null, 4) ], 4), $setup.showColorPicker ? (openBlock(), createElementBlock("div", { key: 0, class: "absolute top-full left-0 mt-1 p-2 border rounded shadow-lg z-10 w-64", style: normalizeStyle($setup.dropdownStyle) }, [ createElementVNode("div", _hoisted_2$6, [ withDirectives(createElementVNode("input", { type: "text", "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => $setup.textColor = $event), class: "w-full px-2 py-1 border rounded text-sm", style: normalizeStyle($setup.inputStyle), placeholder: "#000000", onKeydown: _cache[4] || (_cache[4] = withKeys((...args) => $setup.applyTextColor && $setup.applyTextColor(...args), ["enter"])) }, null, 36), [ [vModelText, $setup.textColor] ]) ]), createElementVNode("div", _hoisted_3$6, [ (openBlock(true), createElementBlock(Fragment, null, renderList($setup.colors, (color) => { return openBlock(), createElementBlock("button", { key: color, class: "w-8 h-8 border rounded-sm hover:opacity-80 active:opacity-70", style: normalizeStyle({ backgroundColor: color, borderColor: $props.theme.edgeColor }), onClick: ($event) => $setup.changeTextColor(color) }, null, 12, _hoisted_4$5); }), 128)) ]), createElementVNode("div", _hoisted_5$5, [ createElementVNode("button", { class: "px-2 py-1 rounded text-sm hover:opacity-90 active:opacity-80", style: normalizeStyle($setup.applyButtonStyle), onClick: _cache[5] || (_cache[5] = (...args) => $setup.applyTextColor && $setup.applyTextColor(...args)) }, " Apply ", 4) ]) ], 4)) : createCommentVNode("", true) ], 512), createElementVNode("div", _hoisted_6$3, [ createElementVNode("button", { class: "p-1 rounded flex items-center", style: normalizeStyle($setup.buttonStyle), onClick: _cache[6] || (_cache[6] = (...args) => $setup.toggleBgColorPicker && $setup.toggleBgColorPicker(...args)), title: "Background Color" }, [ createElementVNode("span", { class: "w-4 h-4 border rounded-sm", style: normalizeStyle({ backgroundColor: $setup.bgColor, borderColor: $props.theme.edgeColor }) }, null, 4) ], 4), $setup.showBgColorPicker ? (openBlock(), createElementBlock("div", { key: 0, class: "absolute top-full left-0 mt-1 p-2 border rounded shadow-lg z-10 w-64", style: normalizeStyle($setup.dropdownStyle) }, [ createElementVNode("div", _hoisted_7$2, [ withDirectives(createElementVNode("input", { type: "text", "onUpdate:modelValue": _cache[7] || (_cache[7] = ($event) => $setup.bgColor = $event), class: "w-full px-2 py-1 border rounded text-sm", style: normalizeStyle($setup.inputStyle), placeholder: "#ffffff", onKeydown: _cache[8] || (_cache[8] = withKeys((...args) => $setup.applyBgColor && $setup.applyBgColor(...args), ["enter"])) }, null, 36), [ [vModelText, $setup.bgColor] ]) ]), createElementVNode("div", _hoisted_8$2, [ (openBlock(true), createElementBlock(Fragment, null, renderList($setup.colors, (color) => { return openBlock(), createElementBlock("button", { key: color, class: "w-8 h-8 border rounded-sm hover:opacity-80 active:opacity-70", style: normalizeStyle({ backgroundColor: color, borderColor: $props.theme.edgeColor }), onClick: ($event) => $setup.changeBackgroundColor(color) }, null, 12, _hoisted_9$2); }), 128)) ]), createElementVNode("div", _hoisted_10$1, [ createElementVNode("button", { class: "px-2 py-1 rounded text-sm hover:opacity-90 active:opacity-80", style: normalizeStyle($setup.applyButtonStyle), onClick: _cache[9] || (_cache[9] = (...args) => $setup.applyBgColor && $setup.applyBgColor(...args)) }, " Apply ", 4) ]) ], 4)) : createCommentVNode("", true) ], 512), createElementVNode("div", { class: "h-8 w-px mx-1", style: normalizeStyle({ backgroundColor: $props.theme.edgeColor }) }, null, 4), createElementVNode("button", { class: normalizeClass(["p-1 rounded", { "editor-button-active": $setup.commandStates.bold }]), style: normalizeStyle($setup.commandStates.bold ? $setup.activeButtonStyle : $setup.buttonStyle), onClick: _cache[10] || (_cache[10] = ($event) => $setup.executeCommand("bold")), title: "Bold" }, [ createVNode(_component_Bold, { class: "h-4 w-4", style: normalizeStyle({ color: $setup.commandStates.bold ? $setup.activeIconColor : $props.theme.headerFgColor }) }, null, 8, ["style"]) ], 6), createElementVNode("button", { class: normalizeClass(["p-1 rounded", { "editor-button-active": $setup.commandStates.italic }]), style: normalizeStyle($setup.commandStates.italic ? $setup.activeButtonStyle : $setup.buttonStyle), onClick: _cache[11] || (_cache[11] = ($event) => $setup.executeCommand("italic")), title: "Italic" }, [ createVNode(_component_Italic, { class: "h-4 w-4", style: normalizeStyle({ color: $setup.commandStates.italic ? $setup.activeIconColor : $props.theme.headerFgColor }) }, null, 8, ["style"]) ], 6), createElementVNode("button", { class: normalizeClass(["p-1 rounded", { "editor-button-active": $setup.commandStates.underline }]), style: normalizeStyle($setup.commandStates.underline ? $setup.activeButtonStyle : $setup.buttonStyle), onClick: _cache[12] || (_cache[12] = ($event) => $setup.executeCommand("underline")), title: "Underline" }, [ createVNode(_component_Underline, { class: "h-4 w-4", style: normalizeStyle({ color: $setup.commandStates.underline ? $setup.activeIconColor : $props.theme.headerFgColor }) }, null, 8, ["style"]) ], 6), createElementVNode("button", { class: normalizeClass(["p-1 rounded", { "editor-button-active": $setup.commandStates.strikeThrough }]), style: normalizeStyle($setup.commandStates.strikeThrough ? $setup.activeButtonStyle : $setup.buttonStyle), onClick: _cache[13] || (_cache[13] = ($event) => $setup.executeCommand("strikeThrough")), title: "Strike Through" }, [ createVNode(_component_Strikethrough, { class: "h-4 w-4", style: normalizeStyle({ color: $setup.commandStates.strikeThrough ? $setup.activeIconColor : $props.theme.headerFgColor }) }, null, 8, ["style"]) ], 6), createElementVNode("div", { class: "h-8 w-px mx-1", style: normalizeStyle({ backgroundColor: $props.theme.edgeColor }) }, null, 4), createElementVNode("button", { class: normalizeClass(["p-1 rounded", { "editor-button-active": $setup.commandStates.justifyLeft }]), style: normalizeStyle($setup.commandStates.justifyLeft ? $setup.activeButtonStyle : $setup.buttonStyle), onClick: _cache[14] || (_cache[14] = ($event) => $setup.executeCommand("justifyLeft")), title: "Align Left" }, [ createVNode(_component_AlignLeft, { class: "h-4 w-4", style: normalizeStyle({ color: $setup.commandStates.justifyLeft ? $setup.activeIconColor : $props.theme.headerFgColor }) }, null, 8, ["style"]) ], 6), createElementVNode("button", { class: normalizeClass(["p-1 rounded", { "editor-button-active": $setup.commandStates.justifyCenter }]), style: normalizeStyle($setup.commandStates.justifyCenter ? $setup.activeButtonStyle : $setup.buttonStyle), onClick: _cache[15] || (_cache[15] = ($event) => $setup.executeCommand("justifyCenter")), title: "Align Center" }, [ createVNode(_component_AlignCenter, { class: "h-4 w-4", style: normalizeStyle({ color: $setup.commandStates.justifyCenter ? $setup.activeIconColor : $props.theme.headerFgColor }) }, null, 8, ["style"]) ], 6), createElementVNode("button", { class: normalizeClass(["p-1 rounded", { "editor-button-active": $setup.commandStates.justifyRight }]), style: normalizeStyle($setup.commandStates.justifyRight ? $setup.activeButtonStyle : $setup.buttonStyle), onClick: _cache[16] || (_cache[16] = ($event) => $setup.executeCommand("justifyRight")), title: "Align Right" }, [ createVNode(_component_AlignRight, { class: "h-4 w-4", style: normalizeStyle({ color: $setup.commandStates.justifyRight ? $setup.activeIconColor : $props.theme.headerFgColor }) }, null, 8, ["style"]) ], 6), createElementVNode("button", { class: normalizeClass(["p-1 rounded", { "editor-button-active": $setup.commandStates.justifyFull }]), style: normalizeStyle($setup.commandStates.justifyFull ? $setup.activeButtonStyle : $setup.buttonStyle), onClick: _cache[17] || (_cache[17] = ($event) => $setup.executeCommand("justifyFull")), title: "Justify" }, [ createVNode(_component_AlignJustify, { class: "h-4 w-4", style: normalizeStyle({ color: $setup.commandStates.justifyFull ? $setup.activeIconColor : $props.theme.headerFgColor }) }, null, 8, ["style"]) ], 6), createElementVNode("div", { class: "h-8 w-px mx-1", style: normalizeStyle({ backgroundColor: $props.theme.edgeColor }) }, null, 4), createElementVNode("button", { class: "p-1 rounded", style: normalizeStyle($setup.buttonStyle), onClick: _cache[18] || (_cache[18] = ($event) => $setup.executeCommand("outdent")), title: "Decrease Indent" }, [ createVNode(_component_Outdent, { class: "h-4 w-4", style: normalizeStyle({ color: $props.theme.headerFgColor }) }, null, 8, ["style"]) ], 4), createElementVNode("button", { class: "p-1 rounded", style: normalizeStyle($setup.buttonStyle), onClick: _cache[19] || (_cache[19] = ($event) => $setup.executeCommand("indent")), title: "Increase Indent" }, [ createVNode(_component_Indent, { class: "h-4 w-4", style: normalizeStyle({ color: $props.theme.headerFgColor }) }, null, 8, ["style"]) ], 4), createElementVNode("div", { class: "h-8 w-px mx-1", style: normalizeStyle({ backgroundColor: $props.theme.edgeColor }) }, null, 4), createElementVNode("button", { class: "p-1 rounded", style: normalizeStyle($setup.buttonStyle), onClick: _cache[20] || (_cache[20] = ($event) => _ctx.$emit("insert-image")), title: "Insert Image" }, [ createVNode(_component_ImageIcon, { class: "h-4 w-4", style: normalizeStyle({ color: $props.theme.headerFgColor }) }, null, 8, ["style"]) ], 4), createElementVNode("button", { class: "p-1 rounded", style: normalizeStyle($setup.buttonStyle), onClick: _cache[21] || (_cache[21] = ($event) => _ctx.$emit("insert-table")), title: "Insert Table" }, [ createVNode(_component_Table, { class: "h-4 w-4", style: normalizeStyle({ color: $props.theme.headerFgColor }) }, null, 8, ["style"]) ], 4), $props.selectedElement && $props.selectedElement.tagName === "TABLE" ? (openBlock(), createElementBlock("div", _hoisted_11$1, [ createElementVNode("button", { class: "p-1 rounded", style: normalizeStyle($setup.buttonStyle), onClick: _cache[22] || (_cache[22] = ($event) => _ctx.$emit("edit-table")), title: "Edit Table" }, [ createVNode(_component_Settings, { class: "h-4 w-4", style: normalizeStyle({ color: $props.theme.headerFgColor }) }, null, 8, ["style"]) ], 4) ])) : createCommentVNode("", true), $props.selectedCell && ($props.selectedCell.tagName === "TD" || $props.selectedCell.tagName === "TH") ? (openBlock(), createElementBlock("div", _hoisted_12$1, [ createElementVNode("button", { class: "p-1 rounded", style: normalizeStyle($setup.buttonStyle), onClick: _cache[23] || (_cache[23] = ($event) => _ctx.$emit("cell-color")), title: "Cell Background Color" }, [ createVNode(_component_Paintbrush, { class: "h-4 w-4", style: normalizeStyle({ color: $props.theme.headerFgColor }) }, null, 8, ["style"]) ], 4) ])) : createCommentVNode("", true), createElementVNode("button", { class: "p-1 rounded", style: normalizeStyle($setup.buttonStyle), onClick: _cache[24] || (_cache[24] = ($event) => _ctx.$emit("insert-link")), title: "Insert Link" }, [ createVNode(_component_Link, { class: "h-4 w-4", style: normalizeStyle({ color: $props.theme.headerFgColor }) }, null, 8, ["style"]) ], 4), createElementVNode("div", { class: "h-8 w-px mx-1", style: normalizeStyle({ backgroundColor: $props.theme.edgeColor }) }, null, 4), createElementVNode("button", { class: "p-1 rounded", style: normalizeStyle($setup.buttonStyle), onClick: _cache[25] || (_cache[25] = ($event) => $setup.executeCommand("undo")), title: "Undo" }, [ createVNode(_component_Undo, { class: "h-4 w-4", style: normalizeStyle({ color: $props.theme.headerFgColor }) }, null, 8, ["style"]) ], 4), createElementVNode("button", { class: "p-1 rounded", style: normalizeStyle($setup.buttonStyle), onClick: _cache[26] || (_cache[26] = ($event) => $setup.executeCommand("redo")), title: "Redo" }, [ createVNode(_component_Redo, { class: "h-4 w-4", style: normalizeStyle({ color: $props.theme.headerFgColor }) }, null, 8, ["style"]) ], 4), createElementVNode("div", { class: "h-8 w-px mx-1", style: normalizeStyle({ backgroundColor: $props.theme.edgeColor }) }, null, 4), createElementVNode("button", { class: "p-1 rounded", style: normalizeStyle($setup.buttonStyle), onClick: _cache[27] || (_cache[27] = ($event) => $setup.executeCommand("removeFormat")), title: "Clear Formatting" }, [ createVNode(_component_X, { class: "h-4 w-4", style: normalizeStyle({ color: $props.theme.headerFgColor }) }, null, 8, ["style"]) ], 4) ], 4); } const EditorToolbar = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["render", _sfc_render$6], ["__scopeId", "data-v-f4d6928b"]]); const _sfc_main$5 = { props: { theme: { type: Object, default: () => ({ headerBgColor: "#f3f4f6", headerFgColor: "#111827", contentBgColor: "#ffffff", contentFgColor: "#111827", edgeColor: "#d1d5db" }) } }, emits: ["close", "insert"], setup(props, { emit }) { const imageUrl = ref(""); const dialogStyle = computed(() => ({ backgroundColor: props.theme.contentBgColor, color: props.theme.contentFgColor, border: `1px solid ${props.theme.edgeColor}`, fontFamily: "inherit" })); const headerStyle = computed(() => ({ backgroundColor: props.theme.headerBgColor, color: props.theme.headerFgColor, padding: "8px", margin: "-24px -24px 16px -24px", borderTopLeftRadius: "0.5rem", borderTopRightRadius: "0.5rem", borderBottom: `1px solid ${props.theme.edgeColor}` })); const inputStyle = computed(() => ({ backgroundColor: props.theme.contentBgColor, color: props.theme.contentFgColor, borderColor: props.theme.edgeColor })); const cancelButtonStyle = computed(() => ({ backgroundColor: "#e5e7eb", color: "#111827" })); const confirmButtonStyle = computed(() => ({ backgroundColor: "#2563eb", color: "#ffffff" })); const insertImage = () => { if (imageUrl.value) { emit("insert", imageUrl.value); } }; return { imageUrl, insertImage, dialogStyle, headerStyle, inputStyle, cancelButtonStyle, confirmButtonStyle }; } }; const _hoisted_1$5 = { class: "mb-4" }; const _hoisted_2$5 = { class: "flex justify-end space-x-2" }; const _hoisted_3$5 = ["disabled"]; function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) { return openBlock(), createElementBlock("div", { class: "rounded-lg p-6 w-full max-w-md shadow-lg", style: normalizeStyle($setup.dialogStyle) }, [ createElementVNode("h3", { class: "text-lg font-medium mb-4", style: normalizeStyle($setup.headerStyle) }, "Insert Image", 4), createElementVNode("div", _hoisted_1$5, [ createElementVNode("label", { class: "block text-sm font-medium mb-1", style: normalizeStyle({ color: $props.theme.contentFgColor }) }, "Image URL:", 4), withDirectives(createElementVNode("input", { type: "text", "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $setup.imageUrl = $event), class: "w-full px-3 py-2 border rounded-md", style: normalizeStyle($setup.inputStyle), placeholder: "https://example.com/image.jpg", onKeydown: _cache[1] || (_cache[1] = withKeys((...args) => $setup.insertImage && $setup.insertImage(...args), ["enter"])) }, null, 36), [ [vModelText, $setup.imageUrl] ]) ]), createElementVNode("div", _hoisted_2$5, [ createElementVNode("button", { class: "px-4 py-2 rounded hover:opacity-90 active:opacity-80", style: normalizeStyle($setup.cancelButtonStyle), onClick: _cache[2] || (_cache[2] = ($event) => _ctx.$emit("close")) }, " Cancel ", 4), createElementVNode("button", { class: "px-4 py-2 rounded hover:opacity-90 active:opacity-80", style: normalizeStyle($setup.confirmButtonStyle), onClick: _cache[3] || (_cache[3] = (...args) => $setup.insertImage && $setup.insertImage(...args)), disabled: !$setup.imageUrl }, " Insert ", 12, _hoisted_3$5) ]) ], 4); } const ImageDialog = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["render", _sfc_render$5], ["__scopeId", "data-v-b6c5bd51"]]); const _sfc_main$4 = { props: { theme: { type: Object, default: () => ({ headerBgColor: "#f3f4f6", headerFgColor: "#111827", contentBgColor: "#ffffff", contentFgColor: "#111827", edgeColor: "#d1d5db" }) } }, emits: ["close", "insert"], setup(props, { emit }) { const rows = ref(3); const cols = ref(3); const cellWidth = ref("100px"); const cellHeight = ref("40px"); const borderWidth = ref("1px"); const borderColor = ref("#dddddd"); const cellPadding = ref("8px"); const includeHeader = ref(false); const dialogStyle = computed(() => ({ backgroundColor: props.theme.contentBgColor, color: props.theme.contentFgColor, border: `1px solid ${props.theme.edgeColor}`, fontFamily: "inherit" })); const headerStyle = computed(() => ({ backgroundColor: props.theme.headerBgColor, color: props.theme.headerFgColor, padding: "8px", margin: "-24px -24px 16px -24px", borderTopLeftRadius: "0.5rem", borderTopRightRadius: "0.5rem", borderBottom: `1px solid ${props.theme.edgeColor}` })); const inputStyle = computed(() => ({ backgroundColor: props.theme.contentBgColor, color: props.theme.contentFgColor, borderColor: props.theme.edgeColor })); const cancelButtonStyle = computed(() => ({ backgroundColor: "#e5e7eb", color: "#111827" })); const confirmButtonStyle = computed(() => ({ backgroundColor: "#2563eb", color: "#ffffff" })); const insertTable = () => { const options = { cellWidth: cellWidth.value, cellHeight: cellHeight.value, borderWidth: borderWidth.value, borderColor: borderColor.value, cellPadding: cellPadding.value, includeHeader: includeHeader.value }; emit("insert", rows.value, cols.value, options); }; return { rows, cols, cellWidth, cellHeight, borderWidth, borderColor, cellPadding, includeHeader, insertTable, dialogStyle, headerStyle, inputStyle, cancelButtonStyle, confirmButtonStyle }; } }; const _hoisted_1$4 = { class: "grid grid-cols-2 gap-4 mb-4" }; const _hoisted_2$4 = { class: "mb-4" }; const _hoisted_3$4 = { class: "mb-4" }; const _hoisted_4$4 = { class: "grid grid-cols-2 gap-4 mb-4" }; const _hoisted_5$4 = { class: "mb-4" }; const _hoisted_6$2 = { class: "relative" }; const _hoisted_7$1 = { class: "mb-4" }; const _hoisted_8$1 = { class: "flex items-center" }; const _hoisted_9$1 = { class: "flex justify-end space-x-2" }; function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) { return openBlock(), createElementBlock("div", { class: "rounded-lg p-6 w-full max-w-md shadow-lg", style: normalizeStyle($setup.dialogStyle) }, [ createElementVNode("h3", { class: "text-lg font-medium mb-4", style: normalizeStyle($setup.headerStyle) }, "Insert Table", 4), createElementVNode("div", _hoisted_1$4, [ createElementVNode("div", null, [ createElementVNode("label", { class: "block text-sm font-medium mb-1", style: normalizeStyle({ color: $props.theme.contentFgColor }) }, "Rows:", 4), withDirectives(createElementVNode("input", { type: "number", "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $setup.rows = $event), min: "1", max: "20", class: "w-full px-3 py-2 border rounded-md", style: normalizeStyle($setup.inputStyle) }, null, 4), [ [ vModelText, $setup.rows, void 0, { number: true } ] ]) ]), createElementVNode("div", null, [ createElementVNode("label", { class: "block text-sm font-medium mb-1", style: normalizeStyle({ color: $props.theme.contentFgColor }) }, "Columns:", 4), withDirectives(createElementVNode("input", { type: "number", "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => $setup.cols = $event), min: "1", max: "10", class: "w-full px-3 py-2 border rounded-md", style: normalizeStyle($setup.inputStyle) }, null, 4), [ [ vModelText, $setup.cols, void 0, { number: true } ] ]) ]) ]), createElementVNode("div", _hoisted_2$4, [ createElementVNode("label", { class: "block text-sm font-medium mb-1", style: normalizeStyle({ color: $props.theme.contentFgColor }) }, "Cell Width:", 4), withDirectives(createElementVNode("input", { type: "text", "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => $setup.cellWidth = $event), class: "w-full px-3 py-2 border rounded-md", style: normalizeStyle($setup.inputStyle), placeholder: "e.g., 100px" }, null, 4), [ [vModelText, $setup.cellWidth] ]) ]), createElementVNode("div", _hoisted_3$4, [ createElementVNode("label", { class: "block text-sm font-medium mb-1", style: normalizeStyle({ color: $props.theme.contentFgColor }) }, "Cell Height:", 4), withDirectives(createElementVNode("input", { type: "text", "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => $setup.cellHeight = $event), class: "w-full px-3 py-2 border rounded-md", style: normalizeStyle($setup.inputStyle), placeholder: "e.g., 40px" }, null, 4), [ [vModelText, $setup.cellHeight] ]) ]), createElementVNode("div", _hoisted_4$4, [ createElementVNode("div", null, [ createElementVNode("label", { class: "block text-sm font-medium mb-1", style: normalizeStyle({ color: $props.theme.contentFgColor }) }, "Border Width:", 4), withDirectives(createElementVNode("input"