@progress/kendo-angular-grid 23.0.2-develop.1 → 23.1.0-develop.1

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.
@@ -68,6 +68,7 @@ export declare class DataBindingDirective implements OnInit, OnDestroy, DoCheck,
68
68
  protected originalData: any[];
69
69
  protected dataChanged: boolean;
70
70
  private stateChangeSubscription;
71
+ private gridStateChangeSubscription;
71
72
  private dataChangedSubscription;
72
73
  private rowReorderSubscription;
73
74
  private searchSubscription;
@@ -3772,6 +3772,17 @@ class NavigationService {
3772
3772
  el !== cell.element;
3773
3773
  if (focusInCell) {
3774
3774
  this.mode = 2 /* NavigationMode.Content */;
3775
+ // Skip cursor.reset when clicking focusable children in detail template cells
3776
+ // to prevent scroll and focus stealing - let the browser handle focus naturally
3777
+ // Use cursor.assume to update position without announcing (which triggers scroll)
3778
+ // Only apply to detail cells (k-detail-cell), not filter cells or nested grids
3779
+ const isDetailCell = cell.element.classList.contains('k-detail-cell');
3780
+ if (isDetailCell && el !== cell.element && isInSameGrid(el, this.meta.gridElement.nativeElement)) {
3781
+ this.cursor.assume(cell.rowIndex, cell.colIndex);
3782
+ this.activeRowIndex = cell.rowIndex;
3783
+ this.activateRow();
3784
+ return;
3785
+ }
3775
3786
  this.cursor.reset(cell.rowIndex, cell.colIndex);
3776
3787
  this.activateRow();
3777
3788
  }
@@ -4201,6 +4212,24 @@ class NavigationService {
4201
4212
  }
4202
4213
  // on some keyboards arrow keys, PageUp/Down, and Home/End are mapped to Numpad keys
4203
4214
  const code = normalizeKeys(args);
4215
+ // Check if we're in a detail template cell (k-detail-cell)
4216
+ // For detail cells, only handle Escape to return focus to cell, let other keys fall through naturally
4217
+ const cellElement = gridCell(document.activeElement, this.meta.gridElement.nativeElement);
4218
+ const isDetailCell = cellElement?.classList.contains('k-detail-cell');
4219
+ if (isDetailCell) {
4220
+ if (code === Keys.Escape && document.activeElement instanceof HTMLElement) {
4221
+ this.leaveCell();
4222
+ const cellElement = gridCell(document.activeElement, this.meta.gridElement.nativeElement);
4223
+ if (cellElement) {
4224
+ const cell = targetCell(cellElement, this.meta.gridElement.nativeElement);
4225
+ if (cell) {
4226
+ this.cursor.reset(cell.rowIndex, cell.colIndex);
4227
+ args.stopPropagation();
4228
+ }
4229
+ }
4230
+ }
4231
+ return;
4232
+ }
4204
4233
  const confirm = !args.defaultPrevented && code === Keys.Enter && isTextInput(args.target);
4205
4234
  if (code === Keys.Escape || code === Keys.F2 || confirm) {
4206
4235
  if (this.tableCellEntered && code === Keys.F2 && this.activeRow.dataRowIndex > -1) {
@@ -4214,7 +4243,7 @@ class NavigationService {
4214
4243
  this.cursor.reset();
4215
4244
  args.stopPropagation();
4216
4245
  }
4217
- else if (isNavigationKey(code) && this.cursor.cell.focusGroup.isNavigable()) {
4246
+ else if (isNavigationKey(code) && this.cursor.cell?.focusGroup?.isNavigable()) {
4218
4247
  this.onCursorKeydown(args);
4219
4248
  if (args.defaultPrevented) {
4220
4249
  this.leaveCell();
@@ -24140,7 +24169,7 @@ const packageMetadata = {
24140
24169
  productCode: 'KENDOUIANGULAR',
24141
24170
  productCodes: ['KENDOUIANGULAR'],
24142
24171
  publishDate: 0,
24143
- version: '23.0.2-develop.1',
24172
+ version: '23.1.0-develop.1',
24144
24173
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
24145
24174
  };
24146
24175
 
@@ -26855,6 +26884,15 @@ class ScrollerService {
26855
26884
  this.firstToLoad = Math.max(firstItemIndex - nonVisibleBuffer, 0);
26856
26885
  this.loadPage(observer);
26857
26886
  }
26887
+ else if (up && this.ctx.grid?.pageable && firstItemIndex < this.virtualSkip) {
26888
+ // Handle rapid scroll to top: sync virtualSkip and offset when scrolled above current virtual position
26889
+ // This prevents blank grid when virtualSkip/offset are out of sync with actual scroll position
26890
+ const nonVisibleBuffer = Math.max(Math.floor((this.virtualPageSize || this.take) * 0.3) - overflow, 0);
26891
+ this.firstToLoad = Math.max(firstItemIndex - nonVisibleBuffer, 0);
26892
+ this.virtualPageChange(this.firstToLoad, observer);
26893
+ this.translate(this.rowHeightService.offset(this.firstToLoad));
26894
+ observer.next(new ScrollAction(this.rowHeightService.offset(this.firstToLoad)));
26895
+ }
26858
26896
  }
26859
26897
  loadPage(observer) {
26860
26898
  if (!this.rowHeightService) {
@@ -27338,6 +27376,7 @@ class ListComponent {
27338
27376
  table;
27339
27377
  resizeSensors = new QueryList();
27340
27378
  scroller;
27379
+ scrollerFactory;
27341
27380
  subscriptions;
27342
27381
  scrollerSubscription;
27343
27382
  dispatcher = new Subject();
@@ -27402,6 +27441,7 @@ class ListComponent {
27402
27441
  this.pdfService = pdfService;
27403
27442
  this.columnInfo = columnInfo;
27404
27443
  this.dataMappingService = dataMappingService;
27444
+ this.scrollerFactory = scrollerFactory;
27405
27445
  this.scroller = this.ctx.scroller = scrollerFactory(this.dispatcher, this.ctx);
27406
27446
  this.subscriptions = detailsService.changes.subscribe(() => this.detailExpand());
27407
27447
  this.subscriptions.add(scrollRequestService.requests.subscribe(req => isPresent(req.adjustIndex) ? this.scrollTo(req.request, req.adjustIndex) : this.scrollToItem(req.request)));
@@ -27480,10 +27520,18 @@ class ListComponent {
27480
27520
  }
27481
27521
  const shouldCalculatePageSize = isDocumentAvailable() && this.isVirtual && !isPresent(this.virtualPageSize) && (!isPresent(this.ctx.grid?.pageSize) || this.ctx.grid?.pageable);
27482
27522
  const previousTotal = this.allItems.length;
27523
+ const previousFirstDataItem = this.allItems[0]?.data;
27483
27524
  this.allItems = this.dataMappingService.dataMapper(this.data, this.nonLockedColumnsToRender, this.lockedLeafColumns, this.detailTemplate, this.showFooter);
27484
27525
  const totalChanged = previousTotal !== this.allItems.length;
27485
27526
  const totalIncreased = this.allItems.length > previousTotal;
27486
- if (this.totalIsAllItems && totalChanged) {
27527
+ const dataContentChanged = this.allItems.length > 0 && this.allItems[0]?.data !== previousFirstDataItem;
27528
+ // For virtual + pageable without grouping: update itemsToRender when data content changes
27529
+ // This handles remote data scenarios where data arrives asynchronously after page change
27530
+ if (dataContentChanged && this.isVirtual && this.ctx.grid?.pageable && !this.ctx.grid?.group?.length && this.virtualPageSize) {
27531
+ this.scroller.virtualSkip = 0;
27532
+ this.itemsToRender = this.allItems.slice(0, this.virtualPageSize);
27533
+ }
27534
+ else if (this.totalIsAllItems && totalChanged) {
27487
27535
  this.scroller.reset(this.skipScroll);
27488
27536
  this.scroller.total = this.allItems.length;
27489
27537
  this.itemsToRender = this.allItems.slice(this.scroller.virtualSkip, this.scroller.virtualSkip + this.virtualPageSize);
@@ -27627,6 +27675,52 @@ class ListComponent {
27627
27675
  }
27628
27676
  }
27629
27677
  }
27678
+ /**
27679
+ * Resets all virtual scrolling state when the data source changes.
27680
+ * Recreates everything as if the grid was just initialized for the first time.
27681
+ * @hidden
27682
+ */
27683
+ resetVirtualScroll(newTotal) {
27684
+ if (!this.isVirtual) {
27685
+ return;
27686
+ }
27687
+ this.skip = 0;
27688
+ this.skipScroll = false;
27689
+ this.containerScrollTop = 0;
27690
+ this.rebind = false;
27691
+ this.scroller.destroy();
27692
+ this.scroller = this.ctx.scroller = this.scrollerFactory(this.dispatcher, this.ctx);
27693
+ if (!this.virtualPageSize) {
27694
+ this.virtualPageSize = this.calcVirtualPageSize();
27695
+ }
27696
+ const rowHeightTotal = this.ctx.grid?.pageable ? this.ctx.grid.pageSize : newTotal;
27697
+ this.rowHeightService = this.scroller.rowHeightService = new RowHeightService(rowHeightTotal, this.rowHeight || this.minRowHeight);
27698
+ if (this.container?.nativeElement) {
27699
+ this.container.nativeElement.scrollTop = 0;
27700
+ }
27701
+ if (this.lockedContainer?.nativeElement) {
27702
+ this.lockedContainer.nativeElement.scrollTop = 0;
27703
+ }
27704
+ if (this.table?.nativeElement) {
27705
+ this.table.nativeElement.style.transform = 'translateY(0px)';
27706
+ }
27707
+ if (this.lockedTable?.nativeElement) {
27708
+ this.lockedTable.nativeElement.style.transform = 'translateY(0px)';
27709
+ }
27710
+ this.setScrollerOptions();
27711
+ this.ngZone.runOutsideAngular(this.createScroller.bind(this));
27712
+ }
27713
+ /**
27714
+ * Checks if the virtual scroll state is out of sync with the expected position.
27715
+ * Used to determine if resetVirtualScroll should be called.
27716
+ * @hidden
27717
+ */
27718
+ isVirtualScrollOutOfSync() {
27719
+ if (!this.isVirtual || !this.scroller) {
27720
+ return false;
27721
+ }
27722
+ return this.scroller.virtualSkip > 0 || this.scroller.tableTransformOffset > 0;
27723
+ }
27630
27724
  lockedScroll() {
27631
27725
  if (!this.suspendService.scroll) {
27632
27726
  const lockedScrollTop = this.lockedContainer.nativeElement.scrollTop;
@@ -27790,6 +27884,25 @@ class ListComponent {
27790
27884
  if (this.lockedContainer) {
27791
27885
  this.lockedContainer.nativeElement.scrollTop = scrollTop;
27792
27886
  }
27887
+ // Sync translateY offset during rapid scrolling with virtual+paging to prevent blank grid
27888
+ if (this.isVirtual && this.ctx.grid?.pageable && this.scroller.rowHeightService) {
27889
+ const expectedFirstIndex = this.scroller.rowHeightService.index(scrollTop);
27890
+ const expectedOffset = this.scroller.rowHeightService.offset(expectedFirstIndex);
27891
+ const currentOffset = this.scroller.tableTransformOffset;
27892
+ // If the offset is significantly out of sync (more than one row height difference), resync
27893
+ const rowHeight = this.rowHeight || this.minRowHeight || 36;
27894
+ if (Math.abs(currentOffset - expectedOffset) > rowHeight) {
27895
+ this.scroller.virtualSkip = expectedFirstIndex;
27896
+ this.scroller.tableTransformOffset = expectedOffset;
27897
+ [
27898
+ maybeNativeElement(this.table),
27899
+ maybeNativeElement(this.lockedTable)
27900
+ ].filter(isPresent).forEach(translateY(this.renderer, expectedOffset));
27901
+ if (this.virtualPageSize) {
27902
+ this.ngZone.run(() => this.itemsToRender = this.allItems.slice(expectedFirstIndex, expectedFirstIndex + this.virtualPageSize));
27903
+ }
27904
+ }
27905
+ }
27793
27906
  }
27794
27907
  handleRowSync() {
27795
27908
  const isLocked = () => isPresent(this.lockedContainer);
@@ -32064,12 +32177,28 @@ class SearchService {
32064
32177
  * Fires when the search descriptor is set.
32065
32178
  */
32066
32179
  changes = new Subject();
32180
+ /**
32181
+ * The descriptor used for searching.
32182
+ */
32183
+ searchFilter;
32184
+ /**
32185
+ * The value used for searching.
32186
+ */
32187
+ searchValue;
32067
32188
  /**
32068
32189
  * Sets the search descriptor.
32069
32190
  *
32070
32191
  * @param {CompositeFilterDescriptor} value - The search descriptor to set.
32071
32192
  */
32072
32193
  search(value) {
32194
+ if (!value) {
32195
+ this.searchValue = '';
32196
+ }
32197
+ else {
32198
+ const flattenDescriptors = flatten(value);
32199
+ this.searchValue = flattenDescriptors[0] ? flattenDescriptors[0].value : '';
32200
+ }
32201
+ this.searchFilter = value;
32073
32202
  this.changes.next(value);
32074
32203
  }
32075
32204
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: SearchService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
@@ -32163,6 +32292,7 @@ class GridComponent {
32163
32292
  dataMappingService;
32164
32293
  aiRequestResponseService;
32165
32294
  idService;
32295
+ searchService;
32166
32296
  /**
32167
32297
  * Sets the data of the Grid. If you provide an array, the Grid gets the total count automatically.
32168
32298
  * ([more information and example](https://www.telerik.com/kendo-angular-ui/components/grid/data-binding/basics)).
@@ -32580,7 +32710,8 @@ class GridComponent {
32580
32710
  skip: this.skip,
32581
32711
  take: this.pageSize,
32582
32712
  columnsState: this.columns.toArray().flatMap(recursiveColumnsFlatMap),
32583
- currentData: structuredClone(this.data)
32713
+ currentData: structuredClone(this.data),
32714
+ searchFilter: this.searchService?.searchFilter
32584
32715
  };
32585
32716
  }
32586
32717
  /**
@@ -33132,7 +33263,7 @@ class GridComponent {
33132
33263
  rowReorderSubscription;
33133
33264
  rtl = false;
33134
33265
  _rowSticky;
33135
- constructor(supportService, selectionService, cellSelectionService, wrapper, groupInfoService, groupsService, changeNotification, detailsService, editService, filterService, pdfService, responsiveService, renderer, excelService, csvService, ngZone, scrollSyncService, domEvents, columnResizingService, changeDetectorRef, columnReorderService, columnInfoService, navigationService, sortService, scrollRequestService, localization, ctx, sizingService, adaptiveGridService, rowReorderService, dataMappingService, aiRequestResponseService, idService) {
33266
+ constructor(supportService, selectionService, cellSelectionService, wrapper, groupInfoService, groupsService, changeNotification, detailsService, editService, filterService, pdfService, responsiveService, renderer, excelService, csvService, ngZone, scrollSyncService, domEvents, columnResizingService, changeDetectorRef, columnReorderService, columnInfoService, navigationService, sortService, scrollRequestService, localization, ctx, sizingService, adaptiveGridService, rowReorderService, dataMappingService, aiRequestResponseService, idService, searchService) {
33136
33267
  this.supportService = supportService;
33137
33268
  this.selectionService = selectionService;
33138
33269
  this.cellSelectionService = cellSelectionService;
@@ -33166,6 +33297,7 @@ class GridComponent {
33166
33297
  this.dataMappingService = dataMappingService;
33167
33298
  this.aiRequestResponseService = aiRequestResponseService;
33168
33299
  this.idService = idService;
33300
+ this.searchService = searchService;
33169
33301
  const isValid = validatePackage(packageMetadata);
33170
33302
  this.licenseMessage = getLicenseMessage(packageMetadata);
33171
33303
  this.showLicenseWatermark = shouldShowValidationUI(isValid);
@@ -33305,6 +33437,12 @@ class GridComponent {
33305
33437
  const leafColumns = this.columnInfoService.leafNamedColumns || [];
33306
33438
  this.aiRequestResponseService.processCommands(response.commands || [], columns, leafColumns);
33307
33439
  }
33440
+ /**
33441
+ * Clears the search operation applied through the SmartBox tool.
33442
+ */
33443
+ clearSearch() {
33444
+ this.searchService?.search(undefined);
33445
+ }
33308
33446
  /**
33309
33447
  * @hidden
33310
33448
  */
@@ -33326,6 +33464,12 @@ class GridComponent {
33326
33464
  ngOnChanges(changes) {
33327
33465
  if (isChanged$1("data", changes)) {
33328
33466
  this.onDataChange();
33467
+ if (this.isVirtual && this.pageable && this.listComponent && this.skip === 0) {
33468
+ if (this.listComponent.isVirtualScrollOutOfSync()) {
33469
+ const total = this._data?.total ?? this._data?.length ?? 0;
33470
+ this.listComponent.resetVirtualScroll(total);
33471
+ }
33472
+ }
33329
33473
  }
33330
33474
  if (this.lockedLeafColumns.length && anyChanged(["pageSize", "skip", "sort", "group"], changes)) {
33331
33475
  this.changeNotification.notify();
@@ -33689,6 +33833,9 @@ class GridComponent {
33689
33833
  this.filter = state.filter;
33690
33834
  this.skip = state.skip;
33691
33835
  this.pageSize = state.take;
33836
+ if (this.searchService && !areObjectsEqual(state.searchFilter || {}, this.searchService.searchFilter || {})) {
33837
+ this.searchService.search(state.searchFilter);
33838
+ }
33692
33839
  if (state.currentData) {
33693
33840
  this.data = state.currentData;
33694
33841
  }
@@ -34185,6 +34332,11 @@ class GridComponent {
34185
34332
  this.listComponent?.resetNavigationViewport();
34186
34333
  }
34187
34334
  })));
34335
+ if (this.searchService) {
34336
+ this.stateChangeSubscription.add(this.searchService.changes.subscribe(() => this.ngZone.run(() => {
34337
+ hasObservers(this.gridStateChange) && this.gridStateChange.emit(this.currentState);
34338
+ })));
34339
+ }
34188
34340
  }
34189
34341
  attachEditHandlers() {
34190
34342
  if (!this.editService) {
@@ -34492,7 +34644,7 @@ class GridComponent {
34492
34644
  this.dragTargetContainer?.notify();
34493
34645
  this.dropTargetContainer?.notify();
34494
34646
  }
34495
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: GridComponent, deps: [{ token: BrowserSupportService }, { token: SelectionService }, { token: CellSelectionService }, { token: i0.ElementRef }, { token: GroupInfoService }, { token: GroupsService }, { token: ChangeNotificationService }, { token: DetailsService }, { token: EditService }, { token: FilterService }, { token: PDFService }, { token: ResponsiveService }, { token: i0.Renderer2 }, { token: ExcelService }, { token: CSVService }, { token: i0.NgZone }, { token: ScrollSyncService }, { token: DomEventsService }, { token: ColumnResizingService }, { token: i0.ChangeDetectorRef }, { token: ColumnReorderService }, { token: ColumnInfoService }, { token: NavigationService }, { token: SortService }, { token: ScrollRequestService }, { token: i1$2.LocalizationService }, { token: ContextService }, { token: SizingOptionsService }, { token: AdaptiveGridService }, { token: RowReorderService }, { token: DataMappingService }, { token: GridAIRequestResponseService }, { token: IdService }], target: i0.ɵɵFactoryTarget.Component });
34647
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: GridComponent, deps: [{ token: BrowserSupportService }, { token: SelectionService }, { token: CellSelectionService }, { token: i0.ElementRef }, { token: GroupInfoService }, { token: GroupsService }, { token: ChangeNotificationService }, { token: DetailsService }, { token: EditService }, { token: FilterService }, { token: PDFService }, { token: ResponsiveService }, { token: i0.Renderer2 }, { token: ExcelService }, { token: CSVService }, { token: i0.NgZone }, { token: ScrollSyncService }, { token: DomEventsService }, { token: ColumnResizingService }, { token: i0.ChangeDetectorRef }, { token: ColumnReorderService }, { token: ColumnInfoService }, { token: NavigationService }, { token: SortService }, { token: ScrollRequestService }, { token: i1$2.LocalizationService }, { token: ContextService }, { token: SizingOptionsService }, { token: AdaptiveGridService }, { token: RowReorderService }, { token: DataMappingService }, { token: GridAIRequestResponseService }, { token: IdService }, { token: SearchService }], target: i0.ɵɵFactoryTarget.Component });
34496
34648
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", type: GridComponent, isStandalone: true, selector: "kendo-grid", inputs: { data: "data", pageSize: "pageSize", height: "height", rowHeight: "rowHeight", adaptiveMode: "adaptiveMode", detailRowHeight: "detailRowHeight", skip: "skip", scrollable: "scrollable", selectable: "selectable", sort: "sort", size: "size", trackBy: "trackBy", filter: "filter", group: "group", virtualColumns: "virtualColumns", filterable: "filterable", sortable: "sortable", pageable: "pageable", groupable: "groupable", gridResizable: "gridResizable", rowReorderable: "rowReorderable", navigable: "navigable", autoSize: "autoSize", rowClass: "rowClass", rowSticky: "rowSticky", rowSelected: "rowSelected", isRowSelectable: "isRowSelectable", cellSelected: "cellSelected", resizable: "resizable", reorderable: "reorderable", loading: "loading", columnMenu: "columnMenu", hideHeader: "hideHeader", showInactiveTools: "showInactiveTools", isDetailExpanded: "isDetailExpanded", isGroupExpanded: "isGroupExpanded", dataLayoutMode: "dataLayoutMode" }, outputs: { filterChange: "filterChange", pageChange: "pageChange", groupChange: "groupChange", sortChange: "sortChange", selectionChange: "selectionChange", rowReorder: "rowReorder", dataStateChange: "dataStateChange", gridStateChange: "gridStateChange", groupExpand: "groupExpand", groupCollapse: "groupCollapse", detailExpand: "detailExpand", detailCollapse: "detailCollapse", edit: "edit", cancel: "cancel", save: "save", remove: "remove", add: "add", cellClose: "cellClose", cellClick: "cellClick", pdfExport: "pdfExport", excelExport: "excelExport", csvExport: "csvExport", columnResize: "columnResize", columnReorder: "columnReorder", columnVisibilityChange: "columnVisibilityChange", columnLockedChange: "columnLockedChange", columnStickyChange: "columnStickyChange", scrollBottom: "scrollBottom", contentScroll: "contentScroll" }, host: { properties: { "attr.dir": "this.dir", "class.k-grid": "this.hostClass", "class.k-grid-sm": "this.sizeSmallClass", "class.k-grid-md": "this.sizeMediumClass", "class.k-grid-stack": "this.stackedClass", "class.k-grid-lockedcolumns": "this.lockedClasses", "class.k-grid-virtual": "this.virtualClasses", "class.k-grid-no-scrollbar": "this.noScrollbarClass", "class.k-grid-resizable": "this.isResizable", "style.minWidth": "this.minWidth", "style.maxWidth": "this.maxWidth", "style.minHeight": "this.minHeight", "style.maxHeight": "this.maxHeight" } }, providers: [
34497
34649
  BrowserSupportService,
34498
34650
  LocalizationService,
@@ -36472,7 +36624,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
36472
36624
  ResizeSensorComponent
36473
36625
  ]
36474
36626
  }]
36475
- }], ctorParameters: () => [{ type: BrowserSupportService }, { type: SelectionService }, { type: CellSelectionService }, { type: i0.ElementRef }, { type: GroupInfoService }, { type: GroupsService }, { type: ChangeNotificationService }, { type: DetailsService }, { type: EditService }, { type: FilterService }, { type: PDFService }, { type: ResponsiveService }, { type: i0.Renderer2 }, { type: ExcelService }, { type: CSVService }, { type: i0.NgZone }, { type: ScrollSyncService }, { type: DomEventsService }, { type: ColumnResizingService }, { type: i0.ChangeDetectorRef }, { type: ColumnReorderService }, { type: ColumnInfoService }, { type: NavigationService }, { type: SortService }, { type: ScrollRequestService }, { type: i1$2.LocalizationService }, { type: ContextService }, { type: SizingOptionsService }, { type: AdaptiveGridService }, { type: RowReorderService }, { type: DataMappingService }, { type: GridAIRequestResponseService }, { type: IdService }], propDecorators: { data: [{
36627
+ }], ctorParameters: () => [{ type: BrowserSupportService }, { type: SelectionService }, { type: CellSelectionService }, { type: i0.ElementRef }, { type: GroupInfoService }, { type: GroupsService }, { type: ChangeNotificationService }, { type: DetailsService }, { type: EditService }, { type: FilterService }, { type: PDFService }, { type: ResponsiveService }, { type: i0.Renderer2 }, { type: ExcelService }, { type: CSVService }, { type: i0.NgZone }, { type: ScrollSyncService }, { type: DomEventsService }, { type: ColumnResizingService }, { type: i0.ChangeDetectorRef }, { type: ColumnReorderService }, { type: ColumnInfoService }, { type: NavigationService }, { type: SortService }, { type: ScrollRequestService }, { type: i1$2.LocalizationService }, { type: ContextService }, { type: SizingOptionsService }, { type: AdaptiveGridService }, { type: RowReorderService }, { type: DataMappingService }, { type: GridAIRequestResponseService }, { type: IdService }, { type: SearchService }], propDecorators: { data: [{
36476
36628
  type: Input
36477
36629
  }], pageSize: [{
36478
36630
  type: Input
@@ -36827,6 +36979,7 @@ class DataBindingDirective {
36827
36979
  originalData = [];
36828
36980
  dataChanged;
36829
36981
  stateChangeSubscription;
36982
+ gridStateChangeSubscription;
36830
36983
  dataChangedSubscription;
36831
36984
  rowReorderSubscription;
36832
36985
  searchSubscription;
@@ -36850,6 +37003,9 @@ class DataBindingDirective {
36850
37003
  this.stateChangeSubscription = this.grid
36851
37004
  .dataStateChange
36852
37005
  .subscribe(this.onStateChange.bind(this));
37006
+ this.gridStateChangeSubscription = this.grid
37007
+ .gridStateChange
37008
+ .subscribe(this.onStateChange.bind(this));
36853
37009
  if (this.rowReorderService) {
36854
37010
  this.rowReorderSubscription = this.grid
36855
37011
  .rowReorder
@@ -36879,9 +37035,17 @@ class DataBindingDirective {
36879
37035
  if (this.searchSubscription) {
36880
37036
  this.searchSubscription.unsubscribe();
36881
37037
  }
37038
+ if (this.gridStateChangeSubscription) {
37039
+ this.gridStateChangeSubscription.unsubscribe();
37040
+ }
36882
37041
  }
36883
37042
  ngOnChanges(changes) {
36884
37043
  if (anyChanged(["pageSize", "skip", "sort", "group", "filter"], changes)) {
37044
+ // Reset skip to 0 when filter changes to avoid showing stale data
37045
+ if (isChanged$1("filter", changes)) {
37046
+ this.state.skip = 0;
37047
+ this.grid.skip = 0;
37048
+ }
36885
37049
  this.rebind();
36886
37050
  }
36887
37051
  }
@@ -36909,9 +37073,17 @@ class DataBindingDirective {
36909
37073
  */
36910
37074
  onSearch(searchFilter) {
36911
37075
  this.searchFilter = searchFilter;
37076
+ this.state.skip = 0;
37077
+ this.grid.skip = 0;
36912
37078
  const combinedFilter = this.combineFilters();
36913
37079
  const state = { ...this.state, filter: combinedFilter };
36914
- this.grid.data = this.process(state);
37080
+ const result = this.process(state);
37081
+ this.grid.data = result;
37082
+ if (this.grid.isVirtual && this.grid.pageable && this.grid.listComponent) {
37083
+ if (this.grid.listComponent.isVirtualScrollOutOfSync()) {
37084
+ this.grid.listComponent.resetVirtualScroll(result.total);
37085
+ }
37086
+ }
36915
37087
  this.grid.updateNavigationMetadata();
36916
37088
  this.grid.ngDoCheck();
36917
37089
  this.dataChanged = false;
@@ -36922,12 +37094,32 @@ class DataBindingDirective {
36922
37094
  rebind() {
36923
37095
  this.data = this.originalData;
36924
37096
  this.updateGridData();
36925
- this.notifyDataChange();
37097
+ if (this.grid.isVirtual && this.grid.pageable && this.grid.listComponent && this.state.skip === 0) {
37098
+ if (this.grid.listComponent.isVirtualScrollOutOfSync()) {
37099
+ const result = this.grid.data;
37100
+ this.grid.listComponent.resetVirtualScroll(result?.total ?? 0);
37101
+ }
37102
+ }
37103
+ this.grid.onDataChange();
37104
+ if (this.changeDetector) {
37105
+ this.changeDetector.markForCheck();
37106
+ }
36926
37107
  }
36927
37108
  /**
36928
37109
  * Notifies the Grid that its data has changed.
36929
37110
  */
36930
37111
  notifyDataChange() {
37112
+ // Reset virtual scroll state completely when data changes
37113
+ if (this.grid.isVirtual && this.grid.listComponent) {
37114
+ this.state.skip = 0;
37115
+ this.grid.skip = 0;
37116
+ this.updateGridData();
37117
+ const newTotal = this.originalData?.length || 0;
37118
+ this.grid.listComponent.resetVirtualScroll(newTotal);
37119
+ }
37120
+ else if (this.dataChanged) {
37121
+ this.updateGridData();
37122
+ }
36931
37123
  this.grid.onDataChange();
36932
37124
  if (this.changeDetector) {
36933
37125
  this.changeDetector.markForCheck();
@@ -36962,9 +37154,8 @@ class DataBindingDirective {
36962
37154
  this.state.take = this.grid.pageSize;
36963
37155
  }
36964
37156
  }
36965
- let combinedFilter = null;
36966
37157
  if (this.searchFilter) {
36967
- combinedFilter = this.combineFilters();
37158
+ const combinedFilter = this.combineFilters();
36968
37159
  const state = { ...this.state, filter: combinedFilter };
36969
37160
  this.grid.data = this.process(state);
36970
37161
  }
@@ -38802,7 +38993,8 @@ class UndoRedoDirective {
38802
38993
  take: state.take,
38803
38994
  sort: state.sort,
38804
38995
  filter: state.filter,
38805
- group: state.group
38996
+ group: state.group,
38997
+ searchFilter: state.searchFilter
38806
38998
  },
38807
38999
  gridState: state
38808
39000
  });
@@ -38875,7 +39067,13 @@ class UndoRedoDirective {
38875
39067
  this.localDataChangesService?.changes.emit();
38876
39068
  }
38877
39069
  else {
38878
- this.host.loadState({ ...this.stack.current.gridState, currentData: null });
39070
+ this.addToState = false;
39071
+ try {
39072
+ this.host.loadState({ ...this.stack.current.gridState, currentData: null });
39073
+ }
39074
+ finally {
39075
+ this.addToState = true;
39076
+ }
38879
39077
  if (this.isDataStateChangeEvent(event.originalEvent)) {
38880
39078
  const { skip, take, sort, filter, group } = event.gridState;
38881
39079
  this.host.dataStateChange.emit({ skip, take, sort, filter, group });
@@ -38891,7 +39089,8 @@ class UndoRedoDirective {
38891
39089
  take: this.host.pageSize,
38892
39090
  sort: this.host.sort,
38893
39091
  filter: this.host.filter,
38894
- group: this.host.group
39092
+ group: this.host.group,
39093
+ searchFilter: this.host.currentState.searchFilter
38895
39094
  }, gridState: this.host.currentState
38896
39095
  });
38897
39096
  }
@@ -38906,7 +39105,13 @@ class UndoRedoDirective {
38906
39105
  redo() {
38907
39106
  if (this.stack.canRedo) {
38908
39107
  this.stack.redo();
38909
- this.host.loadState(this.stack.current.gridState);
39108
+ this.addToState = false;
39109
+ try {
39110
+ this.host.loadState(this.stack.current.gridState);
39111
+ }
39112
+ finally {
39113
+ this.addToState = true;
39114
+ }
38910
39115
  if (!this.stack.canRedo) {
38911
39116
  this.undoRedoService.stackEndReached.next('end');
38912
39117
  }
@@ -38918,7 +39123,13 @@ class UndoRedoDirective {
38918
39123
  undo() {
38919
39124
  if (this.stack.canUndo) {
38920
39125
  this.stack.undo();
38921
- this.host.loadState(this.stack.current.gridState);
39126
+ this.addToState = false;
39127
+ try {
39128
+ this.host.loadState(this.stack.current.gridState);
39129
+ }
39130
+ finally {
39131
+ this.addToState = true;
39132
+ }
38922
39133
  if (!this.stack.canUndo) {
38923
39134
  this.undoRedoService.stackEndReached.next('start');
38924
39135
  }
@@ -40851,7 +41062,6 @@ class GridSmartBoxSearchEvent extends SmartBoxSearchEvent {
40851
41062
  }
40852
41063
  }
40853
41064
 
40854
- const DEFAULT_SIZE$1 = 'medium';
40855
41065
  const SIZES_MAP = {
40856
41066
  small: 'sm',
40857
41067
  medium: 'md',
@@ -40875,10 +41085,10 @@ class SegmentedControlComponent {
40875
41085
  /**
40876
41086
  * Sets the padding of the control.
40877
41087
  *
40878
- * @default 'medium'
41088
+ * @default undefined
40879
41089
  */
40880
41090
  set size(size) {
40881
- const newSize = size || DEFAULT_SIZE$1;
41091
+ const newSize = size;
40882
41092
  this.handleSizeClass(newSize, this._size);
40883
41093
  this._size = newSize;
40884
41094
  }
@@ -40926,14 +41136,14 @@ class SegmentedControlComponent {
40926
41136
  this.renderer.setStyle(selectionIndicator, 'right', `${right}px`);
40927
41137
  }
40928
41138
  selectedButtonIndex = 0;
40929
- _size = DEFAULT_SIZE$1;
41139
+ _size;
40930
41140
  handleSizeClass(newValue, prevValue) {
40931
41141
  if (!this.wrapper) {
40932
41142
  return;
40933
41143
  }
40934
41144
  const elem = this.wrapper.nativeElement;
40935
41145
  const classToRemove = prevValue ? `k-segmented-control-${SIZES_MAP[prevValue]}` : null;
40936
- const classToAdd = newValue ? `k-segmented-control-${SIZES_MAP[newValue]}` : `k-segmented-control-${SIZES_MAP[DEFAULT_SIZE$1]}`;
41146
+ const classToAdd = newValue ? `k-segmented-control-${SIZES_MAP[newValue]}` : null;
40937
41147
  classToRemove && this.renderer.removeClass(elem, classToRemove);
40938
41148
  classToAdd && this.renderer.addClass(elem, classToAdd);
40939
41149
  }
@@ -41354,11 +41564,23 @@ class SmartBoxComponent {
41354
41564
  this.handleSizeClass(this._size);
41355
41565
  this.updateSearchListData();
41356
41566
  this.updateSelectedView();
41567
+ this.searchSubscription = this.searchService.changes.subscribe((descriptor) => {
41568
+ if (!isPresent$1(descriptor)) {
41569
+ this.input.nativeElement.value = '';
41570
+ }
41571
+ else if (!this.input.nativeElement.value || this.input.nativeElement.value !== this.searchService.searchValue) {
41572
+ this.input.nativeElement.value = this.searchService.searchValue || '';
41573
+ }
41574
+ });
41357
41575
  }
41358
41576
  ngOnDestroy() {
41359
41577
  this.destroyPopup();
41360
41578
  this.clearTypingTimeout();
41361
41579
  this.unsubscribeCurrentRequest();
41580
+ if (this.searchSubscription) {
41581
+ this.searchSubscription.unsubscribe();
41582
+ this.searchSubscription = null;
41583
+ }
41362
41584
  }
41363
41585
  focusableId = `k-${guid()}`;
41364
41586
  selectedView;
@@ -41447,7 +41669,12 @@ class SmartBoxComponent {
41447
41669
  this.selectedView = 'aiAssistant';
41448
41670
  }
41449
41671
  this.modeChange.emit(this.selectedView);
41450
- this.clearValue();
41672
+ if (this.selectedView === 'search') {
41673
+ this.input.nativeElement.value = this.lastSearchValue || '';
41674
+ }
41675
+ else {
41676
+ this.input.nativeElement.value = '';
41677
+ }
41451
41678
  this.cdr.detectChanges();
41452
41679
  }
41453
41680
  onSearchItemClick(item) {
@@ -41455,8 +41682,13 @@ class SmartBoxComponent {
41455
41682
  this.searchListData.forEach(i => i.selected = false);
41456
41683
  this.searchListData.find(i => i.text === item.text).selected = true;
41457
41684
  this.selectedView = item.text === 'Search' ? 'search' : 'semanticSearch';
41685
+ if (this.selectedView === 'search') {
41686
+ this.input.nativeElement.value = this.lastSearchValue || '';
41687
+ }
41688
+ else {
41689
+ this.input.nativeElement.value = '';
41690
+ }
41458
41691
  this.modeChange.emit(this.selectedView);
41459
- this.clearValue();
41460
41692
  this.cdr.markForCheck();
41461
41693
  }
41462
41694
  onListItemClick(item) {
@@ -41489,16 +41721,17 @@ class SmartBoxComponent {
41489
41721
  ev = Object.assign(new SmartBoxSearchEvent(), eventArgs);
41490
41722
  }
41491
41723
  else if (this.selectedView === 'semanticSearch') {
41492
- ev = { searchValue: this.input.nativeElement.value };
41724
+ ev = eventArgs;
41493
41725
  }
41494
41726
  this[this.selectedView].emit(ev);
41495
41727
  if (this.selectedView === 'search' && !ev.isDefaultPrevented()) {
41728
+ this.lastSearchValue = this.input.nativeElement.value;
41496
41729
  this.zone.run(() => {
41497
41730
  if (this.input.nativeElement.value === '' || !this.input.nativeElement.value) {
41498
- this.searchService.changes.next(undefined);
41731
+ this.searchService.search(undefined);
41499
41732
  }
41500
41733
  else {
41501
- this.searchService.changes.next({ filters: ev.filters, logic: ev.logic });
41734
+ this.searchService.search({ filters: ev.filters, logic: ev.logic });
41502
41735
  }
41503
41736
  });
41504
41737
  }
@@ -41575,12 +41808,13 @@ class SmartBoxComponent {
41575
41808
  this[this.selectedView].emit(ev);
41576
41809
  });
41577
41810
  if (this.selectedView === 'search' && !ev.isDefaultPrevented()) {
41811
+ this.lastSearchValue = inputValue;
41578
41812
  this.zone.run(() => {
41579
41813
  if (inputValue === '' || !inputValue) {
41580
- this.searchService.changes.next(undefined);
41814
+ this.searchService.search(undefined);
41581
41815
  }
41582
41816
  else {
41583
- this.searchService.changes.next({ filters: ev.filters, logic: ev.logic });
41817
+ this.searchService.search({ filters: ev.filters, logic: ev.logic });
41584
41818
  }
41585
41819
  });
41586
41820
  }
@@ -41661,9 +41895,11 @@ class SmartBoxComponent {
41661
41895
  popupMouseDownHandler = (event) => event.preventDefault();
41662
41896
  requestData;
41663
41897
  currentRequestSubscription = null;
41898
+ searchSubscription = null;
41664
41899
  columns = [];
41665
41900
  leafColumns = [];
41666
41901
  searchTypingTimeout;
41902
+ lastSearchValue = '';
41667
41903
  togglePopup(open) {
41668
41904
  const sameState = this.isOpen === open;
41669
41905
  if (sameState) {
@@ -41897,6 +42133,7 @@ class SmartBoxComponent {
41897
42133
  }
41898
42134
  if (this.searchMode?.enabled) {
41899
42135
  this.selectedView = 'search';
42136
+ isPresent$1(this.lastSearchValue) && (this.input.nativeElement.value = this.lastSearchValue);
41900
42137
  }
41901
42138
  else if (this.semanticSearchMode?.enabled) {
41902
42139
  this.selectedView = 'semanticSearch';
@@ -41939,7 +42176,7 @@ class SmartBoxComponent {
41939
42176
  this.aiAssistantResponseError.emit(responseErrorEvent);
41940
42177
  }
41941
42178
  clearValue() {
41942
- this.input.nativeElement.value = '';
42179
+ this.input.nativeElement.value = this.lastSearchValue = '';
41943
42180
  this.input.nativeElement.focus();
41944
42181
  }
41945
42182
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: SmartBoxComponent, deps: [{ token: i2.PopupService }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: i1$4.IntlService }, { token: ContextService }, { token: GridAIRequestResponseService }, { token: i1$8.HttpClient }, { token: i0.Renderer2 }, { token: ColumnInfoService }, { token: SearchService }], target: i0.ɵɵFactoryTarget.Component });
@@ -42036,10 +42273,11 @@ class SmartBoxComponent {
42036
42273
  @if (segmentedControlButtons.length > 0) {
42037
42274
  <kendo-segmented-control
42038
42275
  [buttons]="segmentedControlButtons"
42039
- (buttonClick)="onModeChange($event)">
42276
+ (buttonClick)="onModeChange($event)"
42277
+ size="small">
42040
42278
  </kendo-segmented-control>
42041
42279
  }
42042
- <div class="k-list k-list-md">
42280
+ <div class="k-list">
42043
42281
  <div class="k-list-content">
42044
42282
  <ul class="k-list-ul">
42045
42283
  @if ((selectedView === 'search' || selectedView === 'semanticSearch') && searchListData.length > 0) {
@@ -42048,7 +42286,7 @@ class SmartBoxComponent {
42048
42286
  (click)="onSearchItemClick(item)">
42049
42287
  @if (item.selected) {
42050
42288
  <kendo-icon-wrapper
42051
- innerCssClass="k-list-item-icon"
42289
+ innerCssClass="k-list-item-icon k-smart-box-check-icon"
42052
42290
  name="check"
42053
42291
  [svgIcon]="checkIcon"
42054
42292
  class="k-list-item-icon-wrapper">
@@ -42309,10 +42547,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
42309
42547
  @if (segmentedControlButtons.length > 0) {
42310
42548
  <kendo-segmented-control
42311
42549
  [buttons]="segmentedControlButtons"
42312
- (buttonClick)="onModeChange($event)">
42550
+ (buttonClick)="onModeChange($event)"
42551
+ size="small">
42313
42552
  </kendo-segmented-control>
42314
42553
  }
42315
- <div class="k-list k-list-md">
42554
+ <div class="k-list">
42316
42555
  <div class="k-list-content">
42317
42556
  <ul class="k-list-ul">
42318
42557
  @if ((selectedView === 'search' || selectedView === 'semanticSearch') && searchListData.length > 0) {
@@ -42321,7 +42560,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
42321
42560
  (click)="onSearchItemClick(item)">
42322
42561
  @if (item.selected) {
42323
42562
  <kendo-icon-wrapper
42324
- innerCssClass="k-list-item-icon"
42563
+ innerCssClass="k-list-item-icon k-smart-box-check-icon"
42325
42564
  name="check"
42326
42565
  [svgIcon]="checkIcon"
42327
42566
  class="k-list-item-icon-wrapper">
@@ -95,6 +95,7 @@ import { AdaptiveRendererComponent } from './adaptiveness/adaptive-renderer.comp
95
95
  import { DataMappingService } from './data/data-mapping.service';
96
96
  import { DataLayoutMode, DataLayoutModeSettings } from './common/data-layout-mode';
97
97
  import { GridColSize } from './common/grid-col-size';
98
+ import { SearchService } from './rendering/toolbar/tools/smartbox/search.service';
98
99
  import * as i0 from "@angular/core";
99
100
  /**
100
101
  * Represents the Kendo UI for Angular Data Grid component.
@@ -165,6 +166,7 @@ export declare class GridComponent implements AfterContentInit, AfterViewInit, O
165
166
  private dataMappingService;
166
167
  private aiRequestResponseService;
167
168
  private idService;
169
+ private searchService;
168
170
  /**
169
171
  * Sets the data of the Grid. If you provide an array, the Grid gets the total count automatically.
170
172
  * ([more information and example](https://www.telerik.com/kendo-angular-ui/components/grid/data-binding/basics)).
@@ -759,7 +761,7 @@ export declare class GridComponent implements AfterContentInit, AfterViewInit, O
759
761
  private rowReorderSubscription;
760
762
  private rtl;
761
763
  private _rowSticky;
762
- constructor(supportService: BrowserSupportService, selectionService: SelectionService, cellSelectionService: CellSelectionService, wrapper: ElementRef, groupInfoService: GroupInfoService, groupsService: GroupsService, changeNotification: ChangeNotificationService, detailsService: DetailsService, editService: EditService, filterService: FilterService, pdfService: PDFService, responsiveService: ResponsiveService, renderer: Renderer2, excelService: ExcelService, csvService: CSVService, ngZone: NgZone, scrollSyncService: ScrollSyncService, domEvents: DomEventsService, columnResizingService: ColumnResizingService, changeDetectorRef: ChangeDetectorRef, columnReorderService: ColumnReorderService, columnInfoService: ColumnInfoService, navigationService: NavigationService, sortService: SortService, scrollRequestService: ScrollRequestService, localization: LocalizationService, ctx: ContextService, sizingService: SizingOptionsService, adaptiveGridService: AdaptiveGridService, rowReorderService: RowReorderService, dataMappingService: DataMappingService, aiRequestResponseService: GridAIRequestResponseService, idService: IdService);
764
+ constructor(supportService: BrowserSupportService, selectionService: SelectionService, cellSelectionService: CellSelectionService, wrapper: ElementRef, groupInfoService: GroupInfoService, groupsService: GroupsService, changeNotification: ChangeNotificationService, detailsService: DetailsService, editService: EditService, filterService: FilterService, pdfService: PDFService, responsiveService: ResponsiveService, renderer: Renderer2, excelService: ExcelService, csvService: CSVService, ngZone: NgZone, scrollSyncService: ScrollSyncService, domEvents: DomEventsService, columnResizingService: ColumnResizingService, changeDetectorRef: ChangeDetectorRef, columnReorderService: ColumnReorderService, columnInfoService: ColumnInfoService, navigationService: NavigationService, sortService: SortService, scrollRequestService: ScrollRequestService, localization: LocalizationService, ctx: ContextService, sizingService: SizingOptionsService, adaptiveGridService: AdaptiveGridService, rowReorderService: RowReorderService, dataMappingService: DataMappingService, aiRequestResponseService: GridAIRequestResponseService, idService: IdService, searchService: SearchService);
763
765
  /**
764
766
  * Expands the master row at the specified data row index ([see example](https://www.telerik.com/kendo-angular-ui/components/grid/master-detail)).
765
767
  *
@@ -838,6 +840,10 @@ export declare class GridComponent implements AfterContentInit, AfterViewInit, O
838
840
  * ```
839
841
  */
840
842
  handleAIResponse(response: any): void;
843
+ /**
844
+ * Clears the search operation applied through the SmartBox tool.
845
+ */
846
+ clearSearch(): void;
841
847
  /**
842
848
  * @hidden
843
849
  */
@@ -7,7 +7,7 @@ export const packageMetadata = {
7
7
  "productCodes": [
8
8
  "KENDOUIANGULAR"
9
9
  ],
10
- "publishDate": 1771334906,
11
- "version": "23.0.2-develop.1",
10
+ "publishDate": 1771342428,
11
+ "version": "23.1.0-develop.1",
12
12
  "licensingDocsUrl": "https://www.telerik.com/kendo-angular-ui/my-license/"
13
13
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@progress/kendo-angular-grid",
3
- "version": "23.0.2-develop.1",
3
+ "version": "23.1.0-develop.1",
4
4
  "description": "Kendo UI Grid for Angular - high performance data grid with paging, filtering, virtualization, CRUD, and more.",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "author": "Progress",
@@ -73,7 +73,7 @@
73
73
  "package": {
74
74
  "productName": "Kendo UI for Angular",
75
75
  "productCode": "KENDOUIANGULAR",
76
- "publishDate": 1771334906,
76
+ "publishDate": 1771342428,
77
77
  "licensingDocsUrl": "https://www.telerik.com/kendo-angular-ui/my-license/"
78
78
  }
79
79
  },
@@ -86,32 +86,32 @@
86
86
  "@progress/kendo-data-query": "^1.7.3",
87
87
  "@progress/kendo-drawing": "^1.24.0",
88
88
  "@progress/kendo-licensing": "^1.10.0",
89
- "@progress/kendo-angular-buttons": "23.0.2-develop.1",
90
- "@progress/kendo-angular-common": "23.0.2-develop.1",
91
- "@progress/kendo-angular-dateinputs": "23.0.2-develop.1",
92
- "@progress/kendo-angular-layout": "23.0.2-develop.1",
93
- "@progress/kendo-angular-navigation": "23.0.2-develop.1",
94
- "@progress/kendo-angular-dropdowns": "23.0.2-develop.1",
95
- "@progress/kendo-angular-excel-export": "23.0.2-develop.1",
96
- "@progress/kendo-angular-icons": "23.0.2-develop.1",
97
- "@progress/kendo-angular-indicators": "23.0.2-develop.1",
98
- "@progress/kendo-angular-inputs": "23.0.2-develop.1",
99
- "@progress/kendo-angular-conversational-ui": "23.0.2-develop.1",
100
- "@progress/kendo-angular-intl": "23.0.2-develop.1",
101
- "@progress/kendo-angular-l10n": "23.0.2-develop.1",
102
- "@progress/kendo-angular-label": "23.0.2-develop.1",
103
- "@progress/kendo-angular-menu": "23.0.2-develop.1",
104
- "@progress/kendo-angular-pager": "23.0.2-develop.1",
105
- "@progress/kendo-angular-pdf-export": "23.0.2-develop.1",
106
- "@progress/kendo-angular-popup": "23.0.2-develop.1",
107
- "@progress/kendo-angular-toolbar": "23.0.2-develop.1",
108
- "@progress/kendo-angular-upload": "23.0.2-develop.1",
109
- "@progress/kendo-angular-utils": "23.0.2-develop.1",
89
+ "@progress/kendo-angular-buttons": "23.1.0-develop.1",
90
+ "@progress/kendo-angular-common": "23.1.0-develop.1",
91
+ "@progress/kendo-angular-dateinputs": "23.1.0-develop.1",
92
+ "@progress/kendo-angular-layout": "23.1.0-develop.1",
93
+ "@progress/kendo-angular-navigation": "23.1.0-develop.1",
94
+ "@progress/kendo-angular-dropdowns": "23.1.0-develop.1",
95
+ "@progress/kendo-angular-excel-export": "23.1.0-develop.1",
96
+ "@progress/kendo-angular-icons": "23.1.0-develop.1",
97
+ "@progress/kendo-angular-indicators": "23.1.0-develop.1",
98
+ "@progress/kendo-angular-inputs": "23.1.0-develop.1",
99
+ "@progress/kendo-angular-conversational-ui": "23.1.0-develop.1",
100
+ "@progress/kendo-angular-intl": "23.1.0-develop.1",
101
+ "@progress/kendo-angular-l10n": "23.1.0-develop.1",
102
+ "@progress/kendo-angular-label": "23.1.0-develop.1",
103
+ "@progress/kendo-angular-menu": "23.1.0-develop.1",
104
+ "@progress/kendo-angular-pager": "23.1.0-develop.1",
105
+ "@progress/kendo-angular-pdf-export": "23.1.0-develop.1",
106
+ "@progress/kendo-angular-popup": "23.1.0-develop.1",
107
+ "@progress/kendo-angular-toolbar": "23.1.0-develop.1",
108
+ "@progress/kendo-angular-upload": "23.1.0-develop.1",
109
+ "@progress/kendo-angular-utils": "23.1.0-develop.1",
110
110
  "rxjs": "^6.5.3 || ^7.0.0"
111
111
  },
112
112
  "dependencies": {
113
113
  "tslib": "^2.3.1",
114
- "@progress/kendo-angular-schematics": "23.0.2-develop.1",
114
+ "@progress/kendo-angular-schematics": "23.1.0-develop.1",
115
115
  "@progress/kendo-common": "^1.0.1",
116
116
  "@progress/kendo-file-saver": "^1.0.0",
117
117
  "@progress/kendo-csv": "^1.0.0"
@@ -101,6 +101,7 @@ export declare class ListComponent implements OnInit, OnDestroy, AfterViewInit,
101
101
  table: ElementRef;
102
102
  resizeSensors: QueryList<ResizeSensorComponent>;
103
103
  private scroller;
104
+ private scrollerFactory;
104
105
  private subscriptions;
105
106
  private scrollerSubscription;
106
107
  private dispatcher;
@@ -141,6 +142,18 @@ export declare class ListComponent implements OnInit, OnDestroy, AfterViewInit,
141
142
  syncRowsHeight(): void;
142
143
  ngOnDestroy(): void;
143
144
  init(): void;
145
+ /**
146
+ * Resets all virtual scrolling state when the data source changes.
147
+ * Recreates everything as if the grid was just initialized for the first time.
148
+ * @hidden
149
+ */
150
+ resetVirtualScroll(newTotal: number): void;
151
+ /**
152
+ * Checks if the virtual scroll state is out of sync with the expected position.
153
+ * Used to determine if resetVirtualScroll should be called.
154
+ * @hidden
155
+ */
156
+ isVirtualScrollOutOfSync(): boolean;
144
157
  lockedScroll(): void;
145
158
  lockedMousewheel(args: any): void;
146
159
  lockedKeydown(args: any): void;
@@ -13,6 +13,14 @@ export declare class SearchService {
13
13
  * Fires when the search descriptor is set.
14
14
  */
15
15
  changes: Subject<CompositeFilterDescriptor>;
16
+ /**
17
+ * The descriptor used for searching.
18
+ */
19
+ searchFilter: CompositeFilterDescriptor;
20
+ /**
21
+ * The value used for searching.
22
+ */
23
+ searchValue: string;
16
24
  /**
17
25
  * Sets the search descriptor.
18
26
  *
@@ -24,7 +24,7 @@ export declare class SegmentedControlComponent implements AfterViewInit {
24
24
  /**
25
25
  * Sets the padding of the control.
26
26
  *
27
- * @default 'medium'
27
+ * @default undefined
28
28
  */
29
29
  set size(size: ButtonSize);
30
30
  get size(): ButtonSize;
@@ -122,9 +122,11 @@ export declare class SmartBoxComponent implements AfterViewInit, OnChanges, OnDe
122
122
  private popupMouseDownHandler;
123
123
  private requestData;
124
124
  private currentRequestSubscription;
125
+ private searchSubscription;
125
126
  private columns;
126
127
  private leafColumns;
127
128
  private searchTypingTimeout;
129
+ private lastSearchValue;
128
130
  togglePopup(open: boolean): void;
129
131
  onPromptSubmit(): void;
130
132
  onSpeechToTextResult(event: any): void;
@@ -9,19 +9,19 @@ const schematics_1 = require("@angular-devkit/schematics");
9
9
  function default_1(options) {
10
10
  const finalOptions = Object.assign(Object.assign({}, options), { mainNgModule: 'GridModule', package: 'grid', peerDependencies: {
11
11
  // peer deps of the dropdowns
12
- '@progress/kendo-angular-treeview': '23.0.2-develop.1',
13
- '@progress/kendo-angular-navigation': '23.0.2-develop.1',
12
+ '@progress/kendo-angular-treeview': '23.1.0-develop.1',
13
+ '@progress/kendo-angular-navigation': '23.1.0-develop.1',
14
14
  // peer dependency of kendo-angular-inputs
15
- '@progress/kendo-angular-dialog': '23.0.2-develop.1',
15
+ '@progress/kendo-angular-dialog': '23.1.0-develop.1',
16
16
  // peer dependency of kendo-angular-icons
17
17
  '@progress/kendo-svg-icons': '^4.0.0',
18
18
  // peer dependency of kendo-angular-layout
19
- '@progress/kendo-angular-progressbar': '23.0.2-develop.1',
19
+ '@progress/kendo-angular-progressbar': '23.1.0-develop.1',
20
20
  // transitive peer dependencies from toolbar
21
- '@progress/kendo-angular-indicators': '23.0.2-develop.1',
21
+ '@progress/kendo-angular-indicators': '23.1.0-develop.1',
22
22
  // transitive peer dependencies from conversational-ui
23
- '@progress/kendo-angular-menu': '23.0.2-develop.1',
24
- '@progress/kendo-angular-upload': '23.0.2-develop.1'
23
+ '@progress/kendo-angular-menu': '23.1.0-develop.1',
24
+ '@progress/kendo-angular-upload': '23.1.0-develop.1'
25
25
  } });
26
26
  return (0, schematics_1.externalSchematic)('@progress/kendo-angular-schematics', 'ng-add', finalOptions);
27
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 { State } from "@progress/kendo-data-query";
5
+ import { CompositeFilterDescriptor, State } from "@progress/kendo-data-query";
6
6
  import { GridDataResult } from "../data/data.collection";
7
7
  import { PreventableEvent } from "@progress/kendo-angular-common";
8
8
  /**
@@ -36,7 +36,7 @@ export interface ColumnState {
36
36
  }
37
37
  /**
38
38
  * Describes the state of the Grid component.
39
- * Includes the current `State`, data, and columns state.
39
+ * Includes the current `State`, data, columns and search state.
40
40
  */
41
41
  export interface GridState extends State {
42
42
  /**
@@ -47,6 +47,10 @@ export interface GridState extends State {
47
47
  * The current data in the Grid.
48
48
  */
49
49
  currentData?: Array<any> | GridDataResult | null;
50
+ /**
51
+ * The descriptors used for searching.
52
+ */
53
+ searchFilter?: CompositeFilterDescriptor;
50
54
  }
51
55
  /**
52
56
  * Provides arguments for the `undo` and `redo` events.