mcpField
C
create-element

create-element

github.com/crafter-station设计与 UI52671 次安装11 周前更新
代码仓库

关于 create-element

面向为 Elements registry 创建组件和区块的开发者技能,涵盖脚手架生成、实现、文档和注册;使用 Context7 查询最新依赖文档。

主要功能

  1. 01生成 registry 元素脚手架
  2. 02遵循组件实现模式
  3. 03通过 Context7 查询依赖文档
  4. 04配置 registry 和提供方元数据
  5. 05构建并验证元素

适用场景

  1. 01创建 UI 基础组件或区块
  2. 02添加组件示例
  3. 03编写新类别文档
  4. 04注册并验证组件

MCP 相关

工作流使用 Context7 MCP 工具解析库 ID,并查询外部依赖文档,为组件实现提供依据。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/crafter-station/elements --skill create-element

安装后在 Claude Code 中输入/create-element确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
component-patterns.md
documentation.md
registry-schema.md
scripts/
scaffold-element.ts

详细介绍

创建元素

为 Elements 注册表(tryelements.dev)创建新元素。

快速入门

Step 1: Scaffold
bun run .claude/skills/create-element/scripts/scaffold-element.ts <category> <name>

Step 2: Implement
Edit component following patterns in references/component-patterns.md

Step 3: Register
bun run build:registry && bun run dev

Context7 集成(至关重要)

在实现任何带有外部依赖的组件之前,先获取最新文档:

步骤 1:解析库 ID
mcp__context7__resolve-library-id
  libraryName: "radix-ui"
  query: "dialog component accessibility patterns"
步骤 2:查询特定文档
mcp__context7__query-docs
  libraryId: "/radix-ui/primitives"
  query: "Dialog API controlled vs uncontrolled portal usage"
常用库
库查询内容
radix-ui基础组件(Dialog、Dropdown、Tabs、Select)
next-themes主题提供程序、useTheme hook、水合
cmdk命令面板模式
class-variance-authorityCVA 变体模式
embla-carousel-react轮播图实现
lucide-react图标用法模式

元素类型

类型示例适用场景
registry:uibutton、card、input基础 UI 原语
registry:blocktheme-switcher、polar-checkout功能完整的区块
registry:examplebutton-demo用法示例

参考资料

根据你的工作内容阅读以下资料:

目录结构

registry/default/blocks/{category}/{component-name}/
├── registry-item.json          # Metadata
├── components/
│   └── elements/
│       └── {component}.tsx     # Main component
└── routes/                     # Optional demo routes
    ├── layout.tsx
    └── page.tsx

工作流示例:主题切换器标签页

1. 搭建
bun run .claude/skills/create-element/scripts/scaffold-element.ts theme theme-switcher-tabs
2. 获取文档
mcp__context7__resolve-library-id
  libraryName: "next-themes"
  query: "useTheme hook theme switching"

mcp__context7__query-docs
  libraryId: "/pacocoursey/next-themes"
  query: "useTheme setTheme resolvedTheme hydration"
3. 实现

编辑 registry/default/blocks/theme/theme-switcher-tabs/components/elements/theme-switcher-tabs.tsx:

"use client";

import { useTheme } from "next-themes";
import { useEffect, useState } from "react";
import { cn } from "@/lib/utils";

export function ThemeSwitcherTabs({ className }: { className?: string }) {
  const { theme, setTheme } = useTheme();
  const [mounted, setMounted] = useState(false);

  useEffect(() => { setMounted(true); }, []);

  if (!mounted) return <div className="h-8 w-24 animate-pulse bg-muted rounded" />;

  return (
    <div data-slot="theme-switcher-tabs" className={cn("...", className)}>
      {/* Implementation */}
    </div>
  );
}
4. 更新 registry-item.json
{
  "name": "theme-switcher-tabs",
  "type": "registry:ui",
  "title": "Theme Switcher Tabs",
  "description": "Tab-based theme switcher with Light/Dark/System options",
  "registryDependencies": [],
  "dependencies": ["next-themes"],
  "files": [...],
  "docs": "Requires ThemeProvider. Tab-style theme switcher with system support."
}
5. 构建与测试
bun run build:registry
bun run dev

验证清单

  • registry-item.json 包含所有必需字段($schema、name、type、title、description、files)
  • 组件导出 PascalCase 函数(例如,export function ThemeSwitcherTabs)
  • 使用 cn() 合并 className
  • 根元素具有 data-slot 属性
  • 客户端组件包含 "use client" 指令
  • 使用主题/客户端状态时可安全进行水合
  • bun run build:registry 成功运行
  • 组件在开发环境中渲染正确
  • 如果是新类别:已配置提供程序分组(参见“创建新类别”部分)

命令

# Scaffold new element
bun run .claude/skills/create-element/scripts/scaffold-element.ts <category> <name>

# Build registry
bun run build:registry

# Development server
bun run dev

# Lint/format
bun run lint
bun run format

常用模式

简单组件(无依赖)
import { cn } from "@/lib/utils";

interface BadgeProps extends React.ComponentProps<"span"> {}

export function Badge({ className, ...props }: BadgeProps) {
  return (
    <span
      data-slot="badge"
      className={cn("inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-semibold", className)}
      {...props}
    />
  );
}
使用 CVA 变体
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";

