Skip to content

Commit 816099e

Browse files
authored
Revert "feat(material/tabs): add the ability to keep content inside the DOM while off-screen (#20393)" (#24298)
This reverts commit c3188c8.
1 parent c3188c8 commit 816099e

File tree

15 files changed

+11
-221
lines changed

15 files changed

+11
-221
lines changed

src/components-examples/material/tabs/index.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import {TabGroupHarnessExample} from './tab-group-harness/tab-group-harness-exam
1717
import {TabGroupDynamicExample} from './tab-group-dynamic/tab-group-dynamic-example';
1818
import {TabGroupHeaderBelowExample} from './tab-group-header-below/tab-group-header-below-example';
1919
import {TabGroupLazyLoadedExample} from './tab-group-lazy-loaded/tab-group-lazy-loaded-example';
20-
import {TabGroupPreserveContentExample} from './tab-group-preserve-content/tab-group-preserve-content-example';
2120
import {TabGroupStretchedExample} from './tab-group-stretched/tab-group-stretched-example';
2221
import {TabGroupThemeExample} from './tab-group-theme/tab-group-theme-example';
2322
import {TabNavBarBasicExample} from './tab-nav-bar-basic/tab-nav-bar-basic-example';
@@ -38,7 +37,6 @@ export {
3837
TabGroupThemeExample,
3938
TabNavBarBasicExample,
4039
TabNavBarWithPanelExample,
41-
TabGroupPreserveContentExample,
4240
};
4341

4442
const EXAMPLES = [
@@ -56,7 +54,6 @@ const EXAMPLES = [
5654
TabGroupThemeExample,
5755
TabNavBarBasicExample,
5856
TabNavBarWithPanelExample,
59-
TabGroupPreserveContentExample,
6057
];
6158

6259
@NgModule({

src/components-examples/material/tabs/tab-group-preserve-content/tab-group-preserve-content-example.html

Lines changed: 0 additions & 14 deletions
This file was deleted.

src/components-examples/material/tabs/tab-group-preserve-content/tab-group-preserve-content-example.ts

Lines changed: 0 additions & 10 deletions
This file was deleted.

src/material-experimental/mdc-tabs/tab-body.scss

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,6 @@
2222
.mat-mdc-tab-group.mat-mdc-tab-group-dynamic-height &.mat-mdc-tab-body-active {
2323
overflow-y: hidden;
2424
}
25-
26-
// Usually the `visibility: hidden` added by the animation is enough to prevent focus from
27-
// entering the collapsed content, but children with their own `visibility` can override it.
28-
// This is a fallback that completely hides the content when the element becomes hidden.
29-
// Note that we can't do this in the animation definition, because the style gets recomputed too
30-
// late, breaking the animation because Angular didn't have time to figure out the target height.
31-
// This can also be achieved with JS, but it has issues when when starting an animation before
32-
// the previous one has finished.
33-
&[style*='visibility: hidden'] {
34-
display: none;
35-
}
3625
}
3726

3827
.mat-mdc-tab-body-content {

src/material-experimental/mdc-tabs/tab-group.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@
6363
[position]="tab.position!"
6464
[origin]="tab.origin"
6565
[animationDuration]="animationDuration"
66-
[preserveContent]="preserveContent"
6766
(_onCentered)="_removeTabBodyWrapperHeight()"
6867
(_onCentering)="_setTabBodyWrapperHeight($event)">
6968
</mat-tab-body>

src/material-experimental/mdc-tabs/tab-group.spec.ts

Lines changed: 1 addition & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -666,56 +666,6 @@ describe('MDC-based MatTabGroup', () => {
666666

667667
expect(tabGroupNode.classList).toContain('mat-mdc-tab-group-inverted-header');
668668
});
669-
670-
it('should be able to opt into keeping the inactive tab content in the DOM', fakeAsync(() => {
671-
fixture.componentInstance.preserveContent = true;
672-
fixture.detectChanges();
673-
674-
expect(fixture.nativeElement.textContent).toContain('Pizza, fries');
675-
expect(fixture.nativeElement.textContent).not.toContain('Peanuts');
676-
677-
tabGroup.selectedIndex = 3;
678-
fixture.detectChanges();
679-
tick();
680-
681-
expect(fixture.nativeElement.textContent).toContain('Pizza, fries');
682-
expect(fixture.nativeElement.textContent).toContain('Peanuts');
683-
}));
684-
685-
it('should visibly hide the content of inactive tabs', fakeAsync(() => {
686-
const contentElements: HTMLElement[] = Array.from(
687-
fixture.nativeElement.querySelectorAll('.mat-mdc-tab-body-content'),
688-
);
689-
690-
expect(contentElements.map(element => element.style.visibility)).toEqual([
691-
'',
692-
'hidden',
693-
'hidden',
694-
'hidden',
695-
]);
696-
697-
tabGroup.selectedIndex = 2;
698-
fixture.detectChanges();
699-
tick();
700-
701-
expect(contentElements.map(element => element.style.visibility)).toEqual([
702-
'hidden',
703-
'hidden',
704-
'',
705-
'hidden',
706-
]);
707-
708-
tabGroup.selectedIndex = 1;
709-
fixture.detectChanges();
710-
tick();
711-
712-
expect(contentElements.map(element => element.style.visibility)).toEqual([
713-
'hidden',
714-
'',
715-
'hidden',
716-
'hidden',
717-
]);
718-
}));
719669
});
720670

721671
describe('lazy loaded tabs', () => {
@@ -1176,7 +1126,7 @@ class AsyncTabsTestApp implements OnInit {
11761126

11771127
@Component({
11781128
template: `
1179-
<mat-tab-group [preserveContent]="preserveContent">
1129+
<mat-tab-group>
11801130
<mat-tab label="Junk food"> Pizza, fries </mat-tab>
11811131
<mat-tab label="Vegetables"> Broccoli, spinach </mat-tab>
11821132
<mat-tab [label]="otherLabel"> {{otherContent}} </mat-tab>
@@ -1185,7 +1135,6 @@ class AsyncTabsTestApp implements OnInit {
11851135
`,
11861136
})
11871137
class TabGroupWithSimpleApi {
1188-
preserveContent = false;
11891138
otherLabel = 'Fruit';
11901139
otherContent = 'Apples, grapes';
11911140
@ViewChild('legumes') legumes: any;

src/material/tabs/tab-body.scss

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,4 @@
55
.mat-tab-group-dynamic-height & {
66
overflow: hidden;
77
}
8-
9-
// Usually the `visibility: hidden` added by the animation is enough to prevent focus from
10-
// entering the collapsed content, but children with their own `visibility` can override it.
11-
// This is a fallback that completely hides the content when the element becomes hidden.
12-
// Note that we can't do this in the animation definition, because the style gets recomputed too
13-
// late, breaking the animation because Angular didn't have time to figure out the target height.
14-
// This can also be achieved with JS, but it has issues when when starting an animation before
15-
// the previous one has finished.
16-
&[style*='visibility: hidden'] {
17-
display: none;
18-
}
198
}

src/material/tabs/tab-body.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,7 @@ export class MatTabBodyPortal extends CdkPortalOutlet implements OnInit, OnDestr
9393
});
9494

9595
this._leavingSub = this._host._afterLeavingCenter.subscribe(() => {
96-
if (!this._host.preserveContent) {
97-
this.detach();
98-
}
96+
this.detach();
9997
});
10098
}
10199

@@ -151,9 +149,6 @@ export abstract class _MatTabBodyBase implements OnInit, OnDestroy {
151149
/** Duration for the tab's animation. */
152150
@Input() animationDuration: string = '500ms';
153151

154-
/** Whether the tab's content should be kept in the DOM while it's off-screen. */
155-
@Input() preserveContent: boolean = false;
156-
157152
/** The shifted index position of the tab body, where zero represents the active center tab. */
158153
@Input()
159154
set position(position: number) {

src/material/tabs/tab-config.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,6 @@ export interface MatTabsConfig {
2929

3030
/** `tabindex` to be set on the inner element that wraps the tab content. */
3131
contentTabIndex?: number;
32-
33-
/**
34-
* By default tabs remove their content from the DOM while it's off-screen.
35-
* Setting this to `true` will keep it in the DOM which will prevent elements
36-
* like iframes and videos from reloading next time it comes back into the view.
37-
*/
38-
preserveContent?: boolean;
3932
}
4033

4134
/** Injection token that can be used to provide the default options the tabs module. */

src/material/tabs/tab-group.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
[position]="tab.position!"
5151
[origin]="tab.origin"
5252
[animationDuration]="animationDuration"
53-
[preserveContent]="preserveContent"
5453
(_onCentered)="_removeTabBodyWrapperHeight()"
5554
(_onCentering)="_setTabBodyWrapperHeight($event)">
5655
</mat-tab-body>

src/material/tabs/tab-group.spec.ts

Lines changed: 1 addition & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -665,56 +665,6 @@ describe('MatTabGroup', () => {
665665

666666
expect(tabGroupNode.classList).toContain('mat-tab-group-inverted-header');
667667
});
668-
669-
it('should be able to opt into keeping the inactive tab content in the DOM', fakeAsync(() => {
670-
fixture.componentInstance.preserveContent = true;
671-
fixture.detectChanges();
672-
673-
expect(fixture.nativeElement.textContent).toContain('Pizza, fries');
674-
expect(fixture.nativeElement.textContent).not.toContain('Peanuts');
675-
676-
tabGroup.selectedIndex = 3;
677-
fixture.detectChanges();
678-
tick();
679-
680-
expect(fixture.nativeElement.textContent).toContain('Pizza, fries');
681-
expect(fixture.nativeElement.textContent).toContain('Peanuts');
682-
}));
683-
684-
it('should visibly hide the content of inactive tabs', fakeAsync(() => {
685-
const contentElements: HTMLElement[] = Array.from(
686-
fixture.nativeElement.querySelectorAll('.mat-tab-body-content'),
687-
);
688-
689-
expect(contentElements.map(element => element.style.visibility)).toEqual([
690-
'',
691-
'hidden',
692-
'hidden',
693-
'hidden',
694-
]);
695-
696-
tabGroup.selectedIndex = 2;
697-
fixture.detectChanges();
698-
tick();
699-
700-
expect(contentElements.map(element => element.style.visibility)).toEqual([
701-
'hidden',
702-
'hidden',
703-
'',
704-
'hidden',
705-
]);
706-
707-
tabGroup.selectedIndex = 1;
708-
fixture.detectChanges();
709-
tick();
710-
711-
expect(contentElements.map(element => element.style.visibility)).toEqual([
712-
'hidden',
713-
'',
714-
'hidden',
715-
'hidden',
716-
]);
717-
}));
718668
});
719669

720670
describe('lazy loaded tabs', () => {
@@ -1122,7 +1072,7 @@ class AsyncTabsTestApp implements OnInit {
11221072

11231073
@Component({
11241074
template: `
1125-
<mat-tab-group [preserveContent]="preserveContent">
1075+
<mat-tab-group>
11261076
<mat-tab label="Junk food"> Pizza, fries </mat-tab>
11271077
<mat-tab label="Vegetables"> Broccoli, spinach </mat-tab>
11281078
<mat-tab [label]="otherLabel"> {{otherContent}} </mat-tab>
@@ -1131,7 +1081,6 @@ class AsyncTabsTestApp implements OnInit {
11311081
`,
11321082
})
11331083
class TabGroupWithSimpleApi {
1134-
preserveContent = false;
11351084
otherLabel = 'Fruit';
11361085
otherContent = 'Apples, grapes';
11371086
@ViewChild('legumes') legumes: any;

src/material/tabs/tab-group.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -163,14 +163,6 @@ export abstract class _MatTabGroupBase
163163
@Input()
164164
disablePagination: boolean;
165165

166-
/**
167-
* By default tabs remove their content from the DOM while it's off-screen.
168-
* Setting this to `true` will keep it in the DOM which will prevent elements
169-
* like iframes and videos from reloading next time it comes back into the view.
170-
*/
171-
@Input()
172-
preserveContent: boolean;
173-
174166
/** Background color of the tab group. */
175167
@Input()
176168
get backgroundColor(): ThemePalette {
@@ -222,7 +214,6 @@ export abstract class _MatTabGroupBase
222214
this.dynamicHeight =
223215
defaultConfig && defaultConfig.dynamicHeight != null ? defaultConfig.dynamicHeight : false;
224216
this.contentTabIndex = defaultConfig?.contentTabIndex ?? null;
225-
this.preserveContent = !!defaultConfig?.preserveContent;
226217
}
227218

228219
/**

src/material/tabs/tabs-animations.ts

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -23,50 +23,26 @@ export const matTabsAnimations: {
2323
} = {
2424
/** Animation translates a tab along the X axis. */
2525
translateTab: trigger('translateTab', [
26-
state(
27-
'center, void, left-origin-center, right-origin-center',
28-
style({
29-
// Transitions to `none` instead of 0, because some browsers might blur the content.
30-
transform: 'none',
31-
// Ensures that the `visibility: hidden` from below is cleared.
32-
visibility: '',
33-
}),
34-
),
26+
// Note: transitions to `none` instead of 0, because some browsers might blur the content.
27+
state('center, void, left-origin-center, right-origin-center', style({transform: 'none'})),
3528

3629
// If the tab is either on the left or right, we additionally add a `min-height` of 1px
3730
// in order to ensure that the element has a height before its state changes. This is
3831
// necessary because Chrome does seem to skip the transition in RTL mode if the element does
3932
// not have a static height and is not rendered. See related issue: #9465
40-
state(
41-
'left',
42-
style({
43-
transform: 'translate3d(-100%, 0, 0)',
44-
minHeight: '1px',
45-
46-
// Normally this is redundant since we detach the content from the DOM, but if the user
47-
// opted into keeping the content in the DOM, we have to hide it so it isn't focusable.
48-
visibility: 'hidden',
49-
}),
50-
),
51-
state(
52-
'right',
53-
style({
54-
transform: 'translate3d(100%, 0, 0)',
55-
minHeight: '1px',
56-
visibility: 'hidden',
57-
}),
58-
),
33+
state('left', style({transform: 'translate3d(-100%, 0, 0)', minHeight: '1px'})),
34+
state('right', style({transform: 'translate3d(100%, 0, 0)', minHeight: '1px'})),
5935

6036
transition(
6137
'* => left, * => right, left => center, right => center',
6238
animate('{{animationDuration}} cubic-bezier(0.35, 0, 0.25, 1)'),
6339
),
6440
transition('void => left-origin-center', [
65-
style({transform: 'translate3d(-100%, 0, 0)', visibility: 'hidden'}),
41+
style({transform: 'translate3d(-100%, 0, 0)'}),
6642
animate('{{animationDuration}} cubic-bezier(0.35, 0, 0.25, 1)'),
6743
]),
6844
transition('void => right-origin-center', [
69-
style({transform: 'translate3d(100%, 0, 0)', visibility: 'hidden'}),
45+
style({transform: 'translate3d(100%, 0, 0)'}),
7046
animate('{{animationDuration}} cubic-bezier(0.35, 0, 0.25, 1)'),
7147
]),
7248
]),

src/material/tabs/tabs.md

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,6 @@ duration can be configured globally using the `MAT_TABS_CONFIG` injection token.
8484
"file": "tab-group-animations-example.html",
8585
"region": "slow-animation-duration"}) -->
8686

87-
### Keeping the tab content inside the DOM while it's off-screen
88-
By default the `<mat-tab-group>` will remove the content of off-screen tabs from the DOM until they
89-
come into the view. This is optimal for most cases since it keeps the DOM size smaller, but it
90-
isn't great for others like when a tab has an `<audio>` or `<video>` element, because the content
91-
will be re-initialized whenever the user navigates to the tab. If you want to keep the content of
92-
off-screen tabs in the DOM, you can set the `preserveContent` input to `true`.
93-
94-
<!-- example(tab-group-preserve-content) -->
95-
9687
### Accessibility
9788
`MatTabGroup` and `MatTabNavBar` implement different interaction patterns for different use-cases.
9889
You should choose the component that works best for your application.

0 commit comments

Comments
 (0)