web-component-development

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Web Component Development

Web组件开发

Workflow

工作流

Phase 1: Design Extraction

阶段1:设计提取

Step 1: Overview (you do this yourself)
You MUST personally inspect the design before delegating anything:
  1. Fetch Figma node via MCP (
    get_design_context
    ,
    get_screenshot
    ).
  2. Take a screenshot — study the overall visual: layout structure, hierarchy, proportions, and color balance.
  3. Understand the design intent, component relationships, and visual rhythm.
  4. Identify distinct components or layers that need detailed extraction (e.g. header, card, button, icon group).
Do NOT skip this step or delegate it. You need the high-level context to coordinate subagents effectively.
Step 2: Parallel deep-dive (MUST delegate to subagents)
You MUST spawn subagents in parallel to extract detailed specs for each identified component/layer. Do NOT attempt to extract fine-grained details yourself — subagents have dedicated context for exhaustive spec extraction.
Each subagent extracts:
  • Font: family, weight, size, line-height, letter-spacing, text-align, text-transform, text-decoration.
  • Color: foreground, background (solid/gradient), border, opacity (exact values including alpha).
  • Spacing: padding, margin, gap (every direction).
  • Dimensions: width, height, min/max constraints.
  • Effects: border-radius (per corner), border-width, box-shadow (offset, blur, spread, color), opacity, overflow.
  • Icons: sizing, stroke width, color.
  • States: hover, active, focus, disabled variations if present.
Each subagent should:
  1. Fetch the specific node's
    get_design_context
    and
    get_screenshot
    .
  2. Record ALL specs exhaustively — leave nothing unspecified.
  3. Map Figma tokens to project design system tokens where they exist; use raw values only when no token matches.
  4. Return a structured spec object for the component.
Step 3: Synthesis
Collect and merge all subagent results into a unified design spec before proceeding to implementation.
步骤1:概览(需自行完成)
在委派任何任务前,你必须亲自检查设计:
  1. 通过MCP获取Figma节点(
    get_design_context
    get_screenshot
    )。
  2. 截取截图——研究整体视觉效果:布局结构、层级、比例和色彩平衡。
  3. 理解设计意图、组件关系和视觉节奏。
  4. 识别需要详细提取的独立组件或图层(例如页眉、卡片、按钮、图标组)。
请勿跳过此步骤或委派他人完成。你需要掌握高层上下文才能有效协调子代理。
步骤2:并行深度解析(必须委派给子代理)
你必须并行生成子代理,为每个已识别的组件/图层提取详细规格。请勿尝试自行提取细粒度细节——子代理具备专门的上下文,可进行详尽的规格提取。
每个子代理提取以下内容:
  • 字体:字体系列、字重、字号、行高、字符间距、文本对齐、文本转换、文本装饰。
  • 颜色:前景色、背景色(纯色/渐变)、边框、透明度(包含alpha通道的精确值)。
  • 间距:内边距、外边距、间隙(各个方向)。
  • 尺寸:宽度、高度、最小/最大约束。
  • 效果:圆角(每个角)、边框宽度、盒阴影(偏移量、模糊度、扩散度、颜色)、透明度、溢出。
  • 图标:尺寸、描边宽度、颜色。
  • 状态:若存在悬停、激活、聚焦、禁用等变体则提取。
每个子代理应执行以下操作:
  1. 获取特定节点的
    get_design_context
    get_screenshot
  2. 详尽记录所有规格——不要遗漏任何细节。
  3. 将Figma标记映射到项目设计系统中已有的标记;仅当无匹配标记时使用原始值。
  4. 返回组件的结构化规格对象。
步骤3:合成
在进入实现阶段前,收集并合并所有子代理的结果,形成统一的设计规格。

Phase 2: Implementation

阶段2:实现

Start small. Start simple.
Build the smallest possible working version first with an elegant, minimal API.
  • Do NOT add anything beyond what the design shows — no bonus features, no "improvements", no embellishments.
  • Do NOT write hacky code — if the approach feels wrong, step back and redesign.
  • Do NOT over-engineer for hypothetical future requirements.
