Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(tabset): lazy loading #2827

Merged
merged 29 commits into from
Nov 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
6ddc5c8
fix(tabset): lazy load
evtkhvch Aug 13, 2021
5a99e0a
ref(tabset): extract view logic
evtkhvch Aug 15, 2021
3eee78f
ref(tabset): turn activeValue into active
evtkhvch Aug 16, 2021
2a32b46
ref(tabset): made init property deprecated
evtkhvch Aug 16, 2021
9aac907
chore(NbTabComponent): init property description
evtkhvch Aug 16, 2021
6579461
style(tabset): add new lines
evtkhvch Aug 16, 2021
64277e1
fix(tabset): remove portal implementation
evtkhvch Sep 20, 2021
aa4b804
fix(tabset): remove portal import
evtkhvch Sep 20, 2021
183494f
fix(tabset): module imports
evtkhvch Sep 20, 2021
b1b779d
style(tabset): rename variable
evtkhvch Sep 20, 2021
3e736ce
fix(tabset): add template outlet
evtkhvch Sep 21, 2021
eb1bc77
style(tabset): remove comments
evtkhvch Sep 21, 2021
7621f86
fix(tabset): add wrap container
evtkhvch Sep 21, 2021
9a0e959
style(tabset): add new line
evtkhvch Sep 21, 2021
87bf2cb
fix(tabset): change lazy directive
evtkhvch Sep 21, 2021
868eb82
fix(tabset): add getter for lazy template
evtkhvch Sep 21, 2021
1aa9b6f
fix(tabset): remove getter
evtkhvch Sep 21, 2021
0c8f1ed
Merge branch 'master' into 1827-fix-lazy-tab-component
yggg Nov 8, 2021
bc2990b
Merge branch 'master' into 1827-fix-lazy-tab-component
yggg Nov 8, 2021
cb4aff7
Merge remote-tracking branch 'origin/master' into 1827-fix-lazy-tab-c…
evtkhvch Nov 11, 2021
8cbeeda
fix(tabset): add lazy content directive to public api
evtkhvch Nov 11, 2021
a3ba8f6
Merge branch 'master' into 1827-fix-lazy-tab-component
yggg Nov 12, 2021
27f58a0
refactor(tabset): rename lazy content directive
yggg Nov 12, 2021
feee75a
style(tabset): remove redundant comment
yggg Nov 12, 2021
4810ac1
style(tabset): update deprecation comments
yggg Nov 12, 2021
1727213
refactor(tabset): remove redundant accessors
yggg Nov 12, 2021
90631dc
refactor(tabset): use a single ng-container
yggg Nov 12, 2021
0f4b2d5
docs(tabset): hide deprecated properties
yggg Nov 15, 2021
a241628
docs(tabset): add nbTabContent usage example
yggg Nov 15, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/framework/theme/components/tabset/tab-content.directive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Directive, TemplateRef } from '@angular/core';

/**
* Directive to wrap tab lazy content.
* */
@Directive({
selector: '[nbTabContent]',
})
export class NbTabContentDirective {
constructor(public templateRef: TemplateRef<any>) {}
}
80 changes: 54 additions & 26 deletions src/framework/theme/components/tabset/tabset.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ import {
AfterContentInit,
HostBinding,
ChangeDetectorRef,
ContentChild,
} from '@angular/core';
import { ActivatedRoute } from '@angular/router';

import { convertToBoolProperty, NbBooleanInput } from '../helpers';
import { NbComponentOrCustomStatus } from '../component-status';
import { NbBadgePosition } from '../badge/badge.component';
import { NbIconConfig } from '../icon/icon.component';
import { NbTabContentDirective } from './tab-content.directive';

