Refactor MainNavigationDrawer to enhance tab navigation and integrate AI chat functionality
- Removed MainNavigationDrawerFixedItems component and replaced it with MainNavigationDrawerTabsRow for improved tab management. - Introduced AIChatThreadsList within the MainNavigationDrawer for chat tab functionality. - Added navigationDrawerActiveTabState to manage active tab state. - Updated NavigationDrawerHeader to include a search button and adjusted styles for better layout consistency.
This commit is contained in:
@@ -1,17 +1,19 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { AIChatThreadsList } from '@/ai/components/AIChatThreadsList';
|
||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||
import { useFavoritesByFolder } from '@/favorites/hooks/useFavoritesByFolder';
|
||||
import { NavigationMenuItemFolderContentDispatcherEffect } from '@/navigation-menu-item/components/NavigationMenuItemFolderContentDispatcher';
|
||||
import { useNavigationMenuItemsByFolder } from '@/navigation-menu-item/hooks/useNavigationMenuItemsByFolder';
|
||||
import { MainNavigationDrawerFixedItems } from '@/navigation/components/MainNavigationDrawerFixedItems';
|
||||
import { MainNavigationDrawerScrollableItems } from '@/navigation/components/MainNavigationDrawerScrollableItems';
|
||||
import { MainNavigationDrawerTabsRow } from '@/navigation/components/MainNavigationDrawerTabsRow';
|
||||
import { NavigationDrawer } from '@/ui/navigation/navigation-drawer/components/NavigationDrawer';
|
||||
import { NavigationDrawerFixedContent } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerFixedContent';
|
||||
import { NavigationDrawerScrollableContent } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerScrollableContent';
|
||||
import { currentFavoriteFolderIdStateV2 } from '@/ui/navigation/navigation-drawer/states/currentFavoriteFolderIdStateV2';
|
||||
import { currentNavigationMenuItemFolderIdStateV2 } from '@/ui/navigation/navigation-drawer/states/currentNavigationMenuItemFolderIdStateV2';
|
||||
import { navigationDrawerActiveTabState } from '@/ui/navigation/states/navigationDrawerActiveTabState';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { FeatureFlagKey } from '~/generated-metadata/graphql';
|
||||
@@ -21,8 +23,16 @@ const StyledScrollableContent = styled.div`
|
||||
min-height: 0;
|
||||
`;
|
||||
|
||||
const StyledAIChatThreadsListWrapper = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
`;
|
||||
|
||||
export const MainNavigationDrawer = ({ className }: { className?: string }) => {
|
||||
const currentWorkspace = useRecoilValue(currentWorkspaceState);
|
||||
const activeTab = useRecoilValueV2(navigationDrawerActiveTabState);
|
||||
const currentFavoriteFolderId = useRecoilValueV2(
|
||||
currentFavoriteFolderIdStateV2,
|
||||
);
|
||||
@@ -55,11 +65,15 @@ export const MainNavigationDrawer = ({ className }: { className?: string }) => {
|
||||
title={currentWorkspace?.displayName ?? ''}
|
||||
>
|
||||
<NavigationDrawerFixedContent>
|
||||
<MainNavigationDrawerFixedItems />
|
||||
<MainNavigationDrawerTabsRow />
|
||||
</NavigationDrawerFixedContent>
|
||||
|
||||
<NavigationDrawerScrollableContent>
|
||||
{isNavigationMenuItemEditingEnabled ? (
|
||||
{activeTab === 'chat' ? (
|
||||
<StyledAIChatThreadsListWrapper>
|
||||
<AIChatThreadsList />
|
||||
</StyledAIChatThreadsListWrapper>
|
||||
) : isNavigationMenuItemEditingEnabled ? (
|
||||
<StyledScrollableContent>
|
||||
{openedFolder ? (
|
||||
<NavigationMenuItemFolderContentDispatcherEffect
|
||||
|
||||
-72
@@ -1,72 +0,0 @@
|
||||
import { useOpenAskAIPageInCommandMenu } from '@/command-menu/hooks/useOpenAskAIPageInCommandMenu';
|
||||
import { useOpenRecordsSearchPageInCommandMenu } from '@/command-menu/hooks/useOpenRecordsSearchPageInCommandMenu';
|
||||
import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem';
|
||||
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
|
||||
import { navigationDrawerExpandedMemorizedStateV2 } from '@/ui/navigation/states/navigationDrawerExpandedMemorizedStateV2';
|
||||
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
|
||||
import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2';
|
||||
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import { SettingsPath } from 'twenty-shared/types';
|
||||
import { getSettingsPath } from 'twenty-shared/utils';
|
||||
import { IconSearch, IconSettings, IconSparkles } from 'twenty-ui/display';
|
||||
import { useIsMobile } from 'twenty-ui/utilities';
|
||||
import { FeatureFlagKey } from '~/generated-metadata/graphql';
|
||||
|
||||
export const MainNavigationDrawerFixedItems = () => {
|
||||
const isMobile = useIsMobile();
|
||||
const location = useLocation();
|
||||
const setNavigationMemorizedUrl = useSetRecoilStateV2(
|
||||
navigationMemorizedUrlState,
|
||||
);
|
||||
|
||||
const [isNavigationDrawerExpanded, setIsNavigationDrawerExpanded] =
|
||||
useRecoilStateV2(isNavigationDrawerExpandedState);
|
||||
const setNavigationDrawerExpandedMemorized = useSetRecoilStateV2(
|
||||
navigationDrawerExpandedMemorizedStateV2,
|
||||
);
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { t } = useLingui();
|
||||
|
||||
const { openRecordsSearchPage } = useOpenRecordsSearchPageInCommandMenu();
|
||||
const { openAskAIPage } = useOpenAskAIPageInCommandMenu();
|
||||
const isAiEnabled = useIsFeatureEnabled(FeatureFlagKey.IS_AI_ENABLED);
|
||||
|
||||
return (
|
||||
!isMobile && (
|
||||
<>
|
||||
<NavigationDrawerItem
|
||||
label={t`Search`}
|
||||
Icon={IconSearch}
|
||||
onClick={openRecordsSearchPage}
|
||||
keyboard={['/']}
|
||||
mouseUpNavigation={true}
|
||||
/>
|
||||
{isAiEnabled && (
|
||||
<NavigationDrawerItem
|
||||
label={t`Ask AI`}
|
||||
Icon={IconSparkles}
|
||||
onClick={() => openAskAIPage({ resetNavigationStack: true })}
|
||||
keyboard={['@']}
|
||||
mouseUpNavigation={true}
|
||||
/>
|
||||
)}
|
||||
<NavigationDrawerItem
|
||||
label={t`Settings`}
|
||||
to={getSettingsPath(SettingsPath.ProfilePage)}
|
||||
onClick={() => {
|
||||
setNavigationDrawerExpandedMemorized(isNavigationDrawerExpanded);
|
||||
setIsNavigationDrawerExpanded(true);
|
||||
setNavigationMemorizedUrl(location.pathname + location.search);
|
||||
navigate(getSettingsPath(SettingsPath.ProfilePage));
|
||||
}}
|
||||
Icon={IconSettings}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
);
|
||||
};
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import {
|
||||
IconComment,
|
||||
IconHome,
|
||||
IconMessageCirclePlus,
|
||||
} from 'twenty-ui/display';
|
||||
import { useIsMobile } from 'twenty-ui/utilities';
|
||||
|
||||
import { useCreateNewAIChatThread } from '@/ai/hooks/useCreateNewAIChatThread';
|
||||
import {
|
||||
type NavigationDrawerActiveTab,
|
||||
navigationDrawerActiveTabState,
|
||||
} from '@/ui/navigation/states/navigationDrawerActiveTabState';
|
||||
import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { FeatureFlagKey } from '~/generated-metadata/graphql';
|
||||
|
||||
const StyledRow = styled.div`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const StyledTabsPill = styled.div`
|
||||
align-items: center;
|
||||
border: 1px solid ${({ theme }) => theme.border.color.medium};
|
||||
border-radius: ${({ theme }) => theme.border.radius.pill};
|
||||
padding: ${({ theme }) => theme.spacing(0.75)};
|
||||
height: ${({ theme }) => theme.spacing(7)};
|
||||
display: flex;
|
||||
width: ${({ theme }) => theme.spacing(18)};
|
||||
gap: ${({ theme }) => theme.spacing(0.5)};
|
||||
box-sizing: border-box;
|
||||
`;
|
||||
|
||||
const StyledTabWrapper = styled.div<{ isActive: boolean }>`
|
||||
border-radius: ${({ theme }) => theme.border.radius.pill};
|
||||
align-items: center;
|
||||
background: ${({ theme, isActive }) =>
|
||||
isActive ? theme.background.transparent.light : 'transparent'};
|
||||
color: ${({ theme, isActive }) =>
|
||||
isActive ? theme.font.color.primary : theme.font.color.tertiary};
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
|
||||
&:hover {
|
||||
background: ${({ theme, isActive }) =>
|
||||
isActive
|
||||
? theme.background.transparent.light
|
||||
: theme.background.transparent.lighter};
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledTabIcon = styled.div`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: ${({ theme }) => theme.spacing(5)};
|
||||
width: ${({ theme }) => theme.spacing(5)};
|
||||
`;
|
||||
|
||||
const StyledNewChatButtonWrapper = styled.div`
|
||||
border: 1px solid ${({ theme }) => theme.border.color.medium};
|
||||
border-radius: ${({ theme }) => theme.border.radius.pill};
|
||||
height: ${({ theme }) => theme.spacing(7)};
|
||||
padding: ${({ theme }) => theme.spacing(0.75)};
|
||||
width: ${({ theme }) => theme.spacing(25.75)};
|
||||
box-sizing: border-box;
|
||||
`;
|
||||
|
||||
const StyledNewChatButton = styled.div`
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
font-size: ${({ theme }) => theme.font.size.sm};
|
||||
font-weight: ${({ theme }) => theme.font.weight.medium};
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border-radius: inherit;
|
||||
color: ${({ theme }) => theme.font.color.secondary};
|
||||
transition:
|
||||
background ${({ theme }) => theme.animation.duration.fast}s ease,
|
||||
color ${({ theme }) => theme.animation.duration.fast}s ease;
|
||||
|
||||
&:hover {
|
||||
background: ${({ theme }) => theme.background.transparent.light};
|
||||
color: ${({ theme }) => theme.font.color.primary};
|
||||
}
|
||||
`;
|
||||
|
||||
export const MainNavigationDrawerTabsRow = () => {
|
||||
const theme = useTheme();
|
||||
const isMobile = useIsMobile();
|
||||
const [activeTab, setActiveTab] = useRecoilStateV2(
|
||||
navigationDrawerActiveTabState,
|
||||
);
|
||||
const { createChatThread } = useCreateNewAIChatThread();
|
||||
const isAiEnabled = useIsFeatureEnabled(FeatureFlagKey.IS_AI_ENABLED);
|
||||
|
||||
if (isMobile || !isAiEnabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const handleTabClick = (tab: NavigationDrawerActiveTab) => () => {
|
||||
setActiveTab(tab);
|
||||
};
|
||||
|
||||
const handleTabKeyDown =
|
||||
(tab: NavigationDrawerActiveTab) => (event: React.KeyboardEvent) => {
|
||||
if (event.key === 'Enter' || event.key === ' ') {
|
||||
event.preventDefault();
|
||||
setActiveTab(tab);
|
||||
}
|
||||
};
|
||||
|
||||
const handleNewChatKeyDown = (event: React.KeyboardEvent) => {
|
||||
if (event.key === 'Enter' || event.key === ' ') {
|
||||
event.preventDefault();
|
||||
createChatThread();
|
||||
}
|
||||
};
|
||||
|
||||
const getTabIconColor = (isActive: boolean) =>
|
||||
isActive ? theme.font.color.primary : theme.font.color.tertiary;
|
||||
|
||||
return (
|
||||
<StyledRow>
|
||||
<StyledTabsPill role="tablist" aria-label={t`Navigation tabs`}>
|
||||
<StyledTabWrapper
|
||||
isActive={activeTab === 'home'}
|
||||
role="tab"
|
||||
aria-selected={activeTab === 'home'}
|
||||
aria-label={t`Home`}
|
||||
tabIndex={activeTab === 'home' ? 0 : -1}
|
||||
onClick={handleTabClick('home')}
|
||||
onKeyDown={handleTabKeyDown('home')}
|
||||
>
|
||||
<StyledTabIcon>
|
||||
<IconHome
|
||||
size={theme.icon.size.sm}
|
||||
color={getTabIconColor(activeTab === 'home')}
|
||||
/>
|
||||
</StyledTabIcon>
|
||||
</StyledTabWrapper>
|
||||
<StyledTabWrapper
|
||||
isActive={activeTab === 'chat'}
|
||||
role="tab"
|
||||
aria-selected={activeTab === 'chat'}
|
||||
aria-label={t`Chat`}
|
||||
tabIndex={activeTab === 'chat' ? 0 : -1}
|
||||
onClick={handleTabClick('chat')}
|
||||
onKeyDown={handleTabKeyDown('chat')}
|
||||
>
|
||||
<StyledTabIcon>
|
||||
<IconComment
|
||||
size={theme.icon.size.sm}
|
||||
color={getTabIconColor(activeTab === 'chat')}
|
||||
/>
|
||||
</StyledTabIcon>
|
||||
</StyledTabWrapper>
|
||||
</StyledTabsPill>
|
||||
<StyledNewChatButtonWrapper>
|
||||
<StyledNewChatButton
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
aria-label={t`New chat`}
|
||||
onClick={() => createChatThread()}
|
||||
onKeyDown={handleNewChatKeyDown}
|
||||
>
|
||||
<IconMessageCirclePlus size={theme.icon.size.md} />
|
||||
{t`New chat`}
|
||||
</StyledNewChatButton>
|
||||
</StyledNewChatButtonWrapper>
|
||||
</StyledRow>
|
||||
);
|
||||
};
|
||||
+29
@@ -19,13 +19,18 @@ import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownM
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { MULTI_WORKSPACE_DROPDOWN_ID } from '@/ui/navigation/navigation-drawer/constants/MultiWorkspaceDropdownId';
|
||||
import { multiWorkspaceDropdownStateV2 } from '@/ui/navigation/navigation-drawer/states/multiWorkspaceDropdownStateV2';
|
||||
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
|
||||
import { navigationDrawerExpandedMemorizedStateV2 } from '@/ui/navigation/states/navigationDrawerExpandedMemorizedStateV2';
|
||||
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
|
||||
import { useColorScheme } from '@/ui/theme/hooks/useColorScheme';
|
||||
import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2';
|
||||
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
|
||||
import { type ApolloError } from '@apollo/client';
|
||||
import styled from '@emotion/styled';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import { AppPath, SettingsPath } from 'twenty-shared/types';
|
||||
import { getSettingsPath } from 'twenty-shared/utils';
|
||||
import {
|
||||
@@ -35,6 +40,7 @@ import {
|
||||
IconLogout,
|
||||
IconMessage,
|
||||
IconPlus,
|
||||
IconSettings,
|
||||
IconSwitchHorizontal,
|
||||
IconUserPlus,
|
||||
} from 'twenty-ui/display';
|
||||
@@ -79,6 +85,17 @@ export const MultiWorkspaceDropdownDefaultComponents = () => {
|
||||
multiWorkspaceDropdownStateV2,
|
||||
);
|
||||
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const [isNavigationDrawerExpanded, setIsNavigationDrawerExpanded] =
|
||||
useRecoilStateV2(isNavigationDrawerExpandedState);
|
||||
const setNavigationDrawerExpandedMemorized = useSetRecoilStateV2(
|
||||
navigationDrawerExpandedMemorizedStateV2,
|
||||
);
|
||||
const setNavigationMemorizedUrl = useSetRecoilStateV2(
|
||||
navigationMemorizedUrlState,
|
||||
);
|
||||
|
||||
const handleSupport = () => {
|
||||
window.FrontChat?.('show');
|
||||
closeDropdown(MULTI_WORKSPACE_DROPDOWN_ID);
|
||||
@@ -225,6 +242,18 @@ export const MultiWorkspaceDropdownDefaultComponents = () => {
|
||||
>
|
||||
<MenuItem LeftIcon={IconUserPlus} text={t`Invite user`} />
|
||||
</UndecoratedLink>
|
||||
<UndecoratedLink
|
||||
to={getSettingsPath(SettingsPath.ProfilePage)}
|
||||
onClick={() => {
|
||||
setNavigationDrawerExpandedMemorized(isNavigationDrawerExpanded);
|
||||
setIsNavigationDrawerExpanded(true);
|
||||
setNavigationMemorizedUrl(location.pathname + location.search);
|
||||
navigate(getSettingsPath(SettingsPath.ProfilePage));
|
||||
closeDropdown(MULTI_WORKSPACE_DROPDOWN_ID);
|
||||
}}
|
||||
>
|
||||
<MenuItem LeftIcon={IconSettings} text={t`Settings`} />
|
||||
</UndecoratedLink>
|
||||
{isSupportChatConfigured && (
|
||||
<MenuItem
|
||||
LeftIcon={IconMessage}
|
||||
|
||||
+28
-11
@@ -1,10 +1,13 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { IconSearch } from 'twenty-ui/display';
|
||||
import { LightIconButton } from 'twenty-ui/input';
|
||||
|
||||
import { MultiWorkspaceDropdownButton } from '@/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/MultiWorkspaceDropdownButton';
|
||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||
|
||||
import { useOpenRecordsSearchPageInCommandMenu } from '@/command-menu/hooks/useOpenRecordsSearchPageInCommandMenu';
|
||||
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';
|
||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { NavigationDrawerCollapseButton } from './NavigationDrawerCollapseButton';
|
||||
|
||||
@@ -16,15 +19,20 @@ const StyledContainer = styled.div`
|
||||
min-height: ${PAGE_BAR_MIN_HEIGHT}px;
|
||||
`;
|
||||
|
||||
const StyledRightActions = styled.div`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
margin-left: auto;
|
||||
`;
|
||||
|
||||
const StyledNavigationDrawerCollapseButton = styled(
|
||||
NavigationDrawerCollapseButton,
|
||||
)<{ show?: boolean }>`
|
||||
height: ${({ theme }) => theme.spacing(4)};
|
||||
margin-left: auto;
|
||||
height: ${({ theme }) => theme.spacing(6)};
|
||||
opacity: ${({ show }) => (show ? 1 : 0)};
|
||||
padding-right: ${({ theme }) => theme.spacing(1)};
|
||||
transition: opacity ${({ theme }) => theme.animation.duration.normal}s;
|
||||
width: ${({ theme }) => theme.spacing(4)};
|
||||
width: ${({ theme }) => theme.spacing(6)};
|
||||
`;
|
||||
|
||||
type NavigationDrawerHeaderProps = {
|
||||
@@ -35,7 +43,7 @@ export const NavigationDrawerHeader = ({
|
||||
showCollapseButton,
|
||||
}: NavigationDrawerHeaderProps) => {
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
const { openRecordsSearchPage } = useOpenRecordsSearchPageInCommandMenu();
|
||||
const isNavigationDrawerExpanded = useRecoilValueV2(
|
||||
isNavigationDrawerExpandedState,
|
||||
);
|
||||
@@ -44,10 +52,19 @@ export const NavigationDrawerHeader = ({
|
||||
<StyledContainer>
|
||||
<MultiWorkspaceDropdownButton />
|
||||
{!isMobile && isNavigationDrawerExpanded && (
|
||||
<StyledNavigationDrawerCollapseButton
|
||||
direction="left"
|
||||
show={showCollapseButton}
|
||||
/>
|
||||
<StyledRightActions>
|
||||
<LightIconButton
|
||||
Icon={IconSearch}
|
||||
accent="tertiary"
|
||||
size="small"
|
||||
onClick={openRecordsSearchPage}
|
||||
aria-label={t`Search`}
|
||||
/>
|
||||
<StyledNavigationDrawerCollapseButton
|
||||
direction="left"
|
||||
show={showCollapseButton}
|
||||
/>
|
||||
</StyledRightActions>
|
||||
)}
|
||||
</StyledContainer>
|
||||
);
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
|
||||
|
||||
export type NavigationDrawerActiveTab = 'home' | 'chat';
|
||||
|
||||
export const navigationDrawerActiveTabState =
|
||||
createStateV2<NavigationDrawerActiveTab>({
|
||||
key: 'navigationDrawerActiveTab',
|
||||
defaultValue: 'home',
|
||||
});
|
||||
Reference in New Issue
Block a user