🎨 style: standardize dropdown styling & fix z-Index layering (#6939)

* fix: Dropdown settings

* refactor: classname cleanup

* refactor: export modal

* fix: Export dropdown
This commit is contained in:
Marco Beretta 2025-04-18 17:36:59 +02:00 committed by GitHub
parent 52f146dd97
commit 150116eefe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 39 additions and 39 deletions

View file

@ -29,7 +29,7 @@ export function BrowserVoiceDropdown() {
onChange={handleVoiceChange}
sizeClasses="min-w-[200px] !max-w-[400px] [--anchor-max-width:400px]"
testId="BrowserVoiceDropdown"
className="rounded-xl"
className="z-50"
/>
</div>
);
@ -58,7 +58,7 @@ export function ExternalVoiceDropdown() {
onChange={handleVoiceChange}
sizeClasses="min-w-[200px] !max-w-[400px] [--anchor-max-width:400px]"
testId="ExternalVoiceDropdown"
className="rounded-xl"
className="z-50"
/>
</div>
);

View file

@ -1,10 +1,18 @@
import filenamify from 'filenamify';
import { useEffect, useState } from 'react';
import { useEffect, useState, useMemo, useCallback } from 'react';
import type { TConversation } from 'librechat-data-provider';
import { OGDialog, Button, Input, Label, Checkbox, Dropdown } from '~/components/ui';
import OGDialogTemplate from '~/components/ui/OGDialogTemplate';
import { useLocalize, useExportConversation } from '~/hooks';
const TYPE_OPTIONS = [
{ value: 'screenshot', label: 'screenshot (.png)' },
{ value: 'text', label: 'text (.txt)' },
{ value: 'markdown', label: 'markdown (.md)' },
{ value: 'json', label: 'json (.json)' },
{ value: 'csv', label: 'csv (.csv)' },
];
export default function ExportModal({
open,
onOpenChange,
@ -21,20 +29,12 @@ export default function ExportModal({
const localize = useLocalize();
const [filename, setFileName] = useState('');
const [type, setType] = useState('Select a file type');
const [type, setType] = useState<string>('screenshot');
const [includeOptions, setIncludeOptions] = useState<boolean | 'indeterminate'>(true);
const [exportBranches, setExportBranches] = useState<boolean | 'indeterminate'>(false);
const [recursive, setRecursive] = useState<boolean | 'indeterminate'>(true);
const typeOptions = [
{ value: 'screenshot', label: 'screenshot (.png)' },
{ value: 'text', label: 'text (.txt)' },
{ value: 'markdown', label: 'markdown (.md)' },
{ value: 'json', label: 'json (.json)' },
{ value: 'csv', label: 'csv (.csv)' },
];
useEffect(() => {
if (!open && triggerRef && triggerRef.current) {
triggerRef.current.focus();
@ -49,17 +49,19 @@ export default function ExportModal({
setRecursive(true);
}, [conversation?.title, open]);
const _setType = (newType: string) => {
const exportBranchesSupport = newType === 'json' || newType === 'csv' || newType === 'webpage';
const exportOptionsSupport = newType !== 'csv' && newType !== 'screenshot';
setExportBranches(exportBranchesSupport);
setIncludeOptions(exportOptionsSupport);
const handleTypeChange = useCallback((newType: string) => {
const branches = newType === 'json' || newType === 'csv' || newType === 'webpage';
const options = newType !== 'csv' && newType !== 'screenshot';
setExportBranches(branches);
setIncludeOptions(options);
setType(newType);
};
}, []);
const exportBranchesSupport = type === 'json' || type === 'csv' || type === 'webpage';
const exportOptionsSupport = type !== 'csv' && type !== 'screenshot';
const exportBranchesSupport = useMemo(
() => type === 'json' || type === 'csv' || type === 'webpage',
[type],
);
const exportOptionsSupport = useMemo(() => type !== 'csv' && type !== 'screenshot', [type]);
const { exportConversation } = useExportConversation({
conversation,
@ -94,7 +96,13 @@ export default function ExportModal({
<Label htmlFor="type" className="text-left text-sm font-medium">
{localize('com_nav_export_type')}
</Label>
<Dropdown value={type} onChange={_setType} options={typeOptions} portal={false} />
<Dropdown
value={type}
onChange={handleTypeChange}
options={TYPE_OPTIONS}
className="z-50"
portal={false}
/>
</div>
</div>
<div className="grid w-full gap-6 sm:grid-cols-2">
@ -108,7 +116,6 @@ export default function ExportModal({
id="includeOptions"
disabled={!exportOptionsSupport}
checked={includeOptions}
className="focus:ring-opacity-20 dark:border-gray-500 dark:bg-gray-700 dark:text-gray-50 dark:focus:ring-gray-600 dark:focus:ring-opacity-50 dark:focus:ring-offset-0"
onCheckedChange={setIncludeOptions}
/>
<label
@ -131,7 +138,6 @@ export default function ExportModal({
id="exportBranches"
disabled={!exportBranchesSupport}
checked={exportBranches}
className="focus:ring-opacity-20 dark:border-gray-500 dark:bg-gray-700 dark:text-gray-50 dark:focus:ring-gray-600 dark:focus:ring-opacity-50 dark:focus:ring-offset-0"
onCheckedChange={setExportBranches}
/>
<label
@ -150,12 +156,7 @@ export default function ExportModal({
{localize('com_nav_export_recursive_or_sequential')}
</Label>
<div className="flex h-[40px] w-full items-center space-x-3">
<Checkbox
id="recursive"
checked={recursive}
className="focus:ring-opacity-20 dark:border-gray-500 dark:bg-gray-700 dark:text-gray-50 dark:focus:ring-gray-600 dark:focus:ring-opacity-50 dark:focus:ring-offset-0"
onCheckedChange={setRecursive}
/>
<Checkbox id="recursive" checked={recursive} onCheckedChange={setRecursive} />
<label
htmlFor="recursive"
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 dark:text-gray-50"

View file

@ -30,7 +30,7 @@ export default function FontSizeSelector() {
onChange={handleChange}
testId="font-size-selector"
sizeClasses="w-[150px]"
className="rounded-xl"
className="z-50"
/>
</div>
);

View file

@ -59,7 +59,7 @@ export const ThemeSelector = ({
options={themeOptions}
sizeClasses="w-[180px]"
testId="theme-selector"
className="rounded-xl"
className="z-50"
/>
</div>
);
@ -113,7 +113,7 @@ export const LangSelector = ({
onChange={onChange}
sizeClasses="[--anchor-max-height:256px]"
options={languageOptions}
className="rounded-xl"
className="z-50"
/>
</div>
);

View file

@ -32,7 +32,7 @@ const EngineSTTDropdown: React.FC<EngineSTTDropdownProps> = ({ external }) => {
options={endpointOptions}
sizeClasses="w-[180px]"
testId="EngineSTTDropdown"
className="rounded-xl"
className="z-50"
/>
</div>
);

View file

@ -31,9 +31,8 @@ const EngineTTSDropdown: React.FC<EngineTTSDropdownProps> = ({ external }) => {
onChange={handleSelect}
options={endpointOptions}
sizeClasses="w-[180px]"
anchor="bottom start"
testId="EngineTTSDropdown"
className="rounded-xl"
className="z-50"
/>
</div>
);

View file

@ -70,7 +70,7 @@ const Dropdown: React.FC<DropdownProps> = ({
<Select.Select
store={selectProps}
className={cn(
'focus:ring-offset-ring-offset relative inline-flex items-center justify-between rounded-lg border border-input bg-background px-3 py-2 text-sm text-text-primary transition-all duration-200 ease-in-out hover:bg-accent hover:text-accent-foreground focus:ring-ring-primary',
'focus:ring-offset-ring-offset relative inline-flex items-center justify-between rounded-xl border border-input bg-background px-3 py-2 text-sm text-text-primary transition-all duration-200 ease-in-out hover:bg-accent hover:text-accent-foreground focus:ring-ring-primary',
iconOnly ? 'h-full w-10' : 'w-fit gap-2',
className,
)}

View file

@ -2518,7 +2518,7 @@ html {
border-width: 1px;
border-style: solid;
border-color: var(--border-light);
background-color: hsl(var(--background));
background-color: var(--surface-primary);
padding: 0.5rem;
color: var(--text-primary);
box-shadow:
@ -2542,7 +2542,7 @@ html {
}
.popover-ui:where(.dark, .dark *) {
background-color: hsl(var(--secondary));
background-color: var(--surface-secondary);
color: var(--text-secondary);
box-shadow:
0 10px 15px -3px rgb(0 0 0 / 0.25),