shadcn
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseShadcn UI Developer Guide
Shadcn UI 开发者指南
This skill provides guidelines, patterns, and best practices for working with shadcn/ui components in this project.
本技能提供在项目中使用shadcn/ui组件的指导方针、模式和最佳实践。
Quick Start
快速开始
- Core Patterns: Read for comprehensive styling, theming, and component patterns.
references/patterns.md - Tailwind Integration: For Tailwind CSS patterns, use the skill.
tailwindcss
- 核心模式:阅读获取全面的样式、主题和组件模式说明。
references/patterns.md - Tailwind集成:如需Tailwind CSS相关模式,请使用技能。
tailwindcss
Core Philosophy
核心理念
- Ownership: Shadcn is copy-paste, not a dependency - you own the code.
- Customization: Components are meant to be modified for your needs.
- Accessibility: Built on Radix UI primitives for proper accessibility.
- Flexibility: Styled with Tailwind CSS for easy customization.
- 所有权:Shadcn采用复制粘贴的方式,而非依赖包——你完全拥有代码的控制权。
- 可定制性:组件专为按需修改而设计。
- 可访问性:基于Radix UI基础组件构建,确保符合无障碍标准。
- 灵活性:使用Tailwind CSS进行样式设计,便于定制。
Critical: Design Token Usage
重要提示:设计令牌的使用
Always use design system tokens for theme switching compatibility:
Required tokens:
- Backgrounds: ,
bg-background,bg-card,bg-mutedbg-popover - Text: ,
text-foreground,text-muted-foregroundtext-card-foreground - Borders: ,
border-border,border-inputborder-ring - Actions: ,
bg-primary text-primary-foregroundbg-secondary text-secondary-foreground - States: ,
bg-destructive text-destructive-foregroundbg-accent text-accent-foreground
Never use explicit colors like , , - they break theme switching.
bg-whitetext-blackborder-gray-200为保证主题切换兼容性,请始终使用设计系统令牌:
必填令牌:
- 背景:,
bg-background,bg-card,bg-mutedbg-popover - 文本:,
text-foreground,text-muted-foregroundtext-card-foreground - 边框:,
border-border,border-inputborder-ring - 操作:,
bg-primary text-primary-foregroundbg-secondary text-secondary-foreground - 状态:,
bg-destructive text-destructive-foregroundbg-accent text-accent-foreground
切勿使用显式颜色值,例如, , ——这类值会破坏主题切换功能。
bg-whitetext-blackborder-gray-200Common Tasks
常见任务
Adding Components
添加组件
Use the CLI to add components, then customize as needed:
bash
npx shadcn-ui@latest add button card dialog使用CLI添加组件,然后按需定制:
bash
npx shadcn-ui@latest add button card dialogExtending Components
扩展组件
Add custom props and variants while preserving accessibility:
typescript
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
loading?: boolean
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, loading, children, ...props }, ref) => {
return (
<button
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
disabled={loading || props.disabled}
{...props}
>
{loading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
{children}
</button>
)
}
)添加自定义属性和变体,同时保留可访问性:
typescript
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
loading?: boolean
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, loading, children, ...props }, ref) => {
return (
<button
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
disabled={loading || props.disabled}
{...props}
>
{loading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
{children}
</button>
)
}
)Compound Components
复合组件
Always use separate exports, NOT namespaced properties:
tsx
// CORRECT
export const CardTech = CardTechRoot;
export const CardTechHeader = CardHeader;
export const CardTechTitle = CardTitle;
export const CardTechContent = CardContent;
// WRONG - Do not use
export const CardTech = Object.assign(CardTechRoot, {
Header: CardHeader,
Content: CardContent,
});请始终使用单独导出,而非命名空间属性:
tsx
// 正确写法
export const CardTech = CardTechRoot;
export const CardTechHeader = CardHeader;
export const CardTechTitle = CardTitle;
export const CardTechContent = CardContent;
// 错误写法 - 请勿使用
export const CardTech = Object.assign(CardTechRoot, {
Header: CardHeader,
Content: CardContent,
});Preserving Accessibility
保留可访问性
Never remove Radix UI's accessibility attributes:
tsx
<Dialog>
<DialogTrigger asChild>
<Button>Open Dialog</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Accessible Title</DialogTitle>
<DialogDescription>
This description helps screen readers understand the dialog's purpose
</DialogDescription>
</DialogHeader>
</DialogContent>
</Dialog>切勿移除Radix UI的可访问性属性:
tsx
<Dialog>
<DialogTrigger asChild>
<Button>Open Dialog</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Accessible Title</DialogTitle>
<DialogDescription>
This description helps screen readers understand the dialog's purpose
</DialogDescription>
</DialogHeader>
</DialogContent>
</Dialog>Theming
主题定制
Use CSS variables for all color values in :
globals.csscss
@layer base {
:root {
--success: 142 76% 36%;
--success-foreground: 355 100% 100%;
}
.dark {
--success: 142 76% 46%;
--success-foreground: 142 76% 10%;
}
}在中使用CSS变量定义所有颜色值:
globals.csscss
@layer base {
:root {
--success: 142 76% 36%;
--success-foreground: 355 100% 100%;
}
.dark {
--success: 142 76% 46%;
--success-foreground: 142 76% 10%;
}
}Validation Checklist
验证清单
Before finishing a task involving shadcn/ui:
- Verify all colors use design tokens, not explicit values.
- Ensure accessibility attributes from Radix UI are preserved.
- Test keyboard navigation works correctly.
- Use separate exports for compound components (not namespaced).
- Run type checks () and tests (
pnpm run typecheck).pnpm run test
For comprehensive patterns, component examples, and detailed guidelines, read .
references/patterns.md完成涉及shadcn/ui的任务前,请检查以下内容:
- 确认所有颜色均使用设计令牌,而非显式值。
- 确保Radix UI的可访问性属性已保留。
- 测试键盘导航功能正常。
- 复合组件使用单独导出(而非命名空间)。
- 运行类型检查()和测试(
pnpm run typecheck)。pnpm run test
如需获取全面的模式、组件示例和详细指南,请阅读。
references/patterns.md