Migrate to twenty-ui - utilities/animation (#7951)

This PR was created by [GitStart](https://gitstart.com/) to address the
requirements from this ticket:
[TWNTY-7538](https://clients.gitstart.com/twenty/5449/tickets/TWNTY-7538).

 --- 

### Description

- Move animation components to `twenty-ui`    \
  \
  \
  Fixes  #7538

Co-authored-by: gitstart-twenty <gitstart-twenty@users.noreply.github.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
gitstart-app[bot]
2024-10-22 18:08:54 +02:00
committed by GitHub
parent edc36c707d
commit 113e9fc8c7
20 changed files with 35 additions and 28 deletions

View File

@ -1,10 +1,9 @@
import styled from '@emotion/styled';
import { ReactElement, useCallback, useEffect, useRef, useState } from 'react';
import { Chip, ChipVariant } from 'twenty-ui';
import { AnimatedContainer, Chip, ChipVariant } from 'twenty-ui';
import { ExpandedListDropdown } from '@/ui/layout/expandable-list/components/ExpandedListDropdown';
import { isFirstOverflowingChildElement } from '@/ui/layout/expandable-list/utils/isFirstOverflowingChildElement';
import { AnimatedContainer } from '@/ui/utilities/animation/components/AnimatedContainer';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
import { isDefined } from '~/utils/isDefined';

View File

@ -1,17 +0,0 @@
import { motion } from 'framer-motion';
import React from 'react';
export const AnimatedContainer = ({
children,
}: {
children: React.ReactNode;
}) => (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.1 }}
whileHover={{ scale: 1.04 }}
>
{children}
</motion.div>
);

View File

@ -1,29 +0,0 @@
import { useTheme } from '@emotion/react';
import { motion } from 'framer-motion';
import { AnimationDuration } from 'twenty-ui';
type AnimatedEaseInProps = Omit<
React.ComponentProps<typeof motion.div>,
'initial' | 'animated' | 'transition'
> & {
duration?: AnimationDuration;
};
export const AnimatedEaseIn = ({
children,
duration = 'normal',
}: AnimatedEaseInProps) => {
const theme = useTheme();
const initial = { opacity: 0 };
const animate = { opacity: 1 };
const transition = {
ease: 'linear',
duration: theme.animation.duration[duration],
};
return (
<motion.div initial={initial} animate={animate} transition={transition}>
{children}
</motion.div>
);
};

View File

@ -1,46 +0,0 @@
import { useTheme } from '@emotion/react';
import { AnimatePresence, motion } from 'framer-motion';
import { AnimationDuration } from 'twenty-ui';
type AnimatedEaseInOutProps = {
isOpen: boolean;
children: React.ReactNode;
duration?: AnimationDuration;
marginBottom?: string;
marginTop?: string;
initial?: boolean;
};
export const AnimatedEaseInOut = ({
children,
isOpen,
marginBottom,
marginTop,
duration = 'normal',
initial = true,
}: AnimatedEaseInOutProps) => {
const theme = useTheme();
return (
<AnimatePresence initial={initial}>
{isOpen && (
<motion.div
initial={{
marginBottom: marginBottom ?? 0,
marginTop: marginTop ?? 0,
height: 0,
opacity: 0,
}}
animate={{ height: 'fit-content', opacity: 1 }}
exit={{ height: 0, opacity: 0, marginBottom: 0, marginTop: 0 }}
transition={{
duration: theme.animation.duration[duration],
ease: 'easeInOut',
}}
>
{children}
</motion.div>
)}
</AnimatePresence>
);
};

View File

@ -1,41 +0,0 @@
import { useTheme } from '@emotion/react';
import { AnimatePresence, motion } from 'framer-motion';
import { AnimationDuration } from 'twenty-ui';
type AnimatedFadeOutProps = {
isOpen: boolean;
children: React.ReactNode;
duration?: AnimationDuration;
marginBottom?: string;
marginTop?: string;
};
export const AnimatedFadeOut = ({
isOpen,
children,
duration = 'normal',
marginBottom,
marginTop,
}: AnimatedFadeOutProps) => {
const theme = useTheme();
return (
<AnimatePresence>
{isOpen && (
<motion.div
initial={{
opacity: 1,
marginBottom: marginBottom ?? 0,
marginTop: marginTop ?? 0,
}}
exit={{ opacity: 0, height: 0, marginBottom: 0, marginTop: 0 }}
transition={{
duration: theme.animation.duration[duration],
ease: 'easeOut',
}}
>
{children}
</motion.div>
)}
</AnimatePresence>
);
};

View File

@ -1,72 +0,0 @@
import React, { useMemo } from 'react';
import styled from '@emotion/styled';
import { motion } from 'framer-motion';
const StyledContainer = styled(motion.div)`
display: flex;
overflow: hidden;
`;
const StyledWord = styled(motion.span)`
white-space: pre;
`;
type AnimatedTextWordProps = Omit<
React.ComponentProps<typeof motion.div>,
'children'
> & {
text: string;
};
const containerAnimation = {
hidden: { opacity: 0 },
visible: (i = 1) => ({
opacity: 1,
transition: { staggerChildren: 0.12, delayChildren: 0.04 * i },
}),
};
const childAnimation = {
visible: {
opacity: 1,
x: 0,
transition: {
type: 'spring',
damping: 12,
stiffness: 100,
},
},
hidden: {
opacity: 0,
x: 20,
transition: {
type: 'spring',
damping: 12,
stiffness: 100,
},
},
};
export const AnimatedTextWord = ({ text = '' }: AnimatedTextWordProps) => {
const words = useMemo(() => {
const words = text.split(' ');
return words.map((value, index) =>
index === words.length - 1 ? value : value + ' ',
);
}, [text]);
return (
<StyledContainer
variants={containerAnimation}
initial="hidden"
animate="visible"
>
{words.map((word, index) => (
<StyledWord variants={childAnimation} key={index}>
{word}
</StyledWord>
))}
</StyledContainer>
);
};

View File

@ -1,33 +0,0 @@
import { useTheme } from '@emotion/react';
import { motion } from 'framer-motion';
type AnimatedTranslationProps = {
children: React.ReactNode;
};
export const AnimatedTranslation = ({ children }: AnimatedTranslationProps) => {
const theme = useTheme();
return (
<motion.div
initial="hidden"
animate="visible"
variants={{
hidden: {
opacity: 0,
y: -20,
},
visible: {
opacity: 1,
y: 0,
transition: {
duration: theme.animation.duration.normal, // Replace this with your theme's duration
ease: 'easeInOut',
},
},
}}
>
{children}
</motion.div>
);
};