import * as _angular_core from '@angular/core'; import { InjectionToken } from '@angular/core'; import * as ngx_theme_stack from 'ngx-theme-stack'; /** * Runtime list of built-in themes. * * Lives here (and not in config/index.ts) because it defines a type: * config/index.ts already imports from types.ts, so placing DEFAULT_THEMES * here avoids any circular dependency. * * ⚠ KEEP IN SYNC with the duplicate in: * projects/ngx-theme-stack/schematics/ng-add/constants.ts → DEFAULT_THEMES * * Schematics compile to CommonJS and cannot import from this ESM file, * so the values are intentionally duplicated. Change both at the same time. */ declare const DEFAULT_THEMES: readonly ["system", "light", "dark"]; /** Literal union of built-in themes: `'system' | 'light' | 'dark'`. */ type DefaultNgTheme = (typeof DEFAULT_THEMES)[number]; /** * Theme type. * * - **Without** `T`: open union — accepts any `string` with IDE autocomplete * hints for the built-in themes (`'system' | 'light' | 'dark'`). * - **With** `T`: closed union — exactly `DefaultNgTheme | T`, enabling * full type-safety for custom theme sets. * * @example * NgTheme // 'system' | 'light' | 'dark' | (string & {}) * NgTheme<'sepia'> // 'system' | 'light' | 'dark' | 'sepia' */ type NgTheme = DefaultNgTheme | T; /** * Resolved theme — always `'light'` or `'dark'`, never `'system'`. * Represents the value that comes from `matchMedia`, not user selection. */ type NgSystemTheme = Exclude; /** * Theme application mode. * - `'attribute'`: sets `data-theme` attribute on `` * - `'class'`: adds theme class to `` * - `'both'`: uses both attribute and class */ type NgMode = 'attribute' | 'class' | 'both'; /** * Theme application strategy. * - `'blocking'`: theme CSS is loaded synchronously before rendering * - `'critters'`: theme CSS is inlined using Critters for SSR/SSG */ type NgStrategy = 'blocking' | 'critters'; /** * Library configuration. * * @typeParam T - Custom theme literals. Defaults to open `string`, preserving * backwards compatibility. Pass specific literals (e.g. `'sepia' | 'ocean'`) * via {@link provideThemeStack} to get a closed, type-safe theme union. */ interface NgConfig { /** The theme to use on first visit or when no preference is saved. Default: 'system'. */ defaultTheme: NgTheme; /** Key used to persist theme preference in localStorage. Default: 'ngx-theme-stack'. */ storageKey: string; /** * How the theme should be applied to the document (via class, attribute or both). * Default: 'class'. */ mode: NgMode; /** * Performance strategy for anti-flash. * Use 'critters' (default) to inline all theme CSS in — works for CSR, SSR, and SSG. * Use 'blocking' to load themes.css as a render-blocking stylesheet (HTTP-cacheable). */ strategy: NgStrategy; /** * The **resolved** list of supported theme identifiers, always including the * built-in themes (`'light'`, `'dark'`, `'system'`). * * When you pass custom themes to {@link provideThemeStack}, they are **merged** * with the built-in defaults — your custom values are appended after them. * * @example * // Input to provideThemeStack: * themes: ['sepia', 'ocean'] as const * * // Resolved value stored in NgConfig: * // ['system', 'light', 'dark', 'sepia', 'ocean'] * * Default (no custom themes): `['system', 'light', 'dark']`. */ themes: NgTheme[]; } /** * Core service for managing the application's color theme. * * Handles theme persistence, system preference detection, and DOM updates. * Supports built-in themes ('dark', 'light', 'system') and custom extensions. */ declare class CoreThemeService { #private; /** List of available themes for Select/Cycle services. Defaults to ['system', 'light', 'dark']. */ readonly availableThemes: string[]; /** The theme explicitly selected by the user. May be `'system'`. */ readonly selectedTheme: _angular_core.Signal; /** Resolved theme applied to the DOM. Always `'dark'` or `'light'` (or custom) — never `'system'`. */ readonly resolvedTheme: _angular_core.Signal<(string & {}) | NgSystemTheme>; /** * Whether the currently applied theme is dark. * * Returns `false` when a custom theme (e.g. `'sunset'`) is active — use * `resolvedTheme()` directly if you need to inspect the current custom theme. */ readonly isDark: _angular_core.Signal; /** * Whether the currently applied theme is light. * * Returns `false` when a custom theme (e.g. `'sepia'`) is active — use * `resolvedTheme()` directly if you need to inspect the current custom theme. */ readonly isLight: _angular_core.Signal; /** Whether the currently applied theme is system. */ readonly isSystem: _angular_core.Signal; readonly isHydrated: _angular_core.Signal; constructor(); /** * Changes the active theme. * * Persists the choice explicitly so that switching e.g. from `'system'` to * `'light'` is saved even when the resolved theme did not change * (system preference was already `'light'`). * * @param theme - The theme to apply: `'dark'`, `'light'`, `'system'`, or a custom theme name. * @throws If `theme` is not a valid theme according to library configuration. */ setTheme(theme: NgTheme): void; private resolveSystemPreference; private resolveInitialTheme; private startSystemThemeListener; private stopSystemThemeListener; private applyThemeToDOM; private applyThemeAttribute; private applyThemeClasses; private applyColorSchemeHint; private captureAntiFlashClass; private readStoredTheme; private saveTheme; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵprov: _angular_core.ɵɵInjectableDeclaration; } /** * ⚠ ATTENTION: SHARED CONFIGURATION VALUES * * These defaults MUST match the schematic defaults in: * projects/ngx-theme-stack/schematics/ng-add/constants.ts → DEFAULTS * * Schematics compile to CommonJS and cannot import from this ESM file, * so the values are intentionally duplicated. Change both at the same time. * * If you change defaults here, also update: * schematics/ng-add/constants.ts → DEFAULTS + DEFAULT_THEMES */ declare const DEFAULT_NG_CONFIG: { defaultTheme: "system"; storageKey: string; mode: "class"; strategy: "critters"; themes: ("system" | "light" | "dark")[]; }; declare const NGX_THEME_STACK_CONFIG: InjectionToken>; /** * Provides Theme Stack configuration to Angular's DI system. * * The `themes` option accepts **additional** theme identifiers beyond the * built-in defaults. They are merged with `'light'`, `'dark'`, and `'system'` * so that the resolved {@link NgConfig.themes} array always includes all of * them — your custom values are appended after the built-ins. * * **Defaults:** * - `themes`: `['light', 'dark', 'system']` * - `defaultTheme`: `'system'` * - `storageKey`: `'ngx-theme-stack'` * - `mode`: `'class'` * - `strategy`: `'critters'` * * The type parameter `T` is **inferred automatically** from the `themes` array * when passed as a `const` — no need to specify it manually. * * @typeParam T - Custom theme string literals, inferred from the `themes` option. * * @param config - Optional partial configuration. Omitted fields fall back to * {@link DEFAULT_NG_CONFIG}. * * @throws {@link NgxThemeStackError} * - If any entry in `themes` is an empty or whitespace-only string. * - If `defaultTheme` is not present in the resolved (merged) themes array. * - If `storageKey` is an empty or whitespace-only string. * * @example * // Default — uses built-in themes and sensible defaults * provideThemeStack() * * @example * // Critters strategy — inlines all theme CSS in (works for CSR, SSR, and SSG) * provideThemeStack({ * strategy: 'critters', * mode: 'class', * }) * * @example * // Closed union: TypeScript infers 'sepia' | 'ocean' from the array * provideThemeStack({ * themes: ['sepia', 'ocean'] as const, * defaultTheme: 'sepia', // ✅ in resolved themes * // defaultTheme: 'nope', // ❌ throws NgxThemeStackError at runtime * }) * * @example * // Custom storage key and mode * provideThemeStack({ * storageKey: 'my-app-theme', * mode: 'attribute', * }) */ declare function provideThemeStack(config?: Partial>): { provide: InjectionToken>; useValue: NgConfig; }; /** * Convenience service for cycling through themes in a fixed order. * * Default cycle: `'system'` → `'light'` → `'dark'` → `'system'` → ... * * Use this when you want to offer users a single button that rotates * through all available theme options. */ declare class ThemeCycleService { #private; /** List of all configured themes for cycling. Defaults to `['light', 'dark', 'system']`. */ readonly availableThemes: string[]; /** The theme explicitly selected by the user. May be `'system'`. */ readonly selectedTheme: _angular_core.Signal; /** Resolved theme currently applied to the DOM. Always concrete — never `'system'`. */ readonly resolvedTheme: _angular_core.Signal<(string & {}) | ngx_theme_stack.NgSystemTheme>; /** Index of the currently selected theme in the cycle. */ readonly cycleIndex: _angular_core.Signal; /** The theme that comes before the currently selected theme in the cycle. */ readonly preceding: _angular_core.Signal; /** The theme that comes after the currently selected theme in the cycle. */ readonly upcoming: _angular_core.Signal; /** Whether the currently applied theme is `'dark'`. */ readonly isDark: _angular_core.Signal; /** Whether the currently applied theme is `'light'`. */ readonly isLight: _angular_core.Signal; /** Whether the user has explicitly selected `'system'` preference. */ readonly isSystem: _angular_core.Signal; /** * Whether the service has completed client-side initialization and * resolved the real persisted theme. Use to prevent hydration flashes. */ readonly isHydrated: _angular_core.Signal; /** * Advances to the next theme in the cycle. * * Cycle order is determined by the configured `themes` property in `NgConfig`. * * If the current theme is not found in the cycle (e.g. set externally), * the cycle restarts from the first theme. */ cycle(): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵprov: _angular_core.ɵɵInjectableDeclaration; } /** * Convenience service for selecting a theme from a list. * * Use this when you want to bind a `