From 14595019c699fc41f8daa0b18c655b917b230765 Mon Sep 17 00:00:00 2001 From: Lukas Spirig Date: Thu, 4 Jul 2024 18:13:42 +0200 Subject: [PATCH] fix(sbb-popover): prevent matchMedia call before hydration --- .../popover/popover/popover.ssr.spec.ts | 63 +++++++++++++------ src/elements/popover/popover/popover.ts | 12 +++- 2 files changed, 55 insertions(+), 20 deletions(-) diff --git a/src/elements/popover/popover/popover.ssr.spec.ts b/src/elements/popover/popover/popover.ssr.spec.ts index be978188eb..977ff50774 100644 --- a/src/elements/popover/popover/popover.ssr.spec.ts +++ b/src/elements/popover/popover/popover.ssr.spec.ts @@ -4,31 +4,58 @@ import { html } from 'lit'; import { ssrHydratedFixture } from '../../core/testing/private.js'; import { SbbPopoverElement } from './popover.js'; + import '../../button.js'; import '../../link.js'; describe(`sbb-popover ssr`, () => { let root: HTMLSpanElement; - beforeEach(async () => { - root = await ssrHydratedFixture( - html` - - Popover trigger - - Popover content. - Link - - Other interactive element - - `, - { modules: ['../../button.js', './popover.js', '../../link.js'] }, - ); + describe('default', () => { + beforeEach(async () => { + root = await ssrHydratedFixture( + html` + + Popover trigger + + Popover content. + Link + + Other interactive element + + `, + { modules: ['../../button.js', './popover.js', '../../link.js'] }, + ); + }); + + it('renders', () => { + assert.instanceOf(root.querySelector('sbb-popover'), SbbPopoverElement); + }); }); - it('renders', () => { - assert.instanceOf(root.querySelector('sbb-popover'), SbbPopoverElement); + describe('hover trigger', () => { + beforeEach(async () => { + root = await ssrHydratedFixture( + html` + + Popover trigger + + Popover content. + Link + + Other interactive element + + `, + { modules: ['../../button.js', './popover.js', '../../link.js'] }, + ); + }); + + it('renders', () => { + assert.instanceOf(root.querySelector('sbb-popover'), SbbPopoverElement); + }); }); }); diff --git a/src/elements/popover/popover/popover.ts b/src/elements/popover/popover/popover.ts index 241f2cbed9..ba315103b6 100644 --- a/src/elements/popover/popover/popover.ts +++ b/src/elements/popover/popover/popover.ts @@ -1,5 +1,5 @@ import type { CSSResultGroup, PropertyValues, TemplateResult } from 'lit'; -import { html, nothing } from 'lit'; +import { html, isServer, nothing } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { ref } from 'lit/directives/ref.js'; @@ -15,6 +15,7 @@ import { findReferencedElement } from '../../core/dom.js'; import { composedPathHasAttribute, EventEmitter } from '../../core/eventing.js'; import { i18nClosePopover } from '../../core/i18n.js'; import type { SbbOpenedClosedState } from '../../core/interfaces.js'; +import { SbbHydrationMixin } from '../../core/mixins.js'; import { getElementPosition, isEventOnElement, @@ -47,7 +48,7 @@ const popoversRef = new Set(); * component is set to `var(--sbb-overlay-default-z-index)` with a value of `1000`. */ @customElement('sbb-popover') -export class SbbPopoverElement extends SbbOpenCloseBaseElement { +export class SbbPopoverElement extends SbbHydrationMixin(SbbOpenCloseBaseElement) { public static override styles: CSSResultGroup = style; /** @@ -210,6 +211,13 @@ export class SbbPopoverElement extends SbbOpenCloseBaseElement { // Check if the trigger is valid and attach click event listeners. private _configure(): void { + if (isServer) { + return; + } else if (this.hydrationRequired) { + this.hydrationComplete.then(() => this._configure); + return; + } + removeAriaOverlayTriggerAttributes(this._triggerElement); if (!this.trigger) {