Add oklch and all new tailwind colors
This commit is contained in:
@@ -1,38 +1,82 @@
|
||||
import { useMemo } from 'react'
|
||||
import React, { useMemo } from 'react'
|
||||
import { TAILWIND_COLORS } from '../utils/colors'
|
||||
|
||||
interface TailwindColorsProps {
|
||||
onColorSelect: (color: string) => void
|
||||
selectedColor?: string
|
||||
format?: 'hex' | 'rgb' | 'hsl' | 'hsb' | 'oklch' | 'tailwind'
|
||||
}
|
||||
|
||||
export function TailwindColors({ onColorSelect, selectedColor }: TailwindColorsProps) {
|
||||
const colorEntries = useMemo(() => Object.entries(TAILWIND_COLORS), [])
|
||||
export function TailwindColors({ onColorSelect, selectedColor, format = 'hex' }: TailwindColorsProps) {
|
||||
// Order colors in specified sequence
|
||||
const orderedColors = useMemo(() => [
|
||||
'red',
|
||||
'orange',
|
||||
'amber',
|
||||
'yellow',
|
||||
'lime',
|
||||
'green',
|
||||
'emerald',
|
||||
'teal',
|
||||
'cyan',
|
||||
'sky',
|
||||
'blue',
|
||||
'indigo',
|
||||
'violet',
|
||||
'purple',
|
||||
'fuchsia',
|
||||
'pink',
|
||||
'rose',
|
||||
'slate',
|
||||
'gray',
|
||||
'zinc',
|
||||
'neutral',
|
||||
'stone',
|
||||
] as const, [])
|
||||
|
||||
const shades = useMemo(() => ['50', '100', '200', '300', '400', '500', '600', '700', '800', '900', '950'] as const, [])
|
||||
|
||||
// Function to determine text color based on background luminance
|
||||
const getTextColor = (hex: string) => {
|
||||
const rgb = hex.match(/^#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i)
|
||||
if (!rgb) return 'text-black'
|
||||
|
||||
const [_, r, g, b] = rgb.map(x => parseInt(x, 16))
|
||||
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255
|
||||
return luminance > 0.5 ? 'text-black' : 'text-white'
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="w-full overflow-x-auto">
|
||||
<div className="grid grid-cols-[repeat(auto-fit,minmax(100px,1fr))] gap-4">
|
||||
{colorEntries.map(([colorName, shades]) => (
|
||||
<div key={colorName} className="space-y-2">
|
||||
<div className="text-sm font-medium text-zinc-600 capitalize">{colorName}</div>
|
||||
<div className="grid grid-rows-[repeat(11,1fr)] gap-1">
|
||||
{Object.entries(shades).map(([shade, hex]) => (
|
||||
<div className="grid grid-cols-[auto_repeat(11,minmax(32px,1fr))] gap-1.5">
|
||||
{/* Color rows */}
|
||||
{orderedColors.map(colorName => (
|
||||
<React.Fragment key={colorName}>
|
||||
<div className="sticky left-0 z-10 bg-white text-sm font-medium text-zinc-600 capitalize py-1 pr-3 whitespace-nowrap">
|
||||
{colorName}
|
||||
</div>
|
||||
{shades.map(shade => {
|
||||
const values = TAILWIND_COLORS[colorName][shade]
|
||||
const hexColor = typeof values === 'string' ? values : values.hex
|
||||
const displayValue = format === 'oklch' && typeof values !== 'string' ? values.oklch : hexColor
|
||||
const textColorClass = getTextColor(hexColor)
|
||||
|
||||
return (
|
||||
<button
|
||||
key={`${colorName}-${shade}`}
|
||||
onClick={() => onColorSelect(hex)}
|
||||
className={`w-full h-7 rounded transition-all hover:scale-105 hover:shadow-lg group relative
|
||||
${selectedColor === hex ? 'ring-2 ring-offset-2 ring-indigo-500' : ''}`}
|
||||
style={{ backgroundColor: hex }}
|
||||
title={`${colorName}-${shade}: ${hex}`}
|
||||
onClick={() => onColorSelect(displayValue)}
|
||||
className={`aspect-square transition-all hover:scale-105 hover:shadow-lg group relative
|
||||
${selectedColor === displayValue ? 'ring-2 ring-offset-1 ring-indigo-500 z-10' : ''}`}
|
||||
style={{ backgroundColor: hexColor }}
|
||||
title={`${colorName}-${shade}: ${displayValue}`}
|
||||
>
|
||||
<span className={`absolute left-2 text-xs font-medium opacity-0 group-hover:opacity-100 transition-opacity
|
||||
${Number(shade) > 500 ? 'text-white' : 'text-black'}`}>
|
||||
<span className={`absolute inset-0 flex items-center justify-center text-[10px] font-medium ${textColorClass}`}>
|
||||
{shade}
|
||||
</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user