Loading...
Loading...
Use when creating Storybook stories, naming story exports, organizing story files, or reviewing story naming conventions. Ensures story names describe user scenarios and component states rather than implementation details.
npx skill4agent add peterknezek/skills story-namingplay// User scenarios (typically with play functions)
export const SelectAndApply: Story = {};
export const SearchByKeyword: Story = {};
export const ClearAllSelections: Story = {};
// Component states (typically static/visual)
export const DisabledState: Story = {};
export const WithPreselectedItems: Story = {};
export const EmptyState: Story = {};// Bad - exposes implementation
export const InteractiveDefault: Story = {};
export const InteractiveWithValidation: Story = {};
export const TestSearchFunctionality: Story = {};
export const PlayFunctionForSearch: Story = {};
// Good - describes user scenario
export const Default: Story = {};
export const WithValidation: Story = {};
export const SearchByKeyword: Story = {};
export const SearchAndFilter: Story = {};playplaytitleconst meta = {
title: 'Components/StructuredFilter/SelectOptions',
component: SelectOptions,
} satisfies Meta<typeof SelectOptions>;| Pattern | Use Case |
|---|---|
| Single component stories |
| Visual state variations |
| User interaction flows |
| Feature-level compositions |
import type { Meta, StoryObj } from '@storybook/react';
import { UserProfile } from './UserProfile';
const meta = {
title: 'Components/UserProfile',
component: UserProfile,
} satisfies Meta<typeof UserProfile>;
export default meta;
type Story = StoryObj<typeof UserProfile>;
export const Default: Story = {};
export const WithLongName: Story = {
args: { name: 'Alexandria Bartholomew Richardson III' },
};
export const EmptyState: Story = {
args: { user: null },
};
export const LoadingState: Story = {
args: { isLoading: true },
};// Good - describes the user action
export const FillAndSubmit: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await userEvent.type(canvas.getByLabelText('Email'), 'user@example.com');
await userEvent.click(canvas.getByRole('button', { name: 'Submit' }));
},
};// Bad - exposes implementation detail
export const InteractiveFormSubmission: Story = { ... };
export const PlayFunctionSubmit: Story = { ... };
export const TestFormValidation: Story = { ... };// States file: Components/DataGrid/States
export const Empty: Story = {};
export const WithSingleRow: Story = {};
export const WithPagination: Story = {};
export const DisabledState: Story = {};
// Flows file: Components/DataGrid/Flows
export const SortByColumn: Story = {};
export const FilterAndSearch: Story = {};
export const SelectMultipleRows: Story = {};
export const EditInlineCell: Story = {};| Current Name | Issue | Suggested Name |
|---|---|---|
| Exposes implementation ( | |
| Exposes implementation ( | |
| Exposes implementation ( | |
| Describes state | |
| Describes state | |
| Anti-Pattern | Why It's Bad | Fix |
|---|---|---|
| Play function already signals interactivity | Remove prefix |
| Stories aren't tests, they're demonstrations | Describe the scenario |
| Implementation detail | Describe what happens |
| All stories render | Describe what's rendered |
| Technical jargon in names | Non-technical stakeholders can't understand | Use plain language |