Spaces:
Running
Running
| import type { KeyboardEvent } from "react"; | |
| import { Icon } from "./Icon"; | |
| type Props = { | |
| text: string; | |
| isEditing: boolean; | |
| editValue: string; | |
| onEditChange: (value: string) => void; | |
| onBeginEdit: () => void; | |
| onSubmitEdit: () => void | Promise<void>; | |
| onCancelEdit: () => void; | |
| }; | |
| export function UserBubble({ | |
| text, | |
| isEditing, | |
| editValue, | |
| onEditChange, | |
| onBeginEdit, | |
| onSubmitEdit, | |
| onCancelEdit, | |
| }: Props) { | |
| const handleKeyDown = (e: KeyboardEvent<HTMLTextAreaElement>) => { | |
| if (e.key === "Enter" && !e.shiftKey) { | |
| e.preventDefault(); | |
| onSubmitEdit(); | |
| } | |
| if (e.key === "Escape") { | |
| e.preventDefault(); | |
| onCancelEdit(); | |
| } | |
| }; | |
| return ( | |
| <div className="flex w-full justify-end"> | |
| {!isEditing ? ( | |
| <div className="flex w-full max-w-[80%] items-start gap-2 sm:max-w-[85%]"> | |
| <button | |
| type="button" | |
| onClick={onBeginEdit} | |
| title="Edit and resend" | |
| aria-label="Edit message" | |
| className="mt-1 flex h-9 w-9 shrink-0 items-center justify-center rounded-full border border-outline-variant bg-white text-primary shadow-sm transition-colors hover:border-primary/35 hover:bg-surface-container-low focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary" | |
| > | |
| <Icon name="edit" className="text-xl" /> | |
| </button> | |
| <button | |
| type="button" | |
| onClick={onBeginEdit} | |
| title="Edit and resend" | |
| className="min-w-0 flex-1 rounded-2xl rounded-tr-none bg-primary px-6 py-4 text-left shadow-sm transition-opacity hover:opacity-95 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary" | |
| > | |
| <p className="break-words font-body-md text-body-md text-on-primary"> | |
| {text} | |
| </p> | |
| </button> | |
| </div> | |
| ) : ( | |
| <div className="max-w-[80%] w-full min-w-[min(100%,280px)] rounded-2xl rounded-tr-none border border-outline-variant bg-white p-4 shadow-md ring-2 ring-primary/15"> | |
| <textarea | |
| className="min-h-[88px] w-full resize-none rounded-lg border border-outline-variant bg-surface-container-low px-3 py-2.5 font-body-md text-body-md text-on-background placeholder:text-secondary/60 focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary" | |
| value={editValue} | |
| onChange={(e) => onEditChange(e.target.value)} | |
| onKeyDown={handleKeyDown} | |
| rows={4} | |
| aria-label="Edit your message" | |
| autoFocus | |
| /> | |
| <div className="mt-3 flex flex-wrap items-center justify-end gap-2"> | |
| <button | |
| type="button" | |
| onClick={onCancelEdit} | |
| className="rounded-xl border border-outline-variant bg-white px-4 py-2 font-body-sm text-sm font-semibold text-secondary transition-colors hover:bg-surface-container-high" | |
| > | |
| Cancel | |
| </button> | |
| <button | |
| type="button" | |
| onClick={onSubmitEdit} | |
| className="flex items-center gap-2 rounded-xl bg-primary px-4 py-2 font-body-sm text-sm font-bold text-on-primary shadow-sm transition-all hover:opacity-95 active:scale-[0.98]" | |
| > | |
| Resend | |
| <Icon name="send" className="text-lg" /> | |
| </button> | |
| </div> | |
| </div> | |
| )} | |
| </div> | |
| ); | |
| } | |