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: `
`,
})
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();
}
}