The Talenra Base library offers support for appearance schemes (dark-/light mode) and color themes. This tutorial demonstrates how to switch between the built-in appearance schemes and color themes and how to add appearance/theme support to your app.
This tutorial assumes you completed the previous tutorials. We will use the code of the previous tutorials as our starting point and extend it to support appearance schemes (dark-mode) and color themes.
Alternatively the source code is available through our tutorials repository. Let's get started by getting the source of the previous tutorials and run it locally. You can skip this step if you have the code from the previous tutorials ready and running.
Example :# Create directory "my-talenra-tutorial" and clone the repo
> git clone git@gitlab.svanet.ch:talenra/talenra-tutorials.git my-talenra-tutorial
# Change to your local tutorial directory
> cd my-talenra-tutorial
# Show the list of commits
> git log --oneline
## Find the hash of the last commit before "feat(appearance-and-theme): …" and checkout a new branch based on that commit
> git checkout -b my/appearance-and-theme <commit-hash>
# Install
> npm i
# Run development server
> ng serveImport the LayoutService and the types AppearanceScheme and Theme from the library. Then inject the layout-service to your component.
Now you're ready to write the toggle logic. In the example below we're using the self-explanatory methods toggleScheme and toggleTheme.
// src/app/welcome/welcome.component.ts
import { Component, inject } from '@angular/core';
import { AppearanceScheme, LayoutService, Theme } from '@talenra/components/layout-service';
import { LocalizeComponent } from '@talenra/components/localize';
import { WorkspaceHeaderComponent } from '@talenra/components/workspace-header';
import { WorkspaceSimpleComponent } from '@talenra/components/workspace-simple';
@Component({
imports: [WorkspaceSimpleComponent, LocalizeComponent, WorkspaceHeaderComponent],
templateUrl: './welcome.component.html',
styleUrl: './welcome.component.scss',
})
export class WelcomeComponent {
private layoutService: LayoutService = inject(LayoutService);
protected toggleScheme(): void {
const currentScheme: AppearanceScheme = this.layoutService.appearanceScheme$.value;
this.layoutService.setAppearance(
currentScheme === AppearanceScheme.Light ? AppearanceScheme.Dark : AppearanceScheme.Light
);
}
protected toggleTheme(): void {
const currentTheme: Theme = this.layoutService.theme$.value;
this.layoutService.setTheme(currentTheme === Theme.Petrol ? Theme.Denim : Theme.Petrol);
}
}All we need to do now is connect the toggle methods with the UI so we can test it in the browser.
Example :<!-- src/app/welcome/welcome.component.html -->
<talenra-workspace-simple>
<!-- ... -->
<p>
<span (click)="toggleScheme()" i18n>Toggle Appearance Scheme</span><br />
<span (click)="toggleTheme()" i18n>Toggle Color Theme</span>
</p>
</talenra-workspace-simple>Switch to your browser click the two triggers!
First let us add the package @talenra/stylebox which provides the basic elements of the Talenra design system, such as typography and colors. In our case, we're specially interested in the latter.
> npm i @talenra/styleboxThe command above will install the latest stable version of the package. Be aware that the version of all
@talenrapackages must align. Check the version of already installed@talenrapackages before installation.
Next we're going to add the .swatch-element, to which appearance scheme and color theme shall be applied to.
<!-- src/app/welcome/welcome.component.html -->
<talenra-workspace-simple>
<!-- ... -->
<p>
<span (click)="toggleScheme()">
<span class="swatch appearance-scheme"></span>
Toggle Appearance Scheme
</span>
<br />
<span (click)="toggleTheme()">
<span class="swatch color-theme"></span>
Toggle Color Theme
</span>
</p>
</talenra-workspace-simple>Let's add some basic styling for the .swatch-element. Note that we're going to consume the colors directly from the @talenra/stylebox package we previously installed.
You'll find the interessting part in the two blocks at the end.
Example :// src/app/welcome/welcome.component.scss
@use '@talenra/stylebox';
.swatch {
display: inline-block;
vertical-align: -0.7rem;
width: 2rem;
height: 2rem;
border-radius: 50%;
border: 1px solid;
&.appearance-scheme {
border-color: stylebox.color-get('black', 20);
background-color: stylebox.color-get('white');
}
&.color-theme {
border-color: stylebox.color-get('petrol-dark');
background-color: stylebox.color-get('petrol');
}
}
// Appearance scheme "dark"
.appearance--dark :host {
.swatch.appearance-scheme {
border-color: stylebox.color-get('black');
background-color: stylebox.color-get('black');
}
}
// Color theme "denim"
.theme--denim :host {
.swatch.color-theme {
border-color: stylebox.color-get('denim-dark');
background-color: stylebox.color-get('denim');
}
}Here's how it works: The <body> element always has two classes attached to reflect the current appearance schema and color theme:
appearance--<name>theme--<name>So if you want to support appearance and theme in your custom elements and components, all you have to do is to add a selector in your stylesheet.
The solution above is perfectly fine. However, the styles might become hard to read and understand once the selectors get more sophisticated. Let's use CSS variables to simplify things!
Example :// src/app/welcome/welcome.component.scss
@use '@talenra/stylebox';
:host {
--color-primary: #{stylebox.color-get('petrol')};
--color-primary--dark: #{stylebox.color-get('petrol-dark')};
--color-border: #{stylebox.color-get('black', 20)};
--color-background: #{stylebox.color-get('white')};
}
.theme--denim :host {
--color-primary: #{stylebox.color-get('denim')};
--color-primary--dark: #{stylebox.color-get('denim-dark')};
}
.appearance--dark :host {
--color-border: #{stylebox.color-get('black')};
--color-background: #{stylebox.color-get('black')};
}
.swatch {
display: inline-block;
vertical-align: -0.7rem;
width: 2rem;
height: 2rem;
border-radius: 50%;
border: 1px solid;
&.appearance-scheme {
border-color: var(--color-border);
background-color: var(--color-background);
}
&.color-theme {
border-color: var(--color-primary--dark);
background-color: var(--color-primary);
}
}Much better to read and understand! So clear we can even remove the comments from the previous version.
By the way: If you need to get or set the appearance scheme or color theme in your controller, use the LayoutService to do so. Please refer to the toggle methods at the beginning of this tutorial for a real-life example.
Happy theming! 🎨