import { ChangeDetectionStrategy, Component, Input, Output, EventEmitter, signal, ChangeDetectorRef, inject, } from '@angular/core'; import { CommonModule } from '@angular/common'; export interface AccordionItem { id: string; title: string; content: string; disabled?: boolean; } @Component({ selector: 'mayvio-accordion', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `

{{ item.content }}
`, }) export class AccordionComponent { private cdr = inject(ChangeDetectorRef); @Input() items: AccordionItem[] = []; @Input() allowMultiple = false; @Input() className = ''; private internalExpandedIds = signal([]); private _expandedIds?: string[]; @Input() set expandedIds(val: string[] | undefined) { this._expandedIds = val; this.cdr.markForCheck(); } get expandedIds(): string[] | undefined { return this._expandedIds; } @Input() set defaultExpandedIds(val: string[]) { this.internalExpandedIds.set([...val]); } @Output() expandedChange = new EventEmitter(); get currentExpandedIds(): string[] { return this._expandedIds !== undefined ? this._expandedIds : this.internalExpandedIds(); } isExpanded(id: string): boolean { return this.currentExpandedIds.includes(id); } toggleItem(id: string): void { const item = this.items.find((i) => i.id === id); if (item?.disabled) return; let nextExpandedIds: string[]; const isExpanded = this.isExpanded(id); if (this.allowMultiple) { if (isExpanded) { nextExpandedIds = this.currentExpandedIds.filter((item) => item !== id); } else { nextExpandedIds = [...this.currentExpandedIds, id]; } } else { if (isExpanded) { nextExpandedIds = []; } else { nextExpandedIds = [id]; } } if (this._expandedIds === undefined) { this.internalExpandedIds.set(nextExpandedIds); } this.expandedChange.emit(nextExpandedIds); this.cdr.markForCheck(); } }