# Masheev Chat UI Components

A [shadcn/ui](https://ui.shadcn.com) 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`

```json
{
  "registries": {
    "@masheev": "https://sdk.masheev.com/{name}.json"
  }
}
```

### 2. Install the full widget (pulls all 6 components)

```bash
npx shadcn add @masheev/chat-widget
```

Or install individual pieces:

```bash
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

```bash
pnpm add @masheev/embed-sdk
```

## Quick Start

```tsx
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:

```tsx
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`.

```bash
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.
