Skip to content

Commit

Permalink
feat: add editor in next.js (#997)
Browse files Browse the repository at this point in the history
  • Loading branch information
Shurtu-gal authored Mar 13, 2024
1 parent 8a49d06 commit e84b96d
Show file tree
Hide file tree
Showing 7 changed files with 760 additions and 11 deletions.
5 changes: 4 additions & 1 deletion apps/studio-next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,20 @@
"lint": "next lint"
},
"dependencies": {
"@codemirror/state": "^6.4.1",
"@types/node": "20.4.6",
"@types/react": "18.2.18",
"@types/react-dom": "18.2.7",
"autoprefixer": "10.4.14",
"codemirror": "^6.0.1",
"eslint": "8.46.0",
"eslint-config-next": "13.4.12",
"next": "13.5.1",
"postcss": "8.4.31",
"react": "18.2.0",
"react-dom": "18.2.0",
"tailwindcss": "3.3.3",
"typescript": "5.1.6"
"typescript": "5.1.6",
"zustand": "^4.5.2"
}
}
6 changes: 4 additions & 2 deletions apps/studio-next/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Editor } from '@/components/Editor/Editor';

export default function Home() {
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
Home
<main className="flex flex-col w-full h-screen">
<Editor />
</main>
)
}
99 changes: 99 additions & 0 deletions apps/studio-next/src/components/Editor/CodeMirror.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
'use client';

import { EditorView, basicSetup } from 'codemirror';
import { EditorState } from '@codemirror/state';
import { useEffect, useRef } from 'react';
import {
oneDarkTheme,
oneDarkHighlightStyle,
} from '@codemirror/theme-one-dark';
import { json } from '@codemirror/lang-json';
import { yaml } from '@codemirror/lang-yaml';
import { syntaxHighlighting } from '@codemirror/language';
import { indentWithTab } from '@codemirror/commands';
import { keymap } from '@codemirror/view';

interface ICodeMirrorProps {
language: 'json' | 'yaml';
value: string;
onChange: (value: string) => void;
readOnly?: boolean;
autoFocus?: boolean;
className?: string;
}

export const CodeMirror = (props: ICodeMirrorProps) => {
const { language, value, onChange, autoFocus, className } = props;

const editorRef = useRef<HTMLDivElement>(null);
const editorViewRef = useRef<EditorView>();

useEffect(() => {
let currentValue;
if (window) {
currentValue = localStorage.getItem('document') || value;
onChange(currentValue);
}

if (editorRef.current) {
const theme = EditorView.theme({
'&': {
backgroundColor: '#252f3f',
color: '#fff',
},

'&.cm-editor': {
height: '100%',
width: '100%',
},

'&.cm-focused': {
backgroundColor: '#1f2a37',
},
});

const editorState = EditorState.create({
doc: currentValue,
extensions: [
basicSetup,
theme,
keymap.of([indentWithTab]),
oneDarkTheme,
syntaxHighlighting(oneDarkHighlightStyle),
language === 'json' ? json() : yaml(),
EditorView.updateListener.of((update) => {
if (update.docChanged) {
onChange(update.state.doc.toString());

if (window !== undefined) {
localStorage.setItem('document', update.state.doc.toString());
}
}

return false;
}),
],
});

editorViewRef.current = new EditorView({
parent: editorRef.current,
state: editorState,
});

if (autoFocus) {
editorViewRef.current.focus();
}

return () => {
editorViewRef.current?.destroy();
};
}
}, [language]);

return (
<div
ref={editorRef}
className={`${className} flex-grow relative overflow-auto`}
/>
);
};
17 changes: 17 additions & 0 deletions apps/studio-next/src/components/Editor/Editor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use client'

import { useFilesState } from '@/state/files.state';
import { CodeMirror } from './CodeMirror';

interface IEditorProps {}

export const Editor = (props: IEditorProps) => {
const { language, content } = useFilesState(state => state.files['asyncapi']);
const handleUpdateFile = useFilesState(state => state.updateFile);

return (
<div className="flex flex-1 overflow-hidden">
<CodeMirror language={language} value={content} onChange={value => handleUpdateFile('asyncapi', { content: value })} />
</div>
);
}
Loading

0 comments on commit e84b96d

Please sign in to comment.