const badgeVariants = cva("inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-semibold", {
  variants: {
    variant: {
      default: "bg-primary text-primary-foreground",
      secondary: "bg-secondary text-secondary-foreground",
      destructive: "bg-destructive text-white",
    },
  },
  defaultVariants: {
    variant: "default",
  },
});

interface BadgeProps extends React.ComponentProps<"span">, VariantProps<typeof badgeVariants> {}

export function Badge({ className, variant, ...props }: BadgeProps) {
  return (
    <span
      data-slot="badge"
      className={cn(badgeVariants({ variant, className }))}
      {...props}
    />
  );
}

export { badgeVariants };
使用外部依赖(Radix)
"use client";

import * as DialogPrimitive from "@radix-ui/react-dialog";
import { cn } from "@/lib/utils";

export function Dialog({ children, ...props }: DialogPrimitive.DialogProps) {
  return <DialogPrimitive.Root {...props}>{children}</DialogPrimitive.Root>;
}

export function DialogTrigger({ className, ...props }: DialogPrimitive.DialogTriggerProps) {
  return <DialogPrimitive.Trigger data-slot="dialog-trigger" className={cn("", className)} {...props} />;
}

需要避免的问题

  • 使用 hook 的组件不要忘记 "use client"
  • 不要硬编码颜色,应使用 CSS 变量(text-foreground、bg-background)
  • 主题相关组件不要跳过水合处理
  • 不要使用 any 类型,应为 props 正确声明类型
  • 修改后不要忘记运行 build:registry

创建新类别(提供程序分组)

创建新的组件类别(而不是在现有类别中添加新组件)时,必须配置提供程序系统,以便在落地页上正确显示。否则,每个组件都会显示为单独的“即将推出”卡片。

适用场景
  • 创建新的集成(例如,charts/、payments/、analytics/)
  • 添加多个应归为一组的相关组件
  • 当前提供程序列表中不存在此类别
必需的双文件配置
1. src/lib/registry-loader.ts

在 getProviderFromName() 中添加分组逻辑(约第 53 行):

// Special case: chart components go to "charts" provider
if (
  name === "area-chart" ||
  name === "bar-chart-vertical" ||
  name === "heatmap-grid" ||
  name === "growth-stats"
) {
  return "charts";
}

在 getProviderMetadata() 中添加提供程序元数据(约第 156 行):

charts: {
  displayName: "Charts",
  description: "Data visualization primitives - area charts, heatmaps, bar charts",
  category: "DATA VIZ",
  brandColor: "#14B8A6",
},
2. src/lib/providers.tsx

在 providerConfig 中添加提供程序配置(约第 46 行):

charts: {
  isEnabled: true,
  displayName: "Charts",
  description: "Data visualization primitives - area charts, heatmaps, bar charts",
  category: "Data Viz",
},

在 ProviderIcon() 中添加提供程序图标(约第 196 行):

charts: <ChartIcon className="w-10 h-10" />,

如有需要,在 src/components/icons/{provider}.tsx 创建图标。

提供方元数据字段
字段示例用途
displayName"Charts"落地页卡片标题
description"Data visualization..."卡片描述
category"DATA VIZ"卡片上显示的徽标
brandColor"#14B8A6"斜线阴影图案颜色
现有提供方(参考)
提供方键显示名称类别
clerkClerkUSER MGMT
polarPolarMONETIZATION
themeTheme SwitcherUI
logosBrand LogosBRAND
uploadthingUploadThingFILES
tinteTinteTHEMING
chartsChartsDATA VIZ
命名约定

默认提取规则会使用连字符前的第一部分:

  • clerk-sign-in → clerk
  • polar-checkout → polar

以下情况请添加特殊处理:

  • 组件属于同一类别,但前缀不同(例如,area-chart、heatmap-grid)
  • 需要自定义提供方名称(例如,theme-switcher-* → theme)
MDX 文档设置

新类别还需要 MDX 文档文件,以确保文档页面正确渲染:

1. 创建演示组件

为每个组件在 /registry/default/examples/{component}-demo.tsx 中创建一个演示:

"use client";

import { MyComponent } from "@/registry/default/blocks/{category}/{component}/components/elements/{component}";

export default function MyComponentDemo() {
  return (
    <div className="flex items-center justify-center p-4">
      <MyComponent />
    </div>
  );
}
2. 在 MDX 组件中注册

在 /src/mdx-components.tsx 中添加导入和映射:

// Add import
import MyComponentDemo from "@/registry/default/examples/my-component-demo";

// Add to getMDXComponents return object
MyComponent: MyComponentDemo,
3. 创建提供方 MDX 文件

创建 /src/content/providers/{provider}.mdx:

---
title: My Provider
description: Description of the category
category: CATEGORY TAG
brandColor: "#hexcolor"
---

## Overview

Brief description.

## Components

### Component Name

<ComponentPreviewItem
  componentKey="component-name"
  installUrl="@elements/component-name"
  category="Category"
  name="Component Name"
>
  <ComponentName />
</ComponentPreviewItem>
4. 创建组件 MDX 文件

为每个组件创建 /src/content/components/{provider}/{component}.mdx:

---
title: Component Name
description: Brief description
---

<ComponentPreviewItem
  componentKey="component-name"
  installUrl="@elements/component-name"
  category="Category"
  name="Component Name"
>
  <ComponentName />
</ComponentPreviewItem>

## Overview

## Installation

## Usage

## Props

## Features

评论

支持 Markdown