style(Nav): improve Nav transition for open/close (#652)

* Revert "Animated sidebar (#649)"

This reverts commit dd19323280.

* in progress

* style(Nav): improve transition for Nav
This commit is contained in:
Danny Avila 2023-07-15 10:43:15 -04:00 committed by GitHub
parent dd19323280
commit 15987abe0a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 74 additions and 124 deletions

View file

@ -12,7 +12,7 @@ export default function MobileNav({ setNavVisible }) {
<div className="fixed left-0 right-0 top-0 z-10 flex items-center border-b border-white/20 bg-gray-800 pl-1 pt-1 text-gray-200 sm:pl-3 md:hidden">
<button
type="button"
className="-ml-0.5 -mt-0.5 inline-flex h-10 w-10 items-center justify-center rounded-md hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white dark:hover:text-white"
className="-ml-0.5 -mt-0.5 inline-flex h-10 w-10 items-center justify-center rounded-md hover:text-gray-900 focus:outline-none focus:ring-0 focus:ring-inset focus:ring-white dark:hover:text-white"
onClick={() => setNavVisible((prev) => !prev)}
>
<span className="sr-only">Open sidebar</span>

View file

@ -1,4 +1,3 @@
/* eslint-disable react-hooks/exhaustive-deps */
import { useCallback, useEffect, useRef, useState } from 'react';
import { useGetConversationsQuery, useSearchQuery } from '@librechat/data-provider';
import { useRecoilValue, useSetRecoilState } from 'recoil';
@ -7,33 +6,12 @@ import Conversations from '../Conversations';
import NavLinks from './NavLinks';
import NewChat from './NewChat';
import Pages from '../Conversations/Pages';
import Panel from '../svg/Panel';
import Spinner from '../svg/Spinner';
import { Panel, Spinner } from '~/components';
import { cn } from '~/utils/';
import store from '~/store';
import { useAuthContext } from '~/hooks/AuthContext';
import useDebounce from '~/hooks/useDebounce';
// import resolveConfig from 'tailwindcss/resolveConfig';
// const tailwindConfig = import('../../../tailwind.config.cjs');
// const fullConfig = resolveConfig(tailwindConfig);
// export const getBreakpointValue = (value) =>
// +fullConfig.theme.screens[value].slice(0, fullConfig.theme.screens[value].indexOf('px'));
// export const getCurrentBreakpoint = () => {
// let currentBreakpoint;
// let biggestBreakpointValue = 0;
// for (const breakpoint of Object.keys(fullConfig.theme.screens)) {
// const breakpointValue = getBreakpointValue(breakpoint);
// if (breakpointValue > biggestBreakpointValue && window.innerWidth >= breakpointValue) {
// biggestBreakpointValue = breakpointValue;
// currentBreakpoint = breakpoint;
// }
// }
// return currentBreakpoint;
// };
export default function Nav({ navVisible, setNavVisible }) {
const [isHovering, setIsHovering] = useState(false);
const { isAuthenticated } = useAuthContext();
@ -140,34 +118,13 @@ export default function Nav({ navVisible, setNavVisible }) {
if (!isSearching) {
getConversationsQuery.refetch();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [pageNumber, conversationId, refreshConversationsHint]);
const toggleNavVisible = () => {
setNavVisible((prev) => !prev);
};
// useEffect(() => {
// let currentBreakpoint = getCurrentBreakpoint();
// if (currentBreakpoint === 'sm') {
// setNavVisible(false);
// } else {
// setNavVisible(true);
// }
// }, [conversationId, setNavVisible]);
const isMobile = () => {
const userAgent = typeof window.navigator === 'undefined' ? '' : navigator.userAgent;
const mobileRegex =
/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile|mobile|CriOS/i;
return mobileRegex.test(userAgent);
};
useEffect(() => {
if (isMobile()) {
setNavVisible(false);
}
}, [conversationId, setNavVisible]);
const containerClasses =
getConversationsQuery.isLoading && pageNumber === 1
? 'flex flex-col gap-2 text-gray-100 text-sm h-full justify-center items-center'
@ -176,69 +133,74 @@ export default function Nav({ navVisible, setNavVisible }) {
return (
<>
<div
className={
'nav dark bg-gray-900 transition-all duration-500 md:inset-y-0' +
(navVisible ? ' active' : '')
}
className="nav active dark flex-shrink-0 overflow-x-hidden bg-gray-900 transition-all duration-200 ease-in-out"
style={{
width: navVisible ? '260px' : '0px',
visibility: navVisible ? 'visible' : 'hidden',
}}
>
<div className="flex h-full min-h-0 flex-col ">
<div className="scrollbar-trigger relative flex h-full w-full flex-1 items-start border-white/20">
<nav className="relative flex h-full flex-1 flex-col space-y-1 p-2">
<div className="mb-2 flex h-11 flex-row">
<NewChat />
<button
type="button"
className={cn(
'nav-close-button inline-flex h-11 w-11 items-center justify-center rounded-md border border-white/20 text-white hover:bg-gray-500/10',
)}
onClick={toggleNavVisible}
>
<span className="sr-only">Close sidebar</span>
<Panel open={false} />
</button>
</div>
<div
className={`flex-1 flex-col overflow-y-auto ${
isHovering ? '' : 'scrollbar-transparent'
} border-b border-white/20`}
onMouseEnter={() => setIsHovering(true)}
onMouseLeave={() => setIsHovering(false)}
ref={containerRef}
>
<div className={containerClasses}>
{(getConversationsQuery.isLoading && pageNumber === 1) || isFetching ? (
<Spinner />
) : (
<Conversations
conversations={conversations}
conversationId={conversationId}
moveToTop={moveToTop}
/>
)}
<Pages
pageNumber={pageNumber}
pages={pages}
nextPage={nextPage}
previousPage={previousPage}
/>
<div className="h-full w-[260px]">
<div className="flex h-full min-h-0 flex-col ">
<div className="scrollbar-trigger relative flex h-full w-full flex-1 items-start border-white/20">
<nav className="relative flex h-full flex-1 flex-col space-y-1 p-2">
<div className="mb-2 flex h-11 flex-row">
<NewChat />
<button
type="button"
className={cn(
'nav-close-button inline-flex h-11 w-11 items-center justify-center rounded-md border border-white/20 text-white hover:bg-gray-500/10',
)}
onClick={toggleNavVisible}
>
<span className="sr-only">Close sidebar</span>
<Panel open={false} />
</button>
</div>
</div>
<NavLinks clearSearch={clearSearch} isSearchEnabled={isSearchEnabled} />
</nav>
<div
className={`flex-1 flex-col overflow-y-auto ${
isHovering ? '' : 'scrollbar-transparent'
} border-b border-white/20`}
onMouseEnter={() => setIsHovering(true)}
onMouseLeave={() => setIsHovering(false)}
ref={containerRef}
>
<div className={containerClasses}>
{(getConversationsQuery.isLoading && pageNumber === 1) || isFetching ? (
<Spinner />
) : (
<Conversations
conversations={conversations}
conversationId={conversationId}
moveToTop={moveToTop}
/>
)}
<Pages
pageNumber={pageNumber}
pages={pages}
nextPage={nextPage}
previousPage={previousPage}
/>
</div>
</div>
<NavLinks clearSearch={clearSearch} isSearchEnabled={isSearchEnabled} />
</nav>
</div>
</div>
</div>
</div>
{!navVisible && (
<button
type="button"
className="nav-open-button fixed left-2 top-0.5 z-10 mt-1 flex h-11 w-11 cursor-pointer items-center gap-3 rounded-md border border-black/10 bg-white p-3 text-sm text-gray-900 transition-colors duration-200 hover:bg-gray-50 dark:border-white/20 dark:bg-gray-800 dark:text-gray-100 dark:hover:bg-gray-700"
onClick={toggleNavVisible}
>
<div className="flex items-center justify-center">
<span className="sr-only">Open sidebar</span>
<Panel open={true} />
</div>
</button>
<div className="absolute left-2 top-2 z-10 hidden md:inline-block">
<button
type="button"
className="nav-open-button flex h-11 cursor-pointer items-center gap-3 rounded-md border border-black/10 bg-white p-3 text-sm text-black transition-colors duration-200 hover:bg-gray-50 dark:border-white/20 dark:bg-gray-800 dark:hover:bg-gray-700"
onClick={toggleNavVisible}
>
<div className="flex items-center justify-center">
<span className="sr-only">Open sidebar</span>
<Panel open={true} />
</div>
</button>
</div>
)}
<div className={'nav-mask' + (navVisible ? ' active' : '')} onClick={toggleNavVisible}></div>

View file

@ -1,6 +1,7 @@
export { default as Plugin } from './Plugin';
export { default as GPTIcon } from './GPTIcon';
export { default as CogIcon } from './CogIcon';
export { default as Panel } from './Panel';
export { default as Spinner } from './Spinner';
export { default as MessagesSquared } from './MessagesSquared';
export { default as StopGeneratingIcon } from './StopGeneratingIcon';