Skip to content

Commit e619d31

Browse files
author
Yann Leflour
committed
add autosizing textarea
1 parent 6ed6e08 commit e619d31

File tree

2 files changed

+83
-19
lines changed

2 files changed

+83
-19
lines changed

ui-sketcher-webview/src/chat/Chat.tsx

Lines changed: 76 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,15 @@ import RMarkdown from "react-markdown";
33
import remarkGfm from "remark-gfm";
44
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
55
import { a11yDark } from "react-syntax-highlighter/dist/esm/styles/prism";
6-
import { useCallback, useEffect, useRef, useState } from "react";
7-
import { ArrowDownCircleFill } from "react-bootstrap-icons";
6+
import {
7+
FormEvent,
8+
KeyboardEvent,
9+
useCallback,
10+
useEffect,
11+
useRef,
12+
useState,
13+
} from "react";
14+
import { ArrowDownCircleFill, ArrowUpSquareFill } from "react-bootstrap-icons";
815

916
function useLocal<T extends object | undefined>(input: T) {
1017
return useRef(proxy(input)).current as T;
@@ -125,17 +132,23 @@ const History = ({ history }: { history: any[] }) => {
125132
switch (item.type) {
126133
case "system":
127134
return (
128-
<div key={index} className="border-b-2 py-4 text-lg font-bold">
129-
<div className="text-l sticky top-0 bg-white">Assistant:</div>
135+
<div key={index} className="pt-4 text-lg font-bold">
136+
<div className="sticky top-0 flex items-center gap-2 bg-white">
137+
<div className="text-l text-primary">Assistant</div>
138+
<div className="flex-1 border-b-2" />
139+
</div>
130140
<div className="prose p-2">
131141
<Mardown>{item.message}</Mardown>
132142
</div>
133143
</div>
134144
);
135145
case "user":
136146
return (
137-
<div key={index} className="border-b-2 py-4 text-lg font-bold">
138-
<div className="sticky top-0 bg-white">You:</div>
147+
<div key={index} className="pt-4 text-lg font-bold">
148+
<div className="sticky top-0 flex items-center gap-2 bg-white">
149+
<div className="text-l text-secondary">You</div>
150+
<div className="flex-1 border-b-2" />
151+
</div>
139152
<div className="prose p-2">
140153
<Mardown>{item.message}</Mardown>
141154
</div>
@@ -157,14 +170,61 @@ const History = ({ history }: { history: any[] }) => {
157170
);
158171
};
159172

160-
const Input = () => {
173+
interface InputProps {
174+
onSubmit: (message: string) => void;
175+
}
176+
177+
const Input = ({ onSubmit }: InputProps) => {
178+
const ref = useRef<HTMLTextAreaElement>(null);
179+
const [message, setMessage] = useState("");
180+
const isEmpty = message.trim().length === 0;
181+
182+
const forwardSubmit = (
183+
e: FormEvent<HTMLFormElement> | KeyboardEvent<HTMLTextAreaElement>,
184+
) => {
185+
e.preventDefault();
186+
onSubmit(message);
187+
setMessage("");
188+
};
189+
190+
const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
191+
if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
192+
forwardSubmit(e);
193+
}
194+
};
195+
196+
useEffect(() => {
197+
if (ref.current) {
198+
// Find a way to make this cleaner, up to 5 lines
199+
if (ref.current.scrollHeight / 32 < 5) {
200+
ref.current.style.height = "auto";
201+
ref.current.style.height = ref.current.scrollHeight + "px";
202+
}
203+
}
204+
}, [message]);
205+
161206
return (
162-
<form>
207+
<form onSubmit={forwardSubmit} className="relative">
208+
<button
209+
type="submit"
210+
className="absolute bottom-4 right-2 opacity-60 hover:opacity-100 disabled:hidden"
211+
disabled={isEmpty}
212+
>
213+
<ArrowUpSquareFill size="2rem" />
214+
</button>
215+
163216
<textarea
164-
className="textarea textarea-primary w-full rounded-none pl-5"
165-
placeholder="Bio"
217+
name="message"
218+
ref={ref}
219+
autoFocus
220+
value={message}
221+
onChange={(e) => setMessage(e.currentTarget.value)}
222+
className="textarea textarea-primary w-full rounded-none bg-white pr-14"
223+
placeholder="Message your assistant..."
224+
onKeyDown={handleKeyDown}
225+
rows={1}
226+
style={{ resize: "none" }}
166227
></textarea>
167-
<span className="button"></span>
168228
</form>
169229
);
170230
};
@@ -178,7 +238,11 @@ export const Chat = () => {
178238
return (
179239
<div className="flex h-full max-h-full flex-col gap-3 bg-white">
180240
<History history={historySnap} />
181-
<Input />
241+
<Input
242+
onSubmit={(data) => {
243+
console.warn(data);
244+
}}
245+
/>
182246
</div>
183247
);
184248
};

ui-sketcher-webview/tailwind.config.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ export default {
1616
themes: [
1717
{
1818
tldraw: {
19-
primary: "#0e00ff",
20-
secondary: "#ff00ef",
21-
accent: "#00d7ff",
19+
primary: "#0766AD",
20+
secondary: "#29ADB2",
21+
accent: "#C5E898",
2222
neutral: "#030d10",
2323
"base-100": "#f5f5f4",
24-
info: "#007cb6",
25-
success: "#00f274",
26-
warning: "#b38600",
27-
error: "#ff7b98",
24+
info: "#00efff",
25+
success: "#00bf7b",
26+
warning: "#ffa800",
27+
error: "#ff324b",
2828
},
2929
},
3030
],

0 commit comments

Comments
 (0)