From aeed1c9f15906adf89a90561c9fe379dbd1f9380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Bosi?= <71827178+bosiraphael@users.noreply.github.com> Date: Tue, 18 Feb 2025 18:07:11 +0100 Subject: [PATCH] 406 animate the command menu button (#10305) Closes https://github.com/twentyhq/core-team-issues/issues/406 - Added animation on the Icon (The dots rotate and transform into an a cross) - Introduced a new component `AnimatedButton`. All the button styling could be extracted to another file so we don't duplicate the code, but since `AnimatedLightIconButton` duplicates the style from `LightIconButton`, I did the same here. - Added an animate presence component on the command menu to have a smooth transition from `open` to `close` state - Merged the open and close command menu button - For all the pages that are not an index page or a record page, we want the old behavior because there is no button in the page header to open the command menu # Before https://github.com/user-attachments/assets/5ec7d9eb-9d8b-4838-af1b-c04382694342 # After https://github.com/user-attachments/assets/f700deec-1c52-4afd-b294-f9ee7b9206e9 --- .../components/CommandMenuContainer.tsx | 33 +- .../components/CommandMenuRouter.tsx | 16 +- .../components/CommandMenuTopBar.tsx | 14 +- .../PageHeaderOpenCommandMenuButton.tsx | 130 ++++- .../button/components/AnimatedButton.tsx | 449 ++++++++++++++++++ packages/twenty-ui/src/input/index.ts | 1 + 6 files changed, 615 insertions(+), 28 deletions(-) create mode 100644 packages/twenty-ui/src/input/button/components/AnimatedButton.tsx diff --git a/packages/twenty-front/src/modules/command-menu/components/CommandMenuContainer.tsx b/packages/twenty-front/src/modules/command-menu/components/CommandMenuContainer.tsx index 3a646f947..60df5e421 100644 --- a/packages/twenty-front/src/modules/command-menu/components/CommandMenuContainer.tsx +++ b/packages/twenty-front/src/modules/command-menu/components/CommandMenuContainer.tsx @@ -20,7 +20,7 @@ import { workflowReactFlowRefState } from '@/workflow/workflow-diagram/states/wo import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; -import { motion } from 'framer-motion'; +import { AnimatePresence, motion } from 'framer-motion'; import { useRef } from 'react'; import { useRecoilValue, useSetRecoilState } from 'recoil'; import { useIsMobile } from 'twenty-ui'; @@ -65,6 +65,7 @@ export const CommandMenuContainer = ({ callback: closeCommandMenu, listenerId: 'COMMAND_MENU_LISTENER_ID', hotkeyScope: AppHotkeyScope.CommandMenuOpen, + excludeClassNames: ['page-header-command-menu-button'], }); const isMobile = useIsMobile(); @@ -114,20 +115,22 @@ export const CommandMenuContainer = ({ )} - {isCommandMenuOpened && ( - - {children} - - )} + + {isCommandMenuOpened && ( + + {children} + + )} + diff --git a/packages/twenty-front/src/modules/command-menu/components/CommandMenuRouter.tsx b/packages/twenty-front/src/modules/command-menu/components/CommandMenuRouter.tsx index dcae344a6..570e2f34e 100644 --- a/packages/twenty-front/src/modules/command-menu/components/CommandMenuRouter.tsx +++ b/packages/twenty-front/src/modules/command-menu/components/CommandMenuRouter.tsx @@ -2,7 +2,9 @@ import { CommandMenuContainer } from '@/command-menu/components/CommandMenuConta import { CommandMenuTopBar } from '@/command-menu/components/CommandMenuTopBar'; import { COMMAND_MENU_PAGES_CONFIG } from '@/command-menu/constants/CommandMenuPagesConfig'; import { commandMenuPageState } from '@/command-menu/states/commandMenuPageState'; +import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; +import { motion } from 'framer-motion'; import { useRecoilValue } from 'recoil'; import { isDefined } from 'twenty-shared'; @@ -20,9 +22,21 @@ export const CommandMenuRouter = () => { <> ); + const theme = useTheme(); + return ( - + + + {commandMenuPageComponent} diff --git a/packages/twenty-front/src/modules/command-menu/components/CommandMenuTopBar.tsx b/packages/twenty-front/src/modules/command-menu/components/CommandMenuTopBar.tsx index 68033af5b..5848b6147 100644 --- a/packages/twenty-front/src/modules/command-menu/components/CommandMenuTopBar.tsx +++ b/packages/twenty-front/src/modules/command-menu/components/CommandMenuTopBar.tsx @@ -16,6 +16,7 @@ import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { useLingui } from '@lingui/react/macro'; import { useMemo, useRef } from 'react'; +import { useLocation } from 'react-router-dom'; import { useRecoilState, useRecoilValue } from 'recoil'; import { isDefined } from 'twenty-shared'; import { @@ -80,6 +81,10 @@ const StyledCloseButtonContainer = styled.div` justify-content: center; `; +const StyledCloseButtonWrapper = styled.div<{ isVisible: boolean }>` + visibility: ${({ isVisible }) => (isVisible ? 'visible' : 'hidden')}; +`; + export const CommandMenuTopBar = () => { const [commandMenuSearch, setCommandMenuSearch] = useRecoilState( commandMenuSearchState, @@ -123,6 +128,11 @@ export const CommandMenuTopBar = () => { }); }, [commandMenuNavigationStack, theme.icon.size.sm]); + const location = useLocation(); + const isButtonVisible = + !location.pathname.startsWith('/objects/') && + !location.pathname.startsWith('/object/'); + return ( @@ -162,7 +172,7 @@ export const CommandMenuTopBar = () => { )} {!isMobile && ( - <> + {isCommandMenuV2Enabled ? (