@dhtmlx/grid 9.3.12 → 9.4.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.
Files changed (38) hide show
  1. package/README.md +1 -1
  2. package/codebase/grid.min.css +1 -1
  3. package/codebase/grid.min.js +3 -3
  4. package/codebase/grid.min.js.map +1 -1
  5. package/codebase/types/ts-calendar/sources/Calendar.d.ts +6 -0
  6. package/codebase/types/ts-calendar/sources/helper.d.ts +1 -0
  7. package/codebase/types/ts-calendar/sources/types.d.ts +3 -0
  8. package/codebase/types/ts-common/date.d.ts +2 -0
  9. package/codebase/types/ts-data/sources/datacollection/group.d.ts +11 -0
  10. package/codebase/types/ts-data/sources/datacollection.d.ts +84 -3
  11. package/codebase/types/ts-data/sources/methods.d.ts +8 -3
  12. package/codebase/types/ts-data/sources/treecollection.d.ts +99 -0
  13. package/codebase/types/ts-data/sources/types.d.ts +12 -2
  14. package/codebase/types/ts-grid/sources/ExtendedGrid.d.ts +3 -1
  15. package/codebase/types/ts-grid/sources/Grid.d.ts +10 -2
  16. package/codebase/types/ts-grid/sources/helpers/data.d.ts +16 -1
  17. package/codebase/types/ts-grid/sources/helpers/default.d.ts +1 -0
  18. package/codebase/types/ts-grid/sources/helpers/dom.d.ts +3 -0
  19. package/codebase/types/ts-grid/sources/helpers/zoneFocus.d.ts +15 -4
  20. package/codebase/types/ts-grid/sources/locales/en.d.ts +0 -2
  21. package/codebase/types/ts-grid/sources/modules/History.d.ts +4 -0
  22. package/codebase/types/ts-grid/sources/modules/Selection.d.ts +3 -0
  23. package/codebase/types/ts-grid/sources/types.d.ts +36 -5
  24. package/codebase/types/ts-grid/sources/ui/cells.d.ts +3 -1
  25. package/codebase/types/ts-grid/sources/ui/content/ComboFilter.d.ts +1 -0
  26. package/codebase/types/ts-grid/sources/ui/content/SelectFilter.d.ts +1 -0
  27. package/codebase/types/ts-grid/sources/ui/content.d.ts +6 -2
  28. package/codebase/types/ts-grid/sources/ui/editors/DateEditor.d.ts +1 -0
  29. package/codebase/types/ts-grid/sources/ui/proContent.d.ts +3 -16
  30. package/codebase/types/ts-layout/sources/Cell.d.ts +10 -0
  31. package/codebase/types/ts-layout/sources/helpers/constants.d.ts +2 -0
  32. package/codebase/types/ts-layout/sources/{helpers.d.ts → helpers/helpers.d.ts} +1 -1
  33. package/codebase/types/ts-layout/sources/types.d.ts +2 -1
  34. package/codebase/types/ts-message/sources/locales/en.d.ts +1 -0
  35. package/codebase/types/ts-treegrid/sources/TreeGrid.d.ts +0 -2
  36. package/codebase/types/ts-treegrid/sources/TreeGridCollection.d.ts +2 -1
  37. package/package.json +1 -1
  38. package/whatsnew.txt +74 -0
@@ -18,7 +18,7 @@ import { PrefixSums } from "./helpers/PrefixSums";
18
18
  import { IBlockSelection, IBlockSelectionConfig } from "./modules/BlockSelection";
19
19
  import { IClipboard, IClipboardConfig } from "./modules/Clipboard";
20
20
  import { IHistory, IHistoryConfig } from "./modules/History";
21
- import { IComboFilterConfig, IContentList, IHeaderFilter, IInputFilterConfig } from "./ui/content";
21
+ import { IComboFilterConfig, IContentList, IHeaderFilter, IInputFilterConfig, ISelectFilterConfig } from "./ui/content";
22
22
  import { ExportType, ICsvExportConfig, IXlsxExportConfig } from "./modules/Exporter";
23
23
  import { IDateFilterConfig, IProContentList, IProHeaderFilter } from "./ui/proContent";
