Skip to content

Commit c974293

Browse files
committed
fix(cdk-experimental/ui-patterns): preserveContent should not render until first visible
1 parent e478208 commit c974293

File tree

3 files changed

+41
-32
lines changed

3 files changed

+41
-32
lines changed

src/cdk-experimental/deferred-content/deferred-content.spec.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,25 @@ describe('DeferredContent', () => {
3232
component.preserveContent.set(true);
3333
});
3434

35-
it('creates the content when hidden.', async () => {
35+
it('does not create the content until first visible.', async () => {
3636
collapsible.injector.get(Collapsible).contentVisible.set(false);
3737
await fixture.whenStable();
38-
expect(collapsible.nativeElement.innerText).toBe('Lazy Content');
38+
expect(collapsible.nativeElement.innerText).toBe('');
3939
});
4040

4141
it('creates the content when visible.', async () => {
4242
collapsible.injector.get(Collapsible).contentVisible.set(true);
4343
await fixture.whenStable();
4444
expect(collapsible.nativeElement.innerText).toBe('Lazy Content');
4545
});
46+
47+
it('does not remove the content when hidden.', async () => {
48+
collapsible.injector.get(Collapsible).contentVisible.set(true);
49+
await fixture.whenStable();
50+
collapsible.injector.get(Collapsible).contentVisible.set(false);
51+
await fixture.whenStable();
52+
expect(collapsible.nativeElement.innerText).toBe('Lazy Content');
53+
});
4654
});
4755
});
4856

src/cdk-experimental/deferred-content/deferred-content.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
*/
88

