Skip to content

Commit c0d4fd0

Browse files
committed
feat: m-template should also project css classes
1 parent a6df5f5 commit c0d4fd0

File tree

6 files changed

+42
-27
lines changed

6 files changed

+42
-27
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
<ng-content />
2-
<ng-container *ngIf="template" [ngTemplateOutlet]="template" />
2+
<ng-container *ngIf="template" [ngTemplateOutlet]="template.ref" />

projects/mantic-ui/src/lib/components/template-outlet/template-outlet.component.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
11
import { CommonModule } from '@angular/common';
2-
import { Component, effect, inject, input, TemplateRef } from '@angular/core';
2+
import { Component, effect, inject, input } from '@angular/core';
33
import { race, Subject } from 'rxjs';
44
import { takeUntil } from 'rxjs/operators';
55
import { Destroyable } from '../../base/destroyable';
6+
import { Template } from '../../models/template';
67
import { TemplateService } from '../../services/template.service';
78

89
@Component({
910
selector: 'm-template-outlet',
1011
imports: [CommonModule],
1112
templateUrl: './template-outlet.component.html',
12-
styleUrl: './template-outlet.component.scss'
13+
styleUrl: './template-outlet.component.scss',
14+
host: {
15+
'[class]': 'template?.class'
16+
}
1317
})
1418
export class TemplateOutletComponent extends Destroyable {
1519
private readonly templateService = inject(TemplateService);
1620
private readonly nextNameSubject = new Subject<void>();
17-
protected template: TemplateRef<unknown> | undefined;
21+
protected template: Template | undefined;
1822
public readonly name = input.required<string | string[]>();
1923

2024
public constructor() {

projects/mantic-ui/src/lib/components/template/template.component.ts

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { Component, inject, input, OnDestroy, TemplateRef, ViewChild } from '@angular/core';
1+
import { Component, effect, inject, input, OnDestroy, TemplateRef, viewChild } from '@angular/core';
2+
import { Template } from '../../models/template';
23
import { TemplateService } from '../../services/template.service';
34

45
@Component({
@@ -9,18 +10,22 @@ import { TemplateService } from '../../services/template.service';
910
})
1011
export class TemplateComponent implements OnDestroy {
1112
private readonly templateService = inject(TemplateService);
13+
private template: Template | undefined;
14+
protected readonly contentTemplate = viewChild<TemplateRef<unknown>>('contentTemplate');
1215
public readonly name = input.required<string | string[]>();
13-
private template: TemplateRef<unknown> | undefined;
16+
public readonly class = input<string>();
1417

15-
@ViewChild('contentTemplate')
16-
protected set contentTemplate(value: TemplateRef<unknown> | undefined) {
17-
if (this.template) {
18-
this.templateService.hide(this.name(), this.template);
19-
}
20-
this.template = value;
21-
if (this.template) {
22-
this.templateService.show(this.name(), this.template);
23-
}
18+
public constructor() {
19+
effect(() => {
20+
const ref = this.contentTemplate();
21+
if (this.template) {
22+
this.templateService.hide(this.name(), this.template);
23+
}
24+
this.template = ref ? { ref, class: this.class() } : undefined;
25+
if (this.template) {
26+
this.templateService.show(this.name(), this.template);
27+
}
28+
});
2429
}
2530

2631
public ngOnDestroy(): void {
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { TemplateRef } from '@angular/core';
2+
3+
export interface Template<T = unknown> {
4+
ref: TemplateRef<T>;
5+
class?: string;
6+
}

projects/mantic-ui/src/lib/services/template.service.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
import { Injectable, TemplateRef } from '@angular/core';
1+
import { Injectable } from '@angular/core';
22
import { BehaviorSubject, distinctUntilChanged, Observable, ReplaySubject, Subject } from 'rxjs';
3+
import { Template } from '../models/template';
34

45
@Injectable({
56
providedIn: 'root'
67
})
78
export class TemplateService {
8-
private readonly subscriptions = new Map<string, Subject<TemplateRef<unknown> | undefined>>();
9-
private readonly templates = new Map<string, TemplateRef<unknown>[]>();
9+
private readonly subscriptions = new Map<string, Subject<Template | undefined>>();
10+
private readonly templates = new Map<string, Template[]>();
1011

11-
public show(names: string | string[], template: TemplateRef<unknown>): void {
12+
public show(names: string | string[], template: Template): void {
1213
names = typeof names === 'string' ? [names] : names ?? [];
13-
const subscriptionSubject = new BehaviorSubject<TemplateRef<unknown> | undefined>(template);
14+
const subscriptionSubject = new BehaviorSubject<Template | undefined>(template);
1415
for (const name of names) {
1516
let list = this.templates.get(name);
1617
if (!list) {
@@ -26,7 +27,7 @@ export class TemplateService {
2627
}
2728
}
2829

29-
public hide(names: string | string[], template: TemplateRef<unknown>): void {
30+
public hide(names: string | string[], template: Template): void {
3031
names = typeof names === 'string' ? [names] : names ?? [];
3132
for (const name of names) {
3233
const list = this.templates.get(name);
@@ -41,17 +42,17 @@ export class TemplateService {
4142
}
4243
}
4344

44-
public get(names: string | string[]): Observable<TemplateRef<unknown> | undefined> {
45+
public get(names: string | string[]): Observable<Template | undefined> {
4546
names = typeof names === 'string' ? [names] : names ?? [];
4647
const existingSubject = names.map(name => this.subscriptions.get(name)).find(subscription => subscription);
47-
const subject = existingSubject ?? new ReplaySubject<TemplateRef<unknown> | undefined>(1);
48+
const subject = existingSubject ?? new ReplaySubject<Template | undefined>(1);
4849
for (const name of names) {
4950
this.subscriptions.set(name, subject);
5051
}
5152
return subject.pipe(distinctUntilChanged());
5253
}
5354

54-
private notify(name: string, template: TemplateRef<unknown> | undefined, fallbackSubscriptionSubject?: BehaviorSubject<TemplateRef<unknown> | undefined>): void {
55+
private notify(name: string, template: Template | undefined, fallbackSubscriptionSubject?: BehaviorSubject<Template | undefined>): void {
5556
if (this.subscriptions.has(name)) {
5657
this.subscriptions.get(name)?.next(template);
5758
}

src/app/examples/template/template.component.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import { NgIf } from '@angular/common';
22
import { Component } from '@angular/core';
3-
import { ButtonComponent, SegmentComponent, TabComponent, TabGroupComponent, TemplateComponent, TemplateOutletComponent, TextareaComponent } from '@mantic-ui/angular';
3+
import { ButtonComponent, HideOnEmptyTemplateDirective, SegmentComponent, TabComponent, TabGroupComponent, TemplateComponent, TemplateOutletComponent } from '@mantic-ui/angular';
44
import { ExampleCodeComponent, ExampleComponent } from '@mantic-ui/angular-doc';
5-
import { HideOnEmptyTemplateDirective } from '../../../../projects/mantic-ui/src/lib/directives/hide-on-empty-template.directive';
65
import { HeaderComponent } from '../../components/header/header.component';
76

87
@Component({
98
selector: 'app-template',
10-
imports: [ExampleCodeComponent, ExampleComponent, HeaderComponent, SegmentComponent, TabComponent, TabGroupComponent, TemplateComponent, TemplateOutletComponent, ButtonComponent, NgIf],
9+
imports: [ExampleCodeComponent, ExampleComponent, HeaderComponent, SegmentComponent, TabComponent, TabGroupComponent, TemplateComponent, TemplateOutletComponent, ButtonComponent, NgIf, HideOnEmptyTemplateDirective],
1110
templateUrl: './template.component.html',
1211
styleUrl: './template.component.scss'
1312
})

0 commit comments

Comments
 (0)