Reusable Expandable/Collapsible Section In Lightning Web Component

The Lightning Web Component library gives us an Accordion base component but it does not have expandable section base component. Section Titles are interactive titles that open and close sections, typically on a form. It looks like:-

Expandable Section LWC

We are going to build a reusable Expandable/Collapsible Section lightning component. We can pass html element to this component and extend it as per your use case. Let’s name the component as expandableSection.

expandableSection.html

The html code of the expandable/collapsible section component has div element which has heading and body. Heading part has button with lightning icon and section label. data attributes has been used to build the expand/collapse logic in the JavaScript controller side. The body has slot which enables it to accept any html element to show inside it. We can pass a lightning web component as well to it.

<template>
    <div class="slds-section slds-is-open" data-id={id}>
        <!--section header-->
        <h3 class="slds-section__title">
            <button type="button" aria-controls={id} class="slds-button slds-section__title-action" data-buttonid={id}
                onclick={toggleSection}>
                <lightning-icon icon-name="utility:switch" alternative-text="button icon" size="x-small"
                    class="slds-section__title-action-icon slds-button__icon_left"></lightning-icon>
                <span class="slds-truncate" title={label}>{label}</span>
            </button>
        </h3>
        <!--section body-->
        <div class="slds-section__content">
            <slot></slot>
        </div>
    </div>
</template>

expandableSection.js

The JavaScript controller of the expandable section component has two public properties:-

  1. id
  2. label

label is used in section header label whereas id is a unique identifier of the expandable collapsible section component and used to toggle the section. The toggleSection method of the component controls the toggle mechanism using style class of parent div of the html markup.

slds-section slds-is-open – It shows the open section
slds-section slds-is-close – It shows the closed section

import { LightningElement, api } from 'lwc';
export default class ExpandableSection extends LightningElement {
    @api id;
    @api label;

    toggleSection(event) {
        let buttonid = event.currentTarget.dataset.buttonid;
        let currentsection = this.template.querySelector('[data-id="' + buttonid + '"]');
        if (currentsection.className.search('slds-is-open') == -1) {
            currentsection.className = 'slds-section slds-is-open';
        } else {
            currentsection.className = 'slds-section slds-is-close';
        }
    }
}

expandableSection.js-meta.xml

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>55.0</apiVersion>
    <isExposed>false</isExposed>
</LightningComponentBundle>

Once you have deployed the code, We will call this component inside parent component and pass the body into it. The beauty of this component is it can be used inside iteration as well. Let’s create another component named expandableSectionExample.

expandableSectionExample.html

This component calls expandable section component and pass the id and label property value along with body. We have used both kind of example i.e. iteration or individual way of using it.

<template>
    <template for:each={sections} for:item="section">
        <c-expandable-section key={section.id} id={section.id} label={section.label}>
            Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Fusce dapibus, tellus ac
            cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Lorem ipsum dolor
            sit amet, consectetur adipiscing elit. Nullam quis risus eget urna mollis ornare vel eu leo. Nulla vitae
            elit libero, a pharetra augue.
        </c-expandable-section>
    </template>

    <c-expandable-section id="4" label="Individual Section 1">
        Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Fusce dapibus, tellus ac
        cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Lorem ipsum dolor
        sit amet, consectetur adipiscing elit. Nullam quis risus eget urna mollis ornare vel eu leo. Nulla vitae
        elit libero, a pharetra augue.
    </c-expandable-section>

    <c-expandable-section id="5" label="Individual Section 2">
        Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Fusce dapibus, tellus ac
        cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Lorem ipsum dolor
        sit amet, consectetur adipiscing elit. Nullam quis risus eget urna mollis ornare vel eu leo. Nulla vitae
        elit libero, a pharetra augue.
    </c-expandable-section>

</template>

expandableSectionExample.js

import { LightningElement } from 'lwc';

export default class ExpandableSectionExample extends LightningElement {
    sections = [
        {
            id: 1,
            label: 'Section 1 in Iteration'
        },
        {
            id: 2,
            label: 'Section 2 in Iteration'
        },
        {
            id: 3,
            label: 'Section 3 in Iteration'
        }
    ]
}

expandableSectionExample.js-meta.xml

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>55.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>
</LightningComponentBundle>

Demo – Reusable Expandable/Collapsible Section

To learn more on Lightning Web Components, Take a look on this – LWC

Leave a Reply