Files
pdf/frontend/src/components/ToolRail.tsx
T

99 lines
4.5 KiB
TypeScript

import { CustomButton } from './custom/CustomButton';
import React from 'react';
import type { ToolId } from '../lib/tools';
import { Popover } from './ui';
import {
SelectIcon, PanIcon, HighlightIcon, DrawIcon, CommentIcon, TextBoxIcon,
SignatureIcon, StampIcon, RedactIcon, InfoIcon, HelpIcon,
} from './icons';
interface ToolDef { id: ToolId; label: string; shortcut: string; icon: React.ReactNode; danger?: boolean }
const TOOLS: (ToolDef | 'divider')[] = [
{ id: 'select', label: 'Select & copy text', shortcut: 'V', icon: <SelectIcon /> },
{ id: 'pan', label: 'Pan', shortcut: 'H', icon: <PanIcon /> },
'divider',
{ id: 'highlight', label: 'Highlight', shortcut: 'K', icon: <HighlightIcon /> },
{ id: 'draw', label: 'Draw (ink)', shortcut: 'D', icon: <DrawIcon /> },
{ id: 'comment', label: 'Comment', shortcut: 'C', icon: <CommentIcon /> },
{ id: 'textbox', label: 'Text box', shortcut: 'T', icon: <TextBoxIcon /> },
{ id: 'signature', label: 'Signature', shortcut: 'S', icon: <SignatureIcon /> },
{ id: 'stamp', label: 'Stamp', shortcut: 'M', icon: <StampIcon /> },
'divider',
{ id: 'redact', label: 'Redact', shortcut: 'R', icon: <RedactIcon />, danger: true },
];
interface ToolRailProps {
activeTool: ToolId;
onToolChange: (t: ToolId) => void;
hasSignature: boolean;
onOpenSignature: () => void;
onOpenAbout: () => void;
}
const RailButton: React.FC<{ t: ToolDef; active: boolean; onClick: () => void }> = ({ t, active, onClick }) => (
<CustomButton variant="unstyled"
title={`${t.label} · ${t.shortcut}`}
aria-label={t.label}
aria-pressed={active}
onClick={onClick}
className={`relative flex h-11 w-11 items-center justify-center rounded-[10px] transition-colors ${
active
? t.danger ? 'bg-[#fdecec] text-[#dc2626]' : 'bg-[#eef4ff] text-[#2563eb]'
: t.danger ? 'text-[#5b6573] hover:bg-[#fdecec] hover:text-[#dc2626]'
: 'text-[#5b6573] hover:bg-[#edeff2] hover:text-[#18212e]'
}`}
>
{active && <span className="absolute left-[-10px] h-5 w-[3px] rounded-full" style={{ background: t.danger ? '#dc2626' : '#2563eb' }} />}
{React.isValidElement(t.icon) ? React.cloneElement(t.icon as React.ReactElement<{ size?: number }>, { size: 22 }) : t.icon}
</CustomButton>
);
export const ToolRail: React.FC<ToolRailProps> = ({ activeTool, onToolChange, hasSignature, onOpenSignature, onOpenAbout }) => {
const pickTool = (id: ToolId) => {
onToolChange(id);
if (id === 'signature' && !hasSignature) onOpenSignature();
};
return (
<nav className="flex h-full shrink-0 flex-col items-center gap-1.5 border-r border-[#ebedf0] bg-[#ffffff]" style={{ width: '80px', paddingTop: '14px', paddingBottom: '12px' }}>
{TOOLS.map((t, i) =>
t === 'divider'
? <div key={`d${i}`} className="my-0.5 h-px w-6 bg-[#ebedf0]" />
: <RailButton key={t.id} t={t} active={activeTool === t.id} onClick={() => pickTool(t.id)} />,
)}
<div className="flex-1" />
<CustomButton variant="unstyled" title="About Maskan PDF Editor" onClick={onOpenAbout} className="flex h-9 w-9 items-center justify-center rounded-[10px] text-[#98a1ad] transition-colors hover:bg-[#edeff2] hover:text-[#18212e]">
<InfoIcon size={19} />
</CustomButton>
<Popover
align="left"
width={210}
trigger={(open) => (
<CustomButton variant="unstyled" title="Keyboard shortcuts" className={`flex h-9 w-9 items-center justify-center rounded-[10px] transition-colors ${open ? 'bg-[#edeff2] text-[#18212e]' : 'text-[#98a1ad] hover:bg-[#edeff2] hover:text-[#18212e]'}`}>
<HelpIcon size={19} />
</CustomButton>
)}
>
<div className="text-[12px]">
<p className="mb-1.5 px-1 font-bold text-[#18212e]">Shortcuts</p>
{TOOLS.filter((t): t is ToolDef => t !== 'divider').map((t) => (
<div key={t.id} className="flex items-center justify-between px-1 py-0.5">
<span className="text-[#5b6573]">{t.label}</span>
<kbd className="rounded border border-[#ebedf0] bg-[#f6f7f9] px-1.5 text-[10px] font-semibold">{t.shortcut}</kbd>
</div>
))}
<div className="my-1 h-px bg-[#ebedf0]" />
<div className="flex items-center justify-between px-1 py-0.5">
<span className="text-[#5b6573]">Undo / Redo</span>
<kbd className="rounded border border-[#ebedf0] bg-[#f6f7f9] px-1.5 text-[10px] font-semibold">Ctrl+Z / Y</kbd>
</div>
</div>
</Popover>
</nav>
);
};