Once verified correct, we incrementally add functionality.
Write the component following these principles:
Design fidelity — Faithfully convey the design's intent, not pixel-for-pixel reproduction of static values. Round obviously unreasonable fractional values that are Figma artifacts (e.g.
12.1px
12px
). Adapt static layouts to responsive/interactive reality. The design is a communication, not a specification.
Shallow DOM — Use modern CSS layout (
flex
,
grid
) directly. Avoid wrapper divs that exist only for styling. Every DOM node should carry semantic or layout purpose.
Border & stroke strategy — Choose deliberately:
TechniqueLayout impactWhen to use
border
Yes (shrinks content)When border is part of the sizing model
outline
+ negative
outline-offset
NoNon-layout-affecting focus rings, selection
box-shadow
(inset or outset)
NoDecorative strokes, glow, elevation
Absolute overlay
div
with
pointer-events-none
NoComplex multi-layer strokes on rounded corners
Maintain border-radius concentricity:
inner-radius = outer-radius − border-width
.
Typography — Set every parameter explicitly:
font-family
,
font-weight
,
font-size
,
line-height
,
letter-spacing
,
color
. Do not rely on inherited or default values for components.
Color — Use exact values from Figma including alpha. Prefer
rgba()
or Tailwind opacity modifiers (
text-black/70
) over approximation. Add
dark:
variants for colors that lose contrast on dark backgrounds.
Touch targets — For buttons and clickable elements with small visual footprints, use an absolutely positioned
::after
pseudo-element (or a child div) with negative inset to expand the interactive area to at least 44×44px without affecting layout.
Animations — Use Motion (previously Framer Motion). Always call
useReducedMotion()
and skip or simplify animation when true. This also ensures deterministic screenshot testing.
从小处着手,从简开始。
首先构建最小可运行版本,采用简洁、极简的API。
  • 请勿添加设计未展示的任何内容——无额外功能、无“改进”、无修饰。
  • 请勿编写粗糙代码——若方法感觉有误,请退一步重新设计。
  • 请勿为假设的未来需求过度设计。
在验证正确后,我们逐步添加功能。
遵循以下原则编写组件:
设计保真度——忠实地传达设计的_意图_,而非静态值的像素级复刻。对明显不合理的Figma artifact小数数值进行取整(例如
12.1px
12px
)。使静态布局适配响应式/交互式实际场景。设计是一种沟通方式,而非严格规范。
扁平化DOM——直接使用现代CSS布局(
flex
grid
)。避免仅用于样式的包装div。每个DOM节点都应承载语义或布局用途。
边框与描边策略——谨慎选择:
技术手段布局影响适用场景
border
是(会缩小内容)当边框属于尺寸模型的一部分时
outline
+ 负
outline-offset
不影响布局的聚焦环、选区
box-shadow
(内阴影或外阴影)
装饰性描边、发光效果、层级提升
绝对定位覆盖
div
+
pointer-events-none
圆角上的复杂多层描边
保持圆角同心度:
inner-radius = outer-radius − border-width
排版——显式设置每个参数:
font-family
font-weight
font-size
line-height
letter-spacing
color
。组件请勿依赖继承或默认值。
颜色——使用Figma中的精确值,包括alpha通道。优先使用
rgba()
或Tailwind透明度修饰符(
text-black/70
)而非近似值。为在深色背景上失去对比度的颜色添加
dark:
变体。
触摸目标——对于视觉尺寸较小的按钮和可点击元素,使用绝对定位的
::after
伪元素(或子div)并设置负inset,将交互区域扩展至至少44×44px且不影响布局。
动画——使用Motion(原Framer Motion)。始终调用
useReducedMotion()
,当返回值为true时跳过或简化动画。这也确保了截图测试的确定性。

Phase 3: Stories

阶段3:Storybook故事

Write Storybook stories covering every meaningful variant before visual verification.
  • One story per variant/state.
  • A single composite story that elegantly lays out all variants — just the components themselves, no extra labels or decorations.
  • Use seeded/deterministic data — no
    Math.random()
    or
    Date.now()
    in stories. Use hardcoded values or a seeded PRNG.
