import { useState, useCallback, useMemo } from 'react'; /** * 批量选择Hook * 用于管理列表项的批量选择状态 */ export interface UseBatchSelectionOptions { /** 是否启用批量选择模式 */ enabled?: boolean; /** 最大选择数量限制 */ maxSelection?: number; } export interface UseBatchSelectionReturn { /** 当前选中的项目ID列表 */ selectedIds: string[]; /** 是否处于批量选择模式 */ isSelectionMode: boolean; /** 是否全选状态 */ isAllSelected: boolean; /** 是否部分选中状态 */ isIndeterminate: boolean; /** 选中项目数量 */ selectedCount: number; /** 切换批量选择模式 */ toggleSelectionMode: () => void; /** 选择/取消选择单个项目 */ toggleItem: (id: string) => void; /** 全选/取消全选 */ toggleAll: (allIds: string[]) => void; /** 清空选择 */ clearSelection: () => void; /** 检查项目是否被选中 */ isSelected: (id: string) => boolean; /** 设置选中的项目ID列表 */ setSelectedIds: (ids: string[]) => void; } export function useBatchSelection( options: UseBatchSelectionOptions = {} ): UseBatchSelectionReturn { const { enabled = true, maxSelection } = options; const [selectedIds, setSelectedIds] = useState([]); const [isSelectionMode, setIsSelectionMode] = useState(false); // 切换批量选择模式 const toggleSelectionMode = useCallback(() => { if (!enabled) return; setIsSelectionMode(prev => { const newMode = !prev; // 退出选择模式时清空选择 if (!newMode) { setSelectedIds([]); } return newMode; }); }, [enabled]); // 选择/取消选择单个项目 const toggleItem = useCallback((id: string) => { if (!enabled || !isSelectionMode) return; setSelectedIds(prev => { const isCurrentlySelected = prev.includes(id); if (isCurrentlySelected) { // 取消选择 return prev.filter(selectedId => selectedId !== id); } else { // 选择项目 if (maxSelection && prev.length >= maxSelection) { console.warn(`最多只能选择 ${maxSelection} 个项目`); return prev; } return [...prev, id]; } }); }, [enabled, isSelectionMode, maxSelection]); // 全选/取消全选 const toggleAll = useCallback((allIds: string[]) => { if (!enabled || !isSelectionMode) return; setSelectedIds(prev => { const isAllSelected = allIds.length > 0 && allIds.every(id => prev.includes(id)); if (isAllSelected) { // 取消全选 return []; } else { // 全选(考虑最大选择数量限制) const idsToSelect = maxSelection ? allIds.slice(0, maxSelection) : allIds; return idsToSelect; } }); }, [enabled, isSelectionMode, maxSelection]); // 清空选择 const clearSelection = useCallback(() => { setSelectedIds([]); }, []); // 检查项目是否被选中 const isSelected = useCallback((id: string) => { return selectedIds.includes(id); }, [selectedIds]); // 计算全选状态 const { isAllSelected, isIndeterminate } = useMemo(() => { return { isAllSelected: false, // 这里需要外部传入allIds才能计算 isIndeterminate: selectedIds.length > 0 }; }, [selectedIds]); return { selectedIds, isSelectionMode, isAllSelected, isIndeterminate, selectedCount: selectedIds.length, toggleSelectionMode, toggleItem, toggleAll, clearSelection, isSelected, setSelectedIds }; } /** * 计算全选状态的辅助函数 */ export function calculateSelectionState(selectedIds: string[], allIds: string[]) { const selectedCount = selectedIds.length; const totalCount = allIds.length; return { isAllSelected: totalCount > 0 && selectedCount === totalCount, isIndeterminate: selectedCount > 0 && selectedCount < totalCount, selectedCount, totalCount }; }