Skip to main content

Overview

Natura Design System provides pre-configured themes for multiple brands within the Natura&Co family. Each theme includes brand-specific colors, typography, spacing, and component styles.

Available Brands

The following brands are available in natds-react:

Natura

The flagship brand with earthy, natural design tokens

Avon

Beauty brand with vibrant, empowering design tokens

The Body Shop

Activist beauty brand with bold, ethical design tokens

Aesop

Luxury skincare brand with minimalist, sophisticated design tokens

Brand Type Definition

The available brands are defined in the TypeScript types:
type Brand = 'natura' | 'natura_v3' | 'avon' | 'avon_v2' | 'avon_v3' | 'theBodyShop' | 'aesop' | 'biome'

Theme Modes

Each brand theme supports two modes:
  • light: Light color scheme (default)
  • dark: Dark color scheme
type ThemeMode = 'light' | 'dark'

buildTheme Utility

The buildTheme function creates a theme object for use with ThemeProvider.

Signature

function buildTheme(
  brand?: Brand,
  mode?: ThemeMode
): Theme

Parameters

brand
Brand
default:"natura"
The brand name to apply. Options: 'natura', 'avon', 'theBodyShop', 'aesop', 'natura_v3', 'avon_v2', 'avon_v3', 'biome'
mode
ThemeMode
default:"light"
The color scheme for the theme. Options: 'light' or 'dark'

Returns

Returns a Theme object that can be passed to ThemeProvider.

Usage

import { buildTheme } from '@naturacosmeticos/natds-react'

// Default: Natura Light theme
const defaultTheme = buildTheme()

// Natura Light theme (explicit)
const naturaLight = buildTheme('natura', 'light')

// Natura Dark theme
const naturaDark = buildTheme('natura', 'dark')

// Avon Light theme
const avonLight = buildTheme('avon', 'light')

// The Body Shop Dark theme
const tbsDark = buildTheme('theBodyShop', 'dark')

// Aesop Light theme
const aesopLight = buildTheme('aesop', 'light')

Theme Object Structure

The theme object returned by buildTheme contains the following properties:

Color Tokens

theme.color // Brand-specific color palette
theme.palette // Material-UI compatible palette

Typography

theme.typography = {
  fontFamily: string,
  fontFamilyBrand1: string,
  fontFamilyBrand2: string,
  fontFamilyBrand3: string,
  fontWeightRegular: number,
  fontWeightMedium: number,
  fontWeightBold: number,
  fontWeightLight: number,
  h1: IFont,
  h2: IFont,
  h3: IFont,
  h4: IFont,
  h5: IFont,
  h6: IFont,
  body1: IFont,
  body2: IFont,
  subtitle1: IFont,
  subtitle2: IFont,
  button: IFont,
  caption: IFont,
  overline: IFont,
  // ... additional typography tokens
}

Spacing

theme.spacing // Function to calculate spacing units
theme.sizes // Predefined size tokens

Shapes & Borders

theme.shape = {
  borderRadius: {
    none: number,
    small: number,
    medium: number,
    large: number,
    circle: number
  }
}

Shadows & Elevation

theme.shadows // Material-UI compatible shadow definitions
theme.opacity // Opacity values for different states

Component-Specific Tokens

theme.iconSizes // Icon size definitions
theme.avatarSizes // Avatar size definitions
theme.asset // Brand assets (logos, etc.)

Direct Theme Access

You can also access themes directly without using buildTheme:
import { themes } from '@naturacosmeticos/natds-web'

// Access themes directly
const naturaLight = themes.natura.light
const naturaDark = themes.natura.dark
const avonLight = themes.avon.light
const tbsLight = themes.theBodyShop.light
const aesopLight = themes.aesop.light

Complete Example

Here’s a complete example showing theme selection:
import React, { useState } from 'react'
import { 
  ThemeProvider, 
  buildTheme, 
  Button,
  Select,
  MenuItem
} from '@naturacosmeticos/natds-react'
import type { Brand, ThemeMode } from '@naturacosmeticos/natds-react'