Layout mode — Ask: "Am I showing a specimen, or simulating a host?"
ModeWhenExample
centered
Displaying a self-contained component whose size is determined by its contentButton, Badge, Input, Card
fullscreen
Simulating a real page host where the component fills or arranges within spaceDashboard, list page, split-pane, sidebar
Container width — When a component's width semantics depend on "how wide is my host" (Card, Dialog, Form), use a decorator to provide an explicit width container:
tsx
export const Default: Story = {
  decorators: [
    (Story) => (
      <div className="w-[360px] max-w-full">
        <Story />
      </div>
    ),
  ],
};
Do NOT hard-code a width when the component is meant to participate in page-level layout (
w-full
,
flex-1
,
grid
). Instead, provide a layout container that defines the spatial context (fullscreen + padding wrapper,
max-w-*
content area, explicit grid/flex parent).
Rule of thumb: unit component story →
centered
+ explicit wrapper width; page/region component story →
fullscreen
+ layout container
.
在视觉验证前,编写涵盖所有有意义变体的Storybook故事。
  • 每个变体/状态对应一个故事。
  • 一个组合故事,优雅地展示所有变体——仅展示组件本身,无额外标签或装饰。
  • 使用种子化/确定性数据——故事中请勿使用
    Math.random()
    Date.now()
    。使用硬编码值或种子化伪随机数生成器。
布局模式——思考:“我是在展示样本,还是模拟宿主环境?”
模式适用场景示例
centered
展示尺寸由内容决定的独立组件时按钮、徽章、输入框、卡片
fullscreen
模拟真实页面宿主环境,组件填充或排列在空间内时仪表盘、列表页、分栏面板、侧边栏
容器宽度——当组件的宽度语义依赖于“宿主有多宽”时(卡片、对话框、表单),使用装饰器提供明确的宽度容器:
tsx
export const Default: Story = {
  decorators: [
    (Story) => (
      <div className="w-[360px] max-w-full">
        <Story />
      </div>
    ),
  ],
};
当组件需要参与页面级布局时(
w-full
flex-1
grid
),请勿硬编码宽度。相反,提供定义空间上下文的布局容器(全屏+内边距包装器、
max-w-*
内容区域、明确的网格/弹性父容器)。
经验法则:单元组件故事 →
centered
+ 明确的包装器宽度;页面/区域组件故事 →
fullscreen
+ 布局容器

Phase 4: Browser Verification

阶段4:浏览器验证

Always verify every component in the browser before considering it done.
  1. Open the story's iframe URL directly (e.g.
    http://localhost:6006/iframe.html?id=components-button--default
    ) to get the isolated component without Storybook chrome.
  2. Inspect the rendered DOM — confirm every CSS property matches the Figma spec:
    • Font: family, weight, size, line-height, letter-spacing.
    • Color: foreground, background, border, opacity.
    • Spacing: padding, margin, gap — verify computed values, not just class names.
    • Dimensions: width, height, border-radius.
  3. Take a screenshot for visual comparison against the Figma screenshot.
  4. If anything is off, fix it and re-verify. Do not proceed until the component matches.
在完成组件前,务必在浏览器中验证每个组件。
  1. 直接打开故事的iframe URL(例如
    http://localhost:6006/iframe.html?id=components-button--default
    ),获取无Storybook界面的孤立组件。
  2. 检查渲染后的DOM——确认每个CSS属性与Figma规格匹配:
    • 字体:字体系列、字重、字号、行高、字符间距。
    • 颜色:前景色、背景色、边框、透明度。
    • 间距:内边距、外边距、间隙——验证计算值,而非仅类名。
    • 尺寸:宽度、高度、圆角。
  3. 截取截图,与Figma截图进行视觉对比。
  4. 若有任何不符,修复后重新验证。在组件匹配前请勿继续。

Phase 5: Testing

阶段5:测试

Only after browser verification confirms the component is correct:
  1. Write unit tests (React Testing Library) covering rendering, props, accessibility, visual styles.
  2. Update snapshots (
    --update
    flag).
  3. Add visual regression (screenshot) tests if the project uses them.
  4. Run tests and confirm all pass.
