Skip to content

Commit

Permalink
feat(nav): nav support responsive (#1273)
Browse files Browse the repository at this point in the history
* feat(nav): nav support responsive

* test(nav): add test about responsive

* fix(nav): fix generate import relative path when extends mixin class

* feat(nav): nav support responsive
  • Loading branch information
luxiaobei authored Jul 12, 2021
1 parent 8bfa5fb commit 4af8f26
Show file tree
Hide file tree
Showing 11 changed files with 719 additions and 111 deletions.
8 changes: 6 additions & 2 deletions src/nav/examples/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ import { NgxTethysModule } from 'ngx-tethys';
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';

import { ThyNavFillExampleComponent } from './fill/fill.component';
import { ThyNavHorizontalExampleComponent } from './horizontal/horizontal.component';
import { ThyNavIconNavExampleComponent } from './icon-nav/icon-nav.component';
import { ThyNavResponsiveExampleComponent } from './responsive/responsive.component';
import { ThyNavTypeExampleComponent } from './type/type.component';
import { ThyNavVerticalExampleComponent } from './vertical/vertical.component';

Expand All @@ -14,13 +17,14 @@ const COMPONENTS = [
ThyNavHorizontalExampleComponent,
ThyNavIconNavExampleComponent,
ThyNavTypeExampleComponent,
ThyNavVerticalExampleComponent
ThyNavVerticalExampleComponent,
ThyNavResponsiveExampleComponent
];

@NgModule({
declarations: COMPONENTS,
entryComponents: COMPONENTS,
imports: [CommonModule, FormsModule, NgxTethysModule],
imports: [CommonModule, FormsModule, NgxTethysModule, RouterModule],
exports: [],
providers: COMPONENTS
})
Expand Down
4 changes: 4 additions & 0 deletions src/nav/examples/responsive/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
order: 50
title: 响应式
---
20 changes: 20 additions & 0 deletions src/nav/examples/responsive/responsive.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<thy-nav thyType="primary" [thyResponsive]="true">
<a href="javascript:;" thyNavLink [thyNavLinkActive]="activeIndex == 1" (click)="activeIndex = 1">导航一</a>
<a href="javascript:;" thyNavLink [thyNavLinkActive]="activeIndex == 2" (click)="activeIndex = 2">导航二</a>
<a href="javascript:;" thyNavLink [thyNavLinkActive]="activeIndex == 3" (click)="activeIndex = 3">导航三</a>
<a href="javascript:;" thyNavLink [thyNavLinkActive]="activeIndex == 4" (click)="activeIndex = 4">导航四</a>
<a href="javascript:;" thyNavLink [thyNavLinkActive]="activeIndex == 5" (click)="activeIndex = 5">导航五</a>
<a href="javascript:;" thyNavLink [thyNavLinkActive]="activeIndex == 6" (click)="activeIndex = 6">导航六</a>
<a href="javascript:;" thyNavLink [thyNavLinkActive]="activeIndex == 7" (click)="activeIndex = 7">导航七</a>
<a href="javascript:;" thyNavLink [thyNavLinkActive]="activeIndex == 8" (click)="activeIndex = 8">导航八</a>
<a href="javascript:;" thyNavLink [thyNavLinkActive]="activeIndex == 9" (click)="activeIndex = 9">导航九</a>

<a href="javascript:;" thyNavLink [thyNavLinkActive]="activeIndex == 10" (click)="activeIndex = 10">导航十</a>

<a href="javascript:;" thyNavLink [thyNavLinkActive]="activeIndex == 11" (click)="activeIndex = 11">导航十一</a>

<a href="javascript:;" thyNavLink [thyNavLinkActive]="activeIndex == 12" (click)="activeIndex = 12">导航十二</a>
<a href="javascript:;" thyNavLink [thyNavLinkActive]="activeIndex == 13" (click)="select(13)">导航十三</a>

<a href="javascript:;" thyNavLink [routerLink]="['../api']" routerLinkActive="active" (click)="activeIndex = 14"><div>导航十四</div></a>
</thy-nav>
17 changes: 17 additions & 0 deletions src/nav/examples/responsive/responsive.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Component, OnInit } from '@angular/core';

@Component({
selector: 'thy-nav-responsive-example',
templateUrl: './responsive.component.html'
})
export class ThyNavResponsiveExampleComponent implements OnInit {
activeIndex = 13;

constructor() {}

ngOnInit(): void {}

select(value: number) {
this.activeIndex = value;
}
}
101 changes: 93 additions & 8 deletions src/nav/nav-link.directive.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,105 @@
import { Component, Directive, ElementRef, Renderer2, Input, HostBinding } from '@angular/core';
import { coerceBooleanProperty } from 'ngx-tethys/util';
import { Constructor, InputBoolean, MixinBase, mixinUnsubscribe, ThyUnsubscribe } from 'ngx-tethys/core';
import { takeUntil } from 'rxjs/operators';

