Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
24 changes: 17 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 @@ -70,6 +70,12 @@ export function isDateType(dataType: string | undefined): boolean {
return dataType === 'date' || dataType === 'datetime';
}

export interface SelectionRange {
selectionStart: number;
selectionEnd: number;
selectionDirection?: 'forward' | 'backward' | 'none';
}

const getIntervalSelector = function () {
const data = arguments[1];
const value = this.calculateCellValue(data);
Expand Down Expand Up @@ -562,23 +568,27 @@ 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,
selectionDirection: focusedElement.selectionDirection ?? undefined,
};
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) {
focusedElement.setSelectionRange(selectionRange.selectionStart, selectionRange.selectionEnd);
if (focusedElement && focusedElement.setSelectionRange && selectionRange.selectionStart >= 0 && selectionRange.selectionEnd >= 0) {
focusedElement.setSelectionRange(selectionRange.selectionStart, selectionRange.selectionEnd, selectionRange.selectionDirection);
}
} catch (e) { /* empty */ }
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import type { ColumnHeadersView } from '../column_headers/m_column_headers';
import type { ColumnsController } from '../columns_controller/m_columns_controller';
import type { DataController } from '../data_controller/m_data_controller';
import modules from '../m_modules';
import gridCoreUtils from '../m_utils';
import gridCoreUtils, { type SelectionRange } from '../m_utils';
import type { RowsView } from './m_rows_view';

const BORDERS_CLASS = 'borders';
Expand Down Expand Up @@ -78,11 +78,17 @@ const calculateFreeWidthWithCurrentMinWidth = function (that, columnIndex, curre
return calculateFreeWidth(that, widths.map((width, index) => (index === columnIndex ? currentMinWidth : width)));
};

