# `ElementorexCms.Editor`
[🔗](https://github.com/rocket4ce/elementorex_cms/blob/v0.1.0/lib/elementorex_cms/editor.ex#L1)

The visual editor, as a LiveComponent.

    <.live_component
      module={ElementorexCms.Editor}
      id="page-editor"
      document={@page.body}
      title={@page.title}
      back={~p"/admin/pages"}
      canvas={ElementorexCms.Canvas.new(stylesheets: [~p"/assets/css/app.css"])}
      locale="es"
    >
      <:status><span class="badge">Draft</span></:status>
      <:actions><button phx-click="publish">Publish</button></:actions>
    </.live_component>

It takes the whole screen (like Elementor): blocks palette and DOM tree on the
left, the canvas (an iframe with your site's CSS) in the middle, the inspector
(*Content*, *Style* and *Advanced*) on the right, and a drawer with the HTML,
CSS and JSON of the selection. Blocks are dragged from the palette into the
canvas or the tree, moved the same way, and text is edited by double-clicking
it on the canvas.

## Saving

The editor keeps its own copy of the document; saving is up to the LiveView
that hosts it. *Save* (or ⌘S) sends

    {ElementorexCms.Editor, editor_id, {:save, document}}

Persist it and confirm with `saved/1` (or report a problem with
`save_failed/2`):

    def handle_info({ElementorexCms.Editor, "page-editor", {:save, doc}}, socket) do
      case Pages.update_page(socket.assigns.page, %{body: doc}) do
        {:ok, page} ->
          ElementorexCms.Editor.saved("page-editor")
          {:noreply, assign(socket, :page, page)}

        {:error, _changeset} ->
          ElementorexCms.Editor.save_failed("page-editor", "Could not save")
          {:noreply, socket}
      end
    end

With `notify_changes`, every change also sends `{:change, document}`.

## Attributes

  * `id` (required), `document` (the initial document; later values are
    ignored unless `remount_key` changes)
  * `title`, `subtitle`, `back` (path of the back link)
  * `canvas` - `ElementorexCms.Canvas` configuration
  * `registry` - `ElementorexCms.Registry` (default: `ElementorexCms.Registry.default/0`)
  * `templates` - template modules (default: the configured ones)
  * `media`, `media_context` - see `ElementorexCms.Media`
  * `data` - passed to the blocks as `@ctx.data`
  * `locale` - language of the interface (`"en"`, `"es"`)
  * `notify_changes` - also send `{:change, document}` on every change
  * `fullscreen` - cover the screen (default `true`)
  * `inline_css` - include the editor stylesheet (default `true`; set it to
    `false` if you import `priv/static/elementorex.css` in your bundle)

Slots: `:status` (next to the title) and `:actions` (before *Save*).

## JavaScript

Register the hook (see the README):

    import {hooks as Elementorex} from "elementorex_cms"
    new LiveSocket("/live", Socket, {hooks: {...Elementorex}})

# `css`

The editor stylesheet (inlined by default, see `inline_css`).

# `replace_document`

```elixir
@spec replace_document(String.t(), map()) :: :ok
```

Replaces the document being edited (it becomes a step that can be undone).

# `save_failed`

```elixir
@spec save_failed(String.t(), String.t()) :: :ok
```

Reports that saving failed, with a message for the user.

# `saved`

```elixir
@spec saved(String.t()) :: :ok
```

Confirms that the document sent with `{:save, doc}` was saved.

---

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