@@ -5,6 +5,7 @@ import { generateZPL } from '../../lib/zplGenerator';
55import { fetchPreview , labelaryErrorMessage } from '../../lib/labelary' ;
66import { triggerDownload } from '../../lib/triggerDownload' ;
77import { useT } from '../../lib/useT' ;
8+ import { DialogShell } from '../ui/DialogShell' ;
89
910interface Props {
1011 onClose : ( ) => void ;
@@ -51,72 +52,65 @@ export function LabelPreviewModal({ onClose }: Props) {
5152 } ;
5253
5354 return (
54- < div
55- className = "fixed inset-0 z-50 flex items-center justify-center bg-black/50"
56- onClick = { onClose }
57- role = "dialog"
58- aria-modal = "true"
59- aria-labelledby = "label-preview-title"
55+ < DialogShell
56+ onClose = { onClose }
57+ labelledBy = "label-preview-title"
58+ boxClassName = "bg-surface border border-border-2 rounded shadow-lg flex flex-col overflow-hidden max-w-[90vw] max-h-[90vh]"
6059 >
61- < div
62- className = "bg-surface border border-border-2 rounded shadow-lg flex flex-col overflow-hidden max-w-[90vw] max-h-[90vh]"
63- onClick = { ( e ) => e . stopPropagation ( ) }
64- >
65- < div className = "flex items-center justify-between px-3 py-1.5 border-b border-border-2 shrink-0" >
66- < span id = "label-preview-title" className = "font-mono text-[10px] text-muted uppercase tracking-widest" >
67- { t . output . previewHeading }
68- </ span >
69- < button
70- onClick = { onClose }
71- aria-label = { t . app . close }
72- className = "p-0.5 rounded text-muted hover:text-text hover:bg-surface-2 transition-colors ml-6"
73- >
74- < XMarkIcon className = "w-4 h-4" />
75- </ button >
76- </ div >
60+ < div className = "flex items-center justify-between px-3 py-1.5 border-b border-border-2 shrink-0" >
61+ < span id = "label-preview-title" className = "font-mono text-[10px] text-muted uppercase tracking-widest" >
62+ { t . output . previewHeading }
63+ </ span >
64+ < button
65+ onClick = { onClose }
66+ aria-label = { t . app . close }
67+ className = "p-0.5 rounded text-muted hover:text-text hover:bg-surface-2 transition-colors ml-6"
68+ >
69+ < XMarkIcon className = "w-4 h-4" />
70+ </ button >
71+ </ div >
7772
78- { /* Inset preview area: bg-bg gives a clear edge against the surrounding
79- surface (especially in light mode where the label image is white).
80- The outer div scrolls; the inner one stays at least as large as the
81- viewport so small previews are still centered. */ }
82- < div className = "flex-1 overflow-auto bg-bg min-h-24 min-w-48" >
83- < div className = "min-h-full min-w-full flex items-center justify-center p-4" >
84- { loading && (
85- < span className = "font-mono text-[10px] text-muted animate-pulse" > { t . output . loading } </ span >
86- ) }
87- { ! loading && error && (
88- < div className = "flex flex-col items-center gap-3 max-w-64 text-center" >
89- < span className = "font-mono text-[10px] text-amber-400 leading-relaxed" > { error } </ span >
90- < button
91- onClick = { handleDownloadFallback }
92- className = "flex items-center gap-1.5 px-3 py-1.5 rounded text-[10px] font-mono bg-surface-2 border border-border text-muted hover:text-text hover:border-accent transition-colors"
93- >
94- < ArrowDownTrayIcon className = "w-3.5 h-3.5" />
95- Export ZPL instead
96- </ button >
97- </ div >
98- ) }
99- { ! loading && ! error && previewUrl && (
100- < img
101- src = { previewUrl }
102- alt = "Label preview"
103- className = "block shrink-0"
104- />
105- ) }
106- </ div >
73+ { /* Inset preview area: bg-bg gives a clear edge against the surrounding
74+ surface (especially in light mode where the label image is white).
75+ The outer div scrolls; the inner one stays at least as large as the
76+ viewport so small previews are still centered. */ }
77+ < div className = "flex-1 overflow-auto bg-bg min-h-24 min-w-48" >
78+ < div className = "min-h-full min-w-full flex items-center justify-center p-4" >
79+ { loading && (
80+ < span className = "font-mono text-[10px] text-muted animate-pulse" > { t . output . loading } </ span >
81+ ) }
82+ { ! loading && error && (
83+ < div className = "flex flex-col items-center gap-3 max-w-64 text-center" >
84+ < span className = "font-mono text-[10px] text-amber-400 leading-relaxed" > { error } </ span >
85+ < button
86+ onClick = { handleDownloadFallback }
87+ className = "flex items-center gap-1.5 px-3 py-1.5 rounded text-[10px] font-mono bg-surface-2 border border-border text-muted hover:text-text hover:border-accent transition-colors"
88+ >
89+ < ArrowDownTrayIcon className = "w-3.5 h-3.5" />
90+ Export ZPL instead
91+ </ button >
92+ </ div >
93+ ) }
94+ { ! loading && ! error && previewUrl && (
95+ < img
96+ src = { previewUrl }
97+ alt = "Label preview"
98+ className = "block shrink-0"
99+ />
100+ ) }
107101 </ div >
102+ </ div >
108103
109- < div className = "px-3 py-1 border-t border-border-2 shrink-0 text-center" >
110- < a
111- href = "https://labelary.com/"
112- target = "_blank"
113- rel = "noreferrer"
114- className = "font-mono text-[9px] text-muted hover:text-accent transition-colors"
115- >
116- { t . output . previewProvider }
117- </ a >
118- </ div >
104+ < div className = "px-3 py-1 border-t border-border-2 shrink-0 text-center" >
105+ < a
106+ href = "https://labelary.com/"
107+ target = "_blank"
108+ rel = "noreferrer"
109+ className = "font-mono text-[9px] text-muted hover:text-accent transition-colors"
110+ >
111+ { t . output . previewProvider }
112+ </ a >
119113 </ div >
120- </ div >
114+ </ DialogShell >
121115 ) ;
122116}
0 commit comments