CSS开发-创建组件Skill css-development-create-component

CSS组件开发技能,指导前端开发者遵循语义化命名、Tailwind组合、深色模式支持和测试覆盖等最佳实践,创建可复用、可维护的UI组件。关键词:CSS组件开发、Tailwind CSS、语义化命名、深色模式、前端测试、UI设计系统、样式化组件、前端工程化。

前端开发 0 次安装 0 次浏览 更新于 2/28/2026

name: css-development-create-component description: 该技能应在创建新的样式化组件或添加新的CSS类时使用。触发词包括“创建组件”、“新按钮”、“新卡片”、“添加样式”、“样式化组件”、“构建UI元素”。指导语义化命名、Tailwind组合、深色模式支持和测试覆盖。

CSS开发:创建组件

概述

指导您按照既定模式创建新的CSS组件:

  • 语义化类命名
  • 通过 @apply 组合Tailwind工具类
  • 默认支持深色模式
  • 测试覆盖(静态CSS + 组件渲染)
  • 组合优先于创建(重用现有类)

这是 css-development 的一个子技能 - 通常通过主技能自动调用。

适用场景

在以下情况使用:

  • 创建新的样式化组件(按钮、卡片、表单字段等)
  • 向 components.css 添加新的语义化CSS类
  • 构建可复用的UI模式
  • 需要确保深色模式支持和测试覆盖

模式参考

本技能遵循主 css-development 技能中记录的模式。关键模式:

语义化命名: .button-primary 而非 .btn-blue Tailwind组合: 使用 @apply 组合工具类 深色模式: 默认包含 dark: 变体 组合优先: 检查现有类是否可以组合 测试覆盖: 静态CSS测试 + 组件渲染测试

工作流程

当调用此技能时,创建一个TodoWrite清单并逐步完成。

宣布使用

首先,宣布您正在使用此技能:

“我正在使用 css-development:create-component 技能来指导创建这个新的CSS组件。”

创建TodoWrite清单

使用TodoWrite工具创建此清单:

创建CSS组件:
- [ ] 调研现有组件(读取 components.css)
- [ ] 检查组合是否能解决问题(现有类可以组合吗?)
- [ ] 识别组件类型(如果需要新类,则识别原子/分子/有机体)
- [ ] 选择语义化名称(遵循现有命名模式)
- [ ] 编写组件类(使用 @apply,包含 dark: 变体)
- [ ] 创建标记集成(展示React/HTML用法)
- [ ] 编写静态CSS测试(验证类是否存在)
- [ ] 编写组件渲染测试(验证 className 应用)
- [ ] 记录组件(添加使用注释)

逐步详情

步骤1:调研现有组件

操作: 使用Read工具读取 styles/components.css

目的: 了解已存在的内容以确保一致性和识别复用机会

关注点:

  • 可以组合的类似组件
  • 需要遵循的现有命名模式
  • 常见模式(按钮变体、卡片样式等)

开始前标记为 in_progress,完成后标记为 completed。


步骤2:检查组合是否能解决问题

操作: 分析组合现有类是否能达到目标

示例:

  • 想要一个“带图标的按钮”?→ 组合 .button-primary + 间距工具类
  • 想要一个“带阴影的卡片”?→ 如果存在 .card 则使用它,如果需要则添加工具类
  • 想要一个“高亮徽章”?→ 组合 .badge + 颜色工具类

YAGNI原则: 仅当组合不起作用或在标记中产生过多重复时才创建新类。

决策:

  • 如果组合有效: 记录组合并跳过剩余步骤(无需新类)
  • 如果需要新类: 继续步骤3

做出决策后标记为 completed。


步骤3:识别组件类型

操作: 确定原子设计级别(如果创建新类)

原子 - 基本构建块:

  • 单一用途的元素
  • 示例:.button.input.badge.spinner.link

分子 - 组合组件:

  • 组合多个原子
  • 示例:.card.form-field.empty-state.alert

有机体 - 复杂组件:

  • 多个分子 + 原子
  • 示例:.page-layout.navigation.session-card.conversation-timeline

重要性: 有助于界定复杂性和依赖关系

识别类型后标记为 completed。


步骤4:选择语义化名称

操作: 根据现有模式选择描述性、语义化的类名

参考代码库中的命名模式:

  • 基础 + 变体: .button-primary.button-secondary.button-danger
  • 组件 + 子元素: .card-title.card-description.form-field
  • 上下文 + 组件: .session-card.marketing-hero.dashboard-layout
  • 状态修饰符: .session-card-active.button-disabled

反模式(避免):

  • 工具类名称:.btn-blue.card-sm.text-big
  • 缩写:.btn.hdr.desc
  • 通用名称:.component.item.thing

验证: 名称应清晰指示目的并符合现有模式

选择名称后标记为 completed。


步骤5:编写组件类

操作: 使用Edit工具在 styles/components.css 中创建CSS类

模板:

/* [组件名称] - [简要描述]
   用法:<[元素] className="[类名]">[内容]</[元素]> */
