Use when refactoring UI code by extracting visual and interactive components, especially after AI-generated pages become bulky, hard to maintain, or have unclear boundaries between page-local, business, shared, and primitive components; 用于重构 UI 代码并抽取包含视觉与交互的组件,尤其是 AI 生成页面臃肿、可维护性差、业务组件与公共组件边界不清时。
这个 skill 用于指导 Codex 抽取包含视觉和交互的 UI 组件。
核心方法是:先从最内侧可交互焦点出发,向外寻找最近的视觉、交互、状态和语义边界,形成组件候选;再根据业务语义、复用性和 API 稳定性决定组件归属层级。
默认行为是先产出组件抽取计划,再修改代码。
以下情况使用本 skill:
以下情况不要使用:
必须按顺序执行:
不要跳过组件抽取计划直接改代码。
从页面中最内侧的焦点开始,向外扩张,直到找到最近的完整 UI 边界。
焦点可以是:
input、button、select、tab、dialog trigger每次向外扩张时检查:
示例:
input
-> input + border + label + error = TextField 候选
-> TextField + button + hint = SearchBox 候选
-> SearchBox + title + description + card shell = SearchPanel 候选
-> SearchPanel + section heading + marketing copy = 页面 section 候选
焦点向外发现法只产生候选,不自动决定公共组件。
最小抽取单元不是单个 DOM 标签,而是具备完整视觉、交互和状态边界的最小 UI 单元。
一个候选组件至少应满足:
判断示例:
input 通常不是最小业务抽取单元;input + border + label + error + help text 才是 TextField 候选button 如果只是样式 primitive,可以是 Button;带 CTA 文案、业务事件或路由时,应保留在业务组件或调用方icon 通常不是组件,除非它来自图标系统或有独立交互状态margin、padding、flex、grid 的 wrapper 不是组件Card 可以是 UI primitive;PricingCard 是业务组件,因为它包含价格、套餐和购买动作如果最小单元无法被清晰命名,不应抽取;应继续向外寻找更完整的边界,或保留在调用方。
遇到以下情况应停止向外扩张:
FlexibleSection、MarketingBlock、CustomCard放置低语义、稳定 API、跨项目或跨页面通用的组件。
适合:
ButtonInputCardBadgeTabsDialog不适合:
放置跨多个页面复用、语义稳定、但高于 UI primitive 的组件。
适合:
SectionHeaderLogoCloudStatCardFeatureGridTestimonialCard必须满足:
放置带业务语义、业务数据结构或业务动作的组件。
适合:
PricingCardPlanComparisonSignupEmailCaptureCheckoutCTAProductFeatureCard判断信号:
放置只服务当前页面叙事或当前页面布局的组件。
适合:
HeroSectionPricingSectionTestimonialsSectionFinalCTASection判断信号:
页面局部组件可以存在,不要为了“看起来像组件”强行放进 shared。
改代码前必须输出计划。
计划至少包含:
候选组件:
当前边界:
焦点来源:
建议层级:
抽取理由:
不放入更高层级的理由:
建议文件位置:
props API:
保留在调用方的内容:
验证方式:
示例:
候选组件: SignupEmailCapture
当前边界: input + button + validation message + loading state
焦点来源: email input
建议层级: business component
抽取理由: 它表达注册转化动作,包含输入、提交、校验和 loading 状态
不放入 shared/ui 的理由: CTA 文案、提交意图和事件属于业务语义
建议文件位置: features/signup/components/signup-email-capture.tsx
props API: value, onChange, onSubmit, status, error
保留在调用方的内容: hero 文案、section 背景、页面布局
验证方式: 提交、错误、loading、键盘 focus 顺序不变
components/ui完成后必须确认:
如果无法验证视觉,应明确说明未验证视觉,只验证了结构或静态检查。