72 lines
1.7 KiB
TypeScript
72 lines
1.7 KiB
TypeScript
import Editor, { loader, EditorProps, Monaco } from '@monaco-editor/react'
|
|
import { CSS } from '@stitches/react'
|
|
import type monaco from 'monaco-editor'
|
|
import { useTheme } from 'next-themes'
|
|
import { FC, MutableRefObject, ReactNode } from 'react'
|
|
import { Flex } from '.'
|
|
import dark from '../theme/editor/amy.json'
|
|
import light from '../theme/editor/xcode_default.json'
|
|
|
|
export type MonacoProps = EditorProps & {
|
|
id?: string
|
|
rootProps?: { css: CSS } & Record<string, any>
|
|
overlay?: ReactNode
|
|
editorRef?: MutableRefObject<monaco.editor.IStandaloneCodeEditor>
|
|
monacoRef?: MutableRefObject<typeof monaco>
|
|
}
|
|
|
|
loader.config({
|
|
paths: {
|
|
vs: 'https://cdn.jsdelivr.net/npm/monaco-editor@0.30.1/min/vs'
|
|
}
|
|
})
|
|
|
|
const Monaco: FC<MonacoProps> = ({
|
|
id,
|
|
path = `file:///${id}`,
|
|
className = id,
|
|
language = 'json',
|
|
overlay,
|
|
editorRef,
|
|
monacoRef,
|
|
beforeMount,
|
|
rootProps,
|
|
...rest
|
|
}) => {
|
|
const { theme } = useTheme()
|
|
const setTheme = (monaco: Monaco) => {
|
|
monaco.editor.defineTheme('dark', dark as any)
|
|
monaco.editor.defineTheme('light', light as any)
|
|
}
|
|
return (
|
|
<Flex
|
|
fluid
|
|
column
|
|
{...rootProps}
|
|
css={{
|
|
position: 'relative',
|
|
height: '100%',
|
|
...rootProps?.css
|
|
}}
|
|
>
|
|
<Editor
|
|
className={className}
|
|
language={language}
|
|
path={path}
|
|
beforeMount={monaco => {
|
|
beforeMount?.(monaco)
|
|
|
|
setTheme(monaco)
|
|
}}
|
|
theme={theme === 'dark' ? 'dark' : 'light'}
|
|
{...rest}
|
|
/>
|
|
{overlay && (
|
|
<Flex css={{ position: 'absolute', bottom: 0, right: 0, width: '100%' }}>{overlay}</Flex>
|
|
)}
|
|
</Flex>
|
|
)
|
|
}
|
|
|
|
export default Monaco
|