# Content Items And Drawing

Drawing support owns vector items. It does not own a second item system for
images, frames, embeds, or remote content.

Use ordinary LivePanels items when the thing on the canvas should render
application content. That keeps one item contract for placement, resize,
selection, ports, persistence, and rendering.

## Use Item Content

Declare content-backed items in the canvas LiveView:

```heex
<.canvas_runtime {canvas_runtime_attrs(assigns)}>
  <:item
    id="reference-1"
    type="reference"
    at={{120, 80}}
    size={{640, 480}}
    live_view={MyAppWeb.ReferenceLive}
  >
  </:item>

  <:item
    id="remote-reference-1"
    type="remote_reference"
    at={{840, 80}}
    size={{760, 480}}
    remote={%{url: "https://example.com"}}
  >
  </:item>
</.canvas_runtime>
```

Then create those items through the normal item command path:

```heex
<button {add_item_attrs("reference", live_view: MyAppWeb.ReferenceLive, w: 640, h: 480)}>
  Reference
</button>

<button {add_item_attrs("remote_reference", remote: %{url: "https://example.com"}, w: 760, h: 480)}>
  Remote reference
</button>
```

The item type and content adapter come from the item attrs or command payload.
The drawing layer should not infer content from names such as `:image` or
`:frame`.

Remote descriptors render sandboxed iframes. Use descriptor options such as
`:sandbox`, `:allow`, and `:referrerpolicy` when an embed needs a different
iframe policy.

## Draw With Item Capabilities

Drawing behavior is item capabilities, not a sealed item class. A normal item
can participate in drawing workflows when it has valid vector capability state
and vector render capability, and it can still keep its other capabilities:

```elixir
LivePanels.Item.Factory.new(:vector, %{
  id: "shape-a",
  kind: :rectangle,
  vector: %{
    version: 2,
    geometry: %{kind: :rectangle},
    style: %{
      color: "#118833",
      width: 4,
      fill_color: "none",
      stroke_style: "solid",
      opacity: 100,
      roundness: 0
    }
  },
  render: %{kind: :vector, surface: :world_svg},
  ports: [
    %{name: "out", direction: :output, type: :any}
  ]
})
```

This is what lets the same visual object act like a vector item, a graph node,
or an app-defined item without introducing drawing-only item types.

## Excalidraw Import And Export

The Excalidraw adapter imports and exports vector items and connector items by
default.

External document elements such as images, frames, and embedded URLs are not
turned into LivePanels items by the drawing adapter. If your product wants that
mapping, perform it at the application level and create normal LivePanels items with
the existing item/content APIs.

That boundary keeps document import policy out of the drawing subsystem and lets
the application decide how assets are stored, authorized, sanitized, and
rendered.

## Boundary Rule

Use vector items for geometry created by drawing tools.

Use normal items for app content: screenshots, remote references, nested panels,
dashboards, domain records, regions, and custom graph nodes.

If a normal item needs to look or behave like a vector item, add vector state
and a vector render capability to the item. If a vector item needs ports, attach
ports to that item. Do not add a separate drawing-owned item type for the
same capability.
