/** * 素材选择器 — V21 设计系统 * 支持批量选择、拖拽排序、预览缩略图、质量分筛选、视图切换 * * 功能: * - 批量选择:checkbox 多选 + 全选/反选 + Shift 连选 * - 拖拽排序:HTML5 DnD,已选素材可拖拽调整顺序 * - 预览缩略图:悬浮放大预览(视频显示时长角标) * - 筛选增强:类型筛选 + 质量分筛选 * - 视图切换:网格视图 / 列表视图 */ import React, { useCallback } from "react" import "./AssetSelector.css" import type { AssetSelectorProps } from "./types" import useAssetFilter from "./hooks/useAssetFilter" import useAssetSelection from "./hooks/useAssetSelection" import useDragReorder from "./hooks/useDragReorder" import useAssetPreview from "./hooks/useAssetPreview" import SelectorToolbar from "./SelectorToolbar" import SelectorBatchBar from "./SelectorBatchBar" import AssetCard from "./AssetCard" import AssetListItem from "./AssetListItem" import PreviewOverlay from "./PreviewOverlay" import EmptyState from "./EmptyState" import type { MediaAsset } from "@/api/template-editor" const AssetSelector: React.FC = ({ assets, selectedIds = [], onSelectionChange, onAssetDragStart, onReorder, showQualityFilter = true, showBatchSelect = true, compact = false, }) => { // 搜索 & 筛选 const { searchText, filterType, filterQuality, viewMode, filteredAssets, setSearchText, setFilterType, setFilterQuality, setViewMode, } = useAssetFilter(assets) // 选中操作 const { selectedSet, toggleSelect, clearSelection } = useAssetSelection({ filteredAssets, selectedIds, onSelectionChange, }) // 拖拽排序 const { dragIdx, dragOverIdx, handleDragStart, handleDragOver, handleDrop, handleDragEnd } = useDragReorder({ filteredAssets, selectedIds, onAssetDragStart, onReorder, }) // 悬浮预览 const { previewAsset, previewPos, handleMouseEnter, handleMouseLeave } = useAssetPreview() /* ── 点击卡片 ── */ const handleCardClick = useCallback( (asset: MediaAsset, idx: number, e: React.MouseEvent) => { const target = e.target as HTMLElement if (target.closest("[data-checkbox]")) return toggleSelect(asset, idx, e.shiftKey) }, [toggleSelect], ) const hasSelection = selectedIds.length > 0 return (
{/* 工具栏 */} {/* 批量操作栏 */} {showBatchSelect && hasSelection && ( )} {/* 素材列表 */}
{filteredAssets.length === 0 ? ( ) : viewMode === "grid" ? ( /* 网格视图 */
{filteredAssets.map((asset, idx) => ( toggleSelect(a, idx, shiftKey)} onCardClick={(a, e) => handleCardClick(a, idx, e)} onDragStart={(e) => handleDragStart(e, idx)} onDragOver={(e) => handleDragOver(e, idx)} onDrop={(e) => handleDrop(e, idx)} onDragEnd={handleDragEnd} onMouseEnter={(e) => handleMouseEnter(asset, e)} onMouseLeave={handleMouseLeave} /> ))}
) : ( /* 列表视图 */
{filteredAssets.map((asset, idx) => ( toggleSelect(a, idx, shiftKey)} onCardClick={(a, e) => handleCardClick(a, idx, e)} onDragStart={(e) => handleDragStart(e, idx)} onDragOver={(e) => handleDragOver(e, idx)} onDrop={(e) => handleDrop(e, idx)} onDragEnd={handleDragEnd} onMouseEnter={(e) => handleMouseEnter(asset, e)} onMouseLeave={handleMouseLeave} /> ))}
)}
{/* 悬浮预览 */} {previewAsset && }
) } export default AssetSelector