title: How to create an animated, variable size accordion component in QtQuick / QML
body: <p>I want to create an animated accordion-like element that expands on click. Here's how it should work.</p>
  
  <p><a href="https://i.stack.imgur.com/1MAoj.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/1MAoj.png" alt="Accordion animation"></a></p>
  
  <p>When the user clicks one of the red rectangles, the green rectangle which is the actual content, should expand. I want this expansion to be animated. The height of the contents of the green rectangles could be different for each red header.</p>
  
  <p>I have been able to implement the click-to-expand behavior, but there's no animation. Here is the code I currently have.</p>
  
  <p><code>AccordionElement.qml</code></p>
  
  <pre><code>import QtQuick 2.5
  import QtQuick.Layouts 1.1
  
  ColumnLayout {
      id: rootElement
  
      property string title: ""
      property bool isOpen: false
      default property alias accordionContent: contentPlaceholder.data
  
      anchors.left: parent.left; anchors.right: parent.right
  
      // Header element
      Rectangle {
          id: accordionHeader
          color: "red"
          anchors.left: parent.left; anchors.right: parent.right
          height: 50
          MouseArea {
              anchors.fill: parent
              Text {
                  text: rootElement.title
                  anchors.centerIn: parent
              }
              cursorShape: Qt.PointingHandCursor
              onClicked: {
                  rootElement.isOpen = !rootElement.isOpen
              }
          }
      }
  
      // This will get filled with the content
      ColumnLayout {
          id: contentPlaceholder
          visible: rootElement.isOpen
          anchors.left: parent.left; anchors.right: parent.right
      }
  }
  </code></pre>
  
  <p>And this is how it is used from the parent element:</p>
  
  <p><code>Accordion.qml</code></p>
  
  <pre><code>ColumnLayout {
      Layout.margins: 5
  
      visible: true
  
      AccordionElement {
          title: "Title1"
          accordionContent: Rectangle {
              anchors.left: parent.left; anchors.right: parent.right
              height: 20
              color: "green"
          }
      }
      AccordionElement {
          title: "Title2"
          accordionContent: Rectangle {
              anchors.left: parent.left; anchors.right: parent.right
              height: 50
              color: "green"
          }
      }
  
      AccordionElement {
          title: "Title3"
          accordionContent: Rectangle {
              anchors.left: parent.left; anchors.right: parent.right
              height: 30
              color: "green"
          }
      }
  
      // Vertical spacer to keep the rectangles in upper part of column
      Item {
          Layout.fillHeight: true
      }
  }
  </code></pre>
  
  <p>This produces the following result (when all rectangles are expanded):</p>
  
  <p><a href="https://i.stack.imgur.com/QeX6L.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/QeX6L.png" alt="Expanded"></a></p>
  
  <p>Ideally I would like the green rectangles to roll out of the red rectangles (like paper out of a printer). But I am stuck on how to do this. I have tried several approaches using the <code>height</code> property, and I got the green rectangle to disappear but the white space remains under the red rectangle.</p>
  
  <p>Any help would be appreciated. Is there an approach I'm missing?</p>