> ## Documentation Index
> Fetch the complete documentation index at: https://anvil.servicetitan.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Guidance Card - Web

> Guidance cards surface recommendations or instructional content.

> [!NOTE]
>
> For development, import `GuidanceCard` from
> `@servicetitan/anvil2-ai-kit`. For design, find it in the
> [AI Kit Web Component Library file](https://www.figma.com/design/QEIsArLktLeJAaFvcpw3PO/AI-Kit-Web-Component-Library).

ai-kit-guidance-card

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-guidance-card?file=src/App.tsx)

```tsx lines theme={null}
import { GuidanceCard } from "@servicetitan/anvil2-ai-kit";

function App() {
  return (
    <div style={{ width: 530 }}>
      <GuidanceCard
        referenceLabel="Estimate #12345"
        changeSections={[
          {
            type: "single",
            changes: [
              {
                id: "labor-hours",
                label: "Labor hours",
                from: "6.5h",
                to: "8.0h",
              },
            ],
          },
        ]}
      />
    </div>
  );
}

export default App;
```

## Options

The Guidance Card supports four lifecycle states, single and table change sections, and an optional linked reference.

### States

ai-kit-guidance-card-states

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-guidance-card-states?file=src/App.tsx)

```tsx lines theme={null}
import { GuidanceCard } from "@servicetitan/anvil2-ai-kit";

const sections = [
  {
    type: "single" as const,
    changes: [
      { id: "labor-hours", label: "Labor hours", from: "6.5h", to: "8.0h" },
    ],
  },
];

function App() {
  return (
    <div
      style={{
        display: "flex",
        flexDirection: "column",
        gap: 16,
        width: 530,
      }}
    >
      {/* Default — interactive review */}
      <GuidanceCard
        referenceLabel="Estimate #12345"
        changeSections={sections}
      />

      {/* Accepted — collapsed summary */}
      <GuidanceCard
        state="accepted"
        referenceLabel="Invoice #1234"
        changeSections={sections}
        appliedChangeIds={["labor-hours"]}
      />

      {/* Rejected — collapsed summary */}
      <GuidanceCard
        state="rejected"
        referenceLabel="Invoice #1234"
        changeSections={sections}
      />

      {/* Skipped — collapsed summary */}
      <GuidanceCard
        state="skipped"
        referenceLabel="Invoice #1234"
        changeSections={sections}
      />
    </div>
  );
}

export default App;
```

`default` shows selectable diffs with Accept, Edit, and Reject actions. `accepted`, `rejected`, and `skipped` collapse the same content into a read-only disclosure that starts closed — expand it to review what was suggested.

### Change Sections

ai-kit-guidance-card-change-sections

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-guidance-card-change-sections?file=src/App.tsx)

```tsx lines theme={null}
import { GuidanceCard } from "@servicetitan/anvil2-ai-kit";

function App() {
  return (
    <div
      style={{
        display: "flex",
        flexDirection: "column",
        gap: 24,
        width: 530,
      }}
    >
      {/* Single section — scalar diff rows */}
      <GuidanceCard
        referenceLabel="Estimate #12345"
        changeSections={[
          {
            type: "single",
            changes: [
              {
                id: "labor-hours",
                label: "Labor hours",
                from: "6.5h",
                to: "8.0h",
              },
              {
                id: "labor-rate",
                label: "Labor rate",
                from: "$95/hr",
                to: "$110/hr",
              },
            ],
          },
        ]}
      />

      {/* Table section — labeled line-item table */}
      <GuidanceCard
        referenceLabel="Estimate #12345"
        changeSections={[
          {
            type: "table",
            label: "Line items",
            changeTables: [
              {
                label: "New",
                columns: [
                  { key: "name", header: "Name", minWidth: 160 },
                  {
                    key: "description",
                    header: "Description",
                    minWidth: 220,
                  },
                ],
                data: [
                  {
                    id: "condensate-drain",
                    name: { type: "addition", value: "Condensate Drain" },
                    description: {
                      type: "addition",
                      value: "Quarterly Maintenance",
                    },
                  },
                ],
              },
            ],
          },
        ]}
      />
    </div>
  );
}

export default App;
```

