Displays collapsible content panels for presenting information in a limited amount of space
The accordion component builds on top of the collapse directive to provide a list of items, with collapsible bodies that are collapsed or expanded by clicking on the item's header.
The easiest way to add an accordion component to your app (will be added to the root module)
Basic
Click headers to expand/collapse content that is broken into logical sections, much like tabs.
<accordion>
<accordion-group heading="Static Header">
This content is straight in the template.
</accordion-group>
<accordion-group heading="Another group">
<p>Some content</p>
</accordion-group>
<accordion-group heading="Another group">
<p>Some content</p>
</accordion-group>
<accordion-group heading="Another group">
<p>Some content</p>
</accordion-group>
</accordion>
import { Component } from '@angular/core';
@Component({
// eslint-disable-next-line @angular-eslint/component-selector
selector: 'demo-accordion-basic',
templateUrl: './basic.html',
standalone: false
})
export class DemoAccordionBasicComponent {}
With animation
Use input property or config property isAnimated to enable/disable animation
<accordion [isAnimated]="true">
<accordion-group heading="Static Header">
This content is straight in the template.
</accordion-group>
<accordion-group heading="Another group">
<p>Some content</p>
</accordion-group>
<accordion-group heading="Another group">
<p>Some content</p>
</accordion-group>
<accordion-group heading="Another group">
<p>Some content</p>
</accordion-group>
</accordion>
import { Component } from '@angular/core';
@Component({
// eslint-disable-next-line @angular-eslint/component-selector
selector: 'demo-accordion-animation',
templateUrl: './animated.html',
standalone: false
})
export class DemoAccordionAnimatedComponent {}
Group opening event
Accordion with isOpenChange event listener.
<accordion>
<accordion-group heading="Group without isOpenChange event listener">
<p>Some content</p>
</accordion-group>
<accordion-group heading="Group with isOpenChange event listener" (isOpenChange)="log($event)">
<p>Some content</p>
</accordion-group>
<accordion-group heading="Group with isOpenChange event listener" (isOpenChange)="log($event)">
<p>Some content</p>
</accordion-group>
</accordion>
import { Component } from '@angular/core';
@Component({
// eslint-disable-next-line @angular-eslint/component-selector
selector: 'demo-accordion-open-event',
templateUrl: './open-event.html',
standalone: false
})
export class DemoAccordionOpenEventComponent {
log(event: boolean) {
console.log(`Accordion has been ${event ? 'opened' : 'closed'}`);
}
}
Custom HTML
<accordion>
<accordion-group>
<button
class="btn btn-link btn-block justify-content-between d-flex w-100 shadow-none"
accordion-heading type="button">
<div class="pull-left float-left">I can have markup!</div>
<span class="badge badge-secondary bg-secondary float-right pull-right">Some HTML here</span>
</button>
This is just some content to illustrate fancy headings.
</accordion-group>
<accordion-group>
<button class="btn btn-link shadow-none" accordion-heading type="button">
I can have markup, too!
</button>
<span class="badge badge-secondary bg-secondary center">And some HTML here</span>
</accordion-group>
</accordion>
import { Component } from '@angular/core';
import { getBsVer, IBsVersion } from 'ngx-bootstrap/utils';
@Component({
// eslint-disable-next-line @angular-eslint/component-selector
selector: 'demo-accordion-custom-html',
templateUrl: './custom-html.html',
standalone: false
})
export class DemoAccordionCustomHTMLComponent {
get _getBsVer(): IBsVersion {
return getBsVer();
}
}
Disabled
<p>
<button type="button" class="btn btn-primary btn-sm" (click)="isFirstDisabled = !isFirstDisabled">
Enable / Disable first panel
</button>
</p>
<accordion>
<accordion-group heading="Static Header"
[isDisabled]="isFirstDisabled">
This content is straight in the template.
</accordion-group>
<accordion-group heading="Content 1">
<p>accordion 1</p>
</accordion-group>
<accordion-group heading="Content 2">
<p>accordion 2</p>
</accordion-group>
</accordion>
import { Component } from '@angular/core';
@Component({
// eslint-disable-next-line @angular-eslint/component-selector
selector: 'demo-accordion-disabled',
templateUrl: './disabled.html',
standalone: false
})
export class DemoAccordionDisabledComponent {
isFirstDisabled = false;
}
Initially opened
<accordion>
<accordion-group heading="Content 1">
<p>accordion 1</p>
</accordion-group>
<accordion-group heading="Initially expanded"
[isOpen]="isFirstOpen">
This content is straight in the template.
</accordion-group>
<accordion-group heading="Content 2">
<p>accordion 3</p>
</accordion-group>
</accordion>
import { Component } from '@angular/core';
@Component({
// eslint-disable-next-line @angular-eslint/component-selector
selector: 'demo-accordion-opened',
templateUrl: './opened.html',
standalone: false
})
export class DemoAccordionOpenedComponent {
isFirstOpen = true;
}
Dynamic accordion
<p>
<button type="button" class="btn btn-primary btn-sm" (click)="addGroupItem()">
Add Group Item
</button>
</p>
<accordion>
@for (group of groups; track group) {
<accordion-group [heading]="group.title">
{{ group?.content }}
</accordion-group>
}
</accordion>
import { Component } from '@angular/core';
@Component({
// eslint-disable-next-line @angular-eslint/component-selector
selector: 'demo-accordion-dynamic',
templateUrl: './dynamic.html',
standalone: false
})
export class DemoAccordionDynamicComponent {
groups = [
{
title: 'Dynamic Group Header - 1',
content: 'Dynamic Group Body - 1'
},
{
title: 'Dynamic Group Header - 2',
content: 'Dynamic Group Body - 2'
}
];
addGroupItem(): void {
this.groups.push({
title: `Dynamic Group Header - ${this.groups.length + 1}`,
content: `Dynamic Group Body - ${this.groups.length + 1}`
});
}
}
Dynamic body content
<accordion>
<accordion-group heading="Dynamic Body Content">
<p>The body of the accordion group grows to fit the contents</p>
<button type="button" class="btn btn-primary btn-sm" (click)="addItem()">Add
Item
</button>
<button type="button" class="btn btn-primary btn-sm ms-3 ml-3" (click)="removeItem()">Remove
Item
</button>
@for (item of items; track item) {
<div>{{item}}</div>
}
</accordion-group>
<accordion-group heading="Content 2">
<p>accordion 2</p>
</accordion-group>
<accordion-group heading="Content 3">
<p>accordion 3</p>
</accordion-group>
</accordion>
import { Component } from '@angular/core';
@Component({
// eslint-disable-next-line @angular-eslint/component-selector
selector: 'demo-accordion-dynamic-body',
templateUrl: './dynamic-body.html',
standalone: false
})
export class DemoAccordionDynamicBodyComponent {
items = ['Item 1', 'Item 2', 'Item 3'];
addItem(): void {
this.items.push(`Item ${this.items.length + 1}`);
}
removeItem(): void {
this.items = this.items.slice(0, this.items.length - 1);
}
}
Manual toggle
accordion 3
<p>
<button type="button" class="btn btn-primary btn-sm"
(click)="isOpen = !isOpen">Toggle last panel
</button>
</p>
<accordion>
<accordion-group heading="Content 1">
<p>accordion 1</p>
</accordion-group>
<accordion-group heading="Content 2">
<p>accordion 2</p>
</accordion-group>
<accordion-group [isOpen]="isOpen" heading="Last panel">
<p>accordion 3</p>
</accordion-group>
</accordion>
import { Component } from '@angular/core';
@Component({
// eslint-disable-next-line @angular-eslint/component-selector
selector: 'demo-accordion-manual-toggle',
templateUrl: './manual-toggle.html',
standalone: false
})
export class DemoAccordionManualToggleComponent {
isOpen = true;
}
Open only one at a time
<div class="checkbox">
<label>
<input type="checkbox" [(ngModel)]="oneAtATime">
Open only one at a time
</label>
</div>
<accordion [closeOthers]="oneAtATime">
<accordion-group heading="Header">
This content is straight in the template.
</accordion-group>
<accordion-group heading="Content 1">
<p>Content 1</p>
</accordion-group>
<accordion-group heading="Content 2">
<p>Content 2</p>
</accordion-group>
</accordion>
import { Component } from '@angular/core';
@Component({
// eslint-disable-next-line @angular-eslint/component-selector
selector: 'demo-accordion-one-time',
templateUrl: './one-at-a-time.html',
standalone: false
})
export class DemoAccordionOneAtATimeComponent {
oneAtATime = true;
}
Styling
<accordion>
<accordion-group heading="Static Header, initially expanded"
[panelClass]="customClass"
[isOpen]="isFirstOpen">
This content is straight in the template.
</accordion-group>
<accordion-group heading="Content 1">
<p>accordion 1</p>
</accordion-group>
<accordion-group heading="Content 2" panelClass="customClass">
<p>accordion 2</p>
</accordion-group>
</accordion>
import { Component } from '@angular/core';
@Component({
// eslint-disable-next-line @angular-eslint/component-selector
selector: 'demo-accordion-styling',
templateUrl: './styling.html',
standalone: false
})
export class DemoAccordionStylingComponent {
customClass = 'customClass';
isFirstOpen = true;
}
Configuring defaults
<accordion [isAnimated]="true">
<accordion-group heading="Header">
This content is straight in the template.
</accordion-group>
<accordion-group heading="Content 1">
<p>Content 1</p>
</accordion-group>
<accordion-group heading="Content 2">
<p>Content 2</p>
</accordion-group>
</accordion>
import { Component } from '@angular/core';
import { AccordionConfig } from 'ngx-bootstrap/accordion';
// such override allows to keep some initial values
export function getAccordionConfig(): AccordionConfig {
return Object.assign(new AccordionConfig(), { closeOthers: true });
}
@Component({
// eslint-disable-next-line @angular-eslint/component-selector
selector: 'demo-accordion-config',
templateUrl: './config.html',
providers: [{ provide: AccordionConfig, useFactory: getAccordionConfig }],
standalone: false
})
export class DemoAccordionConfigComponent {}
API Reference
ng add ngx-bootstrap --component accordion
### Standalone component usage
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AccordionComponent, AccordionPanelComponent } from 'ngx-bootstrap/accordion';
@Component({
standalone: true,
imports: [
BrowserAnimationsModule,
AccordionComponent,
AccordionPanelComponent
...
]
})
export class AppComponent(){}
Also should be added web-animations-js polyfill for IE browser (Edge)
### Module usage
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AccordionModule } from 'ngx-bootstrap/accordion';
@NgModule({
imports: [
BrowserAnimationsModule,
AccordionModule,
...
]
})
export class AppModule(){}
Also should be added web-animations-js polyfill for IE browser (Edge)
AccordionComponent
Displays collapsible content panels for presenting information in a limited amount of space.
| Selector | |
AccordionPanelComponent
Accordion heading
Instead of using heading attribute on the accordion-group, you can use
an accordion-heading attribute on any element inside of a group that
will be used as group's header template.
| Selector | |
AccordionConfig
Configuration service, provides default values for the AccordionComponent.
Properties
closeOthers | Type: booleanDefault value: falseWhether the other panels should be closed when a panel is opened |
isAnimated | Type: booleanDefault value: falseturn on/off animation |
Basic
With animation
Group opening event
Custom HTML
Disabled
Initially opened
Dynamic accordion
Dynamic body content
Manual toggle
accordion 3
