# Event Handing

The Floorplan SDK emits **global events** for interactions inside the embedded plan. Each event delivers a **unified payload** describing the targeted entity (space, room, wall perimeter, or area/background) and its position.

***

### Event names

```ts
export type FloorPlanEvents =
  | "click"
  | "right-click"
  | "double-click"
  | "hover"
  | "blur"
  | "plan-right-click"
  | "outside-click";
```

* **click / double-click / right-click** — Interaction on an entity.
* **hover / blur** — Pointer enters/leaves an entity.
* **plan-right-click** — Context menu on the plan canvas (not on a specific entity).
* **outside-click** — Click detected outside interactive entities (background).

***

### Payload shape

```ts
export type FloorPlanEntityType = "SPACE" | "WALL_PERIMETER" | "ROOM" | "AREA";

export type Center = {
  x: number;        // absolute pixels in canvas coords
  y: number;
  relativeX?: number; // 0..1 within canvas
  relativeY?: number; // 0..1 within canvas
};

export interface FloorPlanEntity<T extends Record<string, any> = {}> {
  id: string;
  type: FloorPlanEntityType;   // "SPACE" | "ROOM" | "WALL_PERIMETER" | "AREA"
  center?: Center;
  properties?: T & { locationId: string; layerId: string };
}

export type SpaceMetadata = any;
export type RoomMetadata = any;
export type WallPerimeterMetadata = any;
export type FloorPlanEntityMetadata =
  | SpaceMetadata
  | RoomMetadata
  | WallPerimeterMetadata;

interface FloorPlanEvent {
  event: FloorPlanEvents;
  id: string; // mirrors metadata.id
  metadata: FloorPlanEntity<FloorPlanEntityMetadata>;
}
```

* `metadata.type` identifies the target: **SPACE**, **ROOM**, **WALL\_PERIMETER**, or **AREA** (background).
* `properties.locationId` and `properties.layerId` help you route events per site/floor.
* `center` provides both pixel and relative coordinates for precise UI placement (e.g., tooltips, context menus).

***

### Subscribing & unsubscribing

```ts
// Subscribe
sdk.on(eventName: FloorPlanEvents, handler: (e: FloorPlanEvent) => void);

// Unsubscribe a specific handler
sdk.off(eventName: FloorPlanEvents, handler: (e: FloorPlanEvent) => void);

// Unsubscribe all handlers for an event
sdk.off(eventName: FloorPlanEvents);
```

***

### Vanilla JS example

```html
<div id="floorplan-root" style="width:100%;height:720px;"></div>
<script type="module">
  import Floorplan from "/node_modules/@gospace-ai/floorplan/dist/floorplan.es.js";

  const sdk = new Floorplan({
    key: "floorplan-root",
    access_token: "<short-lived-access-token>",
    location_id: "loc_123",
    layer_id: "layer_001",
  });

  const onClick = (e) => {
    const { event, id, metadata } = e;
    // Example: SPACE/ROOM selection
    if (metadata.type === "SPACE" || metadata.type === "ROOM") {
      console.log(`[${event}]`, id, metadata);
      // open details panel, booking flow, etc.
    }
  };

  const onPlanContext = (e) => {
    // Show a context menu at e.metadata.center
    console.log("[plan-right-click]", e.metadata.center);
  };

  sdk.on("click", onClick);
  sdk.on("double-click", onClick);
  sdk.on("right-click", onClick);
  sdk.on("plan-right-click", onPlanContext);

  // Optional: hover/blur for highlighting
  sdk.on("hover", (e) => {
    // highlight e.metadata.id
  });
  sdk.on("blur", (e) => {
    // remove highlight for e.metadata.id
  });

  // Outside clicks (background)
  sdk.on("outside-click", (e) => {
    // clear selections
  });

  sdk.init();

  // later:
  // sdk.off("click", onClick);
  // sdk.destroy?.();
</script>
```

***

### Filtering & patterns

**By entity type**

```ts
sdk.on("click", ({ metadata }) => {
  switch (metadata.type) {
    case "SPACE": /* handle desk/seat */ break;
    case "ROOM":  /* handle room      */ break;
    case "WALL_PERIMETER": /* ignore or inspect */ break;
    case "AREA":  /* background */ break;
  }
});
```

**Coordinate‑based UI**

```ts
sdk.on("right-click", ({ metadata }) => {
  const { x, y } = metadata.center || { x: 0, y: 0 };
  // position a context menu at (x, y)
});
```

**Debounce high‑frequency events**

```ts
let hoverT;
sdk.on("hover", (e) => {
  clearTimeout(hoverT);
  hoverT = setTimeout(() => {
    // lightweight hover preview
  }, 80);
});
```

***

### Security

Events are delivered from the embedded iframe via `postMessage`. The SDK validates the origin internally. If you attach your own `window.message` listeners, verify `event.origin === "https://floorplan.gospace.app"` before using payloads.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://developer.gospace.com/floorplan-sdk/event-handing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
