235 lines
7.5 KiB
TypeScript
235 lines
7.5 KiB
TypeScript
import {Direction, Directionality} from '@angular/cdk/bidi';
|
|
import {PortalModule, TemplatePortal} from '@angular/cdk/portal';
|
|
import {CdkScrollable, ScrollingModule} from '@angular/cdk/scrolling';
|
|
import {
|
|
AfterViewInit,
|
|
Component,
|
|
TemplateRef,
|
|
ViewChild,
|
|
ViewContainerRef,
|
|
inject,
|
|
signal,
|
|
} from '@angular/core';
|
|
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
|
|
import {MatRippleModule} from '@angular/material/core';
|
|
import {By} from '@angular/platform-browser';
|
|
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
|
|
import {Subject} from 'rxjs';
|
|
import {MatTabBody, MatTabBodyPortal} from './tab-body';
|
|
|
|
describe('MatTabBody', () => {
|
|
let dir: Direction = 'ltr';
|
|
let dirChange: Subject<Direction> = new Subject<Direction>();
|
|
|
|
beforeEach(waitForAsync(() => {
|
|
dir = 'ltr';
|
|
TestBed.configureTestingModule({
|
|
imports: [
|
|
PortalModule,
|
|
MatRippleModule,
|
|
NoopAnimationsModule,
|
|
MatTabBody,
|
|
MatTabBodyPortal,
|
|
SimpleTabBodyApp,
|
|
],
|
|
providers: [{provide: Directionality, useFactory: () => ({value: dir, change: dirChange})}],
|
|
});
|
|
}));
|
|
|
|
describe('when initialized as center', () => {
|
|
let fixture: ComponentFixture<SimpleTabBodyApp>;
|
|
|
|
it('should be center position if origin is unchanged', () => {
|
|
fixture = TestBed.createComponent(SimpleTabBodyApp);
|
|
fixture.componentInstance.position = 0;
|
|
fixture.detectChanges();
|
|
|
|
expect(fixture.componentInstance.tabBody._position).toBe('center');
|
|
});
|
|
|
|
it('should be center position if origin is explicitly set to null', () => {
|
|
fixture = TestBed.createComponent(SimpleTabBodyApp);
|
|
fixture.componentInstance.position = 0;
|
|
|
|
// It can happen that the `origin` is explicitly set to null through the Angular input
|
|
// binding. This test should ensure that the body does properly such origin value.
|
|
// The `MatTab` class sets the origin by default to null. See related issue: #12455
|
|
fixture.componentInstance.origin = null;
|
|
fixture.detectChanges();
|
|
|
|
expect(fixture.componentInstance.tabBody._position).toBe('center');
|
|
});
|
|
|
|
describe('in LTR direction', () => {
|
|
beforeEach(() => {
|
|
dir = 'ltr';
|
|
fixture = TestBed.createComponent(SimpleTabBodyApp);
|
|
});
|
|
it('should be left-origin-center position with negative or zero origin', () => {
|
|
fixture.componentInstance.position = 0;
|
|
fixture.componentInstance.origin = 0;
|
|
fixture.detectChanges();
|
|
|
|
expect(fixture.componentInstance.tabBody._position).toBe('left-origin-center');
|
|
});
|
|
|
|
it('should be right-origin-center position with positive nonzero origin', () => {
|
|
fixture.componentInstance.position = 0;
|
|
fixture.componentInstance.origin = 1;
|
|
fixture.detectChanges();
|
|
|
|
expect(fixture.componentInstance.tabBody._position).toBe('right-origin-center');
|
|
});
|
|
});
|
|
|
|
describe('in RTL direction', () => {
|
|
beforeEach(() => {
|
|
dir = 'rtl';
|
|
fixture = TestBed.createComponent(SimpleTabBodyApp);
|
|
});
|
|
|
|
it('should be right-origin-center position with negative or zero origin', () => {
|
|
fixture.componentInstance.position = 0;
|
|
fixture.componentInstance.origin = 0;
|
|
fixture.detectChanges();
|
|
|
|
expect(fixture.componentInstance.tabBody._position).toBe('right-origin-center');
|
|
});
|
|
|
|
it('should be left-origin-center position with positive nonzero origin', () => {
|
|
fixture.componentInstance.position = 0;
|
|
fixture.componentInstance.origin = 1;
|
|
fixture.detectChanges();
|
|
|
|
expect(fixture.componentInstance.tabBody._position).toBe('left-origin-center');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('should properly set the position in LTR', () => {
|
|
let fixture: ComponentFixture<SimpleTabBodyApp>;
|
|
|
|
beforeEach(() => {
|
|
dir = 'ltr';
|
|
fixture = TestBed.createComponent(SimpleTabBodyApp);
|
|
fixture.detectChanges();
|
|
});
|
|
|
|
it('to be left position with negative position', () => {
|
|
fixture.componentInstance.position = -1;
|
|
fixture.changeDetectorRef.markForCheck();
|
|
fixture.detectChanges();
|
|
|
|
expect(fixture.componentInstance.tabBody._position).toBe('left');
|
|
});
|
|
|
|
it('to be center position with zero position', () => {
|
|
fixture.componentInstance.position = 0;
|
|
fixture.changeDetectorRef.markForCheck();
|
|
fixture.detectChanges();
|
|
|
|
expect(fixture.componentInstance.tabBody._position).toBe('center');
|
|
});
|
|
|
|
it('to be left position with positive position', () => {
|
|
fixture.componentInstance.position = 1;
|
|
fixture.changeDetectorRef.markForCheck();
|
|
fixture.detectChanges();
|
|
|
|
expect(fixture.componentInstance.tabBody._position).toBe('right');
|
|
});
|
|
});
|
|
|
|
describe('should properly set the position in RTL', () => {
|
|
let fixture: ComponentFixture<SimpleTabBodyApp>;
|
|
|
|
beforeEach(() => {
|
|
dir = 'rtl';
|
|
fixture = TestBed.createComponent(SimpleTabBodyApp);
|
|
fixture.detectChanges();
|
|
});
|
|
|
|
it('to be right position with negative position', () => {
|
|
fixture.componentInstance.position = -1;
|
|
fixture.changeDetectorRef.markForCheck();
|
|
fixture.detectChanges();
|
|
|
|
expect(fixture.componentInstance.tabBody._position).toBe('right');
|
|
});
|
|
|
|
it('to be center position with zero position', () => {
|
|
fixture.componentInstance.position = 0;
|
|
fixture.changeDetectorRef.markForCheck();
|
|
fixture.detectChanges();
|
|
|
|
expect(fixture.componentInstance.tabBody._position).toBe('center');
|
|
});
|
|
|
|
it('to be left position with positive position', () => {
|
|
fixture.componentInstance.position = 1;
|
|
fixture.changeDetectorRef.markForCheck();
|
|
fixture.detectChanges();
|
|
|
|
expect(fixture.componentInstance.tabBody._position).toBe('left');
|
|
});
|
|
});
|
|
|
|
it('should update position if direction changed at runtime', () => {
|
|
const fixture = TestBed.createComponent(SimpleTabBodyApp);
|
|
|
|
fixture.componentInstance.position = 1;
|
|
fixture.detectChanges();
|
|
|
|
expect(fixture.componentInstance.tabBody._position).toBe('right');
|
|
|
|
dirChange.next('rtl');
|
|
dir = 'rtl';
|
|
|
|
fixture.detectChanges();
|
|
|
|
expect(fixture.componentInstance.tabBody._position).toBe('left');
|
|
});
|
|
|
|
it('should mark the tab body content as a scrollable container', () => {
|
|
TestBed.resetTestingModule().configureTestingModule({
|
|
imports: [
|
|
PortalModule,
|
|
MatRippleModule,
|
|
NoopAnimationsModule,
|
|
ScrollingModule,
|
|
SimpleTabBodyApp,
|
|
],
|
|
});
|
|
|
|
const fixture = TestBed.createComponent(SimpleTabBodyApp);
|
|
const tabBodyContent = fixture.nativeElement.querySelector('.mat-mdc-tab-body-content');
|
|
const scrollable = fixture.debugElement.query(By.directive(CdkScrollable));
|
|
|
|
expect(scrollable).toBeTruthy();
|
|
expect(scrollable.nativeElement).toBe(tabBodyContent);
|
|
});
|
|
});
|
|
|
|
@Component({
|
|
template: `
|
|
<ng-template>Tab Body Content</ng-template>
|
|
<mat-tab-body [content]="content()" [position]="position" [origin]="origin"></mat-tab-body>
|
|
`,
|
|
standalone: true,
|
|
imports: [PortalModule, MatRippleModule, MatTabBody],
|
|
})
|
|
class SimpleTabBodyApp implements AfterViewInit {
|
|
content = signal<TemplatePortal | undefined>(undefined);
|
|
position: number;
|
|
origin: number | null;
|
|
|
|
@ViewChild(MatTabBody) tabBody: MatTabBody;
|
|
@ViewChild(TemplateRef) template: TemplateRef<any>;
|
|
|
|
private readonly _viewContainerRef = inject(ViewContainerRef);
|
|
|
|
ngAfterViewInit() {
|
|
this.content.set(new TemplatePortal(this.template, this._viewContainerRef));
|
|
}
|
|
}
|