Zephora UI

配置

为每个 Zephora 组件提供全局设置 — 用 ZephoraConfigProvider 包裹你的应用一次,即可配置 locale、遮罩 z-index 层级、portal 容器以及无头默认值。

配置

import { ZephoraConfigProvider } from "@zephora/react";

export default function App() {
  return (
    <ZephoraConfigProvider
      locale="tr"
      zIndex={{ modal: 2000, toast: 2100 }}
      appendTo={typeof document !== "undefined" ? document.body : null}
      unstyled={false}
    >
      <YourApp />
    </ZephoraConfigProvider>
  );
}

ZephoraConfigProvider props

属性类型默认值说明
localestring"en"Active locale for component UI strings. Only "en" is embedded; load others from @zephora/theme/locales/* (module or JSON) and register with addLocale().
zIndex{ dropdown?, overlay?, modal?, popover?, toast?, tooltip?: number }Overrides the layering of floating elements. Written as --z-index-* CSS variables on the root element.
appendToHTMLElement | nulldocument.bodyContainer that Portal-based overlays (Dialog, Select menus, Tooltip…) render into.
unstyledbooleanfalseMakes every component headless by default for Tailwind-first apps. A per-component unstyled prop still wins.

读取配置

import { useZephoraConfig, useLocale } from "@zephora/react";

function MyField() {
  const config = useZephoraConfig(); // { locale, zIndex, appendTo, unstyled }
  const { t, messages, locale } = useLocale();
  return <button aria-label={t("close")} />;
}

z-index 层级

组件从带内置回退值的 CSS 变量中获取堆叠顺序,因此 provider 和纯 CSS 都能对其重新调整:

:root {
  --z-index-dropdown: 1000;
  --z-index-overlay: 1040;
  --z-index-modal: 1050;
  --z-index-popover: 1060;
  --z-index-toast: 1070;
  --z-index-tooltip: 1080;
}

深色模式

@zephora/theme 内置了自动深色模式辅助工具。useColorScheme hook 会解析出一个配色方案(配合 mode: "system" 会实时跟随操作系统偏好),并默认将解析出的主题全局应用:

import { useColorScheme } from "@zephora/theme";

function App() {
  // mode: "light" | "dark" | "system" (default "system")
  const { scheme, theme } = useColorScheme({ mode: "system" });
  return <span>Active scheme: {scheme}</span>;
}

useColorScheme(options) props

属性类型默认值说明
mode"light" | "dark" | "system""system""system" follows the OS preference live; "light"/"dark" force a scheme.
light / darkThemelightTheme / darkThemeTheme objects used for each scheme.
applybooleantrueWrite the resolved theme to document.documentElement via applyTheme.
→ returns{ scheme: "light" | "dark"; theme: Theme }The resolved scheme and the theme object in effect.

更底层的原语(primitive)也一并导出:

import { getSystemColorScheme, watchSystemColorScheme } from "@zephora/theme";

// Reads the OS color scheme (SSR-safe; defaults to "light").
const scheme = getSystemColorScheme(); // "light" | "dark"

// Subscribes to OS changes. Returns an unsubscribe function.
const stop = watchSystemColorScheme((next) => console.log(next));
stop();

无 FOUC 的 SSR

对于服务端渲染,colorSchemeCss(light?, dark?) 会构建一个随操作系统偏好切换主题的静态样式表 — 不会闪现错误主题,绘制前也无需 JavaScript。在 <html> 上设置 data-zephora-scheme 可覆盖媒体查询(将其接到用户的开关上):

import { colorSchemeCss } from "@zephora/theme";

// Next.js app router — app/layout.tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <head>
        <style dangerouslySetInnerHTML={{ __html: colorSchemeCss() }} />
      </head>
      <body>{children}</body>
    </html>
  );
}

Slot classNames

多插槽组件(Dialog、Sheet、Tabs、Card、Popover、Tooltip…)提供了按插槽划分的 class 约定:根组件接受类型为 Partial<Record<<Name>Slot, string>>classNames(诸如 DialogSlot 之类的插槽名联合类型会被导出)。插槽 class 会追加在模块 class 之后,且不受 unstyled 影响 — 在样式化和无样式模式下都生效;在无样式模式下它们是唯一的 class。classNames.root 会与现有的 className prop 合并,className 仍指向根组件并最后应用。对于复合组件,classNames 在根上设置一次,并通过 context 传递给各部分。

服务器组件

已发布的 @zephora/react 包自带 "use client" 指令,因此你可以直接在 React Server Component 树(Next.js app router)中导入组件,而无需自己添加该指令 — 每个 Zephora 组件都是客户端组件。