ConceptPortal-public/rsconcept/frontend/src/components/RSInput/index.tsx

117 lines
3.4 KiB
TypeScript
Raw Normal View History

import { bracketMatching } from '@codemirror/language';
2023-08-10 18:35:49 +03:00
import { Extension } from '@codemirror/state';
2023-08-13 00:57:31 +03:00
import { tags as t } from '@lezer/highlight';
2023-08-10 18:35:49 +03:00
import { createTheme } from '@uiw/codemirror-themes';
import CodeMirror, { BasicSetupOptions, ReactCodeMirrorProps, ReactCodeMirrorRef } from '@uiw/react-codemirror';
2023-08-10 18:35:49 +03:00
import { EditorView } from 'codemirror';
import { Ref, useMemo } from 'react';
2023-08-10 18:35:49 +03:00
2023-08-12 20:52:11 +03:00
import { useConceptTheme } from '../../context/ThemeContext';
2023-08-13 00:57:31 +03:00
import { RSLanguage } from './rslang';
2023-08-10 18:35:49 +03:00
const editorSetup: BasicSetupOptions = {
highlightSpecialChars: true,
history: true,
drawSelection: true,
syntaxHighlighting: true,
defaultKeymap: true,
historyKeymap: true,
lineNumbers: false,
highlightActiveLineGutter: false,
foldGutter: false,
dropCursor: false,
allowMultipleSelections: false,
indentOnInput: false,
bracketMatching: false,
2023-08-10 18:35:49 +03:00
closeBrackets: false,
autocompletion: false,
rectangularSelection: false,
crosshairCursor: false,
highlightActiveLine: false,
highlightSelectionMatches: false,
closeBracketsKeymap: false,
searchKeymap: false,
foldKeymap: false,
completionKeymap: false,
lintKeymap: false
};
2023-08-11 10:54:53 +03:00
const editorExtensions = [
EditorView.lineWrapping,
2023-08-13 00:57:31 +03:00
RSLanguage,
bracketMatching()
2023-08-11 10:54:53 +03:00
];
interface RSInputProps
extends Omit<ReactCodeMirrorProps, 'onChange'> {
innerref?: Ref<ReactCodeMirrorRef> | undefined
2023-08-11 10:54:53 +03:00
onChange: (newValue: string) => void
onKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => void
2023-08-11 10:54:53 +03:00
}
function RSInput({
innerref, onChange, editable,
2023-08-11 10:54:53 +03:00
...props
}: RSInputProps) {
2023-08-10 18:35:49 +03:00
const { darkMode } = useConceptTheme();
const cursor = useMemo(() => editable ? 'cursor-text': 'cursor-default', [editable]);
const lightTheme: Extension = useMemo(
() => createTheme({
theme: 'light',
settings: {
fontFamily: 'inherit',
background: editable ? '#ffffff' : '#f0f2f7',
foreground: '#000000',
2023-08-13 00:57:31 +03:00
selection: '#aacef2',
caret: '#5d00ff',
},
styles: [
2023-08-13 00:57:31 +03:00
{ tag: t.name, class: 'text-[#b266ff]' }, // GlobalID
{ tag: t.variableName, class: 'text-[#24821a]' }, // LocalID
{ tag: t.propertyName, class: '' }, // Radical
{ tag: t.keyword, class: 'text-[#001aff]' }, // keywords
{ tag: t.controlKeyword, class: 'font-semibold'}, // R | I | D
{ tag: t.unit, class: 'text-[0.75rem]' }, // indicies
]
}), [editable]);
const darkTheme: Extension = useMemo(
() => createTheme({
theme: 'dark',
settings: {
fontFamily: 'inherit',
background: editable ? '#070b12' : '#374151',
foreground: '#e4e4e7',
2023-08-13 00:57:31 +03:00
selection: '#8c6000',
caret: '#ffaa00'
},
styles: [
2023-08-13 00:57:31 +03:00
{ tag: t.name, class: 'text-[#dfbfff]' }, // GlobalID
{ tag: t.variableName, class: 'text-[#69bf60]' }, // LocalID
{ tag: t.propertyName, class: '' }, // Radical
{ tag: t.keyword, class: 'text-[#808dff]' }, // keywords
{ tag: t.controlKeyword, class: 'font-semibold'}, // R | I | D
{ tag: t.unit, class: 'text-[0.75rem]' }, // indicies
]
}), [editable]);
2023-08-10 18:35:49 +03:00
return (
2023-08-13 01:10:46 +03:00
<div className={`w-full ${cursor} text-lg`}>
2023-08-10 18:35:49 +03:00
<CodeMirror
ref={innerref}
2023-08-10 18:35:49 +03:00
basicSetup={editorSetup}
2023-08-11 10:54:53 +03:00
extensions={editorExtensions}
2023-08-10 18:35:49 +03:00
indentWithTab={false}
theme={darkMode ? darkTheme : lightTheme}
onChange={value => onChange(value)}
editable={editable}
2023-08-11 10:54:53 +03:00
{...props}
2023-08-10 18:35:49 +03:00
/>
</div>
);
}
export default RSInput;