Takeaways
- Conduct a Dark Mode Vitals evaluation with your product and design partners.
- Ensure correct WPDS color tokens are applied. Static tokens will not swap with dark mode.
- Check that
@washingtonpost/site-header
and@washingtonpost/wpds-ui-kit
are updated to the latest version. - Insert proper feature flags under the
@washingtonpost/site-header
to turn on required theme selectors - Avoid specifying the wpds-light theme inside on-page components and sections. This will override the code in the header.
Dark Mode Vitals Evaluation
- Identify areas of improvement and prioritize surfaces that require the most attention.
- Ticket design and engineering work accordingly to improve dark mode vitals rating.
- Repeat until dark mode vitals are strong.
- Library Usage: Evaluate the correct use of the design system library for dark mode.
- Poor: Tokens and styles are frequently hardcoded.
- Strong: Exclusive use of the library.
- Readability: Assess text and element readability in dark mode.
- Poor: Page is unreadable in dark mode.
- Strong: No issues reading the page in dark mode.
- Accessibility: Rate alignment with accessibility standards in dark mode.
- Poor: Non-compliance with WCAG and AA standards.
- Strong: Full compliance.
- Consistency with Design Tokens: Ensure that proper theme tokens are applied correctly. (i.e. proper use of static and theme tokens).
- Poor: Inconsistent or off-brand usage of theme tokens.
- Strong: Perfect alignment with theme.
- Visual integrity: Is the integrity of the content or design of the page impacted?
- Poor: Negative impact on page content, off-brand with design system.
- Strong: No impact on page content, perfectly aligned with design system.
Insert Site Header
If you're working on a React.js project, this component is simple to implement and adaptable to your needs.
Within the component, we leverage SWR hooks to get the data for your page, which means that we no longer have to pass in leftNavData, rightNavData, etc., and prop drill throughout our app.
// pages/index.js
import React from "react";
import { Header } from "@washingtonpost/site-header";
export const MyPage = (props) => (
<Header
{...{
locationOnSite: "other", // For Tracking, Location on Site such as Article or Gallery
}}
/>
);
Opt-in to Dark Mode
Website and Webviews
Using Site Header
// pages/index.js
import React from "react";
import { Header } from "@washingtonpost/site-header";
export const MyPage = (props) => (
<Header
{...{
locationOnSite: "other", // For Tracking, Location on Site such as Article or Gallery
serverSideFeatureFlags: [
"showThemeSelector", // This will enable the dark mode toggle and the dark mode support
"darkModeInAppWebViews", // This will enable dark mode in the app webviews
],
}}
/>
);
Without using Site Header
If you want to opt-in to dark mode without using the Site Header, you can do so by using the ThemeToggle component.
// pages/index.js
import React from "react";
import { ThemeToggle } from "@washingtonpost/site-header";
export const MyPage = (props) => (
<ThemeToggle
serverSideFeatureFlags={[
"showThemeSelector", // This will enable the dark mode toggle and the dark mode support
"darkModeInAppWebViews", // This will enable dark mode in the app webviews
]}
/>
);
Using the useIsDarkMode Hook at the component level
If you need to detect whether dark mode is currently active in your components, you can use the useIsDarkMode hook. This is useful when you want to conditionally render different components or visualizations based on the current theme.
The hook automatically:
- Checks user preference stored in localStorage
- Falls back to system preference if no stored value exists
- Updates in response to system theme changes
- Works in both client-side rendering and server-side rendering environments
// DataVisualization.jsx
import React from "react";
import { useIsDarkMode } from "@washingtonpost/site-header";
import Image from "next/image";
const DataVisualization = () => {
// This hook returns a boolean indicating if dark mode is active
const isDarkMode = useIsDarkMode();
// We can use it to swap entire components or data sources based on theme
return (
<div>
{isDarkMode ? (
// Dark mode specific visualization
<iframe
src="https://datawrapper.dwcdn.net/DARK_MODE_CHART_ID/1/"
title="Dark mode optimized chart"
aria-label="Chart showing data with dark background"
frameBorder="0"
scrolling="no"
height="500"
/>
) : (
// Light mode specific visualization
<iframe
src="https://datawrapper.dwcdn.net/LIGHT_MODE_CHART_ID/1/"
title="Light mode optimized chart"
aria-label="Chart showing data with light background"
frameBorder="0"
scrolling="no"
height="500"
/>
)}
{/* We can also swap images based on the theme */}
<Image
src={
isDarkMode
? "/images/infographic-dark.png"
: "/images/infographic-light.png"
}
alt="Infographic explaining the data"
width={800}
height={600}
/>
{/* Theme-specific text styles can be applied */}
<p style={{ color: isDarkMode ? "#e0e0e0" : "#333" }}>
This explanatory text is optimized for readability in both themes.
</p>
</div>
);
};