@progress/kendo-angular-conversational-ui 24.0.0-develop.3 → 24.0.0-develop.30

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.
@@ -0,0 +1,18 @@
1
+ /**-----------------------------------------------------------------------------------------
2
+ * Copyright © 2026 Progress Software Corporation. All rights reserved.
3
+ * Licensed under commercial license. See LICENSE.md in the project root for more information
4
+ *-------------------------------------------------------------------------------------------*/
5
+ /**
6
+ * Arguments for the `loadMore` event of the Chat.
7
+ * Fires when the user scrolls near the edge of the rendered message window in endless scroll mode.
8
+ */
9
+ export interface ChatLoadMoreEvent {
10
+ /**
11
+ * The inclusive start index into the full messages array.
12
+ */
13
+ startIndex: number;
14
+ /**
15
+ * The exclusive end index into the full messages array.
16
+ */
17
+ endIndex: number;
18
+ }
@@ -0,0 +1,18 @@
1
+ /**-----------------------------------------------------------------------------------------
2
+ * Copyright © 2026 Progress Software Corporation. All rights reserved.
3
+ * Licensed under commercial license. See LICENSE.md in the project root for more information
4
+ *-------------------------------------------------------------------------------------------*/
5
+ /**
6
+ * Arguments for the `referencedMessageClick` event of the Chat.
7
+ * Fires when the user clicks a pinned message indicator or a reply preview.
8
+ */
9
+ export interface ChatReferencedMessageClickEvent {
10
+ /**
11
+ * The ID of the referenced message that was clicked.
12
+ */
13
+ id: string | number;
14
+ /**
15
+ * Specifies whether the click originated from a pinned message indicator or a reply preview.
16
+ */
17
+ type: 'pinned' | 'reply';
18
+ }
@@ -5,13 +5,17 @@
5
5
  export * from './action.interface';
6
6
  export * from './attachment.interface';
7
7
  export * from './chat-file-interface';
8
+ export * from './chat-load-more-event';
9
+ export * from './chat-referenced-message-click-event';
8
10
  export * from './chat-suggestion.interface';
9
11
  export * from './execute-action-event';
10
12
  export * from './message-action';
11
13
  export * from './message-width-mode';
12
14
  export * from './message.interface';
13
15
  export * from './message-settings.interface';
16
+ export * from './message-status.interface';
14
17
  export * from './post-message-event';
18
+ export * from './scroll-mode';
15
19
  export * from './user.interface';
16
20
  export * from './file-action';
17
21
  export * from './file-download-event.interface';
@@ -0,0 +1,12 @@
1
+ /**-----------------------------------------------------------------------------------------
2
+ * Copyright © 2026 Progress Software Corporation. All rights reserved.
3
+ * Licensed under commercial license. See LICENSE.md in the project root for more information
4
+ *-------------------------------------------------------------------------------------------*/
5
+ /**
6
+ * Defines the scroll behavior of the Chat message list.
7
+ *
8
+ * - `scrollable`—All messages are rendered with standard scroll behavior.
9
+ * - `endless`—The Chat starts by rendering the last `pageSize` messages
10
+ * and prepends older ones as the user scrolls up.
11
+ */
12
+ export type ScrollMode = 'scrollable' | 'endless';
@@ -7,19 +7,24 @@ import { SpeechToTextButtonSettings } from '@progress/kendo-angular-buttons';
7
7
  import { LocalizationService } from '@progress/kendo-angular-l10n';
8
8
  import { ContextMenuComponent, ContextMenuPopupEvent } from '@progress/kendo-angular-menu';
9
9
  import { SelectEvent } from '@progress/kendo-angular-upload';
10
+ import { LicenseMessage } from '@progress/kendo-licensing';
10
11
  import { SVGIcon } from '@progress/kendo-svg-icons';
11
12
  import { FileSelectButtonSettings } from '../promptbox/common/models';
12
13
  import { ExecuteActionEvent, FileAction, FileActionEvent, FileDownloadEvent, FilesLayoutMode, Message, MessageSettings, ResendMessageEvent, SendButtonSettings, SendMessageEvent } from './api';
13
14
  import { ChatFile } from './api/chat-file-interface';
15
+ import { ChatLoadMoreEvent } from './api/chat-load-more-event';
16
+ import { ChatReferencedMessageClickEvent } from './api/chat-referenced-message-click-event';
14
17
  import { ChatSuggestion } from './api/chat-suggestion.interface';
15
18
  import { MessageAction, MessageActionEvent } from './api/message-action';
