diff --git a/src/renderer/components/editor/EditorPane.tsx b/src/renderer/components/editor/EditorPane.tsx
new file mode 100644
index 0000000..59c45d9
--- /dev/null
+++ b/src/renderer/components/editor/EditorPane.tsx
@@ -0,0 +1,25 @@
+import { CodeMirrorEditor } from './CodeMirrorEditor';
+import { useEditorStore } from '@/stores/editor-store';
+
+export function EditorPane() {
+ const { buffers, activeId } = useEditorStore();
+ const buf = activeId ? buffers.get(activeId) : null;
+
+ if (!buf) {
+ return (
+
+
No file open. Use File → Open to start.
+
+ );
+ }
+
+ return (
+
+
+
+ );
+}
diff --git a/tests/component/editor/EditorPane.test.tsx b/tests/component/editor/EditorPane.test.tsx
new file mode 100644
index 0000000..e9ad5d2
--- /dev/null
+++ b/tests/component/editor/EditorPane.test.tsx
@@ -0,0 +1,38 @@
+import { describe, it, expect, beforeEach, vi } from 'vitest';
+import { render, screen } from '@testing-library/react';
+import { ThemeProvider } from '@/components/theme-provider';
+import { EditorPane } from '@/components/editor/EditorPane';
+import { useEditorStore } from '@/stores/editor-store';
+import { CodeMirrorEditor } from '@/components/editor/CodeMirrorEditor';
+
+vi.mock('@/components/editor/CodeMirrorEditor', () => ({
+ CodeMirrorEditor: ({ initialContent }: { initialContent: string }) => (
+ {initialContent}
+ ),
+}));
+
+describe('EditorPane', () => {
+ beforeEach(() => {
+ useEditorStore.setState({ buffers: new Map(), activeId: null });
+ });
+
+ it('renders the empty state when no buffer is open', () => {
+ render(
+
+
+
+ );
+ expect(screen.getByText(/no file open/i)).toBeInTheDocument();
+ });
+
+ it('renders the editor when a buffer is open', () => {
+ useEditorStore.getState().openBuffer('b1', '/x.md', '# hello');
+ render(
+
+
+
+ );
+ expect(screen.getByTestId('codemirror-mock')).toBeInTheDocument();
+ expect(screen.getByTestId('codemirror-mock')).toHaveTextContent('# hello');
+ });
+});