24
24
  /**
@@ -110,8 +110,8 @@ export interface IGridConfig extends IDragConfig {
110
110
  height?: number | "auto";
111
111
  autoWidth?: boolean;
112
112
  rowHeight?: number;
113
- headerRowHeight?: number;
114
- footerRowHeight?: number;
113
+ headerRowHeight?: TFixedRowHeight;
114
+ footerRowHeight?: TFixedRowHeight;
115
115
  footerPosition?: IFooterPosition;
116
116
  leftSplit?: number;
117
117
  topSplit?: number;
@@ -126,6 +126,7 @@ export interface IGridConfig extends IDragConfig {
126
126
  css?: string;
127
127
  rowCss?: (row: IRow) => string;
128
128
  exportStyles?: boolean | string[];
129
+ ariaLabel?: string;
129
130
  selection?: ISelectionType;
130
131
  multiselection?: boolean;
131
132
  rangeSelection?: boolean | IRangeConfig;
@@ -167,6 +168,8 @@ export interface IGridConfig extends IDragConfig {
167
168
  $footerHeight?: number;
168
169
  $headerHeightMap?: number[];
169
170
  $footerHeightMap?: number[];
171
+ $headerAutoHeightMap?: boolean[];
172
+ $footerAutoHeightMap?: boolean[];
170
173
  $totalWidth?: number;
171
174
  $totalHeight?: number;
172
175
  $rowHeights?: PrefixSums;
@@ -243,6 +246,8 @@ export interface IRendererConfig extends Required<IProGridConfig> {
243
246
  $renderFrom?: RenderFrom;
244
247
  $isDragging?: boolean;
245
248
  $rowIndexShift?: number;
249
+ /** @internal only for {@link ICellState.hideSpans} in a grid with rendered spans */
250
+ $spanAreas?: ISpanArea[];
246
251
  _events?: IEventSystem<GridSystemEvents>;
247
252
  }
