refactor: use CodeSnippet in color ExportMenu, drop inline copy button

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-01 14:13:41 +01:00
parent 11d4207f72
commit c545211cf7

View File

@@ -1,7 +1,7 @@
'use client';
import { useState, useEffect } from 'react';
import { Download, Copy, Check, Loader2 } from 'lucide-react';
import { Download, Loader2 } from 'lucide-react';
import { toast } from 'sonner';
import {
exportAsCSS,
@@ -13,6 +13,7 @@ import {
type ExportColor,
} from '@/lib/color/utils/export';
import { colorAPI } from '@/lib/color/api/client';
import { CodeSnippet } from '@/components/ui/code-snippet';
import { cn } from '@/lib/utils/cn';
interface ExportMenuProps {
@@ -34,7 +35,6 @@ export function ExportMenu({ colors, className }: ExportMenuProps) {
const [colorSpace, setColorSpace] = useState<ColorSpace>('hex');
const [convertedColors, setConvertedColors] = useState<string[]>(colors);
const [isConverting, setIsConverting] = useState(false);
const [copied, setCopied] = useState(false);
useEffect(() => {
async function convertColors() {
@@ -68,13 +68,6 @@ export function ExportMenu({ colors, className }: ExportMenuProps) {
const getExt = () => ({ css: 'css', scss: 'scss', tailwind: 'js', json: 'json', javascript: 'js' }[format]);
const handleCopy = () => {
navigator.clipboard.writeText(getContent());
setCopied(true);
toast.success('Copied!');
setTimeout(() => setCopied(false), 2000);
};
const handleDownload = () => {
downloadAsFile(getContent(), `palette.${getExt()}`, 'text/plain');
toast.success('Downloaded!');
@@ -111,31 +104,20 @@ export function ExportMenu({ colors, className }: ExportMenuProps) {
</div>
{/* Code preview */}
<div
className="relative rounded-xl overflow-hidden border border-white/5 min-h-[80px]"
style={{ background: '#06060e' }}
>
<div className="relative">
{isConverting && (
<div className="absolute inset-0 flex items-center justify-center z-10 bg-black/30">
<div className="absolute inset-0 flex items-center justify-center z-20 rounded-xl bg-black/40">
<Loader2 className="h-4 w-4 animate-spin text-muted-foreground" />
</div>
)}
<pre className="p-3 text-[10px] font-mono text-white/60 overflow-x-auto leading-relaxed">
<code>{getContent()}</code>
</pre>
<CodeSnippet code={getContent()} />
</div>
{/* Actions */}
<div className="flex gap-2">
<button onClick={handleCopy} disabled={isConverting} className={cn(actionBtn, 'flex-1 justify-center')}>
{copied ? <Check className="w-3 h-3" /> : <Copy className="w-3 h-3" />}
{copied ? 'Copied' : 'Copy'}
</button>
<button onClick={handleDownload} disabled={isConverting} className={cn(actionBtn, 'flex-1 justify-center')}>
<Download className="w-3 h-3" />
Download
</button>
</div>
<button onClick={handleDownload} disabled={isConverting} className={cn(actionBtn, 'w-full justify-center')}>
<Download className="w-3 h-3" />
Download
</button>
</div>
);
}