diff --git a/app/palettes/distinct/page.tsx b/app/palettes/distinct/page.tsx
index 9a184cd..5a2c483 100644
--- a/app/palettes/distinct/page.tsx
+++ b/app/palettes/distinct/page.tsx
@@ -2,6 +2,7 @@
import { useState } from 'react';
import { PaletteGrid } from '@/components/color/PaletteGrid';
+import { ExportMenu } from '@/components/tools/ExportMenu';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Select } from '@/components/ui/select';
@@ -125,13 +126,19 @@ export default function DistinctPage() {
{/* Results */}
-
+
Generated Colors {colors.length > 0 && `(${colors.length})`}
+
+ {colors.length > 0 && (
+
+
+
+ )}
diff --git a/app/palettes/gradient/page.tsx b/app/palettes/gradient/page.tsx
index 6394476..94d72fe 100644
--- a/app/palettes/gradient/page.tsx
+++ b/app/palettes/gradient/page.tsx
@@ -3,6 +3,7 @@
import { useState } from 'react';
import { ColorPicker } from '@/components/color/ColorPicker';
import { PaletteGrid } from '@/components/color/PaletteGrid';
+import { ExportMenu } from '@/components/tools/ExportMenu';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Select } from '@/components/ui/select';
@@ -173,6 +174,10 @@ export default function GradientPage() {
+
+
+
+
>
)}
diff --git a/components/tools/ExportMenu.tsx b/components/tools/ExportMenu.tsx
new file mode 100644
index 0000000..5c3ed8c
--- /dev/null
+++ b/components/tools/ExportMenu.tsx
@@ -0,0 +1,125 @@
+'use client';
+
+import { Button } from '@/components/ui/button';
+import { Select } from '@/components/ui/select';
+import { useState } from 'react';
+import { Download, Copy, Check } from 'lucide-react';
+import { toast } from 'sonner';
+import {
+ exportAsCSS,
+ exportAsSCSS,
+ exportAsTailwind,
+ exportAsJSON,
+ exportAsJavaScript,
+ downloadAsFile,
+ type ExportColor,
+} from '@/lib/utils/export';
+
+interface ExportMenuProps {
+ colors: string[];
+ className?: string;
+}
+
+type ExportFormat = 'css' | 'scss' | 'tailwind' | 'json' | 'javascript';
+
+export function ExportMenu({ colors, className }: ExportMenuProps) {
+ const [format, setFormat] = useState('css');
+ const [copied, setCopied] = useState(false);
+
+ const exportColors: ExportColor[] = colors.map((hex) => ({ hex }));
+
+ const getExportContent = (): string => {
+ switch (format) {
+ case 'css':
+ return exportAsCSS(exportColors);
+ case 'scss':
+ return exportAsSCSS(exportColors);
+ case 'tailwind':
+ return exportAsTailwind(exportColors);
+ case 'json':
+ return exportAsJSON(exportColors);
+ case 'javascript':
+ return exportAsJavaScript(exportColors);
+ }
+ };
+
+ const getFileExtension = (): string => {
+ switch (format) {
+ case 'css':
+ return 'css';
+ case 'scss':
+ return 'scss';
+ case 'tailwind':
+ return 'js';
+ case 'json':
+ return 'json';
+ case 'javascript':
+ return 'js';
+ }
+ };
+
+ const handleCopy = () => {
+ const content = getExportContent();
+ navigator.clipboard.writeText(content);
+ setCopied(true);
+ toast.success('Copied to clipboard!');
+ setTimeout(() => setCopied(false), 2000);
+ };
+
+ const handleDownload = () => {
+ const content = getExportContent();
+ const extension = getFileExtension();
+ downloadAsFile(content, `palette.${extension}`, 'text/plain');
+ toast.success('Downloaded!');
+ };
+
+ if (colors.length === 0) {
+ return null;
+ }
+
+ return (
+
+
+
+
Export Palette
+
+
+
+
+
+ {getExportContent()}
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/lib/utils/export.ts b/lib/utils/export.ts
new file mode 100644
index 0000000..3526696
--- /dev/null
+++ b/lib/utils/export.ts
@@ -0,0 +1,83 @@
+/**
+ * Export utilities for color palettes
+ */
+
+export interface ExportColor {
+ name?: string;
+ hex: string;
+}
+
+/**
+ * Export colors as CSS variables
+ */
+export function exportAsCSS(colors: ExportColor[]): string {
+ const variables = colors
+ .map((color, index) => {
+ const name = color.name || `color-${index + 1}`;
+ return ` --${name}: ${color.hex};`;
+ })
+ .join('\n');
+
+ return `:root {\n${variables}\n}`;
+}
+
+/**
+ * Export colors as SCSS variables
+ */
+export function exportAsSCSS(colors: ExportColor[]): string {
+ return colors
+ .map((color, index) => {
+ const name = color.name || `color-${index + 1}`;
+ return `$${name}: ${color.hex};`;
+ })
+ .join('\n');
+}
+
+/**
+ * Export colors as Tailwind config
+ */
+export function exportAsTailwind(colors: ExportColor[]): string {
+ const colorEntries = colors
+ .map((color, index) => {
+ const name = color.name || `color-${index + 1}`;
+ return ` '${name}': '${color.hex}',`;
+ })
+ .join('\n');
+
+ return `module.exports = {\n theme: {\n extend: {\n colors: {\n${colorEntries}\n },\n },\n },\n};`;
+}
+
+/**
+ * Export colors as JSON
+ */
+export function exportAsJSON(colors: ExportColor[]): string {
+ const colorObjects = colors.map((color, index) => ({
+ name: color.name || `color-${index + 1}`,
+ hex: color.hex,
+ }));
+
+ return JSON.stringify({ colors: colorObjects }, null, 2);
+}
+
+/**
+ * Export colors as JavaScript array
+ */
+export function exportAsJavaScript(colors: ExportColor[]): string {
+ const colorArray = colors.map((c) => `'${c.hex}'`).join(', ');
+ return `const colors = [${colorArray}];`;
+}
+
+/**
+ * Download text as file
+ */
+export function downloadAsFile(content: string, filename: string, mimeType: string = 'text/plain') {
+ const blob = new Blob([content], { type: mimeType });
+ const url = URL.createObjectURL(blob);
+ const link = document.createElement('a');
+ link.href = url;
+ link.download = filename;
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ URL.revokeObjectURL(url);
+}