Skip to content

Commit 72a62b9

Browse files
committed
feat(sidebar): minimized state @Input/@output
- When `minimized` input property is set from outside, sidebar will properly switch it's state, eg: `[minimized]="sidebar.minimized$ | async"` - It's possible to listen to `minimized` value changes, eg. to persist in localStorage `[(minimized)]="minimized"` or `[minimized]="minimized$ | async" (minimizedChange)="minimized$.next($event)"`
1 parent 9f76134 commit 72a62b9

File tree

2 files changed

+51
-32
lines changed

2 files changed

+51
-32
lines changed
Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,24 @@
1-
import {Component, ElementRef, HostBinding, HostListener, Inject, OnInit, Renderer2} from '@angular/core';
2-
import {DOCUMENT} from '@angular/common';
1+
import { Component, HostBinding, HostListener, Optional } from '@angular/core';
2+
import { AppSidebarComponent } from './app-sidebar.component';
33

44
@Component({
55
selector: 'app-sidebar-minimizer, cui-sidebar-minimizer',
6-
template: ``,
6+
template: ``
77
})
8-
export class AppSidebarMinimizerComponent implements OnInit {
8+
export class AppSidebarMinimizerComponent {
99

1010
@HostBinding('attr.role') role = 'button';
11+
@HostBinding('class.sidebar-minimizer') _minimizer = true;
1112

1213
@HostListener('click', ['$event'])
1314
toggleOpen($event: any) {
1415
$event.preventDefault();
15-
const body = this.document.body;
16-
body.classList.contains('sidebar-minimized') ?
17-
this.renderer.removeClass(body, 'sidebar-minimized') :
18-
this.renderer.addClass(body, 'sidebar-minimized');
19-
body.classList.contains('brand-minimized') ?
20-
this.renderer.removeClass(body, 'brand-minimized') :
21-
this.renderer.addClass(body, 'brand-minimized');
16+
this.sidebar.toggleMinimized();
2217
}
2318

24-
constructor(
25-
@Inject(DOCUMENT) private document: any,
26-
private renderer: Renderer2,
27-
private hostElement: ElementRef
28-
) {
29-
renderer.addClass(hostElement.nativeElement, 'sidebar-minimizer');
19+
constructor(@Optional() private sidebar: AppSidebarComponent) {
20+
if (!sidebar) {
21+
throw Error(`AppSidebarMinimizer must be placed within a AppSidebar component.`);
22+
}
3023
}
31-
32-
ngOnInit() {}
3324
}
Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import {Component, Input, Inject, OnInit, OnDestroy, Renderer2, ElementRef} from '@angular/core';
21
import { DOCUMENT } from '@angular/common';
3-
2+
import { Component, EventEmitter, HostBinding, Inject, Input, OnDestroy, OnInit, Output, Renderer2 } from '@angular/core';
43
import { sidebarCssClasses } from '../shared';
54

65
@Component({
@@ -11,32 +10,51 @@ export class AppSidebarComponent implements OnInit, OnDestroy {
1110
@Input() compact: boolean;
1211
@Input() display: any;
1312
@Input() fixed: boolean;
14-
@Input() minimized: boolean;
1513
@Input() offCanvas: boolean;
1614

15+
@Input()
16+
get minimized() {
17+
return this._minimized;
18+
}
19+
set minimized(value: boolean) {
20+
// only update / emit events when the value changes
21+
if (this._minimized !== value) {
22+
this._minimized = value;
23+
this._updateMinimized(value);
24+
this.minimizedChange.emit(value);
25+
}
26+
}
27+
private _minimized = false;
28+
29+
/**
30+
* Emits whenever the minimized state of the sidebar changes.
31+
* Primarily used to facilitate two-way binding.
32+
*/
33+
@Output() minimizedChange = new EventEmitter<boolean>();
34+
35+
@HostBinding('class.sidebar') _sidebar = true;
36+
1737
constructor(
1838
@Inject(DOCUMENT) private document: any,
19-
private renderer: Renderer2,
20-
private hostElement: ElementRef
39+
private renderer: Renderer2
2140
) {
22-
renderer.addClass(hostElement.nativeElement, 'sidebar');
2341
}
2442

2543
ngOnInit(): void {
2644
this.displayBreakpoint(this.display);
2745
this.isCompact(this.compact);
2846
this.isFixed(this.fixed);
29-
this.isMinimized(this.minimized);
3047
this.isOffCanvas(this.offCanvas);
3148
}
3249

3350
ngOnDestroy(): void {
34-
this.renderer.removeClass(this.document.body, 'sidebar-fixed' );
51+
this.minimizedChange.complete();
52+
this.renderer.removeClass(this.document.body, 'sidebar-fixed');
3553
}
3654

3755
isCompact(compact: boolean = this.compact): void {
3856
if (compact) {
39-
this.renderer.addClass(this.document.body, 'sidebar-compact' );
57+
this.renderer.addClass(this.document.body, 'sidebar-compact');
4058
}
4159
}
4260

@@ -46,10 +64,8 @@ export class AppSidebarComponent implements OnInit, OnDestroy {
4664
}
4765
}
4866

49-
isMinimized(minimized: boolean = this.minimized): void {
50-
if (minimized) {
51-
this.renderer.addClass(this.document.body, 'sidebar-minimized');
52-
}
67+
toggleMinimized(): void {
68+
this.minimized = !this._minimized;
5369
}
5470

5571
isOffCanvas(offCanvas: boolean = this.offCanvas): void {
@@ -64,4 +80,16 @@ export class AppSidebarComponent implements OnInit, OnDestroy {
6480
this.renderer.addClass(this.document.body, cssClass);
6581
}
6682
}
83+
84+
private _updateMinimized(minimized: boolean): void {
85+
const body = this.document.body;
86+
87+
if (minimized) {
88+
this.renderer.addClass(body, 'sidebar-minimized');
89+
this.renderer.addClass(body, 'brand-minimized');
90+
} else {
91+
this.renderer.removeClass(body, 'sidebar-minimized');
92+
this.renderer.removeClass(body, 'brand-minimized');
93+
}
94+
}
6795
}

0 commit comments

Comments
 (0)