mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-01-18 00:15:30 +01:00
style: Minor Beta UI fixes (#1197)
* style(Header): hide scrollbar but still allow side scroll/swipe/drag/touch * feat: make menu buttons flexiblewith min-width, delete passed in classes, add pointer-cursor * refactor: use conditional for visibility of plugins settings * fix: make advanced settings popover appear over nav * refactor(textarea): minor padding restyling, add max height * style: make menuItem checkmark invisible instead of hidden so it takes up width space * style: make presetsMenu trigger an icon button, remove max-width of presets except in mobile view * style: improve advanced settings mobile styling * feat: newchat and convo items toggle nav on small screens * style: improve no presets view * style: make sure toggle hover effect does not apply on smaller screens
This commit is contained in:
parent
c64970525b
commit
1ba8d4ffa9
18 changed files with 171 additions and 92 deletions
|
|
@ -1,11 +1,16 @@
|
|||
import { useChatContext } from '~/Providers';
|
||||
import { useMediaQuery } from '~/hooks';
|
||||
|
||||
export default function Header() {
|
||||
const { newConversation } = useChatContext();
|
||||
const isSmallScreen = useMediaQuery('(max-width: 768px)');
|
||||
if (isSmallScreen) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className=" btn btn-neutral btn-small border-token-border-medium relative ml-2 flex h-9 w-9 items-center justify-center whitespace-nowrap rounded-lg rounded-lg border focus:ring-0 focus:ring-offset-0"
|
||||
className="btn btn-neutral btn-small border-token-border-medium relative ml-2 flex hidden h-9 w-9 items-center justify-center whitespace-nowrap rounded-lg rounded-lg border focus:ring-0 focus:ring-offset-0 md:flex"
|
||||
onClick={() => newConversation()}
|
||||
>
|
||||
<div className="flex w-full items-center justify-center gap-2">
|
||||
|
|
|
|||
|
|
@ -59,7 +59,20 @@ const PresetItems: FC<{
|
|||
</Dialog>
|
||||
</div>
|
||||
</div>
|
||||
{presets && presets.length === 0 && (
|
||||
<div
|
||||
role="menuitem"
|
||||
className="pointer-none group m-1.5 flex h-8 min-w-[170px] gap-2 rounded px-5 py-2.5 !pr-3 text-sm !opacity-100 hover:bg-black/5 focus:ring-0 radix-disabled:pointer-events-none radix-disabled:opacity-50 dark:hover:bg-white/5 md:min-w-[240px]"
|
||||
tabIndex={-1}
|
||||
>
|
||||
<div className="flex h-full grow items-center justify-end gap-2">
|
||||
{/* TODO: Create Preset from here */}
|
||||
{localize('com_endpoint_no_presets')}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{presets &&
|
||||
presets.length > 0 &&
|
||||
presets.map((preset, i) => {
|
||||
if (!preset) {
|
||||
return null;
|
||||
|
|
@ -70,8 +83,7 @@ const PresetItems: FC<{
|
|||
<div key={`preset-${preset.presetId}`}>
|
||||
<MenuItem
|
||||
key={`preset-item-${preset.presetId}`}
|
||||
className="w-[380px] md:min-w-[240px]"
|
||||
textClassName="text-xs max-w-[180px] md:max-w-[250px]"
|
||||
textClassName="text-xs max-w-[200px] truncate md:max-w-full "
|
||||
title={getPresetTitle(preset)}
|
||||
disableHover={true}
|
||||
onClick={() => onSelectPreset(preset)}
|
||||
|
|
@ -83,7 +95,7 @@ const PresetItems: FC<{
|
|||
>
|
||||
<div className="flex h-full items-center justify-end gap-1">
|
||||
<button
|
||||
className="m-0 h-full rounded-md px-4 text-gray-400 hover:text-gray-700 dark:bg-gray-700 dark:text-gray-400 dark:hover:text-gray-200 sm:invisible sm:p-2 sm:group-hover:visible"
|
||||
className="m-0 h-full rounded-md p-2 px-4 text-gray-400 hover:text-gray-700 dark:bg-gray-700 dark:text-gray-400 dark:hover:text-gray-200 sm:invisible sm:group-hover:visible"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
|
@ -93,7 +105,7 @@ const PresetItems: FC<{
|
|||
<TrashIcon />
|
||||
</button>
|
||||
<button
|
||||
className="m-0 h-full rounded-md px-4 text-gray-400 hover:text-gray-700 dark:bg-gray-700 dark:text-gray-400 dark:hover:text-gray-200 sm:invisible sm:p-2 sm:group-hover:visible"
|
||||
className="m-0 h-full rounded-md p-2 px-4 text-gray-400 hover:text-gray-700 dark:bg-gray-700 dark:text-gray-400 dark:hover:text-gray-200 sm:invisible sm:group-hover:visible"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onChangePreset(preset);
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
import type { FC } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { BookCopy } from 'lucide-react';
|
||||
import {
|
||||
modularEndpoints,
|
||||
useDeletePresetMutation,
|
||||
useCreatePresetMutation,
|
||||
} from 'librechat-data-provider';
|
||||
import type { TPreset } from 'librechat-data-provider';
|
||||
import { Content, Portal, Root } from '@radix-ui/react-popover';
|
||||
import { Content, Portal, Root, Trigger } from '@radix-ui/react-popover';
|
||||
import { useLocalize, useDefaultConvo, useNavigateToConvo } from '~/hooks';
|
||||
import { EditPresetDialog, PresetItems } from './Presets';
|
||||
import { cleanupPreset, cn } from '~/utils';
|
||||
import { useChatContext } from '~/Providers';
|
||||
import TitleButton from './UI/TitleButton';
|
||||
import { cleanupPreset } from '~/utils';
|
||||
import store from '~/store';
|
||||
|
||||
const PresetsMenu: FC = () => {
|
||||
|
|
@ -86,7 +86,20 @@ const PresetsMenu: FC = () => {
|
|||
|
||||
return (
|
||||
<Root>
|
||||
<TitleButton primaryText={'Presets'} />
|
||||
<Trigger asChild>
|
||||
<button
|
||||
className={cn(
|
||||
'pointer-cursor relative flex flex-col rounded-md border border-black/10 bg-white text-left focus:outline-none focus:ring-0 focus:ring-offset-0 dark:border-white/20 dark:bg-gray-800 sm:text-sm',
|
||||
'hover:bg-gray-50 radix-state-open:bg-gray-50 dark:hover:bg-black/10 dark:radix-state-open:bg-black/20',
|
||||
'min-w-4 z-50 flex h-[40px] flex-none items-center justify-center px-3 focus:ring-0 focus:ring-offset-0',
|
||||
)}
|
||||
id="presets-button"
|
||||
data-testid="presets-button"
|
||||
title={localize('com_ui_presets')}
|
||||
>
|
||||
<BookCopy className="icon-sm" id="presets-button" />
|
||||
</button>
|
||||
</Trigger>
|
||||
<Portal>
|
||||
<div
|
||||
style={{
|
||||
|
|
@ -100,29 +113,21 @@ const PresetsMenu: FC = () => {
|
|||
>
|
||||
<Content
|
||||
side="bottom"
|
||||
align="start"
|
||||
className="mt-2 max-h-[495px] max-w-[370px] overflow-x-hidden rounded-lg border border-gray-100 bg-white shadow-lg dark:border-gray-700 dark:bg-gray-900 dark:text-white md:min-w-[400px]"
|
||||
align="center"
|
||||
className="mt-2 max-h-[495px] overflow-x-hidden rounded-lg border border-gray-100 bg-white shadow-lg dark:border-gray-700 dark:bg-gray-900 dark:text-white md:min-w-[400px]"
|
||||
>
|
||||
{presets.length ? (
|
||||
<PresetItems
|
||||
presets={presets}
|
||||
onSelectPreset={onSelectPreset}
|
||||
onChangePreset={onChangePreset}
|
||||
onDeletePreset={onDeletePreset}
|
||||
clearAllPresets={clearAllPresets}
|
||||
onFileSelected={onFileSelected}
|
||||
/>
|
||||
) : (
|
||||
<div className="dark:text-gray-300">{localize('com_endpoint_no_presets')}</div>
|
||||
)}
|
||||
<PresetItems
|
||||
presets={presets}
|
||||
onSelectPreset={onSelectPreset}
|
||||
onChangePreset={onChangePreset}
|
||||
onDeletePreset={onDeletePreset}
|
||||
clearAllPresets={clearAllPresets}
|
||||
onFileSelected={onFileSelected}
|
||||
/>
|
||||
</Content>
|
||||
</div>
|
||||
</Portal>
|
||||
<EditPresetDialog
|
||||
open={presetModalVisible}
|
||||
onOpenChange={setPresetModalVisible}
|
||||
// preset={preset as TPreset}
|
||||
/>
|
||||
<EditPresetDialog open={presetModalVisible} onOpenChange={setPresetModalVisible} />
|
||||
</Root>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ const MenuItem: FC<MenuItemProps> = ({
|
|||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="icon-md block hidden gap-x-1 group-hover:flex "
|
||||
className="icon-md invisible block gap-x-1 group-hover:visible group-hover:flex"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue