refactor!: rename Command Menu page/navigation layer to Side Panel (#18393)
This commit is contained in:
+2
-2
@@ -13,8 +13,8 @@
|
||||
* TODO: add the other remaining components that can appear in the root stacking context
|
||||
*/
|
||||
export enum RootStackingContextZIndices {
|
||||
CommandMenu = 21,
|
||||
CommandMenuButton = 22,
|
||||
SidePanel = 21,
|
||||
SidePanelButton = 22,
|
||||
DropdownPortalBelowModal = 38,
|
||||
RootModalBackDrop = 39,
|
||||
RootModal = 40,
|
||||
|
||||
@@ -10,7 +10,7 @@ export type LayoutRenderingContextType = {
|
||||
|
||||
layoutType: PageLayoutType;
|
||||
|
||||
isInRightDrawer: boolean;
|
||||
isInSidePanel: boolean;
|
||||
};
|
||||
|
||||
export const [LayoutRenderingProvider, useLayoutRenderingContext] =
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { SIDE_PANEL_FOCUS_ID } from '@/command-menu/constants/SidePanelFocusId';
|
||||
import { SIDE_PANEL_FOCUS_ID } from '@/side-panel/constants/SidePanelFocusId';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
|
||||
+35
-36
@@ -1,9 +1,9 @@
|
||||
import { COMMAND_MENU_SEARCH_BAR_HEIGHT_MOBILE } from '@/command-menu/constants/CommandMenuSearchBarHeightMobile';
|
||||
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
|
||||
import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState';
|
||||
import { SIDE_PANEL_TOP_BAR_HEIGHT_MOBILE } from '@/side-panel/constants/SidePanelTopBarHeightMobile';
|
||||
import { useSidePanelMenu } from '@/side-panel/hooks/useSidePanelMenu';
|
||||
import { isSidePanelOpenedState } from '@/side-panel/states/isSidePanelOpenedState';
|
||||
import { isNavigationMenuInEditModeState } from '@/navigation-menu-item/states/isNavigationMenuInEditModeState';
|
||||
import { RootStackingContextZIndices } from '@/ui/layout/constants/RootStackingContextZIndices';
|
||||
import { PAGE_HEADER_COMMAND_MENU_BUTTON_CLICK_OUTSIDE_ID } from '@/ui/layout/page-header/constants/PageHeaderCommandMenuButtonClickOutsideId';
|
||||
import { PAGE_HEADER_SIDE_PANEL_BUTTON_CLICK_OUTSIDE_ID } from '@/ui/layout/page-header/constants/PageHeaderSidePanelButtonClickOutsideId';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { styled } from '@linaria/react';
|
||||
import { i18n } from '@lingui/core';
|
||||
@@ -18,12 +18,12 @@ const StyledButtonWrapper = styled.div<{ alignToTop: boolean }>`
|
||||
align-items: ${({ alignToTop }) => (alignToTop ? 'center' : 'initial')};
|
||||
display: ${({ alignToTop }) => (alignToTop ? 'flex' : 'block')};
|
||||
height: ${({ alignToTop }) =>
|
||||
alignToTop ? `${COMMAND_MENU_SEARCH_BAR_HEIGHT_MOBILE}px` : 'auto'};
|
||||
alignToTop ? `${SIDE_PANEL_TOP_BAR_HEIGHT_MOBILE}px` : 'auto'};
|
||||
position: ${({ alignToTop }) => (alignToTop ? 'fixed' : 'static')};
|
||||
right: ${({ alignToTop }) =>
|
||||
alignToTop ? themeCssVariables.spacing[3] : 'auto'};
|
||||
top: ${({ alignToTop }) => (alignToTop ? '0' : 'auto')};
|
||||
z-index: ${RootStackingContextZIndices.CommandMenuButton};
|
||||
z-index: ${RootStackingContextZIndices.SidePanelButton};
|
||||
`;
|
||||
|
||||
const StyledTooltipWrapper = styled.div`
|
||||
@@ -38,9 +38,9 @@ const xPaths = {
|
||||
};
|
||||
|
||||
const AnimatedIcon = ({
|
||||
isCommandMenuOpened,
|
||||
isSidePanelOpened,
|
||||
}: {
|
||||
isCommandMenuOpened: boolean;
|
||||
isSidePanelOpened: boolean;
|
||||
}) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
@@ -64,8 +64,8 @@ const AnimatedIcon = ({
|
||||
r="1"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{
|
||||
scale: isCommandMenuOpened ? 0 : 1,
|
||||
opacity: isCommandMenuOpened ? 0 : 1,
|
||||
scale: isSidePanelOpened ? 0 : 1,
|
||||
opacity: isSidePanelOpened ? 0 : 1,
|
||||
}}
|
||||
transition={{
|
||||
duration: theme.animation.duration.fast,
|
||||
@@ -79,13 +79,13 @@ const AnimatedIcon = ({
|
||||
d={path}
|
||||
initial={{ pathLength: 0, opacity: 0 }}
|
||||
animate={{
|
||||
pathLength: isCommandMenuOpened ? 1 : 0,
|
||||
opacity: isCommandMenuOpened ? 1 : 0,
|
||||
pathLength: isSidePanelOpened ? 1 : 0,
|
||||
opacity: isSidePanelOpened ? 1 : 0,
|
||||
}}
|
||||
transition={{
|
||||
duration: theme.animation.duration.fast,
|
||||
ease: 'easeInOut',
|
||||
delay: isCommandMenuOpened ? 0.1 : 0,
|
||||
delay: isSidePanelOpened ? 0.1 : 0,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
@@ -97,8 +97,8 @@ const AnimatedIcon = ({
|
||||
r="1"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{
|
||||
scale: isCommandMenuOpened ? 0 : 1,
|
||||
opacity: isCommandMenuOpened ? 0 : 1,
|
||||
scale: isSidePanelOpened ? 0 : 1,
|
||||
opacity: isSidePanelOpened ? 0 : 1,
|
||||
}}
|
||||
transition={{
|
||||
duration: theme.animation.duration.fast,
|
||||
@@ -112,8 +112,8 @@ const AnimatedIcon = ({
|
||||
r="1"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{
|
||||
scale: isCommandMenuOpened ? 0 : 1,
|
||||
opacity: isCommandMenuOpened ? 0 : 1,
|
||||
scale: isSidePanelOpened ? 0 : 1,
|
||||
opacity: isSidePanelOpened ? 0 : 1,
|
||||
}}
|
||||
transition={{
|
||||
duration: theme.animation.duration.fast,
|
||||
@@ -123,39 +123,38 @@ const AnimatedIcon = ({
|
||||
);
|
||||
};
|
||||
|
||||
export const PageHeaderToggleCommandMenuButton = () => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const { toggleCommandMenu } = useCommandMenu();
|
||||
const isCommandMenuOpened = useAtomStateValue(isCommandMenuOpenedState);
|
||||
export const PageHeaderToggleSidePanelButton = () => {
|
||||
const { toggleSidePanelMenu } = useSidePanelMenu();
|
||||
const isSidePanelOpened = useAtomStateValue(isSidePanelOpenedState);
|
||||
const isNavigationMenuInEditMode = useAtomStateValue(
|
||||
isNavigationMenuInEditModeState,
|
||||
);
|
||||
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
const alignWithCommandMenuTopBar =
|
||||
isMobile && isNavigationMenuInEditMode && isCommandMenuOpened;
|
||||
const alignWithSidePanelTopBar =
|
||||
isMobile && isNavigationMenuInEditMode && isSidePanelOpened;
|
||||
|
||||
const ariaLabel = isCommandMenuOpened
|
||||
? t`Close command menu`
|
||||
: t`Open command menu`;
|
||||
const ariaLabel = isSidePanelOpened
|
||||
? t`Close side panel`
|
||||
: t`Open side panel`;
|
||||
|
||||
const { theme } = useContext(ThemeContext);
|
||||
return (
|
||||
<StyledButtonWrapper alignToTop={alignWithCommandMenuTopBar}>
|
||||
<div id="toggle-command-menu-button">
|
||||
<StyledButtonWrapper alignToTop={alignWithSidePanelTopBar}>
|
||||
<div id="toggle-side-panel-button">
|
||||
<AnimatedButton
|
||||
animatedSvg={
|
||||
<AnimatedIcon isCommandMenuOpened={isCommandMenuOpened} />
|
||||
}
|
||||
dataClickOutsideId={PAGE_HEADER_COMMAND_MENU_BUTTON_CLICK_OUTSIDE_ID}
|
||||
dataTestId="page-header-command-menu-button"
|
||||
animatedSvg={<AnimatedIcon isSidePanelOpened={isSidePanelOpened} />}
|
||||
dataClickOutsideId={PAGE_HEADER_SIDE_PANEL_BUTTON_CLICK_OUTSIDE_ID}
|
||||
dataTestId="page-header-side-panel-button"
|
||||
size={isMobile ? 'medium' : 'small'}
|
||||
variant="secondary"
|
||||
accent="default"
|
||||
hotkeys={[getOsControlSymbol(), 'K']}
|
||||
ariaLabel={ariaLabel}
|
||||
onClick={toggleCommandMenu}
|
||||
onClick={toggleSidePanelMenu}
|
||||
animate={{
|
||||
rotate: isCommandMenuOpened ? 90 : 0,
|
||||
rotate: isSidePanelOpened ? 90 : 0,
|
||||
}}
|
||||
transition={{
|
||||
duration: theme.animation.duration.normal,
|
||||
@@ -166,7 +165,7 @@ export const PageHeaderToggleCommandMenuButton = () => {
|
||||
|
||||
<StyledTooltipWrapper>
|
||||
<AppTooltip
|
||||
anchorSelect="#toggle-command-menu-button"
|
||||
anchorSelect="#toggle-side-panel-button"
|
||||
content={i18n._(ariaLabel)}
|
||||
delay={TooltipDelay.longDelay}
|
||||
place={TooltipPosition.Bottom}
|
||||
-2
@@ -1,2 +0,0 @@
|
||||
export const PAGE_HEADER_COMMAND_MENU_BUTTON_CLICK_OUTSIDE_ID =
|
||||
'page-header-command-menu-button';
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
export const PAGE_HEADER_SIDE_PANEL_BUTTON_CLICK_OUTSIDE_ID =
|
||||
'page-header-side-panel-button';
|
||||
@@ -24,7 +24,7 @@ const StyledMainContainer = styled.div`
|
||||
`;
|
||||
|
||||
type LeftContainerProps = {
|
||||
isRightDrawerOpen?: boolean;
|
||||
isSidePanelOpen?: boolean;
|
||||
};
|
||||
|
||||
const StyledLeftContainer = styled.div<LeftContainerProps>`
|
||||
|
||||
-7
@@ -1,7 +0,0 @@
|
||||
import { type ResizablePanelConstraints } from '@/ui/layout/resizable-panel/types/ResizablePanelConstraints';
|
||||
|
||||
export const COMMAND_MENU_CONSTRAINTS: ResizablePanelConstraints = {
|
||||
min: 320,
|
||||
max: 600,
|
||||
default: 400,
|
||||
};
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
import { createRequiredContext } from '~/utils/createRequiredContext';
|
||||
|
||||
type RightDrawerContextType = {
|
||||
isInRightDrawer: boolean;
|
||||
};
|
||||
|
||||
export const [RightDrawerProvider, useIsInRightDrawerOrThrow] =
|
||||
createRequiredContext<RightDrawerContextType>('RightDrawer');
|
||||
+2
-2
@@ -15,11 +15,11 @@ const StyledContainer = styled.div`
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
type RightDrawerFooterProps = {
|
||||
type SidePanelFooterProps = {
|
||||
actions: React.ReactNode[];
|
||||
};
|
||||
|
||||
export const RightDrawerFooter = ({ actions }: RightDrawerFooterProps) => {
|
||||
export const SidePanelFooter = ({ actions }: SidePanelFooterProps) => {
|
||||
return (
|
||||
<StyledContainer>
|
||||
{actions.map((action, index) => (
|
||||
@@ -0,0 +1,8 @@
|
||||
import { createRequiredContext } from '~/utils/createRequiredContext';
|
||||
|
||||
type SidePanelContextType = {
|
||||
isInSidePanel: boolean;
|
||||
};
|
||||
|
||||
export const [SidePanelProvider, useIsInSidePanelOrThrow] =
|
||||
createRequiredContext<SidePanelContextType>('SidePanel');
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { SIDE_PANEL_CLOSE_EVENT_NAME } from '@/ui/layout/right-drawer/utils/emitSidePanelCloseEvent';
|
||||
import { SIDE_PANEL_CLOSE_EVENT_NAME } from '@/ui/layout/side-panel/utils/emitSidePanelCloseEvent';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
export const useListenToSidePanelClosing = (callback: () => void) => {
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { SIDE_PANEL_OPEN_EVENT_NAME } from '@/ui/layout/right-drawer/utils/emitSidePanelOpenEvent';
|
||||
import { SIDE_PANEL_OPEN_EVENT_NAME } from '@/ui/layout/side-panel/utils/emitSidePanelOpenEvent';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
export const useListenToSidePanelOpening = (callback: () => void) => {
|
||||
@@ -46,7 +46,7 @@ export const TabList = ({
|
||||
tabs,
|
||||
loading,
|
||||
behaveAsLinks = true,
|
||||
isInRightDrawer,
|
||||
isInSidePanel,
|
||||
className,
|
||||
componentInstanceId,
|
||||
onChangeTab,
|
||||
@@ -118,7 +118,7 @@ export const TabList = ({
|
||||
>
|
||||
<>
|
||||
<TabListFromUrlOptionalEffect
|
||||
isInRightDrawer={!!isInRightDrawer}
|
||||
isInSidePanel={!!isInSidePanel}
|
||||
tabListIds={tabs.map((tab) => tab.id)}
|
||||
/>
|
||||
|
||||
|
||||
+4
-4
@@ -6,12 +6,12 @@ import { useLocation } from 'react-router-dom';
|
||||
|
||||
type TabListFromUrlOptionalEffectProps = {
|
||||
tabListIds: string[];
|
||||
isInRightDrawer: boolean;
|
||||
isInSidePanel: boolean;
|
||||
};
|
||||
|
||||
export const TabListFromUrlOptionalEffect = ({
|
||||
tabListIds,
|
||||
isInRightDrawer,
|
||||
isInSidePanel,
|
||||
}: TabListFromUrlOptionalEffectProps) => {
|
||||
const location = useLocation();
|
||||
const activeTabId = useAtomComponentStateValue(activeTabIdComponentState);
|
||||
@@ -20,7 +20,7 @@ export const TabListFromUrlOptionalEffect = ({
|
||||
const hash = location.hash.replace('#', '');
|
||||
|
||||
useEffect(() => {
|
||||
if (isInRightDrawer) {
|
||||
if (isInSidePanel) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ export const TabListFromUrlOptionalEffect = ({
|
||||
if (tabListIds.includes(hash)) {
|
||||
setActiveTabId(hash);
|
||||
}
|
||||
}, [hash, activeTabId, setActiveTabId, tabListIds, isInRightDrawer]);
|
||||
}, [hash, activeTabId, setActiveTabId, tabListIds, isInSidePanel]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
|
||||
+1
-1
@@ -76,7 +76,7 @@ export const Default: Story = {
|
||||
componentInstanceId={args.componentInstanceId}
|
||||
loading={args.loading}
|
||||
behaveAsLinks={args.behaveAsLinks}
|
||||
isInRightDrawer={args.isInRightDrawer}
|
||||
isInSidePanel={args.isInSidePanel}
|
||||
className={args.className}
|
||||
/>
|
||||
</StyledInteractiveContainer>
|
||||
|
||||
@@ -5,7 +5,7 @@ export type TabListProps = {
|
||||
loading?: boolean;
|
||||
behaveAsLinks?: boolean;
|
||||
className?: string;
|
||||
isInRightDrawer?: boolean;
|
||||
isInSidePanel?: boolean;
|
||||
componentInstanceId: string;
|
||||
onChangeTab?: (tabId: string) => void;
|
||||
};
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@ import { IconSearch } from 'twenty-ui/display';
|
||||
import { LightIconButton } from 'twenty-ui/input';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
import { useOpenRecordsSearchPageInCommandMenu } from '@/command-menu/hooks/useOpenRecordsSearchPageInCommandMenu';
|
||||
import { useOpenRecordsSearchPageInSidePanel } from '@/side-panel/hooks/useOpenRecordsSearchPageInSidePanel';
|
||||
import { PAGE_BAR_MIN_HEIGHT } from '@/ui/layout/page/constants/PageBarMinHeight';
|
||||
import { MultiWorkspaceDropdownButton } from '@/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/MultiWorkspaceDropdownButton';
|
||||
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
|
||||
@@ -56,7 +56,7 @@ export const NavigationDrawerHeader = ({
|
||||
showCollapseButton,
|
||||
}: NavigationDrawerHeaderProps) => {
|
||||
const isMobile = useIsMobile();
|
||||
const { openRecordsSearchPage } = useOpenRecordsSearchPageInCommandMenu();
|
||||
const { openRecordsSearchPage } = useOpenRecordsSearchPageInSidePanel();
|
||||
const isNavigationDrawerExpanded = useAtomStateValue(
|
||||
isNavigationDrawerExpandedState,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user