The Ionic Accordion Group and the ion-accordion
are awesome. Accordions provide collapsible sections in your content to reduce vertical space while organizing and grouping information.
However, I feel there's an important feature that's missing: the ability to easily expand or collapse all accordion items at once.
While it's technically possible to expand or collapse all items at once, the current method is quite cumbersome. You have to use <ion-accordion-group [value]="valuesOfTheAccordionsThatShouldBeExpanded">
and pass an array of all the values of the accordions (or an empty array if you want to collapse all). This approach is problematic for several reasons:
Typically, you don't want to assign a value to each accordion manually. Ionic already handles this automatically, but as a developer, you can't easily see these values.
Your component suddenly has an extra responsibility: managing the state of each accordion group. This adds unnecessary complexity to your app.
Generally, I appreciate that the Ionic team keeps things lean and leaves extra functionalities to the developer. However, in this case, I would have liked to see an accordionGroup.toggleAll / expandAll / collapseAll
method.
Fortunately, with Angular directives, it's relatively simple to add this functionality cleanly.
Here's an example:
import { ContentChildren, Directive, QueryList } from "@angular/core";
import { IonAccordion, IonAccordionGroup } from "@ionic/angular/standalone";
@Directive({
selector: "[appAccordionGroupToggle]",
exportAs: "appAccordionGroupToggle",
standalone: true,
})
export class AccordionGroupToggleDirective {
@ContentChildren(IonAccordion) accordions!: QueryList<IonAccordion>;
get isCompletelyExpanded() {
const groupValue = this.host.value;
return (
Array.isArray(groupValue) && groupValue?.length === this.accordions.length
);
}
constructor(private host: IonAccordionGroup) {}
toggle() {
if (this.isCompletelyExpanded) {
this.collapse();
} else {
this.expand();
}
}
expand() {
this.host.value = this.accordions.map((accordion) => accordion.value);
}
collapse() {
this.host.value = [];
}
}
The directive works by using @ContentChildren
to get a reference to all ion-accordion
items within the accordion group. This allows the directive to access the state (and thus the values) of all the accordions collectively. The constructor injects the host IonAccordionGroup
, providing access to the groupβs properties and methods.
In the expand
method, the directive sets the value
of the host accordion group to an array containing the values of all the individual accordions, effectively expanding all of them. In the collapse
method, it sets the value
to an empty array, collapsing all the accordions.
The toggle
method first checks if all accordions are already open by checking the value of isCompletelyExpanded
. If it equals true
, it collapses them; if not, it expands them.
You can use the directive as follows (don't forget to import the directive in your component):
<ion-content>
<ion-button (click)="toggler.toggle()">Toggle all</ion-button>
<ion-button (click)="toggler.expand()">Expand all</ion-button>
<ion-button (click)="toggler.collapse()">Collapse all</ion-button>
<ion-accordion-group
appAccordionGroupToggle
#toggler="appAccordionGroupToggle"
>
<ion-accordion>
<ion-item slot="header">
<ion-label>First Accordion</ion-label>
</ion-item>
<div slot="content">π</div>
</ion-accordion>
<ion-accordion>
<ion-item slot="header">
<ion-label>Second Accordion</ion-label>
</ion-item>
<div slot="content">π€©</div>
</ion-accordion>
<ion-accordion>
<ion-item slot="header">
<ion-label>Third Accordion</ion-label>
</ion-item>
<div slot="content">πͺ</div>
</ion-accordion>
</ion-accordion-group>
</ion-content>
In the above example, we use #toggler
to create a reference to the instance of the Group toggle. This is possible because we set exportAs: 'appAccordionGroupToggle' in our directive. Now, we can call any of the public methods (toggle, expand, and collapse) directly from our template.
That's it! Now you can use this directive to easily toggle all accordions at once anywhere you like. While I hope the Ionic team will add expand, collapse, and toggle methods to ion-accordion-group
in the near future, it's great that Angular components make it so easy to add the desired functionality yourself.
Top comments (0)