Show open risk on the ETH book and draft a conservative bid.
AI Chat@paxeer/ai-chat/composerimplemented
Composer
Chat composer using Textarea + Button.
Install
$
pnpm exec designx add @paxeer/ai-chat/composerPreview
Loading preview...
Source code
components/designx/ai-chat/composer.tsxtsx
"use client";
import { type FormEvent, useState } from "react";
import { Button, Card, CardContent, Textarea } from "@paxeer/core";
export interface ComposerProps {
placeholder?: string;
disabled?: boolean;
onSend?: (text: string) => void;
}
export function Composer({
placeholder = "Ask about a file, order, or run",
disabled,
onSend,
}: ComposerProps) {
const [value, setValue] = useState("");
function submit(event?: FormEvent) {
event?.preventDefault();
const text = value.trim();
if (!text) return;
onSend?.(text);
setValue("");
}
return (
<Card className="gap-0 py-3" data-slot="composer">
<CardContent className="px-3">
<form onSubmit={submit} className="flex flex-col gap-2">
<label className="sr-only" htmlFor="designx-composer">
Message
</label>
<Textarea
id="designx-composer"
rows={3}
disabled={disabled}
value={value}
placeholder={placeholder}
onChange={(event) => setValue(event.target.value)}
onKeyDown={(event) => {
if (event.key === "Enter" && !event.shiftKey) {
event.preventDefault();
submit();
}
}}
/>
<div className="flex items-center justify-between gap-2">
<p className="text-[length:var(--md-sys-typescale-label-small-size)] text-on-surface-variant">
Enter to send · Shift+Enter for a new line
</p>
<Button type="submit" size="dense" disabled={disabled || value.trim().length === 0}>
Send
</Button>
</div>
</form>
</CardContent>
</Card>
);
}
Dependencies
Registry dependencies