75 lines
2.1 KiB
TypeScript
75 lines
2.1 KiB
TypeScript
import { useState } from 'react'
|
|
|
|
type RGB = {
|
|
r: number
|
|
g: number
|
|
b: number
|
|
}
|
|
|
|
type HSL = {
|
|
h: number
|
|
s: number
|
|
l: number
|
|
}
|
|
|
|
type HSB = {
|
|
h: number
|
|
s: number
|
|
b: number
|
|
}
|
|
|
|
type ColorFormat = 'hex' | 'rgb' | 'hsl' | 'hsb' | 'tailwind'
|
|
|
|
export function ColorPicker() {
|
|
const [color, setColor] = useState('#6366F1') // Default to indigo-500
|
|
const [format, setFormat] = useState<ColorFormat>('hex')
|
|
|
|
return (
|
|
<div className="w-full max-w-2xl mx-auto p-6 space-y-6">
|
|
<div className="flex flex-col items-center gap-6">
|
|
<h1 className="text-3xl font-bold">Color Picker</h1>
|
|
|
|
{/* Color Preview */}
|
|
<div
|
|
className="w-32 h-32 rounded-lg shadow-lg border border-zinc-200"
|
|
style={{ backgroundColor: color }}
|
|
/>
|
|
|
|
{/* Color Input */}
|
|
<div className="w-full max-w-md">
|
|
<div className="flex gap-2 mb-4">
|
|
{(['hex', 'rgb', 'hsl', 'hsb', 'tailwind'] as const).map((f) => (
|
|
<button
|
|
key={f}
|
|
onClick={() => setFormat(f)}
|
|
className={`px-3 py-1.5 rounded-md text-sm font-medium transition-colors
|
|
${format === f
|
|
? 'bg-indigo-500 text-white'
|
|
: 'bg-zinc-100 text-zinc-700 hover:bg-zinc-200'
|
|
}`}
|
|
>
|
|
{f.toUpperCase()}
|
|
</button>
|
|
))}
|
|
</div>
|
|
|
|
<div className="relative">
|
|
<input
|
|
type="text"
|
|
value={color}
|
|
onChange={(e) => setColor(e.target.value)}
|
|
className="w-full px-4 py-2 rounded-md border border-zinc-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"
|
|
placeholder="Enter color value..."
|
|
/>
|
|
<input
|
|
type="color"
|
|
value={color}
|
|
onChange={(e) => setColor(e.target.value)}
|
|
className="absolute right-2 top-1/2 -translate-y-1/2 w-8 h-8 p-0 border-0 rounded-md cursor-pointer"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|