Configuración
Ajustes globales para cada componente de Zephora — envuelve tu aplicación una sola vez con ZephoraConfigProvider y configura la locale, las capas de z-index de los overlays, el contenedor del portal y el valor por defecto headless.
Configuración inicial
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 | Tipo | Predeterminado | Descripción |
|---|---|---|---|
locale | string | "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. |
appendTo | HTMLElement | null | document.body | Container that Portal-based overlays (Dialog, Select menus, Tooltip…) render into. |
unstyled | boolean | false | Makes every component headless by default for Tailwind-first apps. A per-component unstyled prop still wins. |
Leer la configuración
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")} />;
}Capas de z-index
Los componentes toman su orden de apilamiento de variables CSS con valores de reserva integrados, de modo que tanto el provider como el CSS plano pueden reajustarlas:
: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;
}Modo oscuro
@zephora/theme incluye utilidades automáticas de modo oscuro. El hook useColorScheme resuelve un esquema (con mode: "system" sigue la preferencia del sistema operativo en vivo) y por defecto aplica el tema resuelto de forma global:
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 | Tipo | Predeterminado | Descripción |
|---|---|---|---|
mode | "light" | "dark" | "system" | "system" | "system" follows the OS preference live; "light"/"dark" force a scheme. |
light / dark | Theme | lightTheme / darkTheme | Theme objects used for each scheme. |
apply | boolean | true | Write the resolved theme to document.documentElement via applyTheme. |
→ returns | { scheme: "light" | "dark"; theme: Theme } | — | The resolved scheme and the theme object in effect. |
Las primitivas de nivel inferior también se exportan:
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();SSR sin FOUC
Para el renderizado en el servidor, colorSchemeCss(light?, dark?) construye una hoja de estilos estática que cambia de tema según la preferencia del sistema operativo — sin destello del tema incorrecto, sin necesidad de JavaScript antes del paint. Establecer data-zephora-scheme en <html> sobrescribe la media query (conéctalo a un interruptor del usuario):
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 de slots
Los componentes multi-slot (Dialog, Sheet, Tabs, Card, Popover, Tooltip…) exponen un contrato de clases por slot: la raíz acepta classNames tipado como Partial<Record<<Name>Slot, string>> (las uniones de nombres de slot como DialogSlot se exportan). Las clases de slot se añaden después de las clases del módulo y no dependen de unstyled — funcionan tanto en modo con estilo como sin estilo; en modo sin estilo son las únicas clases. classNames.root se combina junto al prop className existente, que sigue apuntando a la raíz y se aplica en último lugar. Para componentes compuestos, classNames se establece una vez en la raíz y se traslada a las partes mediante el context.
Componentes de servidor
El bundle publicado @zephora/react se distribuye con una directiva "use client", por lo que puedes importar los componentes directamente dentro de árboles de React Server Component (app router de Next.js) sin añadir tú mismo la directiva — cada componente de Zephora es un componente de cliente.