Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion content/solid/composer.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,19 @@ import { Composer } from "@/components/ui/composer"
```tsx
const [text, setText] = React.useState("")

<Composer value={text} onValueChange={setText} onSubmit={send} />
<Composer
value={text}
onValueChange={setText}
onSubmit={send}
textareaProps={{ "aria-label": "Message" }}
/>
```

`textareaProps` names and describes the input itself. It accepts `id`, `aria-label`,
`aria-labelledby`, and `aria-describedby`; use its `id` with an external label's
`htmlFor`. Other HTML attributes, including a top-level `id` or `aria-label`,
continue to apply to the outer wrapper.

## While a turn runs

The send mark has no block behind it in any state: its brightness says what it will do. With `running`, it is the quiet square that stops the turn, until something is typed, which is then sent behind it.
Expand All @@ -52,6 +62,7 @@ The send mark has no block behind it in any state: its brightness says what it w
| `onValueChange` | `(value: string) => void` | - |
| `onSubmit` | `(value: string) => void` | - |
| `onStop` | `() => void` | - |
| `textareaProps` | `Pick<ComponentProps<"textarea">, "id" \| "aria-label" \| "aria-labelledby" \| "aria-describedby">` | - |
| `running` | `boolean` | `false` |
| `leading` | `ReactNode` | - |
| `tags` | `ReactNode` | - |
Expand Down
1 change: 1 addition & 0 deletions src/blocks/agent-workspace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,7 @@ export default function AgentWorkspace() {
<div className="flex shrink-0 justify-center px-4 pb-4 md:px-6">
<div className="w-full max-w-[600px]">
<Composer
textareaProps={{ "aria-label": "Message" }}
value={value}
onValueChange={setValue}
onSubmit={send}
Expand Down
4 changes: 4 additions & 0 deletions src/components/ui/composer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ function Composer({
onStop,
running = false,
placeholder,
textareaProps,
leading,
tags,
above,
Expand All @@ -48,6 +49,8 @@ function Composer({
onStop?: () => void
running?: boolean
placeholder?: string
/** Names and describes the input; other HTML attributes belong to the wrapper. */
textareaProps?: Pick<React.ComponentProps<"textarea">, "id" | "aria-label" | "aria-labelledby" | "aria-describedby">
leading?: React.ReactNode
tags?: React.ReactNode
/** Stands above the line of text: pictures going with the message. */
Expand Down Expand Up @@ -115,6 +118,7 @@ function Composer({
mark is never left on a line of its own. */}
<div className={cn("flex min-w-48 flex-1 items-end gap-1", Boolean(tags) && "ml-1.5", !leading && !tags && "pl-1.5")}>
<textarea
{...textareaProps}
ref={textarea}
rows={1}
value={value}
Expand Down
1 change: 1 addition & 0 deletions src/examples/composer-demo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export default function ComposerDemo() {
return (
<div className="w-full max-w-lg">
<Composer
textareaProps={{ "aria-label": "Message" }}
value={text}
onValueChange={(value) => {
setText(value)
Expand Down
1 change: 1 addition & 0 deletions src/examples/composer-running.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export default function ComposerRunning() {
const [text, setText] = React.useState("")
return (
<Composer
textareaProps={{ "aria-label": "Next message" }}
className="w-full max-w-lg"
value={text}
onValueChange={setText}
Expand Down
Loading