一键导入
storybook-add-component
Add a new component to Console Storybook with complete documentation, proper patterns, and successful builds
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Add a new component to Console Storybook with complete documentation, proper patterns, and successful builds
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | storybook-add-component |
| description | Add a new component to Console Storybook with complete documentation, proper patterns, and successful builds |
This skill provides comprehensive guidance for adding new components to the Console Storybook with complete documentation, proper patterns, and successful builds.
The Console Storybook documents all UI components in isolation. Each component requires a story file that demonstrates its props, slots, and states. Stories must follow specific patterns and conventions to ensure consistency and successful builds.
Storybook Location:
storybook/src/stories/templates/{ComponentName}.stories.js (JavaScript, NOT TypeScript)Templates/{ComponentName}@/templates/{component-path}/index.vueBuild Command:
yarn storybook:build
Story Structure: All stories use this base structure:
import Component from '@/templates/{component-path}/index.vue';
export default {
title: 'Templates/{ComponentName}',
component: Component,
tags: ['autodocs']
};
export const Default = {
args: {}
};
/src/templates/{component-name}/index.vuedefineProps or props option)<slot> tags in template)defineEmits or $emit)storybook/src/stories/templates/{ComponentName}.stories.js@/templates/ alias pathPattern 1: Minimal Story Use for components with no props or slots:
import Component from '@/templates/component-name/index.vue';
export default {
title: 'Templates/ComponentName',
component: Component,
tags: ['autodocs']
};
export const Default = {
args: {}
};
Pattern 2: Extended Story with Props Use for components with props but no slots:
import Component from '@/templates/component-name/index.vue';
export default {
title: 'Templates/ComponentName',
component: Component,
tags: ['autodocs'],
argTypes: {
prop1: {
control: 'boolean',
description: 'Description of prop1'
},
prop2: {
control: 'text',
description: 'Description of prop2'
},
prop3: {
control: 'select',
options: ['option1', 'option2', 'option3'],
description: 'Description of prop3'
}
},
parameters: {
docs: {
description: {
component: 'Full component description explaining purpose and use cases.'
}
}
}
};
export const Default = {
args: {
prop1: false,
prop2: 'Default text',
prop3: 'option1'
}
};
export const Variant1 = {
args: {
prop1: true,
prop2: 'Different text',
prop3: 'option2'
}
};
Pattern 3: Complex Story with Slots Use for components with slots:
import Component from '@/templates/component-name/index.vue';
export default {
title: 'Templates/ComponentName',
component: Component,
tags: ['autodocs'],
argTypes: {
prop1: {
control: 'boolean',
description: 'Description of prop1'
}
},
parameters: {
docs: {
description: {
component: 'Component description.'
}
}
}
};
export const Default = {
render: (args) => ({
components: { Component },
setup() {
return { args };
},
template: `
<Component v-bind="args">
<template #slotName>
<div>Slot content here</div>
</template>
</Component>
`
}),
args: {
prop1: false
}
};
For each prop in the component, add to argTypes:
control: Type of control (boolean, text, select, number, object)description: Clear, concise description of what the prop doesoptions: Array of options (only for select control)Control Type Mapping:
control: 'boolean'control: 'text'control: 'number'control: 'select' with options arraycontrol: 'object'For each slot in the component, create a story using render function:
export const WithSlots = {
render: (args) => ({
components: { Component },
setup() {
return { args };
},
template: `
<Component v-bind="args">
<template #slotName1>
<div>Content for slot 1</div>
</template>
<template #slotName2>
<div>Content for slot 2</div>
</template>
</Component>
`
}),
args: { ... }
};
Create multiple story exports for different states:
Default - Basic state with typical propsLoading - If component has loading stateDisabled - If component has disabled stateVariant - For each significant prop combinationEdgeCase - For boundary values or special configurationsInclude in parameters.docs.description.component:
When a component uses inject() to receive data from a parent provider (common in dynamic dialogs, modals, or service-based components), you need a wrapper component in the story.
Pattern: Wrapper Component for Dependency Injection
Use this pattern when:
inject('dialogRef') or similarExample - DialogCopyKey component:
import DialogCopyKey from '@/templates/dialog-copy-key/index.vue';
import { ref, provide } from 'vue';
export default {
title: 'Templates/DialogCopyKey',
component: DialogCopyKey,
tags: ['autodocs'],
parameters: {
docs: {
description: {
component: 'A dialog component that uses dialogRef injection for data.'
}
}
}
};
// Wrapper component provides the injection
const DialogWrapper = {
components: { DialogCopyKey },
props: {
title: {
type: String,
default: 'API Key'
},
keyValue: {
type: String,
default: 'sk-1234567890abcdef'
}
},
setup(props) {
// Create the data structure the component expects
const dialogData = ref({
title: props.title,
key: props.keyValue
});
// Create dialogRef that mimics PrimeVue's dynamic dialog
const dialogRef = ref({
data: dialogData.value,
close: () => {
console.log('Dialog closed');
}
});
// Provide the injection
provide('dialogRef', dialogRef);
return {};
},
template: `
<DialogCopyKey />
`
};
export const Default = {
render: () => ({
components: { DialogWrapper },
template: '<DialogWrapper title="Personal Token" keyValue="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." />'
})
};
Why this is needed:
dialogRefCommon scenarios requiring wrappers:
inject('dialogRef') - PrimeVue dynamic dialogsinject('toast') - Toast notification servicesinject('router') - Custom router implementationsinject('store') - Vuex/Pinia store injectionsRun build command and verify success:
yarn storybook:build
Fix any errors before completing.
{ComponentName}.stories.js)@/templates/{component-path}/index.vueargTypes entry with control and descriptionparameters.docs.description.componentTemplates/{ComponentName}yarn storybook:build completes without errorstags: ['autodocs'] included in default export.ts extension for story files (use .js)yarn storybook:build@/templates/ alias)tags: ['autodocs'] in default exportExamples: ActionBarBlock, GoBack
Examples: InfoDrawerBlock, EmptyDrawer
Examples: CreateFormBlock, EditFormBlock
Examples: ToastBlock, MessageNotification
Examples: LoadingBlock, EmptyResultsBlock
Before completing, verify:
.stories.js extension@/templates/ aliasyarn storybook:buildMinimal Example (ContentBlock):
import ContentBlock from '@/templates/content-block/index.vue';
export default {
title: 'Templates/ContentBlock',
component: ContentBlock,
tags: ['autodocs']
};
export const Default = {
args: {}
};
Extended Example (ActionBarBlock):
Complex Example (InfoDrawerBlock):
Interactive Example (ToastBlock):
Build Fails:
Props Not Showing:
Slots Not Rendering:
<template #slotName>Component Uses Dependency Injection:
inject() callsprovide('injectionKey', ref({...})) in wrapper's setupComponent Not Found:
@/templates/ alias.js) not TypeScript@/templates/ maps to /src/templates/