878 lines
17 KiB
Markdown
878 lines
17 KiB
Markdown
# 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
|
||
- GitHub:https://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
|