mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 17:00:15 +01:00
🎨 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:
parent
52f146dd97
commit
150116eefe
8 changed files with 39 additions and 39 deletions
|
|
@ -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>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ export default function FontSizeSelector() {
|
|||
onChange={handleChange}
|
||||
testId="font-size-selector"
|
||||
sizeClasses="w-[150px]"
|
||||
className="rounded-xl"
|
||||
className="z-50"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ const EngineSTTDropdown: React.FC<EngineSTTDropdownProps> = ({ external }) => {
|
|||
options={endpointOptions}
|
||||
sizeClasses="w-[180px]"
|
||||
testId="EngineSTTDropdown"
|
||||
className="rounded-xl"
|
||||
className="z-50"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue