| import { OptionTypes } from 'librechat-data-provider'; | |
| import type { DynamicSettingProps } from 'librechat-data-provider'; | |
| import { useLocalize, useDebouncedInput, useParameterEffects, TranslationKeys } from '~/hooks'; | |
| import { Label, TextareaAutosize, HoverCard, HoverCardTrigger } from '@librechat/client'; | |
| import { useChatContext } from '~/Providers'; | |
| import OptionHover from './OptionHover'; | |
| import { ESide } from '~/common'; | |
| import { cn } from '~/utils'; | |
| function DynamicTextarea({ | |
| label = '', | |
| settingKey, | |
| defaultValue, | |
| description = '', | |
| columnSpan, | |
| setOption, | |
| optionType, | |
| placeholder = '', | |
| readonly = false, | |
| showDefault = false, | |
| labelCode = false, | |
| descriptionCode = false, | |
| placeholderCode = false, | |
| conversation, | |
| }: DynamicSettingProps) { | |
| const localize = useLocalize(); | |
| const { preset } = useChatContext(); | |
| const [setInputValue, inputValue, setLocalValue] = useDebouncedInput<string | null>({ | |
| optionKey: settingKey, | |
| initialValue: | |
| optionType !== OptionTypes.Custom | |
| ? (conversation?.[settingKey] as string) | |
| : (defaultValue as string), | |
| setter: () => ({}), | |
| setOption, | |
| }); | |
| useParameterEffects({ | |
| preset, | |
| settingKey, | |
| defaultValue: typeof defaultValue === 'undefined' ? '' : defaultValue, | |
| conversation, | |
| inputValue, | |
| setInputValue: setLocalValue, | |
| }); | |
| return ( | |
| <div | |
| className={`flex flex-col items-center justify-start gap-6 ${ | |
| columnSpan != null ? `col-span-${columnSpan}` : 'col-span-full' | |
| }`} | |
| > | |
| <HoverCard openDelay={300}> | |
| <HoverCardTrigger className="grid w-full items-center gap-2"> | |
| <div className="flex w-full justify-between"> | |
| <Label | |
| htmlFor={`${settingKey}-dynamic-textarea`} | |
| className="text-left text-sm font-medium" | |
| > | |
| {labelCode ? (localize(label as TranslationKeys) ?? label) : label || settingKey}{' '} | |
| {showDefault && ( | |
| <small className="opacity-40"> | |
| ( | |
| {typeof defaultValue === 'undefined' || !(defaultValue as string).length | |
| ? localize('com_endpoint_default_blank') | |
| : `${localize('com_endpoint_default')}: ${defaultValue}`} | |
| ) | |
| </small> | |
| )} | |
| </Label> | |
| </div> | |
| <TextareaAutosize | |
| id={`${settingKey}-dynamic-textarea`} | |
| disabled={readonly} | |
| value={inputValue ?? ''} | |
| onChange={setInputValue} | |
| aria-label={localize(label as TranslationKeys)} | |
| placeholder={ | |
| placeholderCode | |
| ? (localize(placeholder as TranslationKeys) ?? placeholder) | |
| : placeholder | |
| } | |
| className={cn( | |
| // TODO: configurable max height | |
| 'flex max-h-[138px] min-h-[100px] w-full resize-none rounded-lg bg-surface-secondary px-3 py-2 focus:outline-none', | |
| )} | |
| /> | |
| </HoverCardTrigger> | |
| {description && ( | |
| <OptionHover | |
| description={ | |
| descriptionCode | |
| ? (localize(description as TranslationKeys) ?? description) | |
| : description | |
| } | |
| side={ESide.Left} | |
| /> | |
| )} | |
| </HoverCard> | |
| </div> | |
| ); | |
| } | |
| export default DynamicTextarea; | |