Source: uswdsAccordionContainer/uswdsAccordionContainer.js

import { LightningElement, api } from "lwc";
/**
 * @class
 * @alias uswds-accordion-container
 * @hideconstructor
 * @description A container component for managing multiple accordion sections.
 *              Handles the expansion and collapse of sections, and applies styles dynamically.
 * @extends LightningElement
 * @author Mark Vogelgesang <movogelgesang@gmail.com>
 * @since 1.0.0
 */
export default class UswdsAccordionContainer extends LightningElement {
  /**
   * @type {string}
   * @default ""
   * @description Custom CSS class to be applied to the container.
   */
  @api customClass = "";

  /**
   * @type {boolean}
   * @default false
   * @description Determines if multiple sections can be open simultaneously.
   */
  @api allowMultipleSelectable = false;

  /**
   * @type {string}
   * @default "Borderless"
   * @description Determines the styling type of the accordion (e.g., "Borderless" or "Bordered").
   */
  @api accordionType = "Borderless";

  /**
   * @private
   * @type {boolean}
   * @default false
   * @description Internal flag to ensure renderedCallback runs only once.
   */
  hasRendered = false;

  /**
   * @lifecycle
   * @private
   * @description Runs after the component has been inserted into the DOM.
   *              Adds a top margin to all child sections except the first one.
   */
  renderedCallback() {
    // If it has already run, do nothing.
    if (this.hasRendered) {
      return;
    }
    this.hasRendered = true;

    // Find all the child sections that have been passed into the slot
    const sections = this.querySelectorAll("c-uswds-accordion-section");

    if (sections.length > 1) {
      // Loop through the sections, starting from the SECOND one (index 1)
      for (let i = 1; i < sections.length; i++) {
        // Set the public property on the child component instance
        sections[i].applyTopMargin = true;
      }
    }
  }
  /**
   * @event
   * @private
   * @param {CustomEvent} event - The event object containing details of the toggled section.
   * @description Handles the toggle event of a section.
   *              Toggles the clicked section and closes others if multiple selection is not allowed.
   */
  handleSectionToggle(event) {
    const toggledSectionId = event.detail.id;

    // Find sections using the template
    const sections = this.template.querySelectorAll(
      "c-uswds-accordion-section"
    );

    sections.forEach((section) => {
      if (section.sectionId === toggledSectionId) {
        // Toggle the one that was clicked
        section.toggle();
      } else if (!this.allowMultipleSelectable) {
        // If only one can be open, close all others
        section.toggle(false);
      }
    });
  }

  /**
   * @private
   * @description Dynamically generates the class string for the container based on properties.
   * @returns {string} - The class string for the container element.
   */
  get containerClasses() {
    return (
      "usa-accordion" +
      (this.accordionType === "Bordered" ? " usa-accordion--bordered" : "") +
      (this.allowMultipleSelectable ? " usa-accordion--multiselectable" : "")
    );
  }
}