Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite18fd58

Browse files
committed
refactor(sidebar): signal inputs, host bindings, cleanup, use inert attribute
1 parentc7c4035 commite18fd58

File tree

1 file changed

+93
-70
lines changed

1 file changed

+93
-70
lines changed

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

Lines changed: 93 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import{
22
booleanAttribute,
33
Component,
4-
EventEmitter,
5-
HostBinding,
4+
computed,
5+
effect,
66
inject,
7-
Input,
7+
input,
8+
linkedSignal,
89
OnChanges,
910
OnDestroy,
1011
OnInit,
11-
Output,
12+
output,
1213
Renderer2,
14+
signal,
1315
SimpleChanges
1416
}from'@angular/core';
1517
import{DOCUMENT}from'@angular/common';
@@ -23,7 +25,11 @@ import { SidebarBackdropService } from '../sidebar-backdrop/sidebar-backdrop.ser
2325
selector:'c-sidebar',
2426
exportAs:'cSidebar',
2527
template:'<ng-content />',
26-
host:{class:'sidebar'}
28+
host:{
29+
class:'sidebar',
30+
'[class]':'hostClasses()',
31+
'[attr.inert]':'!this.sidebarState.visible || null'
32+
}
2733
})
2834
exportclassSidebarComponentimplementsOnChanges,OnDestroy,OnInit{
2935
readonly #document=inject<Document>(DOCUMENT);
@@ -32,14 +38,13 @@ export class SidebarComponent implements OnChanges, OnDestroy, OnInit {
3238
readonly #sidebarService=inject(SidebarService);
3339
readonly #backdropService=inject(SidebarBackdropService);
3440

35-
#visible=false;
3641
#onMobile=false;
3742
#layoutChangeSubscription!:Subscription;
3843
#stateToggleSubscription!:Subscription;
3944

40-
state:ISidebarAction={
45+
readonlystate=signal<ISidebarAction>({
4146
sidebar:this
42-
};
47+
});
4348

4449
#stateInitial={
4550
narrow:false,
@@ -48,105 +53,120 @@ export class SidebarComponent implements OnChanges, OnDestroy, OnInit {
4853
};
4954

5055
/**
51-
* Sets if the color of text should be colored for a light or dark background. [docs]
52-
*
53-
*@type 'dark' | 'light'
56+
* Sets if the color of text should be colored for a light or dark background.
57+
*@return 'dark' | 'light'
5458
*/
55-
@Input()colorScheme?:'dark'|'light';
59+
readonlycolorScheme=input<'dark'|'light'>();
5660

5761
/**
58-
* Sets html attribute id. [docs]
59-
*
60-
*@type string
62+
* Sets html attribute id.
63+
*@return string
6164
*/
62-
@Input()id?:string;
65+
readonlyid=input<string>();
6366

6467
/**
65-
* Make sidebar narrow. [docs]
66-
*@type boolean
68+
* Make sidebar narrow.
69+
*@return boolean
6770
*@default false
6871
*/
69-
@Input({transform:booleanAttribute})narrow:boolean=false;
72+
readonlynarrowInput=input(false,{transform:booleanAttribute,alias:'narrow'});
73+
74+
readonly #narrow=linkedSignal(this.narrowInput);
75+
76+
setnarrow(value){
77+
this.#narrow.set(value);
78+
}
79+
80+
getnarrow(){
81+
returnthis.#narrow();
82+
}
7083

7184
/**
7285
* Set sidebar to overlaid variant.
73-
*@type boolean
86+
*@return boolean
7487
*@default false
7588
*/
76-
@Input({transform:booleanAttribute})overlaid:boolean=false;
89+
readonlyoverlaid=input(false,{transform:booleanAttribute});
7790

7891
/**
79-
* Components placement, there’s no default placement. [docs]
80-
*@type 'start' | 'end'
92+
* Components placement, there’s no default placement.
93+
*@return 'start' | 'end'
8194
*/
82-
@Input()placement?:'start'|'end';
95+
readonlyplacement=input<'start'|'end'>();
8396

8497
/**
85-
* Place sidebar in non-static positions. [docs]
98+
* Place sidebar in non-static positions.
99+
*@return 'fixed' | 'sticky'
86100
*@default 'fixed'
87101
*/
88-
@Input()position:'fixed'|'sticky'='fixed';
102+
readonlyposition=input<'fixed'|'sticky'>('fixed');
89103

90104
/**
91-
* Size the component small, large, or extra large. [docs]
105+
* Size the component small, large, or extra large.
106+
*@return 'sm' | 'lg' | 'xl'
92107
*/
93-
@Input()size?:'sm'|'lg'|'xl';
108+
readonlysize=input<'sm'|'lg'|'xl'>();
94109

95110
/**
96-
* Expand narrowed sidebar on hover. [docs]
111+
* Expand narrowed sidebar on hover.
97112
*@type boolean
98113
*@default false
99114
*/
100-
@Input({transform:booleanAttribute})unfoldable:boolean=false;
115+
readonlyunfoldableInput=input(false,{transform:booleanAttribute,alias:'unfoldable'});
116+
117+
readonlyunfoldable=linkedSignal({
118+
source:this.unfoldableInput,
119+
computation:(value)=>value
120+
});
101121

102122
/**
103-
* Toggle the visibility of sidebar component. [docs]
123+
* Toggle the visibility of sidebar component.
104124
*@type boolean
105125
*@default false
106126
*/
107-
@Input({transform:booleanAttribute})
127+
readonlyvisibleInput=input(false,{transform:booleanAttribute,alias:'visible'});
128+
129+
readonly #visible=linkedSignal(this.visibleInput);
130+
131+
readonly #visibleEffect=effect(()=>{
132+
this.visibleChange.emit(this.#visible());
133+
});
134+
108135
setvisible(value:boolean){
109-
constvisible=value;
110-
if(this.#visible!==visible){
111-
this.#visible=visible;
112-
this.visibleChange.emit(this.#visible);
113-
}
136+
this.#visible.set(value);
114137
}
115138

116139
getvisible(){
117-
returnthis.#visible;
140+
returnthis.#visible();
118141
}
119142

120143
/**
121-
* Event emitted on visibility change. [docs]
122-
*@type boolean
144+
* Event emitted on visibility change.
145+
*@return boolean
123146
*/
124-
@Output()visibleChange=newEventEmitter<boolean>();
147+
readonlyvisibleChange=output<boolean>();
125148

126149
setsidebarState(value:ISidebarAction){
127150
constnewState=value;
128151
if('toggle'innewState){
129152
if(newState.toggle==='visible'){
130-
newState.visible=!this.state.visible;
131-
this.visible=newState.visible;
153+
newState.visible=!this.state().visible;
154+
this.#visible.set(newState.visible);
132155
}elseif(newState.toggle==='unfoldable'){
133-
newState.unfoldable=!this.state.unfoldable;
134-
this.unfoldable=newState.unfoldable;
156+
newState.unfoldable=!this.state().unfoldable;
157+
this.unfoldable.set(newState.unfoldable);
135158
}
136159
}else{
137-
this.visible=(newState.visible??this.visible)&&!this.overlaid;
160+
this.#visible.update((visible)=>(newState.visible??visible)&&!this.overlaid());
138161
}
139-
this.state={
140-
...this.state,
141-
...newState
142-
};
143-
this.state.mobile&&this.state.visible
162+
this.state.update((state)=>({ ...state, ...newState}));
163+
this.state().mobile&&this.state().visible
144164
?this.#backdropService.setBackdrop(this)
145165
:this.#backdropService.clearBackdrop();
146166
}
147167

148168
getsidebarState():ISidebarAction{
149-
returnthis.state;
169+
return{ ...this.state()};
150170
}
151171

152172
getgetMobileBreakpoint():string{
@@ -164,23 +184,26 @@ export class SidebarComponent implements OnChanges, OnDestroy, OnInit {
164184
this.#backdropService.renderer=this.#renderer;
165185
}
166186

167-
@HostBinding('class')
168-
getgetClasses():any{
169-
const{ mobile, visible}=this.sidebarState;
187+
readonlyhostClasses=computed(()=>{
188+
const{ mobile, visible}={ ...this.sidebarState};
189+
constunfoldable=this.unfoldable();
190+
constplacement=this.placement();
191+
constcolorScheme=this.colorScheme();
192+
constsize=this.size();
170193
return{
171194
sidebar:true,
172-
'sidebar-fixed':this.position==='fixed'&&!mobile,
173-
'sidebar-narrow':this.narrow&&!this.unfoldable,
174-
'sidebar-narrow-unfoldable':this.unfoldable,
175-
'sidebar-overlaid':this.overlaid,
176-
[`sidebar-${this.placement}`]:!!this.placement,
177-
[`sidebar-${this.colorScheme}`]:!!this.colorScheme,
178-
[`sidebar-${this.size}`]:!!this.size,
195+
'sidebar-fixed':this.position()==='fixed'&&!mobile,
196+
'sidebar-narrow':this.#narrow()&&!unfoldable,
197+
'sidebar-narrow-unfoldable':unfoldable,
198+
'sidebar-overlaid':this.overlaid(),
199+
[`sidebar-${placement}`]:!!placement,
200+
[`sidebar-${colorScheme}`]:!!colorScheme,
201+
[`sidebar-${size}`]:!!size,
179202
show:visible,
180203
// show: visible && this.#onMobile, //todo: check
181204
hide:!visible
182205
};
183-
}
206+
});
184207

185208
ngOnInit():void{
186209
this.setInitialState();
@@ -194,7 +217,7 @@ export class SidebarComponent implements OnChanges, OnDestroy, OnInit {
194217
}
195218

196219
ngOnChanges(changes:SimpleChanges):void{
197-
constoldStateMap=newMap(Object.entries(this.state));
220+
constoldStateMap=newMap(Object.entries(this.state()));
198221
constnewStateMap=newMap();
199222
newStateMap.set('sidebar',this);
200223

@@ -219,9 +242,9 @@ export class SidebarComponent implements OnChanges, OnDestroy, OnInit {
219242

220243
setInitialState():void{
221244
this.#stateInitial={
222-
narrow:this.narrow,
223-
visible:this.visible,
224-
unfoldable:this.unfoldable
245+
narrow:this.#narrow(),
246+
visible:this.#visible(),
247+
unfoldable:this.unfoldable()
225248
};
226249
this.#sidebarService.toggle({
227250
...this.#stateInitial,
@@ -232,8 +255,8 @@ export class SidebarComponent implements OnChanges, OnDestroy, OnInit {
232255
privatestateToggleSubscribe(subscribe:boolean=true):void{
233256
if(subscribe){
234257
this.#stateToggleSubscription=this.#sidebarService.sidebarState$.subscribe((state)=>{
235-
if(this===state.sidebar||this.id===state.id){
236-
this.sidebarState=state;
258+
if(this===state.sidebar||this.id()===state.id){
259+
this.sidebarState={ ...state};
237260
}
238261
});
239262
}else{
@@ -249,7 +272,7 @@ export class SidebarComponent implements OnChanges, OnDestroy, OnInit {
249272

250273
this.#layoutChangeSubscription=layoutChanges.subscribe((result:BreakpointState)=>{
251274
constisOnMobile=result.breakpoints[onMobile];
252-
constisUnfoldable=isOnMobile ?false :this.unfoldable;
275+
constisUnfoldable=isOnMobile ?false :this.unfoldable();
253276
if(this.#onMobile!==isOnMobile){
254277
this.#onMobile=isOnMobile;
255278
this.#sidebarService.toggle({

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp