Hone logo
Hone
Problems

Dynamic Theme Switching with Angular

This challenge focuses on implementing a dynamic theme switcher in an Angular application. Users should be able to select a theme (e.g., light, dark, blue) at runtime, and the application's styling should update accordingly. This is a common requirement for modern web applications, allowing users to personalize their experience.

Problem Description

You are tasked with creating an Angular component that allows users to switch between different themes. The component should:

  1. Provide a Theme Selection: Include a dropdown or radio buttons allowing the user to choose from a predefined set of themes (light, dark, blue).
  2. Apply Theme Styles: Dynamically apply CSS classes to the <body> element of the document based on the selected theme. These CSS classes will define the overall theme.
  3. Persist Theme Selection (Optional): Ideally, the selected theme should be stored in local storage so that it persists across page reloads.
  4. Handle Initial Theme: On application load, check local storage for a previously selected theme. If found, apply that theme; otherwise, apply a default theme (e.g., light).

Key Requirements:

  • The solution must be implemented using Angular's component architecture.
  • CSS classes for each theme should be defined in a separate CSS file (e.g., themes.css).
  • The component should be reusable and easily integrated into other parts of the application.
  • The solution should be efficient and avoid unnecessary DOM manipulations.

Expected Behavior:

  • When the user selects a theme, the application's styling should change immediately to reflect the new theme.
  • The selected theme should be stored in local storage (if implemented).
  • On subsequent page loads, the previously selected theme should be applied automatically.
  • The component should handle invalid theme selections gracefully (e.g., by reverting to the default theme).

Edge Cases to Consider:

  • What happens if local storage is unavailable or corrupted?
  • How to handle adding or removing themes in the future without modifying the component's core logic?
  • How to ensure that the theme classes are applied correctly to all elements of the application?

Examples

Example 1:

Input: User selects "dark" theme.
Output: The <body> element has the class "dark-theme" applied.  The CSS defined in `themes.css` for the "dark-theme" class is applied.
Explanation: The component detects the theme change and adds the appropriate class to the body.

Example 2:

Input: User initially visits the page without a theme stored in local storage.
Output: The <body> element has the class "light-theme" applied (default theme).
Explanation: The component checks local storage, finds no theme, and applies the default theme.

Example 3:

Input: User selects "blue" theme, then refreshes the page.
Output: The <body> element has the class "blue-theme" applied.
Explanation: The component retrieves the "blue-theme" from local storage and applies it on page load.

Constraints

  • The solution must be implemented using Angular version 14 or higher.
  • The component should be relatively lightweight and avoid complex state management solutions (e.g., NgRx) unless absolutely necessary. Simple services or component properties are preferred.
  • The CSS file (themes.css) should be well-organized and maintainable.
  • The solution should be performant; avoid excessive DOM manipulations. Adding/removing classes to the body is acceptable.
  • The number of themes supported should be limited to a maximum of 5 (light, dark, blue, green, and orange).

Notes

  • Consider using Angular's Renderer2 for manipulating the DOM directly, which is generally preferred over directly accessing the DOM.
  • Think about how to make the theme selection configurable (e.g., allowing the user to add or remove themes without modifying the component's code).
  • The CSS classes for the themes should be descriptive and easy to understand (e.g., light-theme, dark-theme, blue-theme).
  • Focus on creating a clean, maintainable, and reusable component. Good coding practices are essential.
Loading editor...
typescript