[ACS-7552] - ACA menu column get disabled on resize of browser (#9679)

This commit is contained in:
dominikiwanekhyland
2024-06-04 07:58:18 +02:00
committed by GitHub
parent 43d5df1a01
commit 2c3c2706f6
2 changed files with 147 additions and 120 deletions

View File

@@ -17,170 +17,149 @@
import { LayoutContainerComponent } from './layout-container.component'; import { LayoutContainerComponent } from './layout-container.component';
import { SimpleChange } from '@angular/core'; import { SimpleChange } from '@angular/core';
import { MatSidenav } from '@angular/material/sidenav';
import { Direction } from '@angular/cdk/bidi';
describe('LayoutContainerComponent', () => { describe('LayoutContainerComponent', () => {
let layoutContainerComponent: LayoutContainerComponent; let layoutContainerComponent: LayoutContainerComponent;
const setupComponent = (expandedSidenav: boolean, position: 'start' | 'end', direction: Direction) => {
layoutContainerComponent.expandedSidenav = expandedSidenav;
layoutContainerComponent.position = position;
layoutContainerComponent.direction = direction;
layoutContainerComponent.ngOnInit();
};
const checkContentAnimationState = (value: string, marginProperty: string, marginValue: number) => {
expect(layoutContainerComponent.contentAnimationState).toEqual({
value: value,
params: { [marginProperty]: marginValue }
});
};
const testDirectionChange = (position: 'start' | 'end', direction: Direction, marginProperty: string) => {
layoutContainerComponent.position = position;
layoutContainerComponent.direction = direction;
layoutContainerComponent.ngOnChanges({ direction: new SimpleChange('', '', false) });
expect(layoutContainerComponent.contentAnimationState.params[marginProperty]).not.toBeNull();
};
beforeEach(() => { beforeEach(() => {
layoutContainerComponent = new LayoutContainerComponent(); layoutContainerComponent = new LayoutContainerComponent();
layoutContainerComponent.sidenavMin = 70; layoutContainerComponent.sidenavMin = 70;
layoutContainerComponent.sidenavMax = 200; layoutContainerComponent.sidenavMax = 200;
layoutContainerComponent.mediaQueryList = { layoutContainerComponent.mediaQueryList = {
matches: false, matches: false,
addListener: () => {}, addListener: jasmine.createSpy('addListener').and.callFake((callback) => window.addEventListener('resize', callback)),
removeListener: () => {} removeListener: jasmine.createSpy('removeListener').and.callFake((callback) => window.removeEventListener('resize', callback))
}; };
layoutContainerComponent.sidenav = {
open: jasmine.createSpy('open'),
close: jasmine.createSpy('close'),
toggle: jasmine.createSpy('toggle')
} as unknown as MatSidenav;
}); });
describe('OnInit', () => { describe('OnInit', () => {
describe('Sidenav expanded', () => { it('should initialize sidenav and content states correctly', () => {
beforeEach(() => {
layoutContainerComponent.expandedSidenav = true; layoutContainerComponent.expandedSidenav = true;
layoutContainerComponent.ngOnInit();
expect(layoutContainerComponent.SIDENAV_STATES.MOBILE).toEqual({
value: 'expanded',
params: { width: layoutContainerComponent.sidenavMax }
}); });
expect(layoutContainerComponent.SIDENAV_STATES.EXPANDED).toEqual({
value: 'expanded',
params: { width: layoutContainerComponent.sidenavMax }
});
expect(layoutContainerComponent.SIDENAV_STATES.COMPACT).toEqual({
value: 'compact',
params: { width: layoutContainerComponent.sidenavMin }
});
expect(layoutContainerComponent.CONTENT_STATES.MOBILE).toEqual({ value: 'expanded' });
expect(layoutContainerComponent.mediaQueryList.addListener).toHaveBeenCalled();
});
describe('Sidenav expanded', () => {
beforeEach(() => (layoutContainerComponent.expandedSidenav = true));
describe('Sidenav [start] position', () => { describe('Sidenav [start] position', () => {
beforeEach(() => { beforeEach(() => (layoutContainerComponent.position = 'start'));
layoutContainerComponent.position = 'start';
});
it('should set `margin-left` equal to sidenavMax when direction is `ltr`', () => { it('should set `margin-left` equal to sidenavMax when direction is `ltr`', () => {
layoutContainerComponent.direction = 'ltr'; setupComponent(true, 'start', 'ltr');
layoutContainerComponent.ngOnInit(); checkContentAnimationState('compact', 'margin-left', layoutContainerComponent.sidenavMax);
expect(layoutContainerComponent.contentAnimationState).toEqual({
value: 'compact', params: { 'margin-left': layoutContainerComponent.sidenavMax}
});
}); });
it('should set `margin-right` equal to sidenavMax when direction is `rtl`', () => { it('should set `margin-right` equal to sidenavMax when direction is `rtl`', () => {
layoutContainerComponent.direction = 'rtl'; setupComponent(true, 'start', 'rtl');
layoutContainerComponent.ngOnInit(); checkContentAnimationState('compact', 'margin-right', layoutContainerComponent.sidenavMax);
expect(layoutContainerComponent.contentAnimationState).toEqual({
value: 'compact', params: { 'margin-right': layoutContainerComponent.sidenavMax}
});
}); });
}); });
describe('Sidenav [end] position', () => { describe('Sidenav [end] position', () => {
beforeEach(() => { beforeEach(() => (layoutContainerComponent.position = 'end'));
layoutContainerComponent.position = 'end';
});
it('should set `margin-right` equal to sidenavMax when direction is `ltr`', () => { it('should set `margin-right` equal to sidenavMax when direction is `ltr`', () => {
layoutContainerComponent.direction = 'ltr'; setupComponent(true, 'end', 'ltr');
layoutContainerComponent.ngOnInit(); checkContentAnimationState('compact', 'margin-right', layoutContainerComponent.sidenavMax);
expect(layoutContainerComponent.contentAnimationState).toEqual({
value: 'compact', params: { 'margin-right': layoutContainerComponent.sidenavMax}
});
}); });
it('should set `margin-left` equal to sidenavMax when direction is `rtl`', () => { it('should set `margin-left` equal to sidenavMax when direction is `rtl`', () => {
layoutContainerComponent.direction = 'rtl'; setupComponent(true, 'end', 'rtl');
layoutContainerComponent.ngOnInit(); checkContentAnimationState('compact', 'margin-left', layoutContainerComponent.sidenavMax);
expect(layoutContainerComponent.contentAnimationState).toEqual({
value: 'compact', params: { 'margin-left': layoutContainerComponent.sidenavMax}
});
}); });
}); });
}); });
describe('Sidenav compact', () => { describe('Sidenav compact', () => {
beforeEach(() => { beforeEach(() => (layoutContainerComponent.expandedSidenav = false));
layoutContainerComponent.expandedSidenav = false;
});
describe('Sidenav [start] position', () => { describe('Sidenav [start] position', () => {
beforeEach(() => { beforeEach(() => (layoutContainerComponent.position = 'start'));
layoutContainerComponent.position = 'start';
});
it('should set `margin-left` equal to sidenavMin when direction is `ltr`', () => { it('should set `margin-left` equal to sidenavMin when direction is `ltr`', () => {
layoutContainerComponent.direction = 'ltr'; setupComponent(false, 'start', 'ltr');
layoutContainerComponent.ngOnInit(); checkContentAnimationState('expanded', 'margin-left', layoutContainerComponent.sidenavMin);
expect(layoutContainerComponent.contentAnimationState).toEqual({
value: 'expanded', params: { 'margin-left': layoutContainerComponent.sidenavMin}
});
}); });
it('should set `margin-right` equal to sidenavMin when direction is `rtl`', () => { it('should set `margin-right` equal to sidenavMin when direction is `rtl`', () => {
layoutContainerComponent.direction = 'rtl'; setupComponent(false, 'start', 'rtl');
layoutContainerComponent.ngOnInit(); checkContentAnimationState('expanded', 'margin-right', layoutContainerComponent.sidenavMin);
expect(layoutContainerComponent.contentAnimationState).toEqual({
value: 'expanded', params: { 'margin-right': layoutContainerComponent.sidenavMin}
});
}); });
}); });
describe('Sidenav [end] position', () => { describe('Sidenav [end] position', () => {
beforeEach(() => { beforeEach(() => (layoutContainerComponent.position = 'end'));
layoutContainerComponent.position = 'end';
});
it('should set `margin-right` equal to sidenavMin when direction is `ltr`', () => { it('should set `margin-right` equal to sidenavMin when direction is `ltr`', () => {
layoutContainerComponent.direction = 'ltr'; setupComponent(false, 'end', 'ltr');
layoutContainerComponent.ngOnInit(); checkContentAnimationState('expanded', 'margin-right', layoutContainerComponent.sidenavMin);
expect(layoutContainerComponent.contentAnimationState).toEqual({
value: 'expanded', params: { 'margin-right': layoutContainerComponent.sidenavMin}
});
}); });
it('should set `margin-left` equal to sidenavMin when direction is `rtl`', () => { it('should set `margin-left` equal to sidenavMin when direction is `rtl`', () => {
layoutContainerComponent.direction = 'rtl'; setupComponent(false, 'end', 'rtl');
layoutContainerComponent.ngOnInit(); checkContentAnimationState('expanded', 'margin-left', layoutContainerComponent.sidenavMin);
expect(layoutContainerComponent.contentAnimationState).toEqual({
value: 'expanded', params: { 'margin-left': layoutContainerComponent.sidenavMin}
});
}); });
}); });
}); });
}); });
describe('OnChange direction', () => { describe('OnChange direction', () => {
describe('Sidenav [start] position', () => { it('should set `margin-left` for `start` position and `ltr` direction', () => {
beforeEach(() => { testDirectionChange('start', 'ltr', 'margin-left');
layoutContainerComponent.position = 'start';
}); });
it('should set `margin-left` when current direction is `ltr`', () => { it('should set `margin-right` for `start` position and `rtl` direction', () => {
layoutContainerComponent.direction = 'ltr'; testDirectionChange('start', 'rtl', 'margin-right');
layoutContainerComponent.ngOnChanges({ direction: new SimpleChange('', '', false) });
expect(layoutContainerComponent.contentAnimationState.params['margin-left']).not.toBeNull();
}); });
it('should set `margin-right` when current direction is `rtl`', () => { it('should set `margin-right` for `end` position and `ltr` direction', () => {
layoutContainerComponent.direction = 'rtl'; testDirectionChange('end', 'ltr', 'margin-right');
layoutContainerComponent.ngOnChanges({ direction: new SimpleChange('', '', false) });
expect(layoutContainerComponent.contentAnimationState.params['margin-right']).not.toBeNull();
});
}); });
describe('Sidenav [end] position', () => { it('should set `margin-left` for `end` position and `rtl` direction', () => {
beforeEach(() => { testDirectionChange('end', 'rtl', 'margin-left');
layoutContainerComponent.position = 'end';
});
it('should set `margin-right` when current direction is `ltr`', () => {
layoutContainerComponent.direction = 'ltr';
layoutContainerComponent.ngOnChanges({ direction: new SimpleChange('', '', false) });
expect(layoutContainerComponent.contentAnimationState.params['margin-right']).not.toBeNull();
});
it('should set `margin-left` when current direction is `rtl`', () => {
layoutContainerComponent.direction = 'rtl';
layoutContainerComponent.ngOnChanges({ direction: new SimpleChange('', '', false) });
expect(layoutContainerComponent.contentAnimationState.params['margin-left']).not.toBeNull();
});
}); });
}); });
@@ -188,23 +167,65 @@ describe('LayoutContainerComponent', () => {
it('should switch to sidenav to compact state', () => { it('should switch to sidenav to compact state', () => {
layoutContainerComponent.expandedSidenav = true; layoutContainerComponent.expandedSidenav = true;
layoutContainerComponent.ngOnInit(); layoutContainerComponent.ngOnInit();
layoutContainerComponent.toggleMenu(); layoutContainerComponent.toggleMenu();
expect(layoutContainerComponent.sidenavAnimationState).toEqual({ expect(layoutContainerComponent.sidenavAnimationState).toEqual({
value: 'compact', params: { width: layoutContainerComponent.sidenavMin } value: 'compact',
params: { width: layoutContainerComponent.sidenavMin }
}); });
}); });
it('should switch to sidenav to expanded state', () => { it('should switch to sidenav to expanded state', () => {
layoutContainerComponent.expandedSidenav = false; layoutContainerComponent.expandedSidenav = false;
layoutContainerComponent.ngOnInit(); layoutContainerComponent.ngOnInit();
layoutContainerComponent.toggleMenu(); layoutContainerComponent.toggleMenu();
expect(layoutContainerComponent.sidenavAnimationState).toEqual({ expect(layoutContainerComponent.sidenavAnimationState).toEqual({
value: 'expanded', params: { width: layoutContainerComponent.sidenavMax } value: 'expanded',
params: { width: layoutContainerComponent.sidenavMax }
}); });
}); });
}); });
describe('Media query change', () => {
const expandedState = {
value: 'expanded',
params: { width: 200 }
};
const expandedContentState = {
value: 'expanded'
};
const testMediaQueryChange = (matches: boolean, expectedSidenavState: any, expectedContentState: any) => {
layoutContainerComponent.ngOnInit();
layoutContainerComponent.mediaQueryList.matches = matches;
window.dispatchEvent(new Event('resize'));
expect(layoutContainerComponent.sidenavAnimationState).toEqual(expectedSidenavState);
expect(layoutContainerComponent.contentAnimationState).toEqual(expectedContentState);
};
it('should close sidenav on mobile and open on desktop', () => {
testMediaQueryChange(true, expandedState, expandedContentState);
layoutContainerComponent.mediaQueryList.matches = false;
window.dispatchEvent(new Event('resize'));
expect(layoutContainerComponent.sidenavAnimationState).toEqual(layoutContainerComponent.SIDENAV_STATES.EXPANDED);
expect(layoutContainerComponent.contentAnimationState).toEqual({
value: 'compact',
params: { 'margin-left': layoutContainerComponent.sidenavMax }
});
expect(layoutContainerComponent.sidenav.open).toHaveBeenCalled();
});
it('should keep sidenav compact when resized back to desktop and hideSidenav is true', () => {
layoutContainerComponent.hideSidenav = true;
testMediaQueryChange(true, expandedState, expandedContentState);
layoutContainerComponent.mediaQueryList.matches = false;
window.dispatchEvent(new Event('resize'));
expect(layoutContainerComponent.sidenavAnimationState).toEqual(layoutContainerComponent.SIDENAV_STATES.COMPACT);
expect(layoutContainerComponent.contentAnimationState).toEqual({
value: 'expanded',
params: { 'margin-left': layoutContainerComponent.sidenavMin }
});
expect(layoutContainerComponent.sidenav.open).not.toHaveBeenCalled();
});
});
}); });

