diff --git a/src/elements/select/select.ssr.spec.ts b/src/elements/select/select.ssr.spec.ts index e59508c678..323c0369c0 100644 --- a/src/elements/select/select.ssr.spec.ts +++ b/src/elements/select/select.ssr.spec.ts @@ -1,4 +1,4 @@ -import { assert } from '@open-wc/testing'; +import { assert, expect } from '@open-wc/testing'; import { html } from 'lit'; import { ssrHydratedFixture } from '../core/testing/private.js'; @@ -9,7 +9,7 @@ import '../option.js'; describe(`sbb-select ssr`, () => { let root: SbbSelectElement; - beforeEach(async () => { + it('renders', async () => { root = await ssrHydratedFixture( html` @@ -20,9 +20,25 @@ describe(`sbb-select ssr`, () => { `, { modules: ['./select.js', '../option.js'] }, ); + + assert.instanceOf(root, SbbSelectElement); }); - it('renders', () => { + it('renders with value attribute', async () => { + root = await ssrHydratedFixture( + html` + + First + Second + Third + + `, + { modules: ['./select.js', '../option.js'] }, + ); + assert.instanceOf(root, SbbSelectElement); + expect(root.shadowRoot!.querySelector('.sbb-select__trigger')!.textContent!.trim()).to.be.equal( + 'Second', + ); }); }); diff --git a/src/elements/select/select.ts b/src/elements/select/select.ts index 7bd7a5eed1..cfbca69f45 100644 --- a/src/elements/select/select.ts +++ b/src/elements/select/select.ts @@ -2,6 +2,7 @@ import type { CSSResultGroup, PropertyValues, TemplateResult } from 'lit'; import { html, nothing } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { ref } from 'lit/directives/ref.js'; +import { until } from 'lit/directives/until.js'; import { getNextElementIndex } from '../core/a11y.js'; import { SbbOpenCloseBaseElement } from '../core/base-elements.js'; @@ -9,7 +10,12 @@ import { SbbConnectedAbortController } from '../core/controllers.js'; import { hostAttributes } from '../core/decorators.js'; import { getDocumentWritingMode, isNextjs, isSafari } from '../core/dom.js'; import { EventEmitter } from '../core/eventing.js'; -import { SbbDisabledMixin, SbbNegativeMixin, SbbUpdateSchedulerMixin } from '../core/mixins.js'; +import { + SbbDisabledMixin, + SbbHydrationMixin, + SbbNegativeMixin, + SbbUpdateSchedulerMixin, +} from '../core/mixins.js'; import { isEventOnElement, overlayGapFixCorners, setOverlayPosition } from '../core/overlay.js'; import type { SbbOptGroupElement, SbbOptionElement } from '../option.js'; @@ -49,7 +55,7 @@ export interface SelectChange { role: ariaRoleOnHost ? 'listbox' : null, }) export class SbbSelectElement extends SbbUpdateSchedulerMixin( - SbbDisabledMixin(SbbNegativeMixin(SbbOpenCloseBaseElement)), + SbbDisabledMixin(SbbNegativeMixin(SbbHydrationMixin(SbbOpenCloseBaseElement))), ) { public static override styles: CSSResultGroup = style; @@ -163,7 +169,7 @@ export class SbbSelectElement extends SbbUpdateSchedulerMixin( /** Gets the current displayed value. */ public getDisplayValue(): string { - return !this._displayValue ? '' : this._displayValue; + return this._displayValue ?? ''; } /** Listens to option changes. */ @@ -679,6 +685,19 @@ export class SbbSelectElement extends SbbUpdateSchedulerMixin( } } + private _spreadDeferredDisplayValue( + placeholder: TemplateResult, + ): (TemplateResult | Promise)[] { + return [this._deferredDisplayValue(placeholder), placeholder]; + } + + private async _deferredDisplayValue(placeholder: TemplateResult): Promise { + if (this.hydrationRequired) { + await this.hydrationComplete; + } + return this._displayValue ? html`${this._displayValue}` : placeholder; + } + protected override render(): TemplateResult { return html`