diff --git a/packages/sigma/src/core/captors/mouse.ts b/packages/sigma/src/core/captors/mouse.ts
index 749d00e72..cbc851f4c 100644
--- a/packages/sigma/src/core/captors/mouse.ts
+++ b/packages/sigma/src/core/captors/mouse.ts
@@ -238,7 +238,7 @@ export default class MouseCaptor<
// Only trigger the "mousemove" event when the mouse is actually hovering
// the container, to avoid weirdly hovering nodes and/or edges when the
// mouse is not hover the container:
- if (e.target === this.container) {
+ if (e.target === this.container || e.composedPath()[0] === this.container) {
this.emit("mousemove", mouseCoords);
}
diff --git a/packages/storybook/stories/events-shadowdom/index.html b/packages/storybook/stories/events-shadowdom/index.html
new file mode 100644
index 000000000..67e3a3803
--- /dev/null
+++ b/packages/storybook/stories/events-shadowdom/index.html
@@ -0,0 +1,29 @@
+
+
+
diff --git a/packages/storybook/stories/events-shadowdom/index.ts b/packages/storybook/stories/events-shadowdom/index.ts
new file mode 100644
index 000000000..7d1782646
--- /dev/null
+++ b/packages/storybook/stories/events-shadowdom/index.ts
@@ -0,0 +1,109 @@
+import Graph from "graphology";
+import Sigma from "sigma";
+import { MouseCoords } from "sigma/types";
+
+import data from "../_data/data.json";
+
+/**
+ * This is a minimal example of sigma. You can use it as a base to write new
+ * examples, or reproducible test cases for new issues, for instance.
+ */
+export default () => {
+ const logsDOM = document.getElementById("sigma-logs") as HTMLElement;
+ const graph = new Graph();
+ graph.import(data);
+
+ function logEvent(event: string, itemType: "node" | "edge" | "positions", item: string | MouseCoords): void {
+ const div = document.createElement("div");
+ let message = `Event "${event}"`;
+ if (item && itemType) {
+ if (itemType === "positions") {
+ item = item as MouseCoords;
+ message += `, x ${item.x}, y ${item.y}`;
+ } else {
+ const label =
+ itemType === "node" ? graph.getNodeAttribute(item, "label") : graph.getEdgeAttribute(item, "label");
+ message += `, ${itemType} ${label || "with no label"} (id "${item}")`;
+
+ if (itemType === "edge") {
+ message += `, source ${graph.getSourceAttribute(item, "label")}, target: ${graph.getTargetAttribute(
+ item,
+ "label",
+ )}`;
+ }
+ }
+ }
+ div.innerHTML = `${message}`;
+ logsDOM.appendChild(div);
+ logsDOM.scrollTo({ top: logsDOM.scrollHeight });
+
+ if (logsDOM.children.length > 50) logsDOM.children[0].remove();
+ }
+
+ window.customElements.define(
+ "sigma-shadow",
+ class extends HTMLElement {
+ _container: HTMLDivElement | null = null;
+
+ constructor() {
+ super();
+ }
+
+ connectedCallback() {
+ const shadowRoot = this.attachShadow({ mode: "open" });
+ const container = document.createElement("div");
+ container.style.cssText = `
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ overflow: hidden;
+ `;
+ this._container = container;
+ shadowRoot.appendChild(container);
+
+ let hoveredEdge: null | string = null;
+ const renderer = new Sigma(graph, this._container, {
+ enableEdgeEvents: true,
+ edgeReducer(edge, data) {
+ const res = { ...data };
+ if (edge === hoveredEdge) res.color = "#cc0000";
+ return res;
+ },
+ });
+
+ const nodeEvents = [
+ "enterNode",
+ "leaveNode",
+ "downNode",
+ "clickNode",
+ "rightClickNode",
+ "doubleClickNode",
+ "wheelNode",
+ ] as const;
+ const edgeEvents = ["downEdge", "clickEdge", "rightClickEdge", "doubleClickEdge", "wheelEdge"] as const;
+ const stageEvents = ["downStage", "clickStage", "doubleClickStage", "wheelStage"] as const;
+
+ nodeEvents.forEach((eventType) => renderer.on(eventType, ({ node }) => logEvent(eventType, "node", node)));
+ edgeEvents.forEach((eventType) => renderer.on(eventType, ({ edge }) => logEvent(eventType, "edge", edge)));
+
+ renderer.on("enterEdge", ({ edge }) => {
+ logEvent("enterEdge", "edge", edge);
+ hoveredEdge = edge;
+ renderer.refresh();
+ });
+ renderer.on("leaveEdge", ({ edge }) => {
+ logEvent("leaveEdge", "edge", edge);
+ hoveredEdge = null;
+ renderer.refresh();
+ });
+
+ stageEvents.forEach((eventType) => {
+ renderer.on(eventType, ({ event }) => {
+ logEvent(eventType, "positions", event);
+ });
+ });
+ }
+ },
+ );
+};
diff --git a/packages/storybook/stories/events-shadowdom/stories.ts b/packages/storybook/stories/events-shadowdom/stories.ts
new file mode 100644
index 000000000..81ce9af06
--- /dev/null
+++ b/packages/storybook/stories/events-shadowdom/stories.ts
@@ -0,0 +1,24 @@
+import { Meta, StoryObj } from "@storybook/html";
+
+import play from ".";
+import template from "./index.html?raw";
+import source from "./index?raw";
+
+const meta: Meta = {
+ id: "events-shadowdom",
+ title: "Examples",
+};
+export default meta;
+
+type Story = StoryObj;
+
+export const story: Story = {
+ name: "Events ShadowDom",
+ render: () => template,
+ play: play,
+ parameters: {
+ storySource: {
+ source: source,
+ },
+ },
+};