Refactor UI styles & configurations (#324)

* Refactor UI styles & configurations

-  Modify button styles and their color schemes to create a consistent user experience when interacting with buttons.
-  Adjust the design of the search bar to a more user-friendly layout by changing its background color and styling.
-  Create a responsive mobile behavior for the navigation bar to hide it behind a menu icon instead of permanently displaying it.

* Update .gitignore to exclude unnecessary files for Meilisearch

Update .gitignore to exclude meilisearch.exe and data.ms/*, which are not necessary for Meilisearch.

* feat: Add getCurrentBreakpoint function to get current breakpoint

This commit adds a getCurrentBreakpoint function to determine the current breakpoint of the viewport. The function uses fullConfig to determine the biggest breakpoint value of the window, and returns the corresponding breakpoint. It also updates the useEffect function to use getCurrentBreakpoint instead of checking if the userAgent matches a mobile regex.

* Update tailwind import path in Nav component

The import path for the tailwind config was updated in the Nav component to match the new project structure. This ensures that the correct Tailwind styles are applied to the component and improves maintainability.

* Add ThemeContext and cn utility function to Nav component

This commit adds the ThemeContext and cn utility function to the Nav component's dependencies with useContext and import respectively. It also modifies a class name with a ternary operator that toggles based on the theme value passed via ThemeContext.

* Update Nav button styles for better visibility

Changed the button styles for the Nav close and open buttons to enhance visibility. The text color for both buttons will now change when hovering to gray and gray-600 respectively.

* Improve message header styles and add transition effects

This commit updates the MessageHeader component styles by adjusting the text color, as well as adding transition effects to enhance the hover experience. The commit also tweaks mobile styles by adding a transition effect to `.nav` when resizing the window to mobile size.

* Refactor the message header component styling for better visual contrast

The message header component was refactored to improve its visual contrast by changing the text color for better readability. The styles of the component were modified to improve hover behavior as well as transition effects. The setSaveAsDialogShow method was shifted to the onClick prop to only execute when the endpoint is not 'chatGPTBrowser'.

* refactor: Update styling of MessageHeader and Nav buttons

The commit message describes changes made to the MessageHeader and Nav components. It summarizes the code changes as a refactor of the CSS styling for the buttons in both components, specifically updating the text and hover colors for the dark and light themes.
This commit is contained in:
Anirudh 2023-05-19 20:21:34 +05:30 committed by GitHub
parent 67716f0d2d
commit ee2b3e4fb2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 168 additions and 115 deletions

View file

@ -2,20 +2,9 @@ import React, { useState } from 'react';
import { useRecoilValue } from 'recoil';
import EndpointOptionsDialog from '../Endpoints/EndpointOptionsDialog';
import { cn } from '~/utils/';
import { Button } from '../ui/Button.tsx';
import store from '~/store';
const clipPromptPrefix = (str) => {
if (typeof str !== 'string') {
return null;
} else if (str.length > 10) {
return str.slice(0, 10) + '...';
} else {
return str;
}
};
const MessageHeader = ({ isSearchView = false }) => {
const [saveAsDialogShow, setSaveAsDialogShow] = useState(false);
const conversation = useRecoilValue(store.conversation);
@ -56,7 +45,7 @@ const MessageHeader = ({ isSearchView = false }) => {
<>
<div
className={cn(
'dark:text-gray-450 w-full gap-1 border-b border-black/10 bg-gray-50 text-sm text-gray-500 transition-all hover:bg-gray-100 hover:bg-opacity-30 dark:border-gray-900/50 dark:bg-gray-700 dark:hover:bg-gray-600 dark:hover:bg-opacity-100',
'dark:text-gray-450 w-full gap-1 border-b border-black/10 bg-gray-50 text-sm text-gray-600 transition-all hover:bg-gray-100 hover:bg-opacity-30 dark:border-gray-900/50 dark:bg-gray-700 dark:hover:bg-gray-600 dark:hover:bg-opacity-100 dark:text-gray-500',
endpoint === 'chatGPTBrowser' ? '' : 'cursor-pointer '
)}
onClick={() => (endpoint === 'chatGPTBrowser' ? null : setSaveAsDialogShow(true))}

View file

@ -19,7 +19,7 @@ export default function SearchBar({ clearSearch }) {
};
return (
<div className="flex cursor-pointer items-center gap-3 rounded-md px-3 py-3 text-sm text-white transition-colors duration-200 hover:bg-gray-500/10">
<div className="flex w-full cursor-pointer items-center gap-3 px-3 py-3 text-sm text-white transition-colors duration-200 hover:bg-gray-700">
{<Search className="h-4 w-4" />}
<input
type="text"

View file

@ -1,4 +1,4 @@
import { useState, useEffect, useRef } from 'react';
import { useState, useEffect, useRef, useContext } from 'react';
import NewChat from './NewChat';
import Spinner from '../svg/Spinner';
import Pages from '../Conversations/Pages';
@ -9,10 +9,33 @@ import { useGetConversationsQuery, useSearchQuery } from '~/data-provider';
import useDebounce from '~/hooks/useDebounce';
import store from '~/store';
import { useAuthContext } from '~/hooks/AuthContext';
import { ThemeContext } from '~/hooks/ThemeContext';
import { cn } from '~/utils/';
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();
const { theme, } = useContext(ThemeContext);
const containerRef = useRef(null);
const scrollPositionRef = useRef(null);
@ -75,6 +98,13 @@ export default function Nav({ navVisible, setNavVisible }) {
}
};
const moveToTop = () => {
const container = containerRef.current;
if (container) {
scrollPositionRef.current = container.scrollTop;
}
};
const nextPage = async () => {
moveToTop();
setPageNumber(pageNumber + 1);
@ -111,19 +141,17 @@ export default function Nav({ navVisible, setNavVisible }) {
}
}, [pageNumber, conversationId, refreshConversationsHint]);
const moveToTop = () => {
const container = containerRef.current;
if (container) {
scrollPositionRef.current = container.scrollTop;
}
};
const toggleNavVisible = () => {
setNavVisible((prev) => !prev);
};
useEffect(() => {
let currentBreakpoint = getCurrentBreakpoint();
if (currentBreakpoint === 'sm') {
setNavVisible(false);
} else {
setNavVisible(true);
}
}, [conversationId, setNavVisible]);
const containerClasses =
@ -133,12 +161,7 @@ export default function Nav({ navVisible, setNavVisible }) {
return (
<>
<div
className={
'nav dark bg-gray-900 md:fixed md:inset-y-0 md:flex md:w-[260px] md:flex-col' +
(navVisible ? ' active' : '')
}
>
<div className={'nav dark bg-gray-900 md:inset-y-0' + (navVisible ? ' active' : '')}>
<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">
@ -175,10 +198,10 @@ export default function Nav({ navVisible, setNavVisible }) {
</div>
<button
type="button"
className="nav-close-button -ml-0.5 -mt-0.5 inline-flex h-10 w-10 items-center justify-center rounded-md text-white hover:text-gray-900 hover:text-white focus:outline-none focus:ring-white"
className={cn('nav-close-button -ml-0.5 -mt-2.5 inline-flex h-10 w-10 items-center justify-center rounded-md focus:outline-none focus:ring-white md:-ml-1 md:-mt-2.5', theme === 'dark' ? 'text-gray-500 hover:text-gray-400' : 'text-gray-900 hover:text-gray-600')}
onClick={toggleNavVisible}
>
<span className="sr-only">Open sidebar</span>
<span className="sr-only">Close sidebar</span>
<svg
stroke="currentColor"
fill="none"
@ -186,7 +209,7 @@ export default function Nav({ navVisible, setNavVisible }) {
viewBox="0 0 24 24"
strokeLinecap="round"
strokeLinejoin="round"
className="h-6 w-6"
className="block h-6 w-6 md:hidden"
height="1em"
width="1em"
xmlns="http://www.w3.org/2000/svg"
@ -194,8 +217,46 @@ export default function Nav({ navVisible, setNavVisible }) {
<line x1="3" y1="6" x2="15" y2="18" />
<line x1="3" y1="18" x2="15" y2="6" />
</svg>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className="hidden h-[26px] w-[26px] md:block"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M15.75 9V5.25A2.25 2.25 0 0013.5 3h-6a2.25 2.25 0 00-2.25 2.25v13.5A2.25 2.25 0 007.5 21h6a2.25 2.25 0 002.25-2.25V15M12 9l-3 3m0 0l3 3m-3-3h12.75"
/>
</svg>
</button>
</div>
{!navVisible && (
<button
type="button"
className="nav-open-button fixed left-2 top-0.5 z-10 inline-flex h-10 w-10 items-center justify-center rounded-md text-gray-900 hover:text-gray-600 focus:outline-none focus:ring-white dark:text-gray-500 dark:hover:text-gray-400"
onClick={toggleNavVisible}
>
<span className="sr-only">Open sidebar</span>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className="h-6 w-6"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M15.75 9V5.25A2.25 2.25 0 0013.5 3h-6a2.25 2.25 0 00-2.25 2.25v13.5A2.25 2.25 0 007.5 21h6a2.25 2.25 0 002.25-2.25V15m3 0l3-3m0 0l-3-3m3 3H9"
/>
</svg>
</button>
)}
<div className={'nav-mask' + (navVisible ? ' active' : '')} onClick={toggleNavVisible}></div>
</>
);

View file

@ -100,7 +100,7 @@ const AlertDialogAction = React.forwardRef<
<AlertDialogPrimitive.Action
ref={ref}
className={cn(
'inline-flex h-10 items-center justify-center rounded-md bg-slate-900 px-4 py-2 text-sm font-semibold text-white transition-colors hover:bg-slate-700 focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-slate-100 dark:text-slate-900 dark:hover:bg-slate-200 dark:focus:ring-slate-400 dark:focus:ring-offset-slate-900',
'inline-flex h-10 items-center justify-center rounded-md bg-slate-900 px-4 py-2 text-sm font-semibold text-white transition-colors hover:bg-gray-900 focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-slate-100 dark:text-slate-900 dark:hover:bg-slate-200 dark:focus:ring-slate-400 dark:focus:ring-offset-slate-900',
className
)}
{...props}
@ -115,7 +115,7 @@ const AlertDialogCancel = React.forwardRef<
<AlertDialogPrimitive.Cancel
ref={ref}
className={cn(
'mt-2 inline-flex h-10 items-center justify-center rounded-md border border-slate-200 bg-transparent px-4 py-2 text-sm font-semibold text-slate-900 transition-colors hover:bg-slate-100 focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-700 dark:text-slate-100 dark:hover:bg-slate-700 dark:focus:ring-slate-400 dark:focus:ring-offset-slate-900 sm:mt-0',
'mt-2 inline-flex h-10 items-center justify-center rounded-md border border-slate-200 bg-transparent px-4 py-2 text-sm font-semibold text-slate-900 transition-colors hover:bg-slate-100 focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-700 dark:text-slate-100 dark:hover:bg-gray-900 dark:focus:ring-slate-400 dark:focus:ring-offset-slate-900 sm:mt-0',
className
)}
{...props}

View file

@ -8,12 +8,12 @@ const buttonVariants = cva(
{
variants: {
variant: {
default: 'bg-slate-900 text-white hover:bg-slate-700 dark:bg-slate-50 dark:text-slate-900',
default: 'bg-slate-900 text-white hover:bg-gray-900 dark:bg-slate-50 dark:text-slate-900',
destructive: 'bg-red-500 text-white hover:bg-red-600 dark:hover:bg-red-600',
outline:
'bg-transparent border border-slate-200 hover:bg-slate-100 dark:border-slate-700 dark:text-slate-100',
subtle:
'bg-slate-100 text-slate-900 hover:bg-slate-200 dark:bg-slate-700 dark:text-slate-100',
'bg-slate-100 text-slate-900 hover:bg-slate-200 dark:bg-gray-900 dark:text-slate-100',
ghost:
'bg-transparent hover:bg-slate-100 dark:hover:bg-slate-800 dark:text-slate-100 dark:hover:text-slate-100 data-[state=open]:bg-transparent dark:data-[state=open]:bg-transparent',
link: 'bg-transparent underline-offset-4 hover:underline text-slate-900 dark:text-slate-100 hover:bg-transparent dark:hover:bg-transparent'

View file

@ -102,7 +102,7 @@ const DialogClose = React.forwardRef<
<DialogPrimitive.Close
ref={ref}
className={cn(
'mt-2 inline-flex h-10 items-center justify-center rounded-md border border-slate-200 bg-transparent px-4 py-2 text-sm font-semibold text-slate-900 transition-colors hover:bg-slate-100 focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-700 dark:text-slate-100 dark:hover:bg-slate-700 dark:focus:ring-slate-400 dark:focus:ring-offset-slate-900 sm:mt-0',
'mt-2 inline-flex h-10 items-center justify-center rounded-md border border-slate-200 bg-transparent px-4 py-2 text-sm font-semibold text-slate-900 transition-colors hover:bg-slate-100 focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-700 dark:text-slate-100 dark:hover:bg-gray-900 dark:focus:ring-slate-400 dark:focus:ring-offset-slate-900 sm:mt-0',
className
)}
{...props}
@ -118,7 +118,7 @@ const DialogButton = React.forwardRef<
ref={ref}
variant="outline"
className={cn(
'mt-2 inline-flex h-10 items-center justify-center rounded-md border border-slate-200 bg-transparent px-4 py-2 text-sm font-semibold text-slate-900 transition-colors hover:bg-slate-100 focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-700 dark:text-slate-100 dark:hover:bg-slate-700 dark:focus:ring-slate-400 dark:focus:ring-offset-slate-900 sm:mt-0',
'mt-2 inline-flex h-10 items-center justify-center rounded-md border border-slate-200 bg-transparent px-4 py-2 text-sm font-semibold text-slate-900 transition-colors hover:bg-slate-100 focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-700 dark:text-slate-100 dark:hover:bg-gray-900 dark:focus:ring-slate-400 dark:focus:ring-offset-slate-900 sm:mt-0',
className
)}
{...props}

View file

@ -27,7 +27,7 @@ const DropdownMenuSubTrigger = React.forwardRef<
<DropdownMenuPrimitive.SubTrigger
ref={ref}
className={cn(
'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm font-medium outline-none focus:bg-slate-100 data-[state=open]:bg-slate-100 dark:focus:bg-slate-700 dark:data-[state=open]:bg-slate-700',
'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm font-medium outline-none focus:bg-slate-100 data-[state=open]:bg-slate-100 dark:focus:bg-gray-900 dark:data-[state=open]:bg-gray-900',
inset && 'pl-8',
className
)}
@ -81,7 +81,7 @@ const DropdownMenuItem = React.forwardRef<
<DropdownMenuPrimitive.Item
ref={ref}
className={cn(
'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm font-medium outline-none focus:bg-slate-100 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-slate-700',
'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm font-medium outline-none focus:bg-slate-100 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-gray-900',
inset && 'pl-8',
className
)}
@ -97,7 +97,7 @@ const DropdownMenuCheckboxItem = React.forwardRef<
<DropdownMenuPrimitive.CheckboxItem
ref={ref}
className={cn(
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm font-medium outline-none focus:bg-slate-100 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-slate-700',
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm font-medium outline-none focus:bg-slate-100 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-gray-900',
className
)}
checked={checked}
@ -120,7 +120,7 @@ const DropdownMenuRadioItem = React.forwardRef<
<DropdownMenuPrimitive.RadioItem
ref={ref}
className={cn(
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm font-medium outline-none focus:bg-slate-100 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-slate-700',
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm font-medium outline-none focus:bg-slate-100 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-gray-900',
className
)}
{...props}
@ -159,7 +159,7 @@ const DropdownMenuSeparator = React.forwardRef<
>(({ className, ...props }, ref) => (
<DropdownMenuPrimitive.Separator
ref={ref}
className={cn('-mx-1 my-1 h-px bg-slate-100 dark:bg-slate-700', className)}
className={cn('-mx-1 my-1 h-px bg-slate-100 dark:bg-gray-900', className)}
{...props}
/>
));

View file

@ -1,4 +1,78 @@
.nav-mask {
.switch-container {
display: none;
}
.switch-result {
display: block !important;
visibility: visible;
}
/* .sibling-switch {
left: 114px;
top: unset;
bottom: 4px;
visibility: visible;
z-index: 2;
} */
.sibling-switch {
display: none;
}
.hover-button {
display: block;
visibility: visible;
}
.input-panel-button {
border: 0;
}
.input-panel-button svg {
width: 16px;
height: 16px;
}
.input-panel {
}
.nav-close-button {
display: block;
position: absolute;
left: 100%;
top: 12px;
margin-left: 20px;
}
.nav {
position: fixed;
z-index: 999;
left: calc(-100%);
top: 0;
width: calc(100% - 60px);
max-width: 260px;
bottom: 0;
opacity: 0;
}
.nav.active {
position: relative;
left: 0;
opacity: 1;
}
.nav-mask.active {
opacity: 1;
pointer-events: auto;
}
@media (max-width: 767px) {
.nav {
width: calc(100% - 60px) ;
transition: all 0.5s;
}
.nav-mask {
position: fixed;
z-index: 996;
left: 0;
@ -11,85 +85,14 @@
opacity: 0;
transition: all 0.5s;
pointer-events: none;
}
.nav {
transition: all 0.5s;
}
.nav-close-button {
display: none;
}
@media (min-width: 1024px) {
.switch-container {
display: none;
}
}
.switch-result {
display: block !important;
visibility: visible;
}
@media (max-width: 1024px) {
/* .sibling-switch {
left: 114px;
top: unset;
bottom: 4px;
visibility: visible;
z-index: 2;
} */
.sibling-switch {
display: none;
}
.hover-button {
display: block;
visibility: visible;
}
}
@media (max-width: 767px) {
.input-panel-button {
border: 0;
}
.input-panel-button svg {
width: 16px;
height: 16px;
}
.input-panel {
}
.nav-close-button {
display: block;
position: absolute;
left: 100%;
top: 12px;
margin-left: 20px;
}
.nav {
position: fixed;
z-index: 999;
left: calc(-100%);
top: 0;
bottom: 0;
max-width: 320px;
width: calc(100% - 60px);
opacity: 0;
}
.nav.active {
left: 0;
opacity: 1;
}
.nav-mask.active {
opacity: 1;
pointer-events: auto;
}
.nav.active {
position: fixed;
}
}

View file

@ -51,7 +51,7 @@ export default function Root() {
<>
<div className="flex h-screen">
<Nav navVisible={navVisible} setNavVisible={setNavVisible} />
<div className="flex h-full w-full flex-1 flex-col bg-gray-50 md:pl-[260px]">
<div className="flex h-full w-full flex-1 flex-col bg-gray-50">
<div className="transition-width relative flex h-full w-full flex-1 flex-col items-stretch overflow-hidden bg-white pt-10 dark:bg-gray-800 md:pt-0">
<MobileNav setNavVisible={setNavVisible} />
<Outlet />