A change section is either `single` — one or more scalar diff rows — or `table` — one or more labeled line-item tables. Combine both types, in any order, within `changeSections` to build a mixed review.

### Reference Link

ai-kit-guidance-card-reference-link

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-guidance-card-reference-link?file=src/App.tsx)

```tsx lines theme={null}
import { GuidanceCard } from "@servicetitan/anvil2-ai-kit";

const sections = [
  {
    type: "single" as const,
    changes: [
      { id: "labor-hours", label: "Labor hours", from: "6.5h", to: "8.0h" },
    ],
  },
];

function App() {
  return (
    <div
      style={{
        display: "flex",
        flexDirection: "column",
        gap: 16,
        width: 530,
      }}
    >
      {/* Plain text reference */}
      <GuidanceCard
        referenceLabel="Estimate #12345"
        changeSections={sections}
      />

      {/* Linked reference — opens in a new tab */}
      <GuidanceCard
        referenceLabel="Estimate #12345"
        referenceHref="https://example.com/estimates/12345"
        changeSections={sections}
      />
    </div>
  );
}

export default App;
```

`referenceHref` turns the reference label into a link that opens the related estimate or invoice in a new tab. Omit it to render the label as plain text.

## Behavior

In the default state, every change starts selected; the card tracks its own selection from there and disables its footer actions once everything is deselected.

### Selection

ai-kit-guidance-card-selection

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-guidance-card-selection?file=src/App.tsx)

```tsx lines theme={null}
import { GuidanceCard } from "@servicetitan/anvil2-ai-kit";

function App() {
  return (
    <div
      style={{
        display: "flex",
        flexDirection: "column",
        gap: 24,
        width: 530,
      }}
    >
      {/* Multiple changes — each row gets its own checkbox */}
      <GuidanceCard
        referenceLabel="Estimate #12345"
        changeSections={[
          {
            type: "single",
            changes: [
              {
                id: "labor-hours",
                label: "Labor hours",
                from: "6.5h",
                to: "8.0h",
              },
              {
                id: "labor-rate",
                label: "Labor rate",
                from: "$95/hr",
                to: "$110/hr",
              },
            ],
          },
        ]}
      />

      {/* One change — no checkbox; Accept applies to the sole item */}
      <GuidanceCard
        referenceLabel="Estimate #12345"
        changeSections={[
          {
            type: "single",
            changes: [
              {
                id: "labor-hours",
                label: "Labor hours",
                from: "6.5h",
                to: "8.0h",
              },
            ],
          },
        ]}
      />
    </div>
  );
}

export default App;
```

When a section has more than one selectable change, each row starts checked and gets its own checkbox — uncheck a row to exclude it before accepting. A lone change omits the checkbox entirely; Accept always applies to it.

### Actions

ai-kit-guidance-card-actions

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-guidance-card-actions?file=src/App.tsx)

```tsx lines theme={null}
import { GuidanceCard } from "@servicetitan/anvil2-ai-kit";

const changes = [
  { id: "labor-hours", label: "Labor hours", from: "6.5h", to: "8.0h" },
  { id: "labor-rate", label: "Labor rate", from: "$95/hr", to: "$110/hr" },
];
const sections = [{ type: "single" as const, changes }];

function App() {
  return (
    <div
      style={{
        display: "flex",
        flexDirection: "column",
        gap: 24,
        width: 530,
      }}
    >
      {/* Default — every change starts selected; Accept and Edit are enabled */}
      <GuidanceCard
        referenceLabel="Estimate #12345"
        changeSections={sections}
      />

      {/* Everything deselected — Accept and Edit become disabled */}
      <GuidanceCard
        referenceLabel="Estimate #12345"
        changeSections={sections}
      />
    </div>
  );
}

export default App;
```

Accept and Edit are enabled by default — every change starts selected — and disable only once every change is deselected. Reject is always available and needs no selection. Accept and Edit each receive the ids of the currently selected changes and table rows.

