@ethlete/core 5.0.0-next.4 → 5.0.0-next.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,15 +1,16 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { InjectionToken, AfterViewInit, Signal, ComponentRef, StaticProvider, EmbeddedViewRef, Provider, InjectOptions, TemplateRef, QueryList, InputSignal, InputSignalWithTransform, PipeTransform, TrackByFunction, ElementRef, WritableSignal, DestroyRef, Injector, RendererStyleFlags2, OnInit, OnDestroy } from '@angular/core';
2
+ import { InjectionToken, AfterViewInit, EmbeddedViewRef, ElementRef, QueryList, Signal, WritableSignal, InputSignalWithTransform, Provider, RendererStyleFlags2, Type, ComponentRef, Injector, ViewContainerRef, StaticProvider, Binding, computed, InjectOptions, TemplateRef, InputSignal, PipeTransform, TrackByFunction, ApplicationRef } from '@angular/core';
3
3
  import * as rxjs from 'rxjs';
4
4
  import { Observable, BehaviorSubject, Subject } from 'rxjs';
5
5
  import * as _ethlete_core from '@ethlete/core';
6
- import { OverlayRef } from '@angular/cdk/overlay';
7
- import { ComponentPortal, ComponentType } from '@angular/cdk/portal';
8
- import { Placement, OffsetOptions, Padding } from '@floating-ui/dom';
6
+ import * as _floating_ui_dom from '@floating-ui/dom';
7
+ import { VirtualElement, Placement, OffsetOptions, Padding } from '@floating-ui/dom';
9
8
  import { MatchListView, ParticipantViewUnion, MatchRankingView, StageType } from '@ethlete/types';
10
9
  import * as _angular_platform_browser from '@angular/platform-browser';
