theme.js 1.4 KB

12345678910111213141516171819202122232425262728293031
  1. /*!
  2. * All material copyright ESRI, All Rights Reserved, unless otherwise specified.
  3. * See https://github.com/Esri/calcite-components/blob/master/LICENSE.md for details.
  4. * v1.0.0-beta.97
  5. */
  6. import { autoTheme, darkTheme } from "./resources";
  7. /**
  8. * Emits when the theme is dynamically toggled between light and dark on <body> or in OS preferences.
  9. */
  10. export function initThemeChangeEvent() {
  11. const { classList } = document.body;
  12. const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
  13. const getTheme = () => classList.contains(darkTheme) || (classList.contains(autoTheme) && prefersDark) ? "dark" : "light";
  14. const emitThemeChange = (theme) => document.body.dispatchEvent(new CustomEvent("calciteThemeChange", { bubbles: true, detail: { theme } }));
  15. const themeChangeHandler = (newTheme) => {
  16. currentTheme !== newTheme && emitThemeChange(newTheme);
  17. currentTheme = newTheme;
  18. };
  19. let currentTheme = getTheme();
  20. // emits event on page load
  21. emitThemeChange(currentTheme);
  22. // emits event when changing OS theme preferences
  23. window
  24. .matchMedia("(prefers-color-scheme: dark)")
  25. .addEventListener("change", (event) => themeChangeHandler(event.matches ? "dark" : "light"));
  26. // emits event when toggling between theme classes on <body>
  27. new MutationObserver(() => themeChangeHandler(getTheme())).observe(document.body, {
  28. attributes: true,
  29. attributeFilter: ["class"]
  30. });
  31. }