Chroma Panel

搜索文档

查找页面或章节

EN

深色模式

查看 Markdown

跟随系统、固定主题,或与你的主题切换保持一致。

默认情况下,选择器跟随操作系统的设置。一旦你的应用有了自己的主题切换,问题就来了:两者会不一致。比如有人在浅色的桌面系统上以深色模式浏览你的网站,打开选择器看到的却是一个白色面板。把应用最终生效的主题交给选择器,这个问题就解决了。

"use client";
 
import { ColorInput } from "chroma-panel";
import "chroma-panel/style.css";
import { useTheme } from "next-themes";
 
function panelTheme(value: string | undefined) {
  if (value === "dark") return "dark" as const;
  if (value === "light") return "light" as const;
  return undefined;
}
 
export function ThemedColorInput() {
  const { resolvedTheme } = useTheme();
 
  return (
    <ColorInput
      name="brand"
      defaultValue="#3366cc"
      theme={panelTheme(resolvedTheme)}
    />
  );
}

theme 只接受 "dark""light",而 resolvedTheme 的类型是 string | undefined,所以上面的类型收窄并不是多此一举。返回 undefined 也是有意义的:不传 theme 时,面板会回到跟随系统偏好的状态。在 provider 还没解析出主题之前,这就是最合理的选择。

ChromaPanel 上也有同一个 prop,两者用法完全相同。它和面板的其他 prop 放在一起的情况,请参阅 ChromaPanel 参考文档

跟随系统

这是默认行为。面板的背景、边框、文字和强调色都以 light-dark() 成对声明,面板根元素上声明了 color-scheme: light dark,浏览器会根据用户的偏好选择对应的一侧。不用传任何参数,不涉及水合,首次绘制也不会闪烁,因为这个选择是在 CSS 中完成的,而不是在 JavaScript 中。

固定为一种主题

如果周围的界面不会变,就直接传入 theme。比如在深色编辑器外框中的选择器,即使整个应用是浅色的,也应该保持深色:

<ChromaPanel theme="dark" defaultValue="#3366cc" />

样式表如何决定主题

theme 会以 data-cp-theme 属性的形式出现在面板根元素上,值为 darklight。样式表随后把这个根元素的 color-scheme 设为对应的单一值,于是每个 light-dark() 令牌都会取这一侧的值。如果什么都不传,就不会有这个属性,color-scheme: light dark 保持不变,由用户偏好决定。

宽度小于 640px 时,选择器会变成底部面板,它的样式是单独匹配的,所以遮罩和面板背景会跟随其中的面板,而不会各行其是。

由于这个属性就在面板根元素上,面板进入弹出层时它也会跟着走。弹出层渲染在 document.body 中,而不在你的布局里,因此作用于某个外层元素的深色样式影响不到它,而针对 .cp-root 的选择器可以。

修改深色配色

这个包的样式规则都放在 @layer chroma-panel 级联层中,而不在任何层中的 CSS 优先级高于层内的规则。所以你自己的样式表可以替换任意令牌,不必和选择器优先级较劲:

.cp-root {
  --cp-surface: light-dark(#ffffff, #0b0b0f);
  --cp-accent: light-dark(#2d7ff9, #7aa2ff);
}

把覆盖值也写成 light-dark() 对,就能在一条规则里同时写好两侧,自动切换也能照常工作。完整的令牌列表见主题页面;在 Next.js App Router 中使用选择器的方法,见 Next.js 页面

两种变深色的方式

theme 只作用于面板本身。--cp- 自定义属性决定面板具体用哪些颜色。用 theme 选择深浅;如果内置的深色不是你想要的深色,就用这些自定义属性。