/** * PrintButton — reusable button with dropdown for Print and PDF export. * Uses lucide-react icons and clsx for styling. */ import React, { useState, useRef, useEffect, useCallback } from 'react'; import clsx from 'clsx'; import { Printer, FileDown, ChevronDown } from 'lucide-react'; import { printElement, printCurrentPage, exportToPDF } from '@/utils/print'; export interface PrintButtonProps { /** Element id to print. If omitted, prints the whole page. */ targetId?: string; /** Filename suggestion for PDF export. */ filename?: string; /** Additional Tailwind classes for the trigger button. */ className?: string; } export function PrintButton({ targetId, filename = 'export', className, }: PrintButtonProps) { const [open, setOpen] = useState(false); const containerRef = useRef(null); // Close dropdown when clicking outside useEffect(() => { if (!open) return; const handleClickOutside = (e: MouseEvent) => { if (containerRef.current && !containerRef.current.contains(e.target as Node)) { setOpen(false); } }; const handleEscape = (e: KeyboardEvent) => { if (e.key === 'Escape') setOpen(false); }; document.addEventListener('mousedown', handleClickOutside); document.addEventListener('keydown', handleEscape); return () => { document.removeEventListener('mousedown', handleClickOutside); document.removeEventListener('keydown', handleEscape); }; }, [open]); const handlePrint = useCallback(() => { setOpen(false); if (targetId) { printElement(targetId); } else { printCurrentPage(); } }, [targetId]); const handleExportPDF = useCallback(() => { setOpen(false); if (targetId) { exportToPDF(targetId, filename); } else { // No specific element — use whole-page print which user can save as PDF printCurrentPage(); } }, [targetId, filename]); return (
{open && (
)}
); }