Skip to main content
/
/
/
/
Color mode picker

Color mode picker

Out of the box, Bifrost will apply light or dark mode colors corresponding to current OS color mode by using the prefers-color-scheme media query.

For most apps this should be sufficient but if your app requires a manual color mode picker for some reason, you can apply .bf-darkmode or .bf-lightmode on <html>.

The following example uses use-local-storage-state npm package to persist state in localStorage.

import React from "react";
import useLocalStorageState from "use-local-storage-state";
import { faCircleHalfStroke } from "@fortawesome/free-solid-svg-icons";
import Nav from "@intility/bifrost-react/Nav";
import Checkbox from "@intility/bifrost-react/Checkbox";
import useApplyColorMode from "@intility/bifrost-react/hooks/useApplyColorMode";
import type { ColorMode } from "@intility/bifrost-react";

// ColorModePicker.tsx
export function ColorModePicker() {
  // persist color mode state in local storage.
  // you might want to use a cookie or a database instead?
  const [colorMode, setColorMode] = useLocalStorageState<ColorMode>(
    "colorMode", // local storage key
    {
      defaultValue: "system",
    },
  );

  // keep document color mode in sync with state
  useApplyColorMode(colorMode);

  return (
    <Nav.Group icon={faCircleHalfStroke} aria-label="Color mode picker">
      <section>
        <Nav.Header>Color mode</Nav.Header>
        <Checkbox
          type="radio"
          label="Light"
          name="color-mode"
          checked={colorMode === "light"}
          onChange={() => setColorMode("light")}
        />
        <Checkbox
          type="radio"
          label="Dark"
          name="color-mode"
          checked={colorMode === "dark"}
          onChange={() => setColorMode("dark")}
        />
        <Checkbox
          type="radio"
          label="System"
          name="color-mode"
          checked={colorMode === "system"}
          onChange={() => setColorMode("system")}
        />
      </section>
    </Nav.Group>
  );
}

// App.tsx or wherever you use <Nav>
export default function AppDemo() {
  return (
    <Nav
      logo="Demo app"
      top={
        <>
          {/* other Nav.Items or Nav.Groups */}
          <ColorModePicker />
        </>
      }
    >
      [App content]
    </Nav>
  );
}