248
253
  export declare enum GridEvents {
@@ -447,6 +452,7 @@ export interface ICol {
447
452
  };
448
453
  $uniqueData?: any[];
449
454
  $activeFilterData?: any[];
455
+ $filterOptions?: IOption[];
450
456
  $index?: number;
451
457
  $width?: number;
452
458
  $fixedWidth?: boolean;
@@ -463,6 +469,8 @@ export interface IRow {
463
469
  $opened?: boolean;
464
470
  $subRowHeight?: number;
465
471
  $draggable?: boolean;
472
+ $count?: number;
473
+ $totalCount?: number;
466
474
  }
467
475
  export interface ISpan {
468
476
  row: Id;
@@ -500,7 +508,7 @@ export interface IContent {
500
508
  export type TContentFilter = "inputFilter" | "selectFilter" | "comboFilter" | "dateFilter";
501
509
  export interface IHeader extends IContent {
502
510
  content?: TContentFilter;
503
- filterConfig?: IComboFilterConfig | IInputFilterConfig | IDateFilterConfig;
511
+ filterConfig?: IComboFilterConfig | IInputFilterConfig | IDateFilterConfig | ISelectFilterConfig;
504
512
  customFilter?: (item: string | number | Date | Date[], match: string | string[] | Date | Date[]) => boolean;
505
513
  headerSort?: boolean;
506
514
  sortAs?: SortFunction;
@@ -545,6 +553,8 @@ export interface IGroup {
545
553
  panelHeight: number;
546
554
  hideableColumns?: boolean;
547
555
  showMissed?: boolean | string;
556
+ showEmptyGroups?: boolean;
557
+ counter?: boolean | ((row: IRow) => string);
548
558
  fields?: {
549
559
  [colId: string]: Omit<IGroupOrder, "by">;
550
560
  };
@@ -625,6 +635,7 @@ export interface IOption {
625
635
  value: string;
626
636
  }
627
637
  export type TOption = IOption | string;
638
+ export type TFilterOptions = TOption[] | ((uniqueData: IOption[], col: ICol) => TOption[]);
628
639
  export type SortFunction = (cellValue: any) => string | number;
629
640
  type MarkFunction = (cell: any, columnCells: any[], row: IRow, column: ICol) => string;
630
641
  export interface IMark {
@@ -651,7 +662,7 @@ export interface ILayoutState {
651
662
  footerAtBottom: boolean;
652
663
  }
653
664
  export interface IFixedRowsConfig extends ILayoutState {
654
- name: "header" | "footer";
665
+ name: TFixedRowsName;
655
666
  position: "top" | "bottom";
656
667
  }
657
668
  export interface ICoords {
@@ -676,6 +687,12 @@ export type IDragType = "row" | "column" | "both";
676
687
  export type AdjustTargetType = "data" | "header" | "footer";
677
688
  export type IAdjustBy = AdjustTargetType | boolean;
678
689
  export type IFooterPosition = "bottom" | "relative";
690
+ export type TFixedRowsName = "header" | "footer";
691
+ export type TFixedRowHeight = number | (number | "auto")[];
692
+ export interface IFixedRowLevel {
693
+ height: number;
694
+ auto: boolean;
695
+ }
679
696
  export interface IAdjustColumns {
680
697
  rows: IRow[];
681
698
  cols: ICol[];
@@ -721,5 +738,19 @@ export interface ICellState {
721
738
  }>;
722
739
  editable?: boolean;
723
740
  multiselectable?: boolean;
741
+ /** Read-only cells in an editable grid: a row id and a set of column ids. */
742
+ readonlyCells?: Map<Id, Set<Id>>;
743
+ /** The first cell of a span shows its content, so the span element and the cells under it are hidden. */
744
+ hideSpans?: boolean;
745
+ }
746
+ /** @internal the cells of a rendered span */
747
+ export interface ISpanArea {
748
+ /** the column id of the first cell */
749
+ column: Id;
750
+ /** the data index range of the rows */
751
+ rowStart: number;
752
+ rowEnd: number;
753
+ /** the column ids */
754
+ columns: Set<string>;
724
755
  }
725
756
  export {};
@@ -1,4 +1,4 @@
1
- import { GridEvents, GridSystemEvents, ICoords, IGridConfig, IRendererConfig, ISpan, Split } from "../types";
1
+ import { GridEvents, GridSystemEvents, ICellState, ICoords, IGridConfig, IRendererConfig, ISpan, Split } from "../types";
2
2
  import { IDataCollection } from "../../../ts-data";
3
3
  import { Id } from "../../../ts-common/types";
4
4
  type mouseEvents = GridEvents.cellClick | GridEvents.cellMouseOver | GridEvents.cellMouseDown | GridEvents.cellDblClick | GridEvents.cellRightClick;
@@ -25,6 +25,8 @@ export interface IResolvedCellState {
25
25
  tabRow: Id;
26
26
  tabCol: Id;
27
27
  readonly: "true" | "false";
28
+ /** the cells a host reports as read-only in an editable grid */
29
+ readonlyCells: ICellState["readonlyCells"];
28
30
  /** whether `aria-selected` belongs on a cell at all — it does not in row selection mode */
29
31
  exposeSelected: boolean;
30
32
  isSelected: (rowId: Id, colId: Id) => boolean;
@@ -31,5 +31,6 @@ export declare class ComboFilter implements IHeaderFilter {
31
31
  blur(): void;
32
32
  destructor(): void;
33
33
  private _setData;
34
+ private _getFilterValue;
34
35
  private _checkValue;
35
36
  }
@@ -24,5 +24,6 @@ export declare class SelectFilter implements IHeaderFilter {
24
24
  clear(silent?: boolean): void;
25
25
  focus(): void;
26
26
  blur(): void;
27
+ private _getOptions;
27
28
  private initHandlers;
28
29
  }
@@ -1,5 +1,5 @@
1
1
  import { VNode } from "../../../ts-common/dom";
2
- import { ICol, IExtendedGrid, IGrid, IProGrid, IRendererConfig } from "../types";
2
+ import { ICol, IExtendedGrid, IGrid, IProGrid, IRendererConfig, TFilterOptions } from "../types";
3
3
  import { DataCollection, IDataItem } from "../../../ts-data";
4
4
  import { Combobox } from "../../../ts-combobox";
5
5
  import { IEventSystem } from "../../../ts-common/events";
@@ -12,11 +12,15 @@ export interface IComboFilterConfig {
12
12
  readonly?: boolean;
13
13
  virtual?: boolean;
14
14
  multiselection?: boolean;
15
+ options?: TFilterOptions;
15
16
  }
16
17
  export interface IInputFilterConfig {
17
18
  placeholder?: string;
18
19
  icon?: string;
19
20
  }
21
+ export interface ISelectFilterConfig {
22
+ options?: TFilterOptions;
23
+ }
20
24
  export declare enum HeaderFilterEvent {
21
25
  change = "change"
22
26
  }
@@ -27,7 +31,7 @@ export interface IHeaderFilter {
27
31
  events: IEventSystem<HeaderFilterEvent>;
28
32
  data?: string[] | IDataItem[];
29
33
  id?: Id;
30
- filterConfig?: IComboFilterConfig | IInputFilterConfig;
34
+ filterConfig?: IComboFilterConfig | IInputFilterConfig | ISelectFilterConfig;
31
35
  getFilter(): VNode | Combobox;
32
36
  setValue(value: string | string[], silent?: boolean): void;
33
37
  clear(silent?: boolean): void;
@@ -29,6 +29,7 @@ export declare class DateEditor implements IEditor {
29
29
  thisMonthOnly?: boolean;
30
30
  width?: string | number;
31
31
  $rangeMark?: (a: Date) => string;
32
+ controls?: boolean | import("../../../../ts-calendar").TCalendarControlsInput[];
32
33
  block?: (a: Date) => boolean;
33
34
  view?: import("../../../../ts-calendar").ViewMode;
34
35
  };
@@ -1,22 +1,9 @@
1
1
  import { IExtendedGrid, IProGrid } from "../types";
2
- import { ICellContent, IHeaderFilter } from "./content";
2
+ import { ICellContent, IComboFilterConfig, IHeaderFilter, IInputFilterConfig, ISelectFilterConfig } from "./content";
3
3
  import { VNode } from "../../../ts-common/dom";
4
- import { DataCollection, IDataItem } from "../../../ts-data";
5
4
  import { Calendar, ICalendarConfig } from "../../../ts-calendar";
6
5
  import { Combobox } from "../../../ts-combobox";
7
- export interface IComboFilterConfig {
8
- template?: (item: IDataItem) => string;
9
- filter?: (item: IDataItem, input: string) => boolean;
10
- data?: DataCollection<IDataItem> | IDataItem[];
11
- placeholder?: string;
12
- readonly?: boolean;
13
- virtual?: boolean;
14
- multiselection?: boolean;
15
- }
16
- export interface IInputFilterConfig {
17
- placeholder?: string;
18
- icon?: string;
19
- }
6
+ export { IComboFilterConfig, IInputFilterConfig, ISelectFilterConfig } from "./content";
20
7
  export interface IDateFilterConfig extends Omit<ICalendarConfig, "value" | "css" | "$rangeMark"> {
21
8
  icon?: string;
22
9
  placeholder?: string;
@@ -24,7 +11,7 @@ export interface IDateFilterConfig extends Omit<ICalendarConfig, "value" | "css"
24
11
  }
25
12
  export interface IProHeaderFilter extends Omit<IHeaderFilter, "value" | "filterConfig"> {
26
13
  value: string | string[] | Date | Date[];
27
- filterConfig?: IComboFilterConfig | IDateFilterConfig | IInputFilterConfig;
14
+ filterConfig?: IComboFilterConfig | IDateFilterConfig | IInputFilterConfig | ISelectFilterConfig;
28
15
  getFilter(): VNode | Combobox | Calendar;
29
16
  setValue(value: string | string[] | Date | Date[], silent?: boolean): void;
30
17
  }
@@ -19,6 +19,7 @@ export declare class Cell extends View implements ICell {
19
19
  protected _theme: string;
20
20
  private _isLastFlexCell;
21
21
  private _afterWindowResized;
22
+ private _headerSize;
22
23
  constructor(parent: string | HTMLElement | ILayout, config: ICellConfig);
23
24
  paint(): void;
24
25
  isVisible(): boolean;
@@ -39,11 +40,20 @@ export declare class Cell extends View implements ICell {
39
40
  progressHide(): void;
40
41
  isVisibleProgress(): boolean;
41
42
  toVDOM(nodes?: any[]): any;
43
+ protected _renderHeader(): any;
44
+ protected _isRotatedHeader(): boolean;
45
+ protected _getHeaderStyle(): {
46
+ height?: number;
47
+ minWidth?: number;
48
+ };
49
+ protected _saveHeaderSize(): void;
50
+ protected _renderCellHeaderContent(): any;
42
51
  protected _saveTheme(): void;
43
52
  protected _getProgressBar(): any;
44
53
  protected _getCss(_content?: boolean): string;
45
54
  protected _initHandlers(): void;
46
55
  protected _getCollapsedSize(cell: ICell, nextCell: ICell): number;
56
+ protected _getCellSize(cell: any): number;
47
57
  protected _getCollapseIcon(): "dxi dxi-chevron-down" | "dxi dxi-chevron-right" | "dxi dxi-chevron-left" | "dxi dxi-chevron-up";
48
58
  protected _isLastCell(): boolean;
49
59
  protected _getNextCell(): any;
@@ -0,0 +1,2 @@
1
+ export declare const DEFAULT_CELL_HEADER_HEIGHT = 37;
2
+ export declare const DEFAULT_CELL_HEADER_WIDTH = 45;
@@ -1,4 +1,4 @@
1
- import { ICellConfig } from "./types";
1
+ import { ICellConfig } from "../types";
2
2
  export declare function getBlockRange(block1: ClientRect, block2: ClientRect, isXLayout?: boolean): {
3
3
  min: number;
4
4
  max: number;
@@ -4,11 +4,12 @@ import { IEventSystem } from "../../ts-common/events";
4
4
  import { FlexDirection } from "../../ts-common/html";
5
5
  import { ScrollView } from "../../ts-common/ScrollView";
6
6
  import { TLabelAlignment } from "../../ts-common/types";
7
+ export type TCellHeaderTemplate = (cell: ICellConfig) => string | IView;
7
8
  export interface ICellConfig {
8
9
  id?: string;
9
10
  html?: string;
10
11
  hidden?: boolean;
11
- header?: string;
12
+ header?: string | TCellHeaderTemplate;
12
13
  headerIcon?: string;
13
14
  headerImage?: string;
14
15
  headerHeight?: number;
@@ -1,6 +1,7 @@
1
1
  declare const locale: {
2
2
  apply: string;
3
3
  reject: string;
4
+ aria_alert: string;
4
5
  aria_confirm: string;
5
6
  aria_reject: string;
6
7
  aria_apply: string;
@@ -19,8 +19,6 @@ export declare class TreeGrid extends ExtendedGrid implements ITreeGrid {
19
19
  getSpan(rowId: Id, colId: Id): ISpan;
20
20
  protected _adjustColumnsWidth({ rows, cols, totalCols, adjust, }: IAdjustColumns): IColumnsWidth;
21
21
  protected _createCollection(): void;
22
- protected _getRowIndex(rowId: Id): number;
23
22
  protected _applyLocalFilter(beforePrepareData?: boolean): void;
24
23
  protected _setEventHandlers(): void;
25
- private _serialize;
26
24
  }
@@ -16,6 +16,7 @@ export declare class TreeGridCollection extends TreeCollection {
16
16
  protected _addToOrder(_order: any, obj: any, index: number): void;
17
17
  protected _removeCore(id: Id): void;
18
18
  protected _setParent(item: IDataItem, parent: Id): void;
19
- private _checkItems;
19
+ protected _recalculateGroups(): void;
20
+ protected _checkItems(): void;
20
21
  protected _moveItem(id: any, targetId: any, index: any): void;
21
22
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dhtmlx/grid",
3
- "version": "9.3.12",
3
+ "version": "9.4.1",
4
4
  "description": "DHTMLX Grid - JavaScript data grid library. GPL v2 edition for GPL-compatible open-source projects; commercial licenses are available for proprietary and production use.",
5
5
  "keywords": ["dhtmlx","grid","datagrid","table","treegrid","data-table","javascript","typescript"],
6
6
  "homepage":"https://docs.dhtmlx.com/suite/grid/",
package/whatsnew.txt CHANGED
@@ -1,3 +1,77 @@
1
+ Version 9.4.1 (October 26, 2026)
2
+ ----------------------------
3
+
4
+ ## Version 9.4 (October 22, 2026)
5
+
6
+ ### New functionality
7
+
8
+ #### DataCollection/TreeCollection
9
+
10
+ - The ability to get the position of an item among the visible ones
11
+ - new DataCollection method: `getVisibleIndex()`
12
+ - new TreeCollection method: `getVisibleIndex()`
13
+
14
+ #### Grid
15
+
16
+ - The ability to set an individual height for each row of the header/footer, including the *"auto"* value that adjusts a row to its content (PRO version)
17
+ - updated Grid configuration properties: `headerRowHeight` and `footerRowHeight`
18
+ - Group counters with the possibility to define the text rendered next to the group name and to keep the groups that are left with no rows after filtering (PRO version)
19
+ - new properties of the Grid `group` configuration object: `counter` and `showEmptyGroups`
20
+ - new property of the configuration object of the DataCollection `group()` method: `showEmptyGroups`
21
+ - service properties of a group header row: `$count`, `$totalCount`, `$by`
22
+ - The ability to define the options of a header/footer filter manually instead of building them from the column data
23
+ - new property of the `filterConfig` object of **selectFilter** and **comboFilter**: `options`
24
+
25
+ #### Accessibility
26
+
27
+ - The ability to set the accessible name of a widget, which a screen reader announces to the user, with the new `ariaLabel` configuration property of the following widgets:
28
+ - Grid - names a grid, so that several grids on one page can be told apart
29
+
30
+ ### Updates
31
+
32
+ - DataCollection. The `changeId()` method returns the new id of the item
33
+ - DataCollection. The `changeId()` method doesn't change the id of an item while the data is grouped. It returns the original id and shows a warning in the browser console
34
+ - Grid. The `headerAutoHeight` and `footerAutoHeight` properties, and the header/footer part of `autoHeight`, are ignored for a zone whose `headerRowHeight`/`footerRowHeight` is set as an array
35
+
36
+ #### Accessibility updates
37
+
38
+ - Grid. Keyboard navigation:
39
+ - `Tab` and `Shift` + `Tab` move cell by cell through the header, the body and the footer and leave the grid at its ends, and the arrow keys move within and between these zones whether or not a selection module is enabled.
40
+ - In a grid without a footer, `Tab` from the last body cell leaves the grid.
41
+ - `Tab` in the header and the footer reaches the columns scrolled out of view instead of skipping them.
42
+ - `Enter`, `Space` and `Shift` + `Enter` on a footer cell don't sort the column.
43
+ - In the selection and block selection modes, the keyboard focus moves to the cells of the frozen columns.
44
+
45
+ - Grid. Screen-reader announcements:
46
+ - The new `announce()` method sends a message to the live region of the grid, so a screen reader announces a status change without moving focus.
47
+ - Sorting, filtering, data loading and the range corrections of a numeric editor are announced through the same live region, and the announced texts are translated through the locale.
48
+
49
+ ### Fixes
50
+
51
+ - DataCollection. Fixed removing a group row leaving its items behind and the counters of the groups above it short
52
+ - DataCollection. Fixed changing the id of an item between adding the item and saving the changes, which produced a second save request for the item
53
+ - DataCollection/TreeCollection. Fixed the `avg`, `min` and `max` methods of the `dhx.methods` helper returning `NaN`, `Infinity` and `-Infinity` for an empty set of items instead of `null`
54
+ - DataCollection/TreeCollection. Fixed the counter and the aggregated values of a group staying at the values they had when the grouping was applied. They now follow filtering, adding, removing and updating of items, on every level of a nested grouping
55
+ - DataCollection/TreeCollection. Fixed the group summary rows (`summary: "top"` / `summary: "bottom"`) keeping the aggregates they had before filtering
56
+ - DataCollection/TreeCollection. Fixed filtering breaking the group structure: a rule that did not match a group row dropped that row and its summary row, leaving the items of the group without a header
57
+ - DataCollection/TreeCollection. Fixed a group staying in the collection with a non-zero counter after all its items were filtered out
58
+ - DataCollection/TreeCollection. Fixed the group counters not returning to their original values after `resetFilter()`
59
+ - DataCollection/TreeCollection. Fixed a group staying in the collection after all its items were removed
60
+ - Grid. Fixed the summaries counting the group rows and the group summary rows as data, which doubled the column and common totals in a grouped grid
61
+ - Grid. Fixed the group counters not being recalculated together with the tree structure of the grid
62
+ - Grid. Fixed the spans, the CSS classes added with `addCellCss()` and the selection of a row being lost after the id of the row was changed via `changeId()`
63
+ - Grid. Fixed the undo/redo actions of the History module referring to the old id of a row after the id was changed via `changeId()`
64
+ - Grid. Fixed the keyboard focus being moved back to the active cell after editing ended, when the focus had already gone to the header, the footer or outside the grid
65
+ - Grid. Fixed the `avg`, `min` and `max` summaries of a grid without rows being calculated as `NaN`, `Infinity` and `-Infinity` instead of `null`
66
+ - TreeCollection. Fixed filtering in an ungrouped tree: it skipped the items which carried a `$group` field
67
+ - TreeCollection. Fixed `changeId()` detaching the child items of an item from it, also when a filter was applied
68
+
69
+ ### New samples
70
+
71
+ - [Grid. Flexible header and footer row height](https://snippet.dhtmlx.com/bq7koy9z)
72
+ - [Grid. Custom options for header filters](https://snippet.dhtmlx.com/pcrjqux0)
73
+ - [Grid. Group counter after filtering](https://snippet.dhtmlx.com/sbynrizv)
74
+
1
75
  # Version 9.3.12 (September 23, 2026)
2
76
 
3
77
  ### Updates