131 lines
3.7 KiB
TypeScript
131 lines
3.7 KiB
TypeScript
import React from 'react';
|
|
import type { PageRef } from '../../pdf/pdfTypes';
|
|
import DropIndicator from './DropIndicator';
|
|
import PageCard from './PageCard';
|
|
|
|
interface PageGridProps {
|
|
pages: PageRef[];
|
|
thumbnails: Record<string, string>;
|
|
selectedPageIds: string[];
|
|
isBusy: boolean;
|
|
draggingIndex: number | null;
|
|
dropIndex: number | null;
|
|
draggingSelectionActive: boolean;
|
|
isCopyDragging: boolean;
|
|
dropIndicatorColor: string;
|
|
onDragStart: (visualIndex: number) => React.DragEventHandler<HTMLDivElement>;
|
|
onDragEnd: React.DragEventHandler<HTMLDivElement>;
|
|
onCardDragOver: (
|
|
visualIndex: number
|
|
) => React.DragEventHandler<HTMLDivElement>;
|
|
onEndSlotDragOver: React.DragEventHandler<HTMLDivElement>;
|
|
onDrop: React.DragEventHandler<HTMLDivElement>;
|
|
onOpenPreview: (pageId: string) => void;
|
|
onToggleSelect: (
|
|
pageId: string,
|
|
visualIndex: number
|
|
) => React.MouseEventHandler<HTMLButtonElement>;
|
|
onRotateClockwise: (pageId: string) => void;
|
|
onRotateCounterclockwise: (pageId: string) => void;
|
|
onDelete: (pageId: string) => void;
|
|
}
|
|
|
|
const PageGrid: React.FC<PageGridProps> = ({
|
|
pages,
|
|
thumbnails,
|
|
selectedPageIds,
|
|
isBusy,
|
|
draggingIndex,
|
|
dropIndex,
|
|
draggingSelectionActive,
|
|
isCopyDragging,
|
|
dropIndicatorColor,
|
|
onDragStart,
|
|
onDragEnd,
|
|
onCardDragOver,
|
|
onEndSlotDragOver,
|
|
onDrop,
|
|
onOpenPreview,
|
|
onToggleSelect,
|
|
onRotateClockwise,
|
|
onRotateCounterclockwise,
|
|
onDelete,
|
|
}) => {
|
|
const isSelected = (pageId: string) => selectedPageIds.includes(pageId);
|
|
|
|
const showLeftLine = (visualIndex: number) =>
|
|
dropIndex !== null && dropIndex === visualIndex && draggingIndex !== null;
|
|
|
|
const showRightLine = (visualIndex: number) =>
|
|
dropIndex !== null &&
|
|
dropIndex === visualIndex + 1 &&
|
|
draggingIndex !== null;
|
|
|
|
const showEndLine = () =>
|
|
dropIndex !== null && dropIndex === pages.length && draggingIndex !== null;
|
|
|
|
return (
|
|
<div
|
|
style={{
|
|
display: 'flex',
|
|
flexWrap: 'wrap',
|
|
gap: '0.5rem',
|
|
alignItems: 'flex-start',
|
|
marginBottom: '0.75rem',
|
|
}}
|
|
onDrop={onDrop}
|
|
>
|
|
{pages.map((page, visualIndex) => {
|
|
const selected = isSelected(page.id);
|
|
const isDraggingCard =
|
|
draggingIndex != null &&
|
|
((draggingSelectionActive && selected) ||
|
|
(!draggingSelectionActive && visualIndex === draggingIndex));
|
|
|
|
return (
|
|
<PageCard
|
|
key={page.id}
|
|
page={page}
|
|
visualIndex={visualIndex}
|
|
thumbnail={thumbnails[page.id]}
|
|
selected={selected}
|
|
isDraggingCard={isDraggingCard}
|
|
isBusy={isBusy}
|
|
isCopyDragging={isCopyDragging}
|
|
showLeftLine={showLeftLine(visualIndex)}
|
|
showRightLine={showRightLine(visualIndex)}
|
|
dropIndicatorColor={dropIndicatorColor}
|
|
onDragStart={onDragStart(visualIndex)}
|
|
onDragEnd={onDragEnd}
|
|
onDragOver={onCardDragOver(visualIndex)}
|
|
onOpenPreview={() => onOpenPreview(page.id)}
|
|
onToggleSelect={onToggleSelect(page.id, visualIndex)}
|
|
onRotateClockwise={() => onRotateClockwise(page.id)}
|
|
onRotateCounterclockwise={() => onRotateCounterclockwise(page.id)}
|
|
onDelete={() => onDelete(page.id)}
|
|
/>
|
|
);
|
|
})}
|
|
|
|
{pages.length > 0 && (
|
|
<div
|
|
onDragOver={onEndSlotDragOver}
|
|
onDrop={onDrop}
|
|
style={{
|
|
width: '20px',
|
|
height: '120px',
|
|
position: 'relative',
|
|
alignSelf: 'stretch',
|
|
}}
|
|
>
|
|
{showEndLine() && (
|
|
<DropIndicator side="end" color={dropIndicatorColor} />
|
|
)}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default PageGrid;
|