Effortless Theme Toggling in Angular 17 Standalone Apps with PrimeNG

Ingila Ejaz - Jul 16 - - Dev Community

Theme toggle PrimeNG

As I delved into PrimeNG and PrimeFlex for my recent Angular 17 standalone app with SSR, one aspect truly stood out: built-in themes. Unlike Material UI, PrimeNG offers a delightful selection of pre-built themes that you can easily configure within your application.

But the real cherry on top? Setting up a theme switcher to empower users to personalize their experience is a breeze with just a few lines of code. Let’s dive in!

Priming Your App for Themes:

Installation: Get started by installing PrimeNG using npm or yarn.

npm install primeng --save

Include Styles in angular.json:

Ensure your angular.json file includes the necessary styles. Below is my folder structure and its inclusion in angular.json.

Folder Structure

In each stylesheet, I imported built-in PrimeNG Themes from resources.



 //angular.json 
 "styles": [
              "src/styles.css",
              {
                "input": "src/app/styles/lara-dark-teal.scss",
                "bundleName": "lara-dark-teal",
                "inject": false
              },
              {
                "input": "src/app/styles/lara-light-teal.scss",
                "bundleName": "lara-light-teal",
                "inject": false
              }
            ],


Enter fullscreen mode Exit fullscreen mode

This configuration guarantees the stylesheets are bundled into your final dist folder during build time.

  1. Setting the Default Theme (index.html):

Include Stylesheet: In your index.html file, incorporate the stylesheet for your chosen default theme and assign it an ID for service access:



<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <title>Theme Switcher</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <link id="app-theme" rel="stylesheet" type="text/css" href="lara-light-teal.css">

  <link rel="stylesheet" href="https://unpkg.com/primeflex@latest/primeflex.css">
</head>

<body class="">
  <app-root></app-root>
</body>
</html>


Enter fullscreen mode Exit fullscreen mode
  1. Dynamic Theme Switching with a Service:

Create a Theme Service: Construct a service to manage theme changes. Inject it into your root component for application-wide accessibility:



//themes.service.ts
import { Inject, Injectable } from '@angular/core';
import { DOCUMENT } from '@angular/common';

@Injectable({
    providedIn: 'root',
})
export class ThemeService {

    constructor(@Inject(DOCUMENT) private document: Document) {}

    switchTheme(theme: string) {

        let themeLink = this.document.getElementById('app-theme') as HTMLLinkElement;

        if (themeLink) {
            themeLink.href = theme + '.css';
        }
    }
}


Enter fullscreen mode Exit fullscreen mode
  1. Using the service inside Component:

Inject Service and Document: Within your component, inject the ThemeService and the Document object:



  constructor(private themeService: ThemeService) {

  }
  checked: boolean = false;

  changeTheme() {
    let theme = (this.checked) ? "lara-dark-teal" : "lara-light-teal"
    this.themeService.switchTheme(theme);

  }

}



Enter fullscreen mode Exit fullscreen mode

Template with p-toggle: Utilize the p-toggle component from PrimeNG to render the toggle button. Bind its state to a boolean variable (checked) and trigger the changeTheme() method on click. Employ pi-icons (PrimeNG icons) for visual appeal.



<p-toolbar styleClass="bg-primary shadow-2  opacity-80">

    <div class="flex-grow">
        My Theme Switcher
    </div>
    <p-toggleButton styleClass="bg-primary shadow-2 text-white" [(ngModel)]="checked" onIcon="pi pi-sun"
        offIcon="pi pi-moon" (click)="changeTheme()" />

</p-toolbar>


Enter fullscreen mode Exit fullscreen mode

Separation of Concerns: The service concentrates on theme management, keeping your component clean and focused.

Enhanced Readability: The code is well-structured and easy to comprehend for developers of all levels.

Developer Delight: PrimeNG streamlines the process, empowering you to craft a seamless theme-switching experience in your Angular 17 application.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .