storefront-ui
storefront-ui copied to clipboard
[FEATURE] Accordion content with dynamic height
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
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.
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`)
});
}
}
},
I'm closing this issue as it is no longer valid. SfExpand
component was replaced by sf-expand
transition.