Skip to content

Commit f15c1bf

Browse files
committed
fix: better chat
1 parent 4d68ff0 commit f15c1bf

File tree

2 files changed

+62
-115
lines changed

2 files changed

+62
-115
lines changed
Lines changed: 23 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,50 @@
11
.chat-input {
2-
display: flex;
3-
gap: 12px;
4-
align-items: flex-end;
2+
width: 100%;
53

6-
&__field {
7-
flex: 1;
4+
&__container {
85
position: relative;
6+
7+
width: 100%;
98
}
109

11-
&__textarea {
12-
resize: none;
13-
min-height: 40px;
14-
max-height: 200px;
15-
font-size: 14px;
16-
line-height: 1.4;
17-
18-
&:focus {
19-
outline: none;
10+
&__field {
11+
width: 100%;
12+
13+
.g-text-area__control {
14+
padding-right: 100px;
15+
16+
resize: none;
2017
}
2118
}
2219

23-
&__actions {
24-
display: flex;
25-
flex-direction: column;
26-
gap: 8px;
20+
&__button-container {
21+
position: absolute;
22+
right: 6px;
23+
bottom: 4px;
2724
}
2825

2926
&__send-button,
3027
&__stop-button {
31-
min-width: 80px;
32-
height: 40px;
3328
display: flex;
34-
align-items: center;
3529
justify-content: center;
30+
align-items: center;
3631
gap: 6px;
37-
font-size: 14px;
38-
font-weight: 500;
39-
}
40-
41-
&__send-button {
42-
&:disabled {
43-
opacity: 0.5;
44-
cursor: not-allowed;
45-
}
46-
}
47-
48-
&__stop-button {
49-
background: var(--g-color-base-danger);
50-
border-color: var(--g-color-line-danger);
51-
color: var(--g-color-text-danger);
52-
53-
&:hover:not(:disabled) {
54-
background: var(--g-color-base-danger-hover);
55-
}
56-
}
57-
}
58-
59-
// Auto-resize textarea behavior
60-
.chat-input__textarea {
61-
transition: height 0.1s ease;
62-
overflow-y: hidden;
63-
}
6432

65-
// Focus states
66-
.chat-input:focus-within {
67-
.chat-input__send-button:not(:disabled) {
68-
background: var(--g-color-base-brand);
69-
border-color: var(--g-color-line-brand);
33+
min-width: 80px;
34+
height: 36px;
7035
}
7136
}
7237

73-
// Mobile responsive
7438
@media (max-width: 768px) {
7539
.chat-input {
76-
flex-direction: column;
77-
gap: 8px;
78-
79-
&__actions {
80-
flex-direction: row;
81-
justify-content: flex-end;
40+
&__field .g-text-area__control {
41+
padding-right: 90px;
8242
}
8343

8444
&__send-button,
8545
&__stop-button {
86-
min-width: 60px;
87-
height: 36px;
88-
font-size: 13px;
46+
min-width: 70px;
47+
height: 32px;
8948
}
9049
}
91-
}
50+
}
Lines changed: 39 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
import React from 'react';
22

3-
import {Button, Icon, TextArea} from '@gravity-ui/uikit';
3+
import {CirclePlay, CircleStop} from '@gravity-ui/icons';
4+
import {ActionTooltip, Button, Icon, TextArea} from '@gravity-ui/uikit';
45

56
import './ChatInput.scss';
67

7-
// Icons - these would need to be imported from your icon library
8-
const SendIcon = () => <span></span>;
9-
const StopIcon = () => <span></span>;
10-
118
interface ChatInputProps {
129
onSendMessage: (message: string) => void;
1310
disabled?: boolean;
@@ -26,32 +23,22 @@ export const ChatInput = ({
2623
const [message, setMessage] = React.useState('');
2724
const textAreaRef = React.useRef<HTMLTextAreaElement>(null);
2825

29-
const handleSubmit = (e: React.FormEvent) => {
30-
e.preventDefault();
26+
const handleSubmit = () => {
3127
if (message.trim() && !disabled) {
3228
onSendMessage(message.trim());
3329
setMessage('');
34-
// Reset textarea height
35-
if (textAreaRef.current) {
36-
textAreaRef.current.style.height = 'auto';
37-
}
3830
}
3931
};
4032

4133
const handleKeyDown = (e: React.KeyboardEvent) => {
4234
if (e.key === 'Enter' && !e.shiftKey) {
4335
e.preventDefault();
44-
handleSubmit(e);
36+
handleSubmit();
4537
}
4638
};
4739

4840
const handleChange = (value: string) => {
4941
setMessage(value);
50-
// Auto-resize textarea
51-
if (textAreaRef.current) {
52-
textAreaRef.current.style.height = 'auto';
53-
textAreaRef.current.style.height = `${textAreaRef.current.scrollHeight}px`;
54-
}
5542
};
5643

5744
const handleStop = () => {
@@ -67,50 +54,51 @@ export const ChatInput = ({
6754
}
6855
}, []);
6956

57+
const actionButton = isStreaming ? (
58+
<ActionTooltip title="Stop generation">
59+
<Button
60+
view="flat-danger"
61+
size="m"
62+
onClick={handleStop}
63+
className="chat-input__stop-button"
64+
>
65+
<Icon data={CircleStop} size={16} />
66+
Stop
67+
</Button>
68+
</ActionTooltip>
69+
) : (
70+
<ActionTooltip title="Send message (Enter)">
71+
<Button
72+
view="action"
73+
size="m"
74+
disabled={disabled || !message.trim()}
75+
onClick={handleSubmit}
76+
className="chat-input__send-button"
77+
>
78+
<Icon data={CirclePlay} size={16} />
79+
Send
80+
</Button>
81+
</ActionTooltip>
82+
);
83+
7084
return (
71-
<form className="chat-input" onSubmit={handleSubmit}>
72-
<div className="chat-input__field">
85+
<div className="chat-input">
86+
<div className="chat-input__container">
7387
<TextArea
74-
ref={textAreaRef}
88+
controlRef={textAreaRef}
7589
value={message}
7690
onUpdate={handleChange}
7791
onKeyDown={handleKeyDown}
7892
placeholder={placeholder}
7993
disabled={disabled}
80-
rows={1}
8194
autoFocus
95+
size="xl"
8296
minRows={1}
83-
maxRows={8}
84-
className="chat-input__textarea"
97+
maxRows={6}
98+
className="chat-input__field"
8599
/>
100+
<div className="chat-input__button-container">{actionButton}</div>
86101
</div>
87-
88-
<div className="chat-input__actions">
89-
{isStreaming ? (
90-
<Button
91-
view="action"
92-
size="m"
93-
onClick={handleStop}
94-
title="Stop generation"
95-
className="chat-input__stop-button"
96-
>
97-
<Icon data={StopIcon} />
98-
Stop
99-
</Button>
100-
) : (
101-
<Button
102-
view="action"
103-
size="m"
104-
type="submit"
105-
disabled={disabled || !message.trim()}
106-
title="Send message (Enter)"
107-
className="chat-input__send-button"
108-
>
109-
<Icon data={SendIcon} />
110-
Send
111-
</Button>
112-
)}
113-
</div>
114-
</form>
102+
</div>
115103
);
116104
};

0 commit comments

Comments
 (0)