Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 47 additions & 11 deletions src/components/ReadmePreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import {
type ReadmeExportPreset,
} from '@/config/readmeExportPresets';
import { generateMarkdown as generateMarkdownUtil } from '@/utils/markdownGenerator';
import { useRef, useState } from 'react';
import { Download, Copy, Share2 } from 'lucide-react';
import { useRef, useState, useEffect } from 'react';
import { Download, Copy, Share2, Sun, Moon, Eclipse } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { ElementRenderer } from '@/components/ElementRenderer';
import type { ElementType } from '@/types/elements';
Expand All @@ -27,11 +27,18 @@ export function ReadmePreview({
}: ReadmePreviewProps) {
const [copied, setCopied] = useState(false);
const previewRef = useRef<HTMLDivElement>(null);
const { theme } = useTheme();
const { theme: globalTheme } = useTheme();
const isMobile = useIsMobile();
const isDark =
theme === 'dark' ||
(theme === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches);

// Local preview theme state
const [previewTheme, setPreviewTheme] = useState<'github-light' | 'github-dark' | 'github-dimmed'>('github-dark');

// Sync preview theme with global theme initially
useEffect(() => {
const isGlobalDark = globalTheme === 'dark' ||
(globalTheme === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches);
setPreviewTheme(isGlobalDark ? 'github-dark' : 'github-light');
}, [globalTheme]);

const filteredElements =
preset === 'default'
Expand All @@ -41,7 +48,7 @@ export function ReadmePreview({
);

const generateMarkdown = (): string =>
generateMarkdownUtil(filteredElements, theme);
generateMarkdownUtil(filteredElements, globalTheme);

const copyToClipboard = async () => {
const markdown = generateMarkdown();
Expand Down Expand Up @@ -102,8 +109,39 @@ export function ReadmePreview({
<div className="h-full flex flex-col">
<div className={`border-b border-border p-3 md:p-4 bg-muted/50 ${isMobile ? 'mt-6' : ''}`}>
<div className="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 mb-3">
<div className="flex items-center gap-2">
<div className="flex items-center gap-4">
<h3 className="font-medium text-base md:text-lg">README Preview</h3>

{/* Theme Switcher */}
<div className="flex items-center bg-background/50 border border-border p-1 rounded-full shadow-inner">
<Button
variant="ghost"
size="icon"
className={`h-7 w-7 rounded-full transition-all duration-300 ${previewTheme === 'github-light' ? 'bg-background shadow-sm text-yellow-500 scale-110' : 'text-muted-foreground hover:text-foreground'}`}
onClick={() => setPreviewTheme('github-light')}
title="GitHub Light"
>
<Sun className="h-4 w-4" />
</Button>
<Button
variant="ghost"
size="icon"
className={`h-7 w-7 rounded-full transition-all duration-300 ${previewTheme === 'github-dimmed' ? 'bg-background shadow-sm text-blue-400 scale-110' : 'text-muted-foreground hover:text-foreground'}`}
onClick={() => setPreviewTheme('github-dimmed')}
title="GitHub Dark Dimmed"
>
<Eclipse className="h-4 w-4" />
</Button>
<Button
variant="ghost"
size="icon"
className={`h-7 w-7 rounded-full transition-all duration-300 ${previewTheme === 'github-dark' ? 'bg-background shadow-sm text-purple-500 scale-110' : 'text-muted-foreground hover:text-foreground'}`}
onClick={() => setPreviewTheme('github-dark')}
title="GitHub Dark"
>
<Moon className="h-4 w-4" />
</Button>
</div>
</div>

<div className="flex flex-wrap items-center gap-2 w-full sm:w-auto">
Expand Down Expand Up @@ -169,11 +207,9 @@ export function ReadmePreview({
<TabsContent value="preview" className="flex-1 overflow-auto p-4">
<div
ref={previewRef}
className="p-10 rounded-2xl shadow-xl max-w-4xl mx-auto border"
className={`p-10 rounded-2xl shadow-xl max-w-4xl mx-auto border transition-all duration-500 ${previewTheme}`}
style={{
background: isDark ? '#18181b' : '#ffffff',
fontFamily: 'Inter, sans-serif',
color: isDark ? '#f3f4f6' : '#1e293b',
lineHeight: '1.75',
}}
>
Expand Down
37 changes: 37 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,43 @@
--sidebar-ring: oklch(0.541 0.281 293.009);
}

/* GitHub Preview Themes - Scoped to the preview container */
.github-light {
--background: 0 0% 100%;
--foreground: 210 18% 14%;
--muted: 210 18% 97%;
--muted-foreground: 210 18% 45%;
--border: 210 18% 87%;
--card: 0 0% 100%;
--card-foreground: 210 18% 14%;
background-color: #ffffff !important;
color: #1f2328 !important;
}

.github-dark {
--background: 212 32% 7%;
--foreground: 210 40% 93%;
--muted: 212 32% 11%;
--muted-foreground: 210 40% 65%;
--border: 212 32% 21%;
--card: 212 32% 9%;
--card-foreground: 210 40% 93%;
background-color: #0d1117 !important;
color: #e6edf3 !important;
}

.github-dimmed {
--background: 213 16% 16%;
--foreground: 210 17% 82%;
--muted: 213 16% 20%;
--muted-foreground: 210 17% 60%;
--border: 213 16% 30%;
--card: 213 16% 18%;
--card-foreground: 210 17% 82%;
background-color: #22272e !important;
color: #adbac7 !important;
}

@layer base {
:root {
--background: 220 13% 10%;
Expand Down