Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
9771eca
Refactor _synchronizeColumns method
nightskylark Jul 15, 2026
3d602d3
fix(popover): remove unnecessary type assertion for overlay stack check
nightskylark Jul 15, 2026
9957424
fix(m_utils): handle non-numeric selectionStart and selectionEnd values
nightskylark Jul 15, 2026
32ad957
fix(grid_view): correct spacing in _synchronizeColumns method
nightskylark Jul 15, 2026
dfde56e
fix(m_utils): remove selectionDirection from SelectionRange interface…
nightskylark Jul 21, 2026
ab0d0ef
Merge branch 'main' into T1329677
nightskylark Jul 21, 2026
c3b08be
Merge branch 'main' into T1329677
nightskylark Jul 22, 2026
304db48
Merge branch 'main' into T1329677
nightskylark Jul 24, 2026
7cb4328
Merge branch 'main' into T1329677
nightskylark Jul 29, 2026
99c13db
Merge branch 'main' into T1329677
nightskylark Aug 4, 2026
f73f438
Merge branch 'main' into T1329677
nightskylark Aug 18, 2026
a0ab2ec
Merge branch 'main' into T1329677
nightskylark Sep 22, 2026
781388e
Update after review
nightskylark Sep 22, 2026
fb7512e
Merge branch 'main' into T1329677
nightskylark Sep 22, 2026
1312c25
refactor(ResizingController): simplify expand column width calculation
nightskylark Sep 22, 2026
e86dc6d
refactor(ResizingController): remove redundant comment before measure…
nightskylark Sep 22, 2026
57b55a3
feat(SelectionRange): add SelectionRange interface and update imports
nightskylark Sep 23, 2026
9f83616
refactor(ResizingController): rename private methods for consistency
nightskylark Sep 23, 2026
cdce32f
refactor(ResizingController): rename private method _setMaxWidth to s…
nightskylark Sep 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ export interface Coordinates {
y: number;
}

export interface SelectionRange {
selectionStart: number;
selectionEnd: number;
}

// todo: move to upper .d.ts
type OptionsMethod<TOptions> = (() => TOptions)
& ((options: TOptions) => void)
Expand Down
17 changes: 10 additions & 7 deletions packages/devextreme/js/__internal/grids/grid_core/m_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import sharedFiltering from '@js/ui/shared/filtering';
import { getGlobalFormatByDataType } from '@ts/core/global_format_config';
import { isNumeric } from '@ts/core/utils/m_type';
import type { Column } from '@ts/grids/grid_core/columns_controller/types';
import type { ColumnPoint } from '@ts/grids/grid_core/m_types';
import type { ColumnPoint, SelectionRange } from '@ts/grids/grid_core/m_types';

import { AI_COLUMN_NAME } from './ai_column/const';
import type DataSourceAdapter from './data_source_adapter/m_data_source_adapter';
Expand Down Expand Up @@ -504,22 +504,25 @@ export default {

isDateType,

getSelectionRange(focusedElement) {
getSelectionRange(focusedElement): SelectionRange {
try {
if (focusedElement) {
return {
selectionStart: focusedElement.selectionStart,
selectionEnd: focusedElement.selectionEnd,
selectionStart: isNumeric(focusedElement.selectionStart) ? focusedElement.selectionStart : -1,
selectionEnd: isNumeric(focusedElement.selectionEnd) ? focusedElement.selectionEnd : -1,
};
Comment thread
nightskylark marked this conversation as resolved.
}
} catch (e) { /* empty */ }

return {};
return {
selectionStart: -1,
selectionEnd: -1,
};
},

setSelectionRange(focusedElement, selectionRange) {
setSelectionRange(focusedElement, selectionRange: SelectionRange): void {
try {
if (focusedElement && focusedElement.setSelectionRange) {
if (focusedElement && focusedElement.setSelectionRange && selectionRange.selectionStart >= 0 && selectionRange.selectionEnd >= 0) {
focusedElement.setSelectionRange(selectionRange.selectionStart, selectionRange.selectionEnd);
}
} catch (e) { /* empty */ }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { describe, expect, it } from '@jest/globals';

import type { Column } from '../../columns_controller/types';
import { ResizingController } from '../m_grid_view';

type ColumnWidth = number | string | undefined;

// NOTE: the method is private, so it is picked from the prototype to be tested in isolation.
const resizingControllerPrototype = ResizingController.prototype as unknown as {
normalizeWidthsByExpandColumns: (
resultWidths: ColumnWidth[],
visibleColumns: Column[],
) => void;
};

const normalizeWidthsByExpandColumns = (
resultWidths: ColumnWidth[],
visibleColumns: Column[],
): ColumnWidth[] => {
resizingControllerPrototype.normalizeWidthsByExpandColumns(resultWidths, visibleColumns);

return resultWidths;
};

const expandColumn = (): Column => ({ type: 'groupExpand', command: 'expand' } as Column);
const dataColumn = (dataField: string): Column => ({ dataField } as Column);

describe('ResizingController.normalizeWidthsByExpandColumns', () => {
it('leaves the widths as is when there are no expand columns', () => {
const columns = [dataColumn('a'), dataColumn('b')];

expect(normalizeWidthsByExpandColumns([100, 200], columns)).toEqual([100, 200]);
});

it('leaves the widths as is when there is a single expand column', () => {
const columns = [expandColumn(), dataColumn('a')];

expect(normalizeWidthsByExpandColumns([30, 200], columns)).toEqual([30, 200]);
});

// NOTE: all groupExpand columns share a single column id (command:expand), so the width
// of the last one is the value that _setVisibleWidths actually applies to all of them.
it('applies the width of the LAST expand column to every expand column', () => {
const columns = [expandColumn(), expandColumn(), dataColumn('a')];

expect(normalizeWidthsByExpandColumns([21, 30, 200], columns)).toEqual([30, 30, 200]);
});

it('normalizes expand columns that are not adjacent to each other', () => {
const columns = [
dataColumn('a'),
expandColumn(),
dataColumn('b'),
expandColumn(),
dataColumn('c'),
];

expect(normalizeWidthsByExpandColumns([100, 21, 200, 30, 300], columns))
.toEqual([100, 30, 200, 30, 300]);
});

it('ignores the detailExpand column', () => {
const columns = [
{ type: 'detailExpand', command: 'expand' } as Column,
expandColumn(),
expandColumn(),
];

expect(normalizeWidthsByExpandColumns([15, 21, 30], columns)).toEqual([15, 30, 30]);
});

// NOTE: a falsy width means the column could not be measured (e.g. the grid is hidden).
it.each([
['zero', 0],
['undefined', undefined],
])('keeps the measured widths when the last expand column width is %s', (_, width) => {
const columns = [expandColumn(), expandColumn(), dataColumn('a')];

expect(normalizeWidthsByExpandColumns([21, width, 200], columns)).toEqual([21, width, 200]);
});
});
Loading
Loading