This commit is contained in:
2026-03-23 00:08:19 +08:00
parent ca33e0d3c5
commit 2fdd842b89
11 changed files with 1196 additions and 380 deletions

View File

@@ -1,877 +0,0 @@
# Shadcn UI for Flutter - 技能文档
> Flutter 版本的 shadcn/ui 组件库,提供美观、可定制的 UI 组件
## 📦 安装
```yaml
# pubspec.yaml
dependencies:
shadcn_ui: ^0.2.4 # 使用最新版本
```
```bash
flutter pub add shadcn_ui
```
---
## 🚀 快速开始
### 纯 Shadcn UI
```dart
import 'package:shadcn_ui/shadcn_ui.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return ShadApp(
home: MyHomePage(),
);
}
}
```
### Shadcn + Material推荐
```dart
import 'package:shadcn_ui/shadcn_ui.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return ShadApp.custom(
themeMode: ThemeMode.dark,
darkTheme: ShadThemeData(
brightness: Brightness.dark,
colorScheme: const ShadSlateColorScheme.dark(),
),
appBuilder: (context) {
return MaterialApp(
theme: Theme.of(context),
localizationsDelegates: const [
GlobalShadLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
builder: (context, child) {
return ShadAppBuilder(child: child!);
},
home: MyHomePage(),
);
},
);
}
}
```
---
## 🎨 主题配置
### 颜色方案
支持的颜色方案:
- `blue` - 蓝色
- `gray` - 灰色
- `green` - 绿色
- `neutral` - 中性色
- `orange` - 橙色
- `red` - 红色
- `rose` - 玫瑰色
- `slate` - 石板色(推荐深色模式)
- `stone` - 石头色
- `violet` - 紫罗兰色
- `yellow` - 黄色
- `zinc` - 锌色
```dart
ShadApp(
darkTheme: ShadThemeData(
brightness: Brightness.dark,
colorScheme: const ShadSlateColorScheme.dark(),
),
theme: ShadThemeData(
brightness: Brightness.light,
colorScheme: const ShadZincColorScheme.light(),
),
)
```
### 动态切换主题
```dart
final lightColorScheme = ShadColorScheme.fromName('blue');
final darkColorScheme = ShadColorScheme.fromName('slate', brightness: Brightness.dark);
```
### 自定义颜色
```dart
ShadThemeData(
colorScheme: const ShadZincColorScheme.light(
custom: {
'brand': Color(0xFF00D4AA),
},
),
)
// 访问自定义颜色
ShadTheme.of(context).colorScheme.custom['brand']!
```
---
## 📝 文本样式
```dart
// 标题
Text('Heading 1 Large', style: ShadTheme.of(context).textTheme.h1Large)
Text('Heading 1', style: ShadTheme.of(context).textTheme.h1)
Text('Heading 2', style: ShadTheme.of(context).textTheme.h2)
Text('Heading 3', style: ShadTheme.of(context).textTheme.h3)
Text('Heading 4', style: ShadTheme.of(context).textTheme.h4)
// 正文
Text('Paragraph', style: ShadTheme.of(context).textTheme.p)
Text('Lead', style: ShadTheme.of(context).textTheme.lead)
Text('Large', style: ShadTheme.of(context).textTheme.large)
Text('Small', style: ShadTheme.of(context).textTheme.small)
Text('Muted', style: ShadTheme.of(context).textTheme.muted)
// 其他
Text('Blockquote', style: ShadTheme.of(context).textTheme.blockquote)
Text('Table', style: ShadTheme.of(context).textTheme.table)
Text('List', style: ShadTheme.of(context).textTheme.list)
```
### 自定义字体
```dart
// pubspec.yaml
flutter:
fonts:
- family: CustomFont
fonts:
- asset: fonts/CustomFont-Regular.ttf
// 使用
ShadThemeData(
textTheme: ShadTextTheme(
family: 'CustomFont',
),
)
// 或使用 Google Fonts
ShadThemeData(
textTheme: ShadTextTheme.fromGoogleFont(GoogleFonts.poppins),
)
```
---
## 🧩 核心组件
### Button 按钮
```dart
// 主要按钮
ShadButton(
child: const Text('Primary'),
onPressed: () {},
)
// 次要按钮
ShadButton.secondary(
child: const Text('Secondary'),
onPressed: () {},
)
// 危险按钮
ShadButton.destructive(
child: const Text('Delete'),
onPressed: () {},
)
// 边框按钮
ShadButton.outline(
child: const Text('Outline'),
onPressed: () {},
)
// 幽灵按钮
ShadButton.ghost(
child: const Text('Ghost'),
onPressed: () {},
)
// 链接按钮
ShadButton.link(
child: const Text('Link'),
onPressed: () {},
)
// 带图标
ShadButton(
leading: const Icon(LucideIcons.mail),
child: const Text('Login with Email'),
onPressed: () {},
)
// 加载状态
ShadButton(
leading: SizedBox.square(
dimension: 16,
child: CircularProgressIndicator(
strokeWidth: 2,
color: ShadTheme.of(context).colorScheme.primaryForeground,
),
),
child: const Text('Please wait'),
)
// 渐变和阴影
ShadButton(
gradient: const LinearGradient(colors: [Colors.cyan, Colors.indigo]),
shadows: [
BoxShadow(
color: Colors.blue.withOpacity(.4),
spreadRadius: 4,
blurRadius: 10,
offset: const Offset(0, 2),
),
],
child: const Text('Gradient'),
)
```
### IconButton 图标按钮
```dart
ShadIconButton(
icon: const Icon(LucideIcons.rocket),
onPressed: () {},
)
ShadIconButton.secondary(
icon: const Icon(LucideIcons.settings),
onPressed: () {},
)
ShadIconButton.destructive(
icon: const Icon(LucideIcons.trash),
onPressed: () {},
)
```
### Input 输入框
```dart
// 基础输入框
ShadInput(
placeholder: const Text('Enter your email'),
)
// 表单输入框
ShadInputFormField(
id: 'email',
label: const Text('Email'),
placeholder: const Text('Enter your email'),
description: const Text('We will never share your email.'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Email is required';
}
if (!value.contains('@')) {
return 'Invalid email format';
}
return null;
},
)
```
### Card 卡片
```dart
ShadCard(
width: 350,
title: Text('Create project', style: ShadTheme.of(context).textTheme.h4),
description: const Text('Deploy your new project in one-click.'),
footer: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ShadButton.outline(
child: const Text('Cancel'),
onPressed: () {},
),
ShadButton(
child: const Text('Deploy'),
onPressed: () {},
),
],
),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 16),
child: Column(
children: [
const Text('Name'),
const SizedBox(height: 6),
const ShadInput(placeholder: Text('Project name')),
],
),
),
)
```
### Alert 警告
```dart
// 普通警告
ShadAlert(
icon: Icon(LucideIcons.terminal),
title: Text('Heads up!'),
description: Text('You can add components using the cli.'),
)
// 错误警告
ShadAlert.destructive(
icon: Icon(LucideIcons.circleAlert),
title: Text('Error'),
description: Text('Your session has expired.'),
)
```
### Badge 徽章
```dart
ShadBadge(child: const Text('Primary'))
ShadBadge.secondary(child: const Text('Secondary'))
ShadBadge.destructive(child: const Text('Destructive'))
ShadBadge.outline(child: const Text('Outline'))
```
### Checkbox 复选框
```dart
bool checked = false;
ShadCheckbox(
value: checked,
onChanged: (v) => setState(() => checked = v),
label: const Text('Accept terms and conditions'),
sublabel: const Text('You agree to our Terms of Service.'),
)
// 表单中使用
ShadCheckboxFormField(
id: 'terms',
initialValue: false,
inputLabel: const Text('I accept the terms'),
validator: (v) {
if (!v) return 'You must accept the terms';
return null;
},
)
```
### Switch 开关
```dart
bool enabled = false;
ShadSwitch(
value: enabled,
onChanged: (v) => setState(() => enabled = v),
)
// 表单中使用
ShadSwitchFormField(
id: 'notifications',
initialValue: false,
inputLabel: const Text('Enable notifications'),
)
```
### Select 选择器
```dart
final options = ['Option 1', 'Option 2', 'Option 3'];
String? selected;
ShadSelect<String>(
placeholder: const Text('Select an option'),
options: options
.map((e) => ShadOption(value: e, child: Text(e)))
.toList(),
selectedOptionBuilder: (context, value) {
return Text(value);
},
onChanged: (value) {
setState(() => selected = value);
},
)
// 表单中使用
ShadSelectFormField<String>(
id: 'framework',
label: const Text('Framework'),
placeholder: const Text('Select'),
options: [
ShadOption(value: 'flutter', child: Text('Flutter')),
ShadOption(value: 'react', child: Text('React')),
],
selectedOptionBuilder: (context, value) => Text(value),
)
```
### Dialog 对话框
```dart
// 显示对话框
showShadDialog(
context: context,
builder: (context) => ShadDialog(
title: const Text('Edit Profile'),
description: const Text('Make changes to your profile.'),
actions: [
ShadButton.outline(
child: const Text('Cancel'),
onPressed: () => Navigator.of(context).pop(),
),
ShadButton(
child: const Text('Save'),
onPressed: () => Navigator.of(context).pop(),
),
],
child: Container(
width: 375,
padding: const EdgeInsets.all(20),
child: Column(
children: [
ShadInput(placeholder: Text('Name')),
],
),
),
),
)
// 警告对话框
showShadDialog(
context: context,
builder: (context) => ShadDialog.alert(
title: const Text('Are you sure?'),
description: const Text('This action cannot be undone.'),
actions: [
ShadButton.outline(
child: const Text('Cancel'),
onPressed: () => Navigator.of(context).pop(false),
),
ShadButton.destructive(
child: const Text('Delete'),
onPressed: () => Navigator.of(context).pop(true),
),
],
),
)
```
### DatePicker 日期选择器
```dart
DateTime? selected;
ShadDatePicker(
selected: selected,
onChanged: (date) {
setState(() => selected = date);
},
)
// 日期范围选择器
ShadDatePicker.range()
// 表单中使用
ShadDatePickerFormField(
id: 'birthday',
label: const Text('Date of birth'),
description: const Text('Your date of birth.'),
validator: (v) {
if (v == null) return 'Date of birth is required';
return null;
},
)
```
### Calendar 日历
```dart
DateTime selected = DateTime.now();
ShadCalendar(
selected: selected,
fromMonth: DateTime(2024, 1),
toMonth: DateTime(2024, 12),
)
// 多选
ShadCalendar.multiple(
numberOfMonths: 2,
min: 5,
max: 10,
)
// 范围选择
ShadCalendar.range(
min: 2,
max: 5,
)
```
### Avatar 头像
```dart
ShadAvatar(
'https://example.com/avatar.jpg',
placeholder: Text('CN'),
)
```
### Accordion 手风琴
```dart
final details = [
(title: 'Is it acceptable?', content: 'Yes.'),
(title: 'Is it styled?', content: 'Yes.'),
];
ShadAccordion<({String content, String title})>(
children: details.map(
(detail) => ShadAccordionItem(
value: detail,
title: Text(detail.title),
child: Text(detail.content),
),
),
)
// 多开模式
ShadAccordion<({String content, String title})>.multiple(
children: details.map(...),
)
```
### Breadcrumb 面包屑
```dart
ShadBreadcrumb(
children: [
ShadBreadcrumbLink(
onPressed: () => print('Home'),
child: const Text('Home'),
),
ShadBreadcrumbLink(
onPressed: () => print('Components'),
child: const Text('Components'),
),
Text('Breadcrumb'),
],
)
// 带下拉菜单
ShadBreadcrumb(
children: [
ShadBreadcrumbLink(
onPressed: () {},
child: const Text('Home'),
),
ShadBreadcrumbDropdown(
items: [
ShadBreadcrumbDropMenuItem(
onPressed: () {},
child: const Text('Documentation'),
),
ShadBreadcrumbDropMenuItem(
onPressed: () {},
child: const Text('Themes'),
),
],
child: const Text('Components'),
),
Text('Breadcrumb'),
],
)
```
### Context Menu 右键菜单
```dart
ShadContextMenuRegion(
items: [
const ShadContextMenuItem(child: Text('Copy')),
const ShadContextMenuItem(child: Text('Cut')),
const ShadContextMenuItem(child: Text('Paste')),
const Divider(height: 8),
const ShadContextMenuItem(child: Text('Delete')),
],
child: Container(
width: 300,
height: 200,
child: const Text('Right click here'),
),
)
```
---
## 📋 表单管理
### 基础表单
```dart
final formKey = GlobalKey<ShadFormState>();
ShadForm(
key: formKey,
child: Column(
children: [
ShadInputFormField(
id: 'username',
label: const Text('Username'),
validator: (v) {
if (v == null || v.isEmpty) return 'Username is required';
if (v.length < 3) return 'Username must be at least 3 characters';
return null;
},
),
ShadInputFormField(
id: 'email',
label: const Text('Email'),
validator: (v) {
if (v == null || !v.contains('@')) return 'Invalid email';
return null;
},
),
ShadButton(
child: const Text('Submit'),
onPressed: () {
if (formKey.currentState!.saveAndValidate()) {
print('Form value: ${formKey.currentState!.value}');
}
},
),
],
),
)
```
### 初始值
```dart
ShadForm(
initialValue: {
'username': 'john_doe',
'email': 'john@example.com',
},
child: Column(...),
)
```
### 嵌套表单(点号表示法)
```dart
ShadForm(
child: Column(
children: [
ShadInputFormField(
id: 'user.name',
label: const Text('Name'),
),
ShadInputFormField(
id: 'user.email',
label: const Text('Email'),
),
],
),
)
// 输出: {'user': {'name': '...', 'email': '...'}}
```
---
## 🎯 图标
使用 Lucide Icons
```dart
Icon(LucideIcons.home)
Icon(LucideIcons.settings)
Icon(LucideIcons.user)
Icon(LucideIcons.search)
Icon(LucideIcons.mail)
Icon(LucideIcons.heart)
Icon(LucideIcons.star)
```
浏览所有图标https://lucide.dev/icons/
---
## 🎬 动画
所有组件都支持 `flutter_animate` 动画:
```dart
ShadButton(
child: const Text('Animated Button'),
onPressed: () {},
// 添加动画效果
).animate().fadeIn().slideX()
```
---
## 📦 依赖库
shadcn_ui 包含以下优秀的库:
1. **flutter_animate** - 动画库
2. **lucide_icons_flutter** - 图标库
3. **two_dimensional_scrollables** - 表格组件
4. **intl** - 国际化
5. **universal_image** - 图片加载
---
## 💡 最佳实践
### 1. 与 Material 混用
```dart
// 推荐:使用 ShadApp.custom 包装 MaterialApp
ShadApp.custom(
appBuilder: (context) => MaterialApp(
theme: Theme.of(context),
builder: (context, child) => ShadAppBuilder(child: child!),
home: MyPage(),
),
)
```
### 2. 主题定制
```dart
ShadThemeData(
colorScheme: const ShadZincColorScheme.dark(),
primaryButtonTheme: const ShadButtonTheme(
backgroundColor: Color(0xFF00D4AA),
),
textTheme: ShadTextTheme(
family: 'CustomFont',
),
)
```
### 3. 表单验证
```dart
ShadInputFormField(
id: 'password',
label: const Text('Password'),
obscureText: true,
validator: (v) {
if (v == null || v.isEmpty) return 'Password is required';
if (v.length < 8) return 'Password must be at least 8 characters';
return null;
},
)
```
---
## 🚨 注意事项
1. **必须使用 ShadApp**:不要直接使用 MaterialApp要使用 ShadApp 或 ShadApp.custom
2. **主题访问**:使用 `ShadTheme.of(context)` 访问主题
3. **图标**:使用 `LucideIcons` 而不是 Material Icons
4. **表单**:推荐使用 ShadForm 配合各种 FormField 组件
---
## 📚 参考资源
- 官方文档https://mariuti.com/flutter-shadcn-ui/
- LLM 友好文档https://mariuti.com/flutter-shadcn-ui/llms.txt
- GitHubhttps://github.com/nank1ro/flutter-shadcn-ui
- Lucide 图标https://lucide.dev/icons/
---
## 🎨 示例主题配置
### 深色主题(推荐)
```dart
ShadApp(
themeMode: ThemeMode.dark,
darkTheme: ShadThemeData(
brightness: Brightness.dark,
colorScheme: const ShadSlateColorScheme.dark(),
),
home: MyApp(),
)
```
### 浅色主题
```dart
ShadApp(
themeMode: ThemeMode.light,
theme: ShadThemeData(
brightness: Brightness.light,
colorScheme: const ShadZincColorScheme.light(),
),
home: MyApp(),
)
```
### 自定义品牌色
```dart
ShadThemeData(
colorScheme: const ShadZincColorScheme.dark(
custom: {
'brand': Color(0xFF00D4AA),
'success': Color(0xFF10B981),
'warning': Color(0xFFF59E0B),
'error': Color(0xFFEF4444),
},
),
)
// 使用
Container(
color: ShadTheme.of(context).colorScheme.custom['brand'],
)
```
---
**文档版本**: 0.2.4
**最后更新**: 2026-03-22

View File

@@ -1,23 +0,0 @@
# Shadcn UI Flutter 技能
## 描述
Flutter 版本的 shadcn/ui 组件库技能。提供美观、可定制的 UI 组件支持深色模式、Material 混用、表单管理等功能。当用户需要在 Flutter 项目中使用 shadcn 风格的 UI 组件时使用此技能。
## 使用场景
- 创建新的 Flutter 项目需要现代化 UI
- 将现有 Flutter 项目迁移到 shadcn 风格
- 需要深色模式支持
- 需要表单验证和管理
- 需要与 Material Design 混用
## 快速链接
- [官方文档](https://mariuti.com/flutter-shadcn-ui/)
- [GitHub](https://github.com/nank1ro/flutter-shadcn-ui)
- [Lucide 图标](https://lucide.dev/icons/)
## 关键文件
- `SKILL.md` - 完整技能文档