diff --git a/packages/cookie-banner/src/themed-banner/styles.ts b/packages/cookie-banner/src/themed-banner/styles.ts index a1ff907a8..7584fb4dc 100644 --- a/packages/cookie-banner/src/themed-banner/styles.ts +++ b/packages/cookie-banner/src/themed-banner/styles.ts @@ -106,6 +106,7 @@ export const THEMED_STYLES = ` probo-preference-panel probo-category-list { overflow-y: auto; + overscroll-behavior: contain; flex: 1; min-height: 0; } diff --git a/packages/cookie-banner/src/themed-banner/themed-banner.ts b/packages/cookie-banner/src/themed-banner/themed-banner.ts index 999922512..3d44c18b4 100644 --- a/packages/cookie-banner/src/themed-banner/themed-banner.ts +++ b/packages/cookie-banner/src/themed-banner/themed-banner.ts @@ -21,6 +21,9 @@ import { THEMED_STYLES } from "./styles"; export class ProboThemedBanner extends HTMLElement { private shadow: ShadowRoot; + private scrollLocked = false; + private prevOverflow = ""; + private prevPaddingRight = ""; constructor() { super(); @@ -150,6 +153,11 @@ export class ProboThemedBanner extends HTMLElement { } }); + root.addEventListener("probo-state", (e: Event) => { + const { state } = (e as CustomEvent).detail; + this.setScrollLock(state === "panel"); + }); + this.shadow.querySelector("[data-action=back]")?.addEventListener("click", () => { root.setState(root.client.hasConsent ? "hidden" : "banner"); }); @@ -176,6 +184,31 @@ export class ProboThemedBanner extends HTMLElement { }); } + disconnectedCallback(): void { + this.setScrollLock(false); + } + + private setScrollLock(locked: boolean): void { + if (locked === this.scrollLocked) return; + + const root = document.documentElement; + + if (locked) { + const scrollbarWidth = window.innerWidth - root.clientWidth; + this.prevOverflow = root.style.overflow; + this.prevPaddingRight = root.style.paddingRight; + root.style.overflow = "hidden"; + if (scrollbarWidth > 0) { + root.style.paddingRight = `${scrollbarWidth}px`; + } + } else { + root.style.overflow = this.prevOverflow; + root.style.paddingRight = this.prevPaddingRight; + } + + this.scrollLocked = locked; + } + private applyTexts(config: BannerConfig): void { const texts = config.texts ?? {};