Skip to content

Commit

Permalink
suppoer multiple line input using textarea instead
Browse files Browse the repository at this point in the history
  • Loading branch information
urmauur committed Nov 12, 2023
1 parent 45abf10 commit ef3d89f
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 16 deletions.
1 change: 1 addition & 0 deletions uikit/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ export * from './badge'
export * from './tooltip'
export * from './modal'
export * from './command'
export * from './textarea'
1 change: 1 addition & 0 deletions uikit/src/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
@import './tooltip/styles.scss';
@import './modal/styles.scss';
@import './command/styles.scss';
@import './textarea/styles.scss';

.animate-spin {
animation: spin 1s linear infinite;
Expand Down
21 changes: 21 additions & 0 deletions uikit/src/textarea/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import * as React from 'react'

import { twMerge } from 'tailwind-merge'

export interface TextareaProps
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}

const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
({ className, ...props }, ref) => {
return (
<textarea
className={twMerge('textarea-input', className)}
ref={ref}
{...props}
/>
)
}
)
Textarea.displayName = 'Textarea'

export { Textarea }
6 changes: 6 additions & 0 deletions uikit/src/textarea/styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.textarea-input {
@apply border-border placeholder:text-muted-foreground flex w-full rounded-md border bg-transparent px-3 py-2 transition-colors;
@apply disabled:cursor-not-allowed disabled:opacity-50;
@apply focus-visible:ring-secondary focus-visible:outline-none focus-visible:ring-1;
@apply file:border-0 file:bg-transparent file:font-medium;
}
7 changes: 5 additions & 2 deletions web/screens/Chat/SimpleTextMessage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,11 @@ const SimpleTextMessage: React.FC<Props> = ({
<BubbleLoader />
) : (
<>
<span
className={'message text-[15px] font-normal leading-relaxed'}
<div
className={twMerge(
'message flex flex-grow flex-col gap-y-2 text-[15px] font-normal leading-relaxed',
isUser && 'whitespace-pre-wrap break-words'
)}
// eslint-disable-next-line @typescript-eslint/naming-convention
dangerouslySetInnerHTML={{ __html: parsedText }}
/>
Expand Down
45 changes: 31 additions & 14 deletions web/screens/Chat/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Fragment, useEffect } from 'react'
import { Fragment, useEffect, useRef } from 'react'

import { Model } from '@janhq/core/lib/types'
import { Input, Button, Badge } from '@janhq/uikit'
import { Button, Badge, Textarea } from '@janhq/uikit'

import { useAtom, useAtomValue } from 'jotai'
import { Trash2Icon } from 'lucide-react'
Expand Down Expand Up @@ -54,13 +54,15 @@ const ChatScreen = () => {
const conversations = useAtomValue(userConversationsAtom)
const isEnableChat = (currentConvo && activeModel) || conversations.length > 0

const textareaRef = useRef<HTMLTextAreaElement>(null)

useEffect(() => {
getUserConversations()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])

const handleMessageChange = (value: string) => {
setCurrentPrompt(value)
const handleMessageChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
setCurrentPrompt(e.target.value)
}

const handleSendMessage = async () => {
Expand All @@ -71,6 +73,7 @@ const ChatScreen = () => {
await requestCreateConvo(activeModel as Model)
}
}

useEffect(() => {
if (isWaitingToSend && activeConversationId) {
setIsWaitingToSend(false)
Expand All @@ -79,12 +82,24 @@ const ChatScreen = () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [waitingToSendMessage, activeConversationId])

const handleKeyDown = async (
event: React.KeyboardEvent<HTMLInputElement>
) => {
if (event.key === 'Enter') {
if (!event.shiftKey) {
event.preventDefault()
useEffect(() => {
if (textareaRef.current !== null) {
const scrollHeight = textareaRef.current.scrollHeight
if (currentPrompt.length === 0) {
textareaRef.current.style.height = '40px'
} else {
textareaRef.current.style.height = `${
scrollHeight < 40 ? 40 : scrollHeight
}px`
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [currentPrompt])

const handleKeyDown = async (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
if (e.key === 'Enter') {
if (!e.shiftKey) {
e.preventDefault()
handleSendMessage()
}
}
Expand Down Expand Up @@ -162,9 +177,9 @@ const ChatScreen = () => {
</div>
)}
<div className="mx-auto flex w-full flex-shrink-0 items-center justify-center space-x-4 p-4 lg:w-3/4">
<Input
type="text"
className="h-10"
<Textarea
className="min-h-10 h-10 max-h-16 resize-none pr-20"
ref={textareaRef}
onKeyDown={(e) => handleKeyDown(e)}
placeholder="Type your message ..."
disabled={
Expand All @@ -173,7 +188,9 @@ const ChatScreen = () => {
activeModel._id !== currentConvo?.modelId
}
value={currentPrompt}
onChange={(e) => handleMessageChange(e.target.value)}
onChange={(e) => {
handleMessageChange(e)
}}
/>
<Button
size="lg"
Expand Down

0 comments on commit ef3d89f

Please sign in to comment.