Themable React composer for AI chat UIs — text input, file attachments, model + reasoning picker, voice recording, and empty-state prompt suggestions. Built on Tailwind v4.
Status: feature-complete (v0.1.0, unreleased) — full composer surface implemented,
tsupbuild green (ESM + CJS + DTS forindex/primitives/hooks/types+ bundledstyles/theme.css+styles/animations.css), running in pawrrtal via the git submodule underfrontend/lib/react-chat-composer/. First npm publish pending — until then consume from the submodule path or the package'smainbranch directly.
pnpm add @octavian-tocan/react-chat-composer
# peer deps
pnpm add react react-dom clsx tailwind-merge lucide-react \
@octavian-tocan/react-dropdown @radix-ui/react-tooltipRequires Tailwind CSS v4.
import { ChatComposer, CHAT_MODELS_2026 } from '@octavian-tocan/react-chat-composer';
export function MyChat() {
const [text, setText] = useState('');
return (
<ChatComposer
defaultValue=""
onChange={setText}
onSubmit={({ text, attachments }) => sendMessage(text, attachments)}
models={CHAT_MODELS_2026}
selectedModelId={modelId}
onSelectModel={setModelId}
onTranscribeAudio={async (blob, mime) => {
// Plug in your STT provider (Whisper, Deepgram, xAI, etc.)
return await transcribe(blob, mime);
}}
/>
);
}In your global CSS (typically app/globals.css):
@import "tailwindcss";
/* 1. Tell Tailwind to scan the package's compiled output for utility classes. */
@source "../node_modules/@octavian-tocan/react-chat-composer/dist";
/* 2. Bring in the chat-* token defaults (light + dark). */
@import "@octavian-tocan/react-chat-composer/styles/theme.css";
/* 3. Bring in the non-Tailwind keyframes + animation classes. */
@import "@octavian-tocan/react-chat-composer/styles/animations.css";
/* 4. (Optional) Override any chat-* token to theme the composer. */
:root {
--color-chat-accent: #ff6b35;
}<ChatComposer />— the flagship component<ChatPromptSuggestions />— empty-state suggested-prompt listdefineChatModel()+CHAT_MODELS_2026— model-list helpers/primitives—<ComposerActionSelector />,<ProviderLogo />,<VoiceMeter />/hooks—useVoiceRecording()/types— all public types
A comprehensive docs/API.md reference is forthcoming. Until then, types
are the source of truth — every exported component, hook, and helper has
TSDoc.
What ships today:
- Package scaffold (tsup, tsconfig, vitest, eslint, prettier, semantic-release)
- Submodule integration with
OctavianTocan/ai-nexus - Vendored
prompt-input-*from Vercel AI Elements (form, textarea, attachments, context, footer + submit) - Minimal
Button+ RadixTooltipwrapper (shadcn-derived) -
cn,usePersistedState,useTooltipDropdownutilities -
useVoiceRecording— recording lifecycle +onTranscribeAudioswap point (consumer provides STT) -
ChatComposer+ChatComposerView(View/Container split, controlled or uncontrolled text API) -
ChatComposerControls— AttachButton, VoiceMeter, WaveformTimeline, ComposerTooltip, transcript + voice-recognition helpers -
ModelSelectorPopover+ View + bundled<ProviderLogo>with inline SVGs for 8 known providers (anthropic, openai, google, mistral, xai, meta, deepseek, qwen) + per-model override viaChatModelOption.logo -
ChatPromptSuggestions— empty-state suggested-prompt list -
ComposerActionSelector— generic safety-mode-style dropdown primitive, exposed for consumers to build their own permission selectors -
CHAT_MODELS_2026sample preset +defineChatModelhelper -
styles/theme.css(Tailwind v4@themeblock,chat-*tokens, light + dark defaults) +styles/animations.css - Self-provided
TooltipProviderso the composer drops in without consumer setup - Built
dist/verified: ESM + CJS + DTS for every subpath export
Deferred / next:
- Storybook + lost-pixel visual regression
- First npm publish (semantic-release wired; cut the v0.1.0 tag)
-
docs/API.mdwritten reference - Vitest unit coverage targeting 70%+ statements
MIT — see LICENSE. Vendored code from Vercel AI Elements and shadcn/ui — see NOTICE.md.
