T21: Add Print button and PrintPreview modal to RibbonBar.tsx
This commit is contained in:
@@ -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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user