# `LivePanels.Toolkit.Drawing`
[🔗](https://github.com/livepanels/livepanels/blob/v0.1.0/lib/livepanels/toolkit/drawing.ex#L1)

Drawing-extension DOM attr and JS helpers for Phoenix LiveViews.

`use LivePanels.Toolkit.Drawing` imports `LivePanels.Toolkit.Canvas` plus
committed vector item controls. Drawing mutations stay on
`LivePanels.Drawing`.

These helpers emit drawing command attrs, point handle attrs, and browser
drawing-style updates. They do not render palettes, toolbars, or editor
chrome.

# `add_point_attrs`

```elixir
@spec add_point_attrs(
  LivePanels.Item.t() | map() | String.t(),
  non_neg_integer(),
  map(),
  keyword() | map()
) :: map()
```

Returns attrs for an application control that adds one committed polyline point.

`index` is the position in the committed vector item's point list.

# `erase_attrs`

```elixir
@spec erase_attrs(LivePanels.Item.t() | map() | String.t(), keyword() | map()) ::
  map()
```

Returns attrs for an application control that removes a committed vector item.

This helper emits the vector-owned removal command rather than the generic
remove command, so the server verifies that the target is a vector item before
removing it through the normal item lifecycle.

# `erase_vector_item_target_attrs`

```elixir
@spec erase_vector_item_target_attrs(
  LivePanels.Item.t() | map() | String.t(),
  keyword() | map()
) ::
  map()
```

Returns browser eraser-target attrs for an app-rendered vector item hit area.

The attrs do not choose hit-testing geometry. Applications place them on the SVG
path, transparent button, or other rendered vector item target they want erase mode
to recognize. The browser pushes `remove_vector_item`; the server still verifies
that the target is a committed vector item before removal.

# `flatten_attrs`

```elixir
@spec flatten_attrs(
  LivePanels.Item.t()
  | map()
  | String.t()
  | [LivePanels.Item.t() | map() | String.t()],
  keyword() | map()
) :: map()
```

Returns attrs for an application control that flattens committed vector items into
one item.

`items_or_ids` may be one vector item, a vector item id, or a list of vector items/ids. The
browser sends a compact comma-separated id list; the server verifies that all
targets are committed vector items before replacing them.

# `remove_point_attrs`

```elixir
@spec remove_point_attrs(
  LivePanels.Item.t() | map() | String.t(),
  non_neg_integer(),
  keyword() | map()
) :: map()
```

Returns attrs for an application control that removes one committed polyline point.

# `set_draw_style_js`

```elixir
@spec set_draw_style_js(String.t(), map(), keyword()) :: Phoenix.LiveView.JS.t()
```

Returns a JS command that updates the browser-owned drawing style without
changing the current cursor mode.

If an application mirrors the selected style in LiveView assigns, pass
`push: "event_name"` to append an application `JS.push/2` with the normalized style
payload.

# `unflatten_attrs`

```elixir
@spec unflatten_attrs(LivePanels.Item.t() | map() | String.t(), keyword() | map()) ::
  map()
```

Returns attrs for an application control that restores a preserved flattened vector item into
its component vector items.

# `update_style_attrs`

```elixir
@spec update_style_attrs(
  LivePanels.Item.t() | map() | String.t(),
  map(),
  keyword() | map()
) :: map()
```

Returns attrs for an application control that updates a committed vector item style.

`style` must include all style fields: `:color`, `:width`, `:fill_color`,
`:stroke_style` (`"solid"` | `"dashed"` | `"dotted"`), `:opacity` (0-100),
and `:roundness` (non-negative integer).

# `vector_point_add_handle_attrs`

```elixir
@spec vector_point_add_handle_attrs(
  LivePanels.Item.t() | map() | String.t(),
  non_neg_integer(),
  keyword() | map()
) :: map()
```

Returns protocol attrs for an app-rendered polyline midpoint add handle.

The element must live inside an SVG that shares the committed vector item's
coordinate system. The browser runtime drags the handle locally and pushes
`add_vector_point` with the resulting point coordinate on release.

# `vector_point_handle_attrs`

```elixir
@spec vector_point_handle_attrs(
  LivePanels.Item.t() | map() | String.t(),
  non_neg_integer(),
  keyword() | map()
) :: map()
```

Returns protocol attrs for an app-rendered drawing point handle.

The element must live inside an SVG that shares the committed vector item's
coordinate system. The browser runtime drags the handle locally and pushes
`update_vector_point` with the resulting point coordinate on release.

---

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