Files
digital-pilates/docs/dialog-components.md
2025-08-16 14:15:11 +08:00

5.7 KiB
Raw Blame History

弹窗组件使用指南

本项目提供了一套优雅的弹窗组件系统包括确认弹窗ConfirmDialog和操作选择弹窗ActionSheet

全局使用方式

1. 使用 useGlobalDialog Hook

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 确认弹窗

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 操作选择弹窗

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 配置

interface DialogConfig {
  title: string;              // 标题
  message?: string;           // 消息内容
  confirmText?: string;       // 确认按钮文字,默认"确定"
  cancelText?: string;        // 取消按钮文字,默认"取消"
  destructive?: boolean;      // 是否为危险操作,影响按钮颜色
  icon?: keyof typeof Ionicons.glyphMap;  // 图标名称
  iconColor?: string;         // 图标颜色
}

ActionSheet 配置

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. 触觉反馈:重要操作会自动提供触觉反馈