> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/vercel/chat/llms.txt
> Use this file to discover all available pages before exploring further.

# Cards and UI Components

> Build rich interactive cards with JSX or function API that work across Slack, Teams, and Google Chat

# Cards and UI Components

The Chat SDK provides a unified API for creating rich cards that automatically convert to platform-specific formats:

* **Slack**: Block Kit
* **Microsoft Teams**: Adaptive Cards
* **Google Chat**: Card v2

You can use either JSX syntax or function calls to build cards.

## JSX Syntax

To use JSX, configure your `tsconfig.json`:

```json tsconfig.json theme={null}
{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "chat"
  }
}
```

Then create cards with JSX:

```tsx theme={null}
/** @jsxImportSource chat */
import { Card, Text, Actions, Button } from "chat";

await thread.post(
  <Card title="Order #1234">
    <Text>Total: $50.00</Text>
    <Actions>
      <Button id="approve" style="primary">Approve</Button>
      <Button id="reject" style="danger">Reject</Button>
    </Actions>
  </Card>
);
```

## Function API

Prefer function calls? Same result:

```typescript theme={null}
import { Card, Text, Actions, Button } from "chat";

await thread.post(
  Card({
    title: "Order #1234",
    children: [
      Text("Total: $50.00"),
      Actions([
        Button({ id: "approve", label: "Approve", style: "primary" }),
        Button({ id: "reject", label: "Reject", style: "danger" }),
      ]),
    ],
  })
);
```

## Available Components

### Card

The root container for all card content.

```typescript theme={null}
interface CardElement {
  type: "card";
  title?: string;
  subtitle?: string;
  imageUrl?: string;
  children: CardChild[];
}
```

**Example:**

```tsx theme={null}
<Card 
  title="Welcome" 
  subtitle="Getting started"
  imageUrl="https://example.com/banner.png"
>
  <Text>Hello world</Text>
</Card>
```

### Text

Display text content with optional styling.

```typescript theme={null}
interface TextElement {
  type: "text";
  content: string;
  style?: "plain" | "bold" | "muted";
}
```

**Example:**

```tsx theme={null}
<Text style="bold">Important message</Text>
<Text style="muted">Secondary info</Text>
```

<Note>
  Use `CardText` instead of `Text` if you need to avoid conflicts with the global DOM `Text` constructor.
</Note>

### Image

Embed images in your cards.

```typescript theme={null}
interface ImageElement {
  type: "image";
  url: string;
  alt?: string;
}
```

**Example:**

```tsx theme={null}
<Image 
  url="https://example.com/chart.png" 
  alt="Sales chart"
/>
```

### Divider

A visual separator between sections.

```tsx theme={null}
<Divider />
```

### Section

Group related content together.

```tsx theme={null}
<Section>
  <Text>Grouped content</Text>
  <Image url="..." />
</Section>
```

### Fields

Display key-value pairs in a multi-column layout.

```typescript theme={null}
interface FieldElement {
  type: "field";
  label: string;
  value: string;
}
```

**Example:**

```tsx theme={null}
<Fields>
  <Field label="Status" value="Active" />
  <Field label="Priority" value="High" />
  <Field label="Assignee" value="Alice" />
</Fields>
```

### Table

Display structured data in a table format.

```typescript theme={null}
interface TableElement {
  type: "table";
  headers: string[];
  rows: string[][];
  align?: ("left" | "center" | "right")[];
}
```

**Example:**

```tsx theme={null}
<Table
  headers={["Name", "Age", "Role"]}
  rows={[
    ["Alice", "30", "Engineer"],
    ["Bob", "25", "Designer"],
  ]}
  align={["left", "center", "right"]}
/>
```

### Link

Inline hyperlink element.

```tsx theme={null}
<CardLink url="https://example.com" label="Visit Site" />
```

## Complete Example

Here's a comprehensive card showcasing multiple components:

```tsx theme={null}
/** @jsxImportSource chat */
import { Card, Text, Image, Divider, Fields, Field, Table, Actions, Button, LinkButton } from "chat";

await thread.post(
  <Card 
    title="Project Status Report"
    subtitle="Q1 2024"
    imageUrl="https://example.com/logo.png"
  >
    <Text style="bold">Executive Summary</Text>
    <Text>All milestones on track for Q1 delivery.</Text>
    
    <Divider />
    
    <Fields>
      <Field label="Status" value="On Track" />
      <Field label="Budget" value="$250K" />
      <Field label="Team Size" value="12" />
    </Fields>
    
    <Divider />
    
    <Text style="bold">Milestone Progress</Text>
    <Table
      headers={["Milestone", "Progress", "Due Date"]}
      rows={[
        ["Design", "100%", "Jan 15"],
        ["Development", "75%", "Feb 28"],
        ["Testing", "25%", "Mar 15"],
      ]}
    />
    
    <Actions>
      <Button id="approve" style="primary">Approve</Button>
      <Button id="comment" style="default">Add Comment</Button>
      <LinkButton url="https://project.example.com" label="View Details" />
    </Actions>
  </Card>
);
```

## Fallback Text

Cards automatically generate plain text fallbacks for platforms or clients that can't render rich cards:

```typescript theme={null}
import { cardToFallbackText } from "chat";

const fallback = cardToFallbackText(myCard);
// Returns markdown-formatted plain text
```

## React Integration

If you're using React components, convert them to card elements:

```typescript theme={null}
import { fromReactElement } from "chat";
import React from "react";

const reactElement = (
  <Card title="Hello">
    <Text>World</Text>
  </Card>
);

const cardElement = fromReactElement(reactElement);
await thread.post(cardElement);
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Actions" icon="hand-pointer" href="/actions">
    Add interactive buttons and handle clicks
  </Card>

  <Card title="Modals" icon="window-restore" href="/modals">
    Create forms and dialog workflows
  </Card>
</CardGroup>
