mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-19 01:40:15 +01:00
refactor: dynamic form elements using react-hook-form Controllers
This commit is contained in:
parent
fac2acd4cf
commit
2150c4815d
10 changed files with 376 additions and 619 deletions
|
|
@ -1,55 +1,33 @@
|
|||
// client/src/components/SidePanel/Parameters/DynamicTextarea.tsx
|
||||
import { OptionTypes } from 'librechat-data-provider';
|
||||
import type { DynamicSettingProps } from 'librechat-data-provider';
|
||||
import React from 'react';
|
||||
import { Controller, useFormContext } from 'react-hook-form';
|
||||
import { Label, TextareaAutosize, HoverCard, HoverCardTrigger } from '~/components/ui';
|
||||
import { useLocalize, useDebouncedInput, useParameterEffects } from '~/hooks';
|
||||
import { useLocalize } from '~/hooks';
|
||||
import { cn, defaultTextProps } from '~/utils';
|
||||
import { useChatContext } from '~/Providers';
|
||||
import OptionHover from './OptionHover';
|
||||
import { ESide } from '~/common';
|
||||
import type { DynamicSettingProps } from 'librechat-data-provider';
|
||||
|
||||
function DynamicTextarea({
|
||||
label,
|
||||
label = '',
|
||||
settingKey,
|
||||
defaultValue,
|
||||
description,
|
||||
description = '',
|
||||
columnSpan,
|
||||
setOption,
|
||||
optionType,
|
||||
placeholder,
|
||||
placeholder = '',
|
||||
readonly = false,
|
||||
showDefault = true,
|
||||
labelCode,
|
||||
descriptionCode,
|
||||
placeholderCode,
|
||||
conversation,
|
||||
}: DynamicSettingProps) {
|
||||
const localize = useLocalize();
|
||||
const { preset } = useChatContext();
|
||||
|
||||
const [setInputValue, inputValue] = useDebouncedInput<string | null>({
|
||||
optionKey: optionType !== OptionTypes.Custom ? settingKey : undefined,
|
||||
initialValue:
|
||||
optionType !== OptionTypes.Custom
|
||||
? (conversation?.[settingKey] as string)
|
||||
: (defaultValue as string),
|
||||
setter: () => ({}),
|
||||
setOption,
|
||||
});
|
||||
|
||||
useParameterEffects({
|
||||
preset,
|
||||
settingKey,
|
||||
defaultValue: typeof defaultValue === 'undefined' ? '' : defaultValue,
|
||||
conversation,
|
||||
inputValue,
|
||||
setInputValue,
|
||||
});
|
||||
const { control } = useFormContext();
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`flex flex-col items-center justify-start gap-6 ${
|
||||
columnSpan ? `col-span-${columnSpan}` : 'col-span-full'
|
||||
columnSpan != null ? `col-span-${columnSpan}` : 'col-span-full'
|
||||
}`}
|
||||
>
|
||||
<HoverCard openDelay={300}>
|
||||
|
|
@ -59,34 +37,43 @@ function DynamicTextarea({
|
|||
htmlFor={`${settingKey}-dynamic-textarea`}
|
||||
className="text-left text-sm font-medium"
|
||||
>
|
||||
{labelCode ? localize(label ?? '') || label : label ?? settingKey}{' '}
|
||||
{labelCode === true ? localize(label) ?? label : label || settingKey}{' '}
|
||||
{showDefault && (
|
||||
<small className="opacity-40">
|
||||
(
|
||||
{typeof defaultValue === 'undefined' || !(defaultValue as string)?.length
|
||||
{typeof defaultValue === 'undefined' ||
|
||||
!((defaultValue as string | undefined)?.length ?? 0)
|
||||
? localize('com_endpoint_default_blank')
|
||||
: `${localize('com_endpoint_default')}: ${defaultValue}`}
|
||||
)
|
||||
</small>
|
||||
)}
|
||||
</Label>
|
||||
</div>
|
||||
<TextareaAutosize
|
||||
id={`${settingKey}-dynamic-textarea`}
|
||||
disabled={readonly}
|
||||
value={inputValue ?? ''}
|
||||
onChange={setInputValue}
|
||||
placeholder={placeholderCode ? localize(placeholder ?? '') || placeholder : placeholder}
|
||||
className={cn(
|
||||
defaultTextProps,
|
||||
// TODO: configurable max height
|
||||
'flex max-h-[138px] min-h-[100px] w-full resize-none px-3 py-2',
|
||||
<Controller
|
||||
name={settingKey}
|
||||
control={control}
|
||||
defaultValue={defaultValue as string}
|
||||
render={({ field }) => (
|
||||
<TextareaAutosize
|
||||
id={`${settingKey}-dynamic-textarea`}
|
||||
disabled={readonly}
|
||||
value={field.value ?? ''}
|
||||
onChange={(e) => field.onChange(e.target.value)}
|
||||
placeholder={
|
||||
placeholderCode === true ? localize(placeholder) ?? placeholder : placeholder
|
||||
}
|
||||
className={cn(
|
||||
defaultTextProps,
|
||||
'flex max-h-[138px] min-h-[100px] w-full resize-none px-3 py-2',
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</HoverCardTrigger>
|
||||
{description && (
|
||||
<OptionHover
|
||||
description={descriptionCode ? localize(description) || description : description}
|
||||
description={
|
||||
descriptionCode === true ? localize(description) ?? description : description
|
||||
}
|
||||
side={ESide.Left}
|
||||
/>
|
||||
)}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue