← All proposals

Agentic Split Button

A separate component, `AgenticSplitButton`, a copy of the PDS v2 Split Button, so the engineer's port is mostly a copy:

Net-new componentOpen in Storybook

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

import { AgenticSplitButton } from './AgenticSplitButton';
import { sampleActionItems } from './split-button-sample-data';

const meta: Meta<typeof AgenticSplitButton> = {
	tags: ['new-pattern', 'ready-for-dev'],
	title: 'Component Proposals/Buttons/Agentic Split Button',
	component: AgenticSplitButton,
	parameters: {
		docs: {
			description: {
				component:
					'**New pattern:** not in PDS v2 today. A split button for actions the agent does: a primary action with a menu of additional options, and the AI gradient as the border around the whole control. The secondary look. Everything else is the PDS Split Button.',
			},
		},
	},
	argTypes: {
		actionItems: { table: { category: 'Content' } },
		id: { table: { category: 'Content' } },
		iconName: { control: 'select', table: { category: 'Content' } },
		isAnimated: {
			control: 'boolean',
			table: { category: 'Component configuration' },
		},
		size: {
			control: 'select',
			table: { category: 'Component configuration' },
		},
		anchorToFullButton: {
			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' },
		},
		moreActionsLabel: {
			control: 'text',
			table: { category: 'Translation strings' },
		},
		disabled: { table: { category: 'Base attributes' } },
		className: { table: { category: 'Base attributes' } },
	},
	decorators: [
		(Story) => (
			<div style={{ marginBlockEnd: '10rem' }}>
				<Story />
			</div>
		),
	],
	args: {
		actionItems: sampleActionItems,
		id: 'agentic-split-button',
		isAnimated: true,
		size: 's',
	},
};

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {
	args: {},
};

export const WithIcon: Story = {
	parameters: {
		docs: {
			description: {
				story:
					'Pass `iconName` to show a leading icon on the primary action, the same as on the standalone Button.',
			},
		},
	},
	args: {
		iconName: 'zappy',
	},
};

export const Disabled: Story = {
	args: {
		disabled: true,
	},
};

export const AllSizes: Story = {
	parameters: {
		docs: {
			description: {
				story:
					'Both sizes. The control has the same height as a standalone Agentic Button.',
			},
		},
	},
	render: (args) => (
		<div
			style={{
				alignItems: 'start',
				display: 'grid',
				gap: 'var(--pds-spacing-m)',
				gridTemplateColumns: 'repeat(2, max-content)',
			}}
		>
			{(['s', 'm'] as const).map((size) => (
				<AgenticSplitButton
					{...args}
					id={`agentic-split-${size}`}
					key={size}
					size={size}
				/>
			))}
		</div>
	),
};