
creating-stories
by coveo
Coveo UI kit repository, home of @coveo/headless, @coveo/atomic, and more.
SKILL.md
name: creating-stories description: Creates and modifies Storybook stories for Atomic components and sample pages. Uses MSW for API mocking, follows ui-kit conventions. Use when creating stories, adding component examples, building sample pages, or when user mentions Storybook, stories, or visual testing. license: Apache-2.0 metadata: author: coveo version: "1.0" package: atomic
Creating Stories
Process
Step 1: Determine Story Type
Answer these questions:
- Is this a single component or a full page?
- Which interface type? (Search, Commerce, Insight, IPX, Recommendations)
- Is this a result template component?
- What API mocking is needed?
Locations:
- Components:
packages/atomic/src/components/<category>/<name>/<name>.new.stories.tsx - Pages:
packages/atomic/storybook-pages/<use-case>/<name>.new.stories.tsx
Step 2: Generate Template
This skill includes a small generator that renders Handlebars templates from .claude/skills/creating-stories/assets/.
# Component story
node .claude/skills/creating-stories/scripts/generate-story-template.mjs \
atomic-component-name --category search
# Result template component
node .claude/skills/creating-stories/scripts/generate-story-template.mjs \
atomic-result-field --category search --result
# Sample page
node .claude/skills/creating-stories/scripts/generate-story-template.mjs \
page-name --type page --category commerce
Allowed values:
--type:component(default),page--category:search(default),commerce,insight,ipx,recommendations
Notes:
--resultis only valid for--type component(using it with--type pageis an error).
Step 3: Complete the Story
- Add API mocking - Configure MSW harness for expected responses
- Create story variants - Add stories for different states (empty, error, selected)
- Add custom props - Set component-specific arguments
- Test interactions - Verify story renders and behaves correctly
For EndpointHarness overview and methods, see endpoint-harness-reference.md.
For advanced API mocking patterns, see msw-patterns.md.
For creating a new API mock domain, see creating-new-api-mock.md.
For component examples, see component-examples.md.
For page examples, see sample-page-examples.md.
Step 4: Validate
# Validate the story file
node .claude/skills/creating-stories/scripts/validate_story.mjs packages/atomic/src/components/.../component.new.stories.tsx
# Run Storybook to verify visually
cd packages/atomic && pnpm storybook
Story Structure
Component Story Anatomy
// 1. Create API harness at top level
const searchApiHarness = new MockSearchApi();
// 2. Get interface wrapper
const {decorator, play} = wrapInSearchInterface();
// 3. Get component helpers
const {events, args, argTypes, template} = getStorybookHelpers('atomic-name');
// 4. Configure meta
const meta: Meta = {
component: 'atomic-name',
decorators: [decorator],
parameters: {
msw: {handlers: [...searchApiHarness.handlers]},
},
beforeEach: () => {
searchApiHarness.searchEndpoint.clear();
},
play,
};
// 5. Export stories
export const Default: Story = {};
API Mocking Patterns
Default response:
// Uses base response automatically
Modify for all stories:
searchApiHarness.searchEndpoint.mock((response) => ({
...response,
results: response.results.slice(0, 10),
}));
Story-specific response:
export const NoResults: Story = {
beforeEach: () => {
searchApiHarness.searchEndpoint.mockOnce((response) => ({
...response,
results: [],
totalCount: 0,
}));
},
};
Available API Mocks
| Mock | Import | Use Case |
|---|---|---|
MockSearchApi | @/storybook-utils/api/search/mock | Search interface |
MockCommerceApi | @/storybook-utils/api/commerce/mock | Commerce interface |
MockInsightApi | @/storybook-utils/api/insight/mock | Insight interface |
MockAnswerApi | @/storybook-utils/api/answer/mock | Answer/RGA |
MockRecommendationApi | @/storybook-utils/api/recommendation/mock | Recommendations |
MockMachineLearningApi | @/storybook-utils/api/machinelearning/mock | ML/User Actions |
Interface Wrappers
| Wrapper | Import | Options |
|---|---|---|
wrapInSearchInterface | @/storybook-utils/search/search-interface-wrapper | skipFirstSearch, includeCodeRoot |
wrapInCommerceInterface | @/storybook-utils/commerce/commerce-interface-wrapper | skipFirstSearch, includeCodeRoot |
wrapInInsightInterface | @/storybook-utils/insight/insight-interface-wrapper | skipFirstSearch |
wrapInResultTemplate | @/storybook-utils/search/result-template-wrapper | autoLoad |
Reference Documentation
| Reference | When to Load |
|---|---|
| endpoint-harness-reference.md | EndpointHarness overview, methods, type safety |
| msw-patterns.md | Advanced MSW techniques, pagination, errors |
| creating-new-api-mock.md | Add a new mock domain when needed |
| component-examples.md | Facets, search box, pager, result components |
| sample-page-examples.md | Full page patterns for all interfaces |
Scripts
| Script | Purpose |
|---|---|
generate-story-template.mjs | Generate story boilerplate from templates |
validate_story.mjs | Validate created story files for correctness |
Templates
Templates in assets/ directory:
component.new.stories.tsx.hbs- Standard component storyresult-component.new.stories.tsx.hbs- Result template componentpage.new.stories.tsx.hbs- Sample page story
Validation Checklist
Before completing:
- Story file named
<component-name>.new.stories.tsx - MSW handlers included in parameters
-
beforeEachclears mocked responses - At least
Defaultstory exported - Component imports use path aliases (
@/storybook-utils/...) - For pages: initialization function and
playhandler included - Story follows patterns from similar components
Common Pitfalls
- Forgetting to clear - Always
harness.endpoint.clear()inbeforeEach - Not spreading base response - Always
{...response, field: value} - Wrong import paths - Use
@/storybook-utils/...not relative paths - Missing handlers - Include all harness handlers in
msw.handlers - Wrong decorator order - Result templates need specific order
Common Edge Cases
MSW Responses Not Being Consumed
Symptom: API calls return default responses instead of mocked ones.
Check:
- Endpoint path in harness matches actual API call
- HTTP method (GET/POST) is correct
- Handlers are included in MSW parameters:
msw: { handlers: [...harness.handlers] }
Responses Returned in Wrong Order
Symptom: Wrong response is returned for a queued sequence.
Solution: Ensure you're clearing in beforeEach, not afterEach:
beforeEach: () => {
harness.searchEndpoint.clear();
// Then enqueue in correct order
}
TypeScript Errors on Response Modification
Symptom: Type errors when modifying response objects.
Solution: Spread base response to maintain all required fields:
mockOnce((response) => ({
...response,
results: [], // Modify only what you need
}))
Multiple Stories Interfere With Each Other
Symptom: Stories fail when run together but pass individually.
Solution: Always clear queued responses in beforeEach:
const meta: Meta = {
beforeEach: () => {
searchApiHarness.searchEndpoint.clear();
// Then queue responses specific to each story
},
};
スコア
総合スコア
リポジトリの品質指標に基づく評価
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
3ヶ月以内に更新がある
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
レビュー
レビュー機能は近日公開予定です