View File

@@ -64,16 +64,7 @@ export class LayoutContainerComponent implements OnInit, OnDestroy, OnChanges {
this.mediaQueryList.addListener(this.onMediaQueryChange); this.mediaQueryList.addListener(this.onMediaQueryChange);
if (this.isMobileScreenSize) { this.updateSidenavState();
this.sidenavAnimationState = this.SIDENAV_STATES.MOBILE;
this.contentAnimationState = this.CONTENT_STATES.MOBILE;
} else if (this.expandedSidenav) {
this.sidenavAnimationState = this.SIDENAV_STATES.EXPANDED;
this.contentAnimationState = this.toggledContentAnimation;
} else {
this.sidenavAnimationState = this.SIDENAV_STATES.COMPACT;
this.contentAnimationState = this.toggledContentAnimation;
}
} }
ngOnDestroy(): void { ngOnDestroy(): void {
@@ -148,7 +139,22 @@ export class LayoutContainerComponent implements OnInit, OnDestroy, OnChanges {
} }
private onMediaQueryChange(): void { private onMediaQueryChange(): void {
this.updateSidenavState();
}
private updateSidenavState(): void {
if (this.isMobileScreenSize) {
this.sidenavAnimationState = this.SIDENAV_STATES.MOBILE;
this.contentAnimationState = this.CONTENT_STATES.MOBILE;
} else {
if (this.expandedSidenav && !this.hideSidenav) {
this.sidenavAnimationState = this.SIDENAV_STATES.EXPANDED; this.sidenavAnimationState = this.SIDENAV_STATES.EXPANDED;
this.contentAnimationState = this.toggledContentAnimation; this.contentAnimationState = this.toggledContentAnimation;
this.sidenav.open();
} else {
this.sidenavAnimationState = this.SIDENAV_STATES.COMPACT;
this.contentAnimationState = this.toggledContentAnimation;
}
}
} }
} }