Skip to content
Merged
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
23 changes: 22 additions & 1 deletion packages/devextreme/js/__internal/ui/overlay/overlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ class Overlay<

const isTargetDocument = domUtils.contains(window.document, target);
const isAttachedTarget = $(window.document).is($target) || isTargetDocument;
const isInnerOverlay = $($target).closest(`.${INNER_OVERLAY_CLASS}`).length;
const isInnerOverlay = this._isTargetInLowerInnerOverlay($target);
const isTargetContent = this._$content?.is($target);
const content = this._$content?.get(0);
const isTargetInContent = content ? domUtils.contains(content, target) : false;
Expand Down Expand Up @@ -496,6 +496,27 @@ class Overlay<
this.hide();
}

_isTargetInLowerInnerOverlay($target: dxElementWrapper): boolean {
const $closestInnerOverlay = $target.closest(`.${INNER_OVERLAY_CLASS}`);

if (!$closestInnerOverlay.length) {
return false;
}

const overlayStack = this._overlayStack();
const innerOverlayElement = $closestInnerOverlay.get(0);
// @ts-expect-error this and Overlay have no overlap
const thisIndex = overlayStack.indexOf(this);

for (let i = 0; i < overlayStack.length; i += 1) {
if (overlayStack[i]._$content?.get(0) === innerOverlayElement) {
return thisIndex <= i;
}
}

return true;
}

_getAnonymousTemplateName(): string {
return ANONYMOUS_TEMPLATE_NAME;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2063,6 +2063,46 @@ testModule('hide on outside click', moduleConfig, () => {
assert.equal(overlay1.option('visible'), true, 'Bottom overlay should not get outside click when inner overlay clicked');
});

test('overlay opened above inner overlay should close on click inside inner overlay', function(assert) {
const overlay1 = $('#overlay').dxOverlay({
hideOnOutsideClick: true,
innerOverlay: true,
visible: true,
propagateOutsideClick: true
}).dxOverlay('instance');

const overlay2 = $('#overlay2').dxOverlay({
hideOnOutsideClick: true,
visible: true,
propagateOutsideClick: true
}).dxOverlay('instance');

$(overlay1.$content()).trigger('dxpointerdown');

assert.strictEqual(overlay2.option('visible'), false, 'Overlay opened above inner overlay should close');
assert.strictEqual(overlay1.option('visible'), true, 'Inner overlay itself should stay visible');
});

test('click inside inner overlay should not close overlays below it in stack', function(assert) {
const overlay1 = $('#overlay').dxOverlay({
hideOnOutsideClick: true,
visible: true,
propagateOutsideClick: true
}).dxOverlay('instance');

const overlay2 = $('#overlay2').dxOverlay({
hideOnOutsideClick: true,
innerOverlay: true,
visible: true,
propagateOutsideClick: true
}).dxOverlay('instance');

$(overlay2.$content()).trigger('dxpointerdown');

assert.strictEqual(overlay1.option('visible'), true, 'Overlay below inner overlay should not close');
assert.strictEqual(overlay2.option('visible'), true, 'Inner overlay should stay visible');
});

// T494814
test('overlay should not be hidden after click in detached element', function(assert) {
const overlay = $('#overlayWithAnonymousTmpl').dxOverlay({
Expand Down Expand Up @@ -4125,7 +4165,7 @@ testModule('renderGeometry', {
};
for(const optionName in newOptions) {
QUnit.testInActiveWindow(optionName, function(assert) {
// eslint-disable-next-line qunit/no-async-in-loops

const showingResizeHandled = assert.async();
setTimeout(() => {
this.overlayInstance.option(optionName, newOptions[optionName]);
Expand Down
Loading