UNPKG

chat

Version:

Unified chat abstraction for Slack, Teams, Google Chat, and Discord

269 lines (203 loc) 6.98 kB
--- title: Cards description: Send rich interactive cards with buttons, fields, and images across all platforms. type: guide prerequisites: - /docs/usage related: - /docs/actions - /docs/modals --- Cards let you send structured, interactive messages that render natively on each platform — Block Kit on Slack, Adaptive Cards on Teams, and Google Chat Cards. ## Setup Configure your `tsconfig.json` to use the Chat SDK JSX runtime: ```json title="tsconfig.json" { "compilerOptions": { "jsx": "react-jsx", "jsxImportSource": "chat" } } ``` Or use a per-file pragma: ```tsx title="lib/bot.tsx" /** @jsxImportSource chat */ ``` ## Basic card ```tsx title="lib/bot.tsx" lineNumbers import { Card, CardText, Button, Actions } from "chat"; await thread.post( <Card title="Order #1234"> <CardText>Your order has been received!</CardText> <Actions> <Button id="approve" style="primary">Approve</Button> <Button id="reject" style="danger">Reject</Button> </Actions> </Card> ); ``` ## Components ### Card The top-level container. Accepts `title` and optional `subtitle`. ```tsx title="lib/bot.tsx" lineNumbers <Card title="My Card" subtitle="Optional subtitle"> {/* children */} </Card> ``` ### CardText Renders formatted text. Supports a subset of markdown. ```tsx title="lib/bot.tsx" lineNumbers <CardText>**Bold** and _italic_ text</CardText> <CardText style="bold">Bold section header</CardText> ``` <Callout type="info"> Use `CardText` instead of `Text` when using JSX to avoid conflicts with React's built-in types. </Callout> ### Section Groups related content together. ```tsx title="lib/bot.tsx" lineNumbers <Section> <CardText>Section content here</CardText> </Section> ``` ### Fields Renders key-value pairs in a compact layout. ```tsx title="lib/bot.tsx" lineNumbers <Fields> <Field label="Name" value="John Doe" /> <Field label="Role" value="Developer" /> <Field label="Team" value="Platform" /> </Fields> ``` ### Button An action button that triggers an `onAction` handler. ```tsx title="lib/bot.tsx" lineNumbers <Button id="approve" style="primary">Approve</Button> <Button id="reject" style="danger">Reject</Button> <Button id="details">View Details</Button> ``` The `id` maps to your `onAction` handler. Optional `value` passes extra data: ```tsx title="lib/bot.tsx" <Button id="report" value="bug">Report Bug</Button> ``` Set `actionType="modal"` to indicate the button opens a [modal](/docs/modals). The button still triggers your `onAction` handler, where you call `event.openModal()` — this prop tells adapters like Teams to wire up the button for dialog opening: ```tsx title="lib/bot.tsx" <Button id="open-feedback" actionType="modal">Give Feedback</Button> ``` Optional `callbackUrl` causes the action data to be POSTed to a URL when clicked. See [Callback URLs](/docs/actions#callback-urls) for details. ```tsx title="lib/bot.tsx" <Button callbackUrl={webhook.url} id="approve" style="primary">Approve</Button> ``` ### CardLink Inline hyperlink rendered as text. Unlike `LinkButton` (which must be inside `Actions`), `CardLink` can be placed directly in a card alongside other content. ```tsx title="lib/bot.tsx" <CardLink url="https://example.com/order/1234" label="View order details" /> ``` Or with children as the label: ```tsx title="lib/bot.tsx" <CardLink url="https://example.com/docs">Read the docs</CardLink> ``` <Callout type="info"> `CardLink` renders as a platform-native link: `<url|label>` on Slack, `[label](url)` on Teams/Discord/GitHub/Linear, and `<a href>` on Google Chat. </Callout> ### LinkButton Opens an external URL. No `onAction` handler needed. ```tsx title="lib/bot.tsx" <LinkButton url="https://example.com/order/1234">View Order</LinkButton> ``` ### Actions Container for buttons and interactive elements. ```tsx title="lib/bot.tsx" lineNumbers <Actions> <Button id="approve" style="primary">Approve</Button> <Button id="reject" style="danger">Reject</Button> <LinkButton url="https://example.com">View</LinkButton> </Actions> ``` ### Select Inline dropdown menu. ```tsx title="lib/bot.tsx" lineNumbers <Actions> <Select id="priority" label="Priority" placeholder="Select priority"> <SelectOption label="High" value="high" description="Urgent tasks" /> <SelectOption label="Medium" value="medium" /> <SelectOption label="Low" value="low" /> </Select> </Actions> ``` Selection triggers an `onAction` handler with the `id` as the `actionId` and the selected value. ### RadioSelect Radio button group for mutually exclusive choices. ```tsx title="lib/bot.tsx" lineNumbers <Actions> <RadioSelect id="status" label="Status"> <SelectOption label="Open" value="open" /> <SelectOption label="In Progress" value="in_progress" /> <SelectOption label="Done" value="done" /> </RadioSelect> </Actions> ``` ### Table Structured data display with column headers and rows. Renders as a native table on platforms that support it (Teams, GitHub, Linear) and as padded ASCII text elsewhere. ```tsx title="lib/bot.tsx" lineNumbers <Table headers={["Name", "Age", "Role"]} rows={[ ["Alice", "30", "Engineer"], ["Bob", "25", "Designer"], ]} /> ``` Optional column alignment: ```tsx title="lib/bot.tsx" <Table headers={["Name", "Amount"]} rows={[["Alice", "$100"], ["Bob", "$200"]]} align={["left", "right"]} /> ``` ### Image Embeds an image in the card. ```tsx title="lib/bot.tsx" <Image url="https://example.com/screenshot.png" alt="Screenshot" /> ``` ### Divider A visual separator between sections. ```tsx title="lib/bot.tsx" lineNumbers <CardText>Above the line</CardText> <Divider /> <CardText>Below the line</CardText> ``` ## Full example ```tsx title="lib/bot.tsx" lineNumbers import { Card, CardText, CardLink, Button, LinkButton, Actions, Section, Fields, Field, Divider, Image, Select, SelectOption, RadioSelect, } from "chat"; await thread.post( <Card title="User Profile" subtitle="Account details"> <Image url="https://example.com/avatar.png" alt="User avatar" /> <Fields> <Field label="Name" value="Jane Smith" /> <Field label="Role" value="Engineer" /> <Field label="Team" value="Platform" /> </Fields> <CardLink url="https://example.com/profile/123">View full profile</CardLink> <Divider /> <Section> <CardText>Select an action below to manage this profile.</CardText> </Section> <Actions> <Select id="role" label="Change Role" placeholder="Select role"> <SelectOption label="Engineer" value="engineer" /> <SelectOption label="Manager" value="manager" /> <SelectOption label="Admin" value="admin" /> </Select> <Button id="edit" style="primary">Edit Profile</Button> <Button id="deactivate" style="danger">Deactivate</Button> <LinkButton url="https://example.com/profile/123">View Full Profile</LinkButton> </Actions> </Card> ); ```