16
19
  import { MessageBoxSettings, MessageBoxType } from './api/message-box';
17
20
  import { MessageWidthMode } from './api/message-width-mode';
21
+ import { ScrollMode } from './api/scroll-mode';
18
22
  import { QuickActionsLayoutMode, SuggestionsLayoutMode } from './api/suggestions-layout';
19
23
  import { TimestampVisibilityMode } from './api/timestamp-visibility';
20
24
  import { AuthorMessageContentTemplateDirective, AuthorMessageTemplateDirective, MessageContentTemplateDirective, MessageTemplateDirective, NoDataTemplateDirective, ReceiverMessageContentTemplateDirective, ReceiverMessageTemplateDirective } from './chat.directives';
21
25
  import { ChatService } from './common/chat.service';
22
26
  import { ConversationalUIModelFields } from './common/models/model-fields';
27
+ import { EndlessScrollState } from './common/endless-scroll-state';
23
28
  import { MessageBoxComponent } from './message-box.component';
24
29
  import { AttachmentTemplateDirective } from './templates/attachment-template.directive';
25
30
  import { ChatHeaderTemplateDirective } from './templates/header-template.directive';
@@ -225,6 +230,62 @@ export declare class ChatComponent implements OnInit, AfterViewInit, OnDestroy {
225
230
  */
226
231
  set sendButtonSettings(value: boolean | SendButtonSettings);
227
232
  get sendButtonSettings(): boolean | SendButtonSettings;
233
+ /**
234
+ * Controls the scrolling behavior of the message list.
235
+ *
236
+ * @default 'scrollable'
237
+ */
238
+ scrollMode: ScrollMode;
239
+ /**
240
+ * Sets the number of messages loaded per page in endless scroll mode.
241
+ * Ignored in `scrollable` mode.
242
+ *
243
+ * @default 50
244
+ */
245
+ pageSize: number;
246
+ /**
247
+ * Sets the minimum distance from the top of the visible message area that prevents auto-scrolling when a new receiver message arrives.
248
+ * Accepts a percentage string (for example, `'30%'`) or a pixel value as a number. Set to `0` to always auto-scroll to new messages.
249
+ *
250
+ * Has no effect on author messages, which always scroll to the bottom.
251
+ *
252
+ * For more details, refer to the [Auto-Scroll Threshold](slug:scroll_modes_chat#auto-scroll-threshold) article.
253
+ *
254
+ * @default '20%'
255
+ */
256
+ autoScrollThreshold: number | string;
257
+ /**
258
+ * Sets the total number of messages in the conversation when using endless scrolling with remote data source. For more details, refer to the [Endless Scrolling with Remote Data](slug:scroll_modes_chat#remote-data) section in the documentation.
259
+ */
260
+ total: number;
261
+ /**
262
+ * Sets the index of the first message in the currently loaded batch within the full conversation.
263
+ * Used with remote data sources in endless scroll mode to compute the range for the next [`loadMore`](slug:api_conversational-ui_chatcomponent#loadMore) call.
264
+ * For more details, refer to the [Endless Scrolling with Remote Data](slug:scroll_modes_chat#remote-data) section in the documentation.
265
+ */
266
+ startIndex: number;
267
+ /**
268
+ * Sets the exclusive end index of the currently loaded batch within the full conversation.
269
+ * Used with remote data sources in endless scroll mode to determine whether more messages exist beyond the current batch.
270
+ * For more details, refer to the [Endless Scrolling with Remote Data](slug:scroll_modes_chat#remote-data) section in the documentation.
271
+ */
272
+ endIndex: number;
273
+ /**
274
+ * Sets the full set of pinned messages in the conversation.
275
+ * Used with remote data sources in endless scroll mode to render the pinned message indicator when the pinned message is outside the currently loaded batch.
276
+ * For more details, refer to the [Endless Scrolling with Remote Data](slug:scroll_modes_chat#remote-data) section in the documentation.
277
+ *
278
+ * @default []
279
+ */
280
+ pinnedMessages: Message[];
281
+ /**
282
+ * Sets the messages that serve as reply targets for messages in the currently loaded batch but exist outside it.
283
+ * Used with remote data sources in endless scroll mode to render reply previews when the replied-to message is not in the current batch.
284
+ * For more details, refer to the [Endless Scrolling with Remote Data](slug:scroll_modes_chat#remote-data) section in the documentation.
285
+ *
286
+ * @default []
287
+ */
288
+ repliedToMessages: Message[];
228
289
  /**
229
290
  * Sets the names of the model fields from which the Chat reads its data.
230
291
  * Lets you map custom data types to the expected `Message` format.
@@ -298,6 +359,14 @@ export declare class ChatComponent implements OnInit, AfterViewInit, OnDestroy {
298
359
  * Fires when the user types in the message input box.
299
360
  */
300
361
  inputValueChange: EventEmitter<string>;
362
+ /**
363
+ * Fires when the user scrolls near the edge of the rendered message window in endless scroll mode.
364
+ */
365
+ loadMore: EventEmitter<ChatLoadMoreEvent>;
366
+ /**
367
+ * Fires when the user clicks a referenced message (pinned indicator or reply preview).
368
+ */
369
+ referencedMessageClick: EventEmitter<ChatReferencedMessageClickEvent>;
301
370
  get className(): string;
302
371
  get dirAttr(): string;
303
372
  set messagesContextMenu(contextMenu: ContextMenuComponent);
@@ -328,6 +397,18 @@ export declare class ChatComponent implements OnInit, AfterViewInit, OnDestroy {
328
397
  * Returns processed messages when model fields are used, otherwise returns original messages.
329
398
  */
330
399
  get processedMessages(): Message[];
400
+ /**
401
+ * @hidden
402
+ * Returns `true` when the Chat is in remote endless scroll mode.
403
+ * Remote mode is active whenever the consumer provides a `total`.
404
+ */
405
+ get isRemoteMode(): boolean;
406
+ /**
407
+ * @hidden
408
+ * Returns the messages to render — sliced in endless mode, full in scrollable mode.
409
+ * In remote mode, returns processedMessages as-is (consumer already provides only the current batch).
410
+ */
411
+ get renderedMessages(): Message[];
331
412
  /**
332
413
  * @hidden
333
414
  */
@@ -362,6 +443,19 @@ export declare class ChatComponent implements OnInit, AfterViewInit, OnDestroy {
362
443
  * @hidden
363
444
  */
364
445
  scrollToBottomIcon: SVGIcon;
446
+ /**
447
+ * @hidden
448
+ */
449
+ endlessState: EndlessScrollState;
450
+ /**
451
+ * @hidden
452
+ */
453
+ showLicenseWatermark: boolean;
454
+ /**
455
+ * @hidden
456
+ */
457
+ licenseMessage?: LicenseMessage;
458
+ private anchor;
365
459
  private direction;
366
460
  private subs;
367
461
  private _modelFields;
@@ -372,6 +466,18 @@ export declare class ChatComponent implements OnInit, AfterViewInit, OnDestroy {
372
466
  private _lastModelFields;
373
467
  private _cachedContextMenuActions;
374
468
  private _lastContextMenuActionsReference;
469
+ private _previousMessagesLength;
470
+ private _previousLastMessageId;
471
+ private _hasProcessedMessages;
472
+ private _pendingScrollAction;
473
+ private _scrollHandledBeforePaint;
474
+ private _lastNewMessageId;
475
+ private _cachedRenderedMessages;
476
+ private _renderedMessagesSource;
477
+ private _renderedMessagesStart;
478
+ private _renderedMessagesEnd;
479
+ private _pendingRemoteScrollToMessageId;
480
+ private _remoteScrollToBottom;
375
481
  constructor(localization: LocalizationService, zone: NgZone, renderer: Renderer2, element: ElementRef, chatService: ChatService);
376
482
  /**
377
483
  * @hidden
@@ -400,7 +506,23 @@ export declare class ChatComponent implements OnInit, AfterViewInit, OnDestroy {
400
506
  /**
401
507
  * @hidden
402
508
  */
403
- scrollToPinnedMessage(): void;
509
+ scrollToPinnedMessage(event?: MouseEvent): void;
510
+ /**
511
+ * @hidden
512
+ */
513
+ onNearTop(): void;
514
+ /**
515
+ * @hidden
516
+ */
517
+ onNearBottom(): void;
518
+ /**
519
+ * @hidden
520
+ */
521
+ onScrollToBottomClick(): void;
522
+ /**
523
+ * @hidden
524
+ */
525
+ handleReferencedMessageClick(messageId: string | number, type: 'pinned' | 'reply'): void;
404
526
  /**
405
527
  * @hidden
406
528
  */
@@ -413,9 +535,27 @@ export declare class ChatComponent implements OnInit, AfterViewInit, OnDestroy {
413
535
  * @hidden
414
536
  */
415
537
  onActionButtonClick(event: MouseEvent): void;
538
+ /**
539
+ * @hidden
540
+ */
541
+ onMessageListResize(): void;
542
+ /**
543
+ * Schedules the new-message scroll adjustment on zone.onStable so it runs
544
+ * after Angular renders the new DOM but before the browser paints,
545
+ * preventing a visible intermediate frame.
546
+ */
547
+ private scheduleNewMessageScroll;
548
+ private detectNewMessageScrollAction;
549
+ private getLastNewMessageElement;
416
550
  private findLastPinnedMessage;
551
+ private initEndlessScroll;
552
+ private handleMessagesChange;
553
+ private handleRemoteMessagesChange;
554
+ private handleRemoteReferencedMessageClick;
555
+ private handlePendingRemoteScroll;
417
556
  private updateChatServiceProperties;
557
+ private validateRemoteInputs;
418
558
  private mergeWithDefaultActions;
419
559
  static ɵfac: i0.ɵɵFactoryDeclaration<ChatComponent, never>;
420
- static ɵcmp: i0.ɵɵComponentDeclaration<ChatComponent, "kendo-chat", never, { "messages": { "alias": "messages"; "required": false; }; "authorId": { "alias": "authorId"; "required": false; }; "messageBoxType": { "alias": "messageBoxType"; "required": false; }; "height": { "alias": "height"; "required": false; }; "width": { "alias": "width"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "messageWidthMode": { "alias": "messageWidthMode"; "required": false; }; "timestampVisibility": { "alias": "timestampVisibility"; "required": false; }; "showUsername": { "alias": "showUsername"; "required": false; }; "showAvatar": { "alias": "showAvatar"; "required": false; }; "allowMessageCollapse": { "alias": "allowMessageCollapse"; "required": false; }; "speechToTextButton": { "alias": "speechToTextButton"; "required": false; }; "fileSelectButton": { "alias": "fileSelectButton"; "required": false; }; "messageBoxSettings": { "alias": "messageBoxSettings"; "required": false; }; "messageToolbarActions": { "alias": "messageToolbarActions"; "required": false; }; "inputValue": { "alias": "inputValue"; "required": false; }; "authorMessageSettings": { "alias": "authorMessageSettings"; "required": false; }; "receiverMessageSettings": { "alias": "receiverMessageSettings"; "required": false; }; "messageContextMenuActions": { "alias": "messageContextMenuActions"; "required": false; }; "fileActions": { "alias": "fileActions"; "required": false; }; "messageFilesLayout": { "alias": "messageFilesLayout"; "required": false; }; "suggestionsLayout": { "alias": "suggestionsLayout"; "required": false; }; "quickActionsLayout": { "alias": "quickActionsLayout"; "required": false; }; "suggestions": { "alias": "suggestions"; "required": false; }; "sendButton": { "alias": "sendButton"; "required": false; }; "sendButtonSettings": { "alias": "sendButtonSettings"; "required": false; }; "modelFields": { "alias": "modelFields"; "required": false; }; "scrollToBottomButton": { "alias": "scrollToBottomButton"; "required": false; }; "loading": { "alias": "loading"; "required": false; }; }, { "sendMessage": "sendMessage"; "resendMessage": "resendMessage"; "toolbarActionClick": "toolbarActionClick"; "contextMenuActionClick": "contextMenuActionClick"; "fileActionClick": "fileActionClick"; "download": "download"; "executeAction": "executeAction"; "suggestionExecute": "suggestionExecute"; "fileSelect": "fileSelect"; "fileRemove": "fileRemove"; "unpin": "unpin"; "inputValueChange": "inputValueChange"; }, ["attachmentTemplate", "chatHeaderTemplate", "chatNoDataTemplate", "authorMessageContentTemplate", "receiverMessageContentTemplate", "messageContentTemplate", "authorMessageTemplate", "receiverMessageTemplate", "messageTemplate", "timestampTemplate", "suggestionTemplate", "statusTemplate", "messageBoxTemplate", "messageBoxStartAffixTemplate", "messageBoxEndAffixTemplate", "messageBoxTopAffixTemplate", "userStatusTemplate"], never, true, never>;
560
+ static ɵcmp: i0.ɵɵComponentDeclaration<ChatComponent, "kendo-chat", never, { "messages": { "alias": "messages"; "required": false; }; "authorId": { "alias": "authorId"; "required": false; }; "messageBoxType": { "alias": "messageBoxType"; "required": false; }; "height": { "alias": "height"; "required": false; }; "width": { "alias": "width"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "messageWidthMode": { "alias": "messageWidthMode"; "required": false; }; "timestampVisibility": { "alias": "timestampVisibility"; "required": false; }; "showUsername": { "alias": "showUsername"; "required": false; }; "showAvatar": { "alias": "showAvatar"; "required": false; }; "allowMessageCollapse": { "alias": "allowMessageCollapse"; "required": false; }; "speechToTextButton": { "alias": "speechToTextButton"; "required": false; }; "fileSelectButton": { "alias": "fileSelectButton"; "required": false; }; "messageBoxSettings": { "alias": "messageBoxSettings"; "required": false; }; "messageToolbarActions": { "alias": "messageToolbarActions"; "required": false; }; "inputValue": { "alias": "inputValue"; "required": false; }; "authorMessageSettings": { "alias": "authorMessageSettings"; "required": false; }; "receiverMessageSettings": { "alias": "receiverMessageSettings"; "required": false; }; "messageContextMenuActions": { "alias": "messageContextMenuActions"; "required": false; }; "fileActions": { "alias": "fileActions"; "required": false; }; "messageFilesLayout": { "alias": "messageFilesLayout"; "required": false; }; "suggestionsLayout": { "alias": "suggestionsLayout"; "required": false; }; "quickActionsLayout": { "alias": "quickActionsLayout"; "required": false; }; "suggestions": { "alias": "suggestions"; "required": false; }; "sendButton": { "alias": "sendButton"; "required": false; }; "sendButtonSettings": { "alias": "sendButtonSettings"; "required": false; }; "scrollMode": { "alias": "scrollMode"; "required": false; }; "pageSize": { "alias": "pageSize"; "required": false; }; "autoScrollThreshold": { "alias": "autoScrollThreshold"; "required": false; }; "total": { "alias": "total"; "required": false; }; "startIndex": { "alias": "startIndex"; "required": false; }; "endIndex": { "alias": "endIndex"; "required": false; }; "pinnedMessages": { "alias": "pinnedMessages"; "required": false; }; "repliedToMessages": { "alias": "repliedToMessages"; "required": false; }; "modelFields": { "alias": "modelFields"; "required": false; }; "scrollToBottomButton": { "alias": "scrollToBottomButton"; "required": false; }; "loading": { "alias": "loading"; "required": false; }; }, { "sendMessage": "sendMessage"; "resendMessage": "resendMessage"; "toolbarActionClick": "toolbarActionClick"; "contextMenuActionClick": "contextMenuActionClick"; "fileActionClick": "fileActionClick"; "download": "download"; "executeAction": "executeAction"; "suggestionExecute": "suggestionExecute"; "fileSelect": "fileSelect"; "fileRemove": "fileRemove"; "unpin": "unpin"; "inputValueChange": "inputValueChange"; "loadMore": "loadMore"; "referencedMessageClick": "referencedMessageClick"; }, ["attachmentTemplate", "chatHeaderTemplate", "chatNoDataTemplate", "authorMessageContentTemplate", "receiverMessageContentTemplate", "messageContentTemplate", "authorMessageTemplate", "receiverMessageTemplate", "messageTemplate", "timestampTemplate", "suggestionTemplate", "statusTemplate", "messageBoxTemplate", "messageBoxStartAffixTemplate", "messageBoxEndAffixTemplate", "messageBoxTopAffixTemplate", "userStatusTemplate"], never, true, never>;
421
561
  }
@@ -2,7 +2,7 @@
2
2
  * Copyright © 2026 Progress Software Corporation. All rights reserved.
3
3
  * Licensed under commercial license. See LICENSE.md in the project root for more information
4
4
  *-------------------------------------------------------------------------------------------*/
5
- import { ViewContainerRef, ElementRef } from '@angular/core';
5
+ import { ViewContainerRef, ElementRef, NgZone } from '@angular/core';
6
6
  import { SpeechToTextButtonSettings } from '@progress/kendo-angular-buttons';
7
7
  import { MessageWidthMode } from '../api/message-width-mode';
8
8
  import { FileAction, FileActionEvent, FileDownloadEvent, FilesLayoutMode, Message, MessageAction, MessageActionEvent, MessageSettings, QuickActionsLayoutMode, ResendMessageEvent, SendButtonSettings, SuggestionsLayoutMode } from '../api';
@@ -15,15 +15,17 @@ import * as i0 from "@angular/core";
15
15
  * @hidden
16
16
  */
17
17
  export declare class ChatService {
18
+ private zone;
18
19
  authorId: string | number;
19
20
  messageWidthMode: MessageWidthMode;
20
- messageToolbarActions: MessageAction[];
21
21
  messageContextMenuActions: MessageAction[];
22
22
  calculatedContextMenuActions: MessageAction[];
23
23
  fileActions: FileAction[];
24
24
  toggleMessageState: boolean;
25
+ layoutChangeInProgress: boolean;
25
26
  reply: Message;
26
27
  messages: Message[];
28
+ repliedToMessages: Message[];
27
29
  chatElement: ViewContainerRef;
28
30
  messageElementsMap: Map<string | number, ElementRef>;
29
31
  messagesContextMenu: ContextMenuComponent;
@@ -41,6 +43,7 @@ export declare class ChatService {
41
43
  private _messageBoxSettings;
42
44
  private _suggestionsLayout;
43
45
  private _quickActionsLayout;
46
+ private _messageToolbarActions;
44
47
  _authorMessageSettings: MessageSettings;
45
48
  _receiverMessageSettings: MessageSettings;
46
49
  private _allowMessageCollapse;
@@ -58,6 +61,8 @@ export declare class ChatService {
58
61
  authorMessageSettingsChange$: import("rxjs").Observable<MessageSettings>;
59
62
  receiverMessageSettingsChange$: import("rxjs").Observable<MessageSettings>;
60
63
  allowMessageCollapseChange$: import("rxjs").Observable<boolean>;
64
+ messageToolbarActionsChange$: import("rxjs").Observable<MessageAction[]>;
65
+ constructor(zone: NgZone);
61
66
  set authorMessageSettings(settings: MessageSettings);
62
67
  get authorMessageSettings(): MessageSettings;
63
68
  set receiverMessageSettings(settings: MessageSettings);
@@ -74,6 +79,8 @@ export declare class ChatService {
74
79
  get suggestionsLayout(): SuggestionsLayoutMode;
75
80
  set quickActionsLayout(layoutMode: QuickActionsLayoutMode);
76
81
  get quickActionsLayout(): QuickActionsLayoutMode;
82
+ set messageToolbarActions(value: MessageAction[]);
83
+ get messageToolbarActions(): MessageAction[];
77
84
  set allowMessageCollapse(value: boolean);
78
85
  get allowMessageCollapse(): boolean;
79
86
  calculateContextMenuActions(isOwn: boolean): void;
@@ -81,9 +88,11 @@ export declare class ChatService {
81
88
  getMessageById(id: string | number): Message | undefined;
82
89
  registerMessageElement(messageId: string | number, elementRef: ElementRef): void;
83
90
  unregisterMessageElement(messageId: string | number): void;
84
- scrollToMessage(messageId: string | number): void;
91
+ scrollToMessage(messageId: string | number, behavior?: ScrollBehavior): void;
85
92
  focusActiveMessageElement(): void;
86
93
  isOwnMessage(message: Message): boolean;
94
+ private getScrollContainer;
95
+ private computeScrollTarget;
87
96
  private updateComponentSettings;
88
97
  static ɵfac: i0.ɵɵFactoryDeclaration<ChatService, never>;
89
98
  static ɵprov: i0.ɵɵInjectableDeclaration<ChatService>;
@@ -0,0 +1,36 @@
1
+ /**-----------------------------------------------------------------------------------------
2
+ * Copyright © 2026 Progress Software Corporation. All rights reserved.
3
+ * Licensed under commercial license. See LICENSE.md in the project root for more information
4
+ *-------------------------------------------------------------------------------------------*/
5
+ /**
6
+ * @hidden
7
+ *
8
+ * Tracks the rendered range for endless scroll mode.
9
+ * Pure logic — no Angular dependency.
10
+ */
11
+ export interface EndlessScrollRange {
12
+ start: number;
13
+ end: number;
14
+ }
15
+ /**
16
+ * @hidden
17
+ */
18
+ export declare class EndlessScrollState {
19
+ startIndex: number;
20
+ endIndex: number;
21
+ isLoading: boolean;
22
+ get isAtStart(): boolean;
23
+ get isAtEnd(): boolean;
24
+ private _total;
25
+ private _pageSize;
26
+ get pageSize(): number;
27
+ init(total: number, pageSize: number): EndlessScrollRange;
28
+ extendUp(): EndlessScrollRange | null;
29
+ extendDown(): EndlessScrollRange | null;
30
+ jumpTo(targetIndex: number): EndlessScrollRange;
31
+ jumpToEnd(): EndlessScrollRange;
32
+ updateTotal(total: number): void;
33
+ reset(): void;
34
+ contains(index: number): boolean;
35
+ syncFromInputs(start: number, end: number, total: number): void;
36
+ }
@@ -0,0 +1,11 @@
1
+ /**-----------------------------------------------------------------------------------------
2
+ * Copyright © 2026 Progress Software Corporation. All rights reserved.
3
+ * Licensed under commercial license. See LICENSE.md in the project root for more information
4
+ *-------------------------------------------------------------------------------------------*/
5
+ /**
6
+ * @hidden
7
+ * Scroll action scheduled after a new message is appended.
8
+ * `author` — the local user sent the message; scroll fully to the bottom.
9
+ * `receiver` — a remote message arrived while the user was near the bottom; scroll with threshold.
10
+ */
11
+ export type PendingScrollAction = 'author' | 'receiver';
@@ -13,13 +13,35 @@ export declare class ScrollAnchorDirective implements AfterViewInit, OnInit, OnD
13
13
  private renderer;
14
14
  private cdr;
15
15
  autoScroll: boolean;
16
+ autoScrollThreshold: number | string;
17
+ set endlessMode(value: boolean);
18
+ get endlessMode(): boolean;
19
+ rangeIsAtEnd: boolean;
16
20
  autoScrollChange: EventEmitter<boolean>;
21
+ nearTop: EventEmitter<void>;
22
+ nearBottom: EventEmitter<void>;
17
23
  overflowAnchor: string;
24
+ get scrollBehaviorStyle(): string;
18
25
  showScrollToBottomButton: boolean;
19
26
  showMessageBoxSeparator: boolean;
20
27
  private scrolling;
21
28
  private unsubscribe;
22
29
  private scrollUpdate;
30
+ private _previousScrollHeight;
31
+ private _previousScrollTop;
32
+ private _pendingScrollPreservation;
33
+ private _endlessMode;
34
+ private _nearTopLocked;
35
+ private _nearBottomLocked;
36
+ private _scrollingToMessage;
37
+ private _initialScrollDone;
38
+ private _subs;
39
+ private _streamingFollow;
40
+ private _thresholdScrollCap;
41
+ private _streamingPrevScrollTop;
42
+ private _streamingPrevHeight;
43
+ private _streamingPrevMsgCount;
44
+ private _mutationObserver;
23
45
  constructor(element: ElementRef, zone: NgZone, renderer: Renderer2, cdr: ChangeDetectorRef);
24
46
  ngOnInit(): void;
25
47
  ngAfterViewInit(): void;
@@ -27,9 +49,24 @@ export declare class ScrollAnchorDirective implements AfterViewInit, OnInit, OnD
27
49
  onScroll(): void;
28
50
  autoScrollToBottom(): void;
29
51
  scrollToBottom(): void;
52
+ scrollToBottomWithSettle(onComplete?: () => void): void;
53
+ scrollWithThreshold(messageEl: HTMLElement): void;
54
+ recordScrollHeight(): void;
55
+ preserveScrollPosition(): void;
30
56
  calculateMessageBoxSeparator(): void;
57
+ getDistanceFromBottom(): number;
58
+ setAriaLive(value: string): void;
59
+ lockForMessageScroll(): void;
60
+ unlockForMessageScroll(): void;
61
+ getAutoScrollThresholdPx(): number;
62
+ get isFollowingThreshold(): boolean;
63
+ private followStreamingContent;
64
+ private updateScrollToBottomButton;
65
+ private detectStreamingScrollUp;
66
+ private parseThreshold;
67
+ private getPinnedBarHeight;
31
68
  private setupScrollUpdate;
32
69
  private performScroll;
33
70
  static ɵfac: i0.ɵɵFactoryDeclaration<ScrollAnchorDirective, never>;
34
- static ɵdir: i0.ɵɵDirectiveDeclaration<ScrollAnchorDirective, "[kendoChatScrollAnchor]", ["scrollAnchor"], { "autoScroll": { "alias": "autoScroll"; "required": false; }; }, { "autoScrollChange": "autoScrollChange"; }, never, never, true, never>;
71
+ static ɵdir: i0.ɵɵDirectiveDeclaration<ScrollAnchorDirective, "[kendoChatScrollAnchor]", ["scrollAnchor"], { "autoScroll": { "alias": "autoScroll"; "required": false; }; "autoScrollThreshold": { "alias": "autoScrollThreshold"; "required": false; }; "endlessMode": { "alias": "endlessMode"; "required": false; }; "rangeIsAtEnd": { "alias": "rangeIsAtEnd"; "required": false; }; }, { "autoScrollChange": "autoScrollChange"; "nearTop": "nearTop"; "nearBottom": "nearBottom"; }, never, never, true, never>;
35
72
  }
@@ -7,6 +7,21 @@ import { ConversationalUIModelFields } from "./models/model-fields";
7
7
  import { FileSelectButtonSettings } from '../../promptbox/common/models';
8
8
  import { SpeechToTextButtonSettings } from "@progress/kendo-angular-buttons";
9
9
  import { MessageBoxSettings } from "../api/message-box";
10
+ import { NgZone } from "@angular/core";
11
+ /**
12
+ * @hidden
13
+ *
14
+ * Show the scroll-to-bottom button when the user is this many pixels from the bottom.
15
+ */
16
+ export declare const scrollButtonThreshold = 100;
17
+ /**
18
+ * @hidden
19
+ *
20
+ * Pins a scroll container to a computed target across layout shifts.
21
+ * Observers extend the idle window until layout has settled; the initial and
22
+ * final pins bracket the settle window so the viewport lands exactly on target.
23
+ */
24
+ export declare const settleScroll: (zone: NgZone, el: HTMLElement, computeTarget: () => number | null, onComplete: () => void, idleMs?: number, timeoutMs?: number) => void;
10
25
  /**
11
26
  * @hidden
12
27
  */
@@ -2,7 +2,7 @@
2
2
  * Copyright © 2026 Progress Software Corporation. All rights reserved.
3
3
  * Licensed under commercial license. See LICENSE.md in the project root for more information
4
4
  *-------------------------------------------------------------------------------------------*/
5
- import { ChangeDetectorRef, ElementRef, OnDestroy, OnInit } from '@angular/core';
5
+ import { ChangeDetectorRef, ElementRef, NgZone, OnDestroy, OnInit } from '@angular/core';
6
6
  import { Message } from './api/message.interface';
7
7
  import { MessageStatus } from './api/message-status.interface';
8
8
  import { ChatItem } from './chat-item';
@@ -31,6 +31,7 @@ export declare class MessageComponent extends ChatItem implements OnInit, OnDest
31
31
  chatService: ChatService;
32
32
  private localization;
33
33
  private cdr;
34
+ private zone;
34
35
  set message(value: Message);
35
36
  get message(): Message;
36
37
  tabbable: boolean;
@@ -71,7 +72,7 @@ export declare class MessageComponent extends ChatItem implements OnInit, OnDest
71
72
  get showToolbar(): boolean;
72
73
  private subs;
73
74
  private _message;
74
- constructor(element: ElementRef, intl: IntlService, chatService: ChatService, localization: LocalizationService, cdr: ChangeDetectorRef);
75
+ constructor(element: ElementRef, intl: IntlService, chatService: ChatService, localization: LocalizationService, cdr: ChangeDetectorRef, zone: NgZone);
75
76
  ngOnInit(): void;
76
77
  ngAfterViewInit(): void;
77
78
  ngOnDestroy(): void;
@@ -99,6 +100,7 @@ export declare class MessageComponent extends ChatItem implements OnInit, OnDest
99
100
  private getMessageSettings;
100
101
  private getToolbarActions;
101
102
  private getFileActions;
103
+ private updateExpandCollapseIconAfterStable;
102
104
  static ɵfac: i0.ɵɵFactoryDeclaration<MessageComponent, never>;
103
105
  static ɵcmp: i0.ɵɵComponentDeclaration<MessageComponent, "kendo-chat-message", never, { "message": { "alias": "message"; "required": false; }; "tabbable": { "alias": "tabbable"; "required": false; }; "authorMessageContentTemplate": { "alias": "authorMessageContentTemplate"; "required": false; }; "receiverMessageContentTemplate": { "alias": "receiverMessageContentTemplate"; "required": false; }; "messageContentTemplate": { "alias": "messageContentTemplate"; "required": false; }; "authorMessageTemplate": { "alias": "authorMessageTemplate"; "required": false; }; "receiverMessageTemplate": { "alias": "receiverMessageTemplate"; "required": false; }; "messageTemplate": { "alias": "messageTemplate"; "required": false; }; "statusTemplate": { "alias": "statusTemplate"; "required": false; }; "showMessageTime": { "alias": "showMessageTime"; "required": false; }; "authorId": { "alias": "authorId"; "required": false; }; }, {}, never, never, true, never>;
104
106
  }