Agent Options Takeover
Backend-driven option picker that replaces the chat input with a numbered list of suggested responses.
The AgentOptionsTakeover is an immersive picker shown in place of the chat input when the agent provides explicit response options. Users navigate with the arrow keys and submit with Enter, or press Esc to dismiss and write a custom response.
Installation
The component is exported from the @delphi/features package:
import {
AgentOptionsTakeover,
type AgentOptionsTakeoverData,
} from "@delphi/features/experience/agent-options-takeover";
Live Demo
Options variant
Scale variant (5-point Likert)
Scale variant with icons (satisfaction)
Basic Usage
import { useState } from "react";
import {
AgentOptionsTakeover,
type AgentOptionsTakeoverData,
} from "@delphi/features/experience/agent-options-takeover";
const data: AgentOptionsTakeoverData = {
title: "Are you happy with your response?",
options: [
"Yes, this captures my voice well",
"It's close, but the tone is off",
"Rework it — too generic",
],
};
function Example() {
return (
<AgentOptionsTakeover
data={data}
onSelectOption={(option) => console.log("selected", option)}
onDismiss={() => console.log("dismissed")}
onWriteCustomResponse={() => console.log("write custom")}
/>
);
}
Variants
options (default)
Renders a numbered list of suggested responses. Best for free-form picks where each option is a distinct, complete answer.
scale
Renders a 5-point Likert scale (Strongly disagree → Strongly agree) as RadioCardGroup cells with a primary Save button. Best for sentiment / agreement-style feedback where you want a single committed answer. Submits via onSelectValue(value, label) if provided, or falls back to onSelectOption(label). There is no "Write my own response" escape hatch in this variant — the answer space is constrained to the scale.
Pass an optional icons array (5 entries) to render an icon over each step — useful for satisfaction questions where face emoji read faster than words.
import {
FaceDisappointedIcon,
FaceFrownSlightIcon,
FaceMehIcon,
FaceGrinIcon,
FaceGrinStarsIcon,
} from "@delphi/ui";
<AgentOptionsTakeover
variant="scale"
data={{ title: "Your Delphi responded just like you", options: [] }}
icons={[
FaceDisappointedIcon,
FaceFrownSlightIcon,
FaceMehIcon,
FaceGrinIcon,
FaceGrinStarsIcon,
]}
onSelectValue={(value, label) => console.log(value, label)}
onDismiss={() => {}}
onWriteCustomResponse={() => {}}
onSelectOption={() => {}}
/>;
Keyboard Shortcuts
Options variant
| Key | Action |
|---|---|
↑ / ↓ | Navigate between options (wraps around) |
Enter | Submit the focused option |
Esc | Dismiss and return to freeform input |
Scale variant
| Key | Action |
|---|---|
← / → / ↑ / ↓ | Adjust the scale value (1–5) |
Enter | Save and submit |
Esc | Dismiss and return to freeform input |
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
data | AgentOptionsTakeoverData | required | Title and array of option strings |
variant | "options" | "scale" | "options" | Which body to render |
icons | AgentOptionsTakeoverIcon[] | - | Scale variant only. 5 icon components rendered over each step |
onSelectOption | (option: string) => void | required | Called with the option text when selected (or the Likert label as a fallback) |
onSelectValue | (value: number, label: string) => void | - | Called when the scale variant submits. Falls back to onSelectOption(label) if omitted |
onDismiss | () => void | required | Called when the user closes the takeover |
onWriteCustomResponse | () => void | required | Called when the user opts to write their own response |
className | string | - | Additional CSS classes on the outer wrapper |
AgentOptionsTakeoverData
interface AgentOptionsTakeoverData {
title: string;
options: string[];
}
AgentOptionsTakeoverIcon
type AgentOptionsTakeoverIcon = React.ComponentType<{ className?: string }>;
scale variant with icons for satisfaction questions where face emoji communicate sentiment faster than words