Content Items And Drawing

Copy Markdown View Source

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:

<.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:

<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:

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.