UNPKG

chat

Version:

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

283 lines (232 loc) 5.91 kB
--- title: Cards description: Rich card components for cross-platform interactive messages. type: reference --- Card components render natively on each platform Block Kit on Slack, Adaptive Cards on Teams, Embeds on Discord, and Google Chat Cards. ```typescript 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. ## Card Top-level container for a rich message. ```typescript Card({ title: "Order #1234", subtitle: "Pending approval", children: [Text("Total: $50.00")], }) ``` <TypeTable type={{ title: { description: 'Card title.', type: 'string', }, subtitle: { description: 'Card subtitle.', type: 'string', }, imageUrl: { description: 'Header image URL.', type: 'string', }, children: { description: 'Card content elements.', type: 'CardChild[]', }, }} /> ## Text Text content element. Use `CardText` instead of `Text` in JSX to avoid conflicts with React's built-in types. ```typescript Text("Hello, world!") Text("Important", { style: "bold" }) Text("Subtle note", { style: "muted" }) ``` <TypeTable type={{ content: { description: 'Text content (first argument).', type: 'string', }, 'options.style': { description: 'Text style.', type: '"plain" | "bold" | "muted"', }, }} /> ## Button Interactive button that triggers an `onAction` handler. ```typescript Button({ id: "approve", label: "Approve", style: "primary" }) Button({ id: "delete", label: "Delete", style: "danger", value: "item-123" }) ``` <TypeTable type={{ id: { description: 'Unique action ID for callback routing.', type: 'string', }, label: { description: 'Button label text.', type: 'string', }, style: { description: 'Visual style.', type: '"primary" | "danger" | "default"', }, value: { description: 'Optional payload sent with the action callback.', type: 'string', }, actionType: { description: 'Hints to adapters like Teams that this button will open a modal via event.openModal().', type: '"action" | "modal"', default: '"action"', }, callbackUrl: { description: 'URL to POST action data to when this button is clicked.', type: 'string', }, }} /> ## CardLink Inline hyperlink rendered as text. Can be placed directly in a card alongside other content, unlike `LinkButton` which must live inside `Actions`. ```typescript CardLink({ url: "https://example.com", label: "Visit Site" }) ``` <TypeTable type={{ url: { description: 'URL to link to.', type: 'string', }, label: { description: 'Link label text.', type: 'string', }, }} /> ## LinkButton Button that opens a URL. No `onAction` handler needed. ```typescript LinkButton({ url: "https://example.com", label: "View Docs" }) ``` <TypeTable type={{ url: { description: 'URL to open when clicked.', type: 'string', }, label: { description: 'Button label text.', type: 'string', }, style: { description: 'Visual style.', type: '"primary" | "danger" | "default"', }, }} /> ## Actions Container for buttons and interactive elements. Required wrapper around `Button`, `LinkButton`, `Select`, and `RadioSelect`. ```typescript Actions([ Button({ id: "approve", label: "Approve", style: "primary" }), Button({ id: "reject", label: "Reject", style: "danger" }), LinkButton({ url: "https://example.com", label: "View" }), ]) ``` ## Section Groups related content together. ```typescript Section([ Text("Grouped content"), Image({ url: "https://example.com/photo.png" }), ]) ``` ## Fields Renders key-value pairs in a compact, multi-column layout. ```typescript Fields([ Field({ label: "Name", value: "Jane Smith" }), Field({ label: "Role", value: "Engineer" }), ]) ``` ## Field A single key-value pair. Must be used inside `Fields`. <TypeTable type={{ label: { description: 'Field label.', type: 'string', }, value: { description: 'Field value.', type: 'string', }, }} /> ## Image Embeds an image in the card. ```typescript Image({ url: "https://example.com/screenshot.png", alt: "Screenshot" }) ``` <TypeTable type={{ url: { description: 'Image URL.', type: 'string', }, alt: { description: 'Alt text for accessibility.', type: 'string', }, }} /> ## Table Structured data display with column headers and rows. ```typescript Table({ headers: ["Name", "Age", "Role"], rows: [ ["Alice", "30", "Engineer"], ["Bob", "25", "Designer"], ], }) ``` <TypeTable type={{ headers: { description: 'Column header labels.', type: 'string[]', }, rows: { description: 'Data rows (each row is an array of cell strings).', type: 'string[][]', }, align: { description: 'Column alignment.', type: '"left" | "center" | "right"[]', }, }} /> 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. ## Divider A visual separator between sections. ```typescript Divider() ``` ## CardChild types 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()` |