@@ -180,87 +180,77 @@ const InlineChartComponent = ({ node, updateAttributes, deleteNode }: any) => {
180180 if ( ! chartRef . current ) return ;
181181
182182 setIsExporting ( true ) ;
183+ const originalStyle = chartRef . current . getAttribute ( 'style' ) || '' ;
184+
183185 try {
186+ // 1. LIVE RESIZE: Force the chart to 1000px off-screen in the actual DOM
187+ // This allows Recharts to recalculate the ResponsiveContainer BEFORE capture
188+ chartRef . current . style . position = 'fixed' ;
189+ chartRef . current . style . left = '-5000px' ;
190+ chartRef . current . style . top = '0' ;
191+ chartRef . current . style . width = '1000px' ;
192+ chartRef . current . style . zIndex = '-9999' ;
193+ chartRef . current . style . visibility = 'visible' ;
194+ chartRef . current . style . opacity = '1' ;
195+
196+ // 2. WAIT FOR LAYOUT: Give Recharts 800ms to re-render SVG at 1000px
197+ await new Promise ( resolve => setTimeout ( resolve , 800 ) ) ;
198+
184199 const elementToCapture = chartRef . current ;
185200
186- // Use html2canvas with Clean-Room Reparenting strategy
201+ // 3. CAPTURE WITH ONCLONE ISOLATION
187202 const canvas = await html2canvas ( elementToCapture , {
188203 scale : 2 ,
189204 backgroundColor : isDark ? '#171717' : '#ffffff' ,
190205 useCORS : true ,
191206 logging : false ,
192207 onclone : ( clonedDoc ) => {
193- // 1. CLEAN-ROOM REPARENTING: Find our target chart in the clone
194- // We need to find the specific element that matches our chartRef
195- const chartInClone = clonedDoc . querySelector ( '.inline-chart-wrapper' ) ;
196- if ( ! chartInClone ) return ;
197-
198- // 2. NUCLEAR STRIP: Remove EVERYTHING from the cloned body
199- clonedDoc . body . innerHTML = '' ;
200-
201- // 3. REPARENT: Put the chart directly into the body
202- clonedDoc . body . appendChild ( chartInClone ) ;
203-
204- // 4. STYLE ISOLATION: Remove all project-wide styles and inject safe ones
208+ // NUCLEAR STRIP: Remove modern color crashes
205209 const styles = clonedDoc . querySelectorAll ( 'style, link[rel="stylesheet"]' ) ;
206210 styles . forEach ( s => s . remove ( ) ) ;
207211
208212 const safeStyles = clonedDoc . createElement ( 'style' ) ;
209213 safeStyles . innerHTML = `
210- * { box-sizing: border-box; -webkit-print-color-adjust: exact; }
211- body {
212- background: ${ isDark ? '#0a0a0a' : '#ffffff' } !important;
213- width: 1100px !important;
214- height: auto !important;
215- margin: 0 !important;
216- padding: 60px !important;
217- display: flex !important;
218- justify-content: center !important;
219- align-items: flex-start !important;
220- overflow: visible !important;
221- font-family: -apple-system, system-ui, sans-serif !important;
222- }
214+ * { box-sizing: border-box; }
223215 .inline-chart-wrapper {
224216 width: 1000px !important;
225- display: block !important;
226- background: transparent !important;
227- opacity: 1 !important;
228- visibility: visible !important;
229- transform: none !important;
217+ padding: 40px !important;
218+ background: ${ isDark ? '#171717' : '#ffffff' } !important;
219+ display: block !important;
220+ font-family: -apple-system, sans-serif !important;
230221 }
231222 .bg-\\[var\\(--bg-sidebar\\)\\] {
232- background: ${ isDark ? '#171717' : '#ffffff' } !important;
233- border-radius: 24px !important;
234- padding: 56px !important;
235- border: 1px solid ${ isDark ? '#262626' : '#e5e5e5' } !important;
236- box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25) !important;
223+ background: ${ isDark ? '#171717' : '#ffffff' } !important;
224+ border-radius: 24px !important;
225+ padding: 48px !important;
226+ border: 1px solid ${ isDark ? '#262626' : '#e5e5e5' } !important;
237227 width: 100% !important;
238228 }
239229 .text-\\[var\\(--text-primary\\)\\] { color: ${ isDark ? '#f5f5f5' : '#171717' } !important; }
240230 .text-\\[var\\(--text-muted\\)\\] { color: #888888 !important; }
241- .h-72 { width: 100% !important; height: 450px !important; margin-top: 32px !important; }
242- .text-xl { font-size: 36px !important; font-weight: 800 !important; margin: 0 !important; color: ${ isDark ? '#f5f5f5' : '#171717' } !important; }
243- .text-xs { font-size: 16px !important; margin-top: 8px !important; color: #888888 !important; }
231+ .h-72 { width: 100% !important; height: 400px !important; margin-top: 32px !important; }
232+ .text-xl { font-size: 32px !important; font-weight: 800 !important; margin: 0 !important; }
233+ .text-xs { font-size: 14px !important; margin-top: 6px !important; }
244234 .flex { display: flex !important; }
245235 .items-center { align-items: center !important; }
246236 .items-start { align-items: flex-start !important; }
247237 .justify-between { justify-content: space-between !important; }
248- .mb-6 { margin-bottom: 32px !important; }
249- .gap-3 { gap: 16px !important; }
250- .capture-hide { display: none !important; visibility: hidden !important; }
238+ .mb-6 { margin-bottom: 24px !important; }
239+ .gap-3 { gap: 12px !important; }
240+ .capture-hide { display: none !important; }
251241 .recharts-responsive-container { width: 100% !important; height: 100% !important; }
252242 svg { width: 100% !important; height: 100% !important; display: block; }
253- .recharts-text { fill: #888888 !important; font-size: 13px !important; font-weight: 600 !important; }
243+ .recharts-text { fill: #888888 !important; font-size: 12px !important; font-weight: 600 !important; }
254244 .recharts-legend-item-text { fill: #888888 !important; font-weight: 600 !important; }
255245 .recharts-cartesian-grid-line { stroke: ${ isDark ? '#262626' : '#e5e5e5' } !important; }
256246 ` ;
257247 clonedDoc . head . appendChild ( safeStyles ) ;
258248
259- // 5. SCRUB INLINE OKLAB COLORS
249+ // SCRUB INLINE OKLAB COLORS
260250 clonedDoc . querySelectorAll ( '*' ) . forEach ( el => {
261251 if ( el instanceof HTMLElement ) {
262- const inlineStyle = el . getAttribute ( 'style' ) || '' ;
263- if ( inlineStyle . includes ( 'okl' ) ) {
252+ const s = el . getAttribute ( 'style' ) || '' ;
253+ if ( s . includes ( 'okl' ) ) {
264254 el . style . color = '' ;
265255 el . style . backgroundColor = '' ;
266256 el . style . borderColor = '' ;
@@ -276,8 +266,12 @@ const InlineChartComponent = ({ node, updateAttributes, deleteNode }: any) => {
276266 link . click ( ) ;
277267 } catch ( err : any ) {
278268 console . error ( 'Export Error:' , err ) ;
279- alert ( `Export error : ${ err . message || 'Unknown failure' } ` ) ;
269+ alert ( `Export failed : ${ err . message || 'Unknown failure' } ` ) ;
280270 } finally {
271+ // 4. RESTORE ORIGINAL STATE
272+ if ( chartRef . current ) {
273+ chartRef . current . setAttribute ( 'style' , originalStyle ) ;
274+ }
281275 setIsExporting ( false ) ;
282276 }
283277 } }
0 commit comments