Skip to main content

Getting Started

Setup

  1. Install the library into your React project:

    npm install --save @dr.pogodin/react-themes
  2. Configure support of CSS Modules and SASS in your project:

    1. If you rely on Create React App follow these instructions:

    2. If you rely on alternative starting packs / frameworks, follow their instructions.

    3. If you rely on a barebone React setup, or the starting pack / framework you use does not suggest a way to set these up, follow these instructions:

Basic Themed Component

As the most simple example, let's consider a trivial component that just renders a <div> element wrapping the text provided via children prop:

/src/components/BasicExample/index.jsx
import React from 'react';

export default function BasicExample({ children }) {
return <div>{children}</div>;
}

Say, we want to style this component as a button, using React Themes library to make it easily themeable based on context. This is going to be our default theme:

src/components/BasicExample/default.module.scss
// Boilerplate required by React Themes
*,
.context,
.ad.hoc {

// The actual styling.
&.component {
background: #4169e1;
border-radius: 20px;
color: #f5f5f5;
display: inline-block;
padding: 6px 24px;
margin-bottom: 1em;
}
}

It consists of .component class with default button styling we want to apply to the <div> element, and that class is wrapped into small boilerplate, which will be explained later. With this theme stylesheet at hands we update the BasicExample in the following way:

src/components/BasicExample/default.scss
import React from 'react';
import PT from 'prop-types';
import themed from '@dr.pogodin/react-themes';

import defaultTheme from './default.module.scss';

// The base component.
function BasicExample({ children, theme }) {
return <div className={theme.component}>{children}</div>;
}

// The component is wrapped by React Themes "themed" helper,
// which registers it under "BasicExample" name for theming purposes,
// documents valid classnames, and specifies its default theme.
const ThemedBasicExample = themed('BasicExample', [
'component',
], defaultTheme)(BasicExample);

// This is optional, if you use "propTypes" validation, React Themes helps
// to validate theme keys.
BasicExample.propTypes = {
children: PT.string.isRequired,
theme: ThemedBasicExample.themeType.isRequired,
};

export default ThemedBasicExample;

At this point we can use the component to render a block appearing as a simple button:

Hello World!
src/components/Example01.jsx
import React from 'react';
import BasicExample from './BasicExample';

export default function Example01() {
return <BasicExample>Hello World!</BasicExample>;
}

Now, say some part of your app uses a blue background, where our sample component as is does not look great:

Hello World!
Hello World!
Hello World!
src/components/Example02.jsx
import React from 'react';
import BasicExample from './BasicExample';

export default function Example02() {
return (
<div style={{background: 'blue', padding: '1em 1em 0'}}>
<BasicExample>Hello World!</BasicExample>
<BasicExample>Hello World!</BasicExample>
<BasicExample>Hello World!</BasicExample>
</div>
);
}

Let's use React Themes to apply additional "blue context" theme for our component within blue-background section of the app. This is our additional theme (note, we only define color overrides, and remaining layout styling will be inherited from the original default theme):

src/components/BasicExample/blue-context.module.scss
*,
.context,
.ad.hoc {
&.component {
background: white;
color: #4169e1;
font-weight: bold;
}
}

And we update the example using ThemeProvider component from React Themes. All BasicExample component instances anywhere within this ThemeProvider sub-tree will get the "blue context" theme automatically applied to them:

Hello World!
Hello World!
Hello World!
src/components/Example03.jsx
import React from 'react';
import { ThemeProvider } from '@dr.pogodin/react-themes';

import BasicExample from './BasicExample';
import blueContextTheme from './BasicExample/blue-context.module.scss';

export default function Example02() {
return (
<ThemeProvider themes={{ BasicExample: blueContextTheme }}>
<div style={{background: 'blue', padding: '1em 1em 0'}}>
<BasicExample>Hello World!</BasicExample>
<BasicExample>Hello World!</BasicExample>
<BasicExample>Hello World!</BasicExample>
</div>
</ThemeProvider>
);
}

Now, say we want to add some particular styling to a selected component instance, for example: a different label color, border, and some extra margin around the central component in our example (sure, it would be better to take care about correct horizontal margins inside the default theme, but for the sake of example here we use ad hoc styling of particular component for that).

Here is the sample ad hoc theme we'll use:

src/components/Example04/style.module.scss
*,
.context,
.ad.hoc {
&.component {
border: 1px solid red;
color: red;
margin-left: 1em;
margin-right: 1em;
}
}

And here is how we use it:

Hello World!
Hello World!
Hello World!
src/components/Example04/index.jsx
import React from 'react';
import { ThemeProvider } from '@dr.pogodin/react-themes';

import BasicExample from '../BasicExample';
import blueContextTheme from '../BasicExample/blue-context.module.scss';

import adHocTheme from './style.module.scss';

export default function Example02() {
return (
<ThemeProvider themes={{ BasicExample: blueContextTheme }}>
<div style={{background: 'blue', padding: '1em 1em 0'}}>
<BasicExample>Hello World!</BasicExample>
<BasicExample theme={adHocTheme}>Hello World!</BasicExample>
<BasicExample>Hello World!</BasicExample>
</div>
</ThemeProvider>
);
}