I'm trying to add the plugin found here in a part of my code. I had to rewrite it because I'm using React, but for some reason it still doesn't work. Can you help me solve the problem?
Custom Hook:
import { useRef, useLayoutEffect } from 'react';
import autoAnimate, { getTransitionSizes } from '@formkit/auto-animate';
interface UseAutoAnimateOptions {
parentElement: HTMLElement;
}
const useBouncyAutoAnimate = ({ parentElement }: UseAutoAnimateOptions) => {
const ref = useRef(null);
useLayoutEffect(() => {
if (ref.current) {
autoAnimate(parentElement, (el, action, oldCoords: any, newCoords: any) => {
let keyframes;
// ... (rest of the code remains the same)
if (action === 'add') {
keyframes = [
{ transform: 'scale(0)', opacity: 0 },
{ transform: 'scale(1.15)', opacity: 1, offset: 0.75 },
{ transform: 'scale(1)', opacity: 1 },
];
}
if (action === 'remove') {
keyframes = [
{ transform: 'scale(1)', opacity: 1 },
{ transform: 'scale(1.15)', opacity: 1, offset: 0.33 },
{ transform: 'scale(0.75)', opacity: 0.1, offset: 0.5 },
{ transform: 'scale(0.5)', opacity: 0 },
];
}
if (action === 'remain') {
const deltaX = oldCoords.left - newCoords.left;
const deltaY = oldCoords.top - newCoords.top;
const [widthFrom, widthTo, heightFrom, heightTo] = getTransitionSizes(
el,
oldCoords,
newCoords
);
let start: any = { transform: `translate(${deltaX}px, ${deltaY}px)` };
let mid: any = {
transform: `translate(${deltaX * -0.15}px, ${deltaY * -0.15}px)`,
offset: 0.75,
};
let end: any = { transform: `translate(0, 0)` };
if (widthFrom !== widthTo) {
start.width = `${widthFrom}px`;
mid.width = `${widthFrom >= widthTo ? widthTo / 1.05 : widthTo * 1.05}px`;
end.width = `${widthTo}px`;
}
if (heightFrom !== heightTo) {
start.height = `${heightFrom}px`;
mid.height = `${heightFrom >= heightTo ? heightTo / 1.05 : heightTo * 1.05}px`;
end.height = `${heightTo}px`;
}
keyframes = [start, mid, end];
}
return new KeyframeEffect(el, keyframes as any, {
duration: 600,
easing: 'ease-out',
});
});
}
}, [ref]);
return ref;
};
export default useBouncyAutoAnimate;
Usage:
import React, { useRef, useState } from 'react'
import Word from './Word';
import { useAutoAnimate } from '@formkit/auto-animate/react'
import useBouncyAutoAnimate from './bouncy';
interface Word {
id: number,
visible: boolean,
word: string
}
interface MultiListProps {
words: Word[],
actives: Word[],
setWords: React.Dispatch<React.SetStateAction<Word[]>>,
setActives: React.Dispatch<React.SetStateAction<Word[]>>
}
function MultiList({ words, setWords, actives, setActives }: MultiListProps) {
const parentRef = useRef<HTMLElement | null>(null);
const animateRef = useBouncyAutoAnimate({ parentElement: parentRef.current! });
const [ready, setReady] = useState(false);
return (
<div ref={parentRef as any}>
{
actives.map(word => (
<button onClick={() => {
const has = actives.find(w => w.word === word.word);
if (!has) return;
setActives(x => x.filter(w => w.id !== word.id))
const newWords = words.map(el => {
if (el.id === word.id)
el.visible = true;
return el;
})
setWords(newWords)
}} ref={ word.id === (actives.at(-1)?.id || NaN) ? animateRef as any : undefined}>
<Word word={word} />
</button>
))
}
</div>
)
}
export default MultiList
Addition Element:
import React, { useState } from 'react'
import Word from './Word';
import classnames from 'classnames';
interface Word {
id: number,
visible: boolean,
word: string
}
interface SelectListProps {
words: Word[],
actives: Word[],
setWords: React.Dispatch<React.SetStateAction<Word[]>>,
setActives: React.Dispatch<React.SetStateAction<Word[]>>
}
function SelectList({ words, setWords, actives, setActives }: SelectListProps) {
const [ready, setReady] = useState(false);
return (
<div>
{
words.map(word => (
<button onClick={() => {
const has = actives.find(w => w.word === word.word);
if (has) return;
setActives(x => ([
...x,
word
]))
const newWords = words.map(el => {
if (el.id === word.id)
el.visible = false;
return el;
})
setWords(newWords)
}} className={classnames('transition-opacity', {
'opacity-50': !word.visible
})}>
<Word word={word} />
</button>
))
}
</div>
)
}
export default SelectList
Normally, when we click on it, the new element should be added in a 'bouncy' way, but now it comes flat without any animation.
I think your error is in the import of the package in your custom hook.
Try changing this:
import autoAnimate, { getTransitionSizes } from '@formkit/auto-animate';
For this:
import autoAnimate, { getTransitionSizes } from '@formkit/auto-animate/react';