Rich card components for cross-platform interactive messages.
Card components render natively on each platform — Block Kit on Slack, Adaptive Cards on Teams, Embeds on Discord, and Google Chat Cards.
import { Card, Text, CardLink, Button, Actions, Section, Fields, Field, Divider, Image, LinkButton, Table } from "chat";All components support both function-call and JSX syntax. Function-call syntax is recommended for better type inference.
Top-level container for a rich message.
Card({
title: "Order #1234",
subtitle: "Pending approval",
children: [Text("Total: $50.00")],
})Text
Text content element. Use CardText instead of Text in JSX to avoid conflicts with React's built-in types.
Text("Hello, world!")
Text("Important", { style: "bold" })
Text("Subtle note", { style: "muted" })Interactive button that triggers an onAction handler.
Button({ id: "approve", label: "Approve", style: "primary" })
Button({ id: "delete", label: "Delete", style: "danger", value: "item-123" })Inline hyperlink rendered as text. Can be placed directly in a card alongside other content, unlike LinkButton which must live inside Actions.
CardLink({ url: "https://example.com", label: "Visit Site" })Button that opens a URL. No onAction handler needed.
LinkButton({ url: "https://example.com", label: "View Docs" })Container for buttons and interactive elements. Required wrapper around Button, LinkButton, Select, and RadioSelect.
Actions([
Button({ id: "approve", label: "Approve", style: "primary" }),
Button({ id: "reject", label: "Reject", style: "danger" }),
LinkButton({ url: "https://example.com", label: "View" }),
])Groups related content together.
Section([
Text("Grouped content"),
Image({ url: "https://example.com/photo.png" }),
])Renders key-value pairs in a compact, multi-column layout.
Fields([
Field({ label: "Name", value: "Jane Smith" }),
Field({ label: "Role", value: "Engineer" }),
])A single key-value pair. Must be used inside Fields.
Embeds an image in the card.
Image({ url: "https://example.com/screenshot.png", alt: "Screenshot" })Structured data display with column headers and rows.
Table({
headers: ["Name", "Age", "Role"],
rows: [
["Alice", "30", "Engineer"],
["Bob", "25", "Designer"],
],
})On platforms with native table support (Teams, GitHub, Linear), tables render as formatted tables. On other platforms (Slack, Google Chat, Discord, Telegram), tables render as padded ASCII text.
A visual separator between sections.
The children array in Card and Section accepts these element types:
| Type | Created by |
|---|---|
TextElement | Text() |
LinkElement | CardLink() |
ImageElement | Image() |
DividerElement | Divider() |
ActionsElement | Actions() |
SectionElement | Section() |
FieldsElement | Fields() |
TableElement | Table() |












