Skip to content

Commit c256b76

Browse files
committed
fix(sidebar): open behavior on mobile layout change, refactor
1 parent f4755b1 commit c256b76

File tree

1 file changed

+88
-57
lines changed

1 file changed

+88
-57
lines changed

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

Lines changed: 88 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -10,39 +10,51 @@ import {
1010
Output,
1111
Renderer2,
1212
SimpleChanges
13-
} from '@angular/core';
14-
import { DOCUMENT } from '@angular/common';
15-
import { BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion';
16-
import { BreakpointObserver, BreakpointState } from '@angular/cdk/layout';
17-
import { Subscription } from 'rxjs';
13+
} from "@angular/core";
14+
import { DOCUMENT } from "@angular/common";
15+
import { BooleanInput, coerceBooleanProperty } from "@angular/cdk/coercion";
16+
import { BreakpointObserver, BreakpointState } from "@angular/cdk/layout";
17+
import { Subscription } from "rxjs";
1818

19-
import { ISidebarAction, SidebarService } from '../sidebar.service';
20-
import { SidebarBackdropService } from '../sidebar-backdrop/sidebar-backdrop.service';
19+
import { ISidebarAction, SidebarService } from "../sidebar.service";
20+
import { SidebarBackdropService } from "../sidebar-backdrop/sidebar-backdrop.service";
2121

2222
@Component({
2323
selector: 'c-sidebar',
2424
exportAs: 'cSidebar',
2525
template: '<ng-content></ng-content>'
2626
})
2727
export class SidebarComponent implements OnChanges, OnDestroy, OnInit {
28-
2928
static ngAcceptInputType_narrow: BooleanInput;
3029
static ngAcceptInputType_overlaid: BooleanInput;
3130
static ngAcceptInputType_unfoldable: BooleanInput;
3231
static ngAcceptInputType_visible: BooleanInput;
3332

34-
private _narrow = false;
35-
private _overlaid = false;
36-
private _unfoldable = false;
37-
private _visible = false;
38-
private onMobile = false;
39-
private layoutChangeSubscription!: Subscription;
40-
private stateToggleSubscription!: Subscription;
33+
#narrow = false;
34+
#overlaid = false;
35+
#unfoldable = false;
36+
#visible = false;
37+
#onMobile = false;
38+
#layoutChangeSubscription!: Subscription;
39+
#stateToggleSubscription!: Subscription;
4140

4241
state: ISidebarAction = {
4342
sidebar: this
4443
};
4544

45+
#stateInitial = {
46+
narrow: false,
47+
visible: false,
48+
unfoldable: false
49+
};
50+
51+
/**
52+
* Sets if the color of text should be colored for a light or dark background. [docs]
53+
*
54+
* @type 'dark' | 'light'
55+
*/
56+
@Input() colorScheme?: 'dark' | 'light';
57+
4658
/**
4759
* Sets html attribute id. [docs]
4860
*
@@ -56,11 +68,11 @@ export class SidebarComponent implements OnChanges, OnDestroy, OnInit {
5668
*/
5769
@Input()
5870
set narrow(value: boolean) {
59-
this._narrow = coerceBooleanProperty(value);
71+
this.#narrow = coerceBooleanProperty(value);
6072
}
6173

6274
get narrow() {
63-
return this._narrow;
75+
return this.#narrow;
6476
}
6577

6678
/**
@@ -69,13 +81,19 @@ export class SidebarComponent implements OnChanges, OnDestroy, OnInit {
6981
*/
7082
@Input()
7183
set overlaid(value: boolean) {
72-
this._overlaid = coerceBooleanProperty(value);
84+
this.#overlaid = coerceBooleanProperty(value);
7385
}
7486

7587
get overlaid() {
76-
return this._overlaid;
88+
return this.#overlaid;
7789
}
7890

91+
/**
92+
* Components placement, there’s no default placement. [docs]
93+
* @type 'start' | 'end'
94+
*/
95+
@Input() placement?: 'start' | 'end';
96+
7997
/**
8098
* Place sidebar in non-static positions. [docs]
8199
* @default 'fixed'
@@ -92,11 +110,11 @@ export class SidebarComponent implements OnChanges, OnDestroy, OnInit {
92110
*/
93111
@Input()
94112
set unfoldable(value: boolean) {
95-
this._unfoldable = coerceBooleanProperty(value);
113+
this.#unfoldable = coerceBooleanProperty(value);
96114
}
97115

98116
get unfoldable() {
99-
return this._unfoldable;
117+
return this.#unfoldable;
100118
}
101119

