Add oklch and all new tailwind colors

This commit is contained in:
2025-02-10 11:22:26 -05:00
parent 1d03a56c70
commit 4261e6f436
3 changed files with 449 additions and 155 deletions

View File

@@ -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>