PR-AGENT / src /components /UserBubble.tsx
Seth
Update
84983c9
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>
);
}