← All proposals

Milestone

Net-new, in two parts, in their own family so "timeline" keeps one meaning (the log).

Net-new componentOpen in Storybook

proposals/Milestone/MilestoneList.stories.tsx95 lines · View on GitHub
import { ComponentType } from 'react';

import { Meta, StoryObj } from '@storybook/react-vite';

import { MilestoneList } from './MilestoneList';
import {
	applicationSiblings,
	billingSiblings,
	milestoneAboveArgs,
	milestoneSlotArgs,
	milestoneStoryArgs,
	milestoneStoryArgTypes,
	milestoneStoryDocs,
	MilestoneStoryArgs,
	MilestoneStoryExample,
	slotSiblings,
	withMilestoneCanvas,
} from './milestone-story-shared';
import { MilestoneVariantsExample } from './MilestoneVariantsExample';

const meta: Meta<MilestoneStoryArgs> = {
	tags: ['new-pattern', 'ready-for-dev'],
	title: 'Component Proposals/Milestones/Milestone List',
	// The args are the props of both components (see `milestone-story-shared`),
	// so the list's type is widened to match.
	component: MilestoneList as unknown as ComponentType<MilestoneStoryArgs>,
	decorators: [withMilestoneCanvas],
	parameters: {
		docs: {
			description: {
				component:
					'**New pattern:** not in PDS v2 today. A list of Milestones hung off one line that runs the full height of the list. It owns the list semantics, the spacing, the line and the card or flat look that its milestones follow. The controls on this page and on the Milestone page are the same: each says which component the prop belongs to. The first milestone is the one the controls change; the others are fixed.',
			},
		},
	},
	argTypes: milestoneStoryArgTypes,
	args: milestoneStoryArgs,
	render: (args) => (
		<MilestoneStoryExample args={args} siblings={applicationSiblings} />
	),
};

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {};

export const Flat: Story = {
	args: { variant: 'flat' },
	parameters: { docs: { description: { story: milestoneStoryDocs.flat } } },
};

// On a canvas under 480px wide (a phone) the subtitle falls back to below the title.
export const SubtitleAtStart: Story = {
	args: { subtitlePosition: 'start' },
	parameters: { docs: { description: { story: milestoneStoryDocs.start } } },
};

// The subtitle above the title, on cards and flat.
export const SubtitleAbove: Story = {
	args: milestoneAboveArgs,
	argTypes: { variant: { control: false } },
	parameters: { docs: { description: { story: milestoneStoryDocs.above } } },
	render: (args) => (
		<MilestoneVariantsExample>
			{(variant) => (
				<MilestoneStoryExample
					args={args}
					siblings={billingSiblings}
					variant={variant}
				/>
			)}
		</MilestoneVariantsExample>
	),
};

// `children` is a slot under the title. What goes in it is up to the screen.
export const Slot: Story = {
	args: milestoneSlotArgs,
	argTypes: { variant: { control: false } },
	parameters: { docs: { description: { story: milestoneStoryDocs.slot } } },
	render: (args) => (
		<MilestoneVariantsExample>
			{(variant) => (
				<MilestoneStoryExample
					args={args}
					siblings={slotSiblings}
					variant={variant}
				/>
			)}
		</MilestoneVariantsExample>
	),
};