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 = ({
>