Skip to content

Soracom

Design System
Home Design System Styles Dark mode

Dark mode

Overview 

By default SDS uses light-mode only, but dark-mode support can be controlled by setting html attributes using javascript.

Note, use the light-mode/dark-mode toggle above right to see how specific colors adjust.

Basic usage 

Displaying Dark/Light mode 

Dark/Light mode can be enabled by setting the appropriate data-ds-theme value on the root html element:

Enable dark-mode
<html data-ds-theme="dark">
...
</html>
Enable light-mode
<html data-ds-theme="light">
...
</html>

// Alternatively you can omit/remove the data-ds-theme attribute
<html>
...
</html>

Toggling the current theme 

The following sds component, combined with the example javascript will allow users to toggle the theme or fallback to the current OS theme:

<label class="ds-switch --theme --hide-label">
  <input type="checkbox">
  <div>Dark Mode</div>
</label>
<label class="ds-switch --theme --hide-label --small">
  <input type="checkbox">
  <div>Dark Mode</div>
</label>

The following javascript will firstly check local storage for a ‘ds:theme’ setting. If no setting exists it will fall back to using the OS theme. It will also set all html theme toggles on the page to the correct state and listen for any click events.

////////////////////
// Theme controls
////////////////////

// Import the sds color object - needed for changing chart colors
import { dsColor } from "https://assets.soracom.io/js/sds/latest/color.js";
if (typeof window.Chart !== "undefined") {
	Chart.register(ChartDataLabels);
}

// Check if a specific theme is set in localStorage, otherwise use the system setting
let currentTheme =
	localStorage["ds:theme"] ||
	(window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light");

window.onload = () => {
	// Set the html data-attribute to match the current theme
	if (currentTheme) {
		document.documentElement.dataset.dsTheme = currentTheme;

		// Update any charts
		setChartTheme(currentTheme);
	}

	// Reveal the page (in case it's invisible initially)
	document.body.style.opacity = "1";
};

// Enable theme toggle controls and keep them in sync
let themeToggles = document.querySelectorAll(
	'[class*="ds-switch"][class*="--theme"] input'
);
if (themeToggles.length > 0) {
	for (const toggle of themeToggles) {
		// Set the initial state of the theme-toggle component to match the current theme
		setAllThemeToggles(currentTheme);

		// Change the current theme when the toggle is clicked
		toggle.addEventListener("click", function (e) {
			let targetTheme = toggle.checked ? "dark" : "light";

			// Set the theme
			document.documentElement.dataset.dsTheme = targetTheme;

			// Save the setting to local storage
			localStorage["ds:theme"] = targetTheme;

			// Update all toggles to be the same
			setAllThemeToggles(targetTheme);

			// Change any chart text colors
			setChartTheme(targetTheme);
		});
	}
}

function setAllThemeToggles(theme) {
	for (const toggle of themeToggles) {
		toggle.checked = theme === "dark";
	}
}

function setChartTheme(theme) {
	var textColor =
		theme === "dark" ? dsColor.inkBright.rgb : dsColor.inkShade.rgb;
	if (typeof window.Chart !== "undefined") {
		Chart.helpers.each(Chart.instances, function (instance) {
			instance.options.scales.x.ticks.color = textColor;
			instance.options.scales.y.ticks.color = textColor;
			instance.options.plugins.datalabels.color = textColor;
			instance.options.plugins.legend.labels.color = textColor;
			instance.update();
		});
	}
}

Initial loading state 

It’s recommended adding the following style element to the html head of the page for a better initial page loading experience. This allows the theme script above to reveal the page once the correct theme has been determined, and prevents an initial flash of dark or light colors.

<html>
  <head>
    <style>
    /* Hide the page content, it will be revealed via script when fully loaded */
    body { opacity: 0; }

    /* Set background color if the user OS is in dark mode */
    @media (prefers-color-scheme: dark) {
      body { background-color: var(--color-ink-900); }
    }
    </style>
  </head>
  ...
</html>