Skip to content

Angular

@theme-kit/angular

DIDirectiveSSR

NgModule-free theming: DI providers, reactive injectables, a scoping directive and zero-flash bootstrap helpers.

Installation

Install the package for your framework alongside @theme-kit/core.

bash
pnpm add @theme-kit/angular

Quick Start

Start from scratch — install the package, then wrap your app in the provider at the entry point shown below.

main.ts
ts
1import { bootstrapApplication } from "@angular/platform-browser";
2import { provideThemeKit } from "@theme-kit/angular";
3import { AppComponent } from "./app/app.component";
4import { themes } from "./themes";
5
6bootstrapApplication(AppComponent, {
7  providers: [provideThemeKit({ themes, defaultTheme: "mint-light" })],
8});
Every integration re-exports the full @theme-kit/core surface, so history, batching, snapshots, packs and lifecycle work the same way across frameworks.

Implementation

Read and update theme state from any component using the framework-native primitives below.

app.config.ts
ts
1import { provideThemeKit, injectTheme } from "@theme-kit/angular";
2
3bootstrapApplication(AppComponent, {
4  providers: [provideThemeKit({ themes })],
5});
6
7@Component({ ... })
8export class ThemeSwitcher {
9  private theme = injectTheme();
10  // theme().theme() · theme().mode() · theme().setMode("dark")
11}

What's Available

@theme-kit/angular ships 16 exports in 5 categories. Everything below is also documented in the full API reference. Click any export to reveal what it does and how to use it.

Setup

Injectables

Transition

Directives

SSR & Bootstrap

Use Cases

The important features in practice — copy any of these straight into your app.

Provide the runtime

Wire Theme Kit once in your app config, then inject reactive state anywhere.

Provide the runtime
ts
1import { provideThemeKit } from "@theme-kit/angular";
2
3export const appConfig: ApplicationConfig = {
4  providers: [
5    provideThemeKit({ themes, defaultTheme: "light" }),
6  ],
7};

Toggle light / dark

injectTheme returns reactive ThemeState with setters.

Toggle light / dark
ts
1import { Component, inject } from "@angular/core";
2import { injectTheme } from "@theme-kit/angular";
3
4@Component({ selector: "app-toggle", template: `
5  <button (click)="theme().toggleTheme()">
6    {{ theme().theme.name }} · {{ theme().mode }}
7  </button>
8` })
9export class ThemeToggleComponent {
10  readonly theme = injectTheme();
11}

Undo / redo theme changes

Inject history controls and the runtime for live edits.

Undo / redo theme changes
ts
1import { Component, inject } from "@angular/core";
2import { injectThemeHistory, injectThemeRuntime } from "@theme-kit/angular";
3
4@Component({ selector: "app-history", template: `
5  <button (click)="history.undo()" [disabled]="!history.history().canUndo">Undo</button>
6  <button (click)="history.redo()" [disabled]="!history.history().canRedo">Redo</button>
7  <button (click)="runtime.update({ colors: { primary: '#6366f1' } })">
8    Make primary indigo
9  </button>
10` })
11export class ThemeHistoryComponent {
12  readonly history = injectThemeHistory();
13  readonly runtime = injectThemeRuntime();
14}

Scope a subtree

ThemeScopeDirective themes a single element subtree.

Scope a subtree
ts
1import { Component } from "@angular/core";
2import { ThemeScopeDirective } from "@theme-kit/angular";
3
4@Component({
5  selector: "app-dashboard",
6  template: `
7    <div class="global-theme">Inherits global</div>
8    <div [themeKitScope]="'forest'">Always forest here</div>
9  `,
10  standalone: true,
11  imports: [ThemeScopeDirective],
12})
13export class DashboardComponent {}

Smooth theme transitions

Enable CSS transitions on theme changes for a polished user experience.

Smooth theme transitions
ts
1import { provideThemeKit } from "@theme-kit/angular";
2
3export const appConfig: ApplicationConfig = {
4  providers: [
5    provideThemeKit({
6      themes,
7      defaultTheme: "light",
8      transition: { enabled: true, duration: 300, easing: "ease-in-out" },
9    }),
10  ],
11};

More Examples

Scoped theming, history controls, and framework-specific patterns.

history-controls.ts
ts
1import { Component } from "@angular/core";
2import {
3  provideThemeKit,
4  injectThemeHistory,
5  ThemeScopeDirective,
6} from "@theme-kit/angular";
7
8bootstrapApplication(AppComponent, {
9  providers: [provideThemeKit({ themes })],
10});
11
12@Component({
13  selector: "history-controls",
14  standalone: true,
15  imports: [ThemeScopeDirective],
16  template: `
17    <div [themeKitScope]="'forest'" [themeKitScopeTransition]="transition">Scoped to forest</div>
18    <button (click)="undo()" [disabled]="!canUndo()">Undo</button>
19    <button (click)="redo()" [disabled]="!canRedo()">Redo</button>
20  `,
21})
22export class HistoryControls {
23  private history = injectThemeHistory();
24  canUndo() { return this.history.history().canUndo; }
25  canRedo() { return this.history.history().canRedo; }
26  undo() { this.history.undo(); }
27  redo() { this.history.redo(); }
28
29  transition: import("@theme-kit/core").ThemeTransitionOptions = { duration: 300, easing: "ease" };
30}

API Reference

Setup

ExportDescription
provideThemeKit(options)App-level providers from a ThemeRuntimeOptions config.
provideThemeKitRuntime(runtime)Provide an existing shared runtime instance.

Injectables

ExportDescription
injectThemeRuntime()Inject the full runtime.
injectTheme()Reactive `ThemeState` — theme, mode, family plus setters.
injectThemeHistory()Undo / redo / jump through theme history.
injectThemeBatch()Atomic, coalesced updates.
injectThemeSnapshot() / injectThemeRestore()Serialize and restore runtime state.
injectThemeTimeTravel()`{ history, jump }` — indexed time travel.
injectThemeLifecycle()Subscribe to lifecycle events.
injectThemePacks()Install theme packs at runtime.
injectThemeSchedule()Reactive sunrise/sunset controller: `state()` is a Signal of `enabled`, `status`, `sunrise`, `sunset`, `nextTransition`; plus `enable()`/`disable()`/`set()`. Configure via `scheduled` in `provideThemeKit()`.

Transition

ExportDescription
transition in provideThemeKit()Pass `transition` config to `provideThemeKit()` to enable CSS transitions on theme changes.
runtime.store.set(theme, { suppressTransition: true })Runtime toggle — no mutation hook exists. The transition prop is fixed at runtime creation; for a one-off instant switch, injectThemeRuntime() then runtime.store.set(theme, { suppressTransition: true }) applies immediately without animating. For full control, compose createTransitionPlan + runThemeAnimation from @theme-kit/core.

Directives

ExportDescription
ThemeScopeDirectiveElement-scoped theming via a directive.

SSR & Bootstrap

ExportDescription
createAngularPersistence()Angular-flavored persistence adapter.
createBlockingScriptContent / buildThemeCSSMapZero-flash bootstrap helpers for server-rendered apps.
Angular — Theme Kit