import {
AfterViewInit,
ContentChildren,
Directive,
ElementRef,
HostBinding,
Input,
NgZone,
OnDestroy,
Optional,
QueryList,
Renderer2
} from '@angular/core';
import { RouterLinkActive } from '@angular/router';

export type ThyNavLink = '' | 'active';

const _MixinBase: Constructor<ThyUnsubscribe> & typeof MixinBase = mixinUnsubscribe(MixinBase);

@Directive({
selector: '[thyNavLink]'
})
export class ThyNavLinkDirective {
export class ThyNavLinkDirective extends _MixinBase implements AfterViewInit, OnDestroy {
@HostBinding('class.active')
@Input()
set thyNavLinkActive(active: string) {
this.navLinkActive = coerceBooleanProperty(active);
}

@HostBinding('class.active') navLinkActive = false;
@InputBoolean()
thyNavLinkActive: boolean;

@HostBinding('class.nav-link') navLinkClass = true;

@ContentChildren(ThyNavLinkDirective, { descendants: true }) links: QueryList<ThyNavLinkDirective>;

@ContentChildren(RouterLinkActive, { descendants: true }) routers: QueryList<RouterLinkActive>;

// @HostBinding('attr.href') navLinkHref = 'javascript:;';

public offset: {
width: number;
height: number;
left: number;
top: number;
} = {
width: 0,
height: 0,
left: 0,
top: 0
};

public content: HTMLElement;

public isActive: boolean;

constructor(
public elementRef: ElementRef,
private renderer: Renderer2,
@Optional() private routerLinkActive: RouterLinkActive,
private ngZone: NgZone
) {
super();
}

ngAfterViewInit() {
this.setOffset();

this.content = this.elementRef.nativeElement.outerHTML;

this.ngZone.onStable.pipe(takeUntil(this.ngUnsubscribe$)).subscribe(() => {
this.isActive = this.linkIsActive();
});
}

setOffset() {
this.offset = {
width: this.elementRef.nativeElement.offsetWidth,
height: this.elementRef.nativeElement.offsetHeight,
left: this.elementRef.nativeElement.offsetLeft,
top: this.elementRef.nativeElement.offsetTop
};
}

linkIsActive() {
return (
this.thyNavLinkActive ||
(this.routerLinkActive && this.routerLinkActive.isActive) ||
this.routers.some(router => router.isActive) ||
this.links.some(item => item.thyNavLinkActive)
);
}

setNavLinkHidden(value: boolean) {
if (value) {
this.renderer.addClass(this.elementRef.nativeElement, 'nav-item-hidden');
} else {
this.renderer.removeClass(this.elementRef.nativeElement, 'nav-item-hidden');
}
}

ngOnDestroy() {
this.ngUnsubscribe$.next();
this.ngUnsubscribe$.complete();
}
}
46 changes: 46 additions & 0 deletions src/nav/nav.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<ng-container *ngIf="thyResponsive; else fixed">
<div class="thy-nav-list" #navList>
<ng-container [ngTemplateOutlet]="content"></ng-container>
</div>
<a
href="javascript:;"
class="thy-nav-more-container"
[class.d-none]="hiddenItems.length === 0"
#moreOperationContainer
thyNavLink
[thyNavLinkActive]="moreActive"
(click)="openMore($event, navListPopover)"
>
<ng-container *ngIf="moreOperation; else defaultMoreOperation" [ngTemplateOutlet]="moreOperation"></ng-container>
<ng-template #defaultMoreOperation>
更多
</ng-template>
</a>
</ng-container>

<ng-template #navListPopover>
<ng-template *ngIf="morePopover; else default">
<ng-container [ngTemplateOutlet]="morePopover" [ngTemplateOutletContext]="{ $implicit: hiddenItems }"></ng-container>
</ng-template>
<ng-template #default>
<thy-action-menu>
<ng-container *ngFor="let item of hiddenItems">
<span
class="more-nav-link"
thyActionMenuItem
[thyActionMenuItemActive]="item.isActive"
(click)="navItemClick(item)"
[innerHTML]="item.content"
></span>
</ng-container>
</thy-action-menu>
</ng-template>
</ng-template>

<ng-template #fixed>
<ng-container [ngTemplateOutlet]="content"></ng-container>
</ng-template>

<ng-template #content>
<ng-content></ng-content>
</ng-template>
Loading

0 comments on commit 4af8f26

Please sign in to comment.