Ionic 5 accordion List (Live Demo + Source code)
Today we are going to learn how to create an ionic 5 accordion list.
What’s an ionic 5 accordion list?
Accordion list is a list which can expand and collapse. It saves the page space and helps the user to read a large list of content easily.
Here is the live demo of accordion list and source code link given below the demo screen.
Live Demo
Accordion list with ionic component
Ionic 5 components are very easy to use and useful. So, we are going to use an ionic component to create our accordion list.
Run the following command to generate the ionic component.
ionic g component components/accordion
And now put the below content into accordion.component.ts
import { Component, Input, OnInit } from '@angular/core'; @Component({ selector: 'app-accordion', templateUrl: './accordion.component.html', styleUrls: ['./accordion.component.scss'], }) export class AccordionComponent implements OnInit { @Input() name : string; @Input() description : string; isListItemOpened : boolean = false; constructor() { } ngOnInit() {} toggleAccordion(): void { this.isListItemOpened = !this.isListItemOpened; } }
The logic behind the ionic accordion component is that we are taking a variable called isListItemOpened: boolean
to determine the list item state.
If it is false then css will hide the item content otherwise the item will be expanded.
Here is the html content of the component.
<div class="accordion-container" (click)="toggleAccordion()" [ngClass]="isListItemOpened ? 'open' : ''"> <h1> {{ name }} <div class="arrow"></div> </h1> <div class="content"> <p> {{ description }} </p> </div> </div>
We need css to collapse and expand the list item with the use of a class selector.
/* Arrow Animation Styles Start */ .accordion-container, .accordion-container .arrow, .accordion-container .arrow:before, .accordion-container .arrow:after, .accordion-container .content { transition: all .3s ease-in-out; } .accordion-container .arrow { position: absolute; top: 50%; right: 5%; } .accordion-container .arrow, .accordion-container .arrow:before, .accordion-container .arrow:after { border-radius: 25px; } .accordion-container .arrow:before { content: " "; width: 15px; height: 4px; left: 50%; margin-left: -8px; background-color: black; position: absolute; transform: rotate(45deg); } .accordion-container .arrow:after { content: " "; width: 15px; height: 4px; background-color: black; position: absolute; right: -15px; transform: rotate(-45deg); } .accordion-container.open .arrow:before { transform: rotate(-45deg); } .accordion-container.open .arrow:after { transform: rotate(45deg); } /* Arrow Animation Styles End */ .accordion-container h1 { font-size: 1rem; position: relative; width: 100%; display: block; margin: 0px; padding-right: 28px; } .accordion-container p { font-size: 0.9rem; color: #464545; } .accordion-container { display: block; cursor: pointer; position: relative; background: white; padding: 10px; margin: 10px; } .accordion-container.open { cursor: default; } .accordion-container:hover { background: #ebebeb; } .accordion-container.open:hover { background: #ffffff; } .accordion-container .content { opacity: 0; display: none; } .accordion-container.open .content { display: block; opacity: 1; }
Add Accordion component to page module
In our case, tab1.module.ts is a page module and we need to import our component here like given below.
import { IonicModule } from '@ionic/angular'; import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { Tab1Page } from './tab1.page'; import { ExploreContainerComponentModule } from '../explore-container/explore-container.module'; import { Tab1PageRoutingModule } from './tab1-routing.module'; import { AccordionComponent } from '../components/accordion/accordion.component'; @NgModule({ entryComponents: [AccordionComponent], imports: [ IonicModule, CommonModule, FormsModule, ExploreContainerComponentModule, Tab1PageRoutingModule ], declarations: [Tab1Page, AccordionComponent] }) export class Tab1PageModule {}
Then in the html page we can use the component like this.
<ion-content [fullscreen]="true" class="bg-gray"> <ion-header collapse="condense"> <ion-toolbar> <ion-title size="large">Tab 1</ion-title> </ion-toolbar> </ion-header> <app-accordion *ngFor="let item of questions" name="{{ item?.question }}" description="{{ item?.answer }}"></app-accordion> </ion-content>
Ionic 5 accordion list with angular material
We can use angular material because we are using ionic-angular for this tutorial. So, we can use an angular material expansion panel to create our accordion.
Install angular material
Run the following command at the project root directory to install the angular material.
ng add @angular/material
If you have encountered any version related issue then you can install individual items for the latest available version then remove the package.lock.json
or rename it.
Import the angular material UI component
Now, to use angular material components we need to import each required module to the app.module.ts
or to the particular module page.
In our case we are importing angular material in the tab2.module.ts
and then it will be available to the tab2.page.ts
import { IonicModule } from '@ionic/angular'; import { RouterModule } from '@angular/router'; import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { Tab2Page } from './tab2.page'; import { ExploreContainerComponentModule } from '../explore-container/explore-container.module'; import { Tab2PageRoutingModule } from './tab2-routing.module'; import { MatExpansionModule } from '@angular/material/expansion'; import { MatInputModule } from '@angular/material/input'; import { MatButtonModule } from '@angular/material/button'; import { MatButtonToggleModule } from '@angular/material/button-toggle'; @NgModule({ imports: [ IonicModule, CommonModule, FormsModule, ExploreContainerComponentModule, Tab2PageRoutingModule, MatExpansionModule, MatInputModule, MatButtonModule, MatButtonToggleModule ], declarations: [Tab2Page] }) export class Tab2PageModule {}
import { Component, ViewChild } from '@angular/core'; import {MatAccordion} from '@angular/material/expansion'; @Component({ selector: 'app-tab2', templateUrl: 'tab2.page.html', styleUrls: ['tab2.page.scss'] }) export class Tab2Page { @ViewChild(MatAccordion) accordion: MatAccordion; questions: any = []; isMulti: boolean = false; constructor() { fetch('assets/data/faq.json').then(response => response.json()) .then((resp) => { console.log(resp); this.questions = resp; }) } }
Here we have added some flavor where you can switch this accordion list between single item open at a time to multiple can be opened.
<ion-content [fullscreen]="true" class="bg-gray"> <ion-header collapse="condense"> <ion-toolbar> <ion-title size="large">Tab 2</ion-title> </ion-toolbar> </ion-header> <ion-item> <ion-label>How much can open at a time?</ion-label> </ion-item> <mat-button-toggle-group [(ngModel)]="isMulti"> <mat-button-toggle class="primary-color" value="false" checked>Single</mat-button-toggle> <mat-button-toggle class="primary-color" value="true">Multiple</mat-button-toggle> </mat-button-toggle-group> <mat-accordion class="example-headers-align" multi="{{ isMulti }}"> <mat-expansion-panel *ngFor="let item of questions"> <mat-expansion-panel-header> <mat-panel-title> {{ item?.question }} </mat-panel-title> </mat-expansion-panel-header> {{ item?.answer }} </mat-expansion-panel> </mat-accordion> </ion-content>
Hope you find this article useful.
See you in the next learning journey.