ワンクリックで
storybook-update-component
Update existing Storybook component stories to reflect component changes (props, slots, events)
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Update existing Storybook component stories to reflect component changes (props, slots, events)
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
| name | storybook-update-component |
| description | Update existing Storybook component stories to reflect component changes (props, slots, events) |
This skill provides comprehensive guidance for updating existing component stories in the Console Storybook, ensuring documentation stays synchronized with component changes.
When components are modified (props added/removed, slots changed, events updated), their Storybook stories must be updated to reflect these changes. This skill ensures stories remain accurate, complete, and build successfully.
Storybook Configuration:
storybook/src/stories/templates/{ComponentName}.stories.jsvite.config.js (defines aliases)storybook/.storybook/main.js (resolves aliases)Path Aliases (configured in Storybook):
'@' → '../../src'
'@templates' → '../../src/templates'
'@components' → '../../src/components'
Import Patterns in Stories:
import Component from '@/templates/{component-name}/index.vue'import Component from '@/components/{component-name}/index.vue'Build Command:
yarn storybook:build
The user provides: storybook-update-component @filepath
@src/templates/my-component/index.vue)@storybook/src/stories/templates/MyComponent.stories.js)Read the provided file to determine:
If component file provided:
src/templates/ or src/components/If story file provided:
If package.json export name provided:
Component Location Resolution:
// From story import
import ActionBarBlock from '@/templates/action-bar-block/index.vue'
// Resolves to: src/templates/action-bar-block/index.vue
import SomeComponent from '@/components/some-component/index.vue'
// Resolves to: src/components/some-component/index.vue
Extract from component:
// Vue 3 Composition API
const props = defineProps({
prop1: { type: Boolean, default: false },
prop2: { type: String, default: '' },
prop3: { type: Number, default: 0 }
})
const emit = defineEmits(['update', 'submit'])
// Template
<template>
<div>
<slot name="header"></slot>
<slot>Default slot</slot>
<slot name="footer"></slot>
</div>
</template>
Parse and categorize:
defineProps or props option
<slot> tags in template
defineEmits or $emit calls
Locate story file:
# For templates
storybook/src/stories/templates/{ComponentName}.stories.js
# For components
storybook/src/stories/components/{ComponentName}.stories.js
If story file doesn't exist:
storybook-add-component skill insteadIf story file exists: Read and parse:
title - Component titleargTypes - Prop documentationparameters - Component descriptiontags - Autodocs tagCreate comparison matrix:
| Component Feature | Story Documentation | Status |
|---|---|---|
prop1: Boolean | ✅ in argTypes | MATCH |
prop2: String | ✅ in argTypes | MATCH |
prop3: Number | ❌ missing | MISSING |
slot default | ✅ in render | MATCH |
slot header | ❌ missing | MISSING |
slot footer | ✅ in render | MATCH |
event update | ❌ missing | MISSING |
Categorize changes:
For NEW props:
argTypes: {
// ... existing props
newProp: {
control: 'text', // or 'boolean', 'number', 'select', 'object'
description: 'Description of newProp (inferred from component or generic)'
}
}
For REMOVED props:
argTypes: {
// Remove the deleted prop from argTypes
// Also remove from any story args that use it
}
For MODIFIED props:
argTypes: {
// Update control type if type changed
// Update description if behavior changed
// Update default value in story args
propWithNewType: {
control: 'select', // Changed from 'text'
options: ['option1', 'option2'],
description: 'Updated description'
}
}
For NEW slots:
// Add new story variant demonstrating the slot
export const WithAllSlots = {
render: (args) => ({
components: { Component },
setup() {
return { args };
},
template: `
<Component v-bind="args">
<template #existingSlot>
<div>Existing slot</div>
</template>
<template #newSlot>
<div>New slot content</div>
</template>
</Component>
`
}),
args: { ... }
};
For REMOVED slots:
// Remove slot from render functions
// Remove entire story if it only demonstrated removed slot
For events:
// Events don't have argTypes in Storybook
// Document in parameters.docs.description.component or add to story template
parameters: {
docs: {
description: {
component: `
Component description.
**Events:**
- \`update\`: Emitted when value changes
- \`submit\`: Emitted when form submits
`
}
}
}
For components with dependency injection:
// Component uses inject('dialogRef')
// Story needs a wrapper component to provide the injection
import { ref, provide } from 'vue';
// Wrapper component mimics the provider
const ComponentWrapper = {
components: { Component },
props: {
// Props that will be passed to injected data
prop1: { type: String, default: 'value' }
},
setup(props) {
// Create the injection data
const injectedData = ref({
data: { prop1: props.prop1 },
close: () => console.log('close')
});
// Provide the injection
provide('dialogRef', injectedData);
return {};
},
template: `<Component />`
};
// Story uses wrapper
export const Default = {
render: () => ({
components: { ComponentWrapper },
template: '<ComponentWrapper prop1="value" />'
})
};
When you need a wrapper:
inject('dialogRef') or similarSee Troubleshooting section for more details.
If component purpose changed:
parameters: {
docs: {
description: {
component: 'Updated description reflecting component changes.'
}
}
}
Check existing story variants are still valid:
Update variant stories if needed:
export const Loading = {
args: {
loading: true,
// Add new required props
newProp: 'default value'
}
};
Run build command:
yarn storybook:build
Check for:
If build fails:
Open Storybook:
yarn storybook:dev
Check:
yarn storybook:build completes without errors// Component has prop
const props = defineProps({
newProp: String
})
// Story argTypes doesn't have it
argTypes: {
oldProp: { ... }
// newProp missing!
}
// Component doesn't have prop
const props = defineProps({
existingProp: String
})
// Story argTypes has it
argTypes: {
existingProp: { ... },
removedProp: { ... } // Should be removed!
}
// Component template has slot
<template>
<div>
<slot name="existing"></slot>
<slot name="newSlot"></slot> // New!
</div>
</template>
// Story doesn't show it
template: `
<Component>
<template #existing>...</template>
// #newSlot missing!
</Component>
`
// Component prop type changed
const props = defineProps({
status: {
type: String,
validator: (v) => ['active', 'inactive'].includes(v) // Now enum!
}
})
// Story has wrong control
argTypes: {
status: {
control: 'text' // Should be 'select' with options!
}
}
| Prop Type | Control Type | Additional Config |
|---|---|---|
Boolean | 'boolean' | None |
String | 'text' | None |
String (enum) | 'select' | options: [...] |
Number | 'number' | None |
Array | 'object' | None |
Object | 'object' | None |
Function | 'object' | None |
Date | 'date' | None |
// Component change
const props = defineProps({
disabled: { type: Boolean, default: false } // New prop
})
// Story update
argTypes: {
// ... existing
disabled: {
control: 'boolean',
description: 'Disables the component'
}
}
// Update all story variants
export const Default = {
args: {
// ... existing
disabled: false // Add default
}
};
export const Disabled = { // New variant
args: {
disabled: true
}
};
// Component change
<template>
<div>
<slot></slot>
// <slot name="deprecated"> removed!
</div>
</template>
// Story update
export const Default = {
render: (args) => ({
components: { Component },
setup() {
return { args };
},
template: `
<Component v-bind="args">
// Remove deprecated slot
</Component>
`
}),
args: { ... }
};
// Component change
const props = defineProps({
size: {
type: String,
validator: (v) => ['small', 'medium', 'large'].includes(v) // Changed from any string
}
})
// Story update
argTypes: {
size: {
control: 'select', // Changed from 'text'
options: ['small', 'medium', 'large'],
description: 'Component size'
}
}
// Add size variants
export const Small = {
args: { size: 'small' }
};
export const Medium = {
args: { size: 'medium' }
};
export const Large = {
args: { size: 'large' }
};
Before completing, verify:
yarn storybook:buildStory Not Found:
storybook/src/stories/templates/storybook/src/stories/components/Build Fails After Update:
Props Not Appearing:
Slots Not Rendering:
components: { Component } is included<template #slotName> syntaxWrong Import Path:
@/templates/ for template components@/components/ for other componentsComponent Requires Injection:
If component uses inject() and story fails or renders nothing:
inject('dialogRef') or similarprovide() in wrapper's setup to provide expected injectiondialogRef automatically in productionDebugging Injection Issues:
// Add console.log to understand what component expects
setup() {
const injected = inject('dialogRef');
console.log('Expected injection:', injected);
// This will show undefined if not provided
}
Component change detected:
// New prop added to component
const props = defineProps({
loading: { type: Boolean, default: false },
inDrawer: { type: Boolean, default: false },
cancelDisabled: { type: Boolean, default: false },
primaryActionLabel: { type: String, default: 'Save' },
secondaryActionLabel: { type: String, default: 'Cancel' },
goBack: { type: Function }, // Function prop
size: { type: String, validator: v => ['small', 'medium', 'large'].includes(v) } // New!
})
Story update:
// Read existing story
// Add to argTypes
argTypes: {
// ... existing props
size: { // New!
control: 'select',
options: ['small', 'medium', 'large'],
description: 'Size variant for the action bar'
}
}
// Update story args
export const Default = {
args: {
// ... existing
size: 'medium' // Add default
}
};
// Create new variants
export const Small = {
args: {
loading: false,
size: 'small'
}
};
export const Large = {
args: {
loading: false,
size: 'large'
}
};
Component change detected:
// Component template changed
<template>
<div>
<slot name="header"></slot>
<slot></slot>
// <slot name="deprecated"> removed
</div>
</template>
Story update:
// Find stories using deprecated slot
export const OldStory = {
render: (args) => ({
components: { Component },
setup() {
return { args };
},
template: `
<Component v-bind="args">
<template #header>Header</template>
<template #deprecated>Remove this</template> // Remove!
</Component>
`
}),
args: { ... }
};
// Updated version
export const OldStory = {
render: (args) => ({
components: { Component },
setup() {
return { args };
},
template: `
<Component v-bind="args">
<template #header>Header</template>
</Component>
`
}),
args: { ... }
};
.js) not TypeScript@ maps to /src directory