diff --git a/e2e/testcafe-devextreme/tests/dataGrid/stickyColumns/etalons/datagrid_adaptive_item_focused.png b/e2e/testcafe-devextreme/tests/dataGrid/stickyColumns/etalons/datagrid_adaptive_item_focused.png new file mode 100644 index 000000000000..7de67607a309 Binary files /dev/null and b/e2e/testcafe-devextreme/tests/dataGrid/stickyColumns/etalons/datagrid_adaptive_item_focused.png differ diff --git a/e2e/testcafe-devextreme/tests/dataGrid/stickyColumns/etalons/datagrid_group_footer_row_focused.png b/e2e/testcafe-devextreme/tests/dataGrid/stickyColumns/etalons/datagrid_group_footer_row_focused.png new file mode 100644 index 000000000000..40f1200ac037 Binary files /dev/null and b/e2e/testcafe-devextreme/tests/dataGrid/stickyColumns/etalons/datagrid_group_footer_row_focused.png differ diff --git a/e2e/testcafe-devextreme/tests/dataGrid/stickyColumns/etalons/datagrid_group_row_focused.png b/e2e/testcafe-devextreme/tests/dataGrid/stickyColumns/etalons/datagrid_group_row_focused.png new file mode 100644 index 000000000000..be9187d660a7 Binary files /dev/null and b/e2e/testcafe-devextreme/tests/dataGrid/stickyColumns/etalons/datagrid_group_row_focused.png differ diff --git a/e2e/testcafe-devextreme/tests/dataGrid/stickyColumns/focusOverlay.ts b/e2e/testcafe-devextreme/tests/dataGrid/stickyColumns/focusOverlay.ts new file mode 100644 index 000000000000..a23da83399ea --- /dev/null +++ b/e2e/testcafe-devextreme/tests/dataGrid/stickyColumns/focusOverlay.ts @@ -0,0 +1,120 @@ +import { createScreenshotsComparer } from 'devextreme-screenshot-comparer'; +import DataGrid from 'devextreme-testcafe-models/dataGrid'; +import { createWidget } from '../../../helpers/createWidget'; +import url from '../../../helpers/getPageUrl'; +import { getData } from '../helpers/generateDataSourceData'; + +const DATA_GRID_SELECTOR = '#container'; + +fixture.disablePageReloads`FixedColumns - Focus Overlay` + .page(url(__dirname, '../../container.html')); + +test('Focus overlay should be displayed correctly if sticky columns are turned on', async (t) => { + const { takeScreenshot, compareResults } = createScreenshotsComparer(t); + + const dataGrid = new DataGrid(DATA_GRID_SELECTOR); + + await t.expect(dataGrid.isReady()).ok(); + + await t + .click(dataGrid.getGroupRow(0).element) + .pressKey('tab'); + + await takeScreenshot('datagrid_group_row_focused.png', dataGrid.element); + + await t + .click(dataGrid.getDataRow(2).getCommandCell(40).getAdaptiveButton()) + .pressKey('tab'); + + await takeScreenshot('datagrid_adaptive_item_focused.png', dataGrid.element); + + await t + .click(dataGrid.getGroupFooterRow().nth(0)) + .pressKey('tab'); + + await takeScreenshot('datagrid_group_footer_row_focused.png', dataGrid.element); + + await t + .expect(compareResults.isValid()) + .ok(compareResults.errorMessages()); +}).before(async () => createWidget('dxDataGrid', { + dataSource: getData(20, 40), + columnFixing: { + enabled: true, + }, + groupPanel: { + visible: true, + }, + width: 800, + showColumnHeaders: true, + columnAutoWidth: true, + allowColumnReordering: true, + allowColumnResizing: true, + summary: { + totalItems: [{ + column: 'field_1', + summaryType: 'count', + }, { + column: 'field_6', + summaryType: 'count', + }], + groupItems: [{ + column: 'field_0', + summaryType: 'count', + showInGroupFooter: false, + alignByColumn: true, + }, + { + column: 'field_11', + summaryType: 'count', + showInGroupFooter: false, + alignByColumn: true, + }, { + column: 'field_6', + summaryType: 'count', + showInGroupFooter: true, + }], + }, + customizeColumns(columns) { + columns[5].fixed = true; + columns[6].fixed = true; + + columns[11].fixed = true; + columns[11].fixedPosition = 'right'; + columns[12].fixed = true; + columns[12].fixedPosition = 'right'; + + columns.splice(15, 5, { + caption: 'Band column 1', + columns: [{ + caption: 'Nested column 1', + columns: ['field_15', 'field_16'], + }, + 'field_17', + { + caption: 'Nested column 2', + columns: ['field_18', 'field_19'], + }], + }); + + columns.splice(25, 4, { + caption: 'Band column 2', + columns: [ + 'field_29', + { + caption: 'Nested column 3', + columns: ['field_30', 'field_31'], + }, + 'field_32', + ], + }); + + columns[0].hidingPriority = 0; + columns[columns.length - 1].hidingPriority = 1; + columns[columns.length - 2].hidingPriority = 2; + columns[columns.length - 3].hidingPriority = 3; + + columns[1].groupIndex = 0; + columns[2].groupIndex = 1; + }, +})); diff --git a/packages/devextreme-scss/scss/widgets/base/_gridBase.scss b/packages/devextreme-scss/scss/widgets/base/_gridBase.scss index 7da8534f8dd8..487bc7badfff 100644 --- a/packages/devextreme-scss/scss/widgets/base/_gridBase.scss +++ b/packages/devextreme-scss/scss/widgets/base/_gridBase.scss @@ -1080,7 +1080,7 @@ border-collapse: separate; } - .dx-focused-fixed-cell { + .dx-focused-fixed-element { z-index: 3; } diff --git a/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/const.ts b/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/const.ts index 168f941d76c7..aa70eac76c9b 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/const.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/const.ts @@ -19,6 +19,7 @@ export const EDITOR_CELL_CLASS = 'dx-editor-cell'; export const DROPDOWN_EDITOR_OVERLAY_CLASS = 'dx-dropdowneditor-overlay'; export const COMMAND_EXPAND_CLASS = 'dx-command-expand'; export const ADAPTIVE_COLUMN_NAME_CLASS = 'dx-command-adaptive'; +export const ADAPTIVE_ITEM_TEXT_CLASS = 'dx-adaptive-item-text'; export const COMMAND_SELECT_CLASS = 'dx-command-select'; export const COMMAND_EDIT_CLASS = 'dx-command-edit'; export const COMMAND_CELL_SELECTOR = '[class^=dx-command]'; diff --git a/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation_utils.ts b/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation_utils.ts index 2080a90b9c43..e2136f1fff4e 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation_utils.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation_utils.ts @@ -3,6 +3,7 @@ import { isDefined } from '@js/core/utils/type'; import { EDITOR_CELL_CLASS } from '../editing/const'; import { + ADAPTIVE_ITEM_TEXT_CLASS, COMMAND_SELECT_CLASS, DATA_ROW_CLASS, EDIT_FORM_CLASS, FREESPACE_ROW_CLASS, GROUP_ROW_CLASS, HEADER_ROW_CLASS, MASTER_DETAIL_ROW_CLASS, VIRTUAL_ROW_CLASS, } from './const'; @@ -19,6 +20,10 @@ export function isGroupFooterRow($row) { export function isDetailRow($row) { return $row && $row.hasClass(MASTER_DETAIL_ROW_CLASS); } +export function isAdaptiveItem($element) { + return $element && $element.hasClass(ADAPTIVE_ITEM_TEXT_CLASS); +} + export function isEditForm($row) { return $row && $row.hasClass(MASTER_DETAIL_ROW_CLASS) && $row.hasClass(EDIT_FORM_CLASS); } diff --git a/packages/devextreme/js/__internal/grids/grid_core/sticky_columns/const.ts b/packages/devextreme/js/__internal/grids/grid_core/sticky_columns/const.ts index 4fd240f7aebd..a983617b08b6 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/sticky_columns/const.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/sticky_columns/const.ts @@ -16,7 +16,7 @@ export const CLASSES = { firstHeader: 'first-header', columnNoBorder: 'column-no-border', groupRowContainer: 'group-row-container', - focusedFixedCell: 'dx-focused-fixed-cell', + focusedFixedElement: 'dx-focused-fixed-element', focused: 'dx-focused', hidden: 'dx-hidden', }; diff --git a/packages/devextreme/js/__internal/grids/grid_core/sticky_columns/m_sticky_columns.ts b/packages/devextreme/js/__internal/grids/grid_core/sticky_columns/m_sticky_columns.ts index ec714a4de045..f9893d67b8ba 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/sticky_columns/m_sticky_columns.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/sticky_columns/m_sticky_columns.ts @@ -13,6 +13,11 @@ import type { ColumnsResizerViewController, DraggingHeaderViewController, } from '../columns_resizing_reordering/m_columns_resizing_reordering'; +import { + isAdaptiveItem, + isGroupFooterRow, + isGroupRow as isGroupRowElement, +} from '../keyboard_navigation/m_keyboard_navigation_utils'; import type { ModuleType } from '../m_types'; import gridCoreUtils from '../m_utils'; import { CLASSES as MASTER_DETAIL_CLASSES } from '../master_detail/const'; @@ -768,8 +773,14 @@ const editorFactory = (Base: ModuleType) => class EditorFactorySt if (!isHideBorder) { const isFixedCell = GridCoreStickyColumnsDom .isFixedCell($element, this.addWidgetPrefix.bind(this)); + this._$focusOverlay.toggleClass(CLASSES.focusedFixedElement, isFixedCell); + const isGroupElement = isGroupRowElement($element); + const isGroupFooterRowElement = isGroupFooterRow($element); + const isAdaptiveElement = isAdaptiveItem($element); - this._$focusOverlay.toggleClass(CLASSES.focusedFixedCell, isFixedCell); + if (isFixedCell || isGroupElement || isGroupFooterRowElement || isAdaptiveElement) { + this._$focusOverlay.toggleClass(CLASSES.focusedFixedElement, true); + } } super.updateFocusOverlay($element, isHideBorder);