Build a Theme Switcher - Build a Theme Switcher

Tell us what’s happening:

please help my code didn’t pass the test. 26. When a user clicks on the #theme-switcher-button and selects a theme, the corresponding theme- class should be added to the body element.
Failed:27. When a user clicks the #theme-switcher-button and selects a theme, a message related to the selected theme from the themes array should be displayed in the aria-live=“polite” element.

Your code so far

<!-- file: index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Theme Switcher</title>
  <link rel="stylesheet" href="./styles.css">
</head>
<body>

  <button 
    id="theme-switcher-button"
    aria-haspopup="true"
    aria-expanded="false"
    aria-controls="theme-dropdown"
  >
    Switch Theme
  </button>

  <ul 
    id="theme-dropdown"
    role="menu"
    aria-labelledby="theme-switcher-button"
    hidden
  >
    <li role="menuitem" id="theme-light">Light</li>
    <li role="menuitem" id="theme-dark">Dark</li>
  </ul>

  <div id="status" aria-live="polite"></div>

  <script src="./script.js"></script>
</body>
</html>

/* file: styles.css */
body {
  margin: 0;
  font-family: sans-serif;
  transition: background 0.3s, color 0.3s;
}

ul {
  margin: 0;
  padding: 0;
}

li {
  list-style-type: none;
  padding: 8px;
  cursor: pointer;
}

li:hover {
  background: #eee;
}

#status {
  text-align: center;
  min-height: 20px;
  margin-top: 10px;
}

.theme-light {
  background: white;
  color: black;
}

.theme-dark {
  background: #222;
  color: white;
}

/* file: script.js */
const themes = [
  { name: "light", message: "Light theme activated." },
  { name: "dark", message: "Dark theme activated." }
];

document.addEventListener("DOMContentLoaded", () => {
  const button = document.getElementById("theme-switcher-button");
  const dropdown = document.getElementById("theme-dropdown");
  const status = document.getElementById("status");

  button.addEventListener("click", () => {
    const isExpanded = button.getAttribute("aria-expanded") === "true";

    if (isExpanded) {
      dropdown.hidden = true;
      button.setAttribute("aria-expanded", "false");
    } else {
      dropdown.hidden = false;
      button.setAttribute("aria-expanded", "true");
    }
  });

  dropdown.addEventListener("click", (e) => {
    if (e.target.matches("[role='menuitem']")) {
      const themeName = e.target.id.replace("theme-", "");

      document.body.classList.forEach(cls => {
        if (cls.startsWith("theme-")) {
          document.body.classList.remove(cls);
        }
      });

      document.body.classList.add(`theme-${themeName}`);

      const themeObj = themes.find(t => t.name === themeName);
      status.textContent = themeObj ? themeObj.message : "";

      dropdown.hidden = true;
      button.setAttribute("aria-expanded", "false");
    }
  });
});

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36

Challenge Information:

Build a Theme Switcher - Build a Theme Switcher

Your code looks okay. There’s slight bug in these tests, which causes event dispatched in test to not bubble.

Until PR with fix - fix(curriculum): dispatch bubbling event in Theme Switcher tests by gikf · Pull Request #64102 · freeCodeCamp/freeCodeCamp · GitHub - is merged and then deployed, your approach unfortunately won’t work. Before that, you could rewrite code to add click event listeners on the list items themselves.

1 Like