Skip to main content

Overview

The ThemeProvider is an essential component that applies styling and theming to all Natura Design System components. It must wrap your application or the portion of your app using natds-react components.

Installation

The ThemeProvider is included when you install @naturacosmeticos/natds-react:
npm install @naturacosmeticos/natds-react
This will also install required dependencies:
  • @naturacosmeticos/natds-icons
  • @naturacosmeticos/natds-themes
  • react-jss

Basic Usage

import React from 'react'
import { ThemeProvider, Button, buildTheme } from '@naturacosmeticos/natds-react'

const theme = buildTheme('natura', 'light')

export const App = () => (
  <ThemeProvider theme={theme}>
    <Button variant="contained">
      Hello World
    </Button>
  </ThemeProvider>
)

Props

theme
Theme
required
The theme object to be applied. Use the buildTheme utility to create a theme based on your brand and mode.
children
React.ReactNode
required
The application components that will receive the theme.
cssPrefix
string
A CSS prefix to be added to dynamic class names generation. This option isolates generated class names and is useful for micro frontend architectures.Important: To avoid conflicts with multiple style fonts, it is recommended to always provide a unique cssPrefix.

Usage with CSS Prefix

When building micro frontends or when you need to isolate styles, use the cssPrefix prop:
import React from 'react'
import { ThemeProvider, buildTheme } from '@naturacosmeticos/natds-react'

const theme = buildTheme('natura', 'light')

export const App = () => (
  <ThemeProvider theme={theme} cssPrefix="my-app">
    {/* Your components */}
  </ThemeProvider>
)
This will prefix all generated CSS class names with my-app-, preventing style collisions.

Multiple Brands

You can switch between different brand themes by changing the theme prop:
import React, { useState } from 'react'
import { ThemeProvider, buildTheme, Button } from '@naturacosmeticos/natds-react'
import type { Brand } from '@naturacosmeticos/natds-react'

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

  return (
    <ThemeProvider theme={theme}>
      <Button onClick={() => setBrand('avon')}>
        Switch to Avon
      </Button>
      <Button onClick={() => setBrand('theBodyShop')}>
        Switch to The Body Shop
      </Button>
      {/* Your app content */}
    </ThemeProvider>
  )
}

Dark Mode Support

Toggle between light and dark modes by changing the mode parameter in buildTheme:
import React, { useState } from 'react'
import { ThemeProvider, buildTheme, Button } from '@naturacosmeticos/natds-react'
import type { ThemeMode } from '@naturacosmeticos/natds-react'

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

  return (
    <ThemeProvider theme={theme}>
      <Button onClick={() => setMode(mode === 'light' ? 'dark' : 'light')}>
        Toggle {mode === 'light' ? 'Dark' : 'Light'} Mode
      </Button>
      {/* Your app content */}
    </ThemeProvider>
  )
}

Loading Fonts

Roboto Font

Load the Roboto font with 400 and 500 font weights:
<link href="https://fonts.googleapis.com/css2?family=Roboto+Mono&family=Roboto:wght@400;500&display=swap" rel="stylesheet" />

Brand Custom Fonts

Load brand-specific fonts by adding this to your index.html:
<!-- For Natura -->
<link href="https://cdn.jsdelivr.net/npm/@naturacosmeticos/natds-themes@latest/dist/assets/natura_fonts.css" rel="stylesheet" />

<!-- For Avon -->
<link href="https://cdn.jsdelivr.net/npm/@naturacosmeticos/natds-themes@latest/dist/assets/avon_fonts.css" rel="stylesheet" />

<!-- For The Body Shop -->
<link href="https://cdn.jsdelivr.net/npm/@naturacosmeticos/natds-themes@latest/dist/assets/theBodyShop_fonts.css" rel="stylesheet" />

<!-- For Aesop -->
<link href="https://cdn.jsdelivr.net/npm/@naturacosmeticos/natds-themes@latest/dist/assets/aesop_fonts.css" rel="stylesheet" />

Loading Icons

Load the Natura Design System icon font: Via CDN:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@naturacosmeticos/natds-icons@latest/dist/natds-icons.css">
Via npm/yarn:
import '@naturacosmeticos/natds-icons/natds-icons.css'

Implementation Details

The ThemeProvider uses react-jss under the hood to provide styling capabilities:
ThemeProvider.tsx
import React from 'react'
import { JssProvider, ThemeProvider as Provider } from 'react-jss'
import { ThemeProviderProps } from './ThemeProvider.props'

const ThemeProvider = ({ children, cssPrefix, theme }: ThemeProviderProps): JSX.Element => (
  <JssProvider classNamePrefix={cssPrefix}>
    <Provider theme={theme}>
      {children}
    </Provider>
  </JssProvider>
)

export default ThemeProvider

TypeScript Support

The ThemeProvider is fully typed:
import { Theme } from '@naturacosmeticos/natds-themes'

interface ThemeProviderProps {
  /**
   * The application
   */
  children: React.ReactNode

  /**
   * Theme to be used
   */
  theme: Theme

  /**
   * A css prefix to be added in the dynamic class names generation.
   * This option is used to isolate the generated class names and
   * it is useful if you are developing a micro frontend
   */
  cssPrefix?: string
}

Best Practices

To avoid problems with multiple style fonts and class name collisions, always provide a unique cssPrefix when using ThemeProvider.
Do not try to override theme palette or other tokens. The Design System themes are ready to use and maintain consistency across all brands.
Use only one ThemeProvider at the root of your application. Nested ThemeProviders can cause unexpected styling behavior.
Ensure brand-specific fonts are loaded before your application renders to prevent flash of unstyled content (FOUC).

See Also

Build docs developers (and LLMs) love