## Usage Guidelines

### When to Use

Use the Guidance Card when:

* **Reviewing changes the agent proposes** – The agent suggests changes to a record, such as an estimate or invoice, and the user accepts, edits, or rejects them.
* **Accepting only some changes** – A section holds several changes. Each row gets a checkbox so the user can exclude a change before accepting.
* **Reviewing line-item changes** – Proposed changes affect rows in a list of items. Use a table change section, alone or combined with single change sections.
* **Recording the outcome of a review** – After the user acts, show the accepted, rejected, or skipped state as a read-only summary the user can expand.

### When not to use

Avoid using the Guidance Card for:

* **Showing a change without review actions** – Use the [Diff Value](https://anvil.servicetitan.com/docs/components/diff-value/web.md) instead.
* **Offering follow-up prompts after an agent response** – Use the [Suggestion](https://anvil.servicetitan.com/docs/components/suggestion/web.md) instead.

## Keyboard Interaction

Users can navigate, select, and act on the Guidance Card using standard keyboard controls.

| Key | Description |
| - | - |
| Tab | Moves focus among checkboxes, the reference link, and footer actions |
| Space | Toggles the focused checkbox |
| Enter / Space | Activates the focused reference link or footer action |

## Code

**Implementation**

ai-kit-guidance-card

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-guidance-card?file=src/App.tsx)

```tsx lines expandable theme={null}
import { GuidanceCard } from "@servicetitan/anvil2-ai-kit";

function App() {
  return (
    <div style={{ width: 530 }}>
      <GuidanceCard
        referenceLabel="Estimate #12345"
        changeSections={[
          {
            type: "single",
            changes: [
              {
                id: "labor-hours",
                label: "Labor hours",
                from: "6.5h",
                to: "8.0h",
              },
            ],
          },
        ]}
      />
    </div>
  );
}

export default App;
```

## Common Examples

To use the `GuidanceCard`, pass a `referenceLabel` and ordered `changeSections`. Wire `onApply`, `onEdit`, and `onDismiss` to handle Accept, Edit, and Reject.

```tsx theme={null}
import { GuidanceCard } from "@servicetitan/anvil2-ai-kit";

function ExampleComponent() {
  return (
    <GuidanceCard
      referenceLabel="Estimate #12345"
      changeSections={[
        {
          type: "single",
          changes: [
            {
              id: "labor-hours",
              label: "Labor hours",
              from: "6.5h",
              to: "8.0h",
            },
          ],
        },
      ]}
      onApply={(ids) => apply(ids)}
      onEdit={(ids) => edit(ids)}
      onDismiss={() => reject()}
    />
  );
}
```

### States

`state` is `"default"`, `"accepted"`, `"rejected"`, or `"skipped"`. Non-default states collapse the body unless you set `defaultExpanded`. Accepted state can filter visible rows through `appliedChangeIds`.

ai-kit-guidance-card-states

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-guidance-card-states?file=src/App.tsx)

```tsx lines expandable theme={null}
import { GuidanceCard } from "@servicetitan/anvil2-ai-kit";

const sections = [
  {
    type: "single" as const,
    changes: [
      { id: "labor-hours", label: "Labor hours", from: "6.5h", to: "8.0h" },
    ],
  },
];

function App() {
  return (
    <div
      style={{
        display: "flex",
        flexDirection: "column",
        gap: 16,
        width: 530,
      }}
    >
      {/* Default — interactive review */}
      <GuidanceCard
        referenceLabel="Estimate #12345"
        changeSections={sections}
      />

      {/* Accepted — collapsed summary */}
      <GuidanceCard
        state="accepted"
        referenceLabel="Invoice #1234"
        changeSections={sections}
        appliedChangeIds={["labor-hours"]}
      />

      {/* Rejected — collapsed summary */}
      <GuidanceCard
        state="rejected"
        referenceLabel="Invoice #1234"
        changeSections={sections}
      />

      {/* Skipped — collapsed summary */}
      <GuidanceCard
        state="skipped"
        referenceLabel="Invoice #1234"
        changeSections={sections}
      />
    </div>
  );
}

export default App;
```

