Hone logo
Hone
Problems

Implementing a Vue Context API for Theming

Vue's Context API is a powerful pattern for sharing data between components without prop drilling. This challenge focuses on implementing a simple theming system using this pattern. You'll create a way to globally manage and switch between different color themes for your application.

Problem Description

Your task is to build a basic theming system in a Vue application using the Context API. This system should allow different components to access the current theme and its associated styles, and also provide a mechanism to change the theme.

Key Requirements:

  1. Create a Theme Provider: A Vue component that will wrap your application and provide the theme context.
  2. Define Themes: Create at least two distinct themes (e.g., "light" and "dark") with different background and text colors.
  3. Provide Theme Context: The provider component should expose the current theme's configuration and a function to update the theme to its children.
  4. Consume Theme Context: Create a component that can consume the theme context. This component should dynamically update its styles based on the provided theme.
  5. Theme Toggle: Implement a button or similar UI element within the provider or a dedicated control component that allows users to switch between the available themes.

Expected Behavior:

  • When the application loads, a default theme (e.g., "light") should be active.
  • Components consuming the context should render with the correct styles (background and text color) for the active theme.
  • Clicking the theme toggle should seamlessly switch the active theme, and all consuming components should immediately reflect the new styles.

Edge Cases to Consider:

  • What happens if a component tries to consume the context without a provider above it? (While not strictly required to handle this error for this challenge, be aware of it).
  • Ensure smooth transitions or at least immediate style updates when the theme changes.

Examples

Example 1:

  • Initial State:

    • Theme: light (background: #ffffff, text: #333333)
    • Component A (consuming context): Displays "Hello, World!" with a white background and dark grey text.
  • Action: User clicks a "Switch to Dark Theme" button.

  • Resulting State:

    • Theme: dark (background: #333333, text: #ffffff)
    • Component A: Displays "Hello, World!" with a dark grey background and white text.

Example 2:

  • Theme Definitions:

    • light: { background: '#f0f0f0', text: '#1a1a1a' }
    • dark: { background: '#1a1a1a', text: '#f0f0f0' }
    • blue: { background: '#e3f2fd', text: '#0d47a1' }
  • Initial State:

    • Theme: light
    • Component B (consuming context): Displays "Welcome!" styled with the light theme.
  • Action: User clicks a button to select the blue theme.

  • Resulting State:

    • Theme: blue
    • Component B: Displays "Welcome!" styled with the blue theme.

Constraints

  • The solution must be implemented in TypeScript.
  • You should use Vue 3's Composition API for context management.
  • Limit the number of themes to a maximum of 3 for this challenge.
  • The solution should be performant enough for typical web applications, meaning no excessive re-renders unrelated to theme changes.

Notes

  • Think about how to use provide and inject in Vue's Composition API.
  • Consider using a ref or reactive to manage the current theme state.
  • CSS variables can be a clean way to apply theme-specific styles, but direct style binding is also acceptable for this challenge.
  • The goal is to demonstrate a clear understanding of the context pattern for global state management.
Loading editor...
typescript