# `LivePanels.Item.Content.LiveView`
[🔗](https://github.com/livepanels/livepanels/blob/v0.1.0/lib/livepanels/item/content/live_view.ex#L1)

LiveView entrypoint for content rendered inside a LivePanels canvas item.

An item LiveView is a child process of the canvas LiveView. It owns its own UI
state, while the parent canvas remains the authority for item placement,
visibility, props, graph connectors, vector items, persistence, and shared-mode
broadcasts.

## How Item Communication Works

### Item to Canvas: commands

Self-scoped helpers such as `put_props/2`, `place/2`, and `remove/1` dispatch
requests to the parent canvas. The parent applies those requests through the
normal command pipeline, including validation, authorization, reducers,
persistence, and broadcasts. Helpers return the socket immediately; the parent
processes the request asynchronously.

During disconnected mount, the runtime may not have assigned an item id yet.
Self-scoped helpers log a debug message and return the unchanged socket in
that case. Move those calls to a connected callback such as `handle_event/3`,
`handle_info/2`, or a connected `mount_item/2` branch.

### Canvas to Item: PubSub

Each mounted item LiveView subscribes to its item topic. Handle incoming
messages in `handle_info/2`.

### Item to Item: notify

Use `notify(socket, other_item_id, message)` to publish to another item's
topic.

### Item to Application: custom requests

Use `request(socket, message)` to send app-defined work to the parent canvas
LiveView as `{:livepanels_item_request, message}`.

## Item Commands

`use LivePanels.Item.Content.LiveView` imports socket-first helpers that dispatch work to
the parent canvas LiveView. The self-scoped helpers `add_attached/2`,
`add_attached/3`, `place/2`, `put_props/2`, `merge_props/2`, and
`remove/1` read the current item id from the assigned `LivePanels.Context`.
During disconnected mount, that id may not exist yet; those helpers return the
unchanged socket, log a debug message, and dispatch no parent message. The
explicit item variants `add_attached/4`, `present/3`, `place/3`,
`put_props/3`, `merge_props/3`, and `remove/2` still validate their ids and
dispatch or raise. Identity and communication helpers include `item_id/1`,
`canvas_id/1`, `notify/3`, and `request/2`.

Item LiveView helpers are fire-and-forget messages from a child LiveView to
its parent canvas; they return the socket they receive after dispatching the
parent request.

Override `terminate_item/2` when item content needs teardown. The
runtime passes the shutdown reason through this callback and keeps the
internal `{:terminate_item, reason}` message out of application `handle_info/2`.

In Phoenix apps, start with your app's ordinary LiveView macro so the content
LiveView keeps the same HTML imports, layouts, and verified routes as the
rest of the application:

    use MyAppWeb, :live_view

    use LivePanels.Item.Content.LiveView,
      pubsub: MyApp.PubSub

> #### `use LivePanels.Item.Content.LiveView` {: .info}
>
> When you `use LivePanels.Item.Content.LiveView`, the module sets the
> `LivePanels.Item.Content.LiveView` behaviour, imports item command helpers,
> defines `mount/3`, default overridable `mount_item/2` and
> `terminate_item/2` callbacks, and installs compile-time validation that the
> caller has already used Phoenix LiveView.

Item content LiveViews that want to own `mount/3` directly can call
`mount_runtime/4` instead and import `LivePanels.Item.Content.LiveView.Commands`
explicitly:

    use MyAppWeb, :live_view

    @behaviour LivePanels.Item.Content.LiveView

    @impl true
    def mount(_params, session, socket) do
      LivePanels.Item.Content.LiveView.mount_runtime(__MODULE__, MyApp.PubSub, session, socket)
    end

# `mount_item`

```elixir
@callback mount_item(Phoenix.LiveView.Socket.t(), map()) ::
  {:ok, Phoenix.LiveView.Socket.t()}
```

# `terminate_item`

```elixir
@callback terminate_item(Phoenix.LiveView.Socket.t(), term()) :: any()
```

# `mount_runtime`

```elixir
@spec mount_runtime(module(), module(), map(), Phoenix.LiveView.Socket.t()) ::
  {:ok, Phoenix.LiveView.Socket.t()}
```

Mounts the item LiveView runtime into an existing LiveView socket.

This is the explicit equivalent of the `mount/3` callback installed by
`use LivePanels.Item.Content.LiveView`. It assigns the item context, subscribes the
connected process to its item topic, installs the runtime termination hook, and
calls the item LiveView module's `mount_item/2` callback with the item props map.

# `notify`

```elixir
@spec notify(Phoenix.LiveView.Socket.t(), String.t(), term()) ::
  Phoenix.LiveView.Socket.t()
```

Publishes `message` to the item-scoped topic of an item LiveView.

The LiveView receives it in `handle_info/2`. Item LiveViews are subscribed to their
item topic automatically at mount via `use LivePanels.Item.Content.LiveView`. Item
content LiveViews that use this module can call `notify/3` without a module
qualifier.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
