From b5ec6df62fbbbd56464c14fd2f062308eb993203 Mon Sep 17 00:00:00 2001 From: Abdul Rahman <81605929+abdulrahmancodes@users.noreply.github.com> Date: Mon, 1 Dec 2025 19:57:29 +0530 Subject: [PATCH] Improve command menu animation (#16197) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/user-attachments/assets/c9ff288d-0e68-4877-af6b-8685a6bbeeaf --- > [!NOTE] > Removes legacy layout and refactors `CommandMenuPageLayout` to use width-based animation with shared constants and close-animation cleanup. > > - **UI/Command Menu**: > - **Refactor `CommandMenuPageLayout`**: > - Switch to width/margin animation on `StyledSidePanelWrapper`; remove side panel `x` translate animation. > - Use shared `COMMAND_MENU_SIDE_PANEL_WIDTH` constant. > - Add close-state handling via `isCommandMenuClosingState` and `useCommandMenuCloseAnimationCompleteCleanup` on animation completion. > - Simplify props: remove `isSidePanelOpen`; rely on `isCommandMenuOpenedState` and internal `shouldRenderContent`. > - **Cleanup**: > - Remove obsolete `CommandMenuLayout.tsx`. > > Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit d6cb01114c75b8694fbb746ea4ef31c045d7d16a. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot). --------- Co-authored-by: Félix Malfait --- .../components/CommandMenuLayout.tsx | 151 ------------------ .../components/CommandMenuPageLayout.tsx | 3 - 2 files changed, 154 deletions(-) delete mode 100644 packages/twenty-front/src/modules/object-record/components/CommandMenuLayout.tsx diff --git a/packages/twenty-front/src/modules/object-record/components/CommandMenuLayout.tsx b/packages/twenty-front/src/modules/object-record/components/CommandMenuLayout.tsx deleted file mode 100644 index 20b6da0518a..00000000000 --- a/packages/twenty-front/src/modules/object-record/components/CommandMenuLayout.tsx +++ /dev/null @@ -1,151 +0,0 @@ -import { CommandMenuRouter } from '@/command-menu/components/CommandMenuRouter'; -import { useCommandMenuHotKeys } from '@/command-menu/hooks/useCommandMenuHotKeys'; -import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState'; -import { tableWidthResizeIsActiveState } from '@/object-record/record-table/states/tableWidthResizeIsActivedState'; -import { ModalContainerContext } from '@/ui/layout/modal/contexts/ModalContainerContext'; -import { PageBody } from '@/ui/layout/page/components/PageBody'; -import { useTheme } from '@emotion/react'; -import styled from '@emotion/styled'; -import { motion } from 'framer-motion'; -import { type ReactNode, useCallback, useState } from 'react'; -import { useRecoilValue, useSetRecoilState } from 'recoil'; -import { useIsMobile } from 'twenty-ui/utilities'; - -type CommandMenuPageLayoutProps = { - children: ReactNode; - isSidePanelOpen?: boolean; -}; - -const DEFAULT_SIDE_PANEL_WIDTH = 400; - -const StyledLayout = styled.div` - display: flex; - flex: 1; - min-height: 0; - padding-bottom: ${({ theme }) => theme.spacing(3)}; - padding-right: ${({ theme }) => theme.spacing(3)}; -`; - -const StyledPageBody = styled(PageBody)` - flex: 1; - min-width: 0; - padding-bottom: 0; - padding-right: 0; -`; - -const StyledSidePanelWrapper = styled(motion.div)` - flex-shrink: 0; - min-width: 0; - overflow: hidden; -`; - -const StyledSidePanel = styled(motion.aside)` - background: ${({ theme }) => theme.background.primary}; - border: 1px solid ${({ theme }) => theme.border.color.medium}; - border-radius: ${({ theme }) => theme.border.radius.md}; - display: flex; - flex-direction: column; - height: 100%; - overflow: hidden; - position: relative; - width: ${DEFAULT_SIDE_PANEL_WIDTH}px; - box-sizing: border-box; -`; - -const StyledModalContainer = styled.div` - height: 100%; - left: 0; - pointer-events: none; - position: absolute; - top: 0; - width: 100%; - z-index: 1; -`; - -export const CommandMenuPageLayout = ({ - children, - isSidePanelOpen, -}: CommandMenuPageLayoutProps) => { - const theme = useTheme(); - const isMobile = useIsMobile(); - const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState); - const [modalContainer, setModalContainer] = useState( - null, - ); - - const setTableWidthResizeIsActive = useSetRecoilState( - tableWidthResizeIsActiveState, - ); - - const resolvedIsSidePanelOpen = - isSidePanelOpen ?? isCommandMenuOpened ?? false; - - const [shouldRenderContent, setShouldRenderContent] = useState( - resolvedIsSidePanelOpen, - ); - - const shouldShowContent = resolvedIsSidePanelOpen || shouldRenderContent; - - const handleAnimationComplete = () => { - if (!resolvedIsSidePanelOpen) { - setShouldRenderContent(false); - } - - setTableWidthResizeIsActive(true); - }; - - const handleAnimationStart = () => { - if (resolvedIsSidePanelOpen && !shouldRenderContent) { - setShouldRenderContent(true); - } - - setTableWidthResizeIsActive(false); - }; - - const handleModalContainerRef = useCallback( - (element: HTMLDivElement | null) => { - setModalContainer(element); - }, - [], - ); - - useCommandMenuHotKeys(); - - if (isMobile) { - return <>{children}; - } - - return ( - - {children} - - - - - - {shouldShowContent && } - - - - - ); -}; diff --git a/packages/twenty-front/src/modules/object-record/components/CommandMenuPageLayout.tsx b/packages/twenty-front/src/modules/object-record/components/CommandMenuPageLayout.tsx index 2467681c462..b8daa7c6727 100644 --- a/packages/twenty-front/src/modules/object-record/components/CommandMenuPageLayout.tsx +++ b/packages/twenty-front/src/modules/object-record/components/CommandMenuPageLayout.tsx @@ -135,9 +135,6 @@ export const CommandMenuPageLayout = ({ >