🎨 style: UI Style Enhancements and Refactor for Improved Consistency and Layout (#4471)

* 🎨 style: adjust padding and class names in UI components

* 🎨 style: update ExportModal export button, update Export button hover style, refactor ChatForm style and fixed isRTL styles, update AttachFile position

* 🎨 style: remove redundant border classes in SettingsTabs components for cleaner UI

* 🎨 style: refactor Account component, extract DisplayUsernameMessages, and remove redundant border classes for cleaner layout

* 🎨 style: conditionally render Dropdown in ForkSettings component for improved UI responsiveness

* 🎨 style: replace DropdownNoState with Dropdown in voice selection components for consistency

* 🎨 style: update Settings component layout for better responsivenes on large screens

* 🎨 style: remove redundant margin-top classes for cleaner layout in various components
This commit is contained in:
Marco Beretta 2024-10-20 17:29:47 +02:00 committed by GitHub
parent ecf5699513
commit 4d4a6b53f1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 118 additions and 145 deletions

View file

@ -3,6 +3,7 @@ import { useRecoilState } from 'recoil';
import type { Option } from '~/common'; import type { Option } from '~/common';
import DropdownNoState from '~/components/ui/DropdownNoState'; import DropdownNoState from '~/components/ui/DropdownNoState';
import { useLocalize, useTTSBrowser, useTTSEdge, useTTSExternal } from '~/hooks'; import { useLocalize, useTTSBrowser, useTTSEdge, useTTSExternal } from '~/hooks';
import { Dropdown } from '~/components/ui';
import { logger } from '~/utils'; import { logger } from '~/utils';
import store from '~/store'; import store from '~/store';
@ -22,13 +23,12 @@ export function EdgeVoiceDropdown() {
return ( return (
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div>{localize('com_nav_voice_select')}</div> <div>{localize('com_nav_voice_select')}</div>
<DropdownNoState <Dropdown
key={`edge-voice-dropdown-${voices.length}`} key={`edge-voice-dropdown-${voices.length}`}
value={voice} value={voice ?? ''}
options={voices} options={voices}
onChange={handleVoiceChange} onChange={handleVoiceChange}
sizeClasses="min-w-[200px] !max-w-[400px] [--anchor-max-width:400px]" sizeClasses="min-w-[200px] !max-w-[400px] [--anchor-max-width:400px]"
anchor="bottom start"
testId="EdgeVoiceDropdown" testId="EdgeVoiceDropdown"
/> />
</div> </div>
@ -51,13 +51,12 @@ export function BrowserVoiceDropdown() {
return ( return (
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div>{localize('com_nav_voice_select')}</div> <div>{localize('com_nav_voice_select')}</div>
<DropdownNoState <Dropdown
key={`browser-voice-dropdown-${voices.length}`} key={`browser-voice-dropdown-${voices.length}`}
value={voice} value={voice ?? ''}
options={voices} options={voices}
onChange={handleVoiceChange} onChange={handleVoiceChange}
sizeClasses="min-w-[200px] !max-w-[400px] [--anchor-max-width:400px]" sizeClasses="min-w-[200px] !max-w-[400px] [--anchor-max-width:400px]"
anchor="bottom start"
testId="BrowserVoiceDropdown" testId="BrowserVoiceDropdown"
/> />
</div> </div>
@ -80,13 +79,12 @@ export function ExternalVoiceDropdown() {
return ( return (
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div>{localize('com_nav_voice_select')}</div> <div>{localize('com_nav_voice_select')}</div>
<DropdownNoState <Dropdown
key={`external-voice-dropdown-${voices.length}`} key={`external-voice-dropdown-${voices.length}`}
value={voice} value={voice ?? ''}
options={voices} options={voices}
onChange={handleVoiceChange} onChange={handleVoiceChange}
sizeClasses="min-w-[200px] !max-w-[400px] [--anchor-max-width:400px]" sizeClasses="min-w-[200px] !max-w-[400px] [--anchor-max-width:400px]"
anchor="bottom start"
testId="ExternalVoiceDropdown" testId="ExternalVoiceDropdown"
/> />
</div> </div>

View file

@ -70,7 +70,7 @@ export default function ExportAndShareMenu({
<Ariakit.MenuButton <Ariakit.MenuButton
id="export-menu-button" id="export-menu-button"
aria-label="Export options" aria-label="Export options"
className="mr-4 inline-flex h-10 w-10 items-center justify-center rounded-md border border-border-light bg-transparent p-0 text-sm font-medium transition-all duration-300 ease-in-out focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50" className="inline-flex size-10 items-center justify-center rounded-lg border border-border-light bg-transparent text-text-primary transition-all ease-in-out hover:bg-surface-tertiary disabled:pointer-events-none disabled:opacity-50 radix-state-open:bg-surface-tertiary"
> >
<Upload className="icon-md dark:text-gray-300" aria-hidden="true" focusable="false" /> <Upload className="icon-md dark:text-gray-300" aria-hidden="true" focusable="false" />
</Ariakit.MenuButton> </Ariakit.MenuButton>

View file

@ -131,6 +131,14 @@ const ChatForm = ({ index = 0 }) => {
const endpointSupportsFiles: boolean = supportsFiles[endpointType ?? endpoint ?? ''] ?? false; const endpointSupportsFiles: boolean = supportsFiles[endpointType ?? endpoint ?? ''] ?? false;
const isUploadDisabled: boolean = endpointFileConfig?.disabled ?? false; const isUploadDisabled: boolean = endpointFileConfig?.disabled ?? false;
const baseClasses =
'md:py-3.5 m-0 w-full resize-none bg-surface-tertiary py-[13px] placeholder-black/50 dark:placeholder-white/50 [&:has(textarea:focus)]:shadow-[0_2px_6px_rgba(0,0,0,.05)] max-h-[65vh] md:max-h-[75vh]';
const uploadActive = endpointSupportsFiles && !isUploadDisabled;
const speechClass = isRTL
? `pr-${uploadActive ? '12' : '4'} pl-12`
: `pl-${uploadActive ? '12' : '4'} pr-12`;
return ( return (
<form <form
onSubmit={methods.handleSubmit((data) => submitMessage(data))} onSubmit={methods.handleSubmit((data) => submitMessage(data))}
@ -177,15 +185,7 @@ const ChatForm = ({ index = 0 }) => {
data-testid="text-input" data-testid="text-input"
style={{ height: 44, overflowY: 'auto' }} style={{ height: 44, overflowY: 'auto' }}
rows={1} rows={1}
className={cn( className={cn(baseClasses, speechClass, removeFocusRings)}
endpointSupportsFiles && !isUploadDisabled
? 'pl-10 md:pl-[55px]'
: 'pl-3 md:pl-4',
'md:py-3.5- m-0 w-full resize-none bg-surface-tertiary py-[13px] placeholder-black/50 dark:placeholder-white/50 [&:has(textarea:focus)]:shadow-[0_2px_6px_rgba(0,0,0,.05)]',
SpeechToText && !isRTL ? 'pr-20 md:pr-[85px]' : 'pr-10 md:pr-12',
'max-h-[65vh] md:max-h-[75vh]',
removeFocusRings,
)}
/> />
)} )}
</FileFormWrapper> </FileFormWrapper>

View file

@ -24,7 +24,7 @@ const AttachFile = ({
disabled={isUploadDisabled} disabled={isUploadDisabled}
className={cn( className={cn(
'absolute flex size-[35px] items-center justify-center rounded-full p-1 transition-colors hover:bg-surface-hover', 'absolute flex size-[35px] items-center justify-center rounded-full p-1 transition-colors hover:bg-surface-hover',
isRTL ? 'bottom-2 right-2' : 'bottom-2 left-2', isRTL ? 'bottom-2 right-2' : 'bottom-2 left-1 md:left-2',
)} )}
description={localize('com_sidepanel_attach_files')} description={localize('com_sidepanel_attach_files')}
> >

View file

@ -12,7 +12,7 @@ export default function StopButton({ stop, setShowStopButton }) {
<button <button
type="button" type="button"
className={cn( className={cn(
'rounded-full bg-text-primary p-1.5 text-text-primary outline-offset-4 transition-all duration-200 disabled:cursor-not-allowed disabled:text-text-secondary disabled:opacity-10', 'rounded-full bg-text-primary p-2 text-text-primary outline-offset-4 transition-all duration-200 disabled:cursor-not-allowed disabled:text-text-secondary disabled:opacity-10',
)} )}
aria-label={localize('com_nav_stop_generating')} aria-label={localize('com_nav_stop_generating')}
onClick={(e) => { onClick={(e) => {

View file

@ -52,7 +52,7 @@ export function DeleteConversationDialog({
<OGDialogTemplate <OGDialogTemplate
showCloseButton={false} showCloseButton={false}
title={localize('com_ui_delete_conversation')} title={localize('com_ui_delete_conversation')}
className="z-[1000] max-w-[450px]" className="max-w-[450px]"
main={ main={
<> <>
<div className="flex w-full flex-col items-center gap-2"> <div className="flex w-full flex-col items-center gap-2">

View file

@ -4,7 +4,6 @@ import type { TConversation } from 'librechat-data-provider';
import { OGDialog, Button, Input, Label, Checkbox, Dropdown } from '~/components/ui'; import { OGDialog, Button, Input, Label, Checkbox, Dropdown } from '~/components/ui';
import OGDialogTemplate from '~/components/ui/OGDialogTemplate'; import OGDialogTemplate from '~/components/ui/OGDialogTemplate';
import { useLocalize, useExportConversation } from '~/hooks'; import { useLocalize, useExportConversation } from '~/hooks';
import { cn, defaultTextProps } from '~/utils';
export default function ExportModal({ export default function ExportModal({
open, open,
@ -78,10 +77,6 @@ export default function ExportModal({
value={filename} value={filename}
onChange={(e) => setFileName(filenamify(e.target.value || ''))} onChange={(e) => setFileName(filenamify(e.target.value || ''))}
placeholder={localize('com_nav_export_filename_placeholder')} placeholder={localize('com_nav_export_filename_placeholder')}
className={cn(
defaultTextProps,
'flex h-10 max-h-10 w-full resize-none px-3 py-2',
)}
/> />
</div> </div>
<div className="col-span-1 flex w-full flex-col items-start justify-start gap-2"> <div className="col-span-1 flex w-full flex-col items-start justify-start gap-2">
@ -164,7 +159,7 @@ export default function ExportModal({
} }
buttons={ buttons={
<> <>
<Button onClick={exportConversation} variant="success"> <Button onClick={exportConversation} variant="submit">
{localize('com_endpoint_export')} {localize('com_endpoint_export')}
</Button> </Button>
</> </>

View file

@ -120,7 +120,9 @@ export default function Settings({ open, onOpenChange }: TDialogProps) {
aria-label="Settings" aria-label="Settings"
className={cn( className={cn(
'min-w-auto max-w-auto relative -ml-[8px] flex flex-shrink-0 flex-col flex-nowrap overflow-auto sm:max-w-none', 'min-w-auto max-w-auto relative -ml-[8px] flex flex-shrink-0 flex-col flex-nowrap overflow-auto sm:max-w-none',
isSmallScreen ? 'flex-row rounded-xl bg-surface-secondary' : '', isSmallScreen
? 'flex-row rounded-xl bg-surface-secondary'
: 'sticky top-0 h-full',
)} )}
onKeyDown={handleKeyDown} onKeyDown={handleKeyDown}
> >

View file

@ -1,43 +1,19 @@
import React from 'react'; import React from 'react';
import { useRecoilState } from 'recoil'; import DisplayUsernameMessages from './DisplayUsernameMessages';
import HoverCardSettings from '../HoverCardSettings';
import DeleteAccount from './DeleteAccount'; import DeleteAccount from './DeleteAccount';
import { Switch } from '~/components/ui';
import { useLocalize } from '~/hooks';
import Avatar from './Avatar'; import Avatar from './Avatar';
import store from '~/store';
function Account({ onCheckedChange }: { onCheckedChange?: (value: boolean) => void }) {
const [UsernameDisplay, setUsernameDisplay] = useRecoilState<boolean>(store.UsernameDisplay);
const localize = useLocalize();
const handleCheckedChange = (value: boolean) => {
setUsernameDisplay(value);
if (onCheckedChange) {
onCheckedChange(value);
}
};
function Account() {
return ( return (
<div className="flex flex-col gap-3 p-1 text-sm text-text-primary"> <div className="flex flex-col gap-3 p-1 text-sm text-text-primary">
<div className="border-b border-border-medium pb-3 last-of-type:border-b-0"> <div className="pb-3">
<Avatar /> <Avatar />
</div> </div>
<div className="border-b border-border-medium pb-3 last-of-type:border-b-0"> <div className="pb-3">
<DeleteAccount /> <DeleteAccount />
</div> </div>
<div className="flex items-center justify-between"> <div className="pb-3">
<div className="flex items-center space-x-2"> <DisplayUsernameMessages />
<div>{localize('com_nav_user_name_display')}</div>
<HoverCardSettings side="bottom" text="com_nav_info_user_name_display" />
</div>
<Switch
id="UsernameDisplay"
checked={UsernameDisplay}
onCheckedChange={handleCheckedChange}
className="ml-4 mt-2"
data-testid="UsernameDisplay"
/>
</div> </div>
</div> </div>
); );

View file

@ -0,0 +1,31 @@
import React from 'react';
import { useRecoilState } from 'recoil';
import HoverCardSettings from '../HoverCardSettings';
import { Switch, Label } from '~/components/ui';
import { useLocalize } from '~/hooks';
import store from '~/store';
export default function DisplayUsernameMessages() {
const localize = useLocalize();
const [UsernameDisplay, setUsernameDisplay] = useRecoilState(store.UsernameDisplay);
const handleCheckedChange = (checked: boolean) => {
setUsernameDisplay(checked);
};
return (
<div className="flex items-center justify-between">
<div className="flex items-center space-x-2">
<Label className="font-light">{localize('com_nav_user_name_display')}</Label>
<HoverCardSettings side="bottom" text="com_nav_info_user_name_display" />
</div>
<Switch
id="UsernameDisplay"
checked={UsernameDisplay}
onCheckedChange={handleCheckedChange}
className="ml-4"
data-testid="UsernameDisplay"
/>
</div>
);
}

View file

@ -4,7 +4,7 @@ import CodeArtifacts from './CodeArtifacts';
function Beta() { function Beta() {
return ( return (
<div className="flex flex-col gap-3 p-1 text-sm text-text-primary"> <div className="flex flex-col gap-3 p-1 text-sm text-text-primary">
<div className="border-b border-border-light pb-3 last-of-type:border-b-0"> <div className="pb-3">
<CodeArtifacts /> <CodeArtifacts />
</div> </div>
</div> </div>

View file

@ -86,7 +86,7 @@ function SwitchItem({
id={id} id={id}
checked={checked} checked={checked}
onCheckedChange={onCheckedChange} onCheckedChange={onCheckedChange}
className="ml-4 mt-2" className="ml-4"
data-testid={id} data-testid={id}
disabled={disabled} disabled={disabled}
/> />

View file

@ -11,26 +11,26 @@ import SaveDraft from './SaveDraft';
function Chat() { function Chat() {
return ( return (
<div className="flex flex-col gap-3 p-1 text-sm text-text-primary"> <div className="flex flex-col gap-3 p-1 text-sm text-text-primary">
<div className="border-b border-border-light pb-3 last-of-type:border-b-0"> <div className="pb-3">
<FontSizeSelector /> <FontSizeSelector />
</div> </div>
<div className="border-b border-border-light pb-3 last-of-type:border-b-0"> <div className="pb-3">
<ChatDirection /> <ChatDirection />
</div> </div>
<div className="border-b border-border-light pb-3 last-of-type:border-b-0"> <div className="pb-3">
<SendMessageKeyEnter /> <SendMessageKeyEnter />
</div> </div>
<div className="border-b border-border-light pb-3 last-of-type:border-b-0"> <div className="pb-3">
<ShowCodeSwitch /> <ShowCodeSwitch />
</div> </div>
<div className="border-b border-border-light pb-3 last-of-type:border-b-0"> <div className="pb-3">
<SaveDraft /> <SaveDraft />
</div> </div>
<ForkSettings /> <ForkSettings />
<div className="border-b border-border-light pb-3 last-of-type:border-b-0"> <div className="pb-3">
<ModularChat /> <ModularChat />
</div> </div>
<div className="border-b border-border-light pb-3 last-of-type:border-b-0"> <div className="pb-3">
<LaTeXParsing /> <LaTeXParsing />
</div> </div>
</div> </div>

View file

@ -29,7 +29,7 @@ export default function SendMessageKeyEnter({
id="enterToSend" id="enterToSend"
checked={enterToSend} checked={enterToSend}
onCheckedChange={handleCheckedChange} onCheckedChange={handleCheckedChange}
className="ml-4 mt-2" className="ml-4"
data-testid="enterToSend" data-testid="enterToSend"
/> />
</div> </div>

View file

@ -19,7 +19,20 @@ export const ForkSettings = () => {
return ( return (
<> <>
<div className="border-b border-border-light pb-3 last-of-type:border-b-0"> <div className="pb-3">
<div className="flex items-center justify-between">
<div> {localize('com_ui_fork_default')} </div>
<Switch
id="rememberDefaultFork"
checked={remember}
onCheckedChange={setRemember}
className="ml-4"
data-testid="rememberDefaultFork"
/>
</div>
</div>
{remember && (
<div className="pb-3">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
<div>{localize('com_ui_fork_change_default')}</div> <div>{localize('com_ui_fork_change_default')}</div>
@ -34,19 +47,8 @@ export const ForkSettings = () => {
/> />
</div> </div>
</div> </div>
<div className="border-b border-border-light pb-3 last-of-type:border-b-0"> )}
<div className="flex items-center justify-between"> <div className="pb-3">
<div> {localize('com_ui_fork_default')} </div>
<Switch
id="rememberDefaultFork"
checked={remember}
onCheckedChange={setRemember}
className="ml-4 mt-2"
data-testid="rememberDefaultFork"
/>
</div>
</div>
<div className="border-b border-border-light pb-3 last-of-type:border-b-0">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
<div>{localize('com_ui_fork_split_target_setting')}</div> <div>{localize('com_ui_fork_split_target_setting')}</div>
@ -56,7 +58,7 @@ export const ForkSettings = () => {
id="splitAtTarget" id="splitAtTarget"
checked={splitAtTarget} checked={splitAtTarget}
onCheckedChange={setSplitAtTarget} onCheckedChange={setSplitAtTarget}
className="ml-4 mt-2" className="ml-4"
data-testid="splitAtTarget" data-testid="splitAtTarget"
/> />
</div> </div>

View file

@ -29,7 +29,7 @@ export default function LaTeXParsingSwitch({
id="LaTeXParsing" id="LaTeXParsing"
checked={LaTeXParsing} checked={LaTeXParsing}
onCheckedChange={handleCheckedChange} onCheckedChange={handleCheckedChange}
className="ml-4 mt-2" className="ml-4"
data-testid="LaTeXParsing" data-testid="LaTeXParsing"
/> />
</div> </div>

View file

@ -25,7 +25,7 @@ export default function ModularChatSwitch({
id="modularChat" id="modularChat"
checked={modularChat} checked={modularChat}
onCheckedChange={handleCheckedChange} onCheckedChange={handleCheckedChange}
className="ml-4 mt-2" className="ml-4"
data-testid="modularChat" data-testid="modularChat"
/> />
</div> </div>

View file

@ -29,7 +29,7 @@ export default function SaveDraft({
id="saveDrafts" id="saveDrafts"
checked={saveDrafts} checked={saveDrafts}
onCheckedChange={handleCheckedChange} onCheckedChange={handleCheckedChange}
className="ml-4 mt-2" className="ml-4"
data-testid="saveDrafts" data-testid="saveDrafts"
/> />
</div> </div>

View file

@ -26,7 +26,7 @@ export default function ShowCodeSwitch({
id="showCode" id="showCode"
checked={showCode} checked={showCode}
onCheckedChange={handleCheckedChange} onCheckedChange={handleCheckedChange}
className="ml-4 mt-2" className="ml-4"
data-testid="showCode" data-testid="showCode"
/> />
</div> </div>

View file

@ -18,7 +18,7 @@ export default function AtCommandSwitch() {
id="atCommand" id="atCommand"
checked={atCommand} checked={atCommand}
onCheckedChange={handleCheckedChange} onCheckedChange={handleCheckedChange}
className="ml-4 mt-2" className="ml-4"
data-testid="atCommand" data-testid="atCommand"
/> />
</div> </div>

View file

@ -28,16 +28,16 @@ function Commands() {
<HoverCardSettings side="bottom" text="com_nav_chat_commands_info" /> <HoverCardSettings side="bottom" text="com_nav_chat_commands_info" />
</div> </div>
<div className="flex flex-col gap-3 text-sm text-text-primary"> <div className="flex flex-col gap-3 text-sm text-text-primary">
<div className="border-b border-border-light pb-3 last-of-type:border-b-0"> <div className="pb-3">
<AtCommandSwitch /> <AtCommandSwitch />
</div> </div>
{hasAccessToMultiConvo === true && ( {hasAccessToMultiConvo === true && (
<div className="border-b border-border-light pb-3 last-of-type:border-b-0"> <div className="pb-3">
<PlusCommandSwitch /> <PlusCommandSwitch />
</div> </div>
)} )}
{hasAccessToPrompts === true && ( {hasAccessToPrompts === true && (
<div className="border-b border-border-light pb-3 last-of-type:border-b-0"> <div className="pb-3">
<SlashCommandSwitch /> <SlashCommandSwitch />
</div> </div>
)} )}

View file

@ -18,7 +18,8 @@ export default function PlusCommandSwitch() {
id="plusCommand" id="plusCommand"
checked={plusCommand} checked={plusCommand}
onCheckedChange={handleCheckedChange} onCheckedChange={handleCheckedChange}
className="ml-4 mt-2" f
className="ml-4"
data-testid="plusCommand" data-testid="plusCommand"
/> />
</div> </div>

View file

@ -18,7 +18,7 @@ export default function SlashCommandSwitch() {
id="slashCommand" id="slashCommand"
checked={slashCommand} checked={slashCommand}
onCheckedChange={handleCheckedChange} onCheckedChange={handleCheckedChange}
className="ml-4 mt-2" f
data-testid="slashCommand" data-testid="slashCommand"
/> />
</div> </div>

View file

@ -13,19 +13,19 @@ function Data() {
return ( return (
<div className="flex flex-col gap-3 p-1 text-sm text-text-primary"> <div className="flex flex-col gap-3 p-1 text-sm text-text-primary">
<div className="border-b border-border-medium pb-3 last-of-type:border-b-0"> <div className="pb-3">
<ImportConversations /> <ImportConversations />
</div> </div>
<div className="border-b border-border-medium pb-3 last-of-type:border-b-0"> <div className="pb-3">
<SharedLinks /> <SharedLinks />
</div> </div>
<div className="border-b border-border-medium pb-3 last-of-type:border-b-0"> <div className="pb-3">
<RevokeAllKeys /> <RevokeAllKeys />
</div> </div>
<div className="border-b border-border-medium pb-3 last-of-type:border-b-0"> <div className="pb-3">
<DeleteCache /> <DeleteCache />
</div> </div>
<div className="border-b border-border-medium pb-3 last-of-type:border-b-0"> <div className="pb-3">
<ClearChats /> <ClearChats />
</div> </div>
</div> </div>

View file

@ -26,7 +26,7 @@ export default function AutoScrollSwitch({
checked={autoScroll} checked={autoScroll}
aria-label="Auto-Scroll to latest message on chat open" aria-label="Auto-Scroll to latest message on chat open"
onCheckedChange={handleCheckedChange} onCheckedChange={handleCheckedChange}
className="ml-4 mt-2 ring-ring-primary" className="ml-4"
data-testid="autoScroll" data-testid="autoScroll"
/> />
</div> </div>

View file

@ -1,14 +1,12 @@
import { useRecoilState } from 'recoil'; import { useRecoilState } from 'recoil';
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
import React, { useContext, useCallback } from 'react'; import React, { useContext, useCallback } from 'react';
import type { TDangerButtonProps } from '~/common';
import UserMsgMarkdownSwitch from './UserMsgMarkdownSwitch'; import UserMsgMarkdownSwitch from './UserMsgMarkdownSwitch';
import HideSidePanelSwitch from './HideSidePanelSwitch'; import HideSidePanelSwitch from './HideSidePanelSwitch';
import { ThemeContext, useLocalize } from '~/hooks'; import { ThemeContext, useLocalize } from '~/hooks';
import AutoScrollSwitch from './AutoScrollSwitch'; import AutoScrollSwitch from './AutoScrollSwitch';
import ArchivedChats from './ArchivedChats'; import ArchivedChats from './ArchivedChats';
import { Dropdown } from '~/components/ui'; import { Dropdown } from '~/components/ui';
import DangerButton from '../DangerButton';
import store from '~/store'; import store from '~/store';
export const ThemeSelector = ({ export const ThemeSelector = ({
@ -41,34 +39,6 @@ export const ThemeSelector = ({
); );
}; };
export const ClearChatsButton = ({
confirmClear,
className = '',
showText = true,
mutation,
onClick,
}: Pick<
TDangerButtonProps,
'confirmClear' | 'mutation' | 'className' | 'showText' | 'onClick'
>) => {
return (
<DangerButton
id="clearConvosBtn"
mutation={mutation}
confirmClear={confirmClear}
className={className}
showText={showText}
infoTextCode="com_nav_clear_all_chats"
actionTextCode="com_ui_clear"
confirmActionTextCode="com_nav_confirm_clear"
dataTestIdInitial="clear-convos-initial"
dataTestIdConfirm="clear-convos-confirm"
infoDescriptionCode="com_nav_info_clear_all_chats"
onClick={onClick}
/>
);
};
export const LangSelector = ({ export const LangSelector = ({
langcode, langcode,
onChange, onChange,
@ -78,7 +48,6 @@ export const LangSelector = ({
}) => { }) => {
const localize = useLocalize(); const localize = useLocalize();
// Create an array of options for the Dropdown
const languageOptions = [ const languageOptions = [
{ value: 'auto', label: localize('com_nav_lang_auto') }, { value: 'auto', label: localize('com_nav_lang_auto') },
{ value: 'en-US', label: localize('com_nav_lang_english') }, { value: 'en-US', label: localize('com_nav_lang_english') },
@ -147,22 +116,22 @@ function General() {
return ( return (
<div className="flex flex-col gap-3 p-1 text-sm text-text-primary"> <div className="flex flex-col gap-3 p-1 text-sm text-text-primary">
<div className="border-b border-border-light pb-3 last-of-type:border-b-0"> <div className="pb-3">
<ThemeSelector theme={theme} onChange={changeTheme} /> <ThemeSelector theme={theme} onChange={changeTheme} />
</div> </div>
<div className="border-b border-border-light pb-3 last-of-type:border-b-0"> <div className="pb-3">
<LangSelector langcode={langcode} onChange={changeLang} /> <LangSelector langcode={langcode} onChange={changeLang} />
</div> </div>
<div className="border-b border-border-light pb-3 last-of-type:border-b-0"> <div className="pb-3">
<UserMsgMarkdownSwitch /> <UserMsgMarkdownSwitch />
</div> </div>
<div className="border-b border-border-light pb-3 last-of-type:border-b-0"> <div className="pb-3">
<AutoScrollSwitch /> <AutoScrollSwitch />
</div> </div>
<div className="border-b border-border-light pb-3 last-of-type:border-b-0"> <div className="pb-3">
<HideSidePanelSwitch /> <HideSidePanelSwitch />
</div> </div>
<div className="border-b border-border-light pb-3 last-of-type:border-b-0"> <div className="pb-3">
<ArchivedChats /> <ArchivedChats />
</div> </div>
</div> </div>

View file

@ -27,7 +27,7 @@ export default function HideSidePanelSwitch({
checked={hideSidePanel} checked={hideSidePanel}
aria-label="Hide right-most side panel" aria-label="Hide right-most side panel"
onCheckedChange={handleCheckedChange} onCheckedChange={handleCheckedChange}
className="ml-4 mt-2" className="ml-4"
data-testid="hideSidePanel" data-testid="hideSidePanel"
/> />
</div> </div>

View file

@ -27,7 +27,7 @@ export default function UserMsgMarkdownSwitch({
id="enableUserMsgMarkdown" id="enableUserMsgMarkdown"
checked={enableUserMsgMarkdown} checked={enableUserMsgMarkdown}
onCheckedChange={handleCheckedChange} onCheckedChange={handleCheckedChange}
className="ml-4 mt-2 ring-ring-primary" className="ml-4"
data-testid="enableUserMsgMarkdown" data-testid="enableUserMsgMarkdown"
/> />
</div> </div>

View file

@ -1,6 +1,5 @@
export { default as General } from './General/General'; export { default as General } from './General/General';
export { default as Chat } from './Chat/Chat'; export { default as Chat } from './Chat/Chat';
export { ClearChatsButton } from './General/General';
export { default as Data } from './Data/Data'; export { default as Data } from './Data/Data';
export { default as Beta } from './Beta/Beta'; export { default as Beta } from './Beta/Beta';
export { default as Commands } from './Commands/Commands'; export { default as Commands } from './Commands/Commands';

View file

@ -81,7 +81,7 @@ const OGDialogTemplate = forwardRef((props: DialogTemplateProps, ref: Ref<HTMLDi
onClick={selectHandler} onClick={selectHandler}
className={`${ className={`${
selectClasses ?? defaultSelect selectClasses ?? defaultSelect
} flex h-10 w-full items-center justify-center rounded-lg border-none px-4 py-2 text-sm`} } flex h-10 items-center justify-center rounded-lg border-none px-4 py-2 text-sm`}
> >
{selectText} {selectText}
</OGDialogClose> </OGDialogClose>