@testgorilla/tgo-ui 7.2.10 → 7.4.0

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.
Files changed (43) hide show
  1. package/components/ai-audio-circle/ai-audio-circle.component.d.ts +2 -1
  2. package/components/autocomplete-v2/autocomplete-overflow-detect.directive.d.ts +21 -0
  3. package/components/autocomplete-v2/autocomplete-v2-filter.service.d.ts +24 -0
  4. package/components/autocomplete-v2/autocomplete-v2-utils.d.ts +18 -0
  5. package/components/autocomplete-v2/autocomplete-v2-value-manager.d.ts +27 -0
  6. package/components/autocomplete-v2/autocomplete-v2.component.d.ts +119 -0
  7. package/components/autocomplete-v2/autocomplete-v2.model.d.ts +12 -0
  8. package/components/autocomplete-v2/index.d.ts +5 -0
  9. package/components/autocomplete-v2/infinite-scroll.directive.d.ts +21 -0
  10. package/components/autocomplete-v2/public-api.d.ts +7 -0
  11. package/components/core/directives/index.d.ts +2 -0
  12. package/components/core/directives/prevent-input.directive.d.ts +7 -0
  13. package/components/core/directives/select-text.directive.d.ts +10 -0
  14. package/components/core/pipes/includes.pipe.d.ts +7 -0
  15. package/components/core/pipes/index.d.ts +2 -0
  16. package/components/core/pipes/transform-item.pipe.d.ts +8 -0
  17. package/components/core/public-api.d.ts +2 -1
  18. package/components/validation-error/validation-error.component.d.ts +5 -1
  19. package/fesm2022/testgorilla-tgo-ui-components-ai-audio-circle.mjs +67 -53
  20. package/fesm2022/testgorilla-tgo-ui-components-ai-audio-circle.mjs.map +1 -1
  21. package/fesm2022/testgorilla-tgo-ui-components-autocomplete-v2.mjs +805 -0
  22. package/fesm2022/testgorilla-tgo-ui-components-autocomplete-v2.mjs.map +1 -0
  23. package/fesm2022/testgorilla-tgo-ui-components-autocomplete.mjs +1 -1
  24. package/fesm2022/testgorilla-tgo-ui-components-autocomplete.mjs.map +1 -1
  25. package/fesm2022/testgorilla-tgo-ui-components-checkbox.mjs +1 -1
  26. package/fesm2022/testgorilla-tgo-ui-components-checkbox.mjs.map +1 -1
  27. package/fesm2022/testgorilla-tgo-ui-components-core.mjs +123 -28
  28. package/fesm2022/testgorilla-tgo-ui-components-core.mjs.map +1 -1
  29. package/fesm2022/testgorilla-tgo-ui-components-datepicker.mjs +1 -1
  30. package/fesm2022/testgorilla-tgo-ui-components-datepicker.mjs.map +1 -1
  31. package/fesm2022/testgorilla-tgo-ui-components-dropdown.mjs +1 -1
  32. package/fesm2022/testgorilla-tgo-ui-components-dropdown.mjs.map +1 -1
  33. package/fesm2022/testgorilla-tgo-ui-components-field.mjs +1 -1
  34. package/fesm2022/testgorilla-tgo-ui-components-field.mjs.map +1 -1
  35. package/fesm2022/testgorilla-tgo-ui-components-multi-input.mjs +1 -1
  36. package/fesm2022/testgorilla-tgo-ui-components-multi-input.mjs.map +1 -1
  37. package/fesm2022/testgorilla-tgo-ui-components-phone-input.mjs +1 -1
  38. package/fesm2022/testgorilla-tgo-ui-components-phone-input.mjs.map +1 -1
  39. package/fesm2022/testgorilla-tgo-ui-components-validation-error.mjs +21 -3
  40. package/fesm2022/testgorilla-tgo-ui-components-validation-error.mjs.map +1 -1
  41. package/mcp/catalog.json +1 -1
  42. package/package.json +21 -17
  43. package/components/core/select-text.directive.d.ts +0 -19
@@ -3,7 +3,8 @@ import * as i0 from "@angular/core";
3
3
  export declare enum InterviewState {
4
4
  CandidateSpeaking = "candidate-speaking",
5
5
  AiListening = "ai-listening",
6
- AiSpeaking = "ai-speaking"
6
+ AiSpeaking = "ai-speaking",
7
+ Static = "static"
7
8
  }
