UNPKG

@engie-group/fluid-design-system-angular

Version:

Fluid Design System Angular

122 lines (103 loc) 3.15 kB
import {NgIf, NgIfContext, NgTemplateOutlet} from '@angular/common'; import { AfterContentInit, booleanAttribute, Component, ContentChildren, ElementRef, inject, Input, QueryList, TemplateRef, ViewEncapsulation } from '@angular/core'; import {EngieTemplateDirective} from '../../directives/engie-template.directive'; import {TSizeVariants} from '../../models/size-variant.model'; import {AccordionComponent} from '../accordion/accordion.component'; import {IconComponent} from '../icon/icon.component'; @Component({ selector: 'details[nj-accordion-item]', templateUrl: './accordion-item.component.html', styleUrls: ['./accordion-item.component.scss'], standalone: true, encapsulation: ViewEncapsulation.None, imports: [ IconComponent, NgIf, NgTemplateOutlet ], host: { '[class]': 'classes', '(click)': 'handleClick($event)', } }) export class AccordionItemComponent implements AfterContentInit { private element: ElementRef<HTMLDetailsElement> = inject(ElementRef); private accordion = inject(AccordionComponent); protected iconTemplate?: TemplateRef<unknown>; protected headerTemplate?: TemplateRef<NgIfContext<string>>; /** * Size of the accordion item */ @Input() scale?: Extract<TSizeVariants, 'md' | 'lg'>; /** * Whether the toggle icon is place at the start of the item or not. */ @Input({transform: booleanAttribute}) hasLeadingToggleIcon?: boolean; /** * Whether the toggle use the alternative icons (plus/minus) or the default ones (arrow). */ @Input({transform: booleanAttribute}) useAlternativeToggleIcon?: boolean; /** * This attribute enables multiple <details> elements to be connected, with only one open at a time. */ @Input() name?: string; /** * Item header */ @Input() label?: string; @ContentChildren(EngieTemplateDirective) protected templateDirectives?: QueryList<EngieTemplateDirective>; protected get classes() { const classes = ['nj-accordion-item']; if (this.scale && this.scale !== 'md') { classes.push(`nj-accordion-item--${this.scale}`); } if (this.hasLeadingToggleIcon) { classes.push('nj-accordion-item--leading-toggle'); } return classes; } ngAfterContentInit() { this.templateDirectives.forEach((templateDirective) => { if (templateDirective?.selector === 'icon') { this.iconTemplate = templateDirective.templateRef; } if (templateDirective?.selector === 'header') { this.headerTemplate = templateDirective.templateRef as TemplateRef<NgIfContext<string>>; } }); } protected handleClick(event: MouseEvent) { if (this.name && !this.element.nativeElement.open) { event.preventDefault(); this.accordion.collapseAllItems(this.name); this.expand(); } } /** * Expand the accordion item programmatically */ expand() { if (this.element) { this.element.nativeElement.open = true; } } /** * Collapse the accordion item programmatically */ collapse() { if (this.element) { this.element.nativeElement.open = false; } } }