vuestorefront/storefront-ui

[QUESTION] How to animate an accordion with transition?

Closed this issue · 3 comments

What is your question / Please describe your issue

How to animate an accordion with transition? Vue transition, like the example on Drawer transition.

What package and version of StorefrontUI are you using?

"@storefront-ui/vue": "^2.0.0",

What framework does your application use?

Nuxt

Code of Conduct

  • I agree to follow this project's Code of Conduct

One possible way to animate the open state is with a Vue Transition surrounding the default slot. Then, with a v-if on the root element of the default slot we can trigger animations. https://stackblitz.com/edit/sfui-vue-tne3g6?file=src/App.vue

<SfAccordionItem
   v-model="opened[index]"
 >
    <template #summary>
        summary
     </template>
     <transition>
        <p class="p-4" v-if="opened[index]">
          {{ details }}
        </p>
    </transition>
</SfAccordionItem>

However, since the AccordionItem is implemented with a details and summary elements, the summary section will immediately be hidden once the v-model is false. So it gets tricky if you need to transition the close property.

Two approaches I've seen are:

  1. Manually overriding the close behavior to inject transitional state (StackOverflow)
  2. Using the useDisclosure SFUI hook instead for the logic which gives simple toggle behavior, and then adding these on divs in your project.
FRSgit commented

Hello @Beethoven 👋

To elaborate further on @mattmaribojoc response:
I've prepared a sample implementation of AnimatedAccordionItem component for you.

It is built around the idea that the open attribute of native <details> element should be removed only after the "leaving" transition has ended (when accordion is being closed). We can achieve it by:

  • creating separate isOpen ref which will handle open state of native <details> element,
  • setting isOpen to false only after after-leave event is emitted by <transition> component,
  • setting isOpen to true immediately right after outside state change.

Adding to that - I've proposed a sample collapse behaviour based on CSS-only max-height transition. It's not perfect (with sample implementation accordionItem content shouldn't be bigger than 300px), but I hope you can tweak it to your needs.

Do our two responses answer your question?

BTW.
Nice to see that you're exploring our library - we are eagerly waiting for further feedback from you 😁

Yes!! Thanks!
It would be really cool to see this example in the docs.