diff --git a/src/renderer/components/layout/AppHeader.tsx b/src/renderer/components/layout/AppHeader.tsx
new file mode 100644
index 0000000..78a6359
--- /dev/null
+++ b/src/renderer/components/layout/AppHeader.tsx
@@ -0,0 +1,41 @@
+import { PanelLeft, PanelRight } from 'lucide-react';
+import { Button } from '@/components/ui/button';
+import { ThemeToggle } from '@/components/theme-toggle';
+import { useAppStore } from '@/stores/app-store';
+
+export function AppHeader() {
+ const { sidebarVisible, previewVisible, toggleSidebar, togglePreview } = useAppStore();
+
+ return (
+
+ );
+}
\ No newline at end of file
diff --git a/src/renderer/test/setup.ts b/src/renderer/test/setup.ts
index 9ca14b1..461543e 100644
--- a/src/renderer/test/setup.ts
+++ b/src/renderer/test/setup.ts
@@ -10,3 +10,20 @@ declare global {
if (typeof window !== 'undefined' && !window.electronAPI) {
window.electronAPI = {};
}
+
+// Mock matchMedia for next-themes (jsdom doesn't have it)
+if (typeof window !== 'undefined') {
+ Object.defineProperty(window, 'matchMedia', {
+ writable: true,
+ value: (query: string) => ({
+ matches: false,
+ media: query,
+ onchange: null,
+ addListener: () => {},
+ removeListener: () => {},
+ addEventListener: () => {},
+ removeEventListener: () => {},
+ dispatchEvent: () => true,
+ }),
+ });
+}
diff --git a/tests/component/layout/AppHeader.test.tsx b/tests/component/layout/AppHeader.test.tsx
new file mode 100644
index 0000000..a656f87
--- /dev/null
+++ b/tests/component/layout/AppHeader.test.tsx
@@ -0,0 +1,33 @@
+import { describe, it, expect, beforeEach } from 'vitest';
+import { render, screen } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+import { ThemeProvider } from '@/components/theme-provider';
+import { AppHeader } from '@/components/layout/AppHeader';
+import { useAppStore } from '@/stores/app-store';
+
+describe('AppHeader', () => {
+ beforeEach(() => {
+ localStorage.clear();
+ useAppStore.setState({ sidebarVisible: true, previewVisible: true, zenMode: false });
+ });
+
+ it('renders the app title', () => {
+ render(
+
+
+
+ );
+ expect(screen.getByText(/markdownconverter/i)).toBeInTheDocument();
+ });
+
+ it('toggles sidebar when sidebar button clicked', async () => {
+ render(
+
+
+
+ );
+ const btn = screen.getByRole('button', { name: /toggle sidebar/i });
+ await userEvent.click(btn);
+ expect(useAppStore.getState().sidebarVisible).toBe(false);
+ });
+});
\ No newline at end of file