mirror of
https://github.com/BradNut/svelte-library
synced 2025-09-08 17:40:21 +00:00
Use node animation to animate the open/close of accordion, attach this animation to the svelte component, and create passed props like duration.
This commit is contained in:
parent
bad22ed422
commit
6a68fd734b
2 changed files with 36 additions and 5 deletions
|
|
@ -8,11 +8,20 @@
|
|||
<span class:isOpen>▲</span>
|
||||
{buttonText}</button
|
||||
>
|
||||
<div class="accordion-content" use:slide={isOpen}>
|
||||
<slot />
|
||||
<div
|
||||
class="accordion-content"
|
||||
use:slide={{ isOpen, duration: 200 }}
|
||||
on:animationEnd={() => console.log('Animation ended')}
|
||||
>
|
||||
<div class="wrapper">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.wrapper {
|
||||
padding: 20px;
|
||||
}
|
||||
button {
|
||||
display: block;
|
||||
border: 0;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,34 @@
|
|||
export function slide(node, isOpen) {
|
||||
export function slide(node, { isOpen, duration = 500 }) {
|
||||
// Initialize
|
||||
let initialHeight = node.offsetHeight;
|
||||
node.style.height = isOpen ? 'auto' : 0;
|
||||
node.style.overflow = "hidden";
|
||||
|
||||
let animation = node.animate([
|
||||
{
|
||||
height: 0,
|
||||
}, {
|
||||
height: `${initialHeight}px`,
|
||||
}
|
||||
], {
|
||||
duration,
|
||||
fill: 'both',
|
||||
direction: isOpen ? 'reverse' : 'normal',
|
||||
});
|
||||
animation.pause();
|
||||
|
||||
animation.onfinish = ({ currentTime }) => {
|
||||
if(!currentTime) {
|
||||
animation.reverse();
|
||||
animation.pause();
|
||||
}
|
||||
|
||||
node.dispatchEvent(new CustomEvent('animationEnd'));
|
||||
}
|
||||
|
||||
return {
|
||||
update: (isOpen) => {
|
||||
node.style.height = isOpen ? 'auto' : 0;
|
||||
update: () => {
|
||||
animation.currentTime ? animation.reverse() : animation.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue