# rn-adaptive-card URL: /docs/native/docyrus/adaptive-card Render Microsoft Adaptive Cards JSON natively — elements, inputs, actions, charts, and templating. `AdaptiveCard` renders an [Adaptive Cards](https://adaptivecards.io) JSON document with native React Native primitives — no WebView. It is a 1:1 native port of the web `@docyrus/ui` Adaptive Card renderer and supports the same payloads produced by the Docyrus Adaptive Card Designer: every element, input, action, the chart family (including Teams' grouped and stacked bars), templating (`${...}`, `$data`, `$when`), `requires`/`fallback`, and host-config overrides. ## Installation ```bash pnpm dlx @docyrus/cli add @docyrus/rn-adaptive-card ``` **Dependencies:** - [react-native-svg](https://www.npmjs.com/package/react-native-svg) - [@react-native-community/datetimepicker (optional)](https://www.npmjs.com/package/@react-native-community/datetimepicker) `react-native-svg` powers the chart family, the progress ring, and CDN icons. `@react-native-community/datetimepicker` is optional — when absent, `Input.Date` / `Input.Time` fall back to a plain text field. ## Usage ```tsx import { AdaptiveCard } from '@/components/docyrus-native/adaptive-card'; const payload = { type: 'AdaptiveCard', version: '1.5', body: [ { type: 'TextBlock', text: 'Hello **world**', size: 'large', weight: 'bolder', wrap: true }, { type: 'Input.Text', id: 'name', label: 'Name', isRequired: true }, ], actions: [{ type: 'Action.Submit', title: 'Send', style: 'positive' }], }; ); } ``` ### Filtered Input.ChoiceSet (Data.Query) A `style: 'filtered'` ChoiceSet that declares `choices.data` calls `onChoiceQuery` with the dataset + debounced search text; return the matching choices: ```tsx { const rows = await client.get(`/lookup/${dataset}?q=${search}`); return rows.map(r => ({ title: r.label, value: r.id })); }} /> ``` ## API Reference | Prop | Type | Default | Description | |------|------|---------|-------------| | `payload` | `AdaptiveCardPayload` | — | The Adaptive Card JSON document to render. Required. | | `data` | `unknown` | — | Data context for template expansion (`${path}`, `$data`, `$when`, built-in functions). When provided, the payload is expanded against it before rendering. | | `onAction` | `(event: AdaptiveCardActionEvent) => void \| Promise` | — | Fires for every action: submit, execute, openUrl, toggleVisibility, showCard, resetInputs. | | `hostConfig` | `AdaptiveCardHostConfigOverride` | — | Deep-partial overrides for spacing, actions orientation/limits, etc. Merged over `defaultHostConfig`. | | `customElements` | `Record` | — | Custom renderers keyed by element `type`. Takes precedence over the built-ins — use it to override `Media`, `Component`, or any element. | | `onChoiceQuery` | `(request: { dataset, search, inputId }) => Promise` | — | Async resolver for a filtered `Input.ChoiceSet` declaring `choices.data` (`Data.Query`). | | `className` | `string` | — | Extra classes for the card surface. | ## Supported elements | Group | Types | |-------|-------| | Text & media | `TextBlock`, `RichTextBlock`, `Image`, `ImageSet`, `Media` | | Containers | `Container`, `ColumnSet` / `Column`, `FactSet`, `Table`, `ActionSet` | | Inputs | `Input.Text`, `Input.Number`, `Input.Date`, `Input.Time`, `Input.Toggle`, `Input.ChoiceSet`, `Input.Rating` | | Display (1.6) | `Badge`, `CodeBlock`, `CompoundButton`, `Icon`, `ProgressBar`, `ProgressRing`, `Rating` | | Layout (1.6) | `Carousel`, `Accordion`, `TabSet` | | Charts (1.6) | `Chart.VerticalBar`, `Chart.VerticalBar.Grouped`, `Chart.HorizontalBar`, `Chart.HorizontalBar.Stacked`, `Chart.Pie`, `Chart.Donut`, `Chart.Line` (single or multi-series), `Chart.Gauge` | | Extensibility | `Component`, `LoopComponent` (placeholders) | ## Supported actions | Type | Behavior | |------|----------| | `Action.Submit` | Validates inputs, then fires `onAction` with the collected input map merged with `data`. | | `Action.Execute` | Same as submit plus `verb`. | | `Action.OpenUrl` | Opens the URL via `Linking` and fires `onAction`. | | `Action.ShowCard` | Toggles an inline nested card below the action row. | | `Action.ToggleVisibility` | Shows/hides target elements by id. | | `Action.ResetInputs` | Clears the named inputs (or all in scope). | `selectAction` is supported on `Container`, `Column`, `ColumnSet`, `Image`, `Icon`, `TableCell`, `CompoundButton`, and the card root. ## Action dispatch Every action emits a typed event through `onAction` (`AdaptiveCardActionEvent`, a discriminated union on `type`): | Event `type` | Fields | Triggered by | |--------------|--------|--------------| | `'submit'` | `data`, `action`, `card` | `Action.Submit` (after validation passes) | | `'execute'` | `verb`, `data`, `action`, `card` | `Action.Execute` (after validation passes) | | `'openUrl'` | `url`, `action`, `card` | `Action.OpenUrl` (also opens the URL via `Linking`) | | `'toggleVisibility'` | `action`, `card` | `Action.ToggleVisibility` | | `'showCard'` | `isOpen`, `action`, `card` | `Action.ShowCard` (fires on open and close) | | `'resetInputs'` | `action`, `card` | `Action.ResetInputs` | `data` follows the spec's `associatedInputs` contract: `'auto'` (default) collects every **visible** input in scope; `'none'` ships only `action.data`. `${input.}` placeholders inside `action.data` are substituted with the current input values. ## Helpers All exported from `@/components/docyrus-native/adaptive-card`: | Export | Use | |--------|-----| | `useAdaptiveCard(payload, options)` | Headless hook — state, validation, action dispatch. Returns `{ cardProps, controls, state }`. Also installable on its own as [`@docyrus/rn-hooks-use-adaptive-card`](/docs/native/hooks/use-adaptive-card). | | `AdaptiveCardView` | Renders from a `cardProps` produced by the hook. | | `registerElement(type, renderer)` | Register a **global** custom element renderer (vs. the per-instance `customElements` prop). | | `expandTemplate(payload, data)` | Stand-alone templating expander (`${}`, `$data`, `$when`). | | `evaluateExpression(expr, scope)` / `registerExpressionFunction(name, fn)` | Evaluate / extend the expression language. | | `validateInput` / `validateInputs` / `collectInputs` / `buildSubmitData` | Input validation + submit-payload helpers. | | `defaultHostConfig` / `mergeHostConfig` | Host config base + deep-merge. | | `parseAdaptiveCard` / `isAdaptiveCard` / `isSafeBackgroundUrl` | Payload guards. | | `getElementRenderer` / `listElementTypes` / `registerDefaultElements` | Inspect the element registry or re-register the built-ins. | | `useAdaptiveCardContext` / `useAdaptiveCardInput` / `isElementVisible` | Read card state inside a custom element renderer. | | `ElementNode` / `ElementList` / `ActionBar` / `NativeIcon` | Building blocks for custom element renderers. | | `matchesEnum(value, ...accepted)` / `lookupEnum(map, key)` | Case-insensitive enum matching, the same rules Teams uses. | | `formatChartValue(value, format)` / `formatGaugeValue(value, min, max, format)` | Chart value formatting (`short` / `long` / `percentage` / `fraction`). | | `buildColoredData` / `buildGroupedData` / `buildLineData` / `buildStackedBarData` / `pointValue` / `segmentValue` | Normalize the Teams chart data shapes. | ## Native notes - **Charts** render with `react-native-svg`, without the tooltips of the web charting library. Plain vertical and horizontal bars and the stacked horizontal bar are View-based; the grouped vertical bar, pie, donut, line and gauge are SVG. Horizontal bars show a 0 / ½ / max value axis unless `displayMode` is `AbsoluteNoAxis` or `PartToWhole`, and the grouped chart draws a y-axis with gridlines. - **`Table`** gives a column with a numeric `width` a fixed size (`width` × 50 px, same as web) and scrolls horizontally when the columns are wider than the card. - **Text sizes** never go below `text-xs` (12 px): badge `extraSmall` / `small`, citations, chart labels and compound-button badges were normalized, matching web. - **`Media`** has no bundled player: it shows the poster (or an audio chip) and opens the source via `Linking` on tap. **`Component`** / **`LoopComponent`** render lossless placeholders. Register a `customElements` override for inline playback. - **`TextBlock` / `FactSet` markdown** supports the inline subset: bold, italic, strikethrough, inline code, links. Block lists are not formatted. - **Icons** (`Icon`, `Badge.icon`, accordion/tab headers) map Fluent names to Font Awesome glyphs loaded from the Docyrus icon CDN. ## Type Exports | Type | Description | |------|-------------| | `AdaptiveCardPayload` | The card document (`type`, `version`, `body`, `actions`, …). | | `AdaptiveCardProps` | Props for the `AdaptiveCard` component. | | `AdaptiveCardElement` | Union of all supported element shapes. | | `AdaptiveCardAction` / `AdaptiveCardSelectAction` | Action unions. | | `AdaptiveCardActionEvent` | The `onAction` event union. | | `AdaptiveCardHostConfig` / `AdaptiveCardHostConfigOverride` | Host config + deep-partial override. | | `AdaptiveCardInput` / `AdaptiveCardInputValue` | Input element union + value type. | | `ElementRenderer` | Signature for `customElements` entries. | | `AdaptiveCardContextValue` | The context value `AdaptiveCardView` renders from (`cardProps`). | | `AdaptiveCardViewProps` | Props for `AdaptiveCardView` (`cardProps`, `className`). | | `UseAdaptiveCardOptions` / `UseAdaptiveCardReturn` / `AdaptiveCardChoiceQueryRequest` | Hook option, return and choice-query request types. | | `ValidationResult` | `{ isValid, errorMessage? }` per input. | | `AdaptiveCardChart*` | `AdaptiveCardChart` union, `…VerticalBar`, `…VerticalBarGrouped`, `…HorizontalBar`, `…HorizontalBarStacked`, `…StackedBar`, `…StackedBarSegment`, `…Pie`, `…Donut`, `…Line`, `…Gauge`, `…Point`, `…DataPoint`, `…Segment`, `…ColorSet`, `…Color`, `…ValueFormat`, `…DisplayMode`, `…Thickness`. | | `ChartSeries` / `ColoredDatum` / `LineData` | Return shapes of the chart-data helpers. | Every other schema type from `adaptive-card-types.ts` is re-exported from the barrel as well. That includes the enums (`AdaptiveCardSpacing`, `…Color`, `…FontSize`, `…FontWeight`, `…FontType`, alignments, `…ContainerStyle`, `…ImageSize` / `…ImageStyle`, `…ActionStyle` / `…ActionMode`, …), the elements (`AdaptiveCardTextBlock`, `…RichTextBlock`, `…TextRun`, `…Image`, `…Media`, `…Container`, `…ColumnSet`, `…Table*`, `…Badge`, `…Carousel*`, `…Accordion*`, `…TabSet`, …), the inputs (`AdaptiveCardInputText`, `…InputNumber`, `…InputDate`, `…InputTime`, `…InputToggle`, `…InputChoiceSet`, `…InputRating`, `AdaptiveCardChoice`), the actions (`AdaptiveCardActionSubmit`, `…Execute`, `…OpenUrl`, `…ShowCard`, `…ToggleVisibility`, `…ResetInputs`), the events (`AdaptiveCardSubmitEvent`, …) and the host-config parts, so the native barrel matches the web one. ## Related - [`useAdaptiveCard`](/docs/native/hooks/use-adaptive-card): the headless hook that powers the component. - [`useDocyrusAdaptiveCardItemDetail`](/docs/native/hooks/use-docyrus-adaptive-card-item-detail) / [`useDocyrusAdaptiveCardItemList`](/docs/native/hooks/use-docyrus-adaptive-card-item-list): generate cards from a Docyrus field list plus records. - `registerElement(type, renderer)` — register a global custom element renderer. - `expandTemplate(payload, data)` / `evaluateExpression(expr, scope)` — standalone templating helpers.