### Selection

Multiple single changes each get a checkbox. A single change has no checkbox; Accept applies to that item.

ai-kit-guidance-card-selection

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-guidance-card-selection?file=src/App.tsx)

```tsx lines expandable theme={null}
import { GuidanceCard } from "@servicetitan/anvil2-ai-kit";

function App() {
  return (
    <div
      style={{
        display: "flex",
        flexDirection: "column",
        gap: 24,
        width: 530,
      }}
    >
      {/* Multiple changes — each row gets its own checkbox */}
      <GuidanceCard
        referenceLabel="Estimate #12345"
        changeSections={[
          {
            type: "single",
            changes: [
              {
                id: "labor-hours",
                label: "Labor hours",
                from: "6.5h",
                to: "8.0h",
              },
              {
                id: "labor-rate",
                label: "Labor rate",
                from: "$95/hr",
                to: "$110/hr",
              },
            ],
          },
        ]}
      />

      {/* One change — no checkbox; Accept applies to the sole item */}
      <GuidanceCard
        referenceLabel="Estimate #12345"
        changeSections={[
          {
            type: "single",
            changes: [
              {
                id: "labor-hours",
                label: "Labor hours",
                from: "6.5h",
                to: "8.0h",
              },
            ],
          },
        ]}
      />
    </div>
  );
}

export default App;
```

### Change sections

Use `type: "single"` for scalar diffs and `type: "table"` for labeled line-item tables. Table cells may be a string, `{ type: "text", value }`, `{ type: "diff", from, to }`, or `{ type: "addition", value }`.

ai-kit-guidance-card-change-sections

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-guidance-card-change-sections?file=src/App.tsx)

```tsx lines expandable theme={null}
import { GuidanceCard } from "@servicetitan/anvil2-ai-kit";

function App() {
  return (
    <div
      style={{
        display: "flex",
        flexDirection: "column",
        gap: 24,
        width: 530,
      }}
    >
      {/* Single section — scalar diff rows */}
      <GuidanceCard
        referenceLabel="Estimate #12345"
        changeSections={[
          {
            type: "single",
            changes: [
              {
                id: "labor-hours",
                label: "Labor hours",
                from: "6.5h",
                to: "8.0h",
              },
              {
                id: "labor-rate",
                label: "Labor rate",
                from: "$95/hr",
                to: "$110/hr",
              },
            ],
          },
        ]}
      />

      {/* Table section — labeled line-item table */}
      <GuidanceCard
        referenceLabel="Estimate #12345"
        changeSections={[
          {
            type: "table",
            label: "Line items",
            changeTables: [
              {
                label: "New",
                columns: [
                  { key: "name", header: "Name", minWidth: 160 },
                  {
                    key: "description",
                    header: "Description",
                    minWidth: 220,
                  },
                ],
                data: [
                  {
                    id: "condensate-drain",
                    name: { type: "addition", value: "Condensate Drain" },
                    description: {
                      type: "addition",
                      value: "Quarterly Maintenance",
                    },
                  },
                ],
              },
            ],
          },
        ]}
      />
    </div>
  );
}

export default App;
```

### Reference link

Pass `referenceHref` to make the reference label a link.

ai-kit-guidance-card-reference-link

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-guidance-card-reference-link?file=src/App.tsx)

```tsx lines expandable theme={null}
import { GuidanceCard } from "@servicetitan/anvil2-ai-kit";

const sections = [
  {
    type: "single" as const,
    changes: [
      { id: "labor-hours", label: "Labor hours", from: "6.5h", to: "8.0h" },
    ],
  },
];

function App() {
  return (
    <div
      style={{
        display: "flex",
        flexDirection: "column",
        gap: 16,
        width: 530,
      }}
    >
      {/* Plain text reference */}
      <GuidanceCard
        referenceLabel="Estimate #12345"
        changeSections={sections}
      />

      {/* Linked reference — opens in a new tab */}
      <GuidanceCard
        referenceLabel="Estimate #12345"
        referenceHref="https://example.com/estimates/12345"
        changeSections={sections}
      />
    </div>
  );
}

export default App;
```

