← All proposals

Agentic Menu Button

A separate component, `AgenticMenuButton`, for a menu of actions the agent does:

Net-new componentOpen in Storybook

proposals/AgenticMenuButton/AgenticMenuButton.stories.tsx218 lines · View on GitHub
import { Meta, StoryObj } from '@storybook/react-vite';

import { iconList } from '@pantheon-systems/pds-toolkit-react';

import {
	complexMenuItems,
	iconMenuItems,
	simpleMenuItems,
} from '../_base/MenuButton/menu-button-sample-data';
import { AgenticMenuButton } from './AgenticMenuButton';

const meta: Meta<typeof AgenticMenuButton> = {
	tags: ['new-pattern', 'ready-for-dev'],
	title: 'Component Proposals/Buttons/Agentic Menu Button',
	component: AgenticMenuButton,
	parameters: {
		docs: {
			description: {
				component:
					'**New pattern:** not in PDS v2 today. A menu button whose trigger is the Agentic Button (the secondary look with the AI gradient border), for a menu of actions the agent does. With `iconOnly` the trigger is an Icon Button with the `agentic` variant. Everything else is the Menu Button.',
			},
		},
	},
	argTypes: {
		id: {
			table: {
				category: 'Content',
			},
		},
		label: {
			table: {
				category: 'Content',
			},
		},
		testId: {
			table: {
				category: 'Content',
			},
		},
		menuItems: {
			table: {
				category: 'Content',
			},
			description:
				'Sample data sets of menu items. See docs for how to configure real menu items.',
			options: Object.keys({
				simpleMenuItems,
				iconMenuItems,
				complexMenuItems,
			}),
			mapping: {
				simpleMenuItems,
				iconMenuItems,
				complexMenuItems,
			},
			control: {
				type: 'select',
				labels: {
					simpleMenuItems: 'Simple menu items',
					iconMenuItems: 'Icon menu items',
					complexMenuItems: 'Complex menu items',
				},
			},
		},
		size: {
			control: 'select',
			options: ['xs', 's', 'm'],
			table: {
				category: 'Component configuration',
			},
		},
		iconOnly: {
			control: 'boolean',
			table: {
				category: 'Component configuration',
			},
		},
		isMobileAccordion: {
			control: 'boolean',
			table: {
				category: 'Component configuration',
			},
		},
		placement: {
			control: 'select',
			options: [
				'top',
				'top-start',
				'top-end',
				'right',
				'right-start',
				'right-end',
				'bottom',
				'bottom-start',
				'bottom-end',
				'left',
				'left-start',
				'left-end',
			],
			table: {
				category: 'Component configuration',
			},
		},
		tally: {
			table: {
				category: 'Content',
			},
		},
		statusDot: {
			control: 'select',
			table: {
				category: 'Content',
			},
		},
		onClick: {
			table: {
				category: 'Functions',
			},
		},
		undefinedLabel: {
			table: {
				category: 'Translation strings',
			},
		},
		iconName: {
			control: 'select',
			options: iconList,
			table: {
				category: 'Component configuration',
			},
		},
		disabled: {
			table: {
				category: 'Base attributes',
			},
		},
		className: {
			table: {
				category: 'Base attributes',
			},
		},
		isSplitButton: {
			table: {
				disable: true,
			},
		},
		positionReferenceRef: {
			table: {
				disable: true,
			},
		},
		ref: {
			table: {
				disable: true,
			},
		},
	},
	decorators: [
		(Story) => (
			<div style={{ marginBlockEnd: '27rem' }}>
				<Story />
			</div>
		),
	],
	args: {
		id: 'agentic-menu-button-example',
		label: 'Menu Button',
		menuItems: complexMenuItems,
		iconOnly: false,
		size: 's',
		disabled: false,
	},
};

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {};

export const IconOnly: Story = {
	args: {
		id: 'menu-button-icon-only',
		iconOnly: true,
		iconName: 'ellipsisVertical',
	},
};

export const WithTally: Story = {
	parameters: {
		docs: {
			description: {
				story:
					"Attaches a `Tally` badge to the menu button to surface a count before the user opens the menu — useful for pending items or notification counts scoped to the menu's actions.",
			},
		},
	},
	args: {
		id: 'menu-button-with-tally',
		tally: { label: 4, type: 'neutral' },
	},
};

export const WithStatusDot: Story = {
	parameters: {
		docs: {
			description: {
				story:
					'Overlays a `StatusDot` on the menu button to communicate the real-time health or state of the resource the menu controls, without requiring the user to open the menu.',
			},
		},
	},
	args: {
		id: 'menu-button-with-status-dot',
		statusDot: 'discovery',
	},
};