diff --git a/packages/devextreme/js/__internal/grids/grid_core/m_utils.ts b/packages/devextreme/js/__internal/grids/grid_core/m_utils.ts
index 319552134421..b75a5e9e6318 100644
--- a/packages/devextreme/js/__internal/grids/grid_core/m_utils.ts
+++ b/packages/devextreme/js/__internal/grids/grid_core/m_utils.ts
@@ -23,6 +23,8 @@ import type { ColumnPoint } from '@ts/grids/grid_core/m_types';
import { isEqualSelectors, isSelectorEqualWithCallback } from './utils/index';
+const BASE_LOAD_PANEL_Z_INDEX = 1000;
+
const DATAGRID_SELECTION_DISABLED_CLASS = 'dx-selection-disabled';
const DATAGRID_GROUP_OPENED_CLASS = 'dx-datagrid-group-opened';
const DATAGRID_GROUP_CLOSED_CLASS = 'dx-datagrid-group-closed';
@@ -230,6 +232,7 @@ export default {
shading: false,
message: loadPanelOptions.text,
container: $container,
+ zIndex: BASE_LOAD_PANEL_Z_INDEX,
}, loadPanelOptions);
that._loadPanel = that._createComponent($('
').appendTo($container), LoadPanel, loadPanelOptions);
diff --git a/packages/devextreme/js/__internal/ui/overlay/m_overlay.ts b/packages/devextreme/js/__internal/ui/overlay/m_overlay.ts
index 20ccc22974ad..4d27789c984e 100644
--- a/packages/devextreme/js/__internal/ui/overlay/m_overlay.ts
+++ b/packages/devextreme/js/__internal/ui/overlay/m_overlay.ts
@@ -90,6 +90,8 @@ interface OverlayProperties extends Properties {
restorePosition?: boolean;
+ zIndex?: number;
+
_fixWrapperPosition?: boolean;
_skipContentPositioning?: boolean;
@@ -722,24 +724,42 @@ class Overlay<
this._toggleSubscriptions(visible);
}
+ _handleZIndexOptionChanged(): void {
+ const { zIndex } = this.option();
+
+ this._zIndex = zIndex ?? zIndexPool.create(this._zIndexInitValue());
+
+ this._updateZIndexStackPosition(this._isVisible());
+ }
+
_updateZIndexStackPosition(pushToStack: boolean): void {
const overlayStack = this._overlayStack();
// @ts-expect-error ts-error
const index = overlayStack.indexOf(this);
+ const isInStack = index !== -1;
+ const { zIndex } = this.option();
- if (pushToStack) {
- if (index === -1) {
- this._zIndex = zIndexPool.create(this._zIndexInitValue());
- // @ts-expect-error ts-error
- overlayStack.push(this);
+ if (!pushToStack) {
+ if (isInStack) {
+ overlayStack.splice(index, 1);
+ zIndexPool.remove(this._zIndex);
}
- this._$wrapper.css('zIndex', this._zIndex);
- this._$content.css('zIndex', this._zIndex);
- } else if (index !== -1) {
- overlayStack.splice(index, 1);
- zIndexPool.remove(this._zIndex);
+ return;
}
+
+ if (!isInStack) {
+ this._zIndex = zIndex ?? zIndexPool.create(this._zIndexInitValue());
+ // @ts-expect-error this and Overlay have no overlap
+ overlayStack.push(this);
+ }
+
+ this._updateZIndex();
+ }
+
+ _updateZIndex(): void {
+ this._$wrapper.css('zIndex', this._zIndex);
+ this._$content.css('zIndex', this._zIndex);
}
_toggleShading(visible?: boolean): void {
@@ -1319,6 +1339,9 @@ class Overlay<
this._initHideTopOverlayHandler(value);
this._toggleHideTopOverlayCallback(this.option('visible'));
break;
+ case 'zIndex':
+ this._handleZIndexOptionChanged();
+ break;
case 'hideOnParentScroll':
case '_hideOnParentScrollTarget': {
const { visible } = this.option();
diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataGrid.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataGrid.tests.js
index 91e9931ccd9d..f8c2ea15867e 100644
--- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataGrid.tests.js
+++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataGrid.tests.js
@@ -1275,6 +1275,21 @@ QUnit.module('Initialization', baseModuleConfig, () => {
// assert
assert.strictEqual(onContentReadySpy.callCount, 1, 'onContentReadySpy call count');
});
+
+ QUnit.test('Load panel has custom z-index (T1308742)', function(assert) {
+ const dataGrid = createDataGrid({
+ dataSource: {
+ load: function() {
+ return;
+ }
+ }
+ });
+
+ const loadPanel = dataGrid.getView('rowsView')._loadPanel;
+ const loadPanelZIndex = loadPanel._zIndex;
+
+ assert.strictEqual(loadPanelZIndex, 1000, 'load z-index is set to 1000 by default');
+ });
});
diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets/overlay.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets/overlay.tests.js
index 607f99620619..1c8404f8b9c4 100644
--- a/packages/devextreme/testing/tests/DevExpress.ui.widgets/overlay.tests.js
+++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets/overlay.tests.js
@@ -3108,6 +3108,50 @@ testModule('API', moduleConfig, () => {
assert.strictEqual(resizeStub.callCount, 1, '\'dxresize\' event handler was called');
resizeStub.restore();
});
+
+ test('Overlay uses custom zIndex on init if zIndex option is provided', function(assert) {
+ const overlay = $('#overlay').dxOverlay({
+ visible: true,
+ zIndex: 2000
+ }).dxOverlay('instance');
+
+ const contentZIndex = Number(getComputedStyle(overlay.$content()[0]).zIndex);
+
+ assert.strictEqual(contentZIndex, 2000, 'custom zIndex assigned');
+ });
+
+ test('Changing zIndex option replaces old pool zIndex with custom', function(assert) {
+ const overlay = $('#overlay').dxOverlay({
+ visible: true
+ }).dxOverlay('instance');
+
+ const initialZIndex = Number(getComputedStyle(overlay.$content()[0]).zIndex);
+
+ assert.strictEqual(initialZIndex, 1501, 'overlay has initial pool zIndex');
+
+ overlay.option('zIndex', 5000);
+
+ const finalZIndex = Number(getComputedStyle(overlay.$content()[0]).zIndex);
+
+ assert.strictEqual(finalZIndex, 5000, 'custom zIndex applied');
+ });
+
+ test('Changing zIndex option to undefined resets the default pool zIndex', function(assert) {
+ const overlay = $('#overlay').dxOverlay({
+ visible: true,
+ zIndex: 5000
+ }).dxOverlay('instance');
+
+ const initialZIndex = Number(getComputedStyle(overlay.$content()[0]).zIndex);
+
+ assert.strictEqual(initialZIndex, 5000, 'overlay has custom zIndex');
+
+ overlay.option('zIndex', undefined);
+
+ const finalZIndex = Number(getComputedStyle(overlay.$content()[0]).zIndex);
+
+ assert.strictEqual(finalZIndex, 1501, 'initial pool zIndex applied');
+ });
});