Skip to content

Commit 9c4e451

Browse files
fix(cdk/listbox): improve SSR compatibility by adding an _isBrowser check before calling _setPreviousActiveOptionAsActiveOptionOnWindowBlur (#28746)
* Add _isBrowser check before calling _setPreviousActiveOptionAsActiveOptionOnWindowBlur * add basic example for cdk listbox
1 parent e45946d commit 9c4e451

File tree

3 files changed

+49
-1
lines changed

3 files changed

+49
-1
lines changed

src/cdk/listbox/listbox.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import {defer, fromEvent, merge, Observable, Subject} from 'rxjs';
4040
import {filter, map, startWith, switchMap, takeUntil} from 'rxjs/operators';
4141
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
4242
import {Directionality} from '@angular/cdk/bidi';
43+
import {Platform} from '@angular/cdk/platform';
4344

4445
/** The next id to use for creating unique DOM IDs. */
4546
let nextId = 0;
@@ -402,6 +403,9 @@ export class CdkListbox<T = unknown> implements AfterContentInit, OnDestroy, Con
402403
/** The directionality of the page. */
403404
private readonly _dir = inject(Directionality, {optional: true});
404405

406+
/** Whether the component is being rendered in the browser. */
407+
private readonly _isBrowser: boolean = inject(Platform).isBrowser;
408+
405409
/** A predicate that skips disabled options. */
406410
private readonly _skipDisabledPredicate = (option: CdkOption<T>) => option.disabled;
407411

@@ -415,7 +419,9 @@ export class CdkListbox<T = unknown> implements AfterContentInit, OnDestroy, Con
415419
private _previousActiveOption: CdkOption<T> | null = null;
416420

417421
constructor() {
418-
this._setPreviousActiveOptionAsActiveOptionOnWindowBlur();
422+
if (this._isBrowser) {
423+
this._setPreviousActiveOptionAsActiveOptionOnWindowBlur();
424+
}
419425
}
420426

421427
ngAfterContentInit() {

src/universal-app/kitchen-sink/kitchen-sink.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,15 @@ <h2>Native table with sticky header and footer</h2>
488488
<tr mat-footer-row *matFooterRowDef="tableColumns; sticky: true"></tr>
489489
</table>
490490

491+
<h2>CDK Listbox</h2>
492+
<div class="test-cdk-listbox">
493+
<label>Favorite color</label>
494+
<ul cdkListbox>
495+
<li cdkOption="red">Red</li>
496+
<li cdkOption="green">Green</li>
497+
<li cdkOption="blue">Blue</li>
498+
</ul>
499+
</div>
491500

492501
<h2>Selection list</h2>
493502
<mat-selection-list>

src/universal-app/kitchen-sink/kitchen-sink.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {A11yModule, FocusMonitor} from '@angular/cdk/a11y';
22
import {DragDropModule} from '@angular/cdk/drag-drop';
3+
import {CdkListboxModule} from '@angular/cdk/listbox';
34
import {ScrollingModule, ViewportRuler} from '@angular/cdk/scrolling';
45
import {CdkTableModule, DataSource} from '@angular/cdk/table';
56
import {Component, ElementRef, InjectionToken, inject} from '@angular/core';
@@ -95,6 +96,37 @@ export class TestEntryComponent {}
9596
border: 1px solid black;
9697
}
9798
99+
.test-cdk-listbox {
100+
display: block;
101+
width: 100%;
102+
103+
> label {
104+
display: block;
105+
padding: 5px;
106+
}
107+
108+
> ul {
109+
list-style: none;
110+
padding: 0;
111+
margin: 0;
112+
113+
> li {
114+
position: relative;
115+
padding: 5px 5px 5px 25px;
116+
117+
&:focus {
118+
background: rgba(0, 0, 0, 0.2);
119+
}
120+
121+
&[aria-selected='true']::before {
122+
content: "✔";
123+
position: absolute;
124+
left: 2px;
125+
}
126+
}
127+
}
128+
}
129+
98130
.test-cdk-table {
99131
display: table;
100132
width: 100%;
@@ -146,6 +178,7 @@ export class TestEntryComponent {}
146178
ScrollingModule,
147179

148180
// CDK Modules
181+
CdkListboxModule,
149182
CdkTableModule,
150183
DragDropModule,
151184
A11yModule,

0 commit comments

Comments
 (0)