import Monaco from '@monaco-editor/react' import styled from 'styled-components' import { Text } from 'theme-ui' import { LiveProvider as BaseProvider, LiveError as BaseError, LivePreview as BasePreview } from 'react-live' import { editorThemes } from '@/context/theme-context' import { debounce, isDev } from '@/lib' import { theme } from '@/theme' import * as scope from './presets/scope' const LivePreviewWrapper = styled('div')` height: 100%; width: 100%; margin: auto; overflow: hidden; user-select: none; position: relative; > * { pointer-events: ${!isDev ? 'none' : 'initial'}; } ${({ isEditor }) => isEditor && ` box-shadow: rgba(0, 0, 0, 0.12) 0px 5px 10px 0px; cursor: pointer;`} ` LivePreviewWrapper.defaultProps = { id: 'screenshot' } export const LiveError = styled(BaseError)` background: #ff5555; color: #f8f8f2; font-family: ${theme.fonts.mono}; font-size: ${theme.fontSizes[2]}; margin: 0; padding: ${theme.space[3]}; text-align: left; white-space: pre-wrap; ` export const LivePreview = styled(BasePreview)` > div { height: inherit; width: inherit; } ` LivePreview.defaultProps = { Component: LivePreviewWrapper } const LiveProviderBase = styled(BaseProvider)`` LiveProviderBase.defaultProps = { scope, theme: undefined, noInline: false } export const LiveProvider = ({ queryVariables: query, ...props }) => { const extendedScope = { ...scope, query } return <LiveProviderBase {...props} scope={extendedScope} /> } const LiveEditorBase = styled(Monaco)`` const Loading = () => ( <Text sx={{ fontFamily: 'mono', color: theme.color }}>Loading...</Text> ) export const LiveEditor = ({ code, onChange, themeKey, theme }) => { return ( <LiveEditorBase value={code} language='javascript' theme={themeKey} beforeMount={monaco => { Object.keys(editorThemes).forEach(key => { const value = editorThemes[key] monaco.editor.defineTheme(key, value) }) }} onChange={debounce(onChange)} loading={<Loading theme={theme} />} options={{ fontSize: 14, scrollBeyondLastLine: false, wordWrapColumn: 'on', hideCursorInOverviewRuler: true, minimap: { enabled: false }, lineNumbersMinChars: 0, scrollbar: { useShadows: false } }} /> ) }