@uiw/react-codemirror
Version:
CodeMirror component for React.
135 lines (123 loc) • 3.44 kB
JavaScript
import { useEffect, useState } from 'react';
import { basicSetup as defaultBasicSetup } from '@codemirror/basic-setup';
import { EditorState, StateEffect } from '@codemirror/state';
import { indentWithTab as defaultIndentWithTab } from '@codemirror/commands';
import { EditorView, keymap, placeholder as extendPlaceholder } from '@codemirror/view';
import { oneDarkTheme } from '@codemirror/theme-one-dark';
import { defaultLightThemeOption } from './theme/light';
export function useCodeMirror(props) {
var {
value,
selection,
onChange,
onUpdate,
extensions = [],
autoFocus,
theme = 'light',
height = '',
minHeight = '',
maxHeight = '',
placeholder = '',
width = '',
minWidth = '',
maxWidth = '',
editable = true,
indentWithTab = true,
basicSetup = true
} = props;
var [container, setContainer] = useState(props.container);
var [view, setView] = useState();
var [state, setState] = useState();
var defaultThemeOption = EditorView.theme({
'&': {
height,
minHeight,
maxHeight,
width,
minWidth,
maxWidth
}
});
var updateListener = EditorView.updateListener.of(vu => {
if (vu.docChanged && typeof onChange === 'function') {
var doc = vu.state.doc;
var _value = doc.toString();
onChange(_value, vu);
}
});
var getExtensions = [updateListener, defaultThemeOption];
if (indentWithTab) {
getExtensions.unshift(keymap.of([defaultIndentWithTab]));
}
if (basicSetup) {
getExtensions.unshift(defaultBasicSetup);
}
if (placeholder) {
getExtensions.unshift(extendPlaceholder(placeholder));
}
theme === 'light' ? getExtensions.push(defaultLightThemeOption) : getExtensions.push(oneDarkTheme);
if (editable === false) {
getExtensions.push(EditorView.editable.of(false));
}
if (onUpdate && typeof onUpdate === 'function') {
getExtensions.push(EditorView.updateListener.of(onUpdate));
}
getExtensions = getExtensions.concat(extensions);
useEffect(() => {
if (container && !state) {
var stateCurrent = EditorState.create({
doc: value,
selection,
extensions: getExtensions
});
setState(stateCurrent);
if (!view) {
var viewCurrent = new EditorView({
state: stateCurrent,
parent: container
});
setView(viewCurrent);
}
} // eslint-disable-next-line react-hooks/exhaustive-deps
}, [container, state]);
useEffect(() => {
return () => {
if (view) {
view.destroy();
}
};
}, [view]);
useEffect(() => {
if (view) {
var currentValue = view.state.doc.toString();
view.dispatch({
changes: {
from: 0,
to: currentValue.length,
insert: value || ''
}
});
}
}, [value, view]);
useEffect(() => {
if (view) {
view.dispatch({
effects: StateEffect.reconfigure.of(getExtensions)
});
} // eslint-disable-next-line react-hooks/exhaustive-deps
}, [theme, extensions, placeholder, height, minHeight, maxHeight, width, minWidth, maxWidth, editable, indentWithTab, basicSetup]);
useEffect(() => {
if (autoFocus && view) {
view.focus();
}
}, [autoFocus, view]);
return {
state,
setState,
view,
setView,
container,
setContainer
};
}
//# sourceMappingURL=useCodeMirror.js.map