8
9
  export declare class AiAudioCircleComponent implements OnDestroy, AfterViewInit {
9
10
  pulseCanvasRef?: ElementRef<HTMLCanvasElement>;
@@ -0,0 +1,21 @@
1
+ import { AfterViewInit, OnDestroy } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export declare class AutocompleteOverflowDetectDirective implements AfterViewInit, OnDestroy {
4
+ measureContainer: import("@angular/core").InputSignal<HTMLElement | undefined>;
5
+ itemSelector: import("@angular/core").InputSignal<string>;
6
+ reserveWidth: import("@angular/core").InputSignal<number>;
7
+ visibleCount: import("@angular/core").WritableSignal<number>;
8
+ overflowCount: import("@angular/core").WritableSignal<number>;
9
+ hasMeasured: import("@angular/core").WritableSignal<boolean>;
10
+ tagMaxWidth: import("@angular/core").WritableSignal<number | null>;
11
+ private resizeObserver;
12
+ private rafId;
13
+ private readonly el;
14
+ private readonly ngZone;
15
+ ngAfterViewInit(): void;
16
+ setupObserver(containerSelector: string): void;
17
+ measure(): void;
18
+ ngOnDestroy(): void;
19
+ static ɵfac: i0.ɵɵFactoryDeclaration<AutocompleteOverflowDetectDirective, never>;
20
+ static ɵdir: i0.ɵɵDirectiveDeclaration<AutocompleteOverflowDetectDirective, "[uiAutocompleteOverflowDetect]", ["autocompleteOverflowDetect"], { "measureContainer": { "alias": "measureContainer"; "required": false; "isSignal": true; }; "itemSelector": { "alias": "itemSelector"; "required": false; "isSignal": true; }; "reserveWidth": { "alias": "reserveWidth"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
21
+ }
@@ -0,0 +1,24 @@
1
+ import { OnDestroy } from '@angular/core';
2
+ import { BehaviorSubject, Observable, ReplaySubject } from 'rxjs';
3
+ import { AutocompleteGroup } from './autocomplete-v2.component';
4
+ import * as i0 from "@angular/core";
5
+ export declare class AutocompleteFilterService<T extends Record<string, any> = Record<string, any>> implements OnDestroy {
6
+ readonly textField: import("@angular/core").WritableSignal<string>;
7
+ readonly flatItems: import("@angular/core").WritableSignal<T[]>;
8
+ readonly groupsList: import("@angular/core").WritableSignal<AutocompleteGroup<T>[]>;
9
+ readonly suggestions: import("@angular/core").WritableSignal<T[]>;
10
+ readonly searchText$: BehaviorSubject<string>;
11
+ readonly userInput$: ReplaySubject<string>;
12
+ readonly isSearching$: Observable<boolean>;
13
+ private readonly dynamicSource$;
14
+ private isDynamicMode;
15
+ filteredItems$: Observable<T[] | null>;
16
+ readonly filteredGroupedItems$: Observable<any[] | null>;
17
+ readonly filteredSuggestions$: Observable<T[] | null>;
18
+ search(text: string, minChars: number): void;
19
+ clearSearch(): void;
20
+ ngOnDestroy(): void;
21
+ setDynamicResults(list: T[] | null, loading: boolean): void;
22
+ static ɵfac: i0.ɵɵFactoryDeclaration<AutocompleteFilterService<any>, never>;
23
+ static ɵprov: i0.ɵɵInjectableDeclaration<AutocompleteFilterService<any>>;
24
+ }
@@ -0,0 +1,18 @@
1
+ type Item = Record<string, unknown>;
2
+ export declare class AutocompleteV2Utils {
3
+ static transformDisplayValue<T extends Item>(value: T | null | undefined, textField: string): string;
4
+ static filterItems<T extends Item>(items: T[], inputValue: string, textField: string): T[];
5
+ static filterGroupedItems<T extends Item>(groups: {
6
+ groupName: string;
7
+ items: T[];
8
+ }[], inputValue: string, textField: string): {
9
+ groupName: string;
10
+ items: T[];
11
+ filteredItems: T[];
12
+ }[];
13
+ static excludeSuggestions<T extends Item>(items: T[], excludeItems: T[], valueField: string): T[];
14
+ static createValueItem<T extends Item>(value: T | string, textField: string, valueField: string): T;
15
+ static findDuplicate<T extends Item>(items: T[], selectedValue: T, lookupKey: string): T | undefined;
16
+ static isArray(value: unknown): value is unknown[];
17
+ }
18
+ export {};
@@ -0,0 +1,27 @@
1
+ import { AutocompleteType } from './autocomplete-v2.model';
2
+ import * as i0 from "@angular/core";
3
+ export declare class AutocompleteValueManager<T extends Record<string, any> = Record<string, any>> {
4
+ readonly type: import("@angular/core").WritableSignal<AutocompleteType>;
5
+ readonly textField: import("@angular/core").WritableSignal<string>;
6
+ readonly valueField: import("@angular/core").WritableSignal<string>;
7
+ readonly compareWith: import("@angular/core").WritableSignal<((a: T, b: T) => boolean) | undefined>;
8
+ readonly value: import("@angular/core").WritableSignal<T | T[] | null>;
9
+ readonly isSingle: import("@angular/core").Signal<boolean>;
10
+ readonly displayValue: import("@angular/core").Signal<string>;
11
+ private onChangeFn;
12
+ private onTouchedFn;
13
+ registerOnChange(fn: (value: T | T[] | null) => void): void;
14
+ registerOnTouched(fn: () => void): void;
15
+ notifyChange(): void;
16
+ markAsTouched(): void;
17
+ writeValue(v: T | T[] | null): void;
18
+ addValue(newValue: T): void;
19
+ /**
20
+ * Removes `option` from the value array.
21
+ * Returns the found item (so the caller can deselect the mat-option), or undefined if not found.
22
+ */
23
+ removeValue(option: T): T | undefined;
24
+ clear(): void;
25
+ static ɵfac: i0.ɵɵFactoryDeclaration<AutocompleteValueManager<any>, never>;
26
+ static ɵprov: i0.ɵɵInjectableDeclaration<AutocompleteValueManager<any>>;
27
+ }
@@ -0,0 +1,119 @@
1
+ import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
2
+ import { AfterViewInit, DoCheck, ElementRef, OnDestroy } from '@angular/core';
3
+ import { ControlValueAccessor, NgControl } from '@angular/forms';
4
+ import { MatAutocomplete, MatAutocompleteSelectedEvent, MatAutocompleteTrigger } from '@angular/material/autocomplete';
5
+ import { ApplicationTheme } from '@testgorilla/tgo-ui/components/core';
6
+ import { AutocompleteFilterService } from './autocomplete-v2-filter.service';
7
+ import { AutocompleteV2Utils } from './autocomplete-v2-utils';
8
+ import { AutocompleteValueManager } from './autocomplete-v2-value-manager';
9
+ import { Autocomplete, AutocompleteSize, AutocompleteType } from './autocomplete-v2.model';
10
+ import { AutocompleteOverflowDetectDirective } from './autocomplete-overflow-detect.directive';
11
+ import * as i0 from "@angular/core";
12
+ export interface AutocompleteGroup<T extends Record<string, any> = Record<string, any>> {
13
+ groupName: string;
14
+ items: T[];
15
+ }
16
+ export declare class AutocompleteV2Component<T extends Record<string, any> = Record<string, any>> implements ControlValueAccessor, AfterViewInit, DoCheck, OnDestroy {
17
+ itemsList: import("@angular/core").InputSignal<T[]>;
18
+ suggestionsList: import("@angular/core").InputSignal<T[]>;
19
+ groupsList: import("@angular/core").InputSignal<AutocompleteGroup<T>[]>;
20
+ disabled: import("@angular/core").InputSignal<boolean>;
21
+ allowAdd: import("@angular/core").InputSignal<boolean>;
22
+ textField: import("@angular/core").InputSignal<string>;
23
+ valueField: import("@angular/core").InputSignal<string>;
24
+ label: import("@angular/core").InputSignal<string>;
25
+ placeholder: import("@angular/core").InputSignal<string>;
26
+ type: import("@angular/core").InputSignal<AutocompleteType>;
27
+ minCharactersSearch: import("@angular/core").InputSignal<number>;
28
+ variant: import("@angular/core").InputSignal<"autocomplete" | "dropdown">;
29
+ showBottomContent: import("@angular/core").InputSignal<boolean>;
30
+ required: import("@angular/core").InputSignal<boolean | undefined>;
31
+ virtualScroll: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
32
+ compareWith: import("@angular/core").InputSignal<((a: T, b: T) => boolean) | undefined>;
33
+ dropdownPanelClass: import("@angular/core").InputSignal<string>;
34
+ closeOnScroll: import("@angular/core").InputSignal<boolean>;
35
+ size: import("@angular/core").InputSignal<AutocompleteSize>;
36
+ allowUserInput: import("@angular/core").InputSignal<boolean>;
37
+ clearable: import("@angular/core").InputSignal<boolean>;
38
+ maxLength: import("@angular/core").InputSignal<number | undefined>;
39
+ dynamicFilterLoading: import("@angular/core").InputSignal<boolean>;
40
+ dynamicFilteredList: import("@angular/core").InputSignal<T[] | null>;
41
+ infiniteScroll: import("@angular/core").InputSignal<boolean>;
42
+ hasMoreOptionsForInfiniteScroll: import("@angular/core").InputSignal<boolean>;
43
+ itemValue: import("@angular/core").InputSignal<T | T[] | null>;
44
+ formErrorConfig: import("@angular/core").InputSignal<Record<string, string>>;
45
+ errors: import("@angular/core").InputSignal<string[]>;
46
+ selectionChange: import("@angular/core").OutputEmitterRef<T | T[]>;
47
+ searchTextChange: import("@angular/core").OutputEmitterRef<string>;
48
+ blur: import("@angular/core").OutputEmitterRef<void>;
49
+ focus: import("@angular/core").OutputEmitterRef<void>;
50
+ scrollViewportBottomReached: import("@angular/core").OutputEmitterRef<void>;
51
+ scrollViewportBottomReachedFiltered: import("@angular/core").OutputEmitterRef<void>;
52
+ formFieldElement: ElementRef<HTMLElement>;
53
+ tagContainer: ElementRef<HTMLElement>;
54
+ protected measureElRef?: ElementRef<HTMLElement>;
55
+ overflowDir?: AutocompleteOverflowDetectDirective;
56
+ autocomplete: MatAutocompleteTrigger;
57
+ set cdkViewport(viewport: CdkVirtualScrollViewport);
58
+ matAutocomplete: MatAutocomplete;
59
+ matInput: ElementRef<HTMLInputElement>;
60
+ protected readonly valueManager: AutocompleteValueManager<T>;
61
+ protected readonly filterService: AutocompleteFilterService<T>;
62
+ private readonly scrollManager;
63
+ private readonly cdr;
64
+ private readonly focusMonitor;
65
+ private readonly destroyRef;
66
+ private readonly ngZone;
67
+ readonly ngControl: NgControl | null;
68
+ protected readonly applicationTheme: ApplicationTheme;
69
+ protected inputValue: import("@angular/core").WritableSignal<string>;
70
+ protected isInputFocus: import("@angular/core").WritableSignal<boolean>;
71
+ protected autocompleteType: typeof Autocomplete;
72
+ /** Flat list for default (ungrouped) rendering and virtual scroll */
73
+ protected flatItemsList: import("@angular/core").Signal<T[]>;
74
+ /** Grouped list — only used when isGrouped is true */
75
+ protected groupedItemsList: import("@angular/core").Signal<{
76
+ groupName: string;
77
+ items: T[];
78
+ }[]>;
79
+ protected _isDisabled: import("@angular/core").WritableSignal<boolean>;
80
+ protected translationContext: string;
81
+ protected readonly utils: typeof AutocompleteV2Utils;
82
+ protected keyboardFocused: import("@angular/core").WritableSignal<boolean>;
83
+ protected isAlreadyAdded: import("@angular/core").Signal<boolean>;
84
+ protected showClearButton: import("@angular/core").Signal<any>;
85
+ protected safeErrors: import("@angular/core").Signal<string[]>;
86
+ private controlInvalid;
87
+ protected hasError: import("@angular/core").Signal<boolean>;
88
+ protected hiddenItemsTooltip: import("@angular/core").Signal<string>;
89
+ constructor();
90
+ /**
91
+ * Used to mark component view as dirty when touched programmatically with markAsTouched/markAllAsTouched or errors
92
+ * to display validation errors that might happen (e.g. required)
93
+ */
94
+ ngDoCheck(): void;
95
+ ngAfterViewInit(): void;
96
+ ngOnDestroy(): void;
97
+ registerOnChange(fn: any): void;
98
+ registerOnTouched(fn: any): void;
99
+ setDisabledState(isDisabled: boolean): void;
100
+ writeValue(value: T | T[] | null): void;
101
+ protected get isGrouped(): boolean;
102
+ protected onOptionSelected(event: MatAutocompleteSelectedEvent): void;
103
+ protected onOptionRemoved(option: T): void;
104
+ protected onInputChange(event: Event): void;
105
+ protected onClear(): void;
106
+ protected onBlur(): void;
107
+ protected onPanelOpened(): void;
108
+ protected onScrollBottom(): void;
109
+ protected onFocus(): void;
110
+ private onUpdate;
111
+ protected get isDropdown(): boolean;
112
+ protected onChevronClick(autocomplete: MatAutocomplete): void;
113
+ protected trackByFn: (index: number, value: string) => string;
114
+ protected trackByItem: (_index: number, item: T) => any;
115
+ onKeydown($event: KeyboardEvent): void;
116
+ protected getVirtualScrollHeight(itemCount: number): number;
117
+ static ɵfac: i0.ɵɵFactoryDeclaration<AutocompleteV2Component<any>, never>;
118
+ static ɵcmp: i0.ɵɵComponentDeclaration<AutocompleteV2Component<any>, "ui-autocomplete-v2", never, { "itemsList": { "alias": "itemsList"; "required": false; "isSignal": true; }; "suggestionsList": { "alias": "suggestionsList"; "required": false; "isSignal": true; }; "groupsList": { "alias": "groupsList"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "allowAdd": { "alias": "allowAdd"; "required": false; "isSignal": true; }; "textField": { "alias": "textField"; "required": false; "isSignal": true; }; "valueField": { "alias": "valueField"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "minCharactersSearch": { "alias": "minCharactersSearch"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": true; "isSignal": true; }; "showBottomContent": { "alias": "showBottomContent"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "virtualScroll": { "alias": "virtualScroll"; "required": false; "isSignal": true; }; "compareWith": { "alias": "compareWith"; "required": false; "isSignal": true; }; "dropdownPanelClass": { "alias": "dropdownPanelClass"; "required": false; "isSignal": true; }; "closeOnScroll": { "alias": "closeOnScroll"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "allowUserInput": { "alias": "allowUserInput"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "maxLength": { "alias": "maxLength"; "required": false; "isSignal": true; }; "dynamicFilterLoading": { "alias": "dynamicFilterLoading"; "required": false; "isSignal": true; }; "dynamicFilteredList": { "alias": "dynamicFilteredList"; "required": false; "isSignal": true; }; "infiniteScroll": { "alias": "infiniteScroll"; "required": false; "isSignal": true; }; "hasMoreOptionsForInfiniteScroll": { "alias": "hasMoreOptionsForInfiniteScroll"; "required": false; "isSignal": true; }; "itemValue": { "alias": "itemValue"; "required": false; "isSignal": true; }; "formErrorConfig": { "alias": "formErrorConfig"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; }, { "selectionChange": "selectionChange"; "searchTextChange": "searchTextChange"; "blur": "blur"; "focus": "focus"; "scrollViewportBottomReached": "scrollViewportBottomReached"; "scrollViewportBottomReachedFiltered": "scrollViewportBottomReachedFiltered"; }, never, never, true, never>;
119
+ }
@@ -0,0 +1,12 @@
1
+ export type AutocompleteType = 'single' | 'multi' | 'large';
2
+ export declare enum Autocomplete {
3
+ SINGLE = "single",
4
+ MULTI = "multi",
5
+ LARGE = "large"
6
+ }
7
+ export declare enum DropdownVariation {
8
+ AUTOCOMPLETE = "autocomplete",
9
+ DROPDOWN = "dropdown"
10
+ }
11
+ export type DropdownVariationType = `${DropdownVariation}`;
12
+ export type AutocompleteSize = 'small' | 'medium';
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ /// <amd-module name="@testgorilla/tgo-ui/components/autocomplete-v2" />
5
+ export * from './public-api';
@@ -0,0 +1,21 @@
1
+ import { OnDestroy } from '@angular/core';
2
+ import { MatAutocompleteTrigger } from '@angular/material/autocomplete';
3
+ import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
4
+ import * as i0 from "@angular/core";
5
+ export declare class InfiniteScrollDirective implements OnDestroy {
6
+ private viewport;
7
+ private scrollSub;
8
+ private destroyRef;
9
+ private scrollListener;
10
+ enabled: boolean;
11
+ closeOnScroll: boolean;
12
+ panelTrigger: MatAutocompleteTrigger | null;
13
+ onBottomReached: (() => void) | null;
14
+ attachViewport(viewport: CdkVirtualScrollViewport | undefined): void;
15
+ detachViewport(): void;
16
+ scrollToTop(): void;
17
+ startCloseOnScroll(): void;
18
+ ngOnDestroy(): void;
19
+ static ɵfac: i0.ɵɵFactoryDeclaration<InfiniteScrollDirective, never>;
20
+ static ɵprov: i0.ɵɵInjectableDeclaration<InfiniteScrollDirective>;
21
+ }
@@ -0,0 +1,7 @@
1
+ export * from './autocomplete-v2.component';
2
+ export * from './autocomplete-v2.model';
3
+ export { AutocompleteV2Utils } from './autocomplete-v2-utils';
4
+ export { AutocompleteValueManager } from './autocomplete-v2-value-manager';
5
+ export { AutocompleteFilterService } from './autocomplete-v2-filter.service';
6
+ export { AutocompleteOverflowDetectDirective } from './autocomplete-overflow-detect.directive';
7
+ export { ApplicationTheme } from '@testgorilla/tgo-ui/components/core';
@@ -0,0 +1,2 @@
1
+ export { SelectTextDirective } from './select-text.directive';
2
+ export { PreventInputDirective } from './prevent-input.directive';
@@ -0,0 +1,7 @@
1
+ import * as i0 from "@angular/core";
2
+ export declare class PreventInputDirective {
3
+ uiPreventInput: import("@angular/core").InputSignal<boolean>;
4
+ onKeyDown(event: KeyboardEvent): void;
5
+ static ɵfac: i0.ɵɵFactoryDeclaration<PreventInputDirective, never>;
6
+ static ɵdir: i0.ɵɵDirectiveDeclaration<PreventInputDirective, "[uiPreventInput]", never, { "uiPreventInput": { "alias": "uiPreventInput"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
7
+ }
@@ -0,0 +1,10 @@
1
+ import * as i0 from "@angular/core";
2
+ export declare class SelectTextDirective {
3
+ selectText: import("@angular/core").InputSignal<string | null>;
4
+ private el;
5
+ private highlighted;
6
+ constructor();
7
+ private highlight;
8
+ static ɵfac: i0.ɵɵFactoryDeclaration<SelectTextDirective, never>;
9
+ static ɵdir: i0.ɵɵDirectiveDeclaration<SelectTextDirective, "[selectText]", never, { "selectText": { "alias": "selectText"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
10
+ }
@@ -0,0 +1,7 @@
1
+ import { PipeTransform } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export declare class IncludesPipe implements PipeTransform {
4
+ transform(value: Record<string, any>, values: Record<string, any> | Record<string, any>[], valueField?: string): boolean;
5
+ static ɵfac: i0.ɵɵFactoryDeclaration<IncludesPipe, never>;
6
+ static ɵpipe: i0.ɵɵPipeDeclaration<IncludesPipe, "includes", true>;
7
+ }
@@ -0,0 +1,2 @@
1
+ export { IncludesPipe } from './includes.pipe';
2
+ export { TransformItemPipe } from './transform-item.pipe';
@@ -0,0 +1,8 @@
1
+ import { PipeTransform } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export declare class TransformItemPipe implements PipeTransform {
4
+ transform(value: Record<string, any> | Record<string, any>[] | null | undefined, field: string, getValueList: true): string[];
5
+ transform(value: Record<string, any> | Record<string, any>[] | null | undefined, field: string, getValueList?: false): string;
6
+ static ɵfac: i0.ɵɵFactoryDeclaration<TransformItemPipe, never>;
7
+ static ɵpipe: i0.ɵɵPipeDeclaration<TransformItemPipe, "transformItem", true>;
8
+ }
@@ -9,7 +9,8 @@ export * from './hex-to-rgb';
9
9
  export * from './autocomplete-utils';
10
10
  export * from './digits-only.directive';
11
11
  export * from './has-validation-error.pipe';
12
- export * from './select-text.directive';
12
+ export * from './directives';
13
+ export * from './pipes';
13
14
  export * from './is-mobile';
14
15
  export * from './is-large-tablet';
15
16
  export * from './screen-breakpoints.model';
@@ -15,8 +15,12 @@ export declare class ValidationErrorComponent {
15
15
  * @memberof ValidationErrorComponent
16
16
  */
17
17
  applicationTheme: ApplicationTheme;
18
+ /** Maps validator error keys to display message templates. Supports {{placeholder}} interpolation. */
19
+ customErrors: Record<string, string>;
18
20
  getErrorValue(type: errorType): number;
21
+ get customErrorKeys(): string[];
22
+ resolveErrorMessage(key: string): string;
19
23
  translationContextErrors: string;
20
24
  static ɵfac: i0.ɵɵFactoryDeclaration<ValidationErrorComponent, never>;
21
- static ɵcmp: i0.ɵɵComponentDeclaration<ValidationErrorComponent, "ui-validation-error", never, { "ngControl": { "alias": "ngControl"; "required": false; }; "touchedOn": { "alias": "touchedOn"; "required": false; }; "errorMessage": { "alias": "errorMessage"; "required": false; }; "label": { "alias": "label"; "required": false; }; "applicationTheme": { "alias": "applicationTheme"; "required": false; }; }, {}, never, never, false, never>;
25
+ static ɵcmp: i0.ɵɵComponentDeclaration<ValidationErrorComponent, "ui-validation-error", never, { "ngControl": { "alias": "ngControl"; "required": false; }; "touchedOn": { "alias": "touchedOn"; "required": false; }; "errorMessage": { "alias": "errorMessage"; "required": false; }; "label": { "alias": "label"; "required": false; }; "applicationTheme": { "alias": "applicationTheme"; "required": false; }; "customErrors": { "alias": "customErrors"; "required": false; }; }, {}, never, never, false, never>;
22
26
  }
@@ -8,6 +8,7 @@ var InterviewState;
8
8
  InterviewState["CandidateSpeaking"] = "candidate-speaking";
9
9
  InterviewState["AiListening"] = "ai-listening";
10
10
  InterviewState["AiSpeaking"] = "ai-speaking";
11
+ InterviewState["Static"] = "static";
11
12
  })(InterviewState || (InterviewState = {}));
12
13
  class AiAudioCircleComponent {
13
14
  constructor() {
@@ -204,7 +205,10 @@ class AiAudioCircleComponent {
204
205
  mainLoop() {
205
206
  this.simTime += 0.05;
206
207
  const currentStateValue = this.state();
207
- if (currentStateValue === InterviewState.AiSpeaking) {
208
+ if (currentStateValue === InterviewState.Static) {
209
+ // Static: no amplitude updates — the render locks scale at 1.0
210
+ }
211
+ else if (currentStateValue === InterviewState.AiSpeaking) {
208
212
  if (this.analyser && this.dataArray) {
209
213
  // Use real audio amplitude (already handled in analyzeAudio)
210
214
  }
@@ -242,8 +246,14 @@ class AiAudioCircleComponent {
242
246
  const isListening = currentStateValue === InterviewState.AiListening;
243
247
  const isCandidate = currentStateValue === InterviewState.CandidateSpeaking;
244
248
  const isAiSpeaking = currentStateValue === InterviewState.AiSpeaking;
249
+ const isStatic = currentStateValue === InterviewState.Static;
245
250
  // Scale logic
246
- if (isCandidate) {
251
+ if (isStatic) {
252
+ // Static: fixed scale at 1.0, no breathing, no amplitude reactivity
253
+ this.pulseTargetScale = 1;
254
+ this.pulseScale = 1;
255
+ }
256
+ else if (isCandidate) {
247
257
  // Candidate speaking: Fixed enlarged scale (115%), no breathing effect
248
258
  this.pulseTargetScale = 1.15;
249
259
  const breathing = 0;
@@ -272,18 +282,20 @@ class AiAudioCircleComponent {
272
282
  this.pulseScale += (this.pulseTargetScale + breathing - this.pulseScale) * smoothing;
273
283
  }
274
284
  const currentRadius = baseRadius * this.pulseScale;
275
- // Draw shadows
276
- for (let i = 3; i >= 1; i--) {
277
- const shadowRadius = currentRadius + i * 10;
278
- const shadowOpacity = 0.35 - i * 0.06;
279
- const shadowGradient = ctx.createRadialGradient(centerX, centerY, currentRadius * 0.98, centerX, centerY, shadowRadius);
280
- shadowGradient.addColorStop(0, `rgba(${this.SHADOW_COLOR_RGB}, ${shadowOpacity})`);
281
- shadowGradient.addColorStop(0.6, `rgba(${this.SHADOW_COLOR_RGB}, ${shadowOpacity * 0.5})`);
282
- shadowGradient.addColorStop(1, `rgba(${this.SHADOW_COLOR_RGB}, 0)`);
283
- ctx.beginPath();
284
- ctx.arc(centerX, centerY, shadowRadius, 0, Math.PI * 2);
285
- ctx.fillStyle = shadowGradient;
286
- ctx.fill();
285
+ // Draw shadows (skipped in static state)
286
+ if (!isStatic) {
287
+ for (let i = 3; i >= 1; i--) {
288
+ const shadowRadius = currentRadius + i * 10;
289
+ const shadowOpacity = 0.35 - i * 0.06;
290
+ const shadowGradient = ctx.createRadialGradient(centerX, centerY, currentRadius * 0.98, centerX, centerY, shadowRadius);
291
+ shadowGradient.addColorStop(0, `rgba(${this.SHADOW_COLOR_RGB}, ${shadowOpacity})`);
292
+ shadowGradient.addColorStop(0.6, `rgba(${this.SHADOW_COLOR_RGB}, ${shadowOpacity * 0.5})`);
293
+ shadowGradient.addColorStop(1, `rgba(${this.SHADOW_COLOR_RGB}, 0)`);
294
+ ctx.beginPath();
295
+ ctx.arc(centerX, centerY, shadowRadius, 0, Math.PI * 2);
296
+ ctx.fillStyle = shadowGradient;
297
+ ctx.fill();
298
+ }
287
299
  }
288
300
  // Clip to circle
289
301
  ctx.save();
@@ -315,45 +327,47 @@ class AiAudioCircleComponent {
315
327
  chaosStrength = isAiSpeaking ? 1.8 : 1.0;
316
328
  }
317
329
  this.blobs.forEach((blob, index) => {
318
- // Chaos forces
319
- let chaos1 = Math.sin(this.pulseTime * 0.6 + index * 2.5 + blob.x * 0.02) * 0.15;
320
- let chaos2 = Math.cos(this.pulseTime * 0.4 + index * 1.8 + blob.y * 0.015) * 0.12;
321
- let chaos3 = Math.sin(this.pulseTime * 1.0 + index * 0.7) * 0.08;
322
- if (isAiSpeaking) {
323
- chaos1 += Math.sin(this.pulseTime * 3.2 + index * 1.3) * 0.18;
324
- chaos2 += Math.cos(this.pulseTime * 2.5 + index * 2.1) * 0.14;
325
- chaos3 += Math.sin(this.pulseTime * 4.0 + index * 0.5) * 0.1;
326
- }
327
- // Apply forces
328
- const force = 0.045 * speedMultiplier * chaosStrength;
329
- blob.vx += (chaos1 + chaos3 * Math.cos(this.pulseTime * 1.5 + index)) * force;
330
- blob.vy += (chaos2 + chaos3 * Math.sin(this.pulseTime * 1.2 + index)) * force;
331
- // Friction (slightly less when AI speaking for more sustained movement)
332
- const friction = isAiSpeaking ? 0.985 : 0.98;
333
- blob.vx *= friction;
334
- blob.vy *= friction;
335
- // Max velocity (higher when AI speaking for more erratic motion)
336
- const maxVelBase = isListening ? 3.0 : isAiSpeaking ? 6.0 : 4.5;
337
- const maxVel = maxVelBase * speedMultiplier;
338
- const vel = Math.sqrt(blob.vx * blob.vx + blob.vy * blob.vy);
339
- if (vel > maxVel) {
340
- blob.vx = (blob.vx / vel) * maxVel;
341
- blob.vy = (blob.vy / vel) * maxVel;
342
- }
343
- // Update position
344
- blob.x += blob.vx;
345
- blob.y += blob.vy;
346
- // Keep within bounds
347
- const dx = blob.x - centerX;
348
- const dy = blob.y - centerY;
349
- const dist = Math.sqrt(dx * dx + dy * dy);
350
- const maxDist = currentRadius * 0.55;
351
- if (dist > maxDist) {
352
- const angle = Math.atan2(dy, dx);
353
- blob.x = centerX + Math.cos(angle) * maxDist;
354
- blob.y = centerY + Math.sin(angle) * maxDist;
355
- blob.vx -= dx * 0.065;
356
- blob.vy -= dy * 0.065;
330
+ if (!isStatic) {
331
+ // Chaos forces
332
+ let chaos1 = Math.sin(this.pulseTime * 0.6 + index * 2.5 + blob.x * 0.02) * 0.15;
333
+ let chaos2 = Math.cos(this.pulseTime * 0.4 + index * 1.8 + blob.y * 0.015) * 0.12;
334
+ let chaos3 = Math.sin(this.pulseTime * 1.0 + index * 0.7) * 0.08;
335
+ if (isAiSpeaking) {
336
+ chaos1 += Math.sin(this.pulseTime * 3.2 + index * 1.3) * 0.18;
337
+ chaos2 += Math.cos(this.pulseTime * 2.5 + index * 2.1) * 0.14;
338
+ chaos3 += Math.sin(this.pulseTime * 4.0 + index * 0.5) * 0.1;
339
+ }
340
+ // Apply forces
341
+ const force = 0.045 * speedMultiplier * chaosStrength;
342
+ blob.vx += (chaos1 + chaos3 * Math.cos(this.pulseTime * 1.5 + index)) * force;
343
+ blob.vy += (chaos2 + chaos3 * Math.sin(this.pulseTime * 1.2 + index)) * force;
344
+ // Friction (slightly less when AI speaking for more sustained movement)
345
+ const friction = isAiSpeaking ? 0.985 : 0.98;
346
+ blob.vx *= friction;
347
+ blob.vy *= friction;
348
+ // Max velocity (higher when AI speaking for more erratic motion)
349
+ const maxVelBase = isListening ? 3.0 : isAiSpeaking ? 6.0 : 4.5;
350
+ const maxVel = maxVelBase * speedMultiplier;
351
+ const vel = Math.sqrt(blob.vx * blob.vx + blob.vy * blob.vy);
352
+ if (vel > maxVel) {
353
+ blob.vx = (blob.vx / vel) * maxVel;
354
+ blob.vy = (blob.vy / vel) * maxVel;
355
+ }
356
+ // Update position
357
+ blob.x += blob.vx;
358
+ blob.y += blob.vy;
359
+ // Keep within bounds
360
+ const dx = blob.x - centerX;
361
+ const dy = blob.y - centerY;
362
+ const dist = Math.sqrt(dx * dx + dy * dy);
363
+ const maxDist = currentRadius * 0.55;
364
+ if (dist > maxDist) {
365
+ const angle = Math.atan2(dy, dx);
366
+ blob.x = centerX + Math.cos(angle) * maxDist;
367
+ blob.y = centerY + Math.sin(angle) * maxDist;
368
+ blob.vx -= dx * 0.065;
369
+ blob.vy -= dy * 0.065;
370
+ }
357
371
  }
358
372
  // Parse color to RGB
359
373
  const rgb = this.hexToRgb(blob.color);