function hexToRgb(hex: string): { r: number; g: number; b: number } | null { const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); return result ? { r: parseInt(result[1], 16), g: parseInt(result[2], 16), b: parseInt(result[3], 16), } : null; } function rgbToHsl(r: number, g: number, b: number): { h: number; s: number; l: number } { r /= 255; g /= 255; b /= 255; const max = Math.max(r, g, b); const min = Math.min(r, g, b); let h = 0; let s; const l = (max + min) / 2; if (max === min) { h = s = 0; } else { const d = max - min; s = l > 0.5 ? d / (2 - max - min) : d / (max + min); switch (max) { case r: h = (g - b) / d + (g < b ? 6 : 0); break; case g: h = (b - r) / d + 2; break; case b: h = (r - g) / d + 4; break; } h /= 6; } return { h: Math.round(h * 360), s: Math.round(s * 100), l: Math.round(l * 100), }; } export function getColorFormats(color: string, className?: string) { // If we have a Tailwind class name, include it in the formats if (!color.startsWith("#")) { return { hex: color, rgb: "Computed at runtime", hsl: "Computed at runtime", tailwind: className || "Computed at runtime", }; } const rgb = hexToRgb(color); if (!rgb) return null; const hsl = rgbToHsl(rgb.r, rgb.g, rgb.b); return { hex: color, rgb: `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`, hsl: `hsl(${hsl.h}, ${hsl.s}%, ${hsl.l}%)`, tailwind: className || "Computed at runtime", }; } export function copyToClipboard(text: string): Promise { return navigator.clipboard.writeText(text); }