const restoreFocus = function (focusedElement, selectionRange) {
const restoreFocus = (focusedElement: Element, selectionRange: SelectionRange): void => {
accessibility.hiddenFocus(focusedElement, true);
gridCoreUtils.setSelectionRange(focusedElement, selectionRange);
};

interface MaxWidthController {
isModified: boolean;
set: (value: number) => void;
clear: () => void;
}

export class ResizingController extends modules.ViewController {
private _refreshSizesHandler: any;

Expand All @@ -100,8 +106,6 @@ export class ResizingController extends modules.ViewController {

private _prevContentMinHeight: any;

private _maxWidth: any;

private _hasWidth: any;

private _hasHeight: any;
Expand All @@ -122,6 +126,26 @@ export class ResizingController extends modules.ViewController {

public resizeCompleted!: Callback;

private readonly _maxWidth: MaxWidthController = {
isModified: false,
set: (value): void => {
const $element = this.component.$element();

this._maxWidth.isModified = true;
$element.css('maxWidth', value);
},
clear: (): void => {
const $element = this.component.$element();

if (!this._maxWidth.isModified || !$element || !$element.get(0)) {
return;
}

this._maxWidth.isModified = false;
$element[0].style.maxWidth = '';
},
};

protected callbackNames() {
return ['resizeCompleted'];
}
Expand Down Expand Up @@ -338,85 +362,55 @@ export class ResizingController extends modules.ViewController {
}
}

private _synchronizeColumns() {
const columnsController = this._columnsController;
const visibleColumns = columnsController.getVisibleColumns();
const columnAutoWidth = this.option('columnAutoWidth');
const hasUndefinedColumnWidth = visibleColumns.some((column) => !isDefined(column.width));
let needBestFit = this._needBestFit();
let hasMinWidth = false;
let resetBestFitMode;
let isColumnWidthsCorrected = false;
let resultWidths: any[] = [];
let focusedElement;
let selectionRange;
private _enableTemporaryBestFitMode(): () => void {
const $element = this.component.$element();
const focusedElement = domAdapter.getActiveElement($element.get(0) as HTMLElement | null);
const selectionRange = gridCoreUtils.getSelectionRange(focusedElement);

const normalizeWidthsByExpandColumns = function () {
let expandColumnWidth;
this._toggleBestFitMode(true);

each(visibleColumns, (index, column) => {
if (column.type === 'groupExpand') {
expandColumnWidth = resultWidths[index];
}
});
return (): void => {
this._toggleBestFitMode(false);

each(visibleColumns, (index, column) => {
if (column.type === 'groupExpand' && expandColumnWidth) {
resultWidths[index] = expandColumnWidth;
}
});
};
if (focusedElement && focusedElement !== domAdapter.getActiveElement()) {
const isFocusOutsideWindow = getBoundingRect(focusedElement).bottom < 0;

!needBestFit && each(visibleColumns, (index, column) => {
if (column.width === 'auto') {
needBestFit = true;
return false;
if (!isFocusOutsideWindow) {
restoreFocus(focusedElement, selectionRange);
}
}
return undefined;
});
};
}

each(visibleColumns, (index, column) => {
if (column.minWidth) {
hasMinWidth = true;
return false;
}
return undefined;
});
private _synchronizeColumns(): void {
const columnsController = this._columnsController;
const visibleColumns = columnsController.getVisibleColumns();
const columnAutoWidth = this.option('columnAutoWidth') as boolean;
const hasUndefinedColumnWidth = visibleColumns.some((column) => !isDefined(column.width));
const needBestFit = this._needBestFit() || visibleColumns.some((column) => column.width === 'auto');
const hasMinWidth = visibleColumns.some((column) => !!column.minWidth);

// Prepare for measurement
this._toggleContentMinHeight(this._hasHeight); // T1047239, T1270354

this._setVisibleWidths(visibleColumns, []);

const $element = this.component.$element();

if (needBestFit) {
// @ts-expect-error
focusedElement = domAdapter.getActiveElement($element.get(0));
selectionRange = gridCoreUtils.getSelectionRange(focusedElement);
this._toggleBestFitMode(true);
resetBestFitMode = true;
}

if ($element && $element.get(0) && this._maxWidth) {
delete this._maxWidth;
$element[0].style.maxWidth = '';
}
const restoreAfterBestFitMode = needBestFit && this._enableTemporaryBestFitMode();
this._maxWidth.clear();

// eslint-disable-next-line @typescript-eslint/no-floating-promises
deferUpdate(() => {
if (needBestFit) {
let resultWidths: (number | string | undefined)[] = [];

if (needBestFit || hasMinWidth) {
resultWidths = this._getBestFitWidths();
}

each(visibleColumns, (index, column) => {
each(visibleColumns, (index, column) => {
if (needBestFit) {
const columnId = columnsController.getColumnId(column);
columnsController.columnOption(columnId, 'bestFitWidth', resultWidths[index], true);
});
} else if (hasMinWidth) {
resultWidths = this._getBestFitWidths();
}
}

each(visibleColumns, function (index) {
const { width } = this;
const { width } = column;
if (width !== 'auto') {
if (isDefined(width)) {
resultWidths[index] = isNumeric(width) || isPixelWidth(width) ? parseFloat(width) : width;
Expand All @@ -426,21 +420,14 @@ export class ResizingController extends modules.ViewController {
}
});

if (resetBestFitMode) {
this._toggleBestFitMode(false);
resetBestFitMode = false;
if (focusedElement && focusedElement !== domAdapter.getActiveElement()) {
const isFocusOutsideWindow = getBoundingRect(focusedElement).bottom < 0;
if (!isFocusOutsideWindow) {
restoreFocus(focusedElement, selectionRange);
}
}
if (restoreAfterBestFitMode) {
restoreAfterBestFitMode();
}

isColumnWidthsCorrected = this._correctColumnWidths(resultWidths, visibleColumns);
const isColumnWidthsCorrected = this._correctColumnWidths(resultWidths, visibleColumns);

if (columnAutoWidth) {
normalizeWidthsByExpandColumns();
this._normalizeWidthsByExpandColumns(resultWidths, visibleColumns);
if (this._needStretch()) {
this._processStretch(resultWidths, visibleColumns);
}
Expand Down Expand Up @@ -478,6 +465,21 @@ export class ResizingController extends modules.ViewController {
return freeWidth / columnCountWithoutWidth;
}

private readonly _normalizeWidthsByExpandColumns = (resultWidths, visibleColumns): void => {
const expandColumnIndex = visibleColumns.findIndex((column) => column.type === 'groupExpand');
const expandColumnWidth = resultWidths[expandColumnIndex];

if (!isDefined(expandColumnWidth)) {
return;
}

each(visibleColumns, (index, column) => {
if (column.type === 'groupExpand') {
resultWidths[index] = expandColumnWidth;
}
});
};

/**
* @extended: adaptivity
*/
Expand All @@ -487,7 +489,6 @@ export class ResizingController extends modules.ViewController {
let hasPercentWidth = false;
let hasAutoWidth = false;
let isColumnWidthsCorrected = false;
const $element = that.component.$element();
const hasWidth = that._hasWidth;

for (i = 0; i < visibleColumns.length; i++) {
Expand Down Expand Up @@ -540,9 +541,7 @@ export class ResizingController extends modules.ViewController {
if (hasWidth === false && !hasPercentWidth) {
const borderWidth = gridCoreUtils.getComponentBorderWidth(this, $rowsViewElement);

that._maxWidth = totalWidth + scrollbarWidth + borderWidth;

$element.css('maxWidth', that._maxWidth);
that._maxWidth.set(totalWidth + scrollbarWidth + borderWidth);
}
}
}
Expand Down
Loading