Spec Technique : Overlay Flottant & Isolation DOM (Circuy)

  1. Objectif & Contraintes UX
  1. Architecture Technique (Shadow DOM + WXT) Plutôt que d'utiliser l'API native sidePanel / sidebarAction qui modifie le layout du navigateur, l'extension injecte un composant d'interface encapsulé via l'API Content Script de WXT. ┌──────────────────────────────────────────────────────────┐ │ Page Web Hôte (site du client) │ │ │ │ [ Bouton A ] [ Zone de Contenu ] │ │ │ │ ┌────────────────────────────────────────────────────┐ │ │ │ #shadow-root (closed) │ │ │ │ │ │ │ │ ┌────────────────────────────────────────────┐ │ │ │ │ │ 🎨 Interface React (Circuy Editor) │ │ │ │ │ │ - Position: fixed (z-index: 2147483647) │ │ │ │ │ │ - Width: 380px │ │ │ │ │ └────────────────────────────────────────────┘ │ │ │ └────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────┘
  2. Implémentation du Content Script avec WXT 3.1 Point d'entrée Content Script (src/entrypoints/content/index.ts) WXT fournit la méthode createIntegratedUi qui gère l'injection et le cycle de vie du Shadow DOM sans fuites mémoire ni conflits CSS. import { defineContentScript, createIntegratedUi } from 'wxt/sandbox'; import { createApp } from 'vue'; // Ou React (ReactDOM.createRoot) import EditorApp from './EditorApp.vue'; import styleText from './style.css?inline'; // Import des styles Tailwind/Custom sous forme de string export default defineContentScript({ matches: ['<all_urls>'], // Injecte les styles uniquement dans le Shadow Root, pas dans la page hôte cssInjectionMode: 'ui', async main(ctx) { const ui = await createIntegratedUi(ctx, { position: 'inline', // Injection dans le DOM pour un positionnement fixed anchor: 'body', append: 'last', onMount: (container) => { // Injection manuelle des styles isolés const styleEl = document.createElement('style'); styleEl.textContent = styleText; container.append(styleEl);
    // Montage de l'application UI
    const app = createApp(EditorApp);
    app.mount(container);
    return app;
  },
  onRemove: (app) => {
    app?.unmount();
  },
});

// Écoute les messages du Background Worker pour ouvrir/fermer l'overlay
chrome.runtime.onMessage.addListener((message) => {
  if (message.type === 'TOGGLE_CIRCUY_EDITOR') {
    if (ui.mounted) {
      ui.unmount();
    } else {
      ui.mount();
    }
  }
});

}, }); 4. Stratégie d'Isolation & Style CSS 4.1 Encapsulation du Style (style.css) Le CSS est appliqué au conteneur hôte (:host) présent au sein du Shadow Root. Il garantit la persistance au premier plan absolu. /* Conteneur principal de l'UI Circuy dans le Shadow Root / :host { all: initial; / Annule tout héritage CSS de la page hôte / position: fixed !important; top: 16px; right: 16px; width: 380px; height: calc(100vh - 32px); z-index: 2147483647 !important; / Valeur maximale 32-bit d'un z-index / pointer-events: auto; font-family: 'Inter', system-ui, -apple-system, sans-serif; } / Variante de positionnement : Dock en bas */ :host(.mode-bottom-dock) { top: auto; bottom: 16px; right: 16px; left: 16px; width: auto; height: 280px; } .circuy-editor-card { width: 100%; height: 100%; background-color: #0F172A; color: #F8FAFC; border-radius: 12px; box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.3), 0 8px 10px -6px rgba(0, 0, 0, 0.3); border: 1px solid #1E293B; display: flex; flex-direction: column; overflow: hidden; } 5. Gestion des Interactions avec la Page Hôte Pour permettre à l'utilisateur d'inspecter et de cliquer sur la page tout en gardant l'overlay ouvert :