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.
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 } ],
This configuration guarantees the stylesheets are bundled into your final dist folder during build time.
- 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>
- 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'; } } }
- 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); } }
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>
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.
