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

Commit3578bbd

Browse files
committed
refactor(accordion): input signals, host bindings
1 parentaf82588 commit3578bbd

File tree

6 files changed

+57
-56
lines changed

6 files changed

+57
-56
lines changed
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import{AccordionButtonDirective}from'./accordion-button.directive';
2+
import{TestBed}from'@angular/core/testing';
23

34
describe('AccordionButtonDirective',()=>{
45
it('should create an instance',()=>{
5-
constdirective=newAccordionButtonDirective();
6-
expect(directive).toBeTruthy();
6+
TestBed.runInInjectionContext(()=>{
7+
constdirective=newAccordionButtonDirective();
8+
expect(directive).toBeTruthy();
9+
});
710
});
811
});
Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,30 @@
1-
import{Directive,HostBinding,Input}from'@angular/core';
1+
import{computed,Directive,input}from'@angular/core';
22

33
@Directive({
44
selector:'[cAccordionButton]',
55
standalone:true,
6-
host:{class:'accordion-button'}
6+
host:{'[class]':'hostClasses()','[attr.type]':'type()','[attr.aria-expanded]':'ariaExpanded()'}
77
})
88
exportclassAccordionButtonDirective{
99
/**
1010
* Toggles an accordion button collapsed state. Use in accordionHeaderTemplate. [docs]
1111
*@type boolean
1212
*/
13-
@Input()collapsed!:boolean;
13+
readonlycollapsed=input<boolean|undefined>(undefined);
1414

1515
/**
1616
* Default type for cAccordionButton. [docs]
1717
*@type string
1818
*@default 'button'
1919
*/
20-
@HostBinding('attr.type')
21-
@Input()
22-
type:string='button';
20+
readonlytype=input('button');
2321

24-
@HostBinding('class')
25-
gethostClasses():any{
22+
readonlyhostClasses=computed(()=>{
2623
return{
2724
'accordion-button':true,
28-
collapsed:this.collapsed
25+
collapsed:this.collapsed()
2926
};
30-
}
27+
});
3128

32-
@HostBinding('attr.aria-expanded')getariaExpanded():boolean{
33-
return!this.collapsed;
34-
}
29+
readonlyariaExpanded=computed(()=>!this.collapsed());
3530
}

‎projects/coreui-angular/src/lib/accordion/accordion-item/accordion-item.component.html‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1+
@let tmpl = templates();
12
<ng-container>
23
<divclass="accordion-header">
3-
<ng-container*ngTemplateOutlet="templates['accordionHeaderTemplate'] || defaultAccordionHeaderTemplate; context: itemContext"/>
4+
<ng-container*ngTemplateOutlet="tmpl['accordionHeaderTemplate'] || defaultAccordionHeaderTemplate; context: itemContext"/>
45
</div>
56
<divclass="accordion-collapse"cCollapse[visible]="visible"[attr.aria-expanded]="visible"[id]="contentId">
6-
<ng-container*ngTemplateOutlet="templates['accordionBodyTemplate'] || defaultAccordionBodyTemplate; context: itemContext"/>
7+
<ng-container*ngTemplateOutlet="tmpl['accordionBodyTemplate'] || defaultAccordionBodyTemplate; context: itemContext"/>
78
</div>
89
</ng-container>
910

1011
<ng-template#defaultAccordionHeaderTemplate>
1112
<buttoncAccordionButton[collapsed]="!visible"[attr.aria-controls]="contentId"(click)="toggleItem()">
1213
<ng-container
13-
*ngTemplateOutlet="templates['accordionHeader'] || defaultAccordionHeaderContentTemplate; context: itemContext">
14+
*ngTemplateOutlet="tmpl['accordionHeader'] || defaultAccordionHeaderContentTemplate; context: itemContext">
1415
</ng-container>
1516
</button>
1617
</ng-template>
@@ -22,7 +23,7 @@
2223
<ng-template#defaultAccordionBodyTemplate>
2324
<divclass="accordion-body">
2425
<ng-container
25-
*ngTemplateOutlet="templates['accordionBody'] || defaultAccordionBodyContentTemplate; context: itemContext">
26+
*ngTemplateOutlet="tmpl['accordionBody'] || defaultAccordionBodyContentTemplate; context: itemContext">
2627
</ng-container>
2728
</div>
2829
</ng-template>
Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import{
2-
AfterContentInit,
32
booleanAttribute,
43
Component,
5-
ContentChildren,
4+
computed,
5+
contentChildren,
6+
inject,
67
Input,
78
OnDestroy,
89
OnInit,
9-
QueryList
10+
TemplateRef
1011
}from'@angular/core';
1112
import{NgTemplateOutlet}from'@angular/common';
1213

