← All proposals

Menu Button

Starting point for a MenuButton proposal.

Extends a PDS componentOpen in Storybook

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

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

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

const meta: Meta<typeof MenuButton> = {
	title: 'Proposals/Buttons/Menu Button',
	component: MenuButton,
	parameters: {
		docs: {
			description: {
				component: 'A component used to render a button that opens a menu',
			},
		},
	},
	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',
			},
		},
		variant: {
			control: 'select',
			table: {
				category: 'Component configuration',
			},
		},
		iconOnly: {
			control: 'boolean',
			table: {
				category: 'Component configuration',
			},
		},
		isAgentic: {
			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: 'menu-button-example',
		label: 'Menu Button',
		menuItems: complexMenuItems,
		iconOnly: false,
		isAgentic: true,
		size: 's',
		variant: 'primary',
		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',
	},
};