import React, { useEffect, useMemo, useState } from 'react';
import { useSpring, config, animated } from 'react-spring';
import OverlayTrigger from 'react-bootstrap/OverlayTrigger';
import Tooltip from 'react-bootstrap/Tooltip';
import CodeMirror from '@uiw/react-codemirror';
import 'codemirror/mode/handlebars/handlebars';
import 'codemirror/mode/javascript/javascript';
import 'codemirror/mode/sql/sql';
import 'codemirror/addon/hint/show-hint';
import 'codemirror/addon/display/placeholder';
import 'codemirror/addon/search/match-highlighter';
import 'codemirror/addon/hint/show-hint.css';
import 'codemirror/theme/base16-light.css';
import 'codemirror/theme/duotone-light.css';
import 'codemirror/theme/monokai.css';
import { getSuggestionKeys, onBeforeChange, handleChange } from './utils';
import { resolveReferences } from '@/_helpers/utils';
import useHeight from '@/_hooks/use-height-transition';
import usePortal from '@/_hooks/use-portal';
export function CodeHinter({
initialValue,
onChange,
currentState,
mode,
theme,
lineNumbers,
placeholder,
ignoreBraces,
enablePreview,
height,
minHeight,
lineWrapping,
componentName = null,
usePortalEditor = true,
className = 'code-hinter',
}) {
const darkMode = localStorage.getItem('darkMode') === 'true';
const options = {
lineNumbers: lineNumbers ?? false,
lineWrapping: lineWrapping ?? true,
singleLine: true,
mode: mode || 'handlebars',
tabSize: 2,
theme: theme || 'default',
readOnly: false,
highlightSelectionMatches: true,
placeholder,
};
const [realState, setRealState] = useState(currentState);
const [currentValue, setCurrentValue] = useState(initialValue);
const [isFocused, setFocused] = useState(false);
const [heightRef, currentHeight] = useHeight();
const slideInStyles = useSpring({
config: { ...config.stiff },
from: { opacity: 0, height: 0 },
to: {
opacity: isFocused ? 1 : 0,
height: isFocused ? currentHeight : 0,
},
});
useEffect(() => {
setRealState(currentState);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [currentState.components]);
let suggestions = useMemo(() => {
return getSuggestionKeys(realState);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [realState.components, realState.queries]);
function valueChanged(editor, onChange, suggestions, ignoreBraces) {
handleChange(editor, onChange, suggestions, ignoreBraces);
setCurrentValue(editor.getValue());
}
const getPreviewContent = (content, type) => {
switch (type) {
case 'object':
return JSON.stringify(content);
case 'boolean':
return content.toString();
default:
return content;
}
};
const getPreview = () => {
const [preview, error] = resolveReferences(currentValue, realState, null, {}, true);
const themeCls = darkMode ? 'bg-dark py-1' : 'bg-light py-1';
if (error) {
return (