102120
/**
@@ -105,14 +123,14 @@ export class SidebarComponent implements OnChanges, OnDestroy, OnInit {
105123
@Input()
106124
set visible(value: boolean) {
107125
const visible = coerceBooleanProperty(value);
108-
if (this._visible !== visible) {
109-
this._visible = visible;
110-
this.visibleChange.emit(this._visible);
126+
if (this.#visible !== visible) {
127+
this.#visible = visible;
128+
this.visibleChange.emit(this.#visible);
111129
}
112130
}
113131

114132
get visible() {
115-
return this._visible;
133+
return this.#visible;
116134
}
117135

118136
/**
@@ -126,7 +144,7 @@ export class SidebarComponent implements OnChanges, OnDestroy, OnInit {
126144
if ('toggle' in newState) {
127145
if (newState.toggle === 'visible') {
128146
newState.visible = !this.state.visible;
129-
this.visible = newState.visible && !this.overlaid;
147+
this.visible = newState.visible;
130148
} else if (newState.toggle === 'unfoldable') {
131149
newState.unfoldable = !this.state.unfoldable;
132150
this.unfoldable = newState.unfoldable;
@@ -136,24 +154,31 @@ export class SidebarComponent implements OnChanges, OnDestroy, OnInit {
136154
}
137155
this.state = {
138156
...this.state,
139-
...newState
157+
...newState,
140158
};
141-
this.state.mobile && this.state.visible ? this.backdropService.setBackdrop(this) : this.backdropService.clearBackdrop();
159+
this.state.mobile && this.state.visible
160+
? this.backdropService.setBackdrop(this)
161+
: this.backdropService.clearBackdrop();
142162
}
143163

144164
get sidebarState(): ISidebarAction {
145165
return this.state;
146166
}
147167

148168
get getMobileBreakpoint(): string {
149-
const element = this.document.firstElementChild;
150-
const mobileBreakpoint = getComputedStyle(element).getPropertyValue('--cui-mobile-breakpoint') || 'md';
151-
const breakpointValue = getComputedStyle(element).getPropertyValue(`--cui-breakpoint-${mobileBreakpoint.trim()}`) || '768px';
152-
return `${parseFloat(breakpointValue.trim()) - .02}px` || '767.98px';
169+
const element: Element = this.document.documentElement;
170+
const mobileBreakpoint =
171+
getComputedStyle(element).getPropertyValue('--cui-mobile-breakpoint') ||
172+
'md';
173+
const breakpointValue =
174+
getComputedStyle(element).getPropertyValue(
175+
`--cui-breakpoint-${mobileBreakpoint.trim()}`
176+
) || '768px';
177+
return `${parseFloat(breakpointValue.trim()) - 0.02}px` || '767.98px';
153178
}
154179

155180
constructor(
156-
@Inject(DOCUMENT) private document: any,
181+
@Inject(DOCUMENT) private document: Document,
157182
private renderer: Renderer2,
158183
private breakpointObserver: BreakpointObserver,
159184
private sidebarService: SidebarService,
@@ -164,16 +189,16 @@ export class SidebarComponent implements OnChanges, OnDestroy, OnInit {
164189

165190
@HostBinding('class')
166191
get getClasses(): any {
167-
const { mobile, unfoldable, visible } = this.sidebarState;
192+
const { mobile, visible } = this.sidebarState;
168193
return {
169194
sidebar: true,
170195
'sidebar-fixed': this.position === 'fixed' && !mobile,
171196
'sidebar-narrow': this.narrow && !this.unfoldable,
172197
'sidebar-narrow-unfoldable': this.unfoldable,
173198
'sidebar-overlaid': this.overlaid,
174199
[`sidebar-${this.size}`]: !!this.size,
175-
show: visible && this.onMobile,
176-
hide: !visible && !this.onMobile
200+
show: visible && this.#onMobile,
201+
hide: !visible,
177202
};
178203
}
179204

@@ -213,23 +238,27 @@ export class SidebarComponent implements OnChanges, OnDestroy, OnInit {
213238
}
214239

215240
setInitialState(): void {
216-
this.sidebarService.toggle({
241+
this.#stateInitial = {
217242
narrow: this.narrow,
218243
visible: this.visible,
219244
unfoldable: this.unfoldable,
220-
sidebar: this
245+
};
246+
this.sidebarService.toggle({
247+
...this.#stateInitial,
248+
sidebar: this,
221249
});
222250
}
223251

224252
private stateToggleSubscribe(subscribe: boolean = true): void {
225253
if (subscribe) {
226-
this.stateToggleSubscription = this.sidebarService.sidebarState$.subscribe((state) => {
227-
if (this === state.sidebar || this.id === state.id) {
228-
this.sidebarState = state;
229-
}
230-
});
254+
this.#stateToggleSubscription =
255+
this.sidebarService.sidebarState$.subscribe((state) => {
256+
if (this === state.sidebar || this.id === state.id) {
257+
this.sidebarState = state;
258+
}
259+
});
231260
} else {
232-
this.stateToggleSubscription.unsubscribe();
261+
this.#stateToggleSubscription.unsubscribe();
233262
}
234263
}
235264

@@ -239,21 +268,23 @@ export class SidebarComponent implements OnChanges, OnDestroy, OnInit {
239268
if (subscribe) {
240269
const layoutChanges = this.breakpointObserver.observe([onMobile]);
241270

242-
this.layoutChangeSubscription = layoutChanges.subscribe((result: BreakpointState) => {
243-
const isOnMobile = result.breakpoints[onMobile];
244-
const isUnfoldable = isOnMobile ? false : this.unfoldable;
245-
if (this.onMobile !== isOnMobile) {
246-
this.onMobile = isOnMobile;
247-
this.sidebarService.toggle({
248-
mobile: isOnMobile,
249-
unfoldable: isUnfoldable,
250-
visible: (!isOnMobile) || isUnfoldable,
251-
sidebar: this
252-
});
271+
this.#layoutChangeSubscription = layoutChanges.subscribe(
272+
(result: BreakpointState) => {
273+
const isOnMobile = result.breakpoints[onMobile];
274+
const isUnfoldable = isOnMobile ? false : this.unfoldable;
275+
if (this.#onMobile !== isOnMobile) {
276+
this.#onMobile = isOnMobile;
277+
this.sidebarService.toggle({
278+
mobile: isOnMobile,
279+
unfoldable: isUnfoldable,
280+
visible: isOnMobile ? !isOnMobile : this.#stateInitial.visible,
281+
sidebar: this,
282+
});
283+
}
253284
}
254-
});
285+
);
255286
} else {
256-
this.layoutChangeSubscription.unsubscribe();
287+
this.#layoutChangeSubscription.unsubscribe();
257288
}
258289
}
259290
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy