# useDocyrusAdaptiveCardItemDetail URL: /docs/native/hooks/use-docyrus-adaptive-card-item-detail Generate an Adaptive Card JSON payload from a Docyrus field list + a single record — mapping Docyrus field types onto the Adaptive Cards element vocabulary — and render it with the shared native AdaptiveCard renderer. ## Installation ```bash pnpm dlx @docyrus/cli add @docyrus/rn-hooks-use-docyrus-adaptive-card-item-detail ``` **Dependencies:** - [react](https://react.dev) Installing the hook also installs [rn-adaptive-card](/docs/native/docyrus/adaptive-card) and the pure mapper helpers (`_internal/docyrus-adaptive-card*.ts`). The signature is identical to web `@docyrus/ui`, so the same field list and record produce the same card JSON on both platforms. ## Overview `useDocyrusAdaptiveCardItemDetail` is the bridge between **Docyrus field types** (`field-select`, `field-money`, `field-image`, …) and the **Adaptive Cards** element vocabulary (`TextBlock`, `FactSet`, `Image`, `Badge`, `CodeBlock`, …). You hand it a field list + one record and it **generates an Adaptive Card JSON payload** (`card`) — the primary output. The card is then drawn by the shared [rn-adaptive-card](/docs/native/docyrus/adaptive-card) renderer; the hook also returns a ready-to-render `view` and the full [`useAdaptiveCard`](/docs/native/hooks/use-adaptive-card) runtime (state / controls / `cardProps`) so you can wire actions. It is **backend-agnostic** — no network I/O. Pass any Docyrus-shaped field list (`IField[]`, `DataSourceField[]`, or the loose `DocyrusAdaptiveCardField[]`) and a plain record object. When a [`DocyrusTenantProvider`](/docs/native/hooks/use-docyrus-tenant) is mounted, date / number / currency values are formatted with the tenant's preferences automatically. ## Usage ### Generate + render a detail card ```tsx import { ScrollView } from 'react-native'; import { useDocyrusAdaptiveCardItemDetail } from '@/hooks/docyrus-native/use-docyrus-adaptive-card-item-detail'; export function DealDetail({ fields, record }) { const { view } = useDocyrusAdaptiveCardItemDetail({ fields, record }); return ; } ``` ### Use the generated JSON directly The `card` field is a plain Adaptive Card payload — persist it, post it to Teams, or render it yourself with ``. ```tsx import { AdaptiveCard } from '@/components/docyrus-native/adaptive-card'; import { useDocyrusAdaptiveCardItemDetail } from '@/hooks/docyrus-native/use-docyrus-adaptive-card-item-detail'; const { card } = useDocyrusAdaptiveCardItemDetail({ fields, record }); // `card` === { type: 'AdaptiveCard', version: '1.5', body: [...] } await client.post('/teams/notify', card); return ; ``` ### Pin slots, add actions, react to clicks ```tsx const { view } = useDocyrusAdaptiveCardItemDetail({ fields, record, slots: { titleField: 'name', badgeField: 'status', coverImageField: 'cover', subtitleField: 'description' }, actions: [ { type: 'Action.OpenUrl', title: 'Open record', url: `myapp://records/${record.id}` } ], onAction: (event) => { // Action.OpenUrl also opens the URL via Linking; route in-app links yourself. if (event.type === 'openUrl') router.push(event.url); } }); ``` ## Field-type → Adaptive Card element mapping The card body is assembled from three regions: a header (cover / avatar / title / subtitle / status badge), a `FactSet` of scalar fields, and standalone blocks for rich fields. Slots are auto-detected from field type + slug (see [Slot detection](#slot-detection)); everything else lands in the body. | Docyrus field type | Adaptive Card representation | |--------------------|------------------------------| | `field-text`, `field-email`, `field-url`, `field-phone`, `field-currency`, `field-color`, `field-icon`, `field-formula`, `field-identity` | Header title **or** `FactSet` value (`TextBlock`) | | `field-number`, `field-autonumber`, `field-money`, `field-percent`, `field-duration`, `field-rating` | `FactSet` value — formatted (currency, `%`, `★`, `hh:mm:ss`) | | `field-checkbox`, `field-switch` | `FactSet` value — `Yes`/`No`, `On`/`Off` | | `field-date`, `field-dateTime`, `field-time`, `field-dateRange` | `FactSet` value — tenant-formatted date/time | | `field-select`, `field-radioGroup`, `field-enum`, `field-systemEnum`, `field-status`, `field-approvalStatus` | Header status `Badge` (semantic color) **or** `FactSet` value (option name) | | `field-multiSelect`, `field-tagSelect` | `FactSet` value — comma-joined option names | | `field-userSelect` | `FactSet` value — user display name | | `field-userMultiSelect` | `FactSet` value — joined user names | | `field-relation`, `field-relatedField` | `FactSet` value — related record label | | `field-image`, `field-avatar` | Cover / avatar `Image`, or an `Image` / `ImageSet` body block | | `field-textarea`, `field-markdown`, `field-htmlEditor`, `field-emailEditor`, `field-docEditor` | Wrapped `TextBlock` block (HTML stripped) | | `field-json`, `field-jsonSchema`, `field-jsonata`, `field-handlebars`, `field-code`, `field-codeEditor`, `field-queryBuilder`, `field-dsql` | `CodeBlock` block (language-tagged) | | `field-file` | `FactSet` value — file name | | `field-locationSelect` | `FactSet` value — address label | | `field-taskList`, `field-todo` | `FactSet` value — `done / total` summary | | `field-adaptiveCard`, `field-button`, `field-password`, `field-inlineForm`, `field-schema*`, `field-inlineData`, `field-dynamic`, `field-conversationChannel`, `field-fileStorageFolder`, `field-system*` | Skipped (no meaningful card representation) | Enum / status colors (Tailwind families or hex) are classified to the nearest Adaptive Card badge style: green → `good`, red → `attention`, amber → `warning`, blue/purple → `accent`, otherwise `informative`. ## Slot detection When you don't pin slots, bindings are auto-detected from the field list using the same heuristics as the web data gallery (slug hints first, then type; system audit columns such as `id`, `created_by` and `record_owner` are never picked). Override any slot with a slug, or `null` to disable a detected binding: | Slot | Auto-detected from | |------|--------------------| | `titleField` | slug `name` / `title` / `subject` / `label`, then a text/identity field | | `subtitleField` | slug `description` / `summary` / `subtitle`, then a textarea field | | `coverImageField` | slug `cover` / `image` / `thumbnail` / `banner`, then a `field-image` | | `avatarField` | slug `avatar` / `profile_photo`, then a `field-avatar` | | `badgeField` | slug `status` / `priority` / `stage`, then a status/select field | | `timelineField` | slug `due` / `deadline` / `start`, then a `field-date` (leads the facts) | | `bodyFields` | every remaining non-system field | ## API Reference ### `UseDocyrusAdaptiveCardItemDetailOptions` | Option | Type | Default | Description | |--------|------|---------|-------------| | `fields` | `DocyrusAdaptiveCardField[]` | — | Field metadata (accepts `IField` / `DataSourceField` / `DocyrusFieldLike`). | | `record` | `Record \| null` | — | The record to render. | | `enumOptions` | `Record` | — | Per-field-slug enum options. Falls back to each field's inline `enums`. | | `slots` | `DocyrusAdaptiveCardSlotOverrides` | — | Pin (`string`) or disable (`null`) individual slot bindings. | | `includeFields` | `string[]` | — | Explicit, ordered body field list (replaces auto-detected body). | | `excludeFields` | `string[]` | — | Field slugs to drop from the body. | | `title` | `string` | — | Force the header title text. | | `actions` | `AdaptiveCardAction[]` | — | Card-level actions appended to `payload.actions`. | | `hideEmpty` | `boolean` | `true` | Drop empty fields instead of rendering an em-dash. | | `factLayout` | `'facts' \| 'stacked'` | `'facts'` | Scalar layout — a `FactSet` or stacked label/value blocks. | | `version` | `string` | `'1.5'` | Adaptive Card schema version. | | `formatDate` | `(value) => string` | tenant context | Override the date formatter. | | `formatDateTime` | `(value) => string` | tenant context | Override the datetime formatter. | | `formatNumber` | `(value, opts?: { variant?: 'number' \| 'currency' \| 'percent'; currency?: string; decimalPrecision?: number; thousandSeparator?: string }) => string` | tenant context | Override the number/currency/percent formatter. | | `className` | `string` | — | `className` forwarded to the rendered `view` (``). | | `onAction` | `(event: AdaptiveCardActionEvent) => void \| Promise` | — | Forwarded to `useAdaptiveCard`. | | `hostConfig` | `AdaptiveCardHostConfigOverride` | — | Forwarded to `useAdaptiveCard`. | | `customElements` | `Record` | — | Forwarded to `useAdaptiveCard`. | | `onChoiceQuery` | `(request: AdaptiveCardChoiceQueryRequest) => Promise` | — | Forwarded to `useAdaptiveCard`. | ### `UseDocyrusAdaptiveCardItemDetailReturn` Extends [`UseAdaptiveCardReturn`](/docs/native/hooks/use-adaptive-card) (`state`, `controls`, `cardProps`, `hostConfig`) with: | Field | Type | Description | |-------|------|-------------| | `card` | `AdaptiveCardPayload` | The generated Adaptive Card JSON — the primary output. | | `slots` | `DocyrusAdaptiveCardSlots` | The resolved slot bindings. | | `view` | `ReactNode` | Ready-to-render `` for the generated card. | ## Type Exports | Type | Description | |------|-------------| | `UseDocyrusAdaptiveCardItemDetailOptions` | Hook options. | | `UseDocyrusAdaptiveCardItemDetailReturn` | Hook return. | | `DocyrusAdaptiveCardField` | Minimal field shape (`slug` + `name` + `type`, optional `enums`). | | `DocyrusAdaptiveCardSlots` | Resolved slot bindings. | | `DocyrusAdaptiveCardSlotOverrides` | Slot override map (`string` to pin, `null` to disable). | | `DocyrusAdaptiveCardFactLayout` | `'facts' \| 'stacked'`. | ## See also - [`useDocyrusAdaptiveCardItemList`](/docs/native/hooks/use-docyrus-adaptive-card-item-list) — the same mapping, for a list of records. - [rn-adaptive-card](/docs/native/docyrus/adaptive-card) — the renderer. - [`useAdaptiveCard`](/docs/native/hooks/use-adaptive-card) — the underlying runtime.