import React, { MutableRefObject } from "react"; import { twMerge } from "tailwind-merge"; export type AceEditorComponentType = { editorRef?: MutableRefObject; readOnly?: boolean; /** Function to call when Ctrl+Enter is pressed */ ctrlEnterFn?: (editor: AceAjax.Editor) => void; content?: string; placeholder?: string; mode?: any; fontSize?: string; previewMode?: boolean; onChange?: (value: string) => void; delay?: number; }; let timeout: any; /** * # Powerful Ace Editor * @note **NOTE** head scripts required * @script `https://cdnjs.cloudflare.com/ajax/libs/ace/1.22.0/ace.min.js` * @script `https://cdnjs.cloudflare.com/ajax/libs/ace/1.22.0/ext-language_tools.min.js` */ export default function AceEditor({ editorRef, readOnly, ctrlEnterFn, content = "", placeholder, mode, fontSize, previewMode, onChange, delay = 500, }: AceEditorComponentType) { try { const editorElementRef = React.useRef(); const editorRefInstance = React.useRef(); const [refresh, setRefresh] = React.useState(0); const [darkMode, setDarkMode] = React.useState(false); const [ready, setReady] = React.useState(false); React.useEffect(() => { if (!ready) return; if (!ace?.edit || !editorElementRef.current) { setTimeout(() => { setRefresh((prev) => prev + 1); }, 1000); return; } const editor = ace.edit(editorElementRef.current); editor.setOptions({ mode: `ace/mode/${mode ? mode : "javascript"}`, theme: darkMode ? "ace/theme/tomorrow_night_bright" : "ace/theme/ace_light", value: content, placeholder: placeholder ? placeholder : "", enableBasicAutocompletion: true, enableLiveAutocompletion: true, readOnly: readOnly ? true : false, fontSize: fontSize ? fontSize : null, showLineNumbers: previewMode ? false : true, wrap: true, wrapMethod: "code", // onchange: (e) => { // console.log(e); // }, }); editor.commands.addCommand({ name: "myCommand", bindKey: { win: "Ctrl-Enter", mac: "Command-Enter" }, exec: function (editor) { if (ctrlEnterFn) ctrlEnterFn(editor); }, readOnly: true, }); editor.getSession().on("change", function (e) { if (onChange) { clearTimeout(timeout); setTimeout(() => { onChange(editor.getValue()); console.log(editor.getValue()); }, delay); } }); editorRefInstance.current = editor; if (editorRef) editorRef.current = editor; }, [refresh, darkMode, ready]); React.useEffect(() => { const htmlClassName = document.documentElement.className; if (htmlClassName.match(/dark/i)) setDarkMode(true); setTimeout(() => { setReady(true); }, 200); }, []); return (
); } catch (error: any) { return ( Editor Error:{" "} {error.message} ); } }