/**
* Specific tab container.
Expand All @@ -32,17 +34,23 @@ import { NbIconConfig } from '../icon/icon.component';
* badgeStatus="danger">
* <p>List of <strong>users</strong>.</p>
* </nb-tab>
```
* ```
*/
@Component({
selector: 'nb-tab',
template: `
<ng-container *ngIf="init">
<ng-container
*ngIf="tabContentDirective; else projectedContent"
[ngTemplateOutlet]="tabContentDirective.templateRef"
></ng-container>

<ng-template #projectedContent>
<ng-content></ng-content>
yggg marked this conversation as resolved.
Show resolved Hide resolved
</ng-container>
</ng-template>
yggg marked this conversation as resolved.
Show resolved Hide resolved
`,
})
export class NbTabComponent {
@ContentChild(NbTabContentDirective) tabContentDirective: NbTabContentDirective;

/**
* Tab title
Expand Down Expand Up @@ -133,8 +141,9 @@ export class NbTabComponent {

/**
* Lazy load content before tab selection
* TODO: rename, as lazy is by default, and this is more `instant load`
* @param {boolean} val
* @docs-private
* @deprecated This setting never worked. Wrap content into a `nbTabContent` to make it lazy.
* @breaking-change Remove 10.0.0
*/
@Input()
set lazyLoad(val: boolean) {
Expand Down Expand Up @@ -164,6 +173,11 @@ export class NbTabComponent {
*/
@Input() badgePosition: NbBadgePosition;

/**
* @deprecated
* @breaking-change Remove 10.0.0
* @docs-private
*/
init: boolean = false;
}

Expand Down Expand Up @@ -214,12 +228,26 @@ export class NbTabComponent {
* (`tabset-tab-text-hide-breakpoint` property) for better responsive behaviour.
* You can open the following example and make
* your screen smaller - titles will be hidden in the last tabset in the list:
*
* @stacked-example(Icon, tabset/tabset-icon.component)
*
* It is also possible to disable a tab using `disabled` property:
* @stacked-example(Disabled Tab, tabset/tabset-disabled.component)
*
* By default, the tab contents instantiated straightaway. To make tab contents load lazy,
* declare the body of a tab in a template with `nbTabContent` directive.
* ```html
* <nb-tabset>
* <nb-tab>
* <some-component *nbTabContent>Lazy content</some-component>
* </nb-tab>
* <nb-tab>
* <ng-template nbTabContent>
* Lazy content with template syntax
* </ng-template>
* </nb-tab>
* </nb-tabset>
* ```
*
* @styles
*
* tabset-background-color:
Expand Down Expand Up @@ -267,33 +295,36 @@ export class NbTabComponent {
styleUrls: ['./tabset.component.scss'],
template: `
<ul class="tabset">
<li *ngFor="let tab of tabs"
(click)="selectTab(tab)"
(keyup.space)="selectTab(tab)"
(keyup.enter)="selectTab(tab)"
[class.responsive]="tab.responsive"
[class.active]="tab.active"
[class.disabled]="tab.disabled"
[attr.tabindex]="tab.disabled ? -1 : 0"
[attr.data-tab-id]="tab.tabId"
class="tab">
<li
*ngFor="let tab of tabs"
(click)="selectTab(tab)"
(keyup.space)="selectTab(tab)"
(keyup.enter)="selectTab(tab)"
[class.responsive]="tab.responsive"
[class.active]="tab.active"
[class.disabled]="tab.disabled"
[attr.tabindex]="tab.disabled ? -1 : 0"
[attr.data-tab-id]="tab.tabId"
class="tab"
>
<a href (click)="$event.preventDefault()" tabindex="-1" class="tab-link">
<nb-icon *ngIf="tab.tabIcon" [config]="tab.tabIcon"></nb-icon>
<span *ngIf="tab.tabTitle" class="tab-text">{{ tab.tabTitle }}</span>
</a>
<nb-badge *ngIf="tab.badgeText || tab.badgeDot"
<nb-badge
*ngIf="tab.badgeText || tab.badgeDot"
[text]="tab.badgeText"
[dotMode]="tab.badgeDot"
[status]="tab.badgeStatus"
[position]="tab.badgePosition">
[position]="tab.badgePosition"
>
</nb-badge>
</li>
</ul>
<ng-content select="nb-tab"></ng-content>
`,
})
export class NbTabsetComponent implements AfterContentInit {

@ContentChildren(NbTabComponent) tabs: QueryList<NbTabComponent>;

@HostBinding('class.full-width')
Expand Down Expand Up @@ -321,17 +352,14 @@ export class NbTabsetComponent implements AfterContentInit {
*/
@Output() changeTab = new EventEmitter<any>();

constructor(private route: ActivatedRoute,
private changeDetectorRef: ChangeDetectorRef) {
}
constructor(private route: ActivatedRoute, private changeDetectorRef: ChangeDetectorRef) {}

// TODO: refactoring this component, avoid change detection loop
ngAfterContentInit() {
this.route.params
.pipe(
map(
(params: any) =>
this.tabs.find((tab) => this.routeParam ? tab.route === params[this.routeParam] : tab.active),
map((params: any) =>
this.tabs.find((tab) => (this.routeParam ? tab.route === params[this.routeParam] : tab.active)),
),
delay(0),
map((tab: NbTabComponent) => tab || this.tabs.first),
Expand All @@ -346,7 +374,7 @@ export class NbTabsetComponent implements AfterContentInit {
// TODO: navigate to routeParam
selectTab(selectedTab: NbTabComponent) {
if (!selectedTab.disabled) {
this.tabs.forEach(tab => tab.active = tab === selectedTab);
this.tabs.forEach((tab) => (tab.active = tab === selectedTab));
this.changeTab.emit(selectedTab);
}
}
Expand Down
24 changes: 8 additions & 16 deletions src/framework/theme/components/tabset/tabset.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,15 @@ import { NbSharedModule } from '../shared/shared.module';
import { NbTabsetComponent, NbTabComponent } from './tabset.component';
import { NbBadgeModule } from '../badge/badge.module';
import { NbIconModule } from '../icon/icon.module';
import { NbTabContentDirective } from './tab-content.directive';

const NB_TABSET_COMPONENTS = [
NbTabsetComponent,
NbTabComponent,
];
const NB_TABSET_COMPONENTS = [NbTabsetComponent, NbTabComponent];

const NB_TABSET_DIRECTIVES = [NbTabContentDirective];

@NgModule({
imports: [
NbSharedModule,
NbBadgeModule,
NbIconModule,
],
declarations: [
...NB_TABSET_COMPONENTS,
],
exports: [
...NB_TABSET_COMPONENTS,
],
imports: [NbSharedModule, NbBadgeModule, NbIconModule],
declarations: [...NB_TABSET_COMPONENTS, ...NB_TABSET_DIRECTIVES],
exports: [...NB_TABSET_COMPONENTS, ...NB_TABSET_DIRECTIVES],
})
export class NbTabsetModule { }
export class NbTabsetModule {}
1 change: 1 addition & 0 deletions src/framework/theme/public_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export * from './components/tabset/tabset.module';
export * from './components/datepicker/date-timepicker.component';
export * from './components/datepicker/calendar-with-time.component';
export * from './components/tabset/tabset.component';
export * from './components/tabset/tab-content.directive';
export * from './components/user/user.module';
export * from './components/user/user.component';
export * from './components/actions/actions.module';
Expand Down