From 7fbbd6052554ea1719ebf013a8d4b1896081228f Mon Sep 17 00:00:00 2001 From: Amit Haridas Date: Fri, 5 Jun 2026 11:40:54 +0530 Subject: [PATCH] feat(renderer): AppHeader with sidebar/preview toggles + theme toggle --- src/renderer/components/layout/AppHeader.tsx | 41 ++++++++++++++++++++ src/renderer/test/setup.ts | 17 ++++++++ tests/component/layout/AppHeader.test.tsx | 33 ++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 src/renderer/components/layout/AppHeader.tsx create mode 100644 tests/component/layout/AppHeader.test.tsx 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 ( +
+
+
+

MarkdownConverter

+
+
+ + + +
+
+ ); +} \ 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