Initial commit
This commit is contained in:
266
skills/backstage-style-web/README.md
Normal file
266
skills/backstage-style-web/README.md
Normal file
@@ -0,0 +1,266 @@
|
||||
# Backstage Style Web Skill
|
||||
|
||||
## 概述
|
||||
|
||||
这个skill基于`backstage-style-web`目录中的企业级设计系统,帮助用户生成现代化的React网站应用。该设计系统基于Radix UI、Tailwind CSS和TypeScript构建,提供了完整的组件库和设计规范。
|
||||
|
||||
## 功能特性
|
||||
|
||||
### 🎨 设计系统
|
||||
- 完整的色彩体系(11级品牌色 + 功能色)
|
||||
- 响应式排版系统(Inter/Poppins字体)
|
||||
- 统一的间距和阴影规范
|
||||
- 支持亮色/暗色主题切换
|
||||
|
||||
### 🧩 组件库
|
||||
- 47+ 企业级React组件
|
||||
- 基于Radix UI的可访问性支持
|
||||
- TypeScript类型安全
|
||||
- CVA变体系统
|
||||
|
||||
### 📱 响应式设计
|
||||
- 移动优先的设计方法
|
||||
- 自适应布局组件
|
||||
- 智能侧边栏(桌面折叠,移动抽屉)
|
||||
- 容器查询支持
|
||||
|
||||
### ♿ 可访问性
|
||||
- ARIA标准支持
|
||||
- 键盘导航
|
||||
- 屏幕阅读器兼容
|
||||
- 焦点管理
|
||||
|
||||
## 应用类型
|
||||
|
||||
### 1. 管理后台 (Admin Dashboards)
|
||||
- 数据可视化面板
|
||||
- 用户管理系统
|
||||
- 分析报告界面
|
||||
- 实时监控台
|
||||
|
||||
### 2. 开发者工具 (Developer Tools)
|
||||
- API文档界面
|
||||
- 配置管理工具
|
||||
- 构建和部署面板
|
||||
- 团队协作平台
|
||||
|
||||
### 3. 数据管理应用 (Data Management)
|
||||
- CRUD操作界面
|
||||
- 高级筛选和搜索
|
||||
- 批量操作功能
|
||||
- 数据导出工具
|
||||
|
||||
### 4. 内容管理系统 (CMS)
|
||||
- 内容创建和编辑
|
||||
- 工作流程管理
|
||||
- 用户权限控制
|
||||
- 发布控制台
|
||||
|
||||
## 技术栈
|
||||
|
||||
```
|
||||
React 18+ + TypeScript
|
||||
├── UI框架: Radix UI Primitives
|
||||
├── 样式: Tailwind CSS + CVA
|
||||
├── 表单: React Hook Form + Zod
|
||||
├── 图标: Lucide React
|
||||
├── 主题: CSS Variables
|
||||
└── 构建: Next.js / Vite
|
||||
```
|
||||
|
||||
## 文件结构
|
||||
|
||||
```
|
||||
.claude/skills/backstage-style-web/
|
||||
├── SKILL.md # 主要skill描述
|
||||
├── README.md # 说明文档
|
||||
├── assets/
|
||||
│ └── component_templates.md # 组件模板库
|
||||
├── references/
|
||||
│ └── design_system_guide.md # 设计系统指南
|
||||
└── examples/
|
||||
└── admin_dashboard_example.md # 完整示例项目
|
||||
```
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 1. 启用Skill
|
||||
```bash
|
||||
# 在Claude Code中使用
|
||||
/skill backstage-style-web
|
||||
```
|
||||
|
||||
### 2. 常见用法示例
|
||||
|
||||
#### 创建管理后台
|
||||
```
|
||||
请帮我创建一个用户管理的管理后台,需要包含:
|
||||
- 用户列表和搜索功能
|
||||
- 添加/编辑用户表单
|
||||
- 用户状态管理
|
||||
- 权限角色分配
|
||||
使用Backstage style。
|
||||
```
|
||||
|
||||
#### 创建数据分析面板
|
||||
```
|
||||
需要一个数据分析面板,包括:
|
||||
- 关键指标卡片
|
||||
- 趋势图表
|
||||
- 实时数据更新
|
||||
- 导出功能
|
||||
使用Backstage design system。
|
||||
```
|
||||
|
||||
#### 创建设置页面
|
||||
```
|
||||
帮我创建一个设置页面,包含:
|
||||
- 个人资料管理
|
||||
- 通知偏好设置
|
||||
- 主题切换
|
||||
- 安全设置
|
||||
使用Backstage风格。
|
||||
```
|
||||
|
||||
## 核心组件示例
|
||||
|
||||
### 页面布局
|
||||
```typescript
|
||||
<SidebarProvider>
|
||||
<Sidebar>
|
||||
<SidebarHeader>App Name</SidebarHeader>
|
||||
<SidebarContent>Navigation</SidebarContent>
|
||||
</Sidebar>
|
||||
<main>
|
||||
<PageLayout title="Dashboard">
|
||||
{content}
|
||||
</PageLayout>
|
||||
</main>
|
||||
</SidebarProvider>
|
||||
```
|
||||
|
||||
### 数据展示
|
||||
```typescript
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Analytics</CardTitle>
|
||||
<CardAction>
|
||||
<Button>Export</Button>
|
||||
</CardAction>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<DataTable data={data} />
|
||||
</CardContent>
|
||||
</Card>
|
||||
```
|
||||
|
||||
### 表单处理
|
||||
```typescript
|
||||
<Form {...form}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="email"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Email</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</Form>
|
||||
```
|
||||
|
||||
## 设计原则
|
||||
|
||||
### 1. 一致性优先
|
||||
- 统一的设计语言
|
||||
- 可预测的交互模式
|
||||
- 标准化的组件API
|
||||
|
||||
### 2. 可访问性
|
||||
- 遵循WCAG 2.1标准
|
||||
- 键盘和屏幕阅读器支持
|
||||
- 语义化HTML结构
|
||||
|
||||
### 3. 性能优化
|
||||
- 组件懒加载
|
||||
- 代码分割
|
||||
- 优化的包大小
|
||||
|
||||
### 4. 开发体验
|
||||
- TypeScript类型安全
|
||||
- 清晰的组件文档
|
||||
- 一致的命名约定
|
||||
|
||||
## 主题配置
|
||||
|
||||
### 色彩系统
|
||||
```css
|
||||
/* 品牌色 */
|
||||
--brand-500: #6a4040; /* 主色 */
|
||||
--brand-600: #553333; /* 悬停色 */
|
||||
|
||||
/* 功能色 */
|
||||
--success: emerald色系
|
||||
--warning: amber色系
|
||||
--danger: rose色系
|
||||
--info: blue色系
|
||||
```
|
||||
|
||||
### 间距系统
|
||||
```css
|
||||
/* 4px基础单位 */
|
||||
spacing/1: 4px /* XS */
|
||||
spacing/4: 16px /* 组件间距 */
|
||||
spacing/6: 24px /* 标准间距 */
|
||||
spacing/8: 32px /* 区块间距 */
|
||||
```
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 1. 组件设计
|
||||
- 优先使用复合组件模式
|
||||
- 保持props接口简洁
|
||||
- 支持as polymorphic属性
|
||||
|
||||
### 2. 样式管理
|
||||
- 使用Tailwind utility classes
|
||||
- CVA处理组件变体
|
||||
- CSS变量支持主题切换
|
||||
|
||||
### 3. 状态管理
|
||||
- React Hook Form处理表单
|
||||
- Context API共享状态
|
||||
- URL状态管理筛选器
|
||||
|
||||
### 4. 性能优化
|
||||
- memo化昂贵组件
|
||||
- 虚拟化长列表
|
||||
- 代码分割路由
|
||||
|
||||
## 更新日志
|
||||
|
||||
### v1.0.0 (2025-10-29)
|
||||
- ✅ 初始版本发布
|
||||
- ✅ 完整的47个组件库
|
||||
- ✅ 设计系统文档
|
||||
- ✅ 管理后台示例
|
||||
- ✅ 组件模板库
|
||||
- ✅ 响应式设计支持
|
||||
- ✅ 可访问性实现
|
||||
|
||||
## 技术支持
|
||||
|
||||
如果在使用过程中遇到问题:
|
||||
|
||||
1. 查看`references/design_system_guide.md`了解设计规范
|
||||
2. 参考`assets/component_templates.md`获取组件模板
|
||||
3. 查看`examples/admin_dashboard_example.md`获取完整示例
|
||||
4. 确保已安装所需的依赖包
|
||||
|
||||
## 许可证
|
||||
|
||||
基于原始的backstage-style-web设计系统,遵循相同的开源许可证。
|
||||
530
skills/backstage-style-web/SKILL.md
Normal file
530
skills/backstage-style-web/SKILL.md
Normal file
@@ -0,0 +1,530 @@
|
||||
---
|
||||
name: backstage-style-web
|
||||
description: Generate enterprise-grade web applications using Backstage Design System. Create admin dashboards, developer tools, and internal applications with modern React components, dark/light themes, and responsive design patterns based on Radix UI and Tailwind CSS.
|
||||
---
|
||||
|
||||
# Backstage Style Web Generator
|
||||
|
||||
## Overview
|
||||
|
||||
Create professional, enterprise-grade web applications using the Backstage Design System. This skill generates modern React applications with TypeScript, featuring comprehensive UI components, dark/light theme support, responsive design, and accessibility-first patterns. Perfect for building admin dashboards, developer tools, internal applications, and data management interfaces.
|
||||
|
||||
# Backstage Design System Implementation Guide
|
||||
|
||||
## Core Architecture Overview
|
||||
|
||||
The Backstage Design System is built on modern React patterns and industry-standard libraries:
|
||||
|
||||
### Technology Stack
|
||||
- **React 18+** with TypeScript
|
||||
- **Radix UI Primitives** for accessible, headless components
|
||||
- **Tailwind CSS** for utility-first styling
|
||||
- **Class Variance Authority (CVA)** for type-safe component variants
|
||||
- **React Hook Form** with Zod validation
|
||||
- **Lucide React** for consistent iconography
|
||||
|
||||
### Key Design Principles
|
||||
|
||||
1. **Accessibility First**: Built on Radix UI primitives with ARIA support
|
||||
2. **Type Safety**: Full TypeScript coverage with strict typing
|
||||
3. **Composability**: Components designed for flexible composition
|
||||
4. **Consistency**: Unified design tokens and patterns
|
||||
5. **Performance**: Optimized for bundle size and runtime performance
|
||||
|
||||
## Component Architecture Patterns
|
||||
|
||||
### 1. Compound Components
|
||||
Components are designed with multiple sub-components for maximum flexibility:
|
||||
|
||||
```typescript
|
||||
// Card component structure
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Title</CardTitle>
|
||||
<CardDescription>Description</CardDescription>
|
||||
<CardAction>Action buttons</CardAction>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
Main content
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
Footer content
|
||||
</CardFooter>
|
||||
</Card>
|
||||
```
|
||||
|
||||
### 2. Variant-Based Styling
|
||||
Using CVA for type-safe, predictable component variants:
|
||||
|
||||
```typescript
|
||||
const buttonVariants = cva(
|
||||
"inline-flex items-center justify-center rounded-md text-sm font-medium",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
||||
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
||||
outline: "border border-input bg-background hover:bg-accent",
|
||||
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
||||
ghost: "hover:bg-accent hover:text-accent-foreground",
|
||||
link: "text-primary underline-offset-4 hover:underline",
|
||||
},
|
||||
size: {
|
||||
default: "h-10 px-4 py-2",
|
||||
sm: "h-9 rounded-md px-3",
|
||||
lg: "h-11 rounded-md px-8",
|
||||
icon: "h-10 w-10",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
size: "default",
|
||||
},
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
### 3. Data Attributes for Styling
|
||||
Consistent use of data attributes for component identification and styling:
|
||||
|
||||
```typescript
|
||||
<div
|
||||
data-slot="card"
|
||||
className="bg-card text-card-foreground rounded-lg border"
|
||||
>
|
||||
<div data-slot="card-header">
|
||||
{/* Header content */}
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Theme System Implementation
|
||||
|
||||
### 1. Color Architecture
|
||||
|
||||
#### Brand Colors (11-step scale)
|
||||
```css
|
||||
:root {
|
||||
--brand-050: #F5F1F0; /* 最浅背景色 */
|
||||
--brand-100: #E9DDDB; /* Hover background / light tint */
|
||||
--brand-200: #D6BEBB; /* Soft background */
|
||||
--brand-300: #B78F8A; /* Subtle brand tint */
|
||||
--brand-400: #94635E; /* Hover / outline */
|
||||
--brand-500: #6A4040; /* Primary brand color */
|
||||
--brand-600: #5B3535; /* Active / pressed */
|
||||
--brand-700: #4C2D2D; /* Stronger contrast */
|
||||
--brand-800: #3E2525; /* Deep background */
|
||||
--brand-900: #2E1C1C; /* Text on light */
|
||||
--brand-950: #1C1010; /* Text on dark / darkest tone */
|
||||
}
|
||||
```
|
||||
|
||||
#### Semantic Color Tokens
|
||||
```css
|
||||
|
||||
:root {
|
||||
/* === Light Mode === */
|
||||
--background: hsl(48, 33%, 98%);
|
||||
--foreground: hsl(0, 25%, 33%);
|
||||
--card: hsl(48, 33%, 98%);
|
||||
--card-foreground: hsl(0, 25%, 33%);
|
||||
--popover: hsl(48, 33%, 98%);
|
||||
--popover-foreground: hsl(0, 25%, 33%);
|
||||
--primary: hsl(222, 28%, 14%);
|
||||
--primary-foreground: hsl(48, 33%, 98%);
|
||||
--secondary: hsl(210, 25%, 96%);
|
||||
--secondary-foreground: hsl(0, 25%, 33%);
|
||||
--muted: hsl(210, 25%, 96%);
|
||||
--muted-foreground: hsl(215, 9%, 46%);
|
||||
--accent: hsl(210, 25%, 96%);
|
||||
--accent-foreground: hsl(0, 25%, 33%);
|
||||
--destructive: hsl(0, 82%, 67%);
|
||||
--destructive-foreground: hsl(48, 33%, 98%);
|
||||
--border: hsl(0, 14%, 94%);
|
||||
--input: hsl(214, 27%, 91%);
|
||||
--ring: hsl(0, 25%, 33%);
|
||||
}
|
||||
|
||||
[data-theme='dark'] {
|
||||
/* === Dark Mode === */
|
||||
--background: hsl(0, 25%, 6%);
|
||||
--foreground: hsl(48, 33%, 98%);
|
||||
--card: hsl(0, 25%, 6%);
|
||||
--card-foreground: hsl(48, 33%, 98%);
|
||||
--popover: hsl(0, 25%, 6%);
|
||||
--popover-foreground: hsl(48, 33%, 98%);
|
||||
--primary: hsl(48, 33%, 98%);
|
||||
--primary-foreground: hsl(0, 25%, 33%);
|
||||
--secondary: hsl(0, 22%, 14%);
|
||||
--secondary-foreground: hsl(48, 33%, 98%);
|
||||
--muted: hsl(0, 22%, 14%);
|
||||
--muted-foreground: hsl(0, 20%, 75%);
|
||||
--accent: hsl(0, 22%, 14%);
|
||||
--accent-foreground: hsl(48, 33%, 98%);
|
||||
--destructive: hsl(0, 82%, 67%);
|
||||
--destructive-foreground: hsl(48, 33%, 98%);
|
||||
--border: hsl(0, 22%, 14%);
|
||||
--input: hsl(0, 22%, 14%);
|
||||
--ring: hsl(0, 25%, 33%);
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
|
||||
### 2. Font Families
|
||||
```css
|
||||
/* Import custom fonts */
|
||||
@font-face {
|
||||
font-family: 'Instrument Serif';
|
||||
src: url('./references/InstrumentSerif-Regular.ttf') format('truetype');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Instrument Serif';
|
||||
src: url('./references/InstrumentSerif-Italic.ttf') format('truetype');
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* Typography Rules */
|
||||
/* Paragraph and text content */
|
||||
p, .text-body, .text-content {
|
||||
font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
}
|
||||
|
||||
/* Headings */
|
||||
h1, h2, h3, h4, h5, h6,
|
||||
.heading-1, .heading-2, .heading-3, .heading-4, .heading-5, .heading-6 {
|
||||
font-family: 'Instrument Serif', Georgia, 'Times New Roman', serif;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
/* Prepositions in headings should use italic */
|
||||
h1 .preposition, h2 .preposition, h3 .preposition,
|
||||
h4 .preposition, h5 .preposition, h6 .preposition,
|
||||
.heading-1 .preposition, .heading-2 .preposition, .heading-3 .preposition,
|
||||
.heading-4 .preposition, .heading-5 .preposition, .heading-6 .preposition {
|
||||
font-style: italic;
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Typography Scale
|
||||
```css
|
||||
.text-xxs { font-size: 8px; } /* Micro text */
|
||||
.text-xs { font-size: 10px; } /* Caption */
|
||||
.text-sm { font-size: 12px; } /* Secondary text */
|
||||
.text-base { font-size: 14px; } /* Default body */
|
||||
.text-lg { font-size: 16px; } /* Paragraph */
|
||||
.display-xl { font-size: 60px; } /* Hero headings */
|
||||
```
|
||||
|
||||
### 4. Spacing System (4px base unit)
|
||||
```css
|
||||
.space-1 { margin: 4px; } /* XS */
|
||||
.space-2 { margin: 8px; } /* SM */
|
||||
.space-3 { margin: 12px; } /* MD */
|
||||
.space-4 { margin: 16px; } /* LG - Component spacing */
|
||||
.space-6 { margin: 24px; } /* Standard spacing */
|
||||
.space-8 { margin: 32px; } /* Section padding */
|
||||
.space-16 { margin: 64px; } /* Large sections */
|
||||
```
|
||||
|
||||
## Responsive Design Strategy
|
||||
|
||||
### 1. Breakpoint System
|
||||
```css
|
||||
/* Mobile-first approach */
|
||||
sm: '640px', /* Small devices */
|
||||
md: '768px', /* Tablets */
|
||||
lg: '1024px', /* Laptops */
|
||||
xl: '1280px', /* Desktops */
|
||||
2xl: '1536px' /* Large screens */
|
||||
```
|
||||
|
||||
### 2. Component Responsiveness
|
||||
```typescript
|
||||
// Example: Responsive grid
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{/* Cards automatically adapt */}
|
||||
</div>
|
||||
|
||||
// Custom mobile hook
|
||||
const isMobile = useIsMobile(); // 768px breakpoint
|
||||
```
|
||||
|
||||
### 3. Sidebar Adaptation
|
||||
```typescript
|
||||
// Desktop: Collapsible sidebar
|
||||
// Mobile: Transforms to sheet/drawer
|
||||
{isMobile ? (
|
||||
<Sheet open={openMobile} onOpenChange={setOpenMobile}>
|
||||
<SheetContent side="left" className="p-0">
|
||||
<SidebarContent />
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
) : (
|
||||
<Sidebar className={cn(
|
||||
"transition-all duration-300",
|
||||
state === "collapsed" ? "w-[48px]" : "w-[256px]"
|
||||
)}>
|
||||
<SidebarContent />
|
||||
</Sidebar>
|
||||
)}
|
||||
```
|
||||
|
||||
## Accessibility Implementation
|
||||
|
||||
### 1. ARIA Patterns
|
||||
```typescript
|
||||
// Proper ARIA labeling
|
||||
<button
|
||||
aria-label="Close dialog"
|
||||
aria-expanded={isOpen}
|
||||
aria-controls="dialog-content"
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
</button>
|
||||
|
||||
// Form accessibility
|
||||
<label htmlFor="email" className="sr-only">
|
||||
Email address
|
||||
</label>
|
||||
<input
|
||||
id="email"
|
||||
type="email"
|
||||
aria-describedby="email-description"
|
||||
aria-invalid={hasError}
|
||||
/>
|
||||
<div id="email-description" className="text-sm text-muted-foreground">
|
||||
We'll never share your email
|
||||
</div>
|
||||
```
|
||||
|
||||
### 2. Keyboard Navigation
|
||||
```typescript
|
||||
// Custom keyboard event handling
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (event: KeyboardEvent) => {
|
||||
if (event.key === 'Escape') {
|
||||
onClose();
|
||||
}
|
||||
if (event.key === 'Enter' || event.key === ' ') {
|
||||
onActivate();
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('keydown', handleKeyDown);
|
||||
return () => document.removeEventListener('keydown', handleKeyDown);
|
||||
}, [onClose, onActivate]);
|
||||
```
|
||||
|
||||
### 3. Focus Management
|
||||
```typescript
|
||||
// Focus trap for modals
|
||||
import { FocusTrap } from '@radix-ui/react-focus-trap';
|
||||
|
||||
<FocusTrap asChild>
|
||||
<div className="modal-content">
|
||||
{/* Modal content with proper focus order */}
|
||||
</div>
|
||||
</FocusTrap>
|
||||
```
|
||||
|
||||
## Form Architecture
|
||||
|
||||
### 1. React Hook Form Integration
|
||||
```typescript
|
||||
import { useForm } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import * as z from "zod";
|
||||
|
||||
const formSchema = z.object({
|
||||
email: z.string().email("Invalid email address"),
|
||||
password: z.string().min(8, "Password must be at least 8 characters"),
|
||||
});
|
||||
|
||||
type FormData = z.infer<typeof formSchema>;
|
||||
|
||||
const form = useForm<FormData>({
|
||||
resolver: zodResolver(formSchema),
|
||||
defaultValues: {
|
||||
email: "",
|
||||
password: "",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### 2. Form Field Component Pattern
|
||||
```typescript
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="email"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Email</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="Enter your email" {...field} />
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
We'll use this to send you updates
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
```
|
||||
|
||||
## State Management Patterns
|
||||
|
||||
### 1. Component State
|
||||
```typescript
|
||||
// Local state for UI interactions
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [selectedItems, setSelectedItems] = useState<string[]>([]);
|
||||
|
||||
// Derived state
|
||||
const hasSelection = selectedItems.length > 0;
|
||||
const allSelected = selectedItems.length === items.length;
|
||||
```
|
||||
|
||||
### 2. Context for Shared State
|
||||
```typescript
|
||||
// Theme context
|
||||
const ThemeContext = createContext<{
|
||||
theme: Theme;
|
||||
setTheme: (theme: Theme) => void;
|
||||
} | null>(null);
|
||||
|
||||
// Sidebar context
|
||||
const SidebarContext = createContext<{
|
||||
state: "expanded" | "collapsed";
|
||||
open: boolean;
|
||||
setOpen: (open: boolean) => void;
|
||||
isMobile: boolean;
|
||||
} | null>(null);
|
||||
```
|
||||
|
||||
### 3. URL State Management
|
||||
```typescript
|
||||
// For filters, search, pagination
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
|
||||
const currentPage = Number(searchParams.get('page')) || 1;
|
||||
const searchQuery = searchParams.get('q') || '';
|
||||
|
||||
const updateFilters = (filters: Record<string, string>) => {
|
||||
const newParams = new URLSearchParams(searchParams);
|
||||
Object.entries(filters).forEach(([key, value]) => {
|
||||
if (value) {
|
||||
newParams.set(key, value);
|
||||
} else {
|
||||
newParams.delete(key);
|
||||
}
|
||||
});
|
||||
setSearchParams(newParams);
|
||||
};
|
||||
```
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### 1. Code Splitting
|
||||
```typescript
|
||||
// Lazy loading for routes
|
||||
const Dashboard = lazy(() => import('./pages/Dashboard'));
|
||||
const Settings = lazy(() => import('./pages/Settings'));
|
||||
|
||||
// Wrap in Suspense
|
||||
<Suspense fallback={<LoadingSpinner />}>
|
||||
<Routes>
|
||||
<Route path="/dashboard" element={<Dashboard />} />
|
||||
<Route path="/settings" element={<Settings />} />
|
||||
</Routes>
|
||||
</Suspense>
|
||||
```
|
||||
|
||||
### 2. Memoization
|
||||
```typescript
|
||||
// Expensive calculations
|
||||
const processedData = useMemo(() => {
|
||||
return data.map(item => ({
|
||||
...item,
|
||||
computed: expensiveComputation(item)
|
||||
}));
|
||||
}, [data]);
|
||||
|
||||
// Callback memoization
|
||||
const handleItemClick = useCallback((id: string) => {
|
||||
setSelectedItems(prev =>
|
||||
prev.includes(id)
|
||||
? prev.filter(item => item !== id)
|
||||
: [...prev, id]
|
||||
);
|
||||
}, []);
|
||||
|
||||
// Component memoization
|
||||
const MemoizedTableRow = memo(TableRow);
|
||||
```
|
||||
|
||||
### 3. Virtual Scrolling (for large lists)
|
||||
```typescript
|
||||
import { FixedSizeList as List } from 'react-window';
|
||||
|
||||
const VirtualizedTable = ({ items }: { items: any[] }) => {
|
||||
const Row = ({ index, style }: { index: number; style: React.CSSProperties }) => (
|
||||
<div style={style}>
|
||||
<TableRow data={items[index]} />
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<List
|
||||
height={600}
|
||||
itemCount={items.length}
|
||||
itemSize={50}
|
||||
width="100%"
|
||||
>
|
||||
{Row}
|
||||
</List>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
## Testing Patterns
|
||||
|
||||
### 1. Component Testing
|
||||
```typescript
|
||||
import { render, screen, fireEvent } from '@testing-library/react';
|
||||
import { Button } from './button';
|
||||
|
||||
describe('Button', () => {
|
||||
it('renders with correct variant styles', () => {
|
||||
render(<Button variant="destructive">Delete</Button>);
|
||||
const button = screen.getByRole('button');
|
||||
expect(button).toHaveClass('bg-destructive');
|
||||
});
|
||||
|
||||
it('handles click events', () => {
|
||||
const handleClick = jest.fn();
|
||||
render(<Button onClick={handleClick}>Click me</Button>);
|
||||
fireEvent.click(screen.getByRole('button'));
|
||||
expect(handleClick).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### 2. Accessibility Testing
|
||||
```typescript
|
||||
import { axe, toHaveNoViolations } from 'jest-axe';
|
||||
|
||||
expect.extend(toHaveNoViolations);
|
||||
|
||||
it('should not have accessibility violations', async () => {
|
||||
const { container } = render(<MyComponent />);
|
||||
const results = await axe(container);
|
||||
expect(results).toHaveNoViolations();
|
||||
});
|
||||
```
|
||||
|
||||
This implementation guide provides the foundation for building consistent, accessible, and performant applications using the Backstage Design System.
|
||||
980
skills/backstage-style-web/assets/component_templates.md
Normal file
980
skills/backstage-style-web/assets/component_templates.md
Normal file
@@ -0,0 +1,980 @@
|
||||
# Backstage Style Component Templates
|
||||
|
||||
## Core Page Templates
|
||||
|
||||
### 1. Dashboard Page Template
|
||||
|
||||
```typescript
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardHeader, CardTitle, CardAction } from "@/components/ui/card";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
||||
import { MoreHorizontal, Plus, Search, Filter, Download } from "lucide-react";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
|
||||
interface DashboardData {
|
||||
id: string;
|
||||
name: string;
|
||||
status: "active" | "inactive" | "pending";
|
||||
value: number;
|
||||
lastUpdated: string;
|
||||
}
|
||||
|
||||
export default function DashboardPage() {
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
const [data, setData] = useState<DashboardData[]>([
|
||||
// Sample data
|
||||
{ id: "1", name: "Project Alpha", status: "active", value: 12450, lastUpdated: "2 hours ago" },
|
||||
{ id: "2", name: "Project Beta", status: "pending", value: 8900, lastUpdated: "1 day ago" },
|
||||
{ id: "3", name: "Project Gamma", status: "inactive", value: 3200, lastUpdated: "3 days ago" },
|
||||
]);
|
||||
|
||||
const filteredData = data.filter(item =>
|
||||
item.name.toLowerCase().includes(searchTerm.toLowerCase())
|
||||
);
|
||||
|
||||
const statusVariant = (status: string) => {
|
||||
switch (status) {
|
||||
case "active": return "default";
|
||||
case "pending": return "secondary";
|
||||
case "inactive": return "outline";
|
||||
default: return "secondary";
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex-1 space-y-4 p-4 md:p-8 pt-6">
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h2 className="text-3xl font-bold tracking-tight">Dashboard</h2>
|
||||
<p className="text-muted-foreground">
|
||||
Manage your projects and monitor performance
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<Button variant="outline" size="sm">
|
||||
<Download className="mr-2 h-4 w-4" />
|
||||
Export
|
||||
</Button>
|
||||
<Button size="sm">
|
||||
<Plus className="mr-2 h-4 w-4" />
|
||||
Add Project
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Stats Cards */}
|
||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">Total Projects</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">24</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
+2 from last month
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">Active Projects</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">18</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
+4 from last month
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">Total Value</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">$24,550</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
+12% from last month
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">Completion Rate</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">89%</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
+3% from last month
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Data Table */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Projects</CardTitle>
|
||||
<CardAction>
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="relative">
|
||||
<Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
placeholder="Search projects..."
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
className="pl-8 w-[300px]"
|
||||
/>
|
||||
</div>
|
||||
<Button variant="outline" size="sm">
|
||||
<Filter className="mr-2 h-4 w-4" />
|
||||
Filter
|
||||
</Button>
|
||||
</div>
|
||||
</CardAction>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="rounded-md border">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>Name</TableHead>
|
||||
<TableHead>Status</TableHead>
|
||||
<TableHead>Value</TableHead>
|
||||
<TableHead>Last Updated</TableHead>
|
||||
<TableHead className="w-[70px]">Actions</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{filteredData.map((item) => (
|
||||
<TableRow key={item.id}>
|
||||
<TableCell className="font-medium">{item.name}</TableCell>
|
||||
<TableCell>
|
||||
<Badge variant={statusVariant(item.status)}>
|
||||
{item.status}
|
||||
</Badge>
|
||||
</TableCell>
|
||||
<TableCell>${item.value.toLocaleString()}</TableCell>
|
||||
<TableCell className="text-muted-foreground">
|
||||
{item.lastUpdated}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" size="sm">
|
||||
<MoreHorizontal className="h-4 w-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuItem>Edit</DropdownMenuItem>
|
||||
<DropdownMenuItem>Duplicate</DropdownMenuItem>
|
||||
<DropdownMenuItem className="text-red-600">
|
||||
Delete
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Form Page Template
|
||||
|
||||
```typescript
|
||||
"use client";
|
||||
|
||||
import { useForm } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import * as z from "zod";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
FormDescription,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { toast } from "@/components/ui/use-toast";
|
||||
|
||||
const formSchema = z.object({
|
||||
title: z.string().min(2, "Title must be at least 2 characters"),
|
||||
description: z.string().min(10, "Description must be at least 10 characters"),
|
||||
category: z.string().min(1, "Please select a category"),
|
||||
priority: z.enum(["low", "medium", "high"]),
|
||||
isPublic: z.boolean().default(false),
|
||||
tags: z.array(z.string()).optional(),
|
||||
email: z.string().email("Invalid email address"),
|
||||
});
|
||||
|
||||
type FormData = z.infer<typeof formSchema>;
|
||||
|
||||
export default function FormPage() {
|
||||
const form = useForm<FormData>({
|
||||
resolver: zodResolver(formSchema),
|
||||
defaultValues: {
|
||||
title: "",
|
||||
description: "",
|
||||
category: "",
|
||||
priority: "medium",
|
||||
isPublic: false,
|
||||
tags: [],
|
||||
email: "",
|
||||
},
|
||||
});
|
||||
|
||||
function onSubmit(values: FormData) {
|
||||
toast({
|
||||
title: "Form submitted successfully!",
|
||||
description: "Your data has been saved.",
|
||||
});
|
||||
console.log(values);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex-1 space-y-4 p-4 md:p-8 pt-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h2 className="text-3xl font-bold tracking-tight">Create New Item</h2>
|
||||
<p className="text-muted-foreground">
|
||||
Fill out the form below to create a new item
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-4 md:grid-cols-3">
|
||||
{/* Main Form */}
|
||||
<div className="md:col-span-2">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Item Details</CardTitle>
|
||||
<CardDescription>
|
||||
Provide the basic information for your new item
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="title"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Title</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="Enter a title" {...field} />
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
This will be the display name for your item.
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="description"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Description</FormLabel>
|
||||
<FormControl>
|
||||
<Textarea
|
||||
placeholder="Enter a description"
|
||||
className="min-h-[100px]"
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
Provide a detailed description of your item.
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="category"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Category</FormLabel>
|
||||
<Select onValueChange={field.onChange} defaultValue={field.value}>
|
||||
<FormControl>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select a category" />
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
<SelectItem value="web">Web Development</SelectItem>
|
||||
<SelectItem value="mobile">Mobile Development</SelectItem>
|
||||
<SelectItem value="design">Design</SelectItem>
|
||||
<SelectItem value="marketing">Marketing</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="email"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Email</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="Enter email address" {...field} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="priority"
|
||||
render={({ field }) => (
|
||||
<FormItem className="space-y-3">
|
||||
<FormLabel>Priority Level</FormLabel>
|
||||
<FormControl>
|
||||
<RadioGroup
|
||||
onValueChange={field.onChange}
|
||||
defaultValue={field.value}
|
||||
className="flex flex-row space-x-6"
|
||||
>
|
||||
<div className="flex items-center space-x-2">
|
||||
<RadioGroupItem value="low" id="low" />
|
||||
<Label htmlFor="low">Low</Label>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<RadioGroupItem value="medium" id="medium" />
|
||||
<Label htmlFor="medium">Medium</Label>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<RadioGroupItem value="high" id="high" />
|
||||
<Label htmlFor="high">High</Label>
|
||||
</div>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="isPublic"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex flex-row items-center justify-between rounded-lg border p-4">
|
||||
<div className="space-y-0.5">
|
||||
<FormLabel className="text-base">
|
||||
Make Public
|
||||
</FormLabel>
|
||||
<FormDescription>
|
||||
Allow others to view this item publicly.
|
||||
</FormDescription>
|
||||
</div>
|
||||
<FormControl>
|
||||
<Switch
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<div className="flex gap-3">
|
||||
<Button type="submit">Create Item</Button>
|
||||
<Button type="button" variant="outline">
|
||||
Save as Draft
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</Form>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Sidebar Info */}
|
||||
<div className="space-y-4">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Help</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Need help? Check out our documentation or contact support.
|
||||
</p>
|
||||
<div className="mt-4 space-y-2">
|
||||
<Button variant="outline" size="sm" className="w-full">
|
||||
View Documentation
|
||||
</Button>
|
||||
<Button variant="outline" size="sm" className="w-full">
|
||||
Contact Support
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Quick Stats</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-sm text-muted-foreground">Total Items</span>
|
||||
<span className="text-sm font-medium">247</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-sm text-muted-foreground">This Month</span>
|
||||
<span className="text-sm font-medium">18</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-sm text-muted-foreground">Published</span>
|
||||
<span className="text-sm font-medium">156</span>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Settings Page Template
|
||||
|
||||
```typescript
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { Bell, Shield, User, Palette, Globe } from "lucide-react";
|
||||
|
||||
export default function SettingsPage() {
|
||||
const [notifications, setNotifications] = useState({
|
||||
email: true,
|
||||
push: false,
|
||||
marketing: true,
|
||||
});
|
||||
|
||||
const [theme, setTheme] = useState("system");
|
||||
|
||||
return (
|
||||
<div className="flex-1 space-y-4 p-4 md:p-8 pt-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h2 className="text-3xl font-bold tracking-tight">Settings</h2>
|
||||
<p className="text-muted-foreground">
|
||||
Manage your account settings and preferences
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Tabs defaultValue="general" className="space-y-4">
|
||||
<TabsList className="grid w-full grid-cols-5">
|
||||
<TabsTrigger value="general" className="flex items-center gap-2">
|
||||
<User className="h-4 w-4" />
|
||||
General
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="notifications" className="flex items-center gap-2">
|
||||
<Bell className="h-4 w-4" />
|
||||
Notifications
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="appearance" className="flex items-center gap-2">
|
||||
<Palette className="h-4 w-4" />
|
||||
Appearance
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="privacy" className="flex items-center gap-2">
|
||||
<Shield className="h-4 w-4" />
|
||||
Privacy
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="advanced" className="flex items-center gap-2">
|
||||
<Globe className="h-4 w-4" />
|
||||
Advanced
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="general" className="space-y-4">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Profile Information</CardTitle>
|
||||
<CardDescription>
|
||||
Update your personal information and profile details
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-6">
|
||||
<div className="flex items-center space-x-4">
|
||||
<Avatar className="h-20 w-20">
|
||||
<AvatarImage src="/avatars/01.png" />
|
||||
<AvatarFallback>JD</AvatarFallback>
|
||||
</Avatar>
|
||||
<div className="space-y-2">
|
||||
<Button variant="outline" size="sm">
|
||||
Change Avatar
|
||||
</Button>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
JPG, GIF or PNG. 1MB max.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="firstName">First Name</Label>
|
||||
<Input id="firstName" defaultValue="John" />
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="lastName">Last Name</Label>
|
||||
<Input id="lastName" defaultValue="Doe" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="email">Email</Label>
|
||||
<Input id="email" type="email" defaultValue="john@example.com" />
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="bio">Bio</Label>
|
||||
<Input id="bio" defaultValue="Software developer and designer" />
|
||||
</div>
|
||||
|
||||
<Button>Save Changes</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="notifications" className="space-y-4">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Notification Preferences</CardTitle>
|
||||
<CardDescription>
|
||||
Choose what notifications you want to receive
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="space-y-0.5">
|
||||
<Label className="text-base">Email Notifications</Label>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Receive notifications via email
|
||||
</p>
|
||||
</div>
|
||||
<Switch
|
||||
checked={notifications.email}
|
||||
onCheckedChange={(checked) =>
|
||||
setNotifications(prev => ({ ...prev, email: checked }))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="space-y-0.5">
|
||||
<Label className="text-base">Push Notifications</Label>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Receive push notifications on your devices
|
||||
</p>
|
||||
</div>
|
||||
<Switch
|
||||
checked={notifications.push}
|
||||
onCheckedChange={(checked) =>
|
||||
setNotifications(prev => ({ ...prev, push: checked }))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="space-y-0.5">
|
||||
<Label className="text-base">Marketing Emails</Label>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Receive emails about new features and updates
|
||||
</p>
|
||||
</div>
|
||||
<Switch
|
||||
checked={notifications.marketing}
|
||||
onCheckedChange={(checked) =>
|
||||
setNotifications(prev => ({ ...prev, marketing: checked }))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="appearance" className="space-y-4">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Theme Preferences</CardTitle>
|
||||
<CardDescription>
|
||||
Customize the appearance of your interface
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-6">
|
||||
<div className="space-y-2">
|
||||
<Label>Theme</Label>
|
||||
<Select value={theme} onValueChange={setTheme}>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="light">Light</SelectItem>
|
||||
<SelectItem value="dark">Dark</SelectItem>
|
||||
<SelectItem value="system">System</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Choose your preferred theme or sync with your system
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label>Language</Label>
|
||||
<Select defaultValue="en">
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="en">English</SelectItem>
|
||||
<SelectItem value="zh">中文</SelectItem>
|
||||
<SelectItem value="es">Español</SelectItem>
|
||||
<SelectItem value="fr">Français</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="privacy" className="space-y-4">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Privacy Settings</CardTitle>
|
||||
<CardDescription>
|
||||
Control your privacy and data sharing preferences
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="space-y-0.5">
|
||||
<Label className="text-base">Profile Visibility</Label>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Make your profile visible to other users
|
||||
</p>
|
||||
</div>
|
||||
<Switch defaultChecked />
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="space-y-0.5">
|
||||
<Label className="text-base">Analytics</Label>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Help us improve by sharing usage analytics
|
||||
</p>
|
||||
</div>
|
||||
<Switch defaultChecked />
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
<div className="space-y-4">
|
||||
<Label className="text-base">Data Export</Label>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Download a copy of your data
|
||||
</p>
|
||||
<Button variant="outline">Request Data Export</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="advanced" className="space-y-4">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Advanced Settings</CardTitle>
|
||||
<CardDescription>
|
||||
Advanced configuration options for power users
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-6">
|
||||
<div className="space-y-2">
|
||||
<Label>API Access</Label>
|
||||
<div className="flex items-center space-x-2">
|
||||
<Input
|
||||
readOnly
|
||||
value="sk-1234567890abcdef"
|
||||
className="font-mono text-sm"
|
||||
/>
|
||||
<Button variant="outline" size="sm">
|
||||
Copy
|
||||
</Button>
|
||||
<Button variant="outline" size="sm">
|
||||
Regenerate
|
||||
</Button>
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Use this API key to access our services programmatically
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
<div className="space-y-4">
|
||||
<Label className="text-base text-red-600">Danger Zone</Label>
|
||||
<div className="border border-red-200 rounded-lg p-4 space-y-4">
|
||||
<div>
|
||||
<h4 className="font-medium">Delete Account</h4>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Permanently delete your account and all data
|
||||
</p>
|
||||
</div>
|
||||
<Button variant="destructive" size="sm">
|
||||
Delete Account
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Component Building Blocks
|
||||
|
||||
### 1. Data Display Card
|
||||
|
||||
```typescript
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
interface DataCardProps {
|
||||
title: string;
|
||||
value: string | number;
|
||||
description?: string;
|
||||
trend?: "up" | "down" | "neutral";
|
||||
trendValue?: string;
|
||||
action?: React.ReactNode;
|
||||
}
|
||||
|
||||
export function DataCard({
|
||||
title,
|
||||
value,
|
||||
description,
|
||||
trend,
|
||||
trendValue,
|
||||
action
|
||||
}: DataCardProps) {
|
||||
const trendColor = {
|
||||
up: "text-green-600",
|
||||
down: "text-red-600",
|
||||
neutral: "text-muted-foreground",
|
||||
};
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">{title}</CardTitle>
|
||||
{action}
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">{value}</div>
|
||||
{(description || trendValue) && (
|
||||
<p className={`text-xs ${trend ? trendColor[trend] : 'text-muted-foreground'}`}>
|
||||
{trendValue && <span>{trendValue} </span>}
|
||||
{description}
|
||||
</p>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Action Header
|
||||
|
||||
```typescript
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Search, Plus, Filter, Download } from "lucide-react";
|
||||
|
||||
interface ActionHeaderProps {
|
||||
title: string;
|
||||
description?: string;
|
||||
searchPlaceholder?: string;
|
||||
onSearch?: (value: string) => void;
|
||||
actions?: Array<{
|
||||
label: string;
|
||||
icon?: React.ReactNode;
|
||||
variant?: "default" | "outline" | "secondary";
|
||||
onClick?: () => void;
|
||||
}>;
|
||||
}
|
||||
|
||||
export function ActionHeader({
|
||||
title,
|
||||
description,
|
||||
searchPlaceholder,
|
||||
onSearch,
|
||||
actions = []
|
||||
}: ActionHeaderProps) {
|
||||
return (
|
||||
<div className="flex flex-col space-y-4 md:flex-row md:items-center md:justify-between md:space-y-0">
|
||||
<div>
|
||||
<h2 className="text-3xl font-bold tracking-tight">{title}</h2>
|
||||
{description && (
|
||||
<p className="text-muted-foreground">{description}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center space-x-2">
|
||||
{searchPlaceholder && onSearch && (
|
||||
<div className="relative">
|
||||
<Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
placeholder={searchPlaceholder}
|
||||
onChange={(e) => onSearch(e.target.value)}
|
||||
className="pl-8 w-[300px]"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{actions.map((action, index) => (
|
||||
<Button
|
||||
key={index}
|
||||
variant={action.variant || "default"}
|
||||
size="sm"
|
||||
onClick={action.onClick}
|
||||
>
|
||||
{action.icon}
|
||||
{action.label}
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Status Badge
|
||||
|
||||
```typescript
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
|
||||
const statusVariants = cva("", {
|
||||
variants: {
|
||||
status: {
|
||||
active: "bg-green-100 text-green-800 hover:bg-green-100/80",
|
||||
inactive: "bg-gray-100 text-gray-800 hover:bg-gray-100/80",
|
||||
pending: "bg-yellow-100 text-yellow-800 hover:bg-yellow-100/80",
|
||||
error: "bg-red-100 text-red-800 hover:bg-red-100/80",
|
||||
success: "bg-emerald-100 text-emerald-800 hover:bg-emerald-100/80",
|
||||
warning: "bg-amber-100 text-amber-800 hover:bg-amber-100/80",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
status: "inactive",
|
||||
},
|
||||
});
|
||||
|
||||
interface StatusBadgeProps extends VariantProps<typeof statusVariants> {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function StatusBadge({ status, children, className }: StatusBadgeProps) {
|
||||
return (
|
||||
<Badge variant="secondary" className={statusVariants({ status, className })}>
|
||||
{children}
|
||||
</Badge>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Layout Wrapper
|
||||
|
||||
```typescript
|
||||
interface PageLayoutProps {
|
||||
children: React.ReactNode;
|
||||
title: string;
|
||||
description?: string;
|
||||
actions?: React.ReactNode;
|
||||
}
|
||||
|
||||
export function PageLayout({ children, title, description, actions }: PageLayoutProps) {
|
||||
return (
|
||||
<div className="flex-1 space-y-4 p-4 md:p-8 pt-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h2 className="text-3xl font-bold tracking-tight">{title}</h2>
|
||||
{description && (
|
||||
<p className="text-muted-foreground">{description}</p>
|
||||
)}
|
||||
</div>
|
||||
{actions && <div className="flex items-center space-x-2">{actions}</div>}
|
||||
</div>
|
||||
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
These templates provide a solid foundation for building Backstage-style applications with consistent patterns, proper TypeScript types, and responsive design.
|
||||
683
skills/backstage-style-web/examples/admin_dashboard_example.md
Normal file
683
skills/backstage-style-web/examples/admin_dashboard_example.md
Normal file
@@ -0,0 +1,683 @@
|
||||
# Admin Dashboard Example
|
||||
|
||||
This example demonstrates how to build a comprehensive admin dashboard using the Backstage Design System.
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
admin-dashboard/
|
||||
├── src/
|
||||
│ ├── components/
|
||||
│ │ ├── ui/ # Base UI components
|
||||
│ │ ├── layout/ # Layout components
|
||||
│ │ ├── dashboard/ # Dashboard-specific components
|
||||
│ │ └── forms/ # Form components
|
||||
│ ├── pages/
|
||||
│ │ ├── Dashboard.tsx # Main dashboard page
|
||||
│ │ ├── Users.tsx # User management
|
||||
│ │ ├── Analytics.tsx # Analytics page
|
||||
│ │ └── Settings.tsx # Settings page
|
||||
│ ├── hooks/ # Custom hooks
|
||||
│ ├── lib/ # Utilities
|
||||
│ └── types/ # TypeScript types
|
||||
```
|
||||
|
||||
## Main Dashboard Page
|
||||
|
||||
```typescript
|
||||
"use client";
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
||||
import { Progress } from "@/components/ui/progress";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import {
|
||||
BarChart3,
|
||||
Users,
|
||||
TrendingUp,
|
||||
DollarSign,
|
||||
Search,
|
||||
Filter,
|
||||
Download,
|
||||
Plus,
|
||||
Eye,
|
||||
Edit,
|
||||
Trash2
|
||||
} from "lucide-react";
|
||||
|
||||
interface DashboardStats {
|
||||
totalUsers: number;
|
||||
activeUsers: number;
|
||||
revenue: number;
|
||||
growth: number;
|
||||
}
|
||||
|
||||
interface RecentActivity {
|
||||
id: string;
|
||||
user: string;
|
||||
action: string;
|
||||
timestamp: string;
|
||||
status: "success" | "warning" | "error";
|
||||
}
|
||||
|
||||
interface TopPerformer {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
sales: number;
|
||||
target: number;
|
||||
performance: number;
|
||||
}
|
||||
|
||||
export default function AdminDashboard() {
|
||||
const [stats, setStats] = useState<DashboardStats>({
|
||||
totalUsers: 0,
|
||||
activeUsers: 0,
|
||||
revenue: 0,
|
||||
growth: 0,
|
||||
});
|
||||
|
||||
const [recentActivity, setRecentActivity] = useState<RecentActivity[]>([]);
|
||||
const [topPerformers, setTopPerformers] = useState<TopPerformer[]>([]);
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
const [selectedTab, setSelectedTab] = useState("overview");
|
||||
|
||||
// Simulate data loading
|
||||
useEffect(() => {
|
||||
const loadData = () => {
|
||||
setStats({
|
||||
totalUsers: 12543,
|
||||
activeUsers: 8432,
|
||||
revenue: 245780,
|
||||
growth: 12.5,
|
||||
});
|
||||
|
||||
setRecentActivity([
|
||||
{
|
||||
id: "1",
|
||||
user: "John Doe",
|
||||
action: "Created new project",
|
||||
timestamp: "2 minutes ago",
|
||||
status: "success",
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
user: "Jane Smith",
|
||||
action: "Updated user profile",
|
||||
timestamp: "5 minutes ago",
|
||||
status: "success",
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
user: "Bob Johnson",
|
||||
action: "Failed login attempt",
|
||||
timestamp: "10 minutes ago",
|
||||
status: "error",
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
user: "Alice Brown",
|
||||
action: "Exported data",
|
||||
timestamp: "15 minutes ago",
|
||||
status: "warning",
|
||||
},
|
||||
]);
|
||||
|
||||
setTopPerformers([
|
||||
{
|
||||
id: "1",
|
||||
name: "Sarah Wilson",
|
||||
email: "sarah@example.com",
|
||||
sales: 45000,
|
||||
target: 50000,
|
||||
performance: 90,
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
name: "Mike Chen",
|
||||
email: "mike@example.com",
|
||||
sales: 42000,
|
||||
target: 45000,
|
||||
performance: 93,
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
name: "Emma Davis",
|
||||
email: "emma@example.com",
|
||||
sales: 38000,
|
||||
target: 40000,
|
||||
performance: 95,
|
||||
},
|
||||
]);
|
||||
};
|
||||
|
||||
loadData();
|
||||
}, []);
|
||||
|
||||
const getStatusBadge = (status: RecentActivity["status"]) => {
|
||||
const variants = {
|
||||
success: "default",
|
||||
warning: "secondary",
|
||||
error: "destructive",
|
||||
} as const;
|
||||
|
||||
return variants[status] || "secondary";
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex-1 space-y-4 p-4 md:p-8 pt-6">
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h2 className="text-3xl font-bold tracking-tight">Admin Dashboard</h2>
|
||||
<p className="text-muted-foreground">
|
||||
Welcome back! Here's what's happening with your platform.
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<Button variant="outline" size="sm">
|
||||
<Download className="mr-2 h-4 w-4" />
|
||||
Export
|
||||
</Button>
|
||||
<Button size="sm">
|
||||
<Plus className="mr-2 h-4 w-4" />
|
||||
Add User
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Stats Cards */}
|
||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">Total Users</CardTitle>
|
||||
<Users className="h-4 w-4 text-muted-foreground" />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">{stats.totalUsers.toLocaleString()}</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
+180 from last month
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">Active Users</CardTitle>
|
||||
<TrendingUp className="h-4 w-4 text-muted-foreground" />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">{stats.activeUsers.toLocaleString()}</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
+{((stats.activeUsers / stats.totalUsers) * 100).toFixed(1)}% active rate
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">Revenue</CardTitle>
|
||||
<DollarSign className="h-4 w-4 text-muted-foreground" />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">${stats.revenue.toLocaleString()}</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
+{stats.growth}% from last month
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">Growth Rate</CardTitle>
|
||||
<BarChart3 className="h-4 w-4 text-muted-foreground" />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">{stats.growth}%</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Above target by 2.5%
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Main Content Tabs */}
|
||||
<Tabs value={selectedTab} onValueChange={setSelectedTab} className="space-y-4">
|
||||
<TabsList>
|
||||
<TabsTrigger value="overview">Overview</TabsTrigger>
|
||||
<TabsTrigger value="users">Users</TabsTrigger>
|
||||
<TabsTrigger value="analytics">Analytics</TabsTrigger>
|
||||
<TabsTrigger value="reports">Reports</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="overview" className="space-y-4">
|
||||
<div className="grid gap-4 md:grid-cols-2">
|
||||
{/* Recent Activity */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Recent Activity</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-4">
|
||||
{recentActivity.map((activity) => (
|
||||
<div key={activity.id} className="flex items-center space-x-4">
|
||||
<div className="flex-1 space-y-1">
|
||||
<p className="text-sm font-medium leading-none">
|
||||
{activity.user}
|
||||
</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{activity.action}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-col items-end space-y-1">
|
||||
<Badge variant={getStatusBadge(activity.status)}>
|
||||
{activity.status}
|
||||
</Badge>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{activity.timestamp}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Top Performers */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Top Performers</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-4">
|
||||
{topPerformers.map((performer) => (
|
||||
<div key={performer.id} className="space-y-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="text-sm font-medium">{performer.name}</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{performer.email}
|
||||
</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<p className="text-sm font-medium">
|
||||
${performer.sales.toLocaleString()}
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Target: ${performer.target.toLocaleString()}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<Progress value={performer.performance} className="h-2" />
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{performer.performance}% of target
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="users" className="space-y-4">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>User Management</CardTitle>
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="relative">
|
||||
<Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
placeholder="Search users..."
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
className="pl-8 w-[300px]"
|
||||
/>
|
||||
</div>
|
||||
<Button variant="outline" size="sm">
|
||||
<Filter className="mr-2 h-4 w-4" />
|
||||
Filter
|
||||
</Button>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="rounded-md border">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>Name</TableHead>
|
||||
<TableHead>Email</TableHead>
|
||||
<TableHead>Role</TableHead>
|
||||
<TableHead>Status</TableHead>
|
||||
<TableHead>Last Active</TableHead>
|
||||
<TableHead className="w-[100px]">Actions</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableCell className="font-medium">John Doe</TableCell>
|
||||
<TableCell>john@example.com</TableCell>
|
||||
<TableCell>Admin</TableCell>
|
||||
<TableCell>
|
||||
<Badge>Active</Badge>
|
||||
</TableCell>
|
||||
<TableCell>2 hours ago</TableCell>
|
||||
<TableCell>
|
||||
<div className="flex items-center space-x-2">
|
||||
<Button variant="ghost" size="sm">
|
||||
<Eye className="h-4 w-4" />
|
||||
</Button>
|
||||
<Button variant="ghost" size="sm">
|
||||
<Edit className="h-4 w-4" />
|
||||
</Button>
|
||||
<Button variant="ghost" size="sm" className="text-red-600">
|
||||
<Trash2 className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell className="font-medium">Jane Smith</TableCell>
|
||||
<TableCell>jane@example.com</TableCell>
|
||||
<TableCell>Editor</TableCell>
|
||||
<TableCell>
|
||||
<Badge variant="secondary">Inactive</Badge>
|
||||
</TableCell>
|
||||
<TableCell>1 day ago</TableCell>
|
||||
<TableCell>
|
||||
<div className="flex items-center space-x-2">
|
||||
<Button variant="ghost" size="sm">
|
||||
<Eye className="h-4 w-4" />
|
||||
</Button>
|
||||
<Button variant="ghost" size="sm">
|
||||
<Edit className="h-4 w-4" />
|
||||
</Button>
|
||||
<Button variant="ghost" size="sm" className="text-red-600">
|
||||
<Trash2 className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="analytics" className="space-y-4">
|
||||
<div className="grid gap-4 md:grid-cols-2">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>User Growth</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="h-[200px] flex items-center justify-center text-muted-foreground">
|
||||
Chart Component Here
|
||||
<br />
|
||||
(Integrate with Chart.js, Recharts, or similar)
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Revenue Trends</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="h-[200px] flex items-center justify-center text-muted-foreground">
|
||||
Chart Component Here
|
||||
<br />
|
||||
(Integrate with Chart.js, Recharts, or similar)
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="reports" className="space-y-4">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Generate Reports</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-4">
|
||||
<div className="grid gap-4 md:grid-cols-3">
|
||||
<Button variant="outline" className="h-24 flex flex-col items-center justify-center">
|
||||
<Users className="h-8 w-8 mb-2" />
|
||||
User Report
|
||||
</Button>
|
||||
<Button variant="outline" className="h-24 flex flex-col items-center justify-center">
|
||||
<DollarSign className="h-8 w-8 mb-2" />
|
||||
Revenue Report
|
||||
</Button>
|
||||
<Button variant="outline" className="h-24 flex flex-col items-center justify-center">
|
||||
<BarChart3 className="h-8 w-8 mb-2" />
|
||||
Analytics Report
|
||||
</Button>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Select a report type to generate detailed insights
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Layout Component with Sidebar
|
||||
|
||||
```typescript
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import {
|
||||
Sidebar,
|
||||
SidebarContent,
|
||||
SidebarFooter,
|
||||
SidebarGroup,
|
||||
SidebarGroupContent,
|
||||
SidebarGroupLabel,
|
||||
SidebarHeader,
|
||||
SidebarMenu,
|
||||
SidebarMenuButton,
|
||||
SidebarMenuItem,
|
||||
SidebarProvider,
|
||||
SidebarRail,
|
||||
SidebarTrigger,
|
||||
} from "@/components/ui/sidebar";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import {
|
||||
Home,
|
||||
Users,
|
||||
BarChart3,
|
||||
Settings,
|
||||
FileText,
|
||||
Shield,
|
||||
HelpCircle,
|
||||
LogOut,
|
||||
ChevronUp,
|
||||
} from "lucide-react";
|
||||
|
||||
const navigationItems = [
|
||||
{
|
||||
title: "Overview",
|
||||
items: [
|
||||
{ title: "Dashboard", icon: Home, href: "/" },
|
||||
{ title: "Analytics", icon: BarChart3, href: "/analytics" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Management",
|
||||
items: [
|
||||
{ title: "Users", icon: Users, href: "/users" },
|
||||
{ title: "Reports", icon: FileText, href: "/reports" },
|
||||
{ title: "Security", icon: Shield, href: "/security" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "System",
|
||||
items: [
|
||||
{ title: "Settings", icon: Settings, href: "/settings" },
|
||||
{ title: "Help", icon: HelpCircle, href: "/help" },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
interface AdminLayoutProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function AdminLayout({ children }: AdminLayoutProps) {
|
||||
return (
|
||||
<SidebarProvider defaultOpen={true}>
|
||||
<div className="flex min-h-screen">
|
||||
<Sidebar className="border-r">
|
||||
<SidebarHeader>
|
||||
<div className="flex items-center gap-2 px-2 py-1">
|
||||
<div className="flex h-8 w-8 items-center justify-center rounded-lg bg-primary text-primary-foreground">
|
||||
<Home className="h-4 w-4" />
|
||||
</div>
|
||||
<span className="font-semibold">Admin Panel</span>
|
||||
</div>
|
||||
</SidebarHeader>
|
||||
|
||||
<SidebarContent>
|
||||
{navigationItems.map((section) => (
|
||||
<SidebarGroup key={section.title}>
|
||||
<SidebarGroupLabel>{section.title}</SidebarGroupLabel>
|
||||
<SidebarGroupContent>
|
||||
<SidebarMenu>
|
||||
{section.items.map((item) => (
|
||||
<SidebarMenuItem key={item.title}>
|
||||
<SidebarMenuButton asChild>
|
||||
<a href={item.href} className="flex items-center gap-2">
|
||||
<item.icon className="h-4 w-4" />
|
||||
<span>{item.title}</span>
|
||||
</a>
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
))}
|
||||
</SidebarMenu>
|
||||
</SidebarGroupContent>
|
||||
</SidebarGroup>
|
||||
))}
|
||||
</SidebarContent>
|
||||
|
||||
<SidebarFooter>
|
||||
<SidebarMenu>
|
||||
<SidebarMenuItem>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<SidebarMenuButton className="h-12">
|
||||
<Avatar className="h-8 w-8">
|
||||
<AvatarImage src="/avatars/admin.png" />
|
||||
<AvatarFallback>AD</AvatarFallback>
|
||||
</Avatar>
|
||||
<div className="flex flex-col items-start text-sm">
|
||||
<span className="font-medium">Admin User</span>
|
||||
<span className="text-xs text-muted-foreground">
|
||||
admin@example.com
|
||||
</span>
|
||||
</div>
|
||||
<ChevronUp className="ml-auto h-4 w-4" />
|
||||
</SidebarMenuButton>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" className="w-56">
|
||||
<DropdownMenuItem>
|
||||
<Settings className="mr-2 h-4 w-4" />
|
||||
Account Settings
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
<HelpCircle className="mr-2 h-4 w-4" />
|
||||
Support
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem className="text-red-600">
|
||||
<LogOut className="mr-2 h-4 w-4" />
|
||||
Log out
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</SidebarMenuItem>
|
||||
</SidebarMenu>
|
||||
</SidebarFooter>
|
||||
|
||||
<SidebarRail />
|
||||
</Sidebar>
|
||||
|
||||
<div className="flex-1 flex flex-col">
|
||||
<header className="border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
|
||||
<div className="flex h-14 items-center px-4">
|
||||
<SidebarTrigger className="mr-4" />
|
||||
<div className="flex-1" />
|
||||
<div className="flex items-center space-x-2">
|
||||
<Button variant="outline" size="sm">
|
||||
Notifications
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main className="flex-1">
|
||||
{children}
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</SidebarProvider>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Key Features
|
||||
|
||||
### 1. **Responsive Design**
|
||||
- Mobile-first approach with collapsible sidebar
|
||||
- Adaptive grid layouts for different screen sizes
|
||||
- Touch-friendly interactions on mobile devices
|
||||
|
||||
### 2. **Real-time Data**
|
||||
- Live activity feed with status indicators
|
||||
- Performance metrics with progress bars
|
||||
- Automatic data refresh capabilities
|
||||
|
||||
### 3. **Advanced Filtering & Search**
|
||||
- Global search functionality
|
||||
- Advanced filtering options
|
||||
- URL-based state management for bookmarkable views
|
||||
|
||||
### 4. **Role-based Access Control**
|
||||
- Different permission levels for different user types
|
||||
- Conditional UI rendering based on user roles
|
||||
- Secure routing and API access patterns
|
||||
|
||||
### 5. **Data Visualization**
|
||||
- Integration points for chart libraries
|
||||
- Progress indicators and status displays
|
||||
- Trend analysis and reporting features
|
||||
|
||||
### 6. **Accessibility Features**
|
||||
- Full keyboard navigation support
|
||||
- Screen reader compatibility
|
||||
- High contrast mode support
|
||||
- Focus management for modal interactions
|
||||
|
||||
This admin dashboard provides a solid foundation for building comprehensive management interfaces with the Backstage Design System, featuring modern React patterns, TypeScript safety, and enterprise-grade functionality.
|
||||
BIN
skills/backstage-style-web/references/InstrumentSerif-Italic.ttf
Normal file
BIN
skills/backstage-style-web/references/InstrumentSerif-Italic.ttf
Normal file
Binary file not shown.
Binary file not shown.
519
skills/backstage-style-web/references/design_system_guide.md
Normal file
519
skills/backstage-style-web/references/design_system_guide.md
Normal file
@@ -0,0 +1,519 @@
|
||||
# Backstage Design System Implementation Guide
|
||||
|
||||
## Core Architecture Overview
|
||||
|
||||
The Backstage Design System is built on modern React patterns and industry-standard libraries:
|
||||
|
||||
### Technology Stack
|
||||
- **React 18+** with TypeScript
|
||||
- **Radix UI Primitives** for accessible, headless components
|
||||
- **Tailwind CSS** for utility-first styling
|
||||
- **Class Variance Authority (CVA)** for type-safe component variants
|
||||
- **React Hook Form** with Zod validation
|
||||
- **Lucide React** for consistent iconography
|
||||
|
||||
### Key Design Principles
|
||||
|
||||
1. **Accessibility First**: Built on Radix UI primitives with ARIA support
|
||||
2. **Type Safety**: Full TypeScript coverage with strict typing
|
||||
3. **Composability**: Components designed for flexible composition
|
||||
4. **Consistency**: Unified design tokens and patterns
|
||||
5. **Performance**: Optimized for bundle size and runtime performance
|
||||
|
||||
## Component Architecture Patterns
|
||||
|
||||
### 1. Compound Components
|
||||
Components are designed with multiple sub-components for maximum flexibility:
|
||||
|
||||
```typescript
|
||||
// Card component structure
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Title</CardTitle>
|
||||
<CardDescription>Description</CardDescription>
|
||||
<CardAction>Action buttons</CardAction>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
Main content
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
Footer content
|
||||
</CardFooter>
|
||||
</Card>
|
||||
```
|
||||
|
||||
### 2. Variant-Based Styling
|
||||
Using CVA for type-safe, predictable component variants:
|
||||
|
||||
```typescript
|
||||
const buttonVariants = cva(
|
||||
"inline-flex items-center justify-center rounded-md text-sm font-medium",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
||||
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
||||
outline: "border border-input bg-background hover:bg-accent",
|
||||
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
||||
ghost: "hover:bg-accent hover:text-accent-foreground",
|
||||
link: "text-primary underline-offset-4 hover:underline",
|
||||
},
|
||||
size: {
|
||||
default: "h-10 px-4 py-2",
|
||||
sm: "h-9 rounded-md px-3",
|
||||
lg: "h-11 rounded-md px-8",
|
||||
icon: "h-10 w-10",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
size: "default",
|
||||
},
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
### 3. Data Attributes for Styling
|
||||
Consistent use of data attributes for component identification and styling:
|
||||
|
||||
```typescript
|
||||
<div
|
||||
data-slot="card"
|
||||
className="bg-card text-card-foreground rounded-lg border"
|
||||
>
|
||||
<div data-slot="card-header">
|
||||
{/* Header content */}
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Theme System Implementation
|
||||
|
||||
### 1. Color Architecture
|
||||
|
||||
#### Brand Colors (11-step scale)
|
||||
```css
|
||||
:root {
|
||||
--brand-050: #F5F1F0; /* 最浅背景色 */
|
||||
--brand-100: #E9DDDB; /* Hover background / light tint */
|
||||
--brand-200: #D6BEBB; /* Soft background */
|
||||
--brand-300: #B78F8A; /* Subtle brand tint */
|
||||
--brand-400: #94635E; /* Hover / outline */
|
||||
--brand-500: #6A4040; /* Primary brand color */
|
||||
--brand-600: #5B3535; /* Active / pressed */
|
||||
--brand-700: #4C2D2D; /* Stronger contrast */
|
||||
--brand-800: #3E2525; /* Deep background */
|
||||
--brand-900: #2E1C1C; /* Text on light */
|
||||
--brand-950: #1C1010; /* Text on dark / darkest tone */
|
||||
}
|
||||
```
|
||||
|
||||
#### Semantic Color Tokens
|
||||
```css
|
||||
|
||||
:root {
|
||||
/* === Light Mode === */
|
||||
--background: hsl(48, 33%, 98%);
|
||||
--foreground: hsl(0, 25%, 33%);
|
||||
--card: hsl(48, 33%, 98%);
|
||||
--card-foreground: hsl(0, 25%, 33%);
|
||||
--popover: hsl(48, 33%, 98%);
|
||||
--popover-foreground: hsl(0, 25%, 33%);
|
||||
--primary: hsl(222, 28%, 14%);
|
||||
--primary-foreground: hsl(48, 33%, 98%);
|
||||
--secondary: hsl(210, 25%, 96%);
|
||||
--secondary-foreground: hsl(0, 25%, 33%);
|
||||
--muted: hsl(210, 25%, 96%);
|
||||
--muted-foreground: hsl(215, 9%, 46%);
|
||||
--accent: hsl(210, 25%, 96%);
|
||||
--accent-foreground: hsl(0, 25%, 33%);
|
||||
--destructive: hsl(0, 82%, 67%);
|
||||
--destructive-foreground: hsl(48, 33%, 98%);
|
||||
--border: hsl(0, 14%, 94%);
|
||||
--input: hsl(214, 27%, 91%);
|
||||
--ring: hsl(0, 25%, 33%);
|
||||
}
|
||||
|
||||
[data-theme='dark'] {
|
||||
/* === Dark Mode === */
|
||||
--background: hsl(0, 25%, 6%);
|
||||
--foreground: hsl(48, 33%, 98%);
|
||||
--card: hsl(0, 25%, 6%);
|
||||
--card-foreground: hsl(48, 33%, 98%);
|
||||
--popover: hsl(0, 25%, 6%);
|
||||
--popover-foreground: hsl(48, 33%, 98%);
|
||||
--primary: hsl(48, 33%, 98%);
|
||||
--primary-foreground: hsl(0, 25%, 33%);
|
||||
--secondary: hsl(0, 22%, 14%);
|
||||
--secondary-foreground: hsl(48, 33%, 98%);
|
||||
--muted: hsl(0, 22%, 14%);
|
||||
--muted-foreground: hsl(0, 20%, 75%);
|
||||
--accent: hsl(0, 22%, 14%);
|
||||
--accent-foreground: hsl(48, 33%, 98%);
|
||||
--destructive: hsl(0, 82%, 67%);
|
||||
--destructive-foreground: hsl(48, 33%, 98%);
|
||||
--border: hsl(0, 22%, 14%);
|
||||
--input: hsl(0, 22%, 14%);
|
||||
--ring: hsl(0, 25%, 33%);
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
|
||||
### 2. Font Families
|
||||
```css
|
||||
/* Import custom fonts */
|
||||
@font-face {
|
||||
font-family: 'Instrument Serif';
|
||||
src: url('./references/InstrumentSerif-Regular.ttf') format('truetype');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Instrument Serif';
|
||||
src: url('./references/InstrumentSerif-Italic.ttf') format('truetype');
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* Typography Rules */
|
||||
/* Paragraph and text content */
|
||||
p, .text-body, .text-content {
|
||||
font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
}
|
||||
|
||||
/* Headings */
|
||||
h1, h2, h3, h4, h5, h6,
|
||||
.heading-1, .heading-2, .heading-3, .heading-4, .heading-5, .heading-6 {
|
||||
font-family: 'Instrument Serif', Georgia, 'Times New Roman', serif;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
/* Prepositions in headings should use italic */
|
||||
h1 .preposition, h2 .preposition, h3 .preposition,
|
||||
h4 .preposition, h5 .preposition, h6 .preposition,
|
||||
.heading-1 .preposition, .heading-2 .preposition, .heading-3 .preposition,
|
||||
.heading-4 .preposition, .heading-5 .preposition, .heading-6 .preposition {
|
||||
font-style: italic;
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Typography Scale
|
||||
```css
|
||||
.text-xxs { font-size: 8px; } /* Micro text */
|
||||
.text-xs { font-size: 10px; } /* Caption */
|
||||
.text-sm { font-size: 12px; } /* Secondary text */
|
||||
.text-base { font-size: 14px; } /* Default body */
|
||||
.text-lg { font-size: 16px; } /* Paragraph */
|
||||
.display-xl { font-size: 60px; } /* Hero headings */
|
||||
```
|
||||
|
||||
### 4. Spacing System (4px base unit)
|
||||
```css
|
||||
.space-1 { margin: 4px; } /* XS */
|
||||
.space-2 { margin: 8px; } /* SM */
|
||||
.space-3 { margin: 12px; } /* MD */
|
||||
.space-4 { margin: 16px; } /* LG - Component spacing */
|
||||
.space-6 { margin: 24px; } /* Standard spacing */
|
||||
.space-8 { margin: 32px; } /* Section padding */
|
||||
.space-16 { margin: 64px; } /* Large sections */
|
||||
```
|
||||
|
||||
## Responsive Design Strategy
|
||||
|
||||
### 1. Breakpoint System
|
||||
```css
|
||||
/* Mobile-first approach */
|
||||
sm: '640px', /* Small devices */
|
||||
md: '768px', /* Tablets */
|
||||
lg: '1024px', /* Laptops */
|
||||
xl: '1280px', /* Desktops */
|
||||
2xl: '1536px' /* Large screens */
|
||||
```
|
||||
|
||||
### 2. Component Responsiveness
|
||||
```typescript
|
||||
// Example: Responsive grid
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{/* Cards automatically adapt */}
|
||||
</div>
|
||||
|
||||
// Custom mobile hook
|
||||
const isMobile = useIsMobile(); // 768px breakpoint
|
||||
```
|
||||
|
||||
### 3. Sidebar Adaptation
|
||||
```typescript
|
||||
// Desktop: Collapsible sidebar
|
||||
// Mobile: Transforms to sheet/drawer
|
||||
{isMobile ? (
|
||||
<Sheet open={openMobile} onOpenChange={setOpenMobile}>
|
||||
<SheetContent side="left" className="p-0">
|
||||
<SidebarContent />
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
) : (
|
||||
<Sidebar className={cn(
|
||||
"transition-all duration-300",
|
||||
state === "collapsed" ? "w-[48px]" : "w-[256px]"
|
||||
)}>
|
||||
<SidebarContent />
|
||||
</Sidebar>
|
||||
)}
|
||||
```
|
||||
|
||||
## Accessibility Implementation
|
||||
|
||||
### 1. ARIA Patterns
|
||||
```typescript
|
||||
// Proper ARIA labeling
|
||||
<button
|
||||
aria-label="Close dialog"
|
||||
aria-expanded={isOpen}
|
||||
aria-controls="dialog-content"
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
</button>
|
||||
|
||||
// Form accessibility
|
||||
<label htmlFor="email" className="sr-only">
|
||||
Email address
|
||||
</label>
|
||||
<input
|
||||
id="email"
|
||||
type="email"
|
||||
aria-describedby="email-description"
|
||||
aria-invalid={hasError}
|
||||
/>
|
||||
<div id="email-description" className="text-sm text-muted-foreground">
|
||||
We'll never share your email
|
||||
</div>
|
||||
```
|
||||
|
||||
### 2. Keyboard Navigation
|
||||
```typescript
|
||||
// Custom keyboard event handling
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (event: KeyboardEvent) => {
|
||||
if (event.key === 'Escape') {
|
||||
onClose();
|
||||
}
|
||||
if (event.key === 'Enter' || event.key === ' ') {
|
||||
onActivate();
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('keydown', handleKeyDown);
|
||||
return () => document.removeEventListener('keydown', handleKeyDown);
|
||||
}, [onClose, onActivate]);
|
||||
```
|
||||
|
||||
### 3. Focus Management
|
||||
```typescript
|
||||
// Focus trap for modals
|
||||
import { FocusTrap } from '@radix-ui/react-focus-trap';
|
||||
|
||||
<FocusTrap asChild>
|
||||
<div className="modal-content">
|
||||
{/* Modal content with proper focus order */}
|
||||
</div>
|
||||
</FocusTrap>
|
||||
```
|
||||
|
||||
## Form Architecture
|
||||
|
||||
### 1. React Hook Form Integration
|
||||
```typescript
|
||||
import { useForm } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import * as z from "zod";
|
||||
|
||||
const formSchema = z.object({
|
||||
email: z.string().email("Invalid email address"),
|
||||
password: z.string().min(8, "Password must be at least 8 characters"),
|
||||
});
|
||||
|
||||
type FormData = z.infer<typeof formSchema>;
|
||||
|
||||
const form = useForm<FormData>({
|
||||
resolver: zodResolver(formSchema),
|
||||
defaultValues: {
|
||||
email: "",
|
||||
password: "",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### 2. Form Field Component Pattern
|
||||
```typescript
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="email"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Email</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="Enter your email" {...field} />
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
We'll use this to send you updates
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
```
|
||||
|
||||
## State Management Patterns
|
||||
|
||||
### 1. Component State
|
||||
```typescript
|
||||
// Local state for UI interactions
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [selectedItems, setSelectedItems] = useState<string[]>([]);
|
||||
|
||||
// Derived state
|
||||
const hasSelection = selectedItems.length > 0;
|
||||
const allSelected = selectedItems.length === items.length;
|
||||
```
|
||||
|
||||
### 2. Context for Shared State
|
||||
```typescript
|
||||
// Theme context
|
||||
const ThemeContext = createContext<{
|
||||
theme: Theme;
|
||||
setTheme: (theme: Theme) => void;
|
||||
} | null>(null);
|
||||
|
||||
// Sidebar context
|
||||
const SidebarContext = createContext<{
|
||||
state: "expanded" | "collapsed";
|
||||
open: boolean;
|
||||
setOpen: (open: boolean) => void;
|
||||
isMobile: boolean;
|
||||
} | null>(null);
|
||||
```
|
||||
|
||||
### 3. URL State Management
|
||||
```typescript
|
||||
// For filters, search, pagination
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
|
||||
const currentPage = Number(searchParams.get('page')) || 1;
|
||||
const searchQuery = searchParams.get('q') || '';
|
||||
|
||||
const updateFilters = (filters: Record<string, string>) => {
|
||||
const newParams = new URLSearchParams(searchParams);
|
||||
Object.entries(filters).forEach(([key, value]) => {
|
||||
if (value) {
|
||||
newParams.set(key, value);
|
||||
} else {
|
||||
newParams.delete(key);
|
||||
}
|
||||
});
|
||||
setSearchParams(newParams);
|
||||
};
|
||||
```
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### 1. Code Splitting
|
||||
```typescript
|
||||
// Lazy loading for routes
|
||||
const Dashboard = lazy(() => import('./pages/Dashboard'));
|
||||
const Settings = lazy(() => import('./pages/Settings'));
|
||||
|
||||
// Wrap in Suspense
|
||||
<Suspense fallback={<LoadingSpinner />}>
|
||||
<Routes>
|
||||
<Route path="/dashboard" element={<Dashboard />} />
|
||||
<Route path="/settings" element={<Settings />} />
|
||||
</Routes>
|
||||
</Suspense>
|
||||
```
|
||||
|
||||
### 2. Memoization
|
||||
```typescript
|
||||
// Expensive calculations
|
||||
const processedData = useMemo(() => {
|
||||
return data.map(item => ({
|
||||
...item,
|
||||
computed: expensiveComputation(item)
|
||||
}));
|
||||
}, [data]);
|
||||
|
||||
// Callback memoization
|
||||
const handleItemClick = useCallback((id: string) => {
|
||||
setSelectedItems(prev =>
|
||||
prev.includes(id)
|
||||
? prev.filter(item => item !== id)
|
||||
: [...prev, id]
|
||||
);
|
||||
}, []);
|
||||
|
||||
// Component memoization
|
||||
const MemoizedTableRow = memo(TableRow);
|
||||
```
|
||||
|
||||
### 3. Virtual Scrolling (for large lists)
|
||||
```typescript
|
||||
import { FixedSizeList as List } from 'react-window';
|
||||
|
||||
const VirtualizedTable = ({ items }: { items: any[] }) => {
|
||||
const Row = ({ index, style }: { index: number; style: React.CSSProperties }) => (
|
||||
<div style={style}>
|
||||
<TableRow data={items[index]} />
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<List
|
||||
height={600}
|
||||
itemCount={items.length}
|
||||
itemSize={50}
|
||||
width="100%"
|
||||
>
|
||||
{Row}
|
||||
</List>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
## Testing Patterns
|
||||
|
||||
### 1. Component Testing
|
||||
```typescript
|
||||
import { render, screen, fireEvent } from '@testing-library/react';
|
||||
import { Button } from './button';
|
||||
|
||||
describe('Button', () => {
|
||||
it('renders with correct variant styles', () => {
|
||||
render(<Button variant="destructive">Delete</Button>);
|
||||
const button = screen.getByRole('button');
|
||||
expect(button).toHaveClass('bg-destructive');
|
||||
});
|
||||
|
||||
it('handles click events', () => {
|
||||
const handleClick = jest.fn();
|
||||
render(<Button onClick={handleClick}>Click me</Button>);
|
||||
fireEvent.click(screen.getByRole('button'));
|
||||
expect(handleClick).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### 2. Accessibility Testing
|
||||
```typescript
|
||||
import { axe, toHaveNoViolations } from 'jest-axe';
|
||||
|
||||
expect.extend(toHaveNoViolations);
|
||||
|
||||
it('should not have accessibility violations', async () => {
|
||||
const { container } = render(<MyComponent />);
|
||||
const results = await axe(container);
|
||||
expect(results).toHaveNoViolations();
|
||||
});
|
||||
```
|
||||
|
||||
This implementation guide provides the foundation for building consistent, accessible, and performant applications using the Backstage Design System.
|
||||
95
skills/landing-page-creator/SKILL.md
Normal file
95
skills/landing-page-creator/SKILL.md
Normal file
@@ -0,0 +1,95 @@
|
||||
---
|
||||
name: landing-page-creator
|
||||
description: Create high-converting landing pages with optimized copy, structure, and design elements. Generates complete pages for lead generation, product launches, event registration, and sales campaigns with conversion-focused layouts.
|
||||
---
|
||||
|
||||
# Landing Page Creator
|
||||
|
||||
Build high-converting landing pages with persuasive copy, optimized structure, and conversion-focused design elements tailored to specific campaign goals.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill for:
|
||||
- Lead generation campaigns
|
||||
- Product launch pages
|
||||
- Event registration and webinars
|
||||
- Free trial sign-ups
|
||||
- Newsletter subscriptions
|
||||
- Course or service sales
|
||||
- App download campaigns
|
||||
- Contest and giveaway pages
|
||||
|
||||
## Landing Page Framework
|
||||
|
||||
### Essential Elements
|
||||
Every high-converting landing page includes:
|
||||
- **Compelling Headline**: Clear value proposition in 6-10 words
|
||||
- **Supporting Subheadline**: Elaborates on main benefit
|
||||
- **Hero Image/Video**: Visually supports the main message
|
||||
- **Benefits Section**: Focus on user outcomes, not features
|
||||
- **Social Proof**: Testimonials, reviews, trust badges
|
||||
- **Call-to-Action**: Clear, prominent, action-oriented
|
||||
- **Form Optimization**: Minimal fields, logical flow
|
||||
- **Mobile Responsive**: Optimized for all devices
|
||||
|
||||
### Conversion Optimization
|
||||
Maximize page performance through:
|
||||
- **Single Focus**: One primary goal per page
|
||||
- **Above-Fold CTA**: Primary action visible without scrolling
|
||||
- **Urgency Elements**: Limited time offers, scarcity indicators
|
||||
- **Trust Signals**: Security badges, guarantees, certifications
|
||||
- **Progressive Disclosure**: Complex information revealed gradually
|
||||
- **A/B Testing**: Multiple variations for optimization
|
||||
|
||||
## Page Structure Templates
|
||||
|
||||
### Lead Generation Template
|
||||
```
|
||||
1. Headline + Value Proposition
|
||||
2. Subheadline with Benefits
|
||||
3. Hero Image/Video
|
||||
4. Lead Magnet Description
|
||||
5. Form (Name, Email)
|
||||
6. Social Proof
|
||||
7. Additional Benefits
|
||||
8. FAQ Section
|
||||
9. Footer with Trust Elements
|
||||
```
|
||||
|
||||
### Product Sales Template
|
||||
```
|
||||
1. Problem Statement
|
||||
2. Solution Introduction
|
||||
3. Product Demo/Screenshots
|
||||
4. Features and Benefits
|
||||
5. Pricing Options
|
||||
6. Customer Testimonials
|
||||
7. Guarantee/Risk Reversal
|
||||
8. Urgency/Scarcity
|
||||
9. Final CTA
|
||||
```
|
||||
|
||||
## Content Guidelines
|
||||
|
||||
### Headline Formula
|
||||
- Lead with primary benefit
|
||||
- Include specific outcome or number
|
||||
- Address target audience directly
|
||||
- Create curiosity or urgency
|
||||
- Keep under 10 words when possible
|
||||
|
||||
### Copy Structure
|
||||
- **Problem-Agitation-Solution**: Identify pain, amplify urgency, present solution
|
||||
- **Before-After-Bridge**: Current state, desired future, path to get there
|
||||
- **Features-Advantages-Benefits**: What it is, what it does, what it means
|
||||
|
||||
## Technical Implementation
|
||||
|
||||
Generate clean, conversion-optimized HTML/CSS code with:
|
||||
- **Semantic HTML**: Proper structure for accessibility and SEO
|
||||
- **Mobile-First Design**: Responsive layouts that work on all devices
|
||||
- **Fast Loading**: Optimized images and minimal code
|
||||
- **Form Validation**: Client-side validation for better UX
|
||||
- **Analytics Ready**: Event tracking for conversion measurement
|
||||
|
||||
Create complete, ready-to-deploy landing pages that drive results.
|
||||
135
skills/modern-web-design/SKILL.md
Normal file
135
skills/modern-web-design/SKILL.md
Normal file
@@ -0,0 +1,135 @@
|
||||
---
|
||||
name: modern-web-design
|
||||
description: Create modern, responsive websites with professional design systems. Generates complete HTML/CSS/JS websites with Tailwind CSS, modern animations, and mobile-first responsive design. Perfect for landing pages, portfolios, business sites, and SaaS applications.
|
||||
---
|
||||
|
||||
# Modern Web Design Creator
|
||||
|
||||
Build beautiful, responsive websites using modern design principles, Tailwind CSS, and contemporary UI patterns. Creates production-ready code with animations, responsive layouts, and accessibility features.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill for:
|
||||
- Landing pages and marketing websites
|
||||
- Portfolio and personal brand sites
|
||||
- Business and company websites
|
||||
- SaaS application interfaces
|
||||
- E-commerce product pages
|
||||
- Blog and content sites
|
||||
- Dashboard and admin interfaces
|
||||
|
||||
## Design System Foundation
|
||||
|
||||
### Core Principles
|
||||
- **Mobile-first responsive design** with breakpoint optimization
|
||||
- **Design tokens** for consistent spacing, colors, and typography
|
||||
- **Component-based architecture** for maintainable code
|
||||
- **Accessibility-first** development with ARIA labels and semantic HTML
|
||||
- **Performance optimization** with minimal CSS and efficient animations
|
||||
|
||||
### Style Categories
|
||||
|
||||
Reference `references/design-systems.md` for complete style specifications:
|
||||
|
||||
#### Minimalist Professional
|
||||
- Clean typography with generous whitespace
|
||||
- Neutral color palette with strategic accent colors
|
||||
- Subtle shadows and minimal animations
|
||||
- Focus on content hierarchy and readability
|
||||
|
||||
#### Modern SaaS
|
||||
- Bold gradients and vibrant colors
|
||||
- Card-based layouts with elevation
|
||||
- Micro-interactions and hover states
|
||||
- Dashboard-style components
|
||||
|
||||
#### Creative Portfolio
|
||||
- Experimental layouts and grid systems
|
||||
- Bold typography and creative color schemes
|
||||
- Advanced animations and scroll effects
|
||||
- Image-focused design patterns
|
||||
|
||||
#### E-commerce Optimized
|
||||
- Product-focused layouts
|
||||
- Trust signals and social proof elements
|
||||
- Conversion-optimized CTAs
|
||||
- Shopping and checkout flows
|
||||
|
||||
## Implementation Workflow
|
||||
|
||||
1. **Analyze Requirements**: Determine site purpose, target audience, and functionality needs
|
||||
2. **Select Design Category**: Choose appropriate style system from references
|
||||
3. **Generate Structure**: Create semantic HTML with proper heading hierarchy
|
||||
4. **Apply Styling**: Implement Tailwind CSS classes with design system tokens
|
||||
5. **Add Interactions**: Include animations, hover states, and micro-interactions
|
||||
6. **Optimize Responsive**: Ensure mobile-first responsive behavior
|
||||
7. **Enhance Accessibility**: Add ARIA labels, alt text, and keyboard navigation
|
||||
|
||||
## Code Generation Standards
|
||||
|
||||
### HTML Structure
|
||||
- Semantic HTML5 elements (`<header>`, `<main>`, `<section>`, `<article>`)
|
||||
- Proper heading hierarchy (h1 → h6)
|
||||
- Accessibility attributes (ARIA, alt text, roles)
|
||||
- Meta tags for SEO and responsive design
|
||||
|
||||
### CSS Framework
|
||||
- Tailwind CSS utility classes for rapid development
|
||||
- Custom CSS for complex animations and unique effects
|
||||
- CSS variables for design token consistency
|
||||
- Mobile-first media queries
|
||||
|
||||
### JavaScript Features
|
||||
- Vanilla JavaScript for lightweight interactions
|
||||
- Intersection Observer for scroll animations
|
||||
- Form validation and submission handling
|
||||
- Mobile menu and navigation toggles
|
||||
|
||||
## Component Library
|
||||
|
||||
Load `assets/component-templates.html` for reusable components:
|
||||
|
||||
### Navigation Components
|
||||
- Responsive header with mobile menu
|
||||
- Sticky navigation with scroll effects
|
||||
- Breadcrumb navigation
|
||||
- Footer with social links
|
||||
|
||||
### Content Sections
|
||||
- Hero sections with various layouts
|
||||
- Feature grids and comparison tables
|
||||
- Testimonial carousels
|
||||
- FAQ accordions
|
||||
- Contact forms
|
||||
|
||||
### Interactive Elements
|
||||
- Animated buttons and CTAs
|
||||
- Image galleries and lightboxes
|
||||
- Progress bars and counters
|
||||
- Modal dialogs and tooltips
|
||||
|
||||
## Advanced Features
|
||||
|
||||
### Animation System
|
||||
- CSS transitions for smooth interactions
|
||||
- Keyframe animations for complex movements
|
||||
- Intersection Observer for scroll-triggered effects
|
||||
- Performance-optimized animations
|
||||
|
||||
### Performance Optimization
|
||||
- Minimal CSS footprint with utility-first approach
|
||||
- Lazy loading for images and heavy content
|
||||
- Critical CSS inlining for above-fold content
|
||||
- Progressive enhancement strategies
|
||||
|
||||
### SEO Foundation
|
||||
- Semantic HTML structure
|
||||
- Meta tags and Open Graph
|
||||
- JSON-LD structured data
|
||||
- Performance optimization for Core Web Vitals
|
||||
|
||||
## Supporting Resources
|
||||
|
||||
- `references/design-systems.md`: Complete style guides and color palettes
|
||||
- `assets/component-templates.html`: Reusable HTML component library
|
||||
- `scripts/build-tools.js`: Optimization and build utilities
|
||||
332
skills/modern-web-design/assets/component-templates.html
Normal file
332
skills/modern-web-design/assets/component-templates.html
Normal file
@@ -0,0 +1,332 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Modern Web Design Components</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
<body class="font-['Inter'] bg-gray-50">
|
||||
|
||||
<!-- Navigation Components -->
|
||||
|
||||
<!-- 1. Professional Header -->
|
||||
<header class="bg-white shadow-sm sticky top-0 z-50">
|
||||
<nav class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex justify-between items-center h-16">
|
||||
<div class="flex items-center">
|
||||
<img class="h-8 w-8" src="logo.svg" alt="Logo">
|
||||
<span class="ml-2 text-xl font-semibold text-gray-900">Brand</span>
|
||||
</div>
|
||||
<div class="hidden md:block">
|
||||
<div class="ml-10 flex items-baseline space-x-8">
|
||||
<a href="#" class="text-gray-600 hover:text-gray-900 px-3 py-2 text-sm font-medium transition-colors">Home</a>
|
||||
<a href="#" class="text-gray-600 hover:text-gray-900 px-3 py-2 text-sm font-medium transition-colors">About</a>
|
||||
<a href="#" class="text-gray-600 hover:text-gray-900 px-3 py-2 text-sm font-medium transition-colors">Services</a>
|
||||
<a href="#" class="text-gray-600 hover:text-gray-900 px-3 py-2 text-sm font-medium transition-colors">Contact</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hidden md:block">
|
||||
<button class="bg-blue-600 text-white px-4 py-2 rounded-md text-sm font-medium hover:bg-blue-700 transition-colors">
|
||||
Get Started
|
||||
</button>
|
||||
</div>
|
||||
<div class="md:hidden">
|
||||
<button class="text-gray-600 hover:text-gray-900" id="mobile-menu-button">
|
||||
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<!-- 2. SaaS Gradient Header -->
|
||||
<header class="bg-gradient-to-r from-purple-600 to-blue-600">
|
||||
<nav class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex justify-between items-center h-16">
|
||||
<div class="flex items-center">
|
||||
<span class="text-xl font-bold text-white">SaaS App</span>
|
||||
</div>
|
||||
<div class="hidden md:flex space-x-8">
|
||||
<a href="#" class="text-purple-100 hover:text-white transition-colors">Features</a>
|
||||
<a href="#" class="text-purple-100 hover:text-white transition-colors">Pricing</a>
|
||||
<a href="#" class="text-purple-100 hover:text-white transition-colors">Resources</a>
|
||||
</div>
|
||||
<div class="flex items-center space-x-4">
|
||||
<a href="#" class="text-purple-100 hover:text-white">Sign In</a>
|
||||
<button class="bg-white text-purple-600 px-4 py-2 rounded-md font-medium hover:bg-gray-100 transition-colors">
|
||||
Start Free Trial
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<!-- Hero Sections -->
|
||||
|
||||
<!-- 3. Minimalist Hero -->
|
||||
<section class="bg-white py-20">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="text-center">
|
||||
<h1 class="text-4xl sm:text-5xl lg:text-6xl font-bold text-gray-900 leading-tight">
|
||||
Build something
|
||||
<span class="text-blue-600">amazing</span>
|
||||
</h1>
|
||||
<p class="mt-6 max-w-3xl mx-auto text-xl text-gray-600">
|
||||
Create beautiful, responsive websites with our modern design system and component library.
|
||||
</p>
|
||||
<div class="mt-10 flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<button class="bg-blue-600 text-white px-8 py-3 rounded-md font-medium hover:bg-blue-700 transition-colors transform hover:-translate-y-1">
|
||||
Get Started
|
||||
</button>
|
||||
<button class="border border-gray-300 text-gray-700 px-8 py-3 rounded-md font-medium hover:bg-gray-50 transition-colors">
|
||||
Learn More
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 4. SaaS Hero with Animation -->
|
||||
<section class="bg-gradient-to-br from-indigo-900 via-purple-900 to-pink-900 py-20">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="grid lg:grid-cols-2 gap-12 items-center">
|
||||
<div>
|
||||
<h1 class="text-5xl lg:text-6xl font-bold text-white leading-tight">
|
||||
The future of
|
||||
<span class="text-transparent bg-clip-text bg-gradient-to-r from-pink-400 to-purple-400">
|
||||
productivity
|
||||
</span>
|
||||
</h1>
|
||||
<p class="mt-6 text-xl text-gray-300">
|
||||
Streamline your workflow with AI-powered tools that adapt to your team's needs.
|
||||
</p>
|
||||
<div class="mt-8 flex flex-col sm:flex-row gap-4">
|
||||
<button class="bg-white text-gray-900 px-8 py-3 rounded-md font-semibold hover:bg-gray-100 transition-all transform hover:scale-105">
|
||||
Start Free Trial
|
||||
</button>
|
||||
<button class="border border-purple-400 text-purple-400 px-8 py-3 rounded-md font-semibold hover:bg-purple-400 hover:text-white transition-colors">
|
||||
Watch Demo
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative">
|
||||
<div class="bg-white/10 backdrop-blur-lg rounded-xl p-8 border border-white/20">
|
||||
<div class="space-y-4">
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="w-3 h-3 bg-green-400 rounded-full"></div>
|
||||
<div class="h-2 bg-gray-300 rounded w-32"></div>
|
||||
</div>
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="w-3 h-3 bg-yellow-400 rounded-full"></div>
|
||||
<div class="h-2 bg-gray-300 rounded w-24"></div>
|
||||
</div>
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="w-3 h-3 bg-blue-400 rounded-full"></div>
|
||||
<div class="h-2 bg-gray-300 rounded w-40"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Feature Sections -->
|
||||
|
||||
<!-- 5. Feature Grid -->
|
||||
<section class="py-20 bg-white">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="text-center mb-16">
|
||||
<h2 class="text-3xl sm:text-4xl font-bold text-gray-900">
|
||||
Everything you need to succeed
|
||||
</h2>
|
||||
<p class="mt-4 text-xl text-gray-600">
|
||||
Powerful features to help you build better websites faster
|
||||
</p>
|
||||
</div>
|
||||
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
<div class="text-center p-6 rounded-lg hover:shadow-lg transition-shadow">
|
||||
<div class="w-12 h-12 bg-blue-100 rounded-lg flex items-center justify-center mx-auto mb-4">
|
||||
<svg class="w-6 h-6 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold text-gray-900 mb-2">Lightning Fast</h3>
|
||||
<p class="text-gray-600">Optimized for speed and performance on all devices</p>
|
||||
</div>
|
||||
<div class="text-center p-6 rounded-lg hover:shadow-lg transition-shadow">
|
||||
<div class="w-12 h-12 bg-green-100 rounded-lg flex items-center justify-center mx-auto mb-4">
|
||||
<svg class="w-6 h-6 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold text-gray-900 mb-2">Reliable</h3>
|
||||
<p class="text-gray-600">99.9% uptime guarantee with robust infrastructure</p>
|
||||
</div>
|
||||
<div class="text-center p-6 rounded-lg hover:shadow-lg transition-shadow">
|
||||
<div class="w-12 h-12 bg-purple-100 rounded-lg flex items-center justify-center mx-auto mb-4">
|
||||
<svg class="w-6 h-6 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold text-gray-900 mb-2">Secure</h3>
|
||||
<p class="text-gray-600">Enterprise-grade security to protect your data</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Interactive Components -->
|
||||
|
||||
<!-- 6. Testimonial Carousel -->
|
||||
<section class="py-20 bg-gray-50">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="text-center mb-16">
|
||||
<h2 class="text-3xl font-bold text-gray-900">What our customers say</h2>
|
||||
</div>
|
||||
<div class="max-w-4xl mx-auto">
|
||||
<div class="bg-white rounded-xl shadow-lg p-8">
|
||||
<div class="text-center">
|
||||
<p class="text-xl text-gray-600 italic mb-8">
|
||||
"This platform has completely transformed how we build and deploy websites. The design system is incredible and the performance is outstanding."
|
||||
</p>
|
||||
<div class="flex items-center justify-center">
|
||||
<img class="w-12 h-12 rounded-full mr-4" src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=100&h=100&fit=crop&crop=face" alt="Customer">
|
||||
<div class="text-left">
|
||||
<p class="font-semibold text-gray-900">John Smith</p>
|
||||
<p class="text-gray-600">CEO, TechCorp</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 7. Contact Form -->
|
||||
<section class="py-20 bg-white">
|
||||
<div class="max-w-3xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="text-center mb-12">
|
||||
<h2 class="text-3xl font-bold text-gray-900">Get in touch</h2>
|
||||
<p class="mt-4 text-xl text-gray-600">Ready to start your project? Let's talk.</p>
|
||||
</div>
|
||||
<form class="space-y-6">
|
||||
<div class="grid md:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<label for="first_name" class="block text-sm font-medium text-gray-700 mb-2">First Name</label>
|
||||
<input type="text" id="first_name" class="w-full px-4 py-3 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent">
|
||||
</div>
|
||||
<div>
|
||||
<label for="last_name" class="block text-sm font-medium text-gray-700 mb-2">Last Name</label>
|
||||
<input type="text" id="last_name" class="w-full px-4 py-3 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent">
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label for="email" class="block text-sm font-medium text-gray-700 mb-2">Email</label>
|
||||
<input type="email" id="email" class="w-full px-4 py-3 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent">
|
||||
</div>
|
||||
<div>
|
||||
<label for="message" class="block text-sm font-medium text-gray-700 mb-2">Message</label>
|
||||
<textarea id="message" rows="4" class="w-full px-4 py-3 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent"></textarea>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<button type="submit" class="bg-blue-600 text-white px-8 py-3 rounded-md font-medium hover:bg-blue-700 transition-colors transform hover:-translate-y-1">
|
||||
Send Message
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="bg-gray-900 text-white py-12">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="grid md:grid-cols-4 gap-8">
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold mb-4">Company</h3>
|
||||
<ul class="space-y-2">
|
||||
<li><a href="#" class="text-gray-400 hover:text-white transition-colors">About</a></li>
|
||||
<li><a href="#" class="text-gray-400 hover:text-white transition-colors">Careers</a></li>
|
||||
<li><a href="#" class="text-gray-400 hover:text-white transition-colors">Contact</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold mb-4">Product</h3>
|
||||
<ul class="space-y-2">
|
||||
<li><a href="#" class="text-gray-400 hover:text-white transition-colors">Features</a></li>
|
||||
<li><a href="#" class="text-gray-400 hover:text-white transition-colors">Pricing</a></li>
|
||||
<li><a href="#" class="text-gray-400 hover:text-white transition-colors">Documentation</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold mb-4">Resources</h3>
|
||||
<ul class="space-y-2">
|
||||
<li><a href="#" class="text-gray-400 hover:text-white transition-colors">Blog</a></li>
|
||||
<li><a href="#" class="text-gray-400 hover:text-white transition-colors">Support</a></li>
|
||||
<li><a href="#" class="text-gray-400 hover:text-white transition-colors">Community</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold mb-4">Follow Us</h3>
|
||||
<div class="flex space-x-4">
|
||||
<a href="#" class="text-gray-400 hover:text-white transition-colors">
|
||||
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M24 4.557c-.883.392-1.832.656-2.828.775 1.017-.609 1.798-1.574 2.165-2.724-.951.564-2.005.974-3.127 1.195-.897-.957-2.178-1.555-3.594-1.555-3.179 0-5.515 2.966-4.797 6.045-4.091-.205-7.719-2.165-10.148-5.144-1.29 2.213-.669 5.108 1.523 6.574-.806-.026-1.566-.247-2.229-.616-.054 2.281 1.581 4.415 3.949 4.89-.693.188-1.452.232-2.224.084.626 1.956 2.444 3.379 4.6 3.419-2.07 1.623-4.678 2.348-7.29 2.04 2.179 1.397 4.768 2.212 7.548 2.212 9.142 0 14.307-7.721 13.995-14.646.962-.695 1.797-1.562 2.457-2.549z"/>
|
||||
</svg>
|
||||
</a>
|
||||
<a href="#" class="text-gray-400 hover:text-white transition-colors">
|
||||
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M22.46 6c-.77.35-1.6.58-2.46.69.88-.53 1.56-1.37 1.88-2.38-.83.5-1.75.85-2.72 1.05C18.37 4.5 17.26 4 16 4c-2.35 0-4.27 1.92-4.27 4.29 0 .34.04.67.11.98C8.28 9.09 5.11 7.38 3 4.79c-.37.63-.58 1.37-.58 2.15 0 1.49.75 2.81 1.91 3.56-.71 0-1.37-.2-1.95-.5v.03c0 2.08 1.48 3.82 3.44 4.21a4.22 4.22 0 0 1-1.93.07 4.28 4.28 0 0 0 4 2.98 8.521 8.521 0 0 1-5.33 1.84c-.34 0-.68-.02-1.02-.06C3.44 20.29 5.7 21 8.12 21 16 21 20.33 14.46 20.33 8.79c0-.19 0-.37-.01-.56.84-.6 1.56-1.36 2.14-2.23z"/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-t border-gray-800 mt-8 pt-8 text-center">
|
||||
<p class="text-gray-400">© 2024 Your Company. All rights reserved.</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
// Mobile menu toggle
|
||||
document.getElementById('mobile-menu-button')?.addEventListener('click', function() {
|
||||
// Mobile menu implementation
|
||||
});
|
||||
|
||||
// Smooth scrolling for anchor links
|
||||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||||
anchor.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
document.querySelector(this.getAttribute('href')).scrollIntoView({
|
||||
behavior: 'smooth'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Intersection Observer for animations
|
||||
const observerOptions = {
|
||||
threshold: 0.1,
|
||||
rootMargin: '0px 0px -50px 0px'
|
||||
};
|
||||
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.classList.add('animate-fade-in-up');
|
||||
}
|
||||
});
|
||||
}, observerOptions);
|
||||
|
||||
// Observe all sections for animation
|
||||
document.querySelectorAll('section').forEach(section => {
|
||||
observer.observe(section);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
310
skills/modern-web-design/references/design-systems.md
Normal file
310
skills/modern-web-design/references/design-systems.md
Normal file
@@ -0,0 +1,310 @@
|
||||
# Modern Web Design Systems
|
||||
|
||||
## Design Categories
|
||||
|
||||
### 1. Minimalist Professional
|
||||
|
||||
#### Color Palette
|
||||
```css
|
||||
/* Primary Colors */
|
||||
--primary-50: #f8fafc;
|
||||
--primary-100: #f1f5f9;
|
||||
--primary-500: #64748b;
|
||||
--primary-900: #0f172a;
|
||||
|
||||
/* Accent Colors */
|
||||
--accent-500: #3b82f6;
|
||||
--accent-600: #2563eb;
|
||||
|
||||
/* Semantic Colors */
|
||||
--success: #10b981;
|
||||
--warning: #f59e0b;
|
||||
--error: #ef4444;
|
||||
```
|
||||
|
||||
#### Typography Scale
|
||||
```css
|
||||
/* Font Family */
|
||||
--font-sans: 'Inter', system-ui, sans-serif;
|
||||
--font-mono: 'JetBrains Mono', monospace;
|
||||
|
||||
/* Font Sizes */
|
||||
--text-xs: 0.75rem; /* 12px */
|
||||
--text-sm: 0.875rem; /* 14px */
|
||||
--text-base: 1rem; /* 16px */
|
||||
--text-lg: 1.125rem; /* 18px */
|
||||
--text-xl: 1.25rem; /* 20px */
|
||||
--text-2xl: 1.5rem; /* 24px */
|
||||
--text-3xl: 1.875rem; /* 30px */
|
||||
--text-4xl: 2.25rem; /* 36px */
|
||||
```
|
||||
|
||||
#### Spacing System
|
||||
```css
|
||||
--space-1: 0.25rem; /* 4px */
|
||||
--space-2: 0.5rem; /* 8px */
|
||||
--space-4: 1rem; /* 16px */
|
||||
--space-6: 1.5rem; /* 24px */
|
||||
--space-8: 2rem; /* 32px */
|
||||
--space-12: 3rem; /* 48px */
|
||||
--space-16: 4rem; /* 64px */
|
||||
--space-20: 5rem; /* 80px */
|
||||
```
|
||||
|
||||
### 2. Modern SaaS
|
||||
|
||||
#### Color Palette
|
||||
```css
|
||||
/* Primary Gradient */
|
||||
--primary-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
--primary-500: #667eea;
|
||||
--primary-600: #5a67d8;
|
||||
|
||||
/* Background Colors */
|
||||
--bg-primary: #ffffff;
|
||||
--bg-secondary: #f7fafc;
|
||||
--bg-tertiary: #edf2f7;
|
||||
|
||||
/* Interactive Colors */
|
||||
--interactive-hover: #e2e8f0;
|
||||
--interactive-active: #cbd5e0;
|
||||
```
|
||||
|
||||
#### Component Elevation
|
||||
```css
|
||||
/* Shadow System */
|
||||
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07);
|
||||
--shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
|
||||
--shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.1);
|
||||
```
|
||||
|
||||
#### Animation Timing
|
||||
```css
|
||||
--duration-fast: 150ms;
|
||||
--duration-normal: 250ms;
|
||||
--duration-slow: 350ms;
|
||||
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
```
|
||||
|
||||
### 3. Creative Portfolio
|
||||
|
||||
#### Experimental Color Scheme
|
||||
```css
|
||||
/* Vibrant Palette */
|
||||
--primary-pink: #ec4899;
|
||||
--primary-purple: #8b5cf6;
|
||||
--primary-blue: #06b6d4;
|
||||
--primary-green: #10b981;
|
||||
|
||||
/* Dark Mode */
|
||||
--dark-bg: #0f0f23;
|
||||
--dark-surface: #1a1a3e;
|
||||
--dark-text: #e2e8f0;
|
||||
```
|
||||
|
||||
#### Creative Typography
|
||||
```css
|
||||
/* Display Fonts */
|
||||
--font-display: 'Playfair Display', serif;
|
||||
--font-creative: 'Space Grotesk', sans-serif;
|
||||
|
||||
/* Font Weights */
|
||||
--weight-light: 300;
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
```
|
||||
|
||||
### 4. E-commerce Optimized
|
||||
|
||||
#### Trust & Conversion Colors
|
||||
```css
|
||||
/* Primary Brand */
|
||||
--brand-primary: #059669;
|
||||
--brand-secondary: #0d9488;
|
||||
|
||||
/* Conversion Elements */
|
||||
--cta-primary: #dc2626;
|
||||
--cta-secondary: #ea580c;
|
||||
--trust-green: #059669;
|
||||
--urgency-orange: #ea580c;
|
||||
```
|
||||
|
||||
#### Product Display
|
||||
```css
|
||||
/* Product Card */
|
||||
--product-bg: #ffffff;
|
||||
--product-border: #e5e7eb;
|
||||
--product-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
|
||||
/* Price Display */
|
||||
--price-primary: #1f2937;
|
||||
--price-sale: #dc2626;
|
||||
--price-original: #9ca3af;
|
||||
```
|
||||
|
||||
## Layout Systems
|
||||
|
||||
### Grid Patterns
|
||||
|
||||
#### 12-Column Grid
|
||||
```css
|
||||
.container {
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
||||
.grid-12 {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(12, 1fr);
|
||||
gap: 1.5rem;
|
||||
}
|
||||
```
|
||||
|
||||
#### Card Grid System
|
||||
```css
|
||||
.card-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 2rem;
|
||||
}
|
||||
```
|
||||
|
||||
### Responsive Breakpoints
|
||||
```css
|
||||
/* Mobile First */
|
||||
@media (min-width: 640px) { /* sm */ }
|
||||
@media (min-width: 768px) { /* md */ }
|
||||
@media (min-width: 1024px) { /* lg */ }
|
||||
@media (min-width: 1280px) { /* xl */ }
|
||||
@media (min-width: 1536px) { /* 2xl */ }
|
||||
```
|
||||
|
||||
## Component Patterns
|
||||
|
||||
### Button Variants
|
||||
```css
|
||||
/* Primary Button */
|
||||
.btn-primary {
|
||||
background: var(--primary-500);
|
||||
color: white;
|
||||
padding: 0.75rem 1.5rem;
|
||||
border-radius: 0.5rem;
|
||||
transition: all var(--duration-normal) var(--ease-in-out);
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: var(--primary-600);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
```
|
||||
|
||||
### Card Components
|
||||
```css
|
||||
.card {
|
||||
background: var(--bg-primary);
|
||||
border-radius: 0.75rem;
|
||||
box-shadow: var(--shadow-md);
|
||||
overflow: hidden;
|
||||
transition: all var(--duration-normal) var(--ease-in-out);
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: var(--shadow-xl);
|
||||
}
|
||||
```
|
||||
|
||||
### Input Styling
|
||||
```css
|
||||
.input-field {
|
||||
width: 100%;
|
||||
padding: 0.75rem 1rem;
|
||||
border: 2px solid var(--gray-200);
|
||||
border-radius: 0.5rem;
|
||||
font-size: var(--text-base);
|
||||
transition: border-color var(--duration-fast);
|
||||
}
|
||||
|
||||
.input-field:focus {
|
||||
outline: none;
|
||||
border-color: var(--primary-500);
|
||||
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
|
||||
}
|
||||
```
|
||||
|
||||
## Animation Library
|
||||
|
||||
### Micro-interactions
|
||||
```css
|
||||
/* Hover Lift */
|
||||
.hover-lift {
|
||||
transition: transform var(--duration-normal) var(--ease-in-out);
|
||||
}
|
||||
.hover-lift:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
/* Scale on Hover */
|
||||
.hover-scale {
|
||||
transition: transform var(--duration-normal) var(--ease-in-out);
|
||||
}
|
||||
.hover-scale:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
```
|
||||
|
||||
### Loading States
|
||||
```css
|
||||
@keyframes pulse {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.5; }
|
||||
}
|
||||
|
||||
.loading {
|
||||
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
||||
}
|
||||
```
|
||||
|
||||
### Scroll Animations
|
||||
```css
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.animate-fade-in-up {
|
||||
animation: fadeInUp 0.6s ease-out;
|
||||
}
|
||||
```
|
||||
|
||||
## Accessibility Standards
|
||||
|
||||
### Color Contrast
|
||||
- AA Standard: 4.5:1 for normal text
|
||||
- AA Standard: 3:1 for large text
|
||||
- AAA Standard: 7:1 for normal text
|
||||
|
||||
### Focus States
|
||||
```css
|
||||
.focus-visible {
|
||||
outline: 2px solid var(--primary-500);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
```
|
||||
|
||||
### Screen Reader Support
|
||||
- Use semantic HTML elements
|
||||
- Include ARIA labels where needed
|
||||
- Maintain logical heading hierarchy
|
||||
- Provide alt text for images
|
||||
87
skills/ui-component-builder/SKILL.md
Normal file
87
skills/ui-component-builder/SKILL.md
Normal file
@@ -0,0 +1,87 @@
|
||||
---
|
||||
name: ui-component-builder
|
||||
description: Build reusable UI components with modern frameworks like React, Vue, and vanilla JavaScript. Creates accessible, responsive, and customizable interface elements including buttons, forms, modals, navigation, and complex widgets.
|
||||
---
|
||||
|
||||
# UI Component Builder
|
||||
|
||||
Create modern, reusable UI components with clean code, accessibility features, and responsive design for web applications and design systems.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill for:
|
||||
- Building design system components
|
||||
- Creating reusable interface elements
|
||||
- Developing interactive widgets
|
||||
- Prototyping new UI patterns
|
||||
- Converting designs to code
|
||||
- Building accessible components
|
||||
- Creating component libraries
|
||||
|
||||
## Component Categories
|
||||
|
||||
### Basic Components
|
||||
- **Buttons**: Primary, secondary, outline, icon, loading states
|
||||
- **Inputs**: Text, email, password, textarea, select, checkbox, radio
|
||||
- **Typography**: Headings, paragraphs, lists, code blocks
|
||||
- **Images**: Responsive images, avatars, thumbnails, galleries
|
||||
- **Icons**: SVG icons, icon fonts, custom graphics
|
||||
|
||||
### Layout Components
|
||||
- **Grid Systems**: Flexible grid layouts with breakpoints
|
||||
- **Containers**: Wrappers, sections, cards, panels
|
||||
- **Navigation**: Headers, sidebars, breadcrumbs, pagination
|
||||
- **Spacing**: Margins, padding, dividers, spacers
|
||||
|
||||
### Interactive Components
|
||||
- **Modals**: Dialogs, popups, overlays, confirmations
|
||||
- **Dropdowns**: Menus, selects, autocomplete, combobox
|
||||
- **Tabs**: Tab panels, accordion, collapsible sections
|
||||
- **Forms**: Complete forms, validation, multi-step wizards
|
||||
|
||||
### Advanced Components
|
||||
- **Data Display**: Tables, charts, progress bars, badges
|
||||
- **Media**: Video players, audio controls, image carousels
|
||||
- **Feedback**: Alerts, notifications, tooltips, loading states
|
||||
- **Navigation**: Mega menus, sidebar navigation, mobile menus
|
||||
|
||||
## Technical Standards
|
||||
|
||||
### Framework Support
|
||||
Generate components for:
|
||||
- **React**: Modern hooks, TypeScript support, proper props
|
||||
- **Vue**: Composition API, TypeScript, reactive properties
|
||||
- **Vanilla JS**: Modern ES6+, Web Components, no dependencies
|
||||
- **Svelte**: Reactive declarations, component lifecycle
|
||||
- **Angular**: Component architecture, reactive forms
|
||||
|
||||
### Accessibility Features
|
||||
All components include:
|
||||
- **ARIA Labels**: Proper labeling for screen readers
|
||||
- **Keyboard Navigation**: Tab order, focus management
|
||||
- **Color Contrast**: WCAG AA compliance (4.5:1 ratio)
|
||||
- **Semantic HTML**: Proper element usage and structure
|
||||
- **Focus Indicators**: Visible focus states for all interactive elements
|
||||
|
||||
### Responsive Design
|
||||
Components work across:
|
||||
- **Mobile First**: Optimized for small screens
|
||||
- **Breakpoint System**: sm, md, lg, xl viewport sizes
|
||||
- **Touch Friendly**: Adequate touch targets (44px minimum)
|
||||
- **Flexible Layouts**: Adapts to container constraints
|
||||
|
||||
## Implementation Features
|
||||
|
||||
### Customization Options
|
||||
- **Theme Variables**: CSS custom properties for easy theming
|
||||
- **Size Variants**: Small, medium, large sizing options
|
||||
- **Color Schemes**: Primary, secondary, success, warning, error
|
||||
- **Style Variants**: Filled, outlined, text, ghost styles
|
||||
|
||||
### Code Quality
|
||||
- **Clean Structure**: Semantic HTML with proper nesting
|
||||
- **Efficient CSS**: Modern CSS with minimal specificity
|
||||
- **Performance**: Optimized for fast rendering and interaction
|
||||
- **Documentation**: Inline comments and usage examples
|
||||
|
||||
Create production-ready components that enhance user experience and development efficiency.
|
||||
Reference in New Issue
Block a user