99
import {
10+
afterRenderEffect,
1011
Directive,
11-
effect,
1212
inject,
1313
input,
1414
TemplateRef,
@@ -21,7 +21,7 @@ import {
2121
*/
2222
@Directive()
2323
export class DeferredContentAware {
24-
contentVisible = signal(false);
24+
readonly contentVisible = signal(false);
2525
readonly preserveContent = input(false);
2626
}
2727

@@ -48,16 +48,13 @@ export class DeferredContent {
4848
private _isRendered = false;
4949

5050
constructor() {
51-
effect(() => {
52-
if (
53-
this._deferredContentAware.preserveContent() ||
54-
this._deferredContentAware.contentVisible()
55-
) {
51+
afterRenderEffect(() => {
52+
if (this._deferredContentAware.contentVisible()) {
5653
if (this._isRendered) return;
5754
this._viewContainerRef.clear();
5855
this._viewContainerRef.createEmbeddedView(this._templateRef);
5956
this._isRendered = true;
60-
} else {
57+
} else if (!this._deferredContentAware.preserveContent()) {
6158
this._viewContainerRef.clear();
6259
this._isRendered = false;
6360
}

src/cdk-experimental/tree/tree.spec.ts

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@ describe('CdkTree', () => {
119119
if (config.label !== undefined) node.label = config.label;
120120
if (config.children !== undefined) node.children = config.children;
121121
if (config.disabled !== undefined) node.disabled = config.disabled;
122-
if (config.preserveContent !== undefined) node.preserveContent = config.preserveContent;
123122
updateTree({nodes: newNodes});
124123
return;
125124
}
@@ -151,6 +150,16 @@ describe('CdkTree', () => {
151150
return item?.getAttribute('data-value') ?? undefined;
152151
}
153152

153+
function expandAll() {
154+
const fruitsEl = getTreeItemElementByValue('fruits')!;
155+
click(fruitsEl);
156+
const berriesEl = getTreeItemElementByValue('berries')!;
157+
click(berriesEl);
158+
const vegetablesEl = getTreeItemElementByValue('vegetables')!;
159+
click(vegetablesEl);
160+
updateTree({value: []});
161+
}
162+
154163
afterEach(async () => {
155164
fixture.detectChanges();
156165
await runAccessibilityChecks(fixture.nativeElement);
@@ -160,17 +169,15 @@ describe('CdkTree', () => {
160169
describe('default configuration', () => {
161170
beforeEach(() => {
162171
setupTestTree();
163-
// Preserve collapsed children nodes for checking attributes.
164-
updateTreeItemByValue('fruits', {preserveContent: true});
165-
updateTreeItemByValue('berries', {preserveContent: true});
166-
updateTreeItemByValue('vegetables', {preserveContent: true});
167172
});
168173

169174
it('should correctly set the role attribute to "tree" for CdkTree', () => {
170175
expect(treeElement.getAttribute('role')).toBe('tree');
171176
});
172177

173178
it('should correctly set the role attribute to "treeitem" for CdkTreeItem', () => {
179+
expandAll();
180+
174181
expect(getTreeItemElementByValue('fruits')!.getAttribute('role')).toBe('treeitem');
175182
expect(getTreeItemElementByValue('vegetables')!.getAttribute('role')).toBe('treeitem');
176183
expect(getTreeItemElementByValue('grains')!.getAttribute('role')).toBe('treeitem');
@@ -183,6 +190,8 @@ describe('CdkTree', () => {
183190
});
184191

185192
it('should correctly set the role attribute to "group" for CdkTreeItemGroup', () => {
193+
expandAll();
194+
186195
expect(getTreeItemGroupElementByValue('fruits')!.getAttribute('role')).toBe('group');
187196
expect(getTreeItemGroupElementByValue('vegetables')!.getAttribute('role')).toBe('group');
188197
expect(getTreeItemGroupElementByValue('berries')!.getAttribute('role')).toBe('group');
@@ -215,17 +224,19 @@ describe('CdkTree', () => {
215224
});
216225

217226
it('should set aria-level, aria-setsize, and aria-posinset correctly', () => {
227+
expandAll();
228+
218229
const fruits = getTreeItemElementByValue('fruits')!;
219230
expect(fruits.getAttribute('aria-level')).toBe('1');
220231
expect(fruits.getAttribute('aria-setsize')).toBe('4');
221232
expect(fruits.getAttribute('aria-posinset')).toBe('1');
222-
expect(fruits.getAttribute('aria-expanded')).toBe('false');
233+
expect(fruits.getAttribute('aria-expanded')).toBe('true');
223234

224235
const vegetables = getTreeItemElementByValue('vegetables')!;
225236
expect(vegetables.getAttribute('aria-level')).toBe('1');
226237
expect(vegetables.getAttribute('aria-setsize')).toBe('4');
227238
expect(vegetables.getAttribute('aria-posinset')).toBe('2');
228-
expect(vegetables.getAttribute('aria-expanded')).toBe('false');
239+
expect(vegetables.getAttribute('aria-expanded')).toBe('true');
229240

230241
const grains = getTreeItemElementByValue('grains')!;
231242
expect(grains.getAttribute('aria-level')).toBe('1');
@@ -246,7 +257,7 @@ describe('CdkTree', () => {
246257
expect(berries.getAttribute('aria-level')).toBe('2');
247258
expect(berries.getAttribute('aria-setsize')).toBe('3');
248259
expect(berries.getAttribute('aria-posinset')).toBe('3');
249-
expect(berries.getAttribute('aria-expanded')).toBe('false');
260+
expect(berries.getAttribute('aria-expanded')).toBe('true');
250261

251262
const strawberry = getTreeItemElementByValue('strawberry')!;
252263
expect(strawberry.getAttribute('aria-level')).toBe('3');
@@ -264,10 +275,6 @@ describe('CdkTree', () => {
264275
describe('custom configuration', () => {
265276
beforeEach(() => {
266277
setupTestTree();
267-
// Preserve collapsed children nodes for checking attributes.
268-
updateTreeItemByValue('fruits', {preserveContent: true});
269-
updateTreeItemByValue('berries', {preserveContent: true});
270-
updateTreeItemByValue('vegetables', {preserveContent: true});
271278
});
272279

273280
it('should set aria-orientation to "horizontal"', () => {
@@ -296,6 +303,7 @@ describe('CdkTree', () => {
296303
});
297304

298305
it('should set aria-selected to "true" for selected items', () => {
306+
expandAll();
299307
updateTree({value: ['apple']});
300308

301309
const appleItem = getTreeItemElementByValue('apple')!;
@@ -306,11 +314,13 @@ describe('CdkTree', () => {
306314

307315
it('should set aria-expanded to "true" for expanded items', () => {
308316
right();
317+
309318
const fruitsItem = getTreeItemElementByValue('fruits')!;
310319
expect(fruitsItem.getAttribute('aria-expanded')).toBe('true');
311320
});
312321

313322
it('should set aria-current to specific current type when nav="true"', () => {
323+
expandAll();
314324
updateTree({nav: true, value: ['apple']});
315325

316326
const appleItem = getTreeItemElementByValue('apple')!;
@@ -323,6 +333,8 @@ describe('CdkTree', () => {
323333
});
324334

325335
it('should not set aria-selected when nav="true"', () => {
336+
expandAll();
337+
326338
updateTree({value: ['apple'], nav: true});
327339
const appleItem = getTreeItemElementByValue('apple')!;
328340
expect(appleItem.hasAttribute('aria-selected')).toBe(false);
@@ -402,10 +414,7 @@ describe('CdkTree', () => {
402414
});
403415

404416
it('should set tabindex="-1" for all items', () => {
405-
// Preserve collapsed children nodes for checking attributes.
406-
updateTreeItemByValue('fruits', {preserveContent: true});
407-
updateTreeItemByValue('berries', {preserveContent: true});
408-
updateTreeItemByValue('vegetables', {preserveContent: true});
417+
expandAll();
409418

410419
expect(getTreeItemElementByValue('fruits')!.getAttribute('tabindex')).toBe('-1');
411420
expect(getTreeItemElementByValue('apple')!.getAttribute('tabindex')).toBe('-1');
@@ -425,10 +434,7 @@ describe('CdkTree', () => {
425434
describe('value and selection', () => {
426435
it('should select items based on the initial value input', () => {
427436
setupTestTree();
428-
// Preserve collapsed children nodes for checking attributes.
429-
updateTreeItemByValue('fruits', {preserveContent: true});
430-
updateTreeItemByValue('berries', {preserveContent: true});
431-
updateTreeItemByValue('vegetables', {preserveContent: true});
437+
expandAll();
432438
updateTree({value: ['apple', 'strawberry', 'carrot']});
433439

434440
expect(getTreeItemElementByValue('apple')!.getAttribute('aria-selected')).toBe('true');
@@ -1320,7 +1326,6 @@ interface TestTreeNode<V = string> {
13201326
label: string;
13211327
disabled?: boolean;
13221328
children?: TestTreeNode<V>[];
1323-
preserveContent?: boolean;
13241329
}
13251330

13261331
@Component({
@@ -1359,7 +1364,6 @@ interface TestTreeNode<V = string> {
13591364
<ul
13601365
cdkTreeItemGroup
13611366
[ownedBy]="treeItem"
1362-
[preserveContent]="!!node.preserveContent"
13631367
[attr.data-group-for]="node.value"
13641368
#group="cdkTreeItemGroup">
13651369
<ng-template cdkTreeItemGroupContent>

0 commit comments

Comments
 (0)