@@ -26,15 +27,15 @@ let nextId = 0;
2627
imports:[AccordionButtonDirective,NgTemplateOutlet,CollapseDirective],
2728
host:{class:'accordion-item'}
2829
})
29-
exportclassAccordionItemComponentimplementsOnInit,OnDestroy,AfterContentInit{
30-
constructor(privateaccordionService:AccordionService){}
30+
exportclassAccordionItemComponentimplementsOnInit,OnDestroy{
31+
readonly #accordionService=inject(AccordionService);
3132

3233
/**
3334
* Toggle an accordion item programmatically
3435
*@type boolean
3536
*@default false
3637
*/
37-
@Input({transform:booleanAttribute})visible:string|boolean=false;
38+
@Input({transform:booleanAttribute})visible:boolean=false;
3839

3940
@Input()
4041
setopen(value:boolean){
@@ -47,25 +48,32 @@ export class AccordionItemComponent implements OnInit, OnDestroy, AfterContentIn
4748
}
4849

4950
contentId=`accordion-item-${nextId++}`;
50-
itemContext={$implicit:<boolean>this.visible};
51-
templates:any={};
52-
@ContentChildren(TemplateIdDirective,{descendants:true})contentTemplates!:QueryList<TemplateIdDirective>;
51+
52+
getitemContext(){
53+
return{$implicit:<boolean>this.visible};
54+
}
55+
56+
readonlycontentTemplates=contentChildren(TemplateIdDirective,{descendants:true});
57+
58+
readonlytemplates=computed(()=>{
59+
returnthis.contentTemplates().reduce(
60+
(acc,child)=>{
61+
acc[child.id]=child.templateRef;
62+
returnacc;
63+
},
64+
{}asRecord<string,TemplateRef<any>>
65+
);
66+
});
5367

5468
ngOnInit():void{
55-
this.accordionService.addItem(this);
69+
this.#accordionService.addItem(this);
5670
}
5771

5872
ngOnDestroy():void{
59-
this.accordionService.removeItem(this);
73+
this.#accordionService.removeItem(this);
6074
}
6175

6276
toggleItem():void{
63-
this.accordionService.toggleItem(this);
64-
}
65-
66-
ngAfterContentInit():void{
67-
this.contentTemplates.forEach((child:TemplateIdDirective)=>{
68-
this.templates[child.id]=child.templateRef;
69-
});
77+
this.#accordionService.toggleItem(this);
7078
}
7179
}

‎projects/coreui-angular/src/lib/accordion/accordion.service.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import{Injectable}from'@angular/core';
2-
import{AccordionItemComponent}from'./accordion-item/accordion-item.component';
2+
importtype{AccordionItemComponent}from'./accordion-item/accordion-item.component';
33

44
@Injectable()
55
exportclassAccordionService{
Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import{booleanAttribute,Component,HostBinding,inject,Input}from'@angular/core';
1+
import{booleanAttribute,Component,computed,effect,inject,input}from'@angular/core';
22

33
import{AccordionService}from'../accordion.service';
44

@@ -9,35 +9,29 @@ import { AccordionService } from '../accordion.service';
99
exportAs:'cAccordionItem',
1010
providers:[AccordionService],
1111
standalone:true,
12-
host:{class:'accordion'}
12+
host:{'[class]':'hostClasses()'}
1313
})
1414
exportclassAccordionComponent{
15-
#accordionService=inject(AccordionService);
15+
readonly#accordionService=inject(AccordionService);
1616

1717
/**
1818
* Removes the default background-color, some borders, and some rounded corners to render accordions edge-to-edge with their parent container.
1919
*@type boolean
2020
*/
21-
@Input({transform:booleanAttribute})flush:boolean=false;
21+
readonlyflush=input(false,{transform:booleanAttribute});
2222

2323
/**
2424
* Make accordion items stay open when another item is opened
2525
*@type boolean
2626
*/
27-
@Input({transform:booleanAttribute})
28-
setalwaysOpen(value:boolean){
29-
this.#accordionService.alwaysOpen=value;
30-
}
27+
readonlyalwaysOpen=input(false,{transform:booleanAttribute});
3128

32-
getalwaysOpen():boolean{
33-
returnthis.#accordionService.alwaysOpen;
34-
}
29+
readonly #alwaysOpenEffect=effect(()=>{
30+
this.#accordionService.alwaysOpen=this.alwaysOpen();
31+
});
3532

36-
@HostBinding('class')
37-
gethostClasses():any{
38-
return{
39-
accordion:true,
40-
'accordion-flush':this.flush
41-
};
42-
}
33+
readonlyhostClasses=computed<Record<string,boolean>>(()=>({
34+
accordion:true,
35+
'accordion-flush':this.flush()
36+
}));
4337
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp