diff --git a/src/elements/autocomplete/autocomplete-base-element.ts b/src/elements/autocomplete/autocomplete-base-element.ts
index 07f456bb37..5b4a685f52 100644
--- a/src/elements/autocomplete/autocomplete-base-element.ts
+++ b/src/elements/autocomplete/autocomplete-base-element.ts
@@ -357,6 +357,7 @@ export abstract class SbbAutocompleteBaseElement extends SbbNegativeMixin(
document.addEventListener('scroll', () => this._setOverlayPosition(), {
passive: true,
signal: this._openPanelEventsController.signal,
+ capture: true,
});
window.addEventListener('resize', () => this._setOverlayPosition(), {
passive: true,
diff --git a/src/elements/autocomplete/autocomplete.visual.spec.ts b/src/elements/autocomplete/autocomplete.visual.spec.ts
index 6929965949..df4d5c2746 100644
--- a/src/elements/autocomplete/autocomplete.visual.spec.ts
+++ b/src/elements/autocomplete/autocomplete.visual.spec.ts
@@ -1,3 +1,4 @@
+import { aTimeout } from '@open-wc/testing';
import { sendKeys } from '@web/test-runner-commands';
import { html, nothing, type TemplateResult } from 'lit';
import { styleMap } from 'lit/directives/style-map.js';
@@ -289,5 +290,44 @@ describe('sbb-autocomplete', () => {
});
});
}
+
+ it(
+ `with scroll context`,
+ visualDiffDefault.with(async (setup) => {
+ await setup.withFixture(html`
+
+
forwardEventToHost(e, document)}>
`;
diff --git a/src/elements/dialog/dialog/dialog.stories.ts b/src/elements/dialog/dialog/dialog.stories.ts
index 4c265ebe58..969fd5531e 100644
--- a/src/elements/dialog/dialog/dialog.stories.ts
+++ b/src/elements/dialog/dialog/dialog.stories.ts
@@ -17,6 +17,8 @@ import readme from './readme.md?raw';
import '../../button.js';
import '../../link.js';
import '../../form-field.js';
+import '../../select.js';
+import '../../option.js';
import '../../image.js';
import '../../popover.js';
import '../dialog-content.js';
@@ -225,6 +227,30 @@ const DefaultTemplate = ({
Dialog content
+
+
+ Option 1
+
+ Option 2
+
+ Option 3
+
+ Option 4
+
+ Option 5
+
+
+
Content
+
Content
+
Content
+
Content
+
Content
+
Content
+
Content
+
Content
+
Content
+
Content
+
Content
Some content.
diff --git a/src/elements/dialog/dialog/dialog.ts b/src/elements/dialog/dialog/dialog.ts
index a84dd0a41e..ed36e9a3bb 100644
--- a/src/elements/dialog/dialog/dialog.ts
+++ b/src/elements/dialog/dialog/dialog.ts
@@ -120,7 +120,6 @@ class SbbDialogElement extends SbbOverlayBaseElement {
private _handleOpening(): void {
this.state = 'opened';
- this.didOpen.emit();
this.inertController.activate();
this.attachOpenOverlayEvents();
this.setOverlayFocus();
@@ -131,6 +130,7 @@ class SbbDialogElement extends SbbOverlayBaseElement {
),
);
this.focusHandler.trap(this);
+ this.didOpen.emit();
}
public override connectedCallback(): void {
diff --git a/src/elements/dialog/dialog/dialog.visual.spec.ts b/src/elements/dialog/dialog/dialog.visual.spec.ts
index 1128c2bbf1..1fb8790f2e 100644
--- a/src/elements/dialog/dialog/dialog.visual.spec.ts
+++ b/src/elements/dialog/dialog/dialog.visual.spec.ts
@@ -1,3 +1,4 @@
+import { aTimeout } from '@open-wc/testing';
import { html, nothing, type TemplateResult } from 'lit';
import { describeViewports, visualDiffDefault } from '../../core/testing/private.js';
@@ -6,9 +7,12 @@ import './dialog.js';
import '../dialog-actions.js';
import '../dialog-content.js';
import '../dialog-title.js';
-import '../../link/block-link.js';
import '../../button/button.js';
import '../../button/secondary-button.js';
+import '../../form-field.js';
+import '../../link/block-link.js';
+import '../../option.js';
+import '../../select.js';
describe(`sbb-dialog`, () => {
const negativeCases = [false, true];
@@ -112,5 +116,53 @@ describe(`sbb-dialog`, () => {
setup.withPostSetupAction(() => dialog.open());
}),
);
+
+ it(
+ `with scrolled select`,
+ visualDiffDefault.with(async (setup) => {
+ await setup.withFixture(html`
+
+ ${dialogTitle()}
+
+ Content
+ Content
+ Content
+
+
+ Option 1
+ Option 2
+
+
+ Content
+ Content
+ Content
+ Content
+ Content
+
+ ${dialogFooter()}
+
+ `);
+ const dialog = setup.snapshotElement.querySelector('sbb-dialog')!;
+ const select = setup.snapshotElement.querySelector('sbb-select')!;
+ const scrollContext = setup.snapshotElement
+ .querySelector('sbb-dialog-content')!
+ .shadowRoot!.querySelector
('.sbb-dialog-content')!;
+
+ setup.withSnapshotElement(dialog);
+
+ setup.withPostSetupAction(async () => {
+ dialog.open();
+
+ // We need to wait until the dialog is completely settled.
+ await aTimeout(40);
+
+ select.click();
+ scrollContext.scrollTo(0, 100);
+
+ // We need to ensure content resizing kicked in
+ await aTimeout(0);
+ });
+ }),
+ );
});
});
diff --git a/src/elements/menu/menu/menu.spec.ts b/src/elements/menu/menu/menu.spec.ts
index bb40ed12a7..e314fefc99 100644
--- a/src/elements/menu/menu/menu.spec.ts
+++ b/src/elements/menu/menu/menu.spec.ts
@@ -52,11 +52,9 @@ describe(`sbb-menu`, () => {
await willOpenEventSpy.calledOnce();
expect(willOpenEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
await didOpenEventSpy.calledOnce();
expect(didOpenEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
expect(element).to.have.attribute('data-state', 'opened');
});
@@ -71,12 +69,9 @@ describe(`sbb-menu`, () => {
await willOpenEventSpy.calledOnce();
expect(willOpenEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
await didOpenEventSpy.calledOnce();
expect(didOpenEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
-
expect(element).to.have.attribute('data-state', 'opened');
await sendKeys({ press: tabKey });
@@ -87,11 +82,9 @@ describe(`sbb-menu`, () => {
await willCloseEventSpy.calledOnce();
expect(willCloseEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
await didCloseEventSpy.calledOnce();
expect(didCloseEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
expect(element).to.have.attribute('data-state', 'closed');
});
@@ -108,11 +101,9 @@ describe(`sbb-menu`, () => {
await willOpenEventSpy.calledOnce();
expect(willOpenEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
await didOpenEventSpy.calledOnce();
expect(didOpenEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
expect(element).to.have.attribute('data-state', 'opened');
expect(menuAction).not.to.be.null;
@@ -122,11 +113,8 @@ describe(`sbb-menu`, () => {
await willCloseEventSpy.calledOnce();
expect(willCloseEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
await didCloseEventSpy.calledOnce();
expect(didCloseEventSpy.count).to.be.equal(1);
-
- await waitForLitRender(element);
expect(element).to.have.attribute('data-state', 'closed');
});
@@ -142,11 +130,9 @@ describe(`sbb-menu`, () => {
await willOpenEventSpy.calledOnce();
expect(willOpenEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
await didOpenEventSpy.calledOnce();
expect(didOpenEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
expect(element).to.have.attribute('data-state', 'opened');
expect(menuLink).not.to.be.null;
@@ -156,11 +142,9 @@ describe(`sbb-menu`, () => {
await willCloseEventSpy.calledOnce();
expect(willCloseEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
await didCloseEventSpy.calledOnce();
expect(didCloseEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
expect(element).to.have.attribute('data-state', 'closed');
});
@@ -201,11 +185,9 @@ describe(`sbb-menu`, () => {
await willOpenEventSpy.calledOnce();
expect(willOpenEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
await didOpenEventSpy.calledOnce();
expect(didOpenEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
expect(element).to.have.attribute('data-state', 'opened');
@@ -236,11 +218,9 @@ describe(`sbb-menu`, () => {
await willOpenEventSpy.calledOnce();
expect(willOpenEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
await didOpenEventSpy.calledOnce();
expect(didOpenEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
expect(element).to.have.attribute('data-state', 'opened');
@@ -262,15 +242,11 @@ describe(`sbb-menu`, () => {
await willOpenEventSpy.calledOnce();
expect(willOpenEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
await didOpenEventSpy.calledOnce();
expect(didOpenEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
-
expect(element).to.have.attribute('data-state', 'opened');
- await waitForLitRender(element);
expect(document.activeElement!.id).to.be.equal('menu-link');
});
@@ -292,14 +268,14 @@ describe(`sbb-menu`, () => {
const willCloseEventSpy = new EventSpy(SbbMenuElement.events.willClose, element);
element.open();
- await didOpenEventSpy.calledOnce();
await waitForLitRender(element);
+ await didOpenEventSpy.calledOnce();
element.addEventListener(SbbMenuElement.events.willClose, (ev) => ev.preventDefault());
element.close();
- await willCloseEventSpy.calledOnce();
await waitForLitRender(element);
+ await willCloseEventSpy.calledOnce();
expect(element).to.have.attribute('data-state', 'opened');
});
diff --git a/src/elements/menu/menu/menu.ts b/src/elements/menu/menu/menu.ts
index 724ac8e640..1dc49ec0b8 100644
--- a/src/elements/menu/menu/menu.ts
+++ b/src/elements/menu/menu/menu.ts
@@ -168,11 +168,11 @@ class SbbMenuElement extends SbbNamedSlotListMixin<
private _handleOpening(): void {
this.state = 'opened';
- this.didOpen.emit();
this._inertController.activate();
this._setMenuFocus();
this._focusHandler.trap(this);
this._attachWindowEvents();
+ this.didOpen.emit();
}
private _handleClosing(): void {
@@ -319,6 +319,7 @@ class SbbMenuElement extends SbbNamedSlotListMixin<
document.addEventListener('scroll', () => this._setMenuPosition(), {
passive: true,
signal: this._windowEventsController.signal,
+ capture: true,
});
window.addEventListener('resize', () => this._setMenuPosition(), {
passive: true,
diff --git a/src/elements/menu/menu/menu.visual.spec.ts b/src/elements/menu/menu/menu.visual.spec.ts
index f28f2b271b..fa9325ae53 100644
--- a/src/elements/menu/menu/menu.visual.spec.ts
+++ b/src/elements/menu/menu/menu.visual.spec.ts
@@ -1,3 +1,4 @@
+import { aTimeout } from '@open-wc/testing';
import { html } from 'lit';
import { repeat } from 'lit/directives/repeat.js';
import { styleMap } from 'lit/directives/style-map.js';
@@ -106,4 +107,43 @@ describe(`sbb-menu`, () => {
}),
);
});
+
+ describeViewports({ viewports: ['medium'], viewportHeight: 400 }, () => {
+ it(
+ `with scroll context`,
+ visualDiffDefault.with(async (setup) => {
+ await setup.withFixture(html`
+
+
Content
+
Content
+
Content
+
+
+ Element 1
+ Element 2
+ Element 3
+
+
Content
+
Content
+
Content
+
Content
+
Content
+
Content
+
+ `);
+ const scrollContext = setup.snapshotElement.querySelector('div')!;
+ const menu = setup.snapshotElement.querySelector('sbb-menu')!;
+
+ setup.withSnapshotElement(scrollContext);
+
+ setup.withPostSetupAction(async () => {
+ menu.open();
+ scrollContext.scrollTo(0, 100);
+
+ // We need to ensure content resizing kicked in
+ await aTimeout(40);
+ });
+ }),
+ );
+ });
});
diff --git a/src/elements/navigation/navigation/navigation.spec.ts b/src/elements/navigation/navigation/navigation.spec.ts
index b624c52bb3..8813ddd289 100644
--- a/src/elements/navigation/navigation/navigation.spec.ts
+++ b/src/elements/navigation/navigation/navigation.spec.ts
@@ -89,12 +89,7 @@ describe(`sbb-navigation`, () => {
await didOpenEventSpy.calledOnce();
expect(didOpenEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
-
expect(element).to.have.attribute('data-state', 'opened');
-
- await waitForLitRender(element);
-
expect(action2).to.have.attribute('data-action-active');
expect(action3).to.have.attribute('data-action-active');
expect(element.shadowRoot?.activeElement?.id).to.be.equal('sbb-navigation-close-button');
@@ -135,12 +130,7 @@ describe(`sbb-navigation`, () => {
await didOpenEventSpy.calledOnce();
expect(didOpenEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
-
expect(element).to.have.attribute('data-state', 'opened');
-
- await waitForLitRender(element);
-
expect(actionActive).to.have.attribute('data-action-active');
expect(sectionActionActive).to.have.attribute('data-action-active');
expect(activeSection).to.have.attribute('data-state', 'opened');
@@ -177,12 +167,7 @@ describe(`sbb-navigation`, () => {
await didOpenEventSpy.calledOnce();
expect(didOpenEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
-
expect(element).to.have.attribute('data-state', 'opened');
-
- await waitForLitRender(element);
-
expect(action2).to.have.attribute('data-action-active');
expect(action3).to.have.attribute('data-action-active');
@@ -202,8 +187,6 @@ describe(`sbb-navigation`, () => {
await didCloseEventSpy.calledOnce();
expect(didCloseEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
-
expect(element).to.have.attribute('data-state', 'closed');
element.open();
@@ -211,12 +194,7 @@ describe(`sbb-navigation`, () => {
await didOpenEventSpy.calledTimes(2);
expect(didOpenEventSpy.count).to.be.equal(2);
- await waitForLitRender(element);
-
expect(element).to.have.attribute('data-state', 'opened');
-
- await waitForLitRender(element);
-
expect(action1).not.to.have.attribute('data-action-active');
expect(action4).not.to.have.attribute('data-action-active');
});
@@ -230,8 +208,6 @@ describe(`sbb-navigation`, () => {
await didOpenEventSpy.calledOnce();
expect(didOpenEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
-
expect(element).to.have.attribute('data-state', 'opened');
element.close();
@@ -239,8 +215,6 @@ describe(`sbb-navigation`, () => {
await didCloseEventSpy.calledOnce();
expect(didCloseEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
-
expect(element).to.have.attribute('data-state', 'closed');
});
@@ -255,8 +229,6 @@ describe(`sbb-navigation`, () => {
await didOpenEventSpy.calledOnce();
expect(didOpenEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
-
expect(element).to.have.attribute('data-state', 'opened');
closeButton.click();
@@ -264,8 +236,6 @@ describe(`sbb-navigation`, () => {
await didCloseEventSpy.calledOnce();
expect(didCloseEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
-
expect(element).to.have.attribute('data-state', 'closed');
});
@@ -290,8 +260,6 @@ describe(`sbb-navigation`, () => {
await didCloseEventSpy.calledOnce();
expect(didCloseEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
-
expect(element).to.have.attribute('data-state', 'closed');
});
@@ -324,8 +292,6 @@ describe(`sbb-navigation`, () => {
await didCloseEventSpy.calledOnce();
expect(didCloseEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
-
expect(element).to.have.attribute('data-state', 'closed');
expect(section).to.have.attribute('data-state', 'closed');
});
@@ -341,8 +307,6 @@ describe(`sbb-navigation`, () => {
await didOpenEventSpy.calledOnce();
expect(didOpenEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
-
expect(element).to.have.attribute('data-state', 'opened');
element.close();
@@ -350,8 +314,6 @@ describe(`sbb-navigation`, () => {
await didCloseEventSpy.calledOnce();
expect(didCloseEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
-
expect(element).to.have.attribute('data-state', 'closed');
});
@@ -367,8 +329,6 @@ describe(`sbb-navigation`, () => {
await didOpenEventSpy.calledOnce();
expect(didOpenEventSpy.count).to.be.equal(1);
- await waitForLitRender(element);
-
expect(element).to.have.attribute('data-state', 'opened');
expect(section).to.have.attribute('data-state', 'closed');
diff --git a/src/elements/navigation/navigation/navigation.ts b/src/elements/navigation/navigation/navigation.ts
index 4c273f2002..182e0c60bc 100644
--- a/src/elements/navigation/navigation/navigation.ts
+++ b/src/elements/navigation/navigation/navigation.ts
@@ -206,13 +206,13 @@ class SbbNavigationElement extends SbbUpdateSchedulerMixin(SbbOpenCloseBaseEleme
private _handleOpening(): void {
this.state = 'opened';
- this.didOpen.emit();
this._navigationResizeObserver.observe(this);
this._inertController.activate();
this._focusHandler.trap(this, { filter: this._trapFocusFilter });
this._attachWindowEvents();
this._setNavigationFocus();
this.completeUpdate();
+ this.didOpen.emit();
}
// Removes trigger click listener on trigger change.
diff --git a/src/elements/notification/notification.ts b/src/elements/notification/notification.ts
index 90f2ca6a73..b474c9a4ac 100644
--- a/src/elements/notification/notification.ts
+++ b/src/elements/notification/notification.ts
@@ -219,8 +219,8 @@ class SbbNotificationElement extends LitElement {
private _handleOpening(): void {
this._state = 'opened';
- this._didOpen.emit();
this._notificationResizeObserver.observe(this._notificationElement);
+ this._didOpen.emit();
}
private _handleClosing(): void {
diff --git a/src/elements/overlay/overlay.spec.ts b/src/elements/overlay/overlay.spec.ts
index bf5f6b56f1..252e9e39e0 100644
--- a/src/elements/overlay/overlay.spec.ts
+++ b/src/elements/overlay/overlay.spec.ts
@@ -20,12 +20,9 @@ async function openOverlay(element: SbbOverlayElement): Promise {
await willOpen.calledOnce();
expect(willOpen.count).to.be.equal(1);
- await waitForLitRender(element);
await didOpen.calledOnce();
expect(didOpen.count).to.be.equal(1);
- await waitForLitRender(element);
-
expect(element).to.have.attribute('data-state', 'opened');
}
@@ -61,8 +58,6 @@ describe('sbb-overlay', () => {
await willOpen.calledOnce();
expect(willOpen.count).to.be.equal(1);
- await waitForLitRender(element);
-
expect(didOpen.count).to.be.equal(0);
expect(element).to.have.attribute('data-state', 'closed');
});
@@ -80,12 +75,9 @@ describe('sbb-overlay', () => {
await willClose.calledOnce();
expect(willClose.count).to.be.equal(1);
- await waitForLitRender(element);
await didClose.calledOnce();
expect(didClose.count).to.be.equal(1);
- await waitForLitRender(element);
-
expect(element).to.have.attribute('data-state', 'closed');
expect(ariaLiveRef.textContent).to.be.equal('');
});
@@ -101,8 +93,6 @@ describe('sbb-overlay', () => {
await didClose.calledOnce();
expect(didClose.count).to.be.equal(1);
- await waitForLitRender(element);
-
expect(element).to.have.attribute('data-state', 'closed');
});
@@ -119,8 +109,6 @@ describe('sbb-overlay', () => {
await willClose.calledOnce();
expect(willClose.count).to.be.equal(1);
- await waitForLitRender(element);
-
expect(didClose.count).to.be.equal(0);
expect(element).to.have.attribute('data-state', 'opened');
});
@@ -137,11 +125,9 @@ describe('sbb-overlay', () => {
await willClose.calledOnce();
expect(willClose.count).to.be.equal(1);
- await waitForLitRender(element);
await didClose.calledOnce();
expect(didClose.count).to.be.equal(1);
- await waitForLitRender(element);
expect(element).to.have.attribute('data-state', 'closed');
});
@@ -186,11 +172,9 @@ describe('sbb-overlay', () => {
await willClose.calledOnce();
expect(willClose.count).to.be.equal(1);
- await waitForLitRender(element);
await didClose.calledOnce();
expect(didClose.count).to.be.equal(1);
- await waitForLitRender(element);
expect(element).to.have.attribute('data-state', 'closed');
});
@@ -220,11 +204,9 @@ describe('sbb-overlay', () => {
await willOpen.calledTimes(2);
expect(willOpen.count).to.be.equal(2);
- await waitForLitRender(element);
await didOpen.calledTimes(2);
expect(didOpen.count).to.be.equal(2);
- await waitForLitRender(element);
expect(stackedOverlay).to.have.attribute('data-state', 'opened');
@@ -236,11 +218,9 @@ describe('sbb-overlay', () => {
await willClose.calledOnce();
expect(willClose.count).to.be.equal(1);
- await waitForLitRender(element);
await didClose.calledOnce();
expect(didClose.count).to.be.equal(1);
- await waitForLitRender(element);
expect(stackedOverlay).to.have.attribute('data-state', 'closed');
expect(element).to.have.attribute('data-state', 'opened');
@@ -253,11 +233,9 @@ describe('sbb-overlay', () => {
await willClose.calledTimes(2);
expect(willClose.count).to.be.equal(2);
- await waitForLitRender(element);
await didClose.calledTimes(2);
expect(didClose.count).to.be.equal(2);
- await waitForLitRender(element);
expect(stackedOverlay).to.have.attribute('data-state', 'closed');
expect(element).to.have.attribute('data-state', 'closed');
diff --git a/src/elements/overlay/overlay.ts b/src/elements/overlay/overlay.ts
index 5d729b79a8..307dac8f1f 100644
--- a/src/elements/overlay/overlay.ts
+++ b/src/elements/overlay/overlay.ts
@@ -6,7 +6,7 @@ import { html, unsafeStatic } from 'lit/static-html.js';
import { getFirstFocusableElement, setModalityOnNextFocus } from '../core/a11y.js';
import { forceType } from '../core/decorators.js';
import { isZeroAnimationDuration } from '../core/dom.js';
-import { EventEmitter } from '../core/eventing.js';
+import { EventEmitter, forwardEventToHost } from '../core/eventing.js';
import { i18nCloseDialog, i18nGoBack } from '../core/i18n.js';
import { overlayRefs, SbbOverlayBaseElement } from './overlay-base-element.js';
@@ -111,13 +111,13 @@ class SbbOverlayElement extends SbbOverlayBaseElement {
private _handleOpening(): void {
this.state = 'opened';
- this.didOpen.emit();
this.inertController.activate();
this.attachOpenOverlayEvents();
this.setOverlayFocus();
// Use timeout to read label after focused element
setTimeout(() => this.setAriaLiveRefContent(this.accessibilityLabel));
this.focusHandler.trap(this);
+ this.didOpen.emit();
}
protected override handleClosing(): void {
@@ -201,7 +201,10 @@ class SbbOverlayElement extends SbbOverlayBaseElement {
-
+
forwardEventToHost(e, document)}
+ >
{
const defaultArgs = {
expanded: false,
@@ -82,4 +87,52 @@ describe(`sbb-overlay`, () => {
);
}
});
+
+ describeViewports({ viewports: ['zero'], viewportHeight: 400 }, () => {
+ it(
+ `with scrolled autocomplete`,
+ visualDiffDefault.with(async (setup) => {
+ await setup.withFixture(html`
+
+ Content
+ Content
+ Content
+ Content
+
+
+
+ Option 1
+ Option 2
+
+
+ Content
+ Content
+ Content
+ Content
+ Content
+ Content
+
+ `);
+ const overlay = setup.snapshotElement.querySelector('sbb-overlay')!;
+ const input = setup.snapshotElement.querySelector('input')!;
+ const scrollContext =
+ overlay.shadowRoot!.querySelector('.sbb-overlay__content')!;
+
+ setup.withSnapshotElement(overlay);
+
+ setup.withPostSetupAction(async () => {
+ overlay.open();
+
+ // We need to wait until the dialog is completely settled.
+ await aTimeout(40);
+
+ input.focus();
+ scrollContext.scrollTo(0, 100);
+
+ // We need to ensure content resizing kicked in
+ await aTimeout(0);
+ });
+ }),
+ );
+ });
});
diff --git a/src/elements/popover/popover/popover.ts b/src/elements/popover/popover/popover.ts
index b468b3c3e4..b07e9786a2 100644
--- a/src/elements/popover/popover/popover.ts
+++ b/src/elements/popover/popover/popover.ts
@@ -192,13 +192,13 @@ class SbbPopoverElement extends SbbHydrationMixin(SbbOpenCloseBaseElement) {
private _handleOpening(): void {
this.state = 'opened';
- this.didOpen.emit();
this.inert = false;
this._attachWindowEvents();
this._setPopoverFocus();
this._focusHandler.trap(this, {
postFilter: (el) => el !== this._overlay,
});
+ this.didOpen.emit();
}
// Closes the popover on "Esc" key pressed and traps focus within the popover.
@@ -317,6 +317,7 @@ class SbbPopoverElement extends SbbHydrationMixin(SbbOpenCloseBaseElement) {
document.addEventListener('scroll', () => this._setPopoverPosition(), {
passive: true,
signal: this._openStateController.signal,
+ capture: true,
});
window.addEventListener('resize', () => this._setPopoverPosition(), {
passive: true,
diff --git a/src/elements/select/select.ts b/src/elements/select/select.ts
index df39866159..fc620cbc5c 100644
--- a/src/elements/select/select.ts
+++ b/src/elements/select/select.ts
@@ -577,6 +577,7 @@ class SbbSelectElement extends SbbUpdateSchedulerMixin(
document.addEventListener('scroll', () => this._setOverlayPosition(), {
passive: true,
signal: this._openPanelEventsController.signal,
+ capture: true,
});
window.addEventListener('resize', () => this._setOverlayPosition(), {
passive: true,
diff --git a/src/elements/select/select.visual.spec.ts b/src/elements/select/select.visual.spec.ts
index 14a16aa6e4..ee64df3f9d 100644
--- a/src/elements/select/select.visual.spec.ts
+++ b/src/elements/select/select.visual.spec.ts
@@ -1,3 +1,4 @@
+import { aTimeout } from '@open-wc/testing';
import { html, nothing, type TemplateResult } from 'lit';
import { describeViewports, visualDiffDefault, visualDiffFocus } from '../core/testing/private.js';
@@ -114,6 +115,44 @@ describe('sbb-select', () => {
);
}
}
+
+ it(
+ `with scroll context`,
+ visualDiffDefault.with(async (setup) => {
+ await setup.withFixture(html`
+
+
Content
+
Content
+
Content
+
+
+ Option 1
+ Option 2
+ Option 3
+
+
+
Content
+
Content
+
Content
+
Content
+
Content
+
Content
+
+ `);
+ const scrollContext = setup.snapshotElement.querySelector('div')!;
+ const select = setup.snapshotElement.querySelector('sbb-select')!;
+
+ setup.withSnapshotElement(scrollContext);
+
+ setup.withPostSetupAction(async () => {
+ select.open();
+ scrollContext.scrollTo(0, 100);
+
+ // We need to ensure content resizing kicked in
+ await aTimeout(40);
+ });
+ }),
+ );
});
describeViewports({ viewports: ['zero', 'medium'] }, () => {