11import React , { useState } from 'react' ;
22import { Link } from 'react-router-dom' ;
3- import { ArrowLeftIcon } from '@phosphor-icons/react' ;
3+ import { ArrowLeftIcon , CopySimple } from '@phosphor-icons/react' ;
44import { useToast } from '../../hooks/useToast' ;
55import useSeo from '../../hooks/useSeo' ;
66import BreadcrumbTitle from '../../components/BreadcrumbTitle' ;
@@ -22,6 +22,31 @@ function ColorPaletteGeneratorPage() {
2222 const [ palette , setPalette ] = useState ( [ ] ) ;
2323 const { addToast } = useToast ( ) ;
2424
25+ // Utility functions embedded directly as per user instruction
26+ const hexToRgb = ( hex ) => {
27+ let r = 0 , g = 0 , b = 0 ;
28+ if ( hex . length === 4 ) {
29+ r = parseInt ( hex [ 1 ] + hex [ 1 ] , 16 ) ;
30+ g = parseInt ( hex [ 2 ] + hex [ 2 ] , 16 ) ;
31+ b = parseInt ( hex [ 3 ] + hex [ 3 ] , 16 ) ;
32+ } else if ( hex . length === 7 ) {
33+ r = parseInt ( hex . substring ( 1 , 3 ) , 16 ) ;
34+ g = parseInt ( hex . substring ( 3 , 5 ) , 16 ) ;
35+ b = parseInt ( hex . substring ( 5 , 7 ) , 16 ) ;
36+ }
37+ return [ r , g , b ] ;
38+ } ;
39+
40+ const getLuminance = ( r , g , b ) => {
41+ return ( 0.299 * r + 0.587 * g + 0.114 * b ) ;
42+ } ;
43+
44+ const getContrastTextColor = ( hexColor ) => {
45+ const [ r , g , b ] = hexToRgb ( hexColor ) ;
46+ const luminance = getLuminance ( r , g , b ) ;
47+ return luminance > 128 ? 'black' : 'white' ;
48+ } ;
49+
2550 const generateRandomHexColor = ( ) => {
2651 return (
2752 '#' +
@@ -36,13 +61,13 @@ function ColorPaletteGeneratorPage() {
3661 setPalette ( newPalette ) ;
3762 } ;
3863
39- const copyToClipboard = ( text ) => {
64+ const copyToClipboard = ( text , type ) => {
4065 navigator . clipboard
4166 . writeText ( text )
4267 . then ( ( ) => {
4368 addToast ( {
4469 title : 'Success' ,
45- message : `Copied ${ text } to clipboard!` ,
70+ message : `${ type || text } copied to clipboard!` ,
4671 duration : 2000 ,
4772 } ) ;
4873 } )
@@ -87,22 +112,51 @@ function ColorPaletteGeneratorPage() {
87112 Generate New Palette
88113 </ button >
89114 </ div >
90- < div className = "grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-4 mt-4" >
91- { palette . map ( ( color , index ) => (
92- < div
93- key = { index }
94- className = "flex flex-col items-center p-4 rounded-md cursor-pointer transition-transform duration-200 hover:scale-105"
95- style = { { backgroundColor : color } }
96- onClick = { ( ) => copyToClipboard ( color ) }
97- >
98- < span
99- className = "text-white font-semibold text-shadow-sm "
100- style = { { textShadow : '1px 1px 2px rgba(0,0,0,0.8)' } }
115+ < div className = "flex flex-col gap-4 mt-4 font-mono " >
116+ { palette . map ( ( color , index ) => {
117+ const textColor = getContrastTextColor ( color ) ;
118+ const rgb = hexToRgb ( color ) ;
119+ const rgbString = `rgb( ${ rgb [ 0 ] } , ${ rgb [ 1 ] } , ${ rgb [ 2 ] } )` ;
120+
121+ return (
122+ < div
123+ key = { index }
124+ className = "flex flex-col items-center justify-between p-4 rounded-md transition-transform duration-200 hover:scale-105 h-40 relative group "
125+ style = { { backgroundColor : color } }
101126 >
102- { color }
103- </ span >
104- </ div >
105- ) ) }
127+ < div className = "flex flex-col items-center justify-center h-full" >
128+ < div
129+ className = "font-semibold text-lg flex items-center mb-2"
130+ style = { { color : textColor } }
131+ >
132+ { color }
133+ < CopySimple
134+ size = { 18 }
135+ className = "ml-2 cursor-pointer opacity-0 group-hover:opacity-100 transition-opacity"
136+ onClick = { ( e ) => {
137+ e . stopPropagation ( ) ; // Prevent parent div's onClick
138+ copyToClipboard ( color , 'Hex color' ) ;
139+ } }
140+ />
141+ </ div >
142+ < div
143+ className = "text-sm flex items-center"
144+ style = { { color : textColor } }
145+ >
146+ { rgbString }
147+ < CopySimple
148+ size = { 18 }
149+ className = "ml-2 cursor-pointer opacity-0 group-hover:opacity-100 transition-opacity"
150+ onClick = { ( e ) => {
151+ e . stopPropagation ( ) ; // Prevent parent div's onClick
152+ copyToClipboard ( rgbString , 'RGB color' ) ;
153+ } }
154+ />
155+ </ div >
156+ </ div >
157+ </ div >
158+ ) ;
159+ } ) }
106160 </ div >
107161 </ div >
108162 </ div >
0 commit comments