|
import React from 'react'; |
|
import { Plus, Minus } from 'lucide-react'; |
|
import TextareaAutosize from 'react-textarea-autosize'; |
|
import type { TExample } from 'librechat-data-provider'; |
|
import type { TSetExample } from '~/common'; |
|
import { Button, Label } from '~/components/ui'; |
|
import { cn, defaultTextProps } from '~/utils/'; |
|
import { useLocalize } from '~/hooks'; |
|
|
|
type TExamplesProps = { |
|
readonly?: boolean; |
|
className?: string; |
|
examples: TExample[]; |
|
setExample: TSetExample; |
|
addExample: () => void; |
|
removeExample: () => void; |
|
}; |
|
|
|
function Examples({ readonly, examples, setExample, addExample, removeExample }: TExamplesProps) { |
|
const localize = useLocalize(); |
|
return ( |
|
<> |
|
<div id="examples-grid" className="grid gap-6 sm:grid-cols-2"> |
|
{examples.map((example, idx) => ( |
|
<React.Fragment key={idx}> |
|
{/* Input */} |
|
<div |
|
className={`col-span-${ |
|
examples.length === 1 ? '1' : 'full' |
|
} flex flex-col items-center justify-start gap-6 sm:col-span-1`} |
|
> |
|
<div className="grid w-full items-center gap-2"> |
|
<Label htmlFor={`input-${idx}`} className="text-left text-sm font-medium"> |
|
{localize('com_ui_input')}{' '} |
|
<small className="opacity-40">({localize('com_endpoint_default_blank')})</small> |
|
</Label> |
|
<TextareaAutosize |
|
id={`input-${idx}`} |
|
disabled={readonly} |
|
value={example?.input?.content || ''} |
|
onChange={(e) => setExample(idx, 'input', e.target.value ?? null)} |
|
placeholder="Set example input. Example is ignored if empty." |
|
className={cn( |
|
defaultTextProps, |
|
'flex max-h-[300px] min-h-[75px] w-full resize-none px-3 py-2 ', |
|
)} |
|
/> |
|
</div> |
|
</div> |
|
|
|
{/* Output */} |
|
<div |
|
className={`col-span-${ |
|
examples.length === 1 ? '1' : 'full' |
|
} flex flex-col items-center justify-start gap-6 sm:col-span-1`} |
|
> |
|
<div className="grid w-full items-center gap-2"> |
|
<Label htmlFor={`output-${idx}`} className="text-left text-sm font-medium"> |
|
{localize('com_endpoint_output')}{' '} |
|
<small className="opacity-40">({localize('com_endpoint_default_blank')})</small> |
|
</Label> |
|
<TextareaAutosize |
|
id={`output-${idx}`} |
|
disabled={readonly} |
|
value={example?.output?.content || ''} |
|
onChange={(e) => setExample(idx, 'output', e.target.value ?? null)} |
|
placeholder={'Set example output. Example is ignored if empty.'} |
|
className={cn( |
|
defaultTextProps, |
|
'flex max-h-[300px] min-h-[75px] w-full resize-none px-3 py-2 ', |
|
)} |
|
/> |
|
</div> |
|
</div> |
|
</React.Fragment> |
|
))} |
|
</div> |
|
<div className="flex justify-center"> |
|
<Button |
|
type="button" |
|
className="mr-2 mt-1 h-auto items-center justify-center bg-transparent px-3 py-2 text-xs font-medium font-normal text-black hover:bg-slate-200 hover:text-black focus:ring-0 focus:ring-offset-0 dark:bg-transparent dark:text-white dark:hover:bg-gray-700 dark:hover:text-white dark:focus:outline-none dark:focus:ring-offset-0" |
|
onClick={removeExample} |
|
> |
|
<Minus className="w-[16px]" /> |
|
</Button> |
|
<Button |
|
type="button" |
|
className="mt-1 h-auto items-center justify-center bg-transparent px-3 py-2 text-xs font-medium font-normal text-black hover:bg-slate-200 hover:text-black focus:ring-0 focus:ring-offset-0 dark:bg-transparent dark:text-white dark:hover:bg-gray-700 dark:hover:text-white dark:focus:outline-none dark:focus:ring-offset-0" |
|
onClick={addExample} |
|
> |
|
<Plus className="w-[16px]" /> |
|
</Button> |
|
</div> |
|
</> |
|
); |
|
} |
|
|
|
export default Examples; |
|
|