storefront-ui icon indicating copy to clipboard operation
storefront-ui copied to clipboard

[FEATURE] Accordion content with dynamic height

Open rain2o opened this issue 4 years ago • 2 comments

Describe how this feature will help us improve I see this as a bug, but I could see the argument for it being a feature request, which is why I chose Feature Request.

When we have a component in an SfAccordionItem which could change height for any given reason, the hard-coded height on the SfExpand component is causing a problem. This is also a problem if the content is loaded after mounted.

In our specific example, we have some paginated content inside of the accordion, and this content is loaded asynchronously. So we have 2 instances where the height is a problem - when the initial content loads (we have this accordion default to open), and when the user paginates, if the content changes height on the next page. Sometimes the content runs over the set height, running over the rest of the page content.

Describe the solution you'd considered I'm not really sure of a solution. If there is a good way to do it, it would be useful if there could be a $ref, prop, event, or something for us to change/trigger/emit that will cause the component to re-render, or at least re-run the enter event in SfExpand.

Additional context I have tried doing a $forceUpdate() on the SfAccordionItem, however as that only works for direct children, and not recursively, this did not update the SfExpand utility component.

┆Issue is synchronized with this Jira Zadanie by Unito

rain2o avatar Feb 23 '21 17:02 rain2o

Thanks for noticing it. I think that it should be fixed, but first I thought about some kind of workaround. Didn't find any yet, but I'll think about it. If you'll have some solution, please let us know.

AdamPawlinski avatar Feb 26 '21 09:02 AdamPawlinski

I implemented a temporary workaround for our project. If it can be useful for someone else, I'll post it here. It might not be the best, but it's what we could come up with for now.

We created an Accordion component in our theme, which uses SfAccordion and each of the SfAccordionItem components. The component in each Accordion Item Content slot has a listener @update:content="updateContentHeight(item.key)", and that component can choose to emit update:content when/if it wants (for mine, I just emit it in the updated lifecycle event so it happens every time the html is re-rendered.

Below is what the updateContentHeight method looks like.

/**
 * Update the height of the content container
 * This is necessary because SfAccordionItem sets
 * inline style height for the content on open,
 * but some of our components might have content
 * which dynamically updates in height.
 */
updateContentHeight (key) {
  // get the accordion element (we set this class on each item using the key)
  const accordionElement = document.getElementById(
    `o-product-accordion__item--${key}`
  )
  // if the accordion is open, update the content height
  if (
    // make sure it exists
    accordionElement &&
    // make sure it's open, otherwise we don't care
    accordionElement.getElementsByClassName('o-product-accordion__header--open').length
  ) {
    // find the content element
    const contentElements = accordionElement.getElementsByClassName('sf-accordion-item__content')
    if (contentElements && contentElements.length > 0) {
      const contentElement = contentElements[0]
      // get current height of content
      const height = contentElement.offsetHeight
      // use this because SfExpand uses this, so it's a race issue without it when opening the accordion item
      requestAnimationFrame(() => {
        // set the parent element height to the height of the content
        contentElement.parentElement.style.setProperty('height', `${height}px`)
      });
    }
  }
},

rain2o avatar Feb 26 '21 11:02 rain2o

I'm closing this issue as it is no longer valid. SfExpand component was replaced by sf-expand transition.

AdamPawlinski avatar May 29 '23 11:05 AdamPawlinski