Accordion
Abstract base directive for accordion components. This package provides the base class for creating custom accordion implementations.
Usage
<smart-accordion [options]="options" [(show)]="open">
<span accordionHeader>What is your refund policy?</span>
<p accordionBody>You can request a full refund within 30 days of purchase.</p>
</smart-accordion>
Base Class API
Inputs
| Input | Type | Default | Description |
|---|---|---|---|
show | ModelSignal<boolean> | false | Two-way binding for open state |
options | InputSignal<IAccordionOptions | undefined> | undefined | Accordion configuration |
cssClass | InputSignal<string> | '' | External CSS classes |
headerTpl | InputSignal<TemplateRef> | required | Header template |
bodyTpl | InputSignal<TemplateRef> | required | Body template |
IAccordionOptions
openis the initial state. When it istrueon first render andshowhas not been set totrueby the consumer,AccordionBaseComponent.ngOnInitsetsshowtotrueonce and emitsshowChange, so both<smart-accordion>(default) and<smart-accordion-preset>start expanded and a bound[(show)]is updated totrue. It is applied only once: later changes tooptions.openare ignored and later toggles /[(show)]writes are never overridden. Bind[(show)]to a signal when combining it withopen; a plain class field updated during the first change detection raisesNG0100(ExpressionChangedAfterItHasBeenChecked) in dev mode.disabledmakestoggle()a no-op.animatedis deprecated: no variant (default or preset) animates expand/collapse.
Computed Properties
| Property | Type | Description |
|---|---|---|
sharedContainerClasses | Signal<string[]> | Divider, rounded, border classes with dark mode support |
Methods
| Method | Description |
|---|---|
toggle() | Toggles show signal (no-op if disabled) |
ngOnInit() | Applies options.open as the initial state (sets show to true once) |
Extending the base class
import { NgTemplateOutlet } from '@angular/common';
import {
ChangeDetectionStrategy,
Component,
computed,
signal,
ViewEncapsulation,
} from '@angular/core';
import {
AccordionBaseComponent,
IAccordionOptions,
} from '@smartsoft001/angular';
@Component({
selector: 'docs-custom-accordion',
imports: [NgTemplateOutlet],
template: `
<div [class]="containerClasses()">
<button
type="button"
class="docs-accordion__header"
[disabled]="options()?.disabled ?? false"
[attr.aria-expanded]="show()"
(click)="toggle()"
>
<ng-container [ngTemplateOutlet]="headerTpl()" />
<span aria-hidden="true">{{ show() ? '-' : '+' }}</span>
</button>
@if (show()) {
<div class="docs-accordion__body">
<ng-container [ngTemplateOutlet]="bodyTpl()" />
</div>
}
</div>
`,
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CustomAccordionComponent extends AccordionBaseComponent {
containerClasses = computed(() =>
['docs-accordion', ...this.sharedContainerClasses(), this.cssClass()]
.filter(Boolean)
.join(' '),
);
}
// The accordion has no standard-component token, so a custom implementation is
// rendered directly by its own selector instead of being injected into
// <smart-accordion>. The required headerTpl / bodyTpl inputs are <ng-template>
// references supplied by the host.
@Component({
selector: 'docs-accordion-custom-example',
imports: [CustomAccordionComponent],
template: `
<ng-template #headerTpl
>What is the best thing about Switzerland?</ng-template
>
<ng-template #bodyTpl
>I don't know, but the flag is a big plus.</ng-template
>
<docs-custom-accordion
[headerTpl]="headerTpl"
[bodyTpl]="bodyTpl"
[(show)]="open"
[options]="options"
/>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AccordionCustomExampleComponent {
open = signal(false);
options: IAccordionOptions = { disabled: false };
}
AccordionPresetComponent (<smart-accordion-preset>)
A fully styled, drop-in accordion concrete based on the Preline bordered accordion (FRA-210). It extends AccordionBaseComponent, so it consumes the exact same contract as AccordionDefaultComponent: the headerTpl / bodyTpl required template inputs, the show two-way model, options and cssClass.
Not token-swappable. Unlike most preset variations in this library, the accordion has no
ACCORDION_STANDARD_COMPONENT_TOKENand the<smart-accordion>wrapper hard-codes<smart-accordion-default>. There is no NgComponentOutlet/DI seam, so the preset cannot be registered to restyle<smart-accordion>. Use it directly via the<smart-accordion-preset>selector and supply the templates yourself.
Expand/collapse is driven entirely by the inherited show model signal plus @if — no Preline JS runtime is required. The header arrow is an inline chevron (down when collapsed, up when expanded) and the container border becomes visible only while open.
Source
The component lives in packages/shared/angular/src/lib/components/accordion and is documented for Claude Code by the angular-components-accordion skill.