Try typing @ or /
'use client';
import { useState } from 'react';
import { PromptBar } from '@brand-studio/ui';
import type { PromptSubmission } from '@brand-studio/ui';
export default function PromptBarDemo() {
const [last, setLast] = useState<PromptSubmission>();
return (
<div style={{ width: '100%', maxWidth: 600, display: 'grid', gap: 16, paddingTop: 180 }}>
<PromptBar
sources={[
{ id: 'roasts', label: 'Roast log', hint: 'Sheet' },
{ id: 'notes', label: 'Tasting notes', hint: 'Doc' },
{ id: 'supplier', label: 'Supplier prices', hint: 'Sheet' },
{ id: 'orders', label: 'Open orders', hint: 'Shop' },
]}
commands={[
{ id: 'summarise', label: 'summarise', hint: 'Short summary' },
{ id: 'reorder', label: 'reorder', hint: 'Draft a purchase order' },
{ id: 'email', label: 'email', hint: 'Write to a customer' },
]}
models={[{ value: 'fast', label: 'Fast' }, { value: 'deep', label: 'Deep thinking' }]}
onSubmit={setLast}
/>
<p style={{ margin: 0, minHeight: 24, color: 'var(--bs-muted)', fontSize: 14 }}>
{last ? `${last.command ? `/${last.command} ` : ''}${last.text}${last.sources.length ? ` · sources: ${last.sources.join(', ')}` : ''} · ${last.model}` : 'Try typing @ or /'}
</p>
</div>
);
}Installation
pnpm add @brand-studio/uinpm install @brand-studio/uiyarn add @brand-studio/uibun add @brand-studio/uiInstall the peer dependencies
npm install react react-domImport the stylesheet once
import '@brand-studio/ui/styles.css';Wrap your app in a brand theme
import { BrandTheme, PromptBar } from '@brand-studio/ui'; import brand from './brand.json'; <BrandTheme palette={brand.tokens} mode="system"> {/* your app */} </BrandTheme>
Usage
import { PromptBar } from '@brand-studio/ui';<PromptBar
sources={[{ id: 'roasts', label: 'Roast log', hint: 'Sheet' }]}
commands={[{ id: 'summarise', label: 'summarise' }]}
models={[{ value: 'fast', label: 'Fast' }, { value: 'deep', label: 'Deep thinking' }]}
onSubmit={({ text, sources, command, model }) => ask(text, { sources, command, model })}
/>Type @ anywhere to add a source, or / at the very start for a command. A list opens above the text and narrows as you type. Arrow keys move, Enter or Tab picks, and Escape closes the list. Picks become chips above the text; Backspace in an empty box removes the last one. On send, a band of light crosses the bar once.
Leave room above the bar for the list.
Accessibility
- The text box points at the open list and its highlighted option, so screen readers follow the arrow keys without leaving the text.
- A status line announces how many sources or commands match, and a description tells people that @ and / exist.
- Each chip has a labelled remove button. The model menu is a labelled menu button.
API Reference
| Prop | Type | Default |
|---|---|---|
sources? | PromptOption[] | – |
commands? | PromptOption[] | – |
models? | PromptModel[] | – |
model? | string | – |
onModelChange? | ((value: string) => void) | – |
onSubmit? | ((prompt: PromptSubmission) => void) | – |
onStop? | (() => void) | – |
busy? | boolean | false |
label? | string | 'Prompt' |
placeholder? | string | 'Ask anything. @ adds a source, / runs a command' |
start? | React.ReactNode | – |
className? | string | '' |