.[类名] {
  @apply [背景工具类] [深色模式变体];
  @apply [间距工具类];
  @apply [排版工具类];
  @apply [过渡工具类];
}

必需元素:

  1. 文档注释 - 它是什么,如何使用
  2. 深色模式变体 - 为颜色/背景包含 dark:
  3. 逻辑分组 - 分组相关工具类(背景、间距、排版、过渡)
  4. 交互状态 - 如果适用,包含悬停/焦点/激活状态

示例:

/* 主要按钮 - 具有悬停提升效果的主要行动号召按钮
   用法:<button className="button-primary">点击我</button> */
.button-primary {
  @apply bg-indigo-500 hover:bg-indigo-700 dark:bg-indigo-600 dark:hover:bg-indigo-800;
  @apply px-6 py-3 rounded-lg font-medium text-white;
  @apply transition-all duration-200 hover:-translate-y-0.5;
  @apply focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2;
}

使用Edit工具添加到现有文件(不要覆盖整个文件)

类写入文件后标记为 completed。


步骤6:创建标记集成

操作: 记录如何在不同框架中使用组件

展示以下用法示例:

  • React(如果项目使用React)
  • 原生HTML(始终展示)
  • Vue或其他框架(如果项目使用)

示例文档:

## 使用 button-primary 组件

**React:**
```tsx
const Button = ({ variant = 'primary', className = '', children, ...props }) => {
  const classes = `button-${variant} ${className}`.trim();
  return <button className={classes} {...props}>{children}</button>;
};

// 用法
<Button variant="primary">点击我</Button>
<Button variant="primary" className="w-full">全宽</Button>

原生HTML:

<button class="button-primary">点击我</button>
<button class="button-primary custom-class">带自定义类</button>

**放置位置:** 项目文档、README或组件文件中的注释

**标记示例记录后标记为 completed。**

---

#### 步骤7:编写静态CSS测试

**操作:** 向 `styles/__tests__/components.test.ts` 添加测试(如果不存在则创建)

**目的:** 验证CSS类存在于 components.css 文件中

**测试模式:**
```typescript
import { readFileSync } from 'fs';
import { describe, it, expect } from 'vitest';

describe('components.css', () => {
  const content = readFileSync('styles/components.css', 'utf-8');

  it('应包含 button-primary 组件类', () => {
    expect(content).toContain('.button-primary');
  });

  it('应包含 button-primary 深色模式变体', () => {
    expect(content).toContain('dark:bg-indigo');
  });
});

关键检查:

  • 类存在于文件中
  • 存在深色模式变体(搜索 dark:
  • 存在文档注释(可选但建议)

运行测试:

npm test styles/__tests__/components.test.ts
# 或
vitest styles/__tests__/components.test.ts

预期: 测试通过(绿色)

测试编写并通过后标记为 completed。


步骤8:编写组件渲染测试

操作: 添加组件渲染测试(特定于框架)

目的: 验证 className 在实际组件中的应用

React示例:

import { render, screen } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import { Button } from '@/components/atoms/Button';

describe('Button 组件', () => {
  it('应用 button-primary 类', () => {
    render(<Button variant="primary">点击</Button>);
    expect(screen.getByRole('button')).toHaveClass('button-primary');
  });

  it('接受并应用自定义 className', () => {
    render(<Button variant="primary" className="custom-class">点击</Button>);
    const button = screen.getByRole('button');
    expect(button).toHaveClass('button-primary', 'custom-class');
  });
});

关键检查:

  • 应用了语义化类
  • 可以添加自定义 className
  • 类不冲突

运行测试:

npm test components/atoms/Button.test.tsx
# 或
vitest components/atoms/Button.test.tsx

预期: 测试通过(绿色)

测试编写并通过后标记为 completed。


步骤9:记录组件

操作: 确保组件有使用文档

文档应包含:

  1. CSS中的注释 - 已在步骤5中完成
  2. 标记示例 - 已在步骤6中完成
  3. 组件API(对于框架组件) - 属性、变体等

额外文档(可选但建议):

  • 如果项目有,添加到组件样式指南
  • 如果项目使用,添加到Storybook
  • 添加视觉示例或截图

最低要求: CSS注释 + 标记示例存在

文档验证后标记为 completed。


完成

当所有清单项完成后:

  1. 运行所有测试 以确保一切通过:

    npm test
    
  2. 显示摘要 创建的内容:

    • 组件类名和文件位置
    • 测试文件位置
    • 文档位置
  3. 建议后续步骤:

    • 提交更改
    • 如果需要,创建相关变体
    • 在实际UI中使用组件

示例摘要:

已创建 button-primary 组件!

创建/修改的文件:
- styles/components.css(添加了 .button-primary)
- styles/__tests__/components.test.ts(添加了静态CSS测试)
- components/atoms/Button.test.tsx(添加了渲染测试)
- components/atoms/Button.tsx(标记集成)

后续步骤:
- 提交这些更改:git add . && git commit -m "feat: 添加 button-primary 组件"
- 在您的UI中使用:<Button variant="primary">点击我</Button>
- 如果需要,创建变体:button-secondary、button-danger 等