选择器的底栏中有一行最近使用过的颜色,默认情况下,每次挂载时这一行都是空的。如果用户会经常回到同一个选择器,比如画布编辑器或后台的主题设置页,重新找到昨天用过的颜色往往最费时间,这时就值得把它保存下来。这个列表只是一个普通的字符串数组,存在哪里由你决定。
"use client";
import { ColorInput } from "chroma-panel";
import "chroma-panel/style.css";
import { useEffect, useState } from "react";
const STORAGE_KEY = "chroma-panel:recent";
export function BrandColorInput() {
const [recent, setRecent] = useState<string[]>([]);
useEffect(() => {
const raw = window.localStorage.getItem(STORAGE_KEY);
if (raw === null) return;
try {
const parsed: unknown = JSON.parse(raw);
if (Array.isArray(parsed)) {
setRecent(parsed.filter((c): c is string => typeof c === "string"));
}
} catch {
window.localStorage.removeItem(STORAGE_KEY);
}
}, []);
return (
<ColorInput
name="brand"
defaultValue="#3366cc"
recentColors={recent}
onRecentColorsChange={(colors) => {
setRecent(colors);
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(colors));
}}
/>
);
}读取操作放在 effect 中,而不是渲染过程中,这样服务端渲染和客户端首次渲染得到的都是空列表,不会出现不一致。通用规则请参阅服务端渲染。
哪些颜色会进入列表
面板添加颜色的时机和 onChangeComplete 触发的时机相同:在修改提交时,而不是拖动过程中。颜色以六位十六进制字符串的形式加入,所以即使开启了 showAlpha,历史记录中也不包含透明度。
添加之前,列表会按颜色而不是按字符串去重,所以 #3366CC 和 #3366cc 算作同一项,然后最多保留十个。onRecentColorsChange 每次交给你的都是处理完毕的列表,所以上面的回调可以直接把参数原样存起来。
可能少显示一个色块
底栏会隐藏与当前选中颜色相同的那个最近使用色块,因为点击它不会有任何效果。存储的列表仍然是完整的,只是这一行看起来少了一个。
受控还是非受控
recentColors 和 defaultRecentColors 的用法与 value 和 defaultValue 相同,详见受控与非受控。
传入 defaultRecentColors 可以设置列表的初始值,之后交给面板自己管理。它只在面板挂载时读取一次,所以在 effect 中从存储里读出的列表对它来说已经太晚了。这正是 recentColors 的用途,也是开头示例使用它的原因。
<ColorInput defaultRecentColors={["#3366cc", "#cc3366"]} />传入 recentColors 后,面板就不再保存自己的副本。它会用新列表应有的内容调用 onRecentColorsChange,然后渲染你传回的列表。所以如果忘了保存结果,这一行就会一直不变。
自己添加颜色
如果你在面板之外还有自己的色块按钮,可以用 pushRecent,它和面板遵循同样的规则,两条路径得到的是同一份一致的历史记录。
import { pushRecent } from "chroma-panel";
setRecent((current) => pushRecent(current, "#cc3366"));它的签名是 pushRecent(list, hex, limit?),limit 默认为十。它返回一个新数组,不会修改你传入的数组。
关闭这一行
showRecentColors={false} 会把它去掉。一次性的选择器没有值得保留的历史,就可以这样做。这一行本身以及它旁边的取色器,详见 PanelFooter 参考文档。