Masheev Chat UI Components
A shadcn/ui component registry with pre-built chat UI pieces. Install them into your project via the CLI and customise freely — the source code lives in your codebase.
Registry URL: https://sdk.masheev.com
Installation
1. Add the registry to your components.json
{
"registries": {
"@masheev": "https://sdk.masheev.com/{name}.json"
}
}
2. Install the full widget (pulls all 6 components)
npx shadcn add @masheev/chat-widget
Or install individual pieces:
npx shadcn add @masheev/chat-provider
npx shadcn add @masheev/chat-messages
npx shadcn add @masheev/chat-input
npx shadcn add @masheev/chat-bubble
npx shadcn add @masheev/chat-header
3. Install the peer dependency
pnpm add @masheev/embed-sdk
Quick Start
import { ChatWidget } from "@/components/chat-widget";
function App() {
return (
<ChatWidget
inboxId="your-inbox-id"
turnstileSiteKey="your-site-key"
title="Support"
color="#635BFF"
placeholder="Ask anything..."
/>
);
}
Components
<ChatWidget>
Complete floating chat widget. Composes all other components into a ready-to-use widget.
| Prop | Type | Default | Description |
|---|---|---|---|
inboxId | string | — | Required. Inbox to connect to. |
turnstileSiteKey | string | — | Cloudflare Turnstile key for bot protection. |
apiBase | string | "https://api.masheev.com" | API base URL. |
title | string | "Chat" | Header title. |
color | string | "#635BFF" | Primary colour for bubble and header. |
placeholder | string | — | Input placeholder text. |
Layout: Fixed position overlay, bottom-right corner. Panel is 380 px wide with a max height of min(580px, calc(100vh - 160px)). Smooth open/close animation with scale and opacity transitions.
<ChatProvider>
Context wrapper powered by MasheevProvider from the headless Chat SDK. All other components must be rendered inside it.
| Prop | Type | Default | Description |
|---|---|---|---|
inboxId | string | — | Required. |
turnstileSiteKey | string | — | Turnstile site key. |
apiBase | string | "https://api.masheev.com" | API base URL. |
customerInfo | { name?, email?, phone? } | — | Pre-fill customer identity. |
children | ReactNode | — | Required. |
<ChatMessages>
Scrollable message list. Renders user messages on the right and AI messages on the left. Automatically scrolls to the latest message. Shows a pulsing animation while the AI is responding.
No props — reads from context via useMasheev().
<ChatInput>
Text input with a send button. Sends on Enter (Shift + Enter for newline). Disabled while the AI is responding.
| Prop | Type | Default | Description |
|---|---|---|---|
placeholder | string | "Message..." | Input placeholder. |
<ChatBubble>
Floating toggle button. Renders a message icon when closed and an X icon when open with a smooth rotation animation.
| Prop | Type | Default | Description |
|---|---|---|---|
color | string | "#635BFF" | Bubble background colour. |
className | string | — | Additional CSS classes. |
<ChatHeader>
Panel header with a title and close button.
| Prop | Type | Default | Description |
|---|---|---|---|
title | string | "Chat" | Header text. |
color | string | "#635BFF" | Header background colour. |
Custom Composition
The components are designed to be mixed and matched. ChatWidget is a convenience wrapper — you can assemble your own layout:
import { ChatProvider } from "@/components/chat-provider";
import { ChatMessages } from "@/components/chat-messages";
import { ChatInput } from "@/components/chat-input";
import { ChatHeader } from "@/components/chat-header";
import { ChatBubble } from "@/components/chat-bubble";
import { useMasheev } from "@masheev/embed-sdk/headless";
function MyChat() {
const { isOpen } = useMasheev();
return (
<>
{isOpen && (
<div className="fixed bottom-24 right-6 w-[380px] rounded-2xl border shadow-2xl overflow-hidden bg-background">
<ChatHeader title="Help" color="#0ea5e9" />
<ChatMessages />
<ChatInput placeholder="Type here..." />
</div>
)}
<ChatBubble color="#0ea5e9" />
</>
);
}
export function App() {
return (
<ChatProvider inboxId="inbox_abc" turnstileSiteKey="key_xyz">
<MyChat />
</ChatProvider>
);
}
Component Hierarchy
ChatWidget
├── ChatProvider <- context (MasheevProvider)
│ └── ChatWidgetInner
│ ├── Panel
│ │ ├── ChatHeader
│ │ ├── ChatMessages
│ │ └── ChatInput
│ └── ChatBubble
Dependencies
Every component requires:
@masheev/embed-sdk— headless SDK (context + hooks)lucide-react— icons (MessageCircle, X, ArrowUp)
Components use Tailwind CSS classes and expect shadcn/ui theme variables (--background, --foreground, --primary, --muted, etc.).
Styling
All components use Tailwind CSS. Dynamic colours (bubble, header) are applied via inline style so they work without extending your Tailwind config.
Key classes you might want to customise:
| Element | Default classes |
|---|---|
| Panel container | w-[380px] rounded-2xl shadow-2xl border bg-background |
| User message | bg-primary text-primary-foreground rounded-2xl rounded-br-sm |
| AI message | bg-muted rounded-2xl rounded-bl-sm |
| Message max width | max-w-[80%] |
| Input field | bg-transparent text-sm outline-none |
| Send button | w-8 h-8 rounded-full bg-primary text-primary-foreground |
Since the code lives in your project you can edit any of these directly.
Deployment (maintainers)
The registry is served by the existing Cloudflare static-assets Worker at sdk.masheev.com.
pnpm ship deploy sdk-registry --receipt=.release/local-ci/RUN/manifest.json --execute # from repository root
The r/ directory contains the JSON files that the shadcn CLI fetches at install time.