import { useState } from 'react';
import { PaginationCompact } from '@pantheon-systems/pds-toolkit-react';
import { Meta, StoryObj } from '@storybook/react-vite';
import { Button } from '../_base/Button/Button';
import {
SuggestionCard,
SuggestionCardState,
SuggestionChoice,
} from '../SuggestionCard/SuggestionCard';
const meta: Meta = {
tags: ['new-pattern', 'ready-for-dev'],
title: 'Recipes/Regenerate a suggestion',
parameters: {
docs: {
description: {
component:
'**Recipe:** a composition of existing proposals, not a component. A Suggestion Card with a Regenerate button and a pager to browse the sets the agent has offered.',
},
},
},
};
export default meta;
type Story = StoryObj<typeof meta>;
// Each generation of the suggestion is a set of headline options. Regenerate
// adds the next set, cycling through these.
const HEADLINE_SETS = [
[
{
description: 'Bold and confident.',
label: 'Ship faster with confidence',
},
{ description: 'Reassuring.', label: 'Deploy with confidence, every time' },
{ description: 'Short and simple.', label: 'Your site, live in seconds' },
],
[
{
description: 'Benefit first.',
label: 'Launch without the launch-day stress',
},
{ description: 'Direct.', label: 'Push to production in one click' },
{ description: 'Playful.', label: 'Hit deploy. Go grab a coffee.' },
],
[
{
description: 'Outcome focused.',
label: 'Your best site, always up to date',
},
{ description: 'Team angle.', label: 'Every change, shipped together' },
{ description: 'Plain.', label: 'Deploy your site, simply' },
],
];
export const Interactive: Story = {
parameters: {
docs: {
description: {
story:
'Retry and browse. **Regenerate** asks the agent for a new set of options: the button shows its working state, then the card shows the new set and jumps to it. The PDS Compact Pagination (static, no page jump) sits in `actionsEnd` once there is more than one set, so people can step back to an earlier set. Each set remembers its own selection. Story-only wiring: the screen owns the sets, the selection and what Regenerate does; the card only provides the slots.',
},
},
},
render: () => {
// The index of the HEADLINE_SETS entry behind each page, in order.
const [pages, setPages] = useState<number[]>([0]);
const [page, setPage] = useState(1);
const [picked, setPicked] = useState<Record<number, string>>({ 1: '0' });
const [isRegenerating, setIsRegenerating] = useState(false);
const [state, setState] = useState<SuggestionCardState>('pending');
const options = HEADLINE_SETS[pages[page - 1]];
const regenerate = () => {
setIsRegenerating(true);
// Stands in for the agent's reply.
setTimeout(() => {
const next = pages.length + 1;
setPages((prev) => [...prev, prev.length % HEADLINE_SETS.length]);
setPicked((prev) => ({ ...prev, [next]: '0' }));
setPage(next);
setIsRegenerating(false);
}, 1200);
};
return (
<SuggestionCard
actionsEnd={
pages.length > 1 ? (
<PaginationCompact
currentPage={page}
itemsPerPage={1}
onPageChange={setPage}
pageControlType='static'
totalItemCount={pages.length}
/>
) : undefined
}
actionsStart={
<>
<Button
displayType='icon-start'
iconName='check'
label='Use selected'
onClick={() => setState('accepted')}
variant='primary'
/>
<Button
displayType='icon-start'
iconName='rotate'
isWorking={isRegenerating}
label={isRegenerating ? 'Regenerating' : 'Regenerate'}
onClick={regenerate}
variant='secondary'
/>
<Button
label='Dismiss'
onClick={() => setState('dismissed')}
variant='subtle'
/>
</>
}
description='The current headline is “Deploy your site”. Pick one to replace it.'
state={state}
statusLabel={state === 'dismissed' ? 'Dismissed' : 'Done'}
title='Which headline should I use?'
type='choice'
>
{options.map((option, i) => (
<SuggestionChoice
checked={picked[page] === String(i)}
description={option.description}
id={`regenerate-${page}-${i}`}
key={`${page}-${i}`}
label={option.label}
name={`regenerate-${page}`}
onChange={() =>
setPicked((prev) => ({ ...prev, [page]: String(i) }))
}
selectionType='radio'
value={String(i)}
/>
))}
</SuggestionCard>
);
},
};
Regenerate a suggestion
A recipe, not a component: one interactive story that composes the Suggestion Card (single choice), the Button and the PDS Compact Pagination.
Extends a PDS componentOpen in Storybook