102 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			102 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import React from 'react';
 | 
						|
import * as ReactDOM from 'react-dom/client';
 | 
						|
import r2wc from 'react-to-webcomponent';
 | 
						|
import ExcalidrawWrapper from './ExcalidrawElement';
 | 
						|
import type { Scene } from './types'; // Importer le type Scene si défini ailleurs
 | 
						|
import { exportToBlob, exportToSvg } from '@excalidraw/excalidraw'; // Importer les fonctions exportToBlob et exportToSvg
 | 
						|
 | 
						|
// Définition du type pour l'événement personnalisé
 | 
						|
declare global {
 | 
						|
  interface HTMLElementEventMap {
 | 
						|
    'ready': CustomEvent<{ apiAvailable: boolean }>;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
// Map attributes/props to React props
 | 
						|
const BaseCE = r2wc(ExcalidrawWrapper as any, React as any, ReactDOM as any, {
 | 
						|
  props: {
 | 
						|
    initialData: 'json',
 | 
						|
    readOnly: 'boolean',
 | 
						|
    theme: 'string',
 | 
						|
    lang: 'string',
 | 
						|
    gridMode: 'boolean',
 | 
						|
    zenMode: 'boolean',
 | 
						|
    hostRef: 'object',
 | 
						|
  },
 | 
						|
  // render in light DOM to allow package styles to apply
 | 
						|
});
 | 
						|
 | 
						|
class ExcalidrawElement extends (BaseCE as any) {
 | 
						|
  connectedCallback() {
 | 
						|
    // Ensure the React component receives a reference to the host element before first render
 | 
						|
    (this as any).__host = this;
 | 
						|
    (this as any).hostRef = this;
 | 
						|
 | 
						|
    // Dispatch a ready event once the API has been set on the host by the React wrapper
 | 
						|
    const onReady = () => {
 | 
						|
      console.log('[excalidraw-editor] 🎨 READY event dispatched', { apiAvailable: !!(this as any).__excalidrawAPI });
 | 
						|
      this.dispatchEvent(new CustomEvent('ready', {
 | 
						|
        detail: { apiAvailable: !!(this as any).__excalidrawAPI },
 | 
						|
        bubbles: true,
 | 
						|
        composed: true,
 | 
						|
      }));
 | 
						|
    };
 | 
						|
 | 
						|
    if ((this as any).__excalidrawAPI) {
 | 
						|
      onReady();
 | 
						|
    } else {
 | 
						|
      const checkApi = setInterval(() => {
 | 
						|
        if ((this as any).__excalidrawAPI) {
 | 
						|
          clearInterval(checkApi);
 | 
						|
          onReady();
 | 
						|
        }
 | 
						|
      }, 100);
 | 
						|
    }
 | 
						|
 | 
						|
    super.connectedCallback?.();
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  // Imperative API surface
 | 
						|
  getScene() {
 | 
						|
    const api = (this as any).__excalidrawAPI;
 | 
						|
    if (!api) return { elements: [], appState: {}, files: {} } as Scene;
 | 
						|
    return {
 | 
						|
      elements: api.getSceneElements?.() ?? [],
 | 
						|
      appState: api.getAppState?.() ?? {},
 | 
						|
      files: api.getFiles?.() ?? {},
 | 
						|
    } as Scene;
 | 
						|
  }
 | 
						|
  exportPNG(opts?: { withBackground?: boolean }) {
 | 
						|
    const api = (this as any).__excalidrawAPI;
 | 
						|
    if (!api) return { elements: [], appState: {}, files: {} };
 | 
						|
    const elements = api.getSceneElements?.() ?? [];
 | 
						|
    const appState = { ...(api.getAppState?.() ?? {}), exportBackground: !!opts?.withBackground } as any;
 | 
						|
    const files = api.getFiles?.() ?? {};
 | 
						|
    return exportToBlob({ elements, appState, files, mimeType: 'image/png', quality: 1 });
 | 
						|
  }
 | 
						|
  async exportSVG(opts?: { withBackground?: boolean }) {
 | 
						|
    const api = (this as any).__excalidrawAPI;
 | 
						|
    if (!api) return { elements: [], appState: {}, files: {} };
 | 
						|
    const elements = api.getSceneElements?.() ?? [];
 | 
						|
    const appState = { ...(api.getAppState?.() ?? {}), exportBackground: !!opts?.withBackground } as any;
 | 
						|
    const files = api.getFiles?.() ?? {};
 | 
						|
    const svgEl = await exportToSvg({ elements, appState, files });
 | 
						|
    const svgText = new XMLSerializer().serializeToString(svgEl);
 | 
						|
    return new Blob([svgText], { type: 'image/svg+xml' });
 | 
						|
  }
 | 
						|
  setScene(scene: any) {
 | 
						|
    const api = (this as any).__excalidrawAPI;
 | 
						|
    if (!api) return;
 | 
						|
    api.updateScene(scene);
 | 
						|
  }
 | 
						|
  refresh() {
 | 
						|
    const api = (this as any).__excalidrawAPI;
 | 
						|
    if (!api) return;
 | 
						|
    api.refresh();
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
if (!customElements.get('excalidraw-editor')) {
 | 
						|
  customElements.define('excalidraw-editor', ExcalidrawElement as any);
 | 
						|
} |