GitHub_Trending/ui/ui颜色系统:调色板与颜色选择器实现
引言
在现代Web开发中,颜色系统是构建一致性和可访问性UI的关键要素。GitHub_Trending/ui/ui项目基于Radix UI和Tailwind CSS,提供了一套完整的颜色管理系统,包括丰富的调色板、智能颜色选择器和多格式支持。本文将深入解析该项目的颜色系统实现原理,帮助开发者理解如何构建专业级的颜色管理方案。
颜色系统架构概览
GitHub_Trending/ui/ui的颜色系统采用分层架构设计,包含以下核心组件:
核心颜色数据结构
颜色定义格式
项目使用标准化的颜色数据结构,支持多种颜色格式:
interface ColorDefinition {
scale: number; // 颜色层级(50-950)
hex: string; // HEX格式
rgb: string; // RGB格式
hsl: string; // HSL格式
oklch: string; // OKLCH格式
foreground: string; // 前景色(自动计算)
}
interface ColorPalette {
name: string; // 调色板名称
colors: ColorDefinition[]; // 颜色数组
}
支持的调色板类型
项目内置了完整的Tailwind CSS调色板系统:
调色板名称 | 颜色数量 | 主要用途 |
---|---|---|
neutral | 11 | 中性色调 |
slate | 11 | 石板色调 |
gray | 11 | 灰色调 |
zinc | 11 | 锌色调 |
stone | 11 | 石色调 |
red | 11 | 警告/错误 |
orange | 11 | 警告/提示 |
amber | 11 | 强调色 |
yellow | 11 | 注意色 |
lime | 11 | 成功色 |
green | 11 | 成功色 |
emerald | 11 | 宝石绿色 |
teal | 11 | 青绿色 |
cyan | 11 | 青色 |
sky | 11 | 天空蓝色 |
blue | 11 | 主要蓝色 |
indigo | 11 | 靛蓝色 |
violet | 11 | 紫罗兰色 |
核心组件实现解析
1. 颜色组件(Color.tsx)
颜色组件是系统的基础构建块,负责单个颜色的显示和交互:
export function Color({ color }: { color: Color }) {
const { format, setLastCopied, lastCopied } = useColors()
const { isCopied, copyToClipboard } = useCopyToClipboard({ timeout: 0 })
return (
<button
className="group relative flex aspect-[3/1] w-full flex-1 cursor-pointer flex-col gap-2 text-(--text)"
style={{
"--bg": `${color.oklch}`,
"--text": color.foreground,
} as React.CSSProperties
onClick={() => {
copyToClipboard(color[format])
setLastCopied(color[format])
toast.success(`Copied ${color[format]} to clipboard.`)
}}
>
{/* 复制状态指示器 */}
{isCopied ? <CheckIcon /> : <ClipboardIcon />}
{/* 颜色显示区域 */}
<div className="border-ghost after:border-input w-full flex-1 rounded-md bg-(--bg)" />
{/* 颜色信息 */}
<div className="flex w-full flex-col items-center justify-center gap-1">
<span className="text-muted-foreground group-hover:text-foreground font-mono text-xs">
{color.className}
</span>
<span className="text-muted-foreground group-hover:text-foreground font-mono text-xs">
{color.scale}
</span>
</div>
</button>
)
}
2. 调色板组件(ColorPalette.tsx)
调色板组件组织和管理整个颜色系列:
export function ColorPalette({ colorPalette }: { colorPalette: ColorPalette }) {
return (
<div id={colorPalette.name} className="scroll-mt-20 rounded-lg">
<div className="flex items-center px-4">
<div className="flex-1 pl-1 text-sm font-medium">
<h2 className="capitalize">{colorPalette.name}</h2>
</div>
<ColorFormatSelector color={colorPalette.colors[0]} />
</div>
<div className="flex flex-col gap-4 py-4 sm:flex-row sm:gap-2">
{colorPalette.colors.map((color) => (
<Color key={color.hex} color={color} />
))}
</div>
</div>
)
}
3. 颜色格式选择器(ColorFormatSelector.tsx)
提供用户友好的格式切换功能:
export function ColorFormatSelector({ color }: { color: Color }) {
const { format, setFormat, isLoading } = useColors()
const formats = React.useMemo(() => getColorFormat(color), [color])
return (
<Select value={format} onValueChange={setFormat}>
<SelectTrigger className="bg-secondary text-secondary-foreground border-secondary">
<span className="font-medium">Format: </span>
<span className="text-muted-foreground font-mono">{format}</span>
</SelectTrigger>
<SelectContent align="end" className="rounded-xl">
{Object.entries(formats).map(([format, value]) => (
<SelectItem key={format} value={format}>
<span className="font-medium">{format}</span>
<span className="text-muted-foreground font-mono text-xs">
{value}
</span>
</SelectItem>
))}
</SelectContent>
</Select>
)
}
核心技术实现
1. 颜色工具库(colors.ts)
颜色工具库提供核心的颜色处理功能:
// 获取颜色格式映射
export function getColorFormat(color: Color) {
return {
className: `bg-${color.name}-100`,
hex: color.hex,
rgb: color.rgb,
hsl: color.hsl,
oklch: color.oklch,
var: `--color-${color.name}-${color.scale}`,
}
}
// 自动计算前景色(基于亮度)
function getForegroundFromBackground(rgb: string) {
const [r, g, b] = rgb.split(" ").map(Number)
function toLinear(number: number): number {
const base = number / 255
return base <= 0.04045 ? base / 12.92 : Math.pow((base + 0.055) / 1.055, 2.4)
}
const luminance = 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b)
return luminance > 0.179 ? "#000" : "#fff"
}
2. 状态管理(use-colors.ts)
使用Jotai进行状态管理,确保颜色选择的持久化:
type Config = {
format: ColorFormat
lastCopied: string
}
const colorsAtom = atomWithStorage<Config>("colors", {
format: "hsl",
lastCopied: "",
})
export function useColors() {
const [colors, setColors] = useAtom(colorsAtom)
const mounted = useMounted()
return {
isLoading: !mounted,
format: colors.format,
lastCopied: colors.lastCopied,
setFormat: (format: ColorFormat) => setColors({ ...colors, format }),
setLastCopied: (lastCopied: string) => setColors({ ...colors, lastCopied }),
}
}
颜色格式支持对比
项目支持多种颜色格式,每种格式都有其特定的应用场景:
格式类型 | 语法示例 | 优点 | 缺点 |
---|---|---|---|
HEX | #3b82f6 | 简洁,广泛支持 | 不直观,难以调整 |
RGB | rgb(59, 130, 246) | 直观,易于理解 | 不便于颜色操作 |
HSL | hsl(217.2, 91.2%, 59.8%) | 直观,易于调整 | 设备依赖性 |
OKLCH | oklch(0.62, 0.19, 260) | 感知均匀,现代化 | 较新,支持有限 |
CSS变量 | var(--color-blue-500) | 主题化,动态性 | 需要预处理 |
交互流程分析
最佳实践与使用建议
1. 颜色选择策略
- 主要颜色:使用500级别的颜色作为主要品牌色
- 辅助颜色:使用300-400级别用于悬停状态
- 背景颜色:使用50-100级别用于背景
- 文本颜色:使用700-900级别用于正文文本
2. 可访问性考虑
系统自动计算前景色确保文本可读性:
// 基于WCAG 2.0对比度标准
const luminance = 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b)
return luminance > 0.179 ? "#000" : "#fff" // 4.5:1对比度阈值
3. 性能优化
- 使用React.memo避免不必要的重渲染
- 使用useMemo缓存格式计算
- 懒加载颜色选择器组件
扩展与自定义
添加自定义调色板
// 在registry-colors.ts中添加自定义颜色
export const colors = {
// ... 现有颜色
custom: [
{
scale: 500,
hex: "#8B5CF6",
rgb: "rgb(139, 92, 246)",
hsl: "hsl(258.3, 89.5%, 66.3%)",
oklch: "oklch(0.65, 0.25, 302)",
},
// ... 其他层级
]
}
自定义颜色格式
// 扩展颜色格式支持
function getColorFormat(color: Color) {
return {
// ... 现有格式
custom: `custom-${color.name}-${color.scale}`,
}
}
总结
GitHub_Trending/ui/ui的颜色系统提供了一个完整、可扩展的颜色管理解决方案。通过精心设计的组件架构、智能的颜色计算和用户友好的交互设计,该系统能够满足现代Web应用对颜色管理的各种需求。
关键特性包括:
- ✅ 完整的Tailwind CSS调色板支持
- ✅ 多格式颜色值支持(HEX、RGB、HSL、OKLCH)
- ✅ 智能前景色自动计算
- ✅ 持久化的用户偏好设置
- ✅ 优雅的复制交互体验
- ✅ 可访问性最佳实践
这套颜色系统不仅提供了美观的视觉展示,更重要的是为开发者提供了强大的工具来构建一致、可访问且用户友好的界面。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考