Composer
ngx-prompt-kit original — not part of ibelick/prompt-kit
A chat composer whose text box grows with the draft and then scrolls, with an expand toggle for long drafts, an optional attach button, slots for chips and a model selector, and a send button that becomes stop while a reply streams. The text box is a borderless hlmTextarea and every button an hlmBtn. Put it in whatever frame your layout needs; the examples use a plain bordered box.
Examples
Empty state
A composer centred in an empty chat. Enter sends, Shift+Enter adds a line; the + button opens a file picker.
What can I help with?
<h2>What can I help with?</h2>
<div class="rounded-2xl border bg-background px-3 pt-2 pb-3 max-w-2xl">
<pk-composer
placeholder="Ask anything"
[attachable]="true"
[(value)]="draft"
(submitted)="send($event)"
(filesPicked)="upload($event)"
/>
</div>Busy and stop
While busy, the send button becomes a stop button that emits (stopped). Typing still works, but Enter won't send until the reply is done.
<div class="rounded-2xl border bg-background px-3 pt-2 pb-3">
<pk-composer
[busy]="busy()"
[(value)]="draft"
(submitted)="send($event)"
(stopped)="stop()"
/>
</div>
// e.g. with readChatStream(events$, adapt, handlers, controller.signal)
send(text: string) { this.busy.set(true); … }
stop() { this.controller.abort(); this.busy.set(false); }Long drafts
The text box grows up to maxHeight (here 160px) and then scrolls. Once it overflows, an expand toggle in the corner grows it to 60% of the viewport; sending shrinks it again.
<div class="rounded-2xl border bg-background px-3 pt-2 pb-3">
<pk-composer [maxHeight]="160" [(value)]="draft" />
</div>With a model selector
Project a pk-model-selector into [pkComposerEnd] and anchor its panel to the whole composer via the public element.
<div class="rounded-2xl border bg-background px-3 pt-2 pb-3">
<pk-composer #composer [attachable]="true" [(value)]="draft">
<pk-model-selector
pkComposerEnd
[models]="models"
[anchor]="composer.element"
[(value)]="modelId"
/>
</pk-composer>
</div>Installation
Add the composer component (and the cn() utility) to your project.
ng generate ngx-prompt-kit:composer It is built on spartan/ui, so add these helm components too: button, textarea.
ng g @spartan-ng/cli:ui button textareaComponent API
PkComposer
| Prop | Type | Default | Description |
|---|---|---|---|
| value | string | '' | The draft. Two-way bindable via [(value)], so a draft can survive navigation. |
| placeholder | string | 'Message' | Placeholder of the text box. |
| label | string | 'Message' | Accessible name for the text box (a visually hidden label). |
| busy | boolean | false | A reply is being generated: the send button becomes a stop button and Enter no longer sends. |
| disabled | boolean | false | Disables the text box, the attach button and sending. |
| sendBlocked | boolean | false | Keeps the send button disabled, e.g. while attachments upload. |
| maxHeight | number | 200 | Height in px the text box grows to before it scrolls and the expand toggle appears. |
| attachable | boolean | false | Shows the attach (+) button, which opens a file picker. |
| accept | string | '' | File types the picker offers, as for <input type="file" accept>. |
| describedBy | string | '' | Id(s) for the text box’s aria-describedby, e.g. a hint or error. |
| class | string | '' | Extra classes for the host. |
PkComposer outputs & members
| Prop | Type | Default | Description |
|---|---|---|---|
| submitted | (text: string) => void | — | The trimmed draft, on Enter or the send button. The draft is then cleared and the box shrinks back. |
| stopped | () => void | — | The stop button was pressed while busy. |
| filesPicked | (files: File[]) => void | — | Files picked through the attach button. |
| element | ElementRef<HTMLElement> | — | The composer’s element, e.g. to anchor a model selector’s panel to the whole composer. |
| expanded | WritableSignal<boolean> | — | Whether the text box is grown to 60% of the viewport for long drafts. |
| focus() | void | — | Focuses the text box. Clicks on the composer’s padding do this too. |
PkComposer content projection
| Prop | Type | Default | Description |
|---|---|---|---|
| [pkComposerTop] | element | — | Above the text, e.g. attachment chips or an upload error. |
| [pkComposerStart] | element | — | In the action row, after the attach button. |
| [pkComposerEnd] | element | — | In the action row, before the send button, e.g. a model selector. |