Skip to content

Expansion Panel ​

The Expansion Panel is a container component that manages multiple collapsible panels within a layout. Unlike the accordion component, expanded panels do not resize the container but instead fill the available space and become scrollable when needed.

Usage ​

Suitable for embedded interactive content such as iframes and side panel/utility views.

API Reference ​

Component attribute(s) ​

x-h-exp-panel
x-h-exp-panel-item
x-h-exp-panel-trigger
x-h-exp-panel-content

Attributes ​

x-h-exp-panel ​

AttributeTypeRequiredDescription
data-sizedefault
md
sm
falseHeight of the panel header items.
data-variantdefault
transparent
falseTransparent background color. Does not remove the border.
data-floatingbooleanfalseFloating style panels.

x-h-exp-panel-item ​

AttributeTypeRequiredDescription
selfbooleanfalseDefault expanded state. This is a two-way binding, so if a variable is provided, it will get updated automatically.

x-h-exp-panel-trigger ​

AttributeTypeRequiredDescription
selfstringtrueSets the title of the item. Expects a string literal or a reference to a variable.

Data Slots ​

SlotElement
exp-panelx-h-exp-panel
exp-panel-itemx-h-exp-panel-item
exp-panel-headerx-h-exp-panel-trigger
exp-panel-triggerButton created by x-h-exp-panel-trigger
exp-panel-contentx-h-exp-panel-content

Examples ​

Default Panels ​

html
<div x-h-exp-panel>
  <div x-h-exp-panel-item="true">
    <h3 x-h-exp-panel-trigger="'Panel 1'"></h3>
    <div x-h-exp-panel-content>
      <div x-h-info-page>
        <div x-h-info-page-header>
          <div x-h-info-page-media.icon>
            <svg x-h-icon data-icon="circle-info" role="img" aria-label="information"></svg>
          </div>
          <div x-h-info-page-title>Panel 1</div>
          <div x-h-info-page-description>Just an empty panel</div>
        </div>
      </div>
    </div>
  </div>
  <div x-h-exp-panel-item>
    <h3 x-h-exp-panel-trigger="'Panel 2'"></h3>
    <div x-h-exp-panel-content>
      <div x-h-info-page>
        <div x-h-info-page-header>
          <div x-h-info-page-media.icon>
            <svg x-h-icon data-icon="circle-info" role="img" aria-label="information"></svg>
          </div>
          <div x-h-info-page-title>Panel 2</div>
          <div x-h-info-page-description>Just an empty panel</div>
        </div>
      </div>
    </div>
  </div>
  <div x-h-exp-panel-item>
    <h3 x-h-exp-panel-trigger="'Panel 3'"></h3>
    <div x-h-exp-panel-content>
      <div x-h-info-page>
        <div x-h-info-page-header>
          <div x-h-info-page-media.icon>
            <svg x-h-icon data-icon="circle-info" role="img" aria-label="information"></svg>
          </div>
          <div x-h-info-page-title>Panel 3</div>
          <div x-h-info-page-description>Just an empty panel</div>
        </div>
      </div>
    </div>
  </div>
</div>

Transparent Panels ​

html
<div x-h-exp-panel data-variant="transparent">
  <div x-h-exp-panel-item>
    <h3 x-h-exp-panel-trigger="'Panel 1'"></h3>
    <div x-h-exp-panel-content>Panel content</div>
  </div>
  <div x-h-exp-panel-item>
    <h3 x-h-exp-panel-trigger="'Panel 2'"></h3>
    <div x-h-exp-panel-content>Panel content</div>
  </div>
</div>

Floating Panels ​

html
<div x-h-exp-panel data-floating="true">
  <div x-h-exp-panel-item>
    <h3 x-h-exp-panel-trigger="'Panel 1'"></h3>
    <div x-h-exp-panel-content>Panel content</div>
  </div>
  <div x-h-exp-panel-item>
    <h3 x-h-exp-panel-trigger="'Panel 2'"></h3>
    <div x-h-exp-panel-content>Panel content</div>
  </div>
</div>

Transparent Floating Panels ​

html
<div x-h-exp-panel data-variant="transparent" data-floating="true">
  <div x-h-exp-panel-item>
    <h3 x-h-exp-panel-trigger="'Panel 1'"></h3>
    <div x-h-exp-panel-content>Panel content</div>
  </div>
  <div x-h-exp-panel-item>
    <h3 x-h-exp-panel-trigger="'Panel 2'"></h3>
    <div x-h-exp-panel-content>Panel content</div>
  </div>
</div>

Medium Panels ​

html
<div x-h-exp-panel data-size="md">
  <div x-h-exp-panel-item>
    <h3 x-h-exp-panel-trigger="'Panel 1'"></h3>
    <div x-h-exp-panel-content>Panel content</div>
  </div>
  <div x-h-exp-panel-item>
    <h3 x-h-exp-panel-trigger="'Panel 2'"></h3>
    <div x-h-exp-panel-content>Panel content</div>
  </div>
</div>

Small Panels ​

html
<div x-h-exp-panel data-size="sm">
  <div x-h-exp-panel-item>
    <h3 x-h-exp-panel-trigger="'Panel 1'"></h3>
    <div x-h-exp-panel-content>Panel content</div>
  </div>
  <div x-h-exp-panel-item>
    <h3 x-h-exp-panel-trigger="'Panel 2'"></h3>
    <div x-h-exp-panel-content>Panel content</div>
  </div>
</div>

Two-Way Binding And Watching For Changes ​

In cases where the expanded state must be monitored and/or persisted, the $watch magic function can be used.

It can be used both inline and in a component object.

html
<div x-h-exp-panel x-data="{ panelOneOpen: true }">
  <div x-h-exp-panel-item="panelOneOpen" x-init="$watch('panelOneOpen', (value, oldValue) => console.log('Old value:', value, 'New value', oldValue))">
    <h3 x-h-exp-panel-trigger="'Panel 1'"></h3>
    <div x-h-exp-panel-content>
      <div x-h-info-page>
        <div x-h-info-page-header>
          <div x-h-info-page-media.icon>
            <svg x-h-icon data-icon="circle-info" role="img" aria-label="information"></svg>
          </div>
          <div x-h-info-page-title>Panel 1</div>
          <div x-h-info-page-description>Just an empty panel</div>
        </div>
      </div>
    </div>
  </div>
</div>
  • Component Object ​

html
<div x-h-exp-panel x-data="twoWayPanel">
  <div x-h-exp-panel-item="panelOneOpen">
    <h3 x-h-exp-panel-trigger="'Panel 1'"></h3>
    <div x-h-exp-panel-content>
      <div x-h-info-page>
        <div x-h-info-page-header>
          <div x-h-info-page-media.icon>
            <svg x-h-icon data-icon="circle-info" role="img" aria-label="information"></svg>
          </div>
          <div x-h-info-page-title>Panel 1</div>
          <div x-h-info-page-description>Just an empty panel</div>
        </div>
      </div>
    </div>
  </div>
</div>
<script>
  Alpine.data('twoWayPanel', () => ({
    panelOneOpen: true,
    init() {
      this.$watch('panelOneOpen', (value, oldValue) => {
        console.log('Old value:', value, 'New value', oldValue);
      });
    },
  }));
</script>