Zephora UI

구성

모든 Zephora 컴포넌트를 위한 전역 설정 — 앱을 ZephoraConfigProvider로 한 번 감싸고 locale, 오버레이 z-index 레이어, 포털 컨테이너와 헤드리스 기본값을 구성하세요.

설정

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

Prop타입기본값설명
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 훅은 스킴을 해석하며(mode: "system"이면 OS 설정을 실시간으로 따릅니다), 기본적으로 해석된 테마를 전역으로 적용합니다:

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

Prop타입기본값설명
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?)는 OS 설정에 따라 테마를 전환하는 정적 스타일시트를 생성합니다 — 잘못된 테마의 깜빡임 없이, 페인트 전에 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>
  );
}

슬롯 classNames

다중 슬롯 컴포넌트(Dialog, Sheet, Tabs, Card, Popover, Tooltip…)는 슬롯별 클래스 계약을 노출합니다: 루트는 Partial<Record<<Name>Slot, string>>로 타입이 지정된 classNames를 허용합니다(DialogSlot 같은 슬롯 이름 유니온이 내보내집니다). 슬롯 클래스는 모듈 클래스 뒤에 추가되며 unstyled에 의해 차단되지 않습니다 — 스타일 적용 모드와 미적용 모드 모두에서 작동하며, 미적용 모드에서는 유일한 클래스가 됩니다. classNames.root는 기존 className prop과 함께 병합되며, className은 루트를 계속 대상으로 하고 가장 마지막에 적용됩니다. 복합 컴포넌트의 경우 classNames는 루트에서 한 번 설정되어 context를 통해 각 부분으로 전달됩니다.

서버 컴포넌트

게시된 @zephora/react 번들은 "use client" 지시문과 함께 제공되므로, 지시문을 직접 추가하지 않고도 React Server Component 트리(Next.js app router) 안에서 컴포넌트를 직접 가져올 수 있습니다 — 모든 Zephora 컴포넌트는 클라이언트 컴포넌트입니다.