const App = () => {
  const [brand, setBrand] = useState<Brand>('natura')
  const [mode, setMode] = useState<ThemeMode>('light')
  
  const theme = buildTheme(brand, mode)

  return (
    <ThemeProvider theme={theme} cssPrefix="app">
      <div style={{ padding: '20px' }}>
        <Select
          value={brand}
          onChange={(e) => setBrand(e.target.value as Brand)}
          label="Select Brand"
        >
          <MenuItem value="natura">Natura</MenuItem>
          <MenuItem value="avon">Avon</MenuItem>
          <MenuItem value="theBodyShop">The Body Shop</MenuItem>
          <MenuItem value="aesop">Aesop</MenuItem>
        </Select>

        <Button 
          onClick={() => setMode(mode === 'light' ? 'dark' : 'light')}
          style={{ marginLeft: '10px' }}
        >
          Toggle {mode === 'light' ? 'Dark' : 'Light'} Mode
        </Button>

        <div style={{ marginTop: '20px' }}>
          <h1>Current Theme: {brand} ({mode})</h1>
          <Button variant="contained" color="primary">
            Primary Button
          </Button>
          <Button variant="outlined" color="secondary">
            Secondary Button
          </Button>
        </div>
      </div>
    </ThemeProvider>
  )
}

export default App

Theme Implementation Details

Under the hood, themes are parsed and transformed from the base @naturacosmeticos/natds-styles package:
themes.ts
import { themes as styleThemes } from '@naturacosmeticos/natds-styles'
import { parseTheme } from './parseTheme'
import { createThemesObject } from './createThemesObject'

export const themes = Object.keys(styleThemes).reduce((
  value: IThemesBase<ThemeBrandName>,
  key: string
) => {
  const result = value

  result[key as ThemeBrandName].dark = parseTheme(styleThemes[key as ThemeBrandName].dark)
  result[key as ThemeBrandName].light = parseTheme(styleThemes[key as ThemeBrandName].light)

  return result
}, createThemesObject())
The parseTheme function transforms shadows and typography to be compatible with Material-UI:
parseTheme.ts
import { ITheme } from '@naturacosmeticos/natds-styles'
import { parseShadows } from './parseShadows'

export const parseTheme = (theme: ITheme): IThemeWebBase => {
  const { shadows } = theme

  return {
    ...theme,
    shadows: parseShadows(shadows),
    typography: theme.typography
  }
}

TypeScript Types

import { Theme } from '@naturacosmeticos/natds-themes'
import { Brand, ThemeMode } from '@naturacosmeticos/natds-react'

// Use Theme type for theme objects
const myTheme: Theme = buildTheme('natura', 'light')

// Type-safe brand selection
const brands: Brand[] = ['natura', 'avon', 'theBodyShop', 'aesop']

// Type-safe mode selection
const modes: ThemeMode[] = ['light', 'dark']

Loading Brand Fonts

Each brand requires its custom fonts to be loaded. Add the appropriate font stylesheet to your HTML:
<!-- Choose the font file matching your selected brand -->
<link href="https://cdn.jsdelivr.net/npm/@naturacosmeticos/natds-themes@latest/dist/assets/[BRAND]_fonts.css" rel="stylesheet" />
Replace [BRAND] with: natura, avon, theBodyShop, or aesop.

Error Handling

The buildTheme function includes error handling:
buildTheme.ts
import themes, { BrandThemes, Themes, Theme } from '@naturacosmeticos/natds-themes'

const buildTheme = (brand: Brand = 'natura', mode: ThemeMode = 'light'): Theme => {
  if (!themes) {
    throw new Error('Unable to load tokens dependency. Check the installation logs for errors')
  }

  return themes[brand][mode]
}
If themes fail to load, ensure @naturacosmeticos/natds-themes is properly installed.

See Also

Build docs developers (and LLMs) love