Add interaction card Storybook state matrix

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-07-05 11:09:35 +00:00
1 parent ad961227f5
commit 224741e4d1
2 files changed
+652

No files matched your search

@@ -329,6 +329,34 @@ export const acceptedSuggestedTasksInteraction = createSuggestTasksInteraction({
},
});
export const partialAcceptedSuggestedTasksInteraction = createSuggestTasksInteraction({
id: "interaction-suggest-partial-accepted",
status: "accepted",
resolvedByUserId: issueThreadInteractionFixtureMeta.currentUserId,
resolvedAt: new Date("2026-04-20T14:16:30.000Z"),
updatedAt: new Date("2026-04-20T14:16:30.000Z"),
result: {
version: 1,
createdTasks: [
{
clientKey: "root-design",
issueId: "issue-created-1",
identifier: "PAP-1713",
title: "Prototype issue-thread interaction cards",
},
{
clientKey: "child-stories",
issueId: "issue-created-2",
identifier: "PAP-1714",
title: "Add Storybook coverage for acceptance and rejection states",
parentIssueId: "issue-created-1",
parentIdentifier: "PAP-1713",
},
],
skippedClientKeys: ["child-mixed-thread", "hidden-follow-up"],
},
});
export const rejectedSuggestedTasksInteraction = createSuggestTasksInteraction({
id: "interaction-suggest-rejected",
status: "rejected",
@@ -342,8 +370,92 @@ export const rejectedSuggestedTasksInteraction = createSuggestTasksInteraction({
},
});
export const expiredSuggestedTasksInteraction = createSuggestTasksInteraction({
id: "interaction-suggest-expired",
status: "expired",
resolvedByAgentId: "agent-codex",
resolvedAt: new Date("2026-04-20T14:17:30.000Z"),
updatedAt: new Date("2026-04-20T14:17:30.000Z"),
});
export const cancelledSuggestedTasksInteraction = createSuggestTasksInteraction({
id: "interaction-suggest-cancelled",
status: "cancelled",
resolvedByUserId: issueThreadInteractionFixtureMeta.currentUserId,
resolvedAt: new Date("2026-04-20T14:17:45.000Z"),
updatedAt: new Date("2026-04-20T14:17:45.000Z"),
});
export const failedSuggestedTasksInteraction = createSuggestTasksInteraction({
id: "interaction-suggest-failed",
status: "failed",
updatedAt: new Date("2026-04-20T14:17:55.000Z"),
});
export const pendingAskUserQuestionsInteraction = createAskUserQuestionsInteraction({});
export const everyQuestionTypeAskUserQuestionsInteraction = createAskUserQuestionsInteraction({
id: "interaction-questions-every-type",
title: "Confirm rollout answers",
summary:
"This fixture keeps single-select, multi-select, optional, long-copy, and other free-text inputs visible in one form.",
payload: {
version: 1,
title: "Rollout choices",
submitLabel: "Submit rollout answers",
questions: [
{
id: "free-text",
prompt: "What extra context should the implementer carry into the rollout?",
helpText:
"Use the Other field for free-form text. The schema still stores this as a structured question answer.",
selectionMode: "single",
required: true,
options: [
{
id: "use-other",
label: "I'll write the answer in Other",
description: "Exercises the free-text answer path without adding a separate schema shape.",
},
],
},
{
id: "single-select",
prompt: "Which rollout path should be treated as the default?",
selectionMode: "single",
required: true,
options: [
{ id: "guarded", label: "Guarded rollout", description: "Ship behind the existing flag first." },
{ id: "direct", label: "Direct rollout", description: "Enable the behavior immediately." },
],
},
{
id: "multi-select",
prompt: "Which review signals should be included in the handoff?",
helpText:
"This intentionally uses longer copy so the option rows prove wrapping behavior in the card.",
selectionMode: "multi",
required: true,
options: [
{ id: "storybook", label: "Storybook snapshots", description: "Reference the visual matrix directly." },
{ id: "unit-tests", label: "Focused unit tests", description: "Keep the regression proof close to the component." },
{ id: "accessibility", label: "A11y notes", description: "Flag keyboard and screen-reader concerns while reviewing the card." },
],
},
{
id: "optional",
prompt: "Optional: which follow-up should wait until after this change?",
selectionMode: "multi",
required: false,
options: [
{ id: "animation", label: "Micro-animation polish" },
{ id: "copy-pass", label: "Long-form copy review" },
],
},
],
},
});
export const answeredAskUserQuestionsInteraction = createAskUserQuestionsInteraction({
id: "interaction-questions-answered",
status: "answered",
@@ -370,6 +482,41 @@ export const answeredAskUserQuestionsInteraction = createAskUserQuestionsInterac
},
});
export const everyQuestionTypeAnsweredAskUserQuestionsInteraction = createAskUserQuestionsInteraction({
id: "interaction-questions-every-type-answered",
status: "answered",
title: everyQuestionTypeAskUserQuestionsInteraction.title,
summary: everyQuestionTypeAskUserQuestionsInteraction.summary,
resolvedByUserId: issueThreadInteractionFixtureMeta.currentUserId,
resolvedAt: new Date("2026-04-20T14:24:30.000Z"),
updatedAt: new Date("2026-04-20T14:24:30.000Z"),
payload: everyQuestionTypeAskUserQuestionsInteraction.payload,
result: {
version: 1,
answers: [
{
questionId: "free-text",
optionIds: [],
otherText: "Keep the rollout reversible until QA signs off on mobile-width cards.",
},
{
questionId: "single-select",
optionIds: ["guarded"],
},
{
questionId: "multi-select",
optionIds: ["storybook", "accessibility"],
},
{
questionId: "optional",
optionIds: [],
},
],
summaryMarkdown:
"Use a guarded rollout, include Storybook and a11y notes, and keep the free-text guidance visible.",
},
});
export const commentExpiredAskUserQuestionsInteraction = createAskUserQuestionsInteraction({
id: "interaction-questions-expired-comment",
status: "expired",
@@ -385,6 +532,32 @@ export const commentExpiredAskUserQuestionsInteraction = createAskUserQuestionsI
},
});
export const cancelledAskUserQuestionsInteraction = createAskUserQuestionsInteraction({
id: "interaction-questions-cancelled",
status: "cancelled",
resolvedByUserId: issueThreadInteractionFixtureMeta.currentUserId,
resolvedAt: new Date("2026-04-20T14:25:30.000Z"),
updatedAt: new Date("2026-04-20T14:25:30.000Z"),
result: {
version: 1,
answers: [],
cancelled: true,
cancellationReason: "The board answered this in a later synchronous review.",
summaryMarkdown: null,
},
});
export const failedAskUserQuestionsInteraction = createAskUserQuestionsInteraction({
id: "interaction-questions-failed",
status: "failed",
updatedAt: new Date("2026-04-20T14:25:45.000Z"),
result: {
version: 1,
answers: [],
summaryMarkdown: null,
},
});
export const pendingRequestConfirmationInteraction = createRequestConfirmationInteraction({});
export const genericPendingRequestConfirmationInteraction = createRequestConfirmationInteraction({
@@ -540,6 +713,14 @@ export const failedRequestConfirmationInteraction = createRequestConfirmationInt
updatedAt: new Date("2026-04-20T14:42:00.000Z"),
});
export const cancelledRequestConfirmationInteraction = createRequestConfirmationInteraction({
id: "interaction-confirmation-cancelled",
status: "cancelled",
resolvedByUserId: issueThreadInteractionFixtureMeta.currentUserId,
resolvedAt: new Date("2026-04-20T14:43:00.000Z"),
updatedAt: new Date("2026-04-20T14:43:00.000Z"),
});
export const pendingRequestCheckboxConfirmationInteraction =
createRequestCheckboxConfirmationInteraction({});
@@ -642,6 +823,21 @@ export const rejectedRequestCheckboxConfirmationInteraction =
},
});
export const commentExpiredRequestCheckboxConfirmationInteraction =
createRequestCheckboxConfirmationInteraction({
id: "interaction-checkbox-expired-comment",
status: "expired",
resolvedByUserId: issueThreadInteractionFixtureMeta.currentUserId,
resolvedAt: new Date("2026-04-20T14:50:30.000Z"),
updatedAt: new Date("2026-04-20T14:50:30.000Z"),
result: {
version: 1,
outcome: "superseded_by_comment",
commentId: "22222222-2222-4222-8222-222222222222",
selectedOptionIds: [],
},
});
export const staleTargetRequestCheckboxConfirmationInteraction =
createRequestCheckboxConfirmationInteraction({
id: "interaction-checkbox-stale",
@@ -679,6 +875,22 @@ export const staleTargetRequestCheckboxConfirmationInteraction =
},
});
export const cancelledRequestCheckboxConfirmationInteraction =
createRequestCheckboxConfirmationInteraction({
id: "interaction-checkbox-cancelled",
status: "cancelled",
resolvedByUserId: issueThreadInteractionFixtureMeta.currentUserId,
resolvedAt: new Date("2026-04-20T14:51:30.000Z"),
updatedAt: new Date("2026-04-20T14:51:30.000Z"),
});
export const failedRequestCheckboxConfirmationInteraction =
createRequestCheckboxConfirmationInteraction({
id: "interaction-checkbox-failed",
status: "failed",
updatedAt: new Date("2026-04-20T14:51:45.000Z"),
});
export const issueThreadInteractionComments: IssueChatComment[] = [
createComment({
id: "comment-thread-board",
@@ -10,8 +10,20 @@ import {
answeredAskUserQuestionsInteraction,
acceptedRequestConfirmationInteraction,
boundedRequestCheckboxConfirmationInteraction,
cancelledAskUserQuestionsInteraction,
cancelledRequestCheckboxConfirmationInteraction,
cancelledRequestConfirmationInteraction,
cancelledSuggestedTasksInteraction,
commentExpiredAskUserQuestionsInteraction,
commentExpiredRequestCheckboxConfirmationInteraction,
commentExpiredRequestConfirmationInteraction,
everyQuestionTypeAnsweredAskUserQuestionsInteraction,
everyQuestionTypeAskUserQuestionsInteraction,
expiredSuggestedTasksInteraction,
failedAskUserQuestionsInteraction,
failedRequestCheckboxConfirmationInteraction,
failedRequestConfirmationInteraction,
failedSuggestedTasksInteraction,
genericPendingRequestConfirmationInteraction,
issueThreadInteractionComments,
issueThreadInteractionEvents,
@@ -21,6 +33,7 @@ import {
manyOptionsRequestCheckboxConfirmationInteraction,
mixedIssueThreadInteractions,
optionalDeclineRequestConfirmationInteraction,
partialAcceptedSuggestedTasksInteraction,
pendingAskUserQuestionsInteraction,
pendingRequestCheckboxConfirmationInteraction,
pendingRequestConfirmationInteraction,
@@ -39,6 +52,7 @@ import type {
RequestCheckboxConfirmationInteraction,
RequestConfirmationInteraction,
SuggestTasksInteraction,
IssueThreadInteraction,
} from "@/lib/issue-thread-interactions";
import { storybookAgentMap } from "../fixtures/paperclipData";
@@ -97,6 +111,39 @@ function ScenarioCard({
);
}
function StaticInteractionCard({
interaction,
}: {
interaction: IssueThreadInteraction;
}) {
return (
<IssueThreadInteractionCard
interaction={interaction}
agentMap={storybookAgentMap}
currentUserId={issueThreadInteractionFixtureMeta.currentUserId}
userLabelMap={boardUserLabels}
/>
);
}
function MobileScenario({
title,
interaction,
}: {
title: string;
interaction: IssueThreadInteraction;
}) {
return (
<StoryFrame>
<div className="mx-auto w-[390px] max-w-full">
<ScenarioCard title={title} description="390px-wide mobile render.">
<StaticInteractionCard interaction={interaction} />
</ScenarioCard>
</div>
</StoryFrame>
);
}
function InteractiveSuggestedTasksCard() {
const [interaction, setInteraction] = useState<SuggestTasksInteraction>(
pendingSuggestedTasksInteraction,
@@ -136,6 +183,100 @@ function InteractiveSuggestedTasksCard() {
);
}
function AutoClickInteractionCard({
buttonText,
children,
}: {
buttonText: string;
children: React.ReactNode;
}) {
const ref = useRef<HTMLDivElement | null>(null);
useEffect(() => {
const button = Array.from(ref.current?.querySelectorAll("button") ?? [])
.find((candidate) => candidate.textContent?.includes(buttonText));
button?.click();
}, [buttonText]);
return <div ref={ref}>{children}</div>;
}
function InFlightSuggestedTasksCard() {
return (
<AutoClickInteractionCard buttonText="Accept drafts">
<IssueThreadInteractionCard
interaction={pendingSuggestedTasksInteraction}
agentMap={storybookAgentMap}
currentUserId={issueThreadInteractionFixtureMeta.currentUserId}
userLabelMap={boardUserLabels}
onAcceptInteraction={() => new Promise(() => {})}
onRejectInteraction={() => undefined}
/>
</AutoClickInteractionCard>
);
}
function InFlightAskUserQuestionsCard() {
const readyInteraction: AskUserQuestionsInteraction = {
...pendingAskUserQuestionsInteraction,
result: {
version: 1,
answers: [
{
questionId: "collapse-depth",
optionIds: ["visible-root"],
},
{
questionId: "post-submit-summary",
optionIds: ["answers-inline"],
},
],
},
};
return (
<AutoClickInteractionCard buttonText="Send answers">
<IssueThreadInteractionCard
interaction={readyInteraction}
agentMap={storybookAgentMap}
currentUserId={issueThreadInteractionFixtureMeta.currentUserId}
userLabelMap={boardUserLabels}
onSubmitInteractionAnswers={() => new Promise(() => {})}
/>
</AutoClickInteractionCard>
);
}
function InFlightRequestConfirmationCard() {
return (
<AutoClickInteractionCard buttonText="Approve plan">
<IssueThreadInteractionCard
interaction={pendingRequestConfirmationInteraction}
agentMap={storybookAgentMap}
currentUserId={issueThreadInteractionFixtureMeta.currentUserId}
userLabelMap={boardUserLabels}
onAcceptInteraction={() => new Promise(() => {})}
onRejectInteraction={() => undefined}
/>
</AutoClickInteractionCard>
);
}
function InFlightCheckboxConfirmationCard() {
return (
<AutoClickInteractionCard buttonText="Delete selected">
<IssueThreadInteractionCard
interaction={pendingRequestCheckboxConfirmationInteraction}
agentMap={storybookAgentMap}
currentUserId={issueThreadInteractionFixtureMeta.currentUserId}
userLabelMap={boardUserLabels}
onAcceptInteraction={() => new Promise(() => {})}
onRejectInteraction={() => undefined}
/>
</AutoClickInteractionCard>
);
}
function buildAnsweredInteraction(
answers: AskUserQuestionsAnswer[],
): AskUserQuestionsInteraction {
@@ -314,6 +455,19 @@ export const SuggestedTasksAccepted: Story = {
),
};
export const SuggestedTasksPartiallyAccepted: Story = {
render: () => (
<StoryFrame>
<ScenarioCard
title="Partially accepted suggested tasks"
description="Some suggested tasks became issues while the rest stayed marked as skipped."
>
<StaticInteractionCard interaction={partialAcceptedSuggestedTasksInteraction} />
</ScenarioCard>
</StoryFrame>
),
};
export const SuggestedTasksRejected: Story = {
render: () => (
<StoryFrame>
@@ -332,6 +486,45 @@ export const SuggestedTasksRejected: Story = {
),
};
export const SuggestedTasksExpired: Story = {
render: () => (
<StoryFrame>
<ScenarioCard
title="Expired suggested tasks"
description="The suggestion is no longer actionable, but the proposed task tree remains readable."
>
<StaticInteractionCard interaction={expiredSuggestedTasksInteraction} />
</ScenarioCard>
</StoryFrame>
),
};
export const SuggestedTasksCancelled: Story = {
render: () => (
<StoryFrame>
<ScenarioCard
title="Cancelled suggested tasks"
description="The cancelled state keeps the draft artifact visible without action controls."
>
<StaticInteractionCard interaction={cancelledSuggestedTasksInteraction} />
</ScenarioCard>
</StoryFrame>
),
};
export const SuggestedTasksFailed: Story = {
render: () => (
<StoryFrame>
<ScenarioCard
title="Failed suggested tasks"
description="Failed resolution removes controls while preserving the task tree for inspection."
>
<StaticInteractionCard interaction={failedSuggestedTasksInteraction} />
</ScenarioCard>
</StoryFrame>
),
};
export const AskUserQuestionsPending: Story = {
render: () => (
<StoryFrame>
@@ -345,6 +538,26 @@ export const AskUserQuestionsPending: Story = {
),
};
export const AskUserQuestionsEveryQuestionType: Story = {
render: () => (
<StoryFrame>
<ScenarioCard
title="Every question input shape"
description="Single-select, multi-select, optional, long-copy, and Other free-text paths render together."
>
<IssueThreadInteractionCard
interaction={everyQuestionTypeAskUserQuestionsInteraction}
agentMap={storybookAgentMap}
currentUserId={issueThreadInteractionFixtureMeta.currentUserId}
userLabelMap={boardUserLabels}
onSubmitInteractionAnswers={() => undefined}
onCancelInteraction={() => undefined}
/>
</ScenarioCard>
</StoryFrame>
),
};
export const AskUserQuestionsAnswered: Story = {
render: () => (
<StoryFrame>
@@ -363,6 +576,58 @@ export const AskUserQuestionsAnswered: Story = {
),
};
export const AskUserQuestionsEveryQuestionTypeAnswered: Story = {
render: () => (
<StoryFrame>
<ScenarioCard
title="Answered every question input shape"
description="Answered summaries include selected choices, empty optional answers, and Other free text."
>
<StaticInteractionCard interaction={everyQuestionTypeAnsweredAskUserQuestionsInteraction} />
</ScenarioCard>
</StoryFrame>
),
};
export const AskUserQuestionsExpiredByComment: Story = {
render: () => (
<StoryFrame>
<ScenarioCard
title="Question form expired by comment"
description="A later board comment superseded the unanswered question request."
>
<StaticInteractionCard interaction={commentExpiredAskUserQuestionsInteraction} />
</ScenarioCard>
</StoryFrame>
),
};
export const AskUserQuestionsCancelled: Story = {
render: () => (
<StoryFrame>
<ScenarioCard
title="Cancelled question form"
description="Cancellation records why no answer set was captured."
>
<StaticInteractionCard interaction={cancelledAskUserQuestionsInteraction} />
</ScenarioCard>
</StoryFrame>
),
};
export const AskUserQuestionsFailed: Story = {
render: () => (
<StoryFrame>
<ScenarioCard
title="Failed question form"
description="The failed state is read-only and keeps each unanswered prompt visible."
>
<StaticInteractionCard interaction={failedAskUserQuestionsInteraction} />
</ScenarioCard>
</StoryFrame>
),
};
export const RequestConfirmationPending: Story = {
render: () => (
<StoryFrame>
@@ -570,6 +835,19 @@ export const RequestConfirmationFailed: Story = {
),
};
export const RequestConfirmationCancelled: Story = {
render: () => (
<StoryFrame>
<ScenarioCard
title="Cancelled request confirmation"
description="A cancelled confirmation has the same shell language as other inactive states."
>
<StaticInteractionCard interaction={cancelledRequestConfirmationInteraction} />
</ScenarioCard>
</StoryFrame>
),
};
export const RequestConfirmationAccepted = RequestConfirmationConfirmed;
export const RequestConfirmationRejected = RequestConfirmationDeclinedWithReason;
@@ -661,6 +939,19 @@ export const CheckboxConfirmationRejected: Story = {
),
};
export const CheckboxConfirmationExpiredByComment: Story = {
render: () => (
<StoryFrame>
<ScenarioCard
title="Checkbox confirmation expired by comment"
description="A later board comment superseded the selection before it was confirmed."
>
<StaticInteractionCard interaction={commentExpiredRequestCheckboxConfirmationInteraction} />
</ScenarioCard>
</StoryFrame>
),
};
export const CheckboxConfirmationStaleTarget: Story = {
render: () => (
<StoryFrame>
@@ -679,6 +970,32 @@ export const CheckboxConfirmationStaleTarget: Story = {
),
};
export const CheckboxConfirmationCancelled: Story = {
render: () => (
<StoryFrame>
<ScenarioCard
title="Cancelled checkbox confirmation"
description="The cancelled state keeps the prompt and option context visible without controls."
>
<StaticInteractionCard interaction={cancelledRequestCheckboxConfirmationInteraction} />
</ScenarioCard>
</StoryFrame>
),
};
export const CheckboxConfirmationFailed: Story = {
render: () => (
<StoryFrame>
<ScenarioCard
title="Failed checkbox confirmation"
description="Failed resolution shows the recovery copy used by inactive checkbox confirmations."
>
<StaticInteractionCard interaction={failedRequestCheckboxConfirmationInteraction} />
</ScenarioCard>
</StoryFrame>
),
};
export const CheckboxConfirmationManyOptions: Story = {
render: () => (
<StoryFrame>
@@ -696,6 +1013,129 @@ export const CheckboxConfirmationManyOptions: Story = {
),
};
export const InteractionInFlightStates: Story = {
render: () => (
<StoryFrame>
<Section eyebrow="In-flight" title="Submitting states where the card can represent a pending action">
<div className="grid gap-6 xl:grid-cols-2">
<ScenarioCard
title="Suggested tasks accepting"
description="The primary action shows a loading state while acceptance is in flight."
>
<InFlightSuggestedTasksCard />
</ScenarioCard>
<ScenarioCard
title="Questions submitting"
description="The submit button shows a loading state while answers are being sent."
>
<InFlightAskUserQuestionsCard />
</ScenarioCard>
<ScenarioCard
title="Confirmation accepting"
description="The confirmation button stays disabled and shows progress."
>
<InFlightRequestConfirmationCard />
</ScenarioCard>
<ScenarioCard
title="Checkbox confirmation accepting"
description="Selection confirmation shows progress while the response is unresolved."
>
<InFlightCheckboxConfirmationCard />
</ScenarioCard>
</div>
</Section>
</StoryFrame>
),
};
export const SuggestedTasksMobile390: Story = {
render: () => (
<MobileScenario
title="Suggested tasks mobile"
interaction={pendingSuggestedTasksInteraction}
/>
),
};
export const AskUserQuestionsMobile390: Story = {
render: () => (
<MobileScenario
title="Question form mobile"
interaction={everyQuestionTypeAskUserQuestionsInteraction}
/>
),
};
export const RequestConfirmationMobile390: Story = {
render: () => (
<MobileScenario
title="Confirmation mobile"
interaction={pendingRequestConfirmationInteraction}
/>
),
};
export const CheckboxConfirmationMobile390: Story = {
render: () => (
<MobileScenario
title="Checkbox confirmation mobile"
interaction={pendingRequestCheckboxConfirmationInteraction}
/>
),
};
export const StateMatrix: Story = {
render: () => (
<StoryFrame>
<Section eyebrow="State matrix" title="Issue-thread interaction status coverage">
<div className="grid gap-6 xl:grid-cols-2">
<ScenarioCard title="Suggested tasks" description="Pending, accepted, rejected, expired, cancelled, and failed.">
<div className="space-y-4">
<StaticInteractionCard interaction={pendingSuggestedTasksInteraction} />
<StaticInteractionCard interaction={partialAcceptedSuggestedTasksInteraction} />
<StaticInteractionCard interaction={rejectedSuggestedTasksInteraction} />
<StaticInteractionCard interaction={expiredSuggestedTasksInteraction} />
<StaticInteractionCard interaction={cancelledSuggestedTasksInteraction} />
<StaticInteractionCard interaction={failedSuggestedTasksInteraction} />
</div>
</ScenarioCard>
<ScenarioCard title="Ask user questions" description="Pending, answered, expired by comment, cancelled, and failed.">
<div className="space-y-4">
<StaticInteractionCard interaction={everyQuestionTypeAskUserQuestionsInteraction} />
<StaticInteractionCard interaction={everyQuestionTypeAnsweredAskUserQuestionsInteraction} />
<StaticInteractionCard interaction={commentExpiredAskUserQuestionsInteraction} />
<StaticInteractionCard interaction={cancelledAskUserQuestionsInteraction} />
<StaticInteractionCard interaction={failedAskUserQuestionsInteraction} />
</div>
</ScenarioCard>
<ScenarioCard title="Request confirmation" description="Pending, accepted, rejected, both expiry reasons, cancelled, and failed.">
<div className="space-y-4">
<StaticInteractionCard interaction={pendingRequestConfirmationInteraction} />
<StaticInteractionCard interaction={acceptedRequestConfirmationInteraction} />
<StaticInteractionCard interaction={rejectedRequestConfirmationInteraction} />
<StaticInteractionCard interaction={commentExpiredRequestConfirmationInteraction} />
<StaticInteractionCard interaction={staleTargetRequestConfirmationInteraction} />
<StaticInteractionCard interaction={cancelledRequestConfirmationInteraction} />
<StaticInteractionCard interaction={failedRequestConfirmationInteraction} />
</div>
</ScenarioCard>
<ScenarioCard title="Checkbox confirmation" description="Pending, accepted, rejected, both expiry reasons, cancelled, and failed.">
<div className="space-y-4">
<StaticInteractionCard interaction={pendingRequestCheckboxConfirmationInteraction} />
<StaticInteractionCard interaction={acceptedRequestCheckboxConfirmationInteraction} />
<StaticInteractionCard interaction={rejectedRequestCheckboxConfirmationInteraction} />
<StaticInteractionCard interaction={commentExpiredRequestCheckboxConfirmationInteraction} />
<StaticInteractionCard interaction={staleTargetRequestCheckboxConfirmationInteraction} />
<StaticInteractionCard interaction={cancelledRequestCheckboxConfirmationInteraction} />
<StaticInteractionCard interaction={failedRequestCheckboxConfirmationInteraction} />
</div>
</ScenarioCard>
</div>
</Section>
</StoryFrame>
),
};
export const ReviewSurface: Story = {
render: () => (
<StoryFrame>