Spec Technique : Overlay Flottant & Isolation DOM (Circuy)
- Objectif & Contraintes UX
- Objectif : Afficher l'interface de création/édition de parcours directement au-dessus de l'application hôte.
- Taille & Ergonomie : L'interface doit conserver une largeur fixe par défaut (ex: 380px) et un positionnement au choix (panneau droit, dock bas, ou fenêtre modale).
- Zéro Impact Responsive : La zone d'affichage (viewport) du site client ne doit pas être réduite, évitant tout basculement en mode mobile/tablette.
- Compatibilité Cross-Browser : Comportement 100% identique sur Chrome, Firefox, Edge et Safari.
- 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 │ │ │ │ │ └────────────────────────────────────────────┘ │ │ │ └────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────┘
- 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 :
- Pass-Through de la Souris : L'overlay possède pointer-events: auto. Tout le reste de l'écran conserve son comportement normal.
- Mode Inspection (Targeting) : Lorsque l'utilisateur active le mode "Sélectionner un élément", l'overlay bascule sa fenêtre en état réduit ou transparent, et le Content Script attache un écouteur mouseover sur le DOM hôte pour dessiner un contour de sélection (spotlight) autour de l'élément visé.
- Pointeur & Modales : Si l'overlay contient des composants déroulants (dropdowns/tooltips), ils restent confinés à l'intérieur de la taille fixe de l'overlay ou déclenchent un redimensionnement dynamique du :host.