// preview in
saved for every page

Installation

Two packages, one stylesheet per skin and a StyleProvider. Works with the Next.js App Router, Vite and any React 19 app.

// you'll learn

  • Which packages and CSS files to add
  • How to pick a skin, a mode and a brand color for the whole app
  • How to switch the components' built-in texts to Portuguese

Install the packages

@camaleo/react has the components; @camaleo/styles has the CSS and createBrand.

terminal
pnpm add @camaleo/react @camaleo/styles

Import the CSS

Import base.css once, then one file per skin you use. minimal is the default and needs no file of its own.

app/layout.tsx
import "@camaleo/styles/base.css";
import "@camaleo/styles/neumorphism.css";

Fonts are not bundled. Each skin's fonts are listed in Skins & switching; without them the skin falls back to system fonts.

Wrap the app

StyleProvider applies the skin, the mode and the brand color to everything inside it, popups included.

app/providers.tsx
import { Button, StyleProvider } from "@camaleo/react";

<StyleProvider styleName="neumorphism" mode="system" brand="#7c3aed">
  <Button>Save</Button>
</StyleProvider>
PropValues
styleNameminimal (default), swiss, editorial, progressive, material, cupertino, glass, neumorphism, clay, neubrutalism, retro, retro-pixel, y2k
modelight, dark or system. Left out, it inherits from the parent; at the root it follows the system, with no script
brandAny CSS color. The library builds the scale and keeps text on it at 4.5:1 or more

To skin the whole page from a Server Component, spread styleScopeProps on <html> instead:

app/layout.tsx
import { styleScopeProps } from "@camaleo/react/style-scope";

<html lang="en" {...styleScopeProps({ styleName: "editorial" })}>
TIP

material is inspired by Material Design and cupertino by the Human Interface Guidelines. Camaleo is not affiliated with Google or Apple and uses none of their fonts, icons or trademarks.

Set the component texts

Components that show or announce text on their own (close buttons, "Page 3", empty states) speak English by default. For Brazilian Portuguese, wrap the app once with MessagesProvider:

app/layout.tsx
import { MessagesProvider } from "@camaleo/react";

<MessagesProvider locale="pt-BR">{children}</MessagesProvider>
  • locale: "en" or "pt-BR", the sets bundled with the library. This is the form to use in a Server Component.
  • messages: only the keys you want to change, merged over the locale, for example messages={{ toast: { close: "Dismiss" } }}. Some keys are functions (pagination.page), which only a client component can pass.
  • A component's own prop (say closeLabel) still wins over both. More in Languages & RTL.

Customize

From least to most invasive:

  1. Tokens. Set them on [data-style], outside any layer, and they beat the library: [data-style] { --cml-radius-control: 4px; }. A plain :root doesn't reach inside a provider, because every provider declares the tokens again. See Tokens.
  2. Parts. Target a component's data-slot and state attributes: [data-slot="button"][data-variant="outline"] { … }. To limit a rule to an area or a skin, see Scoped overrides.
  3. Markup. Use className, style or the render prop to change the element a component renders.

Before you ship it

  • @camaleo/react and @camaleo/styles installed
  • base.css imported once, then a file for each skin you use
  • The app wrapped in a StyleProvider (or <html> with styleScopeProps)
  • MessagesProvider set if your app isn't in English
Was this page helpful? · Edit this page on GitHub