T21: Add Print button and PrintPreview modal to RibbonBar.tsx

This commit is contained in:
2026-06-22 23:21:08 +00:00
parent c9f21ea38d
commit 5178e2a4fc
+25 -23
View File
@@ -2,6 +2,7 @@ import React, { useState, useRef, useCallback } from 'react';
import type { YjsDocument } from '../crdt/YjsDocument'; import type { YjsDocument } from '../crdt/YjsDocument';
import { exportDrawing, type ExportFormat } from '../services/exportService'; import { exportDrawing, type ExportFormat } from '../services/exportService';
import { importDrawing, type ImportFormat, type ImportResult } from '../services/importService'; import { importDrawing, type ImportFormat, type ImportResult } from '../services/importService';
import PrintPreview from './PrintPreview/PrintPreview';
import './RibbonBar.css'; import './RibbonBar.css';
interface RibbonBarProps { interface RibbonBarProps {
@@ -14,6 +15,7 @@ const RibbonBar: React.FC<RibbonBarProps> = ({ onTabChange, yjsDoc }) => {
const [showExportMenu, setShowExportMenu] = useState(false); const [showExportMenu, setShowExportMenu] = useState(false);
const [showImportMenu, setShowImportMenu] = useState(false); const [showImportMenu, setShowImportMenu] = useState(false);
const [importStatus, setImportStatus] = useState<string | null>(null); const [importStatus, setImportStatus] = useState<string | null>(null);
const [showPrintPreview, setShowPrintPreview] = useState(false);
const fileInputRef = useRef<HTMLInputElement>(null); const fileInputRef = useRef<HTMLInputElement>(null);
const pendingImportFormat = useRef<ImportFormat>('json'); const pendingImportFormat = useRef<ImportFormat>('json');
@@ -75,7 +77,6 @@ const RibbonBar: React.FC<RibbonBarProps> = ({ onTabChange, yjsDoc }) => {
setImportStatus(`Import error: ${(err as Error).message}`); setImportStatus(`Import error: ${(err as Error).message}`);
} }
setTimeout(() => setImportStatus(null), 5000); setTimeout(() => setImportStatus(null), 5000);
// Reset input so same file can be selected again
if (fileInputRef.current) { if (fileInputRef.current) {
fileInputRef.current.value = ''; fileInputRef.current.value = '';
} }
@@ -96,7 +97,6 @@ const RibbonBar: React.FC<RibbonBarProps> = ({ onTabChange, yjsDoc }) => {
</button> </button>
))} ))}
{/* Export/Import section */}
<div className="ribbon-divider" aria-hidden="true" /> <div className="ribbon-divider" aria-hidden="true" />
<div className="ribbon-dropdown-wrapper"> <div className="ribbon-dropdown-wrapper">
@@ -112,18 +112,10 @@ const RibbonBar: React.FC<RibbonBarProps> = ({ onTabChange, yjsDoc }) => {
</button> </button>
{showExportMenu && ( {showExportMenu && (
<div className="ribbon-dropdown" role="menu"> <div className="ribbon-dropdown" role="menu">
<button className="ribbon-dropdown-item" onClick={() => handleExport('json')} role="menuitem"> <button className="ribbon-dropdown-item" onClick={() => handleExport('json')} role="menuitem">JSON</button>
JSON <button className="ribbon-dropdown-item" onClick={() => handleExport('svg')} role="menuitem">SVG</button>
</button> <button className="ribbon-dropdown-item" onClick={() => handleExport('dxf')} role="menuitem">DXF</button>
<button className="ribbon-dropdown-item" onClick={() => handleExport('svg')} role="menuitem"> <button className="ribbon-dropdown-item" onClick={() => handleExport('pdf')} role="menuitem">PDF</button>
SVG
</button>
<button className="ribbon-dropdown-item" onClick={() => handleExport('dxf')} role="menuitem">
DXF
</button>
<button className="ribbon-dropdown-item" onClick={() => handleExport('pdf')} role="menuitem">
PDF
</button>
</div> </div>
)} )}
</div> </div>
@@ -141,20 +133,26 @@ const RibbonBar: React.FC<RibbonBarProps> = ({ onTabChange, yjsDoc }) => {
</button> </button>
{showImportMenu && ( {showImportMenu && (
<div className="ribbon-dropdown" role="menu"> <div className="ribbon-dropdown" role="menu">
<button className="ribbon-dropdown-item" onClick={() => triggerImport('json')} role="menuitem"> <button className="ribbon-dropdown-item" onClick={() => triggerImport('json')} role="menuitem">JSON</button>
JSON <button className="ribbon-dropdown-item" onClick={() => triggerImport('dxf')} role="menuitem">DXF</button>
</button>
<button className="ribbon-dropdown-item" onClick={() => triggerImport('dxf')} role="menuitem">
DXF
</button>
</div> </div>
)} )}
</div> </div>
<div className="ribbon-divider" aria-hidden="true" />
<button
className="ribbon-tab"
onClick={() => setShowPrintPreview(true)}
role="menuitem"
aria-label="Print Preview"
>
<span className="tab-icon" aria-hidden="true">🖨</span>
<span className="tab-label">Print</span>
</button>
{importStatus && ( {importStatus && (
<span className="ribbon-status" role="status" aria-live="polite"> <span className="ribbon-status" role="status" aria-live="polite">{importStatus}</span>
{importStatus}
</span>
)} )}
<input <input
@@ -163,6 +161,10 @@ const RibbonBar: React.FC<RibbonBarProps> = ({ onTabChange, yjsDoc }) => {
style={{ display: 'none' }} style={{ display: 'none' }}
onChange={handleFileSelected} onChange={handleFileSelected}
/> />
{showPrintPreview && (
<PrintPreview yjsDoc={yjsDoc ?? null} onClose={() => setShowPrintPreview(false)} />
)}
</div> </div>
); );
}; };