Animate the Sidebar Objects Tree view opening (#6521)

@Bonapara 

Issue https://github.com/twentyhq/twenty/issues/6485

Introduced the animation when opening the menu.

Please let me know if this is fine or I need to make further changes.
Thank you.

---------

Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
This commit is contained in:
Ali Elamir
2024-08-06 12:28:06 +03:00
committed by GitHub
parent 23a2821a28
commit cd33471159

View File

@ -1,5 +1,4 @@
import React from 'react'; import { AnimatePresence, motion } from 'framer-motion';
import { useLocation } from 'react-router-dom'; import { useLocation } from 'react-router-dom';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { isDefined, useIcons } from 'twenty-ui'; import { isDefined, useIcons } from 'twenty-ui';
@ -17,6 +16,20 @@ import { NavigationDrawerSubItem } from '@/ui/navigation/navigation-drawer/compo
import { useNavigationSection } from '@/ui/navigation/navigation-drawer/hooks/useNavigationSection'; import { useNavigationSection } from '@/ui/navigation/navigation-drawer/hooks/useNavigationSection';
import { View } from '@/views/types/View'; import { View } from '@/views/types/View';
import { getObjectMetadataItemViews } from '@/views/utils/getObjectMetadataItemViews'; import { getObjectMetadataItemViews } from '@/views/utils/getObjectMetadataItemViews';
import { Theme, useTheme } from '@emotion/react';
const navItemsAnimationVariants = (theme: Theme) => ({
hidden: {
height: 0,
opacity: 0,
marginTop: 0,
},
visible: {
height: 'auto',
opacity: 1,
marginTop: theme.spacing(1),
},
});
export const ObjectMetadataNavItems = ({ isRemote }: { isRemote: boolean }) => { export const ObjectMetadataNavItems = ({ isRemote }: { isRemote: boolean }) => {
const currentUser = useRecoilValue(currentUserState); const currentUser = useRecoilValue(currentUserState);
@ -36,6 +49,8 @@ export const ObjectMetadataNavItems = ({ isRemote }: { isRemote: boolean }) => {
const { records: views } = usePrefetchedData<View>(PrefetchKey.AllViews); const { records: views } = usePrefetchedData<View>(PrefetchKey.AllViews);
const loading = useIsPrefetchLoading(); const loading = useIsPrefetchLoading();
const theme = useTheme();
if (loading && isDefined(currentUser)) { if (loading && isDefined(currentUser)) {
return <ObjectMetadataNavItemsSkeletonLoader />; return <ObjectMetadataNavItemsSkeletonLoader />;
} }
@ -96,7 +111,7 @@ export const ObjectMetadataNavItems = ({ isRemote }: { isRemote: boolean }) => {
objectMetadataViews.length > 1; objectMetadataViews.length > 1;
return ( return (
<React.Fragment key={objectMetadataItem.id}> <div key={objectMetadataItem.id}>
<NavigationDrawerItem <NavigationDrawerItem
key={objectMetadataItem.id} key={objectMetadataItem.id}
label={objectMetadataItem.labelPlural} label={objectMetadataItem.labelPlural}
@ -106,26 +121,38 @@ export const ObjectMetadataNavItems = ({ isRemote }: { isRemote: boolean }) => {
currentPath === `/objects/${objectMetadataItem.namePlural}` currentPath === `/objects/${objectMetadataItem.namePlural}`
} }
/> />
{shouldSubItemsBeDisplayed && <AnimatePresence>
objectMetadataViews {shouldSubItemsBeDisplayed && (
.sort((viewA, viewB) => <motion.div
viewA.key === 'INDEX' initial="hidden"
? -1 animate="visible"
: viewA.position - viewB.position, exit="hidden"
) variants={navItemsAnimationVariants(theme)}
.map((view) => ( transition={{ duration: 0.3, ease: 'easeInOut' }}
<NavigationDrawerSubItem >
key={view.id} {objectMetadataViews
label={view.name} .sort((viewA, viewB) =>
to={`/objects/${objectMetadataItem.namePlural}?view=${view.id}`} viewA.key === 'INDEX'
active={ ? -1
currentPathWithSearch === : viewA.position - viewB.position,
`/objects/${objectMetadataItem.namePlural}?view=${view.id}` )
} .map((view) => (
Icon={getIcon(view.icon)} <div>
/> <NavigationDrawerSubItem
))} label={view.name}
</React.Fragment> to={`/objects/${objectMetadataItem.namePlural}?view=${view.id}`}
active={
currentPathWithSearch ===
`/objects/${objectMetadataItem.namePlural}?view=${view.id}`
}
Icon={getIcon(view.icon)}
/>
</div>
))}
</motion.div>
)}
</AnimatePresence>
</div>
); );
})} })}
</NavigationDrawerSection> </NavigationDrawerSection>