UNPKG

@coveord/plasma-mantine

Version:

A Plasma flavoured Mantine theme

190 lines (189 loc) 6.52 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { Box, Center, Group, Input, Loader, Space, Stack, px, useMantineColorScheme, useMantineTheme, useProps } from '@mantine/core'; import { useUncontrolled } from '@mantine/hooks'; import Editor, { loader } from '@monaco-editor/react'; import { MarkerSeverity } from 'monaco-editor'; import { useEffect, useRef, useState } from 'react'; import cx from 'clsx'; import { useParentHeight } from '../../hooks'; import { CopyToClipboard } from '../copyToClipboard'; import CodeEditorClasses from './CodeEditor.module.css'; import { XML } from './languages/xml'; import { Search } from './search'; const defaultProps = { language: 'plaintext', monacoLoader: 'local', defaultValue: '', minHeight: 300 }; export const CodeEditor = (props)=>{ const { language, defaultValue, onChange, onCopy, onSearch, onFocus, value, label, required, labelProps, error, errorProps, description, descriptionProps, minHeight, maxHeight, disabled, monacoLoader, options: { tabSize } = { tabSize: 2 }, editorHandle, ...others } = useProps('CodeEditor', defaultProps, props); const [loaded, setLoaded] = useState(false); const [_value, handleChange] = useUncontrolled({ value, defaultValue, onChange, finalValue: '' }); const [parentHeight, ref] = useParentHeight(); const editorRef = useRef(null); const loadLocalMonaco = async ()=>{ const monacoInstance = await import('monaco-editor'); loader.config({ monaco: monacoInstance }); setLoaded(true); }; const registerLanguages = (monaco)=>{ if (monaco && language === 'xml') { XML.register(monaco); } }; const registerThemes = (monaco)=>{ monaco.editor.defineTheme('light-disabled', { base: 'vs', inherit: true, rules: [], colors: { 'editor.background': theme.colors.gray[2] } }); monaco.editor.defineTheme('vs-dark-disabled', { base: 'vs-dark', inherit: true, rules: [], colors: { 'editor.background': theme.colors.navy[7] } }); }; const handleSearch = ()=>{ if (editorRef.current) { editorRef.current.focus(); editorRef.current.trigger('editor', 'actions.find', ''); onSearch?.(); } }; const [hasMonacoError, setHasMonacoError] = useState(false); const hasMonacoErrorRef = useRef(false); hasMonacoErrorRef.current = hasMonacoError; const renderErrorOutline = !!error || hasMonacoError; const theme = useMantineTheme(); const { colorScheme } = useMantineColorScheme(); useEffect(()=>{ if (monacoLoader === 'local') { loadLocalMonaco(); } else { setLoaded(true); } }, []); const handleValidate = (markers)=>{ setHasMonacoError(markers.some((marker)=>marker.severity === MarkerSeverity.Error)); }; const _label = label ? /*#__PURE__*/ _jsx(Input.Label, { required: required, ...labelProps, children: label }) : null; const _description = description ? /*#__PURE__*/ _jsx(Input.Description, { ...descriptionProps, children: description }) : null; const _error = error ? /*#__PURE__*/ _jsx(Input.Error, { mt: "xs", ...errorProps, children: error }) : /*#__PURE__*/ _jsx(Space, { h: "xs" }); const _header = _label || _description ? /*#__PURE__*/ _jsxs(Box, { children: [ _label, _description ] }) : null; const _buttons = /*#__PURE__*/ _jsxs(Group, { justify: "right", gap: 0, children: [ /*#__PURE__*/ _jsx(Search, { handleSearch: handleSearch }), /*#__PURE__*/ _jsx(CopyToClipboard, { value: _value, onCopy: ()=>onCopy?.() }) ] }); let editorTheme = colorScheme === 'light' ? 'light' : 'vs-dark'; if (disabled) { editorTheme += '-disabled'; } const _editor = loaded ? /*#__PURE__*/ _jsx(Box, { p: "md", pl: "xs", className: cx(CodeEditorClasses.editor, { [CodeEditorClasses.valid]: !renderErrorOutline }, { [CodeEditorClasses.error]: renderErrorOutline }, { [CodeEditorClasses.disabled]: disabled }), "data-testid": "editor-wrapper", children: /*#__PURE__*/ _jsx(Editor, { onValidate: handleValidate, defaultLanguage: language, theme: editorTheme, options: { minimap: { enabled: false }, wordWrap: 'on', scrollBeyondLastLine: false, formatOnPaste: true, fontSize: px(theme.fontSizes.xs), readOnly: disabled, tabSize }, value: _value, onChange: handleChange, onMount: (editor, monaco)=>{ editorRef.current = editor; if (editorHandle) { editorHandle.current = editor; } registerLanguages(monaco); registerThemes(monaco); editor.onDidFocusEditorText(()=>onFocus?.()); editor.onDidBlurEditorText(async ()=>{ // monaco editor has a timeout of 500ms populating errors, we want to ensure that checking errors happen after that setTimeout(async ()=>{ if (!hasMonacoErrorRef.current) { await editor?.getAction('editor.action.formatDocument')?.run(); } }, 550); }); } }) }) : /*#__PURE__*/ _jsx(Center, { className: CodeEditorClasses.editor, children: /*#__PURE__*/ _jsx(Loader, {}) }); return /*#__PURE__*/ _jsxs(Stack, { justify: "flex-start", gap: 0, h: Math.max(parentHeight, minHeight), mah: maxHeight, ref: ref, ...others, children: [ _header, _buttons, _editor, _error ] }); }; //# sourceMappingURL=CodeEditor.js.map