mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-26 17:24:56 +00:00
ACS-7384: Break Layout dependency on Material Module (#9937)
This commit is contained in:
parent
dd03ae6617
commit
63fa673709
@ -17,7 +17,7 @@
|
||||
|
||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { TestBed, ComponentFixture } from '@angular/core/testing';
|
||||
import { AppConfigService, SidenavLayoutModule } from '@alfresco/adf-core';
|
||||
import { AppConfigService, LAYOUT_DIRECTIVES } from '@alfresco/adf-core';
|
||||
import { ShellLayoutComponent } from './shell.component';
|
||||
import { Router, NavigationStart, RouterModule } from '@angular/router';
|
||||
import { of, Subject } from 'rxjs';
|
||||
@ -62,7 +62,7 @@ describe('AppLayoutComponent', () => {
|
||||
CommonModule,
|
||||
NoopAnimationsModule,
|
||||
HttpClientModule,
|
||||
SidenavLayoutModule,
|
||||
...LAYOUT_DIRECTIVES,
|
||||
ExtensionsModule,
|
||||
RouterModule.forChild([]),
|
||||
TranslateModule.forRoot(),
|
||||
|
@ -75,4 +75,3 @@ The following CSS classes are available for theming:
|
||||
| `--adf-avatar-font-size` | `14px` | The font size of the initials. |
|
||||
| `--adf-avatar-font-weight` | `500` | The font weight of the initials. |
|
||||
| `--adf-avatar-cursor` | `auto` | The cursor style. |
|
||||
```
|
||||
|
@ -19,7 +19,6 @@ import { CommonModule } from '@angular/common';
|
||||
import { APP_INITIALIZER, NgModule, ModuleWithProviders } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { TranslateModule, TranslateLoader, TranslateStore, TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { MaterialModule } from './material.module';
|
||||
import { ABOUT_DIRECTIVES } from './about/about.module';
|
||||
import { CardViewModule } from './card-view/card-view.module';
|
||||
@ -32,7 +31,7 @@ import { PaginationModule } from './pagination/pagination.module';
|
||||
import { ToolbarModule } from './toolbar/toolbar.module';
|
||||
import { ViewerModule } from './viewer/viewer.module';
|
||||
import { FormBaseModule } from './form/form-base.module';
|
||||
import { SidenavLayoutModule } from './layout/layout.module';
|
||||
import { LAYOUT_DIRECTIVES } from './layout/layout.module';
|
||||
import { CommentsModule } from './comments/comments.module';
|
||||
import { CommentListModule } from './comments/comment-list/comment-list.module';
|
||||
import { TemplateModule } from './templates/template.module';
|
||||
@ -45,7 +44,6 @@ import { PipeModule } from './pipes/pipe.module';
|
||||
|
||||
import { TranslationService } from './translation/translation.service';
|
||||
import { SortingPickerModule } from './sorting-picker/sorting-picker.module';
|
||||
import { IconModule } from './icon/icon.module';
|
||||
import { TranslateLoaderService } from './translation/translate-loader.service';
|
||||
import { ExtensionsModule } from '@alfresco/adf-extensions';
|
||||
import { directionalityConfigFactory } from './common/services/directionality-config-factory';
|
||||
@ -67,6 +65,7 @@ import { AdfDateTimeFnsAdapter } from './common/utils/datetime-fns-adapter';
|
||||
import { AppConfigPipe, StoragePrefixFactory } from './app-config';
|
||||
import { UnsavedChangesDialogModule } from './dialogs';
|
||||
import { DynamicChipListModule } from './dynamic-chip-list';
|
||||
import { IconComponent } from './icon';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@ -74,7 +73,7 @@ import { DynamicChipListModule } from './dynamic-chip-list';
|
||||
ExtensionsModule,
|
||||
...ABOUT_DIRECTIVES,
|
||||
ViewerModule,
|
||||
SidenavLayoutModule,
|
||||
...LAYOUT_DIRECTIVES,
|
||||
PipeModule,
|
||||
CommonModule,
|
||||
IdentityUserInfoModule,
|
||||
@ -95,7 +94,7 @@ import { DynamicChipListModule } from './dynamic-chip-list';
|
||||
InfoDrawerModule,
|
||||
DataTableModule,
|
||||
TemplateModule,
|
||||
IconModule,
|
||||
IconComponent,
|
||||
SortingPickerModule,
|
||||
NotificationHistoryModule,
|
||||
SearchTextModule,
|
||||
@ -111,7 +110,7 @@ import { DynamicChipListModule } from './dynamic-chip-list';
|
||||
exports: [
|
||||
...ABOUT_DIRECTIVES,
|
||||
ViewerModule,
|
||||
SidenavLayoutModule,
|
||||
...LAYOUT_DIRECTIVES,
|
||||
PipeModule,
|
||||
CommonModule,
|
||||
DirectiveModule,
|
||||
@ -135,7 +134,7 @@ import { DynamicChipListModule } from './dynamic-chip-list';
|
||||
TranslateModule,
|
||||
TemplateModule,
|
||||
SortingPickerModule,
|
||||
IconModule,
|
||||
IconComponent,
|
||||
NotificationHistoryModule,
|
||||
SearchTextModule,
|
||||
BlankPageModule,
|
||||
|
@ -19,9 +19,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { HeaderLayoutComponent } from './header.component';
|
||||
import { CoreTestingModule } from '../../../testing/core.testing.module';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { SidenavLayoutModule } from '../../layout.module';
|
||||
import { Component } from '@angular/core';
|
||||
import { MaterialModule } from '../../../material.module';
|
||||
import { HarnessLoader } from '@angular/cdk/testing';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { MatToolbarHarness } from '@angular/material/toolbar/testing';
|
||||
@ -34,7 +32,7 @@ describe('HeaderLayoutComponent', () => {
|
||||
describe('Input parameters', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [CoreTestingModule]
|
||||
imports: [CoreTestingModule, HeaderLayoutComponent]
|
||||
});
|
||||
fixture = TestBed.createComponent(HeaderLayoutComponent);
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
@ -253,6 +251,8 @@ describe('HeaderLayoutComponent', () => {
|
||||
describe('Template transclusion', () => {
|
||||
@Component({
|
||||
selector: 'adf-test-layout-header',
|
||||
standalone: true,
|
||||
imports: [HeaderLayoutComponent],
|
||||
template: ` <adf-layout-header title="test" color="primary">
|
||||
<p>Test text</p>
|
||||
<p></p>
|
||||
@ -262,8 +262,7 @@ describe('HeaderLayoutComponent', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [CoreTestingModule, SidenavLayoutModule, MaterialModule],
|
||||
declarations: [HeaderLayoutTesterComponent]
|
||||
imports: [CoreTestingModule, HeaderLayoutTesterComponent]
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { applicationConfig, Meta, moduleMetadata, StoryFn } from '@storybook/angular';
|
||||
import { CoreStoryModule } from '../../../testing/core.story.module';
|
||||
import { SidenavLayoutModule } from '../../layout.module';
|
||||
import { LAYOUT_DIRECTIVES } from '../../layout.module';
|
||||
import { HeaderLayoutComponent } from './header.component';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { importProvidersFrom } from '@angular/core';
|
||||
@ -27,7 +27,7 @@ export default {
|
||||
title: 'Core/Layout/Header',
|
||||
decorators: [
|
||||
moduleMetadata({
|
||||
imports: [CoreStoryModule, SidenavLayoutModule, RouterTestingModule]
|
||||
imports: [CoreStoryModule, ...LAYOUT_DIRECTIVES, RouterTestingModule]
|
||||
}),
|
||||
applicationConfig({
|
||||
providers: [importProvidersFrom(CoreStoryModule)]
|
||||
@ -131,7 +131,7 @@ export default {
|
||||
}
|
||||
} as Meta<HeaderLayoutComponent>;
|
||||
|
||||
const template: StoryFn<SidenavLayoutModule> = (args) => ({
|
||||
const template: StoryFn<HeaderLayoutComponent> = (args) => ({
|
||||
props: args
|
||||
});
|
||||
|
||||
|
@ -18,9 +18,17 @@
|
||||
import { Component, Input, Output, EventEmitter, ViewEncapsulation, OnInit } from '@angular/core';
|
||||
import { ThemePalette } from '@angular/material/core';
|
||||
import { AppConfigService } from '../../../app-config/app-config.service';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-layout-header',
|
||||
standalone: true,
|
||||
imports: [CommonModule, MatToolbarModule, MatButtonModule, MatIconModule, RouterModule, TranslateModule],
|
||||
templateUrl: './header.component.html',
|
||||
styleUrls: ['./header.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
@ -69,10 +77,7 @@ export class HeaderLayoutComponent implements OnInit {
|
||||
/** The side of the page that the drawer is attached to (can be 'start' or 'end') */
|
||||
@Input() position = 'start';
|
||||
|
||||
constructor(
|
||||
private appConfigService: AppConfigService
|
||||
) {
|
||||
}
|
||||
constructor(private appConfigService: AppConfigService) {}
|
||||
|
||||
toggleMenu() {
|
||||
this.clicked.emit(true);
|
||||
|
@ -16,16 +16,44 @@
|
||||
*/
|
||||
|
||||
import { Component, Input, ViewChild, OnInit, OnDestroy, ViewEncapsulation, OnChanges, SimpleChanges } from '@angular/core';
|
||||
import { MatSidenav } from '@angular/material/sidenav';
|
||||
import { sidenavAnimation, contentAnimation } from '../../helpers/animations';
|
||||
import { MatSidenav, MatSidenavModule } from '@angular/material/sidenav';
|
||||
import { Direction } from '@angular/cdk/bidi';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { animate, state, style, transition, trigger } from '@angular/animations';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-layout-container',
|
||||
standalone: true,
|
||||
imports: [CommonModule, MatSidenavModule],
|
||||
templateUrl: './layout-container.component.html',
|
||||
styleUrls: ['./layout-container.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
animations: [sidenavAnimation, contentAnimation]
|
||||
animations: [
|
||||
trigger('sidenavAnimation', [
|
||||
state('expanded', style({ width: '{{ width }}px' }), { params: { width: 0 } }),
|
||||
state('compact', style({ width: '{{ width }}px' }), { params: { width: 0 } }),
|
||||
transition('compact <=> expanded', animate('0.4s cubic-bezier(0.25, 0.8, 0.25, 1)'))
|
||||
]),
|
||||
trigger('contentAnimationLeft', [
|
||||
state(
|
||||
'expanded',
|
||||
style({
|
||||
'margin-left': '{{ margin-left }}px',
|
||||
'margin-right': '{{ margin-right }}px'
|
||||
}),
|
||||
{ params: { 'margin-left': 0, 'margin-right': 0 } }
|
||||
),
|
||||
state(
|
||||
'compact',
|
||||
style({
|
||||
'margin-left': '{{ margin-left }}px',
|
||||
'margin-right': '{{ margin-right }}px'
|
||||
}),
|
||||
{ params: { 'margin-left': 0, 'margin-right': 0 } }
|
||||
),
|
||||
transition('expanded <=> compact', animate('400ms cubic-bezier(0.25, 0.8, 0.25, 1)'))
|
||||
])
|
||||
]
|
||||
})
|
||||
export class LayoutContainerComponent implements OnInit, OnDestroy, OnChanges {
|
||||
@Input() sidenavMin: number;
|
||||
@ -62,13 +90,13 @@ export class LayoutContainerComponent implements OnInit, OnDestroy, OnChanges {
|
||||
|
||||
this.CONTENT_STATES.MOBILE = { value: 'expanded' };
|
||||
|
||||
this.mediaQueryList.addListener(this.onMediaQueryChange);
|
||||
this.mediaQueryList?.addListener(this.onMediaQueryChange);
|
||||
|
||||
this.updateSidenavState();
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.mediaQueryList.removeListener(this.onMediaQueryChange);
|
||||
this.mediaQueryList?.removeListener(this.onMediaQueryChange);
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
@ -87,7 +115,7 @@ export class LayoutContainerComponent implements OnInit, OnDestroy, OnChanges {
|
||||
}
|
||||
|
||||
get isMobileScreenSize(): boolean {
|
||||
return this.mediaQueryList.matches;
|
||||
return !!this.mediaQueryList?.matches;
|
||||
}
|
||||
|
||||
getContentAnimationState(): any {
|
||||
|
@ -17,10 +17,11 @@
|
||||
|
||||
import { Component } from '@angular/core';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { MaterialModule } from '../../../material.module';
|
||||
import { SidebarActionMenuComponent } from './sidebar-action-menu.component';
|
||||
import { CoreTestingModule } from '../../../testing/core.testing.module';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
|
||||
describe('SidebarActionMenuComponent', () => {
|
||||
let element: HTMLElement;
|
||||
@ -29,7 +30,7 @@ describe('SidebarActionMenuComponent', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [CoreTestingModule]
|
||||
imports: [CoreTestingModule, SidebarActionMenuComponent]
|
||||
});
|
||||
fixture = TestBed.createComponent(SidebarActionMenuComponent);
|
||||
element = fixture.nativeElement;
|
||||
@ -51,6 +52,8 @@ describe('SidebarActionMenuComponent', () => {
|
||||
});
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
imports: [CommonModule, SidebarActionMenuComponent, MatIconModule, MatMenuModule],
|
||||
template: `
|
||||
<adf-sidebar-action-menu [expanded]="expanded" [title]="title">
|
||||
<mat-icon adf-sidebar-menu-title-icon>arrow_drop_down</mat-icon>
|
||||
@ -82,8 +85,7 @@ describe('Custom SidebarActionMenuComponent', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [SidebarActionMenuComponent, CustomSidebarActionMenuComponent],
|
||||
imports: [MaterialModule, NoopAnimationsModule]
|
||||
imports: [CoreTestingModule, SidebarActionMenuComponent, CustomSidebarActionMenuComponent]
|
||||
});
|
||||
fixture = TestBed.createComponent(CustomSidebarActionMenuComponent);
|
||||
fixture.detectChanges();
|
||||
|
@ -16,18 +16,21 @@
|
||||
*/
|
||||
|
||||
import { ChangeDetectionStrategy, Component, Directive, Input, ViewEncapsulation } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-sidebar-action-menu',
|
||||
standalone: true,
|
||||
imports: [CommonModule, MatButtonModule, MatMenuModule],
|
||||
templateUrl: './sidebar-action-menu.component.html',
|
||||
styleUrls: ['./sidebar-action-menu.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
host: { class: 'adf-sidebar-action-menu' }
|
||||
})
|
||||
|
||||
export class SidebarActionMenuComponent {
|
||||
|
||||
/** The title of the sidebar action. */
|
||||
@Input()
|
||||
title: string;
|
||||
@ -48,6 +51,20 @@ export class SidebarActionMenuComponent {
|
||||
/**
|
||||
* Directive selectors without adf- prefix will be deprecated on 3.0.0
|
||||
*/
|
||||
@Directive({ selector: '[adf-sidebar-menu-options], [sidebar-menu-options]' }) export class SidebarMenuDirective {}
|
||||
@Directive({ selector: '[adf-sidebar-menu-title-icon], [sidebar-menu-title-icon]' }) export class SidebarMenuTitleIconDirective {}
|
||||
@Directive({ selector: '[adf-sidebar-menu-expand-icon], [sidebar-menu-expand-icon]' }) export class SidebarMenuExpandIconDirective {}
|
||||
@Directive({
|
||||
selector: '[adf-sidebar-menu-options], [sidebar-menu-options]',
|
||||
standalone: true
|
||||
})
|
||||
export class SidebarMenuDirective {}
|
||||
|
||||
@Directive({
|
||||
selector: '[adf-sidebar-menu-title-icon], [sidebar-menu-title-icon]',
|
||||
standalone: true
|
||||
})
|
||||
export class SidebarMenuTitleIconDirective {}
|
||||
|
||||
@Directive({
|
||||
selector: '[adf-sidebar-menu-expand-icon], [sidebar-menu-expand-icon]',
|
||||
standalone: true
|
||||
})
|
||||
export class SidebarMenuExpandIconDirective {}
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { applicationConfig, Meta, moduleMetadata, StoryFn } from '@storybook/angular';
|
||||
import { CoreStoryModule } from '../../../testing/core.story.module';
|
||||
import { SidenavLayoutModule } from '../../layout.module';
|
||||
import { LAYOUT_DIRECTIVES } from '../../layout.module';
|
||||
import { SidebarActionMenuComponent } from './sidebar-action-menu.component';
|
||||
import { importProvidersFrom } from '@angular/core';
|
||||
|
||||
@ -26,7 +26,7 @@ export default {
|
||||
title: 'Core/Layout/Sidebar Action Menu',
|
||||
decorators: [
|
||||
moduleMetadata({
|
||||
imports: [CoreStoryModule, SidenavLayoutModule]
|
||||
imports: [CoreStoryModule, ...LAYOUT_DIRECTIVES]
|
||||
}),
|
||||
applicationConfig({
|
||||
providers: [importProvidersFrom(CoreStoryModule)]
|
||||
@ -71,7 +71,7 @@ export default {
|
||||
}
|
||||
} as Meta<SidebarActionMenuComponent>;
|
||||
|
||||
const template: StoryFn<SidenavLayoutModule> = (args) => ({
|
||||
const template: StoryFn<SidebarActionMenuComponent> = (args) => ({
|
||||
props: args
|
||||
});
|
||||
|
||||
|
@ -18,40 +18,24 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { SidenavLayoutComponent } from './sidenav-layout.component';
|
||||
import { Component, CUSTOM_ELEMENTS_SCHEMA, Input } from '@angular/core';
|
||||
import { LayoutModule, MediaMatcher } from '@angular/cdk/layout';
|
||||
import { PlatformModule } from '@angular/cdk/platform';
|
||||
import { MaterialModule } from '../../../material.module';
|
||||
import { Component } from '@angular/core';
|
||||
import { MediaMatcher } from '@angular/cdk/layout';
|
||||
import { SidenavLayoutContentDirective } from '../../directives/sidenav-layout-content.directive';
|
||||
import { SidenavLayoutHeaderDirective } from '../../directives/sidenav-layout-header.directive';
|
||||
import { SidenavLayoutNavigationDirective } from '../../directives/sidenav-layout-navigation.directive';
|
||||
import { UserPreferencesService } from '../../../common/services/user-preferences.service';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Direction } from '@angular/cdk/bidi';
|
||||
import { of } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-layout-container',
|
||||
template: ` <ng-content select="[app-layout-navigation]"></ng-content>
|
||||
<ng-content select="[app-layout-content]"></ng-content>`
|
||||
})
|
||||
export class DummyLayoutContainerComponent {
|
||||
@Input() sidenavMin: number;
|
||||
@Input() sidenavMax: number;
|
||||
@Input() position: string;
|
||||
@Input() direction: Direction;
|
||||
@Input() mediaQueryList: MediaQueryList;
|
||||
@Input() hideSidenav: boolean;
|
||||
@Input() expandedSidenav: boolean;
|
||||
toggleMenu() {}
|
||||
}
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-test-component-for-sidenav',
|
||||
standalone: true,
|
||||
imports: [SidenavLayoutComponent, SidenavLayoutHeaderDirective, SidenavLayoutNavigationDirective, SidenavLayoutContentDirective],
|
||||
template: ` <adf-sidenav-layout [sidenavMin]="70" [sidenavMax]="320" [stepOver]="600" [hideSidenav]="false">
|
||||
<adf-sidenav-layout-header>
|
||||
<ng-template let-toggleMenu="toggleMenu">
|
||||
<div role="button" id="header-test" (click)="toggleMenu()" role="button" tabindex="0" (keyup.enter)="toggleMenu()"></div>
|
||||
<div id="header-test" (click)="toggleMenu()" role="button" tabindex="0" (keyup.enter)="toggleMenu()"></div>
|
||||
</ng-template>
|
||||
</adf-sidenav-layout-header>
|
||||
|
||||
@ -72,22 +56,14 @@ export class SidenavLayoutTesterComponent {}
|
||||
|
||||
describe('SidenavLayoutComponent', () => {
|
||||
let fixture: ComponentFixture<any>;
|
||||
let mediaMatcher: MediaMatcher;
|
||||
let mediaQueryList: any;
|
||||
let component: SidenavLayoutComponent;
|
||||
let mediaMatcher: MediaMatcher;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [CommonModule, PlatformModule, LayoutModule, MaterialModule],
|
||||
declarations: [
|
||||
DummyLayoutContainerComponent,
|
||||
SidenavLayoutComponent,
|
||||
SidenavLayoutContentDirective,
|
||||
SidenavLayoutHeaderDirective,
|
||||
SidenavLayoutNavigationDirective
|
||||
],
|
||||
providers: [MediaMatcher, { provide: UserPreferencesService, useValue: { select: () => of() } }],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
imports: [CommonModule, NoopAnimationsModule, SidenavLayoutComponent],
|
||||
providers: [MediaMatcher, { provide: UserPreferencesService, useValue: { select: () => of() } }]
|
||||
});
|
||||
mediaQueryList = {
|
||||
mediaFn: null,
|
||||
@ -99,12 +75,7 @@ describe('SidenavLayoutComponent', () => {
|
||||
};
|
||||
|
||||
mediaMatcher = TestBed.inject(MediaMatcher);
|
||||
spyOn(mediaMatcher, 'matchMedia').and.callFake((mediaQuery) => {
|
||||
mediaQueryList.originalMediaQueryPassed = mediaQuery;
|
||||
spyOn(mediaQueryList, 'addListener').and.callThrough();
|
||||
spyOn(mediaQueryList, 'removeListener').and.stub();
|
||||
return mediaQueryList;
|
||||
});
|
||||
spyOn(mediaMatcher, 'matchMedia').and.callFake(() => mediaQueryList);
|
||||
|
||||
fixture = TestBed.createComponent(SidenavLayoutComponent);
|
||||
component = fixture.componentInstance;
|
||||
@ -115,40 +86,10 @@ describe('SidenavLayoutComponent', () => {
|
||||
TestBed.resetTestingModule();
|
||||
});
|
||||
|
||||
describe('General behaviour', () => {
|
||||
beforeEach(() => fixture.detectChanges());
|
||||
|
||||
it('should pass through input parameters', () => {
|
||||
component.sidenavMin = 1;
|
||||
component.sidenavMax = 2;
|
||||
component.hideSidenav = true;
|
||||
component.expandedSidenav = false;
|
||||
fixture.detectChanges();
|
||||
|
||||
const layoutContainerComponent = fixture.debugElement.query(By.directive(DummyLayoutContainerComponent)).componentInstance;
|
||||
|
||||
expect(layoutContainerComponent.sidenavMin).toBe(component.sidenavMin);
|
||||
expect(layoutContainerComponent.sidenavMax).toBe(component.sidenavMax);
|
||||
expect(layoutContainerComponent.hideSidenav).toBe(component.hideSidenav);
|
||||
expect(layoutContainerComponent.expandedSidenav).toBe(component.expandedSidenav);
|
||||
expect(layoutContainerComponent.mediaQueryList.originalMediaQueryPassed).toBe(`(max-width: 600px)`);
|
||||
});
|
||||
|
||||
it('addListener of mediaQueryList should have been called', () => {
|
||||
expect(mediaQueryList.addListener).toHaveBeenCalledTimes(1);
|
||||
expect(mediaQueryList.addListener).toHaveBeenCalledWith(component.onMediaQueryChange);
|
||||
});
|
||||
|
||||
it('addListener of mediaQueryList should have been called', () => {
|
||||
fixture.destroy();
|
||||
|
||||
expect(mediaQueryList.removeListener).toHaveBeenCalledTimes(1);
|
||||
expect(mediaQueryList.removeListener).toHaveBeenCalledWith(component.onMediaQueryChange);
|
||||
});
|
||||
});
|
||||
|
||||
describe('toggleMenu', () => {
|
||||
beforeEach(() => fixture.detectChanges());
|
||||
beforeEach(() => {
|
||||
component.ngOnInit();
|
||||
});
|
||||
|
||||
it('should toggle the isMenuMinimized if the mediaQueryList.matches is false (we are on desktop)', () => {
|
||||
mediaQueryList.matches = false;
|
||||
@ -178,7 +119,7 @@ describe('SidenavLayoutComponent', () => {
|
||||
|
||||
describe('menuOpenState', () => {
|
||||
it('should be true by default', (done) => {
|
||||
fixture.detectChanges();
|
||||
component.ngOnInit();
|
||||
|
||||
component.menuOpenState$.subscribe((value) => {
|
||||
expect(value).toBe(true);
|
||||
@ -188,7 +129,7 @@ describe('SidenavLayoutComponent', () => {
|
||||
|
||||
it('should be the same as the expanded Sidenav value by default', (done) => {
|
||||
component.expandedSidenav = false;
|
||||
fixture.detectChanges();
|
||||
component.ngOnInit();
|
||||
|
||||
component.menuOpenState$.subscribe((value) => {
|
||||
expect(value).toBe(false);
|
||||
@ -198,8 +139,8 @@ describe('SidenavLayoutComponent', () => {
|
||||
|
||||
it('should emit value on toggleMenu action', (done) => {
|
||||
component.expandedSidenav = false;
|
||||
fixture.detectChanges();
|
||||
|
||||
component.ngOnInit();
|
||||
component.toggleMenu();
|
||||
|
||||
component.menuOpenState$.subscribe((value) => {
|
||||
@ -213,31 +154,22 @@ describe('SidenavLayoutComponent', () => {
|
||||
describe('Template transclusion', () => {
|
||||
let fixture: ComponentFixture<any>;
|
||||
let mediaMatcher: MediaMatcher;
|
||||
const mediaQueryList: any = {
|
||||
matches: false,
|
||||
addListener: () => {},
|
||||
removeListener: () => {}
|
||||
};
|
||||
let mediaQueryList: any;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [CommonModule, PlatformModule, LayoutModule, MaterialModule],
|
||||
declarations: [
|
||||
DummyLayoutContainerComponent,
|
||||
SidenavLayoutTesterComponent,
|
||||
SidenavLayoutComponent,
|
||||
SidenavLayoutContentDirective,
|
||||
SidenavLayoutHeaderDirective,
|
||||
SidenavLayoutNavigationDirective
|
||||
],
|
||||
imports: [CommonModule, NoopAnimationsModule, SidenavLayoutTesterComponent],
|
||||
providers: [MediaMatcher, { provide: UserPreferencesService, useValue: { select: () => of() } }]
|
||||
});
|
||||
|
||||
mediaQueryList = {
|
||||
matches: false,
|
||||
addListener: () => {},
|
||||
removeListener: () => {}
|
||||
};
|
||||
|
||||
mediaMatcher = TestBed.inject(MediaMatcher);
|
||||
spyOn(mediaMatcher, 'matchMedia').and.callFake(() => {
|
||||
spyOn(mediaQueryList, 'addListener').and.stub();
|
||||
spyOn(mediaQueryList, 'removeListener').and.stub();
|
||||
return mediaQueryList;
|
||||
});
|
||||
spyOn(mediaMatcher, 'matchMedia').and.callFake(() => mediaQueryList);
|
||||
|
||||
fixture = TestBed.createComponent(SidenavLayoutTesterComponent);
|
||||
fixture.detectChanges();
|
||||
@ -267,32 +199,17 @@ describe('Template transclusion', () => {
|
||||
mediaQueryList.matches = false;
|
||||
fixture.detectChanges();
|
||||
const outerHeaderElement = fixture.debugElement.query(outerHeaderSelector);
|
||||
const innerHeaderElement = fixture.debugElement.query(innerHeaderSelector);
|
||||
|
||||
expect(outerHeaderElement === null).toBe(false, 'Outer header should be shown');
|
||||
expect(innerHeaderElement === null).toBe(true, 'Inner header should not be shown');
|
||||
expect(outerHeaderElement).toBeDefined();
|
||||
});
|
||||
|
||||
it('should contain the transcluded header template inside of the layout-container', () => {
|
||||
mediaQueryList.matches = true;
|
||||
|
||||
fixture.detectChanges();
|
||||
const outerHeaderElement = fixture.debugElement.query(outerHeaderSelector);
|
||||
const innerHeaderElement = fixture.debugElement.query(innerHeaderSelector);
|
||||
|
||||
expect(outerHeaderElement === null).toBe(true, 'Outer header should not be shown');
|
||||
expect(innerHeaderElement === null).toBe(false, 'Inner header should be shown');
|
||||
});
|
||||
|
||||
it(`should call through the layout container's toggleMenu method`, () => {
|
||||
mediaQueryList.matches = false;
|
||||
fixture.detectChanges();
|
||||
const layoutContainerComponent = fixture.debugElement.query(By.directive(DummyLayoutContainerComponent)).componentInstance;
|
||||
spyOn(layoutContainerComponent, 'toggleMenu');
|
||||
|
||||
const outerHeaderElement = fixture.debugElement.query(outerHeaderSelector);
|
||||
outerHeaderElement.triggerEventHandler('click', {});
|
||||
|
||||
expect(layoutContainerComponent.toggleMenu).toHaveBeenCalled();
|
||||
expect(innerHeaderElement).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { applicationConfig, Meta, moduleMetadata, StoryFn } from '@storybook/angular';
|
||||
import { CoreStoryModule } from '../../../testing/core.story.module';
|
||||
import { SidenavLayoutModule } from '../../layout.module';
|
||||
import { LAYOUT_DIRECTIVES } from '../../layout.module';
|
||||
import { SidenavLayoutComponent } from './sidenav-layout.component';
|
||||
import { MatListModule } from '@angular/material/list';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
@ -29,7 +29,7 @@ export default {
|
||||
title: 'Core/Layout/Sidenav Layout',
|
||||
decorators: [
|
||||
moduleMetadata({
|
||||
imports: [SidenavLayoutModule, RouterTestingModule, MatIconModule, MatListModule]
|
||||
imports: [CoreStoryModule, ...LAYOUT_DIRECTIVES, RouterTestingModule, MatIconModule, MatListModule]
|
||||
}),
|
||||
applicationConfig({
|
||||
providers: [importProvidersFrom(CoreStoryModule)]
|
||||
@ -136,7 +136,7 @@ export default {
|
||||
}
|
||||
} as Meta<SidenavLayoutComponent>;
|
||||
|
||||
const template: StoryFn<SidenavLayoutModule> = (args) => ({
|
||||
const template: StoryFn<SidenavLayoutComponent> = (args) => ({
|
||||
props: args,
|
||||
template: `
|
||||
<adf-sidenav-layout
|
||||
|
@ -33,12 +33,16 @@ import { UserPreferencesService } from '../../../common/services/user-preference
|
||||
import { SidenavLayoutContentDirective } from '../../directives/sidenav-layout-content.directive';
|
||||
import { SidenavLayoutHeaderDirective } from '../../directives/sidenav-layout-header.directive';
|
||||
import { SidenavLayoutNavigationDirective } from '../../directives/sidenav-layout-navigation.directive';
|
||||
import { BehaviorSubject, Observable, Subject } from 'rxjs';
|
||||
import { BehaviorSubject, Subject } from 'rxjs';
|
||||
import { Direction } from '@angular/cdk/bidi';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { LayoutContainerComponent } from '../layout-container/layout-container.component';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-sidenav-layout',
|
||||
standalone: true,
|
||||
imports: [CommonModule, LayoutContainerComponent],
|
||||
templateUrl: './sidenav-layout.component.html',
|
||||
styleUrls: ['./sidenav-layout.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
@ -80,8 +84,8 @@ export class SidenavLayoutComponent implements OnInit, AfterViewInit, OnDestroy
|
||||
@ContentChild(SidenavLayoutContentDirective)
|
||||
contentDirective: SidenavLayoutContentDirective;
|
||||
|
||||
private menuOpenStateSubject: BehaviorSubject<boolean>;
|
||||
public menuOpenState$: Observable<boolean>;
|
||||
private menuOpenStateSubject = new BehaviorSubject<boolean>(false);
|
||||
public menuOpenState$ = this.menuOpenStateSubject.asObservable();
|
||||
|
||||
@ViewChild('container', { static: true }) container: any;
|
||||
@ViewChild('emptyTemplate', { static: true }) emptyTemplate: any;
|
||||
@ -96,16 +100,13 @@ export class SidenavLayoutComponent implements OnInit, AfterViewInit, OnDestroy
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
constructor(private mediaMatcher: MediaMatcher, private userPreferencesService: UserPreferencesService ) {
|
||||
constructor(private mediaMatcher: MediaMatcher, private userPreferencesService: UserPreferencesService) {
|
||||
this.onMediaQueryChange = this.onMediaQueryChange.bind(this);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
const initialMenuState = !this.expandedSidenav;
|
||||
|
||||
this.menuOpenStateSubject = new BehaviorSubject<boolean>(initialMenuState);
|
||||
this.menuOpenState$ = this.menuOpenStateSubject.asObservable();
|
||||
|
||||
const stepOver = this.stepOver || SidenavLayoutComponent.STEP_OVER;
|
||||
this.isMenuMinimized = initialMenuState;
|
||||
|
||||
|
@ -18,7 +18,8 @@
|
||||
import { ContentChild, Directive, TemplateRef } from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: 'adf-sidenav-layout-content'
|
||||
selector: 'adf-sidenav-layout-content',
|
||||
standalone: true
|
||||
})
|
||||
export class SidenavLayoutContentDirective {
|
||||
@ContentChild(TemplateRef)
|
||||
|
@ -18,7 +18,8 @@
|
||||
import { ContentChild, Directive, TemplateRef } from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: 'adf-sidenav-layout-header'
|
||||
selector: 'adf-sidenav-layout-header',
|
||||
standalone: true
|
||||
})
|
||||
export class SidenavLayoutHeaderDirective {
|
||||
@ContentChild(TemplateRef)
|
||||
|
@ -18,7 +18,8 @@
|
||||
import { ContentChild, Directive, TemplateRef } from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: 'adf-sidenav-layout-navigation'
|
||||
selector: 'adf-sidenav-layout-navigation',
|
||||
standalone: true
|
||||
})
|
||||
export class SidenavLayoutNavigationDirective {
|
||||
@ContentChild(TemplateRef)
|
||||
|
@ -1,36 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { trigger, transition, animate, style, state, AnimationTriggerMetadata } from '@angular/animations';
|
||||
|
||||
export const sidenavAnimation: AnimationTriggerMetadata = trigger('sidenavAnimation', [
|
||||
state('expanded', style({ width: '{{ width }}px' }), { params : { width: 0 } }),
|
||||
state('compact', style({ width: '{{ width }}px' }), { params : { width: 0 } }),
|
||||
transition('compact <=> expanded', animate('0.4s cubic-bezier(0.25, 0.8, 0.25, 1)'))
|
||||
]);
|
||||
|
||||
export const contentAnimation: AnimationTriggerMetadata = trigger('contentAnimationLeft', [
|
||||
state('expanded', style({
|
||||
'margin-left': '{{ margin-left }}px',
|
||||
'margin-right': '{{ margin-right }}px'
|
||||
}), { params: { 'margin-left': 0, 'margin-right': 0 } }),
|
||||
state('compact', style({
|
||||
'margin-left': '{{ margin-left }}px',
|
||||
'margin-right': '{{ margin-right }}px'
|
||||
}), { params: { 'margin-left': 0, 'margin-right': 0 } }),
|
||||
transition('expanded <=> compact', animate('400ms cubic-bezier(0.25, 0.8, 0.25, 1)'))
|
||||
]);
|
@ -15,49 +15,36 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { MaterialModule } from '../material.module';
|
||||
import { SidenavLayoutContentDirective } from './directives/sidenav-layout-content.directive';
|
||||
import { SidenavLayoutHeaderDirective } from './directives/sidenav-layout-header.directive';
|
||||
import { SidenavLayoutNavigationDirective } from './directives/sidenav-layout-navigation.directive';
|
||||
import { SidenavLayoutComponent } from './components/sidenav-layout/sidenav-layout.component';
|
||||
import { LayoutContainerComponent } from './components/layout-container/layout-container.component';
|
||||
import { SidebarActionMenuComponent, SidebarMenuDirective,
|
||||
SidebarMenuExpandIconDirective, SidebarMenuTitleIconDirective } from './components/sidebar-action/sidebar-action-menu.component';
|
||||
import {
|
||||
SidebarActionMenuComponent,
|
||||
SidebarMenuDirective,
|
||||
SidebarMenuExpandIconDirective,
|
||||
SidebarMenuTitleIconDirective
|
||||
} from './components/sidebar-action/sidebar-action-menu.component';
|
||||
import { HeaderLayoutComponent } from './components/header/header.component';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
export const LAYOUT_DIRECTIVES = [
|
||||
SidenavLayoutHeaderDirective,
|
||||
SidenavLayoutContentDirective,
|
||||
SidenavLayoutNavigationDirective,
|
||||
SidebarMenuDirective,
|
||||
SidebarMenuExpandIconDirective,
|
||||
SidebarMenuTitleIconDirective,
|
||||
HeaderLayoutComponent,
|
||||
SidebarActionMenuComponent,
|
||||
LayoutContainerComponent,
|
||||
SidenavLayoutComponent
|
||||
] as const;
|
||||
|
||||
/** @deprecated Use `...LAYOUT_DIRECTIVES` instead, or import standalone components directly */
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
MaterialModule,
|
||||
RouterModule,
|
||||
TranslateModule
|
||||
],
|
||||
exports: [
|
||||
SidenavLayoutHeaderDirective,
|
||||
SidenavLayoutContentDirective,
|
||||
SidenavLayoutNavigationDirective,
|
||||
SidenavLayoutComponent,
|
||||
LayoutContainerComponent,
|
||||
SidebarActionMenuComponent,
|
||||
SidebarMenuDirective,
|
||||
SidebarMenuExpandIconDirective,
|
||||
SidebarMenuTitleIconDirective,
|
||||
HeaderLayoutComponent
|
||||
],
|
||||
declarations: [
|
||||
SidenavLayoutHeaderDirective,
|
||||
SidenavLayoutContentDirective,
|
||||
SidenavLayoutNavigationDirective,
|
||||
SidenavLayoutComponent,
|
||||
LayoutContainerComponent,
|
||||
SidebarActionMenuComponent,
|
||||
SidebarMenuDirective,
|
||||
SidebarMenuExpandIconDirective,
|
||||
SidebarMenuTitleIconDirective,
|
||||
HeaderLayoutComponent
|
||||
]
|
||||
imports: [...LAYOUT_DIRECTIVES],
|
||||
exports: [...LAYOUT_DIRECTIVES]
|
||||
})
|
||||
export class SidenavLayoutModule {}
|
||||
|
@ -44,6 +44,7 @@ import { MatTabsModule } from '@angular/material/tabs';
|
||||
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||
import { MatBadgeModule } from '@angular/material/badge';
|
||||
|
||||
/** @deprecated This module is deprecated and will be removed in a future release. */
|
||||
@NgModule({
|
||||
imports: [
|
||||
MatAutocompleteModule,
|
||||
|
Loading…
x
Reference in New Issue
Block a user