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:
@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user