@brique-studio/chatbox
v0.2.0
Published
TypeScript UI library of embeddable AI chatbot boxes, pixel-perfect to the official "Apps in ChatGPT" design system.
Maintainers
Readme
@brique-studio/chatbox
A React + TypeScript library of AI chatboxes, one package per
provider: @brique-studio/chatbox/chatgpt (the official
"Apps in ChatGPT" design system, extracted pixel by pixel from the
OpenAI Figma) and @brique-studio/chatbox/gemini (design sampled live
from gemini.google.com). Each package is complete: light/dark theme,
chatbox, composer, messages, animations, scripted scenarios and a
live API connection (streaming + rich boxes).
- 🤖 One package per AI:
import { … } from "@brique-studio/chatbox/chatgpt". - 🧱 Lego-style: every design-system component is an exported component; everything composes.
- 🌍 i18n built in: built-in locales + a clean strings file to add your own.
- 🌗 Light / Dark via
data-bqc-theme/data-bqg-theme(light,dark,auto). - 🪶 Zero runtime dependencies (peer:
react >= 18).
📚 Documentation
The full documentation lives in docs/:
getting started ·
multi-provider architecture ·
internationalization ·
theme & tokens ·
primitives ·
boxes (card, lists,
entity cards, carousel) ·
chatbox (container, composer,
messages, suggestions,
scenarios, ChatGPT connection) ·
Gemini package ·
design fidelity.
The rest of this README is a quick overview.
Installation
npm install @brique-studio/chatbox// Once in your app:
import "@brique-studio/chatbox/chatgpt/styles.css";
// then:
import { ChatGPTChatbox } from "@brique-studio/chatbox/chatgpt";Theme
Apply the theme on a container (or <html>):
<div data-bqc-theme="dark">…</div>
<!-- or "light" (default) / "auto" (follows the OS) -->The ChatGPT chatbox
import {
AssistantMessage, Chatbox, ChatMessages, Composer,
MessageActions, Suggestion, SuggestionGroup, UserMessage,
} from "@brique-studio/chatbox/chatgpt";
<Chatbox>
<ChatMessages>
<UserMessage>Hey, ChatGPT. How far away is the sun?</UserMessage>
<AssistantMessage
actions={<MessageActions onCopy={copy} onLike={like} onDislike={dislike} />}
>
The Sun is about 150 million kilometers away…
</AssistantMessage>
<AssistantMessage loading />
</ChatMessages>
<SuggestionGroup>
<Suggestion label="Brainstorm" sublabel="meal ideas" onClick={…} />
</SuggestionGroup>
<Composer
onSend={(text) => …}
streaming={isStreaming}
onStop={stop}
onVoice={startVoice} // voice button when the field is empty
onAttach={openPicker} // "+" action on the left
/>
</Chatbox>Sizing
The chatbox takes any size and its content adapts to its own width (container queries), not the viewport's:
<Chatbox width={360} height={480} /> // compact widget
<Chatbox width="100%" height="70vh" maxWidth="none" /> // full pagewidth/height/maxWidth: number (px) or any CSS value; by default the box fills its container (max 768px).scale: scales all inner elements (font sizes, paddings, icons, radii). A fixed factor (scale={0.85}) or"auto"— the box then follows its real width relative to the 768px design reference, clamped byscaleRange(default[0.75, 1]).- Box ≤ 480px: wider bubbles, scrolling suggestion row, mobile-style attachments; ≤ 360px: full-width bubbles, compact composer.
Scripted scenarios
Play a conversation on its own in front of the visitor (landing page, product demo): the question types itself into the composer, sends, the assistant thinks, then streams its reply.
import { ScenarioChatbox, type ScenarioStep } from "@brique-studio/chatbox/chatgpt";
const steps: ScenarioStep[] = [
{ role: "user", text: "What can your assistant do?" },
{ role: "assistant", text: "I can answer your questions…", thinking: 1400 },
{ role: "user", text: "Show me an example.", delay: 1200 },
{ role: "assistant", text: "Sure! Send me a PDF…" },
];
<ScenarioChatbox steps={steps} loop loopDelay={4000} showActions scale="auto" />- Steps:
delay(before the step),thinking(pulsing-dot duration),stream: falsefor instant display. - Structured replies: an assistant step accepts
content— any of the library boxes (Carousel, Card, EntityCard…) revealed after the text; a user step acceptsattachment(e.g.AttachmentChip). - Options:
autoStart,loop/loopDelay,typingCps,streamCps,respectReducedMotion(on by default). - Need custom layouts or controls? The engine is a headless hook:
const { messages, composerText, streaming, status,
play, pause, restart, skipToEnd } = useChatScenario(steps, { loop: true });Live ChatGPT connection
import { ChatGPTChatbox, createOpenAITransport } from "@brique-studio/chatbox/chatgpt";
const transport = createOpenAITransport({
baseUrl: "/api/openai", // your backend proxy (recommended)
model: "gpt-4o-mini",
});
<ChatGPTChatbox
transport={transport}
systemPrompt="You are the Pizzazz assistant."
suggestions={[{ label: "Find me", sublabel: "a pizzeria" }]}
scale="auto"
/>Replies stream in, and the model can render the library boxes
(carousel, entity card, card) through built-in display tools —
see the ChatGPT connection guide.
The Gemini equivalent (GeminiLiveChatbox, createGeminiTransport)
is documented in the Gemini package guide.
The boxes
Card (+ header, image, footers, app attribution), ListGroup /
ListRow (media, selection, skeleton), EntityCard (simple, media,
detailed with bento media), Carousel (drag-to-scroll with mouse
support) — all pixel-faithful to the "Apps in ChatGPT" Figma. See
the boxes documentation.
Internationalization
Built-in strings ship in English and French; add languages or tweak phrases through one clean file — see i18n:
import { ChatboxI18nProvider } from "@brique-studio/chatbox/chatgpt";
<ChatboxI18nProvider locale="fr">
<ChatGPTChatbox … />
</ChatboxI18nProvider>Development
npm run dev # Vite demo (all boxes, light/dark, scenarios, live)
npm run typecheck # tsc --noEmit
npm test # vitest (38 tests)
npm run build # tsup → dist/ (ESM + CJS + d.ts + styles.css)Fidelity notes
- All values (colors, spacing, radii, type, shadows) come from the official design sources: the "Apps in ChatGPT" Figma variables and components, and live DOM sampling of gemini.google.com.
- SF Pro and Google Sans are not redistributable; system/Roboto stacks are used — identical rendering on their home platforms, clean equivalents elsewhere.
- Icons are redrawn as SVG (1.5px rounded strokes) close to each design system's icon style.
