← All proposals

Spinner: agentic color variant

Extend the existing PDS v2 Spinner (not a new component).

Extends a PDS componentOpen in Storybook

proposals/Spinner/Spinner.stories.tsx99 lines · View on GitHub
import { FlexContainer } from '@pantheon-systems/pds-toolkit-react';
import { Meta, StoryObj } from '@storybook/react-vite';

import { Spinner, SpinnerSize } from './Spinner';

const sizes: SpinnerSize[] = [
	's',
	'm',
	'l',
	'xl',
	'2xl',
	'3xl',
	'4xl',
	'5xl',
	'6xl',
];

const DISCOVERY = 'var(--pds-color-status-discovery-fill)';

const variants = [
	{ color: 'agentic', name: 'Agentic' },
	{ color: DISCOVERY, name: 'Discovery' },
];

const meta: Meta<typeof Spinner> = {
	title: 'Proposals/Spinner',
	component: Spinner,
	parameters: {
		docs: {
			description: {
				component:
					'An animated loading indicator. `color="agentic"` paints it with the AI gradient.',
			},
		},
	},
	argTypes: {
		className: { table: { category: 'Base attributes' } },
		color: {
			control: 'select',
			mapping: { agentic: 'agentic', discovery: DISCOVERY },
			options: ['agentic', 'discovery'],
			table: { category: 'Appearance' },
		},
		isInline: { table: { category: 'Component configuration' } },
		label: { table: { category: 'Content' } },
		showLabel: { table: { category: 'Component configuration' } },
		size: { control: 'select', table: { category: 'Component configuration' } },
	},
	args: {
		color: 'agentic',
		isInline: false,
		label: 'Loading',
		showLabel: false,
		size: '4xl',
	},
};

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {};

export const AllSizes: Story = {
	render: () => (
		<FlexContainer flexDirection='column' gap='xl'>
			{variants.map(({ color, name }) => (
				<FlexContainer alignItems='center' gap='xl' key={name}>
					{sizes.map((size) => (
						<Spinner color={color} key={size} label={name} size={size} />
					))}
				</FlexContainer>
			))}
		</FlexContainer>
	),
};

export const WithLabel: Story = {
	args: { showLabel: true, label: 'Thinking' },
};

export const InlineWithText: Story = {
	render: () => (
		<FlexContainer flexDirection='column' gap='m'>
			{variants.map(({ color, name }) => (
				<FlexContainer alignItems='center' gap='none' key={name}>
					<Spinner
						className='pds-mar-inline-end-xs'
						color={color}
						isInline
						size='m'
					/>
					<span>Text text</span>
				</FlexContainer>
			))}
		</FlexContainer>
	),
};