Skip to content

Commit 6fc8ec0

Browse files
committedMar 4, 2024
refactor(sidebar): drop sidebar-toggler component, use directive instead, use control flow, use @input() transform
1 parent eb079b6 commit 6fc8ec0

12 files changed

+90
-97
lines changed
 

‎projects/coreui-angular/src/lib/sidebar/public_api.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ export { SidebarComponent } from './sidebar/sidebar.component';
22
export { SidebarService } from './sidebar.service';
33
export { SidebarBrandComponent } from './sidebar-brand/sidebar-brand.component';
44
export { SidebarToggleDirective } from './sidebar-toggle/sidebar-toggle.directive';
5-
export { SidebarTogglerComponent } from './sidebar-toggler/sidebar-toggler.component';
5+
export { SidebarTogglerDirective } from './sidebar-toggler/sidebar-toggler.directive';
66
export { SidebarHeaderComponent } from './sidebar-header/sidebar-header.component';
77
export { SidebarFooterComponent } from './sidebar-footer/sidebar-footer.component';
88

‎projects/coreui-angular/src/lib/sidebar/sidebar-brand/sidebar-brand.component.html

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
@if (brandImg) {
22
<a [routerLink]="routerLink">
33
@if (brandFull) {
4-
<img [cHtmlAttr]="brandFull"
5-
[ngClass]="'sidebar-brand-full'">
4+
<img [cHtmlAttr]="brandFull" [ngClass]="'sidebar-brand-full'">
65
}
76
@if (brandNarrow) {
8-
<img [cHtmlAttr]="brandNarrow"
9-
[ngClass]="'sidebar-brand-narrow'">
7+
<img [cHtmlAttr]="brandNarrow" [ngClass]="'sidebar-brand-narrow'">
108
}
119
</a>
1210
} @else {

‎projects/coreui-angular/src/lib/sidebar/sidebar-nav/sidebar-nav-group.component.html

+5-1
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,19 @@
1212
(@openClose.done)="onAnimationDone($event)"
1313
(@openClose.start)="onAnimationStart($event)"
1414
[@openClose]="open ? 'open' : 'closed'"
15+
[compact]="compact"
1516
[dropdownMode]="dropdownMode"
1617
[groupItems]="true"
1718
[navItems]="navItems"
1819
[ngStyle]="display"
1920
/>
2021

2122
<ng-template #iconTemplate let-item>
23+
<!-- <i *ngIf="item?.icon" [ngClass]="item | cSidebarNavIcon"></i>-->
2224
@if (item?.icon) {
23-
<i [ngClass]="item | cSidebarNavIcon"></i>
25+
<span class="nav-icon">
26+
<span [ngClass]="item.icon ?? ''"></span>
27+
</span>
2428
}
2529
@if (item?.iconComponent) {
2630
<svg

‎projects/coreui-angular/src/lib/sidebar/sidebar-nav/sidebar-nav-label.component.html

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
<a [ngClass]="getItemClass()"
2-
href="{{item.url}}"
3-
[cHtmlAttr]="item.attributes">
1+
<a [cHtmlAttr]="item.attributes"
2+
[ngClass]="getItemClass()"
3+
href="{{item.url}}">
44
@if (helper.hasIcon(item)) {
55
<i [ngClass]="getLabelIconClass()"></i>
66
}

‎projects/coreui-angular/src/lib/sidebar/sidebar-nav/sidebar-nav-link.component.html

+15-19
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
@switch (linkType) {
22
@case ('disabled') {
3-
<a [ngClass]="item | cSidebarNavLink"
4-
[cHtmlAttr]="item.attributes ?? {}"
5-
>
3+
<a [cHtmlAttr]="item.attributes ?? {}" [ngClass]="item | cSidebarNavLink">
64
<ng-container *ngTemplateOutlet="iconTemplate; context: {$implicit: item}" />
75
<c-sidebar-nav-link-content [item]="item" />
86
@if (item.badge) {
@@ -11,11 +9,7 @@
119
</a>
1210
}
1311
@case ('external') {
14-
<a [ngClass]="item | cSidebarNavLink"
15-
[href]="href"
16-
[cHtmlAttr]="item.attributes ?? {}"
17-
(click)="linkClicked()"
18-
>
12+
<a (click)="linkClicked()" [cHtmlAttr]="item.attributes ?? {}" [href]="href" [ngClass]="item | cSidebarNavLink">
1913
<ng-container *ngTemplateOutlet="iconTemplate; context: {$implicit: item}" />
2014
<c-sidebar-nav-link-content [item]="item" />
2115
@if (item.badge) {
@@ -24,20 +18,20 @@
2418
</a>
2519
}
2620
@default {
27-
<a [ngClass]="item | cSidebarNavLink"
21+
<a (click)="linkClicked()"
2822
[cHtmlAttr]="item.attributes ?? {}"
29-
[target]="item.attributes?.['target']"
30-
[queryParams]="item.linkProps?.queryParams ?? null"
3123
[fragment]="item.linkProps?.fragment"
32-
[queryParamsHandling]="item.linkProps?.queryParamsHandling"
24+
[ngClass]="item | cSidebarNavLink"
3325
[preserveFragment]="item.linkProps?.preserveFragment ?? false"
34-
[skipLocationChange]="item.linkProps?.skipLocationChange ?? false"
26+
[queryParamsHandling]="item.linkProps?.queryParamsHandling"
27+
[queryParams]="item.linkProps?.queryParams ?? null"
3528
[replaceUrl]="item.linkProps?.replaceUrl ?? false"
36-
[state]="item.linkProps?.state ?? {}"
29+
[routerLinkActiveOptions]="item.linkProps?.routerLinkActiveOptions ?? { exact: false }"
3730
[routerLink]="item.url"
31+
[skipLocationChange]="item.linkProps?.skipLocationChange ?? false"
32+
[state]="item.linkProps?.state ?? {}"
33+
[target]="item.attributes?.['target']"
3834
routerLinkActive="active"
39-
[routerLinkActiveOptions]="item.linkProps?.routerLinkActiveOptions ?? { exact: false }"
40-
(click)="linkClicked()"
4135
>
4236
<!-- [class.active]="linkActive"-->
4337
<ng-container *ngTemplateOutlet="iconTemplate ; context: {$implicit: item}" />
@@ -48,16 +42,18 @@
4842
</a>
4943
}
5044
}
51-
5245
<ng-template #iconTemplate let-item>
46+
<!-- <i *ngIf="item?.icon" [ngClass]="item | cSidebarNavIcon"></i>-->
5347
@if (item?.icon) {
54-
<i [ngClass]="item | cSidebarNavIcon"></i>
48+
<span class="nav-icon">
49+
<span [ngClass]="item.icon ?? ''"></span>
50+
</span>
5551
}
5652
@if (item?.iconComponent) {
5753
<svg
5854
[cIcon]="item.iconComponent?.content"
59-
[name]="item.iconComponent?.name"
6055
[customClasses]="item | cSidebarNavIcon"
56+
[name]="item.iconComponent?.name"
6157
></svg>
6258
}
6359
@if (!item?.icon && !item?.iconComponent) {

‎projects/coreui-angular/src/lib/sidebar/sidebar-nav/sidebar-nav-link.component.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
21
import { NgClass, NgTemplateOutlet } from '@angular/common';
2+
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
33
import { NavigationEnd, Router, RouterModule } from '@angular/router';
44
import { Observable, Subscription } from 'rxjs';
55
import { filter } from 'rxjs/operators';
6+
import { IconDirective } from '@coreui/icons-angular';
67

78
// import {SidebarService} from '../sidebar.service';
89
import { HtmlAttributesDirective } from '../../shared';
@@ -11,7 +12,6 @@ import { INavData } from './sidebar-nav';
1112
import { SidebarNavLinkPipe } from './sidebar-nav-link.pipe';
1213
import { SidebarNavBadgePipe } from './sidebar-nav-badge.pipe';
1314
import { SidebarNavIconPipe } from './sidebar-nav-icon.pipe';
14-
import { IconDirective } from '@coreui/icons-angular';
1515

1616
@Component({
1717
selector: 'c-sidebar-nav-link-content',
@@ -40,12 +40,12 @@ export class SidebarNavLinkContentComponent {
4040
RouterModule,
4141
HtmlAttributesDirective,
4242
IconDirective,
43-
NgClass,
44-
NgTemplateOutlet,
4543
SidebarNavLinkContentComponent,
4644
SidebarNavLinkPipe,
4745
SidebarNavBadgePipe,
48-
SidebarNavIconPipe
46+
SidebarNavIconPipe,
47+
NgTemplateOutlet,
48+
NgClass
4949
]
5050
})
5151
export class SidebarNavLinkComponent implements OnInit, OnDestroy {

‎projects/coreui-angular/src/lib/sidebar/sidebar-nav/sidebar-nav.component.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
[ngClass]="item | cSidebarNavItemClass"
99
[routerLinkActiveOptions]="{exact: true}"
1010
routerLinkActive="show"
11+
[compact]="compact"
1112
/>
1213
}
1314
@case ('divider') {
@@ -42,4 +43,4 @@
4243
}
4344
}
4445
}
45-
<ng-content />
46+
<ng-content></ng-content>

‎projects/coreui-angular/src/lib/sidebar/sidebar-nav/sidebar-nav.component.ts

+10-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { animate, AnimationEvent, state, style, transition, trigger } from '@angular/animations';
22
import { NgClass, NgStyle, NgTemplateOutlet } from '@angular/common';
33
import {
4+
booleanAttribute,
45
Component,
56
ElementRef,
67
forwardRef,
@@ -80,6 +81,7 @@ export class SidebarNavGroupComponent implements OnInit, OnDestroy {
8081
@Input() item: any;
8182
@Input() dropdownMode: 'path' | 'none' | 'close' = 'path';
8283
@Input() show?: boolean;
84+
@Input({ transform: booleanAttribute }) compact?: boolean;
8385

8486
@HostBinding('class')
8587
get hostClasses(): any {
@@ -204,21 +206,22 @@ export class SidebarNavComponent implements OnChanges {
204206

205207
@Input() navItems?: INavData[] = [];
206208
@Input() dropdownMode: 'path' | 'none' | 'close' = 'path';
207-
@Input() groupItems?: boolean;
208-
@Input() compact?: boolean;
209+
@Input({ transform: booleanAttribute }) groupItems?: boolean;
210+
@Input({ transform: booleanAttribute }) compact?: boolean;
209211

210212
@HostBinding('class')
211213
get hostClasses(): any {
212214
return {
213215
'sidebar-nav': !this.groupItems,
214-
compact: !this.groupItems && !!this.compact
216+
'nav-group-items': this.groupItems,
217+
compact: this.groupItems && this.compact
215218
};
216219
}
217220

218-
@HostBinding('class.nav-group-items')
219-
get sidebarNavGroupItemsClass(): boolean {
220-
return !!this.groupItems;
221-
}
221+
// @HostBinding('class.nav-group-items')
222+
// get sidebarNavGroupItemsClass(): boolean {
223+
// return !!this.groupItems;
224+
// }
222225

223226
@HostBinding('attr.role') role = 'nav';
224227

‎projects/coreui-angular/src/lib/sidebar/sidebar-toggler/sidebar-toggler.component.ts

-15
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Directive, HostBinding, Input } from '@angular/core';
2+
import { SidebarToggleDirective } from '../sidebar-toggle/sidebar-toggle.directive';
3+
4+
@Directive({
5+
selector: '[cSidebarToggler]',
6+
standalone: true,
7+
hostDirectives: [{ directive: SidebarToggleDirective, inputs: ['cSidebarToggle: cSidebarToggler', 'toggle'] }]
8+
})
9+
export class SidebarTogglerDirective {
10+
11+
@HostBinding('attr.role')
12+
@Input() role = 'button';
13+
14+
@HostBinding('class.sidebar-toggler') sidebarTogglerClass = true;
15+
16+
@HostBinding('style')
17+
get getStyles(): any {
18+
return {
19+
appearance: 'button',
20+
'align-items': 'flex-start',
21+
cursor: 'pointer'
22+
};
23+
}
24+
25+
}

‎projects/coreui-angular/src/lib/sidebar/sidebar.module.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { SidebarComponent } from './sidebar/sidebar.component';
44
import { SidebarService } from './sidebar.service';
55
import { SidebarBrandComponent } from './sidebar-brand/sidebar-brand.component';
66
import { SidebarToggleDirective } from './sidebar-toggle/sidebar-toggle.directive';
7-
import { SidebarTogglerComponent } from './sidebar-toggler/sidebar-toggler.component';
7+
import { SidebarTogglerDirective } from './sidebar-toggler/sidebar-toggler.directive';
88
import { SidebarHeaderComponent } from './sidebar-header/sidebar-header.component';
99
import { SidebarFooterComponent } from './sidebar-footer/sidebar-footer.component';
1010
import { SidebarNavGroupService } from './sidebar-nav/sidebar-nav-group.service';
@@ -42,12 +42,12 @@ import {
4242
SidebarNavLinkPipe,
4343
SidebarNavTitleComponent,
4444
SidebarToggleDirective,
45-
SidebarTogglerComponent
45+
SidebarTogglerDirective
4646
],
4747
exports: [
4848
SidebarComponent,
4949
SidebarToggleDirective,
50-
SidebarTogglerComponent,
50+
SidebarTogglerDirective,
5151
SidebarBrandComponent,
5252
SidebarNavComponent,
5353
SidebarHeaderComponent,

‎projects/coreui-angular/src/lib/sidebar/sidebar/sidebar.component.ts

+19-38
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
booleanAttribute,
23
Component,
34
EventEmitter,
45
HostBinding,
@@ -12,7 +13,6 @@ import {
1213
SimpleChanges
1314
} from '@angular/core';
1415
import { DOCUMENT } from '@angular/common';
15-
import { BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion';
1616
import { BreakpointObserver, BreakpointState } from '@angular/cdk/layout';
1717
import { Subscription } from 'rxjs';
1818

@@ -22,18 +22,11 @@ import { SidebarBackdropService } from '../sidebar-backdrop/sidebar-backdrop.ser
2222
@Component({
2323
selector: 'c-sidebar',
2424
exportAs: 'cSidebar',
25-
template: '<ng-content></ng-content>',
25+
template: '<ng-content />',
2626
standalone: true
2727
})
2828
export class SidebarComponent implements OnChanges, OnDestroy, OnInit {
29-
static ngAcceptInputType_narrow: BooleanInput;
30-
static ngAcceptInputType_overlaid: BooleanInput;
31-
static ngAcceptInputType_unfoldable: BooleanInput;
32-
static ngAcceptInputType_visible: BooleanInput;
33-
34-
#narrow = false;
35-
#overlaid = false;
36-
#unfoldable = false;
29+
3730
#visible = false;
3831
#onMobile = false;
3932
#layoutChangeSubscription!: Subscription;
@@ -66,28 +59,16 @@ export class SidebarComponent implements OnChanges, OnDestroy, OnInit {
6659
/**
6760
* Make sidebar narrow. [docs]
6861
* @type boolean
62+
* @default false
6963
*/
70-
@Input()
71-
set narrow(value: boolean) {
72-
this.#narrow = coerceBooleanProperty(value);
73-
}
74-
75-
get narrow() {
76-
return this.#narrow;
77-
}
64+
@Input({ transform: booleanAttribute }) narrow: boolean = false;
7865

7966
/**
8067
* Set sidebar to overlaid variant.
8168
* @type boolean
69+
* @default false
8270
*/
83-
@Input()
84-
set overlaid(value: boolean) {
85-
this.#overlaid = coerceBooleanProperty(value);
86-
}
87-
88-
get overlaid() {
89-
return this.#overlaid;
90-
}
71+
@Input({ transform: booleanAttribute }) overlaid: boolean = false;
9172

9273
/**
9374
* Components placement, there’s no default placement. [docs]
@@ -108,22 +89,19 @@ export class SidebarComponent implements OnChanges, OnDestroy, OnInit {
10889

10990
/**
11091
* Expand narrowed sidebar on hover. [docs]
92+
* @type boolean
93+
* @default false
11194
*/
112-
@Input()
113-
set unfoldable(value: boolean) {
114-
this.#unfoldable = coerceBooleanProperty(value);
115-
}
116-
117-
get unfoldable() {
118-
return this.#unfoldable;
119-
}
95+
@Input({ transform: booleanAttribute }) unfoldable: boolean = false;
12096

12197
/**
12298
* Toggle the visibility of sidebar component. [docs]
99+
* @type boolean
100+
* @default false
123101
*/
124-
@Input()
102+
@Input({ transform: booleanAttribute })
125103
set visible(value: boolean) {
126-
const visible = coerceBooleanProperty(value);
104+
const visible = value;
127105
if (this.#visible !== visible) {
128106
this.#visible = visible;
129107
this.visibleChange.emit(this.#visible);
@@ -192,8 +170,11 @@ export class SidebarComponent implements OnChanges, OnDestroy, OnInit {
192170
'sidebar-narrow': this.narrow && !this.unfoldable,
193171
'sidebar-narrow-unfoldable': this.unfoldable,
194172
'sidebar-overlaid': this.overlaid,
173+
[`sidebar-${this.placement}`]: !!this.placement,
174+
[`sidebar-${this.colorScheme}`]: !!this.colorScheme,
195175
[`sidebar-${this.size}`]: !!this.size,
196-
show: visible && this.#onMobile,
176+
show: visible,
177+
// show: visible && this.#onMobile, //todo: check
197178
hide: !visible
198179
};
199180
}
@@ -219,7 +200,7 @@ export class SidebarComponent implements OnChanges, OnDestroy, OnInit {
219200
for (const propName in changes) {
220201
if (propList.includes(propName)) {
221202
if (changes[propName] && !changes[propName].firstChange) {
222-
const value = coerceBooleanProperty(changes[propName].currentValue);
203+
const value = booleanAttribute(changes[propName].currentValue);
223204
if (oldStateMap.get(propName) !== value) {
224205
newStateMap.set(propName, value);
225206
}

0 commit comments

Comments
 (0)
Please sign in to comment.