仅在浏览器验证确认组件正确后:
  1. 编写单元测试(React Testing Library),涵盖渲染、属性、可访问性、视觉样式。
  2. 更新快照(使用
    --update
    标志)。
  3. 若项目使用视觉回归(截图)测试,则添加此类测试。
  4. 运行测试并确认全部通过。

Phase 6: Commit

阶段6:提交

Only after all tests pass and browser verification is complete:
  1. Run
    pnpm lint && pnpm format
    .
  2. Commit with conventional commit message.
仅在所有测试通过且浏览器验证完成后:
  1. 运行
    pnpm lint && pnpm format
  2. 使用约定式提交信息提交代码。

Decomposition

分解原则

Always build bottom-up: atomic components first, then compose.
  1. Identify the smallest, most reusable pieces (buttons, icons, badges, text styles).
  2. Build each atomic component through the full cycle (implementation → stories → browser verification → tests) independently.
  3. Only after each atomic component is verified and stable, compose them into molecules (card, list item, form field).
  4. Continue composing upward into organisms and full layouts.
Do NOT build top-down by creating a large component and extracting pieces later — this leads to tightly coupled, hard-to-test code.
始终自底向上构建:先构建原子组件,再进行组合。
  1. 识别最小、最可复用的组件(按钮、图标、徽章、文本样式)。
  2. 独立完成每个原子组件的完整流程(实现 → Storybook故事 → 浏览器验证 → 测试)。
  3. 仅在每个原子组件验证通过且稳定后,将它们组合成分子组件(卡片、列表项、表单字段)。
  4. 继续向上组合成组织级组件和完整布局。
请勿自顶向下构建——先创建大型组件再提取部分内容会导致代码耦合紧密、难以测试。

Separation of Concerns

关注点分离

For any component with non-trivial logic, split presentation from logic:
LayerResponsibilityTests
PresentationVisual rendering, styling, layout. Props are primitives and ReactNode. No data fetching, no side effects.Storybook stories, snapshot tests, screenshot tests
ContainerData fetching, state management, event handling. Composes presentation components.Unit tests for logic, integration tests for data flow
Presentation components must render identically given the same props — no internal randomness, no time-dependent rendering.
This separation is NOT optional for complex components. It enables:
  • Independent visual iteration in Storybook without mocking data layers.
  • Logic testing without rendering overhead.
  • Reuse of presentation across different data sources.
对于任何具有非平凡逻辑的组件,将展示层与逻辑层分离:
层级职责测试类型
展示层视觉渲染、样式、布局。属性为基本类型和ReactNode。无数据获取、无副作用。Storybook故事、快照测试、截图测试
容器层数据获取、状态管理、事件处理。组合展示层组件。逻辑单元测试、数据流集成测试
给定相同属性时,展示层组件必须渲染出完全相同的结果——无内部随机性、无时间依赖渲染。
对于复杂组件,此分离是强制性要求。它带来以下好处:
  • 在Storybook中独立进行视觉迭代,无需模拟数据层。
  • 无需渲染开销即可测试逻辑。
  • 展示层可在不同数据源间复用。

Anti-Patterns

反模式

  • Do not commit snapshots/screenshots before browser verification — they lock in wrong output.
  • Do not guess font or color values — always extract from Figma or inspect in browser.
  • Do not add animation without
    useReducedMotion
    guard
    — breaks screenshot tests and a11y.
  • Do not use non-deterministic random data in stories — breaks visual regression.
  • Do not add empty wrapper divs — if a div has only one class for one child, the class belongs on the child.
  • Do not use
    border
    when you need zero layout impact
    — use
    outline
    ,
    box-shadow
    , or an overlay instead.
  • 在浏览器验证前请勿提交快照/截图——这会锁定错误输出。
  • 请勿猜测字体或颜色值——始终从Figma提取或在浏览器中检查。
  • 请勿在无
    useReducedMotion
    防护的情况下添加动画
    ——会破坏截图测试和可访问性。
  • 请勿在故事中使用非确定性随机数据——会破坏视觉回归测试。
  • 请勿添加空包装div——若div仅为一个子元素设置一个类,该类应直接添加到子元素上。
  • 当需要零布局影响时请勿使用
    border
    ——改用
    outline
    box-shadow
    或覆盖层。