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:
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user