mirror of
https://git.mirrors.martin98.com/https://github.com/infiniflow/ragflow.git
synced 2025-08-14 04:15:53 +08:00
### What problem does this PR solve? Feat: Add ChatInput component #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
parent
a03f5dd9f6
commit
891ee85fa6
46
web/src/components/chat-input.tsx
Normal file
46
web/src/components/chat-input.tsx
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import { useEventListener } from 'ahooks';
|
||||||
|
import { Mic, Paperclip, Send } from 'lucide-react';
|
||||||
|
import { useRef, useState } from 'react';
|
||||||
|
import { Button } from './ui/button';
|
||||||
|
import { Textarea } from './ui/textarea';
|
||||||
|
|
||||||
|
export function ChatInput() {
|
||||||
|
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||||
|
const [textareaHeight, setTextareaHeight] = useState<number>(40);
|
||||||
|
|
||||||
|
useEventListener(
|
||||||
|
'keydown',
|
||||||
|
(ev) => {
|
||||||
|
if (ev.shiftKey && ev.code === 'Enter') {
|
||||||
|
setTextareaHeight((h) => {
|
||||||
|
return h + 10;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
target: textareaRef,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className="flex items-end bg-colors-background-neutral-strong px-4 py-3 rounded-xl m-8">
|
||||||
|
<Button variant={'icon'} className="w-10 h-10">
|
||||||
|
<Mic />
|
||||||
|
</Button>
|
||||||
|
<Textarea
|
||||||
|
ref={textareaRef}
|
||||||
|
placeholder="Tell us a little bit about yourself "
|
||||||
|
className="resize-none focus-visible:ring-0 focus-visible:ring-offset-0 bg-transparent border-none min-h-0 max-h-20"
|
||||||
|
style={{ height: textareaHeight }}
|
||||||
|
/>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<Button variant={'icon'} size={'icon'}>
|
||||||
|
<Paperclip />
|
||||||
|
</Button>
|
||||||
|
<Button variant={'tertiary'} size={'icon'}>
|
||||||
|
<Send />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
@ -9,7 +9,7 @@ const Textarea = React.forwardRef<
|
|||||||
return (
|
return (
|
||||||
<textarea
|
<textarea
|
||||||
className={cn(
|
className={cn(
|
||||||
'flex min-h-[80px] w-full rounded-md border border-input bg-colors-background-inverse-weak px-3 py-2 text-base ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
|
'flex min-h-[80px] w-full rounded-md border border-input bg-colors-background-inverse-weak px-3 py-2 text-base ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm overflow-hidden',
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { Button } from '@/components/ui/button';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import { FormProvider, useForm } from 'react-hook-form';
|
import { FormProvider, useForm } from 'react-hook-form';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
@ -35,7 +36,7 @@ export function AppSettings() {
|
|||||||
<div className="text-2xl font-bold mb-4 text-colors-text-neutral-strong px-6">
|
<div className="text-2xl font-bold mb-4 text-colors-text-neutral-strong px-6">
|
||||||
App settings
|
App settings
|
||||||
</div>
|
</div>
|
||||||
<div className="overflow-auto max-h-[88vh] px-6 ">
|
<div className="overflow-auto max-h-[81vh] px-6 ">
|
||||||
<FormProvider {...form}>
|
<FormProvider {...form}>
|
||||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
|
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
|
||||||
<ChatBasicSetting></ChatBasicSetting>
|
<ChatBasicSetting></ChatBasicSetting>
|
||||||
@ -44,6 +45,14 @@ export function AppSettings() {
|
|||||||
</form>
|
</form>
|
||||||
</FormProvider>
|
</FormProvider>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="p-6 text-center">
|
||||||
|
<p className="text-colors-text-neutral-weak mb-1">
|
||||||
|
There are unsaved changes
|
||||||
|
</p>
|
||||||
|
<Button variant={'tertiary'} className="w-full">
|
||||||
|
Update
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
import { ChatInput } from '@/components/chat-input';
|
||||||
|
|
||||||
export function ChatBox() {
|
export function ChatBox() {
|
||||||
return <section className="border-x flex-1">ChatBox</section>;
|
return (
|
||||||
|
<section className="border-x flex-1">
|
||||||
|
<ChatInput></ChatInput>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ module.exports = {
|
|||||||
'colors-text-core-standard': 'var(--colors-text-core-standard)',
|
'colors-text-core-standard': 'var(--colors-text-core-standard)',
|
||||||
'colors-text-neutral-strong': 'var(--colors-text-neutral-strong)',
|
'colors-text-neutral-strong': 'var(--colors-text-neutral-strong)',
|
||||||
'colors-text-neutral-standard': 'var(--colors-text-neutral-standard)',
|
'colors-text-neutral-standard': 'var(--colors-text-neutral-standard)',
|
||||||
|
'colors-text-neutral-weak': 'var(--colors-text-neutral-weak)',
|
||||||
'colors-text-functional-danger': 'var(--colors-text-functional-danger)',
|
'colors-text-functional-danger': 'var(--colors-text-functional-danger)',
|
||||||
'colors-text-inverse-strong': 'var(--colors-text-inverse-strong)',
|
'colors-text-inverse-strong': 'var(--colors-text-inverse-strong)',
|
||||||
'colors-text-persist-light': 'var(--colors-text-persist-light)',
|
'colors-text-persist-light': 'var(--colors-text-persist-light)',
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
--colors-background-inverse-strong: rgba(11, 10, 18, 0.8);
|
--colors-background-inverse-strong: rgba(11, 10, 18, 0.8);
|
||||||
--colors-background-inverse-weak: rgba(17, 16, 23, 0.1);
|
--colors-background-inverse-weak: rgba(17, 16, 23, 0.1);
|
||||||
--colors-background-neutral-standard: white;
|
--colors-background-neutral-standard: white;
|
||||||
|
--colors-background-neutral-strong: rgba(226, 223, 246, 1);
|
||||||
--colors-background-functional-solid-danger: rgba(222, 17, 53, 1);
|
--colors-background-functional-solid-danger: rgba(222, 17, 53, 1);
|
||||||
--colors-background-core-strong: rgba(98, 72, 246, 1);
|
--colors-background-core-strong: rgba(98, 72, 246, 1);
|
||||||
--colors-background-sentiment-solid-primary: rgba(127, 105, 255, 1);
|
--colors-background-sentiment-solid-primary: rgba(127, 105, 255, 1);
|
||||||
@ -53,7 +54,8 @@
|
|||||||
|
|
||||||
--colors-text-core-standard: rgba(127, 105, 255, 1);
|
--colors-text-core-standard: rgba(127, 105, 255, 1);
|
||||||
--colors-text-neutral-strong: rgba(17, 16, 23, 1);
|
--colors-text-neutral-strong: rgba(17, 16, 23, 1);
|
||||||
--colors-text-neutral-standard: rgba(53, 51, 65, 1);
|
--colors-text-neutral-standard: rgba(152, 148, 176, 1);
|
||||||
|
--colors-text-neutral-weak: rgba(170, 160, 197, 1);
|
||||||
--colors-text-functional-danger: rgba(255, 81, 81, 1);
|
--colors-text-functional-danger: rgba(255, 81, 81, 1);
|
||||||
--colors-text-inverse-strong: rgba(255, 255, 255, 1);
|
--colors-text-inverse-strong: rgba(255, 255, 255, 1);
|
||||||
--colors-text-persist-light: rgba(255, 255, 255, 1);
|
--colors-text-persist-light: rgba(255, 255, 255, 1);
|
||||||
@ -136,6 +138,7 @@
|
|||||||
--colors-text-core-standard: rgba(137, 126, 255, 1);
|
--colors-text-core-standard: rgba(137, 126, 255, 1);
|
||||||
--colors-text-neutral-strong: rgba(255, 255, 255, 1);
|
--colors-text-neutral-strong: rgba(255, 255, 255, 1);
|
||||||
--colors-text-neutral-standard: rgba(230, 227, 246, 1);
|
--colors-text-neutral-standard: rgba(230, 227, 246, 1);
|
||||||
|
--colors-text-neutral-weak: rgba(170, 160, 197, 1);
|
||||||
--colors-text-functional-danger: rgba(255, 81, 81, 1);
|
--colors-text-functional-danger: rgba(255, 81, 81, 1);
|
||||||
--colors-text-inverse-strong: rgba(17, 16, 23, 1);
|
--colors-text-inverse-strong: rgba(17, 16, 23, 1);
|
||||||
--colors-text-persist-light: rgba(255, 255, 255, 1);
|
--colors-text-persist-light: rgba(255, 255, 255, 1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user