import React from 'react';
import { ToolType } from '../canvas/tools';
import ColorPicker from './ColorPicker';
interface OnlineUser {
userId: string;
displayName: string;
color: string;
}
interface ToolbarProps {
activeTool: ToolType;
onToolChange: (tool: ToolType) => void;
color: string;
onColorChange: (color: string) => void;
strokeWidth: number;
onStrokeWidthChange: (width: number) => void;
fontSize: number;
onFontSizeChange: (size: number) => void;
zoom: number;
onFitAll: () => void;
onZoomIn?: () => void;
onZoomOut?: () => void;
canUndo: boolean;
canRedo: boolean;
onUndo: () => void;
onRedo: () => void;
onlineUsers: OnlineUser[];
onShareClick?: () => void;
onToggleLayers?: () => void;
showLayers?: boolean;
onToggleHelp?: () => void;
onMmImport?: () => void;
boardName?: string;
}
// SVG icon components
function IconSelect() {
return (
);
}
function IconPan() {
return (
);
}
function IconPen() {
return (
);
}
function IconText() {
return (
);
}
function IconEraser() {
return (
);
}
function IconUndo() {
return (
);
}
function IconRedo() {
return (
);
}
function IconFit() {
return (
);
}
function IconLayers() {
return (
);
}
const toolButtons: { tool: ToolType; label: string; shortcut: string; numKey: string; Icon: React.FC }[] = [
{ tool: ToolType.SELECT, label: 'Select', shortcut: 'V', numKey: '1', Icon: IconSelect },
{ tool: ToolType.PAN, label: 'Pan', shortcut: 'H', numKey: '2', Icon: IconPan },
{ tool: ToolType.PEN, label: 'Draw', shortcut: 'P', numKey: '3', Icon: IconPen },
{ tool: ToolType.TEXT, label: 'Text', shortcut: 'T', numKey: '4', Icon: IconText },
{ tool: ToolType.ERASER, label: 'Eraser', shortcut: 'E', numKey: '5', Icon: IconEraser },
];
export default function Toolbar({
activeTool,
onToolChange,
color,
onColorChange,
strokeWidth,
onStrokeWidthChange,
fontSize,
onFontSizeChange,
zoom,
onFitAll,
onZoomIn,
onZoomOut,
canUndo,
canRedo,
onUndo,
onRedo,
onlineUsers,
onShareClick,
onToggleLayers,
showLayers,
onToggleHelp,
onMmImport,
}: ToolbarProps) {
const showStroke = activeTool === ToolType.PEN;
const showFontSize = activeTool === ToolType.TEXT;
return (
{/* Tool buttons */}
{toolButtons.map(({ tool, label, shortcut, numKey, Icon }) => {
const active = activeTool === tool;
return (
);
})}
{/* Color */}
{/* Stroke width (pen) */}
{showStroke && (
<>
Width
onStrokeWidthChange(Number(e.target.value))}
style={{ width: '60px', height: '3px', accentColor: '#4a9eff', cursor: 'pointer' }}
/>
{strokeWidth}
>
)}
{/* Font size (text) */}
{showFontSize && (
<>
Size
onFontSizeChange(Number(e.target.value))}
style={{ width: '60px', height: '3px', accentColor: '#4a9eff', cursor: 'pointer' }}
/>
{fontSize}
>
)}
{/* Undo/Redo */}
{/* Zoom */}
{onZoomOut && (
)}
{Math.round(zoom * 100)}%
{onZoomIn && (
)}
{/* Layers toggle */}
{onToggleLayers && (
)}
{/* Help / shortcuts */}
{onToggleHelp && (
)}
{/* Mattermost import */}
{onMmImport && (
)}
{/* Spacer */}
{/* Online users */}
{onlineUsers.length > 0 && (
u.displayName).join(', ')}>
{onlineUsers.slice(0, 5).map((u, i) => (
0 ? '-6px' : '0',
zIndex: 5 - i,
boxShadow: '0 1px 3px rgba(0,0,0,0.3)',
}}>
{(u.displayName || '?')[0].toUpperCase()}
))}
{onlineUsers.length > 5 && (
+{onlineUsers.length - 5}
)}
)}
{/* Share */}
{onShareClick && (
)}
);
}
function Divider() {
return ;
}
function ActionBtn({ onClick, disabled, title, children, active }: {
onClick: () => void; disabled?: boolean; title: string; children: React.ReactNode; active?: boolean;
}) {
return (
);
}