mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-09-24 04:26:14 +00:00

# Description of Changes Enable ESLint [no-unused-vars rule](https://typescript-eslint.io/rules/no-unused-vars/)
220 lines
6.4 KiB
TypeScript
220 lines
6.4 KiB
TypeScript
import {
|
|
Tooltip,
|
|
ActionIcon,
|
|
} from "@mantine/core";
|
|
import UndoIcon from "@mui/icons-material/Undo";
|
|
import RedoIcon from "@mui/icons-material/Redo";
|
|
import ContentCutIcon from "@mui/icons-material/ContentCut";
|
|
import RotateLeftIcon from "@mui/icons-material/RotateLeft";
|
|
import RotateRightIcon from "@mui/icons-material/RotateRight";
|
|
import DeleteIcon from "@mui/icons-material/Delete";
|
|
import InsertPageBreakIcon from "@mui/icons-material/InsertPageBreak";
|
|
|
|
interface PageEditorControlsProps {
|
|
// Close/Reset functions
|
|
onClosePdf: () => void;
|
|
|
|
// Undo/Redo
|
|
onUndo: () => void;
|
|
onRedo: () => void;
|
|
canUndo: boolean;
|
|
canRedo: boolean;
|
|
|
|
// Page operations
|
|
onRotate: (direction: 'left' | 'right') => void;
|
|
onDelete: () => void;
|
|
onSplit: () => void;
|
|
onSplitAll: () => void;
|
|
onPageBreak: () => void;
|
|
onPageBreakAll: () => void;
|
|
|
|
// Export functions (moved to right rail)
|
|
onExportAll: () => void;
|
|
exportLoading: boolean;
|
|
|
|
// Selection state
|
|
selectionMode: boolean;
|
|
selectedPageIds: string[];
|
|
displayDocument?: { pages: { id: string; pageNumber: number }[] };
|
|
|
|
// Split state (for tooltip logic)
|
|
splitPositions?: Set<number>;
|
|
totalPages?: number;
|
|
}
|
|
|
|
const PageEditorControls = ({
|
|
onUndo,
|
|
onRedo,
|
|
canUndo,
|
|
canRedo,
|
|
onRotate,
|
|
onDelete,
|
|
onSplit,
|
|
onPageBreak,
|
|
selectedPageIds,
|
|
displayDocument,
|
|
splitPositions,
|
|
totalPages
|
|
}: PageEditorControlsProps) => {
|
|
// Calculate split tooltip text using smart toggle logic
|
|
const getSplitTooltip = () => {
|
|
if (!splitPositions || !totalPages || selectedPageIds.length === 0) {
|
|
return "Split Selected";
|
|
}
|
|
|
|
// Convert selected pages to split positions (same logic as handleSplit)
|
|
const selectedPageNumbers = displayDocument ? selectedPageIds.map(id => {
|
|
const page = displayDocument.pages.find(p => p.id === id);
|
|
return page?.pageNumber || 0;
|
|
}).filter(num => num > 0) : [];
|
|
const selectedSplitPositions = selectedPageNumbers.map(pageNum => pageNum - 1).filter(pos => pos < totalPages - 1);
|
|
|
|
if (selectedSplitPositions.length === 0) {
|
|
return "Split Selected";
|
|
}
|
|
|
|
// Smart toggle logic: follow the majority, default to adding splits if equal
|
|
const existingSplitsCount = selectedSplitPositions.filter(pos => splitPositions.has(pos)).length;
|
|
const noSplitsCount = selectedSplitPositions.length - existingSplitsCount;
|
|
|
|
// Remove splits only if majority already have splits
|
|
// If equal (50/50), default to adding splits
|
|
const willRemoveSplits = existingSplitsCount > noSplitsCount;
|
|
|
|
if (willRemoveSplits) {
|
|
return existingSplitsCount === selectedSplitPositions.length
|
|
? "Remove All Selected Splits"
|
|
: "Remove Selected Splits";
|
|
} else {
|
|
return existingSplitsCount === 0
|
|
? "Split Selected"
|
|
: "Complete Selected Splits";
|
|
}
|
|
};
|
|
|
|
// Calculate page break tooltip text
|
|
const getPageBreakTooltip = () => {
|
|
return selectedPageIds.length > 0
|
|
? `Insert ${selectedPageIds.length} Page Break${selectedPageIds.length > 1 ? 's' : ''}`
|
|
: "Insert Page Breaks";
|
|
};
|
|
|
|
return (
|
|
<div
|
|
style={{
|
|
position: 'absolute',
|
|
left: 0,
|
|
right: 0,
|
|
bottom: 0,
|
|
zIndex: 50,
|
|
display: 'flex',
|
|
justifyContent: 'center',
|
|
pointerEvents: 'none',
|
|
background: 'transparent',
|
|
}}
|
|
>
|
|
<div
|
|
style={{
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
gap: 12,
|
|
borderTopLeftRadius: 16,
|
|
borderTopRightRadius: 16,
|
|
borderBottomLeftRadius: 0,
|
|
borderBottomRightRadius: 0,
|
|
boxShadow: '0 -2px 8px rgba(0,0,0,0.04)',
|
|
backgroundColor: 'var(--bg-toolbar)',
|
|
border: '1px solid var(--border-default)',
|
|
borderRadius: '16px 16px 0 0',
|
|
pointerEvents: 'auto',
|
|
minWidth: 360,
|
|
maxWidth: 700,
|
|
flexWrap: 'wrap',
|
|
justifyContent: 'center',
|
|
padding: "1rem",
|
|
paddingBottom: "1rem"
|
|
}}
|
|
>
|
|
|
|
{/* Undo/Redo */}
|
|
<Tooltip label="Undo">
|
|
<ActionIcon onClick={onUndo} disabled={!canUndo} variant="subtle" radius="md" size="lg">
|
|
<UndoIcon />
|
|
</ActionIcon>
|
|
</Tooltip>
|
|
<Tooltip label="Redo">
|
|
<ActionIcon onClick={onRedo} disabled={!canRedo} variant="subtle" radius="md" size="lg">
|
|
<RedoIcon />
|
|
</ActionIcon>
|
|
</Tooltip>
|
|
|
|
<div style={{ width: 1, height: 28, backgroundColor: 'var(--mantine-color-gray-3)', margin: '0 8px' }} />
|
|
|
|
{/* Page Operations */}
|
|
<Tooltip label="Rotate Selected Left">
|
|
<ActionIcon
|
|
onClick={() => onRotate('left')}
|
|
disabled={selectedPageIds.length === 0}
|
|
variant="subtle"
|
|
style={{ color: 'var(--mantine-color-dimmed)' }}
|
|
radius="md"
|
|
size="lg"
|
|
>
|
|
<RotateLeftIcon />
|
|
</ActionIcon>
|
|
</Tooltip>
|
|
<Tooltip label="Rotate Selected Right">
|
|
<ActionIcon
|
|
onClick={() => onRotate('right')}
|
|
disabled={selectedPageIds.length === 0}
|
|
variant="subtle"
|
|
style={{ color: 'var(--mantine-color-dimmed)' }}
|
|
radius="md"
|
|
size="lg"
|
|
>
|
|
<RotateRightIcon />
|
|
</ActionIcon>
|
|
</Tooltip>
|
|
<Tooltip label="Delete Selected">
|
|
<ActionIcon
|
|
onClick={onDelete}
|
|
disabled={selectedPageIds.length === 0}
|
|
variant="subtle"
|
|
style={{ color: 'var(--mantine-color-dimmed)' }}
|
|
radius="md"
|
|
size="lg"
|
|
>
|
|
<DeleteIcon />
|
|
</ActionIcon>
|
|
</Tooltip>
|
|
<Tooltip label={getSplitTooltip()}>
|
|
<ActionIcon
|
|
onClick={onSplit}
|
|
disabled={selectedPageIds.length === 0}
|
|
variant="subtle"
|
|
style={{ color: 'var(--mantine-color-dimmed)' }}
|
|
radius="md"
|
|
size="lg"
|
|
>
|
|
<ContentCutIcon />
|
|
</ActionIcon>
|
|
</Tooltip>
|
|
<Tooltip label={getPageBreakTooltip()}>
|
|
<ActionIcon
|
|
onClick={onPageBreak}
|
|
disabled={selectedPageIds.length === 0}
|
|
variant="subtle"
|
|
style={{ color: 'var(--mantine-color-dimmed)' }}
|
|
radius="md"
|
|
size="lg"
|
|
>
|
|
<InsertPageBreakIcon />
|
|
</ActionIcon>
|
|
</Tooltip>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default PageEditorControls;
|