@churchapps/apphelper-markdown
Version:
ChurchApps markdown/lexical editor components
71 lines (70 loc) • 4.29 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useState, useEffect } from "react";
import { Dialog, DialogTitle, DialogContent, DialogActions, Button, IconButton, Box, Tabs, Tab, TextField } from "@mui/material";
import { Close, Visibility, Edit, Code } from "@mui/icons-material";
import { HtmlEditor } from "./HtmlEditor";
export function HtmlModal({ open, onClose, title = "HTML Editor", value = "", onChange, onSave, saveButtonText = "Save", maxWidth = "lg", fullWidth = true }) {
const [currentValue, setCurrentValue] = useState(value);
const [htmlSourceValue, setHtmlSourceValue] = useState(value);
const [activeTab, setActiveTab] = useState(0);
// Sync currentValue with prop value when modal opens or value changes
useEffect(() => {
if (open) {
setCurrentValue(value);
setHtmlSourceValue(value);
}
}, [open, value]);
const handleChange = (html) => {
setCurrentValue(html);
setHtmlSourceValue(html);
if (onChange) {
onChange(html);
}
};
const handleHtmlSourceChange = (event) => {
const newHtml = event.target.value;
setHtmlSourceValue(newHtml);
setCurrentValue(newHtml);
if (onChange) {
onChange(newHtml);
}
};
const handleTabChange = (_, newValue) => {
setActiveTab(newValue);
// Sync HTML source when switching to HTML tab
if (newValue === 2) {
setHtmlSourceValue(currentValue);
}
};
const handleSave = () => {
if (onSave) {
onSave(currentValue);
}
onClose();
};
const handleClose = () => {
setCurrentValue(value);
setHtmlSourceValue(value);
onClose();
};
return (_jsxs(Dialog, { open: open, onClose: handleClose, maxWidth: maxWidth, fullWidth: fullWidth, PaperProps: { sx: { height: "80vh" } }, children: [_jsxs(DialogTitle, { sx: { display: "flex", justifyContent: "space-between", alignItems: "center", pb: 1 }, children: [title, _jsx(IconButton, { onClick: handleClose, size: "small", children: _jsx(Close, {}) })] }), _jsxs(DialogContent, { sx: { p: 0 }, children: [_jsxs(Tabs, { value: activeTab, onChange: handleTabChange, sx: { borderBottom: 1, borderColor: "divider", px: 2 }, children: [_jsx(Tab, { icon: _jsx(Edit, {}), label: "Edit" }), _jsx(Tab, { icon: _jsx(Visibility, {}), label: "Preview" }), _jsx(Tab, { icon: _jsx(Code, {}), label: "HTML Source" })] }), _jsx(Box, { sx: { height: "calc(100% - 48px)", overflow: "hidden" }, children: activeTab === 0 ? (_jsx(HtmlEditor, { value: currentValue, onChange: handleChange, style: { height: "100%", border: "none" }, placeholder: "Start typing your HTML content..." })) : activeTab === 1 ? (_jsx(Box, { sx: { p: 2, height: "100%", overflow: "auto" }, dangerouslySetInnerHTML: { __html: currentValue } })) : (_jsx(TextField, { multiline: true, fullWidth: true, value: htmlSourceValue, onChange: handleHtmlSourceChange, placeholder: "Enter HTML code...", sx: {
height: "100%",
"& .MuiInputBase-root": {
height: "100%",
alignItems: "flex-start",
fontFamily: 'Monaco, Consolas, "Courier New", monospace',
fontSize: "14px",
bgcolor: "#f5f5f5"
},
"& .MuiInputBase-input": {
height: "100% !important",
overflow: "auto !important",
padding: 2
}
}, InputProps: {
sx: {
fontFamily: 'Monaco, Consolas, "Courier New", monospace',
fontSize: "14px"
}
} })) })] }), _jsxs(DialogActions, { children: [_jsx(Button, { onClick: handleClose, children: "Cancel" }), _jsx(Button, { onClick: handleSave, variant: "contained", children: saveButtonText })] })] }));
}