11
- import { FormGroup, AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
12
- import { Data, Params, Event as Event$1 } from '@angular/router';
10
+ import { AbstractControl, FormGroup, ValidationErrors, ValidatorFn } from '@angular/forms';
11
+ import * as _angular_router from '@angular/router';
12
+ import { Data, Params, Router } from '@angular/router';
13
+ import { FieldTree } from '@angular/forms/signals';
13
14
 
14
15
  declare const ANIMATABLE_TOKEN: InjectionToken<AnimatableDirective>;
15
16
  type AnimationEndEvent = {
@@ -36,6 +37,14 @@ declare class AnimatableDirective {
36
37
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<AnimatableDirective, "[etAnimatable]", ["etAnimatable"], {}, {}, never, never, true, never>;
37
38
  }
38
39
 
40
+ declare const ANIMATION_DEBUG_STORAGE_KEY = "et-overlay-debug";
41
+ /**
42
+ * Debug logging for overlay and animation lifecycle internals.
43
+ * Enable via `localStorage.setItem('et-overlay-debug', 'true')` and reload.
44
+ */
45
+ declare const isAnimationDebugEnabled: () => boolean;
46
+ declare const animationDebugLog: (scope: string, ...args: unknown[]) => void;
47
+
39
48
  declare const ANIMATED_IF_TOKEN: InjectionToken<AnimatedIfDirective>;
40
49
  declare class AnimatedIfDirective {
41
50
  private templateRef;
@@ -77,187 +86,23 @@ declare class AnimatedLifecycleDirective implements AfterViewInit {
77
86
  private removeClass;
78
87
  private removeClasses;
79
88
  private updateState;
89
+ private debugLog;
80
90
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AnimatedLifecycleDirective, never>;
81
91
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<AnimatedLifecycleDirective, "[etAnimatedLifecycle]", ["etAnimatedLifecycle"], { "skipNextEnter": { "alias": "skipNextEnter"; "required": false; "isSignal": true; }; }, { "stateChange": "stateChange"; "skipNextEnter": "skipNextEnterChange"; }, never, never, true, [{ directive: typeof AnimatableDirective; inputs: {}; outputs: {}; }]>;
82
92
  }
83
93
 
84
- type ThemeRGBColor = `${number} ${number} ${number}`;
85
- type ThemeHSLColor = `${number} ${number}% ${number}%`;
86
- type ThemeColor = ThemeRGBColor | ThemeHSLColor;
87
- type ThemeColorMap = {
88
- default: ThemeColor;
89
- hover: ThemeColor;
90
- focus?: ThemeColor;
91
- active: ThemeColor;
92
- disabled: ThemeColor;
93
- };
94
- type OnThemeColorMap = {
95
- default: ThemeColor;
96
- hover?: ThemeColor;
97
- focus?: ThemeColor;
98
- active?: ThemeColor;
99
- disabled?: ThemeColor;
100
- };
101
- type ThemeSwatch = {
102
- color: ThemeColorMap;
103
- onColor: OnThemeColorMap;
104
- };
105
- type Theme = {
106
- name: string;
107
- isDefault?: boolean;
108
- isDefaultAlt?: boolean;
109
- primary: ThemeSwatch;
110
- secondary?: ThemeSwatch;
111
- tertiary?: ThemeSwatch;
112
- };
113
- declare const createCssThemeName: (name: string) => string;
114
- declare const ɵProvideColorThemes: (valueOverride?: (string | undefined)[] | undefined) => _angular_core.Provider[];
115
- declare const injectColorThemes: {
116
- (): string[];
117
- (options: _angular_core.InjectOptions & {
118
- optional?: false;
119
- }): string[];
120
- (options: _angular_core.InjectOptions): string[] | null;
121
- };
122
- declare const ɵProvideThemesPrefix: (valueOverride?: string | undefined) => _angular_core.Provider[];
123
- declare const injectThemesPrefix: {
124
- (): string;
125
- (options: _angular_core.InjectOptions & {
126
- optional?: false;
127
- }): string;
128
- (options: _angular_core.InjectOptions): string | null;
129
- };
130
- declare const provideColorThemesWithTailwind4: (themes: Theme[], prefix?: string) => _angular_core.Provider[][];
131
-
132
- /**
133
- * @deprecated Migrate to Tailwind v4. Intent to remove in v6.
134
- */
135
- declare const createSwatchCss: (swatch: string, isAlt: boolean, data: ThemeSwatch) => string;
136
- /**
137
- * @deprecated Migrate to Tailwind v4. Intent to remove in v6.
138
- */
139
- declare const createRootThemeCss: (themes: Theme[]) => void;
140
- /**
141
- * @deprecated Migrate to Tailwind v4. Intent to remove in v6.
142
- */
143
- declare const createThemeStyle: (theme: Theme, isAlt: boolean) => void;
144
- /**
145
- * @deprecated Migrate to Tailwind v4. Intent to remove in v6.
146
- */
147
- declare const createTailwindCssVar: (name: string | undefined) => string | null;
148
- /**
149
- * @deprecated Migrate to Tailwind v4. Intent to remove in v6.
150
- */
151
- declare const createTailwindRgbVar: (val: string | undefined) => string | null;
152
- /**
153
- * @deprecated Migrate to Tailwind v4. Intent to remove in v6.
154
- */
155
- declare const createTailwindColorThemes: (themes: Theme[], prefix?: string) => Record<string, {
156
- DEFAULT: string;
157
- hover: string;
158
- focus: string;
159
- active: string;
160
- disabled: string;
161
- }>;
162
- /**
163
- * @deprecated Use provideColorThemesWithTailwind4 instead after migrating to Tailwind CSS v4. Intent to remove in v6.
164
- */
165
- declare const provideColorThemes: (themes: Theme[]) => _angular_core.Provider[][];
166
-
167
- declare const THEME_PROVIDER: InjectionToken<ProvideThemeDirective>;
168
- declare class ProvideThemeDirective {
169
- private themes;
170
- private prefix;
171
- private injector;
172
- private currentProviderSync;
173
- mainTheme: _angular_core.InputSignal<string | null | undefined>;
174
- altTheme: _angular_core.InputSignal<string | null | undefined>;
175
- mainThemeName: _angular_core.Signal<string | undefined>;
176
- altThemeName: _angular_core.Signal<string | undefined>;
177
- protected themeClass: _angular_core.Signal<string>;
178
- syncWithProvider(provider: ProvideThemeDirective): void;
179
- stopSyncWithProvider(): void;
180
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<ProvideThemeDirective, never>;
181
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ProvideThemeDirective, "[etProvideTheme]", never, { "mainTheme": { "alias": "etProvideTheme"; "required": false; "isSignal": true; }; "altTheme": { "alias": "etProvideAltTheme"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
182
- }
183
-
184
- type AnimatedOverlayComponentBase = {
185
- animatedLifecycle: Signal<AnimatedLifecycleDirective | undefined>;
186
- setThemeFromProvider: (provider: ProvideThemeDirective) => void;
187
- };
188
- type AnimatedOverlayMountConfig<T> = {
189
- component: ComponentType<T>;
190
- providers?: StaticProvider[];
191
- data?: Partial<T>;
192
- themeProvider?: ProvideThemeDirective | null;
193
- };
194
- type AnimatedOverlayState = 'init' | 'mounting' | 'mounted' | 'unmounting' | 'unmounted';
195
- declare class AnimatedOverlayDirective<T extends AnimatedOverlayComponentBase> {
196
- private overlayService;
197
- private injector;
198
- private viewContainerRef;
199
- private zone;
200
- private elementRef;
201
- private rootBoundary;
202
- private destroyRef;
203
- private floatingElCleanupFn;
204
- private unmountSubscription;
205
- placement: _angular_core.InputSignal<Placement | undefined>;
206
- fallbackPlacements: _angular_core.InputSignal<Placement[] | undefined>;
207
- offset: _angular_core.InputSignal<OffsetOptions | null>;
208
- arrowPadding: _angular_core.InputSignal<Padding | null>;
209
- viewportPadding: _angular_core.InputSignal<Padding | null>;
210
- autoResize: _angular_core.InputSignalWithTransform<boolean, unknown>;
211
- shift: _angular_core.InputSignalWithTransform<boolean, unknown>;
212
- autoHide: _angular_core.InputSignalWithTransform<boolean, unknown>;
213
- autoCloseIfReferenceHidden: _angular_core.InputSignalWithTransform<boolean, unknown>;
214
- referenceElement: _angular_core.InputSignal<HTMLElement>;
215
- mirrorWidth: _angular_core.InputSignalWithTransform<boolean, unknown>;
216
- portal: ComponentPortal<T> | null;
217
- overlayRef: OverlayRef | null;
218
- componentRef: ComponentRef<T> | null;
219
- beforeOpened$: Subject<void>;
220
- afterOpened$: Subject<void>;
221
- beforeClosed$: Subject<void>;
222
- afterClosed$: Subject<void>;
223
- state: _angular_core.WritableSignal<AnimatedOverlayState>;
224
- isMounted: Signal<boolean>;
225
- isMounting: Signal<boolean>;
226
- isUnmounted: Signal<boolean>;
227
- isUnmounting: Signal<boolean>;
228
- canMount: Signal<boolean>;
229
- canUnmount: Signal<boolean>;
230
- isHidden: _angular_core.WritableSignal<boolean>;
231
- isMounted$: rxjs.Observable<boolean>;
232
- isMounting$: rxjs.Observable<boolean>;
233
- isUnmounted$: rxjs.Observable<boolean>;
234
- isUnmounting$: rxjs.Observable<boolean>;
235
- canMount$: rxjs.Observable<boolean>;
236
- canUnmount$: rxjs.Observable<boolean>;
237
- isHidden$: rxjs.Observable<boolean>;
238
- referenceElementDimensions: Signal<_ethlete_core.NullableElementDimensions>;
239
- constructor();
240
- mount(config: AnimatedOverlayMountConfig<T>): T | undefined;
241
- unmount(): void;
242
- private applyComponentData;
243
- private applyThemeProvider;
244
- private updateOverlaySize;
245
- private setupFloatingUI;
246
- private getFloatingArrow;
247
- private updateFloatingPosition;
248
- private buildFloatingMiddleware;
249
- private applyFloatingStyles;
250
- private applyArrowStyles;
251
- private handleReferenceHidden;
252
- private waitForRenderAndAnimate;
253
- private destroy;
254
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<AnimatedOverlayDirective<any>, never>;
255
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<AnimatedOverlayDirective<any>, "[etAnimatedOverlay]", ["etAnimatedOverlay"], { "placement": { "alias": "placement"; "required": false; "isSignal": true; }; "fallbackPlacements": { "alias": "fallbackPlacements"; "required": false; "isSignal": true; }; "offset": { "alias": "offset"; "required": false; "isSignal": true; }; "arrowPadding": { "alias": "arrowPadding"; "required": false; "isSignal": true; }; "viewportPadding": { "alias": "viewportPadding"; "required": false; "isSignal": true; }; "autoResize": { "alias": "autoResize"; "required": false; "isSignal": true; }; "shift": { "alias": "shift"; "required": false; "isSignal": true; }; "autoHide": { "alias": "autoHide"; "required": false; "isSignal": true; }; "autoCloseIfReferenceHidden": { "alias": "autoCloseIfReferenceHidden"; "required": false; "isSignal": true; }; "referenceElement": { "alias": "referenceElement"; "required": false; "isSignal": true; }; "mirrorWidth": { "alias": "mirrorWidth"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
256
- }
257
-
258
94
  declare const nextFrame: (cb: () => void) => void;
259
95
  declare const fromNextFrame: () => Observable<void>;
260
96
  declare const forceReflow: (element?: HTMLElement) => number;
97
+ /**
98
+ * Whether the user asked for reduced motion, read straight from `matchMedia`.
99
+ *
100
+ * Inside a component, prefer the reactive `injectPrefersReducedMotion()`. This is for the animation
101
+ * helpers that run from effects, event handlers and imperative APIs, where there is no injection
102
+ * context. Pass the element being animated so the query resolves against its own window - otherwise
103
+ * an animation inside an iframe would read the top-level document's preference.
104
+ */
105
+ declare const matchesReducedMotion: (element?: Element) => boolean;
261
106
 
262
107
  type FlipAnimationGroupConfig = {
263
108
  /**
@@ -277,6 +122,15 @@ type FlipAnimationGroupConfig = {
277
122
  * @default 'cubic-bezier(0.4, 0, 0.2, 1)'
278
123
  */
279
124
  easing?: string;
125
+ /**
126
+ * Play the animation even when the user prefers reduced motion.
127
+ *
128
+ * Only set this for movement that carries meaning the user would otherwise miss - decorative
129
+ * movement should stay gated.
130
+ *
131
+ * @default false
132
+ */
133
+ ignoreReducedMotion?: boolean;
280
134
  };
281
135
  declare const createFlipAnimationGroup: (config: FlipAnimationGroupConfig) => {
282
136
  updateInit: () => void;
@@ -306,6 +160,15 @@ type FlipAnimationConfig = {
306
160
  * @default 'cubic-bezier(0.4, 0, 0.2, 1)'
307
161
  */
308
162
  easing?: string;
163
+ /**
164
+ * Play the animation even when the user prefers reduced motion.
165
+ *
166
+ * Only set this for movement that carries meaning the user would otherwise miss - decorative
167
+ * movement should stay gated.
168
+ *
169
+ * @default false
170
+ */
171
+ ignoreReducedMotion?: boolean;
309
172
  };
310
173
  declare const createFlipAnimation: (config: FlipAnimationConfig) => {
311
174
  updateInit: () => void;
@@ -335,1287 +198,2248 @@ declare class RepeatDirective {
335
198
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RepeatDirective, "[etRepeat]", never, { "repeatCount": { "alias": "etRepeat"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
336
199
  }
337
200
 
338
- declare const createComponentId: (prefix: string) => string;
201
+ declare class ScrollObserverEndDirective {
202
+ private elementRef;
203
+ private host;
204
+ constructor();
205
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ScrollObserverEndDirective, never>;
206
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ScrollObserverEndDirective, "[etScrollObserverEnd]", never, {}, {}, never, never, true, never>;
207
+ }
339
208
 
340
- declare const createDestroy: () => rxjs.Observable<boolean>;
209
+ declare class ScrollObserverStartDirective {
210
+ private elementRef;
211
+ private host;
212
+ constructor();
213
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ScrollObserverStartDirective, never>;
214
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ScrollObserverStartDirective, "[etScrollObserverStart]", never, {}, {}, never, never, true, never>;
215
+ }
341
216
 
342
- declare const injectHostElement: <T = HTMLElement>() => T;
343
- declare const injectTemplateRef: <C = unknown>() => TemplateRef<C>;
344
- type CreateProviderOptions = {
217
+ type SignalElementBindingComplexType = HTMLElement | ElementRef<HTMLElement> | QueryList<ElementRef<HTMLElement> | HTMLElement> | Array<ElementRef<HTMLElement> | HTMLElement> | null | undefined;
218
+ type SignalElementBindingType = HTMLElement | ElementRef<HTMLElement> | Observable<SignalElementBindingComplexType> | Signal<SignalElementBindingComplexType> | QueryList<ElementRef<HTMLElement> | HTMLElement> | ElementSignal;
219
+ type ElementSignal = Signal<{
220
+ currentElements: HTMLElement[];
221
+ previousElements: HTMLElement[];
222
+ }>;
223
+ type ElementSignalValue = ReturnType<ElementSignal>;
224
+ declare const isElementSignal: (el: unknown) => el is ElementSignal;
225
+ declare const createDocumentElementSignal: () => ElementSignal;
226
+ declare const createEmptyElementSignal: () => ElementSignal;
227
+ declare const buildElementSignal: (el: SignalElementBindingType | null | undefined) => ElementSignal;
228
+ declare const firstElementSignal: (el: ElementSignal) => Signal<{
229
+ currentElement: HTMLElement | null;
230
+ previousElement: HTMLElement | null;
231
+ }>;
232
+
233
+ type AnimatedSizeAxis = 'block' | 'inline';
234
+ type AnimatedBlockSizeConfig = {
235
+ /** The element whose size is animated. Defaults to the host `ElementRef`. */
236
+ host?: SignalElementBindingType;
345
237
  /**
346
- * Optional name for the provider, useful for debugging.
347
- * If not provided, the name will be a generated string.
238
+ * The content element(s) whose size changes drive the animation. Observe the content (children),
239
+ * **not** the animated host - observing the host would feed the animation back into itself.
240
+ * For the `inline` axis this also means the observed content must be content-sized (e.g.
241
+ * `inline-size: max-content`); a plain block child just mirrors the host's animated width back.
348
242
  */
349
- name?: string;
243
+ observe: SignalElementBindingType | SignalElementBindingType[];
350
244
  /**
351
- * Optional existing InjectionToken to also provide the created provider under.
245
+ * The axes to animate. May be a signal - e.g. to drop the `inline` axis while a panel is in a
246
+ * presentation whose width follows the viewport instead of its content. @default ['block']
352
247
  */
353
- extraInjectionToken?: InjectionToken<unknown>;
248
+ axes?: AnimatedSizeAxis[] | Signal<AnimatedSizeAxis[]>;
249
+ /** Animation duration in ms. @default 160 */
250
+ duration?: number;
251
+ /** Animation easing. @default 'ease' */
252
+ easing?: string;
253
+ /** Class toggled on the host while animating - use it to `overflow: clip` during the resize. */
254
+ resizingClass?: string;
354
255
  };
355
- type ProviderResult<T> = readonly [
356
- provide: () => Provider[],
357
- inject: {
358
- (): T;
359
- (options: InjectOptions & {
360
- optional?: false;
361
- }): T;
362
- (options: InjectOptions): T | null;
363
- },
364
- token: InjectionToken<T>
365
- ];
366
- type StaticProviderResult<T> = readonly [
367
- provide: (valueOverride?: Partial<T>) => Provider[],
368
- inject: {
369
- (): T;
370
- (options: InjectOptions & {
371
- optional?: false;
372
- }): T;
373
- (options: InjectOptions): T | null;
374
- },
375
- token: InjectionToken<T>
376
- ];
377
- type RootProviderResult<T> = readonly [
378
- inject: {
379
- (): T;
380
- (options: InjectOptions & {
381
- optional?: false;
382
- }): T;
383
- (options: InjectOptions): T | null;
384
- },
385
- token: InjectionToken<T>
386
- ];
387
- declare const createProvider: <T>(factory: () => T, options?: CreateProviderOptions) => ProviderResult<T>;
388
- declare const createRootProvider: <T>(factory: () => T, options?: CreateProviderOptions) => ProviderResult<T>;
389
- declare const createStaticProvider: <T>(defaultValue?: T, options?: CreateProviderOptions) => StaticProviderResult<T>;
390
- declare const createStaticRootProvider: <T>(defaultValue?: T, options?: CreateProviderOptions) => StaticProviderResult<T>;
391
-
392
- declare const cloneFormGroup: <T extends FormGroup<any>>(formGroup: T) => T;
393
- declare const getFormGroupValue: <T extends FormGroup>(formGroup: T) => Record<string, unknown>;
394
-
395
- declare const createRxHostListener: <K extends keyof HTMLElementEventMap>(eventName: K, options?: EventListenerOptions) => rxjs.Observable<HTMLElementEventMap[K]>;
396
- declare const applyHostListener: <K extends keyof HTMLElementEventMap>(eventName: K, handler: (event: HTMLElementEventMap[K]) => void, options?: EventListenerOptions) => rxjs.Subscription;
397
- declare const applyHostListeners: (listeners: Partial<{ [K in keyof HTMLElementEventMap]: (event: HTMLElementEventMap[K]) => void; }>, options?: EventListenerOptions) => void;
398
-
399
- declare class TypedQueryList<T> extends QueryList<T> {
400
- get changes(): Observable<TypedQueryList<T>>;
401
- }
402
- declare function switchQueryListChanges(): <T extends TypedQueryList<unknown> | null | undefined>(source: Observable<T>) => Observable<T>;
403
-
404
256
  /**
405
- * Sets the value of an input signal.
406
- * See issue: https://github.com/angular/angular/issues/54782
257
+ * Smoothly animates an element's `block-size` (and optionally `inline-size`, via `axes`) when its
258
+ * content changes size (e.g. a list filtering, a loading state resolving, a column being added).
259
+ * Set up once in an injection context; it observes the given content element(s) and animates the
260
+ * host from its previous size to its new natural size.
261
+ *
262
+ * Robustness notes: the baseline size is captured on the first render (via `afterNextRender`) and
263
+ * only later changes animate, so the initial layout settling never plays as a grow-from-0.
264
+ * A change that interrupts an in-flight animation continues from the current animated size, and
265
+ * zero/pre-layout measurements are ignored. Respects `prefers-reduced-motion`.
266
+ *
267
+ * The animation starts synchronously inside the `ResizeObserver` callback - it runs after layout
268
+ * but **before paint**, so the host never paints a frame at its new natural size. Routing the
269
+ * resize through a signal + effect instead would apply the animation one change-detection cycle
270
+ * (= one painted frame) late: a growing panel would flash at its final size, snap back, and only
271
+ * then animate.
407
272
  */
408
- declare const setInputSignal: <T>(input: InputSignal<T> | InputSignalWithTransform<T, unknown>, value: T) => void;
273
+ declare const injectAnimatedBlockSize: (config: AnimatedBlockSizeConfig) => void;
409
274
 
410
- type NgClassType = string | string[] | Set<string> | {
411
- [klass: string]: any;
412
- } | null | undefined;
413
-
414
- declare const AT_LEAST_ONE_REQUIRED = "atLeastOneRequired";
415
- type ValidateAtLeastOneRequiredConfig = {
275
+ declare const previousSignalValue: <T>(signal: Signal<T>) => Signal<T | undefined>;
276
+ type SyncSignalOptions = {
416
277
  /**
417
- * Keys of form controls to validate in the supplied form group
278
+ * If true, the target signal will not be updated with the source signal's value in a sync operation.
279
+ * This should be set to true for signals that need to be initialized first before syncing (eg. required inputs)
280
+ * @default false
418
281
  */
419
- keys: string[];
282
+ skipSyncRead?: boolean;
420
283
  /**
421
- * If true, the value `false` will result in a validation error
284
+ * If true, the first time the effect will be triggered will be skipped.
422
285
  * @default false
423
286
  */
424
- checkFalse?: boolean;
425
- };
426
- declare const ValidateAtLeastOneRequired: (config: ValidateAtLeastOneRequiredConfig) => ValidatorFn;
427
- declare const IS_ARRAY_NOT_EMPTY = "isArrayNotEmpty";
428
- declare const IsArrayNotEmpty: (control: AbstractControl) => ValidationErrors | null;
429
- declare const IS_EMAIL = "isEmail";
430
- declare const IsEmail: (control: AbstractControl) => ValidationErrors | null;
431
- declare const MUST_MATCH = "mustMatch";
432
- declare const MustMatch: (controlName: string, matchingControlName: string) => (formGroup: AbstractControl) => {
433
- mustMatch: boolean;
434
- } | null;
435
- declare const Validators: {
436
- readonly MustMatch: (controlName: string, matchingControlName: string) => (formGroup: AbstractControl) => {
437
- mustMatch: boolean;
438
- } | null;
439
- readonly IsEmail: (control: AbstractControl) => ValidationErrors | null;
440
- readonly IsArrayNotEmpty: (control: AbstractControl) => ValidationErrors | null;
441
- readonly ValidateAtLeastOneRequired: (config: ValidateAtLeastOneRequiredConfig) => ValidatorFn;
442
- };
443
-
444
- declare const clone: <T>(original: T) => T;
445
- declare const equal: (foo: any, bar: any) => boolean;
446
-
447
- declare const hasCookie: (name: string) => boolean;
448
- declare const getCookie: (name: string) => string | null | undefined;
449
- declare const setCookie: (name: string, data: string, expiresInDays?: number | null, domain?: string | null, path?: string, sameSite?: "strict" | "none" | "lax") => void;
450
- declare const deleteCookie: (name: string, path?: string, domain?: string | null) => void;
451
- declare const getDomain: () => string | null;
452
-
453
- type Translatable = {
454
- i18n: string;
455
- text: string;
456
- };
457
-
458
- declare class KeyPressManager {
459
- readonly key: number;
460
- private readonly _isKeyPressed$;
461
- private readonly _keyPressCount$;
462
- private readonly _stopTimeout$;
463
- constructor(key: number);
464
- isPressed(event: KeyboardEvent): boolean;
465
- clear(): void;
466
- }
467
-
468
- declare const DISABLE_LOGGER_PARAM = "et-logger-quiet";
469
- type CreateLoggerConfig = {
470
- scope: string;
471
- feature: string;
472
- };
473
- declare const createLogger: (config: CreateLoggerConfig) => {
474
- log: (...args: unknown[]) => void;
475
- warn: (...args: unknown[]) => void;
476
- error: (...args: unknown[]) => void;
287
+ skipFirstRun?: boolean;
477
288
  };
478
-
479
- declare const clamp: (value: number, min?: number, max?: number) => number;
480
- declare const round: (value: number, precision?: number) => number;
481
-
482
- declare const isObject: (value: unknown) => value is Record<string, unknown>;
483
- declare const isArray: (value: unknown) => value is unknown[];
484
- declare const getObjectProperty: (obj: Record<string, unknown>, prop: string) => unknown;
485
-
486
- declare const RUNTIME_ERROR_NO_DATA = "__ET_NO_DATA__";
487
- declare class RuntimeError<T extends number> extends Error {
488
- code: T;
489
- devOnly: boolean;
490
- data: unknown;
491
- constructor(code: T, message: null | false | string, devOnly?: boolean, data?: unknown);
492
- }
493
- declare function formatRuntimeError<T extends number>(code: T, message: null | false | string, devOnly: boolean): string;
494
-
289
+ declare const syncSignal: <T>(from: Signal<T>, to: WritableSignal<T>, options?: SyncSignalOptions) => _angular_core.EffectRef;
290
+ type MaybeSignal<T> = T | Signal<T>;
291
+ declare const maybeSignalValue: <T>(value: MaybeSignal<T>) => T;
292
+ /**
293
+ * A computed that will only be reactive until the source signal contains a truthy value.
294
+ * All subsequent changes inside the computation will be ignored.
295
+ */
296
+ declare const computedTillTruthy: <T>(source: Signal<T>) => Signal<T | null>;
495
297
  /**
496
- * Checks if an element or the viewport can scroll in a given direction.
497
- * @param element The element to check. If null/undefined, checks if the viewport can scroll.
498
- * @param direction The direction to check. If not provided, checks both directions.
499
- * @returns true if the element or viewport can scroll in the given direction.
298
+ * A computed that will only be reactive until the source signal contains a falsy value.
299
+ * All subsequent changes inside the computation will be ignored.
500
300
  */
501
- declare const elementCanScroll: (element?: HTMLElement | null, direction?: "x" | "y") => boolean;
502
- type IsElementVisibleOptions = {
301
+ declare const computedTillFalsy: <T>(source: Signal<T>) => Signal<T | null>;
302
+ /**
303
+ * A writeable signal that will be set to the provided value once all inputs are set.
304
+ * During that time, the signal will be set to `null`.
305
+ */
306
+ declare const deferredSignal: <T extends () => unknown>(valueFn: T) => WritableSignal<ReturnType<T> | null>;
307
+ declare const memoizeSignal: <T>(factory: () => Signal<T>) => () => Signal<T>;
308
+
309
+ type SignalAnimatedNumberOptions = {
503
310
  /**
504
- * The element to check if it is visible inside a container.
311
+ * The initial value to start animating from.
312
+ * If not provided, the animation will start from 0
505
313
  */
506
- element?: HTMLElement | null;
314
+ initialValue?: number;
507
315
  /**
508
- * The container to check if the element is visible inside.
509
- * If null or undefined, uses the viewport as the container.
510
- * @default null (viewport)
511
- */
512
- container?: HTMLElement | null;
513
- /**
514
- * The container's rect to check if the element is visible inside. Can be supplied to reduce the amount of DOM reads.
515
- * Only used when container is provided and not null.
516
- * @default container.getBoundingClientRect()
517
- */
518
- containerRect?: DOMRect | null;
519
- /**
520
- * The element's rect. Can be supplied to reduce the amount of DOM reads.
521
- * @default element.getBoundingClientRect()
522
- */
523
- elementRect?: DOMRect | null;
524
- };
525
- type CurrentElementVisibility = {
526
- /**
527
- * Whether the element is visible in the inline direction.
528
- */
529
- inline: boolean;
530
- /**
531
- * Whether the element is visible in the block direction.
532
- */
533
- block: boolean;
534
- /**
535
- * The percentage of the element that is visible in the inline direction.
536
- */
537
- inlineIntersection: number;
538
- /**
539
- * The percentage of the element that is visible in the block direction.
540
- */
541
- blockIntersection: number;
542
- /**
543
- * Whether the element is intersecting the container.
316
+ * Duration of the animation in milliseconds.
317
+ * @default 1000
544
318
  */
545
- isIntersecting: boolean;
319
+ duration?: number;
546
320
  /**
547
- * The ratio of the element that is intersecting the container.
321
+ * Easing function that takes a progress value (0 to 1) and returns an eased value (0 to 1).
322
+ * Options:
323
+ * - `easeLinear()`
324
+ * - `easeIn()`
325
+ * - `easeOut()`
326
+ * - `easeInOut()`
327
+ * - `easeElastic()`
328
+ * - `easeOutBack()`
329
+ * - `easeOutBackStrong()`
330
+ * @default easeOut()
548
331
  */
549
- intersectionRatio: number;
332
+ easing?: (t: number) => number;
550
333
  /**
551
- * The element that is being checked for visibility.
334
+ * Function to round the animated value.
335
+ * @default (v: number) => Math.round(v)
552
336
  */
553
- element: HTMLElement;
337
+ round?: (value: number) => number;
554
338
  /**
555
- * The container's rect used for the calculation.
339
+ * Callback invoked when the animation starts.
556
340
  */
557
- containerRect: DOMRect;
341
+ onAnimationStart?: () => void;
558
342
  /**
559
- * The element's rect used for the calculation.
343
+ * Callback invoked when the animation ends.
560
344
  */
561
- elementRect: DOMRect;
345
+ onAnimationEnd?: () => void;
562
346
  };
563
- declare const isElementVisible: (options: IsElementVisibleOptions) => CurrentElementVisibility | null;
564
- declare const getElementScrollCoordinates: (options: ScrollToElementOptions) => ScrollToOptions;
565
- type ScrollToElementOptions = {
566
- /**
567
- * The element to scroll to.
568
- */
569
- element?: HTMLElement | null;
570
- /**
571
- * The scroll container to scroll to the element in.
572
- * Must be provided - cannot scroll the viewport programmatically with this function.
573
- */
574
- container?: HTMLElement | null;
575
- /**
576
- * The direction to scroll in.
577
- * @default 'both'
578
- */
579
- direction?: 'inline' | 'block' | 'both';
580
- /**
581
- * The origin of the element to scroll to.
582
- * @default 'nearest'
583
- */
584
- origin?: 'start' | 'end' | 'center' | 'nearest';
347
+ type AnimatedNumberSignal = Signal<number> & {
585
348
  /**
586
- * The scroll behavior.
587
- * @default 'smooth'
349
+ * Starts the animation from the current value to the target value.
350
+ * @returns The animated signal for chaining
588
351
  */
589
- behavior?: ScrollBehavior;
352
+ play: () => AnimatedNumberSignal;
590
353
  /**
591
- * The scroll inline-margin
592
- * @default 0
354
+ * Resets the animation to the initial value and stops any ongoing animation.
355
+ * @returns The animated signal for chaining
593
356
  */
594
- scrollInlineMargin?: number;
357
+ reset: () => AnimatedNumberSignal;
595
358
  /**
596
- * The scroll block-margin
597
- * @default 0
359
+ * Stops the current animation at its current position.
360
+ * @returns The animated signal for chaining
598
361
  */
599
- scrollBlockMargin?: number;
362
+ stop: () => AnimatedNumberSignal;
600
363
  };
601
- declare const scrollToElement: (options: ScrollToElementOptions) => void;
364
+ /**
365
+ * Creates a signal that animates the transition of a numeric signal's value over time.
366
+ */
367
+ declare const signalAnimatedNumber: (source: MaybeSignal<number>, options?: SignalAnimatedNumberOptions) => AnimatedNumberSignal;
368
+ declare const easeLinear: (t: number) => number;
369
+ declare const easeIn: (t: number) => number;
370
+ declare const easeOut: (t: number) => number;
371
+ declare const easeInOut: (t: number) => number;
372
+ /** Elastic easing function (overshoots) */
373
+ declare const easeElastic: (t: number) => number;
374
+ /** Back easing function (overshoots slightly then settles) */
375
+ declare const easeOutBack: (t: number) => number;
376
+ /** Back easing function with more overshoot */
377
+ declare const easeOutBackStrong: (t: number) => number;
602
378
 
603
- declare class NormalizeGameResultTypePipe implements PipeTransform {
604
- transform: (type: string | null) => NormalizedGameResultType | null;
605
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<NormalizeGameResultTypePipe, never>;
606
- static ɵpipe: _angular_core.ɵɵPipeDeclaration<NormalizeGameResultTypePipe, "etNormalizeGameResultType", true>;
607
- }
608
- type NormalizedGameResultType = Translatable & {
609
- shortCode: string;
379
+ type Vec2 = [number, number];
380
+ type ViewportConfig = {
381
+ breakpoints: {
382
+ xs: Vec2;
383
+ sm: Vec2;
384
+ md: Vec2;
385
+ lg: Vec2;
386
+ xl: Vec2;
387
+ '2xl': Vec2;
388
+ };
610
389
  };
611
- declare const normalizeGameResultType: (type: string | null) => NormalizedGameResultType | null;
612
-
613
- declare class NormalizeMatchParticipantsPipe implements PipeTransform {
614
- transform: (match: MatchListView | null) => NormalizedMatchParticipants | null;
615
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<NormalizeMatchParticipantsPipe, never>;
616
- static ɵpipe: _angular_core.ɵɵPipeDeclaration<NormalizeMatchParticipantsPipe, "etNormalizeMatchParticipants", true>;
617
- }
618
- type NormalizedMatchParticipants = {
619
- home: NormalizedMatchParticipant | null;
620
- away: NormalizedMatchParticipant | null;
390
+ type Breakpoint = keyof ViewportConfig['breakpoints'];
391
+ declare const BREAKPOINT_ORDER: Breakpoint[];
392
+ /**
393
+ * Default viewport config based on Tailwind CSS.
394
+ * @see https://tailwindcss.com/docs/screens
395
+ */
396
+ declare const DEFAULT_VIEWPORT_CONFIG: ViewportConfig;
397
+ declare const provideViewportConfig: (valueOverride?: Partial<ViewportConfig> | undefined) => _angular_core.Provider[];
398
+ declare const injectViewportConfig: _ethlete_core.InjectFn<ViewportConfig>;
399
+ type BuildMediaQueryOptions = {
400
+ min?: number | Breakpoint;
401
+ max?: number | Breakpoint;
621
402
  };
622
- type NormalizedParticipantType = 'team' | 'player' | 'unknown';
623
- type NormalizedMatchParticipant = ({
624
- type: 'tbd';
625
- participantType: NormalizedParticipantType;
626
- data: ParticipantViewUnion | null;
627
- } & Translatable) | {
628
- type: 'participant';
629
- participantType: NormalizedParticipantType;
630
- data: ParticipantViewUnion;
631
- } | ({
632
- type: 'none';
633
- participantType: NormalizedParticipantType;
634
- data: ParticipantViewUnion | null;
635
- } & Translatable);
636
- declare const normalizeMatchParticipants: (match: MatchListView | null) => NormalizedMatchParticipants | null;
637
- declare const normalizeMatchParticipant: (match: MatchListView | null, side: "home" | "away") => NormalizedMatchParticipant | null;
403
+ declare const provideBreakpointObserver: () => _angular_core.Provider[];
404
+ declare const injectBreakpointObserver: _ethlete_core.InjectFn<{
405
+ observeBreakpoint: (options: BuildMediaQueryOptions) => Signal<boolean>;
406
+ isBreakpointMatched: (options: BuildMediaQueryOptions) => boolean;
407
+ getBreakpointSize: (type: Breakpoint, option: "min" | "max") => number;
408
+ buildMediaQueryString: (options: BuildMediaQueryOptions) => string;
409
+ observeMediaQuery: (mediaQuery: string) => Signal<boolean>;
410
+ isMediaQueryMatched: (mediaQuery: string) => boolean;
411
+ }>;
638
412
 
639
- declare class NormalizeMatchScorePipe implements PipeTransform {
640
- transform: (match: MatchListView | null | undefined) => NormalizedMatchScore | null;
641
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<NormalizeMatchScorePipe, never>;
642
- static ɵpipe: _angular_core.ɵɵPipeDeclaration<NormalizeMatchScorePipe, "etNormalizeMatchScore", true>;
643
- }
644
- declare const enum MatchStateType {
645
- PREPARING_ROUND = "preparingRound",
646
- PRE_MATCH = "preMatch",
647
- LIVE = "live",
648
- POST_MATCH = "postMatch",
649
- AUTO_WIN = "autoWin"
650
- }
651
- type NormalizedMatchScore = {
652
- home: {
653
- score: string | number | null;
654
- isWinner: boolean;
655
- };
656
- away: {
657
- score: string | number | null;
658
- isWinner: boolean;
659
- };
660
- subLine: string | null;
661
- isNumeric: boolean;
413
+ type BreakpointMap<T> = Partial<Record<Breakpoint, T>>;
414
+ type BreakpointInput<T> = T | BreakpointMap<T>;
415
+ declare const breakpointTransformBase: <T, WriteT = BreakpointInput<T>>(coerce: (value: WriteT) => T) => ((value: WriteT) => T);
416
+ /**
417
+ * Transform factory for boolean inputs.
418
+ * Coerces plain values with `booleanAttribute`; resolves {@link BreakpointMap} mobile-first.
419
+ *
420
+ * @example
421
+ * snap = input(false, { transform: boolBreakpointTransform() });
422
+ * // Template: `snap` | `[snap]="true"` | `[snap]="{ xs: false, md: true }"`
423
+ */
424
+ declare const boolBreakpointTransform: () => ((value: BreakpointInput<boolean> | string) => boolean);
425
+ /**
426
+ * Transform factory for number inputs.
427
+ * Coerces plain values with `numberAttribute`; resolves {@link BreakpointMap} mobile-first.
428
+ *
429
+ * @example
430
+ * scrollMargin = input(0, { transform: numberBreakpointTransform() });
431
+ * // Template: `[scrollMargin]="16"` | `[scrollMargin]="{ xs: 0, md: 16 }"`
432
+ */
433
+ declare const numberBreakpointTransform: () => ((value: BreakpointInput<number> | string) => number);
434
+ /**
435
+ * Transform factory for any typed input (string unions, arrays, objects, etc.).
436
+ * Passes plain values through as-is; resolves {@link BreakpointMap} mobile-first.
437
+ * A value is treated as a {@link BreakpointMap} only when all its keys are valid breakpoint names.
438
+ *
439
+ * @example
440
+ * itemSize = input('auto', { transform: typedBreakpointTransform<ScrollableItemSize>() });
441
+ * tags = input([], { transform: typedBreakpointTransform<string[]>() });
442
+ * // Template: `[itemSize]="'third'"` | `[itemSize]="{ xs: 'full', md: 'third' }"`
443
+ */
444
+ declare const typedBreakpointTransform: <T>() => ((value: BreakpointInput<T>) => T);
445
+ type BoolBreakpointSignal = InputSignalWithTransform<boolean, BreakpointInput<boolean> | string>;
446
+ type NumberBreakpointSignal = InputSignalWithTransform<number, BreakpointInput<number> | string>;
447
+ type TypedBreakpointSignal<T> = InputSignalWithTransform<T, BreakpointInput<T>>;
448
+ declare const injectBreakpointInput: <T>(inputSignal: Signal<BreakpointInput<T>>, defaultValue: T) => Signal<T>;
449
+ declare const booleanBreakpointAttribute: (value: unknown) => BreakpointInput<boolean>;
450
+ declare const numberBreakpointAttribute: (value: unknown) => BreakpointInput<number>;
451
+ declare const BREAKPOINT_INSTANCE_TOKEN: InjectionToken<unknown>;
452
+ declare const provideBreakpointInstance: (componentClass: unknown) => {
453
+ provide: InjectionToken<unknown>;
454
+ useExisting: unknown;
662
455
  };
663
- declare const normalizeMatchScore: (match: MatchListView | null | undefined) => NormalizedMatchScore | null;
664
- declare const isKnockoutMatch: (match: MatchListView | null | undefined) => boolean;
665
- declare const isGroupMatch: (match: MatchListView | null | undefined) => boolean;
666
- declare const getKnockoutMatchScore: (score: MatchRankingView | null | undefined) => "match-score.knockout.won" | "match-score.knockout.lost" | "match-score.knockout.tie" | null;
667
- declare const getMatchScoreSubLine: (match: MatchListView | null | undefined) => "match-score.groups.sub-line" | null;
668
- declare const getGroupMatchScore: (match: MatchListView | null | undefined) => {
669
- home: {
670
- score: number;
671
- isWinner: boolean;
672
- };
673
- away: {
674
- score: number;
675
- isWinner: boolean;
676
- };
677
- } | null;
678
- declare const getGroupMatchPoints: (match: MatchListView | null | undefined) => {
679
- home: {
680
- score: number;
681
- isWinner: boolean;
682
- };
683
- away: {
684
- score: number;
685
- isWinner: boolean;
686
- };
687
- } | null;
688
456
 
689
- declare class NormalizeMatchStatePipe implements PipeTransform {
690
- transform: (match: MatchListView | null | undefined) => MatchStateType | null;
691
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<NormalizeMatchStatePipe, never>;
692
- static ɵpipe: _angular_core.ɵɵPipeDeclaration<NormalizeMatchStatePipe, "etNormalizeMatchState", true>;
693
- }
694
- declare const normalizeMatchState: (match: MatchListView | null | undefined) => MatchStateType | null;
457
+ type ControlValueSignalOptions = {
458
+ debounceTime?: number;
459
+ /**
460
+ * @default false
461
+ */
462
+ debounceFirst?: boolean;
463
+ };
464
+ declare const controlValueSignal: <TControlInput extends Signal<AbstractControl | null> | AbstractControl, TControl extends (TControlInput extends Signal<infer TSignalControl> ? TSignalControl : TControlInput)>(control: TControlInput, options?: ControlValueSignalOptions) => Signal<ReturnType<NonNullable<TControl>["getRawValue"]> | null>;
465
+ /**
466
+ * The first item in the pair is the previous value and the second item is the current value.
467
+ */
468
+ declare const controlValueSignalWithPrevious: <T extends AbstractControl>(control: T, options?: ControlValueSignalOptions) => Signal<[ReturnType<NonNullable<T extends Signal<infer TSignalControl> ? TSignalControl : T>["getRawValue"]> | null, ReturnType<NonNullable<T extends Signal<infer TSignalControl> ? TSignalControl : T>["getRawValue"]> | null]>;
695
469
 
696
- declare class NormalizeMatchTypePipe implements PipeTransform {
697
- transform: (matchType: StageType | null | undefined) => Translatable | null;
698
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<NormalizeMatchTypePipe, never>;
699
- static ɵpipe: _angular_core.ɵɵPipeDeclaration<NormalizeMatchTypePipe, "etNormalizeMatchType", true>;
700
- }
701
- declare const normalizeMatchType: (matchType: StageType | null | undefined) => Translatable | null;
470
+ type SignalElementChildrenOptions = {
471
+ /**
472
+ * What the underlying `MutationObserver` watches for. The default is deliberately broad, because any DOM
473
+ * change *might* change which children an element has.
474
+ *
475
+ * Narrow it wherever the consumer knows better. `attributes: true` in particular makes every inline style
476
+ * or class write anywhere in the subtree re-run this - which for a scroll container whose descendants are
477
+ * written to per animation frame is a change detection tick per frame for nothing. Pass an
478
+ * `attributeFilter` (or drop `attributes`) in that case.
479
+ */
480
+ mutations?: MutationObserverInit;
481
+ };
482
+ declare const signalElementChildren: (el: SignalElementBindingType, options?: SignalElementChildrenOptions) => _angular_core.Signal<HTMLElement[]>;
702
483
 
703
- declare class InferMimeTypePipe implements PipeTransform {
704
- transform: (srcset: string) => string | null;
705
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<InferMimeTypePipe, never>;
706
- static ɵpipe: _angular_core.ɵɵPipeDeclaration<InferMimeTypePipe, "inferMimeType", true>;
707
- }
484
+ type BuildSignalEffectsConfig<T extends Record<string, Signal<unknown>>> = {
485
+ /** The tokens to apply and their signal value */
486
+ tokenMap: T;
487
+ /** This function will be invoked for elements that were removed from the signal effects */
488
+ cleanupFn: (el: HTMLElement, tokens: string[]) => void;
489
+ /** This function will be invoked for elements that were added to the signal effects or when their signal value changes */
490
+ updateFn: (el: HTMLElement, tokens: string[], conditionResult: unknown) => void;
491
+ };
492
+ declare const buildSignalEffects: <T extends Record<string, Signal<unknown>>>(el: SignalElementBindingType, config: BuildSignalEffectsConfig<T>) => {
493
+ remove: (tokens: string) => void;
494
+ removeMany: (tokens: string[]) => void;
495
+ has: (tokens: string) => boolean;
496
+ push: (tokens: string, signal: Signal<unknown>) => void;
497
+ pushMany: (map: Record<string, Signal<unknown>>) => void;
498
+ };
499
+ declare const signalClasses: <T extends Record<string, Signal<unknown>>>(el: SignalElementBindingType, classMap: T) => {
500
+ remove: (tokens: string) => void;
501
+ removeMany: (tokens: string[]) => void;
502
+ has: (tokens: string) => boolean;
503
+ push: (tokens: string, signal: Signal<unknown>) => void;
504
+ pushMany: (map: Record<string, Signal<unknown>>) => void;
505
+ };
506
+ declare const signalHostClasses: <T extends Record<string, Signal<unknown>>>(classMap: T) => {
507
+ remove: (tokens: string) => void;
508
+ removeMany: (tokens: string[]) => void;
509
+ has: (tokens: string) => boolean;
510
+ push: (tokens: string, signal: Signal<unknown>) => void;
511
+ pushMany: (map: Record<string, Signal<unknown>>) => void;
512
+ };
513
+ declare const signalAttributes: <T extends Record<string, Signal<unknown>>>(el: SignalElementBindingType, attributeMap: T) => {
514
+ remove: (tokens: string) => void;
515
+ removeMany: (tokens: string[]) => void;
516
+ has: (tokens: string) => boolean;
517
+ push: (tokens: string, signal: Signal<unknown>) => void;
518
+ pushMany: (map: Record<string, Signal<unknown>>) => void;
519
+ };
520
+ declare const signalHostAttributes: <T extends Record<string, Signal<unknown>>>(attributeMap: T) => {
521
+ remove: (tokens: string) => void;
522
+ removeMany: (tokens: string[]) => void;
523
+ has: (tokens: string) => boolean;
524
+ push: (tokens: string, signal: Signal<unknown>) => void;
525
+ pushMany: (map: Record<string, Signal<unknown>>) => void;
526
+ };
527
+ declare const signalStyles: <T extends Record<string, Signal<unknown>>>(el: SignalElementBindingType, styleMap: T) => {
528
+ remove: (tokens: string) => void;
529
+ removeMany: (tokens: string[]) => void;
530
+ has: (tokens: string) => boolean;
531
+ push: (tokens: string, signal: Signal<unknown>) => void;
532
+ pushMany: (map: Record<string, Signal<unknown>>) => void;
533
+ };
534
+ declare const signalHostStyles: <T extends Record<string, Signal<unknown>>>(styleMap: T) => {
535
+ remove: (tokens: string) => void;
536
+ removeMany: (tokens: string[]) => void;
537
+ has: (tokens: string) => boolean;
538
+ push: (tokens: string, signal: Signal<unknown>) => void;
539
+ pushMany: (map: Record<string, Signal<unknown>>) => void;
540
+ };
541
+
542
+ type LogicalSize = {
543
+ inlineSize: number;
544
+ blockSize: number;
545
+ };
546
+ type ElementRect = {
547
+ bottom: number;
548
+ height: number;
549
+ left: number;
550
+ right: number;
551
+ top: number;
552
+ width: number;
553
+ x: number;
554
+ y: number;
555
+ };
556
+ type ElementSize = {
557
+ width: number;
558
+ height: number;
559
+ };
560
+ declare const boundingClientRectToElementRect: (rect: DOMRectReadOnly) => ElementRect;
561
+ declare const createElementDimensions: (el: HTMLElement | null, rect?: DOMRect) => NullableElementDimensions;
562
+ type ElementDimensions = {
563
+ rect: () => ElementRect;
564
+ client: ElementSize;
565
+ scroll: ElementSize;
566
+ offset: ElementSize;
567
+ };
568
+ type NullableElementDimensions = {
569
+ [K in keyof ElementDimensions]: ElementDimensions[K] | null;
570
+ };
571
+ declare const signalElementDimensions: (el: SignalElementBindingType) => Signal<NullableElementDimensions>;
572
+ declare const signalHostElementDimensions: () => Signal<NullableElementDimensions>;
573
+ declare const injectViewportSize: () => Signal<ElementSize>;
574
+
575
+ type SignalElementIntersectionOptions = Omit<IntersectionObserverInit, 'root'> & {
576
+ root?: SignalElementBindingType;
577
+ enabled?: Signal<boolean>;
578
+ };
579
+ type IntersectionObserverEntryWithDetails = IntersectionObserverEntry & {
580
+ isAbove: boolean;
581
+ isBelow: boolean;
582
+ isLeft: boolean;
583
+ isRight: boolean;
584
+ isVisible: boolean;
585
+ };
586
+ declare const signalElementIntersection: (el: SignalElementBindingType, options?: SignalElementIntersectionOptions) => Signal<IntersectionObserverEntryWithDetails[]>;
587
+ declare const signalHostElementIntersection: (options?: SignalElementIntersectionOptions) => Signal<IntersectionObserverEntryWithDetails[]>;
588
+
589
+ declare const signalElementMutations: (el: SignalElementBindingType, options?: MutationObserverInit) => _angular_core.Signal<MutationRecord | null>;
590
+ declare const signalHostElementMutations: (options?: MutationObserverInit) => _angular_core.Signal<MutationRecord | null>;
591
+
592
+ type ElementLastScrollDirectionType = 'up' | 'down' | 'left' | 'right';
593
+ type ElementLastScrollDirection = {
594
+ type: ElementLastScrollDirectionType;
595
+ time: number;
596
+ };
597
+ declare const signalElementLastScrollDirection: (el: SignalElementBindingType) => _angular_core.Signal<ElementLastScrollDirection | null>;
598
+ declare const signalHostElementLastScrollDirection: () => _angular_core.Signal<ElementLastScrollDirection | null>;
599
+
600
+ /**
601
+ * A signal for whether this page is the one the reader is actually looking at - `false` for a backgrounded
602
+ * tab or a minimised window.
603
+ *
604
+ * Not the same question as whether an element is on screen: an IntersectionObserver reports a fully visible
605
+ * element in a background tab, because the tab's own visibility is no part of what it measures. Anything
606
+ * that moves on its own needs to ask both, and a timer is not a substitute - browsers throttle timers in a
607
+ * hidden tab rather than stopping them, so work keeps piling up out of sight.
608
+ */
609
+ declare const injectIsDocumentVisible: () => _angular_core.Signal<boolean>;
610
+
611
+ type SignalElementScrollStateOptions = {
612
+ /** The initial scroll position to scroll to. Once a truthy value get's emitted, all further values will be ignored. */
613
+ initialScrollPosition?: Signal<ScrollToOptions | null>;
614
+ /**
615
+ * What the underlying `MutationObserver` watches for - a proxy for "the content may have changed size, so
616
+ * re-measure whether it still overflows". The default is deliberately broad.
617
+ *
618
+ * Narrow it wherever the consumer knows better. `attributes: true` means every inline style or class write
619
+ * anywhere in the subtree re-runs the measurement, and the measurement reads `scrollWidth`/`scrollHeight`
620
+ * - so a descendant written to per animation frame buys a forced layout per frame.
621
+ */
622
+ mutations?: MutationObserverInit;
623
+ };
624
+ type ElementScrollState = {
625
+ canScroll: boolean;
626
+ canScrollHorizontally: boolean;
627
+ canScrollVertically: boolean;
628
+ elementDimensions: NullableElementDimensions;
629
+ };
630
+ declare const areScrollStatesEqual: (a: ElementScrollState, b: ElementScrollState) => boolean;
631
+ declare const signalElementScrollState: (el: SignalElementBindingType, options?: SignalElementScrollStateOptions) => Signal<ElementScrollState>;
632
+ declare const signalHostElementScrollState: () => Signal<ElementScrollState>;
633
+
634
+ declare const injectAngularRootElement: _ethlete_core.InjectFn<_angular_core.WritableSignal<HTMLElement | null>>;
635
+
636
+ declare const provideBoundaryElement: () => _angular_core.Provider[];
637
+ declare const injectBoundaryElement: _ethlete_core.InjectFn<{
638
+ value: _angular_core.Signal<HTMLElement>;
639
+ override: _angular_core.WritableSignal<HTMLElement | null>;
640
+ }>;
641
+ declare const BOUNDARY_ELEMENT_TOKEN: _angular_core.InjectionToken<{
642
+ value: _angular_core.Signal<HTMLElement>;
643
+ override: _angular_core.WritableSignal<HTMLElement | null>;
644
+ }>;
645
+
646
+ declare const provideFocusVisibleTracker: () => _angular_core.Provider[];
647
+ declare const injectFocusVisibleTracker: _ethlete_core.InjectFn<{
648
+ isFocusVisible: _angular_core.Signal<boolean>;
649
+ }>;
650
+ declare const FOCUS_VISIBLE_TRACKER_TOKEN: _angular_core.InjectionToken<{
651
+ isFocusVisible: _angular_core.Signal<boolean>;
652
+ }>;
653
+
654
+ /**
655
+ * A label set, or a function building one for a locale. The function form is called again whenever
656
+ * {@link injectLocale}'s `currentLocale` changes, so a locale switch re-renders the wording without
657
+ * reloading - that is the seam an app's i18n library plugs into.
658
+ */
659
+ type LabelsSource<T> = Partial<T> | ((locale: string) => Partial<T>);
660
+ /** What {@link defineLabels} returns. */
661
+ type LabelsDefinition<T> = {
662
+ readonly provide: (labels: LabelsSource<T>) => Provider;
663
+ readonly inject: () => Signal<T>;
664
+ readonly token: InjectionToken<LabelsSource<T>>;
665
+ };
666
+ /**
667
+ * The one mechanism for the strings a component renders or announces itself. Every domain in the UI
668
+ * library that has such strings exposes exactly this pair - `provide<Domain>Labels` to localize a
669
+ * subtree, `inject<Domain>Labels()` to read the result - so localizing an app is the same move
670
+ * repeated per domain rather than a different one each time.
671
+ *
672
+ * `defaults` may itself be locale-derived, for a domain that ships more than one language (the
673
+ * `@ethlete/query` error tables, say). Overrides are partial and layer on top of whatever the locale
674
+ * resolved to, so translating into a third language while keeping a shipped one as the base is the
675
+ * same call.
676
+ *
677
+ * The injector returns a **signal**, because both halves can change at runtime - read it in a
678
+ * template or computed, never destructure it once.
679
+ *
680
+ * @example
681
+ * export type BreadcrumbLabels = { navigation: string; overflow: string };
682
+ *
683
+ * export const DEFAULT_BREADCRUMB_LABELS: BreadcrumbLabels = {
684
+ * navigation: 'Breadcrumb',
685
+ * overflow: 'Show hidden levels',
686
+ * };
687
+ *
688
+ * const BREADCRUMB_LABELS_DEF = defineLabels<BreadcrumbLabels>('BREADCRUMB_LABELS', DEFAULT_BREADCRUMB_LABELS);
689
+ *
690
+ * export const provideBreadcrumbLabels = toProvideFn(BREADCRUMB_LABELS_DEF);
691
+ * export const injectBreadcrumbLabels = toInjectFn(BREADCRUMB_LABELS_DEF);
692
+ * export const BREADCRUMB_LABELS = toToken(BREADCRUMB_LABELS_DEF);
693
+ *
694
+ * @example
695
+ * // consumer, fixed wording
696
+ * provideBreadcrumbLabels({ navigation: 'Brotkrumen' });
697
+ *
698
+ * // consumer, driven by the app's i18n and re-resolved on a locale change
699
+ * provideBreadcrumbLabels((locale) => ({ navigation: translate('breadcrumb.nav', locale) }));
700
+ */
701
+ declare const defineLabels: <T extends object>(name: string, defaults: T | ((locale: string) => T)) => LabelsDefinition<T>;
702
+
703
+ declare const provideLocale: () => _angular_core.Provider[];
704
+ declare const injectLocale: _ethlete_core.InjectFn<{
705
+ currentLocale: _angular_core.WritableSignal<string>;
706
+ }>;
707
+
708
+ declare const provideRenderer: () => _angular_core.Provider[];
709
+ declare const injectRenderer: _ethlete_core.InjectFn<{
710
+ addClass: (element: HTMLElement, ...classes: string[]) => void;
711
+ removeClass: (element: HTMLElement, ...classes: string[]) => void;
712
+ toggleClass: (element: HTMLElement, className: string, force?: boolean) => boolean;
713
+ setStyle: (element: HTMLElement, style: Partial<Record<keyof CSSStyleDeclaration, string | null>>, flags?: RendererStyleFlags2) => void;
714
+ removeStyle: (element: HTMLElement, style: keyof CSSStyleDeclaration | string, flags?: RendererStyleFlags2) => void;
715
+ removeStyles: (element: HTMLElement, ...styles: (keyof CSSStyleDeclaration | string)[]) => void;
716
+ setAttribute: (element: HTMLElement, name: string, value: string | null, namespace?: string | null) => void;
717
+ removeAttribute: (element: HTMLElement, ...names: string[]) => void;
718
+ setProperty: (element: HTMLElement, name: string, value: unknown) => void;
719
+ setProperties: (element: HTMLElement, properties: Record<string, unknown>) => void;
720
+ createElement: <K extends keyof HTMLElementTagNameMap>(tagName: K, namespace?: string | null) => HTMLElementTagNameMap[K];
721
+ createText: (value: string) => Text;
722
+ createComment: (value: string) => Comment;
723
+ appendChild: (parent: HTMLElement, newChild: Node) => void;
724
+ insertBefore: (parent: Node, newChild: Node, refChild: Node | null) => void;
725
+ removeChild: (parent: Node, oldChild: Node, isHostElement?: boolean) => void;
726
+ selectRootElement: (selectorOrNode: string | HTMLElement, preserveContent?: boolean) => HTMLElement;
727
+ parentNode: (node: Node) => Node | null;
728
+ nextSibling: (node: Node) => Node | null;
729
+ setValue: (node: Node, value: string) => void;
730
+ listen: (target: HTMLElement | Window | Document | "window" | "document" | "body", eventName: string, callback: (event: Event) => boolean | void) => (() => void);
731
+ destroyNode: (node: Node) => void;
732
+ replaceChild: (parent: Node, newChild: Node, oldChild: Node) => void;
733
+ empty: (element: HTMLElement) => void;
734
+ setTextContent: (element: HTMLElement, text: string) => void;
735
+ setInnerHTML: (element: HTMLElement, html: string) => void;
736
+ setAttributes: (element: HTMLElement, attributes: Record<string, string | null>, namespace?: string | null) => void;
737
+ setDataAttributes: (element: HTMLElement, data: Record<string, string | null>) => void;
738
+ setCssProperty: (element: HTMLElement, name: string, value: string | null) => void;
739
+ setCssProperties: (element: HTMLElement, properties: Record<string, string | null>) => void;
740
+ moveBefore: (config: {
741
+ newParent: HTMLElement;
742
+ child: HTMLElement;
743
+ before?: Node | null;
744
+ }) => void;
745
+ renderer: _angular_core.Renderer2;
746
+ }>;
747
+ type AngularRenderer = NonNullable<ReturnType<typeof injectRenderer>>;
748
+
749
+ type StyleManager = {
750
+ mount: <TComponent>(component: Type<TComponent>) => ComponentRef<TComponent>;
751
+ };
752
+ declare const provideStyleManager: () => _angular_core.Provider[];
753
+ declare const injectStyleManager: _ethlete_core.InjectFn<StyleManager>;
754
+
755
+ type ConsentHandler = {
756
+ /** Signal that is `true` when consent has been granted. */
757
+ isGranted: Signal<boolean>;
758
+ /** Grants consent and writes the decision back to the source. */
759
+ grant: () => void;
760
+ /** Revokes consent and writes the decision back to the source. */
761
+ revoke?: () => void;
762
+ };
763
+ type CreateUserConsentProviderOptions = {
764
+ /** The provider result returned by `createStaticProvider` that this consent provider should be associated with. */
765
+ for: InjectionToken<ConsentHandler | null>;
766
+ /**
767
+ * Factory executed inside the injection context that returns a `Signal<boolean>`.
768
+ *
769
+ * @example
770
+ * isGranted: () => inject(CookieService).hasMediaConsent
771
+ */
772
+ isGranted: () => Signal<boolean>;
773
+ /**
774
+ * Factory executed inside the injection context that returns the grant function.
775
+ *
776
+ * @example
777
+ * grant: () => () => inject(CookieService).acceptAll()
778
+ */
779
+ grant: () => () => void;
780
+ /**
781
+ * Factory executed inside the injection context that returns the revoke function.
782
+ *
783
+ * @example
784
+ * revoke : () => () => inject(CookieService).revokeAll()
785
+ */
786
+ revoke?: () => () => void;
787
+ };
788
+ declare const createUserConsentProvider: (options: CreateUserConsentProviderOptions) => Provider;
789
+
790
+ /** Inject a signal containing a boolean value indicating if the viewport is xs */
791
+ declare const injectIsXs: () => _angular_core.Signal<boolean>;
792
+ /** Inject a signal containing a boolean value indicating if the viewport is sm */
793
+ declare const injectIsSm: () => _angular_core.Signal<boolean>;
794
+ /** Inject a signal containing a boolean value indicating if the viewport is md */
795
+ declare const injectIsMd: () => _angular_core.Signal<boolean>;
796
+ /** Inject a signal containing a boolean value indicating if the viewport is lg */
797
+ declare const injectIsLg: () => _angular_core.Signal<boolean>;
798
+ /** Inject a signal containing a boolean value indicating if the viewport is xl */
799
+ declare const injectIsXl: () => _angular_core.Signal<boolean>;
800
+ /** Inject a signal containing a boolean value indicating if the viewport is 2xl */
801
+ declare const injectIs2Xl: () => _angular_core.Signal<boolean>;
802
+ /**
803
+ * Inject a boolean value indicating if the viewport is matching the provided options.
804
+ * This value is not reactive. If you want to react to changes, use the {@link injectObserveBreakpoint} function instead.
805
+ */
806
+ declare const injectBreakpointIsMatched: (options: BuildMediaQueryOptions) => boolean;
807
+ /**
808
+ * Inject a boolean value indicating if the media query is matched.
809
+ * This value is not reactive. If you want to react to changes, use the {@link injectObserveMediaQuery} function instead.
810
+ */
811
+ declare const injectMediaQueryIsMatched: (mediaQuery: string) => boolean;
812
+ /**
813
+ * Inject a signal containing a boolean value indicating if the viewport is matching the provided options.
814
+ */
815
+ declare const injectObserveBreakpoint: (options: BuildMediaQueryOptions) => _angular_core.Signal<boolean>;
816
+ /**
817
+ * Inject a signal containing a boolean value indicating if the media query is matched.
818
+ */
819
+ declare const injectObserveMediaQuery: (mediaQuery: string) => _angular_core.Signal<boolean>;
820
+ /** Inject a signal containing the current breakpoint. */
821
+ declare const injectCurrentBreakpoint: () => _angular_core.Signal<"xs" | "sm" | "md" | "lg" | "xl" | "2xl">;
822
+ /** Inject a signal that indicates if the user is using a portrait display */
823
+ declare const injectIsPortrait: () => _angular_core.Signal<boolean>;
824
+ /** Inject a signal that indicates if the user is using a landscape display */
825
+ declare const injectIsLandscape: () => _angular_core.Signal<boolean>;
826
+ /** Inject a signal containing the current display orientation */
827
+ declare const injectDisplayOrientation: () => _angular_core.Signal<"portrait" | "landscape">;
828
+ /** Inject a signal that indicates if the device has a touch input */
829
+ declare const injectHasTouchInput: () => _angular_core.Signal<boolean>;
830
+ /** Inject a signal that indicates if the device has a fine input (mouse or stylus) */
831
+ declare const injectHasPrecisionInput: () => _angular_core.Signal<boolean>;
832
+ /** Inject a signal containing the current device input type */
833
+ declare const injectDeviceInputType: () => _angular_core.Signal<"touch" | "mouse">;
834
+ /** Inject a signal that indicates if the user prefers reduced motion */
835
+ declare const injectPrefersReducedMotion: () => _angular_core.Signal<boolean>;
836
+ /** Inject a signal containing a boolean value indicating if the user can hover (eg. using a mouse) */
837
+ declare const injectCanHover: () => _angular_core.Signal<boolean>;
838
+ /** Inject a signal containing the viewport dimensions */
839
+ declare const injectViewportDimensions: () => _angular_core.Signal<_ethlete_core.NullableElementDimensions>;
840
+ /** Inject a signal containing the scrollbar dimensions. Dimensions will be 0 if scrollbars overlap the page contents (like on mobile). */
841
+ declare const injectScrollbarDimensions: () => _angular_core.Signal<{
842
+ width: number;
843
+ height: number;
844
+ } | null>;
845
+
846
+ /**
847
+ * Applies scrollbar size CSS variables to the documentElement (html tag) in pixels.
848
+ * - `--et-sw`: scrollbar width
849
+ * - `--et-sh`: scrollbar height
850
+ */
851
+ declare const writeScrollbarSizeToCssVariables: () => void;
852
+ /**
853
+ * Applies viewport size CSS variables to the documentElement (html tag) in pixels.
854
+ * - `--et-vw`: viewport width excluding scrollbar width
855
+ * - `--et-vh`: viewport height excluding scrollbar height
856
+ */
857
+ declare const writeViewportSizeToCssVariables: () => void;
858
+
859
+ type CursorDragScrollDirection = 'horizontal' | 'vertical' | 'both';
860
+ type CursorDragScrollOptions = {
861
+ /** If true, cursor drag scrolling will be enabled. */
862
+ enabled?: Signal<boolean>;
863
+ /** The allowed scroll direction. */
864
+ allowedDirection?: MaybeSignal<CursorDragScrollDirection>;
865
+ /**
866
+ * Whether the element overflows in the allowed direction - there is nothing to drag if it does not.
867
+ *
868
+ * Measured here when it isn't supplied, which means a MutationObserver and a ResizeObserver of its own.
869
+ * Hand it over wherever the caller already knows: a scrollable that tracks its own scroll state was ending
870
+ * up with two observers watching the same element for the same thing, and both of them re-measured
871
+ * `scrollWidth` - a forced layout - on every inline style written anywhere inside it.
872
+ */
873
+ canScroll?: Signal<boolean>;
874
+ };
875
+ /** A function to apply cursor drag scroll behavior to an element. */
876
+ declare const useCursorDragScroll: (el: SignalElementBindingType, options?: CursorDragScrollOptions) => {
877
+ isDragging: Signal<boolean>;
878
+ currentDragAmount: Signal<{
879
+ x: number;
880
+ y: number;
881
+ }>;
882
+ };
883
+
884
+ /**
885
+ * The element that gets scrolled. Pass a function if the scroll container is created per route or
886
+ * only exists after the app shell rendered - it is resolved on every navigation instead of once at
887
+ * setup time.
888
+ * @default document.documentElement
889
+ */
890
+ type ScrollRestorationScrollElement = HTMLElement | (() => HTMLElement | null | undefined);
891
+ type ScrollRestorationRestoreConfig = {
892
+ /**
893
+ * Restore the previous scroll offset when the user navigates back or forward through the browser
894
+ * history, instead of scrolling to top.
895
+ *
896
+ * The offset is not applied on the loading frame: query driven pages render skeletons/empty states
897
+ * first, so the document is far shorter than it was when the user left. Restoration waits until
898
+ * the content is tall enough to actually reach the saved offset (see `timeout`).
899
+ * @default false
900
+ */
901
+ enabled?: boolean;
902
+ /**
903
+ * How long to keep waiting (in ms) for the content to grow tall enough to reach the saved offset.
904
+ * The clock is suspended while a {@link holdScrollRestoration} registration reads `true`.
905
+ * @default 1000
906
+ */
907
+ timeout?: number;
908
+ /**
909
+ * Absolute upper bound (in ms) for a single restoration attempt, regardless of
910
+ * {@link holdScrollRestoration} registrations. Guards against a page that never stops loading.
911
+ * @default 10000
912
+ */
913
+ maxTimeout?: number;
914
+ /**
915
+ * Whether to apply the saved offset clamped to the reachable maximum once `timeout` elapsed
916
+ * without the content getting tall enough. Landing close to the previous position is usually
917
+ * better than staying at the top.
918
+ * @default true
919
+ */
920
+ clampOnTimeout?: boolean;
921
+ };
922
+ type SetupScrollRestorationConfig = {
923
+ /**
924
+ * The scrollable container.
925
+ * @default document.documentElement
926
+ */
927
+ scrollElement?: ScrollRestorationScrollElement;
928
+ /**
929
+ * A list of query params that should trigger a scroll to top.
930
+ * @default []
931
+ * @example ['page'] // will scroll to top when the page query param changes
932
+ */
933
+ queryParamTriggerList?: string[];
934
+ /**
935
+ * Config for fragment scrolling.
936
+ */
937
+ fragment?: {
938
+ /**
939
+ * Enable fragment scrolling (scroll to element with id)
940
+ * @default false
941
+ */
942
+ enabled?: boolean;
943
+ /**
944
+ * Whether to use smooth scrolling or not.
945
+ * @default false
946
+ */
947
+ smooth?: boolean;
948
+ };
949
+ /**
950
+ * Config for restoring the previous scroll offset on browser back/forward navigation.
951
+ * Disabled by default - without it, history navigation scrolls to top like any other navigation.
952
+ */
953
+ restore?: ScrollRestorationRestoreConfig;
954
+ };
955
+ declare const ET_DISABLE_SCROLL_TOP: unique symbol;
956
+ declare const ET_DISABLE_SCROLL_TOP_AS_RETURN_ROUTE: unique symbol;
957
+ declare const ET_DISABLE_SCROLL_TOP_ON_PATH_PARAM_CHANGE: unique symbol;
958
+ type RouterDisableScrollTopConfig = {
959
+ /**
960
+ * Whether to disable scroll to top ONLY when navigating back to this route.
961
+ * @default false
962
+ */
963
+ asReturnRoute?: boolean;
964
+ /**
965
+ * Whether to disable scroll to top when a path param changes.
966
+ * @default false
967
+ */
968
+ onPathParamChange?: boolean;
969
+ };
970
+ declare const routerDisableScrollTop: (config?: RouterDisableScrollTopConfig) => {
971
+ [ET_DISABLE_SCROLL_TOP_ON_PATH_PARAM_CHANGE]?: boolean | undefined;
972
+ [ET_DISABLE_SCROLL_TOP]: boolean;
973
+ } | {
974
+ [ET_DISABLE_SCROLL_TOP_ON_PATH_PARAM_CHANGE]?: boolean | undefined;
975
+ [ET_DISABLE_SCROLL_TOP_AS_RETURN_ROUTE]: boolean;
976
+ };
977
+ /**
978
+ * Suspend scroll restoration while `isPending` reads `true`.
979
+ *
980
+ * Restoration already waits for the scroll container to grow tall enough to reach the saved offset,
981
+ * so this is only needed when the content may take longer than `restore.timeout` to get there -
982
+ * a slow list request, for instance. Registers for the lifetime of the current injection context.
983
+ *
984
+ * @example
985
+ * // inside a route component
986
+ * holdScrollRestoration(() => query.isLoading());
987
+ */
988
+ declare const holdScrollRestoration: (isPending: () => boolean) => void;
989
+ declare const setupScrollRestoration: (config?: SetupScrollRestorationConfig) => void;
990
+
991
+ declare const signalIsRendered: () => _angular_core.Signal<boolean>;
992
+ declare const createIsRenderedSignal: () => {
993
+ state: _angular_core.WritableSignal<boolean>;
994
+ bind: () => _angular_core.EffectRef;
995
+ };
996
+ declare const createCanAnimateSignal: () => {
997
+ state: _angular_core.Signal<boolean>;
998
+ };
999
+
1000
+ type RouterState = {
1001
+ data: Data;
1002
+ pathParams: Params;
1003
+ queryParams: Params;
1004
+ title: string | null;
1005
+ fragment: string | null;
1006
+ };
1007
+ declare const ET_PROPERTY_REMOVED: unique symbol;
1008
+ type InjectUtilConfig = {
1009
+ /** The injector to use for the injection. Must be provided if the function is not called from within a injection context. */
1010
+ injector?: Injector;
1011
+ };
1012
+ type InjectUtilTransformConfig<In, Out> = {
1013
+ /**
1014
+ * A transform function similar to the `transform` function in Angular input bindings.
1015
+ * Can be used to transform the value before it is returned.
1016
+ * E.g. transforming `"true"` to `true` for a boolean attribute.
1017
+ */
1018
+ transform?: (value: In) => Out;
1019
+ };
1020
+ declare const transformOrReturn: <In, Out>(src: Signal<In>, config?: InjectUtilTransformConfig<In, Out>) => Signal<Out>;
1021
+ /** Inject the current router event */
1022
+ declare const injectRouterEvent: () => Signal<_angular_router.Event>;
1023
+ /**
1024
+ * Signal that indicates whether the router has been initialized.
1025
+ * The router is considered initialized once the first NavigationEnd event with an id different than -1 has been emitted.
1026
+ */
1027
+ declare const injectIsRouterInitialized: () => Signal<boolean>;
1028
+ /**
1029
+ * Inject the current url.
1030
+ * The url includes query params as well as the fragment. Use `injectRoute` instead if you are not intrusted in those.
1031
+ * @example "/my-page?query=1&param=true#fragment"
1032
+ */
1033
+ declare const injectUrl: () => Signal<string>;
1034
+ /**
1035
+ * Inject the current route
1036
+ * @example "/my-page"
1037
+ */
1038
+ declare const injectRoute: () => Signal<string>;
1039
+ declare const createRouterState: (router: Router) => RouterState;
1040
+ /**
1041
+ * Read the current route (the committed url without query params and fragment) straight from the router.
1042
+ * Unlike the `injectRoute` signal this reads synchronously, so it can be used inside a `router.events` handler
1043
+ * where `router.url` is already committed. Falls back to the browser location before the first navigation commits.
1044
+ */
1045
+ declare const createRoute: (router: Router) => string;
1046
+ /**
1047
+ * Inject the complete router state. This includes the current route data, path params, query params, title and fragment.
1048
+ */
1049
+ declare const injectRouterState: () => Signal<RouterState>;
1050
+ /** Inject a signal containing the current route fragment (the part after the # inside the url if present) */
1051
+ declare const injectFragment: <T = string | null>(config?: InjectUtilConfig & InjectUtilTransformConfig<string | null, T>) => Signal<T>;
1052
+ /** Inject all currently available query parameters as a signal */
1053
+ declare const injectQueryParams: () => Signal<Params>;
1054
+ /** Inject all currently available route data as a signal */
1055
+ declare const injectRouteData: () => Signal<Data>;
1056
+ /** Inject the current route title as a signal */
1057
+ declare const injectRouteTitle: <T = string | null>(config?: InjectUtilTransformConfig<string | null, T>) => Signal<T>;
1058
+ /** Inject all currently available path parameters as a signal */
1059
+ declare const injectPathParams: () => Signal<Params>;
1060
+ type InjectQueryParamConfig<T> = InjectUtilTransformConfig<string | null, T> & {
1061
+ /**
1062
+ * If true, the initial value will be read from the browser's url.
1063
+ * Note that this will not work with arrays or complex objects.
1064
+ */
1065
+ requireSync?: boolean;
1066
+ };
1067
+ /** Inject a specific query parameter as a signal */
1068
+ declare const injectQueryParam: <T = string | null>(key: string, config?: InjectQueryParamConfig<T>) => Signal<T>;
1069
+ /** Inject a specific route data item as a signal */
1070
+ declare const injectRouteDataItem: <T = unknown>(key: string, config?: InjectUtilTransformConfig<unknown, T>) => Signal<T>;
1071
+ /** Inject a specific path parameter as a signal */
1072
+ declare const injectPathParam: <T = string | null>(key: string, config?: InjectUtilTransformConfig<string | null, T>) => Signal<T>;
708
1073
  /**
709
- * Infers the mime type of a given url or srcset.
710
- * If a srcset is provided, it will infer the mime type of the first url in the srcset.
711
- * If the srcset contains a query parameter `?fm=`, it will use the value of that parameter, since it is often used to specify the file format in image api's like contentful.
1074
+ * Inject query params that changed during navigation. Unchanged query params will be ignored.
1075
+ * Removed query params will be represented by the symbol `ET_PROPERTY_REMOVED`.
712
1076
  */
713
- declare const inferMimeType: (srcset: string) => string | null;
1077
+ declare const injectQueryParamChanges: () => Signal<Record<string, unknown>>;
1078
+ /**
1079
+ * Inject path params that changed during navigation. Unchanged path params will be ignored.
1080
+ * Removed path params will be represented by the symbol `ET_PROPERTY_REMOVED`.
1081
+ */
1082
+ declare const injectPathParamChanges: () => Signal<Record<string, unknown>>;
1083
+ /**
1084
+ * The state handed to the navigation that is currently in progress, i.e. what
1085
+ * `router.navigate(…, { state })` passed - typed to whatever you expect.
1086
+ *
1087
+ * Read **synchronously**, in a constructor or a resolver, and deliberately not a signal: navigation state exists
1088
+ * only for the duration of the navigation that carries it. By the time an effect flushed, the navigation would be
1089
+ * over and the answer always `null`. Returns `null` when there is no navigation in flight or it carried no state -
1090
+ * which is the normal case for a page arrived at by typing its URL, so always handle it.
1091
+ *
1092
+ * Use it for the things a URL should not carry: a "you were redirected because…" reason, a pre-fetched object the
1093
+ * previous page already had, a scroll intent. Anything the page needs to survive a reload belongs in the URL.
1094
+ *
1095
+ * @example
1096
+ * type CheckoutNavState = { fromCart: boolean };
1097
+ *
1098
+ * export class CheckoutComponent {
1099
+ * private navState = injectRouterNavigationState<CheckoutNavState>();
1100
+ *
1101
+ * protected cameFromCart = this.navState?.fromCart ?? false;
1102
+ * }
1103
+ */
1104
+ declare const injectRouterNavigationState: <T>() => T | null;
714
1105
 
715
- declare class ToArrayPipe implements PipeTransform {
716
- transform: (value: number) => number[];
717
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<ToArrayPipe, never>;
718
- static ɵpipe: _angular_core.ɵɵPipeDeclaration<ToArrayPipe, "toArray", true>;
1106
+ declare class ScrollObserverDirective {
1107
+ private elementRef;
1108
+ enabled: _angular_core.ModelSignal<MaybeSignal<boolean>>;
1109
+ private enabledValue;
1110
+ private _startEl;
1111
+ private _endEl;
1112
+ private _startIntersection;
1113
+ private _endIntersection;
1114
+ isAtStart: Signal<boolean>;
1115
+ isAtEnd: Signal<boolean>;
1116
+ _registerStart(el: ElementRef<HTMLElement>): void;
1117
+ _registerEnd(el: ElementRef<HTMLElement>): void;
1118
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ScrollObserverDirective, never>;
1119
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ScrollObserverDirective, "[etScrollObserver]", ["etScrollObserver"], { "enabled": { "alias": "enabled"; "required": false; "isSignal": true; }; }, { "enabled": "enabledChange"; }, never, never, true, never>;
719
1120
  }
720
- declare const toArray: (value: number) => number[];
721
- declare const toArrayTrackByFn: TrackByFunction<number>;
722
1121
 
723
- declare const createPropHandlers: () => {
724
- classes: {
725
- remove: (tokens: string) => void;
726
- removeMany: (tokens: string[]) => void;
727
- has: (tokens: string) => boolean;
728
- push: (tokens: string, signal: _angular_core.Signal<unknown>) => void;
729
- pushMany: (map: Record<string, _angular_core.Signal<unknown>>) => void;
730
- };
731
- attributes: {
732
- remove: (tokens: string) => void;
733
- removeMany: (tokens: string[]) => void;
734
- has: (tokens: string) => boolean;
735
- push: (tokens: string, signal: _angular_core.Signal<unknown>) => void;
736
- pushMany: (map: Record<string, _angular_core.Signal<unknown>>) => void;
737
- };
738
- styles: {
739
- remove: (tokens: string) => void;
740
- removeMany: (tokens: string[]) => void;
741
- has: (tokens: string) => boolean;
742
- push: (tokens: string, signal: _angular_core.Signal<unknown>) => void;
743
- pushMany: (map: Record<string, _angular_core.Signal<unknown>>) => void;
744
- };
1122
+ type DragStartEvent = {
1123
+ /** Pointer position at pointerdown - NOT at commit-threshold crossing. */
1124
+ readonly clientX: number;
1125
+ readonly clientY: number;
1126
+ };
1127
+ type DragMoveEvent = {
1128
+ readonly stepX: number;
1129
+ readonly stepY: number;
1130
+ readonly clientX: number;
1131
+ readonly clientY: number;
1132
+ /** Cumulative delta from the pointerdown position. */
1133
+ readonly totalDx: number;
1134
+ readonly totalDy: number;
1135
+ };
1136
+ type DragGestureEvent = {
1137
+ readonly type: 'tapped';
1138
+ } | {
1139
+ readonly type: 'start';
1140
+ readonly data: DragStartEvent;
1141
+ } | {
1142
+ readonly type: 'move';
1143
+ readonly data: DragMoveEvent;
1144
+ } | {
1145
+ readonly type: 'end';
1146
+ };
1147
+ /**
1148
+ * Observe one drag gesture, starting from a `pointerdown` on `element`.
1149
+ *
1150
+ * Emits `start` once the pointer has travelled `commitThreshold` px (so a click is not a drag),
1151
+ * immediately followed by a catch-up `move`, then a `move` per pointer move, and finally `end`. A
1152
+ * pointer released before crossing the threshold emits a single `tapped` instead. The stream
1153
+ * completes with the gesture, so there is nothing to unsubscribe on the happy path.
1154
+ *
1155
+ * This is the primitive behind {@link DragHandleDirective}. Prefer the directive; reach for this when
1156
+ * the draggable element belongs to someone else's template (e.g. a table feature attaching a drag to
1157
+ * header cells the table itself renders) and you can only work from a delegated `pointerdown`.
1158
+ */
1159
+ declare const dragGestureFrom: (event: PointerEvent, element: HTMLElement, options?: {
1160
+ commitThreshold?: number;
1161
+ }) => Observable<DragGestureEvent>;
1162
+
1163
+ declare class DragHandleDirective {
1164
+ private el;
1165
+ commitThreshold: _angular_core.InputSignal<number>;
1166
+ disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
1167
+ private gestureStart$;
1168
+ private gesture$;
1169
+ dragTapped: _angular_core.OutputRef<void>;
1170
+ dragStarted: _angular_core.OutputRef<DragStartEvent>;
1171
+ dragMoved: _angular_core.OutputRef<DragMoveEvent>;
1172
+ dragEnded: _angular_core.OutputRef<void>;
1173
+ isDragging: _angular_core.Signal<boolean>;
1174
+ constructor();
1175
+ startGesture(event: PointerEvent): void;
1176
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DragHandleDirective, never>;
1177
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DragHandleDirective, "[etDragHandle]", never, { "commitThreshold": { "alias": "commitThreshold"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "dragTapped": "dragTapped"; "dragStarted": "dragStarted"; "dragMoved": "dragMoved"; "dragEnded": "dragEnded"; }, never, never, true, never>;
1178
+ }
1179
+
1180
+ /**
1181
+ * The browser's notification permission, widened with `'unsupported'` - which covers both a browser
1182
+ * without the Notification API and the server, where there is no `Notification` global to ask.
1183
+ */
1184
+ type NotificationPermissionState = NotificationPermission | 'unsupported';
1185
+ /**
1186
+ * Which of the two ways of putting a notification on screen was used.
1187
+ *
1188
+ * - `page` - the `Notification` constructor. Its events come back to the page, so `onClick`,
1189
+ * `onClose`, `onShow` and `onError` all work, but the notification dies with the tab.
1190
+ * - `service-worker` - `ServiceWorkerRegistration.showNotification()`. The only path Android Chrome
1191
+ * and installed iOS web apps have, and the only one that can render `actions` - but its clicks are
1192
+ * delivered to the service worker rather than to the page, see {@link ShowNotificationConfig.onClick}.
1193
+ * - `unavailable` - nothing was shown: no API, permission not granted, the page path threw and no
1194
+ * service worker was registered to fall back to, or the notification was closed before it appeared.
1195
+ */
1196
+ type NotificationDeliveryPath = 'page' | 'service-worker' | 'unavailable';
1197
+ /**
1198
+ * A button rendered on a notification. Service-worker path only - `show()` routes a notification with
1199
+ * actions there automatically, and a notification pinned to `path: 'page'` drops them.
1200
+ */
1201
+ type NotificationActionConfig = {
1202
+ /** Identifies this button in the service worker's `notificationclick` handler (`event.action`). */
1203
+ action: string;
1204
+ /** The button's label. */
1205
+ title: string;
1206
+ /** Icon URL for the button. Rendered on Android, ignored on desktop. */
1207
+ icon?: string;
1208
+ };
1209
+ /** What {@link ShowNotificationConfig.onClick} is called with. */
1210
+ type NotificationClickContext = {
1211
+ /** The notification's tag - the generated one when the config did not set one. */
1212
+ tag: string;
1213
+ /** Whatever was passed as {@link ShowNotificationConfig.data}. */
1214
+ data: unknown;
1215
+ /** The action button that was clicked. Service-worker path only, and absent for the body itself. */
1216
+ action?: string;
1217
+ /** The underlying DOM event. Page path only. */
1218
+ event?: Event;
1219
+ };
1220
+ /**
1221
+ * The message a service worker posts to relay a notification click back to the page. Matches what
1222
+ * {@link NOTIFICATION_CLICK_MESSAGE_TYPE} documents.
1223
+ */
1224
+ type NotificationClickMessage = {
1225
+ type: typeof NOTIFICATION_CLICK_MESSAGE_TYPE;
1226
+ tag: string;
1227
+ data?: unknown;
1228
+ action?: string;
1229
+ };
1230
+ /**
1231
+ * The `message` type a service worker must post for `onClick` to fire on the service-worker path,
1232
+ * where the click event is dispatched to the worker and never reaches the page.
1233
+ *
1234
+ * Nothing in the SDK can install this handler - a service worker's code is the app's. Add it to yours
1235
+ * to make `onClick` work on Android Chrome and installed iOS web apps:
1236
+ *
1237
+ * ```js
1238
+ * self.addEventListener('notificationclick', (event) => {
1239
+ * event.notification.close();
1240
+ *
1241
+ * event.waitUntil(
1242
+ * self.clients.matchAll({ type: 'window', includeUncontrolled: true }).then((clients) => {
1243
+ * for (const client of clients) {
1244
+ * client.postMessage({
1245
+ * type: 'et:notification-click',
1246
+ * tag: event.notification.tag,
1247
+ * data: event.notification.data,
1248
+ * action: event.action || undefined,
1249
+ * });
1250
+ * }
1251
+ * }),
1252
+ * );
1253
+ * });
1254
+ * ```
1255
+ */
1256
+ declare const NOTIFICATION_CLICK_MESSAGE_TYPE = "et:notification-click";
1257
+ type ShowNotificationConfig = {
1258
+ /** The notification's headline. The only required field. */
1259
+ title: string;
1260
+ /** Body text below the title. */
1261
+ body?: string;
1262
+ /** URL of the image shown as the notification's icon. */
1263
+ icon?: string;
1264
+ /** URL of a small monochrome badge, shown in the Android status bar when the icon does not fit. */
1265
+ badge?: string;
1266
+ /**
1267
+ * URL of a large image shown inside the notification. Service-worker path only, and only honored by
1268
+ * Chromium.
1269
+ */
1270
+ image?: string;
1271
+ /**
1272
+ * Identity of the notification: showing another one with the same tag **replaces** it instead of
1273
+ * stacking, and it is what `close()` matches on the service-worker path.
1274
+ *
1275
+ * Leave it unset for a stand-alone notification - a unique tag is generated, which is what makes
1276
+ * `close()` and click relaying work at all. Set it to coalesce repeated notifications about the same
1277
+ * thing (one per chat, one per upload); `close()` on such a ref closes every notification sharing
1278
+ * the tag.
1279
+ */
1280
+ tag?: string;
1281
+ /** Arbitrary payload, handed back to `onClick` and to the service worker's `notificationclick`. */
1282
+ data?: unknown;
1283
+ /** Language of the title and body, as a BCP 47 tag. */
1284
+ lang?: string;
1285
+ /** Text direction of the title and body. */
1286
+ dir?: NotificationDirection;
1287
+ /** Show without sound or vibration. */
1288
+ silent?: boolean;
1289
+ /**
1290
+ * Keep the notification on screen until the user dismisses it, rather than auto-hiding it. Desktop
1291
+ * Chromium only; ignored elsewhere.
1292
+ */
1293
+ requireInteraction?: boolean;
1294
+ /**
1295
+ * Alert the user again when this notification replaces one with the same tag - by default a
1296
+ * replacement is silent. Requires `tag`; service-worker path only.
1297
+ */
1298
+ renotify?: boolean;
1299
+ /**
1300
+ * Vibration pattern in milliseconds, alternating vibrate and pause. Service-worker path only, and
1301
+ * Android only.
1302
+ */
1303
+ vibrate?: number[];
1304
+ /**
1305
+ * The time the notification is *about*, as an epoch timestamp - not when it is shown. Used for
1306
+ * ordering in the notification tray. Service-worker path only.
1307
+ */
1308
+ timestamp?: number;
1309
+ /** Buttons on the notification. Forces the service-worker path, since the page path cannot render them. */
1310
+ actions?: NotificationActionConfig[];
1311
+ /**
1312
+ * Which delivery path to use.
1313
+ *
1314
+ * - `auto` (default) - the page path first, falling back to the service worker when the constructor
1315
+ * throws, which is how Android Chrome reports that it only does persistent notifications. A
1316
+ * notification with `actions` goes straight to the service worker.
1317
+ * - `page` - constructor only. Fails to `'unavailable'` where the constructor is illegal, and drops
1318
+ * `actions`, `image`, `renotify`, `vibrate` and `timestamp`.
1319
+ * - `service-worker` - persistent only. Fails to `'unavailable'` when no service worker is
1320
+ * registered.
1321
+ * @default 'auto'
1322
+ */
1323
+ path?: 'auto' | 'page' | 'service-worker';
1324
+ /**
1325
+ * Close the notification this many milliseconds after it is shown. Off by default, which leaves the
1326
+ * lifetime to the platform - desktop Chromium hides a notification after about 20 seconds and keeps
1327
+ * it in the tray, Android keeps it until dismissed.
1328
+ */
1329
+ autoClose?: number;
1330
+ /**
1331
+ * Called when the user clicks the notification (or one of its `actions`).
1332
+ *
1333
+ * On the page path this is wired directly to the notification's `click` event. On the
1334
+ * service-worker path the event goes to the worker instead, so this only fires if that worker
1335
+ * relays it - see {@link NOTIFICATION_CLICK_MESSAGE_TYPE} for the handler to add.
1336
+ *
1337
+ * A click does not focus the tab. Call `window.focus()` yourself if that is what you want.
1338
+ */
1339
+ onClick?: (context: NotificationClickContext) => void;
1340
+ /** Called when the notification is closed, by the user or by `close()`. Page path only. */
1341
+ onClose?: () => void;
1342
+ /** Called once the notification is on screen. Page path only. */
1343
+ onShow?: () => void;
1344
+ /** Called when the browser failed to display the notification. Page path only. */
1345
+ onError?: () => void;
1346
+ };
1347
+ /** Handle on a notification handed to {@link Notifications.show}. */
1348
+ type NotificationRef = {
1349
+ /** The notification's tag - generated when the config did not provide one. */
1350
+ readonly tag: string;
1351
+ /**
1352
+ * Emits once the browser has taken the notification, with the path that carried it - or
1353
+ * `'unavailable'` if nothing was shown - and completes. Never errors.
1354
+ *
1355
+ * The notification is shown whether or not anyone subscribes, and the result is replayed, so a late
1356
+ * subscriber still gets it.
1357
+ */
1358
+ readonly shown$: Observable<NotificationDeliveryPath>;
1359
+ /**
1360
+ * Dismiss the notification. Safe to call before `shown$` emits (the notification is then never
1361
+ * displayed) and safe to call twice.
1362
+ */
1363
+ readonly close: () => void;
1364
+ };
1365
+ /** The notification API, injected with `injectNotifications()`. */
1366
+ type Notifications = {
1367
+ /**
1368
+ * Whether this browser exposes a Notification API at all - `false` on the server and in engines
1369
+ * without it. Not a promise that a notification will show: permission still has to be granted, and
1370
+ * a browser that only supports persistent notifications still needs a service worker.
1371
+ */
1372
+ readonly isSupported: boolean;
1373
+ /**
1374
+ * The current permission, kept in sync while the app runs: through the Permissions API where it has
1375
+ * a `notifications` descriptor (Chromium, Firefox), and by re-reading it whenever the tab comes back
1376
+ * to the foreground everywhere else - which is how a permission revoked in browser settings is
1377
+ * picked up on WebKit.
1378
+ */
1379
+ readonly permission: Signal<NotificationPermissionState>;
1380
+ /**
1381
+ * Show the browser's permission prompt, emitting the outcome once and completing. Cold - nothing is
1382
+ * asked until it is subscribed to.
1383
+ *
1384
+ * Subscribe from a user gesture: Safari requires one, and Chromium blocks the prompt entirely on
1385
+ * sites that ask on page load. Emits the current state without prompting when permission was already
1386
+ * granted or denied - the prompt can only be shown once, after which only the user can change it in
1387
+ * site settings.
1388
+ */
1389
+ readonly request: () => Observable<NotificationPermissionState>;
1390
+ /**
1391
+ * Show a notification, if permission has been granted - this never prompts on its own, so run
1392
+ * `request()` first.
1393
+ *
1394
+ * Returns synchronously, and the notification is shown without anyone subscribing to anything; the
1395
+ * ref's `shown$` reports which path carried it.
1396
+ */
1397
+ readonly show: (config: ShowNotificationConfig) => NotificationRef;
1398
+ /**
1399
+ * Close every notification this app has open - the ones shown through `show()` plus any persistent
1400
+ * ones still in the tray from an earlier page load.
1401
+ */
1402
+ readonly closeAll: () => void;
1403
+ };
1404
+
1405
+ declare const provideNotifications: () => _angular_core.Provider[];
1406
+ declare const injectNotifications: _ethlete_core.InjectFn<Notifications>;
1407
+
1408
+ type OverlayRuntimeRole = 'dialog' | 'alertdialog';
1409
+ type OverlayRuntimeAutoFocusTarget = 'container' | 'first-heading' | 'first-tabbable';
1410
+ type OverlayRuntimeCloseSource = 'api' | 'escape' | 'outside-pointer' | 'drag' | 'reference-detached';
1411
+ type OverlayRuntimeCenteredPosition = {
1412
+ kind: 'center';
1413
+ };
1414
+ type OverlayRuntimeGlobalPositionAlignment = 'start' | 'center' | 'end' | 'stretch';
1415
+ type OverlayRuntimeGlobalPosition = {
1416
+ kind: 'global';
1417
+ /** Horizontal placement of the pane inside the viewport. Defaults to `center`. */
1418
+ horizontal?: OverlayRuntimeGlobalPositionAlignment;
1419
+ /** Vertical placement of the pane inside the viewport. Defaults to `center`. */
1420
+ vertical?: OverlayRuntimeGlobalPositionAlignment;
1421
+ /** Padding applied to the host element. Defaults to `0`. */
1422
+ padding?: string;
1423
+ };
1424
+ type OverlayRuntimeShiftOptions = {
1425
+ /**
1426
+ * Also shift along the placement's cross axis (e.g. horizontally for a `right-*` placement)
1427
+ * when no placement fits the viewport. The pane may then overlap its reference element -
1428
+ * desirable for nested menus, usually not for tooltips. Defaults to `false`.
1429
+ */
1430
+ crossAxis?: boolean;
1431
+ };
1432
+ type OverlayRuntimeAnchoredPosition = {
1433
+ kind: 'anchored';
1434
+ referenceElement: HTMLElement | VirtualElement;
1435
+ placement?: Placement;
1436
+ fallbackPlacements?: Placement[];
1437
+ offset?: OffsetOptions | null;
1438
+ arrowPadding?: Padding | null;
1439
+ viewportPadding?: Padding | null;
1440
+ autoResize?: boolean;
1441
+ /**
1442
+ * Keeps the pane on its placement's own side while that side offers at least this much space (px
1443
+ * along the placement's main axis), instead of flipping as soon as the pane's content would
1444
+ * overflow. Below the minimum the pane moves to the opposite side, and when neither side reaches
1445
+ * it the roomier one wins. Requires `autoResize` - the pane has to shrink into what it gets.
1446
+ *
1447
+ * Prefer this over `fallbackPlacements` for a pane whose content is scrollable (a listbox, a
1448
+ * menu): a shorter list under the field beats a full-height one above it, and the decision reads
1449
+ * only the space around the reference, never the pane's own size. `flip` compares that size
1450
+ * against the space it has while `autoResize` derives it from the placement `flip` picked, so a
1451
+ * pane whose height changes while open - a filtered list, an animated resize - flips back and
1452
+ * forth mid-animation. Replaces `flip`, so `fallbackPlacements` no longer applies, and forces
1453
+ * `shift`'s cross axis off - a pane that shrinks into its side must not slide over the reference
1454
+ * element instead.
1455
+ */
1456
+ minAvailableSpace?: number;
1457
+ shift?: boolean | OverlayRuntimeShiftOptions;
1458
+ autoHide?: boolean;
1459
+ autoCloseIfReferenceHidden?: boolean;
1460
+ mirrorWidth?: boolean;
1461
+ /**
1462
+ * Clipping element(s) the pane must stay within when flipping/shifting, instead of the default
1463
+ * viewport (`clippingAncestors`). Use it to keep an anchored pane inside a specific region - e.g.
1464
+ * a rich-text editor's content area, so its selection toolbar flips below rather than covering the
1465
+ * static toolbar above.
1466
+ */
1467
+ boundary?: Element | Element[];
1468
+ };
1469
+ type OverlayRuntimePositionStrategy = OverlayRuntimeCenteredPosition | OverlayRuntimeAnchoredPosition | OverlayRuntimeGlobalPosition;
1470
+ type OverlayRuntimeElements = {
1471
+ rootElement: HTMLElement;
1472
+ hostElement: HTMLElement;
1473
+ backdropElement: HTMLElement | null;
1474
+ paneElement: HTMLElement;
1475
+ };
1476
+ type OverlayRuntimeCloseEvent<TResult = unknown> = {
1477
+ result: TResult | undefined;
1478
+ source: OverlayRuntimeCloseSource;
1479
+ };
1480
+ /**
1481
+ * A synchronous veto for a pending close. Return `false` to cancel the close (the overlay stays
1482
+ * open); return `true` to let it proceed. Registered via `overlayRef.registerCloseGuard`. An async
1483
+ * decision (e.g. a confirm dialog) lives in the guard's owner, which re-issues the close through
1484
+ * `overlayRef.forceClose` once resolved. `reference-detached` closes bypass all guards.
1485
+ */
1486
+ type OverlayRuntimeCloseGuard<TResult = unknown> = (event: OverlayRuntimeCloseEvent<TResult>) => boolean;
1487
+ type OverlayRuntimeComponentBase = {
1488
+ animatedLifecycle?: Signal<AnimatedLifecycleDirective | undefined>;
1489
+ };
1490
+ type OverlayRuntimeAnimationDelegateEnterContext = {
1491
+ lifecycle: AnimatedLifecycleDirective;
1492
+ elements: OverlayRuntimeElements;
1493
+ };
1494
+ type OverlayRuntimeAnimationDelegateLeaveContext = OverlayRuntimeAnimationDelegateEnterContext & {
1495
+ closeEvent: OverlayRuntimeCloseEvent;
1496
+ };
1497
+ /**
1498
+ * Overrides the runtime's default enter/leave animation handling.
1499
+ * A delegate must eventually drive the lifecycle state to `entered` (enter) or `left` (leave),
1500
+ * otherwise the overlay will never finish opening or closing.
1501
+ */
1502
+ type OverlayRuntimeAnimationDelegate = {
1503
+ enter?: (context: OverlayRuntimeAnimationDelegateEnterContext) => void;
1504
+ leave?: (context: OverlayRuntimeAnimationDelegateLeaveContext) => void;
1505
+ };
1506
+ type OverlayRuntimeMountConfig<TComponent extends object> = {
745
1507
  id: string;
746
- elementRef: ElementRef<HTMLElement>;
1508
+ component: Type<TComponent>;
1509
+ viewContainerRef?: ViewContainerRef;
1510
+ injector?: Injector;
1511
+ providers?: StaticProvider[];
1512
+ role?: OverlayRuntimeRole;
1513
+ positionStrategy?: OverlayRuntimePositionStrategy;
1514
+ hasBackdrop?: boolean;
1515
+ modal?: boolean;
1516
+ autoFocus?: OverlayRuntimeAutoFocusTarget | string | false;
1517
+ restoreFocus?: boolean;
1518
+ closeOnEscape?: boolean;
1519
+ closeOnOutsidePointer?: boolean;
1520
+ ariaDescribedBy?: string | null;
1521
+ ariaLabelledBy?: string | null;
1522
+ ariaLabel?: string | null;
1523
+ hostClass?: string[];
1524
+ backdropClass?: string[];
1525
+ paneClass?: string[];
1526
+ /**
1527
+ * Bindings applied to the mounted component, using Angular's native binding API
1528
+ * (`inputBinding`, `outputBinding`, `twoWayBinding`).
1529
+ */
1530
+ bindings?: Binding[];
1531
+ animationDelegate?: OverlayRuntimeAnimationDelegate;
747
1532
  };
748
- type PropHandlers = ReturnType<typeof createPropHandlers>;
749
1533
 
750
- type Props = Readonly<{
751
- attached: Signal<boolean>;
752
- attachedElements: PropsAttachedElements;
753
- }>;
754
- type PropsAttachedElements = {
755
- first: Signal<HTMLElement | null>;
756
- firstId: Signal<string | null>;
757
- get(id: string): HTMLElement | null;
1534
+ type OverlayRuntimeState = 'mounting' | 'mounted' | 'closing' | 'closed';
1535
+ declare const createOverlayRuntimeRef: <TComponent extends object, TResult = unknown>(id: string, config: Omit<OverlayRuntimeMountConfig<TComponent>, "component">, elements: OverlayRuntimeElements, requestClose: (result: TResult | undefined, source: OverlayRuntimeCloseSource) => void) => {
1536
+ id: string;
1537
+ config: Omit<OverlayRuntimeMountConfig<TComponent>, "component">;
1538
+ elements: OverlayRuntimeElements;
1539
+ state: _angular_core.Signal<OverlayRuntimeState>;
1540
+ componentInstance: _angular_core.Signal<TComponent | null>;
1541
+ beforeOpenedSubject: Subject<void>;
1542
+ close(result?: TResult, source?: OverlayRuntimeCloseSource): void;
1543
+ /** Close bypassing every registered close guard - used by a guard's owner to commit a
1544
+ * close it previously vetoed (e.g. after an async confirm resolved). */
1545
+ forceClose(result?: TResult, source?: OverlayRuntimeCloseSource): void;
1546
+ /** Register a synchronous veto for pending closes. Returns an unregister function. */
1547
+ registerCloseGuard(guard: OverlayRuntimeCloseGuard<TResult>): () => void;
1548
+ beforeOpened(): Observable<void>;
1549
+ afterOpened(): Observable<void>;
1550
+ beforeClosed(): Observable<OverlayRuntimeCloseEvent<TResult>>;
1551
+ afterClosed(): Observable<OverlayRuntimeCloseEvent<TResult>>;
1552
+ attachComponentRef(componentRef: ComponentRef<TComponent>): void;
1553
+ /** @internal */
1554
+ attachPositionUpdater(updater: (strategy: OverlayRuntimePositionStrategy) => void): void;
1555
+ updatePositionStrategy(strategy: OverlayRuntimePositionStrategy): void;
1556
+ markOpened(): void;
1557
+ beginClose(closeEvent: OverlayRuntimeCloseEvent<TResult>): boolean;
1558
+ finishClose(closeEvent: OverlayRuntimeCloseEvent<TResult>): void;
1559
+ };
1560
+ type OverlayRuntimeRef<TComponent extends object = object, TResult = unknown> = ReturnType<typeof createOverlayRuntimeRef<TComponent, TResult>>;
1561
+
1562
+ declare const FOCUSABLE_SELECTOR: string;
1563
+ declare const isHTMLElement: (value: unknown) => value is HTMLElement;
1564
+ declare const isFocusable: (element: HTMLElement, document: Document) => boolean;
1565
+ declare const getFocusableElements: (container: HTMLElement, document: Document) => HTMLElement[];
1566
+ declare const getHeadingElement: (container: HTMLElement) => HTMLElement | null;
1567
+ declare const focusElement: (element: HTMLElement | null) => void;
1568
+ declare const applyInitialFocus: (paneElement: HTMLElement, autoFocus: OverlayRuntimeAutoFocusTarget | string | false, document: Document) => void;
1569
+ declare const setupFocusTrap: (paneElement: HTMLElement, overlayRef: OverlayRuntimeRef<object, unknown>, enabled: boolean, isTopMost: (ref: OverlayRuntimeRef<object, unknown>) => boolean, document: Document) => () => void;
1570
+
1571
+ declare const setBaseElementStyles: (config: OverlayRuntimeMountConfig<object>, hostElement: HTMLElement, paneElement: HTMLElement, renderer: AngularRenderer) => void;
1572
+ declare const setBackdropStyles: (backdropElement: HTMLElement, renderer: AngularRenderer) => void;
1573
+ declare const applyCenteredPosition: (hostElement: HTMLElement, paneElement: HTMLElement, renderer: AngularRenderer, _config: OverlayRuntimeCenteredPosition) => void;
1574
+ declare const applyGlobalPosition: (hostElement: HTMLElement, paneElement: HTMLElement, renderer: AngularRenderer, config: OverlayRuntimeGlobalPosition) => void;
1575
+ /**
1576
+ * Clears every inline style any position strategy kind may have set and
1577
+ * restores the base element styles, so a different strategy can be applied afterwards.
1578
+ */
1579
+ declare const resetPositioningStyles: (config: OverlayRuntimeMountConfig<object>, hostElement: HTMLElement, paneElement: HTMLElement, renderer: AngularRenderer) => void;
1580
+ /**
1581
+ * Positions an anchored overlay pane and returns the cleanup for its auto-update loop.
1582
+ */
1583
+ type AnchoredPositionSetup = (strategy: OverlayRuntimeAnchoredPosition, paneElement: HTMLElement, overlayRef: OverlayRuntimeRef<object, unknown>, renderer: AngularRenderer) => () => void;
1584
+ /**
1585
+ * Installs the anchored positioning implementation. Called by `anchoredOverlayPosition()`, which is
1586
+ * the only thing that pulls `@floating-ui/dom` into the bundle - apps that never anchor an overlay
1587
+ * do not ship it.
1588
+ *
1589
+ * @internal
1590
+ */
1591
+ declare const registerAnchoredPositionSetup: (setup: AnchoredPositionSetup) => void;
1592
+ declare const setupPositioning: (config: OverlayRuntimeMountConfig<object>, hostElement: HTMLElement, paneElement: HTMLElement, overlayRef: OverlayRuntimeRef<object, unknown>, renderer: AngularRenderer) => () => void;
1593
+
1594
+ /**
1595
+ * The floating-ui middleware only a subset of anchored overlays needs. Installed by
1596
+ * `enableAnchoredOverlayPositionExtras()`.
1597
+ *
1598
+ * @internal
1599
+ */
1600
+ type AnchoredPositionMiddlewareExtras = {
1601
+ size: typeof _floating_ui_dom.size;
1602
+ arrow: typeof _floating_ui_dom.arrow;
1603
+ hide: typeof _floating_ui_dom.hide;
758
1604
  };
759
- type PropsAttachedElementsInternal = PropsAttachedElements & {
760
- has: (id: string) => boolean;
761
- push: (id: string, element: HTMLElement) => void;
762
- remove: (id: string) => void;
1605
+ /**
1606
+ * Installs the `size` / `arrow` / `hide` middleware. Called by
1607
+ * `enableAnchoredOverlayPositionExtras()`.
1608
+ *
1609
+ * @internal
1610
+ */
1611
+ declare const registerAnchoredPositionMiddlewareExtras: (extras: AnchoredPositionMiddlewareExtras) => void;
1612
+ declare const createAnchoredPositionCleanup: (strategy: OverlayRuntimeAnchoredPosition, paneElement: HTMLElement, overlayRef: OverlayRuntimeRef<object, unknown>, renderer: AngularRenderer) => () => void;
1613
+ /**
1614
+ * Builds an anchored position strategy and installs the anchored positioning implementation.
1615
+ *
1616
+ * Anchored positioning is the only part of the overlay runtime that needs `@floating-ui/dom`, and it
1617
+ * is reachable only through this function - an app that positions its overlays centered or globally
1618
+ * never bundles it. Always build anchored strategies with this helper instead of a plain
1619
+ * `{ kind: 'anchored', ... }` literal.
1620
+ *
1621
+ * Overlays that set `autoResize`, `autoHide`, `autoCloseIfReferenceHidden` or render an arrow
1622
+ * additionally need `enableAnchoredOverlayPositionExtras()`.
1623
+ */
1624
+ declare const anchoredOverlayPosition: (config: Omit<OverlayRuntimeAnchoredPosition, "kind">) => OverlayRuntimeAnchoredPosition;
1625
+
1626
+ /**
1627
+ * Installs the floating-ui middleware anchored overlays need for `autoResize`, `autoHide`,
1628
+ * `autoCloseIfReferenceHidden` and arrows. Call it once wherever such an overlay is built - an
1629
+ * anchored overlay that uses none of those features does not bundle this middleware.
1630
+ */
1631
+ declare const enableAnchoredOverlayPositionExtras: () => void;
1632
+
1633
+ type OverlayRuntime = {
1634
+ mount: <TComponent extends object, TResult = unknown>(config: OverlayRuntimeMountConfig<TComponent>) => OverlayRuntimeRef<TComponent, TResult>;
1635
+ openEntries: ReturnType<typeof computed<OverlayRuntimeRef<object, unknown>[]>>;
763
1636
  };
764
- type PropsInternal = {
765
- single: boolean;
766
- name: string;
767
- bindId: boolean;
768
- attached: Signal<boolean>;
769
- attachedElements: PropsAttachedElementsInternal;
770
- classBindings: Record<string, Signal<unknown>> | null;
771
- attributeBindings: Record<string, Signal<unknown>> | null;
772
- styleBindings: Record<string, Signal<unknown>> | null;
773
- staticClassBindings: string[] | null;
774
- staticAttributeBindings: Record<string, unknown> | null;
775
- staticStyleBindings: Record<string, unknown> | null;
776
- attachEventListeners: ((context: {
777
- on: HTMLElement['addEventListener'];
778
- element: HTMLElement;
779
- }) => void) | null;
1637
+ declare const provideOverlayRuntime: () => _angular_core.Provider[];
1638
+ declare const injectOverlayRuntime: _ethlete_core.InjectFn<OverlayRuntime>;
1639
+
1640
+ declare const createComponentId: (prefix: string) => string;
1641
+ /**
1642
+ * A unique id string. Uses `crypto.randomUUID()` when available, but falls back gracefully when it is
1643
+ * not - crucially in **insecure contexts** (a plain-HTTP page served from a LAN IP, not `localhost`),
1644
+ * where `crypto.randomUUID` is `undefined`. Calling it there throws, so anything using it during e.g.
1645
+ * an overlay/menu open would break on such hosts. Prefer this over `crypto.randomUUID()` directly.
1646
+ */
1647
+ declare const randomId: () => string;
1648
+
1649
+ declare const createDestroy: () => rxjs.Observable<boolean>;
1650
+
1651
+ declare const injectHostElement: <T = HTMLElement>() => T;
1652
+ declare const injectTemplateRef: <C = unknown>() => TemplateRef<C>;
1653
+ type ProviderDefinitionOptions = {
1654
+ /**
1655
+ * Optional name for the provider, useful for debugging.
1656
+ * If not provided, the name will be a generated string.
1657
+ */
1658
+ name?: string;
1659
+ /**
1660
+ * Optional existing InjectionToken to also provide the created provider under.
1661
+ */
1662
+ extraInjectionToken?: InjectionToken<unknown>;
780
1663
  };
781
- type CreatePropsOptions = {
782
- name: string;
783
- bindId?: boolean;
784
- single?: boolean;
785
- classes?: Record<string, Signal<unknown>>;
786
- attributes?: Record<string, Signal<unknown>>;
787
- styles?: Record<string, Signal<unknown>>;
788
- staticClasses?: string[];
789
- staticAttributes?: Record<string, unknown>;
790
- staticStyles?: Record<string, unknown>;
791
- listeners?: (context: {
792
- on: HTMLElement['addEventListener'];
793
- element: HTMLElement;
794
- }) => void;
1664
+ /** The `inject`-shaped half of a provider definition: optional when asked, non-nullable otherwise. */
1665
+ type InjectFn<T> = {
1666
+ (): T;
1667
+ (options: InjectOptions & {
1668
+ optional?: false;
1669
+ }): T;
1670
+ (options: InjectOptions): T | null;
1671
+ };
1672
+ /**
1673
+ * What {@link defineProvider} & co. return: the token plus the two functions a domain re-exports as its
1674
+ * `provideX` / `injectX` pair. Read the halves out with {@link toProvideFn}, {@link toInjectFn} and
1675
+ * {@link toToken} - never by destructuring, see {@link defineProvider}.
1676
+ */
1677
+ type ProviderDefinition<T> = {
1678
+ readonly provide: () => Provider[];
1679
+ readonly inject: InjectFn<T>;
1680
+ readonly token: InjectionToken<T>;
1681
+ };
1682
+ /** {@link ProviderDefinition} for a value provider, whose `provide` takes a partial override. */
1683
+ type StaticProviderDefinition<T> = {
1684
+ readonly provide: (valueOverride?: Partial<T>) => Provider[];
1685
+ readonly inject: InjectFn<T>;
1686
+ readonly token: InjectionToken<T>;
1687
+ };
1688
+ /**
1689
+ * Defines a provider that a subtree opts into - `provideX()` in some component's `providers`, then
1690
+ * `injectX()` below it. Nothing is created until the subtree provides it.
1691
+ *
1692
+ * Assign the result to one `const`, name the halves with {@link toProvideFn} / {@link toInjectFn} /
1693
+ * {@link toToken}, and put a `__PURE__` annotation comment on each of those declarations. Never destructure
1694
+ * the definition: that declaration cannot be tree-shaken, so it ships the factory's whole closure to
1695
+ * every consumer. Enforced by `ethlete/no-impure-top-level-provider`.
1696
+ */
1697
+ declare const defineProvider: <T>(factory: () => T, options?: ProviderDefinitionOptions) => ProviderDefinition<T>;
1698
+ /**
1699
+ * Like {@link defineProvider}, but the factory also runs in the root injector, so `injectX()` works
1700
+ * without anyone calling `provideX()`. `provideX()` still exists, to give a subtree its own instance.
1701
+ */
1702
+ declare const defineRootProvider: <T>(factory: () => T, options?: ProviderDefinitionOptions) => ProviderDefinition<T>;
1703
+ /**
1704
+ * Like {@link defineProvider} for a plain value rather than a factory: `provideX(override)` merges the
1705
+ * partial override over `defaultValue`, which is how every config object in the library is shaped.
1706
+ */
1707
+ declare const defineStaticProvider: <T>(defaultValue?: T, options?: ProviderDefinitionOptions) => StaticProviderDefinition<T>;
1708
+ /**
1709
+ * {@link defineStaticProvider} whose default is also available in the root injector, so `injectX()`
1710
+ * resolves to `defaultValue` in an app that never provides it.
1711
+ */
1712
+ declare const defineStaticRootProvider: <T>(defaultValue?: T, options?: ProviderDefinitionOptions) => StaticProviderDefinition<T>;
1713
+ /** The `provideX` half of a provider definition. A call, so a `__PURE__` annotation makes it droppable. */
1714
+ declare const toProvideFn: <TDefinition extends {
1715
+ readonly provide: unknown;
1716
+ }>(definition: TDefinition) => TDefinition["provide"];
1717
+ /** The `injectX` half of a provider definition. */
1718
+ declare const toInjectFn: <TDefinition extends {
1719
+ readonly inject: unknown;
1720
+ }>(definition: TDefinition) => TDefinition["inject"];
1721
+ /** The token behind a provider definition. */
1722
+ declare const toToken: <TDefinition extends {
1723
+ readonly token: unknown;
1724
+ }>(definition: TDefinition) => TDefinition["token"];
1725
+
1726
+ declare const cloneFormGroup: <T extends FormGroup<any>>(formGroup: T) => T;
1727
+ declare const getFormGroupValue: <T extends FormGroup>(formGroup: T) => Record<string, unknown>;
1728
+
1729
+ declare const createRxHostListener: <K extends keyof HTMLElementEventMap>(eventName: K, options?: EventListenerOptions) => rxjs.Observable<HTMLElementEventMap[K]>;
1730
+ declare const applyHostListener: <K extends keyof HTMLElementEventMap>(eventName: K, handler: (event: HTMLElementEventMap[K]) => void, options?: EventListenerOptions) => rxjs.Subscription;
1731
+ declare const applyHostListeners: (listeners: Partial<{ [K in keyof HTMLElementEventMap]: (event: HTMLElementEventMap[K]) => void; }>, options?: EventListenerOptions) => void;
1732
+
1733
+ declare class TypedQueryList<T> extends QueryList<T> {
1734
+ get changes(): Observable<TypedQueryList<T>>;
1735
+ }
1736
+ declare function switchQueryListChanges(): <T extends TypedQueryList<unknown> | null | undefined>(source: Observable<T>) => Observable<T>;
1737
+
1738
+ /**
1739
+ * Sets the value of an input signal.
1740
+ * See issue: https://github.com/angular/angular/issues/54782
1741
+ */
1742
+ declare const setInputSignal: <T>(input: InputSignal<T> | InputSignalWithTransform<T, unknown>, value: T) => void;
1743
+
1744
+ type NgClassType = string | string[] | Set<string> | {
1745
+ [klass: string]: any;
1746
+ } | null | undefined;
1747
+
1748
+ declare const AT_LEAST_ONE_REQUIRED = "atLeastOneRequired";
1749
+ type ValidateAtLeastOneRequiredConfig = {
1750
+ /**
1751
+ * Keys of form controls to validate in the supplied form group
1752
+ */
1753
+ keys: string[];
1754
+ /**
1755
+ * If true, the value `false` will result in a validation error
1756
+ * @default false
1757
+ */
1758
+ checkFalse?: boolean;
795
1759
  };
796
- declare const createProps: (props: CreatePropsOptions) => Props;
797
- type HostProps = {
798
- props: Props;
799
- handlers: PropHandlers;
1760
+ declare const ValidateAtLeastOneRequired: (config: ValidateAtLeastOneRequiredConfig) => ValidatorFn;
1761
+ declare const IS_ARRAY_NOT_EMPTY = "isArrayNotEmpty";
1762
+ declare const IsArrayNotEmpty: (control: AbstractControl) => ValidationErrors | null;
1763
+ declare const IS_EMAIL = "isEmail";
1764
+ declare const IsEmail: (control: AbstractControl) => ValidationErrors | null;
1765
+ declare const MUST_MATCH = "mustMatch";
1766
+ declare const MustMatch: (controlName: string, matchingControlName: string) => (formGroup: AbstractControl) => {
1767
+ mustMatch: boolean;
1768
+ } | null;
1769
+ declare const Validators: {
1770
+ readonly MustMatch: (controlName: string, matchingControlName: string) => (formGroup: AbstractControl) => {
1771
+ mustMatch: boolean;
1772
+ } | null;
1773
+ readonly IsEmail: (control: AbstractControl) => ValidationErrors | null;
1774
+ readonly IsArrayNotEmpty: (control: AbstractControl) => ValidationErrors | null;
1775
+ readonly ValidateAtLeastOneRequired: (config: ValidateAtLeastOneRequiredConfig) => ValidatorFn;
800
1776
  };
801
- declare const createHostProps: (props: CreatePropsOptions) => HostProps;
802
1777
 
803
- declare const createSetup: <T extends Record<string, unknown>>(config: {
804
- setupFn: (params: T) => void;
805
- this: ThisType<unknown>;
806
- }) => (params: T) => void;
1778
+ declare const copyToClipboard: (text: string) => Observable<boolean>;
1779
+ declare const readFromClipboard: () => Observable<string | null>;
807
1780
 
808
- declare const createDependencyStash: <T extends Record<string, WritableSignal<unknown>>>(stash: T) => T & {
809
- provideSignal: <K extends keyof T>(data: {
810
- signal: Signal<ReturnType<T[K]>>;
811
- for: K;
812
- }) => void;
813
- provideValue: <K extends keyof T>(data: {
814
- value: ReturnType<T[K]>;
815
- for: K;
816
- }) => void;
817
- };
1781
+ declare const clone: <T>(original: T) => T;
1782
+ declare const equal: (foo: any, bar: any) => boolean;
818
1783
 
819
- declare const createElementDictionary: () => {
820
- ids: _angular_core.Signal<string[]>;
821
- elements: _angular_core.Signal<HTMLElement[]>;
822
- has: (id: string) => boolean;
823
- get: (id: string) => HTMLElement | null;
824
- push: (id: string, element: HTMLElement) => void;
825
- remove: (id: string) => void;
826
- isEmpty: _angular_core.Signal<boolean>;
827
- firstElement: _angular_core.Signal<HTMLElement | null>;
828
- firstId: _angular_core.Signal<string | null>;
829
- };
1784
+ declare const hasCookie: (name: string) => boolean;
1785
+ declare const getCookie: (name: string) => string | null | undefined;
1786
+ declare const setCookie: (name: string, data: string, expiresInDays?: number | null, domain?: string | null, path?: string, sameSite?: "strict" | "none" | "lax") => void;
1787
+ declare const deleteCookie: (name: string, path?: string, domain?: string | null) => void;
1788
+ declare const getDomain: () => string | null;
830
1789
 
831
- type BindPropsOptions = {
832
- props: Props | PropsInternal;
833
- handlers: PropHandlers;
834
- };
835
- declare const bindProps: (config: BindPropsOptions) => void;
836
- type UnbindPropsOptions = {
837
- props: Props | PropsInternal;
838
- handlers: PropHandlers;
1790
+ type Translatable = {
1791
+ i18n: string;
1792
+ text: string;
839
1793
  };
840
- declare const unbindProps: (config: UnbindPropsOptions) => void;
841
1794
 
842
- declare class PropsDirective {
843
- destroyRef: DestroyRef;
844
- props: _angular_core.InputSignalWithTransform<PropsInternal, Readonly<{
845
- attached: _angular_core.Signal<boolean>;
846
- attachedElements: _ethlete_core.PropsAttachedElements;
847
- }>>;
848
- propHandlers: {
849
- classes: {
850
- remove: (tokens: string) => void;
851
- removeMany: (tokens: string[]) => void;
852
- has: (tokens: string) => boolean;
853
- push: (tokens: string, signal: _angular_core.Signal<unknown>) => void;
854
- pushMany: (map: Record<string, _angular_core.Signal<unknown>>) => void;
855
- };
856
- attributes: {
857
- remove: (tokens: string) => void;
858
- removeMany: (tokens: string[]) => void;
859
- has: (tokens: string) => boolean;
860
- push: (tokens: string, signal: _angular_core.Signal<unknown>) => void;
861
- pushMany: (map: Record<string, _angular_core.Signal<unknown>>) => void;
862
- };
863
- styles: {
864
- remove: (tokens: string) => void;
865
- removeMany: (tokens: string[]) => void;
866
- has: (tokens: string) => boolean;
867
- push: (tokens: string, signal: _angular_core.Signal<unknown>) => void;
868
- pushMany: (map: Record<string, _angular_core.Signal<unknown>>) => void;
869
- };
870
- id: string;
871
- elementRef: _angular_core.ElementRef<HTMLElement>;
872
- };
873
- constructor();
874
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<PropsDirective, never>;
875
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<PropsDirective, "[etProps]", never, { "props": { "alias": "etProps"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
1795
+ declare class KeyPressManager {
1796
+ readonly key: number;
1797
+ private readonly _isKeyPressed$;
1798
+ private readonly _keyPressCount$;
1799
+ private readonly _stopTimeout$;
1800
+ constructor(key: number);
1801
+ isPressed(event: KeyboardEvent): boolean;
1802
+ clear(): void;
876
1803
  }
877
1804
 
878
- type AnyTemplateType = string | TemplateRef<unknown> | ComponentType<unknown> | TemplateRefWithContext | ComponentTypeWithInputs;
879
- type TemplateRefWithContext<T = Record<string, unknown> | undefined, J = unknown> = {
880
- template: TemplateRef<J>;
881
- context?: T;
882
- injector?: Injector;
883
- };
884
- type ComponentTypeWithInputs<T = Record<string, unknown> | undefined, J = unknown> = {
885
- component: ComponentType<J>;
886
- inputs?: T;
887
- injector?: Injector;
1805
+ declare const DISABLE_LOGGER_PARAM = "et-logger-quiet";
1806
+ type CreateLoggerConfig = {
1807
+ scope: string;
1808
+ feature: string;
888
1809
  };
889
- type StringTemplate = {
890
- type: 'string';
891
- value: string;
1810
+ declare const createLogger: (config: CreateLoggerConfig) => {
1811
+ log: (...args: unknown[]) => void;
1812
+ warn: (...args: unknown[]) => void;
1813
+ error: (...args: unknown[]) => void;
892
1814
  };
893
- type NgTemplateTemplate = {
894
- type: 'template';
895
- value: TemplateRef<unknown>;
896
- context?: Record<string, unknown>;
897
- injector: Injector | null;
1815
+
1816
+ /**
1817
+ * Converts a markdown string to HTML.
1818
+ * Covers headings, bold, italic, strikethrough, inline code, fenced code blocks,
1819
+ * links, images, block quotes, unordered/ordered (and nested) lists, tables, horizontal rules, and paragraphs.
1820
+ */
1821
+ declare const markdownToHtml: (markdown: string) => string;
1822
+ /**
1823
+ * Converts an HTML string to markdown.
1824
+ * Covers headings, bold, italic, strikethrough, inline code, fenced code blocks,
1825
+ * links, images, block quotes, unordered/ordered lists, tables, horizontal rules, and paragraphs.
1826
+ */
1827
+ declare const htmlToMarkdown: (html: string) => string;
1828
+
1829
+ declare const clamp: (value: number, min?: number, max?: number) => number;
1830
+ declare const round: (value: number, precision?: number) => number;
1831
+
1832
+ declare const isObject: (value: unknown) => value is Record<string, unknown>;
1833
+ declare const isArray: (value: unknown) => value is unknown[];
1834
+ declare const getObjectProperty: (obj: Record<string, unknown>, prop: string) => unknown;
1835
+
1836
+ declare const RUNTIME_ERROR_NO_DATA = "__ET_NO_DATA__";
1837
+ declare class RuntimeError<T extends number> extends Error {
1838
+ code: T;
1839
+ data: unknown;
1840
+ constructor(code: T, message: null | false | string, data?: unknown);
1841
+ }
1842
+ declare function formatRuntimeError<T extends number>(code: T, message: null | false | string): string;
1843
+
1844
+ type CreateSessionMemoryConfig<TValue> = {
1845
+ key: string;
1846
+ parse: (storedValue: string) => TValue | null;
1847
+ serialize: (value: TValue) => string;
898
1848
  };
899
- type ComponentTemplate = {
900
- type: 'component';
901
- value: ComponentType<unknown>;
902
- inputs?: Record<string, unknown>;
903
- injector: Injector | null;
1849
+ declare const createAutoSessionMemoryKey: ({ element, prefix }: {
1850
+ element: HTMLElement;
1851
+ prefix: string;
1852
+ }) => string;
1853
+ declare const canUseSessionMemory: () => boolean;
1854
+ declare const createSessionMemory: <TValue>({ key, parse, serialize }: CreateSessionMemoryConfig<TValue>) => {
1855
+ read: () => TValue | null;
1856
+ write: (value: TValue) => boolean;
1857
+ remove: () => boolean;
904
1858
  };
905
- declare const templateComputed: (templateSignal: Signal<AnyTemplateType | null>) => Signal<StringTemplate | NgTemplateTemplate | ComponentTemplate | null>;
906
1859
 
907
- declare const injectAngularRootElement: {
908
- (): _angular_core.WritableSignal<HTMLElement | null>;
909
- (options: _angular_core.InjectOptions & {
910
- optional?: false;
911
- }): _angular_core.WritableSignal<HTMLElement | null>;
912
- (options: _angular_core.InjectOptions): _angular_core.WritableSignal<HTMLElement | null> | null;
1860
+ type SwipeTracker = {
1861
+ update(event: TouchEvent | MouseEvent): SwipeUpdateEvent;
1862
+ end(): SwipeEndEvent;
1863
+ cancel(): void;
913
1864
  };
1865
+ type SwipeEndEvent = {
1866
+ /**
1867
+ * Speed at the moment of release, measured over the trailing {@link SWIPE_VELOCITY_WINDOW_MS} of
1868
+ * the gesture - not the whole-gesture average. A slow drag that ends in a flick reports the
1869
+ * flick, and a flick that ends parked reports ~0.
1870
+ */
1871
+ positivePixelPerSecondX: number;
1872
+ positivePixelPerSecondY: number;
1873
+ pixelPerSecondX: number;
1874
+ pixelPerSecondY: number;
1875
+ movementX: number;
1876
+ movementY: number;
1877
+ positiveMovementX: number;
1878
+ positiveMovementY: number;
1879
+ originClientX: number;
1880
+ originClientY: number;
1881
+ };
1882
+ type SwipeUpdateEvent = {
1883
+ originClientX: number;
1884
+ originClientY: number;
1885
+ timestamp: number;
1886
+ movementX: number;
1887
+ movementY: number;
1888
+ positiveMovementX: number;
1889
+ positiveMovementY: number;
1890
+ isScrolling: boolean;
1891
+ isSwiping: boolean;
1892
+ };
1893
+ /** Trailing window over which {@link SwipeTracker.end} measures the release velocity. */
1894
+ declare const SWIPE_VELOCITY_WINDOW_MS = 100;
1895
+ declare const createSwipeTracker: (startEvent: TouchEvent | MouseEvent) => SwipeTracker;
914
1896
 
915
- declare const provideBoundaryElement: () => _angular_core.Provider[];
916
- declare const injectBoundaryElement: {
917
- (): {
918
- value: _angular_core.Signal<HTMLElement>;
919
- override: _angular_core.WritableSignal<HTMLElement | null>;
920
- };
921
- (options: _angular_core.InjectOptions & {
922
- optional?: false;
923
- }): {
924
- value: _angular_core.Signal<HTMLElement>;
925
- override: _angular_core.WritableSignal<HTMLElement | null>;
926
- };
927
- (options: _angular_core.InjectOptions): {
928
- value: _angular_core.Signal<HTMLElement>;
929
- override: _angular_core.WritableSignal<HTMLElement | null>;
930
- } | null;
1897
+ declare class NormalizeGameResultTypePipe implements PipeTransform {
1898
+ transform: (type: string | null) => NormalizedGameResultType | null;
1899
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NormalizeGameResultTypePipe, never>;
1900
+ static ɵpipe: _angular_core.ɵɵPipeDeclaration<NormalizeGameResultTypePipe, "etNormalizeGameResultType", true>;
1901
+ }
1902
+ type NormalizedGameResultType = Translatable & {
1903
+ shortCode: string;
931
1904
  };
932
- declare const BOUNDARY_ELEMENT_TOKEN: _angular_core.InjectionToken<{
933
- value: _angular_core.Signal<HTMLElement>;
934
- override: _angular_core.WritableSignal<HTMLElement | null>;
935
- }>;
1905
+ declare const normalizeGameResultType: (type: string | null) => NormalizedGameResultType | null;
936
1906
 
937
- type Vec2 = [number, number];
938
- type ViewportConfig = {
939
- breakpoints: {
940
- xs: Vec2;
941
- sm: Vec2;
942
- md: Vec2;
943
- lg: Vec2;
944
- xl: Vec2;
945
- '2xl': Vec2;
946
- };
947
- };
948
- type Breakpoint = keyof ViewportConfig['breakpoints'];
949
- /**
950
- * Default viewport config based on Tailwind CSS.
951
- * @see https://tailwindcss.com/docs/screens
952
- */
953
- declare const DEFAULT_VIEWPORT_CONFIG: ViewportConfig;
954
- declare const provideViewportConfig: (valueOverride?: Partial<ViewportConfig> | undefined) => _angular_core.Provider[];
955
- declare const injectViewportConfig: {
956
- (): ViewportConfig;
957
- (options: _angular_core.InjectOptions & {
958
- optional?: false;
959
- }): ViewportConfig;
960
- (options: _angular_core.InjectOptions): ViewportConfig | null;
961
- };
962
- type BuildMediaQueryOptions = {
963
- min?: number | Breakpoint;
964
- max?: number | Breakpoint;
1907
+ declare class NormalizeMatchParticipantsPipe implements PipeTransform {
1908
+ transform: (match: MatchListView | null) => NormalizedMatchParticipants | null;
1909
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NormalizeMatchParticipantsPipe, never>;
1910
+ static ɵpipe: _angular_core.ɵɵPipeDeclaration<NormalizeMatchParticipantsPipe, "etNormalizeMatchParticipants", true>;
1911
+ }
1912
+ type NormalizedMatchParticipants = {
1913
+ home: NormalizedMatchParticipant | null;
1914
+ away: NormalizedMatchParticipant | null;
965
1915
  };
966
- declare const provideBreakpointObserver: () => _angular_core.Provider[];
967
- declare const injectBreakpointObserver: {
968
- (): {
969
- observeBreakpoint: (options: BuildMediaQueryOptions) => _angular_core.Signal<boolean>;
970
- isBreakpointMatched: (options: BuildMediaQueryOptions) => boolean;
971
- getBreakpointSize: (type: Breakpoint, option: "min" | "max") => number;
972
- buildMediaQueryString: (options: BuildMediaQueryOptions) => string;
973
- observeMediaQuery: (mediaQuery: string) => _angular_core.Signal<boolean>;
974
- isMediaQueryMatched: (mediaQuery: string) => boolean;
1916
+ type NormalizedParticipantType = 'team' | 'player' | 'unknown';
1917
+ type NormalizedMatchParticipant = ({
1918
+ type: 'tbd';
1919
+ participantType: NormalizedParticipantType;
1920
+ data: ParticipantViewUnion | null;
1921
+ } & Translatable) | {
1922
+ type: 'participant';
1923
+ participantType: NormalizedParticipantType;
1924
+ data: ParticipantViewUnion;
1925
+ } | ({
1926
+ type: 'none';
1927
+ participantType: NormalizedParticipantType;
1928
+ data: ParticipantViewUnion | null;
1929
+ } & Translatable);
1930
+ declare const normalizeMatchParticipants: (match: MatchListView | null) => NormalizedMatchParticipants | null;
1931
+ declare const normalizeMatchParticipant: (match: MatchListView | null, side: "home" | "away") => NormalizedMatchParticipant | null;
1932
+
1933
+ declare class NormalizeMatchScorePipe implements PipeTransform {
1934
+ transform: (match: MatchListView | null | undefined) => NormalizedMatchScore | null;
1935
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NormalizeMatchScorePipe, never>;
1936
+ static ɵpipe: _angular_core.ɵɵPipeDeclaration<NormalizeMatchScorePipe, "etNormalizeMatchScore", true>;
1937
+ }
1938
+ declare const enum MatchStateType {
1939
+ PREPARING_ROUND = "preparingRound",
1940
+ PRE_MATCH = "preMatch",
1941
+ LIVE = "live",
1942
+ POST_MATCH = "postMatch",
1943
+ AUTO_WIN = "autoWin"
1944
+ }
1945
+ type NormalizedMatchScore = {
1946
+ home: {
1947
+ score: string | number | null;
1948
+ isWinner: boolean;
975
1949
  };
976
- (options: _angular_core.InjectOptions & {
977
- optional?: false;
978
- }): {
979
- observeBreakpoint: (options: BuildMediaQueryOptions) => _angular_core.Signal<boolean>;
980
- isBreakpointMatched: (options: BuildMediaQueryOptions) => boolean;
981
- getBreakpointSize: (type: Breakpoint, option: "min" | "max") => number;
982
- buildMediaQueryString: (options: BuildMediaQueryOptions) => string;
983
- observeMediaQuery: (mediaQuery: string) => _angular_core.Signal<boolean>;
984
- isMediaQueryMatched: (mediaQuery: string) => boolean;
1950
+ away: {
1951
+ score: string | number | null;
1952
+ isWinner: boolean;
985
1953
  };
986
- (options: _angular_core.InjectOptions): {
987
- observeBreakpoint: (options: BuildMediaQueryOptions) => _angular_core.Signal<boolean>;
988
- isBreakpointMatched: (options: BuildMediaQueryOptions) => boolean;
989
- getBreakpointSize: (type: Breakpoint, option: "min" | "max") => number;
990
- buildMediaQueryString: (options: BuildMediaQueryOptions) => string;
991
- observeMediaQuery: (mediaQuery: string) => _angular_core.Signal<boolean>;
992
- isMediaQueryMatched: (mediaQuery: string) => boolean;
993
- } | null;
1954
+ subLine: string | null;
1955
+ isNumeric: boolean;
994
1956
  };
995
-
996
- declare const provideFocusVisibleTracker: () => _angular_core.Provider[];
997
- declare const injectFocusVisibleTracker: {
998
- (): {
999
- isFocusVisible: _angular_core.Signal<boolean>;
1957
+ declare const normalizeMatchScore: (match: MatchListView | null | undefined) => NormalizedMatchScore | null;
1958
+ declare const isKnockoutMatch: (match: MatchListView | null | undefined) => boolean;
1959
+ declare const isGroupMatch: (match: MatchListView | null | undefined) => boolean;
1960
+ declare const getKnockoutMatchScore: (score: MatchRankingView | null | undefined) => "match-score.knockout.won" | "match-score.knockout.lost" | "match-score.knockout.tie" | null;
1961
+ declare const getMatchScoreSubLine: (match: MatchListView | null | undefined) => "match-score.groups.sub-line" | null;
1962
+ declare const getGroupMatchScore: (match: MatchListView | null | undefined) => {
1963
+ home: {
1964
+ score: number;
1965
+ isWinner: boolean;
1000
1966
  };
1001
- (options: _angular_core.InjectOptions & {
1002
- optional?: false;
1003
- }): {
1004
- isFocusVisible: _angular_core.Signal<boolean>;
1967
+ away: {
1968
+ score: number;
1969
+ isWinner: boolean;
1005
1970
  };
1006
- (options: _angular_core.InjectOptions): {
1007
- isFocusVisible: _angular_core.Signal<boolean>;
1008
- } | null;
1009
- };
1010
- declare const FOCUS_VISIBLE_TRACKER_TOKEN: _angular_core.InjectionToken<{
1011
- isFocusVisible: _angular_core.Signal<boolean>;
1012
- }>;
1013
-
1014
- declare const provideLocale: () => _angular_core.Provider[];
1015
- declare const injectLocale: {
1016
- (): {
1017
- currentLocale: _angular_core.WritableSignal<string>;
1971
+ } | null;
1972
+ declare const getGroupMatchPoints: (match: MatchListView | null | undefined) => {
1973
+ home: {
1974
+ score: number;
1975
+ isWinner: boolean;
1018
1976
  };
1019
- (options: _angular_core.InjectOptions & {
1020
- optional?: false;
1021
- }): {
1022
- currentLocale: _angular_core.WritableSignal<string>;
1977
+ away: {
1978
+ score: number;
1979
+ isWinner: boolean;
1023
1980
  };
1024
- (options: _angular_core.InjectOptions): {
1025
- currentLocale: _angular_core.WritableSignal<string>;
1026
- } | null;
1027
- };
1981
+ } | null;
1028
1982
 
1029
- declare const provideRenderer: () => _angular_core.Provider[];
1030
- declare const injectRenderer: {
1031
- (): {
1032
- addClass: (element: HTMLElement, ...classes: string[]) => void;
1033
- removeClass: (element: HTMLElement, ...classes: string[]) => void;
1034
- toggleClass: (element: HTMLElement, className: string, force?: boolean) => boolean;
1035
- setStyle: (element: HTMLElement, style: Partial<Record<keyof CSSStyleDeclaration, string | null>>, flags?: RendererStyleFlags2) => void;
1036
- removeStyle: (element: HTMLElement, style: keyof CSSStyleDeclaration | string, flags?: RendererStyleFlags2) => void;
1037
- removeStyles: (element: HTMLElement, ...styles: (keyof CSSStyleDeclaration | string)[]) => void;
1038
- setAttribute: (element: HTMLElement, name: string, value: string | null, namespace?: string | null) => void;
1039
- removeAttribute: (element: HTMLElement, ...names: string[]) => void;
1040
- setProperty: (element: HTMLElement, name: string, value: unknown) => void;
1041
- setProperties: (element: HTMLElement, properties: Record<string, unknown>) => void;
1042
- createElement: <K extends keyof HTMLElementTagNameMap>(tagName: K, namespace?: string | null) => HTMLElementTagNameMap[K];
1043
- createText: (value: string) => Text;
1044
- createComment: (value: string) => Comment;
1045
- appendChild: (parent: HTMLElement, newChild: Node) => void;
1046
- insertBefore: (parent: Node, newChild: Node, refChild: Node | null) => void;
1047
- removeChild: (parent: Node, oldChild: Node, isHostElement?: boolean) => void;
1048
- selectRootElement: (selectorOrNode: string | HTMLElement, preserveContent?: boolean) => HTMLElement;
1049
- parentNode: (node: Node) => Node | null;
1050
- nextSibling: (node: Node) => Node | null;
1051
- setValue: (node: Node, value: string) => void;
1052
- listen: (target: HTMLElement | Window | Document | "window" | "document" | "body", eventName: string, callback: (event: Event) => boolean | void) => (() => void);
1053
- destroyNode: (node: Node) => void;
1054
- replaceChild: (parent: Node, newChild: Node, oldChild: Node) => void;
1055
- empty: (element: HTMLElement) => void;
1056
- setTextContent: (element: HTMLElement, text: string) => void;
1057
- setInnerHTML: (element: HTMLElement, html: string) => void;
1058
- setAttributes: (element: HTMLElement, attributes: Record<string, string | null>, namespace?: string | null) => void;
1059
- setDataAttributes: (element: HTMLElement, data: Record<string, string | null>) => void;
1060
- setCssProperty: (element: HTMLElement, name: string, value: string | null) => void;
1061
- setCssProperties: (element: HTMLElement, properties: Record<string, string | null>) => void;
1062
- renderer: _angular_core.Renderer2;
1063
- };
1064
- (options: _angular_core.InjectOptions & {
1065
- optional?: false;
1066
- }): {
1067
- addClass: (element: HTMLElement, ...classes: string[]) => void;
1068
- removeClass: (element: HTMLElement, ...classes: string[]) => void;
1069
- toggleClass: (element: HTMLElement, className: string, force?: boolean) => boolean;
1070
- setStyle: (element: HTMLElement, style: Partial<Record<keyof CSSStyleDeclaration, string | null>>, flags?: RendererStyleFlags2) => void;
1071
- removeStyle: (element: HTMLElement, style: keyof CSSStyleDeclaration | string, flags?: RendererStyleFlags2) => void;
1072
- removeStyles: (element: HTMLElement, ...styles: (keyof CSSStyleDeclaration | string)[]) => void;
1073
- setAttribute: (element: HTMLElement, name: string, value: string | null, namespace?: string | null) => void;
1074
- removeAttribute: (element: HTMLElement, ...names: string[]) => void;
1075
- setProperty: (element: HTMLElement, name: string, value: unknown) => void;
1076
- setProperties: (element: HTMLElement, properties: Record<string, unknown>) => void;
1077
- createElement: <K extends keyof HTMLElementTagNameMap>(tagName: K, namespace?: string | null) => HTMLElementTagNameMap[K];
1078
- createText: (value: string) => Text;
1079
- createComment: (value: string) => Comment;
1080
- appendChild: (parent: HTMLElement, newChild: Node) => void;
1081
- insertBefore: (parent: Node, newChild: Node, refChild: Node | null) => void;
1082
- removeChild: (parent: Node, oldChild: Node, isHostElement?: boolean) => void;
1083
- selectRootElement: (selectorOrNode: string | HTMLElement, preserveContent?: boolean) => HTMLElement;
1084
- parentNode: (node: Node) => Node | null;
1085
- nextSibling: (node: Node) => Node | null;
1086
- setValue: (node: Node, value: string) => void;
1087
- listen: (target: HTMLElement | Window | Document | "window" | "document" | "body", eventName: string, callback: (event: Event) => boolean | void) => (() => void);
1088
- destroyNode: (node: Node) => void;
1089
- replaceChild: (parent: Node, newChild: Node, oldChild: Node) => void;
1090
- empty: (element: HTMLElement) => void;
1091
- setTextContent: (element: HTMLElement, text: string) => void;
1092
- setInnerHTML: (element: HTMLElement, html: string) => void;
1093
- setAttributes: (element: HTMLElement, attributes: Record<string, string | null>, namespace?: string | null) => void;
1094
- setDataAttributes: (element: HTMLElement, data: Record<string, string | null>) => void;
1095
- setCssProperty: (element: HTMLElement, name: string, value: string | null) => void;
1096
- setCssProperties: (element: HTMLElement, properties: Record<string, string | null>) => void;
1097
- renderer: _angular_core.Renderer2;
1098
- };
1099
- (options: _angular_core.InjectOptions): {
1100
- addClass: (element: HTMLElement, ...classes: string[]) => void;
1101
- removeClass: (element: HTMLElement, ...classes: string[]) => void;
1102
- toggleClass: (element: HTMLElement, className: string, force?: boolean) => boolean;
1103
- setStyle: (element: HTMLElement, style: Partial<Record<keyof CSSStyleDeclaration, string | null>>, flags?: RendererStyleFlags2) => void;
1104
- removeStyle: (element: HTMLElement, style: keyof CSSStyleDeclaration | string, flags?: RendererStyleFlags2) => void;
1105
- removeStyles: (element: HTMLElement, ...styles: (keyof CSSStyleDeclaration | string)[]) => void;
1106
- setAttribute: (element: HTMLElement, name: string, value: string | null, namespace?: string | null) => void;
1107
- removeAttribute: (element: HTMLElement, ...names: string[]) => void;
1108
- setProperty: (element: HTMLElement, name: string, value: unknown) => void;
1109
- setProperties: (element: HTMLElement, properties: Record<string, unknown>) => void;
1110
- createElement: <K extends keyof HTMLElementTagNameMap>(tagName: K, namespace?: string | null) => HTMLElementTagNameMap[K];
1111
- createText: (value: string) => Text;
1112
- createComment: (value: string) => Comment;
1113
- appendChild: (parent: HTMLElement, newChild: Node) => void;
1114
- insertBefore: (parent: Node, newChild: Node, refChild: Node | null) => void;
1115
- removeChild: (parent: Node, oldChild: Node, isHostElement?: boolean) => void;
1116
- selectRootElement: (selectorOrNode: string | HTMLElement, preserveContent?: boolean) => HTMLElement;
1117
- parentNode: (node: Node) => Node | null;
1118
- nextSibling: (node: Node) => Node | null;
1119
- setValue: (node: Node, value: string) => void;
1120
- listen: (target: HTMLElement | Window | Document | "window" | "document" | "body", eventName: string, callback: (event: Event) => boolean | void) => (() => void);
1121
- destroyNode: (node: Node) => void;
1122
- replaceChild: (parent: Node, newChild: Node, oldChild: Node) => void;
1123
- empty: (element: HTMLElement) => void;
1124
- setTextContent: (element: HTMLElement, text: string) => void;
1125
- setInnerHTML: (element: HTMLElement, html: string) => void;
1126
- setAttributes: (element: HTMLElement, attributes: Record<string, string | null>, namespace?: string | null) => void;
1127
- setDataAttributes: (element: HTMLElement, data: Record<string, string | null>) => void;
1128
- setCssProperty: (element: HTMLElement, name: string, value: string | null) => void;
1129
- setCssProperties: (element: HTMLElement, properties: Record<string, string | null>) => void;
1130
- renderer: _angular_core.Renderer2;
1131
- } | null;
1132
- };
1133
- type AngularRenderer = NonNullable<ReturnType<typeof injectRenderer>>;
1983
+ declare class NormalizeMatchStatePipe implements PipeTransform {
1984
+ transform: (match: MatchListView | null | undefined) => MatchStateType | null;
1985
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NormalizeMatchStatePipe, never>;
1986
+ static ɵpipe: _angular_core.ɵɵPipeDeclaration<NormalizeMatchStatePipe, "etNormalizeMatchState", true>;
1987
+ }
1988
+ declare const normalizeMatchState: (match: MatchListView | null | undefined) => MatchStateType | null;
1134
1989
 
1135
- declare const previousSignalValue: <T>(signal: Signal<T>) => Signal<T | undefined>;
1136
- type SyncSignalOptions = {
1137
- /**
1138
- * If true, the target signal will not be updated with the source signal's value in a sync operation.
1139
- * This should be set to true for signals that need to be initialized first before syncing (eg. required inputs)
1140
- * @default false
1141
- */
1142
- skipSyncRead?: boolean;
1143
- /**
1144
- * If true, the first time the effect will be triggered will be skipped.
1145
- * @default false
1146
- */
1147
- skipFirstRun?: boolean;
1148
- };
1149
- declare const syncSignal: <T>(from: Signal<T>, to: WritableSignal<T>, options?: SyncSignalOptions) => _angular_core.EffectRef;
1150
- type MaybeSignal<T> = T | Signal<T>;
1151
- declare const maybeSignalValue: <T>(value: MaybeSignal<T>) => T;
1152
- /**
1153
- * A computed that will only be reactive until the source signal contains a truthy value.
1154
- * All subsequent changes inside the computation will be ignored.
1155
- */
1156
- declare const computedTillTruthy: <T>(source: Signal<T>) => Signal<T | null>;
1157
- /**
1158
- * A computed that will only be reactive until the source signal contains a falsy value.
1159
- * All subsequent changes inside the computation will be ignored.
1160
- */
1161
- declare const computedTillFalsy: <T>(source: Signal<T>) => Signal<T | null>;
1162
- /**
1163
- * A writeable signal that will be set to the provided value once all inputs are set.
1164
- * During that time, the signal will be set to `null`.
1165
- */
1166
- declare const deferredSignal: <T extends () => unknown>(valueFn: T) => WritableSignal<ReturnType<T> | null>;
1167
- declare const memoizeSignal: <T>(factory: () => Signal<T>) => () => Signal<T>;
1990
+ declare class NormalizeMatchTypePipe implements PipeTransform {
1991
+ transform: (matchType: StageType | null | undefined) => Translatable | null;
1992
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NormalizeMatchTypePipe, never>;
1993
+ static ɵpipe: _angular_core.ɵɵPipeDeclaration<NormalizeMatchTypePipe, "etNormalizeMatchType", true>;
1994
+ }
1995
+ declare const normalizeMatchType: (matchType: StageType | null | undefined) => Translatable | null;
1168
1996
 
1169
- type SignalAnimatedNumberOptions = {
1170
- /**
1171
- * The initial value to start animating from.
1172
- * If not provided, the animation will start from 0
1173
- */
1174
- initialValue?: number;
1175
- /**
1176
- * Duration of the animation in milliseconds.
1177
- * @default 1000
1178
- */
1179
- duration?: number;
1180
- /**
1181
- * Easing function that takes a progress value (0 to 1) and returns an eased value (0 to 1).
1182
- * Options:
1183
- * - `easeLinear()`
1184
- * - `easeIn()`
1185
- * - `easeOut()`
1186
- * - `easeInOut()`
1187
- * - `easeElastic()`
1188
- * - `easeOutBack()`
1189
- * - `easeOutBackStrong()`
1190
- * @default easeOut()
1191
- */
1192
- easing?: (t: number) => number;
1193
- /**
1194
- * Function to round the animated value.
1195
- * @default (v: number) => Math.round(v)
1196
- */
1197
- round?: (value: number) => number;
1198
- /**
1199
- * Callback invoked when the animation starts.
1200
- */
1201
- onAnimationStart?: () => void;
1202
- /**
1203
- * Callback invoked when the animation ends.
1204
- */
1205
- onAnimationEnd?: () => void;
1206
- };
1207
- type AnimatedNumberSignal = Signal<number> & {
1208
- /**
1209
- * Starts the animation from the current value to the target value.
1210
- * @returns The animated signal for chaining
1211
- */
1212
- play: () => AnimatedNumberSignal;
1213
- /**
1214
- * Resets the animation to the initial value and stops any ongoing animation.
1215
- * @returns The animated signal for chaining
1216
- */
1217
- reset: () => AnimatedNumberSignal;
1218
- /**
1219
- * Stops the current animation at its current position.
1220
- * @returns The animated signal for chaining
1221
- */
1222
- stop: () => AnimatedNumberSignal;
1223
- };
1997
+ declare class HtmlToMarkdownPipe implements PipeTransform {
1998
+ transform: (html: string) => string;
1999
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<HtmlToMarkdownPipe, never>;
2000
+ static ɵpipe: _angular_core.ɵɵPipeDeclaration<HtmlToMarkdownPipe, "htmlToMarkdown", true>;
2001
+ }
2002
+
2003
+ declare class InferMimeTypePipe implements PipeTransform {
2004
+ transform: (srcset: string) => string | null;
2005
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<InferMimeTypePipe, never>;
2006
+ static ɵpipe: _angular_core.ɵɵPipeDeclaration<InferMimeTypePipe, "inferMimeType", true>;
2007
+ }
1224
2008
  /**
1225
- * Creates a signal that animates the transition of a numeric signal's value over time.
2009
+ * Infers the mime type of a given url or srcset.
2010
+ * If a srcset is provided, it will infer the mime type of the first url in the srcset.
2011
+ * If the srcset contains a query parameter `?fm=`, it will use the value of that parameter, since it is often used to specify the file format in image api's like contentful.
1226
2012
  */
1227
- declare const signalAnimatedNumber: (source: MaybeSignal<number>, options?: SignalAnimatedNumberOptions) => AnimatedNumberSignal;
1228
- declare const easeLinear: (t: number) => number;
1229
- declare const easeIn: (t: number) => number;
1230
- declare const easeOut: (t: number) => number;
1231
- declare const easeInOut: (t: number) => number;
1232
- /** Elastic easing function (overshoots) */
1233
- declare const easeElastic: (t: number) => number;
1234
- /** Back easing function (overshoots slightly then settles) */
1235
- declare const easeOutBack: (t: number) => number;
1236
- /** Back easing function with more overshoot */
1237
- declare const easeOutBackStrong: (t: number) => number;
2013
+ declare const inferMimeType: (srcset: string) => string | null;
1238
2014
 
1239
- type ControlValueSignalOptions = {
1240
- debounceTime?: number;
1241
- /**
1242
- * @default false
1243
- */
1244
- debounceFirst?: boolean;
1245
- };
1246
- declare const controlValueSignal: <TControlInput extends Signal<AbstractControl | null> | AbstractControl, TControl extends TControlInput extends Signal<infer TSignalControl> ? TSignalControl : TControlInput>(control: TControlInput, options?: ControlValueSignalOptions) => Signal<ReturnType<NonNullable<TControl>["getRawValue"]> | null>;
2015
+ declare class InitialsPipe implements PipeTransform {
2016
+ transform: (value: string | null | undefined, maxLength?: number) => string;
2017
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<InitialsPipe, never>;
2018
+ static ɵpipe: _angular_core.ɵɵPipeDeclaration<InitialsPipe, "initials", true>;
2019
+ }
1247
2020
  /**
1248
- * The first item in the pair is the previous value and the second item is the current value.
2021
+ * Extracts the initials from a name (or any whitespace separated string).
2022
+ *
2023
+ * Words are split on whitespace, and the first character of each word is taken.
2024
+ * At most `maxLength` initials are returned (defaults to 2), always uppercased.
2025
+ *
2026
+ * @example
2027
+ * initials('John Doe') // 'JD'
2028
+ * initials('john doe smith') // 'JD'
2029
+ * initials('john doe smith', 3) // 'JDS'
2030
+ * initials('Madonna') // 'M'
2031
+ * initials(' ') // ''
2032
+ * initials(null) // ''
1249
2033
  */
1250
- declare const controlValueSignalWithPrevious: <T extends AbstractControl>(control: T, options?: ControlValueSignalOptions) => Signal<[ReturnType<NonNullable<T extends Signal<infer TSignalControl> ? TSignalControl : T>["getRawValue"]> | null, ReturnType<NonNullable<T extends Signal<infer TSignalControl> ? TSignalControl : T>["getRawValue"]> | null]>;
1251
-
1252
- type SignalElementBindingComplexType = HTMLElement | ElementRef<HTMLElement> | QueryList<ElementRef<HTMLElement> | HTMLElement> | Array<ElementRef<HTMLElement> | HTMLElement> | null | undefined;
1253
- type SignalElementBindingType = HTMLElement | ElementRef<HTMLElement> | Observable<SignalElementBindingComplexType> | Signal<SignalElementBindingComplexType> | QueryList<ElementRef<HTMLElement> | HTMLElement> | ElementSignal;
1254
- type ElementSignal = Signal<{
1255
- currentElements: HTMLElement[];
1256
- previousElements: HTMLElement[];
1257
- }>;
1258
- type ElementSignalValue = ReturnType<ElementSignal>;
1259
- declare const isElementSignal: (el: unknown) => el is ElementSignal;
1260
- declare const createDocumentElementSignal: () => ElementSignal;
1261
- declare const createEmptyElementSignal: () => ElementSignal;
1262
- declare const buildElementSignal: (el: SignalElementBindingType | null | undefined) => ElementSignal;
1263
- declare const firstElementSignal: (el: ElementSignal) => Signal<{
1264
- currentElement: HTMLElement | null;
1265
- previousElement: HTMLElement | null;
1266
- }>;
2034
+ declare const initials: (value: string | null | undefined, maxLength?: number) => string;
1267
2035
 
1268
- declare const signalElementChildren: (el: SignalElementBindingType) => _angular_core.Signal<HTMLElement[]>;
2036
+ declare class MarkdownToHtmlPipe implements PipeTransform {
2037
+ transform: (markdown: string) => string;
2038
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MarkdownToHtmlPipe, never>;
2039
+ static ɵpipe: _angular_core.ɵɵPipeDeclaration<MarkdownToHtmlPipe, "markdownToHtml", true>;
2040
+ }
1269
2041
 
1270
- type BuildSignalEffectsConfig<T extends Record<string, Signal<unknown>>> = {
1271
- /** The tokens to apply and their signal value */
1272
- tokenMap: T;
1273
- /** This function will be invoked for elements that were removed from the signal effects */
1274
- cleanupFn: (el: HTMLElement, tokens: string[]) => void;
1275
- /** This function will be invoked for elements that were added to the signal effects or when their signal value changes */
1276
- updateFn: (el: HTMLElement, tokens: string[], conditionResult: unknown) => void;
1277
- };
1278
- declare const buildSignalEffects: <T extends Record<string, Signal<unknown>>>(el: SignalElementBindingType, config: BuildSignalEffectsConfig<T>) => {
1279
- remove: (tokens: string) => void;
1280
- removeMany: (tokens: string[]) => void;
1281
- has: (tokens: string) => boolean;
1282
- push: (tokens: string, signal: Signal<unknown>) => void;
1283
- pushMany: (map: Record<string, Signal<unknown>>) => void;
1284
- };
1285
- declare const signalClasses: <T extends Record<string, Signal<unknown>>>(el: SignalElementBindingType, classMap: T) => {
1286
- remove: (tokens: string) => void;
1287
- removeMany: (tokens: string[]) => void;
1288
- has: (tokens: string) => boolean;
1289
- push: (tokens: string, signal: Signal<unknown>) => void;
1290
- pushMany: (map: Record<string, Signal<unknown>>) => void;
1291
- };
1292
- declare const signalHostClasses: <T extends Record<string, Signal<unknown>>>(classMap: T) => {
1293
- remove: (tokens: string) => void;
1294
- removeMany: (tokens: string[]) => void;
1295
- has: (tokens: string) => boolean;
1296
- push: (tokens: string, signal: Signal<unknown>) => void;
1297
- pushMany: (map: Record<string, Signal<unknown>>) => void;
1298
- };
1299
- declare const signalAttributes: <T extends Record<string, Signal<unknown>>>(el: SignalElementBindingType, attributeMap: T) => {
1300
- remove: (tokens: string) => void;
1301
- removeMany: (tokens: string[]) => void;
1302
- has: (tokens: string) => boolean;
1303
- push: (tokens: string, signal: Signal<unknown>) => void;
1304
- pushMany: (map: Record<string, Signal<unknown>>) => void;
1305
- };
1306
- declare const signalHostAttributes: <T extends Record<string, Signal<unknown>>>(attributeMap: T) => {
1307
- remove: (tokens: string) => void;
1308
- removeMany: (tokens: string[]) => void;
1309
- has: (tokens: string) => boolean;
1310
- push: (tokens: string, signal: Signal<unknown>) => void;
1311
- pushMany: (map: Record<string, Signal<unknown>>) => void;
1312
- };
1313
- declare const signalStyles: <T extends Record<string, Signal<unknown>>>(el: SignalElementBindingType, styleMap: T) => {
1314
- remove: (tokens: string) => void;
1315
- removeMany: (tokens: string[]) => void;
1316
- has: (tokens: string) => boolean;
1317
- push: (tokens: string, signal: Signal<unknown>) => void;
1318
- pushMany: (map: Record<string, Signal<unknown>>) => void;
1319
- };
1320
- declare const signalHostStyles: <T extends Record<string, Signal<unknown>>>(styleMap: T) => {
1321
- remove: (tokens: string) => void;
1322
- removeMany: (tokens: string[]) => void;
1323
- has: (tokens: string) => boolean;
1324
- push: (tokens: string, signal: Signal<unknown>) => void;
1325
- pushMany: (map: Record<string, Signal<unknown>>) => void;
2042
+ declare class SlugifyPipe implements PipeTransform {
2043
+ transform: (value: string | null | undefined) => string;
2044
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SlugifyPipe, never>;
2045
+ static ɵpipe: _angular_core.ɵɵPipeDeclaration<SlugifyPipe, "slugify", true>;
2046
+ }
2047
+ /**
2048
+ * Converts a string into a URL-friendly slug.
2049
+ *
2050
+ * Diacritics are stripped, the string is lowercased, and any run of
2051
+ * non-alphanumeric characters becomes a single hyphen. Leading/trailing
2052
+ * hyphens are trimmed.
2053
+ *
2054
+ * @example
2055
+ * slugify('Hello World') // 'hello-world'
2056
+ * slugify(' Crème brûlée! ') // 'creme-brulee'
2057
+ * slugify('FC Bayern München') // 'fc-bayern-munchen'
2058
+ * slugify('foo_bar / baz') // 'foo-bar-baz'
2059
+ * slugify(null) // ''
2060
+ */
2061
+ declare const slugify: (value: string | null | undefined) => string;
2062
+
2063
+ declare class ToArrayPipe implements PipeTransform {
2064
+ transform: (value: number) => number[];
2065
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ToArrayPipe, never>;
2066
+ static ɵpipe: _angular_core.ɵɵPipeDeclaration<ToArrayPipe, "toArray", true>;
2067
+ }
2068
+ declare const toArray: (value: number) => number[];
2069
+ declare const toArrayTrackByFn: TrackByFunction<number>;
2070
+
2071
+ declare const createPropHandlers: () => {
2072
+ classes: {
2073
+ remove: (tokens: string) => void;
2074
+ removeMany: (tokens: string[]) => void;
2075
+ has: (tokens: string) => boolean;
2076
+ push: (tokens: string, signal: _angular_core.Signal<unknown>) => void;
2077
+ pushMany: (map: Record<string, _angular_core.Signal<unknown>>) => void;
2078
+ };
2079
+ attributes: {
2080
+ remove: (tokens: string) => void;
2081
+ removeMany: (tokens: string[]) => void;
2082
+ has: (tokens: string) => boolean;
2083
+ push: (tokens: string, signal: _angular_core.Signal<unknown>) => void;
2084
+ pushMany: (map: Record<string, _angular_core.Signal<unknown>>) => void;
2085
+ };
2086
+ styles: {
2087
+ remove: (tokens: string) => void;
2088
+ removeMany: (tokens: string[]) => void;
2089
+ has: (tokens: string) => boolean;
2090
+ push: (tokens: string, signal: _angular_core.Signal<unknown>) => void;
2091
+ pushMany: (map: Record<string, _angular_core.Signal<unknown>>) => void;
2092
+ };
2093
+ id: string;
2094
+ elementRef: ElementRef<HTMLElement>;
1326
2095
  };
2096
+ type PropHandlers = ReturnType<typeof createPropHandlers>;
1327
2097
 
1328
- type LogicalSize = {
1329
- inlineSize: number;
1330
- blockSize: number;
2098
+ type Props = Readonly<{
2099
+ attached: Signal<boolean>;
2100
+ attachedElements: PropsAttachedElements;
2101
+ }>;
2102
+ type PropsAttachedElements = {
2103
+ first: Signal<HTMLElement | null>;
2104
+ firstId: Signal<string | null>;
2105
+ get(id: string): HTMLElement | null;
1331
2106
  };
1332
- type ElementRect = {
1333
- bottom: number;
1334
- height: number;
1335
- left: number;
1336
- right: number;
1337
- top: number;
1338
- width: number;
1339
- x: number;
1340
- y: number;
2107
+ type PropsAttachedElementsInternal = PropsAttachedElements & {
2108
+ has: (id: string) => boolean;
2109
+ push: (id: string, element: HTMLElement) => void;
2110
+ remove: (id: string) => void;
1341
2111
  };
1342
- type ElementSize = {
1343
- width: number;
1344
- height: number;
2112
+ type PropsInternal = {
2113
+ single: boolean;
2114
+ name: string;
2115
+ bindId: boolean;
2116
+ attached: Signal<boolean>;
2117
+ attachedElements: PropsAttachedElementsInternal;
2118
+ classBindings: Record<string, Signal<unknown>> | null;
2119
+ attributeBindings: Record<string, Signal<unknown>> | null;
2120
+ styleBindings: Record<string, Signal<unknown>> | null;
2121
+ staticClassBindings: string[] | null;
2122
+ staticAttributeBindings: Record<string, unknown> | null;
2123
+ staticStyleBindings: Record<string, unknown> | null;
2124
+ attachEventListeners: ((context: {
2125
+ on: HTMLElement['addEventListener'];
2126
+ element: HTMLElement;
2127
+ }) => void) | null;
1345
2128
  };
1346
- declare const boundingClientRectToElementRect: (rect: DOMRectReadOnly) => ElementRect;
1347
- declare const createElementDimensions: (el: HTMLElement | null, rect?: DOMRect) => NullableElementDimensions;
1348
- type ElementDimensions = {
1349
- rect: () => ElementRect;
1350
- client: ElementSize;
1351
- scroll: ElementSize;
1352
- offset: ElementSize;
2129
+ type CreatePropsOptions = {
2130
+ name: string;
2131
+ bindId?: boolean;
2132
+ single?: boolean;
2133
+ classes?: Record<string, Signal<unknown>>;
2134
+ attributes?: Record<string, Signal<unknown>>;
2135
+ styles?: Record<string, Signal<unknown>>;
2136
+ staticClasses?: string[];
2137
+ staticAttributes?: Record<string, unknown>;
2138
+ staticStyles?: Record<string, unknown>;
2139
+ listeners?: (context: {
2140
+ on: HTMLElement['addEventListener'];
2141
+ element: HTMLElement;
2142
+ }) => void;
1353
2143
  };
1354
- type NullableElementDimensions = {
1355
- [K in keyof ElementDimensions]: ElementDimensions[K] | null;
2144
+ declare const createProps: (props: CreatePropsOptions) => Props;
2145
+ type HostProps = {
2146
+ props: Props;
2147
+ handlers: PropHandlers;
1356
2148
  };
1357
- declare const signalElementDimensions: (el: SignalElementBindingType) => _angular_core.Signal<NullableElementDimensions>;
1358
- declare const signalHostElementDimensions: () => _angular_core.Signal<NullableElementDimensions>;
2149
+ declare const createHostProps: (props: CreatePropsOptions) => HostProps;
1359
2150
 
1360
- type SignalElementIntersectionOptions = Omit<IntersectionObserverInit, 'root'> & {
1361
- root?: SignalElementBindingType;
1362
- enabled?: Signal<boolean>;
1363
- };
1364
- type IntersectionObserverEntryWithDetails = IntersectionObserverEntry & {
1365
- isAbove: boolean;
1366
- isBelow: boolean;
1367
- isLeft: boolean;
1368
- isRight: boolean;
1369
- isVisible: boolean;
1370
- };
1371
- declare const signalElementIntersection: (el: SignalElementBindingType, options?: SignalElementIntersectionOptions) => Signal<IntersectionObserverEntryWithDetails[]>;
1372
- declare const signalHostElementIntersection: (options?: SignalElementIntersectionOptions) => Signal<IntersectionObserverEntryWithDetails[]>;
2151
+ declare const createSetup: <T extends Record<string, unknown>>(config: {
2152
+ setupFn: (params: T) => void;
2153
+ this: ThisType<unknown>;
2154
+ }) => (params: T) => void;
1373
2155
 
1374
- declare const signalElementMutations: (el: SignalElementBindingType, options?: MutationObserverInit) => _angular_core.Signal<MutationRecord | null>;
1375
- declare const signalHostElementMutations: (options?: MutationObserverInit) => _angular_core.Signal<MutationRecord | null>;
2156
+ declare const createDependencyStash: <T extends Record<string, WritableSignal<unknown>>>(stash: T) => T & {
2157
+ provideSignal: <K extends keyof T>(data: {
2158
+ signal: Signal<ReturnType<T[K]>>;
2159
+ for: K;
2160
+ }) => void;
2161
+ provideValue: <K extends keyof T>(data: {
2162
+ value: ReturnType<T[K]>;
2163
+ for: K;
2164
+ }) => void;
2165
+ };
1376
2166
 
1377
- type ElementLastScrollDirectionType = 'up' | 'down' | 'left' | 'right';
1378
- type ElementLastScrollDirection = {
1379
- type: ElementLastScrollDirectionType;
1380
- time: number;
2167
+ declare const createElementDictionary: () => {
2168
+ ids: _angular_core.Signal<string[]>;
2169
+ elements: _angular_core.Signal<HTMLElement[]>;
2170
+ has: (id: string) => boolean;
2171
+ get: (id: string) => HTMLElement | null;
2172
+ push: (id: string, element: HTMLElement) => void;
2173
+ remove: (id: string) => void;
2174
+ isEmpty: _angular_core.Signal<boolean>;
2175
+ firstElement: _angular_core.Signal<HTMLElement | null>;
2176
+ firstId: _angular_core.Signal<string | null>;
1381
2177
  };
1382
- declare const signalElementLastScrollDirection: (el: SignalElementBindingType) => _angular_core.Signal<ElementLastScrollDirection | null>;
1383
- declare const signalHostElementLastScrollDirection: () => _angular_core.Signal<ElementLastScrollDirection | null>;
1384
2178
 
1385
- type SignalElementScrollStateOptions = {
1386
- /** The initial scroll position to scroll to. Once a truthy value get's emitted, all further values will be ignored. */
1387
- initialScrollPosition?: Signal<ScrollToOptions | null>;
2179
+ type BindPropsOptions = {
2180
+ props: Props | PropsInternal;
2181
+ handlers: PropHandlers;
1388
2182
  };
1389
- type ElementScrollState = {
1390
- canScroll: boolean;
1391
- canScrollHorizontally: boolean;
1392
- canScrollVertically: boolean;
1393
- elementDimensions: NullableElementDimensions;
2183
+ declare const bindProps: (config: BindPropsOptions) => void;
2184
+ type UnbindPropsOptions = {
2185
+ props: Props | PropsInternal;
2186
+ handlers: PropHandlers;
1394
2187
  };
1395
- declare const areScrollStatesEqual: (a: ElementScrollState, b: ElementScrollState) => boolean;
1396
- declare const signalElementScrollState: (el: SignalElementBindingType, options?: SignalElementScrollStateOptions) => Signal<ElementScrollState>;
1397
- declare const signalHostElementScrollState: () => Signal<ElementScrollState>;
1398
-
1399
- /** Inject a signal containing a boolean value indicating if the viewport is xs */
1400
- declare const injectIsXs: () => _angular_core.Signal<boolean>;
1401
- /** Inject a signal containing a boolean value indicating if the viewport is sm */
1402
- declare const injectIsSm: () => _angular_core.Signal<boolean>;
1403
- /** Inject a signal containing a boolean value indicating if the viewport is md */
1404
- declare const injectIsMd: () => _angular_core.Signal<boolean>;
1405
- /** Inject a signal containing a boolean value indicating if the viewport is lg */
1406
- declare const injectIsLg: () => _angular_core.Signal<boolean>;
1407
- /** Inject a signal containing a boolean value indicating if the viewport is xl */
1408
- declare const injectIsXl: () => _angular_core.Signal<boolean>;
1409
- /** Inject a signal containing a boolean value indicating if the viewport is 2xl */
1410
- declare const injectIs2Xl: () => _angular_core.Signal<boolean>;
1411
- /**
1412
- * Inject a boolean value indicating if the viewport is matching the provided options.
1413
- * This value is not reactive. If you want to react to changes, use the {@link injectObserveBreakpoint} function instead.
1414
- */
1415
- declare const injectBreakpointIsMatched: (options: BuildMediaQueryOptions) => boolean;
1416
- /**
1417
- * Inject a boolean value indicating if the media query is matched.
1418
- * This value is not reactive. If you want to react to changes, use the {@link injectObserveMediaQuery} function instead.
1419
- */
1420
- declare const injectMediaQueryIsMatched: (mediaQuery: string) => boolean;
1421
- /**
1422
- * Inject a signal containing a boolean value indicating if the viewport is matching the provided options.
1423
- */
1424
- declare const injectObserveBreakpoint: (options: BuildMediaQueryOptions) => _angular_core.Signal<boolean>;
1425
- /**
1426
- * Inject a signal containing a boolean value indicating if the media query is matched.
1427
- */
1428
- declare const injectObserveMediaQuery: (mediaQuery: string) => _angular_core.Signal<boolean>;
1429
- /** Inject a signal containing the current breakpoint. */
1430
- declare const injectCurrentBreakpoint: () => _angular_core.Signal<"xs" | "sm" | "md" | "lg" | "xl" | "2xl">;
1431
- /** Inject a signal that indicates if the user is using a portrait display */
1432
- declare const injectIsPortrait: () => _angular_core.Signal<boolean>;
1433
- /** Inject a signal that indicates if the user is using a landscape display */
1434
- declare const injectIsLandscape: () => _angular_core.Signal<boolean>;
1435
- /** Inject a signal containing the current display orientation */
1436
- declare const injectDisplayOrientation: () => _angular_core.Signal<"portrait" | "landscape">;
1437
- /** Inject a signal that indicates if the device has a touch input */
1438
- declare const injectHasTouchInput: () => _angular_core.Signal<boolean>;
1439
- /** Inject a signal that indicates if the device has a fine input (mouse or stylus) */
1440
- declare const injectHasPrecisionInput: () => _angular_core.Signal<boolean>;
1441
- /** Inject a signal containing the current device input type */
1442
- declare const injectDeviceInputType: () => _angular_core.Signal<"touch" | "mouse">;
1443
- /** Inject a signal containing a boolean value indicating if the user can hover (eg. using a mouse) */
1444
- declare const injectCanHover: () => _angular_core.Signal<boolean>;
1445
- /** Inject a signal containing the viewport dimensions */
1446
- declare const injectViewportDimensions: () => _angular_core.Signal<_ethlete_core.NullableElementDimensions>;
1447
- /** Inject a signal containing the scrollbar dimensions. Dimensions will be 0 if scrollbars overlap the page contents (like on mobile). */
1448
- declare const injectScrollbarDimensions: () => _angular_core.Signal<{
1449
- width: number;
1450
- height: number;
1451
- } | null>;
2188
+ declare const unbindProps: (config: UnbindPropsOptions) => void;
1452
2189
 
1453
- /**
1454
- * Applies scrollbar size CSS variables to the documentElement (html tag) in pixels.
1455
- * - `--et-sw`: scrollbar width
1456
- * - `--et-sh`: scrollbar height
1457
- */
1458
- declare const writeScrollbarSizeToCssVariables: () => void;
1459
- /**
1460
- * Applies viewport size CSS variables to the documentElement (html tag) in pixels.
1461
- * - `--et-vw`: viewport width excluding scrollbar width
1462
- * - `--et-vh`: viewport height excluding scrollbar height
1463
- */
1464
- declare const writeViewportSizeToCssVariables: () => void;
2190
+ declare class PropsDirective {
2191
+ private destroyRef;
2192
+ props: _angular_core.InputSignalWithTransform<PropsInternal, Readonly<{
2193
+ attached: _angular_core.Signal<boolean>;
2194
+ attachedElements: _ethlete_core.PropsAttachedElements;
2195
+ }>>;
2196
+ propHandlers: {
2197
+ classes: {
2198
+ remove: (tokens: string) => void;
2199
+ removeMany: (tokens: string[]) => void;
2200
+ has: (tokens: string) => boolean;
2201
+ push: (tokens: string, signal: _angular_core.Signal<unknown>) => void;
2202
+ pushMany: (map: Record<string, _angular_core.Signal<unknown>>) => void;
2203
+ };
2204
+ attributes: {
2205
+ remove: (tokens: string) => void;
2206
+ removeMany: (tokens: string[]) => void;
2207
+ has: (tokens: string) => boolean;
2208
+ push: (tokens: string, signal: _angular_core.Signal<unknown>) => void;
2209
+ pushMany: (map: Record<string, _angular_core.Signal<unknown>>) => void;
2210
+ };
2211
+ styles: {
2212
+ remove: (tokens: string) => void;
2213
+ removeMany: (tokens: string[]) => void;
2214
+ has: (tokens: string) => boolean;
2215
+ push: (tokens: string, signal: _angular_core.Signal<unknown>) => void;
2216
+ pushMany: (map: Record<string, _angular_core.Signal<unknown>>) => void;
2217
+ };
2218
+ id: string;
2219
+ elementRef: _angular_core.ElementRef<HTMLElement>;
2220
+ };
2221
+ constructor();
2222
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<PropsDirective, never>;
2223
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<PropsDirective, "[etProps]", never, { "props": { "alias": "etProps"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
2224
+ }
1465
2225
 
1466
- type CursorDragScrollDirection = 'horizontal' | 'vertical' | 'both';
1467
- type CursorDragScrollOptions = {
1468
- /** If true, cursor drag scrolling will be enabled. */
1469
- enabled?: Signal<boolean>;
1470
- /** The allowed scroll direction. */
1471
- allowedDirection?: MaybeSignal<CursorDragScrollDirection>;
2226
+ type ComponentType<T> = new (...args: any[]) => T;
2227
+ type AnyTemplateType = string | TemplateRef<unknown> | ComponentType<unknown> | TemplateRefWithContext | ComponentTypeWithInputs;
2228
+ type TemplateRefWithContext<T = Record<string, unknown> | undefined, J = unknown> = {
2229
+ template: TemplateRef<J>;
2230
+ context?: T;
2231
+ injector?: Injector;
1472
2232
  };
1473
- /** A function to apply cursor drag scroll behavior to an element. */
1474
- declare const useCursorDragScroll: (el: SignalElementBindingType, options?: CursorDragScrollOptions) => {
1475
- isDragging: Signal<boolean>;
1476
- currentDragAmount: Signal<{
1477
- x: number;
1478
- y: number;
1479
- }>;
2233
+ type ComponentTypeWithInputs<T = Record<string, unknown> | undefined, J = unknown> = {
2234
+ component: ComponentType<J>;
2235
+ inputs?: T;
2236
+ injector?: Injector;
2237
+ };
2238
+ type StringTemplate = {
2239
+ type: 'string';
2240
+ value: string;
2241
+ };
2242
+ type NgTemplateTemplate = {
2243
+ type: 'template';
2244
+ value: TemplateRef<unknown>;
2245
+ context?: Record<string, unknown>;
2246
+ injector: Injector | null;
2247
+ };
2248
+ type ComponentTemplate = {
2249
+ type: 'component';
2250
+ value: ComponentType<unknown>;
2251
+ inputs?: Record<string, unknown>;
2252
+ injector: Injector | null;
1480
2253
  };
2254
+ declare const templateComputed: (templateSignal: Signal<AnyTemplateType | null>) => Signal<StringTemplate | NgTemplateTemplate | ComponentTemplate | null>;
1481
2255
 
1482
- type SetupScrollRestorationConfig = {
2256
+ type ResizeEdge = 'n' | 's' | 'e' | 'w' | 'ne' | 'nw' | 'se' | 'sw';
2257
+ type ResizeMoveEvent = {
2258
+ edge: ResizeEdge;
2259
+ /** Cumulative delta from the pointerdown position. */
2260
+ dx: number;
2261
+ dy: number;
2262
+ clientX: number;
2263
+ clientY: number;
2264
+ };
2265
+ declare class ResizeHandlesComponent {
2266
+ edges: _angular_core.InputSignal<ResizeEdge[]>;
2267
+ disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
2268
+ private gestureStart$;
2269
+ private gesture$;
2270
+ resizeStarted: _angular_core.OutputRef<ResizeEdge>;
2271
+ resizeMoved: _angular_core.OutputRef<ResizeMoveEvent>;
2272
+ resizeEnded: _angular_core.OutputRef<void>;
2273
+ isResizing: _angular_core.Signal<boolean>;
2274
+ activeEdge: _angular_core.Signal<ResizeEdge | null>;
2275
+ readonly edgeCursors: Record<ResizeEdge, string>;
2276
+ startResizeGesture(event: PointerEvent, edge: ResizeEdge): void;
2277
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ResizeHandlesComponent, never>;
2278
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<ResizeHandlesComponent, "et-resize-handles", never, { "edges": { "alias": "edges"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "resizeStarted": "resizeStarted"; "resizeMoved": "resizeMoved"; "resizeEnded": "resizeEnded"; }, never, never, true, never>;
2279
+ }
2280
+
2281
+ declare const elementCanScroll: (element?: HTMLElement | null, direction?: "x" | "y") => boolean;
2282
+ type IsElementVisibleOptions = {
1483
2283
  /**
1484
- * The scrollable container.
1485
- * @default document.documentElement
2284
+ * The element to check if it is visible inside a container.
1486
2285
  */
1487
- scrollElement?: HTMLElement;
2286
+ element?: HTMLElement | null;
1488
2287
  /**
1489
- * A list of query params that should trigger a scroll to top.
1490
- * @default []
1491
- * @example ['page'] // will scroll to top when the page query param changes
2288
+ * The container to check if the element is visible inside.
2289
+ * If null or undefined, uses the viewport as the container.
2290
+ * @default null (viewport)
1492
2291
  */
1493
- queryParamTriggerList?: string[];
2292
+ container?: HTMLElement | null;
1494
2293
  /**
1495
- * Config for fragment scrolling.
2294
+ * The container's rect to check if the element is visible inside. Can be supplied to reduce the amount of DOM reads.
2295
+ * Only used when container is provided and not null.
2296
+ * @default container.getBoundingClientRect()
1496
2297
  */
1497
- fragment?: {
1498
- /**
1499
- * Enable fragment scrolling (scroll to element with id)
1500
- * @default false
1501
- */
1502
- enabled?: boolean;
1503
- /**
1504
- * Whether to use smooth scrolling or not.
1505
- * @default false
1506
- */
1507
- smooth?: boolean;
1508
- };
2298
+ containerRect?: DOMRect | null;
2299
+ /**
2300
+ * The element's rect. Can be supplied to reduce the amount of DOM reads.
2301
+ * @default element.getBoundingClientRect()
2302
+ */
2303
+ elementRect?: DOMRect | null;
1509
2304
  };
1510
- declare const ET_DISABLE_SCROLL_TOP: unique symbol;
1511
- declare const ET_DISABLE_SCROLL_TOP_AS_RETURN_ROUTE: unique symbol;
1512
- declare const ET_DISABLE_SCROLL_TOP_ON_PATH_PARAM_CHANGE: unique symbol;
1513
- type RouterDisableScrollTopConfig = {
2305
+ type CurrentElementVisibility = {
1514
2306
  /**
1515
- * Whether to disable scroll to top ONLY when navigating back to this route.
1516
- * @default false
2307
+ * Whether the element is visible in the inline direction.
1517
2308
  */
1518
- asReturnRoute?: boolean;
2309
+ inline: boolean;
1519
2310
  /**
1520
- * Whether to disable scroll to top when a path param changes.
1521
- * @default false
2311
+ * Whether the element is visible in the block direction.
1522
2312
  */
1523
- onPathParamChange?: boolean;
1524
- };
1525
- declare const routerDisableScrollTop: (config?: RouterDisableScrollTopConfig) => {
1526
- [ET_DISABLE_SCROLL_TOP_ON_PATH_PARAM_CHANGE]?: boolean | undefined;
1527
- [ET_DISABLE_SCROLL_TOP]: boolean;
1528
- } | {
1529
- [ET_DISABLE_SCROLL_TOP_ON_PATH_PARAM_CHANGE]?: boolean | undefined;
1530
- [ET_DISABLE_SCROLL_TOP_AS_RETURN_ROUTE]: boolean;
1531
- };
1532
- declare const setupScrollRestoration: (config?: SetupScrollRestorationConfig) => void;
1533
-
1534
- declare const signalIsRendered: () => _angular_core.Signal<boolean>;
1535
- declare const createIsRenderedSignal: () => {
1536
- state: _angular_core.WritableSignal<boolean>;
1537
- bind: () => _angular_core.EffectRef;
1538
- };
1539
- declare const createCanAnimateSignal: () => {
1540
- state: _angular_core.Signal<boolean>;
1541
- };
1542
-
1543
- type RouterState = {
1544
- data: Data;
1545
- pathParams: Params;
1546
- queryParams: Params;
1547
- title: string | null;
1548
- fragment: string | null;
1549
- };
1550
- declare const ET_PROPERTY_REMOVED: unique symbol;
1551
- type InjectUtilConfig = {
1552
- /** The injector to use for the injection. Must be provided if the function is not called from within a injection context. */
1553
- injector?: Injector;
1554
- };
1555
- type InjectUtilTransformConfig<In, Out> = {
2313
+ block: boolean;
1556
2314
  /**
1557
- * A transform function similar to the `transform` function in Angular input bindings.
1558
- * Can be used to transform the value before it is returned.
1559
- * E.g. transforming `"true"` to `true` for a boolean attribute.
2315
+ * The percentage of the element that is visible in the inline direction.
1560
2316
  */
1561
- transform?: (value: In) => Out;
2317
+ inlineIntersection: number;
2318
+ /**
2319
+ * The percentage of the element that is visible in the block direction.
2320
+ */
2321
+ blockIntersection: number;
2322
+ /**
2323
+ * Whether the element is intersecting the container.
2324
+ */
2325
+ isIntersecting: boolean;
2326
+ /**
2327
+ * The ratio of the element that is intersecting the container.
2328
+ */
2329
+ intersectionRatio: number;
2330
+ /**
2331
+ * The element that is being checked for visibility.
2332
+ */
2333
+ element: HTMLElement;
2334
+ /**
2335
+ * The container's rect used for the calculation.
2336
+ */
2337
+ containerRect: DOMRect;
2338
+ /**
2339
+ * The element's rect used for the calculation.
2340
+ */
2341
+ elementRect: DOMRect;
1562
2342
  };
1563
- declare const transformOrReturn: <In, Out>(src: Signal<In>, config?: InjectUtilTransformConfig<In, Out>) => Signal<Out>;
1564
- /** Inject the current router event */
1565
- declare const injectRouterEvent: () => Signal<Event$1>;
1566
- /**
1567
- * Signal that indicates whether the router has been initialized.
1568
- * The router is considered initialized once the first NavigationEnd event with an id different than -1 has been emitted.
1569
- */
1570
- declare const injectIsRouterInitialized: () => Signal<boolean>;
1571
- /**
1572
- * Inject the current url.
1573
- * The url includes query params as well as the fragment. Use `injectRoute` instead if you are not intrusted in those.
1574
- * @example "/my-page?query=1&param=true#fragment"
1575
- */
1576
- declare const injectUrl: () => Signal<string>;
1577
- /**
1578
- * Inject the current route
1579
- * @example "/my-page"
1580
- */
1581
- declare const injectRoute: () => Signal<string>;
1582
- /**
1583
- * Inject the complete router state. This includes the current route data, path params, query params, title and fragment.
1584
- */
1585
- declare const injectRouterState: () => Signal<RouterState>;
1586
- /** Inject a signal containing the current route fragment (the part after the # inside the url if present) */
1587
- declare const injectFragment: <T = string | null>(config?: InjectUtilConfig & InjectUtilTransformConfig<string | null, T>) => Signal<T>;
1588
- /** Inject all currently available query parameters as a signal */
1589
- declare const injectQueryParams: () => Signal<Params>;
1590
- /** Inject all currently available route data as a signal */
1591
- declare const injectRouteData: () => Signal<Data>;
1592
- /** Inject the current route title as a signal */
1593
- declare const injectRouteTitle: <T = string | null>(config?: InjectUtilTransformConfig<string | null, T>) => Signal<T>;
1594
- /** Inject all currently available path parameters as a signal */
1595
- declare const injectPathParams: () => Signal<Params>;
1596
- type InjectQueryParamConfig<T> = InjectUtilTransformConfig<string | null, T> & {
2343
+ declare const isElementVisible: (options: IsElementVisibleOptions) => CurrentElementVisibility | null;
2344
+ declare const getElementScrollCoordinates: (options: ScrollToElementOptions) => ScrollToOptions;
2345
+ type ScrollToElementOptions = {
1597
2346
  /**
1598
- * If true, the initial value will be read from the browser's url.
1599
- * Note that this will not work with arrays or complex objects.
2347
+ * The element to scroll to.
1600
2348
  */
1601
- requireSync?: boolean;
2349
+ element?: HTMLElement | null;
2350
+ /**
2351
+ * The scroll container to scroll to the element in.
2352
+ * Must be provided - cannot scroll the viewport programmatically with this function.
2353
+ */
2354
+ container?: HTMLElement | null;
2355
+ /**
2356
+ * The direction to scroll in.
2357
+ * @default 'both'
2358
+ */
2359
+ direction?: 'inline' | 'block' | 'both';
2360
+ /**
2361
+ * The origin of the element to scroll to.
2362
+ * @default 'nearest'
2363
+ */
2364
+ origin?: 'start' | 'end' | 'center' | 'nearest';
2365
+ /**
2366
+ * The scroll behavior.
2367
+ * @default 'smooth'
2368
+ */
2369
+ behavior?: ScrollBehavior;
2370
+ /**
2371
+ * The scroll inline-margin
2372
+ * @default 0
2373
+ */
2374
+ scrollInlineMargin?: number;
2375
+ /**
2376
+ * The scroll block-margin
2377
+ * @default 0
2378
+ */
2379
+ scrollBlockMargin?: number;
1602
2380
  };
1603
- /** Inject a specific query parameter as a signal */
1604
- declare const injectQueryParam: <T = string | null>(key: string, config?: InjectQueryParamConfig<T>) => Signal<T>;
1605
- /** Inject a specific route data item as a signal */
1606
- declare const injectRouteDataItem: <T = unknown>(key: string, config?: InjectUtilTransformConfig<unknown, T>) => Signal<T>;
1607
- /** Inject a specific path parameter as a signal */
1608
- declare const injectPathParam: <T = string | null>(key: string, config?: InjectUtilTransformConfig<string | null, T>) => Signal<T>;
2381
+ declare const scrollToElement: (options: ScrollToElementOptions) => void;
2382
+
2383
+ type ScrollSnapOrigin = 'auto' | 'start' | 'center' | 'end';
2384
+ type ScrollSnapTarget = {
2385
+ /** The element to snap to. */
2386
+ element: HTMLElement;
2387
+ /** The resolved alignment to use when scrolling to the element. */
2388
+ origin: 'start' | 'center' | 'end';
2389
+ } | null;
2390
+ declare const getScrollSnapTarget: (items: HTMLElement[], container: HTMLElement, direction: "horizontal" | "vertical", origin: ScrollSnapOrigin, margin?: number) => ScrollSnapTarget;
2391
+ type ScrollContainerTarget = {
2392
+ element: HTMLElement;
2393
+ origin: 'start' | 'end';
2394
+ } | null;
2395
+ declare const getScrollContainerTarget: (entries: IntersectionObserverEntry[], direction: "start" | "end") => ScrollContainerTarget;
2396
+ type ScrollItemTarget = {
2397
+ element: HTMLElement;
2398
+ index: number;
2399
+ origin: 'start' | 'end' | 'center';
2400
+ } | null;
2401
+ declare const getScrollItemTarget: (entries: IntersectionObserverEntry[], container: HTMLElement, direction: "start" | "end", scrollOrigin: "auto" | "center" | "start" | "end", axisDirection: "horizontal" | "vertical") => ScrollItemTarget;
2402
+
1609
2403
  /**
1610
- * Inject query params that changed during navigation. Unchanged query params will be ignored.
1611
- * Removed query params will be represented by the symbol `ET_PROPERTY_REMOVED`.
2404
+ * Something drawn on top of the site's favicon.
2405
+ *
2406
+ * - `dot` - a filled badge punched into the bottom-right corner, the "something happened here" marker.
2407
+ * - `progress` - a ring around the icon, `value` in percent (`0`–`100`). The browser exposes no
2408
+ * taskbar/tab progress API, so a favicon ring (or a percentage in the title) is as close as the web
2409
+ * gets to one.
1612
2410
  */
1613
- declare const injectQueryParamChanges: () => Signal<Record<string, unknown>>;
2411
+ type FaviconOverlay = {
2412
+ kind: 'dot';
2413
+ color?: string;
2414
+ } | {
2415
+ kind: 'progress';
2416
+ value: number;
2417
+ color?: string;
2418
+ trackColor?: string;
2419
+ };
1614
2420
  /**
1615
- * Inject path params that changed during navigation. Unchanged path params will be ignored.
1616
- * Removed path params will be represented by the symbol `ET_PROPERTY_REMOVED`.
2421
+ * Owns the `<link rel="icon">` href so overlays can be drawn onto the site's favicon and taken back
2422
+ * off again. The original href is captured on first use and restored once the last overlay is gone.
2423
+ *
2424
+ * Registrations are keyed, and a `progress` overlay wins over a `dot` - a ring that also carries a
2425
+ * badge reads as neither.
1617
2426
  */
1618
- declare const injectPathParamChanges: () => Signal<Record<string, unknown>>;
2427
+ declare const provideFaviconStore: () => _angular_core.Provider[];
2428
+ declare const injectFaviconStore: _ethlete_core.InjectFn<{
2429
+ activeOverlay: _angular_core.Signal<FaviconOverlay | null>;
2430
+ addOverlay: (id: symbol, overlay: FaviconOverlay) => void;
2431
+ removeOverlay: (id: symbol) => void;
2432
+ }>;
2433
+ /**
2434
+ * Draw an overlay on the site's favicon while the binding has a value - an unsaved-changes dot, an
2435
+ * upload's progress ring. The favicon is restored when the binding goes empty or the injector is
2436
+ * destroyed. No-op during SSR.
2437
+ *
2438
+ * ```ts
2439
+ * applyFaviconOverlay(computed(() => (this.saving() ? { kind: 'progress', value: this.percent() } : null)));
2440
+ * ```
2441
+ */
2442
+ declare const applyFaviconOverlay: (binding: MaybeSignal<FaviconOverlay | null | undefined>) => void;
1619
2443
 
1620
2444
  type HeadBinding<T> = {
1621
2445
  id: symbol;
@@ -1626,7 +2450,7 @@ declare const applyHeadBinding: <T>(binding: MaybeSignal<T | null | undefined>,
1626
2450
  declare const createPropertyBinding: <TConfig>(configBuilder: (value: string) => TConfig, applyConfigFn: (config: MaybeSignal<TConfig | null | undefined>) => void) => (binding: MaybeSignal<string | null | undefined>) => void;
1627
2451
  declare const createArrayPropertyBinding: <TConfig>(configBuilder: (value: string, index: number) => TConfig, applyConfigFn: (config: MaybeSignal<TConfig | null | undefined>) => void) => (binding: MaybeSignal<string[] | null | undefined>) => void;
1628
2452
  declare const toStringBinding: (binding: MaybeSignal<string | number | null | undefined>) => MaybeSignal<string | null | undefined>;
1629
- declare const createBulkPropertyBinding: <TConfig extends Record<string, unknown>>(propertyPrefix: string, applyConfigFn: (property: string, binding: MaybeSignal<string | null | undefined>) => void) => (config: TConfig) => void;
2453
+ declare const createBulkPropertyBinding: <TConfig extends Record<string, unknown>>(_propertyPrefix: string, applyConfigFn: (property: string, binding: MaybeSignal<string | null | undefined>) => void) => (config: TConfig) => void;
1630
2454
 
1631
2455
  type Context = {
1632
2456
  '@context': 'https://schema.org';
@@ -1792,33 +2616,13 @@ type LinkStoreConfig = {
1792
2616
  };
1793
2617
  declare const DEFAULT_MULTI_INSTANCE_RELS: Set<string>;
1794
2618
  declare const provideLinkStoreConfig: (valueOverride?: Partial<LinkStoreConfig> | undefined) => _angular_core.Provider[];
1795
- declare const injectLinkStoreConfig: {
1796
- (): LinkStoreConfig;
1797
- (options: _angular_core.InjectOptions & {
1798
- optional?: false;
1799
- }): LinkStoreConfig;
1800
- (options: _angular_core.InjectOptions): LinkStoreConfig | null;
1801
- };
2619
+ declare const injectLinkStoreConfig: _ethlete_core.InjectFn<LinkStoreConfig>;
1802
2620
  declare const provideLinkStore: () => _angular_core.Provider[];
1803
- declare const injectLinkStore: {
1804
- (): {
1805
- addLink: (id: symbol, linkConfig: LinkConfig) => void;
1806
- removeLink: (id: symbol, key?: string) => void;
1807
- getLinkKey: (linkConfig: LinkConfig) => string;
1808
- };
1809
- (options: _angular_core.InjectOptions & {
1810
- optional?: false;
1811
- }): {
1812
- addLink: (id: symbol, linkConfig: LinkConfig) => void;
1813
- removeLink: (id: symbol, key?: string) => void;
1814
- getLinkKey: (linkConfig: LinkConfig) => string;
1815
- };
1816
- (options: _angular_core.InjectOptions): {
1817
- addLink: (id: symbol, linkConfig: LinkConfig) => void;
1818
- removeLink: (id: symbol, key?: string) => void;
1819
- getLinkKey: (linkConfig: LinkConfig) => string;
1820
- } | null;
1821
- };
2621
+ declare const injectLinkStore: _ethlete_core.InjectFn<{
2622
+ addLink: (id: symbol, linkConfig: LinkConfig) => void;
2623
+ removeLink: (id: symbol, key?: string) => void;
2624
+ getLinkKey: (linkConfig: LinkConfig) => string;
2625
+ }>;
1822
2626
  declare const applyLinkBinding: (binding: MaybeSignal<LinkConfig | null | undefined>) => void;
1823
2627
  declare const applyCanonicalBinding: (binding: MaybeSignal<string | null | undefined>) => void;
1824
2628
  declare const applyAlternateBinding: (hreflang: string, binding: MaybeSignal<string | null | undefined>) => void;
@@ -1877,33 +2681,13 @@ type MetaConfig = {
1877
2681
  };
1878
2682
  declare const DEFAULT_MULTI_INSTANCE_TAGS: Set<string>;
1879
2683
  declare const provideMetaConfig: (valueOverride?: Partial<MetaConfig> | undefined) => _angular_core.Provider[];
1880
- declare const injectMetaConfig: {
1881
- (): MetaConfig;
1882
- (options: _angular_core.InjectOptions & {
1883
- optional?: false;
1884
- }): MetaConfig;
1885
- (options: _angular_core.InjectOptions): MetaConfig | null;
1886
- };
2684
+ declare const injectMetaConfig: _ethlete_core.InjectFn<MetaConfig>;
1887
2685
  declare const provideMetaStore: () => _angular_core.Provider[];
1888
- declare const injectMetaStore: {
1889
- (): {
1890
- addTag: (id: symbol, rawConfig: MetaTagConfig) => void;
1891
- removeTag: (id: symbol, selector?: string) => void;
1892
- getSelector: (config: MetaTagConfig) => string;
1893
- };
1894
- (options: _angular_core.InjectOptions & {
1895
- optional?: false;
1896
- }): {
1897
- addTag: (id: symbol, rawConfig: MetaTagConfig) => void;
1898
- removeTag: (id: symbol, selector?: string) => void;
1899
- getSelector: (config: MetaTagConfig) => string;
1900
- };
1901
- (options: _angular_core.InjectOptions): {
1902
- addTag: (id: symbol, rawConfig: MetaTagConfig) => void;
1903
- removeTag: (id: symbol, selector?: string) => void;
1904
- getSelector: (config: MetaTagConfig) => string;
1905
- } | null;
1906
- };
2686
+ declare const injectMetaStore: _ethlete_core.InjectFn<{
2687
+ addTag: (id: symbol, rawConfig: MetaTagConfig) => void;
2688
+ removeTag: (id: symbol, selector?: string) => void;
2689
+ getSelector: (config: MetaTagConfig) => string;
2690
+ }>;
1907
2691
  declare const applyMetaBinding: (binding: MaybeSignal<MetaTagConfig | null | undefined>) => void;
1908
2692
  declare const applyDescriptionBinding: (binding: MaybeSignal<string | null | undefined>) => void;
1909
2693
  declare const applyKeywordsBinding: (binding: MaybeSignal<string[] | null | undefined>) => void;
@@ -1985,78 +2769,6 @@ type SocialMediaConfig = {
1985
2769
  };
1986
2770
  declare const applySocialMediaBindings: (config: SocialMediaConfig) => void;
1987
2771
 
1988
- type MaybeObservable<T> = T | Observable<T>;
1989
- type SeoConfig = {
1990
- title?: MaybeObservable<string>;
1991
- description?: MaybeObservable<string>;
1992
- keywords?: MaybeObservable<string[]>;
1993
- icon?: MaybeObservable<string>;
1994
- themeColor?: MaybeObservable<string>;
1995
- colorScheme?: MaybeObservable<'light' | 'dark'>;
1996
- robots?: MaybeObservable<string>;
1997
- canonical?: MaybeObservable<string>;
1998
- alternate?: MaybeObservable<AlternateLink>[];
1999
- og?: MaybeObservable<OpenGraph>;
2000
- twitter?: MaybeObservable<TwitterCard>;
2001
- facebook?: MaybeObservable<FacebookCard>;
2002
- [key: string]: MaybeObservable<unknown>;
2003
- };
2004
- type AlternateLink = {
2005
- href: string;
2006
- hreflang: string;
2007
- };
2008
- type OpenGraph = {
2009
- title?: MaybeObservable<string>;
2010
- description?: MaybeObservable<string>;
2011
- type?: MaybeObservable<string>;
2012
- url?: MaybeObservable<string>;
2013
- image?: MaybeObservable<string>;
2014
- siteName?: MaybeObservable<string>;
2015
- locale?: MaybeObservable<string>;
2016
- localeAlternate?: MaybeObservable<string[]>;
2017
- };
2018
- type TwitterCard = {
2019
- card?: MaybeObservable<string>;
2020
- site?: MaybeObservable<string>;
2021
- creator?: MaybeObservable<string>;
2022
- title?: MaybeObservable<string>;
2023
- description?: MaybeObservable<string>;
2024
- image?: MaybeObservable<string>;
2025
- imageAlt?: MaybeObservable<string>;
2026
- };
2027
- type FacebookCard = {
2028
- title?: MaybeObservable<string>;
2029
- description?: MaybeObservable<string>;
2030
- image?: MaybeObservable<string>;
2031
- imageAlt?: MaybeObservable<string>;
2032
- type?: MaybeObservable<string>;
2033
- url?: MaybeObservable<string>;
2034
- siteName?: MaybeObservable<string>;
2035
- locale?: MaybeObservable<string>;
2036
- localeAlternate?: MaybeObservable<string[]>;
2037
- };
2038
-
2039
- declare const SEO_DIRECTIVE_TOKEN: InjectionToken<SeoDirective>;
2040
- /** @deprecated use binding utils instead */
2041
- declare class SeoDirective implements OnInit, OnDestroy {
2042
- private readonly _metaService;
2043
- private readonly _titleService;
2044
- private readonly _onDeactivate$;
2045
- private _isDeactivated;
2046
- readonly parent: SeoDirective | null;
2047
- get config(): SeoConfig;
2048
- private _config;
2049
- ngOnInit(): void;
2050
- ngOnDestroy(): void;
2051
- updateConfig(config: SeoConfig): void;
2052
- _activate(): void;
2053
- _deactivate(): void;
2054
- private _update;
2055
- private _cleanUp;
2056
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<SeoDirective, never>;
2057
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<SeoDirective, never, never, {}, {}, never, never, true, never>;
2058
- }
2059
-
2060
2772
  type StructuredDataConfig = {
2061
2773
  /**
2062
2774
  * Where to place the JSON-LD script tag.
@@ -2071,30 +2783,12 @@ type StructuredDataConfig = {
2071
2783
  placement: 'head' | 'body';
2072
2784
  };
2073
2785
  declare const provideStructuredDataConfig: (valueOverride?: Partial<StructuredDataConfig> | undefined) => _angular_core.Provider[];
2074
- declare const injectStructuredDataConfig: {
2075
- (): StructuredDataConfig;
2076
- (options: _angular_core.InjectOptions & {
2077
- optional?: false;
2078
- }): StructuredDataConfig;
2079
- (options: _angular_core.InjectOptions): StructuredDataConfig | null;
2080
- };
2786
+ declare const injectStructuredDataConfig: _ethlete_core.InjectFn<StructuredDataConfig>;
2081
2787
  declare const provideStructuredDataStore: () => _angular_core.Provider[];
2082
- declare const injectStructuredDataStore: {
2083
- (): {
2084
- addStructuredData: (id: symbol, data: WithContext<Thing> | Graph) => void;
2085
- removeStructuredData: (id: symbol) => void;
2086
- };
2087
- (options: _angular_core.InjectOptions & {
2088
- optional?: false;
2089
- }): {
2090
- addStructuredData: (id: symbol, data: WithContext<Thing> | Graph) => void;
2091
- removeStructuredData: (id: symbol) => void;
2092
- };
2093
- (options: _angular_core.InjectOptions): {
2094
- addStructuredData: (id: symbol, data: WithContext<Thing> | Graph) => void;
2095
- removeStructuredData: (id: symbol) => void;
2096
- } | null;
2097
- };
2788
+ declare const injectStructuredDataStore: _ethlete_core.InjectFn<{
2789
+ addStructuredData: (id: symbol, data: WithContext<Thing> | Graph) => void;
2790
+ removeStructuredData: (id: symbol) => void;
2791
+ }>;
2098
2792
  declare const applyStructuredDataBinding: (binding: MaybeSignal<WithContext<Thing> | Graph | null | undefined>) => void;
2099
2793
 
2100
2794
  declare class StructuredDataComponent {
@@ -2134,34 +2828,670 @@ type TitleConfig = {
2134
2828
  prefixPart?: TitlePart;
2135
2829
  };
2136
2830
  declare const provideTitleConfig: (valueOverride?: Partial<TitleConfig> | undefined) => _angular_core.Provider[];
2137
- declare const injectTitleConfig: {
2138
- (): TitleConfig;
2139
- (options: _angular_core.InjectOptions & {
2140
- optional?: false;
2141
- }): TitleConfig;
2142
- (options: _angular_core.InjectOptions): TitleConfig | null;
2143
- };
2831
+ declare const injectTitleConfig: _ethlete_core.InjectFn<TitleConfig>;
2144
2832
  declare const provideTitleStore: () => _angular_core.Provider[];
2145
- declare const injectTitleStore: {
2146
- (): {
2147
- title: _angular_core.Signal<string>;
2148
- addPart: (id: symbol, part: TitlePart) => void;
2149
- removePart: (id: symbol) => void;
2833
+ declare const injectTitleStore: _ethlete_core.InjectFn<{
2834
+ title: _angular_core.Signal<string>;
2835
+ addPart: (id: symbol, part: TitlePart) => void;
2836
+ removePart: (id: symbol) => void;
2837
+ addMarker: (id: symbol, marker: string) => void;
2838
+ removeMarker: (id: symbol) => void;
2839
+ }>;
2840
+ declare const applyHeadTitleBinding: (binding: MaybeSignal<string | number | null | undefined>, options?: Omit<TitlePart, "text">) => void;
2841
+ /**
2842
+ * Prefix the tab title with a short marker (`● Page | App`) while the binding has a value - the
2843
+ * unsaved-changes dot, a pending-count badge, and the like. The marker is removed when the binding
2844
+ * goes empty and on destroy. Unlike a title part, it is not joined by the divider.
2845
+ */
2846
+ declare const applyHeadTitleMarker: (binding: MaybeSignal<string | null | undefined>) => void;
2847
+
2848
+ /**
2849
+ * Cascades hover/active-driven color DOWN to descendants explicitly marked with
2850
+ * `ColorInteractiveDirective` - this element does not color itself. Use it when a wrapper should
2851
+ * expand a nested control's hit/visual area (e.g. clicking a checkbox's label should light up the
2852
+ * checkbox itself), never to give a wrapper its own interactive coloring - that's
2853
+ * `ColorInteractiveDirective`.
2854
+ *
2855
+ * Does nothing unless at least one descendant carries `ColorInteractiveDirective` - check for
2856
+ * that before adding this. It was mistakenly added to a component with no such descendant once
2857
+ * already, where it did nothing but was confusing to read.
2858
+ */
2859
+ declare class ColorInteractiveContainerDirective {
2860
+ private styleManager;
2861
+ constructor();
2862
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ColorInteractiveContainerDirective, never>;
2863
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ColorInteractiveContainerDirective, "[etColorInteractiveContainer]", never, {}, {}, never, never, true, never>;
2864
+ }
2865
+
2866
+ /**
2867
+ * Marks a descendant as NOT counting toward an ancestor's `ColorInteractiveDirective`
2868
+ * `:hover`/`:active` reaction (via the `:has()` guard in color-interactive-styles.component.css).
2869
+ * Use it for content that's incidentally inside an interactive ancestor but isn't part of what
2870
+ * makes that ancestor interactive - e.g. a hint/error block sitting inside a form field's frame.
2871
+ *
2872
+ * This only suppresses the ancestor's OWN reaction to hovering/pressing the excluded element - it
2873
+ * has no effect on custom-property inheritance into descendants past the excluded element. If
2874
+ * what you actually need is "stop my own cosmetic styling from reacting to a parent's unrelated
2875
+ * interaction," this is the wrong tool; that's the class of bug `ColorInteractiveHasFocusDirective`
2876
+ * used to have (see its own comment).
2877
+ */
2878
+ declare class ColorInteractiveExcludeDirective {
2879
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ColorInteractiveExcludeDirective, never>;
2880
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ColorInteractiveExcludeDirective, "[etColorInteractiveExclude]", never, {}, {}, never, never, true, never>;
2881
+ }
2882
+
2883
+ /**
2884
+ * Tints `--et-theme-color-primary-*` etc. only when a descendant genuinely has `:focus-visible`
2885
+ * (`:has(:focus-visible)`) - never on mouse `:hover`/`:active`. Use this for a wrapper (like a
2886
+ * form field's frame) that should show the theme color while its control is focused, but must
2887
+ * NOT react to incidental mouse interaction with unrelated nested widgets (a toolbar button, a
2888
+ * rendered link) that happen to live inside the same wrapper.
2889
+ *
2890
+ * The color it resolves to is the theme's BASE accent, not the `-focus` variant: the `-focus`
2891
+ * shade is the treatment for an element that is itself focused, whereas a container only mirroring
2892
+ * a child's focus should read as the plain accent color.
2893
+ *
2894
+ * Deliberately does NOT also carry `ColorInteractiveDirective`'s `et-color-interactive` class:
2895
+ * that class's plain `:hover`/`:active` rules locally override the same (inheriting)
2896
+ * `--et-theme-color-primary-rgb`, so anything bubbling up from ANYWHERE in the subtree would
2897
+ * leak the transient hover/press color into every descendant reading it for unrelated cosmetics -
2898
+ * exactly the bug this directive's only consumer (form-field) shipped once, before the two
2899
+ * behaviors were split apart. If you need the plain hover/active reaction too, add
2900
+ * `ColorInteractiveDirective` explicitly and make sure you actually want both.
2901
+ */
2902
+ declare class ColorInteractiveHasFocusDirective {
2903
+ private styleManager;
2904
+ constructor();
2905
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ColorInteractiveHasFocusDirective, never>;
2906
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ColorInteractiveHasFocusDirective, "[etColorInteractiveHasFocus]", never, {}, {}, never, never, true, never>;
2907
+ }
2908
+
2909
+ /**
2910
+ * Makes an element react to ITS OWN `:hover`/`:active`/`:focus-visible`/`[disabled]` by tinting
2911
+ * `--et-theme-color-primary-*`/`-on-primary-*`/`-ink-*` with the current color theme. Use this on
2912
+ * a single, self-contained interactive element - a button, a checkbox, a segmented button.
2913
+ *
2914
+ * Do NOT apply this to a wrapper that also contains OTHER, independently-interactive elements
2915
+ * (e.g. a toolbar with its own buttons, or a form-field's control slot). These are ordinary
2916
+ * inheriting CSS custom properties, so a descendant reading them for its own cosmetics (a caret
2917
+ * color, a link color) gets swept along whenever ANYTHING inside the wrapper is hovered or
2918
+ * clicked - not just when the wrapper itself is the thing being interacted with. That exact bug
2919
+ * shipped once already; see ColorInteractiveContainerDirective/ColorInteractiveHasFocusDirective
2920
+ * for the shapes that avoid it.
2921
+ */
2922
+ declare class ColorInteractiveDirective {
2923
+ private styleManager;
2924
+ constructor();
2925
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ColorInteractiveDirective, never>;
2926
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ColorInteractiveDirective, "[etColorInteractive]", never, {}, {}, never, never, true, never>;
2927
+ }
2928
+
2929
+ declare const SURFACE_TYPE: {
2930
+ readonly LIGHT: "light";
2931
+ readonly DARK: "dark";
2932
+ };
2933
+ type SurfaceType = (typeof SURFACE_TYPE)[keyof typeof SURFACE_TYPE];
2934
+ type SurfaceThemeColor = `${number} ${number} ${number}`;
2935
+ type SurfaceInteractionColor = {
2936
+ default: SurfaceThemeColor;
2937
+ hover: SurfaceThemeColor;
2938
+ focus: SurfaceThemeColor;
2939
+ active: SurfaceThemeColor;
2940
+ disabled: SurfaceThemeColor;
2941
+ };
2942
+ type SurfaceTheme = {
2943
+ name: string;
2944
+ type: SurfaceType;
2945
+ elevation: number;
2946
+ isDefault?: boolean;
2947
+ interactionColor?: SurfaceInteractionColor;
2948
+ background: SurfaceThemeColor;
2949
+ color: SurfaceThemeColor;
2950
+ colorMuted: SurfaceThemeColor;
2951
+ colorSubtle: SurfaceThemeColor;
2952
+ border: SurfaceThemeColor;
2953
+ };
2954
+ /**
2955
+ * Augmentable registry for the literal set of surface theme names an app defines. Left
2956
+ * empty by default, which keeps surface-theme-name-accepting APIs (like `etProvideSurface`)
2957
+ * typed as plain `string`.
2958
+ *
2959
+ * Apps that want those APIs checked and autocompleted against their own surface theme
2960
+ * names should augment this interface once, near where their surface themes are defined:
2961
+ *
2962
+ * ```ts
2963
+ * declare module '@ethlete/core' {
2964
+ * interface EthleteSurfaceThemeNameRegistry {
2965
+ * name: 'card' | 'sheet' | 'popover';
2966
+ * }
2967
+ * }
2968
+ * ```
2969
+ */
2970
+ interface EthleteSurfaceThemeNameRegistry {
2971
+ }
2972
+ type RegisteredSurfaceThemeName = EthleteSurfaceThemeNameRegistry extends {
2973
+ name: infer N extends string;
2974
+ } ? N : string;
2975
+ declare const createCssSurfaceName: (name: string) => string;
2976
+ declare const resolveSurfaceByElevation: (themes: SurfaceTheme[], type: SurfaceType, elevation: number) => SurfaceTheme | null;
2977
+ declare const ɵProvideSurfaceThemes: (valueOverride?: (SurfaceTheme | undefined)[] | undefined) => _angular_core.Provider[];
2978
+ declare const injectSurfaceThemes: _ethlete_core.InjectFn<SurfaceTheme[]>;
2979
+ declare const ɵProvideSurfaceThemesPrefix: (valueOverride?: string | undefined) => _angular_core.Provider[];
2980
+ declare const injectSurfaceThemesPrefix: _ethlete_core.InjectFn<string>;
2981
+ declare const provideSurfaceThemesWithTailwind4: (themes: SurfaceTheme[], prefix?: string) => _angular_core.Provider[][];
2982
+
2983
+ declare const SURFACE_PROVIDER: InjectionToken<ProvideSurfaceDirective>;
2984
+ declare class ProvideSurfaceDirective {
2985
+ private themes;
2986
+ private prefix;
2987
+ private injector;
2988
+ private currentProviderSync;
2989
+ private forcedSurface;
2990
+ surface: InputSignal<RegisteredSurfaceThemeName | null | undefined>;
2991
+ effectiveSurface: _angular_core.Signal<string | null | undefined>;
2992
+ resolvedTheme: _angular_core.Signal<SurfaceTheme | null>;
2993
+ elevation: _angular_core.Signal<number>;
2994
+ surfaceType: _angular_core.Signal<_ethlete_core.SurfaceType | null>;
2995
+ surfaceName: _angular_core.Signal<string | undefined>;
2996
+ protected surfaceClass: _angular_core.Signal<string>;
2997
+ syncWithProvider(provider: ProvideSurfaceDirective): void;
2998
+ stopSyncWithProvider(): void;
2999
+ /** @internal */
3000
+ forceSurface(surface: RegisteredSurfaceThemeName | null): void;
3001
+ /** @internal */
3002
+ clearForcedSurface(): void;
3003
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ProvideSurfaceDirective, never>;
3004
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ProvideSurfaceDirective, "[etProvideSurface]", never, { "surface": { "alias": "etProvideSurface"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
3005
+ }
3006
+
3007
+ declare class AutoSurfaceDirective {
3008
+ private ownSurfaceProvider;
3009
+ private contextSurfaceProvider;
3010
+ private surfaceThemes;
3011
+ private surfaceContextTracker;
3012
+ private elementRef;
3013
+ /**
3014
+ * Explicit surface provider to resolve the surface relative to. Falls back to the
3015
+ * surface provider from the surrounding (trigger) context when not set.
3016
+ */
3017
+ surfaceProvider: _angular_core.InputSignal<ProvideSurfaceDirective | null>;
3018
+ private isOverlaySurface;
3019
+ private domSettleTick;
3020
+ resolvedSurface: _angular_core.Signal<string | null>;
3021
+ /**
3022
+ * Mark this auto-surface as its overlay's *own painted surface*. An overlay *panel*
3023
+ * (menu, select/date/cascader panel, tooltip, toggletip, rich-text-editor popups) is
3024
+ * the overlay's surface, so it must paint the overlay's registered elevation exactly -
3025
+ * not stack a level above a parent surface. The elevation is read from the surface-context
3026
+ * tracker (the pane it renders into), which is authoritative across the portal boundary;
3027
+ * the panel's own declaration injector points back at the trigger location and cannot be
3028
+ * trusted.
3029
+ */
3030
+ matchOverlaySurface(): void;
3031
+ constructor();
3032
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<AutoSurfaceDirective, never>;
3033
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<AutoSurfaceDirective, "[etAutoSurface]", never, { "surfaceProvider": { "alias": "surfaceProvider"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof ProvideSurfaceDirective; inputs: {}; outputs: {}; }]>;
3034
+ }
3035
+
3036
+ type ThemeRGBColor = `${number} ${number} ${number}`;
3037
+ type ThemeHSLColor = `${number} ${number}% ${number}%`;
3038
+ type ThemeColor = ThemeRGBColor | ThemeHSLColor;
3039
+ type ThemeColorMap = {
3040
+ default: ThemeColor;
3041
+ hover: ThemeColor;
3042
+ focus?: ThemeColor;
3043
+ active: ThemeColor;
3044
+ disabled: ThemeColor;
3045
+ };
3046
+ type OnThemeColorMap = {
3047
+ default: ThemeColor;
3048
+ hover?: ThemeColor;
3049
+ focus?: ThemeColor;
3050
+ active?: ThemeColor;
3051
+ disabled?: ThemeColor;
3052
+ };
3053
+ type ThemeInkColorMap = {
3054
+ default: ThemeColor;
3055
+ hover?: ThemeColor;
3056
+ focus?: ThemeColor;
3057
+ active?: ThemeColor;
3058
+ disabled?: ThemeColor;
3059
+ };
3060
+ type ThemeSwatch = {
3061
+ color: ThemeColorMap;
3062
+ onColor: OnThemeColorMap;
3063
+ inkColor?: ThemeInkColorMap;
3064
+ };
3065
+ type ColorThemeType = 'success' | 'warning' | 'error';
3066
+ type ColorTheme = {
3067
+ name: string;
3068
+ type?: ColorThemeType;
3069
+ isDefault?: boolean;
3070
+ primary: ThemeSwatch;
3071
+ secondary?: ThemeSwatch;
3072
+ tertiary?: ThemeSwatch;
3073
+ };
3074
+ /**
3075
+ * Augmentable registry for the literal set of color theme names an app defines. Left
3076
+ * empty by default, which keeps theme-name-accepting APIs (like `etProvideColor`) typed
3077
+ * as plain `string`.
3078
+ *
3079
+ * Apps that want those APIs checked and autocompleted against their own theme names
3080
+ * should augment this interface once, near where their themes are defined:
3081
+ *
3082
+ * ```ts
3083
+ * declare module '@ethlete/core' {
3084
+ * interface EthleteColorThemeNameRegistry {
3085
+ * name: 'pitch-green' | 'red' | 'light-grey';
3086
+ * }
3087
+ * }
3088
+ * ```
3089
+ */
3090
+ interface EthleteColorThemeNameRegistry {
3091
+ }
3092
+ type RegisteredColorThemeName = EthleteColorThemeNameRegistry extends {
3093
+ name: infer N extends string;
3094
+ } ? N : string;
3095
+ declare const createCssColorThemeName: (name: string) => string;
3096
+ declare const ɵProvideColorThemes: (valueOverride?: (ColorTheme | undefined)[] | undefined) => _angular_core.Provider[];
3097
+ declare const injectColorThemes: _ethlete_core.InjectFn<ColorTheme[]>;
3098
+ declare const ɵProvideColorThemesPrefix: (valueOverride?: string | undefined) => _angular_core.Provider[];
3099
+ declare const injectColorThemesPrefix: _ethlete_core.InjectFn<string>;
3100
+ declare const provideColorThemesWithTailwind4: (themes: ColorTheme[], prefix?: string) => _angular_core.Provider[][];
3101
+ declare const injectErrorTheme: () => ColorTheme;
3102
+ declare const injectWarningTheme: () => ColorTheme;
3103
+ declare const injectSuccessTheme: () => ColorTheme;
3104
+ declare const injectDefaultColorTheme: () => ColorTheme;
3105
+
3106
+ /**
3107
+ * @deprecated Migrate to Tailwind v4. Intent to remove in v6.
3108
+ */
3109
+ declare const createSwatchCss: (swatch: string, isAlt: boolean, data: ThemeSwatch) => string;
3110
+ /**
3111
+ * @deprecated Migrate to Tailwind v4. Intent to remove in v6.
3112
+ */
3113
+ declare const createRootThemeCss: (themes: ColorTheme[]) => void;
3114
+ /**
3115
+ * @deprecated Migrate to Tailwind v4. Intent to remove in v6.
3116
+ */
3117
+ declare const createThemeStyle: (theme: ColorTheme, isAlt: boolean) => void;
3118
+ /**
3119
+ * @deprecated Migrate to Tailwind v4. Intent to remove in v6.
3120
+ */
3121
+ declare const createTailwindCssVar: (name: string | undefined) => string | null;
3122
+ /**
3123
+ * @deprecated Migrate to Tailwind v4. Intent to remove in v6.
3124
+ */
3125
+ declare function createTailwindRgbVar(val: string): string;
3126
+ declare function createTailwindRgbVar(val: string | undefined): string | null;
3127
+ /**
3128
+ * @deprecated Migrate to Tailwind v4. Intent to remove in v6.
3129
+ */
3130
+ declare const createTailwindColorThemes: (themes: ColorTheme[], prefix?: string) => Record<string, {
3131
+ DEFAULT: string;
3132
+ hover: string;
3133
+ focus: string;
3134
+ active: string;
3135
+ disabled: string;
3136
+ }>;
3137
+ /**
3138
+ * @deprecated Use provideColorThemesWithTailwind4 instead after migrating to Tailwind CSS v4. Intent to remove in v6.
3139
+ */
3140
+ declare const provideColorThemes: (themes: ColorTheme[]) => _angular_core.Provider[][];
3141
+
3142
+ declare const COLOR_PROVIDER: InjectionToken<ProvideColorDirective>;
3143
+ /**
3144
+ * The color provider attached to a bootstrapped root component (e.g. `ProvideColorDirective` in
3145
+ * the app component's `hostDirectives`), if any. Detached DOM such as overlay panes can't reach
3146
+ * it through element DI, so overlay containers fall back to this when resolving the provider to
3147
+ * `syncWithProvider()` - resolve at sync time, not at injection time, since root components only
3148
+ * register with `ApplicationRef` once bootstrap completes.
3149
+ *
3150
+ * @internal
3151
+ */
3152
+ declare const resolveAppRootColorProvider: (appRef: ApplicationRef) => ProvideColorDirective | null;
3153
+ declare class ProvideColorDirective {
3154
+ private themes;
3155
+ private prefix;
3156
+ private injector;
3157
+ private parentProvider;
3158
+ private currentProviderSync;
3159
+ private forcedColor;
3160
+ color: InputSignal<RegisteredColorThemeName | ColorTheme | null | undefined>;
3161
+ effectiveColor: _angular_core.Signal<string | ColorTheme | null | undefined>;
3162
+ /**
3163
+ * The color that actually applies at this provider's location: its own effective color, or -
3164
+ * when this provider is passive (no input, nothing forced) - the nearest ancestor provider's.
3165
+ * Mirrors the CSS cascade, which falls through a provider's `-color--inherited` scope class;
3166
+ * consumers that re-apply context across detached DOM (overlay panes) must use this instead
3167
+ * of `effectiveColor` or a passive in-between provider (e.g. a form field's) erases the theme.
3168
+ */
3169
+ resolvedColor: _angular_core.Signal<string | ColorTheme | null | undefined>;
3170
+ colorName: _angular_core.Signal<string | undefined>;
3171
+ protected themeClass: _angular_core.Signal<string>;
3172
+ syncWithProvider(provider: ProvideColorDirective): void;
3173
+ stopSyncWithProvider(): void;
3174
+ /** @internal */
3175
+ forceColor(color: RegisteredColorThemeName | ColorTheme | null): void;
3176
+ /** @internal */
3177
+ clearForcedColor(): void;
3178
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ProvideColorDirective, never>;
3179
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ProvideColorDirective, "[etProvideColor]", never, { "color": { "alias": "etProvideColor"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
3180
+ }
3181
+
3182
+ type SurfaceContextEntry = {
3183
+ id: string;
3184
+ type: SurfaceType;
3185
+ elevation: number;
3186
+ element: HTMLElement;
3187
+ };
3188
+ type SurfaceContextSurface = {
3189
+ type: SurfaceType;
3190
+ elevation: number;
3191
+ };
3192
+ type SurfaceContextTracker = {
3193
+ topType: Signal<SurfaceType | null>;
3194
+ topElevation: Signal<number>;
3195
+ register: (type: SurfaceType, elevation: number, element: HTMLElement) => () => void;
3196
+ /**
3197
+ * The surface of the innermost registered overlay whose pane actually contains `host` in the DOM,
3198
+ * or `null` when `host` sits outside every open overlay. Reactive: reads the entries signal, so
3199
+ * calling it inside a computed re-runs when overlays open/close.
3200
+ */
3201
+ surfaceForElement: (host: HTMLElement) => SurfaceContextSurface | null;
3202
+ };
3203
+ declare const provideSurfaceContextTracker: () => _angular_core.Provider[];
3204
+ declare const injectSurfaceContextTracker: _ethlete_core.InjectFn<SurfaceContextTracker>;
3205
+
3206
+ /**
3207
+ * Same shape as `ColorInteractiveDirective` - reacts to its own `:hover`/`:focus-visible`/
3208
+ * `:active`/`[disabled]` - but drives `--et-surface-interaction-*`, a neutral/muted tint, instead
3209
+ * of the ambient color theme. Use it for chrome-level interaction feedback that shouldn't borrow
3210
+ * the page's brand color (a tab trigger's hover state, a toggle button that should look neutral
3211
+ * until it's actually active - see `ButtonDirective`'s `mutedUntilPressed`).
3212
+ *
3213
+ * Has no container/exclude/has-focus variants: it has no descendant-cascading CSS at all, so
3214
+ * applying it to a wrapper with independently-interactive children is safe by construction -
3215
+ * unlike `ColorInteractiveDirective`, there's no bubbling-leak failure mode to worry about here.
3216
+ */
3217
+ declare class SurfaceInteractiveDirective {
3218
+ private styleManager;
3219
+ constructor();
3220
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SurfaceInteractiveDirective, never>;
3221
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<SurfaceInteractiveDirective, "[etSurfaceInteractive]", never, {}, {}, never, never, true, never>;
3222
+ }
3223
+
3224
+ /**
3225
+ * Why a guard was abandoned. `'logout'` is issued by `@ethlete/query`'s auth provider; anything else
3226
+ * is app-defined.
3227
+ */
3228
+ type UnsavedChangesAbandonReason = 'logout' | (string & {});
3229
+ /** The second argument every {@link UnsavedChangesConfirmFn} receives. */
3230
+ type UnsavedChangesConfirmContext = {
3231
+ /**
3232
+ * Aborts when the session this confirm belongs to ends underneath it - a logout, or an explicit
3233
+ * `abandonAll()`. **Close your confirm dialog when it fires**, otherwise it is left on screen over
3234
+ * a page the user has already been redirected away from. The guard itself stops waiting either way.
3235
+ *
3236
+ * ```ts
3237
+ * confirm: (value, { signal }) => {
3238
+ * const ref = this.overlays.open(ConfirmDiscardComponent);
3239
+ * signal.addEventListener('abort', () => ref.close(false));
3240
+ * return ref.afterClosed();
3241
+ * };
3242
+ * ```
3243
+ */
3244
+ signal: AbortSignal;
3245
+ };
3246
+ /** @internal A live tracker, as seen by the coordinator. */
3247
+ type UnsavedChangesRegistration = {
3248
+ abandon: (reason: UnsavedChangesAbandonReason) => void;
3249
+ };
3250
+ /**
3251
+ * App-wide coordination for the unsaved-changes family. Two jobs:
3252
+ *
3253
+ * - **One confirm at a time.** A page form, an overlay form and a route guard can all want a decision
3254
+ * at once; stacking three "discard your changes?" dialogs is never the right answer. A check that
3255
+ * starts while another is pending adopts the pending decision instead of asking again.
3256
+ * - **Abandoning guards when the session ends.** `abandonAll()` resolves the pending confirm, tells
3257
+ * its dialog to close (via {@link UnsavedChangesConfirmContext.signal}), and switches every live
3258
+ * guard off: further checks pass, and the tab locks release. Called automatically by
3259
+ * `@ethlete/query`'s auth provider on logout - the edits cannot be saved anymore, so guarding them
3260
+ * only strands dialogs over the login page and blocks the tab.
3261
+ *
3262
+ * Root-provided; every tracker registers itself. Inject it to abandon guards from app code (a session
3263
+ * timeout of your own, a hard reset) or to read whether a confirm is currently on screen.
3264
+ */
3265
+ declare const provideUnsavedChangesCoordinator: () => _angular_core.Provider[];
3266
+ declare const injectUnsavedChangesCoordinator: _ethlete_core.InjectFn<{
3267
+ /** Whether a confirm is currently on screen. */
3268
+ isCheckPending: _angular_core.Signal<boolean>;
3269
+ abandonAll: (reason?: UnsavedChangesAbandonReason) => void;
3270
+ runCheck: (runner: (context: UnsavedChangesConfirmContext) => Promise<boolean>) => Promise<boolean>;
3271
+ register: (registration: UnsavedChangesRegistration) => () => boolean;
3272
+ }>;
3273
+
3274
+ /**
3275
+ * The value source an unsaved-changes tracker watches. In order of preference:
3276
+ *
3277
+ * - **`FieldTree<T>`** (signal forms - primary): read `field().value()`, restore `field().value.set(v)`.
3278
+ * - **`Signal<FieldTree<T> | null>`**: a late/async-created signal form - resolves once the field exists.
3279
+ * - **`AbstractControl`** (reactive forms - migration path): bridged via `controlValueSignal` + `setValue`.
3280
+ * - **`WritableSignal<T>`** (escape hatch for non-form state): read/write directly.
3281
+ */
3282
+ type UnsavedChangesSource<T> = FieldTree<T> | Signal<FieldTree<T> | null> | AbstractControl | WritableSignal<T>;
3283
+ /** A value source reduced to a read signal plus a writer, regardless of its original kind. */
3284
+ type NormalizedUnsavedChangesSource<T> = {
3285
+ /** The current value. `null` while a late/async source has not produced a value yet. */
3286
+ value: Signal<T | null>;
3287
+ /** Writes a value back to the source (used by `restoreDefaultValue`). No-op if the source isn't ready. */
3288
+ setValue: (value: T) => void;
3289
+ };
3290
+ /** Reduces any {@link UnsavedChangesSource} to a uniform read-signal + writer pair. */
3291
+ declare const normalizeUnsavedChangesSource: <T>(source: UnsavedChangesSource<T>) => NormalizedUnsavedChangesSource<T>;
3292
+
3293
+ /** The default tab title marker - a filled dot, prefixed while there are unsaved changes. */
3294
+ declare const UNSAVED_CHANGES_TITLE_MARKER = "\u25CF";
3295
+ /**
3296
+ * How an unsaved-changes tracker surfaces itself on the browser tab.
3297
+ *
3298
+ * Only the `beforeunload` lock is on by default - the title marker and the app badge write to
3299
+ * app-global surfaces, so they are opt-in.
3300
+ */
3301
+ type UnsavedChangesTabConfig = {
3302
+ /**
3303
+ * Make the browser ask for confirmation before the tab is closed, reloaded, or navigated away from
3304
+ * while there are unsaved changes (`beforeunload`).
3305
+ *
3306
+ * The prompt is the browser's own - its wording cannot be customized, and browsers only show it
3307
+ * after the user has interacted with the page at least once (sticky activation). The listener is
3308
+ * attached **only while changes exist**, so a clean page stays eligible for the back/forward cache.
3309
+ * @default true
3310
+ */
3311
+ lock?: boolean;
3312
+ /**
3313
+ * Prefix the tab title with a marker while there are unsaved changes. `true` uses
3314
+ * {@link UNSAVED_CHANGES_TITLE_MARKER}, a string is used as-is.
3315
+ *
3316
+ * Goes through the core title store (`injectTitleStore`), so the app's title must be owned by it
3317
+ * (`applyHeadTitleBinding` / the `etSeo` directive) - an app that writes `document.title` by some
3318
+ * other means would fight the store over it.
3319
+ * @default false
3320
+ */
3321
+ titleMarker?: boolean | string;
3322
+ /**
3323
+ * Blink the tab while there are unsaved changes: the title marker (and the favicon dot, if enabled)
3324
+ * is toggled on and off - the closest thing the web has to an "attention needed" tab flash, since no
3325
+ * browser exposes one. Implies `titleMarker` when that isn't set.
3326
+ *
3327
+ * By default it only blinks while the tab is **in the background** (`whenHidden`), which is the case
3328
+ * worth flagging - a title blinking in the tab the user is already reading is just noise. `interval`
3329
+ * is in ms and defaults to 1000; going faster is pointless because browsers clamp timers in hidden
3330
+ * tabs to roughly one second.
3331
+ * @default false
3332
+ */
3333
+ flash?: boolean | {
3334
+ interval?: number;
3335
+ whenHidden?: boolean;
2150
3336
  };
2151
- (options: _angular_core.InjectOptions & {
2152
- optional?: false;
2153
- }): {
2154
- title: _angular_core.Signal<string>;
2155
- addPart: (id: symbol, part: TitlePart) => void;
2156
- removePart: (id: symbol) => void;
3337
+ /**
3338
+ * Draw a dot on the site's favicon while there are unsaved changes, via the
3339
+ * [favicon store](/core/seo#favicon). Pass a color to override the theme accent.
3340
+ * @default false
3341
+ */
3342
+ favicon?: boolean | {
3343
+ color?: string;
2157
3344
  };
2158
- (options: _angular_core.InjectOptions): {
2159
- title: _angular_core.Signal<string>;
2160
- addPart: (id: symbol, part: TitlePart) => void;
2161
- removePart: (id: symbol) => void;
2162
- } | null;
3345
+ /**
3346
+ * Show an app badge while there are unsaved changes (Badging API). `true` shows a plain dot, a
3347
+ * number shows that count.
3348
+ *
3349
+ * The badge is a per-app surface, not a per-tab one: it is only visible when the app is installed
3350
+ * (PWA / desktop shortcut) and pinned, and it is a silent no-op everywhere else. Counts from
3351
+ * several trackers add up; the badge is cleared once the last one is clean.
3352
+ * @default false
3353
+ */
3354
+ badge?: boolean | number;
2163
3355
  };
2164
- declare const applyHeadTitleBinding: (binding: MaybeSignal<string | number | null | undefined>, options?: Omit<TitlePart, "text">) => void;
3356
+ type CreateUnsavedChangesTabLockConfig = UnsavedChangesTabConfig & {
3357
+ /** Whether there are unsaved changes right now - typically a tracker's `hasChanges`. */
3358
+ hasChanges: Signal<boolean>;
3359
+ };
3360
+ type UnsavedChangesTabLockRef = {
3361
+ /**
3362
+ * Release the lock and remove the title marker / app badge. Also runs automatically when the
3363
+ * injector that created the lock is destroyed.
3364
+ */
3365
+ destroy: () => void;
3366
+ };
3367
+ /**
3368
+ * The browser-tab flavor of the unsaved-changes family: while `hasChanges` reads `true`, the tab
3369
+ * cannot be closed or reloaded without the browser's confirm prompt, and - opt in - the tab title
3370
+ * carries a marker (optionally blinking), the favicon carries a dot, and the installed app carries a
3371
+ * badge.
3372
+ *
3373
+ * Every {@link createUnsavedChangesTracker} sets this up automatically (lock only); reach for it
3374
+ * directly when you track "unsaved" state that isn't a form, or want to lock the tab from a signal
3375
+ * you already have. Call from an injection context.
3376
+ *
3377
+ * ```ts
3378
+ * createUnsavedChangesTabLock({
3379
+ * hasChanges: computed(() => this.uploads().some((u) => u.pending)),
3380
+ * titleMarker: true,
3381
+ * flash: true,
3382
+ * });
3383
+ * ```
3384
+ */
3385
+ declare const createUnsavedChangesTabLock: (config: CreateUnsavedChangesTabLockConfig) => UnsavedChangesTabLockRef;
3386
+
3387
+ /**
3388
+ * Decides whether a value with unsaved changes may be discarded. Called with the current value when
3389
+ * (and only when) changes exist. Return a truthy value / resolved Promise / emitted Observable value
3390
+ * to allow the discard, falsy to keep the changes. Typically opens a confirm dialog.
3391
+ *
3392
+ * The second argument carries an {@link UnsavedChangesConfirmContext.signal} that aborts when the
3393
+ * session ends underneath the confirm (a logout) - close your dialog when it fires.
3394
+ */
3395
+ type UnsavedChangesConfirmFn<T> = (value: T, context: UnsavedChangesConfirmContext) => boolean | Promise<boolean> | Observable<boolean> | unknown;
3396
+ type CreateUnsavedChangesTrackerConfig<T> = {
3397
+ /** The form / value to watch. See {@link UnsavedChangesSource}. */
3398
+ source: UnsavedChangesSource<T>;
3399
+ /**
3400
+ * The baseline the current value is compared against.
3401
+ * If omitted, the first non-null value the source produces is captured automatically (so
3402
+ * async-filled forms work without wiring). A function is evaluated once, eagerly.
3403
+ */
3404
+ defaultValue?: T | (() => T);
3405
+ /**
3406
+ * Required, per call site. Runs only when there are changes to discard.
3407
+ * @see UnsavedChangesConfirmFn
3408
+ */
3409
+ confirm: UnsavedChangesConfirmFn<T>;
3410
+ /**
3411
+ * Custom equality between the current value and the default. Deep-equal by default.
3412
+ *
3413
+ * Note: this is snapshot-vs-default comparison, deliberately **not** signal-forms' `dirty()`
3414
+ * (which means "was edited", so typing then deleting stays dirty - here it's clean again).
3415
+ */
3416
+ compareFn?: (current: T, defaultValue: T) => boolean;
3417
+ /**
3418
+ * How the tracker guards the browser tab itself. The `beforeunload` lock - the browser's confirm
3419
+ * prompt before the tab is closed or reloaded - is **on by default**, since a guard that only
3420
+ * covers in-app navigation still loses the edits to <kbd>Ctrl</kbd>+<kbd>W</kbd>.
3421
+ *
3422
+ * Pass an object to also opt into a tab title marker or an app badge, or `false` to leave the tab
3423
+ * alone entirely. See {@link UnsavedChangesTabConfig}.
3424
+ * @default { lock: true }
3425
+ */
3426
+ tab?: UnsavedChangesTabConfig | false;
3427
+ };
3428
+ type UnsavedChangesTrackerRef<T> = {
3429
+ /** Whether the current value differs from the default. */
3430
+ hasChanges: Signal<boolean>;
3431
+ /**
3432
+ * Whether this guard was switched off because the session ended underneath it (a logout, or an
3433
+ * explicit `injectUnsavedChangesCoordinator().abandonAll()`). An abandoned tracker still reports
3434
+ * `hasChanges`, but `runCheck()` passes without confirming and the tab lock is released - the edits
3435
+ * cannot be saved anymore, so blocking on them only strands the user.
3436
+ */
3437
+ isAbandoned: Signal<boolean>;
3438
+ /** The current baseline. `null` until a value (or explicit default) exists. */
3439
+ defaultValue: Signal<T | null>;
3440
+ /**
3441
+ * Resolves `true` if there are no changes or the user confirmed the discard, `false` otherwise.
3442
+ * Normalizes the `confirm` return (value / Promise / Observable) to a `Promise<boolean>`.
3443
+ *
3444
+ * Only one confirm runs app-wide: a check that starts while another tracker's confirm is on screen
3445
+ * adopts that decision instead of opening a second dialog.
3446
+ */
3447
+ runCheck: () => Promise<boolean>;
3448
+ /** Re-baseline to the current value - e.g. after a save that keeps the form open. */
3449
+ refreshDefaultValue: () => void;
3450
+ /** Write the default back onto the source (revert edits). No-op if there is no default yet. */
3451
+ restoreDefaultValue: () => void;
3452
+ /**
3453
+ * The tab guard (`beforeunload` lock, title marker, app badge) driven by `hasChanges` - `null` when
3454
+ * the tracker was created with `tab: false`. Call `tab.destroy()` to release it before the
3455
+ * injector is destroyed, e.g. right before a deliberate `location.reload()`.
3456
+ */
3457
+ tab: UnsavedChangesTabLockRef | null;
3458
+ };
3459
+ /**
3460
+ * The framework-agnostic core of the unsaved-changes family: snapshots a default value, tracks
3461
+ * whether the watched form/value differs from it, and runs an async confirm before a discard.
3462
+ * Call from an injection context (a field initializer or constructor).
3463
+ *
3464
+ * While there are changes the browser tab is locked too (`beforeunload`), so closing or reloading the
3465
+ * tab needs a confirmation - see the `tab` config for the title-marker / app-badge extras and for
3466
+ * opting out.
3467
+ *
3468
+ * Every tracker registers with the app-wide {@link injectUnsavedChangesCoordinator}, which keeps a
3469
+ * single confirm on screen at a time and switches all guards off when the session ends (logout).
3470
+ *
3471
+ * Overlay and router flavors (`createOverlayUnsavedChangesGuard`, `createUnsavedChangesGuard`) build
3472
+ * on this - use them when you want the guard wired to a close/navigation event automatically.
3473
+ */
3474
+ declare const createUnsavedChangesTracker: <T>(config: CreateUnsavedChangesTrackerConfig<T>) => UnsavedChangesTrackerRef<T>;
3475
+
3476
+ type CreateUnsavedChangesGuardConfig<T> = CreateUnsavedChangesTrackerConfig<T>;
3477
+ type UnsavedChangesGuardRef<T> = UnsavedChangesTrackerRef<T> & {
3478
+ /**
3479
+ * A `CanDeactivateFn`-compatible check: resolves `true` when the route may be left (no changes, or
3480
+ * the user confirmed the discard), `false` to stay. Wire it into a route's `canDeactivate`.
3481
+ *
3482
+ * ```ts
3483
+ * export const editGuard: CanDeactivateFn<EditComponent> = (component) => component.guard.canDeactivate();
3484
+ * ```
3485
+ */
3486
+ canDeactivate: () => Promise<boolean>;
3487
+ };
3488
+ /**
3489
+ * The router / manual flavor of the unsaved-changes family: a {@link createUnsavedChangesTracker}
3490
+ * plus a `canDeactivate` bridge for Angular route guards. It touches no overlay APIs, so it also
3491
+ * serves as a standalone "does this form have unsaved changes, and may I discard them?" helper.
3492
+ * Call from an injection context.
3493
+ */
3494
+ declare const createUnsavedChangesGuard: <T>(config: CreateUnsavedChangesGuardConfig<T>) => UnsavedChangesGuardRef<T>;
2165
3495
 
2166
- export { ANIMATABLE_TOKEN, ANIMATED_IF_TOKEN, ANIMATED_LIFECYCLE_TOKEN, AT_LEAST_ONE_REQUIRED, AnimatableDirective, AnimatedIfDirective, AnimatedLifecycleDirective, AnimatedOverlayDirective, BOUNDARY_ELEMENT_TOKEN, ClickOutsideDirective, DEFAULT_MULTI_INSTANCE_RELS, DEFAULT_MULTI_INSTANCE_TAGS, DEFAULT_VIEWPORT_CONFIG, DISABLE_LOGGER_PARAM, ET_DISABLE_SCROLL_TOP, ET_DISABLE_SCROLL_TOP_AS_RETURN_ROUTE, ET_DISABLE_SCROLL_TOP_ON_PATH_PARAM_CHANGE, ET_PROPERTY_REMOVED, FOCUS_VISIBLE_TRACKER_TOKEN, IS_ARRAY_NOT_EMPTY, IS_EMAIL, InferMimeTypePipe, IsArrayNotEmpty, IsEmail, jsonLd_d as JsonLD, KeyPressManager, MUST_MATCH, MatchStateType, MustMatch, NormalizeGameResultTypePipe, NormalizeMatchParticipantsPipe, NormalizeMatchScorePipe, NormalizeMatchStatePipe, NormalizeMatchTypePipe, PropsDirective, ProvideThemeDirective, RUNTIME_ERROR_NO_DATA, RepeatDirective, RuntimeError, SEO_DIRECTIVE_TOKEN, SeoDirective, StructuredDataComponent, THEME_PROVIDER, ToArrayPipe, TypedQueryList, ValidateAtLeastOneRequired, Validators, applyAlternateBinding, applyAlternateLanguagesBindings, applyArticleBindings, applyAuthorBinding, applyCanonicalBinding, applyDescriptionBinding, applyHeadBinding, applyHeadTitleBinding, applyHostListener, applyHostListeners, applyKeywordsBinding, applyLinkBinding, applyMetaBinding, applyNextBinding, applyOgBinding, applyOpenGraphBindings, applyPrevBinding, applyResourceHintsBindings, applyRobotsBinding, applySocialMediaBindings, applyStructuredDataBinding, applyTwitterCardBindings, areScrollStatesEqual, bindProps, boundingClientRectToElementRect, buildElementSignal, buildSignalEffects, clamp, clone, cloneFormGroup, computedTillFalsy, computedTillTruthy, controlValueSignal, controlValueSignalWithPrevious, createArrayPropertyBinding, createBulkPropertyBinding, createCanAnimateSignal, createComponentId, createCssThemeName, createDependencyStash, createDestroy, createDocumentElementSignal, createElementDictionary, createElementDimensions, createEmptyElementSignal, createFlipAnimation, createFlipAnimationGroup, createHostProps, createIsRenderedSignal, createLogger, createPropHandlers, createPropertyBinding, createProps, createProvider, createRootProvider, createRootThemeCss, createRxHostListener, createSetup, createStaticProvider, createStaticRootProvider, createSwatchCss, createTailwindColorThemes, createTailwindCssVar, createTailwindRgbVar, createThemeStyle, deferredSignal, deleteCookie, easeElastic, easeIn, easeInOut, easeLinear, easeOut, easeOutBack, easeOutBackStrong, elementCanScroll, equal, firstElementSignal, forceReflow, formatRuntimeError, fromNextFrame, getCookie, getDomain, getElementScrollCoordinates, getFormGroupValue, getGroupMatchPoints, getGroupMatchScore, getKnockoutMatchScore, getMatchScoreSubLine, getObjectProperty, hasCookie, inferMimeType, injectAngularRootElement, injectBoundaryElement, injectBreakpointIsMatched, injectBreakpointObserver, injectCanHover, injectColorThemes, injectCurrentBreakpoint, injectDeviceInputType, injectDisplayOrientation, injectFocusVisibleTracker, injectFragment, injectHasPrecisionInput, injectHasTouchInput, injectHostElement, injectIs2Xl, injectIsLandscape, injectIsLg, injectIsMd, injectIsPortrait, injectIsRouterInitialized, injectIsSm, injectIsXl, injectIsXs, injectLinkStore, injectLinkStoreConfig, injectLocale, injectMediaQueryIsMatched, injectMetaConfig, injectMetaStore, injectObserveBreakpoint, injectObserveMediaQuery, injectPathParam, injectPathParamChanges, injectPathParams, injectQueryParam, injectQueryParamChanges, injectQueryParams, injectRenderer, injectRoute, injectRouteData, injectRouteDataItem, injectRouteTitle, injectRouterEvent, injectRouterState, injectScrollbarDimensions, injectStructuredDataConfig, injectStructuredDataStore, injectTemplateRef, injectThemesPrefix, injectTitleConfig, injectTitleStore, injectUrl, injectViewportConfig, injectViewportDimensions, isArray, isElementSignal, isElementVisible, isGroupMatch, isKnockoutMatch, isObject, maybeSignalValue, memoizeSignal, nextFrame, normalizeGameResultType, normalizeMatchParticipant, normalizeMatchParticipants, normalizeMatchScore, normalizeMatchState, normalizeMatchType, previousSignalValue, provideBoundaryElement, provideBreakpointObserver, provideColorThemes, provideColorThemesWithTailwind4, provideFocusVisibleTracker, provideLinkStore, provideLinkStoreConfig, provideLocale, provideMetaConfig, provideMetaStore, provideRenderer, provideStructuredDataConfig, provideStructuredDataStore, provideTitleConfig, provideTitleStore, provideViewportConfig, round, routerDisableScrollTop, scrollToElement, setCookie, setInputSignal, setupScrollRestoration, signalAnimatedNumber, signalAttributes, signalClasses, signalElementChildren, signalElementDimensions, signalElementIntersection, signalElementLastScrollDirection, signalElementMutations, signalElementScrollState, signalHostAttributes, signalHostClasses, signalHostElementDimensions, signalHostElementIntersection, signalHostElementLastScrollDirection, signalHostElementMutations, signalHostElementScrollState, signalHostStyles, signalIsRendered, signalStyles, switchQueryListChanges, syncSignal, templateComputed, toArray, toArrayTrackByFn, toStringBinding, transformOrReturn, unbindProps, useCursorDragScroll, writeScrollbarSizeToCssVariables, writeViewportSizeToCssVariables, ɵProvideColorThemes, ɵProvideThemesPrefix };
2167
- export type { AlternateLanguagesConfig, AlternateLink, AngularRenderer, AnimatedLifecycleState, AnimatedNumberSignal, AnimatedOverlayComponentBase, AnimatedOverlayMountConfig, AnimatedOverlayState, AnimationEndEvent, AnyTemplateType, ArticleConfig, BindPropsOptions, Breakpoint, BuildMediaQueryOptions, BuildSignalEffectsConfig, ComponentTemplate, ComponentTypeWithInputs, ControlValueSignalOptions, CreateLoggerConfig, CreatePropsOptions, CreateProviderOptions, CurrentElementVisibility, CursorDragScrollDirection, CursorDragScrollOptions, ElementDimensions, ElementLastScrollDirection, ElementLastScrollDirectionType, ElementRect, ElementScrollState, ElementSignal, ElementSignalValue, ElementSize, FacebookCard, FlipAnimationConfig, HeadBinding, HostProps, InjectQueryParamConfig, InjectUtilConfig, InjectUtilTransformConfig, IntersectionObserverEntryWithDetails, IsElementVisibleOptions, LinkConfig, LinkStoreConfig, LogicalSize, MaybeObservable, MaybeSignal, MetaConfig, MetaTagConfig, NgClassType, NgTemplateTemplate, NormalizedGameResultType, NormalizedMatchParticipant, NormalizedMatchParticipants, NormalizedMatchScore, NullableElementDimensions, OnThemeColorMap, OpenGraph, OpenGraphConfig, PropHandlers, Props, PropsAttachedElements, PropsAttachedElementsInternal, PropsInternal, ProviderResult, ResourceHintsConfig, RobotsConfig, RootProviderResult, RouterDisableScrollTopConfig, RouterState, ScrollToElementOptions, SeoConfig, SetupScrollRestorationConfig, SignalAnimatedNumberOptions, SignalElementBindingComplexType, SignalElementBindingType, SignalElementIntersectionOptions, SignalElementScrollStateOptions, SocialMediaConfig, StaticProviderResult, StringTemplate, StructuredDataConfig, SyncSignalOptions, TemplateRefWithContext, Theme, ThemeColor, ThemeColorMap, ThemeHSLColor, ThemeRGBColor, ThemeSwatch, TitleConfig, TitlePart, Translatable, TwitterCard, TwitterCardConfig, UnbindPropsOptions, ValidateAtLeastOneRequiredConfig, Vec2, ViewportConfig };
3496
+ export { ANIMATABLE_TOKEN, ANIMATED_IF_TOKEN, ANIMATED_LIFECYCLE_TOKEN, ANIMATION_DEBUG_STORAGE_KEY, AT_LEAST_ONE_REQUIRED, AnimatableDirective, AnimatedIfDirective, AnimatedLifecycleDirective, AutoSurfaceDirective, BOUNDARY_ELEMENT_TOKEN, BREAKPOINT_INSTANCE_TOKEN, BREAKPOINT_ORDER, COLOR_PROVIDER, ClickOutsideDirective, ColorInteractiveContainerDirective, ColorInteractiveDirective, ColorInteractiveExcludeDirective, ColorInteractiveHasFocusDirective, DEFAULT_MULTI_INSTANCE_RELS, DEFAULT_MULTI_INSTANCE_TAGS, DEFAULT_VIEWPORT_CONFIG, DISABLE_LOGGER_PARAM, DragHandleDirective, ET_DISABLE_SCROLL_TOP, ET_DISABLE_SCROLL_TOP_AS_RETURN_ROUTE, ET_DISABLE_SCROLL_TOP_ON_PATH_PARAM_CHANGE, ET_PROPERTY_REMOVED, FOCUSABLE_SELECTOR, FOCUS_VISIBLE_TRACKER_TOKEN, HtmlToMarkdownPipe, IS_ARRAY_NOT_EMPTY, IS_EMAIL, InferMimeTypePipe, InitialsPipe, IsArrayNotEmpty, IsEmail, jsonLd_d as JsonLD, KeyPressManager, MUST_MATCH, MarkdownToHtmlPipe, MatchStateType, MustMatch, NOTIFICATION_CLICK_MESSAGE_TYPE, NormalizeGameResultTypePipe, NormalizeMatchParticipantsPipe, NormalizeMatchScorePipe, NormalizeMatchStatePipe, NormalizeMatchTypePipe, PropsDirective, ProvideColorDirective, ProvideSurfaceDirective, RUNTIME_ERROR_NO_DATA, RepeatDirective, ResizeHandlesComponent, RuntimeError, SURFACE_PROVIDER, SURFACE_TYPE, SWIPE_VELOCITY_WINDOW_MS, ScrollObserverDirective, ScrollObserverEndDirective, ScrollObserverStartDirective, SlugifyPipe, StructuredDataComponent, SurfaceInteractiveDirective, ToArrayPipe, TypedQueryList, UNSAVED_CHANGES_TITLE_MARKER, ValidateAtLeastOneRequired, Validators, anchoredOverlayPosition, animationDebugLog, applyAlternateBinding, applyAlternateLanguagesBindings, applyArticleBindings, applyAuthorBinding, applyCanonicalBinding, applyCenteredPosition, applyDescriptionBinding, applyFaviconOverlay, applyGlobalPosition, applyHeadBinding, applyHeadTitleBinding, applyHeadTitleMarker, applyHostListener, applyHostListeners, applyInitialFocus, applyKeywordsBinding, applyLinkBinding, applyMetaBinding, applyNextBinding, applyOgBinding, applyOpenGraphBindings, applyPrevBinding, applyResourceHintsBindings, applyRobotsBinding, applySocialMediaBindings, applyStructuredDataBinding, applyTwitterCardBindings, areScrollStatesEqual, bindProps, boolBreakpointTransform, booleanBreakpointAttribute, boundingClientRectToElementRect, breakpointTransformBase, buildElementSignal, buildSignalEffects, canUseSessionMemory, clamp, clone, cloneFormGroup, computedTillFalsy, computedTillTruthy, controlValueSignal, controlValueSignalWithPrevious, copyToClipboard, createAnchoredPositionCleanup, createArrayPropertyBinding, createAutoSessionMemoryKey, createBulkPropertyBinding, createCanAnimateSignal, createComponentId, createCssColorThemeName, createCssSurfaceName, createDependencyStash, createDestroy, createDocumentElementSignal, createElementDictionary, createElementDimensions, createEmptyElementSignal, createFlipAnimation, createFlipAnimationGroup, createHostProps, createIsRenderedSignal, createLogger, createOverlayRuntimeRef, createPropHandlers, createPropertyBinding, createProps, createRootThemeCss, createRoute, createRouterState, createRxHostListener, createSessionMemory, createSetup, createSwatchCss, createSwipeTracker, createTailwindColorThemes, createTailwindCssVar, createTailwindRgbVar, createThemeStyle, createUnsavedChangesGuard, createUnsavedChangesTabLock, createUnsavedChangesTracker, createUserConsentProvider, deferredSignal, defineLabels, defineProvider, defineRootProvider, defineStaticProvider, defineStaticRootProvider, deleteCookie, dragGestureFrom, easeElastic, easeIn, easeInOut, easeLinear, easeOut, easeOutBack, easeOutBackStrong, elementCanScroll, enableAnchoredOverlayPositionExtras, equal, firstElementSignal, focusElement, forceReflow, formatRuntimeError, fromNextFrame, getCookie, getDomain, getElementScrollCoordinates, getFocusableElements, getFormGroupValue, getGroupMatchPoints, getGroupMatchScore, getHeadingElement, getKnockoutMatchScore, getMatchScoreSubLine, getObjectProperty, getScrollContainerTarget, getScrollItemTarget, getScrollSnapTarget, hasCookie, holdScrollRestoration, htmlToMarkdown, inferMimeType, initials, injectAngularRootElement, injectAnimatedBlockSize, injectBoundaryElement, injectBreakpointInput, injectBreakpointIsMatched, injectBreakpointObserver, injectCanHover, injectColorThemes, injectColorThemesPrefix, injectCurrentBreakpoint, injectDefaultColorTheme, injectDeviceInputType, injectDisplayOrientation, injectErrorTheme, injectFaviconStore, injectFocusVisibleTracker, injectFragment, injectHasPrecisionInput, injectHasTouchInput, injectHostElement, injectIs2Xl, injectIsDocumentVisible, injectIsLandscape, injectIsLg, injectIsMd, injectIsPortrait, injectIsRouterInitialized, injectIsSm, injectIsXl, injectIsXs, injectLinkStore, injectLinkStoreConfig, injectLocale, injectMediaQueryIsMatched, injectMetaConfig, injectMetaStore, injectNotifications, injectObserveBreakpoint, injectObserveMediaQuery, injectOverlayRuntime, injectPathParam, injectPathParamChanges, injectPathParams, injectPrefersReducedMotion, injectQueryParam, injectQueryParamChanges, injectQueryParams, injectRenderer, injectRoute, injectRouteData, injectRouteDataItem, injectRouteTitle, injectRouterEvent, injectRouterNavigationState, injectRouterState, injectScrollbarDimensions, injectStructuredDataConfig, injectStructuredDataStore, injectStyleManager, injectSuccessTheme, injectSurfaceContextTracker, injectSurfaceThemes, injectSurfaceThemesPrefix, injectTemplateRef, injectTitleConfig, injectTitleStore, injectUnsavedChangesCoordinator, injectUrl, injectViewportConfig, injectViewportDimensions, injectViewportSize, injectWarningTheme, isAnimationDebugEnabled, isArray, isElementSignal, isElementVisible, isFocusable, isGroupMatch, isHTMLElement, isKnockoutMatch, isObject, markdownToHtml, matchesReducedMotion, maybeSignalValue, memoizeSignal, nextFrame, normalizeGameResultType, normalizeMatchParticipant, normalizeMatchParticipants, normalizeMatchScore, normalizeMatchState, normalizeMatchType, normalizeUnsavedChangesSource, numberBreakpointAttribute, numberBreakpointTransform, previousSignalValue, provideBoundaryElement, provideBreakpointInstance, provideBreakpointObserver, provideColorThemes, provideColorThemesWithTailwind4, provideFaviconStore, provideFocusVisibleTracker, provideLinkStore, provideLinkStoreConfig, provideLocale, provideMetaConfig, provideMetaStore, provideNotifications, provideOverlayRuntime, provideRenderer, provideStructuredDataConfig, provideStructuredDataStore, provideStyleManager, provideSurfaceContextTracker, provideSurfaceThemesWithTailwind4, provideTitleConfig, provideTitleStore, provideUnsavedChangesCoordinator, provideViewportConfig, randomId, readFromClipboard, registerAnchoredPositionMiddlewareExtras, registerAnchoredPositionSetup, resetPositioningStyles, resolveAppRootColorProvider, resolveSurfaceByElevation, round, routerDisableScrollTop, scrollToElement, setBackdropStyles, setBaseElementStyles, setCookie, setInputSignal, setupFocusTrap, setupPositioning, setupScrollRestoration, signalAnimatedNumber, signalAttributes, signalClasses, signalElementChildren, signalElementDimensions, signalElementIntersection, signalElementLastScrollDirection, signalElementMutations, signalElementScrollState, signalHostAttributes, signalHostClasses, signalHostElementDimensions, signalHostElementIntersection, signalHostElementLastScrollDirection, signalHostElementMutations, signalHostElementScrollState, signalHostStyles, signalIsRendered, signalStyles, slugify, switchQueryListChanges, syncSignal, templateComputed, toArray, toArrayTrackByFn, toInjectFn, toProvideFn, toStringBinding, toToken, transformOrReturn, typedBreakpointTransform, unbindProps, useCursorDragScroll, writeScrollbarSizeToCssVariables, writeViewportSizeToCssVariables, ɵProvideColorThemes, ɵProvideColorThemesPrefix, ɵProvideSurfaceThemes, ɵProvideSurfaceThemesPrefix };
3497
+ export type { AlternateLanguagesConfig, AnchoredPositionMiddlewareExtras, AnchoredPositionSetup, AngularRenderer, AnimatedBlockSizeConfig, AnimatedLifecycleState, AnimatedNumberSignal, AnimatedSizeAxis, AnimationEndEvent, AnyTemplateType, ArticleConfig, BindPropsOptions, BoolBreakpointSignal, Breakpoint, BreakpointInput, BreakpointMap, BuildMediaQueryOptions, BuildSignalEffectsConfig, ColorTheme, ColorThemeType, ComponentTemplate, ComponentType, ComponentTypeWithInputs, ConsentHandler, ControlValueSignalOptions, CreateLoggerConfig, CreatePropsOptions, CreateSessionMemoryConfig, CreateUnsavedChangesGuardConfig, CreateUnsavedChangesTabLockConfig, CreateUnsavedChangesTrackerConfig, CreateUserConsentProviderOptions, CurrentElementVisibility, CursorDragScrollDirection, CursorDragScrollOptions, DragGestureEvent, DragMoveEvent, DragStartEvent, ElementDimensions, ElementLastScrollDirection, ElementLastScrollDirectionType, ElementRect, ElementScrollState, ElementSignal, ElementSignalValue, ElementSize, EthleteColorThemeNameRegistry, EthleteSurfaceThemeNameRegistry, FaviconOverlay, FlipAnimationConfig, HeadBinding, HostProps, InjectFn, InjectQueryParamConfig, InjectUtilConfig, InjectUtilTransformConfig, IntersectionObserverEntryWithDetails, IsElementVisibleOptions, LabelsDefinition, LabelsSource, LinkConfig, LinkStoreConfig, LogicalSize, MaybeSignal, MetaConfig, MetaTagConfig, NgClassType, NgTemplateTemplate, NormalizedGameResultType, NormalizedMatchParticipant, NormalizedMatchParticipants, NormalizedMatchScore, NormalizedUnsavedChangesSource, NotificationActionConfig, NotificationClickContext, NotificationClickMessage, NotificationDeliveryPath, NotificationPermissionState, NotificationRef, Notifications, NullableElementDimensions, NumberBreakpointSignal, OnThemeColorMap, OpenGraphConfig, OverlayRuntimeAnchoredPosition, OverlayRuntimeAnimationDelegate, OverlayRuntimeAnimationDelegateEnterContext, OverlayRuntimeAnimationDelegateLeaveContext, OverlayRuntimeAutoFocusTarget, OverlayRuntimeCenteredPosition, OverlayRuntimeCloseEvent, OverlayRuntimeCloseGuard, OverlayRuntimeCloseSource, OverlayRuntimeComponentBase, OverlayRuntimeElements, OverlayRuntimeGlobalPosition, OverlayRuntimeGlobalPositionAlignment, OverlayRuntimeMountConfig, OverlayRuntimePositionStrategy, OverlayRuntimeRef, OverlayRuntimeRole, OverlayRuntimeShiftOptions, OverlayRuntimeState, PropHandlers, Props, PropsAttachedElements, PropsAttachedElementsInternal, PropsInternal, ProviderDefinition, ProviderDefinitionOptions, RegisteredColorThemeName, RegisteredSurfaceThemeName, ResizeEdge, ResizeMoveEvent, ResourceHintsConfig, RobotsConfig, RouterDisableScrollTopConfig, RouterState, ScrollContainerTarget, ScrollItemTarget, ScrollRestorationRestoreConfig, ScrollRestorationScrollElement, ScrollSnapOrigin, ScrollSnapTarget, ScrollToElementOptions, SetupScrollRestorationConfig, ShowNotificationConfig, SignalAnimatedNumberOptions, SignalElementBindingComplexType, SignalElementBindingType, SignalElementChildrenOptions, SignalElementIntersectionOptions, SignalElementScrollStateOptions, SocialMediaConfig, StaticProviderDefinition, StringTemplate, StructuredDataConfig, StyleManager, SurfaceContextEntry, SurfaceContextSurface, SurfaceContextTracker, SurfaceInteractionColor, SurfaceTheme, SurfaceThemeColor, SurfaceType, SwipeEndEvent, SwipeTracker, SwipeUpdateEvent, SyncSignalOptions, TemplateRefWithContext, ThemeColor, ThemeColorMap, ThemeHSLColor, ThemeInkColorMap, ThemeRGBColor, ThemeSwatch, TitleConfig, TitlePart, Translatable, TwitterCardConfig, TypedBreakpointSignal, UnbindPropsOptions, UnsavedChangesAbandonReason, UnsavedChangesConfirmContext, UnsavedChangesConfirmFn, UnsavedChangesGuardRef, UnsavedChangesRegistration, UnsavedChangesSource, UnsavedChangesTabConfig, UnsavedChangesTabLockRef, UnsavedChangesTrackerRef, ValidateAtLeastOneRequiredConfig, Vec2, ViewportConfig };