Theming

Read the Styling examples on how to include styles and a theme. This section is about how theming works and how to actually create a custom theme.

Integrated theming

Eufemia supports theming right inside where all the style-sources lives. Having the ability to control different styles as close to the source as possible, will make it possible to carefully handle continues improvements over time.

Themes are independent style packages, which should not be imported in parallel. But rather either – or.

Brand theming

Eufemia is design system that aims to help DNB brands unleash their power.

Eufemia is a system that is build on top of brand-assets. So means, it should be possible to swap out or extend these brand-assets.

Therefore, instead of overwriting Eufemia (DNB main brand) styles inside projects, it is beneficial to create additional brand themes – directly where the source of the original brand lives.

The default DNB brand theme is called: ui which stands for universal identity.

Run your application with a different theme

You can easily switch the static import of styles to a different theme:

import '@dnb/eufemia/style/core' // or /basis, when "dnb-core-style" is used
import '@dnb/eufemia/style/components'
- import '@dnb/eufemia/style/themes/ui'
+ import '@dnb/eufemia/style/themes/eiendom'

How ever, giving the user the ability to switch a theme during runtime, is a very much different challenge.

The Eufemia Portal (documentation) uses gatsby-plugin-eufemia-theme-handler to handle it both in development and production mode. You may install it to use it in your application as well.

Run the portal with a different theme

  • Create a new /packages/dnb-design-system-portal/.env file that includes e.g. GATSBY_THEME_STYLE_DEV=eiendom and start the portal with $ yarn start.
  • What theme gets imported is handled in the Gatsby Plugin gatsby-plugin-eufemia-theme-handler.
  • In the Portal Tools you can switch to a different theme.
  • You can also define a different them in the url itself path/?dnb-theme=ui.

Technical aspects

The included themes are built using SASS. Simply because we can reuse the @mixin's and variables from SASS.

We have the Main Theming File, which is located here: dnb-eufemia/src/style/themes/dnb-theme-[THEME].scss

From here, we "can" reuse some default theming mechanism, just to have a fallback:

@import '../theme-ui/dnb-theme-ui.scss';

All the additional sub theming files (for every component) are automatically added to the Main Theming File by running $ yarn build. More on that further down.

If we need a custom theming file for one or more components, we can do so by creating dnb-eufemia/src/components/[COMPONENT]/style/dnb-button-theme-[THEME].scss.

NB: Every time you create a new theme file, you have to run $ yarn build. This way the new theme file gets added/bundled to the Main Theming File.

Local Theming setup

There are several solutions to create a new theme. One of which is by using the linking feature of Yarn.

Method: yarn link and SASS

Make sure your project can handle *.scss files.

1. make a copy of the repository. Place it somewhere locally on your machine

2. change your command line (Terminal) directory to the sub package @dnb/eufemia (eufemia/packages/eufemia)

3. make the package ready for development by running:

$ yarn install && yarn build && yarn link

4. on your application root directory, run:

$ yarn link "@dnb/eufemia"

5. That's it. Now you can use (import/require) the NPM module in your application like:

import { Button } from 'dnb-eufemia/components'
import 'dnb-eufemia/style/components'
// See the "src" in the path?
import 'dnb-eufemia/src/style/themes/dnb-theme-[MY THEME].scss'

6. Don't forget to add "@dnb/eufemia": "*" with the respective version (alongside React) to your dependencies:

"dependencies": {
"@dnb/eufemia": "*",
"react": "17",
"react-dom": "17",
...
}

WIP: Ready to use themes

Right now, theres work going on to create Eufemia Themes that utilize both color and spacing and the Spatial system.

The plan is to extend the documentation here later on on how to select and use a theme inside an application.

Chrome Extension: Eufemia Theme Manager

Use the Chrome Browser Extension to:

  • test themes on web applications
  • create new possible themes
  • look how the outcome would be if a theme would be used
  • and create areas where a different or a modified theme would make more sense

You can also download the Chrome Browser Extension (ZIP), and install it manually in your browser. To do so, go to chrome://extensions and drag & drop the downloaded ZIP file in the opened extensions tab.

Contributions are welcome. Heres the source code.

Component theming

By default, all the HTML Elements (components) are built by separating the "visual styling" parts from the "functional layout" parts. This way we can create new custom visual styles:

/button/style/_button.scss // layout styles
/button/style/themes/dnb-button-theme-ui.scss // main theme styles
/button/style/themes/dnb-button-theme-eiendom.scss// additional theme styles
  • The main theme (ui) does contain mainly colorization and sizes.
  • While all the raw positioning and layout related properties are in the main .scss file, starting with an underscore: _button.scss

It's still possible to overwrite the layout properties to customize our theme even further, if that is needed.

Theming inside your application

You can skip to import the default theme dnb-theme-ui and create your own visual styles for every component you use in your App:

import '@dnb/eufemia/style/core' // or /basis, when "dnb-core-style" is used
import '@dnb/eufemia/style/components'
- import '@dnb/eufemia/style/themes/ui'

This approach is fragile, because further Eufemia changes and updates will possibly misalign with your customization.

Therefore, its probably a good idea to rather create theme styling files inside of the Eufemia repo itself. More on that topic in integrated theming.

Using postcss-replace

If your applications only need new colors or other CSS properties, you could simply replace all the properties with postcss-replace using this config scheme:

{
resolve: 'gatsby-plugin-postcss',
options: {
postCssPlugins: [
require('postcss-replace')({
pattern: /#([A-Fa-f0-9]+)/,
data: {
'007272': '#YOUR_COLOR' // sea-green
}
})
]
}
}

Using CSS (vars) Custom Properties

This is for sure a very nice and powerful solution, but lacks Internet Explorer support.