Skip to main content

Styling & theming

Overview

Styling and theming Dopt React components is flexible and easy no matter what styling stack you prefer. We’ll go through styling components with CSS and custom themes.

info

When using Dopt React components, your bundler must be configured to interpret CSS imports via JS otherwise the component styles will not be loaded and you may run into a build error. Check out our framework specific docs for more info →

Alternatively, you can reference the component styles manually via the emitted styles.css file for each component.

With CSS

All Dopt React components come with class names that adhere to BEM naming conventions. You can target these class names in CSS or add your own class names to add or override styles. Each components’ classes are documented under their styling API.

For example, to add or override styles for the modal component’s header, you would use the following CSS rule:

.dopt-modal__header {
background: #b4d455;
}

If you’d like to use your own classes to add or override styles, you can simply pass in your own class names to the component via the className prop. This can be especially useful if you’re using a scoped CSS technique like CSS modules.

<Modal.Header className="my-custom-class">
...
</Modal.Header>

If necessary, you can also access the scoped CSS classes that are generated for the default styles through the classes export from each component package.

import { classes } from '@dopt/react-modal';

console.log(classes.modalHeader);

With custom themes

Dopt React components leverage a unified theme which consists of tokens for things like colors, typography, and spacing. You can override or extend these tokens as you go about styling the components.

Leveraging a theme can be useful for quickly styling multiple components at the same time so they all feel cohesive.

For a list of available default tokens, see the token reference.

In CSS

You can override the default theme tokens in CSS by declaring new CSS variables with a matching name for the token at the :root selector.

For example, let’s override the primary color token:

:root {
--dopt-colors-primary: '#b4d455';
}

If you’d only like to override a token for a specific component, you can do so with a locally scoped CSS variable:

.my-custom-class {
--dopt-colors-secondary: '#ba0bab';
}

This override will only apply to elements (and child elements) that .my-custom-class is applied to.

You can reference a theme token in CSS using the var() function:

.my-custom-class {
background: var(--dopt-colors-primary);
}

In JS

You can create custom themes that override or extend the default theme in JS.

Each component has a theme prop that you can use to pass in your custom theme definition.

Let’s walk through an example of creating a custom theme and then apply it to the modal component:

import { createTheme } from '@dopt/react-theme';
import Modal from '@dopt/react-modal';

const customTheme = createTheme({
colors: {
primary: '#b4d455',
},
fonts: {
sans: 'Inter, sans-serif',
},
});

function MyModal() {
return (
<Modal.Root theme={customTheme}>
...
</Modal.Root>
);
}

Applying a theme to a component will automatically cascade that theme definition to all children. However, if you only want to apply a theme to a specific child element, you can specify the theme prop on only that child element (or mix and match!):

<Modal.Root theme={customTheme}>
<Modal.Header theme={anotherCustomTheme}>
...
</Modal.Header>
...
</Modal.Root>

Theme interface

When defining a custom theme, you will need adhere to a strict interface that maps to specific theme tokens as defined in @dopt/core-theme.

interface Theme {
colors?: {
black?: string;
white?: string;
primary?: string;
primaryLight?: string;
primaryDark?: string;
secondary?: string;
secondaryLight?: string;
secondaryDark?: string;
content?: string;
contentLight?: string;
contentContrast?: string;
border?: string;
overlay?: string;
background?: string;
};
space?: {
1?: string;
2?: string;
3?: string;
4?: string;
5?: string;
6?: string;
7?: string;
8?: string;
9?: string;
10?: string;
12?: string;
16?: string;
};
sizes?: {
1?: string;
2?: string;
3?: string;
4?: string;
5?: string;
6?: string;
7?: string;
8?: string;
9?: string;
10?: string;
12?: string;
16?: string;
};
radii?: {
1?: string;
2?: string;
round?: string;
};
shadows?: {
1?: string;
2?: string;
};
fonts?: {
sans?: string;
mono?: string;
};
fontSizes?: {
base?: string;
xs?: string;
sm?: string;
md?: string;
lg?: string;
};
fontWeights?: {
normal?: string;
medium?: string;
bold?: string;
};
lineHeights?: {
base?: string;
sm?: string;
md?: string;
lg?: string;
};
borderWidths?: {
1?: string;
2?: string;
};
transitions?: {
linear?: string;
linearFast?: string;
ease?: string;
easeFast?: string;
};
}

Removing default styles

Dopt React components come with great default styles out of the box, but sometimes you just need to start with a clean slate to really get the level of styling customization your product needs.

You can easily remove all default styling by setting the theme prop to null at the root component:

<Modal.Root theme={null}>
...
</Modal.Root>

Setting the theme at the root component will apply to all child elements. If you only need to remove default styling for a specific child element, you can do so at that specific element:

<Modal.Root>
<Modal.Header theme={null}>
...
</Modal.Header>
...
</Modal.Root>
info

All built-in classes (as specified in each component’s styling API) will remain when default styles are removed. This is purposeful to allow you to target relevant elements with your own custom styling via CSS.