Configuration
Réglages globaux pour chaque composant Zephora — enveloppez votre application une seule fois avec ZephoraConfigProvider et configurez la locale, les couches de z-index des overlays, le conteneur du portail et le défaut headless.
Mise en place
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 | Type | Défaut | Description |
|---|---|---|---|
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. |
Lire la configuration
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")} />;
}Couches de z-index
Les composants tirent leur ordre d'empilement de variables CSS avec des valeurs de repli intégrées, si bien que le provider comme le CSS brut peuvent les réajuster :
: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;
}Mode sombre
@zephora/theme fournit des utilitaires de mode sombre automatiques. Le hook useColorScheme résout un schéma (avec mode: "system", il suit la préférence de l'OS en direct) et applique par défaut le thème résolu globalement :
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 | Type | Défaut | Description |
|---|---|---|---|
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. |
Les primitives de plus bas niveau sont également exportées :
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 sans FOUC
Pour le rendu côté serveur, colorSchemeCss(light?, dark?) construit une feuille de style statique qui bascule les thèmes selon la préférence de l'OS — aucun flash du mauvais thème, aucun JavaScript requis avant le paint. Définir data-zephora-scheme sur <html> surcharge la media query (branchez-le sur un bouton utilisateur) :
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
Les composants multi-slots (Dialog, Sheet, Tabs, Card, Popover, Tooltip…) exposent un contrat de classes par slot : la racine accepte classNames typé comme Partial<Record<<Name>Slot, string>> (les unions de noms de slots comme DialogSlot sont exportées). Les classes de slots sont ajoutées après les classes du module et ne sont pas conditionnées par unstyled — elles fonctionnent en mode stylé comme non stylé ; en mode non stylé, elles sont les seules classes. classNames.root se combine avec le prop className existant, qui continue de cibler la racine et est appliqué en dernier. Pour les composants composés, classNames est défini une fois sur la racine et transmis aux parties via le context.
Composants serveur
Le bundle publié @zephora/react est livré avec une directive "use client", vous pouvez donc importer les composants directement dans des arbres de React Server Component (app router de Next.js) sans ajouter vous-même la directive — chaque composant Zephora est un composant client.