227 lines
5.7 KiB
Markdown
227 lines
5.7 KiB
Markdown
# 弹窗组件使用指南
|
||
|
||
本项目提供了一套优雅的弹窗组件系统,包括确认弹窗(ConfirmDialog)和操作选择弹窗(ActionSheet)。
|
||
|
||
## 全局使用方式
|
||
|
||
### 1. 使用 useGlobalDialog Hook
|
||
|
||
```tsx
|
||
import { useGlobalDialog } from '@/components/ui/DialogProvider';
|
||
|
||
function MyComponent() {
|
||
const { showConfirm, showActionSheet } = useGlobalDialog();
|
||
|
||
// 显示确认弹窗
|
||
const handleDelete = () => {
|
||
showConfirm(
|
||
{
|
||
title: '删除确认',
|
||
message: '确定要删除这个项目吗?删除后无法恢复。',
|
||
icon: 'trash-outline',
|
||
destructive: true,
|
||
},
|
||
() => {
|
||
// 确认后的操作
|
||
console.log('已删除');
|
||
}
|
||
);
|
||
};
|
||
|
||
// 显示操作选择弹窗
|
||
const handleMoreActions = () => {
|
||
showActionSheet(
|
||
{
|
||
title: '更多操作',
|
||
subtitle: '选择要执行的操作',
|
||
},
|
||
[
|
||
{
|
||
id: 'edit',
|
||
title: '编辑',
|
||
subtitle: '修改项目信息',
|
||
icon: 'create-outline',
|
||
iconColor: '#3B82F6',
|
||
onPress: () => {
|
||
console.log('编辑');
|
||
}
|
||
},
|
||
{
|
||
id: 'share',
|
||
title: '分享',
|
||
subtitle: '分享给朋友',
|
||
icon: 'share-outline',
|
||
iconColor: '#10B981',
|
||
onPress: () => {
|
||
console.log('分享');
|
||
}
|
||
},
|
||
{
|
||
id: 'delete',
|
||
title: '删除',
|
||
subtitle: '永久删除项目',
|
||
icon: 'trash-outline',
|
||
iconColor: '#EF4444',
|
||
destructive: true,
|
||
onPress: () => {
|
||
console.log('删除');
|
||
}
|
||
}
|
||
]
|
||
);
|
||
};
|
||
|
||
return (
|
||
<View>
|
||
<TouchableOpacity onPress={handleDelete}>
|
||
<Text>删除</Text>
|
||
</TouchableOpacity>
|
||
<TouchableOpacity onPress={handleMoreActions}>
|
||
<Text>更多操作</Text>
|
||
</TouchableOpacity>
|
||
</View>
|
||
);
|
||
}
|
||
```
|
||
|
||
## 独立使用方式
|
||
|
||
### 1. ConfirmDialog 确认弹窗
|
||
|
||
```tsx
|
||
import { ConfirmDialog } from '@/components/ui/ConfirmDialog';
|
||
|
||
function MyComponent() {
|
||
const [showDialog, setShowDialog] = useState(false);
|
||
|
||
return (
|
||
<>
|
||
<TouchableOpacity onPress={() => setShowDialog(true)}>
|
||
<Text>显示确认弹窗</Text>
|
||
</TouchableOpacity>
|
||
|
||
<ConfirmDialog
|
||
visible={showDialog}
|
||
onClose={() => setShowDialog(false)}
|
||
title="确认操作"
|
||
message="确定要执行这个操作吗?"
|
||
confirmText="确定"
|
||
cancelText="取消"
|
||
destructive={false}
|
||
icon="checkmark-circle-outline"
|
||
iconColor="#22C55E"
|
||
onConfirm={() => {
|
||
console.log('确认操作');
|
||
setShowDialog(false);
|
||
}}
|
||
/>
|
||
</>
|
||
);
|
||
}
|
||
```
|
||
|
||
### 2. ActionSheet 操作选择弹窗
|
||
|
||
```tsx
|
||
import { ActionSheet } from '@/components/ui/ActionSheet';
|
||
|
||
function MyComponent() {
|
||
const [showSheet, setShowSheet] = useState(false);
|
||
|
||
const options = [
|
||
{
|
||
id: 'camera',
|
||
title: '拍照',
|
||
subtitle: '使用相机拍摄照片',
|
||
icon: 'camera-outline' as const,
|
||
iconColor: '#3B82F6',
|
||
onPress: () => {
|
||
console.log('拍照');
|
||
setShowSheet(false);
|
||
}
|
||
},
|
||
{
|
||
id: 'gallery',
|
||
title: '从相册选择',
|
||
subtitle: '从手机相册中选择照片',
|
||
icon: 'images-outline' as const,
|
||
iconColor: '#10B981',
|
||
onPress: () => {
|
||
console.log('相册');
|
||
setShowSheet(false);
|
||
}
|
||
}
|
||
];
|
||
|
||
return (
|
||
<>
|
||
<TouchableOpacity onPress={() => setShowSheet(true)}>
|
||
<Text>选择照片</Text>
|
||
</TouchableOpacity>
|
||
|
||
<ActionSheet
|
||
visible={showSheet}
|
||
onClose={() => setShowSheet(false)}
|
||
title="选择照片"
|
||
subtitle="选择照片来源"
|
||
cancelText="取消"
|
||
options={options}
|
||
/>
|
||
</>
|
||
);
|
||
}
|
||
```
|
||
|
||
## 配置选项
|
||
|
||
### ConfirmDialog 配置
|
||
|
||
```tsx
|
||
interface DialogConfig {
|
||
title: string; // 标题
|
||
message?: string; // 消息内容
|
||
confirmText?: string; // 确认按钮文字,默认"确定"
|
||
cancelText?: string; // 取消按钮文字,默认"取消"
|
||
destructive?: boolean; // 是否为危险操作,影响按钮颜色
|
||
icon?: keyof typeof Ionicons.glyphMap; // 图标名称
|
||
iconColor?: string; // 图标颜色
|
||
}
|
||
```
|
||
|
||
### ActionSheet 配置
|
||
|
||
```tsx
|
||
interface ActionSheetConfig {
|
||
title?: string; // 标题
|
||
subtitle?: string; // 副标题
|
||
cancelText?: string; // 取消按钮文字,默认"取消"
|
||
}
|
||
|
||
interface ActionSheetOption {
|
||
id: string; // 唯一标识
|
||
title: string; // 选项标题
|
||
subtitle?: string; // 选项副标题
|
||
icon?: keyof typeof Ionicons.glyphMap; // 图标名称
|
||
iconColor?: string; // 图标颜色
|
||
destructive?: boolean; // 是否为危险操作
|
||
onPress: () => void; // 点击回调
|
||
}
|
||
```
|
||
|
||
## 设计特点
|
||
|
||
1. **优雅的动画效果**:使用原生动画,流畅自然
|
||
2. **触觉反馈**:集成 Haptics 提供触觉反馈
|
||
3. **响应式设计**:适配不同屏幕尺寸
|
||
4. **无障碍支持**:支持屏幕阅读器等无障碍功能
|
||
5. **类型安全**:完整的 TypeScript 类型定义
|
||
6. **全局管理**:通过 Context 实现全局弹窗管理
|
||
7. **易于使用**:简洁的 API 设计,易于集成
|
||
|
||
## 最佳实践
|
||
|
||
1. **使用全局 Hook**:推荐使用 `useGlobalDialog` 而不是独立组件
|
||
2. **合理使用图标**:为不同类型的操作选择合适的图标
|
||
3. **明确的文案**:使用清晰、简洁的标题和描述
|
||
4. **危险操作标识**:对删除等危险操作使用 `destructive: true`
|
||
5. **触觉反馈**:重要操作会自动提供触觉反馈 |