# @quaylabs/genui

React runtime for structured, streaming AI UIs. Renders OpenAI-compatible streaming responses with ShadCN UI and Tremor charts.

## Installation

```bash
pnpm add @quaylabs/genui
```

## Usage

### Static Response

```tsx
import GodComponent from '@quaylabs/genui';

const response = {
  text: "Here's the sales data:",
  components: [
    {
      type: 'table',
      title: 'Q1 Sales',
      columns: [{ key: 'region', label: 'Region' }, { key: 'sales', label: 'Sales' }],
      rows: [{ region: 'North', sales: 1200 }, { region: 'South', sales: 980 }],
    },
  ],
};

<GodComponent response={response} />
```

### Streaming Response

```tsx
import GodComponent from '@quaylabs/genui';

// With EventSource
const eventSource = new EventSource('/api/chat');
<GodComponent stream={eventSource} />

// With fetch
const response = await fetch('/api/chat', { method: 'POST' });
<GodComponent stream={response} />
```

## Supported Components

### Table

```ts
{
  type: 'table',
  title?: string,
  columns: [{ key: string, label: string, type?: string }],
  rows: Record<string, any>[],
  sortable?: boolean,
  paginated?: boolean,
}
```

### Chart

```ts
{
  type: 'chart',
  chart_type: 'bar' | 'line' | 'pie' | 'doughnut' | 'area',
  title?: string,
  labels: string[],
  datasets: [{ label: string, data: number[], color?: string }],
  show_legend?: boolean,
  show_grid?: boolean,
}
```

### Card

```ts
{
  type: 'card',
  title: string,
  subtitle?: string,
  content?: string,
  image_url?: string,
  actions?: [{ label: string, action: string, variant?: 'primary' | 'secondary' | 'danger' }],
  variant?: 'default' | 'outlined' | 'elevated',
}
```

## Extending with New Components

1. Define schema in `schemas/`:
```ts
export interface MyComponent {
  type: 'my-component';
  // ...fields
}
```

2. Create renderer in `components/`:
```tsx
export function MyComponentRenderer({ component }) {
  return <div>{/* render */}</div>;
}
```

3. Register in `registry/componentRegistry.ts`:
```ts
registerComponent('my-component', MyComponentRenderer);
```

## API Reference

### GodComponent

| Prop | Type | Description |
|------|------|-------------|
| `response` | `GenUIResponse` | Static response object |
| `stream` | `EventSource \| ReadableStream \| Response` | Streaming input |
| `onAction` | `(action: string) => void` | Callback for card actions |
| `onComplete` | `() => void` | Called when streaming completes |
| `onError` | `(error: Error) => void` | Called on error |
| `className` | `string` | Container class |
| `gap` | `'sm' \| 'md' \| 'lg'` | Gap between nodes |

### useGenUI Hook

```ts
const { state, reset, dispatch } = useGenUI({ response, stream, onComplete, onError });
```

## License

MIT