### Actions

Accept and Edit receive the currently selected single-change and table-row ids. Reject calls `onDismiss` with no selection.

ai-kit-guidance-card-actions

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-guidance-card-actions?file=src/App.tsx)

```tsx lines expandable theme={null}
import { GuidanceCard } from "@servicetitan/anvil2-ai-kit";

const changes = [
  { id: "labor-hours", label: "Labor hours", from: "6.5h", to: "8.0h" },
  { id: "labor-rate", label: "Labor rate", from: "$95/hr", to: "$110/hr" },
];
const sections = [{ type: "single" as const, changes }];

function App() {
  return (
    <div
      style={{
        display: "flex",
        flexDirection: "column",
        gap: 24,
        width: 530,
      }}
    >
      {/* Default — every change starts selected; Accept and Edit are enabled */}
      <GuidanceCard
        referenceLabel="Estimate #12345"
        changeSections={sections}
      />

      {/* Everything deselected — Accept and Edit become disabled */}
      <GuidanceCard
        referenceLabel="Estimate #12345"
        changeSections={sections}
      />
    </div>
  );
}

export default App;
```

## Internationalization

`GuidanceCard` owns these localized strings:

* `ai-kit.guidanceCard.suggestedChanges`
* `ai-kit.guidanceCard.suggestionsAccepted`
* `ai-kit.guidanceCard.suggestionsRejected`
* `ai-kit.guidanceCard.suggestionsSkipped`
* `ai-kit.guidanceCard.accept`
* `ai-kit.guidanceCard.edit`
* `ai-kit.guidanceCard.reject`
* `ai-kit.guidanceCard.reasonPrefix`

Localize `referenceLabel`, change labels, reasons, and table headers before passing them. Mount `AiKitIntlProvider` inside `CartoTheme` to switch the built-in strings.

## React Accessibility

* Title text reflects the current `state`.
* Multiple changes expose selectable rows. A single change applies without a checkbox.
* Table groups use the kit table selection semantics, including localized select-all and select-row labels.

**GuidanceCard Props**

```tsx theme={null}
<GuidanceCard
  referenceLabel="Estimate #12345"
  changeSections={sections}
  onApply={apply}
  onEdit={edit}
  onDismiss={reject}
/>
```

## `GuidanceCard` Props

The `GuidanceCard` accepts the following props.

**changeSections** `GuidanceChangeSection[]` *required*

Ordered body sections of single changes or table groups.

**referenceLabel** `string` *required*

Reference shown under the title, such as `"Estimate #12345"`.

**appliedChangeIds** `string[]`

Accepted state: ids of applied single changes and table rows. Filters
visible content.

**className** `string`

Class merged onto the root element.

**defaultExpanded** `boolean` (default: false)

Whether a non-default state starts expanded.

**onApply** `(acceptedChangeIds: string[]) =\> void`

Called when Accept is pressed with the current selection.

**onDismiss** `() =\> void`

Called when Reject is pressed.

**onEdit** `(acceptedChangeIds: string[]) =\> void`

Called when Edit is pressed with the current selection.

**referenceHref** `string`

Optional href for the reference label.

**state** `"default" | "accepted" | "rejected" | "skipped"` (default: default)

Card lifecycle state.

**GuidanceChange**

```tsx theme={null}
const change: GuidanceChange = {
  id: "labor-hours",
  label: "Labor hours",
  from: "6.5h",
  to: "8.0h",
  reason: "Job ran longer than estimated.",
};
```

## `GuidanceChange`

**id** `string` *required*

Stable identity used for selection and accepted-state filtering.

**label** `string` *required*

Eyebrow label for the change.

**from** `string | null`

Previous value. Omit both `from` and `to` to hide the diff. Explicit
`null` still shows empty or removed.

**reason** `string`

Supporting copy shown in the reason callout.

**to** `string | null`

Proposed value.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.