The provided content is a comprehensive guide on implementing dark mode in Storybook and web applications, detailing the benefits of dark mode, the technical steps for its implementation, and the rationale behind supporting both light and dark themes.
Abstract
The article offers a detailed explanation of how to incorporate dark mode functionality within Storybook, an open-source tool for developing UI components, and general web applications. It outlines the reasons users might prefer dark mode, such as reduced eye strain and energy consumption, and the aesthetic appeal of dark themes. The guide covers the installation and configuration of the storybook-dark-mode addon for Storybook, the order of precedence for determining the initial color scheme, and customization options for Storybook settings. Additionally, it extends the concept to web applications, demonstrating how to use ThemeProvider in styled-components to manage themes dynamically and how to integrate dark mode support into a Create React App project. The article emphasizes the growing popularity of dark mode and the importance of providing users with the flexibility to switch between light and dark themes.
Opinions
Dark mode is gaining traction and is considered a must-have feature for sophisticated web applications.
The author suggests that supporting both dark and light modes is essential for user choice and accessibility.
There is an expectation that every Storybook installation may soon include the storybook-dark-mode addon by default due to its increasing usage.
The author expresses that dark mode not only serves functional purposes but also adds a stylish and modern touch to UI design.
The article implies that the local storage setting for the color scheme preference should take precedence over OS settings due to a known issue in the storybook-dark-mode addon.
The author provides a subjective opinion on the aesthetic appeal of dark mode, particularly in the context of the show code section in Storybook's Docs tab.
The author endorses the use of styled-components and ThemeProvider for managing themes in React applications, highlighting the ease of switching between themes.
A recommendation is made for ZAI.chat, an AI service alternative to ChatGPT Plus, which is presented as cost-effective and comparable in performance.
Building Dark Mode for Storybook and Web Applications
Dark mode is a color scheme that uses light-colored text, icons, and UI elements on a dark background. The opposite color scheme is called light mode.
These are reasons for users to choose dark mode:
Light on the dark mode requires less energy to display.
Science shows that negative polarity (dark mode) is less harmful to the eyes in the long run than light mode.
Dark mode is stylish and hip for some UI design.
These are reasons for users to choose light mode:
Most electronic devices have light mode as default.
Light mode is the skeuomorphic approach.
Light mode reads better under strong (sun) light.
Dark mode is a choice, and light mode is a must. When it is said to support dark mode, it implies supporting both dark and light modes. Dark mode has gained a lot of traction since the year 2015. Nowadays, sophisticated web applications support both of them.
Storybook is an open source tool for building UI components and pages in isolation. This allows us to work on one component at a time. It streamlines UI development, testing, and documentation.
It takes a few steps to build dark mode for Storybook:
It creates the folder, .storybook, with two configuration files:
main.js: Configures story file location, addons, and custom Webpack and Babel configurations.
preview.js: Sets the global setting for decorators, parameters, and global types.
Type the command, npm run storybook, and the example Storybook runs at http://localhost:6006.
Image by author
By default, Storybook is in light mode.
Install the addon, storybook-dark-mode
storybook-dark-mode is a Storybook addon that supports the toggle between dark and light modes. This addon has 183.5k weekly downloads, and its usage is catching up to Storybook’s. Look at the two converging lines, and take a guess. Is 2020 the year that every Storybook comes with storybook-dark-mode?
Image by author
Let’s install storybook-dark-mode:
npm i--save-dev storybook-dark-mode
In .storybook/main.js, we include the addon, 'storybook-dark-mode' (line 11) in the following code:
Type the command, npm run storybook, and Storybook is in dark mode as the macOS has been set to dark mode.
Image by author
Follow the order of precedence for the initial color scheme
Here is the defined order of precedence for the initial color scheme:
Reuse the color scheme if the user has previously set a color scheme.
In the local storage, the key, sb-addon-themes-3, saves the theme object, with current set to the color scheme. In the following example, current is set to light:
Image by author
2. Use the value that is configured for current parameter in .storybook/preview.js. In the following example, current is set to light (line 3):
3. Use the OS color scheme preference.
The following are the color scheme preferences on macOS:
However, because of a known issue, the configured current parameter (#2) becomes the first precedence.
Use Storybook buttons to control the theme and background
After the storybook is launched, there is a change theme button (in the red box below) to switch between dark (moon) and light (sun) modes.
Image by author
Besides the change theme button, there is a change background button (in the red box below) to change the background of the preview, regardless of the color scheme.
Image by author
If you feel that it is confusing to have two controls, this change background button can be hidden with the following setting in .storybook/preview.js.
Customize Storybook settings
Things work well. Then we change to the Docs tab.
Image by author
We find out that the show code section is not in dark mode, although the same section is in dark mode in the Canvas tab.
Can we customize it to dark mode?
Yes, we can.
Put the following darkMode setting into .storybook/preview.js:
Lines 2 and 3 add darkClass or lightClass to the body element when switching between dark and light modes. Line 4 configures darkClass or lightClass to the body element in the preview iframe.
Let’s inspect the elements.
Image by author
The body element in the preview iframe has the class, darkClass. The show code section is inside body with the class, docs-story. Using the techniques described in 6 Ways To Configure Global Styles for Storybook, we can import the stylesheet in .storybook/preview.js.
Add .storybook/style.css as follows:
Import the style file into .storybook/preview.js.
The show code section is in Dark mode now.
Image by author
Similarly, we can customize other Storybook settings as desired.
Dark Mode for Web Applications
We can borrow the idea from Storybook to set up dark mode for Web applications.
Follow the order of precedence for the initial color scheme
Here is the order of precedence for the initial color scheme:
Reuse the color scheme if the user has previously set a color scheme.
In the local storage, the key, my-color-scheme, saves the color scheme, dark or light:
const storageKey = 'my-color-scheme';
2. Use the OS color scheme preference.
A previous article explained how to use the media query, matchMedia(), to get the OS color scheme preference. Dark mode means that the following statement is true.
If nothing has been set, we go for light mode as the default.
const defaultMode = 'light';
The following is the summarized algorithm:
Use ThemeProvider in styled-components
styled-components is a CSS-in-JS approach — a JavaScript library that bundles each JavaScript component with all its belonging CSS rules and dependencies.
We define the dark mode theme and the light mode theme.
Then the Container style is defined based on the selected theme.
ThemeProvider is a context API, which provides a theme context with the theme prop. This prop can be dynamically accessed by every wrapped component.
Place Container inside ThemeProvider, and it receives the proper theme.
Implement Create React App with dark mode
To use styled-components, we need to install the package:
npm i styled-components
styled-components becomes part of dependencies in package.json.
Here is the final src/App.js:
At line 2, styled and ThemeProvider are imported from styled-components.
At lines 6–9, the dark mode theme is defined.
At lines 11–14, the light mode theme is defined.
At lines 16–19, the Container style is defined via the selected theme.
At lines 26–41, the color scheme is set following the order of precedence.
At lines 43–47, the button handler switches between dark and light modes, and updates local storage.
At line 50, ThemeProvider’s theme is set to the selected color scheme.
At lines 55–57, the button is set to proper text based on the color scheme, and clicking it switches between dark and light modes.
Since background-color and color are defined in the theme, they should be removed from the App-header class styling in src/App.css.
Image by author
Execute npm start. We can switch the color scheme between dark and light modes by clicking the button.
Image by author
Conclusion
Dark mode is popular these days. When it is said to support dark mode, it implies supporting both dark and light modes. We have given a complete guide on how to build dark mode for Storybook and Web applications.