Initial commit: WYSIWYG Markdown Editor - Go backend + React/TypeScript frontend with Tailwind CSS
Backend: - Cobra CLI with --data-dir, --port, --host flags - Gin HTTP server with REST API for markdown CRUD operations - File storage on disk (.md files only) - Comprehensive logrus logging - Backend tests with CRUD round-trip verification Frontend: - React 18 + TypeScript + Tailwind CSS - Markdown editor with live GFM preview (react-markdown + remark-gfm) - File management UI (list, create, open, save, delete) - Theme switcher with Dark/Light/System modes - Responsive design - Frontend tests with vitest Testing: - All backend tests pass (go test ./...) - All frontend tests pass (npm test)
This commit is contained in:
55
frontend/src/components/ThemeSwitcher.tsx
Normal file
55
frontend/src/components/ThemeSwitcher.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import { ReactNode } from 'react'
|
||||
|
||||
interface ThemeSwitcherProps {
|
||||
darkMode: boolean
|
||||
onToggle: () => void
|
||||
}
|
||||
|
||||
export const ThemeSwitcher: React.FC<ThemeSwitcherProps> = ({
|
||||
darkMode,
|
||||
onToggle,
|
||||
}) => {
|
||||
const icon: ReactNode = darkMode ? (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-6 w-6"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"
|
||||
/>
|
||||
</svg>
|
||||
) : (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-6 w-6"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M20.354 15.354A9 9 0 018 15.354c1.433-2.035 3.49-3.585 5.84-4.238l.092.009a4 4 0 013.477 3.477l.009.092C15.915 7.505 17.465 9.562 19.5 11a9 9 0 01-1.146 3.354z"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
return (
|
||||
<div className="absolute top-4 right-4 z-10">
|
||||
<button
|
||||
onClick={onToggle}
|
||||
className="p-2 rounded-lg bg-gray-300 dark:bg-dark-surface text-gray-700 dark:text-dark-text hover:bg-gray-400 dark:hover:bg-dark-surface transition-colors shadow-md"
|
||||
aria-label="Toggle theme"